mirror of https://github.com/apache/poi.git
Make a start on supporting Chunks
git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@548836 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
f8792d87d7
commit
a90d688de3
|
@ -19,6 +19,7 @@ package org.apache.poi.hdgf;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.poi.hdgf.chunks.ChunkFactory;
|
||||||
import org.apache.poi.hdgf.pointers.Pointer;
|
import org.apache.poi.hdgf.pointers.Pointer;
|
||||||
import org.apache.poi.hdgf.pointers.PointerFactory;
|
import org.apache.poi.hdgf.pointers.PointerFactory;
|
||||||
import org.apache.poi.hdgf.streams.PointerContainingStream;
|
import org.apache.poi.hdgf.streams.PointerContainingStream;
|
||||||
|
@ -47,6 +48,8 @@ public class HDGFDiagram {
|
||||||
|
|
||||||
private Pointer trailerPointer;
|
private Pointer trailerPointer;
|
||||||
private TrailerStream trailer;
|
private TrailerStream trailer;
|
||||||
|
|
||||||
|
private ChunkFactory chunkFactory;
|
||||||
private PointerFactory ptrFactory;
|
private PointerFactory ptrFactory;
|
||||||
|
|
||||||
public HDGFDiagram(POIFSFileSystem fs) throws IOException {
|
public HDGFDiagram(POIFSFileSystem fs) throws IOException {
|
||||||
|
@ -71,15 +74,16 @@ public class HDGFDiagram {
|
||||||
docSize = LittleEndian.getUInt(_docstream, 0x1c);
|
docSize = LittleEndian.getUInt(_docstream, 0x1c);
|
||||||
// ??? 0x20 -> 0x23
|
// ??? 0x20 -> 0x23
|
||||||
|
|
||||||
// Create a Pointer Factory for the document version
|
// Create the Chunk+Pointer Factories for the document version
|
||||||
ptrFactory = new PointerFactory(version);
|
ptrFactory = new PointerFactory(version);
|
||||||
|
chunkFactory = new ChunkFactory(version);
|
||||||
|
|
||||||
// Grab the pointer to the trailer
|
// Grab the pointer to the trailer
|
||||||
trailerPointer = ptrFactory.createPointer(_docstream, 0x24);
|
trailerPointer = ptrFactory.createPointer(_docstream, 0x24);
|
||||||
|
|
||||||
// Now grab the trailer
|
// Now grab the trailer
|
||||||
trailer = (TrailerStream)
|
trailer = (TrailerStream)
|
||||||
Stream.createStream(trailerPointer, _docstream, ptrFactory);
|
Stream.createStream(trailerPointer, _docstream, chunkFactory, ptrFactory);
|
||||||
|
|
||||||
// Finally, find all our streams
|
// Finally, find all our streams
|
||||||
trailer.findChildren(_docstream);
|
trailer.findChildren(_docstream);
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
/* ====================================================================
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
|
this work for additional information regarding copyright ownership.
|
||||||
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
(the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
==================================================================== */
|
||||||
|
package org.apache.poi.hdgf.chunks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base of all chunks, which hold data, flags etc
|
||||||
|
*/
|
||||||
|
public class Chunk {
|
||||||
|
/**
|
||||||
|
* The contents of the chunk, excluding the header,
|
||||||
|
* trailer and separator
|
||||||
|
*/
|
||||||
|
private byte[] contents;
|
||||||
|
private ChunkHeader header;
|
||||||
|
/** May be null */
|
||||||
|
private ChunkTrailer trailer;
|
||||||
|
/** May be null */
|
||||||
|
private ChunkSeparator separator;
|
||||||
|
|
||||||
|
public Chunk(ChunkHeader header, ChunkTrailer trailer, ChunkSeparator separator, byte[] contents) {
|
||||||
|
this.header = header;
|
||||||
|
this.trailer = trailer;
|
||||||
|
this.separator = separator;
|
||||||
|
this.contents = contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the size of the chunk, including any
|
||||||
|
* headers, trailers and separators.
|
||||||
|
*/
|
||||||
|
public int getOnDiskSize() {
|
||||||
|
int size = header.getSizeInBytes() + contents.length;
|
||||||
|
if(trailer != null) {
|
||||||
|
size += trailer.trailerData.length;
|
||||||
|
}
|
||||||
|
if(separator != null) {
|
||||||
|
size += separator.separatorData.length;
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
/* ====================================================================
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
|
this work for additional information regarding copyright ownership.
|
||||||
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
(the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
==================================================================== */
|
||||||
|
package org.apache.poi.hdgf.chunks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factor class to create the appropriate chunks, which
|
||||||
|
* needs the version of the file to process the chunk header
|
||||||
|
* and trailer areas.
|
||||||
|
* Makes use of chunks_parse_cmds.tbl from vsdump to be able
|
||||||
|
* to c
|
||||||
|
*/
|
||||||
|
public class ChunkFactory {
|
||||||
|
private int version;
|
||||||
|
public ChunkFactory(int version) {
|
||||||
|
this.version = version;
|
||||||
|
}
|
||||||
|
public int getVersion() { return version; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the appropriate chunk at the given location.
|
||||||
|
* @param data
|
||||||
|
* @param offset
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Chunk createChunk(byte[] data, int offset) {
|
||||||
|
// Create the header
|
||||||
|
ChunkHeader header =
|
||||||
|
ChunkHeader.createChunkHeader(version, data, offset);
|
||||||
|
|
||||||
|
// Create the trailer and separator, if required
|
||||||
|
ChunkTrailer trailer = null;
|
||||||
|
ChunkSeparator separator = null;
|
||||||
|
if(header.hasTrailer()) {
|
||||||
|
trailer = new ChunkTrailer(
|
||||||
|
data, header.getLength() + header.getSizeInBytes());
|
||||||
|
if(header.hasSeparator()) {
|
||||||
|
separator = new ChunkSeparator(
|
||||||
|
data, header.getLength() + header.getSizeInBytes() + 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now, create the chunk
|
||||||
|
byte[] contents = new byte[header.getLength()];
|
||||||
|
System.arraycopy(data, offset+header.getSizeInBytes(), contents, 0, contents.length);
|
||||||
|
Chunk chunk = new Chunk(header, trailer, separator, contents);
|
||||||
|
|
||||||
|
// Feed in the stuff from chunks_parse_cmds.tbl
|
||||||
|
// TODO
|
||||||
|
|
||||||
|
// All done
|
||||||
|
return chunk;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,83 @@
|
||||||
|
/* ====================================================================
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
|
this work for additional information regarding copyright ownership.
|
||||||
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
(the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
==================================================================== */
|
||||||
|
package org.apache.poi.hdgf.chunks;
|
||||||
|
|
||||||
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A chunk header
|
||||||
|
*/
|
||||||
|
public abstract class ChunkHeader {
|
||||||
|
protected int type;
|
||||||
|
protected int id;
|
||||||
|
protected int length;
|
||||||
|
protected int unknown1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the appropriate ChunkHeader for the Chunk Header at
|
||||||
|
* the given location, for the given document version.
|
||||||
|
*/
|
||||||
|
public static ChunkHeader createChunkHeader(int documentVersion, byte[] data, int offset) {
|
||||||
|
if(documentVersion >= 6) {
|
||||||
|
ChunkHeaderV6 ch;
|
||||||
|
if(documentVersion > 6) {
|
||||||
|
ch = new ChunkHeaderV11();
|
||||||
|
} else {
|
||||||
|
ch = new ChunkHeaderV6();
|
||||||
|
}
|
||||||
|
ch.type = (int)LittleEndian.getUInt(data, offset + 0);
|
||||||
|
ch.id = (int)LittleEndian.getUInt(data, offset + 4);
|
||||||
|
ch.unknown1 = (int)LittleEndian.getUInt(data, offset + 8);
|
||||||
|
ch.length = (int)LittleEndian.getUInt(data, offset + 12);
|
||||||
|
ch.unknown2 = LittleEndian.getShort(data, offset + 16);
|
||||||
|
ch.unknown3 = (short)LittleEndian.getUnsignedByte(data, offset + 18);
|
||||||
|
return ch;
|
||||||
|
} else if(documentVersion == 5) {
|
||||||
|
throw new RuntimeException("TODO");
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Visio files with versions below 5 are not supported, yours was " + documentVersion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract int getSizeInBytes();
|
||||||
|
public abstract boolean hasTrailer();
|
||||||
|
public abstract boolean hasSeparator();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the ID/IX of the chunk
|
||||||
|
*/
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns the length of the trunk, excluding the length
|
||||||
|
* of the header, trailer or separator.
|
||||||
|
*/
|
||||||
|
public int getLength() {
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns the type of the chunk, which affects the
|
||||||
|
* mandatory information
|
||||||
|
*/
|
||||||
|
public int getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
public int getUnknown1() {
|
||||||
|
return unknown1;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
/* ====================================================================
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
|
this work for additional information regarding copyright ownership.
|
||||||
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
(the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
==================================================================== */
|
||||||
|
package org.apache.poi.hdgf.chunks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A chunk header from v11+
|
||||||
|
*/
|
||||||
|
public class ChunkHeaderV11 extends ChunkHeaderV6 {
|
||||||
|
/**
|
||||||
|
* Does the chunk have a separator?
|
||||||
|
*/
|
||||||
|
public boolean hasSeparator() {
|
||||||
|
// If there's a trailer, there's a separator
|
||||||
|
if(hasTrailer()) { return true; }
|
||||||
|
|
||||||
|
if(unknown2 == 2 && unknown3 == 0x55) { return true; }
|
||||||
|
if(unknown2 == 2 && unknown3 == 0x54 && type == 0xaa) { return true; }
|
||||||
|
if(unknown2 == 3 && unknown3 == 0x50 && type == 0xaa) { return true; }
|
||||||
|
if(type == 0x69) { return true; }
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
/* ====================================================================
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
|
this work for additional information regarding copyright ownership.
|
||||||
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
(the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
==================================================================== */
|
||||||
|
package org.apache.poi.hdgf.chunks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A chunk header from v6
|
||||||
|
*/
|
||||||
|
public class ChunkHeaderV6 extends ChunkHeader {
|
||||||
|
protected short unknown2;
|
||||||
|
protected short unknown3;
|
||||||
|
|
||||||
|
public short getUnknown2() {
|
||||||
|
return unknown2;
|
||||||
|
}
|
||||||
|
public short getUnknown3() {
|
||||||
|
return unknown3;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSizeInBytes() {
|
||||||
|
return 19;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Does the chunk have a trailer?
|
||||||
|
*/
|
||||||
|
public boolean hasTrailer() {
|
||||||
|
if(unknown1 != 0 || type == 0x71 || type == 0x70) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if(type == 0x6b || type == 0x6a || type == 0x69 || type == 0x66
|
||||||
|
|| type == 0x65 || type == 0x2c) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Does the chunk have a separator?
|
||||||
|
*/
|
||||||
|
public boolean hasSeparator() {
|
||||||
|
// V6 never has separators
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
/* ====================================================================
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
|
this work for additional information regarding copyright ownership.
|
||||||
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
(the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
==================================================================== */
|
||||||
|
package org.apache.poi.hdgf.chunks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A separator between the trailer of one chunk, and the
|
||||||
|
* header of the next one
|
||||||
|
*/
|
||||||
|
public class ChunkSeparator {
|
||||||
|
protected byte[] separatorData;
|
||||||
|
|
||||||
|
public ChunkSeparator(byte[] data, int offset) {
|
||||||
|
separatorData = new byte[4];
|
||||||
|
System.arraycopy(data, offset, separatorData, 0, 4);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
/* ====================================================================
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
|
this work for additional information regarding copyright ownership.
|
||||||
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
(the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
==================================================================== */
|
||||||
|
package org.apache.poi.hdgf.chunks;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A trailer that follows a chunk
|
||||||
|
*/
|
||||||
|
public class ChunkTrailer {
|
||||||
|
protected byte[] trailerData;
|
||||||
|
|
||||||
|
public ChunkTrailer(byte[] data, int offset) {
|
||||||
|
trailerData = new byte[8];
|
||||||
|
System.arraycopy(data, offset, trailerData, 0, 8);
|
||||||
|
}
|
||||||
|
}
|
|
@ -27,6 +27,7 @@ public class PointerFactory {
|
||||||
public PointerFactory(int version) {
|
public PointerFactory(int version) {
|
||||||
this.version = version;
|
this.version = version;
|
||||||
}
|
}
|
||||||
|
public int getVersion() { return version; }
|
||||||
|
|
||||||
public Pointer createPointer(byte[] data, int offset) {
|
public Pointer createPointer(byte[] data, int offset) {
|
||||||
Pointer p;
|
Pointer p;
|
||||||
|
|
|
@ -29,7 +29,7 @@ public class PointerV6 extends Pointer {
|
||||||
return (0x50 <= format && format < 0x60);
|
return (0x50 <= format && format < 0x60);
|
||||||
}
|
}
|
||||||
public boolean destinationHasChunks() {
|
public boolean destinationHasChunks() {
|
||||||
return (0xd0 <= format && format < 0xd0);
|
return (0xd0 <= format && format < 0xdf);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean destinationCompressed() {
|
public boolean destinationCompressed() {
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
/* ====================================================================
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
contributor license agreements. See the NOTICE file distributed with
|
||||||
|
this work for additional information regarding copyright ownership.
|
||||||
|
The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
(the "License"); you may not use this file except in compliance with
|
||||||
|
the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
==================================================================== */
|
||||||
|
package org.apache.poi.hdgf.streams;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
import org.apache.poi.hdgf.chunks.Chunk;
|
||||||
|
import org.apache.poi.hdgf.chunks.ChunkFactory;
|
||||||
|
import org.apache.poi.hdgf.pointers.Pointer;
|
||||||
|
|
||||||
|
public class ChunkStream extends Stream {
|
||||||
|
private ChunkFactory chunkFactory;
|
||||||
|
/** All the Chunks we contain */
|
||||||
|
private Chunk[] chunks;
|
||||||
|
|
||||||
|
protected ChunkStream(Pointer pointer, StreamStore store, ChunkFactory chunkFactory) {
|
||||||
|
super(pointer, store);
|
||||||
|
this.chunkFactory = chunkFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Chunk[] getChunks() { return chunks; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process the contents of the stream out into chunks
|
||||||
|
*/
|
||||||
|
public void findChunks() {
|
||||||
|
ArrayList chunksA = new ArrayList();
|
||||||
|
|
||||||
|
int pos = 0;
|
||||||
|
byte[] contents = getStore().getContents();
|
||||||
|
while(pos < contents.length) {
|
||||||
|
Chunk chunk = chunkFactory.createChunk(contents, pos);
|
||||||
|
chunksA.add(chunk);
|
||||||
|
|
||||||
|
pos += chunk.getOnDiskSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
chunks = (Chunk[])chunksA.toArray(new Chunk[chunksA.size()]);
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,6 +16,7 @@
|
||||||
==================================================================== */
|
==================================================================== */
|
||||||
package org.apache.poi.hdgf.streams;
|
package org.apache.poi.hdgf.streams;
|
||||||
|
|
||||||
|
import org.apache.poi.hdgf.chunks.ChunkFactory;
|
||||||
import org.apache.poi.hdgf.pointers.Pointer;
|
import org.apache.poi.hdgf.pointers.Pointer;
|
||||||
import org.apache.poi.hdgf.pointers.PointerFactory;
|
import org.apache.poi.hdgf.pointers.PointerFactory;
|
||||||
import org.apache.poi.util.LittleEndian;
|
import org.apache.poi.util.LittleEndian;
|
||||||
|
@ -28,11 +29,13 @@ public class PointerContainingStream extends Stream {
|
||||||
private Pointer[] childPointers;
|
private Pointer[] childPointers;
|
||||||
private Stream[] childStreams;
|
private Stream[] childStreams;
|
||||||
|
|
||||||
|
private ChunkFactory chunkFactory;
|
||||||
private PointerFactory pointerFactory;
|
private PointerFactory pointerFactory;
|
||||||
private int numPointersLocalOffset;
|
private int numPointersLocalOffset;
|
||||||
|
|
||||||
protected PointerContainingStream(Pointer pointer, StreamStore store, PointerFactory pointerFactory) {
|
protected PointerContainingStream(Pointer pointer, StreamStore store, ChunkFactory chunkFactory, PointerFactory pointerFactory) {
|
||||||
super(pointer, store);
|
super(pointer, store);
|
||||||
|
this.chunkFactory = chunkFactory;
|
||||||
this.pointerFactory = pointerFactory;
|
this.pointerFactory = pointerFactory;
|
||||||
|
|
||||||
// Find the offset to the number of child pointers we have
|
// Find the offset to the number of child pointers we have
|
||||||
|
@ -81,9 +84,15 @@ public class PointerContainingStream extends Stream {
|
||||||
childStreams = new Stream[childPointers.length];
|
childStreams = new Stream[childPointers.length];
|
||||||
for(int i=0; i<childPointers.length; i++) {
|
for(int i=0; i<childPointers.length; i++) {
|
||||||
Pointer ptr = childPointers[i];
|
Pointer ptr = childPointers[i];
|
||||||
childStreams[i] = Stream.createStream(ptr, documentData, pointerFactory);
|
childStreams[i] = Stream.createStream(ptr, documentData, chunkFactory, pointerFactory);
|
||||||
|
|
||||||
// Recurse if required
|
// Process chunk streams into their chunks
|
||||||
|
if(childStreams[i] instanceof ChunkStream) {
|
||||||
|
ChunkStream child = (ChunkStream)childStreams[i];
|
||||||
|
// child.findChunks();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recurse into pointer containing streams
|
||||||
if(childStreams[i] instanceof PointerContainingStream) {
|
if(childStreams[i] instanceof PointerContainingStream) {
|
||||||
PointerContainingStream child =
|
PointerContainingStream child =
|
||||||
(PointerContainingStream)childStreams[i];
|
(PointerContainingStream)childStreams[i];
|
||||||
|
|
|
@ -18,6 +18,7 @@ package org.apache.poi.hdgf.streams;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import org.apache.poi.hdgf.chunks.ChunkFactory;
|
||||||
import org.apache.poi.hdgf.pointers.Pointer;
|
import org.apache.poi.hdgf.pointers.Pointer;
|
||||||
import org.apache.poi.hdgf.pointers.PointerFactory;
|
import org.apache.poi.hdgf.pointers.PointerFactory;
|
||||||
|
|
||||||
|
@ -51,7 +52,7 @@ public abstract class Stream {
|
||||||
* @param pointer The Pointer to create a stream for
|
* @param pointer The Pointer to create a stream for
|
||||||
* @param documentData The raw document data
|
* @param documentData The raw document data
|
||||||
*/
|
*/
|
||||||
public static Stream createStream(Pointer pointer, byte[] documentData, PointerFactory pointerFactory) {
|
public static Stream createStream(Pointer pointer, byte[] documentData, ChunkFactory chunkFactory, PointerFactory pointerFactory) {
|
||||||
// Create the store
|
// Create the store
|
||||||
StreamStore store;
|
StreamStore store;
|
||||||
if(pointer.destinationCompressed()) {
|
if(pointer.destinationCompressed()) {
|
||||||
|
@ -71,10 +72,13 @@ public abstract class Stream {
|
||||||
|
|
||||||
// Figure out what sort of Stream to create, create and return it
|
// Figure out what sort of Stream to create, create and return it
|
||||||
if(pointer.getType() == 20) {
|
if(pointer.getType() == 20) {
|
||||||
return new TrailerStream(pointer, store, pointerFactory);
|
return new TrailerStream(pointer, store, chunkFactory, pointerFactory);
|
||||||
}
|
}
|
||||||
else if(pointer.destinationHasPointers()) {
|
else if(pointer.destinationHasPointers()) {
|
||||||
return new PointerContainingStream(pointer, store, pointerFactory);
|
return new PointerContainingStream(pointer, store, chunkFactory, pointerFactory);
|
||||||
|
}
|
||||||
|
else if(pointer.destinationHasChunks()) {
|
||||||
|
return new ChunkStream(pointer, store, chunkFactory);
|
||||||
}
|
}
|
||||||
else if(pointer.destinationHasStrings()) {
|
else if(pointer.destinationHasStrings()) {
|
||||||
return new StringsStream(pointer, store);
|
return new StringsStream(pointer, store);
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
==================================================================== */
|
==================================================================== */
|
||||||
package org.apache.poi.hdgf.streams;
|
package org.apache.poi.hdgf.streams;
|
||||||
|
|
||||||
|
import org.apache.poi.hdgf.chunks.ChunkFactory;
|
||||||
import org.apache.poi.hdgf.pointers.Pointer;
|
import org.apache.poi.hdgf.pointers.Pointer;
|
||||||
import org.apache.poi.hdgf.pointers.PointerFactory;
|
import org.apache.poi.hdgf.pointers.PointerFactory;
|
||||||
|
|
||||||
|
@ -26,7 +27,7 @@ import org.apache.poi.hdgf.pointers.PointerFactory;
|
||||||
* a special series of byte near the start of the file.
|
* a special series of byte near the start of the file.
|
||||||
*/
|
*/
|
||||||
public class TrailerStream extends PointerContainingStream {
|
public class TrailerStream extends PointerContainingStream {
|
||||||
protected TrailerStream(Pointer pointer, StreamStore store, PointerFactory pointerFactory) {
|
protected TrailerStream(Pointer pointer, StreamStore store, ChunkFactory chunkFactory, PointerFactory pointerFactory) {
|
||||||
super(pointer, store, pointerFactory);
|
super(pointer, store, chunkFactory, pointerFactory);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,7 +87,7 @@ public class TestStreamBasics extends StreamTest {
|
||||||
// Create a fake pointer
|
// Create a fake pointer
|
||||||
Pointer ptr = new TestPointer(true, 0, compressedStream.length, -1, (short)-1);
|
Pointer ptr = new TestPointer(true, 0, compressedStream.length, -1, (short)-1);
|
||||||
// Now the stream
|
// Now the stream
|
||||||
Stream stream = Stream.createStream(ptr, compressedStream, null);
|
Stream stream = Stream.createStream(ptr, compressedStream, null, null);
|
||||||
|
|
||||||
// Check
|
// Check
|
||||||
assertNotNull(stream.getPointer());
|
assertNotNull(stream.getPointer());
|
||||||
|
@ -111,7 +111,7 @@ public class TestStreamBasics extends StreamTest {
|
||||||
// Create a fake pointer
|
// Create a fake pointer
|
||||||
Pointer ptr = new TestPointer(false, 0, uncompressedStream.length, -1, (short)-1);
|
Pointer ptr = new TestPointer(false, 0, uncompressedStream.length, -1, (short)-1);
|
||||||
// Now the stream
|
// Now the stream
|
||||||
Stream stream = Stream.createStream(ptr, uncompressedStream, null);
|
Stream stream = Stream.createStream(ptr, uncompressedStream, null, null);
|
||||||
|
|
||||||
// Check
|
// Check
|
||||||
assertNotNull(stream.getPointer());
|
assertNotNull(stream.getPointer());
|
||||||
|
|
|
@ -18,6 +18,7 @@ package org.apache.poi.hdgf.streams;
|
||||||
|
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
|
||||||
|
import org.apache.poi.hdgf.chunks.ChunkFactory;
|
||||||
import org.apache.poi.hdgf.pointers.Pointer;
|
import org.apache.poi.hdgf.pointers.Pointer;
|
||||||
import org.apache.poi.hdgf.pointers.PointerFactory;
|
import org.apache.poi.hdgf.pointers.PointerFactory;
|
||||||
import org.apache.poi.poifs.filesystem.DocumentEntry;
|
import org.apache.poi.poifs.filesystem.DocumentEntry;
|
||||||
|
@ -27,12 +28,14 @@ public class TestStreamComplex extends StreamTest {
|
||||||
private byte[] contents;
|
private byte[] contents;
|
||||||
private int trailerPointerAt = 0x24;
|
private int trailerPointerAt = 0x24;
|
||||||
private int trailerDataAt = 0x8a94;
|
private int trailerDataAt = 0x8a94;
|
||||||
|
private ChunkFactory chunkFactory;
|
||||||
private PointerFactory ptrFactory;
|
private PointerFactory ptrFactory;
|
||||||
|
|
||||||
protected void setUp() throws Exception {
|
protected void setUp() throws Exception {
|
||||||
String dirname = System.getProperty("HDGF.testdata.path");
|
String dirname = System.getProperty("HDGF.testdata.path");
|
||||||
String filename = dirname + "/Test_Visio-Some_Random_Text.vsd";
|
String filename = dirname + "/Test_Visio-Some_Random_Text.vsd";
|
||||||
ptrFactory = new PointerFactory(6);
|
ptrFactory = new PointerFactory(11);
|
||||||
|
chunkFactory = new ChunkFactory(11);
|
||||||
|
|
||||||
FileInputStream fin = new FileInputStream(filename);
|
FileInputStream fin = new FileInputStream(filename);
|
||||||
POIFSFileSystem filesystem = new POIFSFileSystem(fin);
|
POIFSFileSystem filesystem = new POIFSFileSystem(fin);
|
||||||
|
@ -55,7 +58,7 @@ public class TestStreamComplex extends StreamTest {
|
||||||
assertEquals(20, trailerPtr.getType());
|
assertEquals(20, trailerPtr.getType());
|
||||||
assertEquals(trailerDataAt, trailerPtr.getOffset());
|
assertEquals(trailerDataAt, trailerPtr.getOffset());
|
||||||
|
|
||||||
Stream stream = Stream.createStream(trailerPtr, contents, ptrFactory);
|
Stream stream = Stream.createStream(trailerPtr, contents, chunkFactory, ptrFactory);
|
||||||
assertTrue(stream instanceof TrailerStream);
|
assertTrue(stream instanceof TrailerStream);
|
||||||
TrailerStream ts = (TrailerStream)stream;
|
TrailerStream ts = (TrailerStream)stream;
|
||||||
|
|
||||||
|
@ -69,10 +72,14 @@ public class TestStreamComplex extends StreamTest {
|
||||||
assertEquals(0xff, ts.getChildPointers()[3].getType());
|
assertEquals(0xff, ts.getChildPointers()[3].getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testChunks() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public void testStrings() {
|
public void testStrings() {
|
||||||
Pointer trailerPtr = ptrFactory.createPointer(contents, trailerPointerAt);
|
Pointer trailerPtr = ptrFactory.createPointer(contents, trailerPointerAt);
|
||||||
TrailerStream ts = (TrailerStream)
|
TrailerStream ts = (TrailerStream)
|
||||||
Stream.createStream(trailerPtr, contents, ptrFactory);
|
Stream.createStream(trailerPtr, contents, chunkFactory, ptrFactory);
|
||||||
|
|
||||||
// Should be the 1st one
|
// Should be the 1st one
|
||||||
Pointer stringPtr = ts.getChildPointers()[0];
|
Pointer stringPtr = ts.getChildPointers()[0];
|
||||||
|
@ -80,7 +87,7 @@ public class TestStreamComplex extends StreamTest {
|
||||||
assertFalse(stringPtr.destinationHasChunks());
|
assertFalse(stringPtr.destinationHasChunks());
|
||||||
assertFalse(stringPtr.destinationHasPointers());
|
assertFalse(stringPtr.destinationHasPointers());
|
||||||
|
|
||||||
Stream stream = Stream.createStream(stringPtr, contents, ptrFactory);
|
Stream stream = Stream.createStream(stringPtr, contents, chunkFactory, ptrFactory);
|
||||||
assertNotNull(stream);
|
assertNotNull(stream);
|
||||||
assertTrue(stream instanceof StringsStream);
|
assertTrue(stream instanceof StringsStream);
|
||||||
}
|
}
|
||||||
|
@ -94,7 +101,7 @@ public class TestStreamComplex extends StreamTest {
|
||||||
TestPointer ptr44d3 = new TestPointer(true, 0x44d3, 0x51, 0x4e, (short)0x56);
|
TestPointer ptr44d3 = new TestPointer(true, 0x44d3, 0x51, 0x4e, (short)0x56);
|
||||||
ptr44d3.hasPointers = true;
|
ptr44d3.hasPointers = true;
|
||||||
PointerContainingStream s44d3 = (PointerContainingStream)
|
PointerContainingStream s44d3 = (PointerContainingStream)
|
||||||
Stream.createStream(ptr44d3, contents, ptrFactory);
|
Stream.createStream(ptr44d3, contents, chunkFactory, ptrFactory);
|
||||||
|
|
||||||
// Type: 0d Addr: 014ff644 Offset: 4312 Len: 48 Format: 54 From: 44d3
|
// Type: 0d Addr: 014ff644 Offset: 4312 Len: 48 Format: 54 From: 44d3
|
||||||
Pointer ptr4312 = s44d3.getChildPointers()[1];
|
Pointer ptr4312 = s44d3.getChildPointers()[1];
|
||||||
|
@ -106,7 +113,7 @@ public class TestStreamComplex extends StreamTest {
|
||||||
assertFalse(ptr4312.destinationHasStrings());
|
assertFalse(ptr4312.destinationHasStrings());
|
||||||
|
|
||||||
PointerContainingStream s4312 = (PointerContainingStream)
|
PointerContainingStream s4312 = (PointerContainingStream)
|
||||||
Stream.createStream(ptr4312, contents, ptrFactory);
|
Stream.createStream(ptr4312, contents, chunkFactory, ptrFactory);
|
||||||
|
|
||||||
// Check it has 0x347f
|
// Check it has 0x347f
|
||||||
// Type: 1f Addr: 01540004 Offset: 347f Len: 8e8 Format: 46 From: 4312
|
// Type: 1f Addr: 01540004 Offset: 347f Len: 8e8 Format: 46 From: 4312
|
||||||
|
@ -132,7 +139,7 @@ public class TestStreamComplex extends StreamTest {
|
||||||
public void testTrailerContents() {
|
public void testTrailerContents() {
|
||||||
Pointer trailerPtr = ptrFactory.createPointer(contents, trailerPointerAt);
|
Pointer trailerPtr = ptrFactory.createPointer(contents, trailerPointerAt);
|
||||||
TrailerStream ts = (TrailerStream)
|
TrailerStream ts = (TrailerStream)
|
||||||
Stream.createStream(trailerPtr, contents, ptrFactory);
|
Stream.createStream(trailerPtr, contents, chunkFactory, ptrFactory);
|
||||||
|
|
||||||
assertNotNull(ts.getChildPointers());
|
assertNotNull(ts.getChildPointers());
|
||||||
assertNull(ts.getPointedToStreams());
|
assertNull(ts.getPointedToStreams());
|
||||||
|
|
Loading…
Reference in New Issue