diff options
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/addressbook/addressbook_pb.nim | 293 | ||||
| -rw-r--r-- | examples/addressbook/phonenumber_pb.nim | 142 | ||||
| -rw-r--r-- | examples/addressbook/reader.nim | 3 | ||||
| -rw-r--r-- | examples/addressbook/writer.nim | 14 |
4 files changed, 353 insertions, 99 deletions
diff --git a/examples/addressbook/addressbook_pb.nim b/examples/addressbook/addressbook_pb.nim index 3e991f0..6ec734a 100644 --- a/examples/addressbook/addressbook_pb.nim +++ b/examples/addressbook/addressbook_pb.nim @@ -2,64 +2,245 @@ import intsets -import protobuf/gen import protobuf/stream import protobuf/types import phonenumber_pb -const - PersonDesc = MessageDesc( - name: "Person", - fields: @[ - FieldDesc( - name: "name", - number: 1, - ftype: FieldType.String, - label: FieldLabel.Optional, - typeName: "", - packed: false, - ), - FieldDesc( - name: "id", - number: 2, - ftype: FieldType.Int32, - label: FieldLabel.Optional, - typeName: "", - packed: false, - ), - FieldDesc( - name: "email", - number: 3, - ftype: FieldType.String, - label: FieldLabel.Optional, - typeName: "", - packed: false, - ), - FieldDesc( - name: "phones", - number: 4, - ftype: FieldType.Message, - label: FieldLabel.Repeated, - typeName: "PhoneNumber", - packed: false, - ), - ] - ) - AddressBookDesc = MessageDesc( - name: "AddressBook", - fields: @[ - FieldDesc( - name: "people", - number: 1, - ftype: FieldType.Message, - label: FieldLabel.Repeated, - typeName: "Person", - packed: false, - ), - ] - ) -generateMessageType(PersonDesc) -generateMessageProcs(PersonDesc) -generateMessageType(AddressBookDesc) -generateMessageProcs(AddressBookDesc) +type + Person* = ref PersonObj + PersonObj* = object of RootObj + hasField: IntSet + name: string + id: int32 + email: string + phones: seq[PhoneNumber] + AddressBook* = ref AddressBookObj + AddressBookObj* = object of RootObj + hasField: IntSet + people: seq[Person] + +proc newPerson*(): Person = + new(result) + result.hasField = initIntSet() + result.name = "" + result.id = 0 + result.email = "" + result.phones = @[] + +proc clearname*(message: Person) = + message.name = "" + excl(message.hasField, 1) + +proc hasname*(message: Person): bool = + result = contains(message.hasField, 1) + +proc setname*(message: Person, value: string) = + message.name = value + incl(message.hasField, 1) + +proc name*(message: Person): string {.inline.} = + message.name + +proc `name=`*(message: Person, value: string) {.inline.} = + setname(message, value) + +proc clearid*(message: Person) = + message.id = 0 + excl(message.hasField, 2) + +proc hasid*(message: Person): bool = + result = contains(message.hasField, 2) + +proc setid*(message: Person, value: int32) = + message.id = value + incl(message.hasField, 2) + +proc id*(message: Person): int32 {.inline.} = + message.id + +proc `id=`*(message: Person, value: int32) {.inline.} = + setid(message, value) + +proc clearemail*(message: Person) = + message.email = "" + excl(message.hasField, 3) + +proc hasemail*(message: Person): bool = + result = contains(message.hasField, 3) + +proc setemail*(message: Person, value: string) = + message.email = value + incl(message.hasField, 3) + +proc email*(message: Person): string {.inline.} = + message.email + +proc `email=`*(message: Person, value: string) {.inline.} = + setemail(message, value) + +proc clearphones*(message: Person) = + message.phones = @[] + excl(message.hasField, 4) + +proc hasphones*(message: Person): bool = + result = contains(message.hasField, 4) + +proc setphones*(message: Person, value: seq[PhoneNumber]) = + message.phones = value + incl(message.hasField, 4) + +proc addphones*(message: Person, value: PhoneNumber) = + add(message.phones, value) + incl(message.hasField, 4) + +proc phones*(message: Person): seq[PhoneNumber] {.inline.} = + message.phones + +proc `phones=`*(message: Person, value: seq[PhoneNumber]) {.inline.} = + setphones(message, value) + +proc sizeOfPerson*(message: Person): uint64 = + if hasname(message): + let + sizeOfField = sizeOfString(message.name) + sizeOfTag = sizeOfUInt32(uint32(makeTag(1, WireType.LengthDelimited))) + result = result + sizeOfField + sizeOfTag + if hasid(message): + let + sizeOfField = sizeOfInt32(message.id) + sizeOfTag = sizeOfUInt32(uint32(makeTag(2, WireType.Varint))) + result = result + sizeOfField + sizeOfTag + if hasemail(message): + let + sizeOfField = sizeOfString(message.email) + sizeOfTag = sizeOfUInt32(uint32(makeTag(3, WireType.LengthDelimited))) + result = result + sizeOfField + sizeOfTag + for value in message.phones: + let + sizeOfValue = sizeOfPhoneNumber(value) + sizeOfTag = sizeOfUInt32(uint32(makeTag(4, WireType.LengthDelimited))) + result = result + sizeOfValue + sizeOfTag + + result = result + sizeOfUInt64(sizeOfValue) + +proc writePerson*(stream: ProtobufStream, message: Person) = + if hasname(message): + writeTag(stream, 1, WireType.LengthDelimited) + writeString(stream, message.name) + if hasid(message): + writeTag(stream, 2, WireType.Varint) + writeInt32(stream, message.id) + if hasemail(message): + writeTag(stream, 3, WireType.LengthDelimited) + writeString(stream, message.email) + for value in message.phones: + writeTag(stream, 4, WireType.LengthDelimited) + writeVarint(stream, sizeOfPhoneNumber(value)) + writePhoneNumber(stream, value) + +proc readPerson*(stream: ProtobufStream): Person = + result = newPerson() + while not atEnd(stream): + let + tag = readTag(stream) + wireType = getTagWireType(tag) + case getTagFieldNumber(tag) + of 1: + setname(result, readString(stream)) + of 2: + setid(result, readInt32(stream)) + of 3: + setemail(result, readString(stream)) + of 4: + let + size = readVarint(stream) + data = readStr(stream, int(size)) + pbs = newProtobufStream(newStringStream(data)) + addphones(result, readPhoneNumber(pbs)) + else: skipField(stream, wireType) + +proc serialize*(message: Person): string = + let + ss = newStringStream() + pbs = newProtobufStream(ss) + writePerson(pbs, message) + result = ss.data + +proc newPerson*(data: string): Person = + let + ss = newStringStream(data) + pbs = newProtobufStream(ss) + result = readPerson(pbs) + + +proc newAddressBook*(): AddressBook = + new(result) + result.hasField = initIntSet() + result.people = @[] + +proc clearpeople*(message: AddressBook) = + message.people = @[] + excl(message.hasField, 1) + +proc haspeople*(message: AddressBook): bool = + result = contains(message.hasField, 1) + +proc setpeople*(message: AddressBook, value: seq[Person]) = + message.people = value + incl(message.hasField, 1) + +proc addpeople*(message: AddressBook, value: Person) = + add(message.people, value) + incl(message.hasField, 1) + +proc people*(message: AddressBook): seq[Person] {.inline.} = + message.people + +proc `people=`*(message: AddressBook, value: seq[Person]) {.inline.} = + setpeople(message, value) + +proc sizeOfAddressBook*(message: AddressBook): uint64 = + for value in message.people: + let + sizeOfValue = sizeOfPerson(value) + sizeOfTag = sizeOfUInt32(uint32(makeTag(1, WireType.LengthDelimited))) + result = result + sizeOfValue + sizeOfTag + + result = result + sizeOfUInt64(sizeOfValue) + +proc writeAddressBook*(stream: ProtobufStream, message: AddressBook) = + for value in message.people: + writeTag(stream, 1, WireType.LengthDelimited) + writeVarint(stream, sizeOfPerson(value)) + writePerson(stream, value) + +proc readAddressBook*(stream: ProtobufStream): AddressBook = + result = newAddressBook() + while not atEnd(stream): + let + tag = readTag(stream) + wireType = getTagWireType(tag) + case getTagFieldNumber(tag) + of 1: + let + size = readVarint(stream) + data = readStr(stream, int(size)) + pbs = newProtobufStream(newStringStream(data)) + addpeople(result, readPerson(pbs)) + else: skipField(stream, wireType) + +proc serialize*(message: AddressBook): string = + let + ss = newStringStream() + pbs = newProtobufStream(ss) + writeAddressBook(pbs, message) + result = ss.data + +proc newAddressBook*(data: string): AddressBook = + let + ss = newStringStream(data) + pbs = newProtobufStream(ss) + result = readAddressBook(pbs) + + diff --git a/examples/addressbook/phonenumber_pb.nim b/examples/addressbook/phonenumber_pb.nim index 5c183b3..e23cf36 100644 --- a/examples/addressbook/phonenumber_pb.nim +++ b/examples/addressbook/phonenumber_pb.nim @@ -2,41 +2,113 @@ import intsets -import protobuf/gen import protobuf/stream import protobuf/types -const - PhoneTypeDesc = EnumDesc( - name: "PhoneType", - values: @[ - EnumValueDesc(name: "MOBILE", number: 0), - EnumValueDesc(name: "HOME", number: 1), - EnumValueDesc(name: "WORK", number: 2), - ] - ) - PhoneNumberDesc = MessageDesc( - name: "PhoneNumber", - fields: @[ - FieldDesc( - name: "number", - number: 1, - ftype: FieldType.String, - label: FieldLabel.Optional, - typeName: "", - packed: false, - ), - FieldDesc( - name: "type", - number: 2, - ftype: FieldType.Enum, - label: FieldLabel.Optional, - typeName: "PhoneType", - packed: false, - ), - ] - ) -generateEnumType(PhoneTypeDesc) -generateEnumProcs(PhoneTypeDesc) -generateMessageType(PhoneNumberDesc) -generateMessageProcs(PhoneNumberDesc) +type + PhoneType* {.pure.} = enum + MOBILE = 0 + HOME = 1 + WORK = 2 + PhoneNumber* = ref PhoneNumberObj + PhoneNumberObj* = object of RootObj + hasField: IntSet + number: string + ftype: PhoneType + +proc readPhoneType*(stream: ProtobufStream): PhoneType = + PhoneType(readUInt32(stream)) + +proc writePhoneType*(stream: ProtobufStream, value: PhoneType) = + writeUInt32(stream, uint32(value)) + +proc sizeOfPhoneType*(value: PhoneType): uint64 = + sizeOfUInt32(uint32(value)) + +proc newPhoneNumber*(): PhoneNumber = + new(result) + result.hasField = initIntSet() + result.number = "" + result.ftype = PhoneType(0) + +proc clearnumber*(message: PhoneNumber) = + message.number = "" + excl(message.hasField, 1) + +proc hasnumber*(message: PhoneNumber): bool = + result = contains(message.hasField, 1) + +proc setnumber*(message: PhoneNumber, value: string) = + message.number = value + incl(message.hasField, 1) + +proc number*(message: PhoneNumber): string {.inline.} = + message.number + +proc `number=`*(message: PhoneNumber, value: string) {.inline.} = + setnumber(message, value) + +proc clearftype*(message: PhoneNumber) = + message.ftype = PhoneType(0) + excl(message.hasField, 2) + +proc hasftype*(message: PhoneNumber): bool = + result = contains(message.hasField, 2) + +proc setftype*(message: PhoneNumber, value: PhoneType) = + message.ftype = value + incl(message.hasField, 2) + +proc ftype*(message: PhoneNumber): PhoneType {.inline.} = + message.ftype + +proc `ftype=`*(message: PhoneNumber, value: PhoneType) {.inline.} = + setftype(message, value) + +proc sizeOfPhoneNumber*(message: PhoneNumber): uint64 = + if hasnumber(message): + let + sizeOfField = sizeOfString(message.number) + sizeOfTag = sizeOfUInt32(uint32(makeTag(1, WireType.LengthDelimited))) + result = result + sizeOfField + sizeOfTag + if hasftype(message): + let + sizeOfField = sizeOfPhoneType(message.ftype) + sizeOfTag = sizeOfUInt32(uint32(makeTag(2, WireType.Varint))) + result = result + sizeOfField + sizeOfTag + +proc writePhoneNumber*(stream: ProtobufStream, message: PhoneNumber) = + if hasnumber(message): + writeTag(stream, 1, WireType.LengthDelimited) + writeString(stream, message.number) + if hasftype(message): + writeTag(stream, 2, WireType.Varint) + writePhoneType(stream, message.ftype) + +proc readPhoneNumber*(stream: ProtobufStream): PhoneNumber = + result = newPhoneNumber() + while not atEnd(stream): + let + tag = readTag(stream) + wireType = getTagWireType(tag) + case getTagFieldNumber(tag) + of 1: + setnumber(result, readString(stream)) + of 2: + setftype(result, readPhoneType(stream)) + else: skipField(stream, wireType) + +proc serialize*(message: PhoneNumber): string = + let + ss = newStringStream() + pbs = newProtobufStream(ss) + writePhoneNumber(pbs, message) + result = ss.data + +proc newPhoneNumber*(data: string): PhoneNumber = + let + ss = newStringStream(data) + pbs = newProtobufStream(ss) + result = readPhoneNumber(pbs) + + diff --git a/examples/addressbook/reader.nim b/examples/addressbook/reader.nim index 4db86cc..ebbe773 100644 --- a/examples/addressbook/reader.nim +++ b/examples/addressbook/reader.nim @@ -4,6 +4,7 @@ import strformat import protobuf/stream import addressbook_pb +import phonenumber_pb let pbsi = newProtobufStream(newFileStream("addressbook.dat")) @@ -16,4 +17,4 @@ for person in addressBook.people: echo(&"Email: {person.email}") echo("Phones:") for phone in person.phones: - echo(&" {phone.type} {phone.number}") + echo(&" {phone.ftype} {phone.number}") diff --git a/examples/addressbook/writer.nim b/examples/addressbook/writer.nim index 8dbac12..0a3c866 100644 --- a/examples/addressbook/writer.nim +++ b/examples/addressbook/writer.nim @@ -8,19 +8,19 @@ import phonenumber_pb let addressBook = newAddressBook() let john = newPerson() -setName(john, "John Doe") -setId(john, 1) -setEmail(john, "john.doe@example.com") +john.name = "John Doe" +john.id = 1 +john.email = "john.doe@example.com" addPeople(addressBook, john) let johnPhone1 = newPhoneNumber() -setNumber(johnPhone1, "1234") -setType(johnPhone1, MOBILE) +johnPhone1.number = "1234" +johnPhone1.ftype = PhoneType.MOBILE addPhones(john, johnPhone1) let johnPhone2 = newPhoneNumber() setNumber(johnPhone2, "5566") -setType(johnPhone2, WORK) +setFType(johnPhone2, WORK) addPhones(john, johnPhone2) let jane = newPerson() @@ -31,7 +31,7 @@ addPeople(addressBook, jane) let janePhone1 = newPhoneNumber() setNumber(janePhone1, "1432") -setType(janePhone1, HOME) +setFType(janePhone1, HOME) addPhones(jane, janePhone1) let pbso = newProtobufStream(newFileStream("addressbook.dat", fmWrite)) |
