123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452 |
- // $PREAMBLE$ -*- java -*-
- // Copyright (c) 2001, 2002, 2015 Per M.A. Bothner and Brainfood Inc.
- // This is free software; for terms and warranty disclaimer see ./COPYING.
- package gnu.lists;
- import java.io.*;
- /* #ifdef U8|U16|U32|U64 */
- import gnu.math.$BTYPE$;
- /* #endif */
- /* #ifdef BYTE */
- import java.nio.ByteOrder;
- /* #endif */
- /** Simple adjustable-length vector of $DESC$. */
- public @Abstract class $CNAME$ extends $SUPER$
- /* #ifdef OBJECT */
- implements Consumable, Comparable
- /* #endif */
- /* #ifdef S32 */
- implements IntSequence
- /* #endif */
- /* #ifdef BIT|F32|F64 */
- implements Comparable
- /* #endif */
- {
- /* #ifdef OBJECT|BIT|BYTE|SHORT|INT|LONG|F32|F64 */
- $ptype$[] data;
- protected static $ptype$[] empty = new $ptype$[0];
- /* #endif */
- /* #ifdef OBJECT|BIT|S8|S16|S32|S64|U8|U16|U32|U64|F32|F64 */
- public $TAG$Vector() {
- data = empty;
- }
- public $TAG$Vector(int size, $ptype$ value) {
- $ptype$[] array = new $ptype$[size];
- data = array;
- if (value != $ZERO$) {
- while (--size >= 0)
- array[size] = value;
- }
- }
- public $TAG$Vector(int size) {
- this(new $ptype$[size]);
- }
- /** Reuses the argument without making a copy. */
- public $TAG$Vector($ptype$[] data) {
- this.data = data;
- }
- /** Makes a copy of (part of) the argument array. */
- public $TAG$Vector($ptype$[] values, int offset, int length) {
- this(length);
- System.arraycopy(values, offset, data, 0, length);
- }
- /* #endif */
- /* #ifdef OBJECT */
- public FVector(java.util.List seq) {
- this.data = new Object[seq.size()];
- int i = 0;
- for (java.util.Iterator<? extends E> it = seq.iterator(); it.hasNext(); )
- data[i++] = it.next();
- }
- public static FVector make(Object... data) {
- return new FVector(data);
- }
- public static <E> FVector<E> makeConstant(E... data) {
- FVector<E> vec = new FVector(data);
- vec.setReadOnly();
- return vec;
- }
- public void replaceAll(E[] data) {
- this.data = data;
- this.info = VERY_SIMPLE_FLAG;
- }
- public void copyFrom (int index, FVector<E> src, int start, int end) {
- int count = end-start;
- int sz = size();
- int src_sz = src.size();
- if (count < 0 || index+count > sz || end > src_sz)
- throw new ArrayIndexOutOfBoundsException();
- int sseg, dseg;
- if ((sseg = src.getSegmentReadOnly(start, count)) >= 0 &&
- (dseg = getSegment(index, count)) >= 0) {
- System.arraycopy(src.data, sseg, data, dseg, count);
- } else {
- for (int i = 0; i < count; i++)
- set(index+i, src.get(start+i));
- }
- }
- /* #endif */
- /* #ifdef OBJECT|BIT|BYTE|SHORT|INT|LONG|F32|F64 */
- /** Get the allocated length of the data buffer. */
- public int getBufferLength() {
- return data.length;
- }
- public void copyBuffer(int length) {
- int oldLength = data.length;
- if (length == -1)
- length = oldLength;
- if (oldLength != length) {
- $ptype$[] tmp = new $ptype$[length];
- System.arraycopy(data, 0, tmp, 0,
- oldLength < length ? oldLength : length);
- data = tmp;
- }
- }
- public $ptype$[] getBuffer() { return data; }
- protected void setBuffer(Object buffer) { data = ($ptype$[]) buffer; }
- /* #endif */
- /* #ifdef BIT|BYTE|SHORT|INT|LONG|F32|F64 */
- public final $ptype$ get$Ptype$(int index) {
- return data[effectiveIndex(index)];
- }
- public final $ptype$ get$Ptype$Raw(int index) {
- return data[index];
- }
- /* #endif */
- /* #ifdef S8|S16|U8|U16|LONG */
- public final int getIntRaw(int index) {
- return (int) data[index]$MASK$;
- }
- /* #endif */
- /* #ifdef S32|U32 */
- public final long getLongRaw(int index) {
- return (long) data[index]$MASK$;
- }
- /* #endif */
- /* #ifdef OBJECT */
- public final E get(int index) {
- return (E) data[effectiveIndex(index)];
- }
- public final E getRaw(int index) {
- return (E) data[index];
- }
- /* #endif */
- /* #ifdef BIT|S8|S16|S32|S64|U8|U16|U32|U64|F32|F64 */
- public final $BTYPE$ get(int index) {
- return $BTYPE$.valueOf(data[effectiveIndex(index)]);
- }
- public final $BTYPE$ getRaw(int index) {
- return $BTYPE$.valueOf(data[index]);
- }
- /* #endif */
- /* #ifdef BIT|BYTE|SHORT|INT|LONG|F32|F64 */
- public final void set$Ptype$(int index, $ptype$ value) {
- checkCanWrite(); // FIXME maybe inline and fold into following
- data[effectiveIndex(index)] = value;
- }
- public final void set$Ptype$Raw(int index, $ptype$ value) {
- data[index] = value;
- }
- /* #endif */
- /* #ifdef OBJECT */
- @Override
- public final void setRaw(int index, $BTYPE$ value) {
- data[index] = value;
- }
- /* #endif */
- /* #ifdef BIT|S8|S16|S32|S64|U8|U16|U32|U64|F32|F64 */
- @Override
- public final void setRaw(int index, $BTYPE$ value) {
- data[index] = value.$ptype$Value();
- }
- /* #endif */
- /* #ifdef BIT|BYTE|SHORT|INT|LONG|F32|F64 */
- public void add($ptype$ v) {
- int sz = size();
- addSpace(sz, 1);
- set$Ptype$(sz, v);
- }
- /* #endif */
- /* #ifdef OBJECT|BIT|BYTE|SHORT|INT|LONG|F32|F64 */
- protected void clearBuffer(int start, int count) {
- $ptype$[] d = data;
- while (--count >= 0)
- d[start++] = $ZERO$;
- }
- /* #endif */
- /* #ifdef OBJECT|BIT|S8|S16|S32|S64|U8|U16|U32|U64|F32|F64 */
- @Override
- protected $CNAME$ newInstance(int newLength) {
- return new $CNAME$(newLength < 0 ? data : new $ptype$[newLength]);
- }
- public static $TAG$Vector castOrNull(Object obj) {
- if (obj instanceof $ptype$[])
- return new $TAG$Vector(($ptype$[]) obj);
- if (obj instanceof $TAG$Vector)
- return ($TAG$Vector) obj;
- return null;
- }
- public static $TAG$Vector cast(Object value) {
- $TAG$Vector vec = castOrNull(value);
- if (vec == null) {
- String msg;
- if (value == null)
- msg = "cannot convert null to $CNAME$";
- else
- msg = "cannot convert a "+value.getClass().getName()+" to $CNAME$";
- throw new ClassCastException(msg);
- }
- return vec;
- }
- /* #endif */
- /* #ifdef BIT|S8|S16|S32|S64|U8|U16|U32|U64|F32|F64 */
- public int getElementKind() { return $KIND$_VALUE; }
- public String getTag() { return "$tag$"; }
- /* #endif */
- /* #ifdef OBJECT */
- public final void fill(int start, int end, E new_value) {
- if (isVerySimple())
- java.util.Arrays.fill(data, start, end, new_value);
- else
- super.fill(start, end, new_value);
- }
- /* #endif */
- /* #ifdef OBJECT|BIT|S64|U32|U64|F32|F64 */
- public void consumePosRange(int iposStart, int iposEnd, Consumer out) {
- if (out.ignoring())
- return;
- int i = nextIndex(iposStart);
- int end = nextIndex(iposEnd);
- for (; i < end; i++)
- $WRITE(i,out);
- }
- /* #endif */
- /* #ifdef OBJECT */
- public void consume(Consumer out) {
- out.startElement("#vector");
- int len = size();
- for (int i = 0; i < len; i++)
- out.writeObject(get(i));
- out.endElement();
- }
- public boolean equals(Object obj) {
- if (obj == null || !(obj instanceof FVector))
- return false;
- FVector obj_vec = (FVector) obj;
- int n = size();
- if (obj_vec.data == null || obj_vec.size() != n)
- return false;
- Object[] this_data = data;
- Object[] obj_data = obj_vec.data;
- for (int i = 0; i < n; i++) {
- if (! (this_data[effectiveIndex(i)].equals(obj_data[obj_vec.effectiveIndex(i)])))
- return false;
- }
- return true;
- }
- /* #endif */
- /* #ifdef S8|S16|S32|U8|U16|U32 */
- public int compareTo(Object obj) {
- return compareToInt(this, ($TAG$Vector) obj);
- }
- /* #endif */
- /* #ifdef OBJECT|BIT|F32|F64|S64|U64 */
- public int compareTo(Object obj) {
- $TAG$Vector vec2 = ($TAG$Vector) obj;
- $ptype$[] arr1 = data;
- $ptype$[] arr2 = vec2.data;
- int n1 = size();
- int n2 = vec2.size();
- int n = n1 > n2 ? n2 : n1;
- for (int i = 0; i < n; i++) {
- $ptype$ v1 = arr1[effectiveIndex(i)];
- $ptype$ v2 = arr2[effectiveIndex(i)];
- if (v1 != v2)
- $RETURN_IF_UNEQUAL$(v1,v2);
- }
- return n1 - n2;
- }
- /* #endif */
- /* #ifdef BYTE */
- public int readFrom(int start, int count, InputStream in)
- throws IOException {
- int pos = start;
- while (count > 0) {
- long result = getSegment(pos);
- int where = (int) result;
- int size = (int) (result >> 32);
- if (size > count)
- size = count;
- int n = in.read(data, where, size);
- if (n < 0) {
- if (pos == start)
- return -1;
- break;
- }
- pos += n;
- count -= n;
- }
- return pos - start;
- }
- public void writeTo(OutputStream out)
- throws IOException {
- writeTo(0, size(), out);
- }
- public void writeTo(int start, int count, OutputStream out)
- throws IOException {
- while (count > 0) {
- long result = getSegment(start);
- int where = (int) result;
- int size = (int) (result >> 32);
- if (size > count)
- size = count;
- out.write(data, where, size);
- start += size;
- count -= size;
- }
- }
- public void copyFrom (int index, ByteVector src, int start, int end) {
- int count = end-start;
- int sz = size();
- int src_sz = src.size();
- if (count < 0 || index+count > sz || end > src_sz)
- throw new ArrayIndexOutOfBoundsException();
- int sseg, dseg;
- if ((sseg = src.getSegmentReadOnly(start, count)) >= 0 &&
- (dseg = getSegment(index, count)) >= 0) {
- System.arraycopy(src.data, sseg, data, dseg, count);
- } else {
- for (int i = 0; i < count; i++)
- setByte(index+i, src.getByte(start+i));
- }
- }
- public InputStream getInputStream() {
- int sz = size();
- int seg = getSegmentReadOnly(0, sz);
- if (seg >= 0)
- return new ByteArrayInputStream(data, seg, sz);
- else
- return new ByteVectorInputStream(this);
- }
- static class ByteVectorInputStream extends InputStream {
- ByteVector bvec;
- int pos;
- int mark;
- int size;
- public ByteVectorInputStream(ByteVector bvec) {
- this.bvec = bvec;
- this.size = bvec.size();
- }
- public int read() {
- return pos >= size ? -1 :
- (0xff & bvec.getByte(pos++));
- }
- public boolean markSupported() { return true; }
- public void mark(int readLimit) { mark = pos; }
- public void reset() { pos = mark; }
- public void close() { }
- public int available() { return size-pos; }
- public long skip(long n) {
- if (n < 0) n = 0;
- if (n < size-pos) { pos = size; return size-pos; }
- else { pos += n; return n; }
- }
- }
- /** Covert bytes, interpreted as UTF-8 characters, to a String. */
- public String utf8ToString(int start, int length) {
- if (start+length>size()) throw new IndexOutOfBoundsException();
- int seg = getSegmentReadOnly(start, length);
- byte[] buf;
- if (seg >= 0) {
- buf = data;
- start = seg;
- } else {
- buf = new byte[length];
- for (int i = 0; i < length; i++)
- buf[i] = getByte(start+i);
- }
- return Strings.fromUtf8(buf, start, length);
- }
- static final byte BOM_HI = (byte) 0xFE;
- static final byte BOM_LO = (byte) 0xFF;
- public String utf16ToString(int start, int length) {
- boolean bigEndian = ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN;
- if (length >+ 2) {
- byte b0 = getByte(start);
- byte b1 = getByte(start+1);
- if (b0 == BOM_LO && b1 == BOM_HI) {
- start += 2; length -= 2; bigEndian = false;
- } else if (b0 == BOM_HI && b1 == BOM_LO) {
- start += 2; length -= 2; bigEndian = true;
- }
- }
- return utf16ToString(start, length, bigEndian);
- }
- public String utf16ToString(int start, int length, boolean bigEndian) {
- if (start+length>size()) throw new IndexOutOfBoundsException();
- if ((length & 1) != 0)
- throw new IllegalArgumentException("number of bytes must be even");
- char[] buf = new char[length>>1];
- int hi = bigEndian ? 0 : 1;
- int lo = bigEndian ? 1 : 0;
- for (int i = 0; i < length; i += 2) {
- byte bhi = getByte(start+i+hi);
- byte blo = getByte(start+i+lo);
- buf[i>>1] = (char) (((bhi & 0xFF) << 8) | (blo & 0xFF));
- }
- return new String(buf);
- }
- /* #endif */
- }
|