/** * Converts 0-based character offset to 1-based number of the line containing the character. * * @throws IllegalArgumentException if the offset is outside the string. */ public int offsetToLine(int offset) throws IllegalArgumentException { if (offset < 0 || offset > textLength) { throw new IllegalArgumentException("offset out of bounds"); } return binarySearchLine(nlOffsets, offset) + 1; }
/** * Gets the number of characters in the source. Causes the contents of this source to be loaded * if they are loaded lazily. * * @since 0.8 or earlier */ public final int getLength() { return getTextMap().length(); }
/** * The number of text lines in the source, including empty lines; characters at the end of the * source without a terminating newline count as a line. Causes the contents of this source to * be loaded if they are loaded lazily. * * @since 0.8 or earlier */ public final int getLineCount() { return getTextMap().lineCount(); }
/** * Converts 1-based line number and 1-based column number to the 0-based offset of the character * position at the line:column. * * @throws IllegalArgumentException if the column is out of range. */ public int lineColumnToOffset(int line, int column) { final int lineStartOffset = lineStartOffset(line); if (column > (lineLength(line) + 1)) { throw new IllegalArgumentException("column out of range"); } final int charIndex = lineStartOffset + column - 1; return charIndex; }
/** * Constructs map permitting translation between 0-based character offsets and 1-based * lines/columns. */ public static TextMap fromCharSequence(CharSequence text) { final int textLength = text.length(); final ArrayList<Integer> lines = new ArrayList<>(); lines.add(0); int offset = 0; while (offset < textLength) { final int nlIndex = indexOf(text, '\n', offset); if (nlIndex >= 0) { offset = nlIndex + 1; lines.add(offset); } else { break; } } lines.add(Integer.MAX_VALUE); final int[] nlOffsets = new int[lines.size()]; for (int line = 0; line < lines.size(); line++) { nlOffsets[line] = lines.get(line); } final boolean finalNL = textLength > 0 && (textLength == nlOffsets[nlOffsets.length - 2]); return new TextMap(nlOffsets, textLength, finalNL); }
throw new IllegalArgumentException("columnNumber < 1"); final int charIndex = getTextMap().lineColumnToOffset(startLine, startColumn); final int endIndex = getTextMap().lineColumnToOffset(endLine, endColumn); assert charIndex <= endIndex : charIndex + " > " + endIndex; int length = endIndex + 1 - charIndex; int sourceLength = getTextMap().length(); if (length == 1 && charIndex + length > sourceLength) {
/** * Converts 1-based line number to the 0-based offset of the line's first character; this would * be the offset of a newline if the line is empty. * * @throws IllegalArgumentException if there is no such line in the text. */ public int lineStartOffset(int line) throws IllegalArgumentException { if (lineOutOfRange(line)) { throw new IllegalArgumentException("line out of bounds"); } return nlOffsets[line - 1]; }
/** * Given a 1-based line number, return the 0-based offset of the first character in the line. * * @throws UnsupportedOperationException if this source cannot contain {@link #hasCharacters() * characters}. * @throws IllegalArgumentException if there is no such line in the text * @since 0.8 or earlier */ public final int getLineStartOffset(int lineNumber) throws IllegalArgumentException { return getTextMap().lineStartOffset(lineNumber); }
/** * The number of characters (not counting a possible terminating newline) in a (1-based) * numbered line. Causes the contents of this source to be loaded if they are loaded lazily. * * @throws UnsupportedOperationException if this source cannot contain {@link #hasCharacters() * characters}. * @throws IllegalArgumentException if there is no such line in the text * @since 0.8 or earlier */ public final int getLineLength(int lineNumber) throws IllegalArgumentException { return getTextMap().lineLength(lineNumber); }
TextMap createTextMap() { final CharSequence code = getCharacters(); if (code == null) { throw new RuntimeException("can't read file " + getName()); } return TextMap.fromCharSequence(code); }
/** * Given a 0-based character offset, return the 1-based number of the column at the position. * Causes the contents of this source to be loaded if they are loaded lazily. * * @throws UnsupportedOperationException if this source cannot contain {@link #hasCharacters() * characters}. * @throws IllegalArgumentException if the offset is outside the text contents * @since 0.8 or earlier */ public final int getColumnNumber(int offset) throws IllegalArgumentException { return getTextMap().offsetToCol(offset); }
/** * Gets the text (not including a possible terminating newline) in a (1-based) numbered line. * Causes the contents of this source to be loaded if they are loaded lazily. * * @since 0.28 */ public final CharSequence getCharacters(int lineNumber) { final int offset = getTextMap().lineStartOffset(lineNumber); final int length = getTextMap().lineLength(lineNumber); return getCharacters().subSequence(offset, offset + length); }
/** * Constructs map permitting translation between 0-based character offsets and 1-based * lines/columns. */ public static TextMap fromCharSequence(CharSequence text) { final int textLength = text.length(); final ArrayList<Integer> lines = new ArrayList<>(); lines.add(0); int offset = 0; while (offset < textLength) { final int nlIndex = indexOf(text, '\n', offset); if (nlIndex >= 0) { offset = nlIndex + 1; lines.add(offset); } else { break; } } lines.add(Integer.MAX_VALUE); final int[] nlOffsets = new int[lines.size()]; for (int line = 0; line < lines.size(); line++) { nlOffsets[line] = lines.get(line); } final boolean finalNL = textLength > 0 && (textLength == nlOffsets[nlOffsets.length - 2]); return new TextMap(nlOffsets, textLength, finalNL); }
/** * Converts 1-based line number to the 0-based offset of the line's first character; this would * be the offset of a newline if the line is empty. * * @throws IllegalArgumentException if there is no such line in the text. */ public int lineStartOffset(int line) throws IllegalArgumentException { if (textLength == 0) { return 0; } if (lineOutOfRange(line)) { throw new IllegalArgumentException("line out of bounds"); } return nlOffsets[line - 1]; }
/** * Given a 1-based line number, return the 0-based offset of the first character in the line. * * @throws IllegalArgumentException if there is no such line in the text * @since 0.8 or earlier */ public final int getLineStartOffset(int lineNumber) throws IllegalArgumentException { return getTextMap().lineStartOffset(lineNumber); }
/** * The number of characters (not counting a possible terminating newline) in a (1-based) * numbered line. Causes the contents of this source to be loaded if they are loaded lazily. * * @throws IllegalArgumentException if there is no such line in the text * @since 0.8 or earlier */ public final int getLineLength(int lineNumber) throws IllegalArgumentException { return getTextMap().lineLength(lineNumber); }
TextMap createTextMap() { final CharSequence code = getCharacters(); if (code == null) { throw new RuntimeException("can't read file " + getName()); } return TextMap.fromCharSequence(code); }
/** * Given a 0-based character offset, return the 1-based number of the column at the position. * Causes the contents of this source to be loaded if they are loaded lazily. * * @throws IllegalArgumentException if the offset is outside the text contents * @since 0.8 or earlier */ public final int getColumnNumber(int offset) throws IllegalArgumentException { return getTextMap().offsetToCol(offset); }
/** * Gets the text (not including a possible terminating newline) in a (1-based) numbered line. * Causes the contents of this source to be loaded if they are loaded lazily. * * @throws UnsupportedOperationException if this source cannot contain {@link #hasCharacters() * characters}. * @since 0.28 */ public final CharSequence getCharacters(int lineNumber) { final int offset = getTextMap().lineStartOffset(lineNumber); final int length = getTextMap().lineLength(lineNumber); return getCharacters().subSequence(offset, offset + length); }
/** * Gets the number of characters in a line, identified by 1-based line number; <em>does not</em> * include the final newline, if any. * * @throws IllegalArgumentException if there is no such line in the text. */ public int lineLength(int line) throws IllegalArgumentException { if (lineOutOfRange(line)) { throw new IllegalArgumentException("line out of bounds"); } if (line == nlOffsets.length - 1) { return textLength - nlOffsets[line - 1]; } return (nlOffsets[line] - nlOffsets[line - 1]) - 1; }