123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496 |
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Text;
- namespace CommonLang.NIO
- {
- public enum ByteOrder
- {
- LITTLE_ENDIAN,
- BIG_ENDIAN,
- }
- public abstract class Buffer
- {
- // Invariants: mark <= position <= limit <= capacity
- private int mark = -1;
- private int position = 0;
- private int limit;
- private int capacity;
- // Used only by direct buffers
- // NOTE: hoisted here for speed in JNI GetDirectBufferAddress
- //IntPtr address;
- // Creates a new buffer with the given mark, position, limit, and capacity,
- // after checking invariants.
- //
- internal Buffer(int mark, int pos, int lim, int cap)
- {
- if (cap < 0)
- throw new Exception("Negative capacity: " + cap);
- this.capacity = cap;
- Limit(lim);
- Position(pos);
- if (mark >= 0)
- {
- if (mark > pos)
- throw new Exception("mark > position: ("
- + mark + " > " + pos + ")");
- this.mark = mark;
- }
- }
- public int Capacity()
- {
- return capacity;
- }
- public int Position()
- {
- return position;
- }
- public Buffer Position(int newPosition)
- {
- if ((newPosition > limit) || (newPosition < 0))
- throw new Exception("IllegalArgumentException");
- position = newPosition;
- if (mark > position) mark = -1;
- return this;
- }
- public int Limit()
- {
- return limit;
- }
- public Buffer Limit(int newLimit)
- {
- if ((newLimit > capacity) || (newLimit < 0))
- throw new Exception("IllegalArgumentException");
- limit = newLimit;
- if (position > limit) position = limit;
- if (mark > limit) mark = -1;
- return this;
- }
- public Buffer Mark()
- {
- mark = position;
- return this;
- }
- public Buffer Reset()
- {
- int m = mark;
- if (m < 0)
- throw new Exception("InvalidMarkException");
- position = m;
- return this;
- }
- public Buffer Clear()
- {
- position = 0;
- limit = capacity;
- mark = -1;
- return this;
- }
- public Buffer Flip()
- {
- limit = position;
- position = 0;
- mark = -1;
- return this;
- }
- public Buffer Rewind()
- {
- position = 0;
- mark = -1;
- return this;
- }
- public int Remaining()
- {
- return limit - position;
- }
- public bool HasRemaining()
- {
- return position < limit;
- }
- public abstract bool IsReadOnly();
- public abstract bool HasArray();
- public abstract Array Array();
- public abstract int ArrayOffset();
- internal int NextGetIndex()
- {
- if (position >= limit)
- throw new Exception("BufferUnderflowException");
- return position++;
- }
- internal int NextGetIndex(int nb)
- {
- if (limit - position < nb)
- throw new Exception("BufferUnderflowException");
- int p = position;
- position += nb;
- return p;
- }
- internal int NextPutIndex()
- {
- if (position >= limit)
- throw new Exception("BufferOverflowException");
- return position++;
- }
- internal int NextPutIndex(int nb)
- {
- if (limit - position < nb)
- throw new Exception("BufferOverflowException");
- int p = position;
- position += nb;
- return p;
- }
- internal int CheckIndex(int i)
- {
- if ((i < 0) || (i >= limit))
- throw new IndexOutOfRangeException();
- return i;
- }
- internal int CheckIndex(int i, int nb)
- {
- if ((i < 0) || (nb > limit - i))
- throw new IndexOutOfRangeException();
- return i;
- }
- internal int MarkValue()
- {
- return mark;
- }
- internal void Truncate()
- {
- mark = -1;
- position = 0;
- limit = 0;
- capacity = 0;
- }
- internal void DiscardMark()
- {
- mark = -1;
- }
- internal static void CheckBounds(int off, int len, int size)
- {
- if ((off | len | (off + len) | (size - (off + len))) < 0)
- throw new IndexOutOfRangeException();
- }
- }
- public abstract class ByteBuffer : Buffer
- {
- readonly internal byte[] hb;
- readonly internal int offset;
- internal ByteBuffer(int mark, int pos, int lim, int cap,
- byte[] hb, int offset)
- : base(mark, pos, lim, cap)
- {
- this.hb = hb;
- this.offset = offset;
- }
- internal ByteBuffer(int mark, int pos, int lim, int cap)
- : this(mark, pos, lim, cap, null, 0)
- {
- }
- public static ByteBuffer Allocate(int capacity)
- {
- if (capacity < 0)
- throw new Exception("IllegalArgumentException");
- return new HeapByteBuffer(capacity, capacity);
- }
- public static ByteBuffer Wrap(byte[] array, int offset, int length)
- {
- try
- {
- return new HeapByteBuffer(array, offset, length);
- }
- catch (Exception err)
- {
- Console.WriteLine("Wrap 1: " + array + ", catch: " + err);
- throw new IndexOutOfRangeException();
- }
- }
- public static ByteBuffer Wrap(byte[] array)
- {
- return Wrap(array, 0, array.Length);
- }
- public abstract ByteBuffer Slice();
- public abstract ByteBuffer Duplicate();
- public abstract byte Get();
- public abstract ByteBuffer Put(byte b);
- public abstract byte Get(int index);
- public abstract ByteBuffer Put(int index, byte b);
- public virtual ByteBuffer Get(byte[] dst, int offset, int length)
- {
- CheckBounds(offset, length, dst.Length);
- if (length > Remaining())
- throw new Exception("BufferUnderflowException");
- int end = offset + length;
- for (int i = offset; i < end; i++)
- dst[i] = Get();
- return this;
- }
- public virtual ByteBuffer Get(byte[] dst)
- {
- return Get(dst, 0, dst.Length);
- }
- public virtual ByteBuffer Put(ByteBuffer src)
- {
- if (src == this)
- throw new Exception("IllegalArgumentException");
- int n = src.Remaining();
- if (n > Remaining())
- throw new Exception("BufferOverflowException");
- for (int i = 0; i < n; i++)
- Put(src.Get());
- return this;
- }
- public virtual ByteBuffer Put(byte[] src, int offset, int length)
- {
- CheckBounds(offset, length, src.Length);
- if (length > Remaining())
- throw new Exception("BufferOverflowException");
- int end = offset + length;
- for (int i = offset; i < end; i++)
- this.Put(src[i]);
- return this;
- }
- public virtual ByteBuffer Put(byte[] src)
- {
- return Put(src, 0, src.Length);
- }
- public override bool HasArray()
- {
- return (hb != null);
- }
- public override Array Array()
- {
- if (hb == null)
- throw new Exception("UnsupportedOperationException");
- return hb;
- }
- public override int ArrayOffset()
- {
- if (hb == null)
- throw new Exception("UnsupportedOperationException");
- return offset;
- }
- public abstract ByteBuffer Compact();
- public override String ToString()
- {
- StringBuilder sb = new StringBuilder();
- sb.Append(GetType().Name);
- sb.Append("[pos=");
- sb.Append(Position());
- sb.Append(" lim=");
- sb.Append(Limit());
- sb.Append(" cap=");
- sb.Append(Capacity());
- sb.Append("]");
- return sb.ToString();
- }
- public override int GetHashCode()
- {
- int h = 1;
- int p = Position();
- for (int i = Limit() - 1; i >= p; i--)
- h = 31 * h + (int)Get(i);
- return h;
- }
- public override bool Equals(Object ob)
- {
- if (this == ob)
- return true;
- if (!(ob is ByteBuffer))
- return false;
- ByteBuffer that = (ByteBuffer)ob;
- if (this.Remaining() != that.Remaining())
- return false;
- int p = this.Position();
- for (int i = this.Limit() - 1, j = that.Limit() - 1; i >= p; i--, j--)
- if ((this.Get(i) != that.Get(j)))
- return false;
- return true;
- }
- }
- public class HeapByteBuffer : ByteBuffer
- {
- internal HeapByteBuffer(int cap, int lim)
- : base(-1, 0, lim, cap, new byte[cap], 0)
- { }
- internal HeapByteBuffer(byte[] buf, int off, int len)
- : base(-1, off, off + len, buf.Length, buf, 0)
- { }
- protected HeapByteBuffer(byte[] buf, int mark, int pos, int lim, int cap, int off)
- : base(mark, pos, lim, cap, buf, off)
- { }
- public override ByteBuffer Slice()
- {
- return new HeapByteBuffer(hb,
- -1,
- 0,
- this.Remaining(),
- this.Remaining(),
- this.Position() + offset);
- }
- public override ByteBuffer Duplicate()
- {
- return new HeapByteBuffer(hb,
- this.MarkValue(),
- this.Position(),
- this.Limit(),
- this.Capacity(),
- offset);
- }
- protected int ix(int i)
- {
- return i + offset;
- }
- public override byte Get()
- {
- return hb[ix(NextGetIndex())];
- }
- public override byte Get(int i)
- {
- return hb[ix(CheckIndex(i))];
- }
- public override ByteBuffer Get(byte[] dst, int offset, int length)
- {
- CheckBounds(offset, length, dst.Length);
- if (length > Remaining())
- throw new Exception("BufferUnderflowException");
- System.Buffer.BlockCopy(hb, ix(Position()), dst, offset, length);
- Position(Position() + length);
- return this;
- }
- public override bool IsReadOnly()
- {
- return false;
- }
- public override ByteBuffer Put(byte x)
- {
- hb[ix(NextPutIndex())] = x;
- return this;
- }
- public override ByteBuffer Put(int i, byte x)
- {
- hb[ix(CheckIndex(i))] = x;
- return this;
- }
- public override ByteBuffer Put(byte[] src, int offset, int length)
- {
- CheckBounds(offset, length, src.Length);
- if (length > Remaining())
- throw new Exception("BufferOverflowException");
- System.Buffer.BlockCopy(src, offset, hb, ix(Position()), length);
- Position(Position() + length);
- return this;
- }
- public override ByteBuffer Put(ByteBuffer src)
- {
- if (src is HeapByteBuffer)
- {
- if (src == this)
- throw new Exception("IllegalArgumentException");
- HeapByteBuffer sb = (HeapByteBuffer)src;
- int n = sb.Remaining();
- if (n > Remaining())
- throw new Exception("BufferOverflowException");
- System.Buffer.BlockCopy(sb.hb, sb.ix(sb.Position()),
- hb, ix(Position()), n);
- sb.Position(sb.Position() + n);
- Position(Position() + n);
- }
- else
- {
- base.Put(src);
- }
- return this;
- }
- public override ByteBuffer Compact()
- {
- System.Buffer.BlockCopy(hb, ix(Position()), hb, ix(0), Remaining());
- Position(Remaining());
- Limit(Capacity());
- DiscardMark();
- return this;
- }
- }
- }
|