| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 | 
							- package main
 
- import (
 
- 	"bufio"
 
- 	"fmt"
 
- 	"io"
 
- 	"io/ioutil"
 
- 	"log"
 
- 	"os"
 
- 	"strings"
 
- 	"github.com/golang/protobuf/proto"
 
- 	pb "github.com/google/protobuf/examples/tutorial"
 
- )
 
- func promptForAddress(r io.Reader) (*pb.Person, error) {
 
- 	// A protocol buffer can be created like any struct.
 
- 	p := &pb.Person{}
 
- 	rd := bufio.NewReader(r)
 
- 	fmt.Print("Enter person ID number: ")
 
- 	// An int32 field in the .proto file is represented as an int32 field
 
- 	// in the generated Go struct.
 
- 	if _, err := fmt.Fscanf(rd, "%d\n", &p.Id); err != nil {
 
- 		return p, err
 
- 	}
 
- 	fmt.Print("Enter name: ")
 
- 	name, err := rd.ReadString('\n')
 
- 	if err != nil {
 
- 		return p, err
 
- 	}
 
- 	// A string field in the .proto file results in a string field in Go.
 
- 	// We trim the whitespace because rd.ReadString includes the trailing
 
- 	// newline character in its output.
 
- 	p.Name = strings.TrimSpace(name)
 
- 	fmt.Print("Enter email address (blank for none): ")
 
- 	email, err := rd.ReadString('\n')
 
- 	if err != nil {
 
- 		return p, err
 
- 	}
 
- 	p.Email = strings.TrimSpace(email)
 
- 	for {
 
- 		fmt.Print("Enter a phone number (or leave blank to finish): ")
 
- 		phone, err := rd.ReadString('\n')
 
- 		if err != nil {
 
- 			return p, err
 
- 		}
 
- 		phone = strings.TrimSpace(phone)
 
- 		if phone == "" {
 
- 			break
 
- 		}
 
- 		// The PhoneNumber message type is nested within the Person
 
- 		// message in the .proto file.  This results in a Go struct
 
- 		// named using the name of the parent prefixed to the name of
 
- 		// the nested message.  Just as with pb.Person, it can be
 
- 		// created like any other struct.
 
- 		pn := &pb.Person_PhoneNumber{
 
- 			Number: phone,
 
- 		}
 
- 		fmt.Print("Is this a mobile, home, or work phone? ")
 
- 		ptype, err := rd.ReadString('\n')
 
- 		if err != nil {
 
- 			return p, err
 
- 		}
 
- 		ptype = strings.TrimSpace(ptype)
 
- 		// A proto enum results in a Go constant for each enum value.
 
- 		switch ptype {
 
- 		case "mobile":
 
- 			pn.Type = pb.Person_MOBILE
 
- 		case "home":
 
- 			pn.Type = pb.Person_HOME
 
- 		case "work":
 
- 			pn.Type = pb.Person_WORK
 
- 		default:
 
- 			fmt.Printf("Unknown phone type %q.  Using default.\n", ptype)
 
- 		}
 
- 		// A repeated proto field maps to a slice field in Go.  We can
 
- 		// append to it like any other slice.
 
- 		p.Phones = append(p.Phones, pn)
 
- 	}
 
- 	return p, nil
 
- }
 
- // Main reads the entire address book from a file, adds one person based on
 
- // user input, then writes it back out to the same file.
 
- func main() {
 
- 	if len(os.Args) != 2 {
 
- 		log.Fatalf("Usage:  %s ADDRESS_BOOK_FILE\n", os.Args[0])
 
- 	}
 
- 	fname := os.Args[1]
 
- 	// Read the existing address book.
 
- 	in, err := ioutil.ReadFile(fname)
 
- 	if err != nil {
 
- 		if os.IsNotExist(err) {
 
- 			fmt.Printf("%s: File not found.  Creating new file.\n", fname)
 
- 		} else {
 
- 			log.Fatalln("Error reading file:", err)
 
- 		}
 
- 	}
 
- 	// [START marshal_proto]
 
- 	book := &pb.AddressBook{}
 
- 	// [START_EXCLUDE]
 
- 	if err := proto.Unmarshal(in, book); err != nil {
 
- 		log.Fatalln("Failed to parse address book:", err)
 
- 	}
 
- 	// Add an address.
 
- 	addr, err := promptForAddress(os.Stdin)
 
- 	if err != nil {
 
- 		log.Fatalln("Error with address:", err)
 
- 	}
 
- 	book.People = append(book.People, addr)
 
- 	// [END_EXCLUDE]
 
- 	// Write the new address book back to disk.
 
- 	out, err := proto.Marshal(book)
 
- 	if err != nil {
 
- 		log.Fatalln("Failed to encode address book:", err)
 
- 	}
 
- 	if err := ioutil.WriteFile(fname, out, 0644); err != nil {
 
- 		log.Fatalln("Failed to write address book:", err)
 
- 	}
 
- 	// [END marshal_proto]
 
- }
 
 
  |