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 */ 022package org.granite.messaging.jmf.codec.std.impl; 023 024import java.io.IOException; 025import java.io.OutputStream; 026import java.lang.reflect.Array; 027 028import org.granite.messaging.jmf.CodecRegistry; 029import org.granite.messaging.jmf.DumpContext; 030import org.granite.messaging.jmf.InputContext; 031import org.granite.messaging.jmf.JMFEncodingException; 032import org.granite.messaging.jmf.OutputContext; 033import org.granite.messaging.jmf.codec.StandardCodec; 034import org.granite.messaging.jmf.codec.std.ArrayCodec; 035import org.granite.messaging.jmf.codec.std.IntegerCodec; 036import org.granite.messaging.jmf.codec.std.LongCodec; 037 038/** 039 * @author Franck WOLFF 040 */ 041public 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 } 295 break; 296 } 297 298 case JMF_DOUBLE: { 299 double[] a = (double[])v; 300 for (double d : a) { 301 long bits = Double.doubleToLongBits(d); 302 os.write((int)bits); 303 os.write((int)(bits >> 8)); 304 os.write((int)(bits >> 16)); 305 os.write((int)(bits >> 24)); 306 os.write((int)(bits >> 32)); 307 os.write((int)(bits >> 40)); 308 os.write((int)(bits >> 48)); 309 os.write((int)(bits >> 56)); 310 } 311 break; 312 } 313 314 default: 315 throw new JMFEncodingException("Unsupported primitive type: " + jmfComponentType); 316 } 317 } 318 319 protected int getArrayDimensions(Object v) { 320 return v.getClass().getName().lastIndexOf('['); 321 } 322 323 protected Class<?> getComponentType(Object v) { 324 Class<?> componentType = v.getClass().getComponentType(); 325 while (componentType.isArray()) 326 componentType = componentType.getComponentType(); 327 return componentType; 328 } 329 330 protected Object readObjectArray(InputContext ctx, int parameterizedJmfComponentType, int length, int dimensions) throws IOException, ClassNotFoundException { 331 Object v = null; 332 333 String componentTypeName = readString(ctx, parameterizedJmfComponentType, JMF_STRING_TYPE_HANDLER); 334 componentTypeName = ctx.getAlias(componentTypeName); 335 Class<?> componentType = ctx.getSharedContext().getReflection().loadClass(componentTypeName); 336 337 if (dimensions == 0) 338 v = readObjectArray(ctx, componentType, length); 339 else { 340 v = newArray(componentType, length, dimensions); 341 ctx.addSharedObject(v); 342 343 int subDimensions = dimensions - 1; 344 for (int index = 0; index < length; index++) { 345 int subParameterizedJmfType = ctx.safeRead(); 346 int subJmfType = ctx.getSharedContext().getCodecRegistry().extractJmfType(subParameterizedJmfType); 347 348 if (subJmfType == JMF_NULL) 349 Array.set(v, index, null); 350 else if (subJmfType == JMF_ARRAY) { 351 int subLengthOrIndex = readIntData(ctx, (subParameterizedJmfType >> 4) & 0x03, false); 352 if ((subParameterizedJmfType & 0x80) != 0) 353 Array.set(v, index, ctx.getSharedObject(subLengthOrIndex)); 354 else { 355 int subParameterizedJmfComponentType = ctx.safeRead(); 356 Array.set(v, index, readObjectArray(ctx, subParameterizedJmfComponentType, subLengthOrIndex, subDimensions)); 357 } 358 } 359 else 360 newBadTypeJMFEncodingException(subJmfType, subParameterizedJmfType); 361 } 362 } 363 364 return v; 365 } 366 367 protected void dumpObjectArray(DumpContext ctx, int parameterizedJmfComponentType, int length, int dimensions) throws IOException { 368 String componentTypeName = readString(ctx, parameterizedJmfComponentType, JMF_STRING_TYPE_HANDLER); 369 370 if (dimensions == 0) 371 dumpObjectArray(ctx, componentTypeName, length); 372 else { 373 String v = newDumpObjectArray(componentTypeName, length, dimensions); 374 int indexOfStoredObject = ctx.addSharedObject(v); 375 ctx.indentPrintLn(v + "@" + indexOfStoredObject + ": {"); 376 ctx.incrIndent(1); 377 378 int subDimensions = dimensions - 1; 379 for (int index = 0; index < length; index++) { 380 int subParameterizedJmfType = ctx.safeRead(); 381 int subJmfType = ctx.getSharedContext().getCodecRegistry().extractJmfType(subParameterizedJmfType); 382 383 if (subJmfType == JMF_NULL) 384 ctx.indentPrintLn("null"); 385 else if (subJmfType == JMF_ARRAY) { 386 int subLengthOrIndex = readIntData(ctx, (subParameterizedJmfType >> 4) & 0x03, false); 387 if ((subParameterizedJmfType & 0x80) != 0) 388 ctx.indentPrintLn("<" + ctx.getSharedObject(subLengthOrIndex) + "@" + subLengthOrIndex + ">"); 389 else { 390 int subParameterizedJmfComponentType = ctx.safeRead(); 391 dumpObjectArray(ctx, subParameterizedJmfComponentType, subLengthOrIndex, subDimensions); 392 } 393 } 394 else 395 newBadTypeJMFEncodingException(subJmfType, subParameterizedJmfType); 396 } 397 398 ctx.incrIndent(-1); 399 ctx.indentPrintLn("}"); 400 } 401 } 402 403 protected Object readObjectArray(InputContext ctx, Class<?> componentType, int length) throws IOException, ClassNotFoundException { 404 Object v = Array.newInstance(componentType, length); 405 ctx.addSharedObject(v); 406 407 for (int index = 0; index < length; index++) 408 Array.set(v, index, ctx.readObject()); 409 410 return v; 411 } 412 413 protected void dumpObjectArray(DumpContext ctx, String componentTypeName, int length) throws IOException { 414 String v = newDumpObjectArray(componentTypeName, length, 0); 415 int indexOfStoredObject = ctx.addSharedObject(v); 416 ctx.indentPrintLn(v + "@" + indexOfStoredObject + ": {"); 417 ctx.incrIndent(1); 418 419 for (int index = 0; index < length; index++) { 420 int parameterizedJmfType = ctx.safeRead(); 421 int jmfType = ctx.getSharedContext().getCodecRegistry().extractJmfType(parameterizedJmfType); 422 StandardCodec<?> codec = ctx.getSharedContext().getCodecRegistry().getCodec(jmfType); 423 424 if (codec == null) 425 throw new JMFEncodingException("No codec for JMF type: " + jmfType); 426 427 codec.dump(ctx, parameterizedJmfType); 428 } 429 430 ctx.incrIndent(-1); 431 ctx.indentPrintLn("}"); 432 } 433 434 protected String newDumpObjectArray(String componentTypeName, int length, int dimensions) { 435 StringBuilder sb = new StringBuilder(componentTypeName); 436 437 sb.append('[').append(length).append(']'); 438 439 for (int i = 0; i < dimensions; i++) 440 sb.append("[]"); 441 442 return sb.toString(); 443 444 } 445 446 protected Object readPrimitiveArray(InputContext ctx, Class<?> componentType, int jmfComponentType, int length, int dimensions) throws IOException { 447 Object v = null; 448 449 if (dimensions == 0) 450 v = readPrimitiveArray(ctx, componentType, jmfComponentType, length); 451 else { 452 v = newArray(componentType, length, dimensions); 453 ctx.addSharedObject(v); 454 455 int subDimensions = dimensions - 1; 456 for (int index = 0; index < length; index++) { 457 int subArrayJmfType = ctx.safeRead(); 458 if (subArrayJmfType == JMF_NULL) 459 Array.set(v, index, null); 460 else { 461 int subLengthOrIndex = readIntData(ctx, (subArrayJmfType >> 4) & 0x03, false); 462 if ((subArrayJmfType & 0x80) != 0) 463 Array.set(v, index, ctx.getSharedObject(subLengthOrIndex)); 464 else 465 Array.set(v, index, readPrimitiveArray(ctx, componentType, jmfComponentType, subLengthOrIndex, subDimensions)); 466 } 467 } 468 } 469 470 return v; 471 } 472 473 protected void dumpPrimitiveArray(DumpContext ctx, Class<?> componentType, int jmfComponentType, int length, int dimensions) throws IOException { 474 if (dimensions == 0) 475 dumpPrimitiveArray(ctx, componentType, jmfComponentType, length); 476 else { 477 String v = newDumpPrimitiveArray(jmfComponentType, length, dimensions); 478 int indexOfStoredObject = ctx.addSharedObject(v); 479 ctx.indentPrintLn(v + "@" + indexOfStoredObject + ": {"); 480 ctx.incrIndent(1); 481 482 int subDimensions = dimensions - 1; 483 for (int index = 0; index < length; index++) { 484 int subArrayJmfType = ctx.safeRead(); 485 if (subArrayJmfType == JMF_NULL) 486 ctx.indentPrintLn("null"); 487 else { 488 int subLengthOrIndex = readIntData(ctx, (subArrayJmfType >> 4) & 0x03, false); 489 if ((subArrayJmfType & 0x80) != 0) 490 ctx.indentPrintLn("<" + ctx.getSharedObject(subLengthOrIndex) + "@" + subLengthOrIndex + ">"); 491 else 492 dumpPrimitiveArray(ctx, componentType, jmfComponentType, subLengthOrIndex, subDimensions); 493 } 494 } 495 496 ctx.incrIndent(-1); 497 ctx.indentPrintLn("}"); 498 } 499 } 500 501 protected Object readPrimitiveArray(InputContext ctx, Class<?> componentType, int jmfComponentType, int length) throws IOException { 502 Object v = null; 503 504 if (length == 0) 505 v = Array.newInstance(componentType, length); 506 else { 507 switch (jmfComponentType) { 508 case JMF_BOOLEAN: { 509 boolean[] a = new boolean[length]; 510 int nb = lengthOfBooleanArray(length); 511 for (int i = 0; i < nb; i++) { 512 int b = ctx.safeRead(); 513 for (int j = 0; j < 8; j++) { 514 int index = (i * 8) + j; 515 if (index >= length) 516 break; 517 a[index] = ((b & (0x80 >> j)) != 0); 518 } 519 } 520 v = a; 521 break; 522 } 523 524 case JMF_CHARACTER: { 525 char[] a = new char[length]; 526 for (int i = 0; i < length; i++) 527 a[i] = (char)((ctx.safeRead() << 8) | ctx.safeRead()); 528 v = a; 529 break; 530 } 531 532 case JMF_BYTE: { 533 byte[] a = new byte[length]; 534 ctx.safeReadFully(a); 535 v = a; 536 break; 537 } 538 539 case JMF_SHORT: { 540 short[] a = new short[length]; 541 for (int i = 0; i < length; i++) 542 a[i] = (short)((ctx.safeRead() << 8) | ctx.safeRead()); 543 v = a; 544 break; 545 } 546 547 case JMF_INTEGER: { 548 IntegerCodec integerCodec = ctx.getSharedContext().getCodecRegistry().getIntegerCodec(); 549 int[] a = new int[length]; 550 for (int i = 0; i < length; i++) 551 a[i] = integerCodec.readVariableInt(ctx); 552 v = a; 553 break; 554 } 555 556 case JMF_LONG: { 557 LongCodec longCodec = ctx.getSharedContext().getCodecRegistry().getLongCodec(); 558 long[] a = new long[length]; 559 for (int i = 0; i < length; i++) 560 a[i] = longCodec.readVariableLong(ctx); 561 v = a; 562 break; 563 } 564 565 case JMF_FLOAT: { 566 float[] a = new float[length]; 567 for (int i = 0; i < length; i++) 568 a[i] = FloatCodecImpl.readFloatData(ctx, jmfComponentType); 569 v = a; 570 break; 571 } 572 573 case JMF_DOUBLE: { 574 double[] a = new double[length]; 575 for (int i = 0; i < length; i++) 576 a[i] = DoubleCodecImpl.readDoubleData(ctx, jmfComponentType); 577 v = a; 578 break; 579 } 580 581 default: 582 throw new JMFEncodingException("Unsupported primitive type: " + jmfComponentType); 583 } 584 } 585 586 ctx.addSharedObject(v); 587 588 return v; 589 } 590 591 protected void dumpPrimitiveArray(DumpContext ctx, Class<?> componentType, int jmfComponentType, int length) throws IOException { 592 593 String v = newDumpPrimitiveArray(jmfComponentType, length, 0); 594 int indexOfStoredObject = ctx.addSharedObject(v); 595 ctx.indentPrint(v + "@" + indexOfStoredObject + ": {"); 596 597 switch (jmfComponentType) { 598 case JMF_BOOLEAN: { 599 int nb = lengthOfBooleanArray(length); 600 for (int i = 0; i < nb; i++) { 601 int b = ctx.safeRead(); 602 for (int j = 0; j < 8; j++) { 603 int index = (i * 8) + j; 604 if (index >= length) 605 break; 606 if (index > 0) 607 ctx.print(", "); 608 ctx.print(String.valueOf(((b & (0x80 >> j)) != 0))); 609 } 610 } 611 break; 612 } 613 614 case JMF_CHARACTER: { 615 for (int i = 0; i < length; i++) { 616 if (i > 0) 617 ctx.print(", "); 618 ctx.print(String.valueOf((char)((ctx.safeRead() << 8) | ctx.safeRead()))); 619 } 620 break; 621 } 622 623 case JMF_BYTE: { 624 for (int i = 0; i < length; i++) { 625 if (i > 0) 626 ctx.print(", "); 627 ctx.print(String.valueOf((byte)ctx.safeRead())); 628 } 629 break; 630 } 631 632 case JMF_SHORT: { 633 for (int i = 0; i < length; i++) { 634 if (i > 0) 635 ctx.print(", "); 636 ctx.print(String.valueOf((short)(ctx.safeRead() << 8) | ctx.safeRead())); 637 } 638 break; 639 } 640 641 case JMF_INTEGER: { 642 IntegerCodec integerCodec = ctx.getSharedContext().getCodecRegistry().getIntegerCodec(); 643 for (int i = 0; i < length; i++) { 644 if (i > 0) 645 ctx.print(", "); 646 ctx.print(String.valueOf(integerCodec.readVariableInt(ctx))); 647 } 648 break; 649 } 650 651 case JMF_LONG: { 652 LongCodec longCodec = ctx.getSharedContext().getCodecRegistry().getLongCodec(); 653 for (int i = 0; i < length; i++) { 654 if (i > 0) 655 ctx.print(", "); 656 ctx.print(String.valueOf(longCodec.readVariableLong(ctx))); 657 } 658 break; 659 } 660 661 case JMF_FLOAT: { 662 for (int i = 0; i < length; i++) { 663 if (i > 0) 664 ctx.print(", "); 665 ctx.print(String.valueOf(FloatCodecImpl.readFloatData(ctx, jmfComponentType))); 666 } 667 break; 668 } 669 670 case JMF_DOUBLE: { 671 for (int i = 0; i < length; i++) { 672 if (i > 0) 673 ctx.print(", "); 674 ctx.print(String.valueOf(DoubleCodecImpl.readDoubleData(ctx, jmfComponentType))); 675 } 676 break; 677 } 678 679 default: 680 throw new JMFEncodingException("Unsupported primitive type: " + jmfComponentType); 681 } 682 683 ctx.noIndentPrintLn("}"); 684 } 685 686 protected String newDumpPrimitiveArray(int jmfComponentType, int length, int dimensions) throws IOException { 687 StringBuilder sb = new StringBuilder(); 688 689 switch (jmfComponentType) { 690 case JMF_BOOLEAN: sb.append("boolean"); break; 691 case JMF_CHARACTER: sb.append("char"); break; 692 case JMF_BYTE: sb.append("byte"); break; 693 case JMF_SHORT: sb.append("short"); break; 694 case JMF_INTEGER: sb.append("int"); break; 695 case JMF_LONG: sb.append("long"); break; 696 case JMF_FLOAT: sb.append("float"); break; 697 case JMF_DOUBLE: sb.append("double"); break; 698 default: throw new JMFEncodingException("Unsupported primitive type: " + jmfComponentType); 699 } 700 701 sb.append('[').append(length).append(']'); 702 703 for (int i = 0; i < dimensions; i++) 704 sb.append("[]"); 705 706 return sb.toString(); 707 } 708 709 protected Object newArray(Class<?> type, int length, int dimensions) { 710 int[] ld = new int[dimensions + 1]; 711 ld[0] = length; 712 return Array.newInstance(type, ld); 713 } 714 715 protected int lengthOfBooleanArray(int nb) { 716 return (nb / 8) + (nb % 8 != 0 ? 1 : 0); 717 } 718}