LinesAndColumns.java
/*
* Copyright 2013 Michael Mackenzie High
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mackenziehigh.snowflake;
/**
* An instance of this class computes line-numbers and column-numbers regarding a character-array.
*
* @author Michael Mackenzie High
*/
public final class LinesAndColumns
{
/**
* An element in this array is the line-number of the character at the
* equivalently indexed array element in the input.
*/
final int[] lineNumbers;
/**
* An element in this array is the column-number of the character at the
* equivalently indexed array element in the input.
*/
final int[] columnNumbers;
/**
* Sole Constructor.
*
* @param input is the input itself.
* @param newline is the newline that separates lines in the input.
* @throws UnsupportedOperationException if [newline] is not supported.
*/
public LinesAndColumns(final char[] input,
final NewlineStyles newline)
{
Utils.checkNonNull(input);
Utils.checkNonNull(newline);
this.lineNumbers = new int[input.length];
this.columnNumbers = new int[input.length];
switch(newline)
{
case CR: compute(input, '\r'); break;
case LF: compute(input, '\n'); break;
case CR_LF: compute(input, '\r', '\n'); break;
default: throw new UnsupportedOperationException("Unsupported Newline Type");
}
}
/**
* This method computes the line-number and column-number information,
* if the newline is a single character.
*
* @param input is the input that contains the lines and columns.
* @param newline is the newline character itself.
*/
final void compute(final char[] input,
final char newline)
{
int lines = 1;
int columns = 1;
boolean condition = false;
for(int i = 0; i < input.length; i++)
{
lineNumbers[i] = lines;
columnNumbers[i] = columns;
condition = newline == input[i];
lines += condition ? 1 : 0;
columns = condition ? 1 : ++columns;
}
}
/**
* This method computes the line-number and column-number information,
* if the newline is a two character sequence.
*
* @param input is the input that contains the lines and columns.
* @param newlineP1 is the first character in the newline sequence.
* @param newlineP2 is the second character in the newline sequence.
*/
final void compute(final char[] input,
final char newlineP1,
final char newlineP2)
{
int lines = 1;
int columns = 2;
boolean condition = false;
if(input.length > 0)
{
lineNumbers[0] = 1;
columnNumbers[0] = 1;
}
for(int i = 1; i < input.length; i++)
{
lineNumbers[i] = lines;
columnNumbers[i] = columns;
condition = input[i - 1] == newlineP1 && input[i] == newlineP2;
lines += condition ? 1 : 0;
columns = condition ? 1 : ++columns;
}
}
/**
* This method returns an array that contains exactly one element,
* a line-number, for each character in the input that was used to
* create this object.
*
* @return an array of the line-numbers for the input that was used to
* create this object. The returned array has a unique identity per
* instance of this object, but not per invocation of this method.
*/
public int[] lineNumbers()
{
return lineNumbers;
}
/**
* This method returns an array that contains exactly one element,
* a column-number, for each character in the input that was used
* to create this object.
*
* @return an array of the column-numbers for the input that was used
* to create this object. The returned array has a unique identity
* per instance of this object, but not per invocation of this method.
*/
public int[] columnNumbers()
{
return columnNumbers;
}
}