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