func PrintLocationsAsProto(locations map[string]Location) []byte { locProto := &locationProto.LocationInfo{ make([]*locationProto.Location, len(locations)), nil} loc := locProto.Location for name, location := range locations { loc[0] = &locationProto.Location{ proto.String(name), proto.Float64(float64(location.lat)), proto.Float64(float64(location.lng)), nil, proto.Float64(float64(location.accuracy)), proto.Int64(location.timestamp), nil} loc = loc[1:] } data, _ := proto.Marshal(locProto) return data }
func main() { m1 := &test.Member{ Name: proto.String("Linus"), Age: proto.Int32(99), } m1.Skills = []test.Skill{test.Skill_ASM, test.Skill_C} m1_data, err := proto.Marshal(m1) if err != nil { log.Fatal("marshaling error: ", err) os.Exit(1) } fmt.Println("m1: ", m1) fmt.Println("m1.Skills: ", m1.Skills) fmt.Println("actual data: ", m1_data) println("=== unmarshalling m1 into m2 ===") m2 := &test.Member{} proto.Unmarshal(m1_data, m2) fmt.Println("m2: ", m2) port := 9090 fmt.Println("=== END EXAMPLES / SERVER STARTING at %d ===", port) service := fmt.Sprintf(":%d", port) tcpAddr, err := net.ResolveTCPAddr("ip4", service) checkError(err) listener, err := net.ListenTCP("tcp", tcpAddr) checkError(err) for { conn, err := listener.Accept() checkError(err) input := make([]byte, 1024) n, err := conn.Read(input) input = input[:n] fmt.Println("input: ", input) club := &test.Club{} err = proto.Unmarshal(input, club) checkError(err) sum := int32(0) fmt.Println("len: ", len(club.Member)) for _, m := range club.Member { sum += *m.Age } avg := float64(sum) / float64(len(club.Member)) fmt.Printf("avg age: %f (sum: %d)\n", avg, sum) reply := &test.Reply{Average: proto.Float64(avg)} out_data, err := proto.Marshal(reply) conn.Write(out_data) // don't care about return value conn.Close() // we're finished with this client } }
// valueToProto converts a named value to a newly allocated Property. // The returned error string is empty on success. func valueToProto(defaultAppID, name string, v reflect.Value, multiple bool) (p *pb.Property, errStr string) { var ( pv pb.PropertyValue unsupported bool ) switch v.Kind() { case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: pv.Int64Value = proto.Int64(v.Int()) case reflect.Bool: pv.BooleanValue = proto.Bool(v.Bool()) case reflect.String: pv.StringValue = proto.String(v.String()) case reflect.Float32, reflect.Float64: pv.DoubleValue = proto.Float64(v.Float()) case reflect.Ptr: if k, ok := v.Interface().(*Key); ok { if k == nil { return nil, nilKeyErrStr } pv.Referencevalue = keyToReferenceValue(defaultAppID, k) } else { unsupported = true } case reflect.Slice: if b, ok := v.Interface().([]byte); ok { pv.StringValue = proto.String(string(b)) } else { // nvToProto should already catch slice values. // If we get here, we have a slice of slice values. unsupported = true } default: unsupported = true } if unsupported { return nil, "unsupported datastore value type: " + v.Type().String() } p = &pb.Property{ Name: proto.String(name), Value: &pv, Multiple: proto.Bool(multiple), } switch v.Interface().(type) { case []byte: p.Meaning = pb.NewProperty_Meaning(pb.Property_BLOB) case appengine.BlobKey: p.Meaning = pb.NewProperty_Meaning(pb.Property_BLOBKEY) case Time: p.Meaning = pb.NewProperty_Meaning(pb.Property_GD_WHEN) } return p, "" }
// LeaseTasks leases tasks from a queue. // leaseTime is in seconds. // The number of tasks fetched will be at most maxTasks. func LeaseTasks(c appengine.Context, maxTasks int, queueName string, leaseTime int) ([]*Task, os.Error) { req := &taskqueue_proto.TaskQueueQueryAndOwnTasksRequest{ QueueName: []byte(queueName), LeaseSeconds: proto.Float64(float64(leaseTime)), MaxTasks: proto.Int64(int64(maxTasks)), } res := &taskqueue_proto.TaskQueueQueryAndOwnTasksResponse{} if err := c.Call("taskqueue", "QueryAndOwnTasks", req, res); err != nil { return nil, err } tasks := make([]*Task, len(res.Task)) for i, t := range res.Task { // TODO: Handle eta_usec, retry_count. tasks[i] = &Task{ Payload: t.Body, Name: string(t.TaskName), } } return tasks, nil }
// RoundTrip issues a single HTTP request and returns its response. Per the // http.RoundTripper interface, RoundTrip only returns an error if there // was a problem with the request being malformed // (ErrInvalidFetchRequest) or the URL Fetch proxy fails (ErrFetch). // Note that HTTP response codes such as 5xx, 403, 404, etc are not // errors as far as the transport is concerned and will be returned // with err set to nil. func (t *Transport) RoundTrip(req *http.Request) (res *http.Response, err os.Error) { methNum, ok := pb.URLFetchRequest_RequestMethod_value[req.Method] if !ok { return nil, &ErrInvalidFetchRequest{"Unsupported method: " + req.Method, nil} } method := pb.URLFetchRequest_RequestMethod(methNum) freq := &pb.URLFetchRequest{ Method: &method, Url: proto.String(req.URL.String()), FollowRedirects: proto.Bool(false), // http.Client's responsibility MustValidateServerCertificate: proto.Bool(!t.AllowInvalidServerCertificate), } if t.DeadlineSeconds != 0 { freq.Deadline = proto.Float64(t.DeadlineSeconds) } for k, vals := range req.Header { for _, val := range vals { freq.Header = append(freq.Header, &pb.URLFetchRequest_Header{ Key: proto.String(k), Value: proto.String(val), }) } } if methodAcceptsRequestBody[req.Method] { freq.Payload, err = ioutil.ReadAll(req.Body) if err != nil { return nil, &ErrInvalidFetchRequest{"Failed to read body", err} } } fres := &pb.URLFetchResponse{} if err := t.Context.Call("urlfetch", "Fetch", freq, fres); err != nil { return nil, &ErrFetch{err.String()} } res = &http.Response{} res.StatusCode = int(*fres.StatusCode) res.Status = fmt.Sprintf("%d %s", res.StatusCode, statusCodeToText(res.StatusCode)) res.Header = http.Header(make(map[string][]string)) res.RequestMethod = req.Method // Faked: res.ProtoMajor = 1 res.ProtoMinor = 1 res.Proto = "HTTP/1.1" res.Close = true for _, h := range fres.Header { hkey := http.CanonicalHeaderKey(*h.Key) hval := *h.Value if hkey == "Content-Length" { // Will get filled in below for all but HEAD requests. if req.Method == "HEAD" { res.ContentLength, _ = strconv.Atoi64(hval) } continue } res.Header.Add(hkey, hval) } if req.Method != "HEAD" { res.ContentLength = int64(len(fres.Content)) } truncated := proto.GetBool(fres.ContentWasTruncated) res.Body = &bodyReader{content: fres.Content, truncated: truncated} return }