PageRenderTime 25ms CodeModel.GetById 29ms RepoModel.GetById 1ms app.codeStats 0ms

/sdk/storage/azure-storage-internal-avro/src/main/java/com/azure/storage/internal/avro/implementation/schema/complex/AvroArraySchema.java

http://github.com/WindowsAzure/azure-sdk-for-java
Java | 134 lines | 77 code | 12 blank | 45 comment | 8 complexity | 85cb74b13fe1e688a02599ca24444d3f MD5 | raw file
Possible License(s): MIT
  1. // Copyright (c) Microsoft Corporation. All rights reserved.
  2. // Licensed under the MIT License.
  3. package com.azure.storage.internal.avro.implementation.schema.complex;
  4. import com.azure.storage.internal.avro.implementation.AvroParserState;
  5. import com.azure.storage.internal.avro.implementation.schema.AvroCompositeSchema;
  6. import com.azure.storage.internal.avro.implementation.schema.AvroSchema;
  7. import com.azure.storage.internal.avro.implementation.schema.AvroType;
  8. import com.azure.storage.internal.avro.implementation.schema.primitive.AvroLongSchema;
  9. import java.util.ArrayList;
  10. import java.util.List;
  11. import java.util.function.Consumer;
  12. /**
  13. * Arrays are encoded as a series of blocks. Each block consists of a long count value, followed by that many array
  14. * items. A block with count zero indicates the end of the array. Each item is encoded per the array's item schema.
  15. * If a block's count is negative, its absolute value is used, and the count is followed immediately by a long block
  16. * size indicating the number of bytes in the block.
  17. *
  18. * Long Item Item Item .... Long Item Item Item .... Long(0)
  19. * If initial Long parsed is negative, it can look like
  20. * Long(negative) Long Item Item Item ....
  21. */
  22. public class AvroArraySchema extends AvroCompositeSchema {
  23. /* TODO (gapra) : Look into possibly reducing duplicate code between MapSchema and ArraySchema.
  24. This may add a little more complexity to the AvroTypes, so I'm putting it off for now. */
  25. private final AvroType itemType;
  26. private Long blockCount;
  27. private List<Object> ret;
  28. /**
  29. * Constructs a new AvroArraySchema.
  30. *
  31. * @param itemType The type of items in the array.
  32. * @param state The state of the parser.
  33. * @param onResult The result handler.
  34. */
  35. public AvroArraySchema(AvroType itemType, AvroParserState state, Consumer<Object> onResult) {
  36. super(state, onResult);
  37. this.ret = new ArrayList<>();
  38. this.itemType = itemType;
  39. }
  40. @Override
  41. public void pushToStack() {
  42. this.state.pushToStack(this);
  43. /* Read the block size, call onBlockCount. */
  44. AvroLongSchema blockCountSchema = new AvroLongSchema(
  45. this.state,
  46. this::onBlockCount
  47. );
  48. blockCountSchema.pushToStack();
  49. }
  50. /**
  51. * Block count handler
  52. *
  53. * @param blockCount The number of elements in the block.
  54. */
  55. private void onBlockCount(Object blockCount) {
  56. checkType("blockCount", blockCount, Long.class);
  57. Long bc = (Long) blockCount;
  58. /* If blockCount = 0, then we're done.*/
  59. if (bc == 0) {
  60. this.result = this.ret;
  61. this.done = true;
  62. /* If blockCount > 0, read the item, call onItem. */
  63. } else if (bc > 0) {
  64. this.blockCount = bc;
  65. AvroSchema itemSchema = getSchema(
  66. this.itemType,
  67. this.state,
  68. this::onItem
  69. );
  70. itemSchema.pushToStack();
  71. /* If blockCount < 0, use absolute value, read the byteCount, call onByteCount. */
  72. } else {
  73. this.blockCount = -bc;
  74. AvroLongSchema byteCountSchema = new AvroLongSchema(
  75. this.state,
  76. this::onByteCount
  77. );
  78. byteCountSchema.pushToStack();
  79. }
  80. }
  81. /**
  82. * Byte count handler.
  83. *
  84. * @param byteCount The number of bytes in the block.
  85. */
  86. private void onByteCount(Object byteCount) {
  87. /* Read the item, call onItem. */
  88. AvroSchema itemSchema = getSchema(
  89. this.itemType,
  90. this.state,
  91. this::onItem
  92. );
  93. itemSchema.pushToStack();
  94. }
  95. /**
  96. * Item handler.
  97. *
  98. * @param item The item.
  99. */
  100. private void onItem(Object item) {
  101. /* Add the item to the list. */
  102. this.ret.add(item);
  103. /* Decrement the block count. */
  104. this.blockCount--;
  105. /* If blockCount = 0, there are no more items in the block, read another blockCount and call onBlockCount. */
  106. if (this.blockCount == 0) {
  107. AvroLongSchema blockCountSchema = new AvroLongSchema(
  108. this.state,
  109. this::onBlockCount
  110. );
  111. blockCountSchema.pushToStack();
  112. /* If blockCount != 0, there are more items in the block, read another item and call onItem. */
  113. } else {
  114. AvroSchema itemSchema = getSchema(
  115. this.itemType,
  116. this.state,
  117. this::onItem
  118. );
  119. itemSchema.pushToStack();
  120. }
  121. }
  122. }