decode/reader.go   A
last analyzed

Size/Duplication

Total Lines 118
Duplicated Lines 0 %

Test Coverage

Coverage 87.04%

Importance

Changes 0
Metric Value
cc 22
eloc 77
dl 0
loc 118
ccs 47
cts 54
cp 0.8704
crap 23.0535
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A decode.readType 0 9 2
A decode.isStorageContainer 0 2 1
A decode.readSize 0 30 4
F decode.readValue 0 60 15
1
package decode
2
3
import (
4
	"fmt"
5
	"io"
6
7
	"github.com/et-nik/binngo/binn"
8
	"github.com/et-nik/binngo/encode"
9
)
10
11
//nolint:funlen
12
func readValue(btype binn.Type, reader io.Reader) ([]byte, error) {
13 1
	tp := btype &^ binn.StorageTypeMask
14
15 1
	var readingSize int
16 1
	var containerSize int
17
18 1
	var bytes []byte
19
20 1
	switch tp {
21
	case binn.StorageNoBytes:
22 1
		readingSize = 0
23
	case binn.StorageByte:
24 1
		readingSize = 1
25
	case binn.StorageWord:
26 1
		readingSize = 2
27
	case binn.StorageDWord:
28 1
		readingSize = 4
29
	case binn.StorageQWord:
30 1
		readingSize = 8
31
	case binn.StorageString:
32 1
		dataSize, _, err := readSize(reader)
33 1
		if err != nil {
34
			return nil, fmt.Errorf("failed to read string storage size: %w", err)
35
		}
36 1
		readingSize = dataSize + 1 // data size and null terminator
37
	case binn.StorageBlob:
38 1
		dataSize, _, err := readSize(reader)
39 1
		if err != nil {
40
			return nil, fmt.Errorf("failed to read string storage size: %w", err)
41
		}
42 1
		readingSize = dataSize
43
	case binn.StorageContainer:
44 1
		s, l, err := readSize(reader)
45 1
		if err != nil {
46
			return nil, fmt.Errorf("failed to read storage size: %w", err)
47
		}
48
49 1
		containerSize = s
50
51 1
		bytes = append(bytes, encode.Size(s, false)...)
52
53 1
		readingSize = containerSize - 1 - int(l) // minus container type byte and size byte
54
	default:
55
		return nil, ErrUnknownType
56
	}
57
58 1
	if readingSize == 0 {
59 1
		return []byte{byte(btype)}, nil
60
	}
61
62 1
	b := make([]byte, readingSize)
63
64 1
	_, err := reader.Read(b)
65 1
	bytes = append(bytes, b...)
66
67 1
	if err != nil {
68
		return nil, fmt.Errorf("failed to read storage: %w", err)
69
	}
70
71 1
	return bytes, nil
72
}
73
74
func isStorageContainer(btype binn.Type) bool {
75 1
	return (btype &^ binn.StorageTypeMask) == binn.StorageContainer
76
}
77
78
func readType(reader io.Reader) (binn.Type, readLen, error) {
79 1
	var bt = make([]byte, 1)
80
81 1
	_, err := reader.Read(bt)
82 1
	if err != nil {
83 1
		return binn.Null, 0, &FailedToReadTypeError{Previous: err}
84
	}
85
86 1
	return Type(bt), 1, nil
87
}
88
89
func readSize(reader io.Reader) (int, readLen, error) {
90 1
	var bsz = make([]byte, 1)
91 1
	_, err := reader.Read(bsz)
92 1
	if err != nil {
93
		return 0, 0, &FailedToReadSizeError{err}
94
	}
95
96 1
	read := 1
97
98 1
	sz := int(Uint8(bsz))
99
100 1
	if sz > maxOneByteSize {
101 1
		var bszOtherBytes = make([]byte, 3)
102 1
		_, err := reader.Read(bszOtherBytes)
103 1
		if err != nil {
104
			return 0, 0, fmt.Errorf("failed to read long size: %w", err)
105
		}
106 1
		read += 3
107
108 1
		sz = int(Uint32([]byte{
109
			byte(sz),
110
			bszOtherBytes[0],
111
			bszOtherBytes[1],
112
			bszOtherBytes[2],
113
		}))
114
115 1
		sz &= 0x7FFFFFFF
116
	}
117
118 1
	return sz, readLen(read), nil
119
}
120