1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package com.healthmarketscience.jackcess.impl;
18
19 import java.nio.ByteBuffer;
20 import java.util.ArrayList;
21 import java.util.List;
22
23
24
25
26
27
28
29
30
31
32 public class ByteArrayBuilder
33 {
34 private int _pos;
35 private final List<Data> _data = new ArrayList<Data>();
36
37 public ByteArrayBuilder() {
38 }
39
40 public int position() {
41 return _pos;
42 }
43
44 public ByteArrayBuilder reserveInt() {
45 return reserve(4);
46 }
47
48 public ByteArrayBuilder reserveShort() {
49 return reserve(2);
50 }
51
52 public ByteArrayBuilder reserve(int bytes) {
53 _pos += bytes;
54 return this;
55 }
56
57 public ByteArrayBuilder put(byte val) {
58 return put(new ByteData(_pos, val));
59 }
60
61 public ByteArrayBuilder putInt(int val) {
62 return putInt(_pos, val);
63 }
64
65 public ByteArrayBuilder putInt(int pos, int val) {
66 return put(new IntData(pos, val));
67 }
68
69 public ByteArrayBuilder putShort(short val) {
70 return putShort(_pos, val);
71 }
72
73 public ByteArrayBuilder putShort(int pos, short val) {
74 return put(new ShortData(pos, val));
75 }
76
77 public ByteArrayBuilder put(byte[] val) {
78 return put(new BytesData(_pos, val));
79 }
80
81 public ByteArrayBuilder put(ByteBuffer val) {
82 return put(new BufData(_pos, val));
83 }
84
85 private ByteArrayBuilder put(Data data) {
86 _data.add(data);
87 int endPos = data.getEndPos();
88 if(endPos > _pos) {
89 _pos = endPos;
90 }
91 return this;
92 }
93
94 public ByteBuffer toBuffer() {
95 return toBuffer(PageChannel.wrap(new byte[_pos]));
96 }
97
98 public ByteBuffer toBuffer(ByteBuffer buf) {
99 for(Data data : _data) {
100 data.write(buf);
101 }
102 buf.rewind();
103 return buf;
104 }
105
106 public byte[] toArray() {
107 return toBuffer().array();
108 }
109
110 private static abstract class Data
111 {
112 private int _pos;
113
114 protected Data(int pos) {
115 _pos = pos;
116 }
117
118 public int getPos() {
119 return _pos;
120 }
121
122 public int getEndPos() {
123 return getPos() + size();
124 }
125
126 public abstract int size();
127
128 public abstract void write(ByteBuffer buf);
129 }
130
131 private static final class IntData extends Data
132 {
133 private final int _val;
134
135 private IntData(int pos, int val) {
136 super(pos);
137 _val = val;
138 }
139
140 @Override
141 public int size() {
142 return 4;
143 }
144
145 @Override
146 public void write(ByteBuffer buf) {
147 buf.putInt(getPos(), _val);
148 }
149 }
150
151 private static final class ShortData extends Data
152 {
153 private final short _val;
154
155 private ShortData(int pos, short val) {
156 super(pos);
157 _val = val;
158 }
159
160 @Override
161 public int size() {
162 return 2;
163 }
164
165 @Override
166 public void write(ByteBuffer buf) {
167 buf.putShort(getPos(), _val);
168 }
169 }
170
171 private static final class ByteData extends Data
172 {
173 private final byte _val;
174
175 private ByteData(int pos, byte val) {
176 super(pos);
177 _val = val;
178 }
179
180 @Override
181 public int size() {
182 return 1;
183 }
184
185 @Override
186 public void write(ByteBuffer buf) {
187 buf.put(getPos(), _val);
188 }
189 }
190
191 private static final class BytesData extends Data
192 {
193 private final byte[] _val;
194
195 private BytesData(int pos, byte[] val) {
196 super(pos);
197 _val = val;
198 }
199
200 @Override
201 public int size() {
202 return _val.length;
203 }
204
205 @Override
206 public void write(ByteBuffer buf) {
207 buf.position(getPos());
208 buf.put(_val);
209 }
210 }
211
212 private static final class BufData extends Data
213 {
214 private final ByteBuffer _val;
215
216 private BufData(int pos, ByteBuffer val) {
217 super(pos);
218 _val = val;
219 }
220
221 @Override
222 public int size() {
223 return _val.remaining();
224 }
225
226 @Override
227 public void write(ByteBuffer buf) {
228 buf.position(getPos());
229 buf.put(_val);
230 }
231 }
232 }