You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@poi.apache.org by ni...@apache.org on 2007/06/21 23:24:26 UTC

svn commit: r549616 - in /jakarta/poi/trunk/src/scratchpad: src/org/apache/poi/hdgf/chunks/Chunk.java src/org/apache/poi/hdgf/chunks/ChunkFactory.java src/org/apache/poi/hdgf/dev/VSDDumper.java testcases/org/apache/poi/hdgf/chunks/TestChunks.java

Author: nick
Date: Thu Jun 21 14:24:25 2007
New Revision: 549616

URL: http://svn.apache.org/viewvc?view=rev&rev=549616
Log:
Make a start on processing the commands within the chunks, and their values. Includes some tests

Modified:
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/Chunk.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkFactory.java
    jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/dev/VSDDumper.java
    jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hdgf/chunks/TestChunks.java

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/Chunk.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/Chunk.java?view=diff&rev=549616&r1=549615&r2=549616
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/Chunk.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/Chunk.java Thu Jun 21 14:24:25 2007
@@ -16,7 +16,10 @@
 ==================================================================== */
 package org.apache.poi.hdgf.chunks;
 
+import java.util.ArrayList;
+
 import org.apache.poi.hdgf.chunks.ChunkFactory.CommandDefinition;
+import org.apache.poi.util.LittleEndian;
 
 /**
  * Base of all chunks, which hold data, flags etc
@@ -34,6 +37,12 @@
 	private ChunkSeparator separator;
 	/** The possible different commands we can hold */
 	protected CommandDefinition[] commandDefinitions;
