func TestRoundTripProto3(t *testing.T) { m := &pb.Message{ Name: "David", // (2 | 1<<3): 0x0a 0x05 "David" Hilarity: pb.Message_PUNS, // (0 | 2<<3): 0x10 0x01 HeightInCm: 178, // (0 | 3<<3): 0x18 0xb2 0x01 Data: []byte("roboto"), // (2 | 4<<3): 0x20 0x06 "roboto" ResultCount: 47, // (0 | 7<<3): 0x38 0x2f TrueScotsman: true, // (0 | 8<<3): 0x40 0x01 Score: 8.1, // (5 | 9<<3): 0x4d <8.1> Key: []uint64{1, 0xdeadbeef}, Nested: &pb.Nested{ Bunny: "Monty", }, } t.Logf(" m: %v", m) b, err := proto.Marshal(m) if err != nil { t.Fatalf("proto.Marshal: %v", err) } t.Logf(" b: %q", b) m2 := new(pb.Message) if err := proto.Unmarshal(b, m2); err != nil { t.Fatalf("proto.Unmarshal: %v", err) } t.Logf("m2: %v", m2) if !proto.Equal(m, m2) { t.Errorf("proto.Equal returned false:\n m: %v\nm2: %v", m, m2) } }
func call(ctx context.Context, method string, req proto.Message, resp proto.Message) error { payload, err := proto.Marshal(req) if err != nil { return err } url := baseUrl(ctx) + internal.ProjID(ctx) + "/" + method r, err := internal.HTTPClient(ctx).Post(url, "application/x-protobuf", bytes.NewReader(payload)) if err != nil { return err } defer r.Body.Close() all, err := ioutil.ReadAll(r.Body) if r.StatusCode != http.StatusOK { e := &errHTTP{ StatusCode: r.StatusCode, err: err, } if err == nil { e.Body = string(all) } return e } if err != nil { return err } if err = proto.Unmarshal(all, resp); err != nil { return err } return nil }
func TestGetExtensionStability(t *testing.T) { check := func(m *pb.MyMessage) bool { ext1, err := proto.GetExtension(m, pb.E_Ext_More) if err != nil { t.Fatalf("GetExtension() failed: %s", err) } ext2, err := proto.GetExtension(m, pb.E_Ext_More) if err != nil { t.Fatalf("GetExtension() failed: %s", err) } return ext1 == ext2 } msg := &pb.MyMessage{Count: proto.Int32(4)} ext0 := &pb.Ext{} if err := proto.SetExtension(msg, pb.E_Ext_More, ext0); err != nil { t.Fatalf("Could not set ext1: %s", ext0) } if !check(msg) { t.Errorf("GetExtension() not stable before marshaling") } bb, err := proto.Marshal(msg) if err != nil { t.Fatalf("Marshal() failed: %s", err) } msg1 := &pb.MyMessage{} err = proto.Unmarshal(bb, msg1) if err != nil { t.Fatalf("Unmarshal() failed: %s", err) } if !check(msg1) { t.Errorf("GetExtension() not stable after unmarshaling") } }
// DecodeKey decodes a key from the opaque representation returned by Encode. func DecodeKey(encoded string) (*Key, error) { // Re-add padding. if m := len(encoded) % 4; m != 0 { encoded += strings.Repeat("=", 4-m) } b, err := base64.URLEncoding.DecodeString(encoded) if err != nil { return nil, err } pKey := new(pb.Key) if err := proto.Unmarshal(b, pKey); err != nil { return nil, err } return protoToKey(pKey), nil }
func (t *fakeTransport) RoundTrip(req *http.Request) (*http.Response, error) { body, err := ioutil.ReadAll(req.Body) var in pb.RunQueryRequest var resp http.Response if err = proto.Unmarshal(body, &in); err != nil { // Get back an error resp = http.Response{ StatusCode: http.StatusBadRequest, } } else { // Run our fake query and serialize the response var out pb.RunQueryResponse err := t.Handler(&in, &out) if err != nil { resp = http.Response{ StatusCode: http.StatusBadRequest, } } else { payload, err := proto.Marshal(&out) if err != nil { resp = http.Response{ StatusCode: http.StatusBadRequest, } } else { resp = http.Response{ StatusCode: http.StatusOK, Body: ioutil.NopCloser(bytes.NewBuffer(payload)), } } } } // Set common response fields resp.Proto = "HTTP/1.0" resp.ProtoMajor = 1 resp.ProtoMinor = 1 return &resp, nil }
// ReadDelimited decodes a message from the provided length-delimited stream, // where the length is encoded as 32-bit varint prefix to the message body. // It returns the total number of bytes read and any applicable error. This is // roughly equivalent to the companion Java API's // MessageLite#parseDelimitedFrom. As per the reader contract, this function // calls r.Read repeatedly as required until exactly one message including its // prefix is read and decoded (or an error has occurred). The function never // reads more bytes from the stream than required. The function never returns // an error if a message has been read and decoded correctly, even if the end // of the stream has been reached in doing so. In that case, any subsequent // calls return (0, io.EOF). func ReadDelimited(r io.Reader, m proto.Message) (n int, err error) { // Per AbstractParser#parsePartialDelimitedFrom with // CodedInputStream#readRawVarint32. headerBuf := make([]byte, binary.MaxVarintLen32) var bytesRead, varIntBytes int var messageLength uint64 for varIntBytes == 0 { // i.e. no varint has been decoded yet. if bytesRead >= len(headerBuf) { return bytesRead, errInvalidVarint } // We have to read byte by byte here to avoid reading more bytes // than required. Each read byte is appended to what we have // read before. newBytesRead, err := r.Read(headerBuf[bytesRead : bytesRead+1]) if newBytesRead == 0 { if err != nil { return bytesRead, err } // A Reader should not return (0, nil), but if it does, // it should be treated as no-op (according to the // Reader contract). So let's go on... continue } bytesRead += newBytesRead // Now present everything read so far to the varint decoder and // see if a varint can be decoded already. messageLength, varIntBytes = proto.DecodeVarint(headerBuf[:bytesRead]) } messageBuf := make([]byte, messageLength) newBytesRead, err := io.ReadFull(r, messageBuf) bytesRead += newBytesRead if err != nil { return bytesRead, err } return bytesRead, proto.Unmarshal(messageBuf, m) }
func (protoCodec) Unmarshal(data []byte, v interface{}) error { return proto.Unmarshal(data, v.(proto.Message)) }