XdrSchemaDecoder.js 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.XdrSchemaDecoder = void 0;
  4. const Reader_1 = require("@jsonjoy.com/buffers/lib/Reader");
  5. const XdrDecoder_1 = require("./XdrDecoder");
  6. const XdrUnion_1 = require("./XdrUnion");
  7. class XdrSchemaDecoder {
  8. constructor(reader = new Reader_1.Reader()) {
  9. this.reader = reader;
  10. this.decoder = new XdrDecoder_1.XdrDecoder(reader);
  11. }
  12. decode(data, schema) {
  13. this.reader.reset(data);
  14. return this.readValue(schema);
  15. }
  16. readValue(schema) {
  17. switch (schema.type) {
  18. case 'void':
  19. return this.decoder.readVoid();
  20. case 'int':
  21. return this.decoder.readInt();
  22. case 'unsigned_int':
  23. return this.decoder.readUnsignedInt();
  24. case 'boolean':
  25. return this.decoder.readBoolean();
  26. case 'hyper':
  27. return this.decoder.readHyper();
  28. case 'unsigned_hyper':
  29. return this.decoder.readUnsignedHyper();
  30. case 'float':
  31. return this.decoder.readFloat();
  32. case 'double':
  33. return this.decoder.readDouble();
  34. case 'quadruple':
  35. return this.decoder.readQuadruple();
  36. case 'enum':
  37. return this.readEnum(schema);
  38. case 'opaque':
  39. return this.readOpaque(schema);
  40. case 'vopaque':
  41. return this.readVarlenOpaque(schema);
  42. case 'string':
  43. return this.readString(schema);
  44. case 'array':
  45. return this.readArray(schema);
  46. case 'varray':
  47. return this.readVarlenArray(schema);
  48. case 'struct':
  49. return this.readStruct(schema);
  50. case 'union':
  51. return this.readUnion(schema);
  52. case 'optional':
  53. return this.readOptional(schema);
  54. case 'const':
  55. return undefined;
  56. default:
  57. throw new Error(`Unknown schema type: ${schema.type}`);
  58. }
  59. }
  60. readEnum(schema) {
  61. const value = this.decoder.readEnum();
  62. for (const [name, enumValue] of Object.entries(schema.values)) {
  63. if (enumValue === value) {
  64. return name;
  65. }
  66. }
  67. return value;
  68. }
  69. readOpaque(schema) {
  70. return this.decoder.readOpaque(schema.size);
  71. }
  72. readVarlenOpaque(schema) {
  73. const data = this.decoder.readVarlenOpaque();
  74. if (schema.size !== undefined && data.length > schema.size) {
  75. throw new Error(`Variable-length opaque data size ${data.length} exceeds maximum ${schema.size}`);
  76. }
  77. return data;
  78. }
  79. readString(schema) {
  80. const str = this.decoder.readString();
  81. if (schema.size !== undefined && str.length > schema.size) {
  82. throw new Error(`String length ${str.length} exceeds maximum ${schema.size}`);
  83. }
  84. return str;
  85. }
  86. readArray(schema) {
  87. return this.decoder.readArray(schema.size, () => this.readValue(schema.elements));
  88. }
  89. readVarlenArray(schema) {
  90. const array = this.decoder.readVarlenArray(() => this.readValue(schema.elements));
  91. if (schema.size !== undefined && array.length > schema.size) {
  92. throw new Error(`Variable-length array size ${array.length} exceeds maximum ${schema.size}`);
  93. }
  94. return array;
  95. }
  96. readStruct(schema) {
  97. const struct = {};
  98. for (const [fieldSchema, fieldName] of schema.fields) {
  99. struct[fieldName] = this.readValue(fieldSchema);
  100. }
  101. return struct;
  102. }
  103. readUnion(schema) {
  104. const discriminant = this.decoder.readInt();
  105. for (const [armDiscriminant, armSchema] of schema.arms) {
  106. if (armDiscriminant === discriminant) {
  107. const value = this.readValue(armSchema);
  108. return new XdrUnion_1.XdrUnion(discriminant, value);
  109. }
  110. }
  111. if (schema.default) {
  112. const value = this.readValue(schema.default);
  113. return new XdrUnion_1.XdrUnion(discriminant, value);
  114. }
  115. throw new Error(`No matching union arm for discriminant: ${discriminant}`);
  116. }
  117. readOptional(schema) {
  118. const opted = this.decoder.readBoolean();
  119. if (!opted)
  120. return null;
  121. return this.readValue(schema.element);
  122. }
  123. }
  124. exports.XdrSchemaDecoder = XdrSchemaDecoder;
  125. //# sourceMappingURL=XdrSchemaDecoder.js.map