summaryrefslogblamecommitdiff
path: root/src/library/scala/io/Position.scala
blob: 6cb952d37890e1b1a8210d6f146e6c66968e4fc4 (plain) (tree)
1
2
3
4
5
6
7
8

                                                                          
                                                                          


                                                                          

                                                                          


       

                 
                                          
 












                                                                      
                                                                           
          
                                                      
































                                                                              
                             
                        

                  




                               

                                       













                                                                 
                                 





                           
/*                     __                                               *\
**     ________ ___   / /  ___     Scala API                            **
**    / __/ __// _ | / /  / _ |    (c) 2003-2006, LAMP/EPFL             **
**  __\ \/ /__/ __ |/ /__/ __ |                                         **
** /____/\___/_/ |_/____/_/ | |                                         **
**                          |/                                          **
\*                                                                      */

// $Id$


package scala.io;

import scala.runtime.compat.StringBuilder;

/** convenience methods to encode line and column number in one
 *  single integer. The encode line (column)
 * numbers range from 0 to LINE_MASK (COLUMN_MASK), where 0 indicates
 * that the line (column) is the undefined and 1 represents the first
 * line (column). Line (Column) numbers greater than LINE_MASK
 * (COLUMN_MASK) are replaced by LINE_MASK (COLUMN_MASK). Furthermore,
 * if the encoded line number is LINE_MASK, the column number is
 * always set to 0.

 * The following properties hold:
 * - the undefined position is 0: encode(0,0) == 0
 * - encodings are non-negative : encode(line,column) >= 0
 * - position order is preserved:
 *   (line1 < line2) || (line1 == line2 && column1 < column2)
 * implies
 *   encode(line1,column1) <= encode(line2,column2)
 *  @author Burak Emir (translated from work by Matthias Zengers and others)
 */
object Position {

  /** Number of bits used to encode the line number */
  final val LINE_BITS   = 20;
  /** Number of bits used to encode the column number */
  final val COLUMN_BITS = 31 - LINE_BITS; // no negatives => 31

  /** Mask to decode the line number */
  final val LINE_MASK   = (1 << LINE_BITS) - 1;
  /** Mask to decode the column number */
  final val COLUMN_MASK = (1 << COLUMN_BITS) - 1;

  /** The undefined position */
  final val NOPOS       = 0;

  /** The first position in a source file */
  final val FIRSTPOS    = encode(1, 1);

    //########################################################################
    // Public Functions

  /** Encodes a position into a single integer. */
  final def encode(line: Int, column: Int): Int = {
    var line1, column1 = 0;
    if( line < 0 )
      error(line+" < 0");
    if(( line == 0 )&&(column != 0))
      error(line+","+column+" not allowed");
    if( column < 0 )
      error(line+","+column+" not allowed");

    {if (line >= LINE_MASK) {
      line1 = LINE_MASK;
      column1 = 0;
    } else {
      line1 = line;
      if (column > COLUMN_MASK)
        column1 = COLUMN_MASK;
      else
        column1 = column
    }}
    {(line1 << COLUMN_BITS) | column1;}
  }

  /** Returns the line number of the encoded position. */
  final def line(pos: Int): Int = {
    (pos >> COLUMN_BITS) & LINE_MASK;
  }

  /** Returns the column number of the encoded position. */
  final def column(pos: Int): Int = {
    pos & COLUMN_MASK;
  }

  /** Returns a string representation of the encoded position. */
  def toString(pos: Int): String = {
    val sb = new StringBuilder();
    sb.append(line(pos));
    sb.append(':');
    sb.append(column(pos));
    sb.toString();
  }
}