1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package net.sf.dexterim.oscar;
20
21 import net.sf.dexterim.oscar.entity.ByteBased;
22 import net.sf.dexterim.oscar.entity.DWord;
23 import net.sf.dexterim.oscar.entity.Word;
24
25
26 /***
27 * @author Christoph Walcher
28 */
29 class DynamicByteBuffer extends OscarByteBuffer {
30
31 private byte[] data;
32 private int position;
33 private int fill;
34
35 public DynamicByteBuffer() {
36 this(32);
37 }
38
39 public DynamicByteBuffer(int initialSize) {
40 this.data = new byte[initialSize];
41 this.position = 0;
42 this.fill = 0;
43 }
44
45 /***
46 * @param data
47 */
48 public DynamicByteBuffer(byte[] data) {
49 this.data = data;
50 this.position = 0;
51 this.fill = data.length;
52 }
53
54 /***
55 * @see net.sf.dexterim.oscar.OscarByteBuffer#position(int)
56 */
57 public int position(int position) {
58 if (position < 0 || position >= data.length) {
59 reallocateArray(position);
60 this.fill = position;
61 }
62
63 int oldPosition = this.position;
64 this.position = position;
65
66 return oldPosition;
67 }
68
69 /***
70 * @see net.sf.dexterim.oscar.OscarByteBuffer#position()
71 */
72 public int position() {
73 return position;
74 }
75
76 public int size() {
77 return data.length;
78 }
79
80 public int fill() {
81 return fill;
82 }
83
84 public int strip() {
85 return this.fill = position;
86 }
87
88 private void adjustFill() {
89 if (this.position > this.fill) {
90 this.fill = this.position;
91 }
92 }
93
94 /***
95 * @see net.sf.dexterim.oscar.OscarByteBuffer#getWord()
96 */
97 public Word getWord() {
98 Word returnValue = new Word(data[position], data[position+1]);
99
100 position+=returnValue.getLength();
101
102 return returnValue;
103 }
104
105 /***
106 * @see net.sf.dexterim.oscar.OscarByteBuffer#getDWord()
107 */
108 public DWord getDWord() {
109 byte[] targetArray = new byte[4];
110 System.arraycopy(data, position, targetArray, 0, targetArray.length);
111
112 position+=targetArray.length;
113 return new DWord(targetArray);
114 }
115
116 /***
117 * @see net.sf.dexterim.oscar.OscarByteBuffer#getByte()
118 */
119 public int getByte() {
120 return data[position++];
121 }
122
123 public OscarByteBuffer write(ByteBased source) {
124 if (position + source.getLength() > data.length) {
125 reallocateArray(data.length + source.getLength());
126 }
127
128 byte sourceArray[] = source.toByteArray();
129 System.arraycopy(sourceArray, 0, data, position, sourceArray.length);
130
131 position+=sourceArray.length;
132
133 adjustFill();
134
135 return this;
136 }
137
138 /*** Writes a OscarByteBuffer. Uses a single System.arraycopy call.
139 * @see net.sf.dexterim.oscar.OscarByteBuffer#write(net.sf.dexterim.oscar.OscarByteBuffer)
140 */
141 public OscarByteBuffer write(OscarByteBuffer buffer) {
142 byte[] source = buffer.slice();
143
144 if (position + source.length > data.length) {
145 reallocateArray(data.length + source.length);
146 }
147
148 System.arraycopy(source, 0, data, position, source.length);
149 position+=source.length;
150
151 adjustFill();
152
153 return this;
154 }
155
156 public OscarByteBuffer write(byte source) {
157 if (position + 1 > data.length) {
158 reallocateArray(data.length + 1);
159 }
160
161 data[position++] = source;
162
163 adjustFill();
164
165 return this;
166 }
167
168 /***
169 * @param i
170 */
171 private void reallocateArray(int newSize) {
172 byte newData[] = new byte[newSize];
173
174 System.arraycopy(this.data, 0, newData, 0, this.data.length);
175
176 this.data = newData;
177 }
178
179 /***
180 * @see net.sf.dexterim.oscar.OscarByteBuffer#array()
181 */
182 public byte[] array() {
183 return data;
184 }
185
186 /***
187 * Allocates a new Array with position entries and returns this new
188 * Array. Modifications done to return value will not be reflected in
189 * DynamicByteBuffer instance.
190 * @return new allocated array containing data up to position
191 */
192 public byte[] slice() {
193 byte slice[] = new byte[fill];
194
195 System.arraycopy(data, 0, slice, 0, position);
196
197 return slice;
198 }
199 }