You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

162 lines
3.5KB

  1. #include "mov-buffer.h"
  2. #include "mov-file-buffer.h"
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <assert.h>
  7. #if defined(_WIN32) || defined(_WIN64)
  8. #define fseek64 _fseeki64
  9. #define ftell64 _ftelli64
  10. #elif defined(__ANDROID__)
  11. #define fseek64 fseek
  12. #define ftell64 ftell
  13. #elif defined(OS_LINUX)
  14. #define fseek64 fseeko64
  15. #define ftell64 ftello64
  16. #else
  17. #define fseek64 fseek
  18. #define ftell64 ftell
  19. #endif
  20. static int mov_file_read(void* fp, void* data, uint64_t bytes)
  21. {
  22. if (bytes == fread(data, 1, bytes, (FILE*)fp))
  23. return 0;
  24. return 0 != ferror((FILE*)fp) ? ferror((FILE*)fp) : -1 /*EOF*/;
  25. }
  26. static int mov_file_write(void* fp, const void* data, uint64_t bytes)
  27. {
  28. return bytes == fwrite(data, 1, bytes, (FILE*)fp) ? 0 : ferror((FILE*)fp);
  29. }
  30. static int mov_file_seek(void* fp, int64_t offset)
  31. {
  32. return fseek64((FILE*)fp, offset, offset >= 0 ? SEEK_SET : SEEK_END);
  33. }
  34. static int64_t mov_file_tell(void* fp)
  35. {
  36. return ftell64((FILE*)fp);
  37. }
  38. static int mov_file_cache_read(void* fp, void* data, uint64_t bytes)
  39. {
  40. uint8_t* p = (uint8_t*)data;
  41. struct mov_file_cache_t* file = (struct mov_file_cache_t*)fp;
  42. while (bytes > 0)
  43. {
  44. assert(file->off <= file->len);
  45. if (file->off >= file->len)
  46. {
  47. if (bytes >= sizeof(file->ptr))
  48. {
  49. if (bytes == fread(p, 1, bytes, file->fp))
  50. {
  51. file->tell += bytes;
  52. return 0;
  53. }
  54. return 0 != ferror(file->fp) ? ferror(file->fp) : -1 /*EOF*/;
  55. }
  56. else
  57. {
  58. file->off = 0;
  59. file->len = (unsigned int)fread(file->ptr, 1, sizeof(file->ptr), file->fp);
  60. if (file->len < 1)
  61. return 0 != ferror(file->fp) ? ferror(file->fp) : -1 /*EOF*/;
  62. }
  63. }
  64. if (file->off < file->len)
  65. {
  66. unsigned int n = file->len - file->off;
  67. n = n > bytes ? (unsigned int)bytes : n;
  68. memcpy(p, file->ptr + file->off, n);
  69. file->tell += n;
  70. file->off += n;
  71. bytes -= n;
  72. p += n;
  73. }
  74. }
  75. return 0;
  76. }
  77. static int mov_file_cache_write(void* fp, const void* data, uint64_t bytes)
  78. {
  79. struct mov_file_cache_t* file = (struct mov_file_cache_t*)fp;
  80. file->tell += bytes;
  81. if (file->off + bytes < sizeof(file->ptr))
  82. {
  83. memcpy(file->ptr + file->off, data, bytes);
  84. file->off += (unsigned int)bytes;
  85. return 0;
  86. }
  87. // write buffer
  88. if (file->off > 0)
  89. {
  90. if (file->off != fwrite(file->ptr, 1, file->off, file->fp))
  91. return ferror(file->fp);
  92. file->off = 0; // clear buffer
  93. }
  94. // write data;
  95. return bytes == fwrite(data, 1, bytes, file->fp) ? 0 : ferror(file->fp);
  96. }
  97. static int mov_file_cache_seek(void* fp, int64_t offset)
  98. {
  99. int r;
  100. struct mov_file_cache_t* file = (struct mov_file_cache_t*)fp;
  101. if (offset != file->tell)
  102. {
  103. if (file->off > file->len)
  104. {
  105. // write bufferred data
  106. if(file->off != fwrite(file->ptr, 1, file->off, file->fp))
  107. return ferror(file->fp);
  108. }
  109. file->off = file->len = 0;
  110. r = fseek64(file->fp, offset, offset >= 0 ? SEEK_SET : SEEK_END);
  111. file->tell = ftell64(file->fp);
  112. return r;
  113. }
  114. return 0;
  115. }
  116. static int64_t mov_file_cache_tell(void* fp)
  117. {
  118. struct mov_file_cache_t* file = (struct mov_file_cache_t*)fp;
  119. if (ftell64(file->fp) != (int64_t)(file->tell + (uint64_t)(int)(file->len - file->off)))
  120. return -1;
  121. return (int64_t)file->tell;
  122. //return ftell64(file->fp);
  123. }
  124. const struct mov_buffer_t* mov_file_buffer(void)
  125. {
  126. static struct mov_buffer_t s_io = {
  127. mov_file_read,
  128. mov_file_write,
  129. mov_file_seek,
  130. mov_file_tell,
  131. };
  132. return &s_io;
  133. }
  134. const struct mov_buffer_t* mov_file_cache_buffer(void)
  135. {
  136. static struct mov_buffer_t s_io = {
  137. mov_file_cache_read,
  138. mov_file_cache_write,
  139. mov_file_cache_seek,
  140. mov_file_cache_tell,
  141. };
  142. return &s_io;
  143. }