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