1 19 20 package org.netbeans.editor; 21 22 import java.io.IOException ; 23 import java.io.Reader ; 24 import javax.swing.text.Segment ; 25 26 32 33 public class LineSeparatorConversion { 34 35 38 private static final int DEFAULT_CONVERSION_BUFFER_SIZE = 16384; 39 40 private LineSeparatorConversion() { 41 } 43 44 49 public static String convertToLineFeed(String text) { 50 StringBuffer output = new StringBuffer (); 51 convertToLineFeed(text, 0, text.length(), output); 52 return output.toString(); 53 } 54 55 62 public static void convertToLineFeed(String text, int offset, int length, 63 StringBuffer output) { 64 65 int endOffset = offset + length; 66 boolean lastCharCR = false; 68 while (offset < endOffset) { 69 char ch = text.charAt(offset++); 70 if (lastCharCR && ch == '\n') { lastCharCR = false; 72 73 } else { if (ch == '\r') { 75 output.append('\n'); 76 lastCharCR = true; 77 78 } else { lastCharCR = false; 80 output.append(ch); 81 } 82 } 83 } 84 } 85 86 94 public static String convertFromLineFeed(String text, String lineFeedReplace) { 95 StringBuffer output = new StringBuffer (); 96 convertFromLineFeed(text, 0, text.length(), lineFeedReplace, output); 97 return output.toString(); 98 } 99 100 109 public static void convertFromLineFeed(String text, int offset, int length, 110 String lineFeedReplace, StringBuffer output) { 111 int lineFeedReplaceLength = lineFeedReplace.length(); 112 int endOffset = offset + length; 113 while (offset < endOffset) { 114 char ch = text.charAt(offset++); 115 if (ch == '\n') { 116 for (int i = 0; i < lineFeedReplaceLength; i++) { 117 output.append(lineFeedReplace.charAt(i)); 118 } 119 } else { 120 output.append(ch); 121 } 122 } 123 } 124 125 131 public static class ToLineFeed { 132 133 private Reader reader; 134 135 private Segment convertedText; 136 137 private boolean lastCharCR; 138 139 public ToLineFeed(Reader reader) { 140 this(reader, DEFAULT_CONVERSION_BUFFER_SIZE); 141 } 142 143 public ToLineFeed(Reader reader, int convertBufferSize) { 144 this.reader = reader; 145 convertedText = new Segment (); 146 convertedText.array = new char[convertBufferSize]; 147 } 148 149 public Segment nextConverted() throws IOException { 150 if (reader == null) { return null; 152 } 153 154 int readOffset = 0; 155 int readSize = readBuffer(reader, convertedText.array, readOffset, true); 156 157 if (readSize == 0) { reader.close(); 159 reader = null; 160 return null; 161 } 162 163 if (lastCharCR && readSize > 0 && convertedText.array[readOffset] == '\n') { 164 167 readOffset++; 168 readSize--; 169 } 170 171 convertedText.offset = readOffset; 172 convertedText.count = readSize; 173 lastCharCR = convertSegmentToLineFeed(convertedText); 174 return convertedText; 175 } 176 177 191 private static boolean convertSegmentToLineFeed(Segment text) { 192 char[] chars = text.array; 193 int storeOffset = text.offset; int endOffset = storeOffset + text.count; 195 boolean storeChar = false; boolean lastCharCR = false; 198 for (int offset = storeOffset; offset < endOffset; offset++) { 199 char ch = chars[offset]; 200 201 if (lastCharCR && ch == '\n') { lastCharCR = false; 203 storeChar = true; 205 } else { if (ch == '\r') { 207 lastCharCR = true; 208 chars[storeOffset++] = '\n'; 210 } else { lastCharCR = false; 212 if (storeChar) { 213 chars[storeOffset] = ch; 214 } 215 storeOffset++; 216 } 217 } 218 } 219 220 text.count = storeOffset - text.offset; 221 222 return lastCharCR; 223 } 224 225 private static int readBuffer(Reader reader, char[] buffer, int offset, 226 boolean joinReads) throws IOException { 227 int maxReadSize = buffer.length - offset; 228 int totalReadSize = 0; 229 230 do { 231 int readSize = 0; 232 while (readSize == 0) { readSize = reader.read(buffer, offset, maxReadSize); 234 } 235 236 if (readSize == -1) { 237 break; } 239 240 totalReadSize += readSize; 241 offset += readSize; 242 maxReadSize -= readSize; 243 244 } while (joinReads && maxReadSize > 0); 245 246 return totalReadSize; 247 } 248 249 } 250 251 258 public static class FromLineFeed { 259 260 private Object charArrayOrSequence; 261 262 private int offset; 263 264 private int endOffset; 265 266 private String lineFeedReplace; 267 268 private Segment convertedText; 269 270 public FromLineFeed(char[] source, int offset, int length, 271 String lineFeedReplace) { 272 this(source, offset, length, lineFeedReplace, DEFAULT_CONVERSION_BUFFER_SIZE); 273 } 274 275 public FromLineFeed(char[] source, int offset, int length, 276 String lineFeedReplace, int conversionSegmentSize) { 277 this((Object )source, offset, length, lineFeedReplace, conversionSegmentSize); 278 } 279 280 public FromLineFeed(String text, int offset, int length, 281 String lineFeedReplace) { 282 this(text, offset, length, lineFeedReplace, DEFAULT_CONVERSION_BUFFER_SIZE); 283 } 284 285 public FromLineFeed(String text, int offset, int length, 286 String lineFeedReplace, int conversionSegmentSize) { 287 this((Object )text, offset, length, lineFeedReplace, conversionSegmentSize); 288 } 289 290 private FromLineFeed(Object charArrayOrSequence, int offset, int length, 291 String lineFeedReplace, int conversionSegmentSize) { 292 293 if (conversionSegmentSize < lineFeedReplace.length()) { 294 throw new IllegalArgumentException ("conversionSegmentSize=" + conversionSegmentSize + " < lineFeedReplace.length()=" + lineFeedReplace.length() 297 ); 298 } 299 300 this.charArrayOrSequence = charArrayOrSequence; 301 this.offset = offset; 302 this.endOffset = offset + length; 303 this.lineFeedReplace = lineFeedReplace; 304 305 convertedText = new Segment (); 306 convertedText.array = new char[conversionSegmentSize]; 307 } 308 309 public Segment nextConverted() { 310 if (offset == endOffset) { return null; 312 } 313 314 316 char[] convertedArray = convertedText.array; 317 int convertedArrayLength = convertedArray.length; 318 int convertedOffset = 0; 319 320 324 String sourceText; 325 char[] sourceArray; 326 if (charArrayOrSequence instanceof String ) { 327 sourceText = (String )charArrayOrSequence; 328 sourceArray = null; 329 330 } else { 331 sourceArray = (char[])charArrayOrSequence; 332 sourceText = null; 333 } 334 335 int lineFeedReplaceLength = lineFeedReplace.length(); 336 while (offset < endOffset 337 && convertedArrayLength - convertedOffset >= lineFeedReplaceLength 338 ) { 339 char ch = (sourceText != null) 340 ? sourceText.charAt(offset++) 341 : sourceArray[offset++]; 342 343 if (ch == '\n') { 344 for (int i = 0; i < lineFeedReplaceLength; i++) { 345 convertedArray[convertedOffset++] = lineFeedReplace.charAt(i); 346 } 347 348 349 } else { 350 convertedArray[convertedOffset++] = ch; 351 } 352 } 353 354 convertedText.offset = 0; 355 convertedText.count = convertedOffset; 356 357 return convertedText; 358 } 359 360 } 361 362 public static class InitialSeparatorReader extends Reader { 363 364 private static final int AFTER_CR_STATUS = -1; 365 366 private static final int INITIAL_STATUS = 0; 367 368 private static final int CR_SEPARATOR = 1; 369 370 private static final int LF_SEPARATOR = 2; 371 372 private static final int CRLF_SEPARATOR = 3; 373 374 private Reader delegate; 375 376 private int status = INITIAL_STATUS; 377 378 public InitialSeparatorReader(Reader delegate) { 379 this.delegate = delegate; 380 } 381 382 public String getInitialSeparator() { 383 String separator; 384 switch (status) { 385 case CR_SEPARATOR: 386 separator = "\r"; break; 388 389 case LF_SEPARATOR: 390 separator = "\n"; break; 392 393 case CRLF_SEPARATOR: 394 separator = "\r\n"; break; 396 397 case AFTER_CR_STATUS: separator = "\r"; break; 400 401 default: 402 separator = "\n"; break; 404 } 405 406 return separator; 407 } 408 409 private void resolveSeparator(char ch) { 410 switch (status) { 411 case INITIAL_STATUS: 412 switch (ch) { 413 case '\r': 414 status = AFTER_CR_STATUS; 415 break; 416 case '\n': 417 status = LF_SEPARATOR; 418 break; 419 } 420 break; 421 422 case AFTER_CR_STATUS: 423 switch (ch) { 424 case '\n': 425 status = CRLF_SEPARATOR; 426 break; 427 default: 428 status = CR_SEPARATOR; 429 break; 430 } 431 break; 432 433 default: 434 switch (ch) { 435 case '\r': 436 status = AFTER_CR_STATUS; 437 break; 438 case '\n': 439 status = LF_SEPARATOR; 440 break; 441 } 442 break; 443 } 444 } 445 446 private boolean isSeparatorResolved() { 447 return (status > 0); 448 } 449 450 public void close() throws IOException { 451 if (delegate == null) { 452 return; 453 } 454 455 delegate.close(); 456 delegate = null; 457 } 458 459 public int read(char[] cbuf, int off, int len) throws IOException { 460 if (delegate == null) { 461 throw new IOException ("Reader already closed."); } 463 464 int readLen = delegate.read(cbuf, off, len); 465 466 for (int endOff = off + readLen; 467 off < endOff && !isSeparatorResolved(); 468 off++ 469 ) { 470 resolveSeparator(cbuf[off]); 471 } 472 473 return readLen; 474 } 475 476 public int read() throws IOException { 477 if (delegate == null) { 478 throw new IOException ("Reader already closed."); } 480 481 int r = delegate.read(); 482 if (r != -1 && !isSeparatorResolved()) { 483 resolveSeparator((char)r); 484 } 485 486 return r; 487 } 488 489 } 490 491 } 492 | Popular Tags |