47#include "mdb_thread.h"
49 #define LZMA_BUF_SIZE 40960
53#if LZMA_VERSION <= UINT32_C(49990030)
54# define LZMA_EASY_ENCODER(a, b) lzma_easy_encoder_single(a, b)
55#elif LZMA_VERSION <= UINT32_C(49990050)
56# define LZMA_EASY_ENCODER(a, b) lzma_easy_encoder(a, b)
58# define LZMA_EASY_ENCODER(a, b) lzma_easy_encoder(a, b, LZMA_CHECK_CRC32)
63static const lzma_stream lzma_stream_init = LZMA_STREAM_INIT;
69 unsigned char rdbuf[BUF_SIZE];
72static MDB_THREAD_LOCK lzmaCompressionLevelLock = MDB_THREAD_LOCK_INITIALIZER;
73static int lzmaCompressionLevel = 2;
75static int SDDS_GetLockedLZMACompressionLevel(
void) {
77 mdb_thread_lock(&lzmaCompressionLevelLock);
78 level = lzmaCompressionLevel;
79 mdb_thread_unlock(&lzmaCompressionLevelLock);
83void SDDS_SetLZMACompressionLevel(int32_t level) {
84 if (level >= 0 && level <= 9) {
85 mdb_thread_lock(&lzmaCompressionLevelLock);
86 lzmaCompressionLevel = level;
87 mdb_thread_unlock(&lzmaCompressionLevelLock);
91int32_t SDDS_GetLZMACompressionLevel(
void) {
92 return SDDS_GetLockedLZMACompressionLevel();
99void *lzma_open(
const char *path,
const char *mode) {
106 lf->fp = fopen(path, mode);
111 lf->str = lzma_stream_init;
113 if (mode[0] ==
'r') {
114#if LZMA_VERSION <= UINT32_C(49990030)
115 ret = lzma_auto_decoder(&lf->str, NULL, NULL);
117 ret = lzma_auto_decoder(&lf->str, -1, 0);
119 lf->str.avail_in = 0;
121 ret = LZMA_EASY_ENCODER(&lf->str, SDDS_GetLockedLZMACompressionLevel());
123 if (ret != LZMA_OK) {
124 fprintf(stderr,
"lzma_open error: %d\n", ret);
136int lzma_close(
struct lzmafile *file) {
138 unsigned char buf[BUF_SIZE];
142 if (file->mode ==
'w') {
145 file->str.next_out = buf;
146 file->str.avail_out = BUF_SIZE;
147 ret = lzma_code(&file->str, LZMA_FINISH);
148 if (ret != LZMA_STREAM_END && ret != LZMA_OK) {
149 fprintf(stderr,
"lzma_close error: encoding failed: %d\n", ret);
150 lzma_end(&file->str);
155 outsize = BUF_SIZE - file->str.avail_out;
156 if (fwrite(buf, 1, outsize, file->fp) != outsize) {
157 lzma_end(&file->str);
162 if (ret == LZMA_STREAM_END)
166 lzma_end(&file->str);
167 ret = fclose(file->fp);
176long lzma_read(
struct lzmafile *file,
void *buf,
size_t count) {
179 if (file->mode !=
'r')
183 lstr->next_out = buf;
184 lstr->avail_out = count;
187 while (lstr->avail_out) {
188 if (lstr->avail_in == 0) {
190 ret = fread(file->rdbuf, 1, BUF_SIZE, file->fp);
194 lstr->next_in = file->rdbuf;
195 lstr->avail_in = ret;
197 ret = lzma_code(lstr, LZMA_RUN);
200 if (ret != LZMA_OK && ret != LZMA_STREAM_END) {
201 fprintf(stderr,
"lzma_read error: decoding failed: %d\n", ret);
204 if (ret == LZMA_STREAM_END) {
208 return count - lstr->avail_out;
217char *lzma_gets(
char *s,
int size,
struct lzmafile *file) {
221 if (file->mode !=
'r')
223 if (s == NULL || size < 1)
227 lstr->next_out = (
void *)s;
231 if (lstr->avail_in == 0) {
233 ret = fread(file->rdbuf, 1, BUF_SIZE, file->fp);
237 lstr->next_in = file->rdbuf;
238 lstr->avail_in = ret;
245 ret = lzma_code(lstr, LZMA_RUN);
248 if (ret != LZMA_OK && ret != LZMA_STREAM_END) {
249 fprintf(stderr,
"lzma_gets error: decoding failed: %d\n", ret);
252 if (ret == LZMA_STREAM_END) {
258 if ((i == 1) && (s[0] == 32)) {
275long lzma_write(
struct lzmafile *file,
const void *buf,
size_t count) {
277 lzma_stream *lstr = &file->str;
278 unsigned char *bufout;
279 bufout = malloc(
sizeof(
char) * count);
281 if (file->mode !=
'w') {
282 fprintf(stderr,
"lzma_write error: file was not opened for writting\n");
287 lstr->avail_in = count;
288 while (lstr->avail_in) {
289 lstr->next_out = bufout;
290 lstr->avail_out = count;
291 ret = lzma_code(lstr, LZMA_RUN);
292 if (ret != LZMA_OK) {
293 fprintf(stderr,
"lzma_write error: encoding failed: %d\n", ret);
297 ret = fwrite(bufout, 1, count - lstr->avail_out, file->fp);
298 if (ret != count - lstr->avail_out) {
299 fprintf(stderr,
"lzma_write error\n");
311int lzma_puts(
const char *s,
struct lzmafile *file) {
313 lzma_stream *lstr = &file->str;
315 unsigned char *bufout;
318 if (file->mode !=
'w') {
319 fprintf(stderr,
"lzma_puts error: file was not opened for writting\n");
323 bufout = malloc(
sizeof(
unsigned char) * count);
324 buf = malloc(
sizeof(
char) * count);
326 memcpy(buf, s, count);
328 lstr->next_in = (
void *)buf;
329 lstr->avail_in = count;
330 while (lstr->avail_in) {
331 lstr->next_out = bufout;
332 lstr->avail_out = count;
333 ret = lzma_code(lstr, LZMA_RUN);
334 if (ret != LZMA_OK) {
335 fprintf(stderr,
"lzma_puts error: encoding failed: %d\n", ret);
340 ret = fwrite(bufout, 1, count - lstr->avail_out, file->fp);
341 if (ret != count - lstr->avail_out) {
342 fprintf(stderr,
"lzma_puts error\n");
356int lzma_putc(
int c,
struct lzmafile *file) {
358 lzma_stream *lstr = &file->str;
360 unsigned char bufout[1];
363 if (file->mode !=
'w') {
364 fprintf(stderr,
"lzma_putc error: file was not opened for writting\n");
369 lstr->next_in = (
void *)buf;
371 while (lstr->avail_in) {
372 lstr->next_out = bufout;
374 ret = lzma_code(lstr, LZMA_RUN);
375 if (ret != LZMA_OK) {
376 fprintf(stderr,
"lzma_putc error: encoding failed: %d\n", ret);
379 ret = fwrite(bufout, 1, 1 - lstr->avail_out, file->fp);
380 if (ret != 1 - lstr->avail_out) {
381 fprintf(stderr,
"lzma_putc error\n");
385 return (
unsigned char)c;
392int lzma_printf(
struct lzmafile *file,
const char *format, ...) {
395 unsigned char in[32768];
397 va_start(va, format);
400 (void)vsnprintf((
char *)in, size, format, va);
402 len = strlen((
char *)in);
405 if (len <= 0 || len >= (
int)size || in[size - 1] != 0) {
406 fprintf(stderr,
"lzma_printf error: the printf results do not fit in the buffer\n");
410 len = lzma_write(file, in, len);
415int lzma_eof(
struct lzmafile *file) {
418 if (lstr->avail_in == 0) {
419 return feof(file->fp);
430long lzma_tell(
struct lzmafile *file) {
431 return ftell(file->fp);
434int lzma_seek(
struct lzmafile *file,
long offset,
int whence) {
435 return fseek(file->fp, offset, whence);
438void *UnpackLZMAOpen(
char *filename) {
441 return lzma_open(filename,
"rb");
SDDS (Self Describing Data Set) Data Types Definitions and Function Prototypes.