+	/** The command+value pairs we hold */
+	private Command[] commands;
+	/** The blocks (if any) we hold */
+	//private Block[] blocks
+	/** The name of the chunk, as found from the commandDefinitions */
+	private String name;
 	
 	public Chunk(ChunkHeader header, ChunkTrailer trailer, ChunkSeparator separator, byte[] contents) {
 		this.header = header;
@@ -63,6 +72,15 @@
 	public CommandDefinition[] getCommandDefinitions() {
 		return commandDefinitions;
 	}
+	public Command[] getCommands() {
+		return commands;
+	}
+	/**
+	 * Get the name of the chunk, as found from the CommandDefinitions
+	 */
+	public String getName() {
+		return name;
+	}
 
 	/**
 	 * Returns the size of the chunk, including any
@@ -77,5 +95,157 @@
 			size += separator.separatorData.length;
 		}
 		return size;
+	}
+	
+	/**
+	 * Uses our CommandDefinitions to process the commands
+	 *  our chunk type has, and figure out the
+	 *  values for them.
+	 */
+	protected void processCommands() {
+		if(commandDefinitions == null) {
+			throw new IllegalStateException("You must supply the command definitions before calling processCommands!");
+		}
+		
+		// Loop over the definitions, building the commands
+		//  and getting their values
+		ArrayList commands = new ArrayList();
+		for(int i=0; i<commandDefinitions.length; i++) {
+			int type = commandDefinitions[i].getType();
+			int offset = commandDefinitions[i].getOffset();
+			
+			// Handle virtual commands
+			if(type == 10) {
+				name = commandDefinitions[i].getName();
+				continue;
+			} else if(type == 18) {
+				continue;
+			}
+
+			
+			// Build the appropriate command for the type
+			Command command;
+			if(type == 11 || type == 21) {
+				command = new BlockOffsetCommand(commandDefinitions[i]);
+			} else {
+				command = new Command(commandDefinitions[i]);
+			}
+			
+			// Bizarely, many of the offsets are from the start of the
+			//  header, not from the start of the chunk body
+			switch(type) {
+			case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
+			case 11: case 21:
+			case 12: case 16: case 17: case 18: case 28: case 29:
+				// Offset is from start of chunk
+				break;
+			default:
+				// Offset is from start of header!
+				if(offset >= 19) {
+					offset -= 19;
+				}
+			}
+			
+			// Check we seem to have enough data
+			if(offset >= contents.length) {
+				System.err.println("Command offset " + offset + " past end of data at " + contents.length);
+				continue;
+			}
+		
+			// Process
+			switch(type) {
+			// Types 0->7 = a flat at bit 0->7
+			case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
+				int val = contents[offset] & (1<<type);
+				command.value = new Boolean( (val > 0) );
+				break;
+			case 8:
+				command.value = new Byte( contents[offset] );
+				break;
+			case 9:
+				command.value = new Double(
+						LittleEndian.getDouble(contents, offset)
+				);
+				break;
+			case 25:
+				command.value = new Short(
+						LittleEndian.getShort(contents, offset)
+				);
+				break;
+			case 26:
+				command.value = new Integer(
+						LittleEndian.getInt(contents, offset)
+				);
+				break;
+				
+			// Types 11 and 21 hold the offset to the blocks
+			case 11: case 21:
+				if(offset < contents.length - 3) {
+					int bOffset = (int)LittleEndian.getUInt(contents, offset);
+					BlockOffsetCommand bcmd = (BlockOffsetCommand)command;
+					bcmd.setOffset(bOffset);
+				}
+				break;
+				
+			default:
+				//System.err.println("Warning - Command of type " + type + " not processed!");
+			}
+			
+			// Add to the array
+			commands.add(command);
+		}
+		
+		// Save the commands we liked the look of
+		this.commands = (Command[])commands.toArray(
+							new Command[commands.size()] );
+		
+		// Now build up the blocks, if we had a command that tells
+		//  us where a block is
+	}
+	
+	/**
+	 * A command in the visio file. In order to make things fun, 
+	 *  all the chunk actually stores is the value of the command.
+	 * You have to have your own lookup table to figure out what
+	 *  the commands are based on the chunk type.
+	 */
+	public static class Command {
+		protected Object value;
+		private CommandDefinition definition;
+		
+		private Command(CommandDefinition definition, Object value) {
+			this.definition = definition;
+			this.value = value;
+		}
+		private Command(CommandDefinition definition) {
+			this(definition, null);
+		}
+		
+		public CommandDefinition getDefinition() { return definition; }
+		public Object getValue() { return value; }
+	}
+	/**
+	 * A special kind of command that is an artificat of how we
+	 *  process CommandDefinitions, and so doesn't actually exist
+	 *  in the chunk
+	 */
+//	public static class VirtualCommand extends Command {
+//		private VirtualCommand(CommandDefinition definition) {
+//			super(definition);
+//		}
+//	}
+	/**
+	 * A special kind of command that holds the offset to
+	 *  a block
+	 */
+	public static class BlockOffsetCommand extends Command {
+		private int offset;
+		private BlockOffsetCommand(CommandDefinition definition) {
+			super(definition, null);
+		}
+		private void setOffset(int offset) {
+			this.offset = offset;
+			value = new Integer(offset);
+		}
 	}
 }

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkFactory.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkFactory.java?view=diff&rev=549616&r1=549615&r2=549616
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkFactory.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/chunks/ChunkFactory.java Thu Jun 21 14:24:25 2007
@@ -152,7 +152,11 @@
 		// Feed in the stuff from  chunks_parse_cmds.tbl
 		CommandDefinition[] defs = (CommandDefinition[])
 			chunkCommandDefinitions.get(new Integer(header.getType()));
+		if(defs == null) defs = new CommandDefinition[0];
 		chunk.commandDefinitions = defs;
+		
+		// Now get the chunk to process its commands
+		chunk.processCommands();
 		
 		// All done
 		return chunk;

Modified: jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/dev/VSDDumper.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/dev/VSDDumper.java?view=diff&rev=549616&r1=549615&r2=549616
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/dev/VSDDumper.java (original)
+++ jakarta/poi/trunk/src/scratchpad/src/org/apache/poi/hdgf/dev/VSDDumper.java Thu Jun 21 14:24:25 2007
@@ -19,7 +19,10 @@
 import java.io.FileInputStream;
 
 import org.apache.poi.hdgf.HDGFDiagram;
