001: /*
002: *******************************************************************************
003: * Copyright (C) 2002-2004, International Business Machines Corporation and *
004: * others. All Rights Reserved. *
005: *******************************************************************************
006: */
007: package com.ibm.icu.dev.tool.localeconverter;
008:
009: import java.io.*;
010:
011: /**
012: * A LineCharNumberReader is a BufferedReader that
013: * keeps track of the line number and character offset
014: * on that line of the current input stream.
015: */
016: public class LineCharNumberReader extends BufferedReader {
017: private int lineNumber = 0;
018: private int charNumber = 0;
019: private int markedLineNumber;
020: private int markedCharNumber;
021: private boolean skipLF;
022:
023: public LineCharNumberReader(Reader in) {
024: super (in);
025: //{{INIT_CONTROLS
026: //}}
027: }
028:
029: public LineCharNumberReader(Reader in, int sz) {
030: super (in, sz);
031: }
032:
033: public int getLineNumber() {
034: return lineNumber;
035: }
036:
037: public int getCharNumber() {
038: return charNumber;
039: }
040:
041: public int read() throws IOException {
042: synchronized (lock) {
043: int c = super .read();
044: charNumber++;
045: if (skipLF) {
046: if (c == '\n')
047: c = super .read();
048: skipLF = false;
049: }
050: switch (c) {
051: case '\r':
052: skipLF = true;
053: case '\n': /* Fall through */
054: case '\u2028': /* Fall through */
055: case '\u2029': /* Fall through */
056: lineNumber++;
057: charNumber = 0;
058: return '\n';
059: }
060: return c;
061: }
062: }
063:
064: public int read(char cbuf[], int off, int len) throws IOException {
065: synchronized (lock) {
066: int n = super .read(cbuf, off, len);
067:
068: for (int i = off; i < off + len; i++) {
069: int c = cbuf[i];
070: charNumber++;
071: if (skipLF) {
072: skipLF = false;
073: if (c == '\n')
074: continue;
075: }
076: switch (c) {
077: case '\r':
078: skipLF = true;
079: case '\n': /* Fall through */
080: case '\u2028': /* Fall through */
081: case '\u2029': /* Fall through */
082: lineNumber++;
083: charNumber = 0;
084: break;
085: }
086: }
087:
088: return n;
089: }
090: }
091:
092: public String readLine() throws IOException {
093: synchronized (lock) {
094: String l = super .readLine();
095: if (l != null)
096: lineNumber++;
097: charNumber = 0;
098: skipLF = false;
099: return l;
100: }
101: }
102:
103: private static final int maxSkipBufferSize = 8192;
104:
105: private char skipBuffer[] = null;
106:
107: public long skip(long n) throws IOException {
108: int nn = (int) Math.min(n, maxSkipBufferSize);
109: synchronized (lock) {
110: if ((skipBuffer == null) || (skipBuffer.length < nn))
111: skipBuffer = new char[nn];
112: long r = n;
113: while (r > 0) {
114: int nc = read(skipBuffer, 0, nn);
115: if (nc == -1)
116: break;
117: r -= nc;
118: }
119: return n - r;
120: }
121: }
122:
123: public void mark(int readAheadLimit) throws IOException {
124: synchronized (lock) {
125: super .mark(readAheadLimit);
126: markedLineNumber = lineNumber;
127: markedCharNumber = charNumber;
128: }
129: }
130:
131: public void reset() throws IOException {
132: synchronized (lock) {
133: super .reset();
134: lineNumber = markedLineNumber;
135: charNumber = markedCharNumber;
136: }
137: }
138:
139: //{{DECLARE_CONTROLS
140: //}}
141: }
|