diff --git a/.gitignore b/.gitignore index 7a8aed1d..54ed9562 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ # Untracked files +src/AddressBook/bin +src/AddressBook/obj src/ProtocolBuffers/bin/ src/ProtocolBuffers/obj/ src/ProtocolBuffers.Test/bin/ diff --git a/ProtocolBuffers.build b/ProtocolBuffers.build index 2186f91a..97ff2c5d 100644 --- a/ProtocolBuffers.build +++ b/ProtocolBuffers.build @@ -80,6 +80,7 @@ + + + + + + + + /// Builds a person based on user input + /// + static Person PromptForAddress(TextReader input, TextWriter output) { + Person.Builder person = Person.CreateBuilder(); + + output.Write("Enter person ID: "); + person.Id = int.Parse(input.ReadLine()); + + output.Write("Enter name: "); + person.Name = input.ReadLine(); + + output.Write("Enter email address (blank for none): "); + string email = input.ReadLine(); + if (email.Length > 0) { + person.Email = email; + } + + while (true) { + output.Write("Enter a phone number (or leave blank to finish): "); + string number = input.ReadLine(); + if (number.Length == 0) { + break; + } + + Person.Types.PhoneNumber.Builder phoneNumber = + Person.Types.PhoneNumber.CreateBuilder().SetNumber(number); + + output.Write("Is this a mobile, home, or work phone? "); + String type = input.ReadLine(); + switch (type) { + case "mobile": + phoneNumber.Type = Person.Types.PhoneType.MOBILE; + break; + case "home": + phoneNumber.Type = Person.Types.PhoneType.HOME; + break; + case "work": + phoneNumber.Type = Person.Types.PhoneType.WORK; + break; + default: + output.Write("Unknown phone type. Using default."); + break; + } + + person.AddPhone(phoneNumber); + } + return person.Build(); + } + + /// + /// Entry point - loads an existing addressbook or creates a new one, + /// then writes it back to the file. + /// + public static int Main(string[] args) { + if (args.Length != 1) { + Console.Error.WriteLine("Usage: AddPerson ADDRESS_BOOK_FILE"); + return -1; + } + + AddressBook.Builder addressBook = AddressBook.CreateBuilder(); + + if (File.Exists(args[0])) { + using (Stream file = File.OpenRead(args[0])) { + addressBook.MergeFrom(file); + } + } else { + Console.WriteLine("{0}: File not found. Creating a new file.", args[0]); + } + + // Add an address. + addressBook.AddPerson(PromptForAddress(Console.In, Console.Out)); + + // Write the new address book back to disk. + using (Stream output = File.OpenWrite(args[0])) { + addressBook.Build().WriteTo(output); + } + return 0; + } + } +} \ No newline at end of file diff --git a/src/AddressBook/AddressBook.csproj b/src/AddressBook/AddressBook.csproj new file mode 100644 index 00000000..010199cd --- /dev/null +++ b/src/AddressBook/AddressBook.csproj @@ -0,0 +1,63 @@ + + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {A31F5FB2-4FF3-432A-B35B-5CD203606311} + Exe + Properties + Google.ProtocolBuffers.Examples.AddressBook + AddressBook + v2.0 + 512 + + + Google.ProtocolBuffers.Examples.AddressBook.Program + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + {6908BDCE-D925-43F3-94AC-A531E6DF2591} + ProtocolBuffers + + + + + + + + \ No newline at end of file diff --git a/src/AddressBook/AddressBookProtos.cs b/src/AddressBook/AddressBookProtos.cs new file mode 100644 index 00000000..45645eab --- /dev/null +++ b/src/AddressBook/AddressBookProtos.cs @@ -0,0 +1,858 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! + +using pb = global::Google.ProtocolBuffers; +using pbc = global::Google.ProtocolBuffers.Collections; +using pbd = global::Google.ProtocolBuffers.Descriptors; +using scg = global::System.Collections.Generic; +namespace Google.ProtocolBuffers.Examples.AddressBook { + + public static partial class AddressBookProtos { + + #region Descriptor + public static pbd::FileDescriptor Descriptor { + get { return descriptor; } + } + private static readonly pbd::FileDescriptor descriptor = pbd::FileDescriptor.InternalBuildGeneratedFileFrom( + global::System.Convert.FromBase64String( + "Chp0dXRvcmlhbC9hZGRyZXNzYm9vay5wcm90bxIIdHV0b3JpYWwaJGdvb2ds" + + "ZS9wcm90b2J1Zi9jc2hhcnBfb3B0aW9ucy5wcm90bxogZ29vZ2xlL3Byb3Rv" + + "YnVmL2Rlc2NyaXB0b3IucHJvdG8i2gEKBlBlcnNvbhIMCgRuYW1lGAEgAigJ" + + "EgoKAmlkGAIgAigFEg0KBWVtYWlsGAMgASgJEisKBXBob25lGAQgAygLMhwu" + + "dHV0b3JpYWwuUGVyc29uLlBob25lTnVtYmVyGk0KC1Bob25lTnVtYmVyEg4K" + + "Bm51bWJlchgBIAIoCRIuCgR0eXBlGAIgASgOMhoudHV0b3JpYWwuUGVyc29u" + + "LlBob25lVHlwZToESE9NRSIrCglQaG9uZVR5cGUSCgoGTU9CSUxFEAASCAoE" + + "SE9NRRABEggKBFdPUksQAiIvCgtBZGRyZXNzQm9vaxIgCgZwZXJzb24YASAD" + + "KAsyEC50dXRvcmlhbC5QZXJzb25CRUgBwj5ACitHb29nbGUuUHJvdG9jb2xC" + + "dWZmZXJzLkV4YW1wbGVzLkFkZHJlc3NCb29rEhFBZGRyZXNzQm9va1Byb3Rv" + + "cw=="), + new pbd::FileDescriptor[] { + global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.Descriptor, + global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, + }); + #endregion + + #region Static variables + internal static readonly pbd::MessageDescriptor internal__static_tutorial_Person__Descriptor + = Descriptor.MessageTypes[0]; + internal static pb::FieldAccess.FieldAccessorTable internal__static_tutorial_Person__FieldAccessorTable + = new pb::FieldAccess.FieldAccessorTable(internal__static_tutorial_Person__Descriptor, + new string[] { "Name", "Id", "Email", "Phone", }); + internal static readonly pbd::MessageDescriptor internal__static_tutorial_Person_PhoneNumber__Descriptor + = internal__static_tutorial_Person__Descriptor.NestedTypes[0]; + internal static pb::FieldAccess.FieldAccessorTable internal__static_tutorial_Person_PhoneNumber__FieldAccessorTable + = new pb::FieldAccess.FieldAccessorTable(internal__static_tutorial_Person_PhoneNumber__Descriptor, + new string[] { "Number", "Type", }); + internal static readonly pbd::MessageDescriptor internal__static_tutorial_AddressBook__Descriptor + = Descriptor.MessageTypes[1]; + internal static pb::FieldAccess.FieldAccessorTable internal__static_tutorial_AddressBook__FieldAccessorTable + = new pb::FieldAccess.FieldAccessorTable(internal__static_tutorial_AddressBook__Descriptor, + new string[] { "Person", }); + #endregion + } + #region Messages + public sealed partial class Person : pb::GeneratedMessage { + private static readonly Person defaultInstance = new Builder().BuildPartial(); + public static Person DefaultInstance { + get { return defaultInstance; } + } + + public override Person DefaultInstanceForType { + get { return defaultInstance; } + } + + protected override Person ThisMessage { + get { return this; } + } + + public static pbd::MessageDescriptor Descriptor { + get { return global::Google.ProtocolBuffers.Examples.AddressBook.AddressBookProtos.internal__static_tutorial_Person__Descriptor; } + } + + protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors { + get { return global::Google.ProtocolBuffers.Examples.AddressBook.AddressBookProtos.internal__static_tutorial_Person__FieldAccessorTable; } + } + + #region Nested types + public static class Types { + public enum PhoneType { + MOBILE = 0, + HOME = 1, + WORK = 2, + } + + public sealed partial class PhoneNumber : pb::GeneratedMessage { + private static readonly PhoneNumber defaultInstance = new Builder().BuildPartial(); + public static PhoneNumber DefaultInstance { + get { return defaultInstance; } + } + + public override PhoneNumber DefaultInstanceForType { + get { return defaultInstance; } + } + + protected override PhoneNumber ThisMessage { + get { return this; } + } + + public static pbd::MessageDescriptor Descriptor { + get { return global::Google.ProtocolBuffers.Examples.AddressBook.AddressBookProtos.internal__static_tutorial_Person_PhoneNumber__Descriptor; } + } + + protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors { + get { return global::Google.ProtocolBuffers.Examples.AddressBook.AddressBookProtos.internal__static_tutorial_Person_PhoneNumber__FieldAccessorTable; } + } + + private bool hasNumber; + private string number_ = ""; + public bool HasNumber { + get { return hasNumber; } + } + public string Number { + get { return number_; } + } + + private bool hasType; + private global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneType type_ = global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneType.HOME; + public bool HasType { + get { return hasType; } + } + public global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneType Type { + get { return type_; } + } + + public override bool IsInitialized { + get { + if (!hasNumber) return false; + return true; + } + } + + public override void WriteTo(pb::CodedOutputStream output) { + if (HasNumber) { + output.WriteString(1, Number); + } + if (HasType) { + output.WriteEnum(2, (int) Type); + } + UnknownFields.WriteTo(output); + } + + private int memoizedSerializedSize = -1; + public override int SerializedSize { + get { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (HasNumber) { + size += pb::CodedOutputStream.ComputeStringSize(1, Number); + } + if (HasType) { + size += pb::CodedOutputStream.ComputeEnumSize(2, (int) Type); + } + size += UnknownFields.SerializedSize; + memoizedSerializedSize = size; + return size; + } + } + + public static PhoneNumber ParseFrom(pb::ByteString data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static PhoneNumber ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static PhoneNumber ParseFrom(byte[] data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static PhoneNumber ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static PhoneNumber ParseFrom(global::System.IO.Stream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static PhoneNumber ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + public static PhoneNumber ParseFrom(pb::CodedInputStream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static PhoneNumber ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + public static Builder CreateBuilder() { return new Builder(); } + public override Builder CreateBuilderForType() { return new Builder(); } + public static Builder CreateBuilder(PhoneNumber prototype) { + return (Builder) new Builder().MergeFrom(prototype); + } + + public sealed partial class Builder : pb::GeneratedBuilder { + protected override Builder ThisBuilder { + get { return this; } + } + public Builder() {} + + PhoneNumber result = new PhoneNumber(); + + protected override PhoneNumber MessageBeingBuilt { + get { return result; } + } + + public override Builder Clear() { + result = new PhoneNumber(); + return this; + } + + public override Builder Clone() { + return new Builder().MergeFrom(result); + } + + public override pbd::MessageDescriptor DescriptorForType { + get { return PhoneNumber.Descriptor; } + } + + public override PhoneNumber DefaultInstanceForType { + get { return PhoneNumber.DefaultInstance; } + } + + public override PhoneNumber BuildPartial() { + PhoneNumber returnMe = result; + result = null; + return returnMe; + } + + public override Builder MergeFrom(pb::IMessage other) { + if (other is PhoneNumber) { + return MergeFrom((PhoneNumber) other); + } else { + base.MergeFrom(other); + return this; + } + } + + public override Builder MergeFrom(PhoneNumber other) { + if (other == PhoneNumber.DefaultInstance) return this; + if (other.HasNumber) { + Number = other.Number; + } + if (other.HasType) { + Type = other.Type; + } + this.MergeUnknownFields(other.UnknownFields); + return this; + } + + public override Builder MergeFrom(pb::CodedInputStream input) { + return MergeFrom(input, pb::ExtensionRegistry.Empty); + } + + public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + while (true) { + uint tag = input.ReadTag(); + switch (tag) { + case 0: { + this.UnknownFields = unknownFields.Build(); + return this; + } + default: { + if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) { + this.UnknownFields = unknownFields.Build(); + return this; + } + break; + } + case 10: { + Number = input.ReadString(); + break; + } + case 16: { + int rawValue = input.ReadEnum(); + if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneType), rawValue)) { + unknownFields.MergeVarintField(2, (ulong) rawValue); + } else { + Type = (global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneType) rawValue; + } + break; + } + } + } + } + + + public bool HasNumber { + get { return result.HasNumber; } + } + public string Number { + get { return result.Number; } + set { SetNumber(value); } + } + public Builder SetNumber(string value) { + result.hasNumber = true; + result.number_ = value; + return this; + } + public Builder ClearNumber() { + result.hasNumber = false; + result.number_ = ""; + return this; + } + + public bool HasType { + get { return result.HasType; } + } + public global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneType Type { + get { return result.Type; } + set { SetType(value); } + } + public Builder SetType(global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneType value) { + result.hasType = true; + result.type_ = value; + return this; + } + public Builder ClearType() { + result.hasType = false; + result.type_ = global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneType.HOME; + return this; + } + } + } + + } + #endregion + + private bool hasName; + private string name_ = ""; + public bool HasName { + get { return hasName; } + } + public string Name { + get { return name_; } + } + + private bool hasId; + private int id_ = 0; + public bool HasId { + get { return hasId; } + } + public int Id { + get { return id_; } + } + + private bool hasEmail; + private string email_ = ""; + public bool HasEmail { + get { return hasEmail; } + } + public string Email { + get { return email_; } + } + + private pbc::PopsicleList phone_ = new pbc::PopsicleList(); + public scg::IList PhoneList { + get { return phone_; } + } + public int PhoneCount { + get { return phone_.Count; } + } + public global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber GetPhone(int index) { + return phone_[index]; + } + + public override bool IsInitialized { + get { + if (!hasName) return false; + if (!hasId) return false; + foreach (global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber element in PhoneList) { + if (!element.IsInitialized) return false; + } + return true; + } + } + + public override void WriteTo(pb::CodedOutputStream output) { + if (HasName) { + output.WriteString(1, Name); + } + if (HasId) { + output.WriteInt32(2, Id); + } + if (HasEmail) { + output.WriteString(3, Email); + } + foreach (global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber element in PhoneList) { + output.WriteMessage(4, element); + } + UnknownFields.WriteTo(output); + } + + private int memoizedSerializedSize = -1; + public override int SerializedSize { + get { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (HasName) { + size += pb::CodedOutputStream.ComputeStringSize(1, Name); + } + if (HasId) { + size += pb::CodedOutputStream.ComputeInt32Size(2, Id); + } + if (HasEmail) { + size += pb::CodedOutputStream.ComputeStringSize(3, Email); + } + foreach (global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber element in PhoneList) { + size += pb::CodedOutputStream.ComputeMessageSize(4, element); + } + size += UnknownFields.SerializedSize; + memoizedSerializedSize = size; + return size; + } + } + + public static Person ParseFrom(pb::ByteString data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static Person ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static Person ParseFrom(byte[] data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static Person ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static Person ParseFrom(global::System.IO.Stream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static Person ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + public static Person ParseFrom(pb::CodedInputStream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static Person ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + public static Builder CreateBuilder() { return new Builder(); } + public override Builder CreateBuilderForType() { return new Builder(); } + public static Builder CreateBuilder(Person prototype) { + return (Builder) new Builder().MergeFrom(prototype); + } + + public sealed partial class Builder : pb::GeneratedBuilder { + protected override Builder ThisBuilder { + get { return this; } + } + public Builder() {} + + Person result = new Person(); + + protected override Person MessageBeingBuilt { + get { return result; } + } + + public override Builder Clear() { + result = new Person(); + return this; + } + + public override Builder Clone() { + return new Builder().MergeFrom(result); + } + + public override pbd::MessageDescriptor DescriptorForType { + get { return Person.Descriptor; } + } + + public override Person DefaultInstanceForType { + get { return Person.DefaultInstance; } + } + + public override Person BuildPartial() { + result.phone_.MakeReadOnly(); + Person returnMe = result; + result = null; + return returnMe; + } + + public override Builder MergeFrom(pb::IMessage other) { + if (other is Person) { + return MergeFrom((Person) other); + } else { + base.MergeFrom(other); + return this; + } + } + + public override Builder MergeFrom(Person other) { + if (other == Person.DefaultInstance) return this; + if (other.HasName) { + Name = other.Name; + } + if (other.HasId) { + Id = other.Id; + } + if (other.HasEmail) { + Email = other.Email; + } + if (other.phone_.Count != 0) { + base.AddRange(other.phone_, result.phone_); + } + this.MergeUnknownFields(other.UnknownFields); + return this; + } + + public override Builder MergeFrom(pb::CodedInputStream input) { + return MergeFrom(input, pb::ExtensionRegistry.Empty); + } + + public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + while (true) { + uint tag = input.ReadTag(); + switch (tag) { + case 0: { + this.UnknownFields = unknownFields.Build(); + return this; + } + default: { + if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) { + this.UnknownFields = unknownFields.Build(); + return this; + } + break; + } + case 10: { + Name = input.ReadString(); + break; + } + case 16: { + Id = input.ReadInt32(); + break; + } + case 26: { + Email = input.ReadString(); + break; + } + case 34: { + global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber.Builder subBuilder = global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber.CreateBuilder(); + input.ReadMessage(subBuilder, extensionRegistry); + AddPhone(subBuilder.BuildPartial()); + break; + } + } + } + } + + + public bool HasName { + get { return result.HasName; } + } + public string Name { + get { return result.Name; } + set { SetName(value); } + } + public Builder SetName(string value) { + result.hasName = true; + result.name_ = value; + return this; + } + public Builder ClearName() { + result.hasName = false; + result.name_ = ""; + return this; + } + + public bool HasId { + get { return result.HasId; } + } + public int Id { + get { return result.Id; } + set { SetId(value); } + } + public Builder SetId(int value) { + result.hasId = true; + result.id_ = value; + return this; + } + public Builder ClearId() { + result.hasId = false; + result.id_ = 0; + return this; + } + + public bool HasEmail { + get { return result.HasEmail; } + } + public string Email { + get { return result.Email; } + set { SetEmail(value); } + } + public Builder SetEmail(string value) { + result.hasEmail = true; + result.email_ = value; + return this; + } + public Builder ClearEmail() { + result.hasEmail = false; + result.email_ = ""; + return this; + } + + public scg::IList PhoneList { + get { return result.phone_; } + } + public int PhoneCount { + get { return result.PhoneCount; } + } + public global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber GetPhone(int index) { + return result.GetPhone(index); + } + public Builder SetPhone(int index, global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber value) { + result.phone_[index] = value; + return this; + } + public Builder SetPhone(int index, global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber.Builder builderForValue) { + result.phone_[index] = builderForValue.Build(); + return this; + } + public Builder AddPhone(global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber value) { + result.phone_.Add(value); + return this; + } + public Builder AddPhone(global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber.Builder builderForValue) { + result.phone_.Add(builderForValue.Build()); + return this; + } + public Builder AddRangePhone(scg::IEnumerable values) { + base.AddRange(values, result.phone_); + return this; + } + public Builder ClearPhone() { + result.phone_.Clear(); + return this; + } + } + } + + public sealed partial class AddressBook : pb::GeneratedMessage { + private static readonly AddressBook defaultInstance = new Builder().BuildPartial(); + public static AddressBook DefaultInstance { + get { return defaultInstance; } + } + + public override AddressBook DefaultInstanceForType { + get { return defaultInstance; } + } + + protected override AddressBook ThisMessage { + get { return this; } + } + + public static pbd::MessageDescriptor Descriptor { + get { return global::Google.ProtocolBuffers.Examples.AddressBook.AddressBookProtos.internal__static_tutorial_AddressBook__Descriptor; } + } + + protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors { + get { return global::Google.ProtocolBuffers.Examples.AddressBook.AddressBookProtos.internal__static_tutorial_AddressBook__FieldAccessorTable; } + } + + private pbc::PopsicleList person_ = new pbc::PopsicleList(); + public scg::IList PersonList { + get { return person_; } + } + public int PersonCount { + get { return person_.Count; } + } + public global::Google.ProtocolBuffers.Examples.AddressBook.Person GetPerson(int index) { + return person_[index]; + } + + public override bool IsInitialized { + get { + foreach (global::Google.ProtocolBuffers.Examples.AddressBook.Person element in PersonList) { + if (!element.IsInitialized) return false; + } + return true; + } + } + + public override void WriteTo(pb::CodedOutputStream output) { + foreach (global::Google.ProtocolBuffers.Examples.AddressBook.Person element in PersonList) { + output.WriteMessage(1, element); + } + UnknownFields.WriteTo(output); + } + + private int memoizedSerializedSize = -1; + public override int SerializedSize { + get { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + foreach (global::Google.ProtocolBuffers.Examples.AddressBook.Person element in PersonList) { + size += pb::CodedOutputStream.ComputeMessageSize(1, element); + } + size += UnknownFields.SerializedSize; + memoizedSerializedSize = size; + return size; + } + } + + public static AddressBook ParseFrom(pb::ByteString data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static AddressBook ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static AddressBook ParseFrom(byte[] data) { + return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed(); + } + public static AddressBook ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed(); + } + public static AddressBook ParseFrom(global::System.IO.Stream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static AddressBook ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + public static AddressBook ParseFrom(pb::CodedInputStream input) { + return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed(); + } + public static AddressBook ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed(); + } + public static Builder CreateBuilder() { return new Builder(); } + public override Builder CreateBuilderForType() { return new Builder(); } + public static Builder CreateBuilder(AddressBook prototype) { + return (Builder) new Builder().MergeFrom(prototype); + } + + public sealed partial class Builder : pb::GeneratedBuilder { + protected override Builder ThisBuilder { + get { return this; } + } + public Builder() {} + + AddressBook result = new AddressBook(); + + protected override AddressBook MessageBeingBuilt { + get { return result; } + } + + public override Builder Clear() { + result = new AddressBook(); + return this; + } + + public override Builder Clone() { + return new Builder().MergeFrom(result); + } + + public override pbd::MessageDescriptor DescriptorForType { + get { return AddressBook.Descriptor; } + } + + public override AddressBook DefaultInstanceForType { + get { return AddressBook.DefaultInstance; } + } + + public override AddressBook BuildPartial() { + result.person_.MakeReadOnly(); + AddressBook returnMe = result; + result = null; + return returnMe; + } + + public override Builder MergeFrom(pb::IMessage other) { + if (other is AddressBook) { + return MergeFrom((AddressBook) other); + } else { + base.MergeFrom(other); + return this; + } + } + + public override Builder MergeFrom(AddressBook other) { + if (other == AddressBook.DefaultInstance) return this; + if (other.person_.Count != 0) { + base.AddRange(other.person_, result.person_); + } + this.MergeUnknownFields(other.UnknownFields); + return this; + } + + public override Builder MergeFrom(pb::CodedInputStream input) { + return MergeFrom(input, pb::ExtensionRegistry.Empty); + } + + public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) { + pb::UnknownFieldSet.Builder unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields); + while (true) { + uint tag = input.ReadTag(); + switch (tag) { + case 0: { + this.UnknownFields = unknownFields.Build(); + return this; + } + default: { + if (!ParseUnknownField(input, unknownFields, extensionRegistry, tag)) { + this.UnknownFields = unknownFields.Build(); + return this; + } + break; + } + case 10: { + global::Google.ProtocolBuffers.Examples.AddressBook.Person.Builder subBuilder = global::Google.ProtocolBuffers.Examples.AddressBook.Person.CreateBuilder(); + input.ReadMessage(subBuilder, extensionRegistry); + AddPerson(subBuilder.BuildPartial()); + break; + } + } + } + } + + + public scg::IList PersonList { + get { return result.person_; } + } + public int PersonCount { + get { return result.PersonCount; } + } + public global::Google.ProtocolBuffers.Examples.AddressBook.Person GetPerson(int index) { + return result.GetPerson(index); + } + public Builder SetPerson(int index, global::Google.ProtocolBuffers.Examples.AddressBook.Person value) { + result.person_[index] = value; + return this; + } + public Builder SetPerson(int index, global::Google.ProtocolBuffers.Examples.AddressBook.Person.Builder builderForValue) { + result.person_[index] = builderForValue.Build(); + return this; + } + public Builder AddPerson(global::Google.ProtocolBuffers.Examples.AddressBook.Person value) { + result.person_.Add(value); + return this; + } + public Builder AddPerson(global::Google.ProtocolBuffers.Examples.AddressBook.Person.Builder builderForValue) { + result.person_.Add(builderForValue.Build()); + return this; + } + public Builder AddRangePerson(scg::IEnumerable values) { + base.AddRange(values, result.person_); + return this; + } + public Builder ClearPerson() { + result.person_.Clear(); + return this; + } + } + } + + #endregion + +} diff --git a/src/AddressBook/ListPeople.cs b/src/AddressBook/ListPeople.cs new file mode 100644 index 00000000..b2a9a964 --- /dev/null +++ b/src/AddressBook/ListPeople.cs @@ -0,0 +1,57 @@ + +using System; +using System.IO; + +namespace Google.ProtocolBuffers.Examples.AddressBook { + class ListPeople { + /// + /// Iterates though all people in the AddressBook and prints info about them. + /// + static void Print(AddressBook addressBook) { + foreach (Person person in addressBook.PersonList) { + Console.WriteLine("Person ID: {0}", person.Id); + Console.WriteLine(" Name: {0}", person.Name); + if (person.HasEmail) { + Console.WriteLine(" E-mail address: {0}", person.Email); + } + + foreach (Person.Types.PhoneNumber phoneNumber in person.PhoneList) { + switch (phoneNumber.Type) { + case Person.Types.PhoneType.MOBILE: + Console.Write(" Mobile phone #: "); + break; + case Person.Types.PhoneType.HOME: + Console.Write(" Home phone #: "); + break; + case Person.Types.PhoneType.WORK: + Console.Write(" Work phone #: "); + break; + } + Console.WriteLine(phoneNumber.Number); + } + } + } + + /// + /// Entry point - loads the addressbook and then displays it. + /// + public static int Main(string[] args) { + if (args.Length != 1) { + Console.Error.WriteLine("Usage: ListPeople ADDRESS_BOOK_FILE"); + return 1; + } + + if (!File.Exists(args[0])) { + Console.WriteLine("{0} doesn't exist. Add a person to create the file first.", args[0]); + return 0; + } + + // Read the existing address book. + using (Stream stream = File.OpenRead(args[0])) { + AddressBook addressBook = AddressBook.ParseFrom(stream); + Print(addressBook); + } + return 0; + } + } +} diff --git a/src/AddressBook/Program.cs b/src/AddressBook/Program.cs new file mode 100644 index 00000000..b3e10cbb --- /dev/null +++ b/src/AddressBook/Program.cs @@ -0,0 +1,55 @@ +using System; + +namespace Google.ProtocolBuffers.Examples.AddressBook +{ + /// + /// Entry point. Repeatedly prompts user for an action to take, delegating actual behaviour + /// to individual actions. Each action has its own Main method, so that it can be used as an + /// invidual complete program. + /// + class Program { + static int Main(string[] args) { + if (args.Length > 1) { + Console.Error.WriteLine("Usage: AddressBook [file]"); + Console.Error.WriteLine("If the filename isn't specified, \"addressbook.data\" is used instead."); + return 1; + } + string addressBookFile = args.Length > 0 ? args[0] : "addressbook.data"; + + bool stopping = false; + while (!stopping) { + Console.WriteLine("Options:"); + Console.WriteLine(" L: List contents"); + Console.WriteLine(" A: Add new person"); + Console.WriteLine(" Q: Quit"); + Console.Write("Action? "); + Console.Out.Flush(); + char choice = Console.ReadKey().KeyChar; + Console.WriteLine(); + try { + switch (choice) { + case 'A': + case 'a': + AddPerson.Main(new string[] { addressBookFile }); + break; + case 'L': + case 'l': + ListPeople.Main(new string[] { addressBookFile }); + break; + case 'Q': + case 'q': + stopping = true; + break; + default: + Console.WriteLine("Unknown option: {0}", choice); + break; + } + } catch (Exception e) { + Console.WriteLine("Exception executing action: {0}", e); + } + Console.WriteLine(); + } + return 0; + } + } +} \ No newline at end of file diff --git a/src/AddressBook/Properties/AssemblyInfo.cs b/src/AddressBook/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..aac45d58 --- /dev/null +++ b/src/AddressBook/Properties/AssemblyInfo.cs @@ -0,0 +1,35 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("AddressBook")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("AddressBook")] +[assembly: AssemblyCopyright("Copyright © 2008")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("57123e6e-28d1-4b9e-80a5-5e720df8035a")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/src/AddressBook/app.config b/src/AddressBook/app.config new file mode 100644 index 00000000..df20690a --- /dev/null +++ b/src/AddressBook/app.config @@ -0,0 +1,3 @@ + + + diff --git a/src/ProtocolBuffers.sln b/src/ProtocolBuffers.sln index c4f9877b..c2cd0bf6 100644 --- a/src/ProtocolBuffers.sln +++ b/src/ProtocolBuffers.sln @@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProtoGen", "ProtoGen\ProtoG EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProtoGen.Test", "ProtoGen.Test\ProtoGen.Test.csproj", "{C268DA4C-4004-47DA-AF23-44C983281A68}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AddressBook", "AddressBook\AddressBook.csproj", "{A31F5FB2-4FF3-432A-B35B-5CD203606311}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -31,6 +33,10 @@ Global {C268DA4C-4004-47DA-AF23-44C983281A68}.Debug|Any CPU.Build.0 = Debug|Any CPU {C268DA4C-4004-47DA-AF23-44C983281A68}.Release|Any CPU.ActiveCfg = Release|Any CPU {C268DA4C-4004-47DA-AF23-44C983281A68}.Release|Any CPU.Build.0 = Release|Any CPU + {A31F5FB2-4FF3-432A-B35B-5CD203606311}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A31F5FB2-4FF3-432A-B35B-5CD203606311}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A31F5FB2-4FF3-432A-B35B-5CD203606311}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A31F5FB2-4FF3-432A-B35B-5CD203606311}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/todo.txt b/todo.txt index f3d6fb4d..04118790 100644 --- a/todo.txt +++ b/todo.txt @@ -1,9 +1,8 @@ Current task list (not in order) -Diff stuff - - Performance framework -- Optionally remove dependencies to core and csharp options +- Optionally remove dependencies to core and csharp options (2.0.3 + will remove core dependency) - Remove multifile support - Mono support - Docs