用于生成 Office 文件的 .NET 组件。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

444 lines
11 KiB

8 years ago
using System;
namespace Npoi.Core.Util
8 years ago
{
public class ByteBuffer
{
private byte[] buffer;
private int mark = -1; //useless.
private int position = 0;
private int limit;
private int capacity;
private int offset; //not sure about this.
private ByteBuffer(int mark, int pos, int lim, int cap, byte[] buffer, int offset)
{
if (cap < 0)
throw new ArgumentException();
this.capacity = cap;
this.Limit = lim;
this.Position = pos;
if (mark >= 0)
{
if (mark > pos)
throw new ArgumentException();
this.mark = mark;
}
this.buffer = buffer;
this.offset = offset;
}
public ByteBuffer(byte[] buffer, int off, int len)
:this(-1, off, off+len, buffer.Length, buffer, 0)
{
}
public ByteBuffer(int capacity, int limit)
:this(-1, 0, limit, capacity, new byte[capacity], 0)
{
}
protected ByteBuffer(byte[] buffer, int mark, int pos, int lim, int cap, int off)
: this(mark, pos, lim, cap, buffer, off)
{
}
public int Position
{
get { return position; }
set
{
if (value < 0 || value > limit)
throw new ArgumentException();
position = value;
if (mark > position)
mark = -1;
}
}
public int Limit
{
get { return limit; }
set
{
if ((value > capacity) || (value < 0))
throw new ArgumentException();
limit = value;
if (position > limit)
position = limit;
if (mark > limit)
mark = -1;
}
}
/// <summary>
/// Returns the number of elements between the current position and the limit.
/// </summary>
/// <returns>The number of elements remaining in this buffer</returns>
public int Remaining() {
return limit - position;
}
/// <summary>
/// Tells whether there are any elements between the current position and the limit.
/// </summary>
/// <returns>true if, and only if, there is at least one element remaining in this buffer</returns>
public bool HasRemaining() {
return position < limit;
}
//allocate
public static ByteBuffer CreateBuffer(int capacity)
{
if (capacity < 0)
throw new ArgumentException();
return new ByteBuffer(capacity, capacity);
}
//wrap
public static ByteBuffer CreateBuffer(byte[] buffer, int offset, int length)
{
try
{
return new ByteBuffer(buffer, offset, length);
}
catch (ArgumentException)
{
throw new IndexOutOfRangeException();
}
}
public static ByteBuffer CreateBuffer(byte[] buffer)
{
return CreateBuffer(buffer, 0, buffer.Length);
}
public ByteBuffer Slice() //This is not correct! Leon
{
return new ByteBuffer(buffer, -1, 0, this.Remain, this.Remain, this.Position + offset);
}
public ByteBuffer Duplicate()
{
return null;
}
protected int NextGetIndex()
{
if (position >= limit)
throw new IndexOutOfRangeException();
return position++;
}
protected int NextGetIndex(int nb)
{
if (limit - position < nb)
throw new IndexOutOfRangeException();
int p = position;
position += nb;
return p;
}
protected int NextPutIndex()
{
return NextGetIndex();
}
protected int NextPutIndex(int nb)
{
return NextGetIndex(nb);
}
protected int Index(int i)
{
return i + offset;
}
protected int CheckIndex(int i)
{
if(i < 0 || (i >= limit))
throw new IndexOutOfRangeException();
return i;
}
protected int CheckIndex(int i, int nb)
{
if ((i < 0) || (nb > limit - i))
throw new IndexOutOfRangeException();
return i;
}
public byte Read()
{
return buffer[Index(NextGetIndex())];
}
public byte this[int index]
{
get
{
return buffer[Index(CheckIndex(index))];
}
set
{
// buffer[Index(NextPutIndex(index))] = value;
if (index < 0 || index >= limit)
throw new IndexOutOfRangeException();
buffer[Index(index)] = value;
}
}
protected void CheckBounds(int off, int len, int size)
{
if ((off | len | (off + len) | (size - (off + len))) < 0)
throw new IndexOutOfRangeException();
}
public ByteBuffer Read(byte[] buf)
{
return Read(buf, 0, buf.Length);
}
public ByteBuffer Read(byte[] dst, int offset, int length)
{
CheckBounds(offset, length, dst.Length);
if (length > Remain)
throw new ArgumentException();
//for (int i = offset; i < offset + length; i++)
// dst[i] = Read();
System.Array.Copy(buffer, Index(this.position), dst, offset, length);
this.Position = Position + length;
return this;
}
public ByteBuffer Write(byte x)
{
buffer[Index(NextPutIndex())] = x;
return this;
}
public ByteBuffer Write(byte[] src, int offset, int length)
{
CheckBounds(offset, length, src.Length);
if (length > Remain)
throw new IndexOutOfRangeException();
System.Array.Copy(src, offset, buffer, Index(this.Position), length);
this.Position = this.Position + length;
return this;
}
public ByteBuffer Write(ByteBuffer src)
{
if (src == this)
throw new ArgumentException();
int n = src.Remain;
if (n > this.Remain)
throw new IndexOutOfRangeException();
for (int i = 0; i < n; i++)
Write(src.Read());
return this;
}
public ByteBuffer Write(byte[] data)
{
return Write(data, 0, data.Length);
}
public int Remain
{
get { return limit - position; }
}
public byte[] Buffer
{
get { return buffer; }
}
public int Offset
{
get { return offset; }
}
public bool HasBuffer
{
get { return true; }
}
public int Length
{
get { return capacity; }
}
}
}
/*
private byte[] buffer;
private int start;
private int position;
// private int capacity;
private int length;
public ByteBuffer(byte[] buffer, int start, int count)
{
this.buffer = buffer;
this.start = position = start;
//length = capacity = start + count;
length = start + count;
}
public ByteBuffer(int capacity)
{
this.buffer = new byte[capacity];
start = position = 0;
length = capacity;
}
public ByteBuffer(byte[] buffer) : this(buffer, 0, buffer.Length)
{
}
public void Write(byte[] data)
{
Write(data, 0, data.Length);
}
public void Write(byte[] data, int off, int count)
{
int len = data.Length;
if ((off + count) > len || off < 0 || count < 0)
throw new IndexOutOfRangeException();
if (count > Remain)
throw new Exception();
for (int i = off; i < off + count; i++)
buffer[position++] = data[i];
}
public ByteBuffer Write(int index, byte val)
{
if (index < 0 || index >= length)
throw new IndexOutOfRangeException();
buffer[index] = val;
return this;
}
public int Remain
{
get { return length - position; }
}
public ByteBuffer Slice() //This is not correct! Leon
{
ByteBuffer slice = new ByteBuffer(buffer, start + position, Remain);
return slice;
}
public ByteBuffer Read(byte[] buf, int off, int count)
{
int len = buf.Length;
if(off < 0 || count < 0 || (off + count > len))
throw new IndexOutOfRangeException();
if (count > Remain)
throw new Exception();
for (int i = off; i < off + count; i++)
buf[i] = Read();
return this;
}
public ByteBuffer Read(byte[] buf)
{
return Read(buf, 0, buf.Length);
}
public int Position
{
get { return position; }
set
{
if (value < 0 || value > length)
throw new ArgumentException();
position = value;
}
}
public byte Read()
{
if (position == length)
throw new Exception();
return buffer[start + position++];
}
public byte[] Buffer
{
get { return buffer; }
}
public int Offset
{
get { return start; }
}
public bool HasBuffer
{
get { return true; }
}
public int Length
{
get { return length; }
}
//public int Position
//{
// get { return position; }
//}
public byte this[int index]
{
get
{
if (index < 0 || index > length)
throw new IndexOutOfRangeException();
return buffer[index];
}
}
public static ByteBuffer CreateBuffer(int capacity)
{
return new ByteBuffer(capacity);
}
public static ByteBuffer CreateBuffer(byte[] buffer, int start, int count)
{
int len = buffer.Length;
if (start < 0 || count < 0 || (start + count > len))
throw new IndexOutOfRangeException();
ByteBuffer buf = new ByteBuffer(buffer);
buf.position = start;
buf.length = start + count;
return buf;
}
*/