diff --git a/internal/command/acknowledge/acknowledge.go b/internal/command/acknowledge/acknowledge.go index da92cbd..97a3a79 100644 --- a/internal/command/acknowledge/acknowledge.go +++ b/internal/command/acknowledge/acknowledge.go @@ -1,6 +1,7 @@ package acknowledge import ( + "encoding/binary" "michelprogram/photon-parser/internal/context" ) @@ -13,12 +14,12 @@ func Parse(ctx *context.Context) (*Acknowledge, error) { var ack Acknowledge var err error - ack.AckReliableSequenceNumber, err = ctx.Reader.ReadUInt32() + ack.AckReliableSequenceNumber, err = ctx.Reader.ReadUInt32(binary.BigEndian) if err != nil { return nil, err } - ack.AckSentTime, err = ctx.Reader.ReadUInt32() + ack.AckSentTime, err = ctx.Reader.ReadUInt32(binary.BigEndian) if err != nil { return nil, err } diff --git a/internal/command/command.go b/internal/command/command.go index 3ea5cd0..abd4643 100644 --- a/internal/command/command.go +++ b/internal/command/command.go @@ -1,6 +1,7 @@ package command import ( + "encoding/binary" "fmt" "michelprogram/photon-parser/internal/command/acknowledge" "michelprogram/photon-parser/internal/command/connect" @@ -146,12 +147,12 @@ func (s *Command) parseHeader(r *reader.Reader) (types.CommandHeader, error) { return types.CommandHeader{}, err } - header.Length, err = r.ReadUInt32() + header.Length, err = r.ReadUInt32(binary.BigEndian) if err != nil { return types.CommandHeader{}, err } - header.ReliableSequenceNumber, err = r.ReadUInt32() + header.ReliableSequenceNumber, err = r.ReadUInt32(binary.BigEndian) if err != nil { return types.CommandHeader{}, err } diff --git a/internal/command/command_test.go b/internal/command/command_test.go index 98e0ab7..f0a37d0 100644 --- a/internal/command/command_test.go +++ b/internal/command/command_test.go @@ -1,7 +1,6 @@ package command_test import ( - "encoding/binary" "michelprogram/photon-parser/internal/command" "michelprogram/photon-parser/internal/context" v16 "michelprogram/photon-parser/internal/parameters/v16" @@ -14,11 +13,11 @@ func TestParseSession(t *testing.T) { payload := []byte{0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x5e, 0x0, 0x0, 0x0, 0xe, 0xf3, 0x4, 0x1, 0x0, 0x29, 0x0, 0x69, 0x0, 0x4, 0x6c, 0xcb, 0x1, 0x73, 0x0, 0xd, 0x4a, 0x4f, 0x53, 0x45, 0x47, 0x41, 0x4d, 0x45, 0x52, 0x33, 0x31, 0x31, 0x33, 0x2, 0x62, 0x73, 0x3, 0x62, 0x1a, 0x5, 0x78, 0x0, 0x0, 0x0, 0x5, 0x1, 0x0, 0x3, 0x2, 0x5, 0x6, 0x78, 0x0, 0x0, 0x0, 0x5, 0x0, 0x3, 0xa, 0x0, 0x5, 0x7, 0x78, 0x0, 0x0, 0x0, 0x10, 0x12, 0x29, 0xd, 0xf6, 0x67, 0x16, 0x0, 0x43, 0xa8, 0xfa, 0x58, 0x55, 0x10, 0x2c, 0x4c, 0xcf, 0xa, 0x73, 0x0, 0x0, 0xb, 0x69, 0x0, 0x0, 0x0, 0x0, 0xc, 0x69, 0x0, 0x0, 0x0, 0x0, 0xd, 0x73, 0x0, 0x0, 0x10, 0x78, 0x0, 0x0, 0x0, 0x8, 0xc2, 0x46, 0xfb, 0xd4, 0xdd, 0xd8, 0xbd, 0xe8, 0x11, 0x78, 0x0, 0x0, 0x0, 0x8, 0xc2, 0x46, 0xfb, 0xd4, 0xdd, 0xd8, 0xbd, 0xe8, 0x12, 0x69, 0x1, 0x96, 0xb9, 0x9, 0x13, 0x66, 0x40, 0x12, 0x99, 0x68, 0x14, 0x66, 0x40, 0x9e, 0x66, 0x66, 0x16, 0x66, 0x44, 0xc1, 0xc0, 0x0, 0x17, 0x66, 0x44, 0xc1, 0xc0, 0x0, 0x19, 0x66, 0x41, 0x78, 0x2, 0xde, 0x1a, 0x69, 0x1, 0x96, 0xbd, 0x52, 0x1b, 0x66, 0x43, 0x20, 0x0, 0x0, 0x1c, 0x66, 0x43, 0x20, 0x0, 0x0, 0x1e, 0x66, 0x3f, 0xff, 0x95, 0x84, 0x1f, 0x69, 0x1, 0x96, 0xbc, 0xf3, 0x20, 0x66, 0x44, 0xbb, 0xe0, 0x0, 0x21, 0x66, 0x44, 0xbb, 0xe0, 0x0, 0x23, 0x66, 0x41, 0xb6, 0x3d, 0x71, 0x24, 0x69, 0x1, 0x96, 0xbd, 0x53, 0x25, 0x66, 0x47, 0x43, 0x19, 0xf2, 0x26, 0x6c, 0x8, 0xd8, 0xa9, 0xfd, 0x9a, 0xb5, 0x35, 0xc1, 0x27, 0x62, 0x0, 0x28, 0x79, 0x0, 0xa, 0x6b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0x1f, 0xb, 0x26, 0x15, 0x97, 0xb, 0xab, 0x0, 0x0, 0x0, 0x0, 0x2b, 0x79, 0x0, 0xe, 0x6b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf, 0x5e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x33, 0x73, 0x0, 0x0, 0x35, 0x62, 0x0, 0x36, 0x62, 0x0, 0x37, 0x79, 0x0, 0x7, 0x6b, 0x0, 0xc, 0xff, 0xff, 0x0, 0x33, 0x0, 0xaf, 0x0, 0xf7, 0xff, 0xff, 0x1, 0x43, 0x38, 0x62, 0x4, 0x39, 0x62, 0xc, 0x3f, 0x69, 0x0, 0x0, 0x0, 0x0, 0xfc, 0x6b, 0x0, 0x1d, 0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0xa1, 0x0, 0x0, 0x0, 0xf, 0xf3, 0x4, 0x1, 0x0, 0xc, 0x0, 0x69, 0x0, 0x4, 0x6c, 0xcb, 0x1, 0x79, 0x0, 0xb, 0x6b, 0x9, 0x10, 0x4, 0x98, 0x2, 0x21, 0xf, 0xd9, 0x4, 0x97, 0x3, 0xd2, 0x2, 0xe4, 0x3, 0x9a, 0x3, 0xb7, 0x3, 0xb8, 0x3, 0xcc, 0x2, 0x79, 0x0, 0xb, 0x66, 0x42, 0xc8, 0x0, 0x0, 0x43, 0x8a, 0x7e, 0x5d, 0x42, 0xc8, 0x0, 0x0, 0x43, 0x4b, 0x13, 0x26, 0x43, 0x8a, 0x7e, 0x5d, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x3, 0x79, 0x0, 0xb, 0x66, 0x42, 0xc8, 0x0, 0x0, 0x43, 0x3c, 0xfa, 0x21, 0x42, 0xc8, 0x0, 0x0, 0x43, 0x44, 0x7d, 0x8a, 0x43, 0x3c, 0xfa, 0x21, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x4, 0x79, 0x0, 0xb, 0x6c, 0x8, 0xde, 0x8e, 0xa4, 0x47, 0x26, 0x4d, 0x8a, 0x8, 0xde, 0x8e, 0xa4, 0xac, 0x1e, 0x41, 0xd, 0x8, 0xde, 0x86, 0xb2, 0x41, 0x9d, 0xca, 0x71, 0x8, 0xde, 0x8f, 0x4b, 0x16, 0x7f, 0x6b, 0x81, 0x8, 0xde, 0x8f, 0x4b, 0x17, 0x35, 0x2d, 0xe1, 0x8, 0xde, 0x8f, 0x4b, 0x2e, 0xe5, 0xf4, 0x8f, 0x8, 0xde, 0x8f, 0x4b, 0x2e, 0xe6, 0x53, 0xc7, 0x8, 0xde, 0x8f, 0x4b, 0x2e, 0xe6, 0x53, 0xc7, 0x8, 0xde, 0x8f, 0x4b, 0x2e, 0xe6, 0x53, 0xc7, 0x8, 0xde, 0x8f, 0x4b, 0x2e, 0xe6, 0x53, 0xc7, 0x8, 0xde, 0x8f, 0x4b, 0x2e, 0xe5, 0xe7, 0xff, 0x5, 0x78, 0x0, 0x0, 0x0, 0xb, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x6, 0x78, 0x0, 0x0, 0x0, 0x0, 0x7, 0x78, 0x0, 0x0, 0x0, 0x11, 0x5b, 0x82, 0x6d, 0x49, 0x82, 0x24, 0x49, 0x82, 0x1, 0xdb, 0xb6, 0x6d, 0xdb, 0xb6, 0x6d, 0xdb, 0x2, 0x8, 0x79, 0x0, 0x19, 0x69, 0x80, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x77, 0x40, 0x0, 0x1b, 0x77, 0x40, 0x0, 0x1b, 0x77, 0x40, 0xd, 0xd6, 0xc7, 0x8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0xea, 0x60, 0x9, 0x78, 0x0, 0x0, 0x0, 0x2, 0x64, 0x4, 0xa, 0x79, 0x0, 0x4, 0x6b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x8c, 0xfc, 0x6b, 0x0, 0xb, 0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x45, 0x0, 0x0, 0x0, 0x10, 0xf3, 0x4, 0x1, 0x0, 0xa, 0x0, 0x69, 0x0, 0x4, 0x6c, 0xcb, 0x1, 0x69, 0x1, 0x96, 0xbd, 0x75, 0x2, 0x6b, 0xb, 0xab, 0x3, 0x6b, 0x2b, 0xbe, 0x4, 0x66, 0x44, 0xbb, 0xe0, 0x0, 0x5, 0x66, 0x41, 0xb6, 0x3d, 0x71, 0x6, 0x6c, 0x8, 0xde, 0x8f, 0x4b, 0x2f, 0x8d, 0x40, 0xbf, 0x8, 0x6f, 0x1, 0xb, 0x6f, 0x1, 0xfc, 0x6b, 0x0, 0xd1, 0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x11, 0xf3, 0x4, 0x1, 0x0, 0x2, 0x0, 0x62, 0x64, 0xfc, 0x6b, 0x1, 0x43, 0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x5e, 0x0, 0x0, 0x0, 0x12, 0xf3, 0x84, 0xf5, 0x26, 0x3e, 0x6, 0x6f, 0x0, 0xdd, 0x1c, 0xb9, 0x23, 0x98, 0x33, 0xa4, 0x47, 0x4c, 0x5c, 0xe4, 0xae, 0x99, 0x1c, 0xce, 0x9f, 0x21, 0x2, 0x6d, 0x98, 0x1c, 0xa4, 0x7e, 0x1f, 0x65, 0xa, 0x8c, 0x3b, 0xe5, 0xa5, 0xb2, 0xe3, 0xb, 0x4b, 0x67, 0xaa, 0xe2, 0x3c, 0x13, 0x8f, 0x5c, 0xe0, 0xd4, 0xb6, 0x94, 0xd0, 0xd2, 0x9c, 0x1f, 0xd4, 0x3c, 0xb, 0xe4, 0x13, 0x1b, 0x78, 0xad, 0xde, 0xb5, 0x2e, 0x9f, 0x0, 0x5d, 0x93, 0x54, 0xba, 0x92, 0xf8, 0x35, 0x98, 0x2a, 0x97, 0xcc, 0x60, 0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x5d, 0x0, 0x0, 0x0, 0x13, 0xf3, 0x4, 0x1, 0x0, 0xb, 0x0, 0x69, 0x0, 0x4, 0x6c, 0xf1, 0x1, 0x6b, 0x18, 0x74, 0x2, 0x62, 0x1, 0x4, 0x6c, 0x0, 0x0, 0x0, 0x0, 0xae, 0x4b, 0x61, 0x10, 0x5, 0x73, 0x0, 0xf, 0x47, 0x72, 0x7a, 0x65, 0x67, 0x6f, 0x72, 0x7a, 0x4e, 0x69, 0x65, 0x4d, 0x6f, 0x67, 0x65, 0x6, 0x62, 0x2, 0x7, 0x69, 0x1c, 0xa1, 0xfc, 0x7d, 0x8, 0x79, 0x0, 0x3, 0x6b, 0xb, 0x13, 0xb, 0x1d, 0xb, 0x20, 0x9, 0x78, 0x0, 0x0, 0x0, 0x1, 0x12, 0xa, 0x62, 0x0, 0xfc, 0x6b, 0x0, 0x1e, 0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x53, 0x0, 0x0, 0x0, 0x14, 0xf3, 0x4, 0x1, 0x0, 0xb, 0x0, 0x69, 0x0, 0x4, 0x6c, 0xf3, 0x1, 0x6b, 0xf, 0xfc, 0x2, 0x62, 0x1, 0x4, 0x69, 0x48, 0xd9, 0x3c, 0x1, 0x5, 0x73, 0x0, 0xd, 0x53, 0x61, 0x62, 0x65, 0x72, 0x6c, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x31, 0x6, 0x62, 0x2, 0x7, 0x69, 0xf, 0xa8, 0xfd, 0x5e, 0x8, 0x79, 0x0, 0x1, 0x6b, 0xf, 0x10, 0x9, 0x78, 0x0, 0x0, 0x0, 0x1, 0xac, 0xa, 0x62, 0x0, 0xfc, 0x6b, 0x0, 0x1e} ctx := &context.Context{ - Reader: reader.NewReader(payload, reader.Options{ + Reader: reader.NewReader(payload), + Decoders: context.Decoders{ ParameterParser: &v16.Parameter{}, ReliableHeaderParameterCount: &v16.ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }), + }, } cmd, err := command.Parse(ctx) diff --git a/internal/command/connect/connect.go b/internal/command/connect/connect.go index 5026475..da5571a 100644 --- a/internal/command/connect/connect.go +++ b/internal/command/connect/connect.go @@ -1,6 +1,7 @@ package connect import ( + "encoding/binary" "michelprogram/photon-parser/internal/context" ) @@ -18,35 +19,35 @@ type Connect struct { func Parse(ctx *context.Context) (*Connect, error) { var err error connect := Connect{} - connect.Mtu, err = ctx.Reader.ReadUInt32() + connect.Mtu, err = ctx.Reader.ReadUInt32(binary.BigEndian) if err != nil { return nil, err } - connect.WindowSize, err = ctx.Reader.ReadUInt32() + connect.WindowSize, err = ctx.Reader.ReadUInt32(binary.BigEndian) if err != nil { return nil, err } - connect.ChannelCount, err = ctx.Reader.ReadUInt32() + connect.ChannelCount, err = ctx.Reader.ReadUInt32(binary.BigEndian) if err != nil { return nil, err } - connect.IncomingBandwidth, err = ctx.Reader.ReadUInt32() + connect.IncomingBandwidth, err = ctx.Reader.ReadUInt32(binary.BigEndian) if err != nil { return nil, err } - connect.OutgoingBandwidth, err = ctx.Reader.ReadUInt32() + connect.OutgoingBandwidth, err = ctx.Reader.ReadUInt32(binary.BigEndian) if err != nil { return nil, err } - connect.DisconnectThrottle, err = ctx.Reader.ReadUInt32() + connect.DisconnectThrottle, err = ctx.Reader.ReadUInt32(binary.BigEndian) if err != nil { return nil, err } - connect.PacketThrottleAcceleration, err = ctx.Reader.ReadUInt32() + connect.PacketThrottleAcceleration, err = ctx.Reader.ReadUInt32(binary.BigEndian) if err != nil { return nil, err } - connect.PacketThrottleDeceleration, err = ctx.Reader.ReadUInt32() + connect.PacketThrottleDeceleration, err = ctx.Reader.ReadUInt32(binary.BigEndian) if err != nil { return nil, err } diff --git a/internal/command/reliable/fragment.go b/internal/command/reliable/fragment.go index ac5ded3..1c06d22 100644 --- a/internal/command/reliable/fragment.go +++ b/internal/command/reliable/fragment.go @@ -1,6 +1,7 @@ package reliable import ( + "encoding/binary" "michelprogram/photon-parser/internal/context" "michelprogram/photon-parser/internal/reader" "michelprogram/photon-parser/internal/types" @@ -31,32 +32,32 @@ func parseMetadata(reader *reader.Reader) (*Fragment, error) { var fragment Fragment var err error - fragment.ID, err = reader.ReadUInt32() + fragment.ID, err = reader.ReadUInt32(binary.BigEndian) if err != nil { return nil, err } - fragment.Count, err = reader.ReadUInt32() + fragment.Count, err = reader.ReadUInt32(binary.BigEndian) if err != nil { return nil, err } - fragment.Index, err = reader.ReadUInt32() + fragment.Index, err = reader.ReadUInt32(binary.BigEndian) if err != nil { return nil, err } - fragment.Size, err = reader.ReadUInt32() + fragment.Size, err = reader.ReadUInt32(binary.BigEndian) if err != nil { return nil, err } - fragment.Offset, err = reader.ReadUInt32() + fragment.Offset, err = reader.ReadUInt32(binary.BigEndian) if err != nil { return nil, err } - fragment.Data = reader.ReadRest() + fragment.Data = reader.ReadRemaining() return &fragment, nil diff --git a/internal/command/reliable/reliable.go b/internal/command/reliable/reliable.go index 2a15d07..e548b28 100644 --- a/internal/command/reliable/reliable.go +++ b/internal/command/reliable/reliable.go @@ -1,15 +1,17 @@ package reliable import ( + "encoding/binary" "michelprogram/photon-parser/internal/context" "michelprogram/photon-parser/internal/errors" - "michelprogram/photon-parser/internal/reader" "michelprogram/photon-parser/internal/types" ) // HEADER_SIZE is the size in bytes of a reliable message header (5 bytes). const HEADER_SIZE = 5 +const READED_HEADER_SIZE = 14 + // Type represents a Photon reliable message type. type Type uint8 @@ -52,7 +54,7 @@ type Reliable struct { // or an error if any part of parsing fails. func Parse(ctx *context.Context, length uint32) (*Reliable, error) { reliable := Reliable{} - header, err := reliable.parseHeader(ctx.Reader, length) + header, err := reliable.parseHeader(ctx, length) if err != nil { return nil, err } @@ -70,7 +72,7 @@ func Parse(ctx *context.Context, length uint32) (*Reliable, error) { reliable.Parameters = make([]types.Parameter, header.ParameterCount) for i := 0; i < reliable.ParameterCount; i++ { - err := ctx.Reader.ParameterParser.Parse(ctx.Reader, &reliable.Parameters[i], ctx.Hooks) + err := ctx.Decoders.ParameterParser.Parse(ctx.Reader, &reliable.Parameters[i], ctx.Hooks) if err != nil { return nil, err } @@ -80,16 +82,16 @@ func Parse(ctx *context.Context, length uint32) (*Reliable, error) { } -func (r *Reliable) parseHeader(reader *reader.Reader, length uint32) (Header, error) { +func (r *Reliable) parseHeader(ctx *context.Context, length uint32) (Header, error) { var err error var header Header - header.Signature, err = reader.ReadUInt8() + header.Signature, err = ctx.Reader.ReadUInt8() if err != nil { return Header{}, err } - b, err := reader.ReadUInt8() + b, err := ctx.Reader.ReadUInt8() if err != nil { return Header{}, err } @@ -99,27 +101,36 @@ func (r *Reliable) parseHeader(reader *reader.Reader, length uint32) (Header, er switch header.Type { case OperationResponse, OtherOperationResponse: - header.EventCode, err = reader.ReadUInt8() + header.EventCode, err = ctx.Reader.ReadUInt8() if err != nil { return Header{}, err } //Return code - reader.ReadInt16LittleEndian() + _, err = ctx.Reader.ReadInt16(binary.LittleEndian) + if err != nil { + return Header{}, err + } //Read debug msg - reader.ReadByte() + _, err = ctx.Reader.ReadByte() + if err != nil { + return Header{}, err + } case EventDataType, OperationRequest: - header.EventCode, err = reader.ReadUInt8() + header.EventCode, err = ctx.Reader.ReadUInt8() if err != nil { return Header{}, err } default: - reader.ReadBytes(int(length) - 14) + _, err = ctx.Reader.ReadBytes(int(length) - READED_HEADER_SIZE) + if err != nil { + return Header{}, err + } return header, nil } - header.ParameterCount, err = reader.Options.ReliableHeaderParameterCount.Count(reader) + header.ParameterCount, err = ctx.Decoders.ReliableHeaderParameterCount.Count(ctx.Reader) if err != nil { return Header{}, err } diff --git a/internal/command/reliable/reliable_test.go b/internal/command/reliable/reliable_test.go index 85c588a..15a59ca 100644 --- a/internal/command/reliable/reliable_test.go +++ b/internal/command/reliable/reliable_test.go @@ -1,7 +1,6 @@ package reliable_test import ( - "encoding/binary" "log" "michelprogram/photon-parser/internal/command/reliable" "michelprogram/photon-parser/internal/context" @@ -15,11 +14,11 @@ func TestReliableParsing(t *testing.T) { payload := []byte{0xf3, 0x4, 0x1, 0x0, 0x29, 0x0, 0x69, 0x0, 0x4, 0x6c, 0xcb, 0x1, 0x73, 0x0, 0xd, 0x4a, 0x4f, 0x53, 0x45, 0x47, 0x41, 0x4d, 0x45, 0x52, 0x33, 0x31, 0x31, 0x33, 0x2, 0x62, 0x73, 0x3, 0x62, 0x1a, 0x5, 0x78, 0x0, 0x0, 0x0, 0x5, 0x1, 0x0, 0x3, 0x2, 0x5, 0x6, 0x78, 0x0, 0x0, 0x0, 0x5, 0x0, 0x3, 0xa, 0x0, 0x5, 0x7, 0x78, 0x0, 0x0, 0x0, 0x10, 0x12, 0x29, 0xd, 0xf6, 0x67, 0x16, 0x0, 0x43, 0xa8, 0xfa, 0x58, 0x55, 0x10, 0x2c, 0x4c, 0xcf, 0xa, 0x73, 0x0, 0x0, 0xb, 0x69, 0x0, 0x0, 0x0, 0x0, 0xc, 0x69, 0x0, 0x0, 0x0, 0x0, 0xd, 0x73, 0x0, 0x0, 0x10, 0x78, 0x0, 0x0, 0x0, 0x8, 0xc2, 0x46, 0xfb, 0xd4, 0xdd, 0xd8, 0xbd, 0xe8, 0x11, 0x78, 0x0, 0x0, 0x0, 0x8, 0xc2, 0x46, 0xfb, 0xd4, 0xdd, 0xd8, 0xbd, 0xe8, 0x12, 0x69, 0x1, 0x96, 0xb9, 0x9, 0x13, 0x66, 0x40, 0x12, 0x99, 0x68, 0x14, 0x66, 0x40, 0x9e, 0x66, 0x66, 0x16, 0x66, 0x44, 0xc1, 0xc0, 0x0, 0x17, 0x66, 0x44, 0xc1, 0xc0, 0x0, 0x19, 0x66, 0x41, 0x78, 0x2, 0xde, 0x1a, 0x69, 0x1, 0x96, 0xbd, 0x52, 0x1b, 0x66, 0x43, 0x20, 0x0, 0x0, 0x1c, 0x66, 0x43, 0x20, 0x0, 0x0, 0x1e, 0x66, 0x3f, 0xff, 0x95, 0x84, 0x1f, 0x69, 0x1, 0x96, 0xbc, 0xf3, 0x20, 0x66, 0x44, 0xbb, 0xe0, 0x0, 0x21, 0x66, 0x44, 0xbb, 0xe0, 0x0, 0x23, 0x66, 0x41, 0xb6, 0x3d, 0x71, 0x24, 0x69, 0x1, 0x96, 0xbd, 0x53, 0x25, 0x66, 0x47, 0x43, 0x19, 0xf2, 0x26, 0x6c, 0x8, 0xd8, 0xa9, 0xfd, 0x9a, 0xb5, 0x35, 0xc1, 0x27, 0x62, 0x0, 0x28, 0x79, 0x0, 0xa, 0x6b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0x1f, 0xb, 0x26, 0x15, 0x97, 0xb, 0xab, 0x0, 0x0, 0x0, 0x0, 0x2b, 0x79, 0x0, 0xe, 0x6b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf, 0x5e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x33, 0x73, 0x0, 0x0, 0x35, 0x62, 0x0, 0x36, 0x62, 0x0, 0x37, 0x79, 0x0, 0x7, 0x6b, 0x0, 0xc, 0xff, 0xff, 0x0, 0x33, 0x0, 0xaf, 0x0, 0xf7, 0xff, 0xff, 0x1, 0x43, 0x38, 0x62, 0x4, 0x39, 0x62, 0xc, 0x3f, 0x69, 0x0, 0x0, 0x0, 0x0, 0xfc, 0x6b, 0x0, 0x1d} ctx := &context.Context{ - Reader: reader.NewReader(payload, reader.Options{ + Reader: reader.NewReader(payload), + Decoders: context.Decoders{ ParameterParser: &v16.Parameter{}, ReliableHeaderParameterCount: &v16.ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }), + }, } sd, err := reliable.Parse(ctx, 0) diff --git a/internal/context/context.go b/internal/context/context.go index c71bb50..47988d8 100644 --- a/internal/context/context.go +++ b/internal/context/context.go @@ -10,12 +10,14 @@ type Context struct { Reader *reader.Reader Assembler *assembler.Assembler Hooks *hooks.Hooks + Decoders Decoders } -func NewContext(reader *reader.Reader, assembler *assembler.Assembler, hooks *hooks.Hooks) *Context { +func NewContext(reader *reader.Reader, assembler *assembler.Assembler, hooks *hooks.Hooks, decoders Decoders) *Context { return &Context{ Reader: reader, Assembler: assembler, Hooks: hooks, + Decoders: decoders, } } diff --git a/internal/context/decoders.go b/internal/context/decoders.go new file mode 100644 index 0000000..b250dea --- /dev/null +++ b/internal/context/decoders.go @@ -0,0 +1,25 @@ +package context + +import ( + "michelprogram/photon-parser/internal/hooks" + "michelprogram/photon-parser/internal/reader" + "michelprogram/photon-parser/internal/types" +) + +// ParameterParser is implemented by each protocol-version parameters package +// (v16, v18). +// It is wired once at Parser construction so the hot path +type ParameterParser interface { + Parse(*reader.Reader, *types.Parameter, *hooks.Hooks) error +} +// ReliableHeaderParameterCount is implemented by each protocol-version reliable header parameter count package +// (v16, v18). +// It is used to count the number of parameters in a reliable header. +type ReliableHeaderParameterCount interface { + Count(*reader.Reader) (int, error) +} + +type Decoders struct { + ParameterParser ParameterParser + ReliableHeaderParameterCount ReliableHeaderParameterCount +} diff --git a/internal/errors/erros.go b/internal/errors/erros.go index 500dcfc..2c1c5bf 100644 --- a/internal/errors/erros.go +++ b/internal/errors/erros.go @@ -4,3 +4,17 @@ import "errors" var HeaderSize = errors.New("header size too low") var EncryptedPacket = errors.New("packet is encrypted or unknown: unexpected signature byte") +var NotEnoughBytesInt8 = errors.New("not enough bytes to read int8") +var NotEnoughBytesUInt8 = errors.New("not enough bytes to read uint8") +var NotEnoughBytesInt16 = errors.New("not enough bytes to read int16") +var NotEnoughBytesUInt16 = errors.New("not enough bytes to read uint16") +var NotEnoughBytesInt32 = errors.New("not enough bytes to read int32") +var NotEnoughBytesUInt32 = errors.New("not enough bytes to read uint32") +var NotEnoughBytesInt64 = errors.New("not enough bytes to read int64") +var NotEnoughBytesUInt64 = errors.New("not enough bytes to read uint64") +var NotEnoughBytesFloat32 = errors.New("not enough bytes to read float32") +var NotEnoughBytesFloat64 = errors.New("not enough bytes to read float64") +var InvalidBooleanValue = errors.New("invalid value for boolean: (expected 0 or 1)") +var NotEnoughBytesString = errors.New("not enough bytes to read string") +var NotEnoughBytesByte = errors.New("not enough bytes to read byte") +var NotEnoughBytesBytes = errors.New("not enough bytes to read []byte") \ No newline at end of file diff --git a/internal/hooks/hooks_test.go b/internal/hooks/hooks_test.go index 9ea1be9..e5594c6 100644 --- a/internal/hooks/hooks_test.go +++ b/internal/hooks/hooks_test.go @@ -1,7 +1,6 @@ package hooks_test import ( - "encoding/binary" "reflect" "testing" "time" @@ -121,12 +120,12 @@ func TestReader_SessionSyncHookMatchesParsedSession(t *testing.T) { payload := []byte{0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x5e, 0x0, 0x0, 0x0, 0xe, 0xf3, 0x4, 0x1, 0x0, 0x29, 0x0, 0x69, 0x0, 0x4, 0x6c, 0xcb, 0x1, 0x73, 0x0, 0xd, 0x4a, 0x4f, 0x53, 0x45, 0x47, 0x41, 0x4d, 0x45, 0x52, 0x33, 0x31, 0x31, 0x33, 0x2, 0x62, 0x73, 0x3, 0x62, 0x1a, 0x5, 0x78, 0x0, 0x0, 0x0, 0x5, 0x1, 0x0, 0x3, 0x2, 0x5, 0x6, 0x78, 0x0, 0x0, 0x0, 0x5, 0x0, 0x3, 0xa, 0x0, 0x5, 0x7, 0x78, 0x0, 0x0, 0x0, 0x10, 0x12, 0x29, 0xd, 0xf6, 0x67, 0x16, 0x0, 0x43, 0xa8, 0xfa, 0x58, 0x55, 0x10, 0x2c, 0x4c, 0xcf, 0xa, 0x73, 0x0, 0x0, 0xb, 0x69, 0x0, 0x0, 0x0, 0x0, 0xc, 0x69, 0x0, 0x0, 0x0, 0x0, 0xd, 0x73, 0x0, 0x0, 0x10, 0x78, 0x0, 0x0, 0x0, 0x8, 0xc2, 0x46, 0xfb, 0xd4, 0xdd, 0xd8, 0xbd, 0xe8, 0x11, 0x78, 0x0, 0x0, 0x0, 0x8, 0xc2, 0x46, 0xfb, 0xd4, 0xdd, 0xd8, 0xbd, 0xe8, 0x12, 0x69, 0x1, 0x96, 0xb9, 0x9, 0x13, 0x66, 0x40, 0x12, 0x99, 0x68, 0x14, 0x66, 0x40, 0x9e, 0x66, 0x66, 0x16, 0x66, 0x44, 0xc1, 0xc0, 0x0, 0x17, 0x66, 0x44, 0xc1, 0xc0, 0x0, 0x19, 0x66, 0x41, 0x78, 0x2, 0xde, 0x1a, 0x69, 0x1, 0x96, 0xbd, 0x52, 0x1b, 0x66, 0x43, 0x20, 0x0, 0x0, 0x1c, 0x66, 0x43, 0x20, 0x0, 0x0, 0x1e, 0x66, 0x3f, 0xff, 0x95, 0x84, 0x1f, 0x69, 0x1, 0x96, 0xbc, 0xf3, 0x20, 0x66, 0x44, 0xbb, 0xe0, 0x0, 0x21, 0x66, 0x44, 0xbb, 0xe0, 0x0, 0x23, 0x66, 0x41, 0xb6, 0x3d, 0x71, 0x24, 0x69, 0x1, 0x96, 0xbd, 0x53, 0x25, 0x66, 0x47, 0x43, 0x19, 0xf2, 0x26, 0x6c, 0x8, 0xd8, 0xa9, 0xfd, 0x9a, 0xb5, 0x35, 0xc1, 0x27, 0x62, 0x0, 0x28, 0x79, 0x0, 0xa, 0x6b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0x1f, 0xb, 0x26, 0x15, 0x97, 0xb, 0xab, 0x0, 0x0, 0x0, 0x0, 0x2b, 0x79, 0x0, 0xe, 0x6b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf, 0x5e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x33, 0x73, 0x0, 0x0, 0x35, 0x62, 0x0, 0x36, 0x62, 0x0, 0x37, 0x79, 0x0, 0x7, 0x6b, 0x0, 0xc, 0xff, 0xff, 0x0, 0x33, 0x0, 0xaf, 0x0, 0xf7, 0xff, 0xff, 0x1, 0x43, 0x38, 0x62, 0x4, 0x39, 0x62, 0xc, 0x3f, 0x69, 0x0, 0x0, 0x0, 0x0, 0xfc, 0x6b, 0x0, 0x1d, 0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0xa1, 0x0, 0x0, 0x0, 0xf, 0xf3, 0x4, 0x1, 0x0, 0xc, 0x0, 0x69, 0x0, 0x4, 0x6c, 0xcb, 0x1, 0x79, 0x0, 0xb, 0x6b, 0x9, 0x10, 0x4, 0x98, 0x2, 0x21, 0xf, 0xd9, 0x4, 0x97, 0x3, 0xd2, 0x2, 0xe4, 0x3, 0x9a, 0x3, 0xb7, 0x3, 0xb8, 0x3, 0xcc, 0x2, 0x79, 0x0, 0xb, 0x66, 0x42, 0xc8, 0x0, 0x0, 0x43, 0x8a, 0x7e, 0x5d, 0x42, 0xc8, 0x0, 0x0, 0x43, 0x4b, 0x13, 0x26, 0x43, 0x8a, 0x7e, 0x5d, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x3, 0x79, 0x0, 0xb, 0x66, 0x42, 0xc8, 0x0, 0x0, 0x43, 0x3c, 0xfa, 0x21, 0x42, 0xc8, 0x0, 0x0, 0x43, 0x44, 0x7d, 0x8a, 0x43, 0x3c, 0xfa, 0x21, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x4, 0x79, 0x0, 0xb, 0x6c, 0x8, 0xde, 0x8e, 0xa4, 0x47, 0x26, 0x4d, 0x8a, 0x8, 0xde, 0x8e, 0xa4, 0xac, 0x1e, 0x41, 0xd, 0x8, 0xde, 0x86, 0xb2, 0x41, 0x9d, 0xca, 0x71, 0x8, 0xde, 0x8f, 0x4b, 0x16, 0x7f, 0x6b, 0x81, 0x8, 0xde, 0x8f, 0x4b, 0x17, 0x35, 0x2d, 0xe1, 0x8, 0xde, 0x8f, 0x4b, 0x2e, 0xe5, 0xf4, 0x8f, 0x8, 0xde, 0x8f, 0x4b, 0x2e, 0xe6, 0x53, 0xc7, 0x8, 0xde, 0x8f, 0x4b, 0x2e, 0xe6, 0x53, 0xc7, 0x8, 0xde, 0x8f, 0x4b, 0x2e, 0xe6, 0x53, 0xc7, 0x8, 0xde, 0x8f, 0x4b, 0x2e, 0xe6, 0x53, 0xc7, 0x8, 0xde, 0x8f, 0x4b, 0x2e, 0xe5, 0xe7, 0xff, 0x5, 0x78, 0x0, 0x0, 0x0, 0xb, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x6, 0x78, 0x0, 0x0, 0x0, 0x0, 0x7, 0x78, 0x0, 0x0, 0x0, 0x11, 0x5b, 0x82, 0x6d, 0x49, 0x82, 0x24, 0x49, 0x82, 0x1, 0xdb, 0xb6, 0x6d, 0xdb, 0xb6, 0x6d, 0xdb, 0x2, 0x8, 0x79, 0x0, 0x19, 0x69, 0x80, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x77, 0x40, 0x0, 0x1b, 0x77, 0x40, 0x0, 0x1b, 0x77, 0x40, 0xd, 0xd6, 0xc7, 0x8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0xea, 0x60, 0x9, 0x78, 0x0, 0x0, 0x0, 0x2, 0x64, 0x4, 0xa, 0x79, 0x0, 0x4, 0x6b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x8c, 0xfc, 0x6b, 0x0, 0xb, 0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x45, 0x0, 0x0, 0x0, 0x10, 0xf3, 0x4, 0x1, 0x0, 0xa, 0x0, 0x69, 0x0, 0x4, 0x6c, 0xcb, 0x1, 0x69, 0x1, 0x96, 0xbd, 0x75, 0x2, 0x6b, 0xb, 0xab, 0x3, 0x6b, 0x2b, 0xbe, 0x4, 0x66, 0x44, 0xbb, 0xe0, 0x0, 0x5, 0x66, 0x41, 0xb6, 0x3d, 0x71, 0x6, 0x6c, 0x8, 0xde, 0x8f, 0x4b, 0x2f, 0x8d, 0x40, 0xbf, 0x8, 0x6f, 0x1, 0xb, 0x6f, 0x1, 0xfc, 0x6b, 0x0, 0xd1, 0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x11, 0xf3, 0x4, 0x1, 0x0, 0x2, 0x0, 0x62, 0x64, 0xfc, 0x6b, 0x1, 0x43, 0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x5e, 0x0, 0x0, 0x0, 0x12, 0xf3, 0x84, 0xf5, 0x26, 0x3e, 0x6, 0x6f, 0x0, 0xdd, 0x1c, 0xb9, 0x23, 0x98, 0x33, 0xa4, 0x47, 0x4c, 0x5c, 0xe4, 0xae, 0x99, 0x1c, 0xce, 0x9f, 0x21, 0x2, 0x6d, 0x98, 0x1c, 0xa4, 0x7e, 0x1f, 0x65, 0xa, 0x8c, 0x3b, 0xe5, 0xa5, 0xb2, 0xe3, 0xb, 0x4b, 0x67, 0xaa, 0xe2, 0x3c, 0x13, 0x8f, 0x5c, 0xe0, 0xd4, 0xb6, 0x94, 0xd0, 0xd2, 0x9c, 0x1f, 0xd4, 0x3c, 0xb, 0xe4, 0x13, 0x1b, 0x78, 0xad, 0xde, 0xb5, 0x2e, 0x9f, 0x0, 0x5d, 0x93, 0x54, 0xba, 0x92, 0xf8, 0x35, 0x98, 0x2a, 0x97, 0xcc, 0x60, 0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x5d, 0x0, 0x0, 0x0, 0x13, 0xf3, 0x4, 0x1, 0x0, 0xb, 0x0, 0x69, 0x0, 0x4, 0x6c, 0xf1, 0x1, 0x6b, 0x18, 0x74, 0x2, 0x62, 0x1, 0x4, 0x6c, 0x0, 0x0, 0x0, 0x0, 0xae, 0x4b, 0x61, 0x10, 0x5, 0x73, 0x0, 0xf, 0x47, 0x72, 0x7a, 0x65, 0x67, 0x6f, 0x72, 0x7a, 0x4e, 0x69, 0x65, 0x4d, 0x6f, 0x67, 0x65, 0x6, 0x62, 0x2, 0x7, 0x69, 0x1c, 0xa1, 0xfc, 0x7d, 0x8, 0x79, 0x0, 0x3, 0x6b, 0xb, 0x13, 0xb, 0x1d, 0xb, 0x20, 0x9, 0x78, 0x0, 0x0, 0x0, 0x1, 0x12, 0xa, 0x62, 0x0, 0xfc, 0x6b, 0x0, 0x1e, 0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x53, 0x0, 0x0, 0x0, 0x14, 0xf3, 0x4, 0x1, 0x0, 0xb, 0x0, 0x69, 0x0, 0x4, 0x6c, 0xf3, 0x1, 0x6b, 0xf, 0xfc, 0x2, 0x62, 0x1, 0x4, 0x69, 0x48, 0xd9, 0x3c, 0x1, 0x5, 0x73, 0x0, 0xd, 0x53, 0x61, 0x62, 0x65, 0x72, 0x6c, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x31, 0x6, 0x62, 0x2, 0x7, 0x69, 0xf, 0xa8, 0xfd, 0x5e, 0x8, 0x79, 0x0, 0x1, 0x6b, 0xf, 0x10, 0x9, 0x78, 0x0, 0x0, 0x0, 0x1, 0xac, 0xa, 0x62, 0x0, 0xfc, 0x6b, 0x0, 0x1e} ctx := &context.Context{ - Reader: reader.NewReader(payload, reader.Options{ - ParameterParser: &v16.Parameter{}, + Reader: reader.NewReader(payload), + Hooks: hooks.NewHooks(), + Decoders: context.Decoders{ + ParameterParser: &v16.Parameter{}, ReliableHeaderParameterCount: &v16.ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }), - Hooks: hooks.NewHooks(), + }, } var got types.Session @@ -146,12 +145,12 @@ func TestReader_SessionAsyncHookReceivesMatchingSession(t *testing.T) { payload := []byte{0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x5e, 0x0, 0x0, 0x0, 0xe, 0xf3, 0x4, 0x1, 0x0, 0x29, 0x0, 0x69, 0x0, 0x4, 0x6c, 0xcb, 0x1, 0x73, 0x0, 0xd, 0x4a, 0x4f, 0x53, 0x45, 0x47, 0x41, 0x4d, 0x45, 0x52, 0x33, 0x31, 0x31, 0x33, 0x2, 0x62, 0x73, 0x3, 0x62, 0x1a, 0x5, 0x78, 0x0, 0x0, 0x0, 0x5, 0x1, 0x0, 0x3, 0x2, 0x5, 0x6, 0x78, 0x0, 0x0, 0x0, 0x5, 0x0, 0x3, 0xa, 0x0, 0x5, 0x7, 0x78, 0x0, 0x0, 0x0, 0x10, 0x12, 0x29, 0xd, 0xf6, 0x67, 0x16, 0x0, 0x43, 0xa8, 0xfa, 0x58, 0x55, 0x10, 0x2c, 0x4c, 0xcf, 0xa, 0x73, 0x0, 0x0, 0xb, 0x69, 0x0, 0x0, 0x0, 0x0, 0xc, 0x69, 0x0, 0x0, 0x0, 0x0, 0xd, 0x73, 0x0, 0x0, 0x10, 0x78, 0x0, 0x0, 0x0, 0x8, 0xc2, 0x46, 0xfb, 0xd4, 0xdd, 0xd8, 0xbd, 0xe8, 0x11, 0x78, 0x0, 0x0, 0x0, 0x8, 0xc2, 0x46, 0xfb, 0xd4, 0xdd, 0xd8, 0xbd, 0xe8, 0x12, 0x69, 0x1, 0x96, 0xb9, 0x9, 0x13, 0x66, 0x40, 0x12, 0x99, 0x68, 0x14, 0x66, 0x40, 0x9e, 0x66, 0x66, 0x16, 0x66, 0x44, 0xc1, 0xc0, 0x0, 0x17, 0x66, 0x44, 0xc1, 0xc0, 0x0, 0x19, 0x66, 0x41, 0x78, 0x2, 0xde, 0x1a, 0x69, 0x1, 0x96, 0xbd, 0x52, 0x1b, 0x66, 0x43, 0x20, 0x0, 0x0, 0x1c, 0x66, 0x43, 0x20, 0x0, 0x0, 0x1e, 0x66, 0x3f, 0xff, 0x95, 0x84, 0x1f, 0x69, 0x1, 0x96, 0xbc, 0xf3, 0x20, 0x66, 0x44, 0xbb, 0xe0, 0x0, 0x21, 0x66, 0x44, 0xbb, 0xe0, 0x0, 0x23, 0x66, 0x41, 0xb6, 0x3d, 0x71, 0x24, 0x69, 0x1, 0x96, 0xbd, 0x53, 0x25, 0x66, 0x47, 0x43, 0x19, 0xf2, 0x26, 0x6c, 0x8, 0xd8, 0xa9, 0xfd, 0x9a, 0xb5, 0x35, 0xc1, 0x27, 0x62, 0x0, 0x28, 0x79, 0x0, 0xa, 0x6b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0x1f, 0xb, 0x26, 0x15, 0x97, 0xb, 0xab, 0x0, 0x0, 0x0, 0x0, 0x2b, 0x79, 0x0, 0xe, 0x6b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf, 0x5e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x33, 0x73, 0x0, 0x0, 0x35, 0x62, 0x0, 0x36, 0x62, 0x0, 0x37, 0x79, 0x0, 0x7, 0x6b, 0x0, 0xc, 0xff, 0xff, 0x0, 0x33, 0x0, 0xaf, 0x0, 0xf7, 0xff, 0xff, 0x1, 0x43, 0x38, 0x62, 0x4, 0x39, 0x62, 0xc, 0x3f, 0x69, 0x0, 0x0, 0x0, 0x0, 0xfc, 0x6b, 0x0, 0x1d, 0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0xa1, 0x0, 0x0, 0x0, 0xf, 0xf3, 0x4, 0x1, 0x0, 0xc, 0x0, 0x69, 0x0, 0x4, 0x6c, 0xcb, 0x1, 0x79, 0x0, 0xb, 0x6b, 0x9, 0x10, 0x4, 0x98, 0x2, 0x21, 0xf, 0xd9, 0x4, 0x97, 0x3, 0xd2, 0x2, 0xe4, 0x3, 0x9a, 0x3, 0xb7, 0x3, 0xb8, 0x3, 0xcc, 0x2, 0x79, 0x0, 0xb, 0x66, 0x42, 0xc8, 0x0, 0x0, 0x43, 0x8a, 0x7e, 0x5d, 0x42, 0xc8, 0x0, 0x0, 0x43, 0x4b, 0x13, 0x26, 0x43, 0x8a, 0x7e, 0x5d, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x3, 0x79, 0x0, 0xb, 0x66, 0x42, 0xc8, 0x0, 0x0, 0x43, 0x3c, 0xfa, 0x21, 0x42, 0xc8, 0x0, 0x0, 0x43, 0x44, 0x7d, 0x8a, 0x43, 0x3c, 0xfa, 0x21, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x4, 0x79, 0x0, 0xb, 0x6c, 0x8, 0xde, 0x8e, 0xa4, 0x47, 0x26, 0x4d, 0x8a, 0x8, 0xde, 0x8e, 0xa4, 0xac, 0x1e, 0x41, 0xd, 0x8, 0xde, 0x86, 0xb2, 0x41, 0x9d, 0xca, 0x71, 0x8, 0xde, 0x8f, 0x4b, 0x16, 0x7f, 0x6b, 0x81, 0x8, 0xde, 0x8f, 0x4b, 0x17, 0x35, 0x2d, 0xe1, 0x8, 0xde, 0x8f, 0x4b, 0x2e, 0xe5, 0xf4, 0x8f, 0x8, 0xde, 0x8f, 0x4b, 0x2e, 0xe6, 0x53, 0xc7, 0x8, 0xde, 0x8f, 0x4b, 0x2e, 0xe6, 0x53, 0xc7, 0x8, 0xde, 0x8f, 0x4b, 0x2e, 0xe6, 0x53, 0xc7, 0x8, 0xde, 0x8f, 0x4b, 0x2e, 0xe6, 0x53, 0xc7, 0x8, 0xde, 0x8f, 0x4b, 0x2e, 0xe5, 0xe7, 0xff, 0x5, 0x78, 0x0, 0x0, 0x0, 0xb, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x6, 0x78, 0x0, 0x0, 0x0, 0x0, 0x7, 0x78, 0x0, 0x0, 0x0, 0x11, 0x5b, 0x82, 0x6d, 0x49, 0x82, 0x24, 0x49, 0x82, 0x1, 0xdb, 0xb6, 0x6d, 0xdb, 0xb6, 0x6d, 0xdb, 0x2, 0x8, 0x79, 0x0, 0x19, 0x69, 0x80, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x77, 0x40, 0x0, 0x1b, 0x77, 0x40, 0x0, 0x1b, 0x77, 0x40, 0xd, 0xd6, 0xc7, 0x8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0xea, 0x60, 0x9, 0x78, 0x0, 0x0, 0x0, 0x2, 0x64, 0x4, 0xa, 0x79, 0x0, 0x4, 0x6b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x8c, 0xfc, 0x6b, 0x0, 0xb, 0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x45, 0x0, 0x0, 0x0, 0x10, 0xf3, 0x4, 0x1, 0x0, 0xa, 0x0, 0x69, 0x0, 0x4, 0x6c, 0xcb, 0x1, 0x69, 0x1, 0x96, 0xbd, 0x75, 0x2, 0x6b, 0xb, 0xab, 0x3, 0x6b, 0x2b, 0xbe, 0x4, 0x66, 0x44, 0xbb, 0xe0, 0x0, 0x5, 0x66, 0x41, 0xb6, 0x3d, 0x71, 0x6, 0x6c, 0x8, 0xde, 0x8f, 0x4b, 0x2f, 0x8d, 0x40, 0xbf, 0x8, 0x6f, 0x1, 0xb, 0x6f, 0x1, 0xfc, 0x6b, 0x0, 0xd1, 0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x11, 0xf3, 0x4, 0x1, 0x0, 0x2, 0x0, 0x62, 0x64, 0xfc, 0x6b, 0x1, 0x43, 0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x5e, 0x0, 0x0, 0x0, 0x12, 0xf3, 0x84, 0xf5, 0x26, 0x3e, 0x6, 0x6f, 0x0, 0xdd, 0x1c, 0xb9, 0x23, 0x98, 0x33, 0xa4, 0x47, 0x4c, 0x5c, 0xe4, 0xae, 0x99, 0x1c, 0xce, 0x9f, 0x21, 0x2, 0x6d, 0x98, 0x1c, 0xa4, 0x7e, 0x1f, 0x65, 0xa, 0x8c, 0x3b, 0xe5, 0xa5, 0xb2, 0xe3, 0xb, 0x4b, 0x67, 0xaa, 0xe2, 0x3c, 0x13, 0x8f, 0x5c, 0xe0, 0xd4, 0xb6, 0x94, 0xd0, 0xd2, 0x9c, 0x1f, 0xd4, 0x3c, 0xb, 0xe4, 0x13, 0x1b, 0x78, 0xad, 0xde, 0xb5, 0x2e, 0x9f, 0x0, 0x5d, 0x93, 0x54, 0xba, 0x92, 0xf8, 0x35, 0x98, 0x2a, 0x97, 0xcc, 0x60, 0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x5d, 0x0, 0x0, 0x0, 0x13, 0xf3, 0x4, 0x1, 0x0, 0xb, 0x0, 0x69, 0x0, 0x4, 0x6c, 0xf1, 0x1, 0x6b, 0x18, 0x74, 0x2, 0x62, 0x1, 0x4, 0x6c, 0x0, 0x0, 0x0, 0x0, 0xae, 0x4b, 0x61, 0x10, 0x5, 0x73, 0x0, 0xf, 0x47, 0x72, 0x7a, 0x65, 0x67, 0x6f, 0x72, 0x7a, 0x4e, 0x69, 0x65, 0x4d, 0x6f, 0x67, 0x65, 0x6, 0x62, 0x2, 0x7, 0x69, 0x1c, 0xa1, 0xfc, 0x7d, 0x8, 0x79, 0x0, 0x3, 0x6b, 0xb, 0x13, 0xb, 0x1d, 0xb, 0x20, 0x9, 0x78, 0x0, 0x0, 0x0, 0x1, 0x12, 0xa, 0x62, 0x0, 0xfc, 0x6b, 0x0, 0x1e, 0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x53, 0x0, 0x0, 0x0, 0x14, 0xf3, 0x4, 0x1, 0x0, 0xb, 0x0, 0x69, 0x0, 0x4, 0x6c, 0xf3, 0x1, 0x6b, 0xf, 0xfc, 0x2, 0x62, 0x1, 0x4, 0x69, 0x48, 0xd9, 0x3c, 0x1, 0x5, 0x73, 0x0, 0xd, 0x53, 0x61, 0x62, 0x65, 0x72, 0x6c, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x31, 0x6, 0x62, 0x2, 0x7, 0x69, 0xf, 0xa8, 0xfd, 0x5e, 0x8, 0x79, 0x0, 0x1, 0x6b, 0xf, 0x10, 0x9, 0x78, 0x0, 0x0, 0x0, 0x1, 0xac, 0xa, 0x62, 0x0, 0xfc, 0x6b, 0x0, 0x1e} ctx := &context.Context{ - Reader: reader.NewReader(payload, reader.Options{ - ParameterParser: &v16.Parameter{}, + Reader: reader.NewReader(payload), + Hooks: hooks.NewHooks(), + Decoders: context.Decoders{ + ParameterParser: &v16.Parameter{}, ReliableHeaderParameterCount: &v16.ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }), - Hooks: hooks.NewHooks(), + }, } _ = ctx.Hooks.OnSessionAsync(types.HookOptions{Size: 1}) // buffered: emit won’t hit default @@ -174,12 +173,12 @@ func TestReader_CommandSyncHookMatchesParsedCommand(t *testing.T) { payload := []byte{0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x5e, 0x0, 0x0, 0x0, 0xe, 0xf3, 0x4, 0x1, 0x0, 0x29, 0x0, 0x69, 0x0, 0x4, 0x6c, 0xcb, 0x1, 0x73, 0x0, 0xd, 0x4a, 0x4f, 0x53, 0x45, 0x47, 0x41, 0x4d, 0x45, 0x52, 0x33, 0x31, 0x31, 0x33, 0x2, 0x62, 0x73, 0x3, 0x62, 0x1a, 0x5, 0x78, 0x0, 0x0, 0x0, 0x5, 0x1, 0x0, 0x3, 0x2, 0x5, 0x6, 0x78, 0x0, 0x0, 0x0, 0x5, 0x0, 0x3, 0xa, 0x0, 0x5, 0x7, 0x78, 0x0, 0x0, 0x0, 0x10, 0x12, 0x29, 0xd, 0xf6, 0x67, 0x16, 0x0, 0x43, 0xa8, 0xfa, 0x58, 0x55, 0x10, 0x2c, 0x4c, 0xcf, 0xa, 0x73, 0x0, 0x0, 0xb, 0x69, 0x0, 0x0, 0x0, 0x0, 0xc, 0x69, 0x0, 0x0, 0x0, 0x0, 0xd, 0x73, 0x0, 0x0, 0x10, 0x78, 0x0, 0x0, 0x0, 0x8, 0xc2, 0x46, 0xfb, 0xd4, 0xdd, 0xd8, 0xbd, 0xe8, 0x11, 0x78, 0x0, 0x0, 0x0, 0x8, 0xc2, 0x46, 0xfb, 0xd4, 0xdd, 0xd8, 0xbd, 0xe8, 0x12, 0x69, 0x1, 0x96, 0xb9, 0x9, 0x13, 0x66, 0x40, 0x12, 0x99, 0x68, 0x14, 0x66, 0x40, 0x9e, 0x66, 0x66, 0x16, 0x66, 0x44, 0xc1, 0xc0, 0x0, 0x17, 0x66, 0x44, 0xc1, 0xc0, 0x0, 0x19, 0x66, 0x41, 0x78, 0x2, 0xde, 0x1a, 0x69, 0x1, 0x96, 0xbd, 0x52, 0x1b, 0x66, 0x43, 0x20, 0x0, 0x0, 0x1c, 0x66, 0x43, 0x20, 0x0, 0x0, 0x1e, 0x66, 0x3f, 0xff, 0x95, 0x84, 0x1f, 0x69, 0x1, 0x96, 0xbc, 0xf3, 0x20, 0x66, 0x44, 0xbb, 0xe0, 0x0, 0x21, 0x66, 0x44, 0xbb, 0xe0, 0x0, 0x23, 0x66, 0x41, 0xb6, 0x3d, 0x71, 0x24, 0x69, 0x1, 0x96, 0xbd, 0x53, 0x25, 0x66, 0x47, 0x43, 0x19, 0xf2, 0x26, 0x6c, 0x8, 0xd8, 0xa9, 0xfd, 0x9a, 0xb5, 0x35, 0xc1, 0x27, 0x62, 0x0, 0x28, 0x79, 0x0, 0xa, 0x6b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0x1f, 0xb, 0x26, 0x15, 0x97, 0xb, 0xab, 0x0, 0x0, 0x0, 0x0, 0x2b, 0x79, 0x0, 0xe, 0x6b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf, 0x5e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x33, 0x73, 0x0, 0x0, 0x35, 0x62, 0x0, 0x36, 0x62, 0x0, 0x37, 0x79, 0x0, 0x7, 0x6b, 0x0, 0xc, 0xff, 0xff, 0x0, 0x33, 0x0, 0xaf, 0x0, 0xf7, 0xff, 0xff, 0x1, 0x43, 0x38, 0x62, 0x4, 0x39, 0x62, 0xc, 0x3f, 0x69, 0x0, 0x0, 0x0, 0x0, 0xfc, 0x6b, 0x0, 0x1d, 0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0xa1, 0x0, 0x0, 0x0, 0xf, 0xf3, 0x4, 0x1, 0x0, 0xc, 0x0, 0x69, 0x0, 0x4, 0x6c, 0xcb, 0x1, 0x79, 0x0, 0xb, 0x6b, 0x9, 0x10, 0x4, 0x98, 0x2, 0x21, 0xf, 0xd9, 0x4, 0x97, 0x3, 0xd2, 0x2, 0xe4, 0x3, 0x9a, 0x3, 0xb7, 0x3, 0xb8, 0x3, 0xcc, 0x2, 0x79, 0x0, 0xb, 0x66, 0x42, 0xc8, 0x0, 0x0, 0x43, 0x8a, 0x7e, 0x5d, 0x42, 0xc8, 0x0, 0x0, 0x43, 0x4b, 0x13, 0x26, 0x43, 0x8a, 0x7e, 0x5d, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x3, 0x79, 0x0, 0xb, 0x66, 0x42, 0xc8, 0x0, 0x0, 0x43, 0x3c, 0xfa, 0x21, 0x42, 0xc8, 0x0, 0x0, 0x43, 0x44, 0x7d, 0x8a, 0x43, 0x3c, 0xfa, 0x21, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x4, 0x79, 0x0, 0xb, 0x6c, 0x8, 0xde, 0x8e, 0xa4, 0x47, 0x26, 0x4d, 0x8a, 0x8, 0xde, 0x8e, 0xa4, 0xac, 0x1e, 0x41, 0xd, 0x8, 0xde, 0x86, 0xb2, 0x41, 0x9d, 0xca, 0x71, 0x8, 0xde, 0x8f, 0x4b, 0x16, 0x7f, 0x6b, 0x81, 0x8, 0xde, 0x8f, 0x4b, 0x17, 0x35, 0x2d, 0xe1, 0x8, 0xde, 0x8f, 0x4b, 0x2e, 0xe5, 0xf4, 0x8f, 0x8, 0xde, 0x8f, 0x4b, 0x2e, 0xe6, 0x53, 0xc7, 0x8, 0xde, 0x8f, 0x4b, 0x2e, 0xe6, 0x53, 0xc7, 0x8, 0xde, 0x8f, 0x4b, 0x2e, 0xe6, 0x53, 0xc7, 0x8, 0xde, 0x8f, 0x4b, 0x2e, 0xe6, 0x53, 0xc7, 0x8, 0xde, 0x8f, 0x4b, 0x2e, 0xe5, 0xe7, 0xff, 0x5, 0x78, 0x0, 0x0, 0x0, 0xb, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x6, 0x78, 0x0, 0x0, 0x0, 0x0, 0x7, 0x78, 0x0, 0x0, 0x0, 0x11, 0x5b, 0x82, 0x6d, 0x49, 0x82, 0x24, 0x49, 0x82, 0x1, 0xdb, 0xb6, 0x6d, 0xdb, 0xb6, 0x6d, 0xdb, 0x2, 0x8, 0x79, 0x0, 0x19, 0x69, 0x80, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x77, 0x40, 0x0, 0x1b, 0x77, 0x40, 0x0, 0x1b, 0x77, 0x40, 0xd, 0xd6, 0xc7, 0x8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0xea, 0x60, 0x9, 0x78, 0x0, 0x0, 0x0, 0x2, 0x64, 0x4, 0xa, 0x79, 0x0, 0x4, 0x6b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x8c, 0xfc, 0x6b, 0x0, 0xb, 0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x45, 0x0, 0x0, 0x0, 0x10, 0xf3, 0x4, 0x1, 0x0, 0xa, 0x0, 0x69, 0x0, 0x4, 0x6c, 0xcb, 0x1, 0x69, 0x1, 0x96, 0xbd, 0x75, 0x2, 0x6b, 0xb, 0xab, 0x3, 0x6b, 0x2b, 0xbe, 0x4, 0x66, 0x44, 0xbb, 0xe0, 0x0, 0x5, 0x66, 0x41, 0xb6, 0x3d, 0x71, 0x6, 0x6c, 0x8, 0xde, 0x8f, 0x4b, 0x2f, 0x8d, 0x40, 0xbf, 0x8, 0x6f, 0x1, 0xb, 0x6f, 0x1, 0xfc, 0x6b, 0x0, 0xd1, 0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x11, 0xf3, 0x4, 0x1, 0x0, 0x2, 0x0, 0x62, 0x64, 0xfc, 0x6b, 0x1, 0x43, 0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x5e, 0x0, 0x0, 0x0, 0x12, 0xf3, 0x84, 0xf5, 0x26, 0x3e, 0x6, 0x6f, 0x0, 0xdd, 0x1c, 0xb9, 0x23, 0x98, 0x33, 0xa4, 0x47, 0x4c, 0x5c, 0xe4, 0xae, 0x99, 0x1c, 0xce, 0x9f, 0x21, 0x2, 0x6d, 0x98, 0x1c, 0xa4, 0x7e, 0x1f, 0x65, 0xa, 0x8c, 0x3b, 0xe5, 0xa5, 0xb2, 0xe3, 0xb, 0x4b, 0x67, 0xaa, 0xe2, 0x3c, 0x13, 0x8f, 0x5c, 0xe0, 0xd4, 0xb6, 0x94, 0xd0, 0xd2, 0x9c, 0x1f, 0xd4, 0x3c, 0xb, 0xe4, 0x13, 0x1b, 0x78, 0xad, 0xde, 0xb5, 0x2e, 0x9f, 0x0, 0x5d, 0x93, 0x54, 0xba, 0x92, 0xf8, 0x35, 0x98, 0x2a, 0x97, 0xcc, 0x60, 0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x5d, 0x0, 0x0, 0x0, 0x13, 0xf3, 0x4, 0x1, 0x0, 0xb, 0x0, 0x69, 0x0, 0x4, 0x6c, 0xf1, 0x1, 0x6b, 0x18, 0x74, 0x2, 0x62, 0x1, 0x4, 0x6c, 0x0, 0x0, 0x0, 0x0, 0xae, 0x4b, 0x61, 0x10, 0x5, 0x73, 0x0, 0xf, 0x47, 0x72, 0x7a, 0x65, 0x67, 0x6f, 0x72, 0x7a, 0x4e, 0x69, 0x65, 0x4d, 0x6f, 0x67, 0x65, 0x6, 0x62, 0x2, 0x7, 0x69, 0x1c, 0xa1, 0xfc, 0x7d, 0x8, 0x79, 0x0, 0x3, 0x6b, 0xb, 0x13, 0xb, 0x1d, 0xb, 0x20, 0x9, 0x78, 0x0, 0x0, 0x0, 0x1, 0x12, 0xa, 0x62, 0x0, 0xfc, 0x6b, 0x0, 0x1e, 0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x53, 0x0, 0x0, 0x0, 0x14, 0xf3, 0x4, 0x1, 0x0, 0xb, 0x0, 0x69, 0x0, 0x4, 0x6c, 0xf3, 0x1, 0x6b, 0xf, 0xfc, 0x2, 0x62, 0x1, 0x4, 0x69, 0x48, 0xd9, 0x3c, 0x1, 0x5, 0x73, 0x0, 0xd, 0x53, 0x61, 0x62, 0x65, 0x72, 0x6c, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x31, 0x6, 0x62, 0x2, 0x7, 0x69, 0xf, 0xa8, 0xfd, 0x5e, 0x8, 0x79, 0x0, 0x1, 0x6b, 0xf, 0x10, 0x9, 0x78, 0x0, 0x0, 0x0, 0x1, 0xac, 0xa, 0x62, 0x0, 0xfc, 0x6b, 0x0, 0x1e} ctx := &context.Context{ - Reader: reader.NewReader(payload, reader.Options{ - ParameterParser: &v16.Parameter{}, + Reader: reader.NewReader(payload), + Hooks: hooks.NewHooks(), + Decoders: context.Decoders{ + ParameterParser: &v16.Parameter{}, ReliableHeaderParameterCount: &v16.ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }), - Hooks: hooks.NewHooks(), + }, } var got types.Command @@ -199,12 +198,12 @@ func TestReader_CommandAsyncHookReceivesMatchingCommand(t *testing.T) { payload := []byte{0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0x5e, 0x0, 0x0, 0x0, 0xe, 0xf3, 0x4, 0x1, 0x0, 0x29, 0x0, 0x69, 0x0, 0x4, 0x6c, 0xcb, 0x1, 0x73, 0x0, 0xd, 0x4a, 0x4f, 0x53, 0x45, 0x47, 0x41, 0x4d, 0x45, 0x52, 0x33, 0x31, 0x31, 0x33, 0x2, 0x62, 0x73, 0x3, 0x62, 0x1a, 0x5, 0x78, 0x0, 0x0, 0x0, 0x5, 0x1, 0x0, 0x3, 0x2, 0x5, 0x6, 0x78, 0x0, 0x0, 0x0, 0x5, 0x0, 0x3, 0xa, 0x0, 0x5, 0x7, 0x78, 0x0, 0x0, 0x0, 0x10, 0x12, 0x29, 0xd, 0xf6, 0x67, 0x16, 0x0, 0x43, 0xa8, 0xfa, 0x58, 0x55, 0x10, 0x2c, 0x4c, 0xcf, 0xa, 0x73, 0x0, 0x0, 0xb, 0x69, 0x0, 0x0, 0x0, 0x0, 0xc, 0x69, 0x0, 0x0, 0x0, 0x0, 0xd, 0x73, 0x0, 0x0, 0x10, 0x78, 0x0, 0x0, 0x0, 0x8, 0xc2, 0x46, 0xfb, 0xd4, 0xdd, 0xd8, 0xbd, 0xe8, 0x11, 0x78, 0x0, 0x0, 0x0, 0x8, 0xc2, 0x46, 0xfb, 0xd4, 0xdd, 0xd8, 0xbd, 0xe8, 0x12, 0x69, 0x1, 0x96, 0xb9, 0x9, 0x13, 0x66, 0x40, 0x12, 0x99, 0x68, 0x14, 0x66, 0x40, 0x9e, 0x66, 0x66, 0x16, 0x66, 0x44, 0xc1, 0xc0, 0x0, 0x17, 0x66, 0x44, 0xc1, 0xc0, 0x0, 0x19, 0x66, 0x41, 0x78, 0x2, 0xde, 0x1a, 0x69, 0x1, 0x96, 0xbd, 0x52, 0x1b, 0x66, 0x43, 0x20, 0x0, 0x0, 0x1c, 0x66, 0x43, 0x20, 0x0, 0x0, 0x1e, 0x66, 0x3f, 0xff, 0x95, 0x84, 0x1f, 0x69, 0x1, 0x96, 0xbc, 0xf3, 0x20, 0x66, 0x44, 0xbb, 0xe0, 0x0, 0x21, 0x66, 0x44, 0xbb, 0xe0, 0x0, 0x23, 0x66, 0x41, 0xb6, 0x3d, 0x71, 0x24, 0x69, 0x1, 0x96, 0xbd, 0x53, 0x25, 0x66, 0x47, 0x43, 0x19, 0xf2, 0x26, 0x6c, 0x8, 0xd8, 0xa9, 0xfd, 0x9a, 0xb5, 0x35, 0xc1, 0x27, 0x62, 0x0, 0x28, 0x79, 0x0, 0xa, 0x6b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0x1f, 0xb, 0x26, 0x15, 0x97, 0xb, 0xab, 0x0, 0x0, 0x0, 0x0, 0x2b, 0x79, 0x0, 0xe, 0x6b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf, 0x5e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x33, 0x73, 0x0, 0x0, 0x35, 0x62, 0x0, 0x36, 0x62, 0x0, 0x37, 0x79, 0x0, 0x7, 0x6b, 0x0, 0xc, 0xff, 0xff, 0x0, 0x33, 0x0, 0xaf, 0x0, 0xf7, 0xff, 0xff, 0x1, 0x43, 0x38, 0x62, 0x4, 0x39, 0x62, 0xc, 0x3f, 0x69, 0x0, 0x0, 0x0, 0x0, 0xfc, 0x6b, 0x0, 0x1d, 0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x1, 0xa1, 0x0, 0x0, 0x0, 0xf, 0xf3, 0x4, 0x1, 0x0, 0xc, 0x0, 0x69, 0x0, 0x4, 0x6c, 0xcb, 0x1, 0x79, 0x0, 0xb, 0x6b, 0x9, 0x10, 0x4, 0x98, 0x2, 0x21, 0xf, 0xd9, 0x4, 0x97, 0x3, 0xd2, 0x2, 0xe4, 0x3, 0x9a, 0x3, 0xb7, 0x3, 0xb8, 0x3, 0xcc, 0x2, 0x79, 0x0, 0xb, 0x66, 0x42, 0xc8, 0x0, 0x0, 0x43, 0x8a, 0x7e, 0x5d, 0x42, 0xc8, 0x0, 0x0, 0x43, 0x4b, 0x13, 0x26, 0x43, 0x8a, 0x7e, 0x5d, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x3, 0x79, 0x0, 0xb, 0x66, 0x42, 0xc8, 0x0, 0x0, 0x43, 0x3c, 0xfa, 0x21, 0x42, 0xc8, 0x0, 0x0, 0x43, 0x44, 0x7d, 0x8a, 0x43, 0x3c, 0xfa, 0x21, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x42, 0xc8, 0x0, 0x0, 0x4, 0x79, 0x0, 0xb, 0x6c, 0x8, 0xde, 0x8e, 0xa4, 0x47, 0x26, 0x4d, 0x8a, 0x8, 0xde, 0x8e, 0xa4, 0xac, 0x1e, 0x41, 0xd, 0x8, 0xde, 0x86, 0xb2, 0x41, 0x9d, 0xca, 0x71, 0x8, 0xde, 0x8f, 0x4b, 0x16, 0x7f, 0x6b, 0x81, 0x8, 0xde, 0x8f, 0x4b, 0x17, 0x35, 0x2d, 0xe1, 0x8, 0xde, 0x8f, 0x4b, 0x2e, 0xe5, 0xf4, 0x8f, 0x8, 0xde, 0x8f, 0x4b, 0x2e, 0xe6, 0x53, 0xc7, 0x8, 0xde, 0x8f, 0x4b, 0x2e, 0xe6, 0x53, 0xc7, 0x8, 0xde, 0x8f, 0x4b, 0x2e, 0xe6, 0x53, 0xc7, 0x8, 0xde, 0x8f, 0x4b, 0x2e, 0xe6, 0x53, 0xc7, 0x8, 0xde, 0x8f, 0x4b, 0x2e, 0xe5, 0xe7, 0xff, 0x5, 0x78, 0x0, 0x0, 0x0, 0xb, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x6, 0x78, 0x0, 0x0, 0x0, 0x0, 0x7, 0x78, 0x0, 0x0, 0x0, 0x11, 0x5b, 0x82, 0x6d, 0x49, 0x82, 0x24, 0x49, 0x82, 0x1, 0xdb, 0xb6, 0x6d, 0xdb, 0xb6, 0x6d, 0xdb, 0x2, 0x8, 0x79, 0x0, 0x19, 0x69, 0x80, 0x0, 0x0, 0x0, 0x80, 0x0, 0x0, 0x0, 0x0, 0x1b, 0x77, 0x40, 0x0, 0x1b, 0x77, 0x40, 0x0, 0x1b, 0x77, 0x40, 0xd, 0xd6, 0xc7, 0x8, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x75, 0x30, 0x0, 0x0, 0x3a, 0x98, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0xea, 0x60, 0x0, 0x0, 0xea, 0x60, 0x9, 0x78, 0x0, 0x0, 0x0, 0x2, 0x64, 0x4, 0xa, 0x79, 0x0, 0x4, 0x6b, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x2, 0x8c, 0xfc, 0x6b, 0x0, 0xb, 0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x45, 0x0, 0x0, 0x0, 0x10, 0xf3, 0x4, 0x1, 0x0, 0xa, 0x0, 0x69, 0x0, 0x4, 0x6c, 0xcb, 0x1, 0x69, 0x1, 0x96, 0xbd, 0x75, 0x2, 0x6b, 0xb, 0xab, 0x3, 0x6b, 0x2b, 0xbe, 0x4, 0x66, 0x44, 0xbb, 0xe0, 0x0, 0x5, 0x66, 0x41, 0xb6, 0x3d, 0x71, 0x6, 0x6c, 0x8, 0xde, 0x8f, 0x4b, 0x2f, 0x8d, 0x40, 0xbf, 0x8, 0x6f, 0x1, 0xb, 0x6f, 0x1, 0xfc, 0x6b, 0x0, 0xd1, 0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x18, 0x0, 0x0, 0x0, 0x11, 0xf3, 0x4, 0x1, 0x0, 0x2, 0x0, 0x62, 0x64, 0xfc, 0x6b, 0x1, 0x43, 0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x5e, 0x0, 0x0, 0x0, 0x12, 0xf3, 0x84, 0xf5, 0x26, 0x3e, 0x6, 0x6f, 0x0, 0xdd, 0x1c, 0xb9, 0x23, 0x98, 0x33, 0xa4, 0x47, 0x4c, 0x5c, 0xe4, 0xae, 0x99, 0x1c, 0xce, 0x9f, 0x21, 0x2, 0x6d, 0x98, 0x1c, 0xa4, 0x7e, 0x1f, 0x65, 0xa, 0x8c, 0x3b, 0xe5, 0xa5, 0xb2, 0xe3, 0xb, 0x4b, 0x67, 0xaa, 0xe2, 0x3c, 0x13, 0x8f, 0x5c, 0xe0, 0xd4, 0xb6, 0x94, 0xd0, 0xd2, 0x9c, 0x1f, 0xd4, 0x3c, 0xb, 0xe4, 0x13, 0x1b, 0x78, 0xad, 0xde, 0xb5, 0x2e, 0x9f, 0x0, 0x5d, 0x93, 0x54, 0xba, 0x92, 0xf8, 0x35, 0x98, 0x2a, 0x97, 0xcc, 0x60, 0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x5d, 0x0, 0x0, 0x0, 0x13, 0xf3, 0x4, 0x1, 0x0, 0xb, 0x0, 0x69, 0x0, 0x4, 0x6c, 0xf1, 0x1, 0x6b, 0x18, 0x74, 0x2, 0x62, 0x1, 0x4, 0x6c, 0x0, 0x0, 0x0, 0x0, 0xae, 0x4b, 0x61, 0x10, 0x5, 0x73, 0x0, 0xf, 0x47, 0x72, 0x7a, 0x65, 0x67, 0x6f, 0x72, 0x7a, 0x4e, 0x69, 0x65, 0x4d, 0x6f, 0x67, 0x65, 0x6, 0x62, 0x2, 0x7, 0x69, 0x1c, 0xa1, 0xfc, 0x7d, 0x8, 0x79, 0x0, 0x3, 0x6b, 0xb, 0x13, 0xb, 0x1d, 0xb, 0x20, 0x9, 0x78, 0x0, 0x0, 0x0, 0x1, 0x12, 0xa, 0x62, 0x0, 0xfc, 0x6b, 0x0, 0x1e, 0x6, 0x0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x53, 0x0, 0x0, 0x0, 0x14, 0xf3, 0x4, 0x1, 0x0, 0xb, 0x0, 0x69, 0x0, 0x4, 0x6c, 0xf3, 0x1, 0x6b, 0xf, 0xfc, 0x2, 0x62, 0x1, 0x4, 0x69, 0x48, 0xd9, 0x3c, 0x1, 0x5, 0x73, 0x0, 0xd, 0x53, 0x61, 0x62, 0x65, 0x72, 0x6c, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x31, 0x6, 0x62, 0x2, 0x7, 0x69, 0xf, 0xa8, 0xfd, 0x5e, 0x8, 0x79, 0x0, 0x1, 0x6b, 0xf, 0x10, 0x9, 0x78, 0x0, 0x0, 0x0, 0x1, 0xac, 0xa, 0x62, 0x0, 0xfc, 0x6b, 0x0, 0x1e} ctx := &context.Context{ - Reader: reader.NewReader(payload, reader.Options{ - ParameterParser: &v16.Parameter{}, + Reader: reader.NewReader(payload), + Hooks: hooks.NewHooks(), + Decoders: context.Decoders{ + ParameterParser: &v16.Parameter{}, ReliableHeaderParameterCount: &v16.ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }), - Hooks: hooks.NewHooks(), + }, } _ = ctx.Hooks.OnCommandAsync(types.HookOptions{Size: 1}) @@ -228,11 +227,7 @@ func TestReader_ParameterSyncHookMatchesParsedParameter(t *testing.T) { // ID=5, Protocol16 int8 (0x62), value 127 paramBytes := []byte{5, 0x62, 0x7F} - r := reader.NewReader(paramBytes, reader.Options{ - ParameterParser: &v16.Parameter{}, - ReliableHeaderParameterCount: &v16.ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }) + r := reader.NewReader(paramBytes) h := hooks.NewHooks() var got types.Parameter h.SyncHooks.OnParameter = func(p types.Parameter) { got = p } @@ -251,11 +246,7 @@ func TestReader_ParameterSyncHookMatchesParsedParameter(t *testing.T) { func TestReader_ParameterAsyncHookReceivesMatchingParameter(t *testing.T) { paramBytes := []byte{5, 0x62, 0x7F} - r := reader.NewReader(paramBytes, reader.Options{ - ParameterParser: &v16.Parameter{}, - ReliableHeaderParameterCount: &v16.ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }) + r := reader.NewReader(paramBytes) h := hooks.NewHooks() _ = h.OnParameterAsync(types.HookOptions{Size: 1}) diff --git a/internal/parameters/v16/arrays.go b/internal/parameters/v16/arrays.go index 013972d..11cacb6 100644 --- a/internal/parameters/v16/arrays.go +++ b/internal/parameters/v16/arrays.go @@ -1,6 +1,7 @@ package v16 import ( + "encoding/binary" "michelprogram/photon-parser/internal/reader" "michelprogram/photon-parser/internal/types" ) @@ -9,7 +10,7 @@ import ( // Format: uint32 size followed by size int8 values. // Returns an error if the array cannot be fully read. func (p Parameter) readInt8Array(r *reader.Reader) ([]int8, error) { - size, err := r.ReadUInt32() + size, err := r.ReadUInt32(binary.BigEndian) if err != nil { return nil, err } @@ -30,7 +31,7 @@ func (p Parameter) readInt8Array(r *reader.Reader) ([]int8, error) { // Format: uint32 size followed by size int32 values (each in big-endian). // Returns an error if the array cannot be fully read. func (p Parameter) readInt32Array(r *reader.Reader) ([]int32, error) { - size, err := r.ReadUInt32() + size, err := r.ReadUInt32(binary.BigEndian) if err != nil { return nil, err } @@ -38,7 +39,7 @@ func (p Parameter) readInt32Array(r *reader.Reader) ([]int32, error) { val := make([]int32, size) for i := uint32(0); i < size; i++ { - input, err := r.ReadInt32() + input, err := r.ReadInt32(binary.BigEndian) if err != nil { return nil, err } @@ -51,7 +52,7 @@ func (p Parameter) readInt32Array(r *reader.Reader) ([]int32, error) { // Format: uint32 size followed by size Protocol16 strings (each with uint16 length prefix). // Returns an error if the array cannot be fully read. func (p Parameter) readStringArray(r *reader.Reader) ([]string, error) { - size, err := r.ReadUInt32() + size, err := r.ReadUInt32(binary.BigEndian) if err != nil { return nil, err } @@ -81,7 +82,7 @@ func (p Parameter) readStringArray(r *reader.Reader) ([]string, error) { // 0x00 0x00 0x00 0xC8 // 200 func (p Parameter) readArray(r *reader.Reader) ([]any, error) { - size, err := r.ReadUInt16() + size, err := r.ReadUInt16(binary.BigEndian) if err != nil { return nil, err } diff --git a/internal/parameters/v16/arrays_test.go b/internal/parameters/v16/arrays_test.go index 291cf9b..6614daf 100644 --- a/internal/parameters/v16/arrays_test.go +++ b/internal/parameters/v16/arrays_test.go @@ -1,7 +1,6 @@ package v16_test import ( - "encoding/binary" . "michelprogram/photon-parser/internal/parameters/v16" "michelprogram/photon-parser/internal/reader" "michelprogram/photon-parser/internal/types" @@ -50,11 +49,7 @@ func TestReadInt8Array(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - reader := reader.NewReader(tt.input, reader.Options{ - ParameterParser: &Parameter{}, - ReliableHeaderParameterCount: &ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }) + reader := reader.NewReader(tt.input) p := &Parameter{} out := &types.Parameter{} err := p.Parse(reader, out, nil) @@ -123,12 +118,7 @@ func TestReadInt32Array(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - reader := reader.NewReader(tt.input, reader.Options{ - ParameterParser: &Parameter{}, - - ReliableHeaderParameterCount: &ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }) + reader := reader.NewReader(tt.input) p := &Parameter{} out := &types.Parameter{} err := p.Parse(reader, out, nil) @@ -215,11 +205,7 @@ func TestReadStringArray(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - reader := reader.NewReader(tt.input, reader.Options{ - ParameterParser: &Parameter{}, - ReliableHeaderParameterCount: &ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }) + reader := reader.NewReader(tt.input) p := &Parameter{} out := &types.Parameter{} err := p.Parse(reader, out, nil) @@ -336,11 +322,7 @@ func TestReadArray(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - reader := reader.NewReader(tt.input, reader.Options{ - ParameterParser: &Parameter{}, - ReliableHeaderParameterCount: &ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }) + reader := reader.NewReader(tt.input) p := &Parameter{} out := &types.Parameter{} err := p.Parse(reader, out, nil) @@ -366,11 +348,7 @@ func TestReadArrayGeneric(t *testing.T) { 0x00, 0x00, 0x00, 0x64, // 100 0x00, 0x00, 0x00, 0xC8, // 200 } - reader := reader.NewReader(input, reader.Options{ - ParameterParser: &Parameter{}, - ReliableHeaderParameterCount: &ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }) + reader := reader.NewReader(input) p := &Parameter{} out := &types.Parameter{} err := p.Parse(reader, out, nil) @@ -404,12 +382,7 @@ func TestReadArrayGeneric(t *testing.T) { 0x66, // Float32Type 0x3f, 0x80, 0x00, 0x00, // 1.0 BE } - reader := reader.NewReader(input, reader.Options{ - ParameterParser: &Parameter{}, - - ReliableHeaderParameterCount: &ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }) + reader := reader.NewReader(input) p := &Parameter{} out := &types.Parameter{} err := p.Parse(reader, out, nil) @@ -443,11 +416,7 @@ func BenchmarkReadInt8Array(b *testing.B) { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, } b.ResetTimer() - reader := reader.NewReader(data, reader.Options{ - ParameterParser: &Parameter{}, - ReliableHeaderParameterCount: &ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }) + reader := reader.NewReader(data) p := &Parameter{} for i := 0; i < b.N; i++ { @@ -467,11 +436,7 @@ func BenchmarkReadStringArray(b *testing.B) { 0x00, 0x04, 'D', 'a', 't', 'a', } b.ResetTimer() - reader := reader.NewReader(data, reader.Options{ - ParameterParser: &Parameter{}, - ReliableHeaderParameterCount: &ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }) + reader := reader.NewReader(data) p := &Parameter{} for i := 0; i < b.N; i++ { diff --git a/internal/parameters/v16/dicts.go b/internal/parameters/v16/dicts.go index 31495b0..e2c1025 100644 --- a/internal/parameters/v16/dicts.go +++ b/internal/parameters/v16/dicts.go @@ -1,6 +1,7 @@ package v16 import ( + "encoding/binary" "michelprogram/photon-parser/internal/reader" "michelprogram/photon-parser/internal/types" ) @@ -30,7 +31,7 @@ func (p Parameter) readDictionary(r *reader.Reader) (map[any]any, error) { return nil, err } - size, err := r.ReadUInt16() + size, err := r.ReadUInt16(binary.BigEndian) if err != nil { return nil, err } @@ -76,7 +77,7 @@ func (p Parameter) readDictionary(r *reader.Reader) (map[any]any, error) { // // Returns an error if the hashtable cannot be fully read. func (p Parameter) readHashTable(r *reader.Reader) (map[any]any, error) { - size, err := r.ReadUInt16() + size, err := r.ReadUInt16(binary.BigEndian) if err != nil { return nil, err } diff --git a/internal/parameters/v16/dicts_test.go b/internal/parameters/v16/dicts_test.go index 35c740b..94e899a 100644 --- a/internal/parameters/v16/dicts_test.go +++ b/internal/parameters/v16/dicts_test.go @@ -1,7 +1,6 @@ package v16_test import ( - "encoding/binary" . "michelprogram/photon-parser/internal/parameters/v16" "michelprogram/photon-parser/internal/reader" "michelprogram/photon-parser/internal/types" @@ -90,11 +89,7 @@ func TestReadDictionnary(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - reader := reader.NewReader(tt.input, reader.Options{ - ParameterParser: &Parameter{}, - ReliableHeaderParameterCount: &ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }) + reader := reader.NewReader(tt.input) p := &Parameter{} out := &types.Parameter{} err := p.Parse(reader, out, nil) @@ -156,11 +151,7 @@ func TestReadHashtable(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - reader := reader.NewReader(tt.input, reader.Options{ - ParameterParser: &Parameter{}, - ReliableHeaderParameterCount: &ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }) + reader := reader.NewReader(tt.input) p := &Parameter{} out := &types.Parameter{} err := p.Parse(reader, out, nil) diff --git a/internal/parameters/v16/header.go b/internal/parameters/v16/header.go index afaf9ce..f8349c4 100644 --- a/internal/parameters/v16/header.go +++ b/internal/parameters/v16/header.go @@ -1,14 +1,17 @@ package v16 -import "michelprogram/photon-parser/internal/reader" +import ( + "michelprogram/photon-parser/internal/context" + "michelprogram/photon-parser/internal/reader" +) type ReliableHeaderParameterCountV16 struct{} -var _ reader.ReliableHeaderParameterCount = (*ReliableHeaderParameterCountV16)(nil) +var _ context.ReliableHeaderParameterCount = (*ReliableHeaderParameterCountV16)(nil) func (ReliableHeaderParameterCountV16) Count(r *reader.Reader) (int, error) { res, err := r.ReadUInt8() - if err != nil{ + if err != nil { return 0, err } diff --git a/internal/parameters/v16/parameters.go b/internal/parameters/v16/parameters.go index d5ec77a..8316179 100644 --- a/internal/parameters/v16/parameters.go +++ b/internal/parameters/v16/parameters.go @@ -1,7 +1,9 @@ package v16 import ( + "encoding/binary" "fmt" + "michelprogram/photon-parser/internal/context" "michelprogram/photon-parser/internal/hooks" "michelprogram/photon-parser/internal/reader" "michelprogram/photon-parser/internal/types" @@ -11,7 +13,7 @@ type Parameter struct { types.Parameter } -var _ reader.ParameterParser = (*Parameter)(nil) +var _ context.ParameterParser = (*Parameter)(nil) // Parse reads a complete parameter from the reader. // Format: Header (1 byte ID + 1 byte Type), followed by the typed value. @@ -104,15 +106,15 @@ func (p Parameter) decode(reader *reader.Reader, ttype types.ParameterType) (any case types.Int8Type: return reader.ReadInt8() case types.Int16Type: - return reader.ReadInt16() + return reader.ReadInt16(binary.BigEndian) case types.Int32Type: - return reader.ReadInt32() + return reader.ReadInt32(binary.BigEndian) case types.Int64Type: - return reader.ReadInt64() + return reader.ReadInt64(binary.BigEndian) case types.Float32Type: - return reader.ReadFloat32() + return reader.ReadFloat32(binary.BigEndian) case types.Float64Type: - return reader.ReadFloat64() + return reader.ReadFloat64(binary.BigEndian) case types.StringType: return p.readString(reader) case types.BooleanType: diff --git a/internal/parameters/v16/parameters_test.go b/internal/parameters/v16/parameters_test.go index 4657151..3f527f9 100644 --- a/internal/parameters/v16/parameters_test.go +++ b/internal/parameters/v16/parameters_test.go @@ -1,7 +1,6 @@ package v16_test import ( - "encoding/binary" "math" . "michelprogram/photon-parser/internal/parameters/v16" "michelprogram/photon-parser/internal/reader" @@ -166,11 +165,7 @@ func TestDecode(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { fullInput := append([]byte{0x00, byte(tt.ttype)}, tt.input...) - reader := reader.NewReader(fullInput, reader.Options{ - ParameterParser: &Parameter{}, - ReliableHeaderParameterCount: &ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }) + reader := reader.NewReader(fullInput) param := Parameter{} out := &types.Parameter{} err := param.Parse(reader, out, nil) @@ -216,12 +211,7 @@ func TestDecodeAllTypes(t *testing.T) { t.Run(string(rune(ttype)), func(t *testing.T) { fullInput := append([]byte{0x00, byte(ttype)}, input...) - reader := reader.NewReader(fullInput, reader.Options{ - ParameterParser: &Parameter{}, - - ReliableHeaderParameterCount: &ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }) + reader := reader.NewReader(fullInput) param := Parameter{} out := &types.Parameter{} err := param.Parse(reader, out, nil) @@ -239,12 +229,7 @@ func TestDecodeReaderPosition(t *testing.T) { 0x00, byte(types.Int8Type), 0x2A, 0x00, byte(types.Int16Type), 0x03, 0xE8, } - reader := reader.NewReader(input, reader.Options{ - ParameterParser: &Parameter{}, - - ReliableHeaderParameterCount: &ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }) + reader := reader.NewReader(input) param := Parameter{} // Read first value (int8) @@ -280,12 +265,7 @@ func TestDecodeEmptyReader(t *testing.T) { for _, ttype := range parameterTypes { t.Run(string(rune(ttype)), func(t *testing.T) { - reader := reader.NewReader([]byte{}, reader.Options{ - ParameterParser: &Parameter{}, - - ReliableHeaderParameterCount: &ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }) + reader := reader.NewReader([]byte{}) param := Parameter{} out := &types.Parameter{} err := param.Parse(reader, out, nil) @@ -340,11 +320,7 @@ func BenchmarkDecode(b *testing.B) { b.Run(bm.name, func(b *testing.B) { b.ReportAllocs() fullInput := append([]byte{0x00, byte(bm.ttype)}, bm.input...) - r := reader.NewReader(fullInput, reader.Options{ - ParameterParser: &Parameter{}, - ReliableHeaderParameterCount: &ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }) + r := reader.NewReader(fullInput) param := Parameter{} for i := 0; i < b.N; i++ { out := &types.Parameter{} diff --git a/internal/parameters/v16/string.go b/internal/parameters/v16/string.go index 2ce009b..949fdfc 100644 --- a/internal/parameters/v16/string.go +++ b/internal/parameters/v16/string.go @@ -1,6 +1,9 @@ package v16 -import "michelprogram/photon-parser/internal/reader" +import ( + "encoding/binary" + "michelprogram/photon-parser/internal/reader" +) // ReadString reads a Photon Protocol16 string from the reader. // Format: uint16 length (big-endian) followed by UTF-8 bytes. @@ -11,7 +14,7 @@ import "michelprogram/photon-parser/internal/reader" // // 0x00 0x05 'h' 'e' 'l' 'l' 'o' func (p Parameter) readString(reader *reader.Reader) (string, error) { - size, err := reader.ReadUInt16() + size, err := reader.ReadUInt16(binary.BigEndian) if err != nil { return "", err } diff --git a/internal/parameters/v18/arrays.go b/internal/parameters/v18/arrays.go index c89b493..e649405 100644 --- a/internal/parameters/v18/arrays.go +++ b/internal/parameters/v18/arrays.go @@ -1,6 +1,7 @@ package v18 import ( + "encoding/binary" "michelprogram/photon-parser/internal/reader" ) @@ -13,7 +14,7 @@ func (p Parameter) readFloatArray(r *reader.Reader) ([]float32, error) { val := make([]float32, size) for i := uint32(0); i < size; i++ { - input, err := r.ReadFloat32() + input, err := r.ReadFloat32(binary.BigEndian) if err != nil { return nil, err } @@ -49,7 +50,7 @@ func (p Parameter) readInt16Array(r *reader.Reader) ([]int16, error) { val := make([]int16, size) for i := uint32(0); i < size; i++ { - input, err := r.ReadInt16LittleEndian() + input, err := r.ReadInt16(binary.LittleEndian) if err != nil { return nil, err } diff --git a/internal/parameters/v18/dicts.go b/internal/parameters/v18/dicts.go index 4e179c7..a21edd1 100644 --- a/internal/parameters/v18/dicts.go +++ b/internal/parameters/v18/dicts.go @@ -1,6 +1,7 @@ package v18 import ( + "encoding/binary" "michelprogram/photon-parser/internal/reader" ) @@ -75,7 +76,7 @@ func (p Parameter) readDictionary(r *reader.Reader) (map[any]any, error) { // // Returns an error if the hashtable cannot be fully read. func (p Parameter) readHashTable(r *reader.Reader) (map[any]any, error) { - size, err := r.ReadUInt16() + size, err := r.ReadUInt16(binary.BigEndian) if err != nil { return nil, err } diff --git a/internal/parameters/v18/header.go b/internal/parameters/v18/header.go index 6a73ea2..3800ed3 100644 --- a/internal/parameters/v18/header.go +++ b/internal/parameters/v18/header.go @@ -1,16 +1,18 @@ package v18 -import "michelprogram/photon-parser/internal/reader" +import ( + "michelprogram/photon-parser/internal/context" + "michelprogram/photon-parser/internal/reader" +) type ReliableHeaderParameterCountV18 struct{} -var _ reader.ReliableHeaderParameterCount = (*ReliableHeaderParameterCountV18)(nil) +var _ context.ReliableHeaderParameterCount = (*ReliableHeaderParameterCountV18)(nil) func (ReliableHeaderParameterCountV18) Count(r *reader.Reader) (int, error) { res, err := r.ReadVarintUInt32() - if err != nil{ + if err != nil { return 0, err } - return int(res), nil -} +} \ No newline at end of file diff --git a/internal/parameters/v18/parameters.go b/internal/parameters/v18/parameters.go index be3c3d0..25b6028 100644 --- a/internal/parameters/v18/parameters.go +++ b/internal/parameters/v18/parameters.go @@ -1,8 +1,10 @@ package v18 import ( + "encoding/binary" "fmt" "log" + "michelprogram/photon-parser/internal/context" "michelprogram/photon-parser/internal/hooks" "michelprogram/photon-parser/internal/reader" "michelprogram/photon-parser/internal/types" @@ -12,7 +14,7 @@ type Parameter struct { types.Parameter } -var _ reader.ParameterParser = (*Parameter)(nil) +var _ context.ParameterParser = (*Parameter)(nil) // Parse reads a complete parameter from the reader. // Format: Header (1 byte ID + 1 byte Type), followed by the typed value. @@ -48,7 +50,7 @@ func (p *Parameter) Parse(reader *reader.Reader, out *types.Parameter, hooks *ho out.ParameterHeader = header out.Value = value - p.emit(reader, hooks,out) + p.emit(reader, hooks, out) return nil } @@ -116,15 +118,15 @@ func (p Parameter) decode(reader *reader.Reader, ttype ParameterType) (any, erro } return -int32(value), nil case Int16Type: - return reader.ReadInt16LittleEndian() + return reader.ReadInt16(binary.LittleEndian) case Int16Positive: - value, err := reader.ReadUInt16LittleEndian() + value, err := reader.ReadUInt16(binary.LittleEndian) if err != nil { return nil, err } return int32(value), nil case Int16Negative: - value, err := reader.ReadUInt16LittleEndian() + value, err := reader.ReadUInt16(binary.LittleEndian) if err != nil { return nil, err } @@ -142,13 +144,13 @@ func (p Parameter) decode(reader *reader.Reader, ttype ParameterType) (any, erro } return -int64(value), nil case Long16Positive: - value, err := reader.ReadUInt16LittleEndian() + value, err := reader.ReadUInt16(binary.LittleEndian) if err != nil { return nil, err } return int64(value), nil case Long16Negative: - value, err := reader.ReadUInt16LittleEndian() + value, err := reader.ReadUInt16(binary.LittleEndian) if err != nil { return nil, err } @@ -162,7 +164,7 @@ func (p Parameter) decode(reader *reader.Reader, ttype ParameterType) (any, erro case Float32ArrayType: return p.readFloatArray(reader) case Float32Type: - return reader.ReadFloat32() + return reader.ReadFloat32(binary.BigEndian) case Int8Type: return reader.ReadInt8() case BooleanTrueType: diff --git a/internal/reader/reader.go b/internal/reader/reader.go index 587f8c7..a37ea16 100644 --- a/internal/reader/reader.go +++ b/internal/reader/reader.go @@ -2,23 +2,10 @@ package reader import ( "encoding/binary" - "fmt" "math" - "michelprogram/photon-parser/internal/hooks" - "michelprogram/photon-parser/internal/types" + "michelprogram/photon-parser/internal/errors" ) -// ParameterParser is implemented by each protocol-version parameters package -// (v16, v18, ...). It is wired once at Parser construction so the hot path -// has no version branches. -type ParameterParser interface { - Parse(r *Reader, out *types.Parameter, hooks *hooks.Hooks) error -} - -type ReliableHeaderParameterCount interface { - Count(r *Reader) (int, error) -} - const ( INT8_SIZE = 1 INT16_SIZE = 2 @@ -31,46 +18,34 @@ const ( VARINT_MSB_MASK = 0x80 ) -type Options struct { - ParameterParser - ReliableHeaderParameterCount - BinaryOrder binary.ByteOrder -} - type Reader struct { Buffer []byte Max int Cursor int - - Options } -func NewReader(data []byte, options Options) *Reader { +func NewReader(data []byte) *Reader { return &Reader{ - Buffer: data, - Max: len(data), - Cursor: 0, - Options: options, + Buffer: data, + Max: len(data), + Cursor: 0, } } -func (r *Reader) ReadRest() []byte { +// Read Remaining bytes from the reader. +func (r *Reader) ReadRemaining() []byte { tmp := r.Cursor r.Cursor = r.Max return r.Buffer[tmp:] } -func (r *Reader) SetParameterParser(parser ParameterParser) { - r.ParameterParser = parser -} - // ReadInt8 reads an 8-bit signed integer from the reader. // Returns an error if fewer than 1 byte is available. func (r *Reader) ReadInt8() (int8, error) { size := r.Cursor + INT8_SIZE if size > r.Max { - return 0, fmt.Errorf("not enough bytes to read int8") + return 0, errors.NotEnoughBytesInt8 } b := r.Buffer[r.Cursor:size] @@ -84,7 +59,7 @@ func (r *Reader) ReadUInt8() (uint8, error) { size := r.Cursor + INT8_SIZE if size > r.Max { - return 0, fmt.Errorf("not enough bytes to read uint8") + return 0, errors.NotEnoughBytesUInt8 } b := r.Buffer[r.Cursor:size] @@ -92,189 +67,125 @@ func (r *Reader) ReadUInt8() (uint8, error) { return uint8(b[0]), nil } -// ReadInt16 reads a 16-bit signed integer from the reader in big-endian format. +// ReadInt16 reads a 16-bit signed integer from the reader in the given byte order. // Returns an error if fewer than 2 bytes are available. -func (r *Reader) ReadInt16() (int16, error) { +func (r *Reader) ReadInt16(order binary.ByteOrder) (int16, error) { size := r.Cursor + INT16_SIZE if size > r.Max { - return 0, fmt.Errorf("not enough bytes to read int16") + return 0, errors.NotEnoughBytesInt16 } b := r.Buffer[r.Cursor:size] r.Cursor += INT16_SIZE - return int16(b[0])<<8 | int16(b[1]), nil + return int16(order.Uint16(b)), nil } -func (r *Reader) ReadInt16LittleEndian() (int16, error) { - - size := r.Cursor + INT16_SIZE - - if size > r.Max { - return 0, fmt.Errorf("not enough bytes to read int16") - } - - b := r.Buffer[r.Cursor:size] - r.Cursor += INT16_SIZE - - return int16(b[1])<<8 | int16(b[0]), nil -} - -// ReadUInt16 reads a 16-bit unsigned integer from the reader in big-endian format. +// ReadUInt16 reads a 16-bit unsigned integer from the reader in the given byte order. // Returns an error if fewer than 2 bytes are available. -func (r *Reader) ReadUInt16() (uint16, error) { - - size := r.Cursor + INT16_SIZE - - if size > r.Max { - return 0, fmt.Errorf("not enough bytes to read uint16") - } - - b := r.Buffer[r.Cursor:size] - r.Cursor += INT16_SIZE - - return uint16(b[0])<<8 | uint16(b[1]), nil -} - -func (r *Reader) ReadUInt16LittleEndian() (uint16, error) { +func (r *Reader) ReadUInt16(order binary.ByteOrder) (uint16, error) { size := r.Cursor + INT16_SIZE if size > r.Max { - return 0, fmt.Errorf("not enough bytes to read uint16") + return 0, errors.NotEnoughBytesUInt16 } b := r.Buffer[r.Cursor:size] r.Cursor += INT16_SIZE - return uint16(b[1])<<8 | uint16(b[0]), nil + return order.Uint16(b), nil } -// ReadInt32 reads a 32-bit signed integer from the reader in big-endian format. +// ReadInt32 reads a 32-bit signed integer from the reader in the given byte order. // Returns an error if fewer than 4 bytes are available. -func (r *Reader) ReadInt32() (int32, error) { +func (r *Reader) ReadInt32(order binary.ByteOrder) (int32, error) { size := r.Cursor + INT32_SIZE if size > r.Max { - return 0, fmt.Errorf("not enough bytes to read int32") + return 0, errors.NotEnoughBytesInt32 } b := r.Buffer[r.Cursor:size] r.Cursor += INT32_SIZE - return int32(b[0])<<24 | - int32(b[1])<<16 | - int32(b[2])<<8 | - int32(b[3]), nil + return int32(order.Uint32(b)), nil } -func (r *Reader) ReadInt32LittleEndian() (int32, error) { - size := r.Cursor + INT32_SIZE - - if size > r.Max { - return 0, fmt.Errorf("not enough bytes to read int32") - } - - b := r.Buffer[r.Cursor:size] - r.Cursor += INT32_SIZE - - return int32(b[3])<<24 | - int32(b[2])<<16 | - int32(b[1])<<8 | - int32(b[0]), nil -} - -// ReadUInt32 reads a 32-bit unsigned integer from the reader in big-endian format. +// ReadUInt32 reads a 32-bit unsigned integer from the reader in the given byte order. // Returns an error if fewer than 4 bytes are available. -func (r *Reader) ReadUInt32() (uint32, error) { +func (r *Reader) ReadUInt32(order binary.ByteOrder) (uint32, error) { size := r.Cursor + INT32_SIZE if size > r.Max { - return 0, fmt.Errorf("not enough bytes to read uint32") + return 0, errors.NotEnoughBytesUInt32 } b := r.Buffer[r.Cursor:size] r.Cursor += INT32_SIZE - return uint32(b[0])<<24 | - uint32(b[1])<<16 | - uint32(b[2])<<8 | - uint32(b[3]), nil + return order.Uint32(b), nil } -// ReadInt64 reads a 64-bit signed integer from the reader in big-endian format. +// ReadInt64 reads a 64-bit signed integer from the reader in the given byte order. // Returns an error if fewer than 8 bytes are available. -func (r *Reader) ReadInt64() (int64, error) { +func (r *Reader) ReadInt64(order binary.ByteOrder) (int64, error) { size := r.Cursor + INT64_SIZE if size > r.Max { - return 0, fmt.Errorf("not enough bytes to read int64") + return 0, errors.NotEnoughBytesInt64 } b := r.Buffer[r.Cursor:size] r.Cursor += INT64_SIZE - return int64(b[0])<<56 | - int64(b[1])<<48 | - int64(b[2])<<40 | - int64(b[3])<<32 | - int64(b[4])<<24 | - int64(b[5])<<16 | - int64(b[6])<<8 | - int64(b[7]), nil + return int64(order.Uint64(b)), nil } -// ReadUInt64 reads a 64-bit unsigned integer from the reader in big-endian format. +// ReadUInt64 reads a 64-bit unsigned integer from the reader in the given byte order. // Returns an error if fewer than 8 bytes are available. -func (r *Reader) ReadUInt64() (uint64, error) { +func (r *Reader) ReadUInt64(order binary.ByteOrder) (uint64, error) { size := r.Cursor + INT64_SIZE if size > r.Max { - return 0, fmt.Errorf("not enough bytes to read uint64") + return 0, errors.NotEnoughBytesUInt64 } b := r.Buffer[r.Cursor:size] r.Cursor += INT64_SIZE - return uint64(b[0])<<56 | - uint64(b[1])<<48 | - uint64(b[2])<<40 | - uint64(b[3])<<32 | - uint64(b[4])<<24 | - uint64(b[5])<<16 | - uint64(b[6])<<8 | - uint64(b[7]), nil + return order.Uint64(b), nil } -// ReadFloat32 reads a 32-bit floating point number from the reader in big-endian format. +// ReadFloat32 reads a 32-bit floating point number from the reader in the given byte order. // Returns an error if fewer than 4 bytes are available. -func (r *Reader) ReadFloat32() (float32, error) { +func (r *Reader) ReadFloat32(order binary.ByteOrder) (float32, error) { size := r.Cursor + FLOAT32_SIZE if size > r.Max { - return 0, fmt.Errorf("not enough bytes to read float32") + return 0, errors.NotEnoughBytesFloat32 } b := r.Buffer[r.Cursor:size] r.Cursor += FLOAT32_SIZE - return math.Float32frombits(r.BinaryOrder.Uint32(b)), nil + return math.Float32frombits(order.Uint32(b)), nil } -// ReadFloat64 reads a 64-bit floating point number from the reader in big-endian format. +// ReadFloat64 reads a 64-bit floating point number from the reader in the given byte order. // Returns an error if fewer than 8 bytes are available. -func (r *Reader) ReadFloat64() (float64, error) { +func (r *Reader) ReadFloat64(order binary.ByteOrder) (float64, error) { size := r.Cursor + FLOAT64_SIZE if size > r.Max { - return 0, fmt.Errorf("not enough bytes to read float64") + return 0, errors.NotEnoughBytesFloat64 } b := r.Buffer[r.Cursor:size] r.Cursor += INT64_SIZE - return math.Float64frombits(r.BinaryOrder.Uint64(b)), nil + return math.Float64frombits(order.Uint64(b)), nil } // ReadBoolean reads a boolean value from the reader. @@ -284,7 +195,7 @@ func (r *Reader) ReadBoolean() (bool, error) { bit, err := r.ReadUInt8() if err != nil { - return false, fmt.Errorf("not enough bytes to read boolean") + return false, err } if bit == 0 { @@ -295,7 +206,7 @@ func (r *Reader) ReadBoolean() (bool, error) { return true, nil } - return false, fmt.Errorf("invalid value for boolean: %d (expected 0 or 1)", bit) + return false, errors.InvalidBooleanValue } // ReadString reads a string of n size from the reader. @@ -305,7 +216,7 @@ func (r *Reader) ReadString(n int) (string, error) { size := r.Cursor + n if size > r.Max { - return "", fmt.Errorf("not enough bytes to read string of size %d", n) + return "", errors.NotEnoughBytesString } str := string(r.Buffer[r.Cursor:size]) @@ -319,7 +230,7 @@ func (r *Reader) ReadByte() (byte, error) { size := r.Cursor + 1 if size > r.Max { - return 0, fmt.Errorf("not enough bytes to read byte") + return 0, errors.NotEnoughBytesByte } c := r.Buffer[r.Cursor] @@ -335,7 +246,7 @@ func (r *Reader) ReadBytes(n int) ([]byte, error) { size := r.Cursor + n if size > r.Max { - return []byte{}, fmt.Errorf("not enough bytes to read []byte of size %d", n) + return []byte{}, errors.NotEnoughBytesBytes } buff := r.Buffer[r.Cursor:size] @@ -343,6 +254,7 @@ func (r *Reader) ReadBytes(n int) ([]byte, error) { return buff, nil } +// ReadVarintUInt32 reads a 32-bit unsigned integer from the reader in varint format. func (r *Reader) ReadVarintUInt32() (uint32, error) { var res uint32 @@ -365,29 +277,19 @@ func (r *Reader) ReadVarintUInt32() (uint32, error) { return res, nil } +// ReadVarintInt32 reads a 32-bit signed integer from the reader in varint format. func (r *Reader) ReadVarintInt32() (int32, error) { - var res uint32 - var shift uint8 - for { - - buff, err := r.ReadByte() - if err != nil { - return 0, err - } - - res |= uint32(buff&VARINT_MASK) << shift - - if buff&VARINT_MSB_MASK == 0 { - break - } - shift += VARINT_SHIFT + res, err := r.ReadVarintUInt32() + if err != nil { + return 0, err } //ZigZag decode return int32((res >> 1) ^ uint32(-(int32(res & 1)))), nil } +// ReadVarintUInt64 reads a 64-bit unsigned integer from the reader in varint format. func (r *Reader) ReadVarintUInt64() (uint64, error) { var res uint64 @@ -410,29 +312,19 @@ func (r *Reader) ReadVarintUInt64() (uint64, error) { return res, nil } +// ReadVarintInt64 reads a 64-bit signed integer from the reader in varint format. func (r *Reader) ReadVarintInt64() (int64, error) { - var res uint64 - var shift uint8 - for { - - buff, err := r.ReadByte() - if err != nil { - return 0, err - } - - res |= uint64(buff&VARINT_MASK) << shift - - if buff&VARINT_MSB_MASK == 0 { - break - } - shift += VARINT_SHIFT + res, err := r.ReadVarintUInt64() + if err != nil { + return 0, err } //ZigZag decode return int64((res >> 1) ^ uint64(-(int64(res & 1)))), nil } +// Reset resets the reader to the beginning of the buffer. func (r *Reader) Reset(data []byte) { r.Buffer = data r.Cursor = 0 diff --git a/internal/reader/reader_test.go b/internal/reader/reader_test.go index 92695e8..8c38dff 100644 --- a/internal/reader/reader_test.go +++ b/internal/reader/reader_test.go @@ -3,8 +3,6 @@ package reader_test import ( "encoding/binary" "math" - v16 "michelprogram/photon-parser/internal/parameters/v16" - v18 "michelprogram/photon-parser/internal/parameters/v18" "michelprogram/photon-parser/internal/reader" "testing" ) @@ -22,11 +20,7 @@ func TestReadByte(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - r := reader.NewReader(tt.input, reader.Options{ - ParameterParser: &v16.Parameter{}, - ReliableHeaderParameterCount: &v16.ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }) + r := reader.NewReader(tt.input) got, err := r.ReadByte() if (err != nil) != tt.wantErr { t.Fatalf("ReadByte() err = %v, wantErr %v", err, tt.wantErr) @@ -71,11 +65,7 @@ func TestReadVarintInt32(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - r := reader.NewReader(tt.input, reader.Options{ - ParameterParser: &v18.Parameter{}, - ReliableHeaderParameterCount: &v18.ReliableHeaderParameterCountV18{}, - BinaryOrder: binary.LittleEndian, - }) + r := reader.NewReader(tt.input) got, err := r.ReadVarintInt32() if err != nil { t.Fatalf("ReadVarintInt32() err = %v", err) @@ -138,11 +128,7 @@ func TestReadVarintInt64(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - r := reader.NewReader(tt.input, reader.Options{ - ParameterParser: &v18.Parameter{}, - ReliableHeaderParameterCount: &v18.ReliableHeaderParameterCountV18{}, - BinaryOrder: binary.LittleEndian, - }) + r := reader.NewReader(tt.input) got, err := r.ReadVarintInt64() if err != nil { t.Fatalf("ReadVarintInt64() err = %v", err) @@ -190,9 +176,7 @@ func TestReadInt8(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - r := reader.NewReader(tt.input, reader.Options{ - ParameterParser: &v16.Parameter{}, - }) + r := reader.NewReader(tt.input) got, err := r.ReadInt8() if (err != nil) != tt.wantErr { @@ -222,11 +206,7 @@ func TestReadUInt8(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - r := reader.NewReader(tt.input, reader.Options{ - ParameterParser: &v16.Parameter{}, - ReliableHeaderParameterCount: &v16.ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }) + r := reader.NewReader(tt.input) got, err := r.ReadUInt8() if (err != nil) != tt.wantErr { @@ -281,12 +261,8 @@ func TestReadInt16(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - r := reader.NewReader(tt.input, reader.Options{ - ParameterParser: &v16.Parameter{}, - ReliableHeaderParameterCount: &v16.ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }) - got, err := r.ReadInt16() + r := reader.NewReader(tt.input) + got, err := r.ReadInt16(binary.BigEndian) if (err != nil) != tt.wantErr { t.Errorf("ReadInt16() error = %v, wantErr %v", err, tt.wantErr) @@ -316,12 +292,8 @@ func TestReadUInt16(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - r := reader.NewReader(tt.input, reader.Options{ - ParameterParser: &v16.Parameter{}, - ReliableHeaderParameterCount: &v16.ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }) - got, err := r.ReadUInt16() + r := reader.NewReader(tt.input) + got, err := r.ReadUInt16(binary.BigEndian) if (err != nil) != tt.wantErr { t.Errorf("ReadUInt16() error = %v, wantErr %v", err, tt.wantErr) @@ -370,12 +342,8 @@ func TestReadInt32(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - r := reader.NewReader(tt.input, reader.Options{ - ParameterParser: &v16.Parameter{}, - ReliableHeaderParameterCount: &v16.ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }) - got, err := r.ReadInt32() + r := reader.NewReader(tt.input) + got, err := r.ReadInt32(binary.BigEndian) if (err != nil) != tt.wantErr { t.Errorf("ReadInt32() error = %v, wantErr %v", err, tt.wantErr) @@ -404,12 +372,8 @@ func TestReadUInt32(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - r := reader.NewReader(tt.input, reader.Options{ - ParameterParser: &v16.Parameter{}, - ReliableHeaderParameterCount: &v16.ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }) - got, err := r.ReadUInt32() + r := reader.NewReader(tt.input) + got, err := r.ReadUInt32(binary.BigEndian) if (err != nil) != tt.wantErr { t.Errorf("ReadUInt32() error = %v, wantErr %v", err, tt.wantErr) @@ -458,12 +422,8 @@ func TestReadInt64(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - r := reader.NewReader(tt.input, reader.Options{ - ParameterParser: &v16.Parameter{}, - ReliableHeaderParameterCount: &v16.ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }) - got, err := r.ReadInt64() + r := reader.NewReader(tt.input) + got, err := r.ReadInt64(binary.BigEndian) if (err != nil) != tt.wantErr { t.Errorf("ReadInt64() error = %v, wantErr %v", err, tt.wantErr) @@ -508,12 +468,8 @@ func TestReadUInt64(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - r := reader.NewReader(tt.input, reader.Options{ - ParameterParser: &v16.Parameter{}, - ReliableHeaderParameterCount: &v16.ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }) - got, err := r.ReadUInt64() + r := reader.NewReader(tt.input) + got, err := r.ReadUInt64(binary.BigEndian) if (err != nil) != tt.wantErr { t.Errorf("ReadUInt64() error = %v, wantErr %v", err, tt.wantErr) @@ -562,12 +518,8 @@ func TestReadFloat32(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - r := reader.NewReader(tt.input, reader.Options{ - ParameterParser: &v16.Parameter{}, - ReliableHeaderParameterCount: &v16.ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }) - got, err := r.ReadFloat32() + r := reader.NewReader(tt.input) + got, err := r.ReadFloat32(binary.BigEndian) if (err != nil) != tt.wantErr { t.Errorf("ReadFloat32() error = %v, wantErr %v", err, tt.wantErr) @@ -615,12 +567,8 @@ func TestReadFloat64(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - r := reader.NewReader(tt.input, reader.Options{ - ParameterParser: &v16.Parameter{}, - ReliableHeaderParameterCount: &v16.ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }) - got, err := r.ReadFloat64() + r := reader.NewReader(tt.input) + got, err := r.ReadFloat64(binary.BigEndian) if (err != nil) != tt.wantErr { t.Errorf("ReadFloat64() error = %v, wantErr %v", err, tt.wantErr) @@ -672,11 +620,7 @@ func TestReadBoolean(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - r := reader.NewReader(tt.input, reader.Options{ - ParameterParser: &v16.Parameter{}, - ReliableHeaderParameterCount: &v16.ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }) + r := reader.NewReader(tt.input) got, err := r.ReadBoolean() if (err != nil) != tt.wantErr { @@ -733,11 +677,7 @@ func TestReadString(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - r := reader.NewReader(tt.input, reader.Options{ - ParameterParser: &v16.Parameter{}, - ReliableHeaderParameterCount: &v16.ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }) + r := reader.NewReader(tt.input) got, err := r.ReadString(tt.size) if (err != nil) != tt.wantErr { diff --git a/internal/session/session.go b/internal/session/session.go index d607428..6c79d0f 100644 --- a/internal/session/session.go +++ b/internal/session/session.go @@ -4,6 +4,7 @@ package session import ( + "encoding/binary" "errors" "fmt" "michelprogram/photon-parser/internal/command" @@ -80,7 +81,7 @@ func (s *Session) parseHeader(r *reader.Reader) (types.Header, error) { var err error var header types.Header - header.PeerID, err = r.ReadUInt16() + header.PeerID, err = r.ReadUInt16(binary.BigEndian) if err != nil { return types.Header{}, err } @@ -95,12 +96,12 @@ func (s *Session) parseHeader(r *reader.Reader) (types.Header, error) { return types.Header{}, err } - header.Timestamp, err = r.ReadUInt32() + header.Timestamp, err = r.ReadUInt32(binary.BigEndian) if err != nil { return types.Header{}, err } - header.Challenge, err = r.ReadInt32() + header.Challenge, err = r.ReadInt32(binary.BigEndian) if err != nil { return types.Header{}, err } diff --git a/internal/session/session_test.go b/internal/session/session_test.go index 16ab52c..0d287ce 100644 --- a/internal/session/session_test.go +++ b/internal/session/session_test.go @@ -1,7 +1,6 @@ package session_test import ( - "encoding/binary" "encoding/hex" "michelprogram/photon-parser/internal/context" v16 "michelprogram/photon-parser/internal/parameters/v16" @@ -19,13 +18,15 @@ func TestParseSession(t *testing.T) { t.Fatalf("LoadFromWiresharkExport() failed: %v", err) } - ctx := &context.Context{ - Reader: reader.NewReader(cleared, reader.Options{ + ctx := context.NewContext( + reader.NewReader(cleared), + nil, + nil, + context.Decoders{ ParameterParser: &v16.Parameter{}, ReliableHeaderParameterCount: &v16.ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }), - } + }, + ) sess, err := session.Parse(ctx) if err != nil { @@ -64,14 +65,15 @@ func BenchmarkParseSession(b *testing.B) { for b.Loop() { - ctx := &context.Context{ - Reader: reader.NewReader(payload, reader.Options{ + ctx := context.NewContext( + reader.NewReader(payload), + nil, + nil, + context.Decoders{ ParameterParser: &v16.Parameter{}, ReliableHeaderParameterCount: &v16.ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }), - } - + }, + ) sess, err := session.Parse(ctx) if err != nil { b.Fatalf("LoadFromWiresharkExport() failed: %v", err) diff --git a/parser.go b/parser.go index fe4785f..7bd0669 100644 --- a/parser.go +++ b/parser.go @@ -1,7 +1,6 @@ package photon import ( - "encoding/binary" "michelprogram/photon-parser/internal/assembler" "michelprogram/photon-parser/internal/context" "michelprogram/photon-parser/internal/hooks" @@ -19,28 +18,28 @@ type Parser struct { func NewParserV16() *Parser { return &Parser{ Ctx: context.NewContext( - reader.NewReader(nil, reader.Options{ - ParameterParser: &v16.Parameter{}, - ReliableHeaderParameterCount: &v16.ReliableHeaderParameterCountV16{}, - BinaryOrder: binary.BigEndian, - }), + reader.NewReader(nil), assembler.NewAssembler(), hooks.NewHooks(), + context.Decoders{ + ParameterParser: &v16.Parameter{}, + ReliableHeaderParameterCount: &v16.ReliableHeaderParameterCountV16{}, + }, ), } } func NewParserV18() *Parser { return &Parser{ - Ctx: &context.Context{ - Reader: reader.NewReader(nil, reader.Options{ + Ctx: context.NewContext( + reader.NewReader(nil), + assembler.NewAssembler(), + hooks.NewHooks(), + context.Decoders{ ParameterParser: &v18.Parameter{}, ReliableHeaderParameterCount: &v18.ReliableHeaderParameterCountV18{}, - BinaryOrder: binary.LittleEndian, - }), - Assembler: assembler.NewAssembler(), - Hooks: hooks.NewHooks(), - }, + }, + ), } }