XdrSchemaDecoder.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  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. default:
  53. throw new Error(`Unknown schema type: ${schema.type}`);
  54. }
  55. }
  56. readEnum(schema) {
  57. const value = this.decoder.readEnum();
  58. for (const [name, enumValue] of Object.entries(schema.values)) {
  59. if (enumValue === value) {
  60. return name;
  61. }
  62. }
  63. return value;
  64. }
  65. readOpaque(schema) {
  66. return this.decoder.readOpaque(schema.size);
  67. }
  68. readVarlenOpaque(schema) {
  69. const data = this.decoder.readVarlenOpaque();
  70. if (schema.size !== undefined && data.length > schema.size) {
  71. throw new Error(`Variable-length opaque data size ${data.length} exceeds maximum ${schema.size}`);
  72. }
  73. return data;
  74. }
  75. readString(schema) {
  76. const str = this.decoder.readString();
  77. if (schema.size !== undefined && str.length > schema.size) {
  78. throw new Error(`String length ${str.length} exceeds maximum ${schema.size}`);
  79. }
  80. return str;
  81. }
  82. readArray(schema) {
  83. return this.decoder.readArray(schema.size, () => this.readValue(schema.elements));
  84. }
  85. readVarlenArray(schema) {
  86. const array = this.decoder.readVarlenArray(() => this.readValue(schema.elements));
  87. if (schema.size !== undefined && array.length > schema.size) {
  88. throw new Error(`Variable-length array size ${array.length} exceeds maximum ${schema.size}`);
  89. }
  90. return array;
  91. }
  92. readStruct(schema) {
  93. const struct = {};
  94. for (const [fieldSchema, fieldName] of schema.fields) {
  95. struct[fieldName] = this.readValue(fieldSchema);
  96. }
  97. return struct;
  98. }
  99. readUnion(schema) {
  100. const discriminant = this.decoder.readInt();
  101. for (const [armDiscriminant, armSchema] of schema.arms) {
  102. if (armDiscriminant === discriminant) {
  103. const value = this.readValue(armSchema);
  104. return new XdrUnion_1.XdrUnion(discriminant, value);
  105. }
  106. }
  107. if (schema.default) {
  108. const value = this.readValue(schema.default);
  109. return new XdrUnion_1.XdrUnion(discriminant, value);
  110. }
  111. throw new Error(`No matching union arm for discriminant: ${discriminant}`);
  112. }
  113. }
  114. exports.XdrSchemaDecoder = XdrSchemaDecoder;
  115. //# sourceMappingURL=XdrSchemaDecoder.js.map