summary refs log tree commit diff
path: root/vendor/maunium.net/go/mautrix/crypto/goolm/libolmpickle/unpickle.go
blob: dbd275aa6fb6a3cd7b6f0017309c7d48319d187b (plain)
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
package libolmpickle

import (
	"fmt"

	"maunium.net/go/mautrix/crypto/olm"
)

func isZeroByteSlice(bytes []byte) bool {
	b := byte(0)
	for _, s := range bytes {
		b |= s
	}
	return b == 0
}

func UnpickleUInt8(value []byte) (uint8, int, error) {
	if len(value) < 1 {
		return 0, 0, fmt.Errorf("unpickle uint8: %w", olm.ErrValueTooShort)
	}
	return value[0], 1, nil
}

func UnpickleBool(value []byte) (bool, int, error) {
	if len(value) < 1 {
		return false, 0, fmt.Errorf("unpickle bool: %w", olm.ErrValueTooShort)
	}
	return value[0] != uint8(0x00), 1, nil
}

func UnpickleBytes(value []byte, length int) ([]byte, int, error) {
	if len(value) < length {
		return nil, 0, fmt.Errorf("unpickle bytes: %w", olm.ErrValueTooShort)
	}
	resp := value[:length]
	if isZeroByteSlice(resp) {
		return nil, length, nil
	}
	return resp, length, nil
}

func UnpickleUInt32(value []byte) (uint32, int, error) {
	if len(value) < 4 {
		return 0, 0, fmt.Errorf("unpickle uint32: %w", olm.ErrValueTooShort)
	}
	var res uint32
	count := 0
	for i := 3; i >= 0; i-- {
		res |= uint32(value[count]) << (8 * i)
		count++
	}
	return res, 4, nil
}