xref: /aosp_15_r20/external/sandboxed-api/contrib/zstd/wrapper/wrapper_zstd.cc (revision ec63e07ab9515d95e79c211197c445ef84cefa6a)
1*ec63e07aSXin Li // Copyright 2022 Google LLC
2*ec63e07aSXin Li //
3*ec63e07aSXin Li // Licensed under the Apache License, Version 2.0 (the "License");
4*ec63e07aSXin Li // you may not use this file except in compliance with the License.
5*ec63e07aSXin Li // You may obtain a copy of the License at
6*ec63e07aSXin Li //
7*ec63e07aSXin Li //     https://www.apache.org/licenses/LICENSE-2.0
8*ec63e07aSXin Li //
9*ec63e07aSXin Li // Unless required by applicable law or agreed to in writing, software
10*ec63e07aSXin Li // distributed under the License is distributed on an "AS IS" BASIS,
11*ec63e07aSXin Li // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*ec63e07aSXin Li // See the License for the specific language governing permissions and
13*ec63e07aSXin Li // limitations under the License.
14*ec63e07aSXin Li 
15*ec63e07aSXin Li #include "contrib/zstd/wrapper/wrapper_zstd.h"
16*ec63e07aSXin Li 
17*ec63e07aSXin Li #include <errno.h>
18*ec63e07aSXin Li #include <fcntl.h>
19*ec63e07aSXin Li #include <unistd.h>
20*ec63e07aSXin Li 
21*ec63e07aSXin Li #include <cstdio>
22*ec63e07aSXin Li #include <cstdlib>
23*ec63e07aSXin Li #include <iostream>
24*ec63e07aSXin Li #include <memory>
25*ec63e07aSXin Li 
26*ec63e07aSXin Li constexpr size_t kFileMaxSize = 1024 * 1024 * 1024;  // 1GB
27*ec63e07aSXin Li 
FDGetSize(int fd)28*ec63e07aSXin Li off_t FDGetSize(int fd) {
29*ec63e07aSXin Li   off_t size = lseek(fd, 0, SEEK_END);
30*ec63e07aSXin Li   if (size < 0) {
31*ec63e07aSXin Li     return -1;
32*ec63e07aSXin Li   }
33*ec63e07aSXin Li   if (lseek(fd, 0, SEEK_SET) < 0) {
34*ec63e07aSXin Li     return -1;
35*ec63e07aSXin Li   }
36*ec63e07aSXin Li 
37*ec63e07aSXin Li   return size;
38*ec63e07aSXin Li }
39*ec63e07aSXin Li 
ZSTD_compress_fd(int fdin,int fdout,int level)40*ec63e07aSXin Li int ZSTD_compress_fd(int fdin, int fdout, int level) {
41*ec63e07aSXin Li   off_t sizein = FDGetSize(fdin);
42*ec63e07aSXin Li   if (sizein <= 0) {
43*ec63e07aSXin Li     return -1;
44*ec63e07aSXin Li   }
45*ec63e07aSXin Li 
46*ec63e07aSXin Li   size_t sizeout = ZSTD_compressBound(sizein);
47*ec63e07aSXin Li 
48*ec63e07aSXin Li   auto bufin = std::make_unique<int8_t[]>(sizein);
49*ec63e07aSXin Li   auto bufout = std::make_unique<int8_t[]>(sizeout);
50*ec63e07aSXin Li 
51*ec63e07aSXin Li   if (read(fdin, bufin.get(), sizein) != sizein) {
52*ec63e07aSXin Li     return -1;
53*ec63e07aSXin Li   }
54*ec63e07aSXin Li 
55*ec63e07aSXin Li   int retsize =
56*ec63e07aSXin Li       ZSTD_compress(bufout.get(), sizeout, bufin.get(), sizein, level);
57*ec63e07aSXin Li   if (ZSTD_isError(retsize)) {
58*ec63e07aSXin Li     return -1;
59*ec63e07aSXin Li   }
60*ec63e07aSXin Li 
61*ec63e07aSXin Li   if (write(fdout, bufout.get(), retsize) != retsize) {
62*ec63e07aSXin Li     return -1;
63*ec63e07aSXin Li   }
64*ec63e07aSXin Li 
65*ec63e07aSXin Li   return 0;
66*ec63e07aSXin Li }
67*ec63e07aSXin Li 
ZSTD_compressStream_fd(ZSTD_CCtx * cctx,int fdin,int fdout)68*ec63e07aSXin Li int ZSTD_compressStream_fd(ZSTD_CCtx* cctx, int fdin, int fdout) {
69*ec63e07aSXin Li   size_t sizein = ZSTD_CStreamInSize();
70*ec63e07aSXin Li   size_t sizeout = ZSTD_CStreamOutSize();
71*ec63e07aSXin Li 
72*ec63e07aSXin Li   auto bufin = std::make_unique<int8_t[]>(sizein);
73*ec63e07aSXin Li   auto bufout = std::make_unique<int8_t[]>(sizeout);
74*ec63e07aSXin Li 
75*ec63e07aSXin Li   ssize_t size;
76*ec63e07aSXin Li   while ((size = read(fdin, bufin.get(), sizein)) > 0) {
77*ec63e07aSXin Li     ZSTD_inBuffer_s struct_in;
78*ec63e07aSXin Li     struct_in.src = bufin.get();
79*ec63e07aSXin Li     struct_in.pos = 0;
80*ec63e07aSXin Li     struct_in.size = size;
81*ec63e07aSXin Li 
82*ec63e07aSXin Li     ZSTD_EndDirective mode = ZSTD_e_continue;
83*ec63e07aSXin Li     if (size < sizein) {
84*ec63e07aSXin Li       mode = ZSTD_e_end;
85*ec63e07aSXin Li     }
86*ec63e07aSXin Li 
87*ec63e07aSXin Li     bool isdone = false;
88*ec63e07aSXin Li     while (!isdone) {
89*ec63e07aSXin Li       ZSTD_outBuffer_s struct_out;
90*ec63e07aSXin Li       struct_out.dst = bufout.get();
91*ec63e07aSXin Li       struct_out.pos = 0;
92*ec63e07aSXin Li       struct_out.size = sizeout;
93*ec63e07aSXin Li 
94*ec63e07aSXin Li       size_t remaining =
95*ec63e07aSXin Li           ZSTD_compressStream2(cctx, &struct_out, &struct_in, mode);
96*ec63e07aSXin Li       if (ZSTD_isError(remaining)) {
97*ec63e07aSXin Li         return -1;
98*ec63e07aSXin Li       }
99*ec63e07aSXin Li       if (write(fdout, bufout.get(), struct_out.pos) != struct_out.pos) {
100*ec63e07aSXin Li         return -1;
101*ec63e07aSXin Li       }
102*ec63e07aSXin Li 
103*ec63e07aSXin Li       if (mode == ZSTD_e_continue) {
104*ec63e07aSXin Li         isdone = (struct_in.pos == size);
105*ec63e07aSXin Li       } else {
106*ec63e07aSXin Li         isdone = (remaining == 0);
107*ec63e07aSXin Li       }
108*ec63e07aSXin Li     }
109*ec63e07aSXin Li   }
110*ec63e07aSXin Li 
111*ec63e07aSXin Li   if (size != 0) {
112*ec63e07aSXin Li     return -1;
113*ec63e07aSXin Li   }
114*ec63e07aSXin Li 
115*ec63e07aSXin Li   return 0;
116*ec63e07aSXin Li }
117*ec63e07aSXin Li 
ZSTD_decompress_fd(int fdin,int fdout)118*ec63e07aSXin Li int ZSTD_decompress_fd(int fdin, int fdout) {
119*ec63e07aSXin Li   off_t sizein = FDGetSize(fdin);
120*ec63e07aSXin Li   if (sizein <= 0) {
121*ec63e07aSXin Li     return -1;
122*ec63e07aSXin Li   }
123*ec63e07aSXin Li   auto bufin = std::make_unique<int8_t[]>(sizein);
124*ec63e07aSXin Li   if (read(fdin, bufin.get(), sizein) != sizein) {
125*ec63e07aSXin Li     return -1;
126*ec63e07aSXin Li   }
127*ec63e07aSXin Li 
128*ec63e07aSXin Li   size_t sizeout = ZSTD_getFrameContentSize(bufin.get(), sizein);
129*ec63e07aSXin Li   if (ZSTD_isError(sizeout) || sizeout > kFileMaxSize) {
130*ec63e07aSXin Li     return -1;
131*ec63e07aSXin Li   }
132*ec63e07aSXin Li 
133*ec63e07aSXin Li   auto bufout = std::make_unique<int8_t[]>(sizeout);
134*ec63e07aSXin Li 
135*ec63e07aSXin Li   size_t desize = ZSTD_decompress(bufout.get(), sizeout, bufin.get(), sizein);
136*ec63e07aSXin Li   if (ZSTD_isError(desize) || desize != sizeout) {
137*ec63e07aSXin Li     return -1;
138*ec63e07aSXin Li   }
139*ec63e07aSXin Li 
140*ec63e07aSXin Li   if (write(fdout, bufout.get(), sizeout) != sizeout) {
141*ec63e07aSXin Li     return -1;
142*ec63e07aSXin Li   }
143*ec63e07aSXin Li 
144*ec63e07aSXin Li   return 0;
145*ec63e07aSXin Li }
146*ec63e07aSXin Li 
ZSTD_decompressStream_fd(ZSTD_DCtx * dctx,int fdin,int fdout)147*ec63e07aSXin Li int ZSTD_decompressStream_fd(ZSTD_DCtx* dctx, int fdin, int fdout) {
148*ec63e07aSXin Li   size_t sizein = ZSTD_CStreamInSize();
149*ec63e07aSXin Li   size_t sizeout = ZSTD_CStreamOutSize();
150*ec63e07aSXin Li 
151*ec63e07aSXin Li   auto bufin = std::make_unique<int8_t[]>(sizein);
152*ec63e07aSXin Li   auto bufout = std::make_unique<int8_t[]>(sizeout);
153*ec63e07aSXin Li 
154*ec63e07aSXin Li   ssize_t size;
155*ec63e07aSXin Li   while ((size = read(fdin, bufin.get(), sizein)) > 0) {
156*ec63e07aSXin Li     ZSTD_inBuffer_s struct_in;
157*ec63e07aSXin Li     struct_in.src = bufin.get();
158*ec63e07aSXin Li     struct_in.pos = 0;
159*ec63e07aSXin Li     struct_in.size = size;
160*ec63e07aSXin Li 
161*ec63e07aSXin Li     while (struct_in.pos < size) {
162*ec63e07aSXin Li       ZSTD_outBuffer_s struct_out;
163*ec63e07aSXin Li       struct_out.dst = bufout.get();
164*ec63e07aSXin Li       struct_out.pos = 0;
165*ec63e07aSXin Li       struct_out.size = sizeout;
166*ec63e07aSXin Li 
167*ec63e07aSXin Li       size_t ret = ZSTD_decompressStream(dctx, &struct_out, &struct_in);
168*ec63e07aSXin Li       if (ZSTD_isError(ret)) {
169*ec63e07aSXin Li         return -1;
170*ec63e07aSXin Li       }
171*ec63e07aSXin Li       if (write(fdout, bufout.get(), struct_out.pos) != struct_out.pos) {
172*ec63e07aSXin Li         return -1;
173*ec63e07aSXin Li       }
174*ec63e07aSXin Li     }
175*ec63e07aSXin Li   }
176*ec63e07aSXin Li 
177*ec63e07aSXin Li   if (size != 0) {
178*ec63e07aSXin Li     return -1;
179*ec63e07aSXin Li   }
180*ec63e07aSXin Li 
181*ec63e07aSXin Li   return 0;
182*ec63e07aSXin Li }
183