-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathstructure.go
66 lines (56 loc) · 1.59 KB
/
structure.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
package arclib
import (
"encoding/binary"
)
type arcHeader struct {
// The magic value 0x55AA382D. See ARCHeader.
Magic uint32
// RootNodeOffset is the offset from the start of the file to the first
// entry - as the header is always 32 bytes/0x20 in size, it is always
// 32 bytes/0x20.
RootNodeOffset uint32
// HeaderSize is the size of all records and the strings table.
HeaderSize uint32
// DataOffset is RootNodeOffset + HeaderSize + alignment to 64 bytes/0x40.
DataOffset uint32
// Padding
_ [16]byte
}
type arcNode struct {
Type ARCType
NameOffset [3]byte
DataOffset uint32
Size uint32
}
type ARCType uint8
const (
File ARCType = iota
Directory
)
// name returns the name as specified with offsets specified by the node.
// It reads from the specified string table.
func (a *arcNode) name(table []byte) string {
// Nintendo gives us 3 bytes, a "uint24" if you will.
// Alright then... we need to normalize this.
// The Wii uses big-endian throughout every possible corner.
// This means that we can safely convert this to a uint32
// by inserting a null byte in front.
offset := a.NameOffset
posByte := []byte{0x00, offset[0], offset[1], offset[2]}
pos := binary.BigEndian.Uint32(posByte)
// Now that we have this position, we can read in from this
// position to the first null byte.
// I believe Nintendo uses strcpy to achieve this in C.
var tmp []byte
for {
current := table[pos : pos+1][0]
if current == 0x00 {
// We completed our string!
break
}
// Add this current byte to our array.
tmp = append(tmp, current)
pos++
}
return string(tmp)
}