+import org.apache.poi.hdgf.chunks.Chunk;
+import org.apache.poi.hdgf.chunks.Chunk.Command;
 import org.apache.poi.hdgf.pointers.Pointer;
+import org.apache.poi.hdgf.streams.ChunkStream;
 import org.apache.poi.hdgf.streams.PointerContainingStream;
 import org.apache.poi.hdgf.streams.Stream;
 import org.apache.poi.poifs.filesystem.POIFSFileSystem;
@@ -54,6 +57,9 @@
 		for(int i=0; i<indent; i++) {
 			ind += "    ";
 		}
+		String ind2 = ind  + "    ";
+		String ind3 = ind2 + "    ";
+		
 		
 		Pointer ptr = stream.getPointer();
 		System.out.println(ind + "Stream at\t" + ptr.getOffset() +
@@ -84,6 +90,24 @@
 			
 			for(int i=0; i<pcs.getPointedToStreams().length; i++) {
 				dumpStream(pcs.getPointedToStreams()[i], (indent+1));
+			}
+		}
+		if(stream instanceof ChunkStream) {
+			ChunkStream cs = (ChunkStream)stream;
+			System.out.println(ind + "  Has " + cs.getChunks().length +
+					" chunks:");
+			
+			for(int i=0; i<cs.getChunks().length; i++) {
+				Chunk chunk = cs.getChunks()[i];
+				System.out.println(ind2 + "" + chunk.getName());
+				System.out.println(ind2 + "  Holds " + chunk.getCommands().length + " commands");
+				for(int j=0; j<chunk.getCommands().length; j++) {
+					Command command = chunk.getCommands()[j];
+					System.out.println(ind3 + "" + 
+							command.getDefinition().getName() +
+							" " + command.getValue()
+					);
+				}
 			}
 		}
 	}

Modified: jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hdgf/chunks/TestChunks.java
URL: http://svn.apache.org/viewvc/jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hdgf/chunks/TestChunks.java?view=diff&rev=549616&r1=549615&r2=549616
==============================================================================
--- jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hdgf/chunks/TestChunks.java (original)
+++ jakarta/poi/trunk/src/scratchpad/testcases/org/apache/poi/hdgf/chunks/TestChunks.java Thu Jun 21 14:24:25 2007
@@ -47,7 +47,7 @@
 	0, 0, 0, 1, 0, 84, 24, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
 	0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
 	-125, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 2, 0, 85, 5, 0, 0, 
-	0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0
+	0, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
 };
 public static final byte[] data_b = new byte[] { 70, 0, 0, 0,
 	-1, -1, -1, -1, 3, 0, 0, 0, 68, 0, 0, 0, 0, 0, 0, 68, 0, 0, 0, 0, 0, 
@@ -137,9 +137,10 @@
 		assertEquals(70, chunk.getHeader().getType());
 		assertEquals(0x46, chunk.getHeader().getType());
 		
-		// Should have two different chunk commands, a
+		// Should have two virtual chunk commands, a
 		//  10 (page sheet) and an 18
 		assertEquals(2, chunk.commandDefinitions.length);
+		assertEquals(0, chunk.getCommands().length);
 		
 		assertEquals(10, chunk.commandDefinitions[0].getType());
 		assertEquals(0, chunk.commandDefinitions[0].getOffset());
@@ -171,9 +172,10 @@
 		assertEquals(104, chunk.getHeader().getType());
 		assertEquals(0x68, chunk.getHeader().getType());
 		
-		// Should have two different chunk commands, a
+		// Should have two virtual chunk commands, a
 		//  10 (Unknown) and an 18
 		assertEquals(2, chunk.commandDefinitions.length);
+		assertEquals(0, chunk.getCommands().length);
 		
 		assertEquals(10, chunk.commandDefinitions[0].getType());
 		assertEquals(0, chunk.commandDefinitions[0].getOffset());



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@poi.apache.org
For additional commands, e-mail: dev-help@poi.apache.org