1 2 4 package com.thaiopensource.relaxng.parse.compact; 5 6 import com.thaiopensource.util.Utf16; 7 import com.thaiopensource.relaxng.parse.BuildException; 8 9 import java.io.IOException ; 10 11 15 public final class UCode_UCodeESC_CharStream { 16 public static final boolean staticFlag = false; 17 18 static final int hexval(char c) { 19 switch (c) { 20 case '0': 21 return 0; 22 case '1': 23 return 1; 24 case '2': 25 return 2; 26 case '3': 27 return 3; 28 case '4': 29 return 4; 30 case '5': 31 return 5; 32 case '6': 33 return 6; 34 case '7': 35 return 7; 36 case '8': 37 return 8; 38 case '9': 39 return 9; 40 41 case 'a': 42 case 'A': 43 return 10; 44 case 'b': 45 case 'B': 46 return 11; 47 case 'c': 48 case 'C': 49 return 12; 50 case 'd': 51 case 'D': 52 return 13; 53 case 'e': 54 case 'E': 55 return 14; 56 case 'f': 57 case 'F': 58 return 15; 59 } 60 return -1; 61 } 62 63 public int bufpos = -1; 64 int bufsize; 65 int available; 66 int tokenBegin; 67 private int bufline[]; 68 private int bufcolumn[]; 69 70 private int column = 0; 71 private int line = 1; 72 73 private java.io.Reader inputStream; 74 private boolean closed = false; 75 76 private boolean prevCharIsLF = false; 77 78 private char[] nextCharBuf; 79 private char[] buffer; 80 private int maxNextCharInd = 0; 81 private int nextCharInd = -1; 82 private int inBuf = 0; 83 84 private final void ExpandBuff(boolean wrapAround) { 85 char[] newbuffer = new char[bufsize + 2048]; 86 int newbufline[] = new int[bufsize + 2048]; 87 int newbufcolumn[] = new int[bufsize + 2048]; 88 89 if (wrapAround) { 90 System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); 91 System.arraycopy(buffer, 0, newbuffer, 92 bufsize - tokenBegin, bufpos); 93 buffer = newbuffer; 94 95 System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin); 96 System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos); 97 bufline = newbufline; 98 99 System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin); 100 System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos); 101 bufcolumn = newbufcolumn; 102 103 bufpos += (bufsize - tokenBegin); 104 } 105 else { 106 System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); 107 buffer = newbuffer; 108 109 System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin); 110 bufline = newbufline; 111 112 System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin); 113 bufcolumn = newbufcolumn; 114 115 bufpos -= tokenBegin; 116 } 117 118 available = (bufsize += 2048); 119 tokenBegin = 0; 120 } 121 122 private final void FillBuff() throws EOFException { 123 int i; 124 if (maxNextCharInd == 4096) 125 maxNextCharInd = nextCharInd = 0; 126 127 if (closed) 128 throw new EOFException(); 129 try { 130 if ((i = inputStream.read(nextCharBuf, maxNextCharInd, 4096 - maxNextCharInd)) == -1) { 131 closed = true; 132 inputStream.close(); 133 throw new EOFException(); 134 } 135 else 136 maxNextCharInd += i; 137 } 138 catch (IOException e) { 139 throw new BuildException(e); 140 } 141 } 142 143 private final char ReadChar() throws EOFException { 144 if (++nextCharInd >= maxNextCharInd) 145 FillBuff(); 146 147 return nextCharBuf[nextCharInd]; 148 } 149 150 private final char PeekChar() throws EOFException { 151 char c = ReadChar(); 152 --nextCharInd; 153 return c; 154 } 155 156 public final char BeginToken() throws EOFException { 157 if (inBuf > 0) { 158 --inBuf; 159 return buffer[tokenBegin = (bufpos == bufsize - 1) ? (bufpos = 0) 160 : ++bufpos]; 161 } 162 163 tokenBegin = 0; 164 bufpos = -1; 165 166 return readChar(); 167 } 168 169 private final void AdjustBuffSize() { 170 if (available == bufsize) { 171 if (tokenBegin > 2048) { 172 bufpos = 0; 173 available = tokenBegin; 174 } 175 else 176 ExpandBuff(false); 177 } 178 else if (available > tokenBegin) 179 available = bufsize; 180 else if ((tokenBegin - available) < 2048) 181 ExpandBuff(true); 182 else 183 available = tokenBegin; 184 } 185 186 private final void UpdateLineColumn(char c) { 187 column++; 188 189 if (prevCharIsLF) { 190 prevCharIsLF = false; 191 line += (column = 1); 192 } 193 194 switch (c) { 195 case NEWLINE_MARKER: 196 prevCharIsLF = true; 197 break; 198 case '\t': 199 column--; 200 column += (8 - (column & 07)); 201 break; 202 default : 203 break; 204 } 205 206 bufline[bufpos] = line; 207 bufcolumn[bufpos] = column; 208 } 209 210 private final char NEWLINE_MARKER = '\u0000'; 211 212 public final char readChar() throws EOFException { 213 if (inBuf > 0) { 214 --inBuf; 215 return buffer[(bufpos == bufsize - 1) ? (bufpos = 0) : ++bufpos]; 216 } 217 218 char c; 219 try { 220 c = ReadChar(); 221 switch (c) { 222 case '\r': 223 c = NEWLINE_MARKER; 224 try { 225 if (PeekChar() == '\n') 226 ReadChar(); 227 } 228 catch (EOFException e) { 229 } 230 break; 231 case '\n': 232 c = NEWLINE_MARKER; 233 break; 234 case '\t': 235 break; 236 default: 237 if (c >= 0x20) { 238 if (Utf16.isSurrogate(c)) { 239 if (Utf16.isSurrogate2(c)) 240 throw new EscapeSyntaxException("illegal_surrogate_pair", line, column + 1); 241 if (++bufpos == available) 242 AdjustBuffSize(); 243 buffer[bufpos] = c; 244 try { 246 c = ReadChar(); 247 } 248 catch (EOFException e) { 249 throw new EscapeSyntaxException("illegal_surrogate_pair", line, column + 1); 250 } 251 if (!Utf16.isSurrogate2(c)) 252 throw new EscapeSyntaxException("illegal_surrogate_pair", line, column + 2); 253 } 254 break; 255 } 256 case '\uFFFE': 258 case '\uFFFF': 259 throw new EscapeSyntaxException("illegal_char_code", line, column + 1); 260 } 261 } 262 catch (EOFException e) { 263 if (bufpos == -1) { 264 if (++bufpos == available) 265 AdjustBuffSize(); 266 bufline[bufpos] = line; 267 bufcolumn[bufpos] = column; 268 } 269 throw e; 270 } 271 if (++bufpos == available) 272 AdjustBuffSize(); 273 buffer[bufpos] = c; 274 UpdateLineColumn(c); 275 try { 276 if (c != '\\' || PeekChar() != 'x') 277 return c; 278 } 279 catch (EOFException e) { 280 return c; 281 } 282 283 int xCnt = 1; 284 for (;;) { 285 ReadChar(); 286 if (++bufpos == available) 287 AdjustBuffSize(); 288 buffer[bufpos] = 'x'; 289 UpdateLineColumn('x'); 290 try { 291 c = PeekChar(); 292 } 293 catch (EOFException e) { 294 backup(xCnt); 295 return '\\'; 296 } 297 if (c == '{') { 298 ReadChar(); 299 column++; 300 bufpos -= xCnt; 302 if (bufpos < 0) 303 bufpos += bufsize; 304 break; 305 } 306 if (c != 'x') { 307 backup(xCnt); 308 return '\\'; 309 } 310 xCnt++; 311 } 312 try { 313 int scalarValue = hexval(ReadChar()); 314 column++; 315 if (scalarValue < 0) 316 throw new EscapeSyntaxException("illegal_hex_digit", line, column); 317 while ((c = ReadChar()) != '}') { 318 column++; 319 int n = hexval(c); 320 if (n < 0) 321 throw new EscapeSyntaxException("illegal_hex_digit", line, column); 322 scalarValue <<= 4; 323 scalarValue |= n; 324 if (scalarValue >= 0x110000) 325 throw new EscapeSyntaxException("char_code_too_big", line, column); 326 } 327 column++; if (scalarValue <= 0xFFFF) { 329 c = (char)scalarValue; 330 switch (c) { 331 case '\n': 332 case '\r': 333 case '\t': 334 break; 335 default: 336 if (c >= 0x20 && !Utf16.isSurrogate(c)) 337 break; 338 case '\uFFFE': 340 case '\uFFFF': 341 throw new EscapeSyntaxException("illegal_char_code_ref", line, column); 342 } 343 buffer[bufpos] = c; 344 return c; 345 } 346 c = Utf16.surrogate1(scalarValue); 347 buffer[bufpos] = c; 348 int bufpos1 = bufpos; 349 if (++bufpos == bufsize) 350 bufpos = 0; 351 buffer[bufpos] = Utf16.surrogate2(scalarValue); 352 bufline[bufpos] = bufline[bufpos1]; 353 bufcolumn[bufpos] = bufcolumn[bufpos1]; 354 backup(1); 355 return c; 356 } 357 catch (EOFException e) { 358 throw new EscapeSyntaxException("incomplete_escape", line, column); 359 } 360 } 361 362 366 367 public final int getColumn() { 368 return bufcolumn[bufpos]; 369 } 370 371 375 376 public final int getLine() { 377 return bufline[bufpos]; 378 } 379 380 public final int getEndColumn() { 381 return bufcolumn[bufpos]; 382 } 383 384 public final int getEndLine() { 385 return bufline[bufpos]; 386 } 387 388 public final int getBeginColumn() { 389 return bufcolumn[tokenBegin]; 390 } 391 392 public final int getBeginLine() { 393 return bufline[tokenBegin]; 394 } 395 396 public final void backup(int amount) { 397 398 inBuf += amount; 399 if ((bufpos -= amount) < 0) 400 bufpos += bufsize; 401 } 402 403 public UCode_UCodeESC_CharStream(java.io.Reader dstream, 404 int startline, int startcolumn, int buffersize) { 405 inputStream = dstream; 406 line = startline; 407 column = startcolumn - 1; 408 409 available = bufsize = buffersize; 410 buffer = new char[buffersize]; 411 bufline = new int[buffersize]; 412 bufcolumn = new int[buffersize]; 413 nextCharBuf = new char[4096]; 414 skipBOM(); 415 } 416 417 public UCode_UCodeESC_CharStream(java.io.Reader dstream, 418 int startline, int startcolumn) { 419 this(dstream, startline, startcolumn, 4096); 420 } 421 422 public void ReInit(java.io.Reader dstream, 423 int startline, int startcolumn, int buffersize) { 424 inputStream = dstream; 425 closed = false; 426 line = startline; 427 column = startcolumn - 1; 428 429 if (buffer == null || buffersize != buffer.length) { 430 available = bufsize = buffersize; 431 buffer = new char[buffersize]; 432 bufline = new int[buffersize]; 433 bufcolumn = new int[buffersize]; 434 nextCharBuf = new char[4096]; 435 } 436 prevCharIsLF = false; 437 tokenBegin = inBuf = maxNextCharInd = 0; 438 nextCharInd = bufpos = -1; 439 skipBOM(); 440 } 441 442 public void ReInit(java.io.Reader dstream, 443 int startline, int startcolumn) { 444 ReInit(dstream, startline, startcolumn, 4096); 445 } 446 447 public UCode_UCodeESC_CharStream(java.io.InputStream dstream, int startline, 448 int startcolumn, int buffersize) { 449 this(new java.io.InputStreamReader (dstream), startline, startcolumn, 4096); 450 } 451 452 public UCode_UCodeESC_CharStream(java.io.InputStream dstream, int startline, 453 int startcolumn) { 454 this(dstream, startline, startcolumn, 4096); 455 } 456 457 public void ReInit(java.io.InputStream dstream, int startline, 458 int startcolumn, int buffersize) { 459 ReInit(new java.io.InputStreamReader (dstream), startline, startcolumn, 4096); 460 } 461 462 public void ReInit(java.io.InputStream dstream, int startline, 463 int startcolumn) { 464 ReInit(dstream, startline, startcolumn, 4096); 465 } 466 467 static private final char BOM = '\ufeff'; 468 469 private void skipBOM() { 470 try { 471 if (PeekChar() == BOM) 472 ReadChar(); 473 } 474 catch (EOFException e) { 475 } 476 } 477 478 public final String GetImage() { 479 if (bufpos >= tokenBegin) 480 return new String (buffer, tokenBegin, bufpos - tokenBegin + 1); 481 else 482 return new String (buffer, tokenBegin, bufsize - tokenBegin) + 483 new String (buffer, 0, bufpos + 1); 484 } 485 486 public final char[] GetSuffix(int len) { 487 char[] ret = new char[len]; 488 489 if ((bufpos + 1) >= len) 490 System.arraycopy(buffer, bufpos - len + 1, ret, 0, len); 491 else { 492 System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0, 493 len - bufpos - 1); 494 System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1); 495 } 496 497 return ret; 498 } 499 500 public void Done() { 501 nextCharBuf = null; 502 buffer = null; 503 bufline = null; 504 bufcolumn = null; 505 } 506 507 510 public void adjustBeginLineColumn(int newLine, int newCol) { 511 int start = tokenBegin; 512 int len; 513 514 if (bufpos >= tokenBegin) { 515 len = bufpos - tokenBegin + inBuf + 1; 516 } 517 else { 518 len = bufsize - tokenBegin + bufpos + 1 + inBuf; 519 } 520 521 int i = 0, j = 0, k = 0; 522 int nextColDiff = 0, columnDiff = 0; 523 524 while (i < len && 525 bufline[j = start % bufsize] == bufline[k = ++start % bufsize]) { 526 bufline[j] = newLine; 527 nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j]; 528 bufcolumn[j] = newCol + columnDiff; 529 columnDiff = nextColDiff; 530 i++; 531 } 532 533 if (i < len) { 534 bufline[j] = newLine++; 535 bufcolumn[j] = newCol + columnDiff; 536 537 while (i++ < len) { 538 if (bufline[j = start % bufsize] != bufline[++start % bufsize]) 539 bufline[j] = newLine++; 540 else 541 bufline[j] = newLine; 542 } 543 } 544 545 line = bufline[j]; 546 column = bufcolumn[j]; 547 } 548 549 } 550 | Popular Tags |