PrimVector.template 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. // $PREAMBLE$ -*- java -*-
  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. /* #ifdef U8|U16|U32|U64 */
  7. import gnu.math.$BTYPE$;
  8. /* #endif */
  9. /* #ifdef BYTE */
  10. import java.nio.ByteOrder;
  11. /* #endif */
  12. /** Simple adjustable-length vector of $DESC$. */
  13. public @Abstract class $CNAME$ extends $SUPER$
  14. /* #ifdef OBJECT */
  15. implements Consumable, Comparable
  16. /* #endif */
  17. /* #ifdef S32 */
  18. implements IntSequence
  19. /* #endif */
  20. /* #ifdef BIT|F32|F64 */
  21. implements Comparable
  22. /* #endif */
  23. {
  24. /* #ifdef OBJECT|BIT|BYTE|SHORT|INT|LONG|F32|F64 */
  25. $ptype$[] data;
  26. protected static $ptype$[] empty = new $ptype$[0];
  27. /* #endif */
  28. /* #ifdef OBJECT|BIT|S8|S16|S32|S64|U8|U16|U32|U64|F32|F64 */
  29. public $TAG$Vector() {
  30. data = empty;
  31. }
  32. public $TAG$Vector(int size, $ptype$ value) {
  33. $ptype$[] array = new $ptype$[size];
  34. data = array;
  35. if (value != $ZERO$) {
  36. while (--size >= 0)
  37. array[size] = value;
  38. }
  39. }
  40. public $TAG$Vector(int size) {
  41. this(new $ptype$[size]);
  42. }
  43. /** Reuses the argument without making a copy. */
  44. public $TAG$Vector($ptype$[] data) {
  45. this.data = data;
  46. }
  47. /** Makes a copy of (part of) the argument array. */
  48. public $TAG$Vector($ptype$[] values, int offset, int length) {
  49. this(length);
  50. System.arraycopy(values, offset, data, 0, length);
  51. }
  52. /* #endif */
  53. /* #ifdef OBJECT */
  54. public FVector(java.util.List seq) {
  55. this.data = new Object[seq.size()];
  56. int i = 0;
  57. for (java.util.Iterator<? extends E> it = seq.iterator(); it.hasNext(); )
  58. data[i++] = it.next();
  59. }
  60. public static FVector make(Object... data) {
  61. return new FVector(data);
  62. }
  63. public static <E> FVector<E> makeConstant(E... data) {
  64. FVector<E> vec = new FVector(data);
  65. vec.setReadOnly();
  66. return vec;
  67. }
  68. public void replaceAll(E[] data) {
  69. this.data = data;
  70. this.info = VERY_SIMPLE_FLAG;
  71. }
  72. public void copyFrom (int index, FVector<E> src, int start, int end) {
  73. int count = end-start;
  74. int sz = size();
  75. int src_sz = src.size();
  76. if (count < 0 || index+count > sz || end > src_sz)
  77. throw new ArrayIndexOutOfBoundsException();
  78. int sseg, dseg;
  79. if ((sseg = src.getSegmentReadOnly(start, count)) >= 0 &&
  80. (dseg = getSegment(index, count)) >= 0) {
  81. System.arraycopy(src.data, sseg, data, dseg, count);
  82. } else {
  83. for (int i = 0; i < count; i++)
  84. set(index+i, src.get(start+i));
  85. }
  86. }
  87. /* #endif */
  88. /* #ifdef OBJECT|BIT|BYTE|SHORT|INT|LONG|F32|F64 */
  89. /** Get the allocated length of the data buffer. */
  90. public int getBufferLength() {
  91. return data.length;
  92. }
  93. public void copyBuffer(int length) {
  94. int oldLength = data.length;
  95. if (length == -1)
  96. length = oldLength;
  97. if (oldLength != length) {
  98. $ptype$[] tmp = new $ptype$[length];
  99. System.arraycopy(data, 0, tmp, 0,
  100. oldLength < length ? oldLength : length);
  101. data = tmp;
  102. }
  103. }
  104. public $ptype$[] getBuffer() { return data; }
  105. protected void setBuffer(Object buffer) { data = ($ptype$[]) buffer; }
  106. /* #endif */
  107. /* #ifdef BIT|BYTE|SHORT|INT|LONG|F32|F64 */
  108. public final $ptype$ get$Ptype$(int index) {
  109. return data[effectiveIndex(index)];
  110. }
  111. public final $ptype$ get$Ptype$Raw(int index) {
  112. return data[index];
  113. }
  114. /* #endif */
  115. /* #ifdef S8|S16|U8|U16|LONG */
  116. public final int getIntRaw(int index) {
  117. return (int) data[index]$MASK$;
  118. }
  119. /* #endif */
  120. /* #ifdef S32|U32 */
  121. public final long getLongRaw(int index) {
  122. return (long) data[index]$MASK$;
  123. }
  124. /* #endif */
  125. /* #ifdef OBJECT */
  126. public final E get(int index) {
  127. return (E) data[effectiveIndex(index)];
  128. }
  129. public final E getRaw(int index) {
  130. return (E) data[index];
  131. }
  132. /* #endif */
  133. /* #ifdef BIT|S8|S16|S32|S64|U8|U16|U32|U64|F32|F64 */
  134. public final $BTYPE$ get(int index) {
  135. return $BTYPE$.valueOf(data[effectiveIndex(index)]);
  136. }
  137. public final $BTYPE$ getRaw(int index) {
  138. return $BTYPE$.valueOf(data[index]);
  139. }
  140. /* #endif */
  141. /* #ifdef BIT|BYTE|SHORT|INT|LONG|F32|F64 */
  142. public final void set$Ptype$(int index, $ptype$ value) {
  143. checkCanWrite(); // FIXME maybe inline and fold into following
  144. data[effectiveIndex(index)] = value;
  145. }
  146. public final void set$Ptype$Raw(int index, $ptype$ value) {
  147. data[index] = value;
  148. }
  149. /* #endif */
  150. /* #ifdef OBJECT */
  151. @Override
  152. public final void setRaw(int index, $BTYPE$ value) {
  153. data[index] = value;
  154. }
  155. /* #endif */
  156. /* #ifdef BIT|S8|S16|S32|S64|U8|U16|U32|U64|F32|F64 */
  157. @Override
  158. public final void setRaw(int index, $BTYPE$ value) {
  159. data[index] = value.$ptype$Value();
  160. }
  161. /* #endif */
  162. /* #ifdef BIT|BYTE|SHORT|INT|LONG|F32|F64 */
  163. public void add($ptype$ v) {
  164. int sz = size();
  165. addSpace(sz, 1);
  166. set$Ptype$(sz, v);
  167. }
  168. /* #endif */
  169. /* #ifdef OBJECT|BIT|BYTE|SHORT|INT|LONG|F32|F64 */
  170. protected void clearBuffer(int start, int count) {
  171. $ptype$[] d = data;
  172. while (--count >= 0)
  173. d[start++] = $ZERO$;
  174. }
  175. /* #endif */
  176. /* #ifdef OBJECT|BIT|S8|S16|S32|S64|U8|U16|U32|U64|F32|F64 */
  177. @Override
  178. protected $CNAME$ newInstance(int newLength) {
  179. return new $CNAME$(newLength < 0 ? data : new $ptype$[newLength]);
  180. }
  181. public static $TAG$Vector castOrNull(Object obj) {
  182. if (obj instanceof $ptype$[])
  183. return new $TAG$Vector(($ptype$[]) obj);
  184. if (obj instanceof $TAG$Vector)
  185. return ($TAG$Vector) obj;
  186. return null;
  187. }
  188. public static $TAG$Vector cast(Object value) {
  189. $TAG$Vector vec = castOrNull(value);
  190. if (vec == null) {
  191. String msg;
  192. if (value == null)
  193. msg = "cannot convert null to $CNAME$";
  194. else
  195. msg = "cannot convert a "+value.getClass().getName()+" to $CNAME$";
  196. throw new ClassCastException(msg);
  197. }
  198. return vec;
  199. }
  200. /* #endif */
  201. /* #ifdef BIT|S8|S16|S32|S64|U8|U16|U32|U64|F32|F64 */
  202. public int getElementKind() { return $KIND$_VALUE; }
  203. public String getTag() { return "$tag$"; }
  204. /* #endif */
  205. /* #ifdef OBJECT */
  206. public final void fill(int start, int end, E new_value) {
  207. if (isVerySimple())
  208. java.util.Arrays.fill(data, start, end, new_value);
  209. else
  210. super.fill(start, end, new_value);
  211. }
  212. /* #endif */
  213. /* #ifdef OBJECT|BIT|S64|U32|U64|F32|F64 */
  214. public void consumePosRange(int iposStart, int iposEnd, Consumer out) {
  215. if (out.ignoring())
  216. return;
  217. int i = nextIndex(iposStart);
  218. int end = nextIndex(iposEnd);
  219. for (; i < end; i++)
  220. $WRITE(i,out);
  221. }
  222. /* #endif */
  223. /* #ifdef OBJECT */
  224. public void consume(Consumer out) {
  225. out.startElement("#vector");
  226. int len = size();
  227. for (int i = 0; i < len; i++)
  228. out.writeObject(get(i));
  229. out.endElement();
  230. }
  231. public boolean equals(Object obj) {
  232. if (obj == null || !(obj instanceof FVector))
  233. return false;
  234. FVector obj_vec = (FVector) obj;
  235. int n = size();
  236. if (obj_vec.data == null || obj_vec.size() != n)
  237. return false;
  238. Object[] this_data = data;
  239. Object[] obj_data = obj_vec.data;
  240. for (int i = 0; i < n; i++) {
  241. if (! (this_data[effectiveIndex(i)].equals(obj_data[obj_vec.effectiveIndex(i)])))
  242. return false;
  243. }
  244. return true;
  245. }
  246. /* #endif */
  247. /* #ifdef S8|S16|S32|U8|U16|U32 */
  248. public int compareTo(Object obj) {
  249. return compareToInt(this, ($TAG$Vector) obj);
  250. }
  251. /* #endif */
  252. /* #ifdef OBJECT|BIT|F32|F64|S64|U64 */
  253. public int compareTo(Object obj) {
  254. $TAG$Vector vec2 = ($TAG$Vector) obj;
  255. $ptype$[] arr1 = data;
  256. $ptype$[] arr2 = vec2.data;
  257. int n1 = size();
  258. int n2 = vec2.size();
  259. int n = n1 > n2 ? n2 : n1;
  260. for (int i = 0; i < n; i++) {
  261. $ptype$ v1 = arr1[effectiveIndex(i)];
  262. $ptype$ v2 = arr2[effectiveIndex(i)];
  263. if (v1 != v2)
  264. $RETURN_IF_UNEQUAL$(v1,v2);
  265. }
  266. return n1 - n2;
  267. }
  268. /* #endif */
  269. /* #ifdef BYTE */
  270. public int readFrom(int start, int count, InputStream in)
  271. throws IOException {
  272. int pos = start;
  273. while (count > 0) {
  274. long result = getSegment(pos);
  275. int where = (int) result;
  276. int size = (int) (result >> 32);
  277. if (size > count)
  278. size = count;
  279. int n = in.read(data, where, size);
  280. if (n < 0) {
  281. if (pos == start)
  282. return -1;
  283. break;
  284. }
  285. pos += n;
  286. count -= n;
  287. }
  288. return pos - start;
  289. }
  290. public void writeTo(OutputStream out)
  291. throws IOException {
  292. writeTo(0, size(), out);
  293. }
  294. public void writeTo(int start, int count, OutputStream out)
  295. throws IOException {
  296. while (count > 0) {
  297. long result = getSegment(start);
  298. int where = (int) result;
  299. int size = (int) (result >> 32);
  300. if (size > count)
  301. size = count;
  302. out.write(data, where, size);
  303. start += size;
  304. count -= size;
  305. }
  306. }
  307. public void copyFrom (int index, ByteVector src, int start, int end) {
  308. int count = end-start;
  309. int sz = size();
  310. int src_sz = src.size();
  311. if (count < 0 || index+count > sz || end > src_sz)
  312. throw new ArrayIndexOutOfBoundsException();
  313. int sseg, dseg;
  314. if ((sseg = src.getSegmentReadOnly(start, count)) >= 0 &&
  315. (dseg = getSegment(index, count)) >= 0) {
  316. System.arraycopy(src.data, sseg, data, dseg, count);
  317. } else {
  318. for (int i = 0; i < count; i++)
  319. setByte(index+i, src.getByte(start+i));
  320. }
  321. }
  322. public InputStream getInputStream() {
  323. int sz = size();
  324. int seg = getSegmentReadOnly(0, sz);
  325. if (seg >= 0)
  326. return new ByteArrayInputStream(data, seg, sz);
  327. else
  328. return new ByteVectorInputStream(this);
  329. }
  330. static class ByteVectorInputStream extends InputStream {
  331. ByteVector bvec;
  332. int pos;
  333. int mark;
  334. int size;
  335. public ByteVectorInputStream(ByteVector bvec) {
  336. this.bvec = bvec;
  337. this.size = bvec.size();
  338. }
  339. public int read() {
  340. return pos >= size ? -1 :
  341. (0xff & bvec.getByte(pos++));
  342. }
  343. public boolean markSupported() { return true; }
  344. public void mark(int readLimit) { mark = pos; }
  345. public void reset() { pos = mark; }
  346. public void close() { }
  347. public int available() { return size-pos; }
  348. public long skip(long n) {
  349. if (n < 0) n = 0;
  350. if (n < size-pos) { pos = size; return size-pos; }
  351. else { pos += n; return n; }
  352. }
  353. }
  354. /** Covert bytes, interpreted as UTF-8 characters, to a String. */
  355. public String utf8ToString(int start, int length) {
  356. if (start+length>size()) throw new IndexOutOfBoundsException();
  357. int seg = getSegmentReadOnly(start, length);
  358. byte[] buf;
  359. if (seg >= 0) {
  360. buf = data;
  361. start = seg;
  362. } else {
  363. buf = new byte[length];
  364. for (int i = 0; i < length; i++)
  365. buf[i] = getByte(start+i);
  366. }
  367. return Strings.fromUtf8(buf, start, length);
  368. }
  369. static final byte BOM_HI = (byte) 0xFE;
  370. static final byte BOM_LO = (byte) 0xFF;
  371. public String utf16ToString(int start, int length) {
  372. boolean bigEndian = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
  373. if (length >+ 2) {
  374. byte b0 = getByte(start);
  375. byte b1 = getByte(start+1);
  376. if (b0 == BOM_LO && b1 == BOM_HI) {
  377. start += 2; length -= 2; bigEndian = false;
  378. } else if (b0 == BOM_HI && b1 == BOM_LO) {
  379. start += 2; length -= 2; bigEndian = true;
  380. }
  381. }
  382. return utf16ToString(start, length, bigEndian);
  383. }
  384. public String utf16ToString(int start, int length, boolean bigEndian) {
  385. if (start+length>size()) throw new IndexOutOfBoundsException();
  386. if ((length & 1) != 0)
  387. throw new IllegalArgumentException("number of bytes must be even");
  388. char[] buf = new char[length>>1];
  389. int hi = bigEndian ? 0 : 1;
  390. int lo = bigEndian ? 1 : 0;
  391. for (int i = 0; i < length; i += 2) {
  392. byte bhi = getByte(start+i+hi);
  393. byte blo = getByte(start+i+lo);
  394. buf[i>>1] = (char) (((bhi & 0xFF) << 8) | (blo & 0xFF));
  395. }
  396. return new String(buf);
  397. }
  398. /* #endif */
  399. }