stream.monkey2 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  1. Namespace std.stream
  2. Using libc
  3. Using std.memory
  4. Using std.collections
  5. #rem monkeydoc Stream class.
  6. #end
  7. Class Stream
  8. #rem monkeydoc True if no more data can be read from the stream.
  9. #end
  10. Property Eof:Bool() Abstract
  11. #rem monkeydoc Current stream position.
  12. In the case of non-seekable streams, `Position` will always be -1.
  13. #end
  14. Property Position:Int() Abstract
  15. #rem monkeydoc Current stream length.
  16. In the case of non-seekable streams, `Length` is the number of bytes that can be read from the stream without 'blocking'.
  17. #end
  18. Property Length:Int() Abstract
  19. #rem monkeydoc Closes the stream.
  20. #end
  21. Method Close:Void() Abstract
  22. #rem monkeydoc Seeks to a position in the stream.
  23. In debug builds, a runtime error will occur if the stream is not seekable or `position` is out of range.
  24. @param position The position to seek to.
  25. #end
  26. Method Seek( position:Int ) Abstract
  27. #rem monkeydoc Reads data from the filestream to memory.
  28. @param mem A pointer to the memory to read the data into.
  29. @param count The number of bytes to read.
  30. @return The number of bytes actually read.
  31. #end
  32. Method Read:Int( mem:Void Ptr,count:Int ) Abstract
  33. #rem monkeydoc Writes data to the stream from memory.
  34. @param mem A pointer to the memory to write the data from.
  35. @param count The number of bytes to write.
  36. @return The number of bytes actually written.
  37. #end
  38. Method Write:Int( mem:Void Ptr,count:Int ) Abstract
  39. #rem monkeydoc Reads data from the filestream and throws it away.
  40. @param count The number of bytes to skip.
  41. @return The number of bytes actually skipped.
  42. #end
  43. Method Skip:Int( count:Int )
  44. Local tmp:=libc.malloc( count )
  45. Local n:=Read( tmp,count )
  46. libc.free( tmp )
  47. Return n
  48. End
  49. #rem monkeydoc The byte order of the stream.
  50. #end
  51. Property ByteOrder:ByteOrder()
  52. Return _tmpbuf.ByteOrder
  53. Setter( byteOrder:ByteOrder )
  54. _tmpbuf.ByteOrder=byteOrder
  55. End
  56. #rem monkeydoc Reads data from the stream into a databuffer.
  57. @param buf The databuffer to read the data into.
  58. @param offset The start offset in the databuffer.
  59. @param count The number of bytes to transfer.
  60. @return The number of bytes actually read.
  61. #end
  62. Method Read:Int( buf:DataBuffer,offset:Int,count:Int )
  63. DebugAssert( offset>=0 And count>=0 And offset+count<=buf.Length )
  64. Return Read( buf.Data+offset,count )
  65. End
  66. #rem monkeydoc Writes data to a stream from a databuffer.
  67. @param buf The databuffer to write the data from.
  68. @param offset The start offset in the databuffer.
  69. @param count The number of bytes to transfer.
  70. @return The number of bytes actually written.
  71. #end
  72. Method Write:Int( buf:DataBuffer,offset:Int,count:Int )
  73. DebugAssert( offset>=0 And count>=0 And offset+count<=buf.Length )
  74. Return Write( buf.Data+offset,count )
  75. End
  76. #rem monkeydoc Reads a byte from the stream.
  77. @return The byte read.
  78. #end
  79. Method ReadByte:Byte()
  80. If Read( _tmpbuf.Data,1 )=1 Return _tmpbuf.PeekByte( 0 )
  81. Return 0
  82. End
  83. #rem monkeydoc Reads an unsigned byte from the stream.
  84. @return The ubyte read.
  85. #end
  86. Method ReadUByte:UByte()
  87. If Read( _tmpbuf.Data,1 )=1 Return _tmpbuf.PeekUByte( 0 )
  88. Return 0
  89. End
  90. #rem monkeydoc Reads a 16 bit short from the stream.
  91. @return The short read.
  92. #end
  93. Method ReadShort:Short()
  94. If Read( _tmpbuf.Data,2 )=2 Return _tmpbuf.PeekShort( 0 )
  95. Return 0
  96. End
  97. #rem monkeydoc Reads a 16 bit unsigned short from the stream.
  98. @return The ushort read.
  99. #end
  100. Method ReadUShort:UShort()
  101. If Read( _tmpbuf.Data,2 )=2 Return _tmpbuf.PeekUShort( 0 )
  102. Return 0
  103. End
  104. #rem monkeydoc Reads a 32 bit int from the stream.
  105. @return The int read.
  106. #end
  107. Method ReadInt:Int()
  108. If Read( _tmpbuf.Data,4 )=4 Return _tmpbuf.PeekInt( 0 )
  109. Return 0
  110. End
  111. #rem monkeydoc Reads a 32 bit unsigned int from the stream.
  112. @return The uint read.
  113. #end
  114. Method ReadUInt:UInt()
  115. If Read( _tmpbuf.Data,4 )=4 Return _tmpbuf.PeekUInt( 0 )
  116. Return 0
  117. End
  118. #rem monkeydoc Reads a 32 bit long from the stream.
  119. @return The long read.
  120. #end
  121. Method ReadLong:Long()
  122. If Read( _tmpbuf.Data,8 )=8 Return _tmpbuf.PeekLong( 0 )
  123. Return 0
  124. End
  125. #rem monkeydoc Reads a 32 bit unsigned long from the stream.
  126. @return The ulong read.
  127. #end
  128. Method ReadULong:ULong()
  129. If Read( _tmpbuf.Data,8 )=8 Return _tmpbuf.PeekULong( 0 )
  130. Return 0
  131. End
  132. #rem monkeydoc Reads a 32 bit float from the stream.
  133. @return The float read.
  134. #end
  135. Method ReadFloat:Float()
  136. If Read( _tmpbuf.Data,4 )=4 Return _tmpbuf.PeekFloat( 0 )
  137. Return 0
  138. End
  139. #rem monkeydoc Reads a 64 bit double from the stream.
  140. @return The double read.
  141. #end
  142. Method ReadDouble:Double()
  143. If Read( _tmpbuf.Data,8 )=8 Return _tmpbuf.PeekDouble( 0 )
  144. Return 0
  145. End
  146. #rem monkeydoc Reads a null terminated cstring from the stream
  147. @return the string read.
  148. #end
  149. Method ReadCString:String()
  150. Local buf:=New Stack<Byte>
  151. While Not Eof
  152. Local chr:=ReadByte()
  153. If Not chr Exit
  154. buf.Push( chr )
  155. Wend
  156. buf.Push( 0 )
  157. Return String.FromCString( buf.Data.Data )
  158. End
  159. #rem monkeydoc Writes a byte to the stream.
  160. @param data The byte to write.
  161. #end
  162. Method WriteByte( data:Byte )
  163. _tmpbuf.PokeByte( 0,data )
  164. Write( _tmpbuf.Data,1 )
  165. End
  166. #rem monkeydoc Write an unsigned byte to the stream.
  167. @param data The ubyte to write.
  168. #end
  169. Method WriteUByte( data:UByte )
  170. _tmpbuf.PokeUByte( 0,data )
  171. Write( _tmpbuf.Data,1 )
  172. End
  173. #rem monkeydoc Writes a 16 bit short to the stream.
  174. @param data The short to write.
  175. #end
  176. Method WriteShort( data:Short )
  177. _tmpbuf.PokeShort( 0,data )
  178. Write( _tmpbuf.Data,2 )
  179. End
  180. #rem monkeydoc Writes a 16 bit unsigned short to the stream.
  181. @param data The ushort to write.
  182. #end
  183. Method WriteUShort( data:UShort )
  184. _tmpbuf.PokeUShort( 0,data )
  185. Write( _tmpbuf.Data,2 )
  186. End
  187. #rem monkeydoc Writes a 32 bit int to the stream.
  188. @param data The int to write.
  189. #end
  190. Method WriteInt( data:Int )
  191. _tmpbuf.PokeInt( 0,data )
  192. Write( _tmpbuf.Data,4 )
  193. End
  194. #rem monkeydoc Writes a 32 bit unsigned int to the stream.
  195. @param data The uint to write.
  196. #end
  197. Method WriteUInt( data:UInt )
  198. _tmpbuf.PokeUInt( 0,data )
  199. Write( _tmpbuf.Data,4 )
  200. End
  201. #rem monkeydoc Writes a 64 bit long to the stream.
  202. @param data The long to write.
  203. #end
  204. Method WriteLong( data:Long )
  205. _tmpbuf.PokeLong( 0,data )
  206. Write( _tmpbuf.Data,8 )
  207. End
  208. #rem monkeydoc Writes a 64 bit unsigned long to the stream.
  209. @param data The ulong to write.
  210. #end
  211. Method WriteULong( data:ULong )
  212. _tmpbuf.PokeULong( 0,data )
  213. Write( _tmpbuf.Data,8 )
  214. End
  215. #rem monkeydoc Writes a 32 bit float to the stream,
  216. @param data The float to write.
  217. #end
  218. Method WriteFloat:Void( data:Float )
  219. _tmpbuf.PokeFloat( 0,data )
  220. Write( _tmpbuf.Data,4 )
  221. End
  222. #rem monkeydoc Writes a 64 bit double to the stream.
  223. @param data The double to write.
  224. #end
  225. Method WriteDouble( data:Double )
  226. _tmpbuf.PokeDouble( 0,data )
  227. Write( _tmpbuf.Data,8 )
  228. End
  229. #rem monkeydoc Write a nullterminated CString to the stream.
  230. @param data The string to write.
  231. #end
  232. Method WriteCString:Void( data:String )
  233. Local buf:=New Stack<UByte>
  234. buf.Resize( data.Length+1 )
  235. For Local i:=0 Until data.Length
  236. buf[i]=data[i]
  237. Next
  238. buf[ data.Length ]=0
  239. Write( buf.Data.Data,buf.Length )
  240. End
  241. #rem monkeydoc Opens a stream
  242. `mode` should be "r" for read, "w" for write or "rw" for read/write.
  243. @param mode The mode to open the stream in: "r", "w" or "rw"
  244. #end
  245. Function Open:Stream( path:String,mode:String )
  246. Local i:=path.Find( "::" )
  247. If i=-1 Return FileStream.Open( path,mode )
  248. Local proto:=path.Slice( 0,i )
  249. Local ipath:=path.Slice( i+2 )
  250. Return OpenFuncs[proto]( proto,ipath,mode )
  251. End
  252. #rem monkeydoc @hidden
  253. #end
  254. Alias OpenFunc:Stream( proto:String,path:String,mode:String )
  255. #rem monkeydoc @hidden
  256. #end
  257. Const OpenFuncs:=New StringMap<OpenFunc>
  258. Private
  259. Field _tmpbuf:=New DataBuffer( 8 )
  260. End