stream_cache.c 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #include "stream_cache.h"
  2. #define STREAM_CACHE_MAX_SIZE 1024U
  3. struct StreamCache {
  4. uint8_t data[STREAM_CACHE_MAX_SIZE];
  5. size_t data_size;
  6. size_t position;
  7. };
  8. StreamCache* stream_cache_alloc() {
  9. StreamCache* cache = malloc(sizeof(StreamCache));
  10. cache->data_size = 0;
  11. cache->position = 0;
  12. return cache;
  13. }
  14. void stream_cache_free(StreamCache* cache) {
  15. furi_assert(cache);
  16. cache->data_size = 0;
  17. cache->position = 0;
  18. free(cache);
  19. }
  20. void stream_cache_drop(StreamCache* cache) {
  21. cache->data_size = 0;
  22. cache->position = 0;
  23. }
  24. bool stream_cache_at_end(StreamCache* cache) {
  25. furi_assert(cache->data_size >= cache->position);
  26. return cache->data_size == cache->position;
  27. }
  28. size_t stream_cache_size(StreamCache* cache) {
  29. return cache->data_size;
  30. }
  31. size_t stream_cache_pos(StreamCache* cache) {
  32. return cache->position;
  33. }
  34. size_t stream_cache_fill(StreamCache* cache, Stream* stream) {
  35. const size_t size_read = stream_read(stream, cache->data, STREAM_CACHE_MAX_SIZE);
  36. cache->data_size = size_read;
  37. cache->position = 0;
  38. return size_read;
  39. }
  40. bool stream_cache_flush(StreamCache* cache, Stream* stream) {
  41. const size_t size_written = stream_write(stream, cache->data, cache->data_size);
  42. const bool success = (size_written == cache->data_size);
  43. cache->data_size = 0;
  44. cache->position = 0;
  45. return success;
  46. }
  47. size_t stream_cache_read(StreamCache* cache, uint8_t* data, size_t size) {
  48. furi_assert(cache->data_size >= cache->position);
  49. const size_t size_read = MIN(size, cache->data_size - cache->position);
  50. if(size_read > 0) {
  51. memcpy(data, cache->data + cache->position, size_read);
  52. cache->position += size_read;
  53. }
  54. return size_read;
  55. }
  56. size_t stream_cache_write(StreamCache* cache, const uint8_t* data, size_t size) {
  57. furi_assert(cache->data_size >= cache->position);
  58. const size_t size_written = MIN(size, STREAM_CACHE_MAX_SIZE - cache->position);
  59. if(size_written > 0) {
  60. memcpy(cache->data + cache->position, data, size_written);
  61. cache->position += size_written;
  62. if(cache->position > cache->data_size) {
  63. cache->data_size = cache->position;
  64. }
  65. }
  66. return size_written;
  67. }
  68. int32_t stream_cache_seek(StreamCache* cache, int32_t offset) {
  69. furi_assert(cache->data_size >= cache->position);
  70. int32_t actual_offset = 0;
  71. if(offset > 0) {
  72. actual_offset = MIN(cache->data_size - cache->position, (size_t)offset);
  73. } else if(offset < 0) {
  74. actual_offset = MAX(-((int32_t)cache->position), offset);
  75. }
  76. cache->position += actual_offset;
  77. return actual_offset;
  78. }