1 /* Copyright (c) 2002-2009 The University of the West Indies
2  *
3  * Contact: robert.lancashire@uwimona.edu.jm
4  *
5  *  This library is free software; you can redistribute it and/or
6  *  modify it under the terms of the GNU Lesser General Public
7  *  License as published by the Free Software Foundation; either
8  *  version 2.1 of the License, or (at your option) any later version.
9  *
10  *  This library is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  *  Lesser General License for more details.
14  *
15  *  You should have received a copy of the GNU Lesser General Public
16  *  License along with this library; if not, write to the Free Software
17  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 package jspecview.source;
21 
22 import java.io.BufferedReader;
23 import java.io.IOException;
24 
25 import javajs.util.SB;
26 
27 import org.jmol.util.Logger;
28 
29 
30 /**
31  * @author Debbie-Ann Facey
32  * @author Khari A. Bryan
33  * @author Prof Robert J. Lancashire
34  * @see jspecview.source.JDXSource
35  */
36 public class JDXSourceStreamTokenizer {
37 
38   private BufferedReader br;
39 
JDXSourceStreamTokenizer(BufferedReader br)40   JDXSourceStreamTokenizer(BufferedReader br) {
41     this.br = br;
42   }
43 
44   /**
45    * The Label part of the next token
46    */
47   String rawLabel;
48   /**
49    * The value part of the next token
50    */
51   private String value;
52 
53   /**
54    * The line number of the label
55    */
56   int labelLineNo = 0;
57   String line;
58 
59   private int lineNo;
60 
61   public String rawLine;
62 
peakLabel()63   String peakLabel() {
64     return nextLabel(false);
65   }
66 
getLabel()67   String getLabel() {
68     return nextLabel(true);
69   }
70 
nextLabel(boolean isGet)71   private String nextLabel(boolean isGet) {
72     rawLabel = null;
73     value = null;
74     while (line == null || line.length() == 0) {
75       try {
76         readLine();
77         if (line == null) {
78           line = "";
79           return null;
80         }
81         line = line.trim();
82       } catch (IOException e) {
83         line = "";
84         return null;
85       }
86       if (line.startsWith("##"))
87         break;
88       line = null;
89     }
90     rawLine = line;
91     int pt = line.indexOf("=");
92     if (pt < 0) {
93       if (isGet)
94         Logger.info("BAD JDX LINE -- no '=' (line " + lineNo + "): " + line);
95       rawLabel = line;
96       if (!isGet)
97         line = "";
98     } else {
99       rawLabel = line.substring(0, pt).trim();
100       if (isGet)
101         line = line.substring(pt + 1);
102     }
103     labelLineNo = lineNo;
104     if (Logger.debugging)
105       Logger.info(rawLabel);
106     return cleanLabel(rawLabel);
107   }
108 
109   /**
110    * Extracts spaces, underscores etc. from the label
111    *
112    * @param label
113    *        the label to be cleaned
114    * @return the new label
115    */
cleanLabel(String label)116   public static String cleanLabel(String label) {
117     if (label == null)
118       return null;
119     int i;
120     SB str = new SB();
121 
122     for (i = 0; i < label.length(); i++) {
123       switch (label.charAt(i)) {
124       case '/':
125       case '\\':
126       case ' ':
127       case '-':
128       case '_':
129         break;
130       default:
131         str.appendC(label.charAt(i));
132         break;
133       }
134     }
135     return str.toString().toUpperCase();
136   }
137 
getValue()138   public String getValue() {
139     if (value != null)
140       return value;
141     SB sb = new SB().append(line);
142     if (sb.length() > 0)
143       sb.appendC('\n');
144     try {
145       while (readLine() != null) {
146         if (line.indexOf("##") >= 0 && line.trim().startsWith("##"))
147           break;
148         sb.append(line).appendC('\n');
149       }
150     } catch (IOException e) {
151     	Logger.info(e.toString());
152     }
153     value = (rawLabel.startsWith("##$") ? sb.toString().trim() : trimLines(sb));
154     if (Logger.debugging)
155       Logger.info(value);
156     return value;
157   }
158 
readLineTrimmed()159   public String readLineTrimmed() throws IOException {
160     readLine();
161     if (line == null)
162       return null;
163     if (line.indexOf("$$") < 0)
164       return line.trim();
165     SB sb = new SB().append(line);
166     return trimLines(sb);
167   }
168 
flushLine()169   String flushLine() {
170     SB sb = new SB().append(line);
171     line = null;
172     return trimLines(sb);
173   }
174 
readLine()175   private String readLine() throws IOException {
176     line = br.readLine();
177     lineNo++;
178     return line;
179   }
180 
trimLines(SB v)181   private static String trimLines(SB v) {
182     int n = v.length();
183     int ilast = n - 1;
184     int vpt = ptNonWhite(v, 0, n);
185     if (vpt >= n)
186       return "";
187     // no line trimming for XML or <....> data
188 //    if (v.charAt(vpt) == '<') {
189 //      n = v.lastIndexOf(">") + 1;
190 //      if (n == 0)
191 //        n = v.length();
192 //      return v.toString().substring(vpt, n);
193 //    }
194     char[] buffer = new char[n - vpt];
195     int pt = 0;
196     for (;vpt < n; vpt++) {
197       char ch;
198       switch (ch = v.charAt(vpt)) {
199       case '\r':
200         if (vpt < ilast && v.charAt(vpt + 1) == '\n')
201           continue;
202         ch = '\n';
203         break;
204       case '\n':
205         if (pt > 0 && buffer[pt - 1] != '\n')
206           pt -= vpt - ptNonSpaceRev(v, vpt) - 1;
207         vpt = ptNonSpace(v, ++vpt, n) - 1;
208         break;
209       case '$':
210         if (vpt < ilast && v.charAt(vpt + 1) == '$') {
211           vpt++;
212           while (++vpt < n && "\n\r".indexOf(v.charAt(vpt)) < 0) {
213             // skip to end of line
214           }
215           continue;
216         }
217         break;
218       }
219       if (ch == '\n' && pt > 0 && buffer[pt - 1] == '\n')
220         continue;
221       buffer[pt++] = ch;
222     }
223     if (pt > 0 && buffer[pt - 1] == '\n')
224       --pt;
225     return (new String(buffer)).substring(0, pt).trim();
226   }
227 
ptNonWhite(SB v, int pt, int n)228   private static int ptNonWhite(SB v, int pt, int n) {
229     while (pt < n && Character.isWhitespace(v.charAt(pt)))
230       pt++;
231     return pt;
232   }
233 
ptNonSpace(SB v, int pt, int n)234   private static int ptNonSpace(SB v, int pt, int n) {
235     while (pt < n && (v.charAt(pt) == ' ' || v.charAt(pt) == '\t'))
236       pt++;
237     return pt;
238   }
239 
ptNonSpaceRev(SB v, int pt)240   private static int ptNonSpaceRev(SB v, int pt) {
241     while (--pt >= 0 && (v.charAt(pt) == ' ' || v.charAt(pt) == '\t')) {
242       // move on back one character
243     }
244     return pt;
245   }
246 
247 
248 }
249