/***********************************************************************************************************************
* Copyright (C) 2010-2013 by the Stratosphere project (http://stratosphere.eu)
*
* 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 eu.stratosphere.test.iterative.nephele.danglingpagerank;
import java.io.Serializable;
import com.google.common.base.Charsets;
public class AsciiLongArrayView implements Serializable {
private static final long serialVersionUID = 1L;
private byte[] buffer;
private int offset;
private int numBytes;
private int tokenOffset;
private int tokenNumBytes;
private static final int NOT_SET = -1;
private static final int RADIX_TEN = 10;
private static final long MULTMIN_RADIX_TEN = Long.MIN_VALUE / 10;
private static final long N_MULTMAX_RADIX_TEN = -Long.MAX_VALUE / 10;
public void set(byte[] buffer, int offset, int numBytes) {
this.buffer = buffer;
this.offset = offset;
this.numBytes = numBytes;
this.tokenOffset = NOT_SET;
checkForSingleTrailingWhitespace();
}
private void checkForSingleTrailingWhitespace() {
if (Character.isWhitespace((char) buffer[offset + numBytes -1])) {
numBytes--;
}
}
public int numElements() {
int matches = 0;
int pos = offset;
while (pos < offset + numBytes) {
if (Character.isWhitespace((char) buffer[pos])) {
matches++;
}
pos++;
}
return matches + 1;
}
public boolean next() {
if (tokenOffset == NOT_SET) {
tokenOffset = offset;
} else {
tokenOffset += tokenNumBytes + 1;
if (tokenOffset > offset + numBytes) {
return false;
}
}
tokenNumBytes = 1;
while (true) {
int candidatePos = tokenOffset + tokenNumBytes;
if (candidatePos >= offset + numBytes || Character.isWhitespace((char) buffer[candidatePos])) {
break;
}
tokenNumBytes++;
}
return true;
}
private char tokenCharAt(int pos) {
return (char) buffer[tokenOffset + pos];
}
public long element() {
long result = 0;
boolean negative = false;
int i = 0, max = tokenNumBytes;
long limit;
long multmin;
int digit;
if (max > 0) {
if (tokenCharAt(0) == '-') {
negative = true;
limit = Long.MIN_VALUE;
i++;
} else {
limit = -Long.MAX_VALUE;
}
multmin = negative ? MULTMIN_RADIX_TEN : N_MULTMAX_RADIX_TEN;
if (i < max) {
digit = Character.digit(tokenCharAt(i++), RADIX_TEN);
if (digit < 0) {
throw new NumberFormatException(toString());
} else {
result = -digit;
}
}
while (i < max) {
// Accumulating negatively avoids surprises near MAX_VALUE
digit = Character.digit(tokenCharAt(i++), RADIX_TEN);
if (digit < 0) {
throw new NumberFormatException(toString());
}
if (result < multmin) {
throw new NumberFormatException(toString());
}
result *= RADIX_TEN;
if (result < limit + digit) {
throw new NumberFormatException(toString());
}
result -= digit;
}
} else {
throw new NumberFormatException(toString());
}
if (negative) {
if (i > 1) {
return result;
} else { /* Only got "-" */
throw new NumberFormatException(toString());
}
} else {
return -result;
}
}
// public double elementAsDouble() {
// String token = new String(buffer, tokenOffset, tokenNumBytes, Charsets.US_ASCII);
// return Double.valueOf(token);
// }
@Override
public String toString() {
return "[" + new String(buffer, offset, numBytes, Charsets.US_ASCII) + "] (buffer length: " + buffer.length +
", offset: " + offset + ", numBytes: " + numBytes + ")";
}
}