filestream.monkey2 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  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. Note: This method should not be used to open an 'asset stream' because assets are not always files. You should instead use
  64. [[Stream.Open]] for streams that have a stream path prefix such as `asset::`, `internal::`, `external::` etc.
  65. @param path The path of the file to open.
  66. @param mode The mode to open the file in: "r", "w" or "rw".
  67. @return A new filestream, or null if the file could not be opened.
  68. #end
  69. Function Open:FileStream( path:String,mode:String )
  70. Select mode
  71. Case "r"
  72. mode="rb"
  73. Case "w"
  74. mode="wb"
  75. Case "rw"
  76. mode="r+b"
  77. Default
  78. Return Null
  79. End
  80. path=RealPath( path )
  81. Local file:=fopen( path,mode )
  82. If Not file Return Null
  83. Return New FileStream( file )
  84. End
  85. Protected
  86. Method OnDiscard() Override
  87. fclose( _file )
  88. _file=Null
  89. _pos=0
  90. _end=0
  91. end
  92. Method OnFinalize() Override
  93. fclose( _file )
  94. End
  95. Private
  96. Field _file:FILE Ptr
  97. Field _pos:Int
  98. Field _end:Int
  99. Method New( cfile:FILE Ptr )
  100. _file=cfile
  101. _pos=ftell( _file )
  102. fseek( _file,0,SEEK_END )
  103. _end=ftell( _file )
  104. fseek( _file,_pos,SEEK_SET )
  105. DebugAssert( ftell( _file )=_pos ) 'Sanity check...
  106. End
  107. End