filestream.monkey2 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  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 Seeks to a position in the filestream.
  26. @param offset The position to seek to.
  27. #end
  28. Method Seek( position:Int ) Override
  29. DebugAssert( position>=0 And position<=_end )
  30. fseek( _file,position,SEEK_SET )
  31. _pos=position
  32. DebugAssert( ftell( _file )=_pos ) 'Sanity check...
  33. End
  34. #rem monkeydoc Reads data from the filestream.
  35. @param buf A pointer to the memory to read the data into.
  36. @param count The number of bytes to read.
  37. @return The number of bytes actually read.
  38. #end
  39. Method Read:Int( buf:Void Ptr,count:Int ) Override
  40. count=Clamp( count,0,_end-_pos )
  41. count=fread( buf,1,count,_file )
  42. _pos+=count
  43. DebugAssert( ftell( _file )=_pos ) 'Sanity check...
  44. Return count
  45. End
  46. #rem monkeydoc Writes data to the filestream.
  47. Writing past the end of the file will increase the length of a filestream.
  48. @param buf A pointer to the memory to write the data from.
  49. @param count The number of bytes to write.
  50. @return The number of bytes actually written.
  51. #end
  52. Method Write:Int( buf:Void Ptr,count:Int ) Override
  53. If count<=0 Return 0
  54. count=fwrite( buf,1,count,_file )
  55. _pos+=count
  56. _end=Max( _pos,_end )
  57. DebugAssert( ftell( _file )=_pos ) 'Sanity check...
  58. Return count
  59. End
  60. #rem monkeydoc Opens a file and returns a new filestream.
  61. When opening a file using "r" or "rw", the file must already exist or the function will fail and null will be returned.
  62. When opening a file using "w", any existing file at the same path will be overwritten.
  63. @param path The path of the file to open.
  64. @param mode The mode to open the file in: "r", "w" or "rw".
  65. @return A new filestream, or null if the file could not be opened.
  66. #end
  67. Function Open:FileStream( path:String,mode:String )
  68. Select mode
  69. Case "r" mode="rb"
  70. Case "w" mode="wb"
  71. Case "rw" mode="r+b"
  72. Default
  73. Return Null
  74. End
  75. Local file:=OpenCFile( path,mode )
  76. If Not file Return Null
  77. Return New FileStream( file )
  78. End
  79. Protected
  80. Method OnDiscard() Override
  81. fclose( _file )
  82. _file=Null
  83. _pos=0
  84. _end=0
  85. end
  86. Method OnFinalize() Override
  87. fclose( _file )
  88. End
  89. Private
  90. Field _file:FILE Ptr
  91. Field _pos:Int
  92. Field _end:Int
  93. Method New( cfile:FILE Ptr )
  94. _file=cfile
  95. _pos=ftell( _file )
  96. fseek( _file,0,SEEK_END )
  97. _end=ftell( _file )
  98. fseek( _file,_pos,SEEK_SET )
  99. DebugAssert( ftell( _file )=_pos ) 'Sanity check...
  100. End
  101. End