001/* 002 GRANITE DATA SERVICES 003 Copyright (C) 2013 GRANITE DATA SERVICES S.A.S. 004 005 This file is part of Granite Data Services. 006 007 Granite Data Services is free software; you can redistribute it and/or modify 008 it under the terms of the GNU Library General Public License as published by 009 the Free Software Foundation; either version 2 of the License, or (at your 010 option) any later version. 011 012 Granite Data Services is distributed in the hope that it will be useful, but 013 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 014 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License 015 for more details. 016 017 You should have received a copy of the GNU Library General Public License 018 along with this library; if not, see <http://www.gnu.org/licenses/>. 019*/ 020 021package org.granite.messaging.jmf.codec.std.impl; 022 023import java.io.IOException; 024import java.io.OutputStream; 025import java.lang.reflect.Array; 026 027import org.granite.messaging.jmf.CodecRegistry; 028import org.granite.messaging.jmf.DumpContext; 029import org.granite.messaging.jmf.InputContext; 030import org.granite.messaging.jmf.JMFEncodingException; 031import org.granite.messaging.jmf.OutputContext; 032import org.granite.messaging.jmf.codec.StandardCodec; 033import org.granite.messaging.jmf.codec.std.ArrayCodec; 034import org.granite.messaging.jmf.codec.std.IntegerCodec; 035import org.granite.messaging.jmf.codec.std.LongCodec; 036 037/** 038 * @author Franck WOLFF 039 */ 040public class ArrayCodecImpl extends AbstractIntegerStringCodec<Object> implements ArrayCodec { 041 042 public int getObjectType() { 043 return JMF_ARRAY; 044 } 045 046 public boolean canEncode(Object v) { 047 return v.getClass().isArray(); 048 } 049 050 public void encode(OutputContext ctx, Object v) throws IOException { 051 int dimensions = getArrayDimensions(v); 052 Class<?> componentType = getComponentType(v); 053 054 int jmfComponentType = ctx.getSharedContext().getCodecRegistry().jmfTypeOfPrimitiveClass(componentType); 055 if (jmfComponentType != -1) 056 writePrimitiveArray(ctx, v, jmfComponentType, dimensions, true); 057 else 058 writeObjectArray(ctx, v, dimensions, true); 059 } 060 061 public Object decode(InputContext ctx, int parameterizedJmfType) throws IOException, ClassNotFoundException { 062 final CodecRegistry codecRegistry = ctx.getSharedContext().getCodecRegistry(); 063 064 int jmfType = codecRegistry.extractJmfType(parameterizedJmfType); 065 066 if (jmfType != JMF_ARRAY) 067 throw newBadTypeJMFEncodingException(jmfType, parameterizedJmfType); 068 069 Object v = null; 070 071 int indexOrLength = readIntData(ctx, (parameterizedJmfType >> 4) & 0x03, false); 072 if ((parameterizedJmfType & 0x80) != 0) 073 v = ctx.getSharedObject(indexOrLength); 074 else { 075 int dimensions = ((parameterizedJmfType & 0x40) == 0 ? 0 : ctx.safeRead()); 076 int parameterizedJmfComponentType = ctx.safeRead(); 077 int jmfComponentType = codecRegistry.extractJmfType(parameterizedJmfComponentType); 078 079 Class<?> componentType = codecRegistry.primitiveClassOfJmfType(jmfComponentType); 080 081 if (componentType != null) 082 v = readPrimitiveArray(ctx, componentType, jmfComponentType, indexOrLength, dimensions); 083 else 084 v = readObjectArray(ctx, parameterizedJmfComponentType, indexOrLength, dimensions); 085 } 086 087 return v; 088 } 089 090 public void dump(DumpContext ctx, int parameterizedJmfType) throws IOException { 091 final CodecRegistry codecRegistry = ctx.getSharedContext().getCodecRegistry(); 092 093 int jmfType = codecRegistry.extractJmfType(parameterizedJmfType); 094 095 if (jmfType != JMF_ARRAY) 096 throw newBadTypeJMFEncodingException(jmfType, parameterizedJmfType); 097 098 int indexOrLength = readIntData(ctx, (parameterizedJmfType >> 4) & 0x03, false); 099 if ((parameterizedJmfType & 0x80) != 0) 100 ctx.indentPrintLn("<" + ctx.getSharedObject(indexOrLength) + "@" + indexOrLength + ">"); 101 else { 102 int dimensions = ((parameterizedJmfType & 0x40) == 0 ? 0 : ctx.safeRead()); 103 int parameterizedJmfComponentType = ctx.safeRead(); 104 int jmfComponentType = codecRegistry.extractJmfType(parameterizedJmfComponentType); 105 106 Class<?> componentType = codecRegistry.primitiveClassOfJmfType(jmfComponentType); 107 108 if (componentType != null) 109 dumpPrimitiveArray(ctx, componentType, jmfComponentType, indexOrLength, dimensions); 110 else 111 dumpObjectArray(ctx, parameterizedJmfComponentType, indexOrLength, dimensions); 112 } 113 } 114 115 protected void writeObjectArray(OutputContext ctx, Object v, int dimensions, boolean writeDimensions) throws IOException { 116 final OutputStream os = ctx.getOutputStream(); 117 118 if (v == null) 119 os.write(JMF_NULL); 120 else { 121 int indexOfStoredObject = ctx.indexOfStoredObjects(v); 122 if (indexOfStoredObject >= 0) { 123 IntegerComponents ics = intComponents(indexOfStoredObject); 124 ctx.getOutputStream().write(0x80 | (ics.length << 4) | JMF_ARRAY); 125 writeIntData(ctx, ics); 126 } 127 else { 128 ctx.addToStoredObjects(v); 129 130 if (dimensions == 0) 131 writeObjectArray(ctx, v); 132 else { 133 int length = Array.getLength(v); 134 135 IntegerComponents ics = intComponents(length); 136 if (writeDimensions) { 137 os.write(0x40 | (ics.length << 4) | JMF_ARRAY); 138 writeIntData(ctx, ics); 139 os.write(dimensions); 140 } 141 else { 142 os.write((ics.length << 4) | JMF_ARRAY); 143 writeIntData(ctx, ics); 144 } 145 146 Class<?> componentType = getComponentType(v); 147 String className = ctx.getAlias(componentType.getName()); 148 writeString(ctx, className, JMF_STRING_TYPE_HANDLER); 149 150 int subDimensions = dimensions - 1; 151 for (int index = 0; index < length; index++) 152 writeObjectArray(ctx, Array.get(v, index), subDimensions, false); 153 } 154 } 155 } 156 } 157 158 protected void writeObjectArray(OutputContext ctx, Object v) throws IOException { 159 final OutputStream os = ctx.getOutputStream(); 160 161 int length = Array.getLength(v); 162 Class<?> componentType = v.getClass().getComponentType(); 163 String className = ctx.getAlias(componentType.getName()); 164 165 IntegerComponents ics = intComponents(length); 166 os.write((ics.length << 4) | JMF_ARRAY); 167 writeIntData(ctx, ics); 168 169 writeString(ctx, className, JMF_STRING_TYPE_HANDLER); 170 for (int index = 0; index < length; index++) 171 ctx.writeObject(Array.get(v, index)); 172 } 173 174 protected void writePrimitiveArray(OutputContext ctx, Object v, int jmfComponentType, int dimensions, boolean writeDimensionsAndType) throws IOException { 175 final OutputStream os = ctx.getOutputStream(); 176 177 if (v == null) 178 os.write(JMF_NULL); 179 else { 180 int indexOfStoredObject = ctx.indexOfStoredObjects(v); 181 if (indexOfStoredObject >= 0) { 182 IntegerComponents ics = intComponents(indexOfStoredObject); 183 ctx.getOutputStream().write(0x80 | (ics.length << 4) | JMF_ARRAY); 184 writeIntData(ctx, ics); 185 } 186 else { 187 ctx.addToStoredObjects(v); 188 if (dimensions == 0) 189 writePrimitiveArray(ctx, v, jmfComponentType, writeDimensionsAndType); 190 else { 191 int length = Array.getLength(v); 192 193 IntegerComponents ics = intComponents(length); 194 if (writeDimensionsAndType) { 195 os.write(0x40 | (ics.length << 4) | JMF_ARRAY); 196 writeIntData(ctx, ics); 197 os.write(dimensions); 198 os.write(jmfComponentType); 199 } 200 else { 201 os.write((ics.length << 4) | JMF_ARRAY); 202 writeIntData(ctx, ics); 203 } 204 205 int subDimensions = dimensions - 1; 206 for (int index = 0; index < length; index++) 207 writePrimitiveArray(ctx, Array.get(v, index), jmfComponentType, subDimensions, false); 208 } 209 } 210 } 211 } 212 213 protected void writePrimitiveArray(OutputContext ctx, Object v, int jmfComponentType, boolean writeType) throws IOException { 214 final OutputStream os = ctx.getOutputStream(); 215 216 final int length = Array.getLength(v); 217 218 IntegerComponents ics = intComponents(length); 219 os.write((ics.length << 4) | JMF_ARRAY); 220 writeIntData(ctx, ics); 221 222 if (writeType) 223 os.write(jmfComponentType); 224 225 if (length == 0) 226 return; 227 228 switch (jmfComponentType) { 229 case JMF_BOOLEAN: { 230 byte[] bytes = new byte[lengthOfBooleanArray(length)]; 231 int i = 0, j = 0; 232 for (boolean b : (boolean[])v) { 233 if (b) 234 bytes[i] |= 0x80 >> j; 235 j++; 236 if (j >= 8) { 237 j = 0; 238 i++; 239 } 240 } 241 os.write(bytes); 242 break; 243 } 244 245 case JMF_CHARACTER: { 246 char[] a = (char[])v; 247 for (char c : a) { 248 os.write(c >> 8); 249 os.write(c); 250 } 251 break; 252 } 253 254 case JMF_BYTE: { 255 os.write((byte[])v); 256 break; 257 } 258 259 case JMF_SHORT: { 260 short[] a = (short[])v; 261 for (short s : a) { 262 os.write(s >> 8); 263 os.write(s); 264 } 265 break; 266 } 267 268 case JMF_INTEGER: { 269 IntegerCodec integerCodec = ctx.getSharedContext().getCodecRegistry().getIntegerCodec(); 270 int[] a = (int[])v; 271 for (int i : a) 272 integerCodec.writeVariableInt(ctx, i); 273 break; 274 } 275 276 case JMF_LONG: { 277 LongCodec longCodec = ctx.getSharedContext().getCodecRegistry().getLongCodec(); 278 long[] a = (long[])v; 279 for (long l : a) 280 longCodec.writeVariableLong(ctx, l); 281 break; 282 } 283 284 case JMF_FLOAT: { 285 float[] a = (float[])v; 286 for (float f : a) { 287 int bits = Float.floatToIntBits(f); 288 os.write(bits); 289 os.write(bits >> 8); 290 os.write(bits >> 16); 291 os.write(bits >> 24); 292 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 a[i] = FloatCodecImpl.readFloatData(ctx, jmfComponentType); 568 v = a; 569 break; 570 } 571 572 case JMF_DOUBLE: { 573 double[] a = new double[length]; 574 for (int i = 0; i < length; i++) 575 a[i] = DoubleCodecImpl.readDoubleData(ctx, jmfComponentType); 576 v = a; 577 break; 578 } 579 580 default: 581 throw new JMFEncodingException("Unsupported primitive type: " + jmfComponentType); 582 } 583 } 584 585 ctx.addSharedObject(v); 586 587 return v; 588 } 589 590 protected void dumpPrimitiveArray(DumpContext ctx, Class<?> componentType, int jmfComponentType, int length) throws IOException { 591 592 String v = newDumpPrimitiveArray(jmfComponentType, length, 0); 593 int indexOfStoredObject = ctx.addSharedObject(v); 594 ctx.indentPrint(v + "@" + indexOfStoredObject + ": {"); 595 596 switch (jmfComponentType) { 597 case JMF_BOOLEAN: { 598 int nb = lengthOfBooleanArray(length); 599 for (int i = 0; i < nb; i++) { 600 int b = ctx.safeRead(); 601 for (int j = 0; j < 8; j++) { 602 int index = (i * 8) + j; 603 if (index >= length) 604 break; 605 if (index > 0) 606 ctx.print(", "); 607 ctx.print(String.valueOf(((b & (0x80 >> j)) != 0))); 608 } 609 } 610 break; 611 } 612 613 case JMF_CHARACTER: { 614 for (int i = 0; i < length; i++) { 615 if (i > 0) 616 ctx.print(", "); 617 ctx.print(String.valueOf((char)((ctx.safeRead() << 8) | ctx.safeRead()))); 618 } 619 break; 620 } 621 622 case JMF_BYTE: { 623 for (int i = 0; i < length; i++) { 624 if (i > 0) 625 ctx.print(", "); 626 ctx.print(String.valueOf((byte)ctx.safeRead())); 627 } 628 break; 629 } 630 631 case JMF_SHORT: { 632 for (int i = 0; i < length; i++) { 633 if (i > 0) 634 ctx.print(", "); 635 ctx.print(String.valueOf((short)(ctx.safeRead() << 8) | ctx.safeRead())); 636 } 637 break; 638 } 639 640 case JMF_INTEGER: { 641 IntegerCodec integerCodec = ctx.getSharedContext().getCodecRegistry().getIntegerCodec(); 642 for (int i = 0; i < length; i++) { 643 if (i > 0) 644 ctx.print(", "); 645 ctx.print(String.valueOf(integerCodec.readVariableInt(ctx))); 646 } 647 break; 648 } 649 650 case JMF_LONG: { 651 LongCodec longCodec = ctx.getSharedContext().getCodecRegistry().getLongCodec(); 652 for (int i = 0; i < length; i++) { 653 if (i > 0) 654 ctx.print(", "); 655 ctx.print(String.valueOf(longCodec.readVariableLong(ctx))); 656 } 657 break; 658 } 659 660 case JMF_FLOAT: { 661 for (int i = 0; i < length; i++) { 662 if (i > 0) 663 ctx.print(", "); 664 ctx.print(String.valueOf(FloatCodecImpl.readFloatData(ctx, jmfComponentType))); 665 } 666 break; 667 } 668 669 case JMF_DOUBLE: { 670 for (int i = 0; i < length; i++) { 671 if (i > 0) 672 ctx.print(", "); 673 ctx.print(String.valueOf(DoubleCodecImpl.readDoubleData(ctx, jmfComponentType))); 674 } 675 break; 676 } 677 678 default: 679 throw new JMFEncodingException("Unsupported primitive type: " + jmfComponentType); 680 } 681 682 ctx.noIndentPrintLn("}"); 683 } 684 685 protected String newDumpPrimitiveArray(int jmfComponentType, int length, int dimensions) throws IOException { 686 StringBuilder sb = new StringBuilder(); 687 688 switch (jmfComponentType) { 689 case JMF_BOOLEAN: sb.append("boolean"); break; 690 case JMF_CHARACTER: sb.append("char"); break; 691 case JMF_BYTE: sb.append("byte"); break; 692 case JMF_SHORT: sb.append("short"); break; 693 case JMF_INTEGER: sb.append("int"); break; 694 case JMF_LONG: sb.append("long"); break; 695 case JMF_FLOAT: sb.append("float"); break; 696 case JMF_DOUBLE: sb.append("double"); break; 697 default: throw new JMFEncodingException("Unsupported primitive type: " + jmfComponentType); 698 } 699 700 sb.append('[').append(length).append(']'); 701 702 for (int i = 0; i < dimensions; i++) 703 sb.append("[]"); 704 705 return sb.toString(); 706 } 707 708 protected Object newArray(Class<?> type, int length, int dimensions) { 709 int[] ld = new int[dimensions + 1]; 710 ld[0] = length; 711 return Array.newInstance(type, ld); 712 } 713 714 protected int lengthOfBooleanArray(int nb) { 715 return (nb / 8) + (nb % 8 != 0 ? 1 : 0); 716 } 717}