Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit b936af4

Browse filesBrowse files
Hook up message encoding feature
1 parent a938467 commit b936af4
Copy full SHA for b936af4

File tree

Expand file treeCollapse file tree

4 files changed

+103
-13
lines changed
Filter options
Expand file treeCollapse file tree

4 files changed

+103
-13
lines changed

‎src/decoder.js

Copy file name to clipboardExpand all lines: src/decoder.js
+8-10Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,14 @@ function missing(field) {
1616
*/
1717
function decoder(mtype) {
1818
/* eslint-disable no-unexpected-multiline */
19-
var gen = util.codegen(["r", "l"], mtype.name + "$decode")
19+
var gen = util.codegen(["r", "l", "e"], mtype.name + "$decode")
2020
("if(!(r instanceof Reader))")
2121
("r=Reader.create(r)")
2222
("var c=l===undefined?r.len:r.pos+l,m=new this.ctor" + (mtype.fieldsArray.filter(function(field) { return field.map; }).length ? ",k,value" : ""))
2323
("while(r.pos<c){")
24-
("var t=r.uint32()");
25-
if (mtype.group) gen
26-
("if((t&7)===4)")
27-
("break");
28-
gen
24+
("var t=r.uint32()")
25+
("if(t===e)")
26+
("break")
2927
("switch(t>>>3){");
3028

3129
var i = 0;
@@ -91,15 +89,15 @@ function decoder(mtype) {
9189
("}else");
9290

9391
// Non-packed
94-
if (types.basic[type] === undefined) gen(field.resolvedType.group
95-
? "%s.push(types[%i].decode(r))"
92+
if (types.basic[type] === undefined) gen(field.delimited
93+
? "%s.push(types[%i].decode(r,undefined,((t&~7)|4)))"
9694
: "%s.push(types[%i].decode(r,r.uint32()))", ref, i);
9795
else gen
9896
("%s.push(r.%s())", ref, type);
9997

10098
// Non-repeated
101-
} else if (types.basic[type] === undefined) gen(field.resolvedType.group
102-
? "%s=types[%i].decode(r)"
99+
} else if (types.basic[type] === undefined) gen(field.delimited
100+
? "%s=types[%i].decode(r,undefined,((t&~7)|4))"
103101
: "%s=types[%i].decode(r,r.uint32())", ref, i);
104102
else gen
105103
("%s=r.%s()", ref, type);

‎src/encoder.js

Copy file name to clipboardExpand all lines: src/encoder.js
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ var Enum = require("./enum"),
1515
* @ignore
1616
*/
1717
function genTypePartial(gen, field, fieldIndex, ref) {
18-
return field.resolvedType.group
18+
return field.delimited
1919
? gen("types[%i].encode(%s,w.uint32(%i)).uint32(%i)", fieldIndex, ref, (field.id << 3 | 3) >>> 0, (field.id << 3 | 4) >>> 0)
2020
: gen("types[%i].encode(%s,w.uint32(%i).fork()).ldelim()", fieldIndex, ref, (field.id << 3 | 2) >>> 0);
2121
}

‎src/field.js

Copy file name to clipboardExpand all lines: src/field.js
+17Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,20 @@ Object.defineProperty(Field.prototype, "optional", {
202202
}
203203
});
204204

205+
/**
206+
* Determines whether this field uses tag-delimited encoding. In proto2 this
207+
* corresponded to group syntax.
208+
* @name Field#delimited
209+
* @type {boolean}
210+
* @readonly
211+
*/
212+
Object.defineProperty(Field.prototype, "delimited", {
213+
get: function() {
214+
return this.resolvedType instanceof Type &&
215+
this._features.message_encoding === "DELIMITED";
216+
}
217+
});
218+
205219
/**
206220
* Determines whether this field is packed. Only relevant when repeated.
207221
* @name Field#packed
@@ -335,6 +349,9 @@ Field.prototype._inferLegacyProtoFeatures = function _inferLegacyProtoFeatures(e
335349
if (this.rule === "required") {
336350
features.field_presence = "LEGACY_REQUIRED";
337351
}
352+
if (this.resolvedType instanceof Type && this.resolvedType.group) {
353+
features.message_encoding = "DELIMITED";
354+
}
338355
if (this.getOption("packed") === true) {
339356
features.repeated_field_encoding = "PACKED";
340357
} else if (this.getOption("packed") === false) {

‎tests/comp_groups.js

Copy file name to clipboardExpand all lines: tests/comp_groups.js
+77-2Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ var protoRepeated = "message Test {\
1717
}";
1818

1919
tape.test("legacy groups", function(test) {
20-
var root = protobuf.parse(protoRequired).root;
20+
var root = protobuf.parse(protoRequired).root.resolveAll();
2121

22-
var Test = root.resolveAll().lookup("Test");
22+
var Test = root.lookup("Test");
2323
var MyGroupType = Test.get("MyGroup");
2424
var MyGroupField = Test.get("myGroup");
2525
var msg = {
@@ -30,6 +30,7 @@ tape.test("legacy groups", function(test) {
3030

3131
test.ok(MyGroupType instanceof protobuf.Type && MyGroupField instanceof protobuf.Field, "should parse to a type and a field");
3232
test.equal(MyGroupType.group, true, "should have the group flag set on the type");
33+
test.equal(MyGroupField.delimited, true, "should have the delimited flag set on the field");
3334
test.equal(MyGroupField.resolvedType, MyGroupType, "should reference the type from the field");
3435
var json = MyGroupType.toJSON();
3536
test.equal(json.group, true, "should export group=true to JSON");
@@ -77,3 +78,77 @@ tape.test("legacy groups", function(test) {
7778

7879
test.end();
7980
});
81+
82+
83+
tape.test("delimited encoding", function(test) {
84+
var root = protobuf.parse(`
85+
edition = "2023";
86+
message Message {
87+
uint32 a = 2;
88+
};
89+
message Test {
90+
Message msg = 1 [features.message_encoding = DELIMITED];
91+
}
92+
`).root.resolveAll();
93+
94+
var Test = root.lookup("Test");
95+
var Message = root.get("Message");
96+
var Field = Test.get("msg");
97+
var msg = {
98+
msg: {
99+
a: 111
100+
}
101+
};
102+
103+
test.ok(Message instanceof protobuf.Type && Field instanceof protobuf.Field, "should parse to a type and a field");
104+
test.notOk(Message.group, "should not have the group flag set on the type");
105+
test.ok(Field.delimited, "should have the delimited flag set on the field");
106+
test.equal(Field.resolvedType, Message, "should reference the type from the field");
107+
108+
test.test(test.name + " - should encode required", (function(Test, msg) { return function(test) {
109+
var buf = Test.encode(msg).finish();
110+
test.equal(buf.length, 4, "a total of 4 bytes");
111+
test.equal(buf[0], 1 << 3 | 3, "id 1, wireType 3");
112+
test.equal(buf[1], 2 << 3 | 0, "id 2, wireType 0");
113+
test.equal(buf[2], 111, "111");
114+
test.equal(buf[3], 1 << 3 | 4, "id 1, wireType 4");
115+
test.same(Test.decode(buf), msg, "and decode back the original message");
116+
test.end();
117+
};})(Test, msg));
118+
119+
// Same but repeated
120+
root = protobuf.parse(`
121+
edition = "2023";
122+
message Message {
123+
uint32 a = 2;
124+
};
125+
message Test {
126+
repeated Message msg = 1 [features.message_encoding = DELIMITED];
127+
}
128+
`).root;
129+
Test = root.resolveAll().lookup("Test");
130+
msg = {
131+
msg: [{
132+
a: 111
133+
},{
134+
a: 112
135+
}]
136+
};
137+
138+
test.test(test.name + " - should encode repeated", (function(Test, msg) { return function(test) {
139+
var buf = Test.encode(msg).finish();
140+
test.equal(buf.length, 8, "a total of 8 bytes");
141+
test.equal(buf[0], 1 << 3 | 3, "id 1, wireType 3");
142+
test.equal(buf[1], 2 << 3 | 0, "id 2, wireType 0");
143+
test.equal(buf[2], 111, "111");
144+
test.equal(buf[3], 1 << 3 | 4, "id 1, wireType 4");
145+
test.equal(buf[4], 1 << 3 | 3, "id 1, wireType 3");
146+
test.equal(buf[5], 2 << 3 | 0, "id 2, wireType 0");
147+
test.equal(buf[6], 112, "112");
148+
test.equal(buf[7], 1 << 3 | 4, "id 1, wireType 4");
149+
test.same(Test.decode(buf), msg, "and decode back the original message");
150+
test.end();
151+
};})(Test, msg));
152+
153+
test.end();
154+
});

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.