SDDS ToolKit Programs and Libraries for C and Python
Loading...
Searching...
No Matches
SDDS_lzma.c File Reference

Detailed Description

Implementation of LZMA-compressed file handling functions.

This file provides a set of functions to work with files compressed using the LZMA compression algorithm. It abstracts the complexities of LZMA stream handling, offering a simple file-like interface for reading from and writing to compressed files.

Features:

  • Open and close LZMA-compressed files.
  • Read and write data with automatic compression/decompression.
  • Support for reading lines and formatted output.
  • Error handling with descriptive messages.
License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Authors
R. Soliday

Definition in file SDDS_lzma.c.

#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdint.h>
#include <string.h>
#include <stdarg.h>
#include <lzma.h>
#include "mdb.h"
#include "mdb_thread.h"

Go to the source code of this file.

Functions

static int SDDS_GetLockedLZMACompressionLevel (void)
 
void SDDS_SetLZMACompressionLevel (int32_t level)
 
int32_t SDDS_GetLZMACompressionLevel (void)
 
void * lzma_open (const char *path, const char *mode)
 
int lzma_close (struct lzmafile *file)
 
long lzma_read (struct lzmafile *file, void *buf, size_t count)
 
char * lzma_gets (char *s, int size, struct lzmafile *file)
 
long lzma_write (struct lzmafile *file, const void *buf, size_t count)
 
int lzma_puts (const char *s, struct lzmafile *file)
 
int lzma_putc (int c, struct lzmafile *file)
 
int lzma_printf (struct lzmafile *file, const char *format,...)
 
int lzma_eof (struct lzmafile *file)
 
long lzma_tell (struct lzmafile *file)
 
int lzma_seek (struct lzmafile *file, long offset, int whence)
 
void * UnpackLZMAOpen (char *filename)
 

Function Documentation

◆ lzma_close()

int lzma_close ( struct lzmafile * file)

Definition at line 136 of file SDDS_lzma.c.

136 {
137 int ret, outsize;
138 unsigned char buf[BUF_SIZE]; /* buffer used when flushing remaining
139 output data in write mode */
140 if (!file)
141 return -1;
142 if (file->mode == 'w') {
143 /* flush LZMA output buffer */
144 for (;;) {
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);
151 fclose(file->fp);
152 free(file);
153 return EOF;
154 }
155 outsize = BUF_SIZE - file->str.avail_out;
156 if (fwrite(buf, 1, outsize, file->fp) != outsize) {
157 lzma_end(&file->str);
158 fclose(file->fp);
159 free(file);
160 return EOF;
161 }
162 if (ret == LZMA_STREAM_END)
163 break;
164 }
165 }
166 lzma_end(&file->str);
167 ret = fclose(file->fp);
168 free(file);
169 return ret;
170}

◆ lzma_eof()

int lzma_eof ( struct lzmafile * file)

Definition at line 415 of file SDDS_lzma.c.

415 {
416 lzma_stream *lstr;
417 lstr = &file->str;
418 if (lstr->avail_in == 0) {
419 return feof(file->fp);
420 } else {
421 return 0;
422 }
423}

◆ lzma_gets()

char * lzma_gets ( char * s,
int size,
struct lzmafile * file )

Definition at line 217 of file SDDS_lzma.c.

217 {
218 int ret;
219 int i = 0;
220 lzma_stream *lstr;
221 if (file->mode != 'r')
222 return NULL;
223 if (s == NULL || size < 1)
224 return NULL;
225 s[0] = '\0';
226 lstr = &file->str;
227 lstr->next_out = (void *)s;
228
229 /* decompress until newline or EOF or output buffer is full */
230 while (1) {
231 if (lstr->avail_in == 0) {
232 /* refill input buffer */
233 ret = fread(file->rdbuf, 1, BUF_SIZE, file->fp);
234 if (ret == 0) {
235 break; /* EOF */
236 }
237 lstr->next_in = file->rdbuf; /* buffer containing lzma data just read */
238 lstr->avail_in = ret; /* number of bytes read */
239 }
240 if (i + 1 == size) {
241 s[i] = '\0';
242 break;
243 }
244 lstr->avail_out = 1;
245 ret = lzma_code(lstr, LZMA_RUN);
246 /* this fills up lstr->next_out and decreases lstr->avail_out */
247 /* it also emptys lstr->next_in and decreases lstr->avail_in */
248 if (ret != LZMA_OK && ret != LZMA_STREAM_END) {
249 fprintf(stderr, "lzma_gets error: decoding failed: %d\n", ret);
250 return NULL;
251 }
252 if (ret == LZMA_STREAM_END) { /* EOF */
253 s[i + 1] = '\0';
254 break;
255 }
256 if (s[i] == 10) { /* 10 is the value for \n */
257 if (i > 0) { /* we sometimes get \10\10 */
258 if ((i == 1) && (s[0] == 32)) {
259 /* when uncompressing the lzma stream we some times end
260 up with \10\32\10 instead of a simple \10 */
261 } else {
262 s[i + 1] = '\0';
263 break;
264 }
265 }
266 }
267 i++;
268 }
269 return s;
270}

