mirror of
				https://github.com/python/cpython.git
				synced 2025-10-30 21:21:22 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			177 lines
		
	
	
	
		
			4.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			177 lines
		
	
	
	
		
			4.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #pragma once
 | |
| /*
 | |
| Low level interface to Meta's zstd library for use in the compression.zstd
 | |
| Python module.
 | |
| */
 | |
| 
 | |
| /* Declarations shared between different parts of the _zstd module*/
 | |
| 
 | |
| #include "Python.h"
 | |
| 
 | |
| #include "zstd.h"
 | |
| #include "zdict.h"
 | |
| 
 | |
| 
 | |
| /* Forward declaration of module state */
 | |
| typedef struct _zstd_state _zstd_state;
 | |
| 
 | |
| /* Forward reference of module def */
 | |
| extern PyModuleDef _zstdmodule;
 | |
| 
 | |
| /* For clinic type calculations */
 | |
| static inline _zstd_state *
 | |
| get_zstd_state_from_type(PyTypeObject *type) {
 | |
|     PyObject *module = PyType_GetModuleByDef(type, &_zstdmodule);
 | |
|     if (module == NULL) {
 | |
|         return NULL;
 | |
|     }
 | |
|     void *state = PyModule_GetState(module);
 | |
|     assert(state != NULL);
 | |
|     return (_zstd_state *)state;
 | |
| }
 | |
| 
 | |
| extern PyType_Spec zstd_dict_type_spec;
 | |
| extern PyType_Spec zstd_compressor_type_spec;
 | |
| extern PyType_Spec zstd_decompressor_type_spec;
 | |
| 
 | |
| struct _zstd_state {
 | |
|     PyObject *empty_bytes;
 | |
| 
 | |
|     PyTypeObject *ZstdDict_type;
 | |
|     PyTypeObject *ZstdCompressor_type;
 | |
|     PyTypeObject *ZstdDecompressor_type;
 | |
|     PyObject *ZstdError;
 | |
| 
 | |
|     PyTypeObject *CParameter_type;
 | |
|     PyTypeObject *DParameter_type;
 | |
| };
 | |
| 
 | |
| typedef struct {
 | |
|     PyObject_HEAD
 | |
| 
 | |
|     /* Reusable compress/decompress dictionary, they are created once and
 | |
|        can be shared by multiple threads concurrently, since its usage is
 | |
|        read-only.
 | |
|        c_dicts is a dict, int(compressionLevel):PyCapsule(ZSTD_CDict*) */
 | |
|     ZSTD_DDict *d_dict;
 | |
|     PyObject *c_dicts;
 | |
| 
 | |
|     /* Content of the dictionary, bytes object. */
 | |
|     PyObject *dict_content;
 | |
|     /* Dictionary id */
 | |
|     uint32_t dict_id;
 | |
| 
 | |
|     /* __init__ has been called, 0 or 1. */
 | |
|     int inited;
 | |
| } ZstdDict;
 | |
| 
 | |
| typedef struct {
 | |
|     PyObject_HEAD
 | |
| 
 | |
|     /* Compression context */
 | |
|     ZSTD_CCtx *cctx;
 | |
| 
 | |
|     /* ZstdDict object in use */
 | |
|     PyObject *dict;
 | |
| 
 | |
|     /* Last mode, initialized to ZSTD_e_end */
 | |
|     int last_mode;
 | |
| 
 | |
|     /* (nbWorker >= 1) ? 1 : 0 */
 | |
|     int use_multithread;
 | |
| 
 | |
|     /* Compression level */
 | |
|     int compression_level;
 | |
| 
 | |
|     /* __init__ has been called, 0 or 1. */
 | |
|     int inited;
 | |
| } ZstdCompressor;
 | |
| 
 | |
| typedef struct {
 | |
|     PyObject_HEAD
 | |
| 
 | |
|     /* Decompression context */
 | |
|     ZSTD_DCtx *dctx;
 | |
| 
 | |
|     /* ZstdDict object in use */
 | |
|     PyObject *dict;
 | |
| 
 | |
|     /* Unconsumed input data */
 | |
|     char *input_buffer;
 | |
|     size_t input_buffer_size;
 | |
|     size_t in_begin, in_end;
 | |
| 
 | |
|     /* Unused data */
 | |
|     PyObject *unused_data;
 | |
| 
 | |
|     /* 0 if decompressor has (or may has) unconsumed input data, 0 or 1. */
 | |
|     char needs_input;
 | |
| 
 | |
|     /* For decompress(), 0 or 1.
 | |
|        1 when both input and output streams are at a frame edge, means a
 | |
|        frame is completely decoded and fully flushed, or the decompressor
 | |
|        just be initialized. */
 | |
|     char at_frame_edge;
 | |
| 
 | |
|     /* For ZstdDecompressor, 0 or 1.
 | |
|        1 means the end of the first frame has been reached. */
 | |
|     char eof;
 | |
| 
 | |
|     /* Used for fast reset above three variables */
 | |
|     char _unused_char_for_align;
 | |
| 
 | |
|     /* __init__ has been called, 0 or 1. */
 | |
|     int inited;
 | |
| } ZstdDecompressor;
 | |
| 
 | |
| typedef enum {
 | |
|     TYPE_DECOMPRESSOR,          // <D>, ZstdDecompressor class
 | |
|     TYPE_ENDLESS_DECOMPRESSOR,  // <E>, decompress() function
 | |
| } decompress_type;
 | |
| 
 | |
| typedef enum {
 | |
|     ERR_DECOMPRESS,
 | |
|     ERR_COMPRESS,
 | |
| 
 | |
|     ERR_LOAD_D_DICT,
 | |
|     ERR_LOAD_C_DICT,
 | |
| 
 | |
|     ERR_GET_C_BOUNDS,
 | |
|     ERR_GET_D_BOUNDS,
 | |
|     ERR_SET_C_LEVEL,
 | |
| 
 | |
|     ERR_TRAIN_DICT,
 | |
|     ERR_FINALIZE_DICT,
 | |
| } error_type;
 | |
| 
 | |
| typedef enum {
 | |
|     DICT_TYPE_DIGESTED = 0,
 | |
|     DICT_TYPE_UNDIGESTED = 1,
 | |
|     DICT_TYPE_PREFIX = 2
 | |
| } dictionary_type;
 | |
| 
 | |
| static inline int
 | |
| mt_continue_should_break(ZSTD_inBuffer *in, ZSTD_outBuffer *out) {
 | |
|     return in->size == in->pos && out->size != out->pos;
 | |
| }
 | |
| 
 | |
| /* Format error message and set ZstdError. */
 | |
| extern void
 | |
| set_zstd_error(const _zstd_state* const state,
 | |
|                const error_type type, size_t zstd_ret);
 | |
| 
 | |
| extern void
 | |
| set_parameter_error(const _zstd_state* const state, int is_compress,
 | |
|                     int key_v, int value_v);
 | |
| 
 | |
| static const char init_twice_msg[] = "__init__ method is called twice.";
 | |
| 
 | |
| extern PyObject *
 | |
| decompress_impl(ZstdDecompressor *self, ZSTD_inBuffer *in,
 | |
|                 Py_ssize_t max_length,
 | |
|                 Py_ssize_t initial_size,
 | |
|                 decompress_type type);
 | |
| 
 | |
| extern PyObject *
 | |
| compress_impl(ZstdCompressor *self, Py_buffer *data,
 | |
|               ZSTD_EndDirective end_directive);
 | 
