forked from linxGnu/gosmpp
/
Buffer.go
134 lines (111 loc) · 2.74 KB
/
Buffer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package pdu
import (
"bytes"
"encoding/binary"
"fmt"
"github.com/JorgenPo/gosmpp/data"
)
const (
// SizeByte is size of byte.
SizeByte = 1
// SizeShort is size of short.
SizeShort = 2
// SizeInt is size of int.
SizeInt = 4
// SizeLong is size of long.
SizeLong = 8
)
var (
// ErrBufferNotEnoughByteToRead indicates not enough byte(s) to read from buffer.
ErrBufferNotEnoughByteToRead = fmt.Errorf("Not enough byte to read from buffer")
endianese = binary.BigEndian
)
// ByteBuffer wraps over bytes.Buffer with additional features.
type ByteBuffer struct {
*bytes.Buffer
}
// NewBuffer create new buffer from preallocated buffer array.
func NewBuffer(inp []byte) *ByteBuffer {
if inp == nil {
inp = make([]byte, 0, 512)
}
return &ByteBuffer{Buffer: bytes.NewBuffer(inp)}
}
// ReadN read n-bytes from buffer.
func (c *ByteBuffer) ReadN(n int) (r []byte, err error) {
if n > 0 {
if c.Len() >= n { // optimistic branching
r = make([]byte, n)
_, _ = c.Read(r)
} else {
err = ErrBufferNotEnoughByteToRead
}
}
return
}
// ReadShort reads short from buffer.
func (c *ByteBuffer) ReadShort() (r int16, err error) {
v, err := c.ReadN(SizeShort)
if err == nil {
r = int16(endianese.Uint16(v))
}
return
}
// WriteShort writes short to buffer.
func (c *ByteBuffer) WriteShort(v int16) {
var b [SizeShort]byte
endianese.PutUint16(b[:], uint16(v))
_, _ = c.Write(b[:])
}
// ReadInt reads int from buffer.
func (c *ByteBuffer) ReadInt() (r int32, err error) {
v, err := c.ReadN(SizeInt)
if err == nil {
r = int32(endianese.Uint32(v))
}
return
}
// WriteInt writes int to buffer.
func (c *ByteBuffer) WriteInt(v int32) {
var b [SizeInt]byte
endianese.PutUint32(b[:], uint32(v))
_, _ = c.Write(b[:])
}
// WriteBuffer appends buffer.
func (c *ByteBuffer) WriteBuffer(d *ByteBuffer) {
if d != nil {
_, _ = c.Write(d.Bytes())
}
}
func (c *ByteBuffer) writeString(st string, isCString bool, enc data.Encoding) (err error) {
if len(st) > 0 {
var payload []byte
if payload, err = enc.Encode(st); err == nil {
_, _ = c.Write(payload)
}
}
if err == nil && isCString {
_ = c.WriteByte(0)
}
return
}
// WriteCString writes c-string.
func (c *ByteBuffer) WriteCString(s string) error {
return c.writeString(s, true, data.ASCII)
}
// WriteCStringWithEnc write c-string with encoding.
func (c *ByteBuffer) WriteCStringWithEnc(s string, enc data.Encoding) error {
return c.writeString(s, true, enc)
}
// ReadCString read c-string.
func (c *ByteBuffer) ReadCString() (st string, err error) {
buf, err := c.ReadBytes(0)
if err == nil && len(buf) > 0 { // optimistic branching
st = string(buf[:len(buf)-1])
}
return
}
// HexDump returns hex dump.
func (c *ByteBuffer) HexDump() string {
return fmt.Sprintf("%x", c.Buffer.Bytes())
}