bug 22195 ClassID support, by Michael Zalewski, sync from branch, pls verify

git-svn-id: https://svn.apache.org/repos/asf/jakarta/poi/trunk@353429 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Avik Sengupta 2003-10-31 16:39:05 +00:00
parent e16e9b24e1
commit f52aea647a
5 changed files with 234 additions and 4 deletions

View File

@ -55,6 +55,10 @@
*/
package org.apache.poi.hpsf;
import java.io.*;
import org.apache.poi.util.HexDump;
import org.apache.poi.util.LittleEndian;
/**
* <p>Represents a class ID (16 bytes). Unlike other little-endian
* type the {@link ClassID} is not just 16 bytes stored in the wrong
@ -229,7 +233,25 @@ public class ClassID
return true;
}
/**
* Returns a human readable representation of the Class ID
* in standard format <code>"{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}"</code>
* @return String representation of the Class ID represented
* by this object.
*/
public String toString()
{
StringBuffer sbClassId = new StringBuffer( 38);
sbClassId.append( '{');
for( int i=0; i < 16; i++) {
sbClassId.append( HexDump.toHex( bytes[ i]));
if( i == 3 || i == 5 || i == 7 || i == 9) {
sbClassId.append( '-');
}
}
sbClassId.append( '}');
return sbClassId.toString();
}
/**
* @see Object#hashCode()

View File

@ -59,6 +59,8 @@ import java.io.*;
import java.util.*;
import org.apache.poi.hpsf.ClassID;
import org.apache.poi.poifs.common.POIFSConstants;
import org.apache.poi.poifs.dev.POIFSViewable;
import org.apache.poi.util.ByteField;
@ -87,6 +89,8 @@ public abstract class Property
static final private int _previous_property_offset = 0x44;
static final private int _next_property_offset = 0x48;
static final private int _child_property_offset = 0x4C;
static final private int _storage_clsid_offset = 0x50;
static final private int _user_flags_offset = 0x60;
static final private int _seconds_1_offset = 0x64;
static final private int _days_1_offset = 0x68;
static final private int _seconds_2_offset = 0x6C;
@ -107,6 +111,8 @@ public abstract class Property
private IntegerField _previous_property;
private IntegerField _next_property;
private IntegerField _child_property;
private ClassID _storage_clsid;
private IntegerField _user_flags;
private IntegerField _seconds_1;
private IntegerField _days_1;
private IntegerField _seconds_2;
@ -136,6 +142,8 @@ public abstract class Property
_NO_INDEX, _raw_data);
_child_property = new IntegerField(_child_property_offset,
_NO_INDEX, _raw_data);
_storage_clsid = new ClassID(_raw_data,_storage_clsid_offset);
_user_flags = new IntegerField(_user_flags_offset, 0, _raw_data);
_seconds_1 = new IntegerField(_seconds_1_offset, 0,
_raw_data);
_days_1 = new IntegerField(_days_1_offset, 0, _raw_data);
@ -173,6 +181,8 @@ public abstract class Property
_raw_data);
_child_property = new IntegerField(_child_property_offset,
_raw_data);
_storage_clsid = new ClassID(_raw_data,_storage_clsid_offset);
_user_flags = new IntegerField(_user_flags_offset, 0, _raw_data);
_seconds_1 = new IntegerField(_seconds_1_offset, _raw_data);
_days_1 = new IntegerField(_days_1_offset, _raw_data);
_seconds_2 = new IntegerField(_seconds_2_offset, _raw_data);
@ -295,12 +305,21 @@ public abstract class Property
abstract public boolean isDirectory();
/**
* Sets the storage clsid, which is the Class ID of a COM object which
* reads and writes this stream
* @return storage Class ID for this property stream
*/
public ClassID getStorageClsid()
{
return _storage_clsid;
}
/**
* Set the name; silently truncates the name if it's too long.
*
* @param name the new name
*/
protected final void setName(final String name)
{
char[] char_array = name.toCharArray();
@ -327,6 +346,20 @@ public abstract class Property
* LittleEndianConsts.SHORT_SIZE), _raw_data);
}
/**
* Sets the storage class ID for this property stream. This is the Class ID
* of the COM object which can read and write this property stream
* @param clsidStorage Storage Class ID
*/
public void setStorageClsid( ClassID clsidStorage)
{
_storage_clsid = clsidStorage;
if( clsidStorage == null) {
Arrays.fill( _raw_data, _storage_clsid_offset, _storage_clsid_offset + ClassID.LENGTH, (byte) 0);
} else {
clsidStorage.write( _raw_data, _storage_clsid_offset);
}
}
/**
* Set the property type. Makes no attempt to validate the value.
*

View File

@ -0,0 +1,171 @@
/* ====================================================================
* The Apache Software License, Version 1.1
*
* Copyright (c) 2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Apache" and "Apache Software Foundation" and
* "Apache POI" must not be used to endorse or promote products
* derived from this software without prior written permission. For
* written permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* "Apache POI", nor may "Apache" appear in their name, without
* prior written permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
package org.apache.poi.hpsf.basic;
import junit.framework.Assert;
import junit.framework.TestCase;
import org.apache.poi.hpsf.ClassID;
/**
* <p>Tests ClassID structure.</p>
*
* @author Michael Zalewski (zalewski@optonline.net)
*/
public class TestClassID extends TestCase
{
/**
* <p>Constructor</p>
*
* @param name the test case's name
*/
public TestClassID(final String name)
{
super(name);
}
/**
* Various tests of overridden .equals()
*/
public void testEquals()
{
ClassID clsidTest1 = new ClassID(
new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 }
, 0
);
ClassID clsidTest2 = new ClassID(
new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 }
, 0
);
ClassID clsidTest3 = new ClassID(
new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x11 }
, 0
);
Assert.assertEquals( clsidTest1, clsidTest1);
Assert.assertEquals( clsidTest1, clsidTest2);
Assert.assertFalse( clsidTest1.equals( clsidTest3));
Assert.assertFalse( clsidTest1.equals( null));
}
/**
* Try to write to a buffer that is too small. This should
* throw an Exception
*/
public void testWriteArrayStoreException()
{
ClassID clsidTest = new ClassID(
new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 }
, 0
);
boolean bExceptionOccurred = false;
try {
clsidTest.write( new byte[ 15], 0);
} catch( Exception e) {
bExceptionOccurred = true;
}
Assert.assertTrue( bExceptionOccurred);
bExceptionOccurred = false;
try {
clsidTest.write( new byte[ 16], 1);
} catch( Exception e) {
bExceptionOccurred = true;
}
Assert.assertTrue( bExceptionOccurred);
// These should work without throwing an Exception
bExceptionOccurred = false;
try {
clsidTest.write( new byte[ 16], 0);
clsidTest.write( new byte[ 17], 1);
} catch( Exception e) {
bExceptionOccurred = true;
}
Assert.assertFalse( bExceptionOccurred);
}
/**
* <p>Tests the {@link PropertySet} methods. The test file has two
* property set: the first one is a {@link SummaryInformation},
* the second one is a {@link DocumentSummaryInformation}.</p>
*/
public void testClassID()
{
ClassID clsidTest = new ClassID(
new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10 }
, 0
);
Assert.assertEquals(
clsidTest.toString().toUpperCase()
, "{04030201-0605-0807-090A-0B0C0D0E0F10}"
);
}
/**
* <p>Runs the test cases stand-alone.</p>
*/
public static void main(final String[] args)
{
System.setProperty("HPSF.testdata.path",
"./src/testcases/org/apache/poi/hpsf/data");
junit.textui.TestRunner.run(TestClassID.class);
}
}

