AbstractCharVector.java 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. package gnu.lists;
  2. import gnu.text.Char;
  3. import gnu.kawa.io.CharArrayInPort;
  4. import gnu.kawa.io.InPort;
  5. import java.io.*;
  6. public abstract class AbstractCharVector<E>
  7. extends SimpleVector<E> implements Comparable
  8. {
  9. protected char[] data;
  10. protected static char[] empty = new char[0];
  11. public int length() { return super.length(); }
  12. /** Get the allocated length of the data buffer. */
  13. public int getBufferLength() {
  14. return data.length;
  15. }
  16. public void copyBuffer(int length) {
  17. int oldLength = data.length;
  18. if (length == -1)
  19. length = oldLength;
  20. if (oldLength != length) {
  21. char[] tmp = new char[length];
  22. System.arraycopy(data, 0, tmp, 0,
  23. oldLength < length ? oldLength : length);
  24. data = tmp;
  25. }
  26. }
  27. public void ensureBufferLength (int sz) {
  28. if (sz > data.length) {
  29. char[] d = new char[sz < 60 ? 120 : 2 * sz];
  30. System.arraycopy(data, 0, d, 0, data.length);
  31. data = d;
  32. }
  33. }
  34. @Override
  35. public char[] getBuffer() { return data; }
  36. protected void setBuffer(Object buffer) { data = (char[]) buffer; }
  37. public final char charAt(int index) {
  38. // Use super.effectiveIndex because FString overrides it
  39. return data[super.effectiveIndex(index)];
  40. }
  41. public final char getCharRaw(int index) {
  42. return data[index];
  43. }
  44. /** Copy characters into a destination buffer.
  45. * Same interface as java.lang.String's getChars. */
  46. public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
  47. if (srcBegin < 0 || srcBegin > srcEnd)
  48. throw new StringIndexOutOfBoundsException(srcBegin);
  49. int size = length();
  50. if (srcEnd > size)
  51. throw new StringIndexOutOfBoundsException(srcEnd);
  52. if (dstBegin+srcEnd-srcBegin > dst.length)
  53. throw new StringIndexOutOfBoundsException(dstBegin);
  54. int len = srcEnd - srcBegin;
  55. if (len <= 0)
  56. return;
  57. if (isVerySimple())
  58. System.arraycopy(data, srcBegin, dst, dstBegin, len);
  59. else {
  60. for (int i = 0; i < len; i++)
  61. dst[dstBegin+i] = charAt(srcBegin+i);
  62. }
  63. }
  64. protected void clearBuffer(int start, int count) {
  65. char[] d = data; // Move to local to help optimizer.
  66. while (--count >= 0)
  67. d[start++] = 0;
  68. }
  69. public int hashCode() {
  70. /* Matches String.hashCode specification, as updated specification in
  71. http://www.javasoft.com/docs/books/jls/clarify.html. */
  72. char[] val = data;
  73. int len = length();
  74. int hash = 0;
  75. if (! isVerySimple()) {
  76. for (int i = 0; i < len; i++)
  77. hash = 31 * hash + val[effectiveIndex(i)];
  78. } else {
  79. for (int i = 0; i < len; i++)
  80. hash = 31 * hash + val[i];
  81. }
  82. return hash;
  83. }
  84. /** Must override, since we override hashCode. */
  85. public abstract boolean equals(Object obj);
  86. public static boolean equals(AbstractCharVector<?> c1,
  87. AbstractCharVector<?> c2) {
  88. int len1 = c1.length();
  89. int len2 = c2.length();
  90. return len1 == len2 && compareTo(c1.data, c2.data, len1) == 0;
  91. }
  92. public int compareTo(Object obj) {
  93. AbstractCharVector<?> cv1 = this;
  94. AbstractCharVector<?> cv2 = (AbstractCharVector) obj;
  95. int n1 = cv1.length();
  96. int n2 = cv2.length();
  97. int n = n1 > n2 ? n2 : n1;
  98. int d = compareTo(cv1, cv2, n);
  99. return d != 0 ? d : n1 - n2;
  100. }
  101. public static int compareTo(AbstractCharVector<?> cv1,
  102. AbstractCharVector<?> cv2,
  103. int length) {
  104. // Needlessly conservative - could use the 'else' case also
  105. // if both indexes are simple ranges starting at 0 stepping by 1.
  106. if (! cv1.isVerySimple() || ! cv2.isVerySimple()) {
  107. for (int i = 0; i < length; i++) {
  108. char c1 = cv1.charAt(i);
  109. char c2 = cv2.charAt(i);
  110. int d = c1 - c2;
  111. if (d != 0)
  112. return d;
  113. }
  114. return 0;
  115. } else {
  116. return compareTo(cv1.data, cv2.data, length);
  117. }
  118. }
  119. public static int compareTo(char[] arr1, char[] arr2, int length) {
  120. for (int i = 0; i < length; i++) {
  121. char c1 = arr1[i];
  122. char c2 = arr2[i];
  123. int d = c1 - c2;
  124. if (d != 0)
  125. return d;
  126. }
  127. return 0;
  128. }
  129. public CharArrayInPort openReader() {
  130. return new CharArrayInPort(this, data, 0, length());
  131. }
  132. public CharArrayInPort openReader(int start, int end) {
  133. return new CharArrayInPort(this, data, start, end);
  134. }
  135. }