filestream.monkey2 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. Namespace std.stream
  2. Using libc
  3. #rem monkeydoc FileStream class.
  4. #end
  5. Class FileStream Extends Stream
  6. #rem monkeydoc True if no more data can be read from the stream.
  7. You can still write to a filestream even if `Eof` is true - disk space permitting!
  8. #end
  9. Property Eof:Bool() Override
  10. Return _pos>=_end
  11. End
  12. #rem monkeydoc Current filestream position.
  13. The current file read/write position.
  14. #end
  15. Property Position:Int() Override
  16. Return _pos
  17. End
  18. #rem monkeydoc Current filestream length.
  19. The length of the filestream. This is the same as the length of the file.
  20. The file length can increase if you write past the end of the file.
  21. #end
  22. Property Length:Int() Override
  23. Return _end
  24. End
  25. #rem monkeydoc Closes the filestream.
  26. Closing the filestream also sets its position and length to 0.
  27. #end
  28. Method OnClose() Override
  29. If Not _file Return
  30. fclose( _file )
  31. _file=Null
  32. _pos=0
  33. _end=0
  34. End
  35. #rem monkeydoc Seeks to a position in the filestream.
  36. @param offset The position to seek to.
  37. #end
  38. Method Seek( position:Int ) Override
  39. DebugAssert( position>=0 And position<=_end )
  40. fseek( _file,position,SEEK_SET )
  41. _pos=position
  42. DebugAssert( ftell( _file )=_pos ) 'Sanity check...
  43. End
  44. #rem monkeydoc Reads data from the filestream.
  45. @param buf A pointer to the memory to read the data into.
  46. @param count The number of bytes to read.
  47. @return The number of bytes actually read.
  48. #end
  49. Method Read:Int( buf:Void Ptr,count:Int ) Override
  50. count=Clamp( count,0,_end-_pos )
  51. count=fread( buf,1,count,_file )
  52. _pos+=count
  53. DebugAssert( ftell( _file )=_pos ) 'Sanity check...
  54. Return count
  55. End
  56. #rem monkeydoc Writes data to the filestream.
  57. Writing past the end of the file will increase the length of a filestream.
  58. @param buf A pointer to the memory to write the data from.
  59. @param count The number of bytes to write.
  60. @return The number of bytes actually written.
  61. #end
  62. Method Write:Int( buf:Void Ptr,count:Int ) Override
  63. If count<=0 Return 0
  64. count=fwrite( buf,1,count,_file )
  65. _pos+=count
  66. _end=Max( _pos,_end )
  67. DebugAssert( ftell( _file )=_pos ) 'Sanity check...
  68. Return count
  69. End
  70. #rem monkeydoc Opens a file and returns a new filestream.
  71. @param path The path of the file to open.
  72. @param mode The mode to open the file in: "r", "w" or "rw".
  73. @return A new filestream, or null if the file could not be opened.
  74. #end
  75. Function Open:FileStream( path:String,mode:String )
  76. Select mode
  77. Case "r"
  78. mode="rb"
  79. Case "w"
  80. mode="wb"
  81. Case "rw"
  82. mode="r+b"
  83. Default
  84. Return Null
  85. End
  86. Local file:=fopen( path,mode )
  87. If Not file Return Null
  88. Return New FileStream( file )
  89. End
  90. Private
  91. Field _file:FILE Ptr
  92. Field _pos:Int
  93. Field _end:Int
  94. Method New( cfile:FILE Ptr )
  95. _file=cfile
  96. _pos=ftell( _file )
  97. fseek( _file,0,SEEK_END )
  98. _end=ftell( _file )
  99. fseek( _file,_pos,SEEK_SET )
  100. DebugAssert( ftell( _file )=_pos ) 'Sanity check...
  101. End
  102. End