1 #pragma once 2 3 #include <functional> 4 #include <vector> 5 #include <map> 6 #include "uv_helper.h" 7 #include "compress.h" 8 #include "cso.h" 9 #include "sector.h" 10 11 namespace maxcso { 12 13 typedef std::function<void (int64_t pos, int64_t total, int64_t written)> OutputCallback; 14 typedef std::function<void (bool status, const char *reason)> OutputFinishCallback; 15 16 class Output { 17 public: 18 Output(uv_loop_t *loop, const Task &task); 19 ~Output(); 20 21 void SetFile(uv_file file, int64_t srcSize, uint32_t blockSize, CSOFormat fmt); 22 void Enqueue(int64_t pos, uint8_t *buffer); 23 bool QueueFull(); 24 25 void OnProgress(OutputCallback callback); 26 void OnFinish(OutputFinishCallback callback); 27 28 private: 29 void CheckFinish(); 30 void Flush(); 31 void WriteCSOIndex(); 32 void WriteDAXIndex(); 33 void HandleReadySector(Sector *sector); 34 bool ShouldCompress(int64_t pos, uint8_t *buffer); 35 36 int32_t Align(int64_t &pos); 37 inline int64_t SrcSizeAligned(); 38 int64_t DstFirstSectorPos(uint32_t totalSectors); 39 40 bool UpdateIndex(int64_t srcPos, int64_t dstPos, uint32_t compressedSize, SectorFormat compressedFmt); 41 42 enum State { 43 STATE_INIT = 0x00, 44 STATE_HAS_FILE = 0x01, 45 STATE_INDEX_READY = 0x02, 46 STATE_INDEX_WRITTEN = 0x04, 47 STATE_DATA_WRITTEN = 0x08, 48 }; 49 50 UVHelper uv_; 51 uv_loop_t *loop_; 52 uint32_t flags_; 53 uint32_t state_; 54 CSOFormat fmt_; 55 double origMaxCostPercent_; 56 double lz4MaxCostPercent_; 57 58 uv_file file_; 59 uv_fs_t flush_; 60 61 int64_t srcSize_; 62 int64_t srcPos_; 63 int64_t dstPos_; 64 65 uint32_t *index_; 66 uint8_t indexShift_; 67 uint32_t indexAlign_; 68 uint32_t blockSize_; 69 uint8_t blockShift_; 70 71 OutputCallback progress_; 72 OutputFinishCallback finish_; 73 74 std::vector<Sector *> freeSectors_; 75 std::map<int64_t, Sector *> pendingSectors_; 76 std::unordered_map<uint32_t, Sector *> partialSectors_; 77 }; 78 79 }; 80