diff options
Diffstat (limited to 'src/stable/lzma.cpp')
-rw-r--r-- | src/stable/lzma.cpp | 368 |
1 files changed, 184 insertions, 184 deletions
diff --git a/src/stable/lzma.cpp b/src/stable/lzma.cpp index 9df8f57..9ec2ce0 100644 --- a/src/stable/lzma.cpp +++ b/src/stable/lzma.cpp | |||
@@ -15,234 +15,234 @@ | |||
15 | using namespace Bu; | 15 | using namespace Bu; |
16 | 16 | ||
17 | Bu::Lzma::Lzma( Bu::Stream &rNext, int nCompression, Format eFmt ) : | 17 | Bu::Lzma::Lzma( Bu::Stream &rNext, int nCompression, Format eFmt ) : |
18 | Bu::Filter( rNext ), | 18 | Bu::Filter( rNext ), |
19 | prState( NULL ), | 19 | prState( NULL ), |
20 | nCompression( nCompression ), | 20 | nCompression( nCompression ), |
21 | sTotalOut( 0 ), | 21 | sTotalOut( 0 ), |
22 | eFmt( eFmt ), | 22 | eFmt( eFmt ), |
23 | bEos( false ) | 23 | bEos( false ) |
24 | { | 24 | { |
25 | TRACE( nCompression ); | 25 | TRACE( nCompression ); |
26 | start(); | 26 | start(); |
27 | } | 27 | } |
28 | 28 | ||
29 | Bu::Lzma::~Lzma() | 29 | Bu::Lzma::~Lzma() |
30 | { | 30 | { |
31 | TRACE(); | 31 | TRACE(); |
32 | stop(); | 32 | stop(); |
33 | } | 33 | } |
34 | 34 | ||
35 | void Bu::Lzma::start() | 35 | void Bu::Lzma::start() |
36 | { | 36 | { |
37 | TRACE(); | 37 | TRACE(); |
38 | nBufSize = 64*1024; | 38 | nBufSize = 64*1024; |
39 | pBuf = new char[nBufSize]; | 39 | pBuf = new char[nBufSize]; |
40 | } | 40 | } |
41 | 41 | ||
42 | Bu::size Bu::Lzma::stop() | 42 | Bu::size Bu::Lzma::stop() |
43 | { | 43 | { |
44 | TRACE(); | 44 | TRACE(); |
45 | if( pState ) | 45 | if( pState ) |
46 | { | 46 | { |
47 | if( bReading ) | 47 | if( bReading ) |
48 | { | 48 | { |
49 | lzma_end( pState ); | 49 | lzma_end( pState ); |
50 | delete[] pBuf; | 50 | delete[] pBuf; |
51 | pBuf = NULL; | 51 | pBuf = NULL; |
52 | delete pState; | 52 | delete pState; |
53 | prState = NULL; | 53 | prState = NULL; |
54 | return 0; | 54 | return 0; |
55 | } | 55 | } |
56 | else | 56 | else |
57 | { | 57 | { |
58 | for(;;) | 58 | for(;;) |
59 | { | 59 | { |
60 | pState->next_in = NULL; | 60 | pState->next_in = NULL; |
61 | pState->avail_in = 0; | 61 | pState->avail_in = 0; |
62 | pState->avail_out = nBufSize; | 62 | pState->avail_out = nBufSize; |
63 | pState->next_out = (uint8_t *)pBuf; | 63 | pState->next_out = (uint8_t *)pBuf; |
64 | int res = lzma_code( pState, LZMA_FINISH ); | 64 | int res = lzma_code( pState, LZMA_FINISH ); |
65 | if( pState->avail_out < nBufSize ) | 65 | if( pState->avail_out < nBufSize ) |
66 | { | 66 | { |
67 | sTotalOut += rNext.write( pBuf, nBufSize-pState->avail_out ); | 67 | sTotalOut += rNext.write( pBuf, nBufSize-pState->avail_out ); |
68 | } | 68 | } |
69 | if( res == LZMA_STREAM_END ) | 69 | if( res == LZMA_STREAM_END ) |
70 | break; | 70 | break; |
71 | } | 71 | } |
72 | lzma_end( pState ); | 72 | lzma_end( pState ); |
73 | delete[] pBuf; | 73 | delete[] pBuf; |
74 | pBuf = NULL; | 74 | pBuf = NULL; |
75 | delete pState; | 75 | delete pState; |
76 | prState = NULL; | 76 | prState = NULL; |
77 | return sTotalOut; | 77 | return sTotalOut; |
78 | } | 78 | } |
79 | } | 79 | } |
80 | return 0; | 80 | return 0; |
81 | } | 81 | } |
82 | 82 | ||
83 | void Bu::Lzma::lzmaError( int code ) | 83 | void Bu::Lzma::lzmaError( int code ) |
84 | { | 84 | { |
85 | TRACE( code ); | 85 | TRACE( code ); |
86 | switch( code ) | 86 | switch( code ) |
87 | { | 87 | { |
88 | case LZMA_OK: | 88 | case LZMA_OK: |
89 | case LZMA_STREAM_END: | 89 | case LZMA_STREAM_END: |
90 | case LZMA_NO_CHECK: | 90 | case LZMA_NO_CHECK: |
91 | case LZMA_UNSUPPORTED_CHECK: | 91 | case LZMA_UNSUPPORTED_CHECK: |
92 | break; | 92 | break; |
93 | 93 | ||
94 | case LZMA_MEM_ERROR: | 94 | case LZMA_MEM_ERROR: |
95 | throw ExceptionBase("Lzma: Memory allocation error."); | 95 | throw ExceptionBase("Lzma: Memory allocation error."); |
96 | 96 | ||
97 | case LZMA_MEMLIMIT_ERROR: | 97 | case LZMA_MEMLIMIT_ERROR: |
98 | throw ExceptionBase("Lzma: Memory usage limit was reached."); | 98 | throw ExceptionBase("Lzma: Memory usage limit was reached."); |
99 | 99 | ||
100 | case LZMA_FORMAT_ERROR: | 100 | case LZMA_FORMAT_ERROR: |
101 | throw ExceptionBase("Lzma: File format not recognized."); | 101 | throw ExceptionBase("Lzma: File format not recognized."); |
102 | 102 | ||
103 | case LZMA_OPTIONS_ERROR: | 103 | case LZMA_OPTIONS_ERROR: |
104 | throw ExceptionBase("Lzma: Invalid or unsupported options."); | 104 | throw ExceptionBase("Lzma: Invalid or unsupported options."); |
105 | 105 | ||
106 | case LZMA_DATA_ERROR: | 106 | case LZMA_DATA_ERROR: |
107 | throw ExceptionBase("Lzma: Data is corrupt."); | 107 | throw ExceptionBase("Lzma: Data is corrupt."); |
108 | 108 | ||
109 | case LZMA_BUF_ERROR: | 109 | case LZMA_BUF_ERROR: |
110 | throw ExceptionBase("Lzma: No progress is possible."); | 110 | throw ExceptionBase("Lzma: No progress is possible."); |
111 | 111 | ||
112 | case LZMA_PROG_ERROR: | 112 | case LZMA_PROG_ERROR: |
113 | throw ExceptionBase("Lzma: Programming error."); | 113 | throw ExceptionBase("Lzma: Programming error."); |
114 | 114 | ||
115 | default: | 115 | default: |
116 | throw ExceptionBase("Lzma: Unknown error encountered." ); | 116 | throw ExceptionBase("Lzma: Unknown error encountered." ); |
117 | } | 117 | } |
118 | } | 118 | } |
119 | 119 | ||
120 | Bu::size Bu::Lzma::read( void *pData, Bu::size nBytes ) | 120 | Bu::size Bu::Lzma::read( void *pData, Bu::size nBytes ) |
121 | { | 121 | { |
122 | TRACE( pData, nBytes ); | 122 | TRACE( pData, nBytes ); |
123 | if( !pState ) | 123 | if( !pState ) |
124 | { | 124 | { |
125 | prState = new ::lzma_stream; | 125 | prState = new ::lzma_stream; |
126 | lzma_stream zEmpty = LZMA_STREAM_INIT; | 126 | lzma_stream zEmpty = LZMA_STREAM_INIT; |
127 | Bu::memcpy( prState, &zEmpty, sizeof(lzma_stream) ); | 127 | Bu::memcpy( prState, &zEmpty, sizeof(lzma_stream) ); |
128 | 128 | ||
129 | bReading = true; | 129 | bReading = true; |
130 | lzmaError( lzma_auto_decoder( pState, UINT64_MAX, 0 ) ); | 130 | lzmaError( lzma_auto_decoder( pState, UINT64_MAX, 0 ) ); |
131 | pState->next_in = (uint8_t *)pBuf; | 131 | pState->next_in = (uint8_t *)pBuf; |
132 | pState->avail_in = 0; | 132 | pState->avail_in = 0; |
133 | } | 133 | } |
134 | if( bReading == false ) | 134 | if( bReading == false ) |
135 | throw ExceptionBase("This lzma filter is in writing mode, you can't read."); | 135 | throw ExceptionBase("This lzma filter is in writing mode, you can't read."); |
136 | 136 | ||
137 | int nRead = 0; | 137 | int nRead = 0; |
138 | int nReadTotal = pState->total_out; | 138 | int nReadTotal = pState->total_out; |
139 | pState->next_out = (uint8_t *)pData; | 139 | pState->next_out = (uint8_t *)pData; |
140 | pState->avail_out = nBytes; | 140 | pState->avail_out = nBytes; |
141 | for(;;) | 141 | for(;;) |
142 | { | 142 | { |
143 | int ret = lzma_code( pState, LZMA_RUN ); | 143 | int ret = lzma_code( pState, LZMA_RUN ); |
144 | // printf("inflate returned %d; avail in=%d, out=%d\n", ret, | 144 | // printf("inflate returned %d; avail in=%d, out=%d\n", ret, |
145 | // pState->avail_in, pState->avail_out ); | 145 | // pState->avail_in, pState->avail_out ); |
146 | 146 | ||
147 | nReadTotal += nRead-pState->avail_out; | 147 | nReadTotal += nRead-pState->avail_out; |
148 | 148 | ||
149 | if( ret == LZMA_STREAM_END ) | 149 | if( ret == LZMA_STREAM_END ) |
150 | { | 150 | { |
151 | bEos = true; | 151 | bEos = true; |
152 | if( pState->avail_in > 0 ) | 152 | if( pState->avail_in > 0 ) |
153 | { | 153 | { |
154 | if( rNext.isSeekable() ) | 154 | if( rNext.isSeekable() ) |
155 | { | 155 | { |
156 | rNext.seek( -pState->avail_in ); | 156 | rNext.seek( -pState->avail_in ); |
157 | } | 157 | } |
158 | } | 158 | } |
159 | return nBytes-pState->avail_out; | 159 | return nBytes-pState->avail_out; |
160 | } | 160 | } |
161 | // if( ret != LZMA_BUF_ERROR ) | 161 | // if( ret != LZMA_BUF_ERROR ) |
162 | lzmaError( ret ); | 162 | lzmaError( ret ); |
163 | 163 | ||
164 | if( pState->avail_out ) | 164 | if( pState->avail_out ) |
165 | { | 165 | { |
166 | if( pState->avail_in == 0 ) | 166 | if( pState->avail_in == 0 ) |
167 | { | 167 | { |
168 | nRead = rNext.read( pBuf, nBufSize ); | 168 | nRead = rNext.read( pBuf, nBufSize ); |
169 | if( nRead == 0 && rNext.isEos() ) | 169 | if( nRead == 0 && rNext.isEos() ) |
170 | { | 170 | { |
171 | throw Bu::ExceptionBase("Premature end of underlying " | 171 | throw Bu::ExceptionBase("Premature end of underlying " |
172 | "stream found reading deflate stream."); | 172 | "stream found reading deflate stream."); |
173 | } | 173 | } |
174 | pState->next_in = (uint8_t *)pBuf; | 174 | pState->next_in = (uint8_t *)pBuf; |
175 | pState->avail_in = nRead; | 175 | pState->avail_in = nRead; |
176 | } | 176 | } |
177 | } | 177 | } |
178 | else | 178 | else |
179 | { | 179 | { |
180 | return nBytes-pState->avail_out; | 180 | return nBytes-pState->avail_out; |
181 | } | 181 | } |
182 | } | 182 | } |
183 | return 0; | 183 | return 0; |
184 | } | 184 | } |
185 | 185 | ||
186 | Bu::size Bu::Lzma::write( const void *pData, Bu::size nBytes ) | 186 | Bu::size Bu::Lzma::write( const void *pData, Bu::size nBytes ) |
187 | { | 187 | { |
188 | TRACE( pData, nBytes ); | 188 | TRACE( pData, nBytes ); |
189 | if( !pState ) | 189 | if( !pState ) |
190 | { | 190 | { |
191 | prState = new ::lzma_stream; | 191 | prState = new ::lzma_stream; |
192 | lzma_stream zEmpty = LZMA_STREAM_INIT; | 192 | lzma_stream zEmpty = LZMA_STREAM_INIT; |
193 | Bu::memcpy( prState, &zEmpty, sizeof(lzma_stream) ); | 193 | Bu::memcpy( prState, &zEmpty, sizeof(lzma_stream) ); |
194 | 194 | ||
195 | bReading = false; | 195 | bReading = false; |
196 | if( eFmt == Xz ) | 196 | if( eFmt == Xz ) |
197 | lzmaError( | 197 | lzmaError( |
198 | lzma_easy_encoder( pState, nCompression, LZMA_CHECK_CRC64 ) | 198 | lzma_easy_encoder( pState, nCompression, LZMA_CHECK_CRC64 ) |
199 | ); | 199 | ); |
200 | else if( eFmt == LzmaAlone ) | 200 | else if( eFmt == LzmaAlone ) |
201 | { | 201 | { |
202 | lzma_options_lzma opt; | 202 | lzma_options_lzma opt; |
203 | lzma_lzma_preset( &opt, nCompression ); | 203 | lzma_lzma_preset( &opt, nCompression ); |
204 | lzmaError( lzma_alone_encoder( pState, &opt ) ); | 204 | lzmaError( lzma_alone_encoder( pState, &opt ) ); |
205 | } | 205 | } |
206 | else | 206 | else |
207 | throw Bu::ExceptionBase("Invalid format for lzma."); | 207 | throw Bu::ExceptionBase("Invalid format for lzma."); |
208 | } | 208 | } |
209 | if( bReading == true ) | 209 | if( bReading == true ) |
210 | throw ExceptionBase("This lzma filter is in reading mode, you can't write."); | 210 | throw ExceptionBase("This lzma filter is in reading mode, you can't write."); |
211 | 211 | ||
212 | pState->next_in = (uint8_t *)pData; | 212 | pState->next_in = (uint8_t *)pData; |
213 | pState->avail_in = nBytes; | 213 | pState->avail_in = nBytes; |
214 | for(;;) | 214 | for(;;) |
215 | { | 215 | { |
216 | pState->avail_out = nBufSize; | 216 | pState->avail_out = nBufSize; |
217 | pState->next_out = (uint8_t *)pBuf; | 217 | pState->next_out = (uint8_t *)pBuf; |
218 | 218 | ||
219 | lzmaError( lzma_code( pState, LZMA_RUN ) ); | 219 | lzmaError( lzma_code( pState, LZMA_RUN ) ); |
220 | 220 | ||
221 | if( pState->avail_out < nBufSize ) | 221 | if( pState->avail_out < nBufSize ) |
222 | { | 222 | { |
223 | sTotalOut += rNext.write( pBuf, nBufSize-pState->avail_out ); | 223 | sTotalOut += rNext.write( pBuf, nBufSize-pState->avail_out ); |
224 | } | 224 | } |
225 | if( pState->avail_in == 0 ) | 225 | if( pState->avail_in == 0 ) |
226 | break; | 226 | break; |
227 | } | 227 | } |
228 | 228 | ||
229 | return nBytes; | 229 | return nBytes; |
230 | } | 230 | } |
231 | 231 | ||
232 | bool Bu::Lzma::isOpen() | 232 | bool Bu::Lzma::isOpen() |
233 | { | 233 | { |
234 | TRACE(); | 234 | TRACE(); |
235 | return (pState != NULL); | 235 | return (pState != NULL); |
236 | } | 236 | } |
237 | 237 | ||
238 | bool Bu::Lzma::isEos() | 238 | bool Bu::Lzma::isEos() |
239 | { | 239 | { |
240 | TRACE(); | 240 | TRACE(); |
241 | return bEos; | 241 | return bEos; |
242 | } | 242 | } |
243 | 243 | ||
244 | Bu::size Bu::Lzma::getCompressedSize() | 244 | Bu::size Bu::Lzma::getCompressedSize() |
245 | { | 245 | { |
246 | return sTotalOut; | 246 | return sTotalOut; |
247 | } | 247 | } |
248 | 248 | ||