◆ lzma_open()

void * lzma_open ( const char * path,
const char * mode )

Definition at line 99 of file SDDS_lzma.c.

99 {
100 int ret;
101
102 /* initialize LZMA stream */
103 struct lzmafile *lf = malloc(sizeof(struct lzmafile));
104 if (!lf)
105 return NULL;
106 lf->fp = fopen(path, mode);
107 if (!lf->fp) {
108 free(lf);
109 return NULL;
110 }
111 lf->str = lzma_stream_init;
112 lf->mode = mode[0];
113 if (mode[0] == 'r') {
114#if LZMA_VERSION <= UINT32_C(49990030)
115 ret = lzma_auto_decoder(&lf->str, NULL, NULL);
116#else
117 ret = lzma_auto_decoder(&lf->str, -1, 0);
118#endif
119 lf->str.avail_in = 0;
120 } else {
121 ret = LZMA_EASY_ENCODER(&lf->str, SDDS_GetLockedLZMACompressionLevel());
122 }
123 if (ret != LZMA_OK) {
124 fprintf(stderr, "lzma_open error: %d\n", ret);
125 lzma_end(&lf->str);
126 fclose(lf->fp);
127 free(lf);
128 return NULL;
129 }
130 return (void *)lf;
131}

◆ lzma_printf()

int lzma_printf ( struct lzmafile * file,
const char * format,
... )

Definition at line 392 of file SDDS_lzma.c.

392 {
393 size_t size = 32768;
394 int len;
395 unsigned char in[32768];
396 va_list va;
397 va_start(va, format);
398
399 in[size - 1] = 0;
400 (void)vsnprintf((char *)in, size, format, va);
401 va_end(va);
402 len = strlen((char *)in);
403
404 /* check that printf() results fit in buffer */
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");
407 return -1;
408 }
409 in[len] = '\0';
410 len = lzma_write(file, in, len);
411
412 return len;
413}

◆ lzma_putc()

int lzma_putc ( int c,
struct lzmafile * file )

Definition at line 356 of file SDDS_lzma.c.

356 {
357 int ret;
358 lzma_stream *lstr = &file->str;
359
360 unsigned char bufout[1]; /* compressed output buffer */
361 char buf[1];
362
363 if (file->mode != 'w') {
364 fprintf(stderr, "lzma_putc error: file was not opened for writting\n");
365 return EOF;
366 }
367 buf[0] = c;
368
369 lstr->next_in = (void *)buf;
370 lstr->avail_in = 1;
371 while (lstr->avail_in) {
372 lstr->next_out = bufout;
373 lstr->avail_out = 1;
374 ret = lzma_code(lstr, LZMA_RUN);
375 if (ret != LZMA_OK) {
376 fprintf(stderr, "lzma_putc error: encoding failed: %d\n", ret);
377 return EOF;
378 }
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");
382 return EOF;
383 }
384 }
385 return (unsigned char)c;
386}

◆ lzma_puts()

int lzma_puts ( const char * s,
struct lzmafile * file )

Definition at line 311 of file SDDS_lzma.c.

311 {
312 int ret;
313 lzma_stream *lstr = &file->str;
314 int count;
315 unsigned char *bufout; /* compressed output buffer */
316 char *buf;
317
318 if (file->mode != 'w') {
319 fprintf(stderr, "lzma_puts error: file was not opened for writting\n");
320 return EOF;
321 }
322 count = strlen(s);
323 bufout = malloc(sizeof(unsigned char) * count);
324 buf = malloc(sizeof(char) * count);
325 //strncpy(buf, s, count);
326 memcpy(buf, s, count);
327
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);
336 free(bufout);
337 free(buf);
338 return EOF;
339 }
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");
343 free(bufout);
344 free(buf);
345 return EOF;
346 }
347 }
348 free(bufout);
349 free(buf);
350 return count;
351}

