Compare commits
	
		
			14 Commits
		
	
	
		
			benchmark
			...
			92c0e83e73
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 92c0e83e73 | |||
| 0eb0f5d773 | |||
| 161ff14189 | |||
| 7bcc02c66d | |||
| 31efd3fdef | |||
| 38976d6bc8 | |||
| d25058fdec | |||
| 2453d639ff | |||
| 14c861ccb4 | |||
| 500cb11235 | |||
| ec04fa1fb6 | |||
| a12c22587d | |||
| f30680c26f | |||
| bed69fbfd3 | 
@@ -1,12 +0,0 @@
 | 
				
			|||||||
goos: linux
 | 
					 | 
				
			||||||
goarch: amd64
 | 
					 | 
				
			||||||
pkg: smpptester/pdu
 | 
					 | 
				
			||||||
cpu: Intel(R) Core(TM) i5-8400 CPU @ 2.80GHz
 | 
					 | 
				
			||||||
BenchmarkBufferPoolManager-6              	13663852	        90.76 ns/op
 | 
					 | 
				
			||||||
BenchmarkBufferPoolManager_Concurrent-6   	 9525358	       130.7 ns/op
 | 
					 | 
				
			||||||
BenchmarkBufferPoolManager_Memory-6       	16205492	        74.61 ns/op
 | 
					 | 
				
			||||||
BenchmarkEncodeWithBufferPool-6           	 8466584	       143.2 ns/op
 | 
					 | 
				
			||||||
BenchmarkEncodeWithoutBufferPool-6        	 6701893	       221.0 ns/op
 | 
					 | 
				
			||||||
BenchmarkDecodeBufferPool-6               	 7069999	       162.3 ns/op
 | 
					 | 
				
			||||||
PASS
 | 
					 | 
				
			||||||
ok  	smpptester/pdu	8.413s
 | 
					 | 
				
			||||||
@@ -1,12 +0,0 @@
 | 
				
			|||||||
goos: linux
 | 
					 | 
				
			||||||
goarch: amd64
 | 
					 | 
				
			||||||
pkg: smpptester/pdu
 | 
					 | 
				
			||||||
cpu: Intel(R) Core(TM) i5-8400 CPU @ 2.80GHz
 | 
					 | 
				
			||||||
BenchmarkBufferPoolManager-6              	16792826	        71.92 ns/op
 | 
					 | 
				
			||||||
BenchmarkBufferPoolManager_Concurrent-6   	 9800792	       127.2 ns/op
 | 
					 | 
				
			||||||
BenchmarkBufferPoolManager_Memory-6       	13066466	        79.52 ns/op
 | 
					 | 
				
			||||||
BenchmarkEncodeWithBufferPool-6           	 8162733	       141.6 ns/op
 | 
					 | 
				
			||||||
BenchmarkEncodeWithoutBufferPool-6        	 6148492	       272.3 ns/op
 | 
					 | 
				
			||||||
BenchmarkDecodeBufferPool-6               	 7300572	       170.5 ns/op
 | 
					 | 
				
			||||||
PASS
 | 
					 | 
				
			||||||
ok  	smpptester/pdu	10.059s
 | 
					 | 
				
			||||||
@@ -1,12 +0,0 @@
 | 
				
			|||||||
goos: linux
 | 
					 | 
				
			||||||
goarch: amd64
 | 
					 | 
				
			||||||
pkg: smpptester/pdu
 | 
					 | 
				
			||||||
cpu: Intel(R) Core(TM) i5-8400 CPU @ 2.80GHz
 | 
					 | 
				
			||||||
BenchmarkBufferPoolManager-6              	  433611	      2688 ns/op
 | 
					 | 
				
			||||||
BenchmarkBufferPoolManager_Concurrent-6   	 1467840	       683.2 ns/op
 | 
					 | 
				
			||||||
BenchmarkBufferPoolManager_Memory-6       	  497097	      2389 ns/op
 | 
					 | 
				
			||||||
BenchmarkEncode-6                         	 8964351	       148.5 ns/op
 | 
					 | 
				
			||||||
BenchmarkEncodeInto-6                     	371218869	         2.987 ns/op
 | 
					 | 
				
			||||||
BenchmarkDecode-6                         	1000000000	         0.2681 ns/op
 | 
					 | 
				
			||||||
PASS
 | 
					 | 
				
			||||||
ok  	smpptester/pdu	7.851s
 | 
					 | 
				
			||||||
@@ -1,13 +0,0 @@
 | 
				
			|||||||
goos: linux
 | 
					 | 
				
			||||||
goarch: amd64
 | 
					 | 
				
			||||||
pkg: smpptester/pdu
 | 
					 | 
				
			||||||
cpu: Intel(R) Core(TM) i5-8400 CPU @ 2.80GHz
 | 
					 | 
				
			||||||
BenchmarkBufferPoolManager-6              	  457300	      2609 ns/op
 | 
					 | 
				
			||||||
BenchmarkBufferPoolManager_Concurrent-6   	 2050396	       561.0 ns/op
 | 
					 | 
				
			||||||
BenchmarkBufferPoolManager_Memory-6       	  504205	      2242 ns/op
 | 
					 | 
				
			||||||
BenchmarkEncode-6                         	27733428	        44.06 ns/op
 | 
					 | 
				
			||||||
BenchmarkEncodeWithBufferPool-6           	27795820	        42.97 ns/op
 | 
					 | 
				
			||||||
BenchmarkEncodeInto-6                     	397897166	         3.004 ns/op
 | 
					 | 
				
			||||||
BenchmarkDecode-6                         	1000000000	         0.2653 ns/op
 | 
					 | 
				
			||||||
PASS
 | 
					 | 
				
			||||||
ok  	smpptester/pdu	10.935s
 | 
					 | 
				
			||||||
@@ -1,27 +0,0 @@
 | 
				
			|||||||
?   	smpptester	[no test files]
 | 
					 | 
				
			||||||
?   	smpptester/benchmark	[no test files]
 | 
					 | 
				
			||||||
?   	smpptester/client	[no test files]
 | 
					 | 
				
			||||||
goos: linux
 | 
					 | 
				
			||||||
goarch: amd64
 | 
					 | 
				
			||||||
pkg: smpptester/encoding
 | 
					 | 
				
			||||||
cpu: Intel(R) Core(TM) i5-8400 CPU @ 2.80GHz
 | 
					 | 
				
			||||||
BenchmarkGSM7EncodeSimpleASCIIString-6              	19589385	        67.23 ns/op
 | 
					 | 
				
			||||||
BenchmarkGSM7EncodeComplexASCIIString-6             	 3757233	       288.3 ns/op
 | 
					 | 
				
			||||||
BenchmarkGSM7EncodeComplex8nASCIIString-6           	 2576941	       532.0 ns/op
 | 
					 | 
				
			||||||
BenchmarkGSM7EncodeComplex8nASCIIStringPrealloc-6   	 2611428	       460.3 ns/op
 | 
					 | 
				
			||||||
PASS
 | 
					 | 
				
			||||||
ok  	smpptester/encoding	6.483s
 | 
					 | 
				
			||||||
?   	smpptester/lua	[no test files]
 | 
					 | 
				
			||||||
goos: linux
 | 
					 | 
				
			||||||
goarch: amd64
 | 
					 | 
				
			||||||
pkg: smpptester/pdu
 | 
					 | 
				
			||||||
cpu: Intel(R) Core(TM) i5-8400 CPU @ 2.80GHz
 | 
					 | 
				
			||||||
BenchmarkBufferPoolManager-6              	16908814	        71.62 ns/op
 | 
					 | 
				
			||||||
BenchmarkBufferPoolManager_Concurrent-6   	 8895826	       125.1 ns/op
 | 
					 | 
				
			||||||
BenchmarkBufferPoolManager_Memory-6       	13243089	        80.48 ns/op
 | 
					 | 
				
			||||||
BenchmarkEncodeWithBufferPool-6           	 8433070	       139.2 ns/op
 | 
					 | 
				
			||||||
BenchmarkEncodeWithoutBufferPool-6        	 7134577	       248.2 ns/op
 | 
					 | 
				
			||||||
BenchmarkDecodeBufferPool-6               	 6587127	       166.0 ns/op
 | 
					 | 
				
			||||||
PASS
 | 
					 | 
				
			||||||
ok  	smpptester/pdu	8.296s
 | 
					 | 
				
			||||||
?   	smpptester/server	[no test files]
 | 
					 | 
				
			||||||
@@ -1,27 +0,0 @@
 | 
				
			|||||||
?   	smpptester	[no test files]
 | 
					 | 
				
			||||||
?   	smpptester/benchmark	[no test files]
 | 
					 | 
				
			||||||
?   	smpptester/client	[no test files]
 | 
					 | 
				
			||||||
goos: linux
 | 
					 | 
				
			||||||
goarch: amd64
 | 
					 | 
				
			||||||
pkg: smpptester/encoding
 | 
					 | 
				
			||||||
cpu: Intel(R) Core(TM) i5-8400 CPU @ 2.80GHz
 | 
					 | 
				
			||||||
BenchmarkGSM7EncodeSimpleASCIIString-6              	14935776	        76.91 ns/op
 | 
					 | 
				
			||||||
BenchmarkGSM7EncodeComplexASCIIString-6             	 3364554	       353.1 ns/op
 | 
					 | 
				
			||||||
BenchmarkGSM7EncodeComplex8nASCIIString-6           	 1840044	       591.6 ns/op
 | 
					 | 
				
			||||||
BenchmarkGSM7EncodeComplex8nASCIIStringPrealloc-6   	 2081725	       520.4 ns/op
 | 
					 | 
				
			||||||
PASS
 | 
					 | 
				
			||||||
ok  	smpptester/encoding	6.270s
 | 
					 | 
				
			||||||
?   	smpptester/lua	[no test files]
 | 
					 | 
				
			||||||
goos: linux
 | 
					 | 
				
			||||||
goarch: amd64
 | 
					 | 
				
			||||||
pkg: smpptester/pdu
 | 
					 | 
				
			||||||
cpu: Intel(R) Core(TM) i5-8400 CPU @ 2.80GHz
 | 
					 | 
				
			||||||
BenchmarkBufferPoolManager-6              	16804492	        75.91 ns/op
 | 
					 | 
				
			||||||
BenchmarkBufferPoolManager_Concurrent-6   	11214482	       134.8 ns/op
 | 
					 | 
				
			||||||
BenchmarkBufferPoolManager_Memory-6       	15180892	        71.99 ns/op
 | 
					 | 
				
			||||||
BenchmarkEncodeWithBufferPool-6           	 8587657	       139.1 ns/op
 | 
					 | 
				
			||||||
BenchmarkEncodeWithoutBufferPool-6        	 5282655	       223.4 ns/op
 | 
					 | 
				
			||||||
BenchmarkDecodeBufferPool-6               	 6659464	       170.4 ns/op
 | 
					 | 
				
			||||||
PASS
 | 
					 | 
				
			||||||
ok  	smpptester/pdu	10.264s
 | 
					 | 
				
			||||||
?   	smpptester/server	[no test files]
 | 
					 | 
				
			||||||
@@ -1,27 +0,0 @@
 | 
				
			|||||||
?   	smpptester	[no test files]
 | 
					 | 
				
			||||||
?   	smpptester/benchmark	[no test files]
 | 
					 | 
				
			||||||
?   	smpptester/client	[no test files]
 | 
					 | 
				
			||||||
goos: linux
 | 
					 | 
				
			||||||
goarch: amd64
 | 
					 | 
				
			||||||
pkg: smpptester/encoding
 | 
					 | 
				
			||||||
cpu: Intel(R) Core(TM) i5-8400 CPU @ 2.80GHz
 | 
					 | 
				
			||||||
BenchmarkGSM7EncodeSimpleASCIIString-6              	17371128	        63.88 ns/op
 | 
					 | 
				
			||||||
BenchmarkGSM7EncodeComplexASCIIString-6             	 4210346	       332.9 ns/op
 | 
					 | 
				
			||||||
BenchmarkGSM7EncodeComplex8nASCIIString-6           	 2748054	       517.4 ns/op
 | 
					 | 
				
			||||||
BenchmarkGSM7EncodeComplex8nASCIIStringPrealloc-6   	 2576667	       469.9 ns/op
 | 
					 | 
				
			||||||
