read_line.java 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. package kawa.standard;
  2. import gnu.kawa.io.InPort;
  3. import gnu.lists.FString;
  4. import gnu.mapping.*;
  5. public class read_line
  6. {
  7. public static Object apply(InPort in, String handling)
  8. throws java.io.IOException
  9. {
  10. int ch = in.read();
  11. if (ch < 0)
  12. return gnu.expr.Special.eof;
  13. int start = in.pos - 1;
  14. int pos = start;
  15. int limit = in.limit;
  16. char[] buffer = in.buffer;
  17. int delim = -1; // Length of delimiter.
  18. // First do a quick scan of what is in in's input buffer.
  19. while (pos < limit)
  20. {
  21. ch = buffer[pos++];
  22. if (ch == '\r' || ch == '\n')
  23. {
  24. pos--;
  25. if (handling == "trim" || handling == "peek")
  26. {
  27. if (handling == "peek")
  28. delim = 0;
  29. if (ch == '\n')
  30. delim = 1;
  31. else if (pos+1 < limit)
  32. delim = buffer[pos+1] == '\n' ? 2 : 1;
  33. else
  34. break;
  35. in.pos = pos + delim;
  36. }
  37. else if (handling == "concat" && ch == '\n')
  38. {
  39. in.pos = ++pos;
  40. }
  41. else
  42. break;
  43. return new FString(buffer, start, pos - start);
  44. }
  45. }
  46. // Ok, we haven't found the end-of-line yet, so use the general
  47. // readLine method in InPort.
  48. StringBuffer sbuf = new StringBuffer(100);
  49. if (pos > start)
  50. sbuf.append(buffer, start, pos - start);
  51. in.pos = pos;
  52. char mode = handling == "peek" ? 'P'
  53. : handling == "concat" || handling == "split" ? 'A'
  54. : 'I';
  55. in.readLine(sbuf, mode);
  56. int length = sbuf.length();
  57. if (handling == "split")
  58. {
  59. if (length == 0)
  60. delim = 0;
  61. else
  62. {
  63. char last = sbuf.charAt(length - 1);
  64. if (last == '\r')
  65. delim = 1;
  66. else if (last != '\n')
  67. delim = 0;
  68. else if (last > 2 && sbuf.charAt(length-2) == '\r')
  69. delim = 2;
  70. else
  71. delim = 1;
  72. length -= delim;
  73. }
  74. }
  75. FString dataStr = new FString(sbuf, 0, length);
  76. if (handling == "split")
  77. {
  78. FString delimStr = new FString(sbuf, length-delim, delim);
  79. return Values.values2(dataStr, delimStr);
  80. }
  81. else
  82. return dataStr;
  83. }
  84. }