All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scalax.io.Line.scala Maven / Gradle / Ivy

The newest version!
/*                     __                                               *\
**     ________ ___   / /  ___     Scala API                            **
**    / __/ __// _ | / /  / _ |    (c) 2009-2010, Jesse Eichar             **
**  __\ \/ /__/ __ |/ /__/ __ |    http://scala-lang.org/               **
** /____/\___/_/ |_/____/_/ | |                                         **
**                          |/                                          **
\*                                                                      */

package scalax.io

/**
 * A modularizing object for containing objects/classes related to reading lines
 */
object Line {
  object Terminators {
    protected[io] case class LineSplit(line:Seq[Char], term:Seq[Char] = "", nextLine:Seq[Char] = "") {
      def toString(includeTerminator:Boolean) = if(includeTerminator) line ++ term mkString "" else line mkString ""
    }

    /**
     * The super class for different types of line terminators/separators
     *
     * @see [[scalax.io.LineTraversable]]
     */
    sealed abstract class Terminator {
      /**
       * Splits the characters into three parts, the line, the terminator string and the nextLine.
       */
      def split(chars: Seq[Char]) : LineSplit
    }

    /**
     * The Auto terminator detects the line terminator.
     * It can detect N,R and RN line terminators
     */
    case class Auto() extends Terminator {
        private var choices = RNPair :: NewLine :: CarriageReturn ::  Nil

        def split(chars: Seq[Char]) = synchronized {
          val splits = choices.view.map{c => (c,c split chars)}
          //val pairDoesNotMatch = splits.get(RNPair).forall{_.term isEmpty}
          splits.find{_._2.term.nonEmpty} match {
            case None =>
              splits.head._2
            case Some((RNPair,split)) =>
              choices = RNPair :: Nil
              split
            case Some((choice,split)) =>
              if(split.nextLine.nonEmpty)
                choices = choice :: Nil
              split

          }
        }
    }
    private[Terminators] abstract class Simple(val sep:String) extends Terminator {
        private val custom = Custom(sep)
        def split(chars: Seq[Char]) = custom.split (chars)
    }
    /*
     * The \n line terminator
     */
     case object NewLine extends Simple("\n")
    /**
     * The \r line terminator
     */
    case object CarriageReturn extends Simple("\r")
    /**
     * The \r\n line terminator
     */
    case object RNPair extends Simple("\r\n")
    /**
     * A custom line terminator.  It can be an arbitrary string but
     * can be less performant than one of the other terminators
     */
    case class Custom(separator: String) extends Terminator {
        def split(chars: Seq[Char]) = {
            chars.indexOfSlice(separator) match {
              case -1 => LineSplit(chars)
              case i =>
                val (line, rest) = chars.splitAt(i)
                val nextLine = rest.drop(separator.length)
                LineSplit(line,separator,nextLine)
            }
        }
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy