1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.hadoop.hbase.hbql.io;
22
23 import org.apache.hadoop.hbase.hbql.client.HBqlException;
24 import org.apache.hadoop.hbase.hbql.mapping.FieldType;
25 import org.apache.hadoop.hbase.util.Bytes;
26
27 import java.io.ByteArrayInputStream;
28 import java.io.ByteArrayOutputStream;
29 import java.io.IOException;
30 import java.io.ObjectInputStream;
31 import java.io.ObjectOutputStream;
32 import java.io.Serializable;
33 import java.lang.reflect.Array;
34
35 public class HadoopSerialization extends Serialization {
36
37 private static final int arraysize = Bytes.SIZEOF_INT;
38
39 public Object getScalarFromBytes(final FieldType fieldType, final byte[] b) throws HBqlException {
40
41 if (b == null || b.length == 0)
42 return null;
43
44 try {
45 switch (fieldType) {
46
47 case BooleanType:
48 return Bytes.toBoolean(b);
49
50 case ByteType:
51 return b[0];
52
53 case CharType: {
54 final String s = Bytes.toString(b);
55 return s.charAt(0);
56 }
57
58 case ShortType:
59 return Bytes.toShort(b);
60
61 case IntegerType:
62 return Bytes.toInt(b);
63
64 case LongType:
65 return Bytes.toLong(b);
66
67 case FloatType:
68 return Bytes.toFloat(b);
69
70 case DoubleType:
71 return Bytes.toDouble(b);
72
73 case KeyType:
74 case StringType:
75 return Bytes.toString(b);
76
77 case DateType:
78 case ObjectType: {
79 final ByteArrayInputStream bais = new ByteArrayInputStream(b);
80 final ObjectInputStream ois = new ObjectInputStream(bais);
81 try {
82 return ois.readObject();
83 }
84 finally {
85 ois.close();
86 }
87 }
88
89 default:
90 throw new HBqlException("Unknown type in getScalarFromBytes() - " + fieldType);
91 }
92 }
93 catch (IOException e) {
94
95 throw new HBqlException(getExceptionMessage("getScalarFromBytes()", e));
96 }
97 catch (ClassNotFoundException e) {
98 throw new HBqlException(getExceptionMessage("getScalarFromBytes()", e));
99 }
100 }
101
102 public byte[] getScalarAsBytes(final FieldType fieldType, final Object obj) throws HBqlException {
103
104 if (obj == null)
105 return null;
106
107 try {
108 switch (fieldType) {
109
110 case BooleanType:
111 return Bytes.toBytes((Boolean)obj);
112
113 case ByteType: {
114 final byte[] retval = {((Byte)obj).byteValue()};
115 return retval;
116 }
117
118 case CharType: {
119 final String s = String.valueOf(obj);
120 return Bytes.toBytes(s);
121 }
122
123 case ShortType:
124 return Bytes.toBytes((Short)obj);
125
126 case IntegerType:
127 return Bytes.toBytes((Integer)obj);
128
129 case LongType:
130 return Bytes.toBytes((Long)obj);
131
132 case FloatType:
133 return Bytes.toBytes((Float)obj);
134
135 case DoubleType:
136 return Bytes.toBytes((Double)obj);
137
138 case KeyType:
139 case StringType:
140 return Bytes.toBytes((String)obj);
141
142 case DateType:
143 case ObjectType:
144 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
145 final ObjectOutputStream oos = new ObjectOutputStream(baos);
146 oos.writeObject((Serializable)obj);
147 oos.flush();
148 try {
149 return baos.toByteArray();
150 }
151 finally {
152 oos.close();
153 }
154
155 default:
156 throw new HBqlException("Unknown type in getScalarAsBytes() - " + fieldType);
157 }
158 }
159 catch (IOException e) {
160
161 throw new HBqlException(getExceptionMessage("getScalarAsBytes()", e));
162 }
163 }
164
165 public Object getArrayFromBytes(final FieldType fieldType, final Class clazz, final byte[] b) throws HBqlException {
166
167 if (b == null || b.length == 0)
168 return null;
169
170 try {
171 switch (fieldType) {
172
173 case BooleanType: {
174 final ByteArrayInputStream bais = new ByteArrayInputStream(b);
175 final ObjectInputStream ois = new ObjectInputStream(bais);
176 final int length = ois.readInt();
177 final Object array = Array.newInstance(clazz, length);
178 for (int i = 0; i < length; i++) {
179 Array.set(array, i, ois.readBoolean());
180 }
181 return array;
182 }
183
184 case ByteType: {
185 final int length = this.readLength(b);
186 int offset = arraysize;
187 final Object array = Array.newInstance(clazz, length);
188 for (int i = 0; i < length; i++) {
189 Array.set(array, i, b[offset]);
190 offset += fieldType.getSize();
191 }
192 return array;
193 }
194
195 case CharType: {
196 final String s = new String(b);
197 return s.toCharArray();
198 }
199
200 case ShortType: {
201 final int length = this.readLength(b);
202 int offset = arraysize;
203 final Object array = Array.newInstance(clazz, length);
204 for (int i = 0; i < length; i++) {
205 Array.set(array, i, Bytes.toShort(b, offset));
206 offset += fieldType.getSize();
207 }
208 return array;
209 }
210
211 case IntegerType: {
212 final int length = this.readLength(b);
213 int offset = arraysize;
214 final Object array = Array.newInstance(clazz, length);
215 for (int i = 0; i < length; i++) {
216 Array.set(array, i, Bytes.toInt(b, offset));
217 offset += fieldType.getSize();
218 }
219 return array;
220 }
221
222 case LongType: {
223 final int length = this.readLength(b);
224 int offset = arraysize;
225 final Object array = Array.newInstance(clazz, length);
226 for (int i = 0; i < length; i++) {
227 Array.set(array, i, Bytes.toLong(b, offset));
228 offset += fieldType.getSize();
229 }
230 return array;
231 }
232
233 case FloatType: {
234 final int length = this.readLength(b);
235 int offset = arraysize;
236 final Object array = Array.newInstance(clazz, length);
237 for (int i = 0; i < length; i++) {
238 final float val = Bytes.toFloat(b, offset);
239 Array.set(array, i, val);
240 offset += fieldType.getSize();
241 }
242 return array;
243 }
244
245 case DoubleType: {
246 final int length = this.readLength(b);
247 int offset = arraysize;
248 final Object array = Array.newInstance(clazz, length);
249 for (int i = 0; i < length; i++) {
250 final double val = Bytes.toDouble(b, offset);
251 Array.set(array, i, val);
252 offset += fieldType.getSize();
253 }
254 return array;
255 }
256
257 case StringType: {
258 final ByteArrayInputStream bais = new ByteArrayInputStream(b);
259 final ObjectInputStream ois = new ObjectInputStream(bais);
260 final int length = ois.readInt();
261 final Object array = Array.newInstance(clazz, length);
262 for (int i = 0; i < length; i++) {
263 Array.set(array, i, ois.readUTF());
264 }
265 return array;
266 }
267
268 case DateType:
269 case ObjectType: {
270 final ByteArrayInputStream bais = new ByteArrayInputStream(b);
271 final ObjectInputStream ois = new ObjectInputStream(bais);
272 try {
273 final int length = ois.readInt();
274 final Object array = Array.newInstance(clazz, length);
275 for (int i = 0; i < length; i++) {
276 Array.set(array, i, ois.readObject());
277 }
278 return array;
279 }
280 finally {
281 ois.close();
282 }
283 }
284
285 default:
286 throw new HBqlException("Unknown type in getArrayFromBytes() - " + fieldType);
287 }
288 }
289 catch (IOException e) {
290 throw new HBqlException(getExceptionMessage("getArrayFromBytes()", e));
291 }
292 catch (ClassNotFoundException e) {
293 throw new HBqlException(getExceptionMessage("getArrayFromBytes()", e));
294 }
295 }
296
297 public byte[] getArrayAsBytes(final FieldType fieldType, final Object obj) throws HBqlException {
298
299 if (obj == null)
300 return null;
301
302 try {
303 switch (fieldType) {
304
305 case BooleanType: {
306 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
307 final ObjectOutputStream oos = new ObjectOutputStream(baos);
308 oos.writeInt(((boolean[])obj).length);
309 for (final boolean val : (boolean[])obj) {
310 oos.writeBoolean(val);
311 }
312 oos.flush();
313 return baos.toByteArray();
314 }
315
316 case ByteType: {
317 final int length = ((byte[])obj).length;
318 final byte[] b = new byte[(length * fieldType.getSize()) + arraysize];
319 this.writeLength(b, length);
320 int offset = arraysize;
321 for (final byte val : (byte[])obj) {
322 Bytes.putByte(b, offset, val);
323 offset += fieldType.getSize();
324 }
325 return b;
326 }
327
328 case CharType: {
329 final String s = new String((char[])obj);
330 return Bytes.toBytes(s);
331 }
332
333 case ShortType: {
334 final int length = ((short[])obj).length;
335 final byte[] b = new byte[(length * fieldType.getSize()) + arraysize];
336 this.writeLength(b, length);
337 int offset = arraysize;
338 for (final short val : (short[])obj) {
339 Bytes.putShort(b, offset, val);
340 offset += fieldType.getSize();
341 }
342 return b;
343 }
344
345 case IntegerType: {
346 final int length = ((int[])obj).length;
347 final byte[] b = new byte[(length * fieldType.getSize()) + arraysize];
348 this.writeLength(b, length);
349 int offset = arraysize;
350 for (final int val : (int[])obj) {
351 Bytes.putInt(b, offset, val);
352 offset += fieldType.getSize();
353 }
354 return b;
355 }
356
357 case LongType: {
358 final int length = ((long[])obj).length;
359 final byte[] b = new byte[(length * fieldType.getSize()) + arraysize];
360 this.writeLength(b, length);
361 int offset = arraysize;
362 for (final long val : (long[])obj) {
363 Bytes.putLong(b, offset, val);
364 offset += fieldType.getSize();
365 }
366 return b;
367 }
368
369 case FloatType: {
370 final int length = ((float[])obj).length;
371 final byte[] b = new byte[(length * fieldType.getSize()) + arraysize];
372 this.writeLength(b, length);
373 int offset = arraysize;
374 for (final float val : (float[])obj) {
375 Bytes.putFloat(b, offset, val);
376 offset += fieldType.getSize();
377 }
378 return b;
379 }
380
381 case DoubleType: {
382 final int length = ((double[])obj).length;
383 final byte[] b = new byte[(length * fieldType.getSize()) + arraysize];
384 this.writeLength(b, length);
385 int offset = arraysize;
386 for (final double val : (double[])obj) {
387 Bytes.putDouble(b, offset, val);
388 offset += fieldType.getSize();
389 }
390 return b;
391 }
392
393 case StringType: {
394 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
395 final ObjectOutputStream oos = new ObjectOutputStream(baos);
396 oos.writeInt(((Object[])obj).length);
397 for (final String val : (String[])obj) {
398 oos.writeUTF(val);
399 }
400 oos.flush();
401 return baos.toByteArray();
402 }
403
404 case DateType:
405 case ObjectType: {
406 final ByteArrayOutputStream baos = new ByteArrayOutputStream();
407 final ObjectOutputStream oos = new ObjectOutputStream(baos);
408 oos.writeInt(((Object[])obj).length);
409 for (final Object val : (Object[])obj) {
410 oos.writeObject((Serializable)val);
411 }
412 oos.flush();
413 return baos.toByteArray();
414 }
415
416 default:
417 throw new HBqlException("Unknown type in getArrayAsBytes() - " + fieldType);
418 }
419 }
420 catch (IOException e) {
421 throw new HBqlException(getExceptionMessage("getArrayAsBytes()", e));
422 }
423 }
424
425 private int readLength(final byte[] b) {
426 return Bytes.toInt(b);
427 }
428
429 private void writeLength(final byte[] b, final int length) {
430 Bytes.putInt(b, 0, length);
431 }
432 }