KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > xml > xmlc > misc > LineNumberRecorder


1 /*
2  * Enhydra Java Application Server Project
3  *
4  * The contents of this file are subject to the Enhydra Public License
5  * Version 1.1 (the "License"); you may not use this file except in
6  * compliance with the License. You may obtain a copy of the License on
7  * the Enhydra web site ( http://www.enhydra.org/ ).
8  *
9  * Software distributed under the License is distributed on an "AS IS"
10  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
11  * the License for the specific terms governing rights and limitations
12  * under the License.
13  *
14  * The Initial Developer of the Enhydra Application Server is Lutris
15  * Technologies, Inc. The Enhydra Application Server and portions created
16  * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
17  * All Rights Reserved.
18  *
19  * Contributor(s):
20  *
21  * $Id: LineNumberRecorder.java,v 1.2 2005/01/26 08:29:24 jkjome Exp $
22  */

23
24 package org.enhydra.xml.xmlc.misc;
25
26 import java.util.ArrayList JavaDoc;
27 import java.util.EmptyStackException JavaDoc;
28
29 /**
30  * Class that records information to translate a line number or
31  * byte offset in a stream into a source file and line number.
32  */

33 public final class LineNumberRecorder extends LineNumberMap {
34     /*
35      * Structure used to implement stack of file names and line numbers.
36      */

37     private class FileStackEntry {
38         /** Saved file name, line number, and char offset */
39         public final String JavaDoc fileName;
40         public final int lineNum;
41
42         /** Constructor */
43         public FileStackEntry(String JavaDoc fileName,
44                               int lineNum) {
45             this.fileName = fileName;
46             this.lineNum = lineNum;
47         }
48     }
49
50     /**
51      * Current source file name.
52      */

53     private String JavaDoc fFileName;
54
55     /**
56      * Current line-number in the file.
57      */

58     private int fLineNum = 1;
59     
60     /**
61      * Line number in the stream.
62      */

63     private int fStreamLineNum = 1;
64
65     /**
66      * Character offset in the stream.
67      */

68     private int fStreamCharOffset;
69
70     /**
71      * Was the previous character a return?
72      */

73     private boolean fPrevWasReturn;
74
75     /**
76      * Stack of FileStackEntry objects
77      */

78     private ArrayList JavaDoc fFileStack;
79
80     /**
81      * Constructor, setting initial file.
82      */

83     public LineNumberRecorder(String JavaDoc fileName) {
84         pushFile(fileName);
85     }
86
87     /**
88      * Constructor with no initial file.
89      */

90     public LineNumberRecorder() {
91     }
92
93     /**
94      * Push a file on the stack. Called when an included file is opened.
95      */

96     public void pushFile(String JavaDoc fileName) {
97         // Don't push an entry if this is the initial file.
98
if (fFileName != null) {
99             if (fFileStack == null) {
100                 fFileStack = new ArrayList JavaDoc();
101             }
102             fFileStack.add(new FileStackEntry(fFileName, fLineNum));
103         }
104         fFileName = fileName;
105         fLineNum = 1;
106         // Add a line with a zero offset
107
addLine();
108     }
109
110     /**
111      * Pop a file from the stack. Called when an included file is closed.
112      * Allows for an extra pop to close the originally opened file.
113      */

114     public void popFile() {
115         if ((fFileStack == null) || (fFileStack.size() == 0)) {
116             if (fFileName == null) {
117                 throw new EmptyStackException JavaDoc();
118             }
119             // Pop original file.
120
fFileName = null;
121         } else {
122             FileStackEntry entry = (FileStackEntry)fFileStack.get(fFileStack.size()-1);
123             fFileName = entry.fileName;
124             fLineNum = entry.lineNum;
125             fFileStack.remove(fFileStack.size()-1);
126         }
127     }
128
129     /**
130      * Add a line to the map.
131      */

132     private void addLine() {
133         addLine(fFileName, fLineNum, fStreamLineNum, fStreamCharOffset);
134     }
135
136     /**
137      * Count a character read (and hope this gets inlined).
138      */

139     public final void countChar(char ch) {
140         fStreamCharOffset++;
141         if (fPrevWasReturn) {
142             fPrevWasReturn = false;
143         } else {
144             switch (ch) {
145             case '\r':
146                 fPrevWasReturn = true;
147             case '\n':
148                 fLineNum++;
149                 fStreamLineNum++;
150                 addLine();
151             }
152         }
153     }
154
155     /**
156      * Count an array character's readed
157      */

158     public final void countChars(final char[] chBuf,
159                                  int off,
160                                  int len) {
161         int endOff = off+len-1;
162         for (int idx = 0; idx <= endOff; idx++) {
163             countChar(chBuf[idx]);
164         }
165     }
166 }
167
Popular Tags