23.1.2
by Juan Zacarias
Added FLWOR Foundation Copyright notice to files that missed it. |
1 |
/*
|
2 |
* Copyright 2012 The FLWOR Foundation.
|
|
3 |
*
|
|
4 |
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5 |
* you may not use this file except in compliance with the License.
|
|
6 |
* You may obtain a copy of the License at
|
|
7 |
*
|
|
8 |
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9 |
*
|
|
10 |
* Unless required by applicable law or agreed to in writing, software
|
|
11 |
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12 |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13 |
* See the License for the specific language governing permissions and
|
|
14 |
* limitations under the License.
|
|
15 |
*/
|
|
16 |
||
48
by Paul J. Lucas
Include file clean-up. |
17 |
#include <algorithm> |
18 |
#include <cassert> |
|
19 |
#include <cstdio> |
|
20 |
#include <fstream> |
|
21 |
#include <iostream> |
|
22 |
#include <string> |
|
23 |
#include <sys/types.h> |
|
24 |
||
25 |
#include <sys/timeb.h> |
|
26 |
#ifdef UNIX
|
|
27 |
# include <sys/time.h>
|
|
28 |
#endif
|
|
29 |
#ifdef WIN32
|
|
30 |
# include <strptime.h>
|
|
31 |
# include <MMSystem.h>
|
|
32 |
#endif
|
|
33 |
||
34 |
#include <zorba/diagnostic_list.h> |
|
35 |
#include <zorba/empty_sequence.h> |
|
5
by Juan Zacarias
Changed name to archive module |
36 |
#include <zorba/item_factory.h> |
37 |
#include <zorba/singleton_item_sequence.h> |
|
38 |
#include <zorba/user_exception.h> |
|
49
by Paul J. Lucas
Include file clean-up. |
39 |
#include <zorba/util/base64_util.h> |
48
by Paul J. Lucas
Include file clean-up. |
40 |
#include <zorba/util/base64_stream.h> |
41 |
#include <zorba/util/transcode_stream.h> |
|
5
by Juan Zacarias
Changed name to archive module |
42 |
|
43 |
#include "archive.h" |
|
44 |
#include "archive_entry.h" |
|
48
by Paul J. Lucas
Include file clean-up. |
45 |
#include "archive_module.h" |
35
by Matthias Brantner
- reworked the way options are passed and named |
46 |
#include "config.h" |
5
by Juan Zacarias
Changed name to archive module |
47 |
|
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
48 |
#define ERROR_ENTRY_COUNT_MISMATCH "ENTRY-COUNT"
|
49 |
#define ERROR_INVALID_OPTIONS "INVALID-OPTIONS"
|
|
50 |
#define ERROR_INVALID_ENTRY_VALS "INVALID-ENTRY-VALS"
|
|
51 |
#define ERROR_INVALID_ENCODING "INVALID-ENCODING"
|
|
52 |
#define ERROR_CORRUPTED_ARCHIVE "CORRUPTED-ARCHIVE"
|
|
53 |
#define ERROR_DIFFERENT_COMPRESSIONS_NOT_SUPPORTED "DIFFERENT-COMPRESSIONS-NOT-SUPPORTED"
|
|
54 |
||
53
by Luis Rodriguez Gonzalez
All comments fixed |
55 |
#define FORMAT_KEY_NAME "format"
|
56 |
#define COMPRESSION_KEY_NAME "compression"
|
|
57 |
#define NAME_KEY_NAME "name"
|
|
58 |
#define TYPE_KEY_NAME "type"
|
|
59 |
#define SIZE_KEY_NAME "size"
|
|
60 |
#define LAST_MODIFIED_KEY_NAME "last-modified"
|
|
61 |
#define ENCODING_KEY_NAME "encoding"
|
|
62 |
||
7
by Matthias Brantner
fixed two build problems: |
63 |
namespace zorba { namespace archive { |
64 |
||
65 |
||
11
by Matthias Brantner
- extract-text#1 function (without transcoding) |
66 |
/*******************************************************************************
|
67 |
******************************************************************************/
|
|
7
by Matthias Brantner
fixed two build problems: |
68 |
zorba::ExternalFunction* |
69 |
ArchiveModule::getExternalFunction(const zorba::String& localName) |
|
70 |
{
|
|
71 |
FuncMap_t::iterator lIte = theFunctions.find(localName); |
|
72 |
||
73 |
ExternalFunction*& lFunc = theFunctions[localName]; |
|
74 |
||
75 |
if (lIte == theFunctions.end()) |
|
76 |
{
|
|
77 |
if (localName == "create") |
|
78 |
{
|
|
79 |
lFunc = new CreateFunction(this); |
|
80 |
}
|
|
81 |
else if (localName == "entries") |
|
82 |
{
|
|
83 |
lFunc = new EntriesFunction(this); |
|
84 |
}
|
|
85 |
else if (localName == "extract-text") |
|
86 |
{
|
|
87 |
lFunc = new ExtractTextFunction(this); |
|
88 |
}
|
|
89 |
else if (localName == "extract-binary") |
|
90 |
{
|
|
91 |
lFunc = new ExtractBinaryFunction(this); |
|
92 |
}
|
|
93 |
else if (localName == "delete") |
|
94 |
{
|
|
95 |
lFunc = new DeleteFunction(this); |
|
96 |
}
|
|
97 |
else if (localName == "update") |
|
98 |
{
|
|
99 |
lFunc = new UpdateFunction(this); |
|
100 |
}
|
|
14.1.2
by Matthias Brantner
added the archive:options function to return algorithm and format options of an archive |
101 |
else if (localName == "options") |
102 |
{
|
|
103 |
lFunc = new OptionsFunction(this); |
|
104 |
}
|
|
7
by Matthias Brantner
fixed two build problems: |
105 |
}
|
106 |
||
107 |
return lFunc; |
|
108 |
}
|
|
109 |
||
110 |
void ArchiveModule::destroy() |
|
111 |
{
|
|
112 |
delete this; |
|
113 |
}
|
|
114 |
||
115 |
ArchiveModule::~ArchiveModule() |
|
116 |
{
|
|
117 |
for (FuncMap_t::const_iterator lIter = theFunctions.begin(); |
|
118 |
lIter != theFunctions.end(); ++lIter) |
|
119 |
{
|
|
120 |
delete lIter->second; |
|
121 |
}
|
|
122 |
theFunctions.clear(); |
|
123 |
}
|
|
124 |
||
9
by Matthias Brantner
- introduced a schema for entries and options |
125 |
zorba::Item |
126 |
ArchiveModule::createDateTimeItem(time_t& aTime) |
|
127 |
{
|
|
42.1.4
by Matthias Brantner
use UTC instead of no timezone |
128 |
// create a datetime item with UTC as timezone
|
129 |
// this seems to be what mtime from libarchive returns
|
|
9
by Matthias Brantner
- introduced a schema for entries and options |
130 |
struct ::tm gmtm; |
131 |
#ifdef WIN32
|
|
42.1.4
by Matthias Brantner
use UTC instead of no timezone |
132 |
gmtime_s(&gmtm, &aTime); |
9
by Matthias Brantner
- introduced a schema for entries and options |
133 |
#else
|
42.1.4
by Matthias Brantner
use UTC instead of no timezone |
134 |
gmtime_r(&aTime, &gmtm); |
9
by Matthias Brantner
- introduced a schema for entries and options |
135 |
#endif
|
136 |
||
42.1.6
by luisrod
- Added ability to create directories |
137 |
// create a datetime item without timezone because
|
138 |
// this is what the entry tells us (at least for zip)
|
|
9
by Matthias Brantner
- introduced a schema for entries and options |
139 |
Item lModifiedItem = getItemFactory()->createDateTime( |
140 |
static_cast<short>(gmtm.tm_year + 1900), |
|
141 |
static_cast<short>(gmtm.tm_mon + 1), |
|
142 |
static_cast<short>(gmtm.tm_mday), |
|
143 |
static_cast<short>(gmtm.tm_hour), |
|
144 |
static_cast<short>(gmtm.tm_min), |
|
42.1.4
by Matthias Brantner
use UTC instead of no timezone |
145 |
gmtm.tm_sec, |
146 |
0); |
|
9
by Matthias Brantner
- introduced a schema for entries and options |
147 |
return lModifiedItem; |
148 |
}
|
|
149 |
||
20
by Matthias Brantner
properly set value for last-modified attribute (use current time if no value is given for an entry) |
150 |
void
|
151 |
ArchiveModule::parseDateTimeItem(const zorba::Item& i, time_t& t) |
|
152 |
{
|
|
153 |
const char* lTime = i.getStringValue().c_str(); |
|
154 |
||
155 |
struct tm tm; |
|
156 |
memset(&tm, 0, sizeof(struct tm)); |
|
157 |
||
158 |
char* lTmp = strptime(lTime, "%Y-%m-%dT%T", &tm); |
|
159 |
if (lTmp != lTime + 19) |
|
160 |
{
|
|
161 |
std::ostringstream lMsg; |
|
162 |
lMsg << i.getStringValue() |
|
163 |
<< ": invalid value for last-modified attribute "; |
|
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
164 |
ArchiveFunction::throwError(ERROR_INVALID_ENTRY_VALS, lMsg.str().c_str()); |
20
by Matthias Brantner
properly set value for last-modified attribute (use current time if no value is given for an entry) |
165 |
}
|
166 |
}
|
|
167 |
||
11
by Matthias Brantner
- extract-text#1 function (without transcoding) |
168 |
/*******************************************************************************
|
23.2.1
by Juan Zacarias
changed ArchiveCompressor's namespace to ArchiveFunction |
169 |
****************************** ArchiveFunction ********************************
|
11
by Matthias Brantner
- extract-text#1 function (without transcoding) |
170 |
******************************************************************************/
|
7
by Matthias Brantner
fixed two build problems: |
171 |
ArchiveFunction::ArchiveFunction(const ArchiveModule* aModule) |
172 |
: theModule(aModule) |
|
173 |
{
|
|
174 |
}
|
|
175 |
||
176 |
ArchiveFunction::~ArchiveFunction() |
|
177 |
{
|
|
178 |
}
|
|
179 |
||
23.2.1
by Juan Zacarias
changed ArchiveCompressor's namespace to ArchiveFunction |
180 |
|
181 |
/******************
|
|
182 |
** Archive Entry **
|
|
183 |
******************/
|
|
184 |
||
17
by Matthias Brantner
first very basic version of create#2 and #3 |
185 |
ArchiveFunction::ArchiveEntry::ArchiveEntry() |
42.1.6
by luisrod
- Added ability to create directories |
186 |
: theEncoding("UTF-8"), |
187 |
theEntryType(regular) |
|
17
by Matthias Brantner
first very basic version of create#2 and #3 |
188 |
{
|
20
by Matthias Brantner
properly set value for last-modified attribute (use current time if no value is given for an entry) |
189 |
// use current time as a default for each entry
|
190 |
#if defined (WIN32)
|
|
191 |
struct _timeb timebuffer; |
|
192 |
_ftime_s( &timebuffer ); |
|
193 |
#else
|
|
194 |
struct timeb timebuffer; |
|
195 |
ftime( &timebuffer ); |
|
196 |
#endif
|
|
197 |
theLastModified = timebuffer.time; |
|
17
by Matthias Brantner
first very basic version of create#2 and #3 |
198 |
}
|
199 |
||
200 |
void
|
|
28
by Juan Zacarias
Implemented the add in the archive update function |
201 |
ArchiveFunction::ArchiveEntry::setValues(struct archive_entry* aEntry) |
202 |
{
|
|
203 |
theEntryPath = archive_entry_pathname(aEntry); |
|
204 |
||
205 |
if (archive_entry_size_is_set(aEntry)) |
|
206 |
{
|
|
42.1.6
by luisrod
- Added ability to create directories |
207 |
theSize = (int)archive_entry_size(aEntry); |
28
by Juan Zacarias
Implemented the add in the archive update function |
208 |
}
|
209 |
||
210 |
if (archive_entry_mtime_is_set(aEntry)) |
|
211 |
{
|
|
212 |
theLastModified = archive_entry_mtime(aEntry); |
|
213 |
}
|
|
214 |
//check if it is encoded
|
|
42.1.6
by luisrod
- Added ability to create directories |
215 |
|
216 |
switch(archive_entry_filetype(aEntry)) |
|
217 |
{
|
|
218 |
case AE_IFDIR: theEntryType = directory; break; |
|
219 |
default: theEntryType = regular; break; |
|
220 |
}
|
|
28
by Juan Zacarias
Implemented the add in the archive update function |
221 |
}
|
222 |
||
223 |
void
|
|
17
by Matthias Brantner
first very basic version of create#2 and #3 |
224 |
ArchiveFunction::ArchiveEntry::setValues(zorba::Item& aEntry) |
225 |
{
|
|
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
226 |
if (aEntry.isJSONItem()) |
17
by Matthias Brantner
first very basic version of create#2 and #3 |
227 |
{
|
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
228 |
Item lKey; |
17
by Matthias Brantner
first very basic version of create#2 and #3 |
229 |
|
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
230 |
Iterator_t lKeyIter = aEntry.getObjectKeys(); |
231 |
lKeyIter->open(); |
|
232 |
while (lKeyIter->next(lKey)) |
|
17
by Matthias Brantner
first very basic version of create#2 and #3 |
233 |
{
|
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
234 |
Item lKeyValue; |
235 |
lKeyValue = aEntry.getObjectValue(lKey.getStringValue()); |
|
17
by Matthias Brantner
first very basic version of create#2 and #3 |
236 |
|
53
by Luis Rodriguez Gonzalez
All comments fixed |
237 |
if(lKey.getStringValue() == NAME_KEY_NAME) |
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
238 |
{
|
239 |
theEntryPath = lKeyValue.getStringValue(); |
|
240 |
}
|
|
53
by Luis Rodriguez Gonzalez
All comments fixed |
241 |
else if(lKey.getStringValue() == TYPE_KEY_NAME) |
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
242 |
{
|
243 |
String filetype = lKeyValue.getStringValue(); |
|
42.1.6
by luisrod
- Added ability to create directories |
244 |
if(filetype == "directory") |
245 |
{
|
|
246 |
theEntryType = directory; |
|
247 |
}
|
|
248 |
}
|
|
53
by Luis Rodriguez Gonzalez
All comments fixed |
249 |
else if (lKey.getStringValue() == LAST_MODIFIED_KEY_NAME) |
17
by Matthias Brantner
first very basic version of create#2 and #3 |
250 |
{
|
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
251 |
ArchiveModule::parseDateTimeItem(lKeyValue, theLastModified); |
17
by Matthias Brantner
first very basic version of create#2 and #3 |
252 |
}
|
53
by Luis Rodriguez Gonzalez
All comments fixed |
253 |
else if (lKey.getStringValue() == ENCODING_KEY_NAME) |
17
by Matthias Brantner
first very basic version of create#2 and #3 |
254 |
{
|
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
255 |
theEncoding = lKeyValue.getStringValue(); |
21
by Matthias Brantner
- case insensitive entry and format options |
256 |
std::transform( |
257 |
theEncoding.begin(), theEncoding.end(), |
|
258 |
theEncoding.begin(), ::toupper); |
|
259 |
if (!transcode::is_supported(theEncoding.c_str())) |
|
260 |
{
|
|
261 |
std::ostringstream lMsg; |
|
262 |
lMsg << theEncoding << ": unsupported encoding"; |
|
263 |
||
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
264 |
throwError(ERROR_INVALID_ENCODING, lMsg.str().c_str()); |
21
by Matthias Brantner
- case insensitive entry and format options |
265 |
}
|
17
by Matthias Brantner
first very basic version of create#2 and #3 |
266 |
}
|
53
by Luis Rodriguez Gonzalez
All comments fixed |
267 |
else if (lKey.getStringValue() == COMPRESSION_KEY_NAME) |
42
by Matthias Brantner
- new option skip-extra-attrs (same effect as zip -X) but needs a special version of libarchive |
268 |
{
|
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
269 |
theCompression = lKeyValue.getStringValue(); |
35
by Matthias Brantner
- reworked the way options are passed and named |
270 |
std::transform( |
271 |
theCompression.begin(), |
|
272 |
theCompression.end(), |
|
273 |
theCompression.begin(), ::toupper); |
|
31
by luisrod
- Code added to provide options for each entry |
274 |
}
|
17
by Matthias Brantner
first very basic version of create#2 and #3 |
275 |
}
|
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
276 |
} else |
277 |
theEntryPath = aEntry.getStringValue(); |
|
17
by Matthias Brantner
first very basic version of create#2 and #3 |
278 |
}
|
279 |
||
23.2.1
by Juan Zacarias
changed ArchiveCompressor's namespace to ArchiveFunction |
280 |
/********************
|
281 |
** Archive Options **
|
|
282 |
********************/
|
|
283 |
||
17
by Matthias Brantner
first very basic version of create#2 and #3 |
284 |
ArchiveFunction::ArchiveOptions::ArchiveOptions() |
35
by Matthias Brantner
- reworked the way options are passed and named |
285 |
: theCompression("DEFLATE"), |
42
by Matthias Brantner
- new option skip-extra-attrs (same effect as zip -X) but needs a special version of libarchive |
286 |
theFormat("ZIP"), |
287 |
theSkipExtraAttrs(false) |
|
17
by Matthias Brantner
first very basic version of create#2 and #3 |
288 |
{}
|
289 |
||
290 |
void
|
|
28
by Juan Zacarias
Implemented the add in the archive update function |
291 |
ArchiveFunction::ArchiveOptions::setValues(struct archive* aArchive) |
292 |
{
|
|
35
by Matthias Brantner
- reworked the way options are passed and named |
293 |
theCompression = ArchiveFunction::compressionName( |
294 |
archive_compression(aArchive)); |
|
28
by Juan Zacarias
Implemented the add in the archive update function |
295 |
theFormat = ArchiveFunction::formatName(archive_format(aArchive)); |
296 |
}
|
|
297 |
||
298 |
void
|
|
17
by Matthias Brantner
first very basic version of create#2 and #3 |
299 |
ArchiveFunction::ArchiveOptions::setValues(Item& aOptions) |
300 |
{
|
|
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
301 |
if(aOptions.isJSONItem()) |
302 |
{
|
|
303 |
Item lOptionKey; |
|
304 |
Iterator_t lKeyIter = aOptions.getObjectKeys(); |
|
305 |
lKeyIter->open(); |
|
306 |
||
307 |
while (lKeyIter->next(lOptionKey)) |
|
308 |
{
|
|
309 |
Item lOptionValue; |
|
310 |
lOptionValue = aOptions.getObjectValue(lOptionKey.getStringValue()); |
|
311 |
||
53
by Luis Rodriguez Gonzalez
All comments fixed |
312 |
if (lOptionKey.getStringValue() == COMPRESSION_KEY_NAME) |
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
313 |
{
|
314 |
theCompression = lOptionValue.getStringValue().c_str(); |
|
315 |
std::transform( |
|
316 |
theCompression.begin(), |
|
317 |
theCompression.end(), |
|
318 |
theCompression.begin(), ::toupper); |
|
319 |
}
|
|
53
by Luis Rodriguez Gonzalez
All comments fixed |
320 |
else if (lOptionKey.getStringValue() == FORMAT_KEY_NAME) |
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
321 |
{
|
322 |
theFormat = lOptionValue.getStringValue().c_str(); |
|
323 |
std::transform( |
|
324 |
theFormat.begin(), |
|
325 |
theFormat.end(), |
|
326 |
theFormat.begin(), ::toupper); |
|
327 |
}
|
|
328 |
else if (lOptionKey.getStringValue() == "skip-extra-attributes") |
|
329 |
{
|
|
330 |
theSkipExtraAttrs = lOptionValue.getStringValue() == "true" ? true : false; |
|
331 |
}
|
|
332 |
}
|
|
333 |
if (theFormat == "ZIP") |
|
334 |
{
|
|
335 |
if (theCompression != "STORE" && theCompression != "DEFLATE" && theCompression != "NONE") |
|
336 |
{
|
|
337 |
std::ostringstream lMsg; |
|
338 |
lMsg
|
|
339 |
<< theCompression |
|
340 |
<< ": compression algorithm not supported for ZIP format (required: deflate, store)"; |
|
341 |
throwError(ERROR_INVALID_OPTIONS, lMsg.str().c_str()); |
|
342 |
}
|
|
343 |
}
|
|
344 |
if (theFormat == "TAR") |
|
53
by Luis Rodriguez Gonzalez
All comments fixed |
345 |
{ if (theCompression != "GZIP" |
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
346 |
#ifndef WIN32
|
347 |
&& theCompression != "BZIP2" |
|
348 |
&& theCompression != "LZMA" |
|
349 |
#endif
|
|
350 |
)
|
|
351 |
{
|
|
352 |
std::ostringstream lMsg; |
|
353 |
lMsg
|
|
354 |
<< theCompression |
|
355 |
<< ": compression algorithm not supported for TAR format (required: gzip" |
|
356 |
#ifndef WIN32
|
|
357 |
<< ", bzip2, lzma" |
|
358 |
#endif
|
|
359 |
<< ")"; |
|
360 |
throwError(ERROR_INVALID_OPTIONS, lMsg.str().c_str()); |
|
361 |
}
|
|
36
by Matthias Brantner
better errors + removed support for exotic formats and compressions |
362 |
}
|
363 |
}
|
|
15
by Juan Zacarias
Partial implementation of create function |
364 |
}
|
365 |
||
23.2.1
by Juan Zacarias
changed ArchiveCompressor's namespace to ArchiveFunction |
366 |
/************************
|
367 |
** Archive Compressor ***
|
|
368 |
************************/
|
|
369 |
||
370 |
ArchiveFunction::ArchiveCompressor::ArchiveCompressor() |
|
371 |
: theArchive(0), |
|
372 |
theEntry(0), |
|
373 |
theStream(new std::stringstream()) |
|
374 |
{
|
|
375 |
theEntry = archive_entry_new(); |
|
376 |
}
|
|
377 |
||
378 |
ArchiveFunction::ArchiveCompressor::~ArchiveCompressor() |
|
379 |
{
|
|
380 |
archive_entry_free(theEntry); |
|
381 |
}
|
|
382 |
||
383 |
void
|
|
384 |
ArchiveFunction::ArchiveCompressor::setOptions(const ArchiveOptions& aOptions) |
|
385 |
{
|
|
35
by Matthias Brantner
- reworked the way options are passed and named |
386 |
theOptions = aOptions; |
387 |
||
23.2.1
by Juan Zacarias
changed ArchiveCompressor's namespace to ArchiveFunction |
388 |
int lFormatCode = formatCode(aOptions.getFormat().c_str()); |
389 |
int lErr = archive_write_set_format(theArchive, lFormatCode); |
|
390 |
ArchiveFunction::checkForError(lErr, 0, theArchive); |
|
391 |
||
35
by Matthias Brantner
- reworked the way options are passed and named |
392 |
int lCompressionCode = compressionCode(aOptions.getCompression().c_str()); |
23.2.1
by Juan Zacarias
changed ArchiveCompressor's namespace to ArchiveFunction |
393 |
setArchiveCompression(theArchive, lCompressionCode); |
394 |
||
42
by Matthias Brantner
- new option skip-extra-attrs (same effect as zip -X) but needs a special version of libarchive |
395 |
if (aOptions.getSkipExtraAttrs()) |
396 |
{
|
|
397 |
// ignore result value because some libarchive versions
|
|
398 |
// don't support this option
|
|
399 |
archive_write_set_options(theArchive, "zip:skip-extras=true"); |
|
400 |
}
|
|
401 |
||
23.2.1
by Juan Zacarias
changed ArchiveCompressor's namespace to ArchiveFunction |
402 |
lErr = archive_write_open( |
403 |
theArchive, this, 0, ArchiveFunction::writeStream, 0); |
|
404 |
ArchiveFunction::checkForError(lErr, 0, theArchive); |
|
405 |
}
|
|
406 |
||
407 |
bool
|
|
408 |
ArchiveFunction::ArchiveCompressor::getStreamForString( |
|
409 |
const zorba::String& aEncoding, |
|
410 |
zorba::Item& aFile, |
|
411 |
std::istream*& aResStream, |
|
412 |
uint64_t& aResFileSize) const |
|
413 |
{
|
|
414 |
// 1. always need to materialize if transcoding is necessary
|
|
415 |
// or stream is not seekable to compute resulting file size
|
|
416 |
if (aFile.isStreamable() && |
|
417 |
(!aFile.isSeekable() || |
|
418 |
transcode::is_necessary(aEncoding.c_str()))) |
|
419 |
{
|
|
420 |
aResStream = &aFile.getStream(); |
|
421 |
||
422 |
if (transcode::is_necessary(aEncoding.c_str())) |
|
423 |
{
|
|
424 |
transcode::attach(*aResStream, aEncoding.c_str()); |
|
425 |
}
|
|
426 |
||
427 |
std::stringstream* lStream = new std::stringstream(); |
|
428 |
||
429 |
char lBuf[ZORBA_ARCHIVE_MAX_READ_BUF]; |
|
430 |
while (aResStream->good()) |
|
431 |
{
|
|
432 |
aResStream->read(lBuf, ZORBA_ARCHIVE_MAX_READ_BUF); |
|
433 |
lStream->write(lBuf, aResStream->gcount()); |
|
434 |
aResFileSize += aResStream->gcount(); |
|
435 |
}
|
|
436 |
aResStream = lStream; |
|
437 |
return true; // delete after use |
|
438 |
}
|
|
439 |
// 2. seekable and no transcoding is best cast
|
|
440 |
// => compute size by seeking and return stream as-is
|
|
441 |
else if (aFile.isStreamable()) |
|
442 |
{
|
|
443 |
aResStream = &aFile.getStream(); |
|
444 |
||
445 |
aResStream->seekg(0, std::ios::end); |
|
446 |
aResFileSize = aResStream->tellg(); |
|
447 |
aResStream->seekg(0, std::ios::beg); |
|
448 |
return false; |
|
449 |
}
|
|
450 |
// 3. non-streamable string
|
|
451 |
else
|
|
452 |
{
|
|
453 |
std::stringstream* lStream = new std::stringstream(); |
|
454 |
||
455 |
// 3.1 with transcoding
|
|
456 |
if (transcode::is_necessary(aEncoding.c_str())) |
|
457 |
{
|
|
458 |
transcode::stream<std::istringstream> lTranscoder( |
|
459 |
aEncoding.c_str(), |
|
460 |
aFile.getStringValue().c_str() |
|
461 |
);
|
|
462 |
char lBuf[ZORBA_ARCHIVE_MAX_READ_BUF]; |
|
463 |
while (lTranscoder.good()) |
|
464 |
{
|
|
465 |
lTranscoder.read(lBuf, ZORBA_ARCHIVE_MAX_READ_BUF); |
|
466 |
lStream->write(lBuf, lTranscoder.gcount()); |
|
467 |
aResFileSize += lTranscoder.gcount(); |
|
468 |
}
|
|
469 |
}
|
|
470 |
else // 3.2 without transcoding |
|
471 |
{
|
|
472 |
zorba::String lString = aFile.getStringValue(); |
|
473 |
aResFileSize = lString.length(); |
|
474 |
lStream->write(lString.c_str(), aResFileSize); |
|
475 |
}
|
|
476 |
aResStream = lStream; |
|
477 |
return true; |
|
478 |
}
|
|
479 |
}
|
|
480 |
||
481 |
bool
|
|
482 |
ArchiveFunction::ArchiveCompressor::getStreamForBase64( |
|
483 |
zorba::Item& aFile, |
|
484 |
std::istream*& aResStream, |
|
485 |
uint64_t& aResFileSize) const |
|
486 |
{
|
|
487 |
if (aFile.isStreamable() && aFile.isSeekable()) |
|
488 |
{
|
|
489 |
aResStream = &aFile.getStream(); |
|
490 |
||
491 |
aResStream->seekg(0, std::ios::end); |
|
492 |
aResFileSize = aResStream->tellg(); |
|
493 |
aResStream->seekg(0, std::ios::beg); |
|
494 |
||
495 |
if (aFile.isEncoded()) |
|
496 |
{
|
|
497 |
base64::attach(*aResStream); |
|
498 |
// compute the size of the stream after base64 decoding
|
|
499 |
aResFileSize = ((aResFileSize / 4) + !!(aResFileSize % 4)) * 3; |
|
500 |
}
|
|
501 |
return false; |
|
502 |
}
|
|
503 |
else
|
|
504 |
{
|
|
505 |
std::stringstream* lStream = new std::stringstream(); |
|
506 |
||
507 |
size_t lResFileSize; |
|
508 |
const char* lBinValue = aFile.getBase64BinaryValue(lResFileSize); |
|
509 |
||
510 |
if (aFile.isEncoded()) |
|
511 |
{
|
|
512 |
zorba::String lEncoded(lBinValue, lResFileSize); |
|
48
by Paul J. Lucas
Include file clean-up. |
513 |
zorba::String lDecoded = zorba::base64::decode(lEncoded); |
23.2.1
by Juan Zacarias
changed ArchiveCompressor's namespace to ArchiveFunction |
514 |
lStream->write(lDecoded.c_str(), lDecoded.length()); |
515 |
aResFileSize = lDecoded.size(); |
|
516 |
}
|
|
517 |
else
|
|
518 |
{
|
|
519 |
lStream->write(lBinValue, lResFileSize); |
|
520 |
aResFileSize = lResFileSize; |
|
521 |
}
|
|
522 |
aResStream = lStream; |
|
523 |
return true; |
|
524 |
}
|
|
525 |
}
|
|
526 |
||
527 |
bool
|
|
528 |
ArchiveFunction::ArchiveCompressor::getStream( |
|
529 |
const ArchiveEntry& aEntry, |
|
530 |
zorba::Item& aFile, |
|
531 |
std::istream*& aResStream, |
|
532 |
uint64_t& aResFileSize) const |
|
533 |
{
|
|
534 |
aResFileSize = 0; |
|
535 |
||
536 |
switch (aFile.getTypeCode()) |
|
537 |
{
|
|
538 |
case store::XS_STRING: |
|
539 |
{
|
|
540 |
const zorba::String& lEncoding = aEntry.getEncoding(); |
|
541 |
||
542 |
return getStreamForString(lEncoding, aFile, aResStream, aResFileSize); |
|
543 |
}
|
|
544 |
case store::XS_BASE64BINARY: |
|
545 |
{
|
|
546 |
return getStreamForBase64(aFile, aResStream, aResFileSize); |
|
547 |
}
|
|
548 |
default: |
|
549 |
{
|
|
550 |
String errNS("http://www.w3.org/2005/xqt-errors"); |
|
551 |
Item errQName = ArchiveModule::getItemFactory()->createQName( |
|
552 |
errNS, "FORG0006"); |
|
553 |
std::ostringstream lMsg; |
|
554 |
lMsg << aFile.getType().getStringValue() |
|
555 |
<< ": invalid content argument " |
|
556 |
<< "(xs:string or xs:base64binary)"; |
|
557 |
throw USER_EXCEPTION(errQName, lMsg.str()); |
|
558 |
}
|
|
559 |
}
|
|
560 |
||
561 |
}
|
|
562 |
||
563 |
void
|
|
564 |
ArchiveFunction::ArchiveCompressor::open( |
|
565 |
const ArchiveOptions& aOptions) |
|
566 |
{
|
|
567 |
theArchive = archive_write_new(); |
|
568 |
||
569 |
if (!theArchive) |
|
570 |
ArchiveFunction::throwError( |
|
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
571 |
ERROR_CORRUPTED_ARCHIVE, "internal error (couldn't create archive)"); |
23.2.1
by Juan Zacarias
changed ArchiveCompressor's namespace to ArchiveFunction |
572 |
|
573 |
setOptions(aOptions); |
|
574 |
}
|
|
575 |
||
576 |
void
|
|
577 |
ArchiveFunction::ArchiveCompressor::compress( |
|
578 |
const std::vector<ArchiveEntry>& aEntries, |
|
579 |
zorba::Iterator_t& aFiles) |
|
580 |
{
|
|
581 |
zorba::Item lFile; |
|
582 |
aFiles->open(); |
|
583 |
||
584 |
for (size_t i = 0; i < aEntries.size(); ++i) |
|
585 |
{
|
|
42.1.6
by luisrod
- Added ability to create directories |
586 |
if(aEntries[i].getEntryType() == ArchiveEntry::regular) |
23.2.1
by Juan Zacarias
changed ArchiveCompressor's namespace to ArchiveFunction |
587 |
{
|
42.1.6
by luisrod
- Added ability to create directories |
588 |
if (!aFiles->next(lFile)) |
589 |
{
|
|
590 |
std::ostringstream lMsg; |
|
591 |
lMsg << "number of entries (" << aEntries.size() |
|
592 |
<< ") doesn't match number of content arguments (" << i << ")"; |
|
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
593 |
throwError(ERROR_ENTRY_COUNT_MISMATCH, lMsg.str().c_str()); |
42.1.6
by luisrod
- Added ability to create directories |
594 |
}
|
23.2.1
by Juan Zacarias
changed ArchiveCompressor's namespace to ArchiveFunction |
595 |
}
|
596 |
||
597 |
const ArchiveEntry& lEntry = aEntries[i]; |
|
28
by Juan Zacarias
Implemented the add in the archive update function |
598 |
|
599 |
compress(lEntry, lFile); |
|
600 |
||
601 |
}
|
|
602 |
||
603 |
if (aFiles->next(lFile)) |
|
604 |
{
|
|
605 |
std::ostringstream lMsg; |
|
606 |
lMsg << "number of entries (" << aEntries.size() |
|
607 |
<< ") less than number of content arguments"; |
|
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
608 |
throwError(ERROR_ENTRY_COUNT_MISMATCH, lMsg.str().c_str()); |
28
by Juan Zacarias
Implemented the add in the archive update function |
609 |
}
|
610 |
||
611 |
aFiles->close(); |
|
612 |
}
|
|
613 |
||
614 |
void ArchiveFunction::ArchiveCompressor::compress(const ArchiveEntry& aEntry, Item aFile) |
|
615 |
{
|
|
23.2.1
by Juan Zacarias
changed ArchiveCompressor's namespace to ArchiveFunction |
616 |
std::istream* lStream; |
617 |
bool lDeleteStream; |
|
618 |
uint64_t lFileSize; |
|
619 |
||
28
by Juan Zacarias
Implemented the add in the archive update function |
620 |
archive_entry_set_pathname(theEntry, aEntry.getEntryPath().c_str()); |
621 |
archive_entry_set_mtime(theEntry, aEntry.getLastModified(), 0); |
|
42.1.6
by luisrod
- Added ability to create directories |
622 |
if(aEntry.getEntryType() == ArchiveEntry::regular){ |
623 |
archive_entry_set_filetype(theEntry, AE_IFREG); |
|
624 |
lDeleteStream = getStream( |
|
625 |
aEntry, aFile, lStream, lFileSize); |
|
626 |
} else { |
|
627 |
archive_entry_set_filetype(theEntry, AE_IFDIR); |
|
628 |
lDeleteStream = false; |
|
629 |
lFileSize = 0; |
|
630 |
}
|
|
23.2.1
by Juan Zacarias
changed ArchiveCompressor's namespace to ArchiveFunction |
631 |
// TODO: specifies the permits of a file
|
632 |
archive_entry_set_perm(theEntry, 0644); |
|
633 |
archive_entry_set_size(theEntry, lFileSize); |
|
634 |
||
35
by Matthias Brantner
- reworked the way options are passed and named |
635 |
if (theOptions.getFormat() == "ZIP") |
636 |
{
|
|
637 |
int lNextComp; |
|
638 |
std::string lNextCompString; |
|
639 |
if (aEntry.getCompression().length() > 0) |
|
640 |
{
|
|
641 |
lNextCompString = aEntry.getCompression().c_str(); |
|
642 |
lNextComp = compressionCode(lNextCompString); |
|
643 |
#ifndef ZORBA_LIBARCHIVE_HAVE_SET_COMPRESSION
|
|
644 |
std::ostringstream lMsg; |
|
645 |
lMsg << lNextCompString << ": setting different compression algorithms for each entry is not supported by the used version of libarchive"; |
|
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
646 |
throwError(ERROR_DIFFERENT_COMPRESSIONS_NOT_SUPPORTED, lMsg.str().c_str()); |
35
by Matthias Brantner
- reworked the way options are passed and named |
647 |
#endif
|
648 |
}
|
|
649 |
else
|
|
650 |
{
|
|
651 |
lNextCompString = theOptions.getCompression(); |
|
652 |
lNextComp = compressionCode(lNextCompString); |
|
653 |
}
|
|
37
by Matthias Brantner
fix if libarchive is not patched |
654 |
if (lNextComp < ZORBA_ARCHIVE_COMPRESSION_DEFLATE && lNextComp != ARCHIVE_COMPRESSION_NONE) |
35
by Matthias Brantner
- reworked the way options are passed and named |
655 |
{
|
656 |
std::ostringstream lMsg; |
|
657 |
lMsg << lNextCompString << ": compression algorithm not supported for ZIP format (required: deflate, store)"; |
|
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
658 |
throwError(ERROR_INVALID_OPTIONS, lMsg.str().c_str()); |
35
by Matthias Brantner
- reworked the way options are passed and named |
659 |
}
|
660 |
||
661 |
#ifdef ZORBA_LIBARCHIVE_HAVE_SET_COMPRESSION
|
|
662 |
setArchiveCompression(theArchive, lNextComp); |
|
663 |
#endif
|
|
664 |
}
|
|
36
by Matthias Brantner
better errors + removed support for exotic formats and compressions |
665 |
else
|
666 |
{
|
|
667 |
if (aEntry.getCompression().length() > 0) |
|
668 |
{
|
|
669 |
std::ostringstream lMsg; |
|
670 |
lMsg << aEntry.getCompression() << ": compression attribute only allowed for zip format"; |
|
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
671 |
throwError(ERROR_DIFFERENT_COMPRESSIONS_NOT_SUPPORTED, lMsg.str().c_str()); |
36
by Matthias Brantner
better errors + removed support for exotic formats and compressions |
672 |
}
|
673 |
}
|
|
35
by Matthias Brantner
- reworked the way options are passed and named |
674 |
|
23.2.1
by Juan Zacarias
changed ArchiveCompressor's namespace to ArchiveFunction |
675 |
archive_write_header(theArchive, theEntry); |
676 |
||
42.1.6
by luisrod
- Added ability to create directories |
677 |
if(aEntry.getEntryType() == ArchiveEntry::regular) |
23.2.1
by Juan Zacarias
changed ArchiveCompressor's namespace to ArchiveFunction |
678 |
{
|
42.1.6
by luisrod
- Added ability to create directories |
679 |
char lBuf[ZORBA_ARCHIVE_MAX_READ_BUF]; |
680 |
while (lStream->good()) |
|
681 |
{
|
|
682 |
lStream->read(lBuf, ZORBA_ARCHIVE_MAX_READ_BUF); |
|
683 |
archive_write_data(theArchive, lBuf, lStream->gcount()); |
|
684 |
}
|
|
23.2.1
by Juan Zacarias
changed ArchiveCompressor's namespace to ArchiveFunction |
685 |
}
|
686 |
||
687 |
archive_entry_clear(theEntry); |
|
688 |
archive_write_finish_entry(theArchive); |
|
689 |
||
690 |
if (lDeleteStream) |
|
691 |
{
|
|
692 |
delete lStream; |
|
693 |
lStream = 0; |
|
694 |
}
|
|
695 |
}
|
|
696 |
||
697 |
void
|
|
698 |
ArchiveFunction::ArchiveCompressor::close() |
|
699 |
{
|
|
700 |
archive_write_close(theArchive); |
|
701 |
archive_write_finish(theArchive); |
|
702 |
}
|
|
703 |
||
704 |
std::stringstream* |
|
705 |
ArchiveFunction::ArchiveCompressor::getResultStream() |
|
706 |
{
|
|
707 |
return theStream; |
|
708 |
}
|
|
709 |
||
710 |
||
15
by Juan Zacarias
Partial implementation of create function |
711 |
String
|
23.2.1
by Juan Zacarias
changed ArchiveCompressor's namespace to ArchiveFunction |
712 |
ArchiveFunction::getURI() const |
15
by Juan Zacarias
Partial implementation of create function |
713 |
{
|
714 |
return theModule->getURI(); |
|
7
by Matthias Brantner
fixed two build problems: |
715 |
}
|
716 |
||
717 |
void
|
|
23.2.1
by Juan Zacarias
changed ArchiveCompressor's namespace to ArchiveFunction |
718 |
ArchiveFunction::throwError( |
9
by Matthias Brantner
- introduced a schema for entries and options |
719 |
const char* aLocalName, |
720 |
const char* aErrorMessage) |
|
7
by Matthias Brantner
fixed two build problems: |
721 |
{
|
9
by Matthias Brantner
- introduced a schema for entries and options |
722 |
String errNS(ArchiveModule::getModuleURI()); |
723 |
Item errQName = ArchiveModule::getItemFactory()->createQName( |
|
724 |
errNS, aLocalName); |
|
725 |
throw USER_EXCEPTION(errQName, aErrorMessage); |
|
5
by Juan Zacarias
Changed name to archive module |
726 |
}
|
727 |
||
9
by Matthias Brantner
- introduced a schema for entries and options |
728 |
void
|
23.2.1
by Juan Zacarias
changed ArchiveCompressor's namespace to ArchiveFunction |
729 |
ArchiveFunction::checkForError( |
9
by Matthias Brantner
- introduced a schema for entries and options |
730 |
int aErrNo, |
731 |
const char* aLocalName, |
|
732 |
struct archive *a) |
|
5
by Juan Zacarias
Changed name to archive module |
733 |
{
|
9
by Matthias Brantner
- introduced a schema for entries and options |
734 |
if (aErrNo != ARCHIVE_OK) |
5
by Juan Zacarias
Changed name to archive module |
735 |
{
|
9
by Matthias Brantner
- introduced a schema for entries and options |
736 |
if (!aLocalName) |
737 |
{
|
|
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
738 |
throwError(ERROR_CORRUPTED_ARCHIVE, archive_error_string(a)); |
9
by Matthias Brantner
- introduced a schema for entries and options |
739 |
}
|
740 |
else
|
|
741 |
{
|
|
742 |
throwError(aLocalName, archive_error_string(a)); |
|
743 |
}
|
|
5
by Juan Zacarias
Changed name to archive module |
744 |
}
|
9
by Matthias Brantner
- introduced a schema for entries and options |
745 |
}
|
746 |
||
747 |
zorba::Item |
|
748 |
ArchiveFunction::getOneItem(const Arguments_t& aArgs, int aIndex) |
|
749 |
{
|
|
750 |
Item lItem; |
|
751 |
Iterator_t args_iter = aArgs[aIndex]->getIterator(); |
|
752 |
args_iter->open(); |
|
753 |
args_iter->next(lItem); |
|
754 |
args_iter->close(); |
|
755 |
||
756 |
return lItem; |
|
757 |
}
|
|
758 |
||
14.1.2
by Matthias Brantner
added the archive:options function to return algorithm and format options of an archive |
759 |
std::string |
760 |
ArchiveFunction::formatName(int f) |
|
761 |
{
|
|
762 |
// first 16 bit indicate the format family
|
|
763 |
switch (f & ARCHIVE_FORMAT_BASE_MASK) |
|
764 |
{
|
|
765 |
case ARCHIVE_FORMAT_TAR: return "TAR"; |
|
766 |
case ARCHIVE_FORMAT_ZIP: return "ZIP"; |
|
767 |
default: return ""; |
|
768 |
}
|
|
769 |
}
|
|
770 |
||
771 |
std::string |
|
772 |
ArchiveFunction::compressionName(int c) |
|
773 |
{
|
|
774 |
switch (c) |
|
775 |
{
|
|
776 |
case ARCHIVE_COMPRESSION_NONE: return "NONE"; |
|
35
by Matthias Brantner
- reworked the way options are passed and named |
777 |
case ZORBA_ARCHIVE_COMPRESSION_DEFLATE: return "DEFLATE"; |
778 |
case ZORBA_ARCHIVE_COMPRESSION_STORE: return "STORE"; |
|
14.1.2
by Matthias Brantner
added the archive:options function to return algorithm and format options of an archive |
779 |
case ARCHIVE_COMPRESSION_GZIP: return "GZIP"; |
780 |
case ARCHIVE_COMPRESSION_BZIP2: return "BZIP2"; |
|
781 |
case ARCHIVE_COMPRESSION_LZMA: return "LZMA"; |
|
782 |
default: return ""; |
|
783 |
}
|
|
784 |
}
|
|
785 |
||
19
by Matthias Brantner
support for create options |
786 |
int
|
787 |
ArchiveFunction::formatCode(const std::string& f) |
|
788 |
{
|
|
36
by Matthias Brantner
better errors + removed support for exotic formats and compressions |
789 |
if (f == "TAR") |
19
by Matthias Brantner
support for create options |
790 |
{
|
21
by Matthias Brantner
- case insensitive entry and format options |
791 |
return ARCHIVE_FORMAT_TAR_USTAR; |
19
by Matthias Brantner
support for create options |
792 |
}
|
793 |
else if (f == "ZIP") |
|
794 |
{
|
|
795 |
return ARCHIVE_FORMAT_ZIP; |
|
796 |
}
|
|
797 |
else
|
|
798 |
{
|
|
799 |
std::ostringstream lMsg; |
|
800 |
lMsg << f << ": archive format not supported"; |
|
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
801 |
throwError(ERROR_INVALID_OPTIONS, lMsg.str().c_str()); |
19
by Matthias Brantner
support for create options |
802 |
}
|
803 |
return 0; |
|
804 |
}
|
|
805 |
||
806 |
int
|
|
807 |
ArchiveFunction::compressionCode(const std::string& c) |
|
808 |
{
|
|
809 |
if (c == "NONE") |
|
810 |
{
|
|
811 |
return ARCHIVE_COMPRESSION_NONE; |
|
812 |
}
|
|
42
by Matthias Brantner
- new option skip-extra-attrs (same effect as zip -X) but needs a special version of libarchive |
813 |
else if (c == "STORE") |
35
by Matthias Brantner
- reworked the way options are passed and named |
814 |
{
|
815 |
return ZORBA_ARCHIVE_COMPRESSION_STORE; |
|
816 |
}
|
|
42
by Matthias Brantner
- new option skip-extra-attrs (same effect as zip -X) but needs a special version of libarchive |
817 |
else if (c == "DEFLATE") |
35
by Matthias Brantner
- reworked the way options are passed and named |
818 |
{
|
819 |
return ZORBA_ARCHIVE_COMPRESSION_DEFLATE; |
|
820 |
}
|
|
19
by Matthias Brantner
support for create options |
821 |
else if (c == "GZIP") |
822 |
{
|
|
823 |
return ARCHIVE_COMPRESSION_GZIP; |
|
824 |
}
|
|
825 |
else if (c == "BZIP2") |
|
826 |
{
|
|
827 |
return ARCHIVE_COMPRESSION_BZIP2; |
|
828 |
}
|
|
829 |
else if (c == "LZMA") |
|
830 |
{
|
|
831 |
return ARCHIVE_COMPRESSION_LZMA; |
|
832 |
}
|
|
833 |
else
|
|
834 |
{
|
|
835 |
std::ostringstream lMsg; |
|
836 |
lMsg << c << ": compression algorithm not supported"; |
|
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
837 |
throwError(ERROR_INVALID_OPTIONS, lMsg.str().c_str()); |
19
by Matthias Brantner
support for create options |
838 |
}
|
839 |
return 0; |
|
840 |
}
|
|
841 |
||
842 |
void
|
|
843 |
ArchiveFunction::setArchiveCompression(struct archive* a, int c) |
|
844 |
{
|
|
21
by Matthias Brantner
- case insensitive entry and format options |
845 |
int lErr = 0; |
19
by Matthias Brantner
support for create options |
846 |
switch (c) |
847 |
{
|
|
35
by Matthias Brantner
- reworked the way options are passed and named |
848 |
#ifdef ZORBA_LIBARCHIVE_HAVE_SET_COMPRESSION
|
849 |
case ZORBA_ARCHIVE_COMPRESSION_STORE: |
|
850 |
lErr = archive_write_zip_set_compression_store(a); break; |
|
851 |
case ZORBA_ARCHIVE_COMPRESSION_DEFLATE: |
|
852 |
case ARCHIVE_COMPRESSION_NONE: |
|
853 |
lErr = archive_write_zip_set_compression_deflate(a); break; |
|
854 |
#else
|
|
855 |
case ZORBA_ARCHIVE_COMPRESSION_STORE: |
|
38
by Matthias Brantner
renamed module: |
856 |
archive_write_set_options(a, "zip:compression=store"); |
35
by Matthias Brantner
- reworked the way options are passed and named |
857 |
break; |
858 |
case ZORBA_ARCHIVE_COMPRESSION_DEFLATE: |
|
38
by Matthias Brantner
renamed module: |
859 |
archive_write_set_options(a, "zip:compression=deflate"); |
35
by Matthias Brantner
- reworked the way options are passed and named |
860 |
break; |
19
by Matthias Brantner
support for create options |
861 |
case ARCHIVE_COMPRESSION_NONE: |
21
by Matthias Brantner
- case insensitive entry and format options |
862 |
lErr = archive_write_set_compression_none(a); break; |
35
by Matthias Brantner
- reworked the way options are passed and named |
863 |
#endif
|
19
by Matthias Brantner
support for create options |
864 |
case ARCHIVE_COMPRESSION_GZIP: |
21
by Matthias Brantner
- case insensitive entry and format options |
865 |
lErr = archive_write_set_compression_gzip(a); break; |
19
by Matthias Brantner
support for create options |
866 |
case ARCHIVE_COMPRESSION_BZIP2: |
21
by Matthias Brantner
- case insensitive entry and format options |
867 |
lErr = archive_write_set_compression_bzip2(a); break; |
19
by Matthias Brantner
support for create options |
868 |
case ARCHIVE_COMPRESSION_LZMA: |
21
by Matthias Brantner
- case insensitive entry and format options |
869 |
lErr = archive_write_set_compression_lzma(a); break; |
19
by Matthias Brantner
support for create options |
870 |
default: assert(false); |
871 |
}
|
|
21
by Matthias Brantner
- case insensitive entry and format options |
872 |
ArchiveFunction::checkForError(lErr, 0, a); |
19
by Matthias Brantner
support for create options |
873 |
}
|
874 |
||
9
by Matthias Brantner
- introduced a schema for entries and options |
875 |
#ifdef WIN32
|
876 |
long
|
|
877 |
#else
|
|
878 |
ssize_t
|
|
879 |
#endif
|
|
11
by Matthias Brantner
- extract-text#1 function (without transcoding) |
880 |
ArchiveItemSequence::readStream(struct archive*, void *data, const void **buff) |
9
by Matthias Brantner
- introduced a schema for entries and options |
881 |
{
|
11
by Matthias Brantner
- extract-text#1 function (without transcoding) |
882 |
ArchiveItemSequence::CallbackData* lData = |
883 |
reinterpret_cast<ArchiveItemSequence::CallbackData*>(data); |
|
9
by Matthias Brantner
- introduced a schema for entries and options |
884 |
|
14
by Matthias Brantner
make sure that multiple xquery functions accessing the same zip file works |
885 |
if (lData->theEnd) return 0; |
886 |
||
9
by Matthias Brantner
- introduced a schema for entries and options |
887 |
std::istream* lStream = lData->theStream; |
888 |
||
14
by Matthias Brantner
make sure that multiple xquery functions accessing the same zip file works |
889 |
// seek to where we left of
|
890 |
if (lData->theSeekable) lStream->seekg(lData->thePos, std::ios::beg); |
|
891 |
||
9
by Matthias Brantner
- introduced a schema for entries and options |
892 |
lStream->read(lData->theBuffer, ZORBA_ARCHIVE_MAX_READ_BUF); |
893 |
*buff = lData->theBuffer; |
|
894 |
||
14
by Matthias Brantner
make sure that multiple xquery functions accessing the same zip file works |
895 |
if (lStream->eof()) lData->theEnd = true; |
896 |
||
897 |
// remember the stream pos before leaving the function
|
|
898 |
if (lData->theSeekable) lData->thePos = lStream->tellg(); |
|
899 |
||
9
by Matthias Brantner
- introduced a schema for entries and options |
900 |
return lStream->gcount(); |
901 |
}
|
|
902 |
||
22
by Matthias Brantner
- properly handle base64 values |
903 |
ArchiveItemSequence::ArchiveIterator::ArchiveIterator(zorba::Item& a) |
11
by Matthias Brantner
- extract-text#1 function (without transcoding) |
904 |
: theArchiveItem(a), |
905 |
theArchive(0), |
|
906 |
theFactory(Zorba::getInstance(0)->getItemFactory()) |
|
907 |
{}
|
|
908 |
||
909 |
void
|
|
910 |
ArchiveItemSequence::ArchiveIterator::open() |
|
911 |
{
|
|
912 |
// open archive and allow for all kinds of formats and compression algos
|
|
913 |
theArchive = archive_read_new(); |
|
914 |
||
915 |
if (!theArchive) |
|
916 |
ArchiveFunction::throwError( |
|
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
917 |
ERROR_CORRUPTED_ARCHIVE, "internal error (couldn't create archive)"); |
11
by Matthias Brantner
- extract-text#1 function (without transcoding) |
918 |
|
919 |
int lErr = archive_read_support_compression_all(theArchive); |
|
920 |
ArchiveFunction::checkForError(lErr, 0, theArchive); |
|
921 |
||
922 |
archive_read_support_format_all(theArchive); |
|
923 |
ArchiveFunction::checkForError(lErr, 0, theArchive); |
|
924 |
||
925 |
if (theArchiveItem.isStreamable()) |
|
926 |
{
|
|
927 |
theData.theStream = &theArchiveItem.getStream(); |
|
14
by Matthias Brantner
make sure that multiple xquery functions accessing the same zip file works |
928 |
theData.theStream->clear(); |
929 |
theData.theSeekable = theArchiveItem.isSeekable(); |
|
930 |
theData.theEnd = false; |
|
931 |
theData.thePos = 0; |
|
11
by Matthias Brantner
- extract-text#1 function (without transcoding) |
932 |
|
22
by Matthias Brantner
- properly handle base64 values |
933 |
if (theArchiveItem.isEncoded()) |
934 |
{
|
|
935 |
base64::attach(*theData.theStream); |
|
936 |
}
|
|
11
by Matthias Brantner
- extract-text#1 function (without transcoding) |
937 |
|
45.1.1
by Luis Rodriguez Gonzalez
-Replaced open functions with old ones to make it work with Macports |
938 |
lErr = archive_read_open(theArchive, &theData, NULL, ArchiveItemSequence::readStream, NULL); |
11
by Matthias Brantner
- extract-text#1 function (without transcoding) |
939 |
ArchiveFunction::checkForError(lErr, 0, theArchive); |
940 |
}
|
|
941 |
else
|
|
942 |
{
|
|
943 |
size_t lLen = 0; |
|
22
by Matthias Brantner
- properly handle base64 values |
944 |
char* lData = const_cast<char*>( |
945 |
theArchiveItem.getBase64BinaryValue(lLen)); |
|
946 |
||
947 |
if (theArchiveItem.isEncoded()) |
|
948 |
{
|
|
949 |
zorba::String lEncoded(lData, lLen); |
|
48
by Paul J. Lucas
Include file clean-up. |
950 |
theDecodedData = base64::decode(lEncoded); |
22
by Matthias Brantner
- properly handle base64 values |
951 |
lLen = theDecodedData.size(); |
952 |
lErr = archive_read_open_memory(theArchive, |
|
953 |
const_cast<char*>(theDecodedData.c_str()), lLen); |
|
954 |
ArchiveFunction::checkForError(lErr, 0, theArchive); |
|
955 |
}
|
|
956 |
else
|
|
957 |
{
|
|
958 |
lErr = archive_read_open_memory(theArchive, lData, lLen); |
|
959 |
ArchiveFunction::checkForError(lErr, 0, theArchive); |
|
960 |
}
|
|
961 |
||
11
by Matthias Brantner
- extract-text#1 function (without transcoding) |
962 |
}
|
963 |
}
|
|
964 |
||
965 |
void
|
|
966 |
ArchiveItemSequence::ArchiveIterator::close() |
|
967 |
{
|
|
968 |
int lErr = archive_read_finish(theArchive); |
|
969 |
ArchiveFunction::checkForError(lErr, 0, theArchive); |
|
970 |
theArchive = 0; |
|
971 |
}
|
|
9
by Matthias Brantner
- introduced a schema for entries and options |
972 |
|
15
by Juan Zacarias
Partial implementation of create function |
973 |
#ifdef WIN32
|
974 |
long
|
|
975 |
#else
|
|
976 |
ssize_t
|
|
977 |
#endif
|
|
17
by Matthias Brantner
first very basic version of create#2 and #3 |
978 |
ArchiveFunction::writeStream( |
979 |
struct archive *, |
|
980 |
void *func, |
|
981 |
const void *buff, |
|
982 |
size_t n) |
|
15
by Juan Zacarias
Partial implementation of create function |
983 |
{
|
28
by Juan Zacarias
Implemented the add in the archive update function |
984 |
ArchiveFunction::ArchiveCompressor* lFunc = |
985 |
static_cast<ArchiveFunction::ArchiveCompressor*>(func); |
|
15
by Juan Zacarias
Partial implementation of create function |
986 |
|
17
by Matthias Brantner
first very basic version of create#2 and #3 |
987 |
const char * lBuf = static_cast<const char *>(buff); |
22
by Matthias Brantner
- properly handle base64 values |
988 |
lFunc->getResultStream()->write(lBuf, n); |
15
by Juan Zacarias
Partial implementation of create function |
989 |
|
990 |
return n; |
|
991 |
}
|
|
992 |
||
17
by Matthias Brantner
first very basic version of create#2 and #3 |
993 |
/*******************************************************************************
|
994 |
******************************************************************************/
|
|
5
by Juan Zacarias
Changed name to archive module |
995 |
zorba::ItemSequence_t |
996 |
CreateFunction::evaluate( |
|
997 |
const Arguments_t& aArgs, |
|
998 |
const zorba::StaticContext* aSctx, |
|
999 |
const zorba::DynamicContext* aDctx) const |
|
1000 |
{
|
|
17
by Matthias Brantner
first very basic version of create#2 and #3 |
1001 |
std::vector<ArchiveEntry> lEntries; |
1002 |
||
1003 |
{
|
|
1004 |
Iterator_t lEntriesIter = aArgs[0]->getIterator(); |
|
1005 |
||
1006 |
zorba::Item lEntry; |
|
1007 |
lEntriesIter->open(); |
|
1008 |
while (lEntriesIter->next(lEntry)) |
|
1009 |
{
|
|
1010 |
lEntries.resize(lEntries.size() + 1); |
|
1011 |
lEntries.back().setValues(lEntry); |
|
1012 |
}
|
|
1013 |
lEntriesIter->close(); |
|
1014 |
}
|
|
1015 |
||
1016 |
ArchiveOptions lOptions; |
|
1017 |
||
1018 |
if (aArgs.size() == 3) |
|
1019 |
{
|
|
1020 |
zorba::Item lOptionsItem = getOneItem(aArgs, 2); |
|
1021 |
lOptions.setValues(lOptionsItem); |
|
1022 |
}
|
|
1023 |
||
1024 |
ArchiveCompressor lArchive; |
|
1025 |
||
1026 |
zorba::Iterator_t lFileIter = aArgs[1]->getIterator(); |
|
23.2.1
by Juan Zacarias
changed ArchiveCompressor's namespace to ArchiveFunction |
1027 |
lArchive.open(lOptions); |
1028 |
lArchive.compress(lEntries, lFileIter); |
|
1029 |
lArchive.close(); |
|
17
by Matthias Brantner
first very basic version of create#2 and #3 |
1030 |
|
1031 |
zorba::Item lRes = theModule->getItemFactory()-> |
|
1032 |
createStreamableBase64Binary( |
|
22
by Matthias Brantner
- properly handle base64 values |
1033 |
*lArchive.getResultStream(), |
28
by Juan Zacarias
Implemented the add in the archive update function |
1034 |
&(ArchiveFunction::ArchiveCompressor::releaseStream), |
17
by Matthias Brantner
first very basic version of create#2 and #3 |
1035 |
true, // seekable |
1036 |
false // not encoded |
|
1037 |
);
|
|
1038 |
return ItemSequence_t(new SingletonItemSequence(lRes)); |
|
7
by Matthias Brantner
fixed two build problems: |
1039 |
}
|
1040 |
||
15
by Juan Zacarias
Partial implementation of create function |
1041 |
|
22
by Matthias Brantner
- properly handle base64 values |
1042 |
/*******************************************************************************
|
1043 |
******************************************************************************/
|
|
5
by Juan Zacarias
Changed name to archive module |
1044 |
zorba::ItemSequence_t |
8
by Matthias Brantner
streaming archive:entries |
1045 |
EntriesFunction::evaluate( |
1046 |
const Arguments_t& aArgs, |
|
1047 |
const zorba::StaticContext* aSctx, |
|
1048 |
const zorba::DynamicContext* aDctx) const |
|
5
by Juan Zacarias
Changed name to archive module |
1049 |
{
|
9
by Matthias Brantner
- introduced a schema for entries and options |
1050 |
Item lArchive = getOneItem(aArgs, 0); |
8
by Matthias Brantner
streaming archive:entries |
1051 |
|
1052 |
return ItemSequence_t(new EntriesItemSequence(lArchive)); |
|
1053 |
}
|
|
1054 |
||
1055 |
EntriesFunction::EntriesItemSequence::EntriesIterator::EntriesIterator( |
|
1056 |
zorba::Item& aArchive) |
|
11
by Matthias Brantner
- extract-text#1 function (without transcoding) |
1057 |
: ArchiveIterator(aArchive) |
8
by Matthias Brantner
streaming archive:entries |
1058 |
{
|
53
by Luis Rodriguez Gonzalez
All comments fixed |
1059 |
gNameKey = theFactory->createString(NAME_KEY_NAME); |
1060 |
gTypeKey = theFactory->createString(TYPE_KEY_NAME); |
|
1061 |
gSizeKey = theFactory->createString(SIZE_KEY_NAME); |
|
1062 |
gLastModifiedKey = theFactory->createString(LAST_MODIFIED_KEY_NAME); |
|
8
by Matthias Brantner
streaming archive:entries |
1063 |
}
|
1064 |
||
1065 |
bool
|
|
9
by Matthias Brantner
- introduced a schema for entries and options |
1066 |
EntriesFunction::EntriesItemSequence::EntriesIterator::next(zorba::Item& aRes) |
8
by Matthias Brantner
streaming archive:entries |
1067 |
{
|
1068 |
struct archive_entry *lEntry; |
|
1069 |
||
9
by Matthias Brantner
- introduced a schema for entries and options |
1070 |
int lErr = archive_read_next_header(theArchive, &lEntry); |
1071 |
||
1072 |
if (lErr == ARCHIVE_EOF) return false; |
|
1073 |
||
1074 |
if (lErr != ARCHIVE_OK) |
|
8
by Matthias Brantner
streaming archive:entries |
1075 |
{
|
9
by Matthias Brantner
- introduced a schema for entries and options |
1076 |
ArchiveFunction::checkForError(lErr, 0, theArchive); |
8
by Matthias Brantner
streaming archive:entries |
1077 |
}
|
1078 |
||
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
1079 |
std::vector<std::pair<zorba::Item, zorba::Item> > lObjectArray; |
1080 |
std::pair<zorba::Item, zorba::Item> lElemPair; |
|
1081 |
||
9
by Matthias Brantner
- introduced a schema for entries and options |
1082 |
// create text content (i.e. path name)
|
8
by Matthias Brantner
streaming archive:entries |
1083 |
String lName = archive_entry_pathname(lEntry); |
53
by Luis Rodriguez Gonzalez
All comments fixed |
1084 |
lElemPair = std::make_pair<zorba::Item, zorba::Item>(gNameKey, |
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
1085 |
theFactory->createString(lName)); |
1086 |
lObjectArray.push_back(lElemPair); |
|
9
by Matthias Brantner
- introduced a schema for entries and options |
1087 |
|
1088 |
// create size attr if the value is set in the archive
|
|
1089 |
if (archive_entry_size_is_set(lEntry)) |
|
1090 |
{
|
|
1091 |
long long lSize = archive_entry_size(lEntry); |
|
53
by Luis Rodriguez Gonzalez
All comments fixed |
1092 |
lElemPair = std::make_pair<zorba::Item, zorba::Item>(gSizeKey, |
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
1093 |
theFactory->createInteger(lSize)); |
1094 |
lObjectArray.push_back(lElemPair); |
|
9
by Matthias Brantner
- introduced a schema for entries and options |
1095 |
}
|
1096 |
||
1097 |
// create last-modified attr if the value is set in the archive
|
|
1098 |
if (archive_entry_mtime_is_set(lEntry)) |
|
1099 |
{
|
|
1100 |
time_t lTime = archive_entry_mtime(lEntry); |
|
53
by Luis Rodriguez Gonzalez
All comments fixed |
1101 |
lElemPair = std::make_pair<zorba::Item, zorba::Item>(gLastModifiedKey, |
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
1102 |
ArchiveModule::createDateTimeItem(lTime)); |
1103 |
lObjectArray.push_back(lElemPair); |
|
9
by Matthias Brantner
- introduced a schema for entries and options |
1104 |
}
|
1105 |
||
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
1106 |
std::string lEntryType; |
42.1.6
by luisrod
- Added ability to create directories |
1107 |
if(archive_entry_filetype(lEntry) == AE_IFDIR) |
1108 |
{
|
|
1109 |
// this entry is a directory
|
|
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
1110 |
lEntryType = "directory"; |
42.1.6
by luisrod
- Added ability to create directories |
1111 |
}
|
1112 |
else if(archive_entry_filetype(lEntry) == AE_IFREG) |
|
1113 |
{
|
|
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
1114 |
lEntryType = "regular"; |
42.1.6
by luisrod
- Added ability to create directories |
1115 |
}
|
1116 |
else
|
|
1117 |
{
|
|
1118 |
// error! type not supported!
|
|
1119 |
// for the time being don't do anything
|
|
1120 |
}
|
|
1121 |
||
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
1122 |
//lMemberName = theFactory->createString("type");
|
53
by Luis Rodriguez Gonzalez
All comments fixed |
1123 |
lElemPair = std::make_pair<zorba::Item, zorba::Item>(gTypeKey, |
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
1124 |
theFactory->createString(lEntryType)); |
1125 |
lObjectArray.push_back(lElemPair); |
|
42.1.6
by luisrod
- Added ability to create directories |
1126 |
|
9
by Matthias Brantner
- introduced a schema for entries and options |
1127 |
// skip to the next entry and raise an error if that fails
|
1128 |
lErr = archive_read_data_skip(theArchive); |
|
1129 |
ArchiveFunction::checkForError(lErr, 0, theArchive); |
|
8
by Matthias Brantner
streaming archive:entries |
1130 |
|
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
1131 |
aRes = theFactory->createJSONObject(lObjectArray); |
1132 |
||
8
by Matthias Brantner
streaming archive:entries |
1133 |
return true; |
1134 |
}
|
|
1135 |
||
12
by Matthias Brantner
extract-text#2 and extract-text#3 |
1136 |
/*******************************************************************************
|
1137 |
******************************************************************************/
|
|
27.1.1
by luisrod
- a:delete() added |
1138 |
|
1139 |
/*******************************************************************************
|
|
1140 |
* This function is meant to replace all the look for specific headers that are
|
|
1141 |
* or are not in a list (ArchiveEntrySet)
|
|
1142 |
******************************************************************************/
|
|
1143 |
struct archive_entry* |
|
35
by Matthias Brantner
- reworked the way options are passed and named |
1144 |
ExtractFunction::ExtractItemSequence::ExtractIterator::lookForHeader( |
1145 |
bool aMatch, |
|
1146 |
ArchiveOptions* aOptions) |
|
27.1.1
by luisrod
- a:delete() added |
1147 |
{
|
30.1.1
by Matthias Brantner
- fixed a memory leak in the update and delete functions |
1148 |
struct archive_entry *lEntry = 0; |
27.1.1
by luisrod
- a:delete() added |
1149 |
|
1150 |
while (true) |
|
1151 |
{
|
|
1152 |
int lErr = archive_read_next_header(theArchive, &lEntry); |
|
1153 |
||
1154 |
if (lErr == ARCHIVE_EOF) return NULL; |
|
1155 |
||
1156 |
if (lErr != ARCHIVE_OK) |
|
1157 |
{
|
|
1158 |
ArchiveFunction::checkForError(lErr, 0, theArchive); |
|
1159 |
}
|
|
1160 |
||
30.1.3
by Juan Zacarias
Added General Options to Delete and Update Function |
1161 |
if(aOptions) |
1162 |
aOptions->setValues(theArchive); |
|
1163 |
||
27.1.1
by luisrod
- a:delete() added |
1164 |
if (theReturnAll) break; |
1165 |
||
1166 |
String lName = archive_entry_pathname(lEntry); |
|
1167 |
if(aMatch) { |
|
30
by Juan Zacarias
Added Delete Function |
1168 |
if (theEntryNames.find(lName.str()) != theEntryNames.end()) |
27.1.1
by luisrod
- a:delete() added |
1169 |
{
|
1170 |
break; |
|
1171 |
}
|
|
1172 |
} else { |
|
30
by Juan Zacarias
Added Delete Function |
1173 |
if (theEntryNames.find(lName.str()) == theEntryNames.end()) |
27.1.1
by luisrod
- a:delete() added |
1174 |
{
|
1175 |
break; |
|
1176 |
}
|
|
1177 |
}
|
|
1178 |
}
|
|
1179 |
||
1180 |
return lEntry; |
|
1181 |
}
|
|
1182 |
||
11
by Matthias Brantner
- extract-text#1 function (without transcoding) |
1183 |
zorba::ItemSequence_t |
1184 |
ExtractTextFunction::evaluate( |
|
1185 |
const Arguments_t& aArgs, |
|
1186 |
const zorba::StaticContext* aSctx, |
|
1187 |
const zorba::DynamicContext* aDctx) const |
|
1188 |
{
|
|
1189 |
Item lArchive = getOneItem(aArgs, 0); |
|
12
by Matthias Brantner
extract-text#2 and extract-text#3 |
1190 |
|
1191 |
zorba::String lEncoding("UTF-8"); |
|
1192 |
if (aArgs.size() == 3) |
|
1193 |
{
|
|
1194 |
zorba::Item lItem = getOneItem(aArgs, 2); |
|
1195 |
lEncoding = lItem.getStringValue(); |
|
1196 |
if (!transcode::is_supported(lEncoding.c_str())) |
|
1197 |
{
|
|
1198 |
std::ostringstream lMsg; |
|
1199 |
lMsg << lEncoding << ": unsupported encoding"; |
|
1200 |
||
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
1201 |
throwError(ERROR_INVALID_ENCODING, lMsg.str().c_str()); |
12
by Matthias Brantner
extract-text#2 and extract-text#3 |
1202 |
}
|
1203 |
}
|
|
11
by Matthias Brantner
- extract-text#1 function (without transcoding) |
1204 |
|
12
by Matthias Brantner
extract-text#2 and extract-text#3 |
1205 |
// return all entries if no second arg is given
|
1206 |
bool lReturnAll = aArgs.size() == 1; |
|
1207 |
||
1208 |
std::auto_ptr<ExtractItemSequence> lSeq( |
|
14.1.1
by Matthias Brantner
extract-binary |
1209 |
new ExtractTextItemSequence(lArchive, lReturnAll, lEncoding)); |
12
by Matthias Brantner
extract-text#2 and extract-text#3 |
1210 |
|
1211 |
// get the names of all entries that should be retruned
|
|
1212 |
if (aArgs.size() > 1) |
|
1213 |
{
|
|
14.1.1
by Matthias Brantner
extract-binary |
1214 |
ExtractFunction::ExtractItemSequence::EntryNameSet& lSet |
1215 |
= lSeq->getNameSet(); |
|
12
by Matthias Brantner
extract-text#2 and extract-text#3 |
1216 |
|
1217 |
zorba::Item lItem; |
|
1218 |
Iterator_t lIter = aArgs[1]->getIterator(); |
|
1219 |
lIter->open(); |
|
1220 |
while (lIter->next(lItem)) |
|
1221 |
{
|
|
30
by Juan Zacarias
Added Delete Function |
1222 |
lSet.insert(lItem.getStringValue().str()); |
12
by Matthias Brantner
extract-text#2 and extract-text#3 |
1223 |
}
|
1224 |
||
1225 |
lIter->close(); |
|
1226 |
}
|
|
1227 |
||
1228 |
return ItemSequence_t(lSeq.release()); |
|
11
by Matthias Brantner
- extract-text#1 function (without transcoding) |
1229 |
}
|
1230 |
||
8
by Matthias Brantner
streaming archive:entries |
1231 |
bool
|
14.1.1
by Matthias Brantner
extract-binary |
1232 |
ExtractTextFunction::ExtractTextItemSequence::ExtractTextIterator::next( |
12
by Matthias Brantner
extract-text#2 and extract-text#3 |
1233 |
zorba::Item& aRes) |
11
by Matthias Brantner
- extract-text#1 function (without transcoding) |
1234 |
{
|
27.1.1
by luisrod
- a:delete() added |
1235 |
struct archive_entry *lEntry = lookForHeader(true); |
11
by Matthias Brantner
- extract-text#1 function (without transcoding) |
1236 |
|
30
by Juan Zacarias
Added Delete Function |
1237 |
//NULL is EOF
|
1238 |
if (!lEntry) |
|
1239 |
return false; |
|
1240 |
||
11
by Matthias Brantner
- extract-text#1 function (without transcoding) |
1241 |
String lResult; |
1242 |
||
1243 |
// reserve some space if we know the decompressed size
|
|
1244 |
if (archive_entry_size_is_set(lEntry)) |
|
1245 |
{
|
|
1246 |
long long lSize = archive_entry_size(lEntry); |
|
1247 |
lResult.reserve(lSize); |
|
1248 |
}
|
|
1249 |
||
1250 |
char lBuf[ZORBA_ARCHIVE_MAX_READ_BUF]; |
|
1251 |
||
1252 |
// read entire entry into a string
|
|
1253 |
while (true) |
|
1254 |
{
|
|
14
by Matthias Brantner
make sure that multiple xquery functions accessing the same zip file works |
1255 |
int s = archive_read_data( |
11
by Matthias Brantner
- extract-text#1 function (without transcoding) |
1256 |
theArchive, &lBuf, ZORBA_ARCHIVE_MAX_READ_BUF); |
1257 |
||
1258 |
if (s == 0) break; |
|
1259 |
||
1260 |
lResult.append(lBuf, s); |
|
1261 |
}
|
|
1262 |
||
12
by Matthias Brantner
extract-text#2 and extract-text#3 |
1263 |
if (transcode::is_necessary(theEncoding.c_str())) |
1264 |
{
|
|
1265 |
zorba::String lTranscodedString; |
|
1266 |
transcode::stream<std::istringstream> lTranscoder( |
|
1267 |
theEncoding.c_str(), |
|
1268 |
lResult.c_str() |
|
1269 |
);
|
|
1270 |
char buf[1024]; |
|
1271 |
while (lTranscoder.good()) |
|
1272 |
{
|
|
1273 |
lTranscoder.read(buf, 1024); |
|
1274 |
lTranscodedString.append(buf, lTranscoder.gcount()); |
|
1275 |
}
|
|
1276 |
aRes = theFactory->createString(lTranscodedString); |
|
1277 |
}
|
|
1278 |
else
|
|
1279 |
{
|
|
1280 |
aRes = theFactory->createString(lResult); |
|
1281 |
}
|
|
11
by Matthias Brantner
- extract-text#1 function (without transcoding) |
1282 |
|
1283 |
return true; |
|
7
by Matthias Brantner
fixed two build problems: |
1284 |
}
|
1285 |
||
14.1.1
by Matthias Brantner
extract-binary |
1286 |
/*******************************************************************************
|
1287 |
******************************************************************************/
|
|
5
by Juan Zacarias
Changed name to archive module |
1288 |
zorba::ItemSequence_t |
1289 |
ExtractBinaryFunction::evaluate( |
|
1290 |
const Arguments_t& aArgs, |
|
1291 |
const zorba::StaticContext* aSctx, |
|
1292 |
const zorba::DynamicContext* aDctx) const |
|
1293 |
{
|
|
14.1.1
by Matthias Brantner
extract-binary |
1294 |
Item lArchive = getOneItem(aArgs, 0); |
1295 |
||
1296 |
// return all entries if no second arg is given
|
|
1297 |
bool lReturnAll = aArgs.size() == 1; |
|
1298 |
||
1299 |
std::auto_ptr<ExtractItemSequence> lSeq( |
|
1300 |
new ExtractBinaryItemSequence(lArchive, lReturnAll)); |
|
1301 |
||
1302 |
// get the names of all entries that should be retruned
|
|
1303 |
if (aArgs.size() > 1) |
|
1304 |
{
|
|
1305 |
ExtractFunction::ExtractItemSequence::EntryNameSet& lSet |
|
1306 |
= lSeq->getNameSet(); |
|
1307 |
||
1308 |
zorba::Item lItem; |
|
1309 |
Iterator_t lIter = aArgs[1]->getIterator(); |
|
1310 |
lIter->open(); |
|
1311 |
while (lIter->next(lItem)) |
|
1312 |
{
|
|
30
by Juan Zacarias
Added Delete Function |
1313 |
lSet.insert(lItem.getStringValue().str()); |
14.1.1
by Matthias Brantner
extract-binary |
1314 |
}
|
1315 |
||
1316 |
lIter->close(); |
|
1317 |
}
|
|
1318 |
||
1319 |
return ItemSequence_t(lSeq.release()); |
|
1320 |
}
|
|
1321 |
||
1322 |
bool
|
|
1323 |
ExtractBinaryFunction::ExtractBinaryItemSequence::ExtractBinaryIterator::next( |
|
1324 |
zorba::Item& aRes) |
|
1325 |
{
|
|
27.1.1
by luisrod
- a:delete() added |
1326 |
struct archive_entry *lEntry = lookForHeader(true); |
14.1.1
by Matthias Brantner
extract-binary |
1327 |
|
30
by Juan Zacarias
Added Delete Function |
1328 |
//NULL is EOF
|
1329 |
if (!lEntry) |
|
1330 |
return false; |
|
1331 |
||
14.1.1
by Matthias Brantner
extract-binary |
1332 |
std::vector<unsigned char> lResult; |
1333 |
||
1334 |
// reserve some space if we know the decompressed size
|
|
1335 |
if (archive_entry_size_is_set(lEntry)) |
|
1336 |
{
|
|
1337 |
long long lSize = archive_entry_size(lEntry); |
|
1338 |
lResult.reserve(lSize); |
|
1339 |
}
|
|
1340 |
||
1341 |
std::vector<unsigned char> lBuf; |
|
1342 |
lBuf.resize(ZORBA_ARCHIVE_MAX_READ_BUF); |
|
1343 |
||
1344 |
// read entire entry into a string
|
|
1345 |
while (true) |
|
1346 |
{
|
|
1347 |
int s = archive_read_data( |
|
1348 |
theArchive, &lBuf[0], ZORBA_ARCHIVE_MAX_READ_BUF); |
|
1349 |
||
1350 |
if (s == 0) break; |
|
1351 |
||
1352 |
lResult.insert(lResult.end(), lBuf.begin(), lBuf.begin() + s); |
|
1353 |
}
|
|
1354 |
||
49.1.1
by Paul J. Lucas
Fixes. |
1355 |
aRes = theFactory->createBase64Binary(reinterpret_cast<char const*>(&lResult[0]), lResult.size(), false); |
14.1.1
by Matthias Brantner
extract-binary |
1356 |
|
1357 |
return true; |
|
7
by Matthias Brantner
fixed two build problems: |
1358 |
}
|
1359 |
||
14.1.2
by Matthias Brantner
added the archive:options function to return algorithm and format options of an archive |
1360 |
|
1361 |
/*******************************************************************************
|
|
1362 |
******************************************************************************/
|
|
1363 |
zorba::ItemSequence_t |
|
1364 |
OptionsFunction::evaluate( |
|
1365 |
const Arguments_t& aArgs, |
|
1366 |
const zorba::StaticContext* aSctx, |
|
1367 |
const zorba::DynamicContext* aDctx) const |
|
1368 |
{
|
|
1369 |
Item lArchive = getOneItem(aArgs, 0); |
|
1370 |
||
1371 |
return ItemSequence_t(new OptionsItemSequence(lArchive)); |
|
1372 |
}
|
|
1373 |
||
53
by Luis Rodriguez Gonzalez
All comments fixed |
1374 |
OptionsFunction::OptionsItemSequence::OptionsIterator::OptionsIterator(Item &aArchive) |
1375 |
:ArchiveIterator(aArchive) |
|
1376 |
{
|
|
1377 |
gFormatKey = theFactory->createString(FORMAT_KEY_NAME); |
|
1378 |
gCompressionKey = theFactory->createString(COMPRESSION_KEY_NAME); |
|
1379 |
}
|
|
1380 |
||
14.1.2
by Matthias Brantner
added the archive:options function to return algorithm and format options of an archive |
1381 |
bool
|
1382 |
OptionsFunction::OptionsItemSequence::OptionsIterator::next( |
|
1383 |
zorba::Item& aRes) |
|
1384 |
{
|
|
1385 |
if (lExhausted) return false; |
|
1386 |
||
1387 |
lExhausted = true; |
|
1388 |
||
1389 |
struct archive_entry *lEntry; |
|
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
1390 |
typedef std::pair<zorba::Item, zorba::Item> tArrElemt; |
1391 |
tArrElemt lElemt; |
|
1392 |
std::vector<tArrElemt> lJSONObject; |
|
14.1.2
by Matthias Brantner
added the archive:options function to return algorithm and format options of an archive |
1393 |
|
1394 |
// to get the format, we need to peek into the first header
|
|
1395 |
int lErr = archive_read_next_header(theArchive, &lEntry); |
|
1396 |
||
1397 |
if (lErr != ARCHIVE_OK && lErr != ARCHIVE_EOF) |
|
1398 |
{
|
|
1399 |
ArchiveFunction::checkForError(lErr, 0, theArchive); |
|
1400 |
}
|
|
1401 |
||
1402 |
std::string lFormat = |
|
1403 |
ArchiveFunction::formatName(archive_format(theArchive)); |
|
35
by Matthias Brantner
- reworked the way options are passed and named |
1404 |
std::string lCompression = |
14.1.2
by Matthias Brantner
added the archive:options function to return algorithm and format options of an archive |
1405 |
ArchiveFunction::compressionName(archive_compression(theArchive)); |
1406 |
||
1407 |
if (lFormat == "ZIP") |
|
1408 |
{
|
|
35
by Matthias Brantner
- reworked the way options are passed and named |
1409 |
lCompression = "DEFLATE"; |
14.1.2
by Matthias Brantner
added the archive:options function to return algorithm and format options of an archive |
1410 |
}
|
1411 |
||
53
by Luis Rodriguez Gonzalez
All comments fixed |
1412 |
lElemt = std::make_pair<zorba::Item, zorba::Item>(gFormatKey, |
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
1413 |
theFactory->createString(lFormat)); |
1414 |
lJSONObject.push_back(lElemt); |
|
1415 |
||
53
by Luis Rodriguez Gonzalez
All comments fixed |
1416 |
lElemt = std::make_pair<zorba::Item, zorba::Item>(gCompressionKey, |
51
by Luis Rodriguez Gonzalez
Changes to make this module JSONiq friendly done. |
1417 |
theFactory->createString(lCompression)); |
1418 |
lJSONObject.push_back(lElemt); |
|
1419 |
||
1420 |
aRes = theFactory->createJSONObject(lJSONObject); |
|
14.1.2
by Matthias Brantner
added the archive:options function to return algorithm and format options of an archive |
1421 |
|
1422 |
return true; |
|
1423 |
}
|
|
1424 |
||
5
by Juan Zacarias
Changed name to archive module |
1425 |
/*******************************************************************************************
|
1426 |
*******************************************************************************************/
|
|
28
by Juan Zacarias
Implemented the add in the archive update function |
1427 |
bool
|
1428 |
UpdateFunction::UpdateItemSequence::UpdateIterator::next( |
|
1429 |
zorba::Item& aRes) |
|
1430 |
{
|
|
30.1.3
by Juan Zacarias
Added General Options to Delete and Update Function |
1431 |
struct archive_entry *lEntry = lookForHeader(false, &theOptions); |
30
by Juan Zacarias
Added Delete Function |
1432 |
|
1433 |
//NULL is EOF
|
|
1434 |
if (!lEntry) |
|
1435 |
return false; |
|
30.1.3
by Juan Zacarias
Added General Options to Delete and Update Function |
1436 |
|
28
by Juan Zacarias
Implemented the add in the archive update function |
1437 |
//form an ArchiveEntry with the entry
|
30.1.1
by Matthias Brantner
- fixed a memory leak in the update and delete functions |
1438 |
theEntry.setValues(lEntry); |
42.1.6
by luisrod
- Added ability to create directories |
1439 |
|
1440 |
if(archive_entry_filetype(lEntry) == AE_IFREG){ |
|
1441 |
//read entry content
|
|
1442 |
std::vector<unsigned char> lResult; |
|
1443 |
||
1444 |
if (archive_entry_size_is_set(lEntry)) |
|
1445 |
{
|
|
1446 |
long long lSize = archive_entry_size(lEntry); |
|
1447 |
lResult.reserve(lSize); |
|
1448 |
}
|
|
1449 |
||
1450 |
std::vector<unsigned char> lBuf; |
|
1451 |
lBuf.resize(ZORBA_ARCHIVE_MAX_READ_BUF); |
|
1452 |
||
1453 |
//read entry into string
|
|
1454 |
while (true) |
|
1455 |
{
|
|
1456 |
int s = archive_read_data( |
|
1457 |
theArchive, &lBuf[0], ZORBA_ARCHIVE_MAX_READ_BUF); |
|
28
by Juan Zacarias
Implemented the add in the archive update function |
1458 |
|
42.1.6
by luisrod
- Added ability to create directories |
1459 |
if (s == 0) break; |
1460 |
||
1461 |
lResult.insert(lResult.end(), lBuf.begin(), lBuf.begin() + s); |
|
1462 |
}
|
|
1463 |
||
49.1.1
by Paul J. Lucas
Fixes. |
1464 |
aRes = theFactory->createBase64Binary(reinterpret_cast<char const*>(&lResult[0]), lResult.size(), false); |
28
by Juan Zacarias
Implemented the add in the archive update function |
1465 |
}
|
1466 |
||
1467 |
return true; |
|
1468 |
}
|
|
1469 |
||
5
by Juan Zacarias
Changed name to archive module |
1470 |
zorba::ItemSequence_t |
1471 |
UpdateFunction::evaluate( |
|
1472 |
const Arguments_t& aArgs, |
|
1473 |
const zorba::StaticContext* aSctx, |
|
1474 |
const zorba::DynamicContext* aDctx) const |
|
1475 |
{
|
|
36.1.1
by Juan Zacarias
Updated Delete and Update function's in line documentation |
1476 |
//Base64 Binary of the Archive
|
28
by Juan Zacarias
Implemented the add in the archive update function |
1477 |
Item lArchive = getOneItem(aArgs, 0); |
1478 |
||
36.1.1
by Juan Zacarias
Updated Delete and Update function's in line documentation |
1479 |
//Initialize an Update Iterator with the Archive recived from the function
|
30
by Juan Zacarias
Added Delete Function |
1480 |
std::auto_ptr<UpdateItemSequence> lSeq( |
1481 |
new UpdateItemSequence(lArchive, false)); |
|
1482 |
||
28
by Juan Zacarias
Implemented the add in the archive update function |
1483 |
std::vector<ArchiveEntry> lEntries; |
1484 |
||
36.1.1
by Juan Zacarias
Updated Delete and Update function's in line documentation |
1485 |
//prepare list of entries to be updated into the Archive
|
28
by Juan Zacarias
Implemented the add in the archive update function |
1486 |
{
|
1487 |
Iterator_t lEntriesIter = aArgs[1]->getIterator(); |
|
1488 |
||
1489 |
zorba::Item lEntry; |
|
1490 |
lEntriesIter->open(); |
|
30
by Juan Zacarias
Added Delete Function |
1491 |
ExtractFunction::ExtractItemSequence::EntryNameSet& lNameSet |
1492 |
= lSeq->getNameSet(); |
|
28
by Juan Zacarias
Implemented the add in the archive update function |
1493 |
while (lEntriesIter->next(lEntry)) |
1494 |
{
|
|
1495 |
lEntries.resize(lEntries.size() + 1); |
|
1496 |
lEntries.back().setValues(lEntry); |
|
30
by Juan Zacarias
Added Delete Function |
1497 |
lNameSet.insert(lEntries.back().getEntryPath().str()); |
28
by Juan Zacarias
Implemented the add in the archive update function |
1498 |
}
|
1499 |
lEntriesIter->close(); |
|
30
by Juan Zacarias
Added Delete Function |
1500 |
}
|
28
by Juan Zacarias
Implemented the add in the archive update function |
1501 |
|
36.1.1
by Juan Zacarias
Updated Delete and Update function's in line documentation |
1502 |
//get the iterator of Files to include in the archive
|
28
by Juan Zacarias
Implemented the add in the archive update function |
1503 |
zorba::Iterator_t lFileIter = aArgs[2]->getIterator(); |
1504 |
||
36.1.1
by Juan Zacarias
Updated Delete and Update function's in line documentation |
1505 |
//Prepare new archive, for compressing the Files form the original
|
1506 |
//updated with the new Files specified
|
|
28
by Juan Zacarias
Implemented the add in the archive update function |
1507 |
ArchiveCompressor lResArchive; |
30
by Juan Zacarias
Added Delete Function |
1508 |
ArchiveOptions lOptions; |
28
by Juan Zacarias
Implemented the add in the archive update function |
1509 |
|
1510 |
Item lItem; |
|
1511 |
Iterator_t lSeqIter = lSeq->getIterator(); |
|
30.1.3
by Juan Zacarias
Added General Options to Delete and Update Function |
1512 |
|
36.1.1
by Juan Zacarias
Updated Delete and Update function's in line documentation |
1513 |
//read first header and file of the archive so we can get the options before creating
|
1514 |
//the new archive.
|
|
28
by Juan Zacarias
Implemented the add in the archive update function |
1515 |
lSeqIter->open(); |
45.1.1
by Luis Rodriguez Gonzalez
-Replaced open functions with old ones to make it work with Macports |
1516 |
lSeqIter->next(lItem); |
36.1.1
by Juan Zacarias
Updated Delete and Update function's in line documentation |
1517 |
//set the options of the archive
|
30.1.3
by Juan Zacarias
Added General Options to Delete and Update Function |
1518 |
lOptions = lSeq->getOptions(); |
36.1.1
by Juan Zacarias
Updated Delete and Update function's in line documentation |
1519 |
//create new archive with the options read
|
30.1.3
by Juan Zacarias
Added General Options to Delete and Update Function |
1520 |
lResArchive.open(lOptions); |
45.1.1
by Luis Rodriguez Gonzalez
-Replaced open functions with old ones to make it work with Macports |
1521 |
if (!lItem.isNull()) |
28
by Juan Zacarias
Implemented the add in the archive update function |
1522 |
{
|
30.1.3
by Juan Zacarias
Added General Options to Delete and Update Function |
1523 |
do
|
1524 |
{
|
|
36.1.1
by Juan Zacarias
Updated Delete and Update function's in line documentation |
1525 |
//add and compress the files of the old archive into the new archive.
|
30.1.3
by Juan Zacarias
Added General Options to Delete and Update Function |
1526 |
lResArchive.compress(lSeq->getEntry(), lItem); |
1527 |
} while (lSeqIter->next(lItem)); |
|
28
by Juan Zacarias
Implemented the add in the archive update function |
1528 |
}
|
1529 |
lSeqIter->close(); |
|
1530 |
||
36.1.1
by Juan Zacarias
Updated Delete and Update function's in line documentation |
1531 |
//add and compress the new file sspecified as a parameter for the function.
|
28
by Juan Zacarias
Implemented the add in the archive update function |
1532 |
lResArchive.compress(lEntries, lFileIter); |
1533 |
lResArchive.close(); |
|
1534 |
||
1535 |
Item lRes = theModule->getItemFactory()-> |
|
1536 |
createStreamableBase64Binary( |
|
1537 |
*lResArchive.getResultStream(), |
|
1538 |
&(ArchiveFunction::ArchiveCompressor::releaseStream), |
|
1539 |
true, // seekable |
|
1540 |
false // no encoded |
|
1541 |
);
|
|
1542 |
return ItemSequence_t(new SingletonItemSequence(lRes)); |
|
7
by Matthias Brantner
fixed two build problems: |
1543 |
}
|
1544 |
||
5
by Juan Zacarias
Changed name to archive module |
1545 |
/*******************************************************************************************
|
7
by Matthias Brantner
fixed two build problems: |
1546 |
*******************************************************************************************/
|
5
by Juan Zacarias
Changed name to archive module |
1547 |
zorba::ItemSequence_t |
1548 |
DeleteFunction::evaluate( |
|
1549 |
const Arguments_t& aArgs, |
|
1550 |
const zorba::StaticContext* aSctx, |
|
1551 |
const zorba::DynamicContext* aDctx) const |
|
1552 |
{
|
|
36.1.1
by Juan Zacarias
Updated Delete and Update function's in line documentation |
1553 |
//Base64 Binary of the Archive
|
27.1.1
by luisrod
- a:delete() added |
1554 |
Item lArchive = getOneItem(aArgs, 0); |
1555 |
||
30
by Juan Zacarias
Added Delete Function |
1556 |
std::auto_ptr<DeleteItemSequence> lSeq( |
1557 |
new DeleteItemSequence(lArchive)); |
|
27.1.1
by luisrod
- a:delete() added |
1558 |
|
36.1.1
by Juan Zacarias
Updated Delete and Update function's in line documentation |
1559 |
//set list of files to delete from the archive.
|
27.1.1
by luisrod
- a:delete() added |
1560 |
zorba::Item lItem; |
1561 |
Iterator_t lIter = aArgs[1]->getIterator(); |
|
1562 |
lIter->open(); |
|
30
by Juan Zacarias
Added Delete Function |
1563 |
ExtractFunction::ExtractItemSequence::EntryNameSet& lNameSet = |
1564 |
lSeq->getNameSet(); |
|
1565 |
while (lIter->next(lItem)) |
|
1566 |
{
|
|
1567 |
lNameSet.insert(lItem.getStringValue().str()); |
|
1568 |
}
|
|
1569 |
lIter->close(); |
|
1570 |
||
36.1.1
by Juan Zacarias
Updated Delete and Update function's in line documentation |
1571 |
//prepare new archive
|
30
by Juan Zacarias
Added Delete Function |
1572 |
ArchiveCompressor lResArchive; |
27.1.1
by luisrod
- a:delete() added |
1573 |
ArchiveOptions lOptions; |
30
by Juan Zacarias
Added Delete Function |
1574 |
|
30.1.3
by Juan Zacarias
Added General Options to Delete and Update Function |
1575 |
Item lContent; |
30
by Juan Zacarias
Added Delete Function |
1576 |
Iterator_t lSeqIter = lSeq->getIterator(); |
36.1.1
by Juan Zacarias
Updated Delete and Update function's in line documentation |
1577 |
|
1578 |
//read first header and file of the archive so we can get the options before creating
|
|
1579 |
//the new archive.
|
|
30
by Juan Zacarias
Added Delete Function |
1580 |
lSeqIter->open(); |
30.1.3
by Juan Zacarias
Added General Options to Delete and Update Function |
1581 |
lSeqIter->next(lContent); |
36.1.1
by Juan Zacarias
Updated Delete and Update function's in line documentation |
1582 |
//set the options of the archive
|
30.1.3
by Juan Zacarias
Added General Options to Delete and Update Function |
1583 |
lOptions = lSeq->getOptions(); |
36.1.1
by Juan Zacarias
Updated Delete and Update function's in line documentation |
1584 |
//create new archive with the options read
|
30.1.3
by Juan Zacarias
Added General Options to Delete and Update Function |
1585 |
lResArchive.open(lOptions); |
1586 |
if (!lContent.isNull()) |
|
30
by Juan Zacarias
Added Delete Function |
1587 |
{
|
30.1.3
by Juan Zacarias
Added General Options to Delete and Update Function |
1588 |
do
|
1589 |
{
|
|
36.1.1
by Juan Zacarias
Updated Delete and Update function's in line documentation |
1590 |
//add and compress the files of the old archive into the new archive.
|
30.1.3
by Juan Zacarias
Added General Options to Delete and Update Function |
1591 |
lResArchive.compress(lSeq->getEntry(), lContent); |
1592 |
} while (lSeqIter->next(lContent)); |
|
30
by Juan Zacarias
Added Delete Function |
1593 |
}
|
1594 |
lSeqIter->close(); |
|
30.1.3
by Juan Zacarias
Added General Options to Delete and Update Function |
1595 |
|
30
by Juan Zacarias
Added Delete Function |
1596 |
lResArchive.close(); |
27.1.1
by luisrod
- a:delete() added |
1597 |
|
1598 |
zorba::Item lRes = theModule->getItemFactory()-> |
|
1599 |
createStreamableBase64Binary( |
|
30
by Juan Zacarias
Added Delete Function |
1600 |
*lResArchive.getResultStream(), |
27.1.1
by luisrod
- a:delete() added |
1601 |
&(ArchiveFunction::ArchiveCompressor::releaseStream), |
1602 |
true, // seekable |
|
1603 |
false // not encoded |
|
1604 |
);
|
|
1605 |
return ItemSequence_t(new SingletonItemSequence(lRes)); |
|
1606 |
}
|
|
1607 |
||
1608 |
bool
|
|
1609 |
DeleteFunction::DeleteItemSequence::DeleteIterator::next( |
|
1610 |
zorba::Item& aRes) |
|
1611 |
{
|
|
30.1.3
by Juan Zacarias
Added General Options to Delete and Update Function |
1612 |
struct archive_entry *lEntry = lookForHeader(false, &theOptions); |
30
by Juan Zacarias
Added Delete Function |
1613 |
|
1614 |
//NULL is EOF
|
|
1615 |
if (!lEntry) |
|
1616 |
return false; |
|
1617 |
||
1618 |
//form an ArchiveEntry with the entry
|
|
30.1.1
by Matthias Brantner
- fixed a memory leak in the update and delete functions |
1619 |
theEntry.setValues(lEntry); |
42.1.6
by luisrod
- Added ability to create directories |
1620 |
|
1621 |
if(archive_entry_filetype(lEntry) == AE_IFREG){ |
|
30
by Juan Zacarias
Added Delete Function |
1622 |
|
42.1.6
by luisrod
- Added ability to create directories |
1623 |
//read entry content
|
1624 |
std::vector<unsigned char> lResult; |
|
1625 |
||
1626 |
if (archive_entry_size_is_set(lEntry)) |
|
1627 |
{
|
|
1628 |
long long lSize = archive_entry_size(lEntry); |
|
1629 |
lResult.reserve(lSize); |
|
1630 |
}
|
|
1631 |
||
1632 |
std::vector<unsigned char> lBuf; |
|
1633 |
lBuf.resize(ZORBA_ARCHIVE_MAX_READ_BUF); |
|
1634 |
||
1635 |
//read entry into string
|
|
1636 |
while (true) |
|
1637 |
{
|
|
1638 |
int s = archive_read_data( |
|
1639 |
theArchive, &lBuf[0], ZORBA_ARCHIVE_MAX_READ_BUF); |
|
30
by Juan Zacarias
Added Delete Function |
1640 |
|
42.1.6
by luisrod
- Added ability to create directories |
1641 |
if (s == 0) break; |
1642 |
||
1643 |
lResult.insert(lResult.end(), lBuf.begin(), lBuf.begin() + s); |
|
1644 |
}
|
|
1645 |
||
49.1.1
by Paul J. Lucas
Fixes. |
1646 |
aRes = theFactory->createBase64Binary(reinterpret_cast<char const*>(&lResult[0]), lResult.size(), false); |
27.1.1
by luisrod
- a:delete() added |
1647 |
}
|
42.1.6
by luisrod
- Added ability to create directories |
1648 |
// else? if the entry represents a directory what are we
|
1649 |
// going to return??
|
|
53
by Luis Rodriguez Gonzalez
All comments fixed |
1650 |
// answer: nothing, the directory will have no contents at all
|
27.1.1
by luisrod
- a:delete() added |
1651 |
|
1652 |
return true; |
|
1653 |
}
|
|
1654 |
||
7
by Matthias Brantner
fixed two build problems: |
1655 |
} /* namespace zorba */ } /* namespace archive*/ |
5
by Juan Zacarias
Changed name to archive module |
1656 |
|
17
by Matthias Brantner
first very basic version of create#2 and #3 |
1657 |
std::ostream& std::operator<<( |
1658 |
std::ostream& out, |
|
1659 |
const zorba::archive::ArchiveFunction::ArchiveEntry& e) |
|
1660 |
{
|
|
1661 |
out << "name " << e.getEntryPath() << "; encoding " << e.getEncoding() |
|
1662 |
<< "; last-modified " << e.getLastModified(); |
|
1663 |
return out; |
|
1664 |
}
|
|
1665 |
||
1666 |
||
5
by Juan Zacarias
Changed name to archive module |
1667 |
#ifdef WIN32
|
1668 |
# define DLL_EXPORT __declspec(dllexport)
|
|
1669 |
#else
|
|
1670 |
# define DLL_EXPORT __attribute__ ((visibility("default")))
|
|
1671 |
#endif
|
|
1672 |
||
1673 |
extern "C" DLL_EXPORT zorba::ExternalModule* createModule() { |
|
1674 |
return new zorba::archive::ArchiveModule(); |
|
7
by Matthias Brantner
fixed two build problems: |
1675 |
}
|