001 /**
002 * GRANITE DATA SERVICES
003 * Copyright (C) 2006-2013 GRANITE DATA SERVICES S.A.S.
004 *
005 * This file is part of the Granite Data Services Platform.
006 *
007 * Granite Data Services is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * Granite Data Services is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
015 * General Public License for more details.
016 *
017 * You should have received a copy of the GNU Lesser General Public
018 * License along with this library; if not, write to the Free Software
019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
020 * USA, or see <http://www.gnu.org/licenses/>.
021 */
022 package org.granite.messaging.jmf.codec.std.impl;
023
024 import java.io.IOException;
025 import java.io.OutputStream;
026 import java.lang.reflect.Array;
027
028 import org.granite.messaging.jmf.CodecRegistry;
029 import org.granite.messaging.jmf.DumpContext;
030 import org.granite.messaging.jmf.InputContext;
031 import org.granite.messaging.jmf.JMFEncodingException;
032 import org.granite.messaging.jmf.OutputContext;
033 import org.granite.messaging.jmf.codec.StandardCodec;
034 import org.granite.messaging.jmf.codec.std.ArrayCodec;
035 import org.granite.messaging.jmf.codec.std.IntegerCodec;
036 import org.granite.messaging.jmf.codec.std.LongCodec;
037
038 /**
039 * @author Franck WOLFF
040 */
041 public class ArrayCodecImpl extends AbstractIntegerStringCodec<Object> implements ArrayCodec {
042
043 public int getObjectType() {
044 return JMF_ARRAY;
045 }
046
047 public boolean canEncode(Object v) {
048 return v.getClass().isArray();
049 }
050
051 public void encode(OutputContext ctx, Object v) throws IOException {
052 int dimensions = getArrayDimensions(v);
053 Class<?> componentType = getComponentType(v);
054
055 int jmfComponentType = ctx.getSharedContext().getCodecRegistry().jmfTypeOfPrimitiveClass(componentType);
056 if (jmfComponentType != -1)
057 writePrimitiveArray(ctx, v, jmfComponentType, dimensions, true);
058 else
059 writeObjectArray(ctx, v, dimensions, true);
060 }
061
062 public Object decode(InputContext ctx, int parameterizedJmfType) throws IOException, ClassNotFoundException {
063 final CodecRegistry codecRegistry = ctx.getSharedContext().getCodecRegistry();
064
065 int jmfType = codecRegistry.extractJmfType(parameterizedJmfType);
066
067 if (jmfType != JMF_ARRAY)
068 throw newBadTypeJMFEncodingException(jmfType, parameterizedJmfType);
069
070 Object v = null;
071
072 int indexOrLength = readIntData(ctx, (parameterizedJmfType >> 4) & 0x03, false);
073 if ((parameterizedJmfType & 0x80) != 0)
074 v = ctx.getSharedObject(indexOrLength);
075 else {
076 int dimensions = ((parameterizedJmfType & 0x40) == 0 ? 0 : ctx.safeRead());
077 int parameterizedJmfComponentType = ctx.safeRead();
078 int jmfComponentType = codecRegistry.extractJmfType(parameterizedJmfComponentType);
079
080 Class<?> componentType = codecRegistry.primitiveClassOfJmfType(jmfComponentType);
081
082 if (componentType != null)
083 v = readPrimitiveArray(ctx, componentType, jmfComponentType, indexOrLength, dimensions);
084 else
085 v = readObjectArray(ctx, parameterizedJmfComponentType, indexOrLength, dimensions);
086 }
087
088 return v;
089 }
090
091 public void dump(DumpContext ctx, int parameterizedJmfType) throws IOException {
092 final CodecRegistry codecRegistry = ctx.getSharedContext().getCodecRegistry();
093
094 int jmfType = codecRegistry.extractJmfType(parameterizedJmfType);
095
096 if (jmfType != JMF_ARRAY)
097 throw newBadTypeJMFEncodingException(jmfType, parameterizedJmfType);
098
099 int indexOrLength = readIntData(ctx, (parameterizedJmfType >> 4) & 0x03, false);
100 if ((parameterizedJmfType & 0x80) != 0)
101 ctx.indentPrintLn("<" + ctx.getSharedObject(indexOrLength) + "@" + indexOrLength + ">");
102 else {
103 int dimensions = ((parameterizedJmfType & 0x40) == 0 ? 0 : ctx.safeRead());
104 int parameterizedJmfComponentType = ctx.safeRead();
105 int jmfComponentType = codecRegistry.extractJmfType(parameterizedJmfComponentType);
106
107 Class<?> componentType = codecRegistry.primitiveClassOfJmfType(jmfComponentType);
108
109 if (componentType != null)
110 dumpPrimitiveArray(ctx, componentType, jmfComponentType, indexOrLength, dimensions);
111 else
112 dumpObjectArray(ctx, parameterizedJmfComponentType, indexOrLength, dimensions);
113 }
114 }
115
116 protected void writeObjectArray(OutputContext ctx, Object v, int dimensions, boolean writeDimensions) throws IOException {
117 final OutputStream os = ctx.getOutputStream();
118
119 if (v == null)
120 os.write(JMF_NULL);
121 else {
122 int indexOfStoredObject = ctx.indexOfStoredObjects(v);
123 if (indexOfStoredObject >= 0) {
124 IntegerComponents ics = intComponents(indexOfStoredObject);
125 ctx.getOutputStream().write(0x80 | (ics.length << 4) | JMF_ARRAY);
126 writeIntData(ctx, ics);
127 }
128 else {
129 ctx.addToStoredObjects(v);
130
131 if (dimensions == 0)
132 writeObjectArray(ctx, v);
133 else {
134 int length = Array.getLength(v);
135
136 IntegerComponents ics = intComponents(length);
137 if (writeDimensions) {
138 os.write(0x40 | (ics.length << 4) | JMF_ARRAY);
139 writeIntData(ctx, ics);
140 os.write(dimensions);
141 }
142 else {
143 os.write((ics.length << 4) | JMF_ARRAY);
144 writeIntData(ctx, ics);
145 }
146
147 Class<?> componentType = getComponentType(v);
148 String className = ctx.getAlias(componentType.getName());
149 writeString(ctx, className, JMF_STRING_TYPE_HANDLER);
150
151 int subDimensions = dimensions - 1;
152 for (int index = 0; index < length; index++)
153 writeObjectArray(ctx, Array.get(v, index), subDimensions, false);
154 }
155 }
156 }
157 }
158
159 protected void writeObjectArray(OutputContext ctx, Object v) throws IOException {
160 final OutputStream os = ctx.getOutputStream();
161
162 int length = Array.getLength(v);
163 Class<?> componentType = v.getClass().getComponentType();
164 String className = ctx.getAlias(componentType.getName());
165
166 IntegerComponents ics = intComponents(length);
167 os.write((ics.length << 4) | JMF_ARRAY);
168 writeIntData(ctx, ics);
169
170 writeString(ctx, className, JMF_STRING_TYPE_HANDLER);
171 for (int index = 0; index < length; index++)
172 ctx.writeObject(Array.get(v, index));
173 }
174
175 protected void writePrimitiveArray(OutputContext ctx, Object v, int jmfComponentType, int dimensions, boolean writeDimensionsAndType) throws IOException {
176 final OutputStream os = ctx.getOutputStream();
177
178 if (v == null)
179 os.write(JMF_NULL);
180 else {
181 int indexOfStoredObject = ctx.indexOfStoredObjects(v);
182 if (indexOfStoredObject >= 0) {
183 IntegerComponents ics = intComponents(indexOfStoredObject);
184 ctx.getOutputStream().write(0x80 | (ics.length << 4) | JMF_ARRAY);
185 writeIntData(ctx, ics);
186 }
187 else {
188 ctx.addToStoredObjects(v);
189 if (dimensions == 0)
190 writePrimitiveArray(ctx, v, jmfComponentType, writeDimensionsAndType);
191 else {
192 int length = Array.getLength(v);
193
194 IntegerComponents ics = intComponents(length);
195 if (writeDimensionsAndType) {
196 os.write(0x40 | (ics.length << 4) | JMF_ARRAY);
197 writeIntData(ctx, ics);
198 os.write(dimensions);
199 os.write(jmfComponentType);
200 }
201 else {
202 os.write((ics.length << 4) | JMF_ARRAY);
203 writeIntData(ctx, ics);
204 }
205
206 int subDimensions = dimensions - 1;
207 for (int index = 0; index < length; index++)
208 writePrimitiveArray(ctx, Array.get(v, index), jmfComponentType, subDimensions, false);
209 }
210 }
211 }
212 }
213
214 protected void writePrimitiveArray(OutputContext ctx, Object v, int jmfComponentType, boolean writeType) throws IOException {
215 final OutputStream os = ctx.getOutputStream();
216
217 final int length = Array.getLength(v);
218
219 IntegerComponents ics = intComponents(length);
220 os.write((ics.length << 4) | JMF_ARRAY);
221 writeIntData(ctx, ics);
222
223 if (writeType)
224 os.write(jmfComponentType);
225
226 if (length == 0)
227 return;
228
229 switch (jmfComponentType) {
230 case JMF_BOOLEAN: {
231 byte[] bytes = new byte[lengthOfBooleanArray(length)];
232 int i = 0, j = 0;
233 for (boolean b : (boolean[])v) {
234 if (b)
235 bytes[i] |= 0x80 >> j;
236 j++;
237 if (j >= 8) {
238 j = 0;
239 i++;
240 }
241 }
242 os.write(bytes);
243 break;
244 }
245
246 case JMF_CHARACTER: {
247 char[] a = (char[])v;
248 for (char c : a) {
249 os.write(c >> 8);
250 os.write(c);
251 }
252 break;
253 }
254
255 case JMF_BYTE: {
256 os.write((byte[])v);
257 break;
258 }
259
260 case JMF_SHORT: {
261 short[] a = (short[])v;
262 for (short s : a) {
263 os.write(s >> 8);
264 os.write(s);
265 }
266 break;
267 }
268
269 case JMF_INTEGER: {
270 IntegerCodec integerCodec = ctx.getSharedContext().getCodecRegistry().getIntegerCodec();
271 int[] a = (int[])v;
272 for (int i : a)
273 integerCodec.writeVariableInt(ctx, i);
274 break;
275 }
276
277 case JMF_LONG: {
278 LongCodec longCodec = ctx.getSharedContext().getCodecRegistry().getLongCodec();
279 long[] a = (long[])v;
280 for (long l : a)
281 longCodec.writeVariableLong(ctx, l);
282 break;
283 }
284
285 case JMF_FLOAT: {
286 float[] a = (float[])v;
287 for (float f : a) {
288 int bits = Float.floatToIntBits(f);
289 os.write(bits);
290 os.write(bits >> 8);
291 os.write(bits >> 16);
292 os.write(bits >> 24);
293 }
294 break;
295 }
296
297 case JMF_DOUBLE: {
298 double[] a = (double[])v;
299 for (double d : a) {
300 long bits = Double.doubleToLongBits(d);
301 os.write((int)bits);
302 os.write((int)(bits >> 8));
303 os.write((int)(bits >> 16));
304 os.write((int)(bits >> 24));
305 os.write((int)(bits >> 32));
306 os.write((int)(bits >> 40));
307 os.write((int)(bits >> 48));
308 os.write((int)(bits >> 56));
309 }
310 break;
311 }
312
313 default:
314 throw new JMFEncodingException("Unsupported primitive type: " + jmfComponentType);
315 }
316 }
317
318 protected int getArrayDimensions(Object v) {
319 return v.getClass().getName().lastIndexOf('[');
320 }
321
322 protected Class<?> getComponentType(Object v) {
323 Class<?> componentType = v.getClass().getComponentType();
324 while (componentType.isArray())
325 componentType = componentType.getComponentType();
326 return componentType;
327 }
328
329 protected Object readObjectArray(InputContext ctx, int parameterizedJmfComponentType, int length, int dimensions) throws IOException, ClassNotFoundException {
330 Object v = null;
331
332 String componentTypeName = readString(ctx, parameterizedJmfComponentType, JMF_STRING_TYPE_HANDLER);
333 componentTypeName = ctx.getAlias(componentTypeName);
334 Class<?> componentType = ctx.getSharedContext().getReflection().loadClass(componentTypeName);
335
336 if (dimensions == 0)
337 v = readObjectArray(ctx, componentType, length);
338 else {
339 v = newArray(componentType, length, dimensions);
340 ctx.addSharedObject(v);
341
342 int subDimensions = dimensions - 1;
343 for (int index = 0; index < length; index++) {
344 int subParameterizedJmfType = ctx.safeRead();
345 int subJmfType = ctx.getSharedContext().getCodecRegistry().extractJmfType(subParameterizedJmfType);
346
347 if (subJmfType == JMF_NULL)
348 Array.set(v, index, null);
349 else if (subJmfType == JMF_ARRAY) {
350 int subLengthOrIndex = readIntData(ctx, (subParameterizedJmfType >> 4) & 0x03, false);
351 if ((subParameterizedJmfType & 0x80) != 0)
352 Array.set(v, index, ctx.getSharedObject(subLengthOrIndex));
353 else {
354 int subParameterizedJmfComponentType = ctx.safeRead();
355 Array.set(v, index, readObjectArray(ctx, subParameterizedJmfComponentType, subLengthOrIndex, subDimensions));
356 }
357 }
358 else
359 newBadTypeJMFEncodingException(subJmfType, subParameterizedJmfType);
360 }
361 }
362
363 return v;
364 }
365
366 protected void dumpObjectArray(DumpContext ctx, int parameterizedJmfComponentType, int length, int dimensions) throws IOException {
367 String componentTypeName = readString(ctx, parameterizedJmfComponentType, JMF_STRING_TYPE_HANDLER);
368
369 if (dimensions == 0)
370 dumpObjectArray(ctx, componentTypeName, length);
371 else {
372 String v = newDumpObjectArray(componentTypeName, length, dimensions);
373 int indexOfStoredObject = ctx.addSharedObject(v);
374 ctx.indentPrintLn(v + "@" + indexOfStoredObject + ": {");
375 ctx.incrIndent(1);
376
377 int subDimensions = dimensions - 1;
378 for (int index = 0; index < length; index++) {
379 int subParameterizedJmfType = ctx.safeRead();
380 int subJmfType = ctx.getSharedContext().getCodecRegistry().extractJmfType(subParameterizedJmfType);
381
382 if (subJmfType == JMF_NULL)
383 ctx.indentPrintLn("null");
384 else if (subJmfType == JMF_ARRAY) {
385 int subLengthOrIndex = readIntData(ctx, (subParameterizedJmfType >> 4) & 0x03, false);
386 if ((subParameterizedJmfType & 0x80) != 0)
387 ctx.indentPrintLn("<" + ctx.getSharedObject(subLengthOrIndex) + "@" + subLengthOrIndex + ">");
388 else {
389 int subParameterizedJmfComponentType = ctx.safeRead();
390 dumpObjectArray(ctx, subParameterizedJmfComponentType, subLengthOrIndex, subDimensions);
391 }
392 }
393 else
394 newBadTypeJMFEncodingException(subJmfType, subParameterizedJmfType);
395 }
396
397 ctx.incrIndent(-1);
398 ctx.indentPrintLn("}");
399 }
400 }
401
402 protected Object readObjectArray(InputContext ctx, Class<?> componentType, int length) throws IOException, ClassNotFoundException {
403 Object v = Array.newInstance(componentType, length);
404 ctx.addSharedObject(v);
405
406 for (int index = 0; index < length; index++)
407 Array.set(v, index, ctx.readObject());
408
409 return v;
410 }
411
412 protected void dumpObjectArray(DumpContext ctx, String componentTypeName, int length) throws IOException {
413 String v = newDumpObjectArray(componentTypeName, length, 0);
414 int indexOfStoredObject = ctx.addSharedObject(v);
415 ctx.indentPrintLn(v + "@" + indexOfStoredObject + ": {");
416 ctx.incrIndent(1);
417
418 for (int index = 0; index < length; index++) {
419 int parameterizedJmfType = ctx.safeRead();
420 int jmfType = ctx.getSharedContext().getCodecRegistry().extractJmfType(parameterizedJmfType);
421 StandardCodec<?> codec = ctx.getSharedContext().getCodecRegistry().getCodec(jmfType);
422
423 if (codec == null)
424 throw new JMFEncodingException("No codec for JMF type: " + jmfType);
425
426 codec.dump(ctx, parameterizedJmfType);
427 }
428
429 ctx.incrIndent(-1);
430 ctx.indentPrintLn("}");
431 }
432
433 protected String newDumpObjectArray(String componentTypeName, int length, int dimensions) {
434 StringBuilder sb = new StringBuilder(componentTypeName);
435
436 sb.append('[').append(length).append(']');
437
438 for (int i = 0; i < dimensions; i++)
439 sb.append("[]");
440
441 return sb.toString();
442
443 }
444
445 protected Object readPrimitiveArray(InputContext ctx, Class<?> componentType, int jmfComponentType, int length, int dimensions) throws IOException {
446 Object v = null;
447
448 if (dimensions == 0)
449 v = readPrimitiveArray(ctx, componentType, jmfComponentType, length);
450 else {
451 v = newArray(componentType, length, dimensions);
452 ctx.addSharedObject(v);
453
454 int subDimensions = dimensions - 1;
455 for (int index = 0; index < length; index++) {
456 int subArrayJmfType = ctx.safeRead();
457 if (subArrayJmfType == JMF_NULL)
458 Array.set(v, index, null);
459 else {
460 int subLengthOrIndex = readIntData(ctx, (subArrayJmfType >> 4) & 0x03, false);
461 if ((subArrayJmfType & 0x80) != 0)
462 Array.set(v, index, ctx.getSharedObject(subLengthOrIndex));
463 else
464 Array.set(v, index, readPrimitiveArray(ctx, componentType, jmfComponentType, subLengthOrIndex, subDimensions));
465 }
466 }
467 }
468
469 return v;
470 }
471
472 protected void dumpPrimitiveArray(DumpContext ctx, Class<?> componentType, int jmfComponentType, int length, int dimensions) throws IOException {
473 if (dimensions == 0)
474 dumpPrimitiveArray(ctx, componentType, jmfComponentType, length);
475 else {
476 String v = newDumpPrimitiveArray(jmfComponentType, length, dimensions);
477 int indexOfStoredObject = ctx.addSharedObject(v);
478 ctx.indentPrintLn(v + "@" + indexOfStoredObject + ": {");
479 ctx.incrIndent(1);
480
481 int subDimensions = dimensions - 1;
482 for (int index = 0; index < length; index++) {
483 int subArrayJmfType = ctx.safeRead();
484 if (subArrayJmfType == JMF_NULL)
485 ctx.indentPrintLn("null");
486 else {
487 int subLengthOrIndex = readIntData(ctx, (subArrayJmfType >> 4) & 0x03, false);
488 if ((subArrayJmfType & 0x80) != 0)
489 ctx.indentPrintLn("<" + ctx.getSharedObject(subLengthOrIndex) + "@" + subLengthOrIndex + ">");
490 else
491 dumpPrimitiveArray(ctx, componentType, jmfComponentType, subLengthOrIndex, subDimensions);
492 }
493 }
494
495 ctx.incrIndent(-1);
496 ctx.indentPrintLn("}");
497 }
498 }
499
500 protected Object readPrimitiveArray(InputContext ctx, Class<?> componentType, int jmfComponentType, int length) throws IOException {
501 Object v = null;
502
503 if (length == 0)
504 v = Array.newInstance(componentType, length);
505 else {
506 switch (jmfComponentType) {
507 case JMF_BOOLEAN: {
508 boolean[] a = new boolean[length];
509 int nb = lengthOfBooleanArray(length);
510 for (int i = 0; i < nb; i++) {
511 int b = ctx.safeRead();
512 for (int j = 0; j < 8; j++) {
513 int index = (i * 8) + j;
514 if (index >= length)
515 break;
516 a[index] = ((b & (0x80 >> j)) != 0);
517 }
518 }
519 v = a;
520 break;
521 }
522
523 case JMF_CHARACTER: {
524 char[] a = new char[length];
525 for (int i = 0; i < length; i++)
526 a[i] = (char)((ctx.safeRead() << 8) | ctx.safeRead());
527 v = a;
528 break;
529 }
530
531 case JMF_BYTE: {
532 byte[] a = new byte[length];
533 ctx.safeReadFully(a);
534 v = a;
535 break;
536 }
537
538 case JMF_SHORT: {
539 short[] a = new short[length];
540 for (int i = 0; i < length; i++)
541 a[i] = (short)((ctx.safeRead() << 8) | ctx.safeRead());
542 v = a;
543 break;
544 }
545
546 case JMF_INTEGER: {
547 IntegerCodec integerCodec = ctx.getSharedContext().getCodecRegistry().getIntegerCodec();
548 int[] a = new int[length];
549 for (int i = 0; i < length; i++)
550 a[i] = integerCodec.readVariableInt(ctx);
551 v = a;
552 break;
553 }
554
555 case JMF_LONG: {
556 LongCodec longCodec = ctx.getSharedContext().getCodecRegistry().getLongCodec();
557 long[] a = new long[length];
558 for (int i = 0; i < length; i++)
559 a[i] = longCodec.readVariableLong(ctx);
560 v = a;
561 break;
562 }
563
564 case JMF_FLOAT: {
565 float[] a = new float[length];
566 for (int i = 0; i < length; i++) {
567 int bits = ctx.safeRead();
568 bits |= ctx.safeRead() << 8;
569 bits |= ctx.safeRead() << 16;
570 bits |= ctx.safeRead() << 24;
571 a[i] = Float.intBitsToFloat(bits);
572 }
573 v = a;
574 break;
575 }
576
577 case JMF_DOUBLE: {
578 double[] a = new double[length];
579 for (int i = 0; i < length; i++) {
580 long bits = ctx.safeRead();
581 bits |= ((long)ctx.safeRead()) << 8;
582 bits |= ((long)ctx.safeRead()) << 16;
583 bits |= ((long)ctx.safeRead()) << 24;
584 bits |= ((long)ctx.safeRead()) << 32;
585 bits |= ((long)ctx.safeRead()) << 40;
586 bits |= ((long)ctx.safeRead()) << 48;
587 bits |= ((long)ctx.safeRead()) << 56;
588 a[i] = Double.longBitsToDouble(bits);
589 }
590 v = a;
591 break;
592 }
593
594 default:
595 throw new JMFEncodingException("Unsupported primitive type: " + jmfComponentType);
596 }
597 }
598
599 ctx.addSharedObject(v);
600
601 return v;
602 }
603
604 protected void dumpPrimitiveArray(DumpContext ctx, Class<?> componentType, int jmfComponentType, int length) throws IOException {
605
606 String v = newDumpPrimitiveArray(jmfComponentType, length, 0);
607 int indexOfStoredObject = ctx.addSharedObject(v);
608 ctx.indentPrint(v + "@" + indexOfStoredObject + ": {");
609
610 switch (jmfComponentType) {
611 case JMF_BOOLEAN: {
612 int nb = lengthOfBooleanArray(length);
613 for (int i = 0; i < nb; i++) {
614 int b = ctx.safeRead();
615 for (int j = 0; j < 8; j++) {
616 int index = (i * 8) + j;
617 if (index >= length)
618 break;
619 if (index > 0)
620 ctx.print(", ");
621 ctx.print(String.valueOf(((b & (0x80 >> j)) != 0)));
622 }
623 }
624 break;
625 }
626
627 case JMF_CHARACTER: {
628 for (int i = 0; i < length; i++) {
629 if (i > 0)
630 ctx.print(", ");
631 ctx.print(String.valueOf((char)((ctx.safeRead() << 8) | ctx.safeRead())));
632 }
633 break;
634 }
635
636 case JMF_BYTE: {
637 for (int i = 0; i < length; i++) {
638 if (i > 0)
639 ctx.print(", ");
640 ctx.print(String.valueOf((byte)ctx.safeRead()));
641 }
642 break;
643 }
644
645 case JMF_SHORT: {
646 for (int i = 0; i < length; i++) {
647 if (i > 0)
648 ctx.print(", ");
649 ctx.print(String.valueOf((short)(ctx.safeRead() << 8) | ctx.safeRead()));
650 }
651 break;
652 }
653
654 case JMF_INTEGER: {
655 IntegerCodec integerCodec = ctx.getSharedContext().getCodecRegistry().getIntegerCodec();
656 for (int i = 0; i < length; i++) {
657 if (i > 0)
658 ctx.print(", ");
659 ctx.print(String.valueOf(integerCodec.readVariableInt(ctx)));
660 }
661 break;
662 }
663
664 case JMF_LONG: {
665 LongCodec longCodec = ctx.getSharedContext().getCodecRegistry().getLongCodec();
666 for (int i = 0; i < length; i++) {
667 if (i > 0)
668 ctx.print(", ");
669 ctx.print(String.valueOf(longCodec.readVariableLong(ctx)));
670 }
671 break;
672 }
673
674 case JMF_FLOAT: {
675 for (int i = 0; i < length; i++) {
676 if (i > 0)
677 ctx.print(", ");
678 ctx.print(String.valueOf(FloatCodecImpl.readFloatData(ctx, jmfComponentType)));
679 }
680 break;
681 }
682
683 case JMF_DOUBLE: {
684 for (int i = 0; i < length; i++) {
685 if (i > 0)
686 ctx.print(", ");
687 ctx.print(String.valueOf(DoubleCodecImpl.readDoubleData(ctx, jmfComponentType)));
688 }
689 break;
690 }
691
692 default:
693 throw new JMFEncodingException("Unsupported primitive type: " + jmfComponentType);
694 }
695
696 ctx.noIndentPrintLn("}");
697 }
698
699 protected String newDumpPrimitiveArray(int jmfComponentType, int length, int dimensions) throws IOException {
700 StringBuilder sb = new StringBuilder();
701
702 switch (jmfComponentType) {
703 case JMF_BOOLEAN: sb.append("boolean"); break;
704 case JMF_CHARACTER: sb.append("char"); break;
705 case JMF_BYTE: sb.append("byte"); break;
706 case JMF_SHORT: sb.append("short"); break;
707 case JMF_INTEGER: sb.append("int"); break;
708 case JMF_LONG: sb.append("long"); break;
709 case JMF_FLOAT: sb.append("float"); break;
710 case JMF_DOUBLE: sb.append("double"); break;
711 default: throw new JMFEncodingException("Unsupported primitive type: " + jmfComponentType);
712 }
713
714 sb.append('[').append(length).append(']');
715
716 for (int i = 0; i < dimensions; i++)
717 sb.append("[]");
718
719 return sb.toString();
720 }
721
722 protected Object newArray(Class<?> type, int length, int dimensions) {
723 int[] ld = new int[dimensions + 1];
724 ld[0] = length;
725 return Array.newInstance(type, ld);
726 }
727
728 protected int lengthOfBooleanArray(int nb) {
729 return (nb / 8) + (nb % 8 != 0 ? 1 : 0);
730 }
731 }