diff --git a/main.go b/main.go index 8b55329..ba63991 100644 --- a/main.go +++ b/main.go @@ -136,6 +136,7 @@ func main() { // go handleConnection(conn) // } // }() + log.Println(createSubmitSMPDU()) wg := &sync.WaitGroup{} wg.Add(1) diff --git a/pdu/bind.go b/pdu/bind.go index f936f92..ebf3643 100644 --- a/pdu/bind.go +++ b/pdu/bind.go @@ -6,15 +6,15 @@ type ( system_id string password string system_type string - interface_version uint8 - addr_ton uint8 - addr_npi uint8 + interface_version byte + addr_ton byte + addr_npi byte address_range string } BIND_RESP struct { header PDU_HEADER system_id string - sc_interface_version uint8 + sc_interface_version byte } BIND_RECVEIVER struct { BIND diff --git a/pdu/bufpool.go b/pdu/bufpool.go index 5a7435b..4bdd6b0 100644 --- a/pdu/bufpool.go +++ b/pdu/bufpool.go @@ -1,21 +1,22 @@ package pdu import ( + "bytes" "sync" ) type BufferPoolManager struct { - pools map[uint]*sync.Pool + pools map[int]*sync.Pool mu sync.RWMutex } func NewBufferPoolManager() *BufferPoolManager { return &BufferPoolManager{ - pools: make(map[uint]*sync.Pool), + pools: make(map[int]*sync.Pool), } } -func (bpm *BufferPoolManager) Get(size uint) *[]uint8 { +func (bpm *BufferPoolManager) Get(size int) *bytes.Buffer { bpm.mu.RLock() pool, exists := bpm.pools[size] bpm.mu.RUnlock() @@ -27,8 +28,7 @@ func (bpm *BufferPoolManager) Get(size uint) *[]uint8 { if !exists { pool = &sync.Pool{ New: func() interface{} { - buf := make([]uint8, size) - return &buf + return bytes.NewBuffer(make([]byte, size)) }, } bpm.pools[size] = pool @@ -36,11 +36,11 @@ func (bpm *BufferPoolManager) Get(size uint) *[]uint8 { bpm.mu.Unlock() } - return pool.Get().(*[]uint8) + return pool.Get().(*bytes.Buffer); } -func (bpm *BufferPoolManager) Put(buf *[]uint8) { - size := uint(len(*buf)) +func (bpm *BufferPoolManager) Put(buf *bytes.Buffer) { + size := buf.Len() bpm.mu.RLock() pool, exists := bpm.pools[size] bpm.mu.RUnlock() @@ -49,10 +49,6 @@ func (bpm *BufferPoolManager) Put(buf *[]uint8) { return } - // Clear buffer - for i := range *buf { - (*buf)[i] = 0 - } - + buf.Reset() pool.Put(buf) } diff --git a/pdu/bufpool_test.go b/pdu/bufpool_test.go index f1d944d..e89382a 100644 --- a/pdu/bufpool_test.go +++ b/pdu/bufpool_test.go @@ -10,14 +10,14 @@ func TestRetrieveBufferOfRequestedSize(t *testing.T) { bpm := NewBufferPoolManager() size := 1024 - buffer := bpm.Get(uint(size)) + buffer := bpm.Get(size) if buffer == nil { t.Fatalf("Expected buffer, got nil") } - if len(*buffer) != size { - t.Errorf("Expected buffer size %d, got %d", size, len(*buffer)) + if buffer.Len() != size { + t.Errorf("Expected buffer size %d, got %d", size, buffer.Len()) } } @@ -25,14 +25,14 @@ func TestRequestBufferSizeZero(t *testing.T) { bpm := NewBufferPoolManager() size := 0 - buffer := bpm.Get(uint(size)) + buffer := bpm.Get(size) if buffer == nil { t.Fatalf("Expected buffer, got nil") } - if len(*buffer) != size { - t.Errorf("Expected buffer size %d, got %d", size, len(*buffer)) + if buffer.Len() != size { + t.Errorf("Expected buffer size %d, got %d", size, buffer.Len()) } } @@ -47,12 +47,12 @@ func TestConcurrentAccessToBufferPool(t *testing.T) { wg.Add(1) go func() { defer wg.Done() - buffer := bpm.Get(uint(size)) + buffer := bpm.Get(size) if buffer == nil { t.Errorf("Expected buffer, got nil") } - if len(*buffer) != size { - t.Errorf("Expected buffer size %d, got %d", size, len(*buffer)) + if buffer.Len() != size { + t.Errorf("Expected buffer size %d, got %d", size, buffer.Len()) } }() } @@ -64,14 +64,14 @@ func TestGetBufferLockUnlock(t *testing.T) { bpm := NewBufferPoolManager() size := 1024 - buffer := bpm.Get(uint(size)) + buffer := bpm.Get(size) if buffer == nil { t.Fatalf("Expected buffer, got nil") } - if len(*buffer) != size { - t.Errorf("Expected buffer size %d, got %d", size, len(*buffer)) + if buffer.Len() != size { + t.Errorf("Expected buffer size %d, got %d", size, buffer.Len()) } } @@ -79,14 +79,14 @@ func TestVerifyPoolCreationForNewSizes(t *testing.T) { bpm := NewBufferPoolManager() size := 512 - buffer := bpm.Get(uint(size)) + buffer := bpm.Get(size) if buffer == nil { t.Fatalf("Expected buffer, got nil") } - if len(*buffer) != size { - t.Errorf("Expected buffer size %d, got %d", size, len(*buffer)) + if buffer.Len() != size { + t.Errorf("Expected buffer size %d, got %d", size, buffer.Len()) } } @@ -94,14 +94,14 @@ func TestBufferPoolManagerGetBuffer(t *testing.T) { bpm := NewBufferPoolManager() size := 1024 - buffer := bpm.Get(uint(size)) + buffer := bpm.Get(size) if buffer == nil { t.Fatalf("Expected buffer, got nil") } - if len(*buffer) != size { - t.Errorf("Expected buffer size %d, got %d", size, len(*buffer)) + if buffer.Len() != size { + t.Errorf("Expected buffer size %d, got %d", size, buffer.Len()) } } @@ -110,14 +110,14 @@ func TestGetBufferWithMultipleSizes(t *testing.T) { sizes := []int{512, 1024, 2048} for _, size := range sizes { - buffer := bpm.Get(uint(size)) + buffer := bpm.Get(size) if buffer == nil { t.Fatalf("Expected buffer for size %d, got nil", size) } - if len(*buffer) != size { - t.Errorf("Expected buffer size %d, got %d", size, len(*buffer)) + if buffer.Len() != size { + t.Errorf("Expected buffer size %d, got %d", size, buffer.Len()) } } } @@ -125,7 +125,7 @@ func TestGetBufferWithMultipleSizes(t *testing.T) { func TestGetBufferIsAlwaysZero(t *testing.T) { bpm := NewBufferPoolManager() - var size uint = 1024 * 64 + size := 1024 * 64 for i := 0; i < 1000; i++ { buffer := bpm.Get(size) @@ -133,11 +133,11 @@ func TestGetBufferIsAlwaysZero(t *testing.T) { t.Fatalf("Expected buffer for size %d, got nil", size) } - if uint(len(*buffer)) != size { - t.Errorf("Expected buffer size %d, got %d", size, len(*buffer)) + if buffer.Len() != size { + t.Errorf("Expected buffer size %d, got %d", size, buffer.Len()) } - for _, b := range *buffer { + for _, b := range buffer.Bytes() { if b != 0 { t.Errorf("Expected buffer to be zero, got %d", b) } @@ -149,7 +149,7 @@ func TestGetBufferIsAlwaysZero(t *testing.T) { func BenchmarkBufferPoolManager(b *testing.B) { bpm := NewBufferPoolManager() - bufSize := uint(128 * 1024) // a PDU should not be larger than this... Even this is way too large + bufSize := 128 * 1024 // a PDU should not be larger than this... Even this is way too large b.ResetTimer() @@ -163,7 +163,7 @@ func BenchmarkBufferPoolManager(b *testing.B) { func BenchmarkBufferPoolManager_Concurrent(b *testing.B) { bpm := NewBufferPoolManager() - bufSize := uint(128 * 1024) // a PDU should not be larger than this... Even this is vway too large + bufSize := 128 * 1024 // a PDU should not be larger than this... Even this is way too large b.ResetTimer() @@ -186,17 +186,17 @@ func BenchmarkBufferPoolManager_Concurrent(b *testing.B) { func BenchmarkBufferPoolManager_Memory(b *testing.B) { bpm := NewBufferPoolManager() - bufSize := uint(128 * 1024) // a PDU should not be larger than this... Even this is vway too large + bufSize := 128 * 1024 // a PDU should not be larger than this... Even this is way too large b.ResetTimer() - var i uint8 + var i byte buf := bpm.Get(bufSize) b.StopTimer() // Simulate some work time.Sleep(10 * time.Millisecond) - for k := range *buf { - (*buf)[k] = i % 255 + for _ = range buf.Bytes() { + buf.WriteByte(i % 255) } b.StartTimer() diff --git a/pdu/cancel.go b/pdu/cancel.go index 1591250..a6f1366 100644 --- a/pdu/cancel.go +++ b/pdu/cancel.go @@ -5,11 +5,11 @@ type ( header PDU_HEADER service_type string message_id string - source_addr_ton uint8 - source_addr_npi uint8 + source_addr_ton byte + source_addr_npi byte source_addr string - dest_addr_ton uint8 - dest_addr_npi uint8 + dest_addr_ton byte + dest_addr_npi byte destination_addr string } CANCEL_SM_RESP struct { diff --git a/pdu/pdu.go b/pdu/pdu.go index e53eb57..2a34f80 100644 --- a/pdu/pdu.go +++ b/pdu/pdu.go @@ -1,17 +1,16 @@ package pdu import ( + "bytes" "encoding/binary" - "fmt" ) type ( PDU interface { - EncodeInto(*[]uint8) - Encode() []uint8 - Decode([]uint8) + Encode(*bytes.Buffer) error + Decode(*bytes.Buffer) error // Size in bytes - Size() uint32 + Size() int } PDU_HEADER struct { @@ -57,41 +56,20 @@ type ( // What are the other 0s? // Don't know -func (p *PDU_HEADER) Encode() (*[]uint8, error) { - buf := ByteBufferPool.Get(uint(p.Size())) - err := p.EncodeInto(buf) - return buf, err -} -func (p *PDU_HEADER) EncodeInto(buf *[]uint8) error { - if buf == nil { - return fmt.Errorf("cannot encode PDU_HEADER, buffer is nil") - } - if len(*buf) < 16 { - return fmt.Errorf("cannot encode PDU_HEADER, buffer too small (%d, required 16)", len(*buf)) - } - bufVal := *buf - binary.BigEndian.PutUint32(bufVal[0:4], p.command_length) - binary.BigEndian.PutUint32(bufVal[4:8], p.command_id) - binary.BigEndian.PutUint32(bufVal[8:12], p.command_status) - binary.BigEndian.PutUint32(bufVal[12:16], p.sequence_number) +func (p *PDU_HEADER) Encode(buf *bytes.Buffer) error { + binary.Write(buf, binary.BigEndian, p.command_length) + binary.Write(buf, binary.BigEndian, p.command_id) + binary.Write(buf, binary.BigEndian, p.command_status) + binary.Write(buf, binary.BigEndian, p.sequence_number) return nil } -func (p *PDU_HEADER) Decode(data []uint8) error { - if len(data) >= 4 { - p.command_length = binary.BigEndian.Uint32(data[0:4]) - } - if len(data) >= 8 { - p.command_id = binary.BigEndian.Uint32(data[4:8]) - } - if len(data) >= 12 { - p.command_status = binary.BigEndian.Uint32(data[8:12]) - - } - if len(data) >= 16 { - p.sequence_number = binary.BigEndian.Uint32(data[12:16]) - } +func (p *PDU_HEADER) Decode(buf *bytes.Buffer) error { + binary.Read(buf, binary.BigEndian, &p.command_length) + binary.Read(buf, binary.BigEndian, &p.command_id) + binary.Read(buf, binary.BigEndian, &p.command_status) + binary.Read(buf, binary.BigEndian, &p.sequence_number) return nil } -func (p *PDU_HEADER) Size() uint32 { +func (p *PDU_HEADER) Size() int { return 16 } diff --git a/pdu/pdu_test.go b/pdu/pdu_test.go index 2f05e53..e2df0f9 100644 --- a/pdu/pdu_test.go +++ b/pdu/pdu_test.go @@ -1,6 +1,7 @@ package pdu import ( + "bytes" "encoding/binary" "math" "sync" @@ -15,13 +16,14 @@ func TestEncodeReturnsByteSliceOfLength16(t *testing.T) { command_status: 1, sequence_number: 1, } - result, err := p.Encode() + buf := bytes.NewBuffer(make([]byte, 16)) + err := p.Encode(buf) if err != nil { t.Errorf("Expected no error, got %v", err) } - if len(*result) != 16 { - t.Errorf("Expected byte slice of length 16, got %d", len(*result)) + if buf.Len() != 16 { + t.Errorf("Expected byte slice of length 16, got %d", buf.Len()) } } @@ -32,15 +34,16 @@ func TestEncodeHandlesZeroValues(t *testing.T) { command_status: 0, sequence_number: 0, } - result, err := p.Encode() + buf := bytes.NewBuffer(make([]byte, 16)) + err := p.Encode(buf) if err != nil { t.Errorf("Expected no error, got %v", err) } - expected := make([]uint8, 16) - for i, v := range *result { + expected := make([]byte, 16) + for i, v := range buf.Bytes() { if v != expected[i] { - t.Errorf("Expected byte slice with zero values, got %v", *result) + t.Errorf("Expected byte slice with zero values, got %v", buf.Bytes()) break } } @@ -53,16 +56,17 @@ func TestEncodeEncodesProperly(t *testing.T) { command_status: 3, sequence_number: 4, } - result, err := p.Encode() + buf := bytes.NewBuffer(make([]byte, 16)) + err := p.Encode(buf) if err != nil { t.Errorf("Expected no error, got %v", err) } - expected := []uint8{0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4} - for i, v := range *result { + expected := []byte{0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4} + for i, v := range buf.Bytes() { if v != expected[i] { - t.Errorf("Expected byte slice with values %v, got %v", expected, *result) + t.Errorf("Expected byte slice with values %v, got %v", expected, buf.Bytes()) break } } @@ -75,16 +79,17 @@ func TestEncodeEncodesProperlyComplex(t *testing.T) { command_status: 35634264, sequence_number: 476543523, } - result, err := p.Encode() + buf := bytes.NewBuffer(make([]byte, 16)) + err := p.Encode(buf) if err != nil { t.Errorf("Expected no error, got %v", err) } - expected := []uint8{0, 204, 224, 36, 0, 3, 225, 144, 2, 31, 188, 88, 28, 103, 122, 35} - for i, v := range *result { + expected := []byte{0, 204, 224, 36, 0, 3, 225, 144, 2, 31, 188, 88, 28, 103, 122, 35} + for i, v := range buf.Bytes() { if v != expected[i] { - t.Errorf("Expected byte slice with values %v, got %v", expected, *result) + t.Errorf("Expected byte slice with values %v, got %v", expected, buf.Bytes()) break } } @@ -97,24 +102,25 @@ func TestEncodeIntoCorrectlyEncodesFields(t *testing.T) { command_status: 0, sequence_number: 12345, } - buf := make([]uint8, 16) - err := p.EncodeInto(&buf) + buf := bytes.NewBuffer(make([]byte, 16)) + err := p.Encode(buf) if err != nil { t.Errorf("Expected no error, got %v", err) } - if binary.BigEndian.Uint32(buf[0:4]) != p.command_length { - t.Errorf("Expected command_length %d, got %d", p.command_length, binary.BigEndian.Uint32(buf[0:4])) + innerbuf := buf.Bytes() + if binary.BigEndian.Uint32(innerbuf[0:4]) != p.command_length { + t.Errorf("Expected command_length %d, got %d", p.command_length, binary.BigEndian.Uint32(innerbuf[0:4])) } - if binary.BigEndian.Uint32(buf[4:8]) != p.command_id { - t.Errorf("Expected command_id %d, got %d", p.command_id, binary.BigEndian.Uint32(buf[4:8])) + if binary.BigEndian.Uint32(innerbuf[4:8]) != p.command_id { + t.Errorf("Expected command_id %d, got %d", p.command_id, binary.BigEndian.Uint32(innerbuf[4:8])) } - if binary.BigEndian.Uint32(buf[8:12]) != p.command_status { - t.Errorf("Expected command_status %d, got %d", p.command_status, binary.BigEndian.Uint32(buf[8:12])) + if binary.BigEndian.Uint32(innerbuf[8:12]) != p.command_status { + t.Errorf("Expected command_status %d, got %d", p.command_status, binary.BigEndian.Uint32(innerbuf[8:12])) } - if binary.BigEndian.Uint32(buf[12:16]) != p.sequence_number { - t.Errorf("Expected sequence_number %d, got %d", p.sequence_number, binary.BigEndian.Uint32(buf[12:16])) + if binary.BigEndian.Uint32(innerbuf[12:16]) != p.sequence_number { + t.Errorf("Expected sequence_number %d, got %d", p.sequence_number, binary.BigEndian.Uint32(innerbuf[12:16])) } } @@ -125,9 +131,8 @@ func TestEncodeIntoHandlesNilBuffer(t *testing.T) { command_status: 0, sequence_number: 12345, } - var buf *[]uint8 = nil - - err := p.EncodeInto(buf) + var buf bytes.Buffer + err := p.Encode(&buf) if err == nil { t.Errorf("Expected error when buffer is nil") } @@ -140,9 +145,8 @@ func TestEncodeIntoHandlesSmallerBuffer(t *testing.T) { command_status: 0, sequence_number: 12345, } - buf := make([]uint8, 12) // smaller buffer size - - err := p.EncodeInto(&buf) + buf := bytes.NewBuffer(make([]byte, 12)) // smaller buffer size + err := p.Encode(buf) if err == nil { t.Errorf("Expected error when buffer is too small") } @@ -155,24 +159,25 @@ func TestEncodeIntoHandlesLargerBuffer(t *testing.T) { command_status: 0, sequence_number: 12345, } - buf := make([]uint8, 20) - err := p.EncodeInto(&buf) + buf := bytes.NewBuffer(make([]byte, 20)) // larger buffer size + err := p.Encode(buf) if err != nil { t.Errorf("Expected no error, got %v", err) } - if binary.BigEndian.Uint32(buf[0:4]) != p.command_length { - t.Errorf("Expected command_length %d, got %d", p.command_length, binary.BigEndian.Uint32(buf[0:4])) + innerbuf := buf.Bytes() + if binary.BigEndian.Uint32(innerbuf[0:4]) != p.command_length { + t.Errorf("Expected command_length %d, got %d", p.command_length, binary.BigEndian.Uint32(innerbuf[0:4])) } - if binary.BigEndian.Uint32(buf[4:8]) != p.command_id { - t.Errorf("Expected command_id %d, got %d", p.command_id, binary.BigEndian.Uint32(buf[4:8])) + if binary.BigEndian.Uint32(innerbuf[4:8]) != p.command_id { + t.Errorf("Expected command_id %d, got %d", p.command_id, binary.BigEndian.Uint32(innerbuf[4:8])) } - if binary.BigEndian.Uint32(buf[8:12]) != p.command_status { - t.Errorf("Expected command_status %d, got %d", p.command_status, binary.BigEndian.Uint32(buf[8:12])) + if binary.BigEndian.Uint32(innerbuf[8:12]) != p.command_status { + t.Errorf("Expected command_status %d, got %d", p.command_status, binary.BigEndian.Uint32(innerbuf[8:12])) } - if binary.BigEndian.Uint32(buf[12:16]) != p.sequence_number { - t.Errorf("Expected sequence_number %d, got %d", p.sequence_number, binary.BigEndian.Uint32(buf[12:16])) + if binary.BigEndian.Uint32(innerbuf[12:16]) != p.sequence_number { + t.Errorf("Expected sequence_number %d, got %d", p.sequence_number, binary.BigEndian.Uint32(innerbuf[12:16])) } } @@ -183,24 +188,25 @@ func TestEncodeIntoUsesBigEndianEncoding(t *testing.T) { command_status: 0, sequence_number: 12345, } - buf := make([]uint8, 16) - err := p.EncodeInto(&buf) + buf := bytes.NewBuffer(make([]byte, 16)) + err := p.Encode(buf) if err != nil { t.Errorf("Expected no error, got %v", err) } - if binary.BigEndian.Uint32(buf[0:4]) != p.command_length { - t.Errorf("Expected command_length %d, got %d", p.command_length, binary.BigEndian.Uint32(buf[0:4])) + innerbuf := buf.Bytes() + if binary.BigEndian.Uint32(innerbuf[0:4]) != p.command_length { + t.Errorf("Expected command_length %d, got %d", p.command_length, binary.BigEndian.Uint32(innerbuf[0:4])) } - if binary.BigEndian.Uint32(buf[4:8]) != p.command_id { - t.Errorf("Expected command_id %d, got %d", p.command_id, binary.BigEndian.Uint32(buf[4:8])) + if binary.BigEndian.Uint32(innerbuf[4:8]) != p.command_id { + t.Errorf("Expected command_id %d, got %d", p.command_id, binary.BigEndian.Uint32(innerbuf[4:8])) } - if binary.BigEndian.Uint32(buf[8:12]) != p.command_status { - t.Errorf("Expected command_status %d, got %d", p.command_status, binary.BigEndian.Uint32(buf[8:12])) + if binary.BigEndian.Uint32(innerbuf[8:12]) != p.command_status { + t.Errorf("Expected command_status %d, got %d", p.command_status, binary.BigEndian.Uint32(innerbuf[8:12])) } - if binary.BigEndian.Uint32(buf[12:16]) != p.sequence_number { - t.Errorf("Expected sequence_number %d, got %d", p.sequence_number, binary.BigEndian.Uint32(buf[12:16])) + if binary.BigEndian.Uint32(innerbuf[12:16]) != p.sequence_number { + t.Errorf("Expected sequence_number %d, got %d", p.sequence_number, binary.BigEndian.Uint32(innerbuf[12:16])) } } @@ -211,28 +217,29 @@ func TestEncodeIntoConcurrencySafety(t *testing.T) { command_status: 0, sequence_number: 12345, } - buf := make([]uint8, 16) + buf := bytes.NewBuffer(make([]byte, 16)) var wg sync.WaitGroup for i := 0; i < 1000; i++ { wg.Add(1) go func() { defer wg.Done() - p.EncodeInto(&buf) + p.Encode(buf) }() } wg.Wait() - if binary.BigEndian.Uint32(buf[0:4]) != p.command_length { - t.Errorf("Expected command_length %d, got %d", p.command_length, binary.BigEndian.Uint32(buf[0:4])) + innerbuf := buf.Bytes() + if binary.BigEndian.Uint32(innerbuf[0:4]) != p.command_length { + t.Errorf("Expected command_length %d, got %d", p.command_length, binary.BigEndian.Uint32(innerbuf[0:4])) } - if binary.BigEndian.Uint32(buf[4:8]) != p.command_id { - t.Errorf("Expected command_id %d, got %d", p.command_id, binary.BigEndian.Uint32(buf[4:8])) + if binary.BigEndian.Uint32(innerbuf[4:8]) != p.command_id { + t.Errorf("Expected command_id %d, got %d", p.command_id, binary.BigEndian.Uint32(innerbuf[4:8])) } - if binary.BigEndian.Uint32(buf[8:12]) != p.command_status { - t.Errorf("Expected command_status %d, got %d", p.command_status, binary.BigEndian.Uint32(buf[8:12])) + if binary.BigEndian.Uint32(innerbuf[8:12]) != p.command_status { + t.Errorf("Expected command_status %d, got %d", p.command_status, binary.BigEndian.Uint32(innerbuf[8:12])) } - if binary.BigEndian.Uint32(buf[12:16]) != p.sequence_number { - t.Errorf("Expected sequence_number %d, got %d", p.sequence_number, binary.BigEndian.Uint32(buf[12:16])) + if binary.BigEndian.Uint32(innerbuf[12:16]) != p.sequence_number { + t.Errorf("Expected sequence_number %d, got %d", p.sequence_number, binary.BigEndian.Uint32(innerbuf[12:16])) } } @@ -243,24 +250,25 @@ func TestEncodeIntoWithMaximumValues(t *testing.T) { command_status: math.MaxUint32, sequence_number: math.MaxUint32, } - buf := make([]uint8, 16) - err := p.EncodeInto(&buf) + buf := bytes.NewBuffer(make([]byte, 16)) + err := p.Encode(buf) if err != nil { t.Errorf("Expected no error, got %v", err) } - if binary.BigEndian.Uint32(buf[0:4]) != p.command_length { - t.Errorf("Expected command_length %d, got %d", p.command_length, binary.BigEndian.Uint32(buf[0:4])) + innerbuf := buf.Bytes() + if binary.BigEndian.Uint32(innerbuf[0:4]) != p.command_length { + t.Errorf("Expected command_length %d, got %d", p.command_length, binary.BigEndian.Uint32(innerbuf[0:4])) } - if binary.BigEndian.Uint32(buf[4:8]) != p.command_id { - t.Errorf("Expected command_id %d, got %d", p.command_id, binary.BigEndian.Uint32(buf[4:8])) + if binary.BigEndian.Uint32(innerbuf[4:8]) != p.command_id { + t.Errorf("Expected command_id %d, got %d", p.command_id, binary.BigEndian.Uint32(innerbuf[4:8])) } - if binary.BigEndian.Uint32(buf[8:12]) != p.command_status { - t.Errorf("Expected command_status %d, got %d", p.command_status, binary.BigEndian.Uint32(buf[8:12])) + if binary.BigEndian.Uint32(innerbuf[8:12]) != p.command_status { + t.Errorf("Expected command_status %d, got %d", p.command_status, binary.BigEndian.Uint32(innerbuf[8:12])) } - if binary.BigEndian.Uint32(buf[12:16]) != p.sequence_number { - t.Errorf("Expected sequence_number %d, got %d", p.sequence_number, binary.BigEndian.Uint32(buf[12:16])) + if binary.BigEndian.Uint32(innerbuf[12:16]) != p.sequence_number { + t.Errorf("Expected sequence_number %d, got %d", p.sequence_number, binary.BigEndian.Uint32(innerbuf[12:16])) } } @@ -271,240 +279,285 @@ func TestEncodeIntoWithBoundaryValues(t *testing.T) { command_status: 0, sequence_number: 0, } - buf := make([]uint8, 16) - err := p.EncodeInto(&buf) + buf := bytes.NewBuffer(make([]byte, 16)) + err := p.Encode(buf) if err != nil { t.Errorf("Expected no error, got %v", err) } - if binary.BigEndian.Uint32(buf[0:4]) != p.command_length { - t.Errorf("Expected command_length %d, got %d", p.command_length, binary.BigEndian.Uint32(buf[0:4])) + innerbuf := buf.Bytes() + if binary.BigEndian.Uint32(innerbuf[0:4]) != p.command_length { + t.Errorf("Expected command_length %d, got %d", p.command_length, binary.BigEndian.Uint32(innerbuf[0:4])) } - if binary.BigEndian.Uint32(buf[4:8]) != p.command_id { - t.Errorf("Expected command_id %d, got %d", p.command_id, binary.BigEndian.Uint32(buf[4:8])) + if binary.BigEndian.Uint32(innerbuf[4:8]) != p.command_id { + t.Errorf("Expected command_id %d, got %d", p.command_id, binary.BigEndian.Uint32(innerbuf[4:8])) } - if binary.BigEndian.Uint32(buf[8:12]) != p.command_status { - t.Errorf("Expected command_status %d, got %d", p.command_status, binary.BigEndian.Uint32(buf[8:12])) + if binary.BigEndian.Uint32(innerbuf[8:12]) != p.command_status { + t.Errorf("Expected command_status %d, got %d", p.command_status, binary.BigEndian.Uint32(innerbuf[8:12])) } - if binary.BigEndian.Uint32(buf[12:16]) != p.sequence_number { - t.Errorf("Expected sequence_number %d, got %d", p.sequence_number, binary.BigEndian.Uint32(buf[12:16])) + if binary.BigEndian.Uint32(innerbuf[12:16]) != p.sequence_number { + t.Errorf("Expected sequence_number %d, got %d", p.sequence_number, binary.BigEndian.Uint32(innerbuf[12:16])) } } -// region decode -func TestDecodeHandlesShortByteSlice(t *testing.T) { - var p PDU_HEADER - data := []uint8{0, 0, 0, 10} - defer func() { - if r := recover(); r != nil { - t.Errorf("Decode panicked with short byte slice") - } - }() - err := p.Decode(data) - if err != nil { - t.Errorf("Expected no error, got %v", err) - } -} +// func TestRealScenario(t *testing.T) { +// expected := []byte{0, 0, 0, 54, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 67, 77, 84, 0, 1, 1, 49, 50, 51, 52, 53, 0, 1, 1, 54, 55, 56, 57, 48, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 12, 72, 101, 108, 108, 111, 44, 32, 83, 77, 80, 80, 33} +// p := &SUBMIT_SM{ +// header: PDU_HEADER{ +// command_length: 0, +// command_id: 4, +// command_status: 0, +// sequence_number: 1, +// }, +// service_type: "CMT", +// source_addr_ton: 1, +// source_addr_npi: 1, +// source_addr: "12345", +// dest_addr_ton: 1, +// dest_addr_npi: 1, +// destination_addr: "67890", +// esm_class: 0, +// protocol_id: 0, +// priority_flag: 0, +// schedule_delivery_time: "", +// validity_period: "", +// registered_delivery: 1, +// data_coding: 0, +// sm_default_msg_id: 0, +// short_message: "Hello, SMPP!", +// } +// p.header.command_length = uint32(p.Size()) +// p.sm_length = byte(len(p.short_message)) +// buf := make([]byte, p.Size()) +// err := p.EncodeInto(&buf) +// if err != nil { +// t.Errorf("Expected no error, got %v", err) +// } +// if len(buf) != len(expected) { +// t.Errorf("Expected byte slice of length %d, got %d", len(expected), len(buf)) +// } +// for i, v := range buf { +// if v != expected[i] { +// t.Errorf("Expected byte slice with values %v, got %v", expected, buf) +// break +// } +// } +// } -func TestDecodeParsesValidByteSlice(t *testing.T) { - var p PDU_HEADER - data := []uint8{0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3} - err := p.Decode(data) +// // region decode +// func TestDecodeHandlesShortByteSlice(t *testing.T) { +// var p PDU_HEADER +// data := []byte{0, 0, 0, 10} +// defer func() { +// if r := recover(); r != nil { +// t.Errorf("Decode panicked with short byte slice") +// } +// }() +// err := p.Decode(data) +// if err != nil { +// t.Errorf("Expected no error, got %v", err) +// } +// } - if err != nil { - t.Errorf("Expected no error, got %v", err) - } +// func TestDecodeParsesValidByteSlice(t *testing.T) { +// var p PDU_HEADER +// data := []byte{0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3} +// err := p.Decode(data) - if p.command_length != 16 { - t.Errorf("Expected command_length to be 16, got %d", p.command_length) - } - if p.command_id != 1 { - t.Errorf("Expected command_id to be 1, got %d", p.command_id) - } - if p.command_status != 2 { - t.Errorf("Expected command_status to be 2, got %d", p.command_status) - } - if p.sequence_number != 3 { - t.Errorf("Expected sequence_number to be 3, got %d", p.sequence_number) - } -} +// if err != nil { +// t.Errorf("Expected no error, got %v", err) +// } -func TestDecodeHandlesLongerByteSliceWithoutCrashing(t *testing.T) { - var p PDU_HEADER - data := make([]uint8, 20) - defer func() { - if r := recover(); r != nil { - t.Errorf("Decode panicked with long byte slice") - } - }() - err := p.Decode(data) - if err != nil { - t.Errorf("Expected no error, got %v", err) - } -} +// if p.command_length != 16 { +// t.Errorf("Expected command_length to be 16, got %d", p.command_length) +// } +// if p.command_id != 1 { +// t.Errorf("Expected command_id to be 1, got %d", p.command_id) +// } +// if p.command_status != 2 { +// t.Errorf("Expected command_status to be 2, got %d", p.command_status) +// } +// if p.sequence_number != 3 { +// t.Errorf("Expected sequence_number to be 3, got %d", p.sequence_number) +// } +// } -func TestDecodeHandlesNilDataInput(t *testing.T) { - var p PDU_HEADER - err := p.Decode(nil) +// func TestDecodeHandlesLongerByteSliceWithoutCrashing(t *testing.T) { +// var p PDU_HEADER +// data := make([]byte, 20) +// defer func() { +// if r := recover(); r != nil { +// t.Errorf("Decode panicked with long byte slice") +// } +// }() +// err := p.Decode(data) +// if err != nil { +// t.Errorf("Expected no error, got %v", err) +// } +// } - if err != nil { - t.Errorf("Expected no error, got %v", err) - } +// func TestDecodeHandlesNilDataInput(t *testing.T) { +// var p PDU_HEADER +// err := p.Decode(nil) - if p.command_length != 0 { - t.Errorf("Expected command_length to be 0, got %d", p.command_length) - } - if p.command_id != 0 { - t.Errorf("Expected command_id to be 0, got %d", p.command_id) - } - if p.command_status != 0 { - t.Errorf("Expected command_status to be 0, got %d", p.command_status) - } - if p.sequence_number != 0 { - t.Errorf("Expected sequence_number to be 0, got %d", p.sequence_number) - } -} +// if err != nil { +// t.Errorf("Expected no error, got %v", err) +// } -func TestDecodeHandlesEmptyByteSliceGracefully(t *testing.T) { - var p PDU_HEADER - data := []uint8{} - err := p.Decode(data) +// if p.command_length != 0 { +// t.Errorf("Expected command_length to be 0, got %d", p.command_length) +// } +// if p.command_id != 0 { +// t.Errorf("Expected command_id to be 0, got %d", p.command_id) +// } +// if p.command_status != 0 { +// t.Errorf("Expected command_status to be 0, got %d", p.command_status) +// } +// if p.sequence_number != 0 { +// t.Errorf("Expected sequence_number to be 0, got %d", p.sequence_number) +// } +// } - if err != nil { - t.Errorf("Expected no error, got %v", err) - } +// func TestDecodeHandlesEmptyByteSliceGracefully(t *testing.T) { +// var p PDU_HEADER +// data := []byte{} +// err := p.Decode(data) - if p.command_length != 0 { - t.Errorf("Expected command_length to be 0, got %d", p.command_length) - } - if p.command_id != 0 { - t.Errorf("Expected command_id to be 0, got %d", p.command_id) - } - if p.command_status != 0 { - t.Errorf("Expected command_status to be 0, got %d", p.command_status) - } - if p.sequence_number != 0 { - t.Errorf("Expected sequence_number to be 0, got %d", p.sequence_number) - } -} +// if err != nil { +// t.Errorf("Expected no error, got %v", err) +// } -func TestDecodeDoesNotModifyInputByteSlice(t *testing.T) { - var p PDU_HEADER - data := []uint8{0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3} - originalData := make([]uint8, len(data)) - copy(originalData, data) +// if p.command_length != 0 { +// t.Errorf("Expected command_length to be 0, got %d", p.command_length) +// } +// if p.command_id != 0 { +// t.Errorf("Expected command_id to be 0, got %d", p.command_id) +// } +// if p.command_status != 0 { +// t.Errorf("Expected command_status to be 0, got %d", p.command_status) +// } +// if p.sequence_number != 0 { +// t.Errorf("Expected sequence_number to be 0, got %d", p.sequence_number) +// } +// } - err := p.Decode(data) +// func TestDecodeDoesNotModifyInputByteSlice(t *testing.T) { +// var p PDU_HEADER +// data := []byte{0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3} +// originalData := make([]byte, len(data)) +// copy(originalData, data) - if err != nil { - t.Errorf("Expected no error, got %v", err) - } +// err := p.Decode(data) - for i := range data { - if data[i] != originalData[i] { - t.Errorf("Expected data at index %d to be %d, got %d", i, originalData[i], data[i]) - } - } -} +// if err != nil { +// t.Errorf("Expected no error, got %v", err) +// } -func TestDecodeHandlesByteSlicesWithMaxUint32Values(t *testing.T) { - var p PDU_HEADER - data := []uint8{255, 255, 255, 255, 255, 255, 255, 255} - err := p.Decode(data) +// for i := range data { +// if data[i] != originalData[i] { +// t.Errorf("Expected data at index %d to be %d, got %d", i, originalData[i], data[i]) +// } +// } +// } - if err != nil { - t.Errorf("Expected no error, got %v", err) - } +// func TestDecodeHandlesByteSlicesWithMaxUint32Values(t *testing.T) { +// var p PDU_HEADER +// data := []byte{255, 255, 255, 255, 255, 255, 255, 255} +// err := p.Decode(data) - if p.command_length != math.MaxUint32 { - t.Errorf("Expected command_length to be %d, got %d", math.MaxUint32, p.command_length) - } - if p.command_id != math.MaxUint32 { - t.Errorf("Expected command_id to be %d, got %d", math.MaxUint32, p.command_id) - } -} +// if err != nil { +// t.Errorf("Expected no error, got %v", err) +// } -func TestDecodeHandlesByteSlicesWithMinimumUint32Values(t *testing.T) { - var p PDU_HEADER - data := []uint8{0, 0, 0, 0, 0, 0, 0, 0} - err := p.Decode(data) +// if p.command_length != math.MaxUint32 { +// t.Errorf("Expected command_length to be %d, got %d", math.MaxUint32, p.command_length) +// } +// if p.command_id != math.MaxUint32 { +// t.Errorf("Expected command_id to be %d, got %d", math.MaxUint32, p.command_id) +// } +// } - if err != nil { - t.Errorf("Expected no error, got %v", err) - } +// func TestDecodeHandlesByteSlicesWithMinimumUint32Values(t *testing.T) { +// var p PDU_HEADER +// data := []byte{0, 0, 0, 0, 0, 0, 0, 0} +// err := p.Decode(data) - if p.command_length != 0 { - t.Errorf("Expected command_length to be 0, got %d", p.command_length) - } - if p.command_id != 0 { - t.Errorf("Expected command_id to be 0, got %d", p.command_id) - } -} +// if err != nil { +// t.Errorf("Expected no error, got %v", err) +// } -// region size -func TestSizeReturns16(t *testing.T) { - var p PDU_HEADER - if p.Size() != 16 { - t.Errorf("Expected size to be 16, got %d", p.Size()) - } -} +// if p.command_length != 0 { +// t.Errorf("Expected command_length to be 0, got %d", p.command_length) +// } +// if p.command_id != 0 { +// t.Errorf("Expected command_id to be 0, got %d", p.command_id) +// } +// } -// region benchmarks +// // region size +// func TestSizeReturns16(t *testing.T) { +// var p PDU_HEADER +// if p.Size() != 16 { +// t.Errorf("Expected size to be 16, got %d", p.Size()) +// } +// } -// With buffer pool -func BenchmarkEncode(b *testing.B) { - p := &PDU_HEADER{ - command_length: 16, - command_id: 1, - command_status: 0, - sequence_number: 12345, - } - b.ResetTimer() - for i := 0; i < b.N; i++ { - buf, _ := p.Encode() - ByteBufferPool.Put(buf) - } -} +// // region benchmarks -// These two are effectively the same but there is difference in execution time -// I wonder why... -// I should stop writing benchmarks... -func BenchmarkEncodeWithBufferPool(b *testing.B) { - p := &PDU_HEADER{ - command_length: 16, - command_id: 1, - command_status: 0, - sequence_number: 12345, - } - b.ResetTimer() - for i := 0; i < b.N; i++ { - buf := ByteBufferPool.Get(uint(p.Size())) - p.EncodeInto(buf) - ByteBufferPool.Put(buf) - } -} +// // With buffer pool +// func BenchmarkEncode(b *testing.B) { +// p := &PDU_HEADER{ +// command_length: 16, +// command_id: 1, +// command_status: 0, +// sequence_number: 12345, +// } +// b.ResetTimer() +// for i := 0; i < b.N; i++ { +// buf, _ := p.Encode() +// ByteBufferPool.Put(buf) +// } +// } -// Without buffer pool -func BenchmarkEncodeInto(b *testing.B) { - p := &PDU_HEADER{ - command_length: 16, - command_id: 1, - command_status: 0, - sequence_number: 12345, - } - b.ResetTimer() - for i := 0; i < b.N; i++ { - buf := make([]uint8, 16) - p.EncodeInto(&buf) - } -} +// // These two are effectively the same but there is difference in execution time +// // I wonder why... +// // I should stop writing benchmarks... +// func BenchmarkEncodeWithBufferPool(b *testing.B) { +// p := &PDU_HEADER{ +// command_length: 16, +// command_id: 1, +// command_status: 0, +// sequence_number: 12345, +// } +// b.ResetTimer() +// for i := 0; i < b.N; i++ { +// buf := ByteBufferPool.Get(uint(p.Size())) +// p.EncodeInto(buf) +// ByteBufferPool.Put(buf) +// } +// } -func BenchmarkDecode(b *testing.B) { - p := &PDU_HEADER{} - data := []uint8{0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3} - b.ResetTimer() - for i := 0; i < b.N; i++ { - p.Decode(data) - } -} +// // Without buffer pool +// func BenchmarkEncodeInto(b *testing.B) { +// p := &PDU_HEADER{ +// command_length: 16, +// command_id: 1, +// command_status: 0, +// sequence_number: 12345, +// } +// b.ResetTimer() +// for i := 0; i < b.N; i++ { +// buf := make([]byte, 16) +// p.EncodeInto(&buf) +// } +// } + +// func BenchmarkDecode(b *testing.B) { +// p := &PDU_HEADER{} +// data := []byte{0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3} +// b.ResetTimer() +// for i := 0; i < b.N; i++ { +// p.Decode(data) +// } +// } diff --git a/pdu/submit.go b/pdu/submit.go index 9d37663..c84a9ac 100644 --- a/pdu/submit.go +++ b/pdu/submit.go @@ -1,56 +1,60 @@ package pdu -import "fmt" +import ( + "bytes" + "encoding/ascii85" + "encoding/binary" +) type ( SUBMIT_SM struct { header PDU_HEADER service_type string - source_addr_ton uint8 - source_addr_npi uint8 + source_addr_ton byte + source_addr_npi byte source_addr string - dest_addr_ton uint8 - dest_addr_npi uint8 + dest_addr_ton byte + dest_addr_npi byte destination_addr string - esm_class uint8 - protocol_id uint8 - priority_flag uint8 + esm_class byte + protocol_id byte + priority_flag byte schedule_delivery_time string validity_period string - registered_delivery uint8 - replace_if_present uint8 - data_coding uint8 - sm_default_msg_id uint8 - sm_length uint8 + registered_delivery byte + replace_if_present byte + data_coding byte + sm_default_msg_id byte + sm_length byte short_message string // user_message_reference uint16 // source_port uint16 - // source_addr_subunit uint8 + // source_addr_subunit byte // destination_port uint16 - // dest_addr_subunit uint8 + // dest_addr_subunit byte // sar_msg_ref_num uint16 - // sar_total_segments uint8 - // sar_segment_seqnum uint8 - // more_messages_to_send uint8 - // payload_type uint8 + // sar_total_segments byte + // sar_segment_seqnum byte + // more_messages_to_send byte + // payload_type byte // message_payload string - // privacy_indicator uint8 + // privacy_indicator byte // callback_num string - // callback_num_pres uint8 + // callback_num_pres byte // callback_num_atag string // source_subaddress string // dest_subaddress string - // user_response_code uint8 - // display_time uint8 - // sms_signal uint8 - // ms_validity uint8 - // ms_msg_wait_facilities uint8 - // number_of_messages uint8 - // alert_on_message_delivery uint8 - // language_indicator uint8 - // its_reply_type uint8 - // its_session_info uint8 - // ussd_service_op uint8 + // user_response_code byte + // display_time byte + // sms_signal byte + // ms_validity byte + // ms_msg_wait_facilities byte + // number_of_messages byte + // alert_on_message_delivery byte + // language_indicator byte + // its_reply_type byte + // its_session_info byte + // ussd_service_op byte } SUBMIT_SM_RESP struct { header PDU_HEADER @@ -60,45 +64,56 @@ type ( SUBMIT_MULTI_RESP struct{} ) -func (p *SUBMIT_SM) Encode() (*[]byte, error) { - buf := ByteBufferPool.Get(uint(p.Size())) - err := p.EncodeInto(buf) - return buf, err -} -func (p *SUBMIT_SM) EncodeInto(buf *[]byte) error { - if buf == nil { - return fmt.Errorf("cannot encode SUBMIT_SM, buffer is nil") - } - if len(*buf) < int(p.Size()) { - return fmt.Errorf("cannot encode SUBMIT_SM, buffer too small (%d, required %d)", len(*buf), p.Size()) - } - - p.header.EncodeInto(buf) +func (p *SUBMIT_SM) Encode(buf *bytes.Buffer) error { + p.header.Encode(buf) + n := ascii85.Encode(buf.Bytes(), []byte(p.service_type)) + buf.Truncate(n) + binary.Write(buf, binary.BigEndian, byte(len(p.service_type))) + + // service_type string + // source_addr_ton byte + // source_addr_npi byte + // source_addr string + // dest_addr_ton byte + // dest_addr_npi byte + // destination_addr string + // esm_class byte + // protocol_id byte + // priority_flag byte + // schedule_delivery_time string + // validity_period string + // registered_delivery byte + // replace_if_present byte + // data_coding byte + // sm_default_msg_id byte + // sm_length byte + // short_message string return nil } -func (p *SUBMIT_SM) Decode(data []byte) { +func (p *SUBMIT_SM) Decode(buf *bytes.Buffer) error { + return nil } -func (p *SUBMIT_SM) Size() uint32 { - var size uint32 +func (p *SUBMIT_SM) Size() int { + var size int size += p.header.Size() - size += uint32(len(p.service_type) * 1) + size += len(p.service_type) * 1 size += 1 // source_addr_ton size += 1 // source_addr_npi - size += uint32(len(p.source_addr) * 1) + size += len(p.source_addr) * 1 size += 1 // dest_addr_ton size += 1 // dest_addr_npi - size += uint32(len(p.destination_addr) * 1) + size += len(p.destination_addr) * 1 size += 1 // esm_class size += 1 // protocol_id size += 1 // priority_flag - size += uint32(len(p.schedule_delivery_time) * 1) - size += uint32(len(p.validity_period) * 1) + size += len(p.schedule_delivery_time) * 1 + size += len(p.validity_period) * 1 size += 1 // registered_delivery size += 1 // replace_if_present size += 1 // data_coding size += 1 // sm_default_msg_id size += 1 // sm_length - size += uint32(len(p.short_message) * 1) + size += len(p.short_message) * 1 return size } diff --git a/pdu/submit_test.go b/pdu/submit_test.go index bf6e6d6..f9f4e7b 100644 --- a/pdu/submit_test.go +++ b/pdu/submit_test.go @@ -14,7 +14,7 @@ func TestCalculateSizeTypicalInstance(t *testing.T) { validity_period: "", short_message: "Hello, World!", } - expectedSize := uint32(16 + len(p.service_type) + 1 + 1 + len(p.source_addr) + 1 + 1 + len(p.destination_addr) + 1 + 1 + 1 + len(p.schedule_delivery_time) + len(p.validity_period) + 1 + 1 + 1 + 1 + 1 + len(p.short_message)) + expectedSize := 16 + len(p.service_type) + 1 + 1 + len(p.source_addr) + 1 + 1 + len(p.destination_addr) + 1 + 1 + 1 + len(p.schedule_delivery_time) + len(p.validity_period) + 1 + 1 + 1 + 1 + 1 + len(p.short_message) actualSize := p.Size() if actualSize != expectedSize { t.Errorf("Expected size %d, but got %d", expectedSize, actualSize) @@ -31,7 +31,7 @@ func TestCalculateSizeMaxLengths(t *testing.T) { validity_period: string(make([]byte, maxLen)), short_message: string(make([]byte, maxLen)), } - expectedSize := uint32(16 + maxLen + 1 + 1 + maxLen + 1 + 1 + maxLen + 1 + 1 + 1 + maxLen + maxLen + 1 + 1 + 1 + 1 + 1 + maxLen) + expectedSize := 16 + maxLen + 1 + 1 + maxLen + 1 + 1 + maxLen + 1 + 1 + 1 + maxLen + maxLen + 1 + 1 + 1 + 1 + 1 + maxLen actualSize := p.Size() if actualSize != expectedSize { t.Errorf("Expected size %d, but got %d", expectedSize, actualSize) @@ -47,7 +47,7 @@ func TestHandlesEmptyStringsForAllStringFields(t *testing.T) { validity_period: "", short_message: "", } - expectedSize := uint32(16 + len(p.service_type) + 1 + 1 + len(p.source_addr) + 1 + 1 + len(p.destination_addr) + 1 + 1 + 1 + len(p.schedule_delivery_time) + len(p.validity_period) + 1 + 1 + 1 + 1 + 1 + len(p.short_message)) + expectedSize := 16 + len(p.service_type) + 1 + 1 + len(p.source_addr) + 1 + 1 + len(p.destination_addr) + 1 + 1 + 1 + len(p.schedule_delivery_time) + len(p.validity_period) + 1 + 1 + 1 + 1 + 1 + len(p.short_message) actualSize := p.Size() if actualSize != expectedSize { t.Errorf("Expected size %d, but got %d", expectedSize, actualSize)