LibreOffice Module xmerge (master) 1
OfficeZip.java
Go to the documentation of this file.
1/*
2 * This file is part of the LibreOffice project.
3 *
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
7 *
8 * This file incorporates work covered by the following license notice:
9 *
10 * Licensed to the Apache Software Foundation (ASF) under one or more
11 * contributor license agreements. See the NOTICE file distributed
12 * with this work for additional information regarding copyright
13 * ownership. The ASF licenses this file to you under the Apache
14 * License, Version 2.0 (the "License"); you may not use this file
15 * except in compliance with the License. You may obtain a copy of
16 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
17 */
18
19package org.openoffice.xmerge.converter.xml;
20
21import java.util.List;
22import java.util.ListIterator;
23import java.util.LinkedList;
24import java.util.zip.ZipInputStream;
25import java.util.zip.ZipOutputStream;
26import java.util.zip.ZipEntry;
27import java.util.zip.CRC32;
28import java.io.InputStream;
29import java.io.OutputStream;
30import java.io.IOException;
31import java.io.ByteArrayOutputStream;
32
34
40class OfficeZip {
41
43 private static final String CONTENTXML = "content.xml";
44
45 private static final String STYLEXML = "styles.xml";
46 private static final String METAXML = "meta.xml";
47 private static final String SETTINGSXML = "settings.xml";
48 private static final String MANIFESTXML = "META-INF/manifest.xml";
49
50 private static final int BUFFERSIZE = 1024;
51
52 private final List<Entry> entryList;
53
54 private int contentIndex = -1;
55 private int styleIndex = -1;
56 private int metaIndex = -1;
57 private int settingsIndex = -1;
58 private int manifestIndex = -1;
59
61 OfficeZip() {
62
63 entryList = new LinkedList<Entry>();
64 }
65
81 void read(InputStream is) throws IOException {
82
83 ZipInputStream zis = new ZipInputStream(is);
84 ZipEntry ze;
85 int i = -1;
86
87 while ((ze = zis.getNextEntry()) != null) {
88
89 String name = ze.getName();
90
91 Debug.log(Debug.TRACE, "reading entry: " + name);
92
93 ByteArrayOutputStream baos = new ByteArrayOutputStream();
94
95 int len;
96 byte buffer[] = new byte[BUFFERSIZE];
97
98 while ((len = zis.read(buffer)) > 0) {
99 baos.write(buffer, 0, len);
100 }
101
102 byte bytes[] = baos.toByteArray();
103 Entry entry = new Entry(ze,bytes);
104
105 entryList.add(entry);
106
107 i++;
108
109 if (name.equalsIgnoreCase(CONTENTXML)) {
110 contentIndex = i;
111 }
112 else if (name.equalsIgnoreCase(STYLEXML)) {
113 styleIndex = i;
114 }
115 else if (name.equalsIgnoreCase(METAXML)) {
116 metaIndex = i;
117 }
118 else if (name.equalsIgnoreCase(SETTINGSXML)) {
119 settingsIndex = i;
120 }
121 else if (name.equalsIgnoreCase(MANIFESTXML)) {
122 manifestIndex = i;
123 }
124
125 }
126
127 zis.close();
128 }
129
137 byte[] getContentXMLBytes() {
138
139 return getEntryBytes(contentIndex);
140 }
141
150 byte[] getStyleXMLBytes() {
151
152 return getEntryBytes(styleIndex);
153 }
154
163 byte[] getMetaXMLBytes() {
164 return getEntryBytes(metaIndex);
165 }
166
175 byte[] getSettingsXMLBytes() {
176 return getEntryBytes(settingsIndex);
177 }
178
187 byte[] getManifestXMLBytes() {
188 return getEntryBytes(manifestIndex);
189 }
190
200 byte[] getNamedBytes(String name) {
201
202 // The list is not sorted, and sorting it for a binary search would
203 // invalidate the indices stored for the main files.
204
205 // Could improve performance by caching the name and index when
206 // iterating through the ZipFile in read().
207 for (int i = 0; i < entryList.size(); i++) {
208 Entry e = entryList.get(i);
209
210 if (e.zipEntry.getName().equals(name)) {
211 return getEntryBytes(i);
212 }
213 }
214
215 return null;
216 }
217
229 void setNamedBytes(String name, byte[] bytes) {
230 for (int i = 0; i < entryList.size(); i++) {
231 Entry e = entryList.get(i);
232
233 if (e.zipEntry.getName().equals(name)) {
234 setEntryBytes(i, bytes, name);
235 return;
236 }
237 }
238
239 // If we're here, no entry was found. Call setEntryBytes with an index
240 // of -1 to insert a new entry.
241 setEntryBytes(-1, bytes, name);
242 }
243
254 private byte[] getEntryBytes(int index) {
255
256 byte[] bytes = null;
257
258 if (index > -1) {
259 Entry entry = entryList.get(index);
260 bytes = entry.bytes;
261 }
262 return bytes;
263 }
264
270 void setContentXMLBytes(byte bytes[]) {
271
272 contentIndex = setEntryBytes(contentIndex, bytes, CONTENTXML);
273 }
274
280 void setStyleXMLBytes(byte bytes[]) {
281
282 styleIndex = setEntryBytes(styleIndex, bytes, STYLEXML);
283 }
284
290 void setMetaXMLBytes(byte bytes[]) {
291
292 metaIndex = setEntryBytes(metaIndex, bytes, METAXML);
293 }
294
300 void setSettingsXMLBytes(byte bytes[]) {
301
302 settingsIndex = setEntryBytes(settingsIndex, bytes, SETTINGSXML);
303 }
304
310 void setManifestXMLBytes(byte bytes[]) {
311 manifestIndex = setEntryBytes(manifestIndex, bytes, MANIFESTXML);
312 }
313
328 private int setEntryBytes(int index, byte bytes[], String name) {
329
330 if (index > -1) {
331 // replace existing entry in entryList
332 Entry entry = entryList.get(index);
333 name = entry.zipEntry.getName();
334 int method = entry.zipEntry.getMethod();
335
336 ZipEntry ze = createZipEntry(name, bytes, method);
337
338 entry.zipEntry = ze;
339 entry.bytes= bytes;
340
341 } else {
342 // add a new entry into entryList
343 ZipEntry ze = createZipEntry(name, bytes, ZipEntry.DEFLATED);
344 Entry entry = new Entry(ze, bytes);
345 entryList.add(entry);
346 index = entryList.size() - 1;
347 }
348
349 return index;
350 }
351
359 void write(OutputStream os) throws IOException {
360
361 Debug.log(Debug.TRACE, "Writing out the following entries into zip.");
362
363 ZipOutputStream zos = new ZipOutputStream(os);
364
365 ListIterator<Entry> iterator = entryList.listIterator();
366 while (iterator.hasNext()) {
367
368 Entry entry = iterator.next();
369 ZipEntry ze = entry.zipEntry;
370
371 String name = ze.getName();
372
373 Debug.log(Debug.TRACE, "... " + name);
374
375 zos.putNextEntry(ze);
376 zos.write(entry.bytes);
377 }
378
379 zos.close();
380 }
381
391 private ZipEntry createZipEntry(String name, byte bytes[], int method) {
392
393 ZipEntry ze = new ZipEntry(name);
394
395 ze.setMethod(method);
396 ze.setSize(bytes.length);
397
398 CRC32 crc = new CRC32();
399 crc.reset();
400 crc.update(bytes);
401 ze.setCrc(crc.getValue());
402
403 ze.setTime(System.currentTimeMillis());
404
405 return ze;
406 }
407
414 private static class Entry {
415
416 ZipEntry zipEntry = null;
417 byte bytes[] = null;
418
419 Entry(ZipEntry zipEntry, byte bytes[]) {
420 this.zipEntry = zipEntry;
421 this.bytes = bytes;
422 }
423 }
424}
std::deque< std::string > LinkedList
This inner class is used as a data structure for holding a ZipEntry info and its corresponding bytes.
Definition: OfficeZip.java:414
This class is used for logging debug messages.
Definition: Debug.java:39
const char * name
int i
index
Provides general purpose utilities.
Provides interfaces for converting between two Document formats, and supports a "merge" interface for...
Definition: Convert.java:19
std::vector< sal_uInt8 > bytes