1 module java.nio.ByteBuffer;
2 
3 //TODO: Always little endian.
4 struct ByteBuffer
5 {
6 public: //Variables.
7 	ubyte[] buffer;
8 	size_t position;
9 
10 public: //Methods.
11 	this(ubyte[] buffer)
12 	{
13 		this.buffer = buffer;
14 		this.limit_ = buffer.length;
15 	}
16 	
17 	this(ubyte[] buffer, size_t limit_, size_t position)
18 	{
19 		this.buffer = buffer;
20 		this.limit_ = limit_;
21 		this.position = position;
22 	}
23 	
24 	static ByteBuffer prepare(size_t size)
25 	{
26 		return ByteBuffer(null, size, 0);
27 	}
28 	
29 	ByteBuffer slice()
30 	{
31 		return ByteBuffer(buffer[position..limit]);
32 	}
33 	
34 	ubyte[] opSlice(size_t i, size_t j)
35 	{
36 		return buffer[i..j];
37 	}
38 	
39 	void limit(size_t newLimit)
40 	{
41 		limit_ = newLimit;
42 		if(position > limit_)
43 			position = limit_;
44 	}
45 	
46 	size_t limit() const
47 	{
48 		return limit_;
49 	}
50 	
51 	void rewind()
52 	{
53 		position = 0;
54 	}
55 	
56 	bool empty() const
57 	{
58 		return remaining == 0;
59 	}
60 	
61 	size_t remaining() const
62 	{
63 		if(position >= limit_)
64 			return 0;
65 		return limit_ - position;
66 	}
67 	
68 	size_t capacity() const
69 	{
70 		return buffer.length;
71 	}
72 	
73 	void clear()
74 	{
75 		position = 0;
76 		limit_ = capacity();
77 	}
78 	
79 	void put(T)(ref T src) if(is(T == ByteBuffer))
80 	{
81 		size_t n = src.remaining;
82 		//if(n > remaining())
83 		//	throw new Exception("Buffer overflow.");
84 		buffer[position..position+n] = src.buffer[src.position..src.position+n];
85 		src.position += n;
86 		position += n;
87 	}
88 	
89 	void put(T)(T src)
90 	{
91 		scope(exit) position += T.sizeof;
92 		put(position, src);
93 	}
94 	
95 	void put(T)(size_t pos, T src)
96 	{
97 		//if(remaining() == 0)
98 		//	throw new Exception("Buffer overflow.");
99 		buffer[pos..pos+T.sizeof] = (cast(ubyte*)&src)[0..T.sizeof];
100 	}
101 	
102 	void get(ref ubyte[] dst, size_t offset, size_t length)
103 	{
104 		//if(length > remaining())
105 		//	throw new Exception("Buffer underflow.");
106 		dst[offset..offset+length] = buffer[position..position+length];
107 		position += length;
108 	}
109 	
110 	T get(T)()
111 	{
112 		scope(exit) position += T.sizeof;
113 		return get!T(position);
114 	}
115 	
116 	T get(T)(size_t index) const
117 	{
118 		return *cast(T*)buffer[index..index+T.sizeof];
119 	}
120 
121 private: //Variables.
122 	size_t limit_;
123 }