ByteVector.java 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. // This file is generated from PrimVector.template. DO NOT EDIT!
  2. // Copyright (c) 2001, 2002, 2015 Per M.A. Bothner and Brainfood Inc.
  3. // This is free software; for terms and warranty disclaimer see ./COPYING.
  4. package gnu.lists;
  5. import java.io.*;
  6. import java.nio.ByteOrder;
  7. /** Simple adjustable-length vector of signed or unsigned 8-bit integers (bytes). */
  8. public abstract class ByteVector<E> extends PrimIntegerVector<E>
  9. {
  10. byte[] data;
  11. protected static byte[] empty = new byte[0];
  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. byte[] tmp = new byte[length];
  22. System.arraycopy(data, 0, tmp, 0,
  23. oldLength < length ? oldLength : length);
  24. data = tmp;
  25. }
  26. }
  27. public byte[] getBuffer() { return data; }
  28. protected void setBuffer(Object buffer) { data = (byte[]) buffer; }
  29. public final byte getByte(int index) {
  30. return data[effectiveIndex(index)];
  31. }
  32. public final byte getByteRaw(int index) {
  33. return data[index];
  34. }
  35. public final void setByte(int index, byte value) {
  36. checkCanWrite(); // FIXME maybe inline and fold into following
  37. data[effectiveIndex(index)] = value;
  38. }
  39. public final void setByteRaw(int index, byte value) {
  40. data[index] = value;
  41. }
  42. public void add(byte v) {
  43. int sz = size();
  44. addSpace(sz, 1);
  45. setByte(sz, v);
  46. }
  47. protected void clearBuffer(int start, int count) {
  48. byte[] d = data;
  49. while (--count >= 0)
  50. d[start++] = 0;
  51. }
  52. public int readFrom(int start, int count, InputStream in)
  53. throws IOException {
  54. int pos = start;
  55. while (count > 0) {
  56. long result = getSegment(pos);
  57. int where = (int) result;
  58. int size = (int) (result >> 32);
  59. if (size > count)
  60. size = count;
  61. int n = in.read(data, where, size);
  62. if (n < 0) {
  63. if (pos == start)
  64. return -1;
  65. break;
  66. }
  67. pos += n;
  68. count -= n;
  69. }
  70. return pos - start;
  71. }
  72. public void writeTo(OutputStream out)
  73. throws IOException {
  74. writeTo(0, size(), out);
  75. }
  76. public void writeTo(int start, int count, OutputStream out)
  77. throws IOException {
  78. while (count > 0) {
  79. long result = getSegment(start);
  80. int where = (int) result;
  81. int size = (int) (result >> 32);
  82. if (size > count)
  83. size = count;
  84. out.write(data, where, size);
  85. start += size;
  86. count -= size;
  87. }
  88. }
  89. public void copyFrom (int index, ByteVector src, int start, int end) {
  90. int count = end-start;
  91. int sz = size();
  92. int src_sz = src.size();
  93. if (count < 0 || index+count > sz || end > src_sz)
  94. throw new ArrayIndexOutOfBoundsException();
  95. int sseg, dseg;
  96. if ((sseg = src.getSegmentReadOnly(start, count)) >= 0 &&
  97. (dseg = getSegment(index, count)) >= 0) {
  98. System.arraycopy(src.data, sseg, data, dseg, count);
  99. } else {
  100. for (int i = 0; i < count; i++)
  101. setByte(index+i, src.getByte(start+i));
  102. }
  103. }
  104. public InputStream getInputStream() {
  105. int sz = size();
  106. int seg = getSegmentReadOnly(0, sz);
  107. if (seg >= 0)
  108. return new ByteArrayInputStream(data, seg, sz);
  109. else
  110. return new ByteVectorInputStream(this);
  111. }
  112. static class ByteVectorInputStream extends InputStream {
  113. ByteVector bvec;
  114. int pos;
  115. int mark;
  116. int size;
  117. public ByteVectorInputStream(ByteVector bvec) {
  118. this.bvec = bvec;
  119. this.size = bvec.size();
  120. }
  121. public int read() {
  122. return pos >= size ? -1 :
  123. (0xff & bvec.getByte(pos++));
  124. }
  125. public boolean markSupported() { return true; }
  126. public void mark(int readLimit) { mark = pos; }
  127. public void reset() { pos = mark; }
  128. public void close() { }
  129. public int available() { return size-pos; }
  130. public long skip(long n) {
  131. if (n < 0) n = 0;
  132. if (n < size-pos) { pos = size; return size-pos; }
  133. else { pos += n; return n; }
  134. }
  135. }
  136. /** Covert bytes, interpreted as UTF-8 characters, to a String. */
  137. public String utf8ToString(int start, int length) {
  138. if (start+length>size()) throw new IndexOutOfBoundsException();
  139. int seg = getSegmentReadOnly(start, length);
  140. byte[] buf;
  141. if (seg >= 0) {
  142. buf = data;
  143. start = seg;
  144. } else {
  145. buf = new byte[length];
  146. for (int i = 0; i < length; i++)
  147. buf[i] = getByte(start+i);
  148. }
  149. return Strings.fromUtf8(buf, start, length);
  150. }
  151. static final byte BOM_HI = (byte) 0xFE;
  152. static final byte BOM_LO = (byte) 0xFF;
  153. public String utf16ToString(int start, int length) {
  154. boolean bigEndian = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
  155. if (length >+ 2) {
  156. byte b0 = getByte(start);
  157. byte b1 = getByte(start+1);
  158. if (b0 == BOM_LO && b1 == BOM_HI) {
  159. start += 2; length -= 2; bigEndian = false;
  160. } else if (b0 == BOM_HI && b1 == BOM_LO) {
  161. start += 2; length -= 2; bigEndian = true;
  162. }
  163. }
  164. return utf16ToString(start, length, bigEndian);
  165. }
  166. public String utf16ToString(int start, int length, boolean bigEndian) {
  167. if (start+length>size()) throw new IndexOutOfBoundsException();
  168. if ((length & 1) != 0)
  169. throw new IllegalArgumentException("number of bytes must be even");
  170. char[] buf = new char[length>>1];
  171. int hi = bigEndian ? 0 : 1;
  172. int lo = bigEndian ? 1 : 0;
  173. for (int i = 0; i < length; i += 2) {
  174. byte bhi = getByte(start+i+hi);
  175. byte blo = getByte(start+i+lo);
  176. buf[i>>1] = (char) (((bhi & 0xFF) << 8) | (blo & 0xFF));
  177. }
  178. return new String(buf);
  179. }
  180. }