forked from nielsAD/gowarcraft3
/
dwordstring.go
66 lines (58 loc) · 1.59 KB
/
dwordstring.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
// Author: Niels A.D.
// Project: gowarcraft3 (https://github.com/nielsAD/gowarcraft3)
// License: Mozilla Public License, v2.0
package protocol
import (
"errors"
)
// Errors
var (
ErrInvalidDString = errors.New("dwstr: Length of input for DString() exceeds 4")
)
// DWordString is a string of size dword (4 bytes / characters)
type DWordString uint32
// DString converts str to DWordString
// panic if input invalid
func DString(str string) DWordString {
switch len(str) {
case 0:
return DWordString(0)
case 1:
return DWordString(uint32(str[0]))
case 2:
return DWordString(uint32(str[0]) | uint32(str[1])<<8)
case 3:
return DWordString(uint32(str[0]) | uint32(str[1])<<8 | uint32(str[2])<<16)
case 4:
return DWordString(uint32(str[0]) | uint32(str[1])<<8 | uint32(str[2])<<16 | uint32(str[3])<<24)
default:
panic(ErrInvalidDString)
}
}
func (s DWordString) String() string {
if s == 0 {
return ""
}
if s&0xFF000000 != 0 {
return string([]byte{byte(uint32(s)), byte(uint32(s) >> 8), byte(uint32(s) >> 16), byte(uint32(s) >> 24)})
}
if s&0xFF0000 != 0 {
return string([]byte{byte(uint32(s)), byte(uint32(s) >> 8), byte(uint32(s) >> 16)})
}
if s&0xFF00 != 0 {
return string([]byte{byte(uint32(s)), byte(uint32(s) >> 8)})
}
return string([]byte{byte(uint32(s))})
}
// MarshalText implements TextMarshaler
func (s DWordString) MarshalText() ([]byte, error) {
return []byte(s.String()), nil
}
// UnmarshalText implements TextUnmarshaler
func (s *DWordString) UnmarshalText(txt []byte) error {
if len(txt) > 4 {
return ErrInvalidDString
}
*s = DString(string(txt))
return nil
}