PASS
 | 
					 | 
				
			||||||
ok  	smpptester/encoding	6.462s
 | 
					 | 
				
			||||||
?   	smpptester/lua	[no test files]
 | 
					 | 
				
			||||||
goos: linux
 | 
					 | 
				
			||||||
goarch: amd64
 | 
					 | 
				
			||||||
pkg: smpptester/pdu
 | 
					 | 
				
			||||||
cpu: Intel(R) Core(TM) i5-8400 CPU @ 2.80GHz
 | 
					 | 
				
			||||||
BenchmarkBufferPoolManager-6              	16765892	        70.02 ns/op
 | 
					 | 
				
			||||||
BenchmarkBufferPoolManager_Concurrent-6   	 9238833	       119.7 ns/op
 | 
					 | 
				
			||||||
BenchmarkBufferPoolManager_Memory-6       	15343066	        75.22 ns/op
 | 
					 | 
				
			||||||
BenchmarkEncodeWithBufferPool-6           	 8445075	       139.0 ns/op
 | 
					 | 
				
			||||||
BenchmarkEncodeWithoutBufferPool-6        	 5464392	       274.3 ns/op
 | 
					 | 
				
			||||||
BenchmarkDecodeBufferPool-6               	 6709528	       165.3 ns/op
 | 
					 | 
				
			||||||
PASS
 | 
					 | 
				
			||||||
ok  	smpptester/pdu	8.739s
 | 
					 | 
				
			||||||
?   	smpptester/server	[no test files]
 | 
					 | 
				
			||||||
@@ -1,27 +0,0 @@
 | 
				
			|||||||
?   	smpptester	[no test files]
 | 
					 | 
				
			||||||
?   	smpptester/benchmark	[no test files]
 | 
					 | 
				
			||||||
?   	smpptester/client	[no test files]
 | 
					 | 
				
			||||||
goos: linux
 | 
					 | 
				
			||||||
goarch: amd64
 | 
					 | 
				
			||||||
pkg: smpptester/encoding
 | 
					 | 
				
			||||||
cpu: Intel(R) Core(TM) i5-8400 CPU @ 2.80GHz
 | 
					 | 
				
			||||||
BenchmarkGSM7EncodeSimpleASCIIString-6              	18785672	        65.00 ns/op
 | 
					 | 
				
			||||||
BenchmarkGSM7EncodeComplexASCIIString-6             	 4313766	       332.7 ns/op
 | 
					 | 
				
			||||||
BenchmarkGSM7EncodeComplex8nASCIIString-6           	 2686035	       520.9 ns/op
 | 
					 | 
				
			||||||
BenchmarkGSM7EncodeComplex8nASCIIStringPrealloc-6   	 2613550	       461.0 ns/op
 | 
					 | 
				
			||||||
PASS
 | 
					 | 
				
			||||||
ok  	smpptester/encoding	6.548s
 | 
					 | 
				
			||||||
?   	smpptester/lua	[no test files]
 | 
					 | 
				
			||||||
goos: linux
 | 
					 | 
				
			||||||
goarch: amd64
 | 
					 | 
				
			||||||
pkg: smpptester/pdu
 | 
					 | 
				
			||||||
cpu: Intel(R) Core(TM) i5-8400 CPU @ 2.80GHz
 | 
					 | 
				
			||||||
BenchmarkBufferPoolManager-6              	16675815	        69.97 ns/op
 | 
					 | 
				
			||||||
BenchmarkBufferPoolManager_Concurrent-6   	 9622903	       120.8 ns/op
 | 
					 | 
				
			||||||
BenchmarkBufferPoolManager_Memory-6       	15080410	        84.43 ns/op
 | 
					 | 
				
			||||||
BenchmarkEncodeWithBufferPool-6           	 8589709	       138.9 ns/op
 | 
					 | 
				
			||||||
BenchmarkEncodeWithoutBufferPool-6        	 6965332	       228.4 ns/op
 | 
					 | 
				
			||||||
BenchmarkDecodeBufferPool-6               	 7003172	       165.4 ns/op
 | 
					 | 
				
			||||||
PASS
 | 
					 | 
				
			||||||
ok  	smpptester/pdu	8.384s
 | 
					 | 
				
			||||||
?   	smpptester/server	[no test files]
 | 
					 | 
				
			||||||
@@ -1,12 +0,0 @@
 | 
				
			|||||||
goos: linux
 | 
					 | 
				
			||||||
goarch: amd64
 | 
					 | 
				
			||||||
pkg: smpptester/pdu
 | 
					 | 
				
			||||||
cpu: Intel(R) Core(TM) i5-8400 CPU @ 2.80GHz
 | 
					 | 
				
			||||||
BenchmarkBufferPoolManager-6              	15687109	        91.05 ns/op
 | 
					 | 
				
			||||||
BenchmarkBufferPoolManager_Concurrent-6   	11083287	       128.9 ns/op
 | 
					 | 
				
			||||||
BenchmarkBufferPoolManager_Memory-6       	16576201	        74.12 ns/op
 | 
					 | 
				
			||||||
BenchmarkEncodeWithBufferPool-6           	 7868800	       138.1 ns/op
 | 
					 | 
				
			||||||
BenchmarkEncodeWithoutBufferPool-6        	 6833810	       221.2 ns/op
 | 
					 | 
				
			||||||
BenchmarkDecodeBufferPool-6               	 7195328	       166.0 ns/op
 | 
					 | 
				
			||||||
PASS
 | 
					 | 
				
			||||||
ok  	smpptester/pdu	8.763s
 | 
					 | 
				
			||||||
@@ -1,12 +0,0 @@
 | 
				
			|||||||
goos: linux
 | 
					 | 
				
			||||||
goarch: amd64
 | 
					 | 
				
			||||||
pkg: smpptester/pdu
 | 
					 | 
				
			||||||
cpu: Intel(R) Core(TM) i5-8400 CPU @ 2.80GHz
 | 
					 | 
				
			||||||
BenchmarkBufferPoolManager-6              	14983336	        90.65 ns/op
 | 
					 | 
				
			||||||
BenchmarkBufferPoolManager_Concurrent-6   	10671728	       124.4 ns/op
 | 
					 | 
				
			||||||
BenchmarkBufferPoolManager_Memory-6       	16471220	        75.06 ns/op
 | 
					 | 
				
			||||||
BenchmarkEncodeWithBufferPool-6           	 8545360	       139.1 ns/op
 | 
					 | 
				
			||||||
BenchmarkEncodeWithoutBufferPool-6        	 6794032	       224.7 ns/op
 | 
					 | 
				
			||||||
BenchmarkDecodeBufferPool-6               	 6737445	       165.3 ns/op
 | 
					 | 
				
			||||||
PASS
 | 
					 | 
				
			||||||
ok  	smpptester/pdu	8.681s
 | 
					 | 
				
			||||||
@@ -1,28 +0,0 @@
 | 
				
			|||||||
?   	smpptester	[no test files]
 | 
					 | 
				
			||||||
?   	smpptester/benchmark	[no test files]
 | 
					 | 
				
			||||||
?   	smpptester/client	[no test files]
 | 
					 | 
				
			||||||
goos: linux
 | 
					 | 
				
			||||||
goarch: amd64
 | 
					 | 
				
			||||||
pkg: smpptester/encoding
 | 
					 | 
				
			||||||
cpu: Intel(R) Core(TM) i5-8400 CPU @ 2.80GHz
 | 
					 | 
				
			||||||
BenchmarkGSM7EncodeSimpleASCIIString-6              	17190692	        63.88 ns/op
 | 
					 | 
				
			||||||
BenchmarkGSM7EncodeComplexASCIIString-6             	 3987712	       302.8 ns/op
 | 
					 | 
				
			||||||
BenchmarkGSM7EncodeComplex8nASCIIString-6           	 2563090	       523.2 ns/op
 | 
					 | 
				
			||||||
BenchmarkGSM7EncodeComplex8nASCIIStringPrealloc-6   	 2615463	       462.5 ns/op
 | 
					 | 
				
			||||||
PASS
 | 
					 | 
				
			||||||
ok  	smpptester/encoding	6.235s
 | 
					 | 
				
			||||||
?   	smpptester/lua	[no test files]
 | 
					 | 
				
			||||||
goos: linux
 | 
					 | 
				
			||||||
goarch: amd64
 | 
					 | 
				
			||||||
pkg: smpptester/pdu
 | 
					 | 
				
			||||||
cpu: Intel(R) Core(TM) i5-8400 CPU @ 2.80GHz
 | 
					 | 
				
			||||||
BenchmarkBufferPoolManager-6              	16913668	        70.22 ns/op
 | 
					 | 
				
			||||||
BenchmarkBufferPoolManager_Concurrent-6   	 9289608	       129.8 ns/op
 | 
					 | 
				
			||||||
BenchmarkBufferPoolManager_Memory-6       	13000988	        83.78 ns/op
 | 
					 | 
				
			||||||
BenchmarkEncodeWithBufferPool-6           	 7950153	       137.7 ns/op
 | 
					 | 
				
			||||||
BenchmarkEncodeWithoutBufferPool-6        	 6290456	       172.9 ns/op
 | 
					 | 
				
			||||||
BenchmarkDecodeBufferPool-6               	 7194349	       162.7 ns/op
 | 
					 | 
				
			||||||
PASS
 | 
					 | 
				
			||||||
ok  	smpptester/pdu	7.717s
 | 
					 | 
				
			||||||
?   	smpptester/server	[no test files]
 | 
					 | 
				
			||||||
