1*27162e4eSAndroid Build Coastguard Worker /*
2*27162e4eSAndroid Build Coastguard Worker * LZ4 file library
3*27162e4eSAndroid Build Coastguard Worker * Copyright (C) 2022, Xiaomi Inc.
4*27162e4eSAndroid Build Coastguard Worker *
5*27162e4eSAndroid Build Coastguard Worker * BSD 2-Clause License (http://www.opensource.org/licenses/bsd-license.php)
6*27162e4eSAndroid Build Coastguard Worker *
7*27162e4eSAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
8*27162e4eSAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions are
9*27162e4eSAndroid Build Coastguard Worker * met:
10*27162e4eSAndroid Build Coastguard Worker *
11*27162e4eSAndroid Build Coastguard Worker * - Redistributions of source code must retain the above copyright
12*27162e4eSAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
13*27162e4eSAndroid Build Coastguard Worker * - Redistributions in binary form must reproduce the above
14*27162e4eSAndroid Build Coastguard Worker * copyright notice, this list of conditions and the following disclaimer
15*27162e4eSAndroid Build Coastguard Worker * in the documentation and/or other materials provided with the
16*27162e4eSAndroid Build Coastguard Worker * distribution.
17*27162e4eSAndroid Build Coastguard Worker *
18*27162e4eSAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19*27162e4eSAndroid Build Coastguard Worker * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20*27162e4eSAndroid Build Coastguard Worker * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21*27162e4eSAndroid Build Coastguard Worker * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22*27162e4eSAndroid Build Coastguard Worker * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23*27162e4eSAndroid Build Coastguard Worker * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24*27162e4eSAndroid Build Coastguard Worker * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25*27162e4eSAndroid Build Coastguard Worker * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26*27162e4eSAndroid Build Coastguard Worker * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27*27162e4eSAndroid Build Coastguard Worker * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28*27162e4eSAndroid Build Coastguard Worker * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29*27162e4eSAndroid Build Coastguard Worker *
30*27162e4eSAndroid Build Coastguard Worker * You can contact the author at :
31*27162e4eSAndroid Build Coastguard Worker * - LZ4 homepage : http://www.lz4.org
32*27162e4eSAndroid Build Coastguard Worker * - LZ4 source repository : https://github.com/lz4/lz4
33*27162e4eSAndroid Build Coastguard Worker */
34*27162e4eSAndroid Build Coastguard Worker #include <stdlib.h> /* malloc, free */
35*27162e4eSAndroid Build Coastguard Worker #include <string.h>
36*27162e4eSAndroid Build Coastguard Worker #include <assert.h>
37*27162e4eSAndroid Build Coastguard Worker #include "lz4.h"
38*27162e4eSAndroid Build Coastguard Worker #include "lz4file.h"
39*27162e4eSAndroid Build Coastguard Worker
returnErrorCode(LZ4F_errorCodes code)40*27162e4eSAndroid Build Coastguard Worker static LZ4F_errorCode_t returnErrorCode(LZ4F_errorCodes code)
41*27162e4eSAndroid Build Coastguard Worker {
42*27162e4eSAndroid Build Coastguard Worker return (LZ4F_errorCode_t)-(ptrdiff_t)code;
43*27162e4eSAndroid Build Coastguard Worker }
44*27162e4eSAndroid Build Coastguard Worker #undef RETURN_ERROR
45*27162e4eSAndroid Build Coastguard Worker #define RETURN_ERROR(e) return returnErrorCode(LZ4F_ERROR_ ## e)
46*27162e4eSAndroid Build Coastguard Worker
47*27162e4eSAndroid Build Coastguard Worker /* ===== read API ===== */
48*27162e4eSAndroid Build Coastguard Worker
49*27162e4eSAndroid Build Coastguard Worker struct LZ4_readFile_s {
50*27162e4eSAndroid Build Coastguard Worker LZ4F_dctx* dctxPtr;
51*27162e4eSAndroid Build Coastguard Worker FILE* fp;
52*27162e4eSAndroid Build Coastguard Worker LZ4_byte* srcBuf;
53*27162e4eSAndroid Build Coastguard Worker size_t srcBufNext;
54*27162e4eSAndroid Build Coastguard Worker size_t srcBufSize;
55*27162e4eSAndroid Build Coastguard Worker size_t srcBufMaxSize;
56*27162e4eSAndroid Build Coastguard Worker };
57*27162e4eSAndroid Build Coastguard Worker
LZ4F_freeReadFile(LZ4_readFile_t * lz4fRead)58*27162e4eSAndroid Build Coastguard Worker static void LZ4F_freeReadFile(LZ4_readFile_t* lz4fRead)
59*27162e4eSAndroid Build Coastguard Worker {
60*27162e4eSAndroid Build Coastguard Worker if (lz4fRead==NULL) return;
61*27162e4eSAndroid Build Coastguard Worker LZ4F_freeDecompressionContext(lz4fRead->dctxPtr);
62*27162e4eSAndroid Build Coastguard Worker free(lz4fRead->srcBuf);
63*27162e4eSAndroid Build Coastguard Worker free(lz4fRead);
64*27162e4eSAndroid Build Coastguard Worker }
65*27162e4eSAndroid Build Coastguard Worker
LZ4F_freeAndNullReadFile(LZ4_readFile_t ** statePtr)66*27162e4eSAndroid Build Coastguard Worker static void LZ4F_freeAndNullReadFile(LZ4_readFile_t** statePtr)
67*27162e4eSAndroid Build Coastguard Worker {
68*27162e4eSAndroid Build Coastguard Worker assert(statePtr != NULL);
69*27162e4eSAndroid Build Coastguard Worker LZ4F_freeReadFile(*statePtr);
70*27162e4eSAndroid Build Coastguard Worker *statePtr = NULL;
71*27162e4eSAndroid Build Coastguard Worker }
72*27162e4eSAndroid Build Coastguard Worker
LZ4F_readOpen(LZ4_readFile_t ** lz4fRead,FILE * fp)73*27162e4eSAndroid Build Coastguard Worker LZ4F_errorCode_t LZ4F_readOpen(LZ4_readFile_t** lz4fRead, FILE* fp)
74*27162e4eSAndroid Build Coastguard Worker {
75*27162e4eSAndroid Build Coastguard Worker char buf[LZ4F_HEADER_SIZE_MAX];
76*27162e4eSAndroid Build Coastguard Worker size_t consumedSize;
77*27162e4eSAndroid Build Coastguard Worker LZ4F_errorCode_t ret;
78*27162e4eSAndroid Build Coastguard Worker
79*27162e4eSAndroid Build Coastguard Worker if (fp == NULL || lz4fRead == NULL) {
80*27162e4eSAndroid Build Coastguard Worker RETURN_ERROR(parameter_null);
81*27162e4eSAndroid Build Coastguard Worker }
82*27162e4eSAndroid Build Coastguard Worker
83*27162e4eSAndroid Build Coastguard Worker *lz4fRead = (LZ4_readFile_t*)calloc(1, sizeof(LZ4_readFile_t));
84*27162e4eSAndroid Build Coastguard Worker if (*lz4fRead == NULL) {
85*27162e4eSAndroid Build Coastguard Worker RETURN_ERROR(allocation_failed);
86*27162e4eSAndroid Build Coastguard Worker }
87*27162e4eSAndroid Build Coastguard Worker
88*27162e4eSAndroid Build Coastguard Worker ret = LZ4F_createDecompressionContext(&(*lz4fRead)->dctxPtr, LZ4F_VERSION);
89*27162e4eSAndroid Build Coastguard Worker if (LZ4F_isError(ret)) {
90*27162e4eSAndroid Build Coastguard Worker LZ4F_freeAndNullReadFile(lz4fRead);
91*27162e4eSAndroid Build Coastguard Worker return ret;
92*27162e4eSAndroid Build Coastguard Worker }
93*27162e4eSAndroid Build Coastguard Worker
94*27162e4eSAndroid Build Coastguard Worker (*lz4fRead)->fp = fp;
95*27162e4eSAndroid Build Coastguard Worker consumedSize = fread(buf, 1, sizeof(buf), (*lz4fRead)->fp);
96*27162e4eSAndroid Build Coastguard Worker if (consumedSize != sizeof(buf)) {
97*27162e4eSAndroid Build Coastguard Worker LZ4F_freeAndNullReadFile(lz4fRead);
98*27162e4eSAndroid Build Coastguard Worker RETURN_ERROR(io_read);
99*27162e4eSAndroid Build Coastguard Worker }
100*27162e4eSAndroid Build Coastguard Worker
101*27162e4eSAndroid Build Coastguard Worker { LZ4F_frameInfo_t info;
102*27162e4eSAndroid Build Coastguard Worker LZ4F_errorCode_t const r = LZ4F_getFrameInfo((*lz4fRead)->dctxPtr, &info, buf, &consumedSize);
103*27162e4eSAndroid Build Coastguard Worker if (LZ4F_isError(r)) {
104*27162e4eSAndroid Build Coastguard Worker LZ4F_freeAndNullReadFile(lz4fRead);
105*27162e4eSAndroid Build Coastguard Worker return r;
106*27162e4eSAndroid Build Coastguard Worker }
107*27162e4eSAndroid Build Coastguard Worker
108*27162e4eSAndroid Build Coastguard Worker switch (info.blockSizeID) {
109*27162e4eSAndroid Build Coastguard Worker case LZ4F_default :
110*27162e4eSAndroid Build Coastguard Worker case LZ4F_max64KB :
111*27162e4eSAndroid Build Coastguard Worker (*lz4fRead)->srcBufMaxSize = 64 * 1024;
112*27162e4eSAndroid Build Coastguard Worker break;
113*27162e4eSAndroid Build Coastguard Worker case LZ4F_max256KB:
114*27162e4eSAndroid Build Coastguard Worker (*lz4fRead)->srcBufMaxSize = 256 * 1024;
115*27162e4eSAndroid Build Coastguard Worker break;
116*27162e4eSAndroid Build Coastguard Worker case LZ4F_max1MB:
117*27162e4eSAndroid Build Coastguard Worker (*lz4fRead)->srcBufMaxSize = 1 * 1024 * 1024;
118*27162e4eSAndroid Build Coastguard Worker break;
119*27162e4eSAndroid Build Coastguard Worker case LZ4F_max4MB:
120*27162e4eSAndroid Build Coastguard Worker (*lz4fRead)->srcBufMaxSize = 4 * 1024 * 1024;
121*27162e4eSAndroid Build Coastguard Worker break;
122*27162e4eSAndroid Build Coastguard Worker default:
123*27162e4eSAndroid Build Coastguard Worker LZ4F_freeAndNullReadFile(lz4fRead);
124*27162e4eSAndroid Build Coastguard Worker RETURN_ERROR(maxBlockSize_invalid);
125*27162e4eSAndroid Build Coastguard Worker }
126*27162e4eSAndroid Build Coastguard Worker }
127*27162e4eSAndroid Build Coastguard Worker
128*27162e4eSAndroid Build Coastguard Worker (*lz4fRead)->srcBuf = (LZ4_byte*)malloc((*lz4fRead)->srcBufMaxSize);
129*27162e4eSAndroid Build Coastguard Worker if ((*lz4fRead)->srcBuf == NULL) {
130*27162e4eSAndroid Build Coastguard Worker LZ4F_freeAndNullReadFile(lz4fRead);
131*27162e4eSAndroid Build Coastguard Worker RETURN_ERROR(allocation_failed);
132*27162e4eSAndroid Build Coastguard Worker }
133*27162e4eSAndroid Build Coastguard Worker
134*27162e4eSAndroid Build Coastguard Worker (*lz4fRead)->srcBufSize = sizeof(buf) - consumedSize;
135*27162e4eSAndroid Build Coastguard Worker memcpy((*lz4fRead)->srcBuf, buf + consumedSize, (*lz4fRead)->srcBufSize);
136*27162e4eSAndroid Build Coastguard Worker
137*27162e4eSAndroid Build Coastguard Worker return ret;
138*27162e4eSAndroid Build Coastguard Worker }
139*27162e4eSAndroid Build Coastguard Worker
LZ4F_read(LZ4_readFile_t * lz4fRead,void * buf,size_t size)140*27162e4eSAndroid Build Coastguard Worker size_t LZ4F_read(LZ4_readFile_t* lz4fRead, void* buf, size_t size)
141*27162e4eSAndroid Build Coastguard Worker {
142*27162e4eSAndroid Build Coastguard Worker LZ4_byte* p = (LZ4_byte*)buf;
143*27162e4eSAndroid Build Coastguard Worker size_t next = 0;
144*27162e4eSAndroid Build Coastguard Worker
145*27162e4eSAndroid Build Coastguard Worker if (lz4fRead == NULL || buf == NULL)
146*27162e4eSAndroid Build Coastguard Worker RETURN_ERROR(parameter_null);
147*27162e4eSAndroid Build Coastguard Worker
148*27162e4eSAndroid Build Coastguard Worker while (next < size) {
149*27162e4eSAndroid Build Coastguard Worker size_t srcsize = lz4fRead->srcBufSize - lz4fRead->srcBufNext;
150*27162e4eSAndroid Build Coastguard Worker size_t dstsize = size - next;
151*27162e4eSAndroid Build Coastguard Worker size_t ret;
152*27162e4eSAndroid Build Coastguard Worker
153*27162e4eSAndroid Build Coastguard Worker if (srcsize == 0) {
154*27162e4eSAndroid Build Coastguard Worker ret = fread(lz4fRead->srcBuf, 1, lz4fRead->srcBufMaxSize, lz4fRead->fp);
155*27162e4eSAndroid Build Coastguard Worker if (ret > 0) {
156*27162e4eSAndroid Build Coastguard Worker lz4fRead->srcBufSize = ret;
157*27162e4eSAndroid Build Coastguard Worker srcsize = lz4fRead->srcBufSize;
158*27162e4eSAndroid Build Coastguard Worker lz4fRead->srcBufNext = 0;
159*27162e4eSAndroid Build Coastguard Worker } else if (ret == 0) {
160*27162e4eSAndroid Build Coastguard Worker break;
161*27162e4eSAndroid Build Coastguard Worker } else {
162*27162e4eSAndroid Build Coastguard Worker RETURN_ERROR(io_read);
163*27162e4eSAndroid Build Coastguard Worker }
164*27162e4eSAndroid Build Coastguard Worker }
165*27162e4eSAndroid Build Coastguard Worker
166*27162e4eSAndroid Build Coastguard Worker ret = LZ4F_decompress(lz4fRead->dctxPtr,
167*27162e4eSAndroid Build Coastguard Worker p, &dstsize,
168*27162e4eSAndroid Build Coastguard Worker lz4fRead->srcBuf + lz4fRead->srcBufNext,
169*27162e4eSAndroid Build Coastguard Worker &srcsize,
170*27162e4eSAndroid Build Coastguard Worker NULL);
171*27162e4eSAndroid Build Coastguard Worker if (LZ4F_isError(ret)) {
172*27162e4eSAndroid Build Coastguard Worker return ret;
173*27162e4eSAndroid Build Coastguard Worker }
174*27162e4eSAndroid Build Coastguard Worker
175*27162e4eSAndroid Build Coastguard Worker lz4fRead->srcBufNext += srcsize;
176*27162e4eSAndroid Build Coastguard Worker next += dstsize;
177*27162e4eSAndroid Build Coastguard Worker p += dstsize;
178*27162e4eSAndroid Build Coastguard Worker }
179*27162e4eSAndroid Build Coastguard Worker
180*27162e4eSAndroid Build Coastguard Worker return next;
181*27162e4eSAndroid Build Coastguard Worker }
182*27162e4eSAndroid Build Coastguard Worker
LZ4F_readClose(LZ4_readFile_t * lz4fRead)183*27162e4eSAndroid Build Coastguard Worker LZ4F_errorCode_t LZ4F_readClose(LZ4_readFile_t* lz4fRead)
184*27162e4eSAndroid Build Coastguard Worker {
185*27162e4eSAndroid Build Coastguard Worker if (lz4fRead == NULL)
186*27162e4eSAndroid Build Coastguard Worker RETURN_ERROR(parameter_null);
187*27162e4eSAndroid Build Coastguard Worker LZ4F_freeReadFile(lz4fRead);
188*27162e4eSAndroid Build Coastguard Worker return LZ4F_OK_NoError;
189*27162e4eSAndroid Build Coastguard Worker }
190*27162e4eSAndroid Build Coastguard Worker
191*27162e4eSAndroid Build Coastguard Worker /* ===== write API ===== */
192*27162e4eSAndroid Build Coastguard Worker
193*27162e4eSAndroid Build Coastguard Worker struct LZ4_writeFile_s {
194*27162e4eSAndroid Build Coastguard Worker LZ4F_cctx* cctxPtr;
195*27162e4eSAndroid Build Coastguard Worker FILE* fp;
196*27162e4eSAndroid Build Coastguard Worker LZ4_byte* dstBuf;
197*27162e4eSAndroid Build Coastguard Worker size_t maxWriteSize;
198*27162e4eSAndroid Build Coastguard Worker size_t dstBufMaxSize;
199*27162e4eSAndroid Build Coastguard Worker LZ4F_errorCode_t errCode;
200*27162e4eSAndroid Build Coastguard Worker };
201*27162e4eSAndroid Build Coastguard Worker
LZ4F_freeWriteFile(LZ4_writeFile_t * state)202*27162e4eSAndroid Build Coastguard Worker static void LZ4F_freeWriteFile(LZ4_writeFile_t* state)
203*27162e4eSAndroid Build Coastguard Worker {
204*27162e4eSAndroid Build Coastguard Worker if (state == NULL) return;
205*27162e4eSAndroid Build Coastguard Worker LZ4F_freeCompressionContext(state->cctxPtr);
206*27162e4eSAndroid Build Coastguard Worker free(state->dstBuf);
207*27162e4eSAndroid Build Coastguard Worker free(state);
208*27162e4eSAndroid Build Coastguard Worker }
209*27162e4eSAndroid Build Coastguard Worker
LZ4F_freeAndNullWriteFile(LZ4_writeFile_t ** statePtr)210*27162e4eSAndroid Build Coastguard Worker static void LZ4F_freeAndNullWriteFile(LZ4_writeFile_t** statePtr)
211*27162e4eSAndroid Build Coastguard Worker {
212*27162e4eSAndroid Build Coastguard Worker assert(statePtr != NULL);
213*27162e4eSAndroid Build Coastguard Worker LZ4F_freeWriteFile(*statePtr);
214*27162e4eSAndroid Build Coastguard Worker *statePtr = NULL;
215*27162e4eSAndroid Build Coastguard Worker }
216*27162e4eSAndroid Build Coastguard Worker
LZ4F_writeOpen(LZ4_writeFile_t ** lz4fWrite,FILE * fp,const LZ4F_preferences_t * prefsPtr)217*27162e4eSAndroid Build Coastguard Worker LZ4F_errorCode_t LZ4F_writeOpen(LZ4_writeFile_t** lz4fWrite, FILE* fp, const LZ4F_preferences_t* prefsPtr)
218*27162e4eSAndroid Build Coastguard Worker {
219*27162e4eSAndroid Build Coastguard Worker LZ4_byte buf[LZ4F_HEADER_SIZE_MAX];
220*27162e4eSAndroid Build Coastguard Worker size_t ret;
221*27162e4eSAndroid Build Coastguard Worker
222*27162e4eSAndroid Build Coastguard Worker if (fp == NULL || lz4fWrite == NULL)
223*27162e4eSAndroid Build Coastguard Worker RETURN_ERROR(parameter_null);
224*27162e4eSAndroid Build Coastguard Worker
225*27162e4eSAndroid Build Coastguard Worker *lz4fWrite = (LZ4_writeFile_t*)calloc(1, sizeof(LZ4_writeFile_t));
226*27162e4eSAndroid Build Coastguard Worker if (*lz4fWrite == NULL) {
227*27162e4eSAndroid Build Coastguard Worker RETURN_ERROR(allocation_failed);
228*27162e4eSAndroid Build Coastguard Worker }
229*27162e4eSAndroid Build Coastguard Worker if (prefsPtr != NULL) {
230*27162e4eSAndroid Build Coastguard Worker switch (prefsPtr->frameInfo.blockSizeID) {
231*27162e4eSAndroid Build Coastguard Worker case LZ4F_default :
232*27162e4eSAndroid Build Coastguard Worker case LZ4F_max64KB :
233*27162e4eSAndroid Build Coastguard Worker (*lz4fWrite)->maxWriteSize = 64 * 1024;
234*27162e4eSAndroid Build Coastguard Worker break;
235*27162e4eSAndroid Build Coastguard Worker case LZ4F_max256KB:
236*27162e4eSAndroid Build Coastguard Worker (*lz4fWrite)->maxWriteSize = 256 * 1024;
237*27162e4eSAndroid Build Coastguard Worker break;
238*27162e4eSAndroid Build Coastguard Worker case LZ4F_max1MB:
239*27162e4eSAndroid Build Coastguard Worker (*lz4fWrite)->maxWriteSize = 1 * 1024 * 1024;
240*27162e4eSAndroid Build Coastguard Worker break;
241*27162e4eSAndroid Build Coastguard Worker case LZ4F_max4MB:
242*27162e4eSAndroid Build Coastguard Worker (*lz4fWrite)->maxWriteSize = 4 * 1024 * 1024;
243*27162e4eSAndroid Build Coastguard Worker break;
244*27162e4eSAndroid Build Coastguard Worker default:
245*27162e4eSAndroid Build Coastguard Worker LZ4F_freeAndNullWriteFile(lz4fWrite);
246*27162e4eSAndroid Build Coastguard Worker RETURN_ERROR(maxBlockSize_invalid);
247*27162e4eSAndroid Build Coastguard Worker }
248*27162e4eSAndroid Build Coastguard Worker } else {
249*27162e4eSAndroid Build Coastguard Worker (*lz4fWrite)->maxWriteSize = 64 * 1024;
250*27162e4eSAndroid Build Coastguard Worker }
251*27162e4eSAndroid Build Coastguard Worker
252*27162e4eSAndroid Build Coastguard Worker (*lz4fWrite)->dstBufMaxSize = LZ4F_compressBound((*lz4fWrite)->maxWriteSize, prefsPtr);
253*27162e4eSAndroid Build Coastguard Worker (*lz4fWrite)->dstBuf = (LZ4_byte*)malloc((*lz4fWrite)->dstBufMaxSize);
254*27162e4eSAndroid Build Coastguard Worker if ((*lz4fWrite)->dstBuf == NULL) {
255*27162e4eSAndroid Build Coastguard Worker LZ4F_freeAndNullWriteFile(lz4fWrite);
256*27162e4eSAndroid Build Coastguard Worker RETURN_ERROR(allocation_failed);
257*27162e4eSAndroid Build Coastguard Worker }
258*27162e4eSAndroid Build Coastguard Worker
259*27162e4eSAndroid Build Coastguard Worker ret = LZ4F_createCompressionContext(&(*lz4fWrite)->cctxPtr, LZ4F_VERSION);
260*27162e4eSAndroid Build Coastguard Worker if (LZ4F_isError(ret)) {
261*27162e4eSAndroid Build Coastguard Worker LZ4F_freeAndNullWriteFile(lz4fWrite);
262*27162e4eSAndroid Build Coastguard Worker return ret;
263*27162e4eSAndroid Build Coastguard Worker }
264*27162e4eSAndroid Build Coastguard Worker
265*27162e4eSAndroid Build Coastguard Worker ret = LZ4F_compressBegin((*lz4fWrite)->cctxPtr, buf, LZ4F_HEADER_SIZE_MAX, prefsPtr);
266*27162e4eSAndroid Build Coastguard Worker if (LZ4F_isError(ret)) {
267*27162e4eSAndroid Build Coastguard Worker LZ4F_freeAndNullWriteFile(lz4fWrite);
268*27162e4eSAndroid Build Coastguard Worker return ret;
269*27162e4eSAndroid Build Coastguard Worker }
270*27162e4eSAndroid Build Coastguard Worker
271*27162e4eSAndroid Build Coastguard Worker if (ret != fwrite(buf, 1, ret, fp)) {
272*27162e4eSAndroid Build Coastguard Worker LZ4F_freeAndNullWriteFile(lz4fWrite);
273*27162e4eSAndroid Build Coastguard Worker RETURN_ERROR(io_write);
274*27162e4eSAndroid Build Coastguard Worker }
275*27162e4eSAndroid Build Coastguard Worker
276*27162e4eSAndroid Build Coastguard Worker (*lz4fWrite)->fp = fp;
277*27162e4eSAndroid Build Coastguard Worker (*lz4fWrite)->errCode = LZ4F_OK_NoError;
278*27162e4eSAndroid Build Coastguard Worker return LZ4F_OK_NoError;
279*27162e4eSAndroid Build Coastguard Worker }
280*27162e4eSAndroid Build Coastguard Worker
LZ4F_write(LZ4_writeFile_t * lz4fWrite,const void * buf,size_t size)281*27162e4eSAndroid Build Coastguard Worker size_t LZ4F_write(LZ4_writeFile_t* lz4fWrite, const void* buf, size_t size)
282*27162e4eSAndroid Build Coastguard Worker {
283*27162e4eSAndroid Build Coastguard Worker const LZ4_byte* p = (const LZ4_byte*)buf;
284*27162e4eSAndroid Build Coastguard Worker size_t remain = size;
285*27162e4eSAndroid Build Coastguard Worker size_t chunk;
286*27162e4eSAndroid Build Coastguard Worker size_t ret;
287*27162e4eSAndroid Build Coastguard Worker
288*27162e4eSAndroid Build Coastguard Worker if (lz4fWrite == NULL || buf == NULL)
289*27162e4eSAndroid Build Coastguard Worker RETURN_ERROR(parameter_null);
290*27162e4eSAndroid Build Coastguard Worker while (remain) {
291*27162e4eSAndroid Build Coastguard Worker if (remain > lz4fWrite->maxWriteSize)
292*27162e4eSAndroid Build Coastguard Worker chunk = lz4fWrite->maxWriteSize;
293*27162e4eSAndroid Build Coastguard Worker else
294*27162e4eSAndroid Build Coastguard Worker chunk = remain;
295*27162e4eSAndroid Build Coastguard Worker
296*27162e4eSAndroid Build Coastguard Worker ret = LZ4F_compressUpdate(lz4fWrite->cctxPtr,
297*27162e4eSAndroid Build Coastguard Worker lz4fWrite->dstBuf, lz4fWrite->dstBufMaxSize,
298*27162e4eSAndroid Build Coastguard Worker p, chunk,
299*27162e4eSAndroid Build Coastguard Worker NULL);
300*27162e4eSAndroid Build Coastguard Worker if (LZ4F_isError(ret)) {
301*27162e4eSAndroid Build Coastguard Worker lz4fWrite->errCode = ret;
302*27162e4eSAndroid Build Coastguard Worker return ret;
303*27162e4eSAndroid Build Coastguard Worker }
304*27162e4eSAndroid Build Coastguard Worker
305*27162e4eSAndroid Build Coastguard Worker if (ret != fwrite(lz4fWrite->dstBuf, 1, ret, lz4fWrite->fp)) {
306*27162e4eSAndroid Build Coastguard Worker lz4fWrite->errCode = returnErrorCode(LZ4F_ERROR_io_write);
307*27162e4eSAndroid Build Coastguard Worker RETURN_ERROR(io_write);
308*27162e4eSAndroid Build Coastguard Worker }
309*27162e4eSAndroid Build Coastguard Worker
310*27162e4eSAndroid Build Coastguard Worker p += chunk;
311*27162e4eSAndroid Build Coastguard Worker remain -= chunk;
312*27162e4eSAndroid Build Coastguard Worker }
313*27162e4eSAndroid Build Coastguard Worker
314*27162e4eSAndroid Build Coastguard Worker return size;
315*27162e4eSAndroid Build Coastguard Worker }
316*27162e4eSAndroid Build Coastguard Worker
LZ4F_writeClose(LZ4_writeFile_t * lz4fWrite)317*27162e4eSAndroid Build Coastguard Worker LZ4F_errorCode_t LZ4F_writeClose(LZ4_writeFile_t* lz4fWrite)
318*27162e4eSAndroid Build Coastguard Worker {
319*27162e4eSAndroid Build Coastguard Worker LZ4F_errorCode_t ret = LZ4F_OK_NoError;
320*27162e4eSAndroid Build Coastguard Worker
321*27162e4eSAndroid Build Coastguard Worker if (lz4fWrite == NULL) {
322*27162e4eSAndroid Build Coastguard Worker RETURN_ERROR(parameter_null);
323*27162e4eSAndroid Build Coastguard Worker }
324*27162e4eSAndroid Build Coastguard Worker
325*27162e4eSAndroid Build Coastguard Worker if (lz4fWrite->errCode == LZ4F_OK_NoError) {
326*27162e4eSAndroid Build Coastguard Worker ret = LZ4F_compressEnd(lz4fWrite->cctxPtr,
327*27162e4eSAndroid Build Coastguard Worker lz4fWrite->dstBuf, lz4fWrite->dstBufMaxSize,
328*27162e4eSAndroid Build Coastguard Worker NULL);
329*27162e4eSAndroid Build Coastguard Worker if (LZ4F_isError(ret)) {
330*27162e4eSAndroid Build Coastguard Worker goto out;
331*27162e4eSAndroid Build Coastguard Worker }
332*27162e4eSAndroid Build Coastguard Worker
333*27162e4eSAndroid Build Coastguard Worker if (ret != fwrite(lz4fWrite->dstBuf, 1, ret, lz4fWrite->fp)) {
334*27162e4eSAndroid Build Coastguard Worker ret = returnErrorCode(LZ4F_ERROR_io_write);
335*27162e4eSAndroid Build Coastguard Worker }
336*27162e4eSAndroid Build Coastguard Worker }
337*27162e4eSAndroid Build Coastguard Worker
338*27162e4eSAndroid Build Coastguard Worker out:
339*27162e4eSAndroid Build Coastguard Worker LZ4F_freeWriteFile(lz4fWrite);
340*27162e4eSAndroid Build Coastguard Worker return ret;
341*27162e4eSAndroid Build Coastguard Worker }
342