decoder.js 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. "use strict";
  2. module.exports = decoder;
  3. var Enum = require("./enum"),
  4. types = require("./types"),
  5. util = require("./util");
  6. function missing(field) {
  7. return "missing required '" + field.name + "'";
  8. }
  9. /**
  10. * Generates a decoder specific to the specified message type.
  11. * @param {Type} mtype Message type
  12. * @returns {Codegen} Codegen instance
  13. */
  14. function decoder(mtype) {
  15. /* eslint-disable no-unexpected-multiline */
  16. var gen = util.codegen(["r", "l"], mtype.name + "$decode")
  17. ("if(!(r instanceof Reader))")
  18. ("r=Reader.create(r)")
  19. ("var c=l===undefined?r.len:r.pos+l,m=new this.ctor" + (mtype.fieldsArray.filter(function(field) { return field.map; }).length ? ",k" : ""))
  20. ("while(r.pos<c){")
  21. ("var t=r.uint32()");
  22. if (mtype.group) gen
  23. ("if((t&7)===4)")
  24. ("break");
  25. gen
  26. ("switch(t>>>3){");
  27. var i = 0;
  28. for (; i < /* initializes */ mtype.fieldsArray.length; ++i) {
  29. var field = mtype._fieldsArray[i].resolve(),
  30. type = field.resolvedType instanceof Enum ? "int32" : field.type,
  31. ref = "m" + util.safeProp(field.name); gen
  32. ("case %i:", field.id);
  33. // Map fields
  34. if (field.map) { gen
  35. ("r.skip().pos++") // assumes id 1 + key wireType
  36. ("if(%s===util.emptyObject)", ref)
  37. ("%s={}", ref)
  38. ("k=r.%s()", field.keyType)
  39. ("r.pos++"); // assumes id 2 + value wireType
  40. if (types.long[field.keyType] !== undefined) {
  41. if (types.basic[type] === undefined) gen
  42. ("%s[typeof k===\"object\"?util.longToHash(k):k]=types[%i].decode(r,r.uint32())", ref, i); // can't be groups
  43. else gen
  44. ("%s[typeof k===\"object\"?util.longToHash(k):k]=r.%s()", ref, type);
  45. } else {
  46. if (types.basic[type] === undefined) gen
  47. ("%s[k]=types[%i].decode(r,r.uint32())", ref, i); // can't be groups
  48. else gen
  49. ("%s[k]=r.%s()", ref, type);
  50. }
  51. // Repeated fields
  52. } else if (field.repeated) { gen
  53. ("if(!(%s&&%s.length))", ref, ref)
  54. ("%s=[]", ref);
  55. // Packable (always check for forward and backward compatiblity)
  56. if (types.packed[type] !== undefined) gen
  57. ("if((t&7)===2){")
  58. ("var c2=r.uint32()+r.pos")
  59. ("while(r.pos<c2)")
  60. ("%s.push(r.%s())", ref, type)
  61. ("}else");
  62. // Non-packed
  63. if (types.basic[type] === undefined) gen(field.resolvedType.group
  64. ? "%s.push(types[%i].decode(r))"
  65. : "%s.push(types[%i].decode(r,r.uint32()))", ref, i);
  66. else gen
  67. ("%s.push(r.%s())", ref, type);
  68. // Non-repeated
  69. } else if (types.basic[type] === undefined) gen(field.resolvedType.group
  70. ? "%s=types[%i].decode(r)"
  71. : "%s=types[%i].decode(r,r.uint32())", ref, i);
  72. else gen
  73. ("%s=r.%s()", ref, type);
  74. gen
  75. ("break");
  76. // Unknown fields
  77. } gen
  78. ("default:")
  79. ("r.skipType(t&7)")
  80. ("break")
  81. ("}")
  82. ("}");
  83. // Field presence
  84. for (i = 0; i < mtype._fieldsArray.length; ++i) {
  85. var rfield = mtype._fieldsArray[i];
  86. if (rfield.required) gen
  87. ("if(!m.hasOwnProperty(%j))", rfield.name)
  88. ("throw util.ProtocolError(%j,{instance:m})", missing(rfield));
  89. }
  90. return gen
  91. ("return m");
  92. /* eslint-enable no-unexpected-multiline */
  93. }