zstd-seek.h (7213B)
1 /* ****************************************************************** 2 * libzstd-seek 3 * Copyright (c) 2020, Martinelli Marco 4 * 5 * You can contact the author at : 6 * - Source repository : https://github.com/martinellimarco/libzstd-seek 7 * 8 * This source code is licensed under the GPLv3 (found in the LICENSE 9 * file in the root directory of this source tree). 10 ****************************************************************** */ 11 12 #ifndef _ZSTD_SEEK_ 13 #define _ZSTD_SEEK_ 14 15 #if defined (__cplusplus) 16 extern "C" { 17 #endif 18 19 #include <stdio.h> 20 #include <zstd.h> 21 22 #ifndef _ZSTD_SEEK_DEBUG_ 23 #define _ZSTD_SEEK_DEBUG_ 0 24 #endif 25 26 #ifdef _WIN32 27 #define DEBUG(...) 28 #else 29 #define DEBUG(...) \ 30 do { \ 31 if (_ZSTD_SEEK_DEBUG_){ \ 32 flockfile(stderr); \ 33 fprintf(stderr, "%s(): ", __func__); \ 34 fprintf(stderr, __VA_ARGS__); \ 35 funlockfile(stderr); \ 36 } \ 37 } while (0) 38 #endif 39 40 /* Error constants */ 41 #define ZSTDSEEK_ERR_NEGATIVE_SEEK -1 42 #define ZSTDSEEK_ERR_BEYOND_END_SEEK -2 43 #define ZSTDSEEK_ERR_READ -3 44 45 /* Seekable format constants */ 46 #define ZSTD_SEEK_TABLE_FOOTER_SIZE 9 47 #define ZSTD_SEEKABLE_MAGICNUMBER 0x8F92EAB1 48 #define ZSTD_SKIPPABLE_HEADER_SIZE 8 49 50 /* Structs */ 51 52 typedef struct{ 53 size_t compressedPos; //where this frame begin in the compressed stream 54 size_t uncompressedPos;//the equivalent position in the uncompressed stream 55 } ZSTDSeek_JumpTableRecord; 56 57 typedef struct{ 58 ZSTDSeek_JumpTableRecord *records; 59 uint64_t length; 60 uint64_t capacity; 61 } ZSTDSeek_JumpTable; 62 63 typedef struct ZSTDSeek_Context_s ZSTDSeek_Context; 64 65 /* Jump Table API */ 66 67 /* 68 * Returns a pointer to the jump table used by the given context, 0 if the context is not valid. 69 */ 70 ZSTDSeek_JumpTable* ZSTDSeek_getJumpTableOfContext(ZSTDSeek_Context *sctx); 71 72 /* 73 * These are for advanced use. Don't use them unless you understand exactly what you are doing. 74 */ 75 ZSTDSeek_JumpTable* ZSTDSeek_newJumpTable(); 76 void ZSTDSeek_freeJumpTable(ZSTDSeek_JumpTable* jt); 77 78 /* 79 * Add a new record to the jump table jt. It's a simple map between compressed and uncompressed positions. 80 * Uncompressed positions must be at the start of a frame. 81 * The last record is special. The compressedPos is the compressed file size and the uncompressedPos is the uncompressed file size. 82 */ 83 void ZSTDSeek_addJumpTableRecord(ZSTDSeek_JumpTable* jt, size_t compressedPos, size_t uncompressedPos); 84 85 /* 86 * Parse the file and fill the jump table. Don't use in combination with addJumpTableRecord. 87 * You don't need to call this unless you used a create*WithoutJumpTable method to get the context. 88 */ 89 int ZSTDSeek_initializeJumpTable(ZSTDSeek_Context *sctx); 90 91 /* 92 * Parse the file and fill the jump table up until a certain uncompressed position. Don't use in combination with addJumpTableRecord. 93 * You don't need to call this unless you used a create*WithoutJumpTable method to get the context. 94 */ 95 int ZSTDSeek_initializeJumpTableUpUntilPos(ZSTDSeek_Context *sctx, size_t upUntilPos); 96 97 /* 98 * Return 1 if the jump table is fully initialized, 0 otherwise. 99 */ 100 int ZSTDSeek_jumpTableIsInitialized(ZSTDSeek_Context *sctx); 101 102 /* Seek API */ 103 104 /* 105 * Create a ZSTDSeek_Context from a file and initialize the jump table. 106 * file is the path to the file 107 * On success returns a valid ZSTDSeek_Context. 108 * Returns ZSTDSEEK_CREATE_OPEN_FAILED if the file can't be opened. 109 * Returns ZSTDSEEK_CREATE_MAP_FAILED if the file can't be memory mapped. 110 */ 111 ZSTDSeek_Context* ZSTDSeek_createFromFile(const char* file); 112 113 /* 114 * Create a ZSTDSeek_Context from a file but does not initialze the jump table. 115 * You'll have to call ZSTDSeek_initializeJumpTable manually or add records with ZSTDSeek_addJumpTableRecord. 116 * file is the path to the file 117 * On success returns a valid ZSTDSeek_Context. 118 * Returns ZSTDSEEK_CREATE_OPEN_FAILED if the file can't be opened. 119 * Returns ZSTDSEEK_CREATE_MAP_FAILED if the file can't be memory mapped. 120 */ 121 ZSTDSeek_Context* ZSTDSeek_createFromFileWithoutJumpTable(const char* file); 122 123 /* 124 * Create a ZSTDSeek_Context from a buffer and initialize the jump table. 125 * buff is a buffer with the whole zstd data, eg a memory mapped file. 126 * length is the length of buff. 127 * Returns 0 in case of failure. 128 */ 129 ZSTDSeek_Context* ZSTDSeek_create(void *buff, size_t size); 130 131 /* 132 * Create a ZSTDSeek_Context from a buffer but does not initialze the jump table. 133 * You'll have to call ZSTDSeek_initializeJumpTable manually or add records with ZSTDSeek_addJumpTableRecord. 134 * buff is a buffer with the whole zstd data, eg a memory mapped file. 135 * length is the length of buff. 136 * Returns 0 in case of failure. 137 */ 138 ZSTDSeek_Context* ZSTDSeek_createWithoutJumpTable(void *buff, size_t size); 139 140 /* 141 * Create a ZSTDSeek_Context from a file descriptor but does not initialze the jump table. 142 * You'll have to call ZSTDSeek_initializeJumpTable manually or add records with ZSTDSeek_addJumpTableRecord. 143 * USE WITH CAUTION. The file descriptor will be used with mmap. 144 * fd is the file descriptor 145 * On success returns a valid ZSTDSeek_Context. 146 * Returns ZSTDSEEK_CREATE_MAP_FAILED if the fd can't be memory mapped. 147 */ 148 ZSTDSeek_Context* ZSTDSeek_createFromFileDescriptorWithoutJumpTable(int fd); 149 150 /* 151 * Create a ZSTDSeek_Context from a file descriptor and initialize the jump table. 152 * USE WITH CAUTION. The file descriptor will be used with mmap. 153 * fd is the file descriptor 154 * On success returns a valid ZSTDSeek_Context. 155 * Returns ZSTDSEEK_CREATE_MAP_FAILED if the fd can't be memory mapped. 156 */ 157 ZSTDSeek_Context* ZSTDSeek_createFromFileDescriptor(int fd); 158 159 /* 160 * It reads outBuffSize bytes of uncompressed data from the sctx context buffer into outBuff. 161 * Returns the number of bytes read. 162 */ 163 size_t ZSTDSeek_read(void *outBuff, size_t outBuffSize, ZSTDSeek_Context *sctx); 164 165 /* 166 * Like fseek. 167 * Origin can be SEEK_SET, SEEK_END or SEEK_CUR. 168 * Returns 0 if seek was successfull. 169 */ 170 int ZSTDSeek_seek(ZSTDSeek_Context *sctx, long offset, int origin); 171 172 /* 173 * Like ftell. 174 * Returns the current position in the uncompressed file or -1 in case of failure. 175 */ 176 long ZSTDSeek_tell(ZSTDSeek_Context *sctx); 177 178 /* 179 * Like ftell. 180 * Returns the current position in the compressed file or -1 in case of failure. 181 */ 182 long ZSTDSeek_compressedTell(ZSTDSeek_Context *sctx); 183 184 /* 185 * Return the size of the uncompressed file. It will trigger the initialization of the full jump table. 186 */ 187 size_t ZSTDSeek_uncompressedFileSize(ZSTDSeek_Context *sctx); 188 189 /* 190 * Return the last known size of the uncompressed file. It's the size of all the uncompressed frames discovered so far stored in the jump table. 191 */ 192 size_t ZSTDSeek_lastKnownUncompressedFileSize(ZSTDSeek_Context *sctx); 193 194 /* 195 * Return the file descriptor associated with the memory mapped file if available, -1 otherwise. 196 * USE WITH CAUTION. IF YOU DON'T KNOW WHY YOU NEED IT YOU DON'T NEED IT. 197 */ 198 int ZSTDSeek_fileno(ZSTDSeek_Context *sctx); 199 200 /* 201 * Returns the number of frames in the file. 202 */ 203 size_t ZSTDSeek_getNumberOfFrames(ZSTDSeek_Context *sctx); 204 205 /* 206 * Returns 1 if there are more than one frame in the file. 207 */ 208 int ZSTDSeek_isMultiframe(ZSTDSeek_Context *sctx); 209 210 /* 211 * Free the context. 212 */ 213 void ZSTDSeek_free(ZSTDSeek_Context *sctx); 214 215 #if defined (__cplusplus) 216 } 217 #endif 218 219 #endif