◆ lzma_read()

long lzma_read ( struct lzmafile * file,
void * buf,
size_t count )

Definition at line 176 of file SDDS_lzma.c.

176 {
177 int ret;
178 lzma_stream *lstr;
179 if (file->mode != 'r')
180 return -1;
181
182 lstr = &file->str;
183 lstr->next_out = buf;
184 lstr->avail_out = count;
185
186 /* decompress until EOF or output buffer is full */
187 while (lstr->avail_out) {
188 if (lstr->avail_in == 0) {
189 /* refill input buffer */
190 ret = fread(file->rdbuf, 1, BUF_SIZE, file->fp);
191 if (ret == 0) {
192 break; /* EOF */
193 }
194 lstr->next_in = file->rdbuf; /* buffer containing lzma data just read */
195 lstr->avail_in = ret; /* number of bytes read */
196 }
197 ret = lzma_code(lstr, LZMA_RUN);
198 /* this fills up lstr->next_out and decreases lstr->avail_out */
199 /* it also emptys lstr->next_in and decreases lstr->avail_in */
200 if (ret != LZMA_OK && ret != LZMA_STREAM_END) {
201 fprintf(stderr, "lzma_read error: decoding failed: %d\n", ret);
202 return -1;
203 }
204 if (ret == LZMA_STREAM_END) {
205 break; /* EOF */
206 }
207 }
208 return count - lstr->avail_out; /* length of buf that has valid data */
209}

◆ lzma_seek()

int lzma_seek ( struct lzmafile * file,
long offset,
int whence )

Definition at line 434 of file SDDS_lzma.c.

434 {
435 return fseek(file->fp, offset, whence);
436}

◆ lzma_tell()

long lzma_tell ( struct lzmafile * file)

Definition at line 430 of file SDDS_lzma.c.

430 {
431 return ftell(file->fp);
432}

◆ lzma_write()

long lzma_write ( struct lzmafile * file,
const void * buf,
size_t count )

Definition at line 275 of file SDDS_lzma.c.

275 {
276 int ret;
277 lzma_stream *lstr = &file->str;
278 unsigned char *bufout; /* compressed output buffer */
279 bufout = malloc(sizeof(char) * count);
280
281 if (file->mode != 'w') {
282 fprintf(stderr, "lzma_write error: file was not opened for writting\n");
283 free(bufout);
284 return -1;
285 }
286 lstr->next_in = buf;
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);
294 free(bufout);
295 return -1;
296 }
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");
300 free(bufout);
301 return -1;
302 }
303 }
304 free(bufout);
305 return count;
306}

◆ SDDS_GetLockedLZMACompressionLevel()

static int SDDS_GetLockedLZMACompressionLevel ( void )
static

Definition at line 75 of file SDDS_lzma.c.

75 {
76 int level;
77 mdb_thread_lock(&lzmaCompressionLevelLock);
78 level = lzmaCompressionLevel;
79 mdb_thread_unlock(&lzmaCompressionLevelLock);
80 return level;
81}

◆ SDDS_GetLZMACompressionLevel()

int32_t SDDS_GetLZMACompressionLevel ( void )

Definition at line 91 of file SDDS_lzma.c.

91 {
92 return SDDS_GetLockedLZMACompressionLevel();
93}

◆ SDDS_SetLZMACompressionLevel()

void SDDS_SetLZMACompressionLevel ( int32_t level)

Definition at line 83 of file SDDS_lzma.c.

83 {
84 if (level >= 0 && level <= 9) {
85 mdb_thread_lock(&lzmaCompressionLevelLock);
86 lzmaCompressionLevel = level;
87 mdb_thread_unlock(&lzmaCompressionLevelLock);
88 }
89}

◆ UnpackLZMAOpen()

void * UnpackLZMAOpen ( char * filename)

Definition at line 438 of file SDDS_lzma.c.

438 {
439 if (!filename)
440 return NULL;
441 return lzma_open(filename, "rb");
442}