Skip to content

Commit

Permalink
make DecodeCompact and EncodeCompact methods public
Browse files Browse the repository at this point in the history
Summary: make DecodeCompact and EncodeCompact methods public

Reviewed By: codyohl

Differential Revision: D65061423

fbshipit-source-id: 64e7a001ce67591801cd56d47c8e39a69de609e2
  • Loading branch information
echistyakov authored and facebook-github-bot committed Dec 6, 2024
1 parent 11366c5 commit 2b25291
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ func TestWriteBinaryEmptyBinaryFormat(t *testing.T) {

func TestSkipUnknownTypeBinaryFormat(t *testing.T) {
var m MyTestStruct
d := NewDeserializer()
d := NewBinaryDeserializer()
// skip over a map with invalid key/value type and ~550M entries
data := make([]byte, 1100000000)
copy(data[:], []byte("\n\x10\rO\t6\x03\n\n\n\x10\r\n\tsl ce\x00"))
transport, _ := d.Transport.(*MemoryBuffer)
transport := d.Transport
transport.Buffer = bytes.NewBuffer(data)
start := time.Now()
err := m.Read(d.Protocol)
Expand All @@ -65,7 +65,7 @@ func TestSkipUnknownTypeBinaryFormat(t *testing.T) {

func TestInitialAllocationMapBinaryFormat(t *testing.T) {
var m MyTestStruct
d := NewDeserializer()
d := NewBinaryDeserializer()
// attempts to allocate a map with 1.8B elements for a 20 byte message
data := []byte("\n\x10\rO\t6\x03\n\n\n\x10\r\n\tslice\x00")
err := d.Read(&m, data)
Expand All @@ -78,7 +78,7 @@ func TestInitialAllocationMapBinaryFormat(t *testing.T) {

func TestInitialAllocationListBinaryFormat(t *testing.T) {
var m MyTestStruct
d := NewDeserializer()
d := NewBinaryDeserializer()
// attempts to allocate a list with 1.8B elements for a 20 byte message
data := []byte("\n\x10\rO\t6\x03\n\n\n\x10\x0f\n\tslice\x00")
err := d.Read(&m, data)
Expand All @@ -91,7 +91,7 @@ func TestInitialAllocationListBinaryFormat(t *testing.T) {

func TestInitialAllocationSetBinaryFormat(t *testing.T) {
var m MyTestStruct
d := NewDeserializer()
d := NewBinaryDeserializer()
// attempts to allocate a set with 1.8B elements for a 20 byte message
data := []byte("\n\x12\rO\t6\x03\n\n\n\x10\x0e\n\tslice\x00")
err := d.Read(&m, data)
Expand Down
63 changes: 36 additions & 27 deletions third-party/thrift/src/thrift/lib/go/thrift/deserializer.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,66 +17,75 @@
package thrift

import (
"io"

"github.com/facebook/fbthrift/thrift/lib/go/thrift/types"
)

type Deserializer struct {
Transport io.ReadWriteCloser
Transport *MemoryBuffer
Protocol types.Decoder
}

// Deprecated: use NewBinaryDeserializer instead.
func NewDeserializer() *Deserializer {
return NewBinaryDeserializer()
}

// NewBinaryDeserializer creates a new deserializer using the binary protocol
func NewBinaryDeserializer() *Deserializer {
transport := NewMemoryBufferLen(1024)
protocol := NewBinaryFormat(transport)
return &Deserializer{transport, protocol}
return &Deserializer{Transport: transport, Protocol: protocol}
}

// NewCompactDeserializer creates a new deserializer using the compact protocol
func NewCompactDeserializer() *Deserializer {
transport := NewMemoryBufferLen(1024)
protocol := NewCompactFormat(transport)
return &Deserializer{transport, protocol}
}

func deserializeCompact(data []byte, msg types.Struct) error {
buffer := NewMemoryBufferWithData(data)
format := NewCompactFormat(buffer)
return msg.Read(format)
return &Deserializer{Transport: transport, Protocol: protocol}
}

// NewCompactJSONDeserializer creates a new deserializer using the JSON protocol
func NewCompactJSONDeserializer() *Deserializer {
transport := NewMemoryBufferLen(1024)
protocol := NewCompactJSONFormat(transport)
return &Deserializer{transport, protocol}
return &Deserializer{Transport: transport, Protocol: protocol}
}

// NewSimpleJSONDeserializer creates a new deserializer using the simple JSON protocol
func NewSimpleJSONDeserializer() *Deserializer {
transport := NewMemoryBufferLen(1024)
protocol := NewSimpleJSONFormat(transport)
return &Deserializer{transport, protocol}
return &Deserializer{Transport: transport, Protocol: protocol}
}

// DecodeCompact deserializes a compact protocol message
func DecodeCompact(data []byte, msg types.Struct) error {
return NewCompactDeserializer().Read(msg, data)
}

// DecodeBinary deserializes a binary protocol message
func DecodeBinary(data []byte, msg types.Struct) error {
return NewBinaryDeserializer().Read(msg, data)
}

func (t *Deserializer) ReadString(msg types.Struct, s string) (err error) {
err = nil
if _, err = t.Transport.Write([]byte(s)); err != nil {
return
// ReadString deserializes a Thrift struct from a string
func (t *Deserializer) ReadString(msg types.Struct, s string) error {
if _, err := t.Transport.Write([]byte(s)); err != nil {
return err
}
if err = msg.Read(t.Protocol); err != nil {
return
if err := msg.Read(t.Protocol); err != nil {
return err
}
return
return nil
}

func (t *Deserializer) Read(msg types.Struct, b []byte) (err error) {
err = nil
if _, err = t.Transport.Write(b); err != nil {
return
// Read deserializes a Thrift struct from a byte slice
func (t *Deserializer) Read(msg types.Struct, b []byte) error {
if _, err := t.Transport.Write(b); err != nil {
return err
}
if err = msg.Read(t.Protocol); err != nil {
return
if err := msg.Read(t.Protocol); err != nil {
return err
}
return
return nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func decodeServerMetadataPushVersion8(msg payload.Payload) (*serverMetadataPaylo
}
// Use ServerPushMetadata{} and do not use &ServerPushMetadata{} to ensure stack and avoid heap allocation.
metadata := rpcmetadata.ServerPushMetadata{}
if err := deserializeCompact(metadataBytes, &metadata); err != nil {
if err := DecodeCompact(metadataBytes, &metadata); err != nil {
panic(fmt.Errorf("unable to deserialize metadata push into ServerPushMetadata %w", err))
}
if metadata.SetupResponse != nil {
Expand All @@ -67,7 +67,7 @@ func encodeServerMetadataPushVersion8(zstdSupported bool) (payload.Payload, erro
SetSetupResponse(rpcmetadata.NewSetupResponse().
SetVersion(&version).
SetZstdSupported(&zstdSupported))
metadataBytes, err := serializeCompact(res)
metadataBytes, err := EncodeCompact(res)
if err != nil {
return nil, fmt.Errorf("unable to serialize metadata push %w", err)
}
Expand All @@ -86,7 +86,7 @@ func decodeClientMetadataPush(msg payload.Payload) *clientMetadataPayload {
}
// Use ClientPushMetadata{} and do not use &ClientPushMetadata{} to ensure stack and avoid heap allocation.
metadata := rpcmetadata.ClientPushMetadata{}
if err := deserializeCompact(metadataBytes, &metadata); err != nil {
if err := DecodeCompact(metadataBytes, &metadata); err != nil {
panic(fmt.Errorf("unable to deserialize metadata push into ClientPushMetadata %w", err))
}
res := &clientMetadataPayload{}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func encodeRequestPayload(name string, protoID types.ProtocolID, typeID types.Me
}
metadata.OtherMetadata = make(map[string]string)
maps.Copy(metadata.OtherMetadata, headers)
metadataBytes, err := serializeCompact(metadata)
metadataBytes, err := EncodeCompact(metadata)
if err != nil {
return nil, err
}
Expand All @@ -72,7 +72,7 @@ func decodeRequestPayload(msg payload.Payload) (*requestPayload, error) {
metadataBytes, ok := msg.Metadata()
if ok {
metadata := &rpcmetadata.RequestRpcMetadata{}
if err := deserializeCompact(metadataBytes, metadata); err != nil {
if err := DecodeCompact(metadataBytes, metadata); err != nil {
return nil, err
}
res.metadata = metadata
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func decodeResponsePayload(msg payload.Payload) (*responsePayload, error) {
var err error
metadataBytes, ok := msg.Metadata()
if ok {
if err := deserializeCompact(metadataBytes, res.metadata); err != nil {
if err := DecodeCompact(metadataBytes, res.metadata); err != nil {
return nil, err
}
if res.Zstd() {
Expand All @@ -86,7 +86,7 @@ func encodeResponsePayload(name string, messageType types.MessageType, headers m
excpetionMetadata := newUnknownPayloadExceptionMetadataBase(name, string(dataBytes))
metadata.SetPayloadMetadata(rpcmetadata.NewPayloadMetadata().SetExceptionMetadata(excpetionMetadata))
}
metadataBytes, err := serializeCompact(metadata)
metadataBytes, err := EncodeCompact(metadata)
if err != nil {
return nil, err
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ func checkRequestSetupMetadata8(pay payload.Payload) error {
return fmt.Errorf("expected key %d, got %d", rpcmetadata.KRocketProtocolKey, key)
}
req := rpcmetadata.RequestSetupMetadata{}
if err := deserializeCompact(metdataBytes[4:], &req); err != nil {
if err := DecodeCompact(metdataBytes[4:], &req); err != nil {
return err
}
minVersion := req.GetMinVersion()
Expand Down
52 changes: 31 additions & 21 deletions third-party/thrift/src/thrift/lib/go/thrift/serializer.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,65 +26,75 @@ type Serializer struct {
Protocol types.Encoder
}

// NewSerializer create a new serializer using the binary format
// Deprecated: use NewBinarySerializer instead.
func NewSerializer() *Serializer {
return NewBinarySerializer()
}

// NewBinarySerializer create a new serializer using the binary format
func NewBinarySerializer() *Serializer {
transport := NewMemoryBufferLen(1024)
protocol := NewBinaryFormat(transport)
return &Serializer{transport, protocol}
return &Serializer{Transport: transport, Protocol: protocol}
}

// NewCompactSerializer creates a new serializer using the compact format
func NewCompactSerializer() *Serializer {
transport := NewMemoryBufferLen(1024)
protocol := NewCompactFormat(transport)
return &Serializer{transport, protocol}
}

func serializeCompact(msg types.Struct) ([]byte, error) {
return NewCompactSerializer().Write(msg)
return &Serializer{Transport: transport, Protocol: protocol}
}

// NewCompactJSONSerializer creates a new serializer using the compact JSON format
func NewCompactJSONSerializer() *Serializer {
transport := NewMemoryBufferLen(1024)
protocol := NewCompactJSONFormat(transport)
return &Serializer{transport, protocol}
return &Serializer{Transport: transport, Protocol: protocol}
}

// NewSimpleJSONSerializer creates a new serializer using the SimpleJSON format
func NewSimpleJSONSerializer() *Serializer {
transport := NewMemoryBufferLen(1024)
protocol := NewSimpleJSONFormat(transport)
return &Serializer{transport, protocol}
return &Serializer{Transport: transport, Protocol: protocol}
}

// EncodeCompact serializes msg using the compact format
func EncodeCompact(msg types.Struct) ([]byte, error) {
return NewCompactSerializer().Write(msg)
}

// EncodeBinary serializes msg using the binary format
func EncodeBinary(msg types.Struct) ([]byte, error) {
return NewBinarySerializer().Write(msg)
}

// WriteString writes msg to the serializer and returns it as a string
func (s *Serializer) WriteString(msg types.Struct) (str string, err error) {
func (s *Serializer) WriteString(msg types.Struct) (string, error) {
s.Transport.Reset()

if err = msg.Write(s.Protocol); err != nil {
return
if err := msg.Write(s.Protocol); err != nil {
return "", err
}

if err = s.Protocol.Flush(); err != nil {
return
if err := s.Protocol.Flush(); err != nil {
return "", err
}

return s.Transport.String(), nil
}

// Write writes msg to the serializer and returns it as a byte array
func (s *Serializer) Write(msg types.Struct) (b []byte, err error) {
func (s *Serializer) Write(msg types.Struct) ([]byte, error) {
s.Transport.Reset()

if err = msg.Write(s.Protocol); err != nil {
return
if err := msg.Write(s.Protocol); err != nil {
return nil, err
}

if err = s.Protocol.Flush(); err != nil {
return
if err := s.Protocol.Flush(); err != nil {
return nil, err
}

b = append(b, s.Transport.Bytes()...)
return
return s.Transport.Bytes(), nil
}
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,11 @@ func ProtocolTest2(test *testing.T, serial *Serializer, deserial *Deserializer)
func TestSerializer(t *testing.T) {

serializers := make(map[string]*Serializer)
serializers["Binary"] = NewSerializer()
serializers["Binary"] = NewBinarySerializer()
serializers["Compact"] = NewCompactSerializer()
serializers["JSON"] = NewCompactJSONSerializer()
deserializers := make(map[string]*Deserializer)
deserializers["Binary"] = NewDeserializer()
deserializers["Binary"] = NewBinaryDeserializer()
deserializers["Compact"] = NewCompactDeserializer()
deserializers["JSON"] = NewCompactJSONDeserializer()

Expand Down

0 comments on commit 2b25291

Please sign in to comment.