/SampleTOAPIA/FAT32/FAT32/FL_File.cs

https://github.com/Wiladams/NewTOAPIA · C# · 468 lines · 277 code · 96 blank · 95 comment · 53 complexity · 052dd160228eb70e6107fab3cd041fbe MD5 · raw file

  1. namespace FAT32
  2. {
  3. public class FL_FILE : fatlib
  4. {
  5. internal fatfs Fs; // The file system objects
  6. public ulong parentcluster;
  7. public ulong startcluster;
  8. public ulong bytenum;
  9. public ulong filelength;
  10. public int filelength_changed;
  11. public byte[] path = new byte[FATFS_MAX_LONG_FILENAME];
  12. public byte[] filename = new byte[FATFS_MAX_LONG_FILENAME];
  13. public byte[] shortfilename = new byte[11];
  14. // Read/Write sector buffer
  15. public sector_buffer file_data;
  16. // File fopen flags
  17. public byte flags;
  18. public const int FILE_READ = 0x01; // (1 << 0);
  19. public const int FILE_WRITE = 0x02; // (1 << 1);
  20. public const int FILE_APPEND = 0x04; // (1 << 2);
  21. public const int FILE_BINARY = 0x08; // (1 << 3);
  22. public const int FILE_ERASE = 0x10; // (1 << 4);
  23. public const int FILE_CREATE = 0x20; // (1 << 5);
  24. public FL_FILE next;
  25. //-----------------------------------------------------------------------------
  26. // fl_fflush: Flush un-written data to the file
  27. //-----------------------------------------------------------------------------
  28. public int fl_fflush()
  29. {
  30. #if FATFS_INC_WRITE_SUPPORT
  31. FL_LOCK(Fs);
  32. // If some write data still in buffer
  33. if (this.file_data.dirty)
  34. {
  35. // Write back current sector before loading next
  36. if (Fs.fatfs_sector_writer(this.startcluster, this.file_data.address, this.file_data.sector))
  37. this.file_data.dirty = false;
  38. }
  39. FL_UNLOCK(Fs);
  40. #endif
  41. return 0;
  42. }
  43. //-----------------------------------------------------------------------------
  44. // fl_fclose: Close an open file
  45. //-----------------------------------------------------------------------------
  46. public void fl_fclose()
  47. {
  48. FL_LOCK(Fs);
  49. // Flush un-written data to file
  50. fl_fflush();
  51. // File size changed?
  52. if (this.filelength_changed)
  53. {
  54. #if FATFS_INC_WRITE_SUPPORT
  55. // Update filesize in directory
  56. fatfs_update_file_length(&Fs, file.parentcluster, (char*)file.shortfilename, file.filelength);
  57. #endif
  58. this.filelength_changed = 0;
  59. }
  60. this.bytenum = 0;
  61. this.filelength = 0;
  62. this.startcluster = 0;
  63. this.file_data.address = 0xFFFFFFFF;
  64. this.file_data.dirty = false;
  65. this.filelength_changed = 0;
  66. // Free file handle
  67. _free_file(file);
  68. Fs.fatfs_fat_purge();
  69. FL_UNLOCK(Fs);
  70. }
  71. //-----------------------------------------------------------------------------
  72. // fl_fgetc: Get a character in the stream
  73. //-----------------------------------------------------------------------------
  74. int fl_fgetc()
  75. {
  76. int res;
  77. byte[] data = new byte[1];
  78. res = fl_fread(data, 1, 1);
  79. if (res == 1)
  80. return (int)data;
  81. else
  82. return res;
  83. }
  84. //-----------------------------------------------------------------------------
  85. // fl_fread: Read a block of data from the file
  86. //-----------------------------------------------------------------------------
  87. public int fl_fread(byte[] buffer, int size, int length)
  88. {
  89. ulong sector;
  90. ulong offset;
  91. int copyCount;
  92. int count = size * length;
  93. int bytesRead = 0;
  94. if (buffer == null)
  95. return -1;
  96. // No read permissions
  97. if (!(this.flags & FILE_READ))
  98. return -1;
  99. // Nothing to be done
  100. if (!count)
  101. return 0;
  102. // Check if read starts past end of file
  103. if (this.bytenum >= this.filelength)
  104. return -1;
  105. // Limit to file size
  106. if ((this.bytenum + count) > this.filelength)
  107. count = this.filelength - this.bytenum;
  108. // Calculate start sector
  109. sector = this.bytenum / FAT_SECTOR_SIZE;
  110. // Offset to start copying data from first sector
  111. offset = this.bytenum % FAT_SECTOR_SIZE;
  112. while (bytesRead < count)
  113. {
  114. // Do we need to re-read the sector?
  115. if (this.file_data.address != sector)
  116. {
  117. // Flush un-written data to file
  118. if (this.file_data.dirty)
  119. fl_fflush();
  120. // Read sector of file
  121. if (!Fs.fatfs_sector_reader(this.startcluster, sector, this.file_data.sector))
  122. // Read failed - out of range (probably)
  123. break;
  124. this.file_data.address = sector;
  125. this.file_data.dirty = false;
  126. }
  127. // We have upto one sector to copy
  128. copyCount = FAT_SECTOR_SIZE - offset;
  129. // Only require some of this sector?
  130. if (copyCount > (count - bytesRead))
  131. copyCount = (count - bytesRead);
  132. // Copy to application buffer
  133. memcpy((byte*)((byte*)buffer + bytesRead), (byte*)(tjos.file_data.sector + offset), copyCount);
  134. // Increase total read count
  135. bytesRead += copyCount;
  136. // Increment file pointer
  137. this.bytenum += copyCount;
  138. // Move onto next sector and reset copy offset
  139. sector++;
  140. offset = 0;
  141. }
  142. return bytesRead;
  143. }
  144. //-----------------------------------------------------------------------------
  145. // fl_fseek: Seek to a specific place in the file
  146. //-----------------------------------------------------------------------------
  147. int fl_fseek(long offset, int origin)
  148. {
  149. int res = -1;
  150. if (origin == SEEK_END && offset != 0)
  151. return -1;
  152. FL_LOCK(Fs);
  153. // Invalidate file buffer
  154. this.file_data.address = 0xFFFFFFFF;
  155. this.file_data.dirty = false;
  156. if (origin == SEEK_SET)
  157. {
  158. this.bytenum = (ulong)offset;
  159. if (this.bytenum > this.filelength)
  160. this.bytenum = this.filelength;
  161. res = 0;
  162. }
  163. else if (origin == SEEK_CUR)
  164. {
  165. // Positive shift
  166. if (offset >= 0)
  167. {
  168. this.bytenum += offset;
  169. if (this.bytenum > this.filelength)
  170. this.bytenum = this.filelength;
  171. }
  172. // Negative shift
  173. else
  174. {
  175. // Make shift positive
  176. offset = -offset;
  177. // Limit to negative shift to start of file
  178. if ((ulong)offset > this.bytenum)
  179. this.bytenum = 0;
  180. else
  181. this.bytenum -= offset;
  182. }
  183. res = 0;
  184. }
  185. else if (origin == SEEK_END)
  186. {
  187. this.bytenum = this.filelength;
  188. res = 0;
  189. }
  190. else
  191. res = -1;
  192. FL_UNLOCK(Fs);
  193. return res;
  194. }
  195. //-----------------------------------------------------------------------------
  196. // fl_fgetpos: Get the current file position
  197. //-----------------------------------------------------------------------------
  198. public int fl_fgetpos(ref ulong position)
  199. {
  200. FL_LOCK(Fs);
  201. // Get position
  202. position = file.bytenum;
  203. FL_UNLOCK(Fs);
  204. return 0;
  205. }
  206. //-----------------------------------------------------------------------------
  207. // fl_ftell: Get the current file position
  208. //-----------------------------------------------------------------------------
  209. public long fl_ftell()
  210. {
  211. ulong pos = 0;
  212. fl_fgetpos(f, ref pos);
  213. return (long)pos;
  214. }
  215. //-----------------------------------------------------------------------------
  216. // fl_feof: Is the file pointer at the end of the stream?
  217. //-----------------------------------------------------------------------------
  218. public int fl_feof()
  219. {
  220. int res;
  221. FL_LOCK(Fs);
  222. if (this.bytenum == this.filelength)
  223. res = EOF;
  224. else
  225. res = 0;
  226. FL_UNLOCK(Fs);
  227. return res;
  228. }
  229. //-----------------------------------------------------------------------------
  230. // fl_fputc: Write a character to the stream
  231. //-----------------------------------------------------------------------------
  232. #if FATFS_INC_WRITE_SUPPORT
  233. int fl_fputc(int c, void *f)
  234. {
  235. byte data = (byte)c;
  236. int res;
  237. res = fl_fwrite(&data, 1, 1, f);
  238. if (res == 1)
  239. return c;
  240. else
  241. return res;
  242. }
  243. #endif
  244. //-----------------------------------------------------------------------------
  245. // fl_fwrite: Write a block of data to the stream
  246. //-----------------------------------------------------------------------------
  247. #if FATFS_INC_WRITE_SUPPORT
  248. int fl_fwrite(const void * data, int size, int count, void *f )
  249. {
  250. FL_FILE *file = (FL_FILE *)f;
  251. unsigned long sector;
  252. unsigned long offset;
  253. unsigned long length = (size*count);
  254. byte *buffer = (byte *)data;
  255. int dirtySector = 0;
  256. unsigned long bytesWritten = 0;
  257. unsigned long copyCount;
  258. // If first call to library, initialise
  259. CHECK_FL_INIT();
  260. if (!file)
  261. return -1;
  262. FL_LOCK(&Fs);
  263. // No write permissions
  264. if (!(file.flags & FILE_WRITE))
  265. {
  266. FL_UNLOCK(&Fs);
  267. return -1;
  268. }
  269. // Append writes to end of file
  270. if (file.flags & FILE_APPEND)
  271. file.bytenum = file.filelength;
  272. // Else write to current position
  273. // Calculate start sector
  274. sector = file.bytenum / FAT_SECTOR_SIZE;
  275. // Offset to start copying data from first sector
  276. offset = file.bytenum % FAT_SECTOR_SIZE;
  277. while (bytesWritten < length)
  278. {
  279. // We have upto one sector to copy
  280. copyCount = FAT_SECTOR_SIZE - offset;
  281. // Only require some of this sector?
  282. if (copyCount > (length - bytesWritten))
  283. copyCount = (length - bytesWritten);
  284. // Do we need to read a new sector?
  285. if (file.file_data.address != sector)
  286. {
  287. // Flush un-written data to file
  288. if (file.file_data.dirty)
  289. fl_fflush(file);
  290. // If we plan to overwrite the whole sector, we don't need to read it first!
  291. if (copyCount != FAT_SECTOR_SIZE)
  292. {
  293. // Read the appropriate sector
  294. // NOTE: This does not have succeed; if last sector of file
  295. // reached, no valid data will be read in, but write will
  296. // allocate some more space for new data.
  297. fatfs_sector_reader(&Fs, file.startcluster, sector, file.file_data.sector);
  298. }
  299. file.file_data.address = sector;
  300. file.file_data.dirty = false;
  301. }
  302. // Copy from application buffer into sector buffer
  303. memcpy((byte*)(file.file_data.sector + offset), (byte*)(buffer + bytesWritten), copyCount);
  304. // Mark buffer as dirty
  305. file.file_data.dirty = true;
  306. // Increase total read count
  307. bytesWritten += copyCount;
  308. // Increment file pointer
  309. file.bytenum += copyCount;
  310. // Move onto next sector and reset copy offset
  311. sector++;
  312. offset = 0;
  313. }
  314. // Write increased extent of the file?
  315. if (file.bytenum > file.filelength)
  316. {
  317. // Increase file size to new point
  318. file.filelength = file.bytenum;
  319. // We are changing the file length and this
  320. // will need to be writen back at some point
  321. file.filelength_changed = 1;
  322. }
  323. FL_UNLOCK(&Fs);
  324. return (size*count);
  325. }
  326. #endif
  327. //-----------------------------------------------------------------------------
  328. // fl_fputs: Write a character string to the stream
  329. //-----------------------------------------------------------------------------
  330. #if FATFS_INC_WRITE_SUPPORT
  331. int fl_fputs(const char * str, void *f)
  332. {
  333. int len = (int)strlen(str);
  334. int res = fl_fwrite(str, 1, len, f);
  335. if (res == len)
  336. return len;
  337. else
  338. return res;
  339. }
  340. #endif
  341. //-----------------------------------------------------------------------------
  342. // fl_remove: Remove a file from the filesystem
  343. //-----------------------------------------------------------------------------
  344. #if FATFS_INC_WRITE_SUPPORT
  345. int fl_remove( const char * filename )
  346. {
  347. FL_FILE* file;
  348. int res = -1;
  349. FL_LOCK(&Fs);
  350. // Use read_file as this will check if the file is already open!
  351. file = fl_fopen((char*)filename, "r");
  352. if (file)
  353. {
  354. // Delete allocated space
  355. if (fatfs_free_cluster_chain(&Fs, file.startcluster))
  356. {
  357. // Remove directory entries
  358. if (fatfs_mark_file_deleted(&Fs, file.parentcluster, (char*)file.shortfilename))
  359. {
  360. // Close the file handle (this should not write anything to the file
  361. // as we have not changed the file since opening it!)
  362. fl_fclose(file);
  363. res = 0;
  364. }
  365. }
  366. }
  367. FL_UNLOCK(&Fs);
  368. return res;
  369. }
  370. #endif
  371. }
  372. }