1 17 package org.eclipse.emf.ecore.xmi.impl; 18 19 20 import java.io.File ; 21 import java.io.FileInputStream ; 22 import java.io.FileOutputStream ; 23 import java.io.IOException ; 24 import java.io.InputStream ; 25 import java.io.InputStreamReader ; 26 import java.io.OutputStream ; 27 import java.io.OutputStreamWriter ; 28 import java.io.Writer ; 29 30 import java.util.Iterator ; 31 import java.util.ListIterator ; 32 33 import org.eclipse.emf.common.util.BasicEList; 34 35 36 39 public class StringSegment extends BasicEList 40 { 41 protected final static int LIST_SIZE = 100; 42 43 protected static final int ELEMENT_SIZE = 1000; 44 45 protected static final int BUFFER_SIZE = 8192; 46 47 protected int segmentCapacity; 48 49 protected byte[] outputbytes; 50 51 protected char[] outputchars; 52 53 protected char[] buffer; 54 55 protected Element cursor; 56 57 protected int cursorIndex = 0; 58 59 protected String lineSeparator = System.getProperty("line.separator"); 60 61 protected String temporaryFileName; 62 63 protected Writer temporaryFile; 64 65 protected int bufferPosition; 66 67 public StringSegment() 68 { 69 this(LIST_SIZE); 70 } 71 72 public StringSegment(int minimumCapacity) 73 { 74 this(minimumCapacity, ELEMENT_SIZE); 75 } 76 77 public StringSegment(int minimumCapacity, int segmentCapacity) 78 { 79 super(minimumCapacity); 80 add(cursor = new Element(this.segmentCapacity = segmentCapacity)); 81 outputchars = new char [BUFFER_SIZE]; 82 } 83 84 public StringSegment(String temporaryFileName) 85 { 86 this(LIST_SIZE, ELEMENT_SIZE); 87 setTemporaryFileName(temporaryFileName); 88 } 89 90 public void setTemporaryFileName(String tempFile) 91 { 92 temporaryFileName = tempFile; 93 if (temporaryFileName != null) 94 { 95 buffer = new char [BUFFER_SIZE]; 96 } 97 else 98 { 99 buffer = null; 100 } 101 } 102 103 public String getTemporaryFileName() 104 { 105 return temporaryFileName; 106 } 107 108 protected Object [] newData(int capacity) 109 { 110 return new Element [capacity]; 111 } 112 113 public void reset() 114 { 115 bufferPosition = 0; 116 cursor = (Element)data[0]; 117 cursorIndex = 0; 118 for (int i = 0; i < size; i++) 119 { 120 ((Element)data[i]).size = 0; 121 } 122 } 123 124 public void add(String newString) 125 { 126 128 if (temporaryFile != null) 131 { 132 int length = newString.length(); 133 if (length + bufferPosition >= buffer.length) 134 { 135 try 136 { 137 temporaryFile.write(buffer, 0, bufferPosition); 138 } 139 catch (IOException exception) 140 { 141 } 142 bufferPosition = 0; 143 if (length > buffer.length) 144 { 145 buffer = new char [length]; 146 } 147 } 148 newString.getChars(0, length, buffer, bufferPosition); 149 bufferPosition += length; 150 return; 151 } 152 153 if (cursor.size < segmentCapacity) 156 { 157 cursor.add(newString); 158 return; 159 } 160 161 Element oldCursor = cursor; 162 int index = size - 1; 163 if (cursorIndex < index) 164 { 165 cursor = (Element)data[++cursorIndex]; 166 if (cursor.size == 0) 167 { 168 cursor.add(newString); 169 return; 170 } 171 } 172 173 cursor = new Element(segmentCapacity); 174 cursor.add(newString); 175 176 if (data[index] == oldCursor) 180 { 181 super.add(cursor); 182 cursorIndex = ++index; 183 } 184 else 185 { 186 int counter = 0; 189 while (counter < index) 190 { 191 if (data[counter++] == oldCursor) 192 { 193 cursorIndex = counter; 194 super.add(cursorIndex, cursor); 195 break; 196 } 197 } 198 } 199 } 200 201 public void addLine() 202 { 203 add(lineSeparator); 204 } 205 206 public Object mark() 207 { 208 Element result = cursor; 209 if (cursor.size == 0) 210 { 211 result.add(""); 212 } 213 int i = size - 1; 214 if (cursorIndex < i) 215 { 216 cursor = (Element)data[++cursorIndex]; 217 } 218 else 219 { 220 cursorIndex++; 221 cursor = new Element(segmentCapacity); 222 super.add(cursor); 223 } 224 225 if (temporaryFileName != null && temporaryFile == null) 226 { 227 try 228 { 229 temporaryFile = new OutputStreamWriter (new FileOutputStream (temporaryFileName), "UTF8"); 230 } 231 catch (IOException exception) 232 { 233 } 234 } 235 236 return result; 237 } 238 239 public void resetToMark(Object mark) 240 { 241 if (temporaryFile != null) 242 { 243 cursor.add(""); 244 try 245 { 246 temporaryFile.write(buffer, 0, bufferPosition); 247 temporaryFile.close(); 248 } 249 catch (IOException exception) 250 { 251 } 252 temporaryFile = null; 253 } 254 cursor = (Element)mark; 255 for (int i = 0; i < data.length; i++) 256 { 257 if (data[i] == cursor) 258 { 259 cursorIndex = i; 260 return; 261 } 262 } 263 } 264 265 public int getLength() 266 { 267 Element[] elements = (Element[])data; 268 int length = 0; 269 for (int i = 0; i < size; ++i) 270 { 271 Element element = elements[i]; 272 int segmentSize = element.size; 273 for (int j = 0; j < segmentSize; ++j) 274 { 275 String s = element.data[j]; 276 length += s.length(); 277 } 278 } 279 return length; 280 } 281 282 public int getChars(char[] destination, int position) 283 { 284 Element[] elements = (Element[])data; 285 for (int i = 0; i < size; ++i) 286 { 287 Element element = elements[i]; 288 int segmentSize = element.size; 289 for (int j = 0; j < segmentSize; ++j) 290 { 291 String string = element.data[j]; 292 int length = string.length(); 293 string.getChars(0, length, destination, position); 294 position += length; 295 } 296 } 297 return position; 298 } 299 300 public void writeAscii(OutputStream os, int flushThreshold) throws IOException 301 { 302 if (outputbytes == null) 303 { 304 outputbytes = new byte [BUFFER_SIZE]; 305 } 306 Element[] elements = (Element[])data; 307 int position = 0; 308 int count = 0; 309 310 for (int i = 0; i < size; ++i) 311 { 312 Element element = elements[i]; 313 int segmentSize = element.size; 314 for (int j = 0; j < segmentSize; ++j) 315 { 316 String string = element.data[j]; 317 int length = string.length(); 318 if (length + position >= outputchars.length) 319 { 320 for (int x = 0; x < position; x++) 321 { 322 outputbytes[x] = (byte)(outputchars[x] & 0xFF); 323 } 324 os.write(outputbytes, 0, position); 325 position = 0; 326 if (length > outputchars.length) 327 { 328 outputchars = new char [length]; 329 outputbytes = new byte [length]; 330 } 331 } 332 string.getChars(0, length, outputchars, position); 333 position += length; 334 count += length; 335 if (count > flushThreshold) 336 { 337 os.flush(); 338 count = 0; 339 } 340 } 341 } 342 for (int x = 0; x < position; x++) 343 { 344 outputbytes[x] = (byte)(outputchars[x] & 0xFF); 345 } 346 347 os.write(outputbytes, 0, position); 348 349 String temporaryFileName = this.temporaryFileName; 350 if (temporaryFileName != null) 351 { 352 InputStream inputStream = new FileInputStream (temporaryFileName); 353 for (int length = inputStream.read(outputbytes, 0, outputbytes.length); length > 0; length = inputStream.read( 354 outputbytes, 355 0, 356 outputbytes.length)) 357 { 358 os.write(outputbytes, 0, length); 359 count += length; 360 if (count > flushThreshold) 361 { 362 os.flush(); 363 count = 0; 364 } 365 } 366 inputStream.close(); 367 new File (temporaryFileName).delete(); 368 } 369 } 370 371 public void write(OutputStreamWriter os, int flushThreshold) throws IOException 372 { 373 Element[] elements = (Element[])data; 374 int position = 0; 375 int count = 0; 376 for (int i = 0; i < size; ++i) 377 { 378 Element element = elements[i]; 379 int segmentSize = element.size; 380 for (int j = 0; j < segmentSize; ++j) 381 { 382 String string = element.data[j]; 383 int length = string.length(); 384 if (length + position >= outputchars.length) 385 { 386 os.write(outputchars, 0, position); 387 position = 0; 388 if (length > outputchars.length) 389 { 390 outputchars = new char [length]; 391 } 392 } 393 string.getChars(0, length, outputchars, position); 394 position += length; 395 count += length; 396 if (count > flushThreshold) 397 { 398 os.flush(); 399 count = 0; 400 } 401 } 402 } 403 os.write(outputchars, 0, position); 404 405 String temporaryFileName = this.temporaryFileName; 406 if (temporaryFileName != null) 407 { 408 InputStreamReader reader = new InputStreamReader (new FileInputStream (temporaryFileName), "UTF8"); 409 for (int length = reader.read(outputchars, 0, outputchars.length); length > 0; length = reader.read( 410 outputchars, 411 0, 412 outputchars.length)) 413 { 414 os.write(outputchars, 0, length); 415 count += length; 416 if (count > flushThreshold) 417 { 418 os.flush(); 419 count = 0; 420 } 421 } 422 reader.close(); 423 new File (temporaryFileName).delete(); 424 } 425 426 } 427 428 protected static class Element 429 { 430 int size; 431 432 String [] data; 433 434 Element(int capacity) 435 { 436 data = new String [capacity]; 437 } 438 439 void add(String newString) 440 { 441 data[size++] = newString; 442 } 443 } 444 445 public Iterator iterator() 446 { 447 return new SegmentIterator(); 448 } 449 450 public ListIterator listIterator() 451 { 452 return new SegmentIterator(); 453 } 454 455 protected class SegmentIterator implements ListIterator 456 { 457 protected int outerIndex = 0; 458 459 protected int innerIndex = 0; 460 461 SegmentIterator() 462 { 463 } 464 465 public boolean hasNext() 466 { 467 return outerIndex < size - 1 || (outerIndex == size - 1 && innerIndex < ((Element)data[outerIndex]).size); 468 } 469 470 public boolean hasPrevious() 471 { 472 return outerIndex > 0 || innerIndex > 0; 473 } 474 475 public Object next() 476 { 477 Element element = (Element)data[outerIndex]; 478 if (innerIndex < element.size) 479 { 480 return element.data[innerIndex++]; 481 } 482 else 483 { 484 innerIndex = 1; 485 return ((Element)data[++outerIndex]).data[0]; 486 } 487 } 488 489 public Object previous() 490 { 491 if (innerIndex > 0) 492 { 493 return ((Element)data[outerIndex]).data[--innerIndex]; 494 } 495 else 496 { 497 Element element = (Element)data[--outerIndex]; 498 innerIndex = element.size - 1; 499 return element.data[innerIndex]; 500 } 501 } 502 503 public void add(Object newElement) 504 { 505 throw new UnsupportedOperationException (SegmentIterator.class.toString()); 506 } 507 508 public void remove() 509 { 510 throw new UnsupportedOperationException (SegmentIterator.class.toString()); 511 } 512 513 public void set(Object newElement) 514 { 515 throw new UnsupportedOperationException (SegmentIterator.class.toString()); 516 } 517 518 public int nextIndex() 519 { 520 throw new UnsupportedOperationException (SegmentIterator.class.toString()); 521 } 522 523 public int previousIndex() 524 { 525 throw new UnsupportedOperationException (SegmentIterator.class.toString()); 526 } 527 } 528 } 529 | Popular Tags |