?? propertyset.java
字號:
stream.reset(); return isPropertySetStream; } /** * <p>Checks whether a byte array is in the Horrible Property Set * Format.</p> * * @param src The byte array to check. * @param offset The offset in the byte array. * @param length The significant number of bytes in the byte * array. Only this number of bytes will be checked. * @return <code>true</code> if the byte array is a property set * stream, <code>false</code> if not. */ public static boolean isPropertySetStream(final byte[] src, final int offset, final int length) { /* FIXME (3): Ensure that at most "length" bytes are read. */ /* * Read the header fields of the stream. They must always be * there. */ int o = offset; final int byteOrder = LittleEndian.getUShort(src, o); o += LittleEndian.SHORT_SIZE; byte[] temp = new byte[LittleEndian.SHORT_SIZE]; LittleEndian.putShort(temp, (short) byteOrder); if (!Util.equal(temp, BYTE_ORDER_ASSERTION)) return false; final int format = LittleEndian.getUShort(src, o); o += LittleEndian.SHORT_SIZE; temp = new byte[LittleEndian.SHORT_SIZE]; LittleEndian.putShort(temp, (short) format); if (!Util.equal(temp, FORMAT_ASSERTION)) return false; // final long osVersion = LittleEndian.getUInt(src, offset); o += LittleEndian.INT_SIZE; // final ClassID classID = new ClassID(src, offset); o += ClassID.LENGTH; final long sectionCount = LittleEndian.getUInt(src, o); o += LittleEndian.INT_SIZE; if (sectionCount < 1) return false; return true; } /** * <p>Initializes this {@link PropertySet} instance from a byte * array. The method assumes that it has been checked already that * the byte array indeed represents a property set stream. It does * no more checks on its own.</p> * * @param src Byte array containing the property set stream * @param offset The property set stream starts at this offset * from the beginning of <var>src</src> * @param length Length of the property set stream. */ private void init(final byte[] src, final int offset, final int length) throws UnsupportedEncodingException { /* FIXME (3): Ensure that at most "length" bytes are read. */ /* * Read the stream's header fields. */ int o = offset; byteOrder = LittleEndian.getUShort(src, o); o += LittleEndian.SHORT_SIZE; format = LittleEndian.getUShort(src, o); o += LittleEndian.SHORT_SIZE; osVersion = (int) LittleEndian.getUInt(src, o); o += LittleEndian.INT_SIZE; classID = new ClassID(src, o); o += ClassID.LENGTH; final int sectionCount = LittleEndian.getInt(src, o); o += LittleEndian.INT_SIZE; if (sectionCount <= 0) throw new HPSFRuntimeException("Section count " + sectionCount + " must be greater than 0."); /* * Read the sections, which are following the header. They * start with an array of section descriptions. Each one * consists of a format ID telling what the section contains * and an offset telling how many bytes from the start of the * stream the section begins. */ /* * Most property sets have only one section. The Document * Summary Information stream has 2. Everything else is a rare * exception and is no longer fostered by Microsoft. */ sections = new ArrayList(sectionCount); /* * Loop over the section descriptor array. Each descriptor * consists of a ClassID and a DWord, and we have to increment * "offset" accordingly. */ for (int i = 0; i < sectionCount; i++) { final Section s = new Section(src, o); o += ClassID.LENGTH + LittleEndian.INT_SIZE; sections.add(s); } } /** * <p>Checks whether this {@link PropertySet} represents a Summary * Information.</p> * * @return <code>true</code> if this {@link PropertySet} * represents a Summary Information, else <code>false</code>. */ public boolean isSummaryInformation() { return Util.equal(((Section) sections.get(0)).getFormatID().getBytes(), SectionIDMap.SUMMARY_INFORMATION_ID); } /** * <p>Checks whether this {@link PropertySet} is a Document * Summary Information.</p> * * @return <code>true</code> if this {@link PropertySet} * represents a Document Summary Information, else <code>false</code>. */ public boolean isDocumentSummaryInformation() { return Util.equal(((Section) sections.get(0)).getFormatID().getBytes(), SectionIDMap.DOCUMENT_SUMMARY_INFORMATION_ID); } /** * <p>Convenience method returning the {@link Property} array * contained in this property set. It is a shortcut for getting * the {@link PropertySet}'s {@link Section}s list and then * getting the {@link Property} array from the first {@link * Section}. However, it can only be used if the {@link * PropertySet} contains exactly one {@link Section}, so check * {@link #getSectionCount} first!</p> * * @return The properties of the only {@link Section} of this * {@link PropertySet}. * @throws NoSingleSectionException if the {@link PropertySet} has * more or less than one {@link Section}. */ public Property[] getProperties() throws NoSingleSectionException { return getSingleSection().getProperties(); } /** * <p>Convenience method returning the value of the property with * the specified ID. If the property is not available, * <code>null</code> is returned and a subsequent call to {@link * #wasNull} will return <code>true</code> .</p> * * @param id The property ID * @return The property value * @throws NoSingleSectionException if the {@link PropertySet} has * more or less than one {@link Section}. */ protected Object getProperty(final int id) throws NoSingleSectionException { return getSingleSection().getProperty(id); } /** * <p>Convenience method returning the value of a boolean property * with the specified ID. If the property is not available, * <code>false</code> is returned. A subsequent call to {@link * #wasNull} will return <code>true</code> to let the caller * distinguish that case from a real property value of * <code>false</code>.</p> * * @param id The property ID * @return The property value * @throws NoSingleSectionException if the {@link PropertySet} has * more or less than one {@link Section}. */ protected boolean getPropertyBooleanValue(final int id) throws NoSingleSectionException { return getSingleSection().getPropertyBooleanValue(id); } /** * <p>Convenience method returning the value of the numeric * property with the specified ID. If the property is not * available, 0 is returned. A subsequent call to {@link #wasNull} * will return <code>true</code> to let the caller distinguish * that case from a real property value of 0.</p> * * @param id The property ID * @return The propertyIntValue value * @throws NoSingleSectionException if the {@link PropertySet} has * more or less than one {@link Section}. */ protected int getPropertyIntValue(final int id) throws NoSingleSectionException { return getSingleSection().getPropertyIntValue(id); } /** * <p>Checks whether the property which the last call to {@link * #getPropertyIntValue} or {@link #getProperty} tried to access * was available or not. This information might be important for * callers of {@link #getPropertyIntValue} since the latter * returns 0 if the property does not exist. Using {@link * #wasNull}, the caller can distiguish this case from a * property's real value of 0.</p> * * @return <code>true</code> if the last call to {@link * #getPropertyIntValue} or {@link #getProperty} tried to access a * property that was not available, else <code>false</code>. * @throws NoSingleSectionException if the {@link PropertySet} has * more than one {@link Section}. */ public boolean wasNull() throws NoSingleSectionException { return getSingleSection().wasNull(); } /** * <p>If the {@link PropertySet} has only a single section this * method returns it.</p> * * @return The singleSection value */ public Section getSingleSection() { final int sectionCount = getSectionCount(); if (sectionCount != 1) throw new NoSingleSectionException ("Property set contains " + sectionCount + " sections."); return ((Section) sections.get(0)); } /** * <p>Returns <code>true</code> if the <code>PropertySet</code> is equal * to the specified parameter, else <code>false</code>.</p> * * @param o the object to compare this <code>PropertySet</code> with * * @return <code>true</code> if the objects are equal, <code>false</code> * if not */ public boolean equals(final Object o) { if (o == null || !(o instanceof PropertySet)) return false; final PropertySet ps = (PropertySet) o; int byteOrder1 = ps.getByteOrder(); int byteOrder2 = getByteOrder(); ClassID classID1 = ps.getClassID(); ClassID classID2 = getClassID(); int format1 = ps.getFormat(); int format2 = getFormat(); int osVersion1 = ps.getOSVersion(); int osVersion2 = getOSVersion(); int sectionCount1 = ps.getSectionCount(); int sectionCount2 = getSectionCount(); if (byteOrder1 != byteOrder2 || !classID1.equals(classID2) || format1 != format2 || osVersion1 != osVersion2 || sectionCount1 != sectionCount2) return false; /* Compare the sections: */ return Util.equals(getSections(), ps.getSections()); } /** * @see Object#hashCode() */ public int hashCode() { throw new UnsupportedOperationException("FIXME: Not yet implemented."); } /** * @see Object#toString() */ public String toString() { final StringBuffer b = new StringBuffer(); final int sectionCount = getSectionCount(); b.append(getClass().getName()); b.append('['); b.append("byteOrder: "); b.append(getByteOrder()); b.append(", classID: "); b.append(getClassID()); b.append(", format: "); b.append(getFormat()); b.append(", OSVersion: "); b.append(getOSVersion()); b.append(", sectionCount: "); b.append(sectionCount); b.append(", sections: [\n"); final List sections = getSections(); for (int i = 0; i < sectionCount; i++) b.append(((Section) sections.get(i)).toString()); b.append(']'); b.append(']'); return b.toString(); }}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -