import java.util.Arrays;
-import org.apache.poi.util.HexDump;
+import org.apache.commons.codec.binary.Hex;
+import org.apache.poi.common.Duplicatable;
+import org.apache.poi.util.LittleEndianInput;
+import org.apache.poi.util.LittleEndianOutput;
/**
* 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>
- *
- * The ClassID (or CLSID) is a UUID - see RFC 4122
+ *
+ * The ClassID (or CLSID) is a UUID - see RFC 4122
*/
-public class ClassID {
+public class ClassID implements Duplicatable {
/** @deprecated use enum {@link ClassIDPredefined} */ @Deprecated
public static final ClassID OLE10_PACKAGE = ClassIDPredefined.OLE_V1_PACKAGE.getClassID();
/** @deprecated use enum {@link ClassIDPredefined} */ @Deprecated
public static final ClassID POWERPOINT2007_MACRO = ClassIDPredefined.POWERPOINT_V12_MACRO.getClassID();
/** @deprecated use enum {@link ClassIDPredefined} */ @Deprecated
public static final ClassID EQUATION30 = ClassIDPredefined.EQUATION_V3.getClassID();
-
+
/** The number of bytes occupied by this object in the byte stream. */
public static final int LENGTH = 16;
-
+
/**
* The bytes making out the class ID in correct order, i.e. big-endian.
*/
Arrays.fill(bytes, (byte)0);
}
+ /**
+ * Clones the given ClassID
+ */
+ public ClassID(ClassID other) {
+ System.arraycopy(other.bytes, 0, bytes, 0, bytes.length);
+ }
+
/**
- * Creates a {@link ClassID} from a human-readable representation of the Class ID in standard
+ * Creates a {@link ClassID} from a human-readable representation of the Class ID in standard
* format {@code "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}"}.
- *
+ *
* @param externalForm representation of the Class ID represented by this object.
*/
public ClassID(String externalForm) {
bytes[i/2] = (byte)Integer.parseInt(clsStr.substring(i, i+2), 16);
}
}
-
+
+ /**
+ * Reads the ClassID from the input
+ * @param lei the input (stream)
+ */
+ public ClassID(LittleEndianInput lei) {
+ byte[] buf = bytes.clone();
+ lei.readFully(buf);
+ read(buf, 0);
+ }
/**
* @return The number of bytes occupied by this object in the byte stream.
("Destination byte[] must have room for at least 16 bytes, " +
"but has a length of only " + dst.length + ".");
}
-
+
/* Write double word. */
dst[0 + offset] = bytes[3];
dst[1 + offset] = bytes[2];
System.arraycopy(bytes, 8, dst, 8 + offset, 8);
}
-
+ /**
+ * Write the class ID to a LittleEndianOutput (stream)
+ *
+ * @param leo the output
+ */
+ public void write(LittleEndianOutput leo) {
+ byte[] buf = bytes.clone();
+ write(buf, 0);
+ leo.write(buf);
+ }
/**
* Checks whether this {@code ClassID} is equal to another object.
}
/**
- * Returns a human-readable representation of the Class ID in standard
+ * Returns a human-readable representation of the Class ID in standard
* format {@code "{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}"}.
- *
+ *
* @return String representation of the Class ID represented by this object.
*/
@Override
public String toString() {
- StringBuilder sbClassId = new StringBuilder(38);
- sbClassId.append('{');
- for (int i = 0; i < LENGTH; i++) {
- sbClassId.append(HexDump.toHex(bytes[i]));
- if (i == 3 || i == 5 || i == 7 || i == 9) {
- sbClassId.append('-');
- }
- }
- sbClassId.append('}');
- return sbClassId.toString();
+ String hex = Hex.encodeHexString(bytes, false);
+ return "{" + hex.substring(0,8) +
+ "-" + hex.substring(8,12) +
+ "-" + hex.substring(12,16) +
+ "-" + hex.substring(16,20) +
+ "-" + hex.substring(20) + "}";
+ }
+
+ @Override
+ public ClassID copy() {
+ return new ClassID(this);
}
}
/** Plain Text Persistent Handler **/
TXT_ONLY ("{5e941d80-bf96-11cd-b579-08002b30bfeb}", ".txt", "text/plain"),
/** Microsoft Paint **/
- PAINT ("{0003000A-0000-0000-C000-000000000046}", null, null)
+ PAINT ("{0003000A-0000-0000-C000-000000000046}", null, null),
+ /** Standard Hyperlink / STD Moniker **/
+ STD_MONIKER ("{79EAC9D0-BAF9-11CE-8C82-00AA004BA90B}", null, null),
+ /** URL Moniker **/
+ URL_MONIKER ("{79EAC9E0-BAF9-11CE-8C82-00AA004BA90B}", null, null),
+ /** File Moniker **/
+ FILE_MONIKER ("{00000303-0000-0000-C000-000000000046}", null, null)
;
-
+
+
private static final Map<String,ClassIDPredefined> LOOKUP = new HashMap<>();
static {
LOOKUP.put(p.externalForm, p);
}
}
-
+
private final String externalForm;
private ClassID classId;
private final String fileExtension;
private final String contentType;
-
+
ClassIDPredefined(final String externalForm, final String fileExtension, final String contentType) {
this.externalForm = externalForm;
this.fileExtension = fileExtension;
this.contentType = contentType;
}
-
+
public ClassID getClassID() {
synchronized (this) {
// TODO: init classId directly in the constructor when old statics have been removed from ClassID
public String getContentType() {
return contentType;
}
-
+
public static ClassIDPredefined lookup(final String externalForm) {
return LOOKUP.get(externalForm);
}
public static ClassIDPredefined lookup(final ClassID classID) {
return (classID == null) ? null : LOOKUP.get(classID.toString());
}
+
+ public boolean equals(ClassID classID) {
+ return getClassID().equals(classID);
+ }
}
package org.apache.poi.hssf.record;
+import static org.apache.poi.hpsf.ClassIDPredefined.FILE_MONIKER;
+import static org.apache.poi.hpsf.ClassIDPredefined.STD_MONIKER;
+import static org.apache.poi.hpsf.ClassIDPredefined.URL_MONIKER;
+
+import org.apache.poi.hpsf.ClassID;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.util.HexDump;
import org.apache.poi.util.HexRead;
import org.apache.poi.util.IOUtils;
-import org.apache.poi.util.LittleEndian;
import org.apache.poi.util.LittleEndianInput;
import org.apache.poi.util.LittleEndianOutput;
import org.apache.poi.util.POILogFactory;
*/
public final class HyperlinkRecord extends StandardRecord {
public static final short sid = 0x01B8;
- private static POILogger logger = POILogFactory.getLogger(HyperlinkRecord.class);
+ private static final POILogger logger = POILogFactory.getLogger(HyperlinkRecord.class);
//arbitrarily selected; may need to increase
private static final int MAX_RECORD_LENGTH = 100_000;
- // TODO: replace with ClassID
- static final class GUID {
- /*
- * this class is currently only used here, but could be moved to a
- * common package if needed
- */
- private static final int TEXT_FORMAT_LENGTH = 36;
-
- public static final int ENCODED_SIZE = 16;
-
- /** 4 bytes - little endian */
- private final int _d1;
- /** 2 bytes - little endian */
- private final int _d2;
- /** 2 bytes - little endian */
- private final int _d3;
- /**
- * 8 bytes - serialized as big endian, stored with inverted endianness here
- */
- private final long _d4;
-
- public GUID(GUID other) {
- _d1 = other._d1;
- _d2 = other._d2;
- _d3 = other._d3;
- _d4 = other._d4;
- }
-
- public GUID(LittleEndianInput in) {
- this(in.readInt(), in.readUShort(), in.readUShort(), in.readLong());
- }
-
- public GUID(int d1, int d2, int d3, long d4) {
- _d1 = d1;
- _d2 = d2;
- _d3 = d3;
- _d4 = d4;
- }
-
- public void serialize(LittleEndianOutput out) {
- out.writeInt(_d1);
- out.writeShort(_d2);
- out.writeShort(_d3);
- out.writeLong(_d4);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (!(obj instanceof GUID)) {
- return false;
- }
- GUID other = (GUID) obj;
- return _d1 == other._d1 && _d2 == other._d2
- && _d3 == other._d3 && _d4 == other._d4;
- }
-
- @Override
- public int hashCode() {
- assert false : "hashCode not designed";
- return 42; // any arbitrary constant will do
- }
-
- public int getD1() {
- return _d1;
- }
-
- public int getD2() {
- return _d2;
- }
-
- public int getD3() {
- return _d3;
- }
-
- public long getD4() {
- byte[] result = new byte[Long.SIZE/Byte.SIZE];
- long l = _d4;
- for (int i = result.length-1; i >= 0; i--) {
- result[i] = (byte)(l & 0xFF);
- l >>= 8;
- }
-
- return LittleEndian.getLong(result, 0);
- }
-
- public String formatAsString() {
-
- StringBuilder sb = new StringBuilder(36);
-
- int PREFIX_LEN = "0x".length();
- sb.append(HexDump.intToHex(_d1).substring(PREFIX_LEN));
- sb.append("-");
- sb.append(HexDump.shortToHex(_d2).substring(PREFIX_LEN));
- sb.append("-");
- sb.append(HexDump.shortToHex(_d3).substring(PREFIX_LEN));
- sb.append("-");
- String d4Chars = HexDump.longToHex(getD4());
- sb.append(d4Chars, PREFIX_LEN, PREFIX_LEN+4);
- sb.append("-");
- sb.append(d4Chars.substring(PREFIX_LEN+4));
- return sb.toString();
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder(64);
- sb.append(getClass().getName()).append(" [");
- sb.append(formatAsString());
- sb.append("]");
- return sb.toString();
- }
-
- /**
- * Read a GUID in standard text form e.g.<br>
- * 13579BDF-0246-8ACE-0123-456789ABCDEF
- * <br> -> <br>
- * 0x13579BDF, 0x0246, 0x8ACE 0x0123456789ABCDEF
- */
- public static GUID parse(String rep) {
- char[] cc = rep.toCharArray();
- if (cc.length != TEXT_FORMAT_LENGTH) {
- throw new RecordFormatException("supplied text is the wrong length for a GUID");
- }
- int d0 = (parseShort(cc, 0) << 16) + (parseShort(cc, 4) << 0);
- int d1 = parseShort(cc, 9);
- int d2 = parseShort(cc, 14);
- System.arraycopy(cc, 19, cc, 20, 4);
- long d3 = parseLELong(cc, 20);
-
- return new GUID(d0, d1, d2, d3);
- }
-
- private static long parseLELong(char[] cc, int startIndex) {
- long acc = 0;
- for (int i = startIndex + 14; i >= startIndex; i -= 2) {
- acc <<= 4;
- acc += parseHexChar(cc[i + 0]);
- acc <<= 4;
- acc += parseHexChar(cc[i + 1]);
- }
- return acc;
- }
-
- private static int parseShort(char[] cc, int startIndex) {
- int acc = 0;
- for (int i = 0; i < 4; i++) {
- acc <<= 4;
- acc += parseHexChar(cc[startIndex + i]);
- }
- return acc;
- }
-
- private static int parseHexChar(char c) {
- if (c >= '0' && c <= '9') {
- return c - '0';
- }
- if (c >= 'A' && c <= 'F') {
- return c - 'A' + 10;
- }
- if (c >= 'a' && c <= 'f') {
- return c - 'a' + 10;
- }
- throw new RecordFormatException("Bad hex char '" + c + "'");
- }
- }
-
/*
* Link flags
*/
private static final int HLINK_TARGET_FRAME = 0x80; // has 'target frame'
private static final int HLINK_UNC_PATH = 0x100; // has UNC path
- static final GUID STD_MONIKER = GUID.parse("79EAC9D0-BAF9-11CE-8C82-00AA004BA90B");
- static final GUID URL_MONIKER = GUID.parse("79EAC9E0-BAF9-11CE-8C82-00AA004BA90B");
- static final GUID FILE_MONIKER = GUID.parse("00000303-0000-0000-C000-000000000046");
/** expected Tail of a URL link */
private static final byte[] URL_TAIL = HexRead.readFromString("79 58 81 F4 3B 1D 7F 48 AF 2C 82 5D C4 85 27 63 00 00 00 00 A5 AB 00 00");
/** expected Tail of a file link */
private CellRangeAddress _range;
/** 16-byte GUID */
- private GUID _guid;
+ private ClassID _guid;
/** Some sort of options for file links. */
private int _fileOpts;
/** Link options. Can include any of HLINK_* flags. */
private String _targetFrame;
/** Moniker. Makes sense only for URL and file links */
- private GUID _moniker;
+ private ClassID _moniker;
/** in 8:3 DOS format No Unicode string header,
* always 8-bit characters, zero-terminated */
private String _shortFilename;
public HyperlinkRecord(HyperlinkRecord other) {
super(other);
_range = (other._range == null) ? null : other._range.copy();
- _guid = (other._guid == null) ? null : new GUID(other._guid);
+ _guid = (other._guid == null) ? null : other._guid.copy();
_fileOpts = other._fileOpts;
_linkOpts = other._linkOpts;
_label = other._label;
_targetFrame = other._targetFrame;
- _moniker = (other._moniker == null) ? null : new GUID(other._moniker);
+ _moniker = (other._moniker == null) ? null : other._moniker.copy();
_shortFilename = other._shortFilename;
_address = other._address;
_textMark = other._textMark;
}
/**
- * @return 16-byte guid identifier Seems to always equal {@link #STD_MONIKER}
+ * @return 16-byte guid identifier Seems to always equal {@link org.apache.poi.hpsf.ClassIDPredefined#STD_MONIKER}
*/
- GUID getGuid() {
+ ClassID getGuid() {
return _guid;
}
/**
* @return 16-byte moniker
*/
- GUID getMoniker()
+ ClassID getMoniker()
{
return _moniker;
}
public HyperlinkRecord(RecordInputStream in) {
_range = new CellRangeAddress(in);
- _guid = new GUID(in);
+ _guid = new ClassID(in);
- /**
+ /*
* streamVersion (4 bytes): An unsigned integer that specifies the version number
* of the serialization implementation used to save this structure. This value MUST equal 2.
*/
}
if ((_linkOpts & HLINK_URL) != 0 && (_linkOpts & HLINK_UNC_PATH) == 0) {
- _moniker = new GUID(in);
+ _moniker = new ClassID(in);
if(URL_MONIKER.equals(_moniker)){
int length = in.readInt();
- /**
+ /*
* The value of <code>length<code> be either the byte size of the url field
* (including the terminating NULL character) or the byte size of the url field plus 24.
* If the value of this field is set to the byte size of the url field,
} else {
int nChars = (length - TAIL_SIZE)/2;
_address = in.readUnicodeLEString(nChars);
- /**
+ /*
* TODO: make sense of the remaining bytes
* According to the spec they consist of:
* 1. 16-byte GUID: This field MUST equal
public void serialize(LittleEndianOutput out) {
_range.serialize(out);
- _guid.serialize(out);
+ _guid.write(out);
out.writeInt(0x00000002); // TODO const
out.writeInt(_linkOpts);
}
if ((_linkOpts & HLINK_URL) != 0 && (_linkOpts & HLINK_UNC_PATH) == 0) {
- _moniker.serialize(out);
+ _moniker.write(out);
if(URL_MONIKER.equals(_moniker)){
if (_uninterpretedTail == null) {
out.writeInt(_address.length()*2);
protected int getDataSize() {
int size = 0;
size += 2 + 2 + 2 + 2; //rwFirst, rwLast, colFirst, colLast
- size += GUID.ENCODED_SIZE;
+ size += ClassID.LENGTH;
size += 4; //label_opts
size += 4; //link_opts
if ((_linkOpts & HLINK_LABEL) != 0){
size += _address.length()*2;
}
if ((_linkOpts & HLINK_URL) != 0 && (_linkOpts & HLINK_UNC_PATH) == 0) {
- size += GUID.ENCODED_SIZE;
+ size += ClassID.LENGTH;
if(URL_MONIKER.equals(_moniker)){
size += 4; //address length
size += _address.length()*2;
buffer.append("[HYPERLINK RECORD]\n");
buffer.append(" .range = ").append(_range.formatAsString()).append("\n");
- buffer.append(" .guid = ").append(_guid.formatAsString()).append("\n");
+ buffer.append(" .guid = ").append(_guid.toString()).append("\n");
buffer.append(" .linkOpts= ").append(HexDump.intToHex(_linkOpts)).append("\n");
buffer.append(" .label = ").append(getLabel()).append("\n");
if ((_linkOpts & HLINK_TARGET_FRAME) != 0) {
buffer.append(" .targetFrame= ").append(getTargetFrame()).append("\n");
}
if((_linkOpts & HLINK_URL) != 0 && _moniker != null) {
- buffer.append(" .moniker = ").append(_moniker.formatAsString()).append("\n");
+ buffer.append(" .moniker = ").append(_moniker.toString()).append("\n");
}
if ((_linkOpts & HLINK_PLACE) != 0) {
buffer.append(" .textMark= ").append(getTextMark()).append("\n");
*
* @return true, if this is a url link
*/
+ @SuppressWarnings("unused")
public boolean isUrlLink() {
return (_linkOpts & HLINK_URL) > 0
&& (_linkOpts & HLINK_ABS) > 0;
*/
public void newUrlLink() {
_range = new CellRangeAddress(0, 0, 0, 0);
- _guid = STD_MONIKER;
+ _guid = STD_MONIKER.getClassID();
_linkOpts = HLINK_URL | HLINK_ABS | HLINK_LABEL;
setLabel("");
- _moniker = URL_MONIKER;
+ _moniker = URL_MONIKER.getClassID();
setAddress("");
_uninterpretedTail = URL_TAIL;
}
*/
public void newFileLink() {
_range = new CellRangeAddress(0, 0, 0, 0);
- _guid = STD_MONIKER;
+ _guid = STD_MONIKER.getClassID();
_linkOpts = HLINK_URL | HLINK_LABEL;
_fileOpts = 0;
setLabel("");
- _moniker = FILE_MONIKER;
+ _moniker = FILE_MONIKER.getClassID();
setAddress(null);
setShortFilename("");
_uninterpretedTail = FILE_TAIL;
*/
public void newDocumentLink() {
_range = new CellRangeAddress(0, 0, 0, 0);
- _guid = STD_MONIKER;
+ _guid = STD_MONIKER.getClassID();
_linkOpts = HLINK_LABEL | HLINK_PLACE;
setLabel("");
- _moniker = FILE_MONIKER;
+ _moniker = FILE_MONIKER.getClassID();
setAddress("");
setTextMark("");
}
@Override
- @SuppressWarnings("squid:S2975")
+ @SuppressWarnings({"squid:S2975", "MethodDoesntCallSuperMethod"})
@Deprecated
@Removal(version = "5.0.0")
public HyperlinkRecord clone() {
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
-import static org.junit.Assert.fail;
+import static org.junit.Assert.assertNotNull;
-import org.apache.poi.hssf.record.HyperlinkRecord.GUID;
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+
+import org.apache.poi.hpsf.ClassID;
+import org.apache.poi.hpsf.ClassIDPredefined;
import org.apache.poi.util.HexDump;
import org.apache.poi.util.HexRead;
import org.apache.poi.util.LittleEndianByteArrayInputStream;
};
- private void confirmGUID(GUID expectedGuid, GUID actualGuid) {
+ private void confirmGUID(ClassID expectedGuid, ClassID actualGuid) {
assertEquals(expectedGuid, actualGuid);
}
assertEquals(2, link.getLastRow());
assertEquals(0, link.getFirstColumn());
assertEquals(0, link.getLastColumn());
- confirmGUID(HyperlinkRecord.STD_MONIKER, link.getGuid());
- confirmGUID(HyperlinkRecord.URL_MONIKER, link.getMoniker());
+ confirmGUID(ClassIDPredefined.STD_MONIKER.getClassID(), link.getGuid());
+ confirmGUID(ClassIDPredefined.URL_MONIKER.getClassID(), link.getMoniker());
assertEquals(2, link.getLabelOptions());
int opts = HyperlinkRecord.HLINK_URL | HyperlinkRecord.HLINK_ABS | HyperlinkRecord.HLINK_LABEL;
assertEquals(0x17, opts);
assertEquals(0, link.getLastRow());
assertEquals(0, link.getFirstColumn());
assertEquals(0, link.getLastColumn());
- confirmGUID(HyperlinkRecord.STD_MONIKER, link.getGuid());
- confirmGUID(HyperlinkRecord.FILE_MONIKER, link.getMoniker());
+ confirmGUID(ClassIDPredefined.STD_MONIKER.getClassID(), link.getGuid());
+ confirmGUID(ClassIDPredefined.FILE_MONIKER.getClassID(), link.getMoniker());
assertEquals(2, link.getLabelOptions());
int opts = HyperlinkRecord.HLINK_URL | HyperlinkRecord.HLINK_LABEL;
assertEquals(0x15, opts);
assertEquals(1, link.getLastRow());
assertEquals(0, link.getFirstColumn());
assertEquals(0, link.getLastColumn());
- confirmGUID(HyperlinkRecord.STD_MONIKER, link.getGuid());
- confirmGUID(HyperlinkRecord.URL_MONIKER, link.getMoniker());
+ confirmGUID(ClassIDPredefined.STD_MONIKER.getClassID(), link.getGuid());
+ confirmGUID(ClassIDPredefined.URL_MONIKER.getClassID(), link.getMoniker());
assertEquals(2, link.getLabelOptions());
int opts = HyperlinkRecord.HLINK_URL | HyperlinkRecord.HLINK_ABS | HyperlinkRecord.HLINK_LABEL;
assertEquals(0x17, opts);
assertEquals(3, link.getLastRow());
assertEquals(0, link.getFirstColumn());
assertEquals(0, link.getLastColumn());
- confirmGUID(HyperlinkRecord.STD_MONIKER, link.getGuid());
+ confirmGUID(ClassIDPredefined.STD_MONIKER.getClassID(), link.getGuid());
assertEquals(2, link.getLabelOptions());
int opts = HyperlinkRecord.HLINK_LABEL | HyperlinkRecord.HLINK_PLACE;
assertEquals(0x1C, opts);
HyperlinkRecord hr = new HyperlinkRecord(in);
byte[] ser = hr.serialize();
TestcaseRecordInputStream.confirmRecordEncoding(HyperlinkRecord.sid, dataUNC, ser);
- try {
- hr.toString();
- } catch (NullPointerException e) {
- fail("Identified bug with option URL and UNC set at same time");
- }
+ assertNotNull(hr.toString());
}
@Test
- public void testGUID() {
- GUID g;
- g = GUID.parse("3F2504E0-4F89-11D3-9A0C-0305E82C3301");
+ public void testGUID() throws IOException {
+ ClassID g;
+ g = new ClassID("3F2504E0-4F89-11D3-9A0C-0305E82C3301");
confirmGUID(g, 0x3F2504E0, 0x4F89, 0x11D3, 0x9A0C0305E82C3301L);
- assertEquals("3F2504E0-4F89-11D3-9A0C-0305E82C3301", g.formatAsString());
+ assertEquals("{3F2504E0-4F89-11D3-9A0C-0305E82C3301}", g.toString());
- g = GUID.parse("13579BDF-0246-8ACE-0123-456789ABCDEF");
+ g = new ClassID("13579BDF-0246-8ACE-0123-456789ABCDEF");
confirmGUID(g, 0x13579BDF, 0x0246, 0x8ACE, 0x0123456789ABCDEFL);
- assertEquals("13579BDF-0246-8ACE-0123-456789ABCDEF", g.formatAsString());
+ assertEquals("{13579BDF-0246-8ACE-0123-456789ABCDEF}", g.toString());
byte[] buf = new byte[16];
- g.serialize(new LittleEndianByteArrayOutputStream(buf, 0));
+ g.write(new LittleEndianByteArrayOutputStream(buf, 0));
String expectedDump = "[DF, 9B, 57, 13, 46, 02, CE, 8A, 01, 23, 45, 67, 89, AB, CD, EF]";
assertEquals(expectedDump, HexDump.toHex(buf));
// STD Moniker
g = createFromStreamDump("[D0, C9, EA, 79, F9, BA, CE, 11, 8C, 82, 00, AA, 00, 4B, A9, 0B]");
- assertEquals("79EAC9D0-BAF9-11CE-8C82-00AA004BA90B", g.formatAsString());
+ assertEquals("{79EAC9D0-BAF9-11CE-8C82-00AA004BA90B}", g.toString());
// URL Moniker
g = createFromStreamDump("[E0, C9, EA, 79, F9, BA, CE, 11, 8C, 82, 00, AA, 00, 4B, A9, 0B]");
- assertEquals("79EAC9E0-BAF9-11CE-8C82-00AA004BA90B", g.formatAsString());
+ assertEquals("{79EAC9E0-BAF9-11CE-8C82-00AA004BA90B}", g.toString());
// File Moniker
g = createFromStreamDump("[03, 03, 00, 00, 00, 00, 00, 00, C0, 00, 00, 00, 00, 00, 00, 46]");
- assertEquals("00000303-0000-0000-C000-000000000046", g.formatAsString());
+ assertEquals("{00000303-0000-0000-C000-000000000046}", g.toString());
}
- private static GUID createFromStreamDump(String s) {
- return new GUID(new LittleEndianByteArrayInputStream(HexRead.readFromString(s)));
+ private static ClassID createFromStreamDump(String s) {
+ return new ClassID(new LittleEndianByteArrayInputStream(HexRead.readFromString(s)));
}
- private void confirmGUID(GUID g, int d1, int d2, int d3, long d4) {
- assertEquals(HexDump.intToHex(d1), HexDump.intToHex(g.getD1()));
- assertEquals(HexDump.shortToHex(d2), HexDump.shortToHex(g.getD2()));
- assertEquals(HexDump.shortToHex(d3), HexDump.shortToHex(g.getD3()));
- assertEquals(HexDump.longToHex(d4), HexDump.longToHex(g.getD4()));
+ private void confirmGUID(ClassID g, int d1, int d2, int d3, long d4) throws IOException {
+ try (DataInputStream dis = new DataInputStream(new ByteArrayInputStream(g.getBytes()))) {
+ assertEquals(d1, dis.readInt());
+ assertEquals(d2, dis.readShort() & 0xFFFF);
+ assertEquals(d3, dis.readShort() & 0xFFFF);
+ assertEquals(d4, dis.readLong());
+ }
}
@Test
assertEquals(2, link.getLastRow());
assertEquals(0, link.getFirstColumn());
assertEquals(0, link.getLastColumn());
- confirmGUID(HyperlinkRecord.STD_MONIKER, link.getGuid());
- confirmGUID(HyperlinkRecord.URL_MONIKER, link.getMoniker());
+ confirmGUID(ClassIDPredefined.STD_MONIKER.getClassID(), link.getGuid());
+ confirmGUID(ClassIDPredefined.URL_MONIKER.getClassID(), link.getMoniker());
assertEquals(2, link.getLabelOptions());
int opts = HyperlinkRecord.HLINK_URL | HyperlinkRecord.HLINK_LABEL;
assertEquals(opts, link.getLinkOptions());