2004-04-09 09:05:39 -04:00
|
|
|
/* ====================================================================
|
2006-12-22 14:18:16 -05:00
|
|
|
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
|
2004-04-09 09:05:39 -04:00
|
|
|
|
|
|
|
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.
|
|
|
|
==================================================================== */
|
|
|
|
|
2002-05-11 10:48:00 -04:00
|
|
|
package org.apache.poi.hpsf;
|
|
|
|
|
2003-10-31 11:39:05 -05:00
|
|
|
import org.apache.poi.util.HexDump;
|
|
|
|
|
2002-05-11 10:48:00 -04:00
|
|
|
/**
|
2002-07-17 12:23:22 -04:00
|
|
|
* <p>Represents a class ID (16 bytes). Unlike other little-endian
|
|
|
|
* type the {@link ClassID} is not just 16 bytes stored in the wrong
|
|
|
|
* order. Instead, it is a double word (4 bytes) followed by two
|
|
|
|
* words (2 bytes each) followed by 8 bytes.</p>
|
2002-05-11 10:48:00 -04:00
|
|
|
*
|
2003-08-30 05:13:53 -04:00
|
|
|
* @author Rainer Klute <a
|
|
|
|
* href="mailto:klute@rainer-klute.de"><klute@rainer-klute.de></a>
|
2002-07-17 12:23:22 -04:00
|
|
|
* @version $Id$
|
|
|
|
* @since 2002-02-09
|
2002-05-11 10:48:00 -04:00
|
|
|
*/
|
2002-07-17 12:23:22 -04:00
|
|
|
public class ClassID
|
|
|
|
{
|
2002-05-11 10:48:00 -04:00
|
|
|
|
|
|
|
/**
|
2002-07-17 12:23:22 -04:00
|
|
|
* <p>The bytes making out the class ID in correct order,
|
|
|
|
* i.e. big-endian.</p>
|
|
|
|
*/
|
|
|
|
protected byte[] bytes;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* <p>Creates a {@link ClassID} and reads its value from a byte
|
|
|
|
* array.</p>
|
2002-05-11 10:48:00 -04:00
|
|
|
*
|
2002-07-17 12:23:22 -04:00
|
|
|
* @param src The byte array to read from.
|
|
|
|
* @param offset The offset of the first byte to read.
|
2002-05-11 10:48:00 -04:00
|
|
|
*/
|
2002-07-17 12:23:22 -04:00
|
|
|
public ClassID(final byte[] src, final int offset)
|
|
|
|
{
|
|
|
|
read(src, offset);
|
2002-05-11 10:48:00 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2003-02-22 09:27:16 -05:00
|
|
|
/**
|
|
|
|
* <p>Creates a {@link ClassID} and initializes its value with
|
|
|
|
* 0x00 bytes.</p>
|
|
|
|
*/
|
|
|
|
public ClassID()
|
|
|
|
{
|
2003-08-02 15:02:28 -04:00
|
|
|
bytes = new byte[LENGTH];
|
|
|
|
for (int i = 0; i < LENGTH; i++)
|
|
|
|
bytes[i] = 0x00;
|
2003-02-22 09:27:16 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2002-05-11 10:48:00 -04:00
|
|
|
|
2003-08-02 15:02:28 -04:00
|
|
|
/** <p>The number of bytes occupied by this object in the byte
|
|
|
|
* stream.</p> */
|
|
|
|
public static final int LENGTH = 16;
|
2002-05-11 10:48:00 -04:00
|
|
|
|
2003-08-02 15:02:28 -04:00
|
|
|
/**
|
|
|
|
* @return The number of bytes occupied by this object in the byte
|
|
|
|
* stream.
|
|
|
|
*/
|
2002-07-17 12:23:22 -04:00
|
|
|
public int length()
|
|
|
|
{
|
2002-05-11 10:48:00 -04:00
|
|
|
return LENGTH;
|
|
|
|
}
|
|
|
|
|
2002-05-19 14:09:26 -04:00
|
|
|
|
2002-07-17 12:23:22 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* <p>Gets the bytes making out the class ID. They are returned in
|
|
|
|
* correct order, i.e. big-endian.</p>
|
2003-08-30 05:13:53 -04:00
|
|
|
*
|
2003-08-02 15:02:28 -04:00
|
|
|
* @return the bytes making out the class ID.
|
2002-07-17 12:23:22 -04:00
|
|
|
*/
|
|
|
|
public byte[] getBytes()
|
|
|
|
{
|
2003-08-02 15:02:28 -04:00
|
|
|
return bytes;
|
2002-05-19 14:09:26 -04:00
|
|
|
}
|
|
|
|
|
2002-05-11 10:48:00 -04:00
|
|
|
|
2002-07-17 12:23:22 -04:00
|
|
|
|
2004-08-13 18:38:52 -04:00
|
|
|
/**
|
|
|
|
* <p>Sets the bytes making out the class ID.</p>
|
|
|
|
*
|
|
|
|
* @param bytes The bytes making out the class ID in big-endian format. They
|
|
|
|
* are copied without their order being changed.
|
|
|
|
*/
|
|
|
|
public void setBytes(final byte[] bytes)
|
|
|
|
{
|
|
|
|
for (int i = 0; i < this.bytes.length; i++)
|
|
|
|
this.bytes[i] = bytes[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2002-05-11 10:48:00 -04:00
|
|
|
/**
|
2003-02-22 09:27:16 -05:00
|
|
|
* <p>Reads the class ID's value from a byte array by turning
|
|
|
|
* little-endian into big-endian.</p>
|
2002-07-17 12:23:22 -04:00
|
|
|
*
|
|
|
|
* @param src The byte array to read from
|
2002-05-11 10:48:00 -04:00
|
|
|
*
|
2002-07-17 12:23:22 -04:00
|
|
|
* @param offset The offset within the <var>src</var> byte array
|
|
|
|
*
|
|
|
|
* @return A byte array containing the class ID.
|
2002-05-11 10:48:00 -04:00
|
|
|
*/
|
2002-07-17 12:23:22 -04:00
|
|
|
public byte[] read(final byte[] src, final int offset)
|
|
|
|
{
|
|
|
|
bytes = new byte[16];
|
2002-07-17 08:01:50 -04:00
|
|
|
|
2002-07-17 12:23:22 -04:00
|
|
|
/* Read double word. */
|
|
|
|
bytes[0] = src[3 + offset];
|
|
|
|
bytes[1] = src[2 + offset];
|
|
|
|
bytes[2] = src[1 + offset];
|
|
|
|
bytes[3] = src[0 + offset];
|
2002-07-17 08:01:50 -04:00
|
|
|
|
2002-07-17 12:23:22 -04:00
|
|
|
/* Read first word. */
|
|
|
|
bytes[4] = src[5 + offset];
|
|
|
|
bytes[5] = src[4 + offset];
|
2002-07-17 08:01:50 -04:00
|
|
|
|
2002-07-17 12:23:22 -04:00
|
|
|
/* Read second word. */
|
|
|
|
bytes[6] = src[7 + offset];
|
|
|
|
bytes[7] = src[6 + offset];
|
2002-07-17 08:01:50 -04:00
|
|
|
|
2003-08-02 15:02:28 -04:00
|
|
|
/* Read 8 bytes. */
|
|
|
|
for (int i = 8; i < 16; i++)
|
|
|
|
bytes[i] = src[i + offset];
|
2002-07-17 08:01:50 -04:00
|
|
|
|
2002-07-17 12:23:22 -04:00
|
|
|
return bytes;
|
2002-05-11 10:48:00 -04:00
|
|
|
}
|
|
|
|
|
2003-02-22 09:27:16 -05:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* <p>Writes the class ID to a byte array in the
|
2004-08-13 18:38:52 -04:00
|
|
|
* little-endian format.</p>
|
2003-02-22 09:27:16 -05:00
|
|
|
*
|
|
|
|
* @param dst The byte array to write to.
|
|
|
|
*
|
|
|
|
* @param offset The offset within the <var>dst</var> byte array.
|
|
|
|
*
|
2003-08-30 05:13:53 -04:00
|
|
|
* @exception ArrayStoreException if there is not enough room for the class
|
2003-08-02 15:02:28 -04:00
|
|
|
* ID 16 bytes in the byte array after the <var>offset</var> position.
|
2003-02-22 09:27:16 -05:00
|
|
|
*/
|
|
|
|
public void write(final byte[] dst, final int offset)
|
2003-08-02 15:02:28 -04:00
|
|
|
throws ArrayStoreException
|
2003-02-22 09:27:16 -05:00
|
|
|
{
|
2003-08-02 15:02:28 -04:00
|
|
|
/* Check array size: */
|
|
|
|
if (dst.length < 16)
|
|
|
|
throw new ArrayStoreException
|
|
|
|
("Destination byte[] must have room for at least 16 bytes, " +
|
|
|
|
"but has a length of only " + dst.length + ".");
|
2003-02-22 09:27:16 -05:00
|
|
|
/* Write double word. */
|
2003-08-02 15:02:28 -04:00
|
|
|
dst[0 + offset] = bytes[3];
|
|
|
|
dst[1 + offset] = bytes[2];
|
|
|
|
dst[2 + offset] = bytes[1];
|
|
|
|
dst[3 + offset] = bytes[0];
|
2003-02-22 09:27:16 -05:00
|
|
|
|
|
|
|
/* Write first word. */
|
2003-08-02 15:02:28 -04:00
|
|
|
dst[4 + offset] = bytes[5];
|
|
|
|
dst[5 + offset] = bytes[4];
|
2003-02-22 09:27:16 -05:00
|
|
|
|
|
|
|
/* Write second word. */
|
2003-08-02 15:02:28 -04:00
|
|
|
dst[6 + offset] = bytes[7];
|
|
|
|
dst[7 + offset] = bytes[6];
|
2003-02-22 09:27:16 -05:00
|
|
|
|
2003-08-02 15:02:28 -04:00
|
|
|
/* Write 8 bytes. */
|
|
|
|
for (int i = 8; i < 16; i++)
|
|
|
|
dst[i + offset] = bytes[i];
|
2003-02-22 09:27:16 -05:00
|
|
|
}
|
|
|
|
|
2003-08-03 16:16:46 -04:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* <p>Checks whether this <code>ClassID</code> is equal to another
|
|
|
|
* object.</p>
|
|
|
|
*
|
|
|
|
* @param o the object to compare this <code>PropertySet</code> with
|
|
|
|
* @return <code>true</code> if the objects are equal, else
|
|
|
|
* <code>false</code>.</p>
|
|
|
|
*/
|
|
|
|
public boolean equals(final Object o)
|
|
|
|
{
|
|
|
|
if (o == null || !(o instanceof ClassID))
|
|
|
|
return false;
|
|
|
|
final ClassID cid = (ClassID) o;
|
|
|
|
if (bytes.length != cid.bytes.length)
|
|
|
|
return false;
|
|
|
|
for (int i = 0; i < bytes.length; i++)
|
|
|
|
if (bytes[i] != cid.bytes[i])
|
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2003-11-07 14:24:29 -05:00
|
|
|
|
|
|
|
|
2003-10-31 11:39:05 -05:00
|
|
|
/**
|
2003-11-07 14:24:29 -05:00
|
|
|
* @see Object#hashCode()
|
2003-10-31 11:39:05 -05:00
|
|
|
*/
|
2003-11-07 14:24:29 -05:00
|
|
|
public int hashCode()
|
2003-10-31 11:39:05 -05:00
|
|
|
{
|
2003-11-07 14:24:29 -05:00
|
|
|
return new String(bytes).hashCode();
|
2003-10-31 11:39:05 -05:00
|
|
|
}
|
2003-08-30 05:13:53 -04:00
|
|
|
|
2003-11-07 14:24:29 -05:00
|
|
|
|
|
|
|
|
2003-08-30 05:13:53 -04:00
|
|
|
/**
|
2003-11-07 14:24:29 -05:00
|
|
|
* <p>Returns a human-readable representation of the Class ID in standard
|
|
|
|
* format <code>"{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}"</code>.</p>
|
|
|
|
*
|
|
|
|
* @return String representation of the Class ID represented by this object.
|
2003-08-30 05:13:53 -04:00
|
|
|
*/
|
2003-11-07 14:24:29 -05:00
|
|
|
public String toString()
|
2003-08-30 05:13:53 -04:00
|
|
|
{
|
2003-11-07 14:24:29 -05:00
|
|
|
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();
|
2003-08-30 05:13:53 -04:00
|
|
|
}
|
|
|
|
|
2002-05-11 10:48:00 -04:00
|
|
|
}
|