View File

@ -150,6 +150,7 @@ public class TestDocumentProperty
( byte ) 0xFE, ( byte ) 0xFF, ( byte ) 0xFF, ( byte ) 0xFF,
( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0x57, ( byte ) 0x00, ( byte ) 0x6F, ( byte ) 0x00,
( byte ) 0x72, ( byte ) 0x00, ( byte ) 0x6B, ( byte ) 0x00,
( byte ) 0x62, ( byte ) 0x00, ( byte ) 0x6F, ( byte ) 0x00,
@ -182,6 +183,7 @@ public class TestDocumentProperty
( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0x00, ( byte ) 0x10, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0x05, ( byte ) 0x00, ( byte ) 0x53, ( byte ) 0x00,
( byte ) 0x75, ( byte ) 0x00, ( byte ) 0x6D, ( byte ) 0x00,
( byte ) 0x6D, ( byte ) 0x00, ( byte ) 0x61, ( byte ) 0x00,
@ -214,6 +216,7 @@ public class TestDocumentProperty
( byte ) 0x08, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0x00, ( byte ) 0x10, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00,
( byte ) 0x05, ( byte ) 0x00, ( byte ) 0x44, ( byte ) 0x00,
( byte ) 0x6F, ( byte ) 0x00, ( byte ) 0x63, ( byte ) 0x00,
( byte ) 0x75, ( byte ) 0x00, ( byte ) 0x6D, ( byte ) 0x00,

View File

@ -217,11 +217,11 @@ public class TestRootProperty
( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00, ( byte ) 0x00
};
verifyReadingProperty(0, input, 0, "Root Entry");
verifyReadingProperty(0, input, 0, "Root Entry", "{00020820-0000-0000-C000-000000000046}");
}
private void verifyReadingProperty(int index, byte [] input, int offset,
String name)
String name, String sClsId)
throws IOException
{
RootProperty property = new RootProperty(index, input,
@ -242,6 +242,7 @@ public class TestRootProperty
assertEquals(index, property.getIndex());
assertEquals(name, property.getName());
assertTrue(!property.getChildren().hasNext());
assertEquals(property.getStorageClsid().toString(), sClsId);
}
/**