diff options
| author | Oskari Timperi <oskari.timperi@iki.fi> | 2018-04-02 11:38:35 +0300 |
|---|---|---|
| committer | Oskari Timperi <oskari.timperi@iki.fi> | 2018-04-02 11:39:36 +0300 |
| commit | e1f5d2e73a1f305ca003b24f6025615abade5d64 (patch) | |
| tree | 3ee8589b78cdda9cf01e54f3d2248db6dcb5af15 | |
| parent | 2427dd3c04c37dd78a54a73da41141b74182590a (diff) | |
| download | nimpb-e1f5d2e73a1f305ca003b24f6025615abade5d64.tar.gz nimpb-e1f5d2e73a1f305ca003b24f6025615abade5d64.zip | |
Fix packed field size calculation
The size was calculated based on wire type. We need to calculate based on
field type because for sint32/sint64 we need to zigzag encode the value
before calculating the size of varint.
| -rw-r--r-- | generator/protoc_gen_nim.nim | 7 | ||||
| -rw-r--r-- | src/protobuf/stream.nim | 21 |
2 files changed, 19 insertions, 9 deletions
diff --git a/generator/protoc_gen_nim.nim b/generator/protoc_gen_nim.nim index d371859..cec2761 100644 --- a/generator/protoc_gen_nim.nim +++ b/generator/protoc_gen_nim.nim @@ -206,6 +206,9 @@ proc wiretypeStr(field: Field): string = of FieldDescriptorProtoType.TypeSInt32: result &= "Varint" of FieldDescriptorProtoType.TypeSInt64: result &= "Varint" +proc fieldTypeStr(field: Field): string = + result = "FieldType." & $field.ftype + proc isKeyword(s: string): bool = case s of "addr", "and", "as", "asm", "bind", "block", "break", "case", "cast", @@ -593,7 +596,7 @@ iterator genWriteMessageProc(msg: Message): string = if field.packed: yield indent(&"if has{field.name}(message):", 4) yield indent(&"writeTag(stream, {field.number}, WireType.LengthDelimited)", 8) - yield indent(&"writeVarint(stream, packedFieldSize(message.{field.name}, {wiretypeStr(field)}))", 8) + yield indent(&"writeVarint(stream, packedFieldSize(message.{field.name}, {field.fieldTypeStr}))", 8) yield indent(&"for value in message.{field.name}:", 8) yield indent(&"{writer}(stream, value)", 12) else: @@ -748,7 +751,7 @@ iterator genSizeOfMessageProc(msg: Message): string = if has{field.name}(message): let sizeOfTag = sizeOfUInt32(uint32(makeTag({field.number}, WireType.LengthDelimited))) - sizeOfData = packedFieldSize(message.{field.name}, {wiretypeStr(field)}) + sizeOfData = packedFieldSize(message.{field.name}, {field.fieldTypeStr}) sizeOfSize = sizeOfUInt64(sizeOfData) result = sizeOfTag + sizeOfData + sizeOfSize""", 4) else: diff --git a/src/protobuf/stream.nim b/src/protobuf/stream.nim index 9d843e6..824ad60 100644 --- a/src/protobuf/stream.nim +++ b/src/protobuf/stream.nim @@ -274,17 +274,24 @@ proc sizeOfVarint[T](value: T): uint64 = inc(result) inc(result) -proc packedFieldSize*[T](values: seq[T], wiretype: WireType): uint64 = - case wiretype - of WireType.Fixed32: - result = uint64(len(values)) * 4 - of WireType.Fixed64: +proc packedFieldSize*[T](values: seq[T], fieldtype: FieldType): uint64 = + case fieldtype + of FieldType.Fixed64, FieldType.SFixed64, FieldType.Double: result = uint64(len(values)) * 8 - of WireType.Varint: + of FieldType.Fixed32, FieldType.SFixed32, FieldType.Float: + result = uint64(len(values)) * 4 + of FieldType.Int64, FieldType.UInt64, FieldType.Int32, FieldType.Bool, + FieldType.UInt32, FieldType.Enum: for value in values: result += sizeOfVarint(value) + of FieldType.SInt32: + for value in values: + result += sizeOfVarint(zigzagEncode(int32(value))) + of FieldType.SInt64: + for value in values: + result += sizeOfVarint(zigzagEncode(int64(value))) else: - raise newException(Exception, "invalid wiretype") + raise newException(Exception, "invalid fieldtype") proc sizeOfString*(s: string): uint64 = result = sizeOfVarint(len(s).uint64) + len(s).uint64 |
