-
Notifications
You must be signed in to change notification settings - Fork 2
/
stream.monkey
166 lines (136 loc) · 3.51 KB
/
stream.monkey
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
Import mojo
#if TARGET="ios"
Import "native/stream.${TARGET}.${LANG}"
Extern
Function LoadBinaryString$(file$)="LoadBinaryString"
Public
#else
Function LoadBinaryString$(file$)
Local ret := LoadString(file)
Return ret
End
#end
Class Stream
Global floatChars := ["","0","1","2","3","4","5","6","7","8","9","-",".","e"] '4-bit
Field littleEndian:Bool
Field stream$
Field serializedStream$
Field pos%
Method New()
littleEndian = True
End
Method New(file$)
littleEndian = True
Open(file)
End
Method Open(file$)
pos = 0
stream = LoadBinaryString(file)
End
Method ReadInt%()
Local result$ = stream[pos..pos+4]
pos += 4
If (littleEndian)
Return StringToLittleEndianInt(result)
Else
Return StringToInt(result)
End
End
' WARNING! Only Works with STRING FLOAT Representation
Method ReadFloat#()
Local result#
Local len% = ReadInt()
Local val := ReadString(len)
Return Float(val)
End
Method ReadBool?()
Local result:Bool
result = Bool(stream[pos])
pos+=1
Return result
End
Method Eof?()
Return (pos >= stream.Length)
End
Method ReadLine$()
Local result$ = ""
For Local p% = pos To stream.Length-1
If stream[p] = 13 or stream[p] = 10
result = stream[pos..p+1]
pos = p+1
Return result
End
Next
pos += 1
Return result
End
Method Close:Void()
stream = ""
pos = 0
End
Method Save:Void()
'SaveState(stream)
End
Method ReadString:String(strLen%)
Local result:String
If strLen > 0
result = stream[pos..pos+strLen]
pos+=strLen
End
Return result
End
Method WriteString(s$)
stream += s
serializedStream += "S:" + s + ";"
End
Method WriteBool:String(b?)
stream += String.FromChar(b)
serializedStream += "B:" + Int(b) + ";"
End
Method WriteInt:String(i%)
If (littleEndian)
stream += LittleEndianIntToString(i)
Else
stream += IntToString(i)
End
serializedStream += "I:" + i + ";"
End
Method Seek:Void(p%)
pos = p
End
Method Pos:Int()
Return pos
End
Method LittleEndianIntToString:String(val:Int)
Local result:String
result = String.FromChar((val) & $FF)
result+= String.FromChar((val Shr 8) & $FF)
result+= String.FromChar((val Shr 16) & $FF)
result+= String.FromChar((val Shr 24) & $FF)
Return result
End
Method StringToLittleEndianInt:Int(val:String)
Local result:Int
result = (val[0])
result|= (val[1] Shl 8)
result|= (val[2] Shl 16)
result|= (val[3] Shl 24)
Return result
End
Method IntToString:String(val:Int)
Local result:String
result = String.FromChar((val Shr 24) & $FF)
result+= String.FromChar((val Shr 16) & $FF)
result+= String.FromChar((val Shr 8) & $FF)
result+= String.FromChar(val & $FF)
Return result
End
Method StringToInt:Int(val:String)
Local result:Int
result = (val[0] Shl 24)
result|= (val[1] Shl 16)
result|= (val[2] Shl 8)
result|= val[3]
Return result
End
End