?   	smpptester/utils	[no test files]
 | 
					 | 
				
			||||||
							
								
								
									
										14
									
								
								encoding/ascii.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								encoding/ascii.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					package encoding
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "bytes"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type ASCIICoder struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *ASCIICoder) Encode(s string, buf *bytes.Buffer) error {
 | 
				
			||||||
 | 
						buf.WriteString(s)
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *ASCIICoder) Decode(buf *bytes.Buffer) (string, error) {
 | 
				
			||||||
 | 
						return buf.String(), nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										74
									
								
								encoding/ascii_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								encoding/ascii_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,74 @@
 | 
				
			|||||||
 | 
					package encoding
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestASCIIEncodeSimpleASCIIString(t *testing.T) {
 | 
				
			||||||
 | 
						coder := &ASCIICoder{}
 | 
				
			||||||
 | 
						var buf bytes.Buffer
 | 
				
			||||||
 | 
						input := "Hello, World!"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						expected := []byte{72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100, 33}
 | 
				
			||||||
 | 
						err := coder.Encode(input, &buf)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Errorf("Expected no error, but got %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if !bytes.Equal(buf.Bytes(), expected) {
 | 
				
			||||||
 | 
							t.Errorf("Expected %v, but got %v", expected, buf.Bytes())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestASCIIDecodeSimpleASCIIString(t *testing.T) {
 | 
				
			||||||
 | 
						coder := &ASCIICoder{}
 | 
				
			||||||
 | 
						var buf bytes.Buffer
 | 
				
			||||||
 | 
						input := []byte{72, 101, 108, 108, 111, 44, 32, 87, 111, 114, 108, 100, 33}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						expected := "Hello, World!"
 | 
				
			||||||
 | 
						buf.Write(input)
 | 
				
			||||||
 | 
						output, err := coder.Decode(&buf)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Errorf("Expected no error, but got %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if output != expected {
 | 
				
			||||||
 | 
							t.Errorf("Expected %v, but got %v", expected, output)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestASCIIEncodeEmptyString(t *testing.T) {
 | 
				
			||||||
 | 
						coder := &ASCIICoder{}
 | 
				
			||||||
 | 
						var buf bytes.Buffer
 | 
				
			||||||
 | 
						input := ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						expected := []byte{}
 | 
				
			||||||
 | 
						err := coder.Encode(input, &buf)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Errorf("Expected no error, but got %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if !bytes.Equal(buf.Bytes(), expected) {
 | 
				
			||||||
 | 
							t.Errorf("Expected %v, but got %v", expected, buf.Bytes())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestASCIIDecodeEmptyString(t *testing.T) {
 | 
				
			||||||
 | 
						coder := &ASCIICoder{}
 | 
				
			||||||
 | 
						buf := bytes.NewBuffer([]byte{})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						expected := ""
 | 
				
			||||||
 | 
						output, err := coder.Decode(buf)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Errorf("Expected no error, but got %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if output != expected {
 | 
				
			||||||
 | 
							t.Errorf("Expected %v, but got %v", expected, output)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										5
									
								
								encoding/charset.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								encoding/charset.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
						"ucs2": {
 | 
				
			||||||
 | 
							"link": "http://www.columbia.edu/kermit/ucs2.html"
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										8
									
								
								encoding/coder.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								encoding/coder.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,8 @@
 | 
				
			|||||||
 | 
					package encoding
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "bytes"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type Coder interface {
 | 
				
			||||||
 | 
						Encode(s string, buf *bytes.Buffer) error
 | 
				
			||||||
 | 
						Decode(buf *bytes.Buffer) (string, error)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										18
									
								
								encoding/gsm7.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								encoding/gsm7.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					package encoding
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
 | 
						"log"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type GSM7Coder struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *GSM7Coder) Encode(s string, buf *bytes.Buffer) {
 | 
				
			||||||
 | 
						utf8 := []byte(s)
 | 
				
			||||||
 | 
						log.Println(utf8)
 | 
				
			||||||
 | 
						buf.Write(utf8)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *GSM7Coder) Decode(buf *bytes.Buffer) string {
 | 
				
			||||||
 | 
						return buf.String()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										58
									
								
								encoding/gsm7_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								encoding/gsm7_test.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
				
			|||||||
 | 
					package encoding
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestGSM7EncodeSimpleASCIIString(t *testing.T) {
 | 
				
			||||||
 | 
						coder := &GSM7Coder{}
 | 
				
			||||||
 | 
						var buf bytes.Buffer
 | 
				
			||||||
 | 
						input := "Sunshine"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						expected := []byte{0b11010011, 0b10111001, 0b10111011, 0b10001110, 0b01001110, 0b10111011, 0b11001011}
 | 
				
			||||||
 | 
						coder.Encode(input, &buf)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if !bytes.Equal(buf.Bytes(), expected) {
 | 
				
			||||||
 | 
							t.Errorf("Expected %v, but got %v", expected, buf.Bytes())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestGSM7DecodeSimpleASCIIString(t *testing.T) {
 | 
				
			||||||
 | 
						coder := &GSM7Coder{}
 | 
				
			||||||
 | 
						var buf bytes.Buffer
 | 
				
			||||||
 | 
						input := []byte{0b11010011, 0b10111001, 0b10111011, 0b10001110, 0b01001110, 0b10111011, 0b11001011}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						expected := "Sunshine"
 | 
				
			||||||
 | 
						buf.Write(input)
 | 
				
			||||||
 | 
						output := coder.Decode(&buf)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if output != expected {
 | 
				
			||||||
 | 
							t.Errorf("Expected %v, but got %v", expected, output)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestGSM7EncodeEmptyString(t *testing.T) {
 | 
				
			||||||
 | 
						coder := &GSM7Coder{}
 | 
				
			||||||
 | 
						var buf bytes.Buffer
 | 
				
			||||||
 | 
						input := ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						expected := []byte{}
 | 
				
			||||||
 | 
						coder.Encode(input, &buf)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if !bytes.Equal(buf.Bytes(), expected) {
 | 
				
			||||||
 | 
							t.Errorf("Expected %v, but got %v", expected, buf.Bytes())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestGSM7DecodeEmptyString(t *testing.T) {
 | 
				
			||||||
 | 
						coder := &GSM7Coder{}
 | 
				
			||||||
 | 
						buf := bytes.NewBuffer([]byte{})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						expected := ""
 | 
				
			||||||
 | 
						output := coder.Decode(buf)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if output != expected {
 | 
				
			||||||
 | 
							t.Errorf("Expected %v, but got %v", expected, output)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										13
									
								
								encoding/ucs2.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								encoding/ucs2.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					package encoding
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "bytes"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type UCS2Coder struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *UCS2Coder) Encode(s string, buf *bytes.Buffer) {
 | 
				
			||||||
 | 
						panic("UCS2 not implemented yet")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (c *UCS2Coder) Decode(buf *bytes.Buffer) string {
 | 
				
			||||||
 | 
						panic("UCS2 not implemented yet")
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										5
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								go.mod
									
									
									
									
									
								
							@@ -2,4 +2,7 @@ module smpptester
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
go 1.22.4
 | 
					go 1.22.4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require github.com/yuin/gopher-lua v1.1.1
 | 
					require (
 | 
				
			||||||
 | 
						github.com/warthog618/sms v0.3.0
 | 
				
			||||||
 | 
						github.com/yuin/gopher-lua v1.1.1
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										14
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										14
									
								
								go.sum
									
									
									
									
									
								
							@@ -1,2 +1,16 @@
 | 
				
			|||||||
 | 
					github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
				
			||||||
 | 
					github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
				
			||||||
 | 
					github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 | 
				
			||||||
 | 
					github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 | 
				
			||||||
 | 
					github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
 | 
				
			||||||
 | 
					github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 | 
				
			||||||
 | 
					github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 | 
				
			||||||
 | 
					github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 | 
				
			||||||
 | 
					github.com/warthog618/sms v0.3.0 h1:LYAb5ngmu2qjNExgji3B7xi2tIZ9+DsuE9pC5xs4wwc=
 | 
				
			||||||
 | 
					github.com/warthog618/sms v0.3.0/go.mod h1:+bYZGeBxu003sxD5xhzsrIPBAjPBzTABsRTwSpd7ld4=
 | 
				
			||||||
github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M=
 | 
					github.com/yuin/gopher-lua v1.1.1 h1:kYKnWBjvbNP4XLT3+bPEwAXJx262OhaHDWDVOPjL46M=
 | 
				
			||||||
github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw=
 | 
					github.com/yuin/gopher-lua v1.1.1/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw=
 | 
				
			||||||
 | 
					gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 | 
				
			||||||
 | 
					gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 | 
				
			||||||
 | 
					gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 | 
				
			||||||
 | 
					gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								main.go
									
									
									
									
									
								
							@@ -136,6 +136,7 @@ func main() {
 | 
				
			|||||||
	// 		go handleConnection(conn)
 | 
						// 		go handleConnection(conn)
 | 
				
			||||||
	// 	}
 | 
						// 	}
 | 
				
			||||||
	// }()
 | 
						// }()
 | 
				
			||||||
 | 
						log.Println(createSubmitSMPDU())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	wg := &sync.WaitGroup{}
 | 
						wg := &sync.WaitGroup{}
 | 
				
			||||||
	wg.Add(1)
 | 
						wg.Add(1)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										16
									
								
								pdu/bind.go
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								pdu/bind.go
									
									
									
									
									
								
							@@ -2,19 +2,19 @@ package pdu
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type (
 | 
					type (
 | 
				
			||||||
	BIND struct {
 | 
						BIND struct {
 | 
				
			||||||
		header            PDU_HEADER
 | 
							header            *PDU_HEADER
 | 
				
			||||||
		system_id         string
 | 
							system_id         string
 | 
				
			||||||
		password          string
 | 
							password          string
 | 
				
			||||||
		system_type       string
 | 
							system_type       string
 | 
				
			||||||
		interface_version uint8
 | 
							interface_version byte
 | 
				
			||||||
		addr_ton          uint8
 | 
							addr_ton          byte
 | 
				
			||||||
		addr_npi          uint8
 | 
							addr_npi          byte
 | 
				
			||||||
		address_range     string
 | 
							address_range     string
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	BIND_RESP struct {
 | 
						BIND_RESP struct {
 | 
				
			||||||
		header               PDU_HEADER
 | 
							header               *PDU_HEADER
 | 
				
			||||||
		system_id            string
 | 
							system_id            string
 | 
				
			||||||
		sc_interface_version uint8
 | 
							sc_interface_version byte
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	BIND_RECVEIVER struct {
 | 
						BIND_RECVEIVER struct {
 | 
				
			||||||
		BIND
 | 
							BIND
 | 
				
			||||||
@@ -36,9 +36,9 @@ type (
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	UNBIND struct {
 | 
						UNBIND struct {
 | 
				
			||||||
		PDU_HEADER
 | 
							header *PDU_HEADER
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	UNBIND_RESP struct {
 | 
						UNBIND_RESP struct {
 | 
				
			||||||
		PDU_HEADER
 | 
							header *PDU_HEADER
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,21 +1,30 @@
 | 
				
			|||||||
package pdu
 | 
					package pdu
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
 | 
						"log"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type BufferPoolManager struct {
 | 
					type BufferPoolManager struct {
 | 
				
			||||||
	pools map[uint]*sync.Pool
 | 
						pools map[int]*sync.Pool
 | 
				
			||||||
	mu    sync.RWMutex
 | 
						mu    sync.RWMutex
 | 
				
			||||||
 | 
						debug bool
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (bpm *BufferPoolManager) logf(format string, args ...interface{}) {
 | 
				
			||||||
 | 
						if bpm.debug {
 | 
				
			||||||
 | 
							log.Printf(format, args...)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewBufferPoolManager() *BufferPoolManager {
 | 
					func NewBufferPoolManager() *BufferPoolManager {
 | 
				
			||||||
	return &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()
 | 
						bpm.mu.RLock()
 | 
				
			||||||
	pool, exists := bpm.pools[size]
 | 
						pool, exists := bpm.pools[size]
 | 
				
			||||||
	bpm.mu.RUnlock()
 | 
						bpm.mu.RUnlock()
 | 
				
			||||||
@@ -25,10 +34,13 @@ func (bpm *BufferPoolManager) Get(size uint) *[]uint8 {
 | 
				
			|||||||
		// Double-check if another goroutine added the pool while we were waiting
 | 
							// Double-check if another goroutine added the pool while we were waiting
 | 
				
			||||||
		pool, exists = bpm.pools[size]
 | 
							pool, exists = bpm.pools[size]
 | 
				
			||||||
		if !exists {
 | 
							if !exists {
 | 
				
			||||||
 | 
								bpm.logf("Creating new pool for size %d\n", size)
 | 
				
			||||||
			pool = &sync.Pool{
 | 
								pool = &sync.Pool{
 | 
				
			||||||
				New: func() interface{} {
 | 
									New: func() interface{} {
 | 
				
			||||||
					buf := make([]uint8, size)
 | 
										bpm.logf("Creating new buffer of size %d\n", size)
 | 
				
			||||||
					return &buf
 | 
										buf := bytes.NewBuffer(make([]byte, size))
 | 
				
			||||||
 | 
										buf.Reset()
 | 
				
			||||||
 | 
										return buf
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			bpm.pools[size] = pool
 | 
								bpm.pools[size] = pool
 | 
				
			||||||
@@ -36,23 +48,23 @@ func (bpm *BufferPoolManager) Get(size uint) *[]uint8 {
 | 
				
			|||||||
		bpm.mu.Unlock()
 | 
							bpm.mu.Unlock()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return pool.Get().(*[]uint8)
 | 
						buf := pool.Get().(*bytes.Buffer)
 | 
				
			||||||
 | 
						bpm.logf("Returning buffer of size %d: %p\n", buf.Cap(), buf)
 | 
				
			||||||
 | 
						return buf
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (bpm *BufferPoolManager) Put(buf *[]uint8) {
 | 
					func (bpm *BufferPoolManager) Put(buf *bytes.Buffer) {
 | 
				
			||||||
	size := uint(len(*buf))
 | 
						size := buf.Cap()
 | 
				
			||||||
	bpm.mu.RLock()
 | 
						bpm.mu.RLock()
 | 
				
			||||||
	pool, exists := bpm.pools[size]
 | 
						pool, exists := bpm.pools[size]
 | 
				
			||||||
	bpm.mu.RUnlock()
 | 
						bpm.mu.RUnlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if !exists {
 | 
						if !exists {
 | 
				
			||||||
 | 
							bpm.logf("Cannot return %p, No pool for size %d\n", buf, size)
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Clear buffer
 | 
						buf.Reset()
 | 
				
			||||||
	for i := range *buf {
 | 
					 | 
				
			||||||
		(*buf)[i] = 0
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	pool.Put(buf)
 | 
						pool.Put(buf)
 | 
				
			||||||
 | 
						bpm.logf("Returned buffer of size %d: %p\n", size, buf)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,14 +10,14 @@ func TestRetrieveBufferOfRequestedSize(t *testing.T) {
 | 
				
			|||||||
	bpm := NewBufferPoolManager()
 | 
						bpm := NewBufferPoolManager()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	size := 1024
 | 
						size := 1024
 | 
				
			||||||
	buffer := bpm.Get(uint(size))
 | 
						buffer := bpm.Get(size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if buffer == nil {
 | 
						if buffer == nil {
 | 
				
			||||||
		t.Fatalf("Expected buffer, got nil")
 | 
							t.Fatalf("Expected buffer, got nil")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if len(*buffer) != size {
 | 
						if buffer.Cap() != size {
 | 
				
			||||||
		t.Errorf("Expected buffer size %d, got %d", size, len(*buffer))
 | 
							t.Errorf("Expected buffer size %d, got %d", size, buffer.Cap())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -25,14 +25,14 @@ func TestRequestBufferSizeZero(t *testing.T) {
 | 
				
			|||||||
	bpm := NewBufferPoolManager()
 | 
						bpm := NewBufferPoolManager()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	size := 0
 | 
						size := 0
 | 
				
			||||||
	buffer := bpm.Get(uint(size))
 | 
						buffer := bpm.Get(size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if buffer == nil {
 | 
						if buffer == nil {
 | 
				
			||||||
		t.Fatalf("Expected buffer, got nil")
 | 
							t.Fatalf("Expected buffer, got nil")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if len(*buffer) != size {
 | 
						if buffer.Cap() != size {
 | 
				
			||||||
		t.Errorf("Expected buffer size %d, got %d", size, len(*buffer))
 | 
							t.Errorf("Expected buffer size %d, got %d", size, buffer.Cap())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -47,12 +47,12 @@ func TestConcurrentAccessToBufferPool(t *testing.T) {
 | 
				
			|||||||
		wg.Add(1)
 | 
							wg.Add(1)
 | 
				
			||||||
		go func() {
 | 
							go func() {
 | 
				
			||||||
			defer wg.Done()
 | 
								defer wg.Done()
 | 
				
			||||||
			buffer := bpm.Get(uint(size))
 | 
								buffer := bpm.Get(size)
 | 
				
			||||||
			if buffer == nil {
 | 
								if buffer == nil {
 | 
				
			||||||
				t.Errorf("Expected buffer, got nil")
 | 
									t.Errorf("Expected buffer, got nil")
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if len(*buffer) != size {
 | 
								if buffer.Cap() != size {
 | 
				
			||||||
				t.Errorf("Expected buffer size %d, got %d", size, len(*buffer))
 | 
									t.Errorf("Expected buffer size %d, got %d", size, buffer.Cap())
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}()
 | 
							}()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -64,14 +64,14 @@ func TestGetBufferLockUnlock(t *testing.T) {
 | 
				
			|||||||
	bpm := NewBufferPoolManager()
 | 
						bpm := NewBufferPoolManager()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	size := 1024
 | 
						size := 1024
 | 
				
			||||||
	buffer := bpm.Get(uint(size))
 | 
						buffer := bpm.Get(size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if buffer == nil {
 | 
						if buffer == nil {
 | 
				
			||||||
		t.Fatalf("Expected buffer, got nil")
 | 
							t.Fatalf("Expected buffer, got nil")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if len(*buffer) != size {
 | 
						if buffer.Cap() != size {
 | 
				
			||||||
		t.Errorf("Expected buffer size %d, got %d", size, len(*buffer))
 | 
							t.Errorf("Expected buffer size %d, got %d", size, buffer.Cap())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -79,14 +79,14 @@ func TestVerifyPoolCreationForNewSizes(t *testing.T) {
 | 
				
			|||||||
	bpm := NewBufferPoolManager()
 | 
						bpm := NewBufferPoolManager()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	size := 512
 | 
						size := 512
 | 
				
			||||||
	buffer := bpm.Get(uint(size))
 | 
						buffer := bpm.Get(size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if buffer == nil {
 | 
						if buffer == nil {
 | 
				
			||||||
		t.Fatalf("Expected buffer, got nil")
 | 
							t.Fatalf("Expected buffer, got nil")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if len(*buffer) != size {
 | 
						if buffer.Cap() != size {
 | 
				
			||||||
		t.Errorf("Expected buffer size %d, got %d", size, len(*buffer))
 | 
							t.Errorf("Expected buffer size %d, got %d", size, buffer.Cap())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -94,14 +94,14 @@ func TestBufferPoolManagerGetBuffer(t *testing.T) {
 | 
				
			|||||||
	bpm := NewBufferPoolManager()
 | 
						bpm := NewBufferPoolManager()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	size := 1024
 | 
						size := 1024
 | 
				
			||||||
	buffer := bpm.Get(uint(size))
 | 
						buffer := bpm.Get(size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if buffer == nil {
 | 
						if buffer == nil {
 | 
				
			||||||
		t.Fatalf("Expected buffer, got nil")
 | 
							t.Fatalf("Expected buffer, got nil")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if len(*buffer) != size {
 | 
						if buffer.Cap() != size {
 | 
				
			||||||
		t.Errorf("Expected buffer size %d, got %d", size, len(*buffer))
 | 
							t.Errorf("Expected buffer size %d, got %d", size, buffer.Cap())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -110,14 +110,14 @@ func TestGetBufferWithMultipleSizes(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	sizes := []int{512, 1024, 2048}
 | 
						sizes := []int{512, 1024, 2048}
 | 
				
			||||||
	for _, size := range sizes {
 | 
						for _, size := range sizes {
 | 
				
			||||||
		buffer := bpm.Get(uint(size))
 | 
							buffer := bpm.Get(size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if buffer == nil {
 | 
							if buffer == nil {
 | 
				
			||||||
			t.Fatalf("Expected buffer for size %d, got nil", size)
 | 
								t.Fatalf("Expected buffer for size %d, got nil", size)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if len(*buffer) != size {
 | 
							if buffer.Cap() != size {
 | 
				
			||||||
			t.Errorf("Expected buffer size %d, got %d", size, len(*buffer))
 | 
								t.Errorf("Expected buffer size %d, got %d", size, buffer.Cap())
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -125,7 +125,7 @@ func TestGetBufferWithMultipleSizes(t *testing.T) {
 | 
				
			|||||||
func TestGetBufferIsAlwaysZero(t *testing.T) {
 | 
					func TestGetBufferIsAlwaysZero(t *testing.T) {
 | 
				
			||||||
	bpm := NewBufferPoolManager()
 | 
						bpm := NewBufferPoolManager()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var size uint = 1024 * 64
 | 
						size := 1024 * 64
 | 
				
			||||||
	for i := 0; i < 1000; i++ {
 | 
						for i := 0; i < 1000; i++ {
 | 
				
			||||||
		buffer := bpm.Get(size)
 | 
							buffer := bpm.Get(size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -133,11 +133,11 @@ func TestGetBufferIsAlwaysZero(t *testing.T) {
 | 
				
			|||||||
			t.Fatalf("Expected buffer for size %d, got nil", size)
 | 
								t.Fatalf("Expected buffer for size %d, got nil", size)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if uint(len(*buffer)) != size {
 | 
							if buffer.Cap() != size {
 | 
				
			||||||
			t.Errorf("Expected buffer size %d, got %d", size, len(*buffer))
 | 
								t.Errorf("Expected buffer size %d, got %d", size, buffer.Cap())
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for _, b := range *buffer {
 | 
							for _, b := range buffer.Bytes() {
 | 
				
			||||||
			if b != 0 {
 | 
								if b != 0 {
 | 
				
			||||||
				t.Errorf("Expected buffer to be zero, got %d", b)
 | 
									t.Errorf("Expected buffer to be zero, got %d", b)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -147,9 +147,26 @@ func TestGetBufferIsAlwaysZero(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestPoolReusesBuffers(t *testing.T) {
 | 
				
			||||||
 | 
						bpm := NewBufferPoolManager()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						size := 1024
 | 
				
			||||||
 | 
						buffer := bpm.Get(size)
 | 
				
			||||||
 | 
						initialPtr := buffer
 | 
				
			||||||
 | 
						bpm.Put(buffer)
 | 
				
			||||||
 | 
						for i := 0; i < 1000; i++ {
 | 
				
			||||||
 | 
							buffer = bpm.Get(size)
 | 
				
			||||||
 | 
							if buffer != initialPtr {
 | 
				
			||||||
 | 
								t.Errorf("Expected initial buffer (%p) to be reused, got %p", initialPtr, buffer)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							bpm.Put(buffer)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// region benchmark
 | 
				
			||||||
func BenchmarkBufferPoolManager(b *testing.B) {
 | 
					func BenchmarkBufferPoolManager(b *testing.B) {
 | 
				
			||||||
	bpm := NewBufferPoolManager()
 | 
						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()
 | 
						b.ResetTimer()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -163,7 +180,7 @@ func BenchmarkBufferPoolManager(b *testing.B) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func BenchmarkBufferPoolManager_Concurrent(b *testing.B) {
 | 
					func BenchmarkBufferPoolManager_Concurrent(b *testing.B) {
 | 
				
			||||||
	bpm := NewBufferPoolManager()
 | 
						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()
 | 
						b.ResetTimer()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -186,17 +203,17 @@ func BenchmarkBufferPoolManager_Concurrent(b *testing.B) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func BenchmarkBufferPoolManager_Memory(b *testing.B) {
 | 
					func BenchmarkBufferPoolManager_Memory(b *testing.B) {
 | 
				
			||||||
	bpm := NewBufferPoolManager()
 | 
						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()
 | 
						b.ResetTimer()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var i uint8
 | 
						var i byte
 | 
				
			||||||
	buf := bpm.Get(bufSize)
 | 
						buf := bpm.Get(bufSize)
 | 
				
			||||||
	b.StopTimer()
 | 
						b.StopTimer()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Simulate some work
 | 
						// Simulate some work
 | 
				
			||||||
	time.Sleep(10 * time.Millisecond)
 | 
						time.Sleep(10 * time.Millisecond)
 | 
				
			||||||
	for k := range *buf {
 | 
						for range buf.Bytes() {
 | 
				
			||||||
		(*buf)[k] = i % 255
 | 
							buf.WriteByte(i % 255)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	b.StartTimer()
 | 
						b.StartTimer()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,17 +2,17 @@ package pdu
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type (
 | 
					type (
 | 
				
			||||||
	CANCEL_SM struct {
 | 
						CANCEL_SM struct {
 | 
				
			||||||
		header           PDU_HEADER
 | 
							header           *PDU_HEADER
 | 
				
			||||||
		service_type     string
 | 
							service_type     string
 | 
				
			||||||
		message_id       string
 | 
							message_id       string
 | 
				
			||||||
		source_addr_ton  uint8
 | 
							source_addr_ton  byte
 | 
				
			||||||
		source_addr_npi  uint8
 | 
							source_addr_npi  byte
 | 
				
			||||||
		source_addr      string
 | 
							source_addr      string
 | 
				
			||||||
		dest_addr_ton    uint8
 | 
							dest_addr_ton    byte
 | 
				
			||||||
		dest_addr_npi    uint8
 | 
							dest_addr_npi    byte
 | 
				
			||||||
		destination_addr string
 | 
							destination_addr string
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	CANCEL_SM_RESP struct {
 | 
						CANCEL_SM_RESP struct {
 | 
				
			||||||
		header PDU_HEADER
 | 
							header *PDU_HEADER
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,11 +2,11 @@ package pdu
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type (
 | 
					type (
 | 
				
			||||||
	DELIVER_SM struct {
 | 
						DELIVER_SM struct {
 | 
				
			||||||
		header PDU_HEADER
 | 
							header *PDU_HEADER
 | 
				
			||||||
		SUBMIT_SM
 | 
							SUBMIT_SM
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	DELIVER_SM_RESP struct {
 | 
						DELIVER_SM_RESP struct {
 | 
				
			||||||
		header PDU_HEADER
 | 
							header *PDU_HEADER
 | 
				
			||||||
		SUBMIT_SM_RESP
 | 
							SUBMIT_SM_RESP
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,9 +2,9 @@ package pdu
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
type (
 | 
					type (
 | 
				
			||||||
	ENQUIRE_LINK struct {
 | 
						ENQUIRE_LINK struct {
 | 
				
			||||||
		header PDU_HEADER
 | 
							header *PDU_HEADER
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	ENQUIRE_LINK_RESP struct {
 | 
						ENQUIRE_LINK_RESP struct {
 | 
				
			||||||
		header PDU_HEADER
 | 
							header *PDU_HEADER
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,5 @@
 | 
				
			|||||||
package pdu
 | 
					package pdu
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var ByteBufferPool = NewBufferPoolManager()
 | 
					var ByteBufferPool = NewBufferPoolManager()
 | 
				
			||||||
 | 
					const NULL = byte(0x00)
 | 
				
			||||||
 | 
					var NULL_ARR = []byte{NULL}
 | 
				
			||||||
							
								
								
									
										57
									
								
								pdu/pdu.go
									
									
									
									
									
								
							
							
						
						
									
										57
									
								
								pdu/pdu.go
									
									
									
									
									
								
							@@ -1,17 +1,18 @@
 | 
				
			|||||||
package pdu
 | 
					package pdu
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
	"encoding/binary"
 | 
						"encoding/binary"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type (
 | 
					type (
 | 
				
			||||||
	PDU interface {
 | 
						PDU interface {
 | 
				
			||||||
		EncodeInto(*[]uint8)
 | 
							Encode(*bytes.Buffer) error
 | 
				
			||||||
		Encode() []uint8
 | 
							Decode(*bytes.Buffer) error
 | 
				
			||||||
		Decode([]uint8)
 | 
					 | 
				
			||||||
		// Size in bytes
 | 
							// Size in bytes
 | 
				
			||||||
		Size() uint32
 | 
							Size() int
 | 
				
			||||||
 | 
							UpdateSize()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	PDU_HEADER struct {
 | 
						PDU_HEADER struct {
 | 
				
			||||||
@@ -22,7 +23,7 @@ type (
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	GENERIC_NACK struct {
 | 
						GENERIC_NACK struct {
 | 
				
			||||||
		header PDU_HEADER
 | 
							header *PDU_HEADER
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -57,41 +58,29 @@ type (
 | 
				
			|||||||
// What are the other 0s?
 | 
					// What are the other 0s?
 | 
				
			||||||
// Don't know
 | 
					// Don't know
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (p *PDU_HEADER) Encode() (*[]uint8, error) {
 | 
					func (p *PDU_HEADER) Encode(buf *bytes.Buffer) 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 {
 | 
						if buf == nil {
 | 
				
			||||||
		return fmt.Errorf("cannot encode PDU_HEADER, buffer is nil")
 | 
							return fmt.Errorf("cannot encode into nil buffer")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if len(*buf) < 16 {
 | 
						binary.Write(buf, binary.BigEndian, p.command_length)
 | 
				
			||||||
		return fmt.Errorf("cannot encode PDU_HEADER, buffer too small (%d, required 16)", len(*buf))
 | 
						binary.Write(buf, binary.BigEndian, p.command_id)
 | 
				
			||||||
	}
 | 
						binary.Write(buf, binary.BigEndian, p.command_status)
 | 
				
			||||||
	bufVal := *buf
 | 
						binary.Write(buf, binary.BigEndian, p.sequence_number)
 | 
				
			||||||
	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)
 | 
					 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (p *PDU_HEADER) Decode(data []uint8) error {
 | 
					func (p *PDU_HEADER) Decode(buf *bytes.Buffer) error {
 | 
				
			||||||
	if len(data) >= 4 {
 | 
						if buf == nil {
 | 
				
			||||||
		p.command_length = binary.BigEndian.Uint32(data[0:4])
 | 
							return fmt.Errorf("cannot decode nil buffer")
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	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])
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						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
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (p *PDU_HEADER) Size() uint32 {
 | 
					func (p *PDU_HEADER) Size() int {
 | 
				
			||||||
	return 16
 | 
						return 16
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					func (p *PDU_HEADER) UpdateSize() {
 | 
				
			||||||
 | 
						p.command_length = uint32(p.Size())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										260
									
								
								pdu/pdu_test.go
									
									
									
									
									
								
							
							
						
						
									
										260
									
								
								pdu/pdu_test.go
									
									
									
									
									
								
							@@ -1,6 +1,7 @@
 | 
				
			|||||||
package pdu
 | 
					package pdu
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
	"encoding/binary"
 | 
						"encoding/binary"
 | 
				
			||||||
	"math"
 | 
						"math"
 | 
				
			||||||
	"sync"
 | 
						"sync"
 | 
				
			||||||
@@ -15,13 +16,15 @@ func TestEncodeReturnsByteSliceOfLength16(t *testing.T) {
 | 
				
			|||||||
		command_status:  1,
 | 
							command_status:  1,
 | 
				
			||||||
		sequence_number: 1,
 | 
							sequence_number: 1,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	result, err := p.Encode()
 | 
						buf := bytes.NewBuffer(make([]byte, 16))
 | 
				
			||||||
 | 
						buf.Reset()
 | 
				
			||||||
 | 
						err := p.Encode(buf)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Errorf("Expected no error, got %v", err)
 | 
							t.Errorf("Expected no error, got %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if len(*result) != 16 {
 | 
						if buf.Cap() != 16 {
 | 
				
			||||||
		t.Errorf("Expected byte slice of length 16, got %d", len(*result))
 | 
							t.Errorf("Expected byte slice of length 16, got %d", buf.Cap())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -32,15 +35,17 @@ func TestEncodeHandlesZeroValues(t *testing.T) {
 | 
				
			|||||||
		command_status:  0,
 | 
							command_status:  0,
 | 
				
			||||||
		sequence_number: 0,
 | 
							sequence_number: 0,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	result, err := p.Encode()
 | 
						buf := bytes.NewBuffer(make([]byte, 16))
 | 
				
			||||||
 | 
						buf.Reset()
 | 
				
			||||||
 | 
						err := p.Encode(buf)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Errorf("Expected no error, got %v", err)
 | 
							t.Errorf("Expected no error, got %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	expected := make([]uint8, 16)
 | 
						expected := make([]byte, 16)
 | 
				
			||||||
	for i, v := range *result {
 | 
						for i, v := range buf.Bytes() {
 | 
				
			||||||
		if v != expected[i] {
 | 
							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
 | 
								break
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -53,16 +58,18 @@ func TestEncodeEncodesProperly(t *testing.T) {
 | 
				
			|||||||
		command_status:  3,
 | 
							command_status:  3,
 | 
				
			||||||
		sequence_number: 4,
 | 
							sequence_number: 4,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	result, err := p.Encode()
 | 
						buf := bytes.NewBuffer(make([]byte, 16))
 | 
				
			||||||
 | 
						buf.Reset()
 | 
				
			||||||
 | 
						err := p.Encode(buf)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Errorf("Expected no error, got %v", err)
 | 
							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}
 | 
						expected := []byte{0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 4}
 | 
				
			||||||
	for i, v := range *result {
 | 
						for i, v := range buf.Bytes() {
 | 
				
			||||||
		if v != expected[i] {
 | 
							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
 | 
								break
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -75,16 +82,18 @@ func TestEncodeEncodesProperlyComplex(t *testing.T) {
 | 
				
			|||||||
		command_status:  35634264,
 | 
							command_status:  35634264,
 | 
				
			||||||
		sequence_number: 476543523,
 | 
							sequence_number: 476543523,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	result, err := p.Encode()
 | 
						buf := bytes.NewBuffer(make([]byte, 16))
 | 
				
			||||||
 | 
						buf.Reset()
 | 
				
			||||||
 | 
						err := p.Encode(buf)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Errorf("Expected no error, got %v", err)
 | 
							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}
 | 
						expected := []byte{0, 204, 224, 36, 0, 3, 225, 144, 2, 31, 188, 88, 28, 103, 122, 35}
 | 
				
			||||||
	for i, v := range *result {
 | 
						for i, v := range buf.Bytes() {
 | 
				
			||||||
		if v != expected[i] {
 | 
							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
 | 
								break
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -97,54 +106,26 @@ func TestEncodeIntoCorrectlyEncodesFields(t *testing.T) {
 | 
				
			|||||||
		command_status:  0,
 | 
							command_status:  0,
 | 
				
			||||||
		sequence_number: 12345,
 | 
							sequence_number: 12345,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	buf := make([]uint8, 16)
 | 
						buf := bytes.NewBuffer(make([]byte, 16))
 | 
				
			||||||
	err := p.EncodeInto(&buf)
 | 
						buf.Reset()
 | 
				
			||||||
 | 
						err := p.Encode(buf)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Errorf("Expected no error, got %v", err)
 | 
							t.Errorf("Expected no error, got %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if binary.BigEndian.Uint32(buf[0:4]) != p.command_length {
 | 
						innerbuf := buf.Bytes()
 | 
				
			||||||
		t.Errorf("Expected command_length %d, got %d", p.command_length, binary.BigEndian.Uint32(buf[0:4]))
 | 
						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 {
 | 
						if binary.BigEndian.Uint32(innerbuf[4:8]) != p.command_id {
 | 
				
			||||||
		t.Errorf("Expected command_id %d, got %d", p.command_id, binary.BigEndian.Uint32(buf[4:8]))
 | 
							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 {
 | 
						if binary.BigEndian.Uint32(innerbuf[8:12]) != p.command_status {
 | 
				
			||||||
		t.Errorf("Expected command_status %d, got %d", p.command_status, binary.BigEndian.Uint32(buf[8:12]))
 | 
							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 {
 | 
						if binary.BigEndian.Uint32(innerbuf[12:16]) != p.sequence_number {
 | 
				
			||||||
		t.Errorf("Expected sequence_number %d, got %d", p.sequence_number, binary.BigEndian.Uint32(buf[12:16]))
 | 
							t.Errorf("Expected sequence_number %d, got %d", p.sequence_number, binary.BigEndian.Uint32(innerbuf[12:16]))
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestEncodeIntoHandlesNilBuffer(t *testing.T) {
 | 
					 | 
				
			||||||
	p := &PDU_HEADER{
 | 
					 | 
				
			||||||
		command_length:  16,
 | 
					 | 
				
			||||||
		command_id:      1,
 | 
					 | 
				
			||||||
		command_status:  0,
 | 
					 | 
				
			||||||
		sequence_number: 12345,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	var buf *[]uint8 = nil
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	err := p.EncodeInto(buf)
 | 
					 | 
				
			||||||
	if err == nil {
 | 
					 | 
				
			||||||
		t.Errorf("Expected error when buffer is nil")
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func TestEncodeIntoHandlesSmallerBuffer(t *testing.T) {
 | 
					 | 
				
			||||||
	p := &PDU_HEADER{
 | 
					 | 
				
			||||||
		command_length:  16,
 | 
					 | 
				
			||||||
		command_id:      1,
 | 
					 | 
				
			||||||
		command_status:  0,
 | 
					 | 
				
			||||||
		sequence_number: 12345,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	buf := make([]uint8, 12) // smaller buffer size
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	err := p.EncodeInto(&buf)
 | 
					 | 
				
			||||||
	if err == nil {
 | 
					 | 
				
			||||||
		t.Errorf("Expected error when buffer is too small")
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -155,24 +136,26 @@ func TestEncodeIntoHandlesLargerBuffer(t *testing.T) {
 | 
				
			|||||||
		command_status:  0,
 | 
							command_status:  0,
 | 
				
			||||||
		sequence_number: 12345,
 | 
							sequence_number: 12345,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	buf := make([]uint8, 20)
 | 
						buf := bytes.NewBuffer(make([]byte, 20)) // larger buffer size
 | 
				
			||||||
	err := p.EncodeInto(&buf)
 | 
						buf.Reset()
 | 
				
			||||||
 | 
						err := p.Encode(buf)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Errorf("Expected no error, got %v", err)
 | 
							t.Errorf("Expected no error, got %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if binary.BigEndian.Uint32(buf[0:4]) != p.command_length {
 | 
						innerbuf := buf.Bytes()
 | 
				
			||||||
		t.Errorf("Expected command_length %d, got %d", p.command_length, binary.BigEndian.Uint32(buf[0:4]))
 | 
						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 {
 | 
						if binary.BigEndian.Uint32(innerbuf[4:8]) != p.command_id {
 | 
				
			||||||
		t.Errorf("Expected command_id %d, got %d", p.command_id, binary.BigEndian.Uint32(buf[4:8]))
 | 
							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 {
 | 
						if binary.BigEndian.Uint32(innerbuf[8:12]) != p.command_status {
 | 
				
			||||||
		t.Errorf("Expected command_status %d, got %d", p.command_status, binary.BigEndian.Uint32(buf[8:12]))
 | 
							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 {
 | 
						if binary.BigEndian.Uint32(innerbuf[12:16]) != p.sequence_number {
 | 
				
			||||||
		t.Errorf("Expected sequence_number %d, got %d", p.sequence_number, binary.BigEndian.Uint32(buf[12:16]))
 | 
							t.Errorf("Expected sequence_number %d, got %d", p.sequence_number, binary.BigEndian.Uint32(innerbuf[12:16]))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -183,24 +166,26 @@ func TestEncodeIntoUsesBigEndianEncoding(t *testing.T) {
 | 
				
			|||||||
		command_status:  0,
 | 
							command_status:  0,
 | 
				
			||||||
		sequence_number: 12345,
 | 
							sequence_number: 12345,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	buf := make([]uint8, 16)
 | 
						buf := bytes.NewBuffer(make([]byte, 16))
 | 
				
			||||||
	err := p.EncodeInto(&buf)
 | 
						buf.Reset()
 | 
				
			||||||
 | 
						err := p.Encode(buf)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Errorf("Expected no error, got %v", err)
 | 
							t.Errorf("Expected no error, got %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if binary.BigEndian.Uint32(buf[0:4]) != p.command_length {
 | 
						innerbuf := buf.Bytes()
 | 
				
			||||||
		t.Errorf("Expected command_length %d, got %d", p.command_length, binary.BigEndian.Uint32(buf[0:4]))
 | 
						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 {
 | 
						if binary.BigEndian.Uint32(innerbuf[4:8]) != p.command_id {
 | 
				
			||||||
		t.Errorf("Expected command_id %d, got %d", p.command_id, binary.BigEndian.Uint32(buf[4:8]))
 | 
							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 {
 | 
						if binary.BigEndian.Uint32(innerbuf[8:12]) != p.command_status {
 | 
				
			||||||
		t.Errorf("Expected command_status %d, got %d", p.command_status, binary.BigEndian.Uint32(buf[8:12]))
 | 
							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 {
 | 
						if binary.BigEndian.Uint32(innerbuf[12:16]) != p.sequence_number {
 | 
				
			||||||
		t.Errorf("Expected sequence_number %d, got %d", p.sequence_number, binary.BigEndian.Uint32(buf[12:16]))
 | 
							t.Errorf("Expected sequence_number %d, got %d", p.sequence_number, binary.BigEndian.Uint32(innerbuf[12:16]))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -211,28 +196,30 @@ func TestEncodeIntoConcurrencySafety(t *testing.T) {
 | 
				
			|||||||
		command_status:  0,
 | 
							command_status:  0,
 | 
				
			||||||
		sequence_number: 12345,
 | 
							sequence_number: 12345,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	buf := make([]uint8, 16)
 | 
						buf := bytes.NewBuffer(make([]byte, 16))
 | 
				
			||||||
 | 
						buf.Reset()
 | 
				
			||||||
	var wg sync.WaitGroup
 | 
						var wg sync.WaitGroup
 | 
				
			||||||
	for i := 0; i < 1000; i++ {
 | 
						for i := 0; i < 1000; i++ {
 | 
				
			||||||
		wg.Add(1)
 | 
							wg.Add(1)
 | 
				
			||||||
		go func() {
 | 
							go func() {
 | 
				
			||||||
			defer wg.Done()
 | 
								defer wg.Done()
 | 
				
			||||||
			p.EncodeInto(&buf)
 | 
								p.Encode(buf)
 | 
				
			||||||
		}()
 | 
							}()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	wg.Wait()
 | 
						wg.Wait()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if binary.BigEndian.Uint32(buf[0:4]) != p.command_length {
 | 
						innerbuf := buf.Bytes()
 | 
				
			||||||
		t.Errorf("Expected command_length %d, got %d", p.command_length, binary.BigEndian.Uint32(buf[0:4]))
 | 
						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 {
 | 
						if binary.BigEndian.Uint32(innerbuf[4:8]) != p.command_id {
 | 
				
			||||||
		t.Errorf("Expected command_id %d, got %d", p.command_id, binary.BigEndian.Uint32(buf[4:8]))
 | 
							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 {
 | 
						if binary.BigEndian.Uint32(innerbuf[8:12]) != p.command_status {
 | 
				
			||||||
		t.Errorf("Expected command_status %d, got %d", p.command_status, binary.BigEndian.Uint32(buf[8:12]))
 | 
							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 {
 | 
						if binary.BigEndian.Uint32(innerbuf[12:16]) != p.sequence_number {
 | 
				
			||||||
		t.Errorf("Expected sequence_number %d, got %d", p.sequence_number, binary.BigEndian.Uint32(buf[12:16]))
 | 
							t.Errorf("Expected sequence_number %d, got %d", p.sequence_number, binary.BigEndian.Uint32(innerbuf[12:16]))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -243,24 +230,26 @@ func TestEncodeIntoWithMaximumValues(t *testing.T) {
 | 
				
			|||||||
		command_status:  math.MaxUint32,
 | 
							command_status:  math.MaxUint32,
 | 
				
			||||||
		sequence_number: math.MaxUint32,
 | 
							sequence_number: math.MaxUint32,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	buf := make([]uint8, 16)
 | 
						buf := bytes.NewBuffer(make([]byte, 16))
 | 
				
			||||||
	err := p.EncodeInto(&buf)
 | 
						buf.Reset()
 | 
				
			||||||
 | 
						err := p.Encode(buf)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Errorf("Expected no error, got %v", err)
 | 
							t.Errorf("Expected no error, got %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if binary.BigEndian.Uint32(buf[0:4]) != p.command_length {
 | 
						innerbuf := buf.Bytes()
 | 
				
			||||||
		t.Errorf("Expected command_length %d, got %d", p.command_length, binary.BigEndian.Uint32(buf[0:4]))
 | 
						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 {
 | 
						if binary.BigEndian.Uint32(innerbuf[4:8]) != p.command_id {
 | 
				
			||||||
		t.Errorf("Expected command_id %d, got %d", p.command_id, binary.BigEndian.Uint32(buf[4:8]))
 | 
							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 {
 | 
						if binary.BigEndian.Uint32(innerbuf[8:12]) != p.command_status {
 | 
				
			||||||
		t.Errorf("Expected command_status %d, got %d", p.command_status, binary.BigEndian.Uint32(buf[8:12]))
 | 
							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 {
 | 
						if binary.BigEndian.Uint32(innerbuf[12:16]) != p.sequence_number {
 | 
				
			||||||
		t.Errorf("Expected sequence_number %d, got %d", p.sequence_number, binary.BigEndian.Uint32(buf[12:16]))
 | 
							t.Errorf("Expected sequence_number %d, got %d", p.sequence_number, binary.BigEndian.Uint32(innerbuf[12:16]))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -271,38 +260,39 @@ func TestEncodeIntoWithBoundaryValues(t *testing.T) {
 | 
				
			|||||||
		command_status:  0,
 | 
							command_status:  0,
 | 
				
			||||||
		sequence_number: 0,
 | 
							sequence_number: 0,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	buf := make([]uint8, 16)
 | 
						buf := bytes.NewBuffer(make([]byte, 16))
 | 
				
			||||||
	err := p.EncodeInto(&buf)
 | 
						buf.Reset()
 | 
				
			||||||
 | 
						err := p.Encode(buf)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Errorf("Expected no error, got %v", err)
 | 
							t.Errorf("Expected no error, got %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if binary.BigEndian.Uint32(buf[0:4]) != p.command_length {
 | 
						innerbuf := buf.Bytes()
 | 
				
			||||||
		t.Errorf("Expected command_length %d, got %d", p.command_length, binary.BigEndian.Uint32(buf[0:4]))
 | 
						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 {
 | 
						if binary.BigEndian.Uint32(innerbuf[4:8]) != p.command_id {
 | 
				
			||||||
		t.Errorf("Expected command_id %d, got %d", p.command_id, binary.BigEndian.Uint32(buf[4:8]))
 | 
							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 {
 | 
						if binary.BigEndian.Uint32(innerbuf[8:12]) != p.command_status {
 | 
				
			||||||
		t.Errorf("Expected command_status %d, got %d", p.command_status, binary.BigEndian.Uint32(buf[8:12]))
 | 
							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 {
 | 
						if binary.BigEndian.Uint32(innerbuf[12:16]) != p.sequence_number {
 | 
				
			||||||
		t.Errorf("Expected sequence_number %d, got %d", p.sequence_number, binary.BigEndian.Uint32(buf[12:16]))
 | 
							t.Errorf("Expected sequence_number %d, got %d", p.sequence_number, binary.BigEndian.Uint32(innerbuf[12:16]))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
// region decode
 | 
					// region decode
 | 
				
			||||||
func TestDecodeHandlesShortByteSlice(t *testing.T) {
 | 
					func TestDecodeHandlesShortByteSlice(t *testing.T) {
 | 
				
			||||||
	var p PDU_HEADER
 | 
						var p PDU_HEADER
 | 
				
			||||||
	data := []uint8{0, 0, 0, 10}
 | 
						data := []byte{0, 0, 0, 10}
 | 
				
			||||||
	defer func() {
 | 
						defer func() {
 | 
				
			||||||
		if r := recover(); r != nil {
 | 
							if r := recover(); r != nil {
 | 
				
			||||||
			t.Errorf("Decode panicked with short byte slice")
 | 
								t.Errorf("Decode panicked with short byte slice")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
	err := p.Decode(data)
 | 
						err := p.Decode(bytes.NewBuffer(data))
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Errorf("Expected no error, got %v", err)
 | 
							t.Errorf("Expected no error, got %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -310,8 +300,8 @@ func TestDecodeHandlesShortByteSlice(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestDecodeParsesValidByteSlice(t *testing.T) {
 | 
					func TestDecodeParsesValidByteSlice(t *testing.T) {
 | 
				
			||||||
	var p PDU_HEADER
 | 
						var p PDU_HEADER
 | 
				
			||||||
	data := []uint8{0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3}
 | 
						data := []byte{0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3}
 | 
				
			||||||
	err := p.Decode(data)
 | 
						err := p.Decode(bytes.NewBuffer(data))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Errorf("Expected no error, got %v", err)
 | 
							t.Errorf("Expected no error, got %v", err)
 | 
				
			||||||
@@ -333,13 +323,13 @@ func TestDecodeParsesValidByteSlice(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestDecodeHandlesLongerByteSliceWithoutCrashing(t *testing.T) {
 | 
					func TestDecodeHandlesLongerByteSliceWithoutCrashing(t *testing.T) {
 | 
				
			||||||
	var p PDU_HEADER
 | 
						var p PDU_HEADER
 | 
				
			||||||
	data := make([]uint8, 20)
 | 
						data := make([]byte, 20)
 | 
				
			||||||
	defer func() {
 | 
						defer func() {
 | 
				
			||||||
		if r := recover(); r != nil {
 | 
							if r := recover(); r != nil {
 | 
				
			||||||
			t.Errorf("Decode panicked with long byte slice")
 | 
								t.Errorf("Decode panicked with long byte slice")
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}()
 | 
						}()
 | 
				
			||||||
	err := p.Decode(data)
 | 
						err := p.Decode(bytes.NewBuffer(data))
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Errorf("Expected no error, got %v", err)
 | 
							t.Errorf("Expected no error, got %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -349,8 +339,8 @@ func TestDecodeHandlesNilDataInput(t *testing.T) {
 | 
				
			|||||||
	var p PDU_HEADER
 | 
						var p PDU_HEADER
 | 
				
			||||||
	err := p.Decode(nil)
 | 
						err := p.Decode(nil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err == nil {
 | 
				
			||||||
		t.Errorf("Expected no error, got %v", err)
 | 
							t.Errorf("Expected error, got none")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if p.command_length != 0 {
 | 
						if p.command_length != 0 {
 | 
				
			||||||
@@ -369,8 +359,8 @@ func TestDecodeHandlesNilDataInput(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestDecodeHandlesEmptyByteSliceGracefully(t *testing.T) {
 | 
					func TestDecodeHandlesEmptyByteSliceGracefully(t *testing.T) {
 | 
				
			||||||
	var p PDU_HEADER
 | 
						var p PDU_HEADER
 | 
				
			||||||
	data := []uint8{}
 | 
						data := []byte{}
 | 
				
			||||||
	err := p.Decode(data)
 | 
						err := p.Decode(bytes.NewBuffer(data))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Errorf("Expected no error, got %v", err)
 | 
							t.Errorf("Expected no error, got %v", err)
 | 
				
			||||||
@@ -392,11 +382,11 @@ func TestDecodeHandlesEmptyByteSliceGracefully(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestDecodeDoesNotModifyInputByteSlice(t *testing.T) {
 | 
					func TestDecodeDoesNotModifyInputByteSlice(t *testing.T) {
 | 
				
			||||||
	var p PDU_HEADER
 | 
						var p PDU_HEADER
 | 
				
			||||||
	data := []uint8{0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3}
 | 
						data := []byte{0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3}
 | 
				
			||||||
	originalData := make([]uint8, len(data))
 | 
						originalData := make([]byte, len(data))
 | 
				
			||||||
	copy(originalData, data)
 | 
						copy(originalData, data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err := p.Decode(data)
 | 
						err := p.Decode(bytes.NewBuffer(data))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Errorf("Expected no error, got %v", err)
 | 
							t.Errorf("Expected no error, got %v", err)
 | 
				
			||||||
@@ -411,8 +401,8 @@ func TestDecodeDoesNotModifyInputByteSlice(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestDecodeHandlesByteSlicesWithMaxUint32Values(t *testing.T) {
 | 
					func TestDecodeHandlesByteSlicesWithMaxUint32Values(t *testing.T) {
 | 
				
			||||||
	var p PDU_HEADER
 | 
						var p PDU_HEADER
 | 
				
			||||||
	data := []uint8{255, 255, 255, 255, 255, 255, 255, 255}
 | 
						data := []byte{255, 255, 255, 255, 255, 255, 255, 255}
 | 
				
			||||||
	err := p.Decode(data)
 | 
						err := p.Decode(bytes.NewBuffer(data))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Errorf("Expected no error, got %v", err)
 | 
							t.Errorf("Expected no error, got %v", err)
 | 
				
			||||||
@@ -428,8 +418,8 @@ func TestDecodeHandlesByteSlicesWithMaxUint32Values(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func TestDecodeHandlesByteSlicesWithMinimumUint32Values(t *testing.T) {
 | 
					func TestDecodeHandlesByteSlicesWithMinimumUint32Values(t *testing.T) {
 | 
				
			||||||
	var p PDU_HEADER
 | 
						var p PDU_HEADER
 | 
				
			||||||
	data := []uint8{0, 0, 0, 0, 0, 0, 0, 0}
 | 
						data := []byte{0, 0, 0, 0, 0, 0, 0, 0}
 | 
				
			||||||
	err := p.Decode(data)
 | 
						err := p.Decode(bytes.NewBuffer(data))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		t.Errorf("Expected no error, got %v", err)
 | 
							t.Errorf("Expected no error, got %v", err)
 | 
				
			||||||
@@ -452,9 +442,8 @@ func TestSizeReturns16(t *testing.T) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// region benchmarks
 | 
					// region benchmarks
 | 
				
			||||||
 | 
					 | 
				
			||||||
// With buffer pool
 | 
					// With buffer pool
 | 
				
			||||||
func BenchmarkEncode(b *testing.B) {
 | 
					func BenchmarkEncodeWithBufferPool(b *testing.B) {
 | 
				
			||||||
	p := &PDU_HEADER{
 | 
						p := &PDU_HEADER{
 | 
				
			||||||
		command_length:  16,
 | 
							command_length:  16,
 | 
				
			||||||
		command_id:      1,
 | 
							command_id:      1,
 | 
				
			||||||
@@ -463,12 +452,14 @@ func BenchmarkEncode(b *testing.B) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	b.ResetTimer()
 | 
						b.ResetTimer()
 | 
				
			||||||
	for i := 0; i < b.N; i++ {
 | 
						for i := 0; i < b.N; i++ {
 | 
				
			||||||
		p.Encode()
 | 
							buf := ByteBufferPool.Get(p.Size())
 | 
				
			||||||
 | 
							p.Encode(buf)
 | 
				
			||||||
 | 
							ByteBufferPool.Put(buf)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Without buffer pool
 | 
					// Without buffer pool
 | 
				
			||||||
func BenchmarkEncodeInto(b *testing.B) {
 | 
					func BenchmarkEncodeWithoutBufferPool(b *testing.B) {
 | 
				
			||||||
	p := &PDU_HEADER{
 | 
						p := &PDU_HEADER{
 | 
				
			||||||
		command_length:  16,
 | 
							command_length:  16,
 | 
				
			||||||
		command_id:      1,
 | 
							command_id:      1,
 | 
				
			||||||
@@ -477,16 +468,19 @@ func BenchmarkEncodeInto(b *testing.B) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	b.ResetTimer()
 | 
						b.ResetTimer()
 | 
				
			||||||
	for i := 0; i < b.N; i++ {
 | 
						for i := 0; i < b.N; i++ {
 | 
				
			||||||
		buf := make([]uint8, 16)
 | 
							buf := bytes.Buffer{}
 | 
				
			||||||
		p.EncodeInto(&buf)
 | 
							p.Encode(&buf)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func BenchmarkDecode(b *testing.B) {
 | 
					func BenchmarkDecodeBufferPool(b *testing.B) {
 | 
				
			||||||
	p := &PDU_HEADER{}
 | 
						p := &PDU_HEADER{}
 | 
				
			||||||
	data := []uint8{0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3}
 | 
					 | 
				
			||||||
	b.ResetTimer()
 | 
						b.ResetTimer()
 | 
				
			||||||
	for i := 0; i < b.N; i++ {
 | 
						for i := 0; i < b.N; i++ {
 | 
				
			||||||
		p.Decode(data)
 | 
							data := []byte{0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 2, 0, 0, 0, 3}
 | 
				
			||||||
 | 
							buf := ByteBufferPool.Get(len(data))
 | 
				
			||||||
 | 
							buf.Write(data)
 | 
				
			||||||
 | 
							p.Decode(buf)
 | 
				
			||||||
 | 
							ByteBufferPool.Put(buf)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										168
									
								
								pdu/submit.go
									
									
									
									
									
								
							
							
						
						
									
										168
									
								
								pdu/submit.go
									
									
									
									
									
								
							@@ -1,104 +1,162 @@
 | 
				
			|||||||
package pdu
 | 
					package pdu
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import "fmt"
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
 | 
						"encoding/ascii85"
 | 
				
			||||||
 | 
						"encoding/binary"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"log"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/warthog618/sms/encoding/gsm7"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type (
 | 
					type (
 | 
				
			||||||
	SUBMIT_SM struct {
 | 
						SUBMIT_SM struct {
 | 
				
			||||||
		header                 PDU_HEADER
 | 
							header                 *PDU_HEADER
 | 
				
			||||||
		service_type           string
 | 
							service_type           string
 | 
				
			||||||
		source_addr_ton        uint8
 | 
							source_addr_ton        byte
 | 
				
			||||||
		source_addr_npi        uint8
 | 
							source_addr_npi        byte
 | 
				
			||||||
		source_addr            string
 | 
							source_addr            string
 | 
				
			||||||
		dest_addr_ton          uint8
 | 
							dest_addr_ton          byte
 | 
				
			||||||
		dest_addr_npi          uint8
 | 
							dest_addr_npi          byte
 | 
				
			||||||
		destination_addr       string
 | 
							destination_addr       string
 | 
				
			||||||
		esm_class              uint8
 | 
							esm_class              byte
 | 
				
			||||||
		protocol_id            uint8
 | 
							protocol_id            byte
 | 
				
			||||||
		priority_flag          uint8
 | 
							priority_flag          byte
 | 
				
			||||||
		schedule_delivery_time string
 | 
							schedule_delivery_time string
 | 
				
			||||||
		validity_period        string
 | 
							validity_period        string
 | 
				
			||||||
		registered_delivery    uint8
 | 
							registered_delivery    byte
 | 
				
			||||||
		replace_if_present     uint8
 | 
							replace_if_present     byte
 | 
				
			||||||
		data_coding            uint8
 | 
							data_coding            byte
 | 
				
			||||||
		sm_default_msg_id      uint8
 | 
							sm_default_msg_id      byte
 | 
				
			||||||
		sm_length              uint8
 | 
							sm_length              byte
 | 
				
			||||||
		short_message          string
 | 
							short_message          string
 | 
				
			||||||
		// user_message_reference uint16
 | 
							// user_message_reference uint16
 | 
				
			||||||
		// source_port               uint16
 | 
							// source_port               uint16
 | 
				
			||||||
		// source_addr_subunit       uint8
 | 
							// source_addr_subunit       byte
 | 
				
			||||||
		// destination_port          uint16
 | 
							// destination_port          uint16
 | 
				
			||||||
		// dest_addr_subunit         uint8
 | 
							// dest_addr_subunit         byte
 | 
				
			||||||
		// sar_msg_ref_num           uint16
 | 
							// sar_msg_ref_num           uint16
 | 
				
			||||||
		// sar_total_segments        uint8
 | 
							// sar_total_segments        byte
 | 
				
			||||||
		// sar_segment_seqnum        uint8
 | 
							// sar_segment_seqnum        byte
 | 
				
			||||||
		// more_messages_to_send     uint8
 | 
							// more_messages_to_send     byte
 | 
				
			||||||
		// payload_type              uint8
 | 
							// payload_type              byte
 | 
				
			||||||
		// message_payload           string
 | 
							// message_payload           string
 | 
				
			||||||
		// privacy_indicator         uint8
 | 
							// privacy_indicator         byte
 | 
				
			||||||
		// callback_num              string
 | 
							// callback_num              string
 | 
				
			||||||
		// callback_num_pres         uint8
 | 
							// callback_num_pres         byte
 | 
				
			||||||
		// callback_num_atag         string
 | 
							// callback_num_atag         string
 | 
				
			||||||
		// source_subaddress         string
 | 
							// source_subaddress         string
 | 
				
			||||||
		// dest_subaddress           string
 | 
							// dest_subaddress           string
 | 
				
			||||||
		// user_response_code        uint8
 | 
							// user_response_code        byte
 | 
				
			||||||
		// display_time              uint8
 | 
							// display_time              byte
 | 
				
			||||||
		// sms_signal                uint8
 | 
							// sms_signal                byte
 | 
				
			||||||
		// ms_validity               uint8
 | 
							// ms_validity               byte
 | 
				
			||||||
		// ms_msg_wait_facilities    uint8
 | 
							// ms_msg_wait_facilities    byte
 | 
				
			||||||
		// number_of_messages        uint8
 | 
							// number_of_messages        byte
 | 
				
			||||||
		// alert_on_message_delivery uint8
 | 
							// alert_on_message_delivery byte
 | 
				
			||||||
		// language_indicator        uint8
 | 
							// language_indicator        byte
 | 
				
			||||||
		// its_reply_type            uint8
 | 
							// its_reply_type            byte
 | 
				
			||||||
		// its_session_info          uint8
 | 
							// its_session_info          byte
 | 
				
			||||||
		// ussd_service_op           uint8
 | 
							// ussd_service_op           byte
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	SUBMIT_SM_RESP struct {
 | 
						SUBMIT_SM_RESP struct {
 | 
				
			||||||
		header     PDU_HEADER
 | 
							header     *PDU_HEADER
 | 
				
			||||||
		message_id string
 | 
							message_id string
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	SUBMIT_MULTI      struct{}
 | 
						SUBMIT_MULTI      struct{}
 | 
				
			||||||
	SUBMIT_MULTI_RESP struct{}
 | 
						SUBMIT_MULTI_RESP struct{}
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (p *SUBMIT_SM) Encode() (*[]byte, error) {
 | 
					func (p *SUBMIT_SM) Encode(buf *bytes.Buffer) 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 {
 | 
						if buf == nil {
 | 
				
			||||||
		return fmt.Errorf("cannot encode SUBMIT_SM, buffer is nil")
 | 
							return fmt.Errorf("cannot encode into nil buffer")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if len(*buf) < int(p.Size()) {
 | 
						// This won't do...
 | 
				
			||||||
		return fmt.Errorf("cannot encode SUBMIT_SM, buffer too small (%d, required %d)", len(*buf), p.Size())
 | 
						// TODO: Implement your own encoders and shit
 | 
				
			||||||
 | 
						// ASCII is easy
 | 
				
			||||||
 | 
						// UCS2 should also be fairly easy, use uint16 or something
 | 
				
			||||||
 | 
						// GSM7 will not be easy
 | 
				
			||||||
 | 
						// See https://www.codeproject.com/Tips/470755/Encoding-Decoding-7-bit-User-Data-for-SMS-PDU-PDU
 | 
				
			||||||
 | 
						asciiEncoder := ascii85.NewEncoder(buf)
 | 
				
			||||||
 | 
						// TODO: Implement encodings bsed on p.data_coding
 | 
				
			||||||
 | 
						messageEncoder := gsm7.NewEncoder()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p.header.Encode(buf)
 | 
				
			||||||
 | 
						n, err := asciiEncoder.Write([]byte("OOO"))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						log.Println(n)
 | 
				
			||||||
	p.header.EncodeInto(buf)
 | 
						// asciiEncoder.Write([]byte(p.service_type))
 | 
				
			||||||
 | 
						buf.Write(NULL_ARR)
 | 
				
			||||||
 | 
						binary.Write(buf, binary.BigEndian, p.source_addr_ton)
 | 
				
			||||||
 | 
						binary.Write(buf, binary.BigEndian, p.source_addr_npi)
 | 
				
			||||||
 | 
						asciiEncoder.Write([]byte(p.source_addr))
 | 
				
			||||||
 | 
						buf.Write(NULL_ARR)
 | 
				
			||||||
 | 
						binary.Write(buf, binary.BigEndian, p.dest_addr_ton)
 | 
				
			||||||
 | 
						binary.Write(buf, binary.BigEndian, p.dest_addr_npi)
 | 
				
			||||||
 | 
						asciiEncoder.Write([]byte(p.destination_addr))
 | 
				
			||||||
 | 
						buf.Write(NULL_ARR)
 | 
				
			||||||
 | 
						binary.Write(buf, binary.BigEndian, p.esm_class)
 | 
				
			||||||
 | 
						binary.Write(buf, binary.BigEndian, p.protocol_id)
 | 
				
			||||||
 | 
						binary.Write(buf, binary.BigEndian, p.priority_flag)
 | 
				
			||||||
 | 
						asciiEncoder.Write([]byte(p.schedule_delivery_time))
 | 
				
			||||||
 | 
						buf.Write(NULL_ARR)
 | 
				
			||||||
 | 
						asciiEncoder.Write([]byte(p.validity_period))
 | 
				
			||||||
 | 
						buf.Write(NULL_ARR)
 | 
				
			||||||
 | 
						binary.Write(buf, binary.BigEndian, p.registered_delivery)
 | 
				
			||||||
 | 
						binary.Write(buf, binary.BigEndian, p.replace_if_present)
 | 
				
			||||||
 | 
						binary.Write(buf, binary.BigEndian, p.data_coding)
 | 
				
			||||||
 | 
						binary.Write(buf, binary.BigEndian, p.sm_default_msg_id)
 | 
				
			||||||
 | 
						binary.Write(buf, binary.BigEndian, p.sm_length)
 | 
				
			||||||
 | 
						encodedMsg, err := messageEncoder.Encode([]byte(p.short_message))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						buf.Write(encodedMsg)
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (p *SUBMIT_SM) Decode(data []byte) {
 | 
					func (p *SUBMIT_SM) Decode(buf *bytes.Buffer) error {
 | 
				
			||||||
 | 
						if buf == nil {
 | 
				
			||||||
 | 
							return fmt.Errorf("cannot decode nil buffer")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
func (p *SUBMIT_SM) Size() uint32 {
 | 
					func (p *SUBMIT_SM) Size() int {
 | 
				
			||||||
	var size uint32
 | 
						var size int
 | 
				
			||||||
	size += p.header.Size()
 | 
						size += p.header.Size()
 | 
				
			||||||
	size += uint32(len(p.service_type) * 1)
 | 
						size += 1 + len(p.service_type)
 | 
				
			||||||
	size += 1 // source_addr_ton
 | 
						size += 1 // source_addr_ton
 | 
				
			||||||
	size += 1 // source_addr_npi
 | 
						size += 1 // source_addr_npi
 | 
				
			||||||
	size += uint32(len(p.source_addr) * 1)
 | 
						size += 1 + len(p.source_addr)
 | 
				
			||||||
	size += 1 // dest_addr_ton
 | 
						size += 1 // dest_addr_ton
 | 
				
			||||||
	size += 1 // dest_addr_npi
 | 
						size += 1 // dest_addr_npi
 | 
				
			||||||
	size += uint32(len(p.destination_addr) * 1)
 | 
						size += 1 + len(p.destination_addr)
 | 
				
			||||||
	size += 1 // esm_class
 | 
						size += 1 // esm_class
 | 
				
			||||||
	size += 1 // protocol_id
 | 
						size += 1 // protocol_id
 | 
				
			||||||
	size += 1 // priority_flag
 | 
						size += 1 // priority_flag
 | 
				
			||||||
	size += uint32(len(p.schedule_delivery_time) * 1)
 | 
						size += 1 + len(p.schedule_delivery_time)
 | 
				
			||||||
	size += uint32(len(p.validity_period) * 1)
 | 
						size += 1 + len(p.validity_period)
 | 
				
			||||||
	size += 1 // registered_delivery
 | 
						size += 1 // registered_delivery
 | 
				
			||||||
	size += 1 // replace_if_present
 | 
						size += 1 // replace_if_present
 | 
				
			||||||
	size += 1 // data_coding
 | 
						size += 1 // data_coding
 | 
				
			||||||
	size += 1 // sm_default_msg_id
 | 
						size += 1 // sm_default_msg_id
 | 
				
			||||||
	size += 1 // sm_length
 | 
						size += 1 // sm_length
 | 
				
			||||||
	size += uint32(len(p.short_message) * 1)
 | 
						// TODO: Handle encoding based on p.data_coding
 | 
				
			||||||
 | 
						switch p.data_coding {
 | 
				
			||||||
 | 
						case 0b00000000: // GSM7
 | 
				
			||||||
 | 
							size += (len(p.short_message)*7 + 8 - 1) / 8
 | 
				
			||||||
 | 
						case 0b00000001: // ASCII
 | 
				
			||||||
 | 
							size += len(p.short_message)
 | 
				
			||||||
 | 
						case 0b00000011: // LATIN1
 | 
				
			||||||
 | 
							size += len(p.short_message)
 | 
				
			||||||
 | 
						case 0b00001000: // UCS2
 | 
				
			||||||
 | 
							size += len(p.short_message) * 2
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	return size
 | 
						return size
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					func (p *SUBMIT_SM) UpdateSize() {
 | 
				
			||||||
 | 
						p.header.command_length = uint32(p.Size())
 | 
				
			||||||
 | 
						p.sm_length = byte(len(p.short_message))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,72 @@
 | 
				
			|||||||
package pdu
 | 
					package pdu
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
	"testing"
 | 
						"testing"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// region encode
 | 
				
			||||||
 | 
					// See examples: https://www.openmarket.com/docs/Content/apis/v4smpp/mt-examples.htm
 | 
				
			||||||
 | 
					func TestEncodeFunctionCorrectlyEncodesAllFields(t *testing.T) {
 | 
				
			||||||
 | 
						p := &SUBMIT_SM{
 | 
				
			||||||
 | 
							header: &PDU_HEADER{
 | 
				
			||||||
 | 
								command_length:  0,
 | 
				
			||||||
 | 
								command_id:      4,
 | 
				
			||||||
 | 
								command_status:  0,
 | 
				
			||||||
 | 
								sequence_number: 378019,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							service_type:           "OMV4",
 | 
				
			||||||
 | 
							source_addr_ton:        3,
 | 
				
			||||||
 | 
							source_addr_npi:        1,
 | 
				
			||||||
 | 
							source_addr:            "80362",
 | 
				
			||||||
 | 
							dest_addr_ton:          1,
 | 
				
			||||||
 | 
							dest_addr_npi:          1,
 | 
				
			||||||
 | 
							destination_addr:       "812345001000",
 | 
				
			||||||
 | 
							esm_class:              0,
 | 
				
			||||||
 | 
							protocol_id:            0,
 | 
				
			||||||
 | 
							priority_flag:          0,
 | 
				
			||||||
 | 
							schedule_delivery_time: "",
 | 
				
			||||||
 | 
							validity_period:        "180105120000004+",
 | 
				
			||||||
 | 
							registered_delivery:    1,
 | 
				
			||||||
 | 
							data_coding:            1, // The example uses 0 and claims to use GSM but the message is encoded as ASCII...
 | 
				
			||||||
 | 
							sm_default_msg_id:      0,
 | 
				
			||||||
 | 
							short_message:          "Reply Yes to opt in or No to opt out.",
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						p.UpdateSize()
 | 
				
			||||||
 | 
						buf := ByteBufferPool.Get(p.Size())
 | 
				
			||||||
 | 
						err := p.Encode(buf)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							t.Fatalf("expected no error, got %v", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						expected := []byte{0,0,0,107,0,0,0,4,0,0,0,0,0,5,196,163,79,77,86,52,0,3,1,56,48,51,54,50,0,1,1,56,49,50,51,52,53,48,48,49,48,48,48,0,0,0,0,0,49,56,48,49,48,53,49,50,48,48,48,48,48,48,52,43,0,1,0,0,0,37,82,101,112,108,121,32,89,101,115,32,116,111,32,111,112,116,32,105,110,32,111,114,32,78,111,32,116,111,32,111,112,116,32,111,117,116,46}
 | 
				
			||||||
 | 
						if !bytes.Equal(buf.Bytes(), expected) {
 | 
				
			||||||
 | 
							t.Fatalf("expected %v, got %v", expected, buf.Bytes())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// func TestRealScenario(t *testing.T) {
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// 	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
 | 
				
			||||||
 | 
					// 		}
 | 
				
			||||||
 | 
					// 	}
 | 
				
			||||||
 | 
					// }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// region decode
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// region size
 | 
					// region size
 | 
				
			||||||
func TestCalculateSizeTypicalInstance(t *testing.T) {
 | 
					func TestCalculateSizeTypicalInstance(t *testing.T) {
 | 
				
			||||||
	p := &SUBMIT_SM{
 | 
						p := &SUBMIT_SM{
 | 
				
			||||||
@@ -14,7 +77,7 @@ func TestCalculateSizeTypicalInstance(t *testing.T) {
 | 
				
			|||||||
		validity_period:        "",
 | 
							validity_period:        "",
 | 
				
			||||||
		short_message:          "Hello, World!",
 | 
							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()
 | 
						actualSize := p.Size()
 | 
				
			||||||
	if actualSize != expectedSize {
 | 
						if actualSize != expectedSize {
 | 
				
			||||||
		t.Errorf("Expected size %d, but got %d", expectedSize, actualSize)
 | 
							t.Errorf("Expected size %d, but got %d", expectedSize, actualSize)
 | 
				
			||||||
@@ -31,7 +94,7 @@ func TestCalculateSizeMaxLengths(t *testing.T) {
 | 
				
			|||||||
		validity_period:        string(make([]byte, maxLen)),
 | 
							validity_period:        string(make([]byte, maxLen)),
 | 
				
			||||||
		short_message:          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()
 | 
						actualSize := p.Size()
 | 
				
			||||||
	if actualSize != expectedSize {
 | 
						if actualSize != expectedSize {
 | 
				
			||||||
		t.Errorf("Expected size %d, but got %d", expectedSize, actualSize)
 | 
							t.Errorf("Expected size %d, but got %d", expectedSize, actualSize)
 | 
				
			||||||
@@ -47,9 +110,11 @@ func TestHandlesEmptyStringsForAllStringFields(t *testing.T) {
 | 
				
			|||||||
		validity_period:        "",
 | 
							validity_period:        "",
 | 
				
			||||||
		short_message:          "",
 | 
							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()
 | 
						actualSize := p.Size()
 | 
				
			||||||
	if actualSize != expectedSize {
 | 
						if actualSize != expectedSize {
 | 
				
			||||||
		t.Errorf("Expected size %d, but got %d", expectedSize, actualSize)
 | 
							t.Errorf("Expected size %d, but got %d", expectedSize, actualSize)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// region benchmark
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user