📄 property.java
字号:
/* ==================================================================== Copyright 2002-2004 Apache Software Foundation Licensed 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 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.==================================================================== */ package org.apache.poi.poifs.property;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;import org.apache.poi.util.IntegerField;import org.apache.poi.util.LittleEndianConsts;import org.apache.poi.util.ShortField;/** * This abstract base class is the ancestor of all classes * implementing POIFS Property behavior. * * @author Marc Johnson (mjohnson at apache dot org) */public abstract class Property implements Child, POIFSViewable{ static final private byte _default_fill = ( byte ) 0x00; static final private int _name_size_offset = 0x40; static final private int _max_name_length = (_name_size_offset / LittleEndianConsts.SHORT_SIZE) - 1; static final protected int _NO_INDEX = -1; // useful offsets static final private int _node_color_offset = 0x43; 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; static final private int _days_2_offset = 0x70; static final private int _start_block_offset = 0x74; static final private int _size_offset = 0x78; // node colors static final protected byte _NODE_BLACK = 1; static final protected byte _NODE_RED = 0; // documents must be at least this size to be stored in big blocks static final private int _big_block_minimum_bytes = 4096; private String _name; private ShortField _name_size; private ByteField _property_type; private ByteField _node_color; 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; private IntegerField _days_2; private IntegerField _start_block; private IntegerField _size; private byte[] _raw_data; private int _index; private Child _next_child; private Child _previous_child; /** * Default constructor */ protected Property() { _raw_data = new byte[ POIFSConstants.PROPERTY_SIZE ]; Arrays.fill(_raw_data, _default_fill); _name_size = new ShortField(_name_size_offset); _property_type = new ByteField(PropertyConstants.PROPERTY_TYPE_OFFSET); _node_color = new ByteField(_node_color_offset); _previous_property = new IntegerField(_previous_property_offset, _NO_INDEX, _raw_data); _next_property = new IntegerField(_next_property_offset, _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); _seconds_2 = new IntegerField(_seconds_2_offset, 0, _raw_data); _days_2 = new IntegerField(_days_2_offset, 0, _raw_data); _start_block = new IntegerField(_start_block_offset); _size = new IntegerField(_size_offset, 0, _raw_data); _index = _NO_INDEX; setName(""); setNextChild(null); setPreviousChild(null); } /** * Constructor from byte data * * @param index index number * @param array byte data * @param offset offset into byte data */ protected Property(final int index, final byte [] array, final int offset) { _raw_data = new byte[ POIFSConstants.PROPERTY_SIZE ]; System.arraycopy(array, offset, _raw_data, 0, POIFSConstants.PROPERTY_SIZE); _name_size = new ShortField(_name_size_offset, _raw_data); _property_type = new ByteField(PropertyConstants.PROPERTY_TYPE_OFFSET, _raw_data); _node_color = new ByteField(_node_color_offset, _raw_data); _previous_property = new IntegerField(_previous_property_offset, _raw_data); _next_property = new IntegerField(_next_property_offset, _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); _days_2 = new IntegerField(_days_2_offset, _raw_data); _start_block = new IntegerField(_start_block_offset, _raw_data); _size = new IntegerField(_size_offset, _raw_data); _index = index; int name_length = (_name_size.get() / LittleEndianConsts.SHORT_SIZE) - 1; if (name_length < 1) { _name = ""; } else { char[] char_array = new char[ name_length ]; int name_offset = 0; for (int j = 0; j < name_length; j++) { char_array[ j ] = ( char ) new ShortField(name_offset, _raw_data).get(); name_offset += LittleEndianConsts.SHORT_SIZE; } _name = new String(char_array, 0, name_length); } _next_child = null; _previous_child = null; } /** * Write the raw data to an OutputStream. * * @param stream the OutputStream to which the data should be * written. * * @exception IOException on problems writing to the specified * stream. */ public void writeData(final OutputStream stream) throws IOException { stream.write(_raw_data); } /** * Set the start block for the document referred to by this * Property. * * @param startBlock the start block index */ public void setStartBlock(final int startBlock) { _start_block.set(startBlock, _raw_data); } /** * @return the start block */ public int getStartBlock() { return _start_block.get(); } /** * find out the document size * * @return size in bytes */ public int getSize() { return _size.get(); } /** * Based on the currently defined size, should this property use * small blocks? * * @return true if the size is less than _big_block_minimum_bytes */ public boolean shouldUseSmallBlocks() { return Property.isSmall(_size.get()); } /** * does the length indicate a small document? * * @param length length in bytes * * @return true if the length is less than * _big_block_minimum_bytes */ public static boolean isSmall(final int length) { return length < _big_block_minimum_bytes; } /** * Get the name of this property * * @return property name as String */ public String getName() { return _name; } /** * @return true if a directory type 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) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -