Repository navigation
Expand file tree
/
Copy pathintelreader.go
More file actions
65 lines (58 loc) · 1.67 KB
/
Copy pathintelreader.go
File metadata and controls
65 lines (58 loc) · 1.67 KB
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
package lzx
import (
"encoding/binary"
"io"
)
type intelReader struct {
Internal io.Reader
buffer []byte
*persistentData
}
func (i *intelReader) Read(b []byte) (int, error) {
if i.IntelFileSize == 0 || !i.IntelStarted {
n, err := i.Internal.Read(b)
i.IntelCursorPosition += n
return n, err
}
bufferedBytes := copy(b, i.buffer)
i.buffer = i.buffer[bufferedBytes:]
b = b[bufferedBytes:]
n := bufferedBytes
i.IntelCursorPosition += bufferedBytes
if len(b) == 0 {
return n, nil
}
readBytes, err := i.Internal.Read(b)
n += readBytes
for index := 0; index < readBytes; index++ {
readByte := b[index]
if readByte == 0xE8 {
callBytes := make([]byte, 4)
alreadyReadBytecount := copy(callBytes, b[index+1:readBytes])
if alreadyReadBytecount < 4 {
// Need to read extra bytes for conversion
if _, err := io.ReadFull(i.Internal, callBytes[alreadyReadBytecount:]); err != nil {
if err == io.ErrUnexpectedEOF || err == io.EOF { // Not enough bytes; ignore bad call instruction
continue
}
return n, err
}
}
absoluteOffset := int32(binary.LittleEndian.Uint32(callBytes))
if absoluteOffset >= -int32(i.IntelCursorPosition+index) && absoluteOffset < int32(i.IntelFileSize) {
var relativeOffset int32
if absoluteOffset >= 0 {
relativeOffset = absoluteOffset - int32(i.IntelCursorPosition+index)
} else {
relativeOffset = absoluteOffset + int32(i.IntelFileSize)
}
binary.LittleEndian.PutUint32(callBytes, uint32(relativeOffset))
}
copiedBackBytes := copy(b[index+1:readBytes], callBytes)
i.buffer = callBytes[copiedBackBytes:]
index += 4
}
}
i.IntelCursorPosition += readBytes
return n, err
}