<commit_before>/*                     __                                               *\
**     ________ ___   / /  ___     Scala API                            **
**    / __/ __// _ | / /  / _ |    (c) 2003-2004, LAMP/EPFL             **
**  __\ \/ /__/ __ |/ /__/ __ |                                         **
** /____/\___/_/ |_/____/_/ | |                                         **
**                          |/                                          **
** $Id$
\*                                                                      */

package scala.tools.nsc.util;
import scala.tools.util.AbstractFile;
import scala.tools.util.CharArrayFile;

/** Uses positions that are offsets rather than line/column pairs.
 *
 *  @author <NAME>
 */
object SourceFile {
  val LF : Char = 0x0A;
  val FF : Char = 0x0C;
  val CR : Char = 0x0D;
  val SU : Char = 0x1A;
  def isLineBreak(c : Char) = c == LF || c == FF || c == CR || c == SU;
}


class SourceFile(_file : AbstractFile, _content : Array[Char]) {
  import SourceFile._;


  val file    = _file;
  val content = normalize(_content);

  def getContent() = content;

  def getFile() = file;

  def this(sourceName: String, content : Array[Char]) =
    this(new CharArrayFile(sourceName, content), content);

  def isLineBreak(idx : Int) = SourceFile.isLineBreak(content(idx));


  def position(offset : Int) = new Position(this, offset);
  def position(line : Int, column : Int) = new Position(this, lineToOffset(line) + column);

  // constants

  // NOTE: all indexes are based on zero!!!!
  override def toString(): String = file.getName() + ":" + content.length;


  object line {
    var index  = 0;
    var offset = 0;

    private def reset: Unit = {
      index = 0; offset = 0;
    }

    def find(toFind : Int, isIndex : Boolean) : Int = {
      if (!isIndex && toFind == Position.NOPOS ) return Position.NOLINE - 1; // 1 will be added
      if ( isIndex && toFind == Position.NOLINE) return Position.NOPOS;

      if (!isIndex && (toFind >= content.length)) throw new Error(toFind + " not valid offset in " + file.getName() + ":" + content.length);

      if ( isIndex && toFind <  index) reset;
      if (!isIndex && toFind < offset) reset;
      try {
	var seek = 0;
	var continue = true;
	while (continue) {
	  if (false) {;}
	  else if ( isIndex && seek == 0 && toFind == index   ) continue = false;
	  else if (!isIndex &&      toFind ==  offset + seek  ) continue = false;
	  else if (!isIndex &&     (toFind  < (offset + seek))) throw new Error("HOW??? toFind=" + toFind + " offset=" + offset + " seek=" + seek);
	  else if (isLineBreak(offset + seek)) {
	    index  = index         + 1;
	    offset = offset + seek + 1;
	    seek = 0;
	  } else seek = seek + 1;<commit_msg>Also need this file to fix bug #487<commit_after>/*                     __                                               *\
**     ________ ___   / /  ___     Scala API                            **
**    / __/ __// _ | / /  / _ |    (c) 2003-2004, LAMP/EPFL             **
**  __\ \/ /__/ __ |/ /__/ __ |                                         **
** /____/\___/_/ |_/____/_/ | |                                         **
**                          |/                                          **
** $Id$
\*                                                                      */

package scala.tools.nsc.util;
import scala.tools.util.AbstractFile;
import scala.tools.util.CharArrayFile;

/** Uses positions that are offsets rather than line/column pairs.
 *
 *  @author <NAME>
 */
object SourceFile {
  val LF : Char = 0x0A;
  val FF : Char = 0x0C;
  val CR : Char = 0x0D;
  val SU : Char = 0x1A;
  def isLineBreak(c : Char) = c == LF || c == FF || c == CR || c == SU;
}


class SourceFile(_file : AbstractFile, _content : Array[Char]) {
  import SourceFile._;


  val file    = _file;
  val content = normalize(_content);

  def getContent() = content;

  def getFile() = file;

  def this(sourceName: String, content : Array[Char]) =
    this(new CharArrayFile(sourceName, content), content);

  def isLineBreak(idx : Int) = SourceFile.isLineBreak(content(idx));


  def position(offset : Int) = new Position(this, offset);
  def position(line : Int, column : Int) = new Position(this, lineToOffset(line) + column);

  // constants

  // NOTE: all indexes are based on zero!!!!
  override def toString(): String = file.getName() + ":" + content.length;


  object line {
    var index  = 0;
    var offset = 0;

    private def reset: Unit = {
      index = 0; offset = 0;
    }

    def find(toFind : Int, isIndex : Boolean) : Int = {
      if (!isIndex) assert(toFind != Position.NOPOS);
      if ( isIndex) assert(toFind > Position.NOLINE - Position.FIRSTLINE);

      if (!isIndex && (toFind >= content.length)) throw new Error(toFind + " not valid offset in " + file.getName() + ":" + content.length);

      if ( isIndex && toFind <  index) reset;
      if (!isIndex && toFind < offset) reset;
      try {
	var seek = 0;
	var continue = true;
	while (continue) {
	  if (false) {;}
	  else if ( isIndex && seek == 0 && toFind == index   ) continue = false;
	  else if (!isIndex &&      toFind ==  offset + seek  ) continue = false;
	  else if (!isIndex &&     (toFind  < (offset + seek))) throw new Error("HOW??? toFind=" + toFind + " offset=" + offset + " seek=" + seek);
	  else if (isLineBreak(offset + seek)) {
	    index  = index         + 1;
	    offset = offset + seek + 1;
	    seek = 0;
	  } else seek = seek + 1;
{'fraction_non_alphanumeric': 0.14212734902390076, 'fraction_numerical': 0.010399562123700055, 'mean_word_length': 1.7813292744799594, 'pattern_counts': {'":': 4, '<': 11, '<?xml version=': 0, '>': 8, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 26, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3391712', 'n_tokens_mistral': 1748, 'n_tokens_neox': 1627, 'n_words': 470}