static int lzmafs_fileop_read(void *ref, uint8_t *buf, int len) { lzmafs_file_t *file = (lzmafs_file_t *) ref; int res = 0; int err; int amtcopy; int ttlcopy = 0; unsigned int in_processed; ELzmaFinishMode finishMode = LZMA_FINISH_ANY; ELzmaStatus status; if (len == 0) return 0; while (len) { /* Figure the amount to copy. This is the min of what we have left to do and what is available. */ amtcopy = len; if (amtcopy > file->lzmafs_outlen) { amtcopy = file->lzmafs_outlen; } /* Copy the data. */ if (buf) { memcpy(buf, file->lzmafs_outptr, amtcopy); buf += amtcopy; } /* Update the pointers. */ file->lzmafs_outptr += amtcopy; file->lzmafs_outlen -= amtcopy; len -= amtcopy; ttlcopy += amtcopy; file->lzmafs_unpackSize -= amtcopy; if (file->lzmafs_unpackSize == 0) { file->lzmafs_eofseen = 1; } /* If we've eaten all of the output, reset and call decode again. */ if (file->lzmafs_outlen == 0) { /* If no input data to decompress, get some more if we can. */ if (file->lzmafs_eofseen) break; if (file->lzmafs_inlen == 0) { file->lzmafs_inlen = BDREAD(file->lzmafs_fsctx->lzmafsctx_subops, file->lzmafs_subfile, file->lzmafs_inbuf, LZMAFS_INBUFSIZE); /* If at EOF or error, get out. */ if (file->lzmafs_inlen <= 0) break; file->lzmafs_inptr = file->lzmafs_inbuf; } in_processed = file->lzmafs_inlen; file->lzmafs_outlen = LZMAFS_OUTBUFSIZE; file->lzmafs_outptr = file->lzmafs_outbuf; if (file->lzmafs_outlen > file->lzmafs_unpackSize) { file->lzmafs_outlen = (SizeT)file->lzmafs_unpackSize; finishMode = LZMA_FINISH_END; } /* decompress the input data. */ err = LzmaDec_DecodeToBuf(file->lzmafs_state, file->lzmafs_outbuf, (SizeT *)&file->lzmafs_outlen, file->lzmafs_inptr, &in_processed, finishMode, &status); file->lzmafs_inptr += in_processed; file->lzmafs_inlen -= in_processed; if (err != SZ_OK) { res = CFE_ERR; break; } } } file->lzmafs_fileoffset += ttlcopy; return (res < 0) ? res : ttlcopy; }
int fs_read(fileio_ctx_t *fsctx,void *ref,uint8_t *buffer,int len) { return BDREAD(fsctx->ops,ref,buffer,len); }
static int lzmafs_fileop_open(void **ref,void *fsctx_arg,char *filename,int mode) { lzmafs_fsctx_t *fsctx; lzmafs_file_t *file; int err = 0, i; /* header: 5 bytes of LZMA properties and 8 bytes of uncompressed size */ unsigned char header[LZMA_PROPS_SIZE + 8]; if (mode != FILE_MODE_READ) return CFE_ERR_UNSUPPORTED; fsctx = (lzmafs_fsctx_t *) fsctx_arg; file = KMALLOC(sizeof(lzmafs_file_t), 0); if (!file) { return CFE_ERR_NOMEM; } file->lzmafs_fileoffset = 0; file->lzmafs_fsctx = fsctx; file->lzmafs_inlen = 0; file->lzmafs_eofseen = 0; file->lzmafs_state = KMALLOC(sizeof(CLzmaDec), 0); if (!file->lzmafs_state) goto error2; file->lzmafs_outlen = 0; /* Open the raw file system */ err = BDOPEN(fsctx->lzmafsctx_subops, &(file->lzmafs_subfile), fsctx->lzmafsctx_subfsctx, filename); if (err != 0) goto error2; err = BDREAD(file->lzmafs_fsctx->lzmafsctx_subops, file->lzmafs_subfile, header, sizeof(header)); if (err < 0) goto error; file->lzmafs_unpackSize = 0; /* uncompressed size */ for (i = 0; i < 8; i++) file->lzmafs_unpackSize += header[LZMA_PROPS_SIZE + i] << (i * 8); LzmaDec_Construct(file->lzmafs_state); RINOK(LzmaDec_Allocate(file->lzmafs_state, header, LZMA_PROPS_SIZE, &g_Alloc)); file->lzmafs_inbuf = KMALLOC(LZMAFS_INBUFSIZE, 0); file->lzmafs_outbuf = KMALLOC(LZMAFS_OUTBUFSIZE, 0); if (!file->lzmafs_inbuf || !file->lzmafs_outbuf) { err = CFE_ERR_NOMEM; goto error; } file->lzmafs_outptr = file->lzmafs_outbuf; LzmaDec_Init(file->lzmafs_state); fsctx->lzmafsctx_refcnt++; *ref = file; return 0; error: BDCLOSE(file->lzmafs_fsctx->lzmafsctx_subops, file->lzmafs_subfile); error2: if (file->lzmafs_inbuf) KFREE(file->lzmafs_inbuf); if (file->lzmafs_outbuf) KFREE(file->lzmafs_outbuf); if (file->lzmafs_state) { LzmaDec_Free(file->lzmafs_state, &g_Alloc); KFREE(file->lzmafs_state); } if (file) KFREE(file); return err; }