001: /* ====================================================================
002: Licensed to the Apache Software Foundation (ASF) under one or more
003: contributor license agreements. See the NOTICE file distributed with
004: this work for additional information regarding copyright ownership.
005: The ASF licenses this file to You under the Apache License, Version 2.0
006: (the "License"); you may not use this file except in compliance with
007: the License. You may obtain a copy of the License at
008:
009: http://www.apache.org/licenses/LICENSE-2.0
010:
011: Unless required by applicable law or agreed to in writing, software
012: distributed under the License is distributed on an "AS IS" BASIS,
013: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: See the License for the specific language governing permissions and
015: limitations under the License.
016: ==================================================================== */
017:
018: package org.apache.poi.hwpf.model;
019:
020: import java.util.ArrayList;
021:
022: import org.apache.poi.util.LittleEndian;
023:
024: /**
025: * common data structure in a Word file. Contains an array of 4 byte ints in
026: * the front that relate to an array of abitrary data structures in the back.
027: *
028: *
029: * @author Ryan Ackley
030: */
031: public class PlexOfCps {
032: private int _count;
033: private int _offset;
034: private int _sizeOfStruct;
035: private ArrayList _props;
036:
037: public PlexOfCps(int sizeOfStruct) {
038: _props = new ArrayList();
039: _sizeOfStruct = sizeOfStruct;
040: }
041:
042: /**
043: * Constructor
044: *
045: * @param size The size in bytes of this PlexOfCps
046: * @param sizeOfStruct The size of the data structure type stored in
047: * this PlexOfCps.
048: */
049: public PlexOfCps(byte[] buf, int start, int size, int sizeOfStruct) {
050: _count = (size - 4) / (4 + sizeOfStruct);
051: _sizeOfStruct = sizeOfStruct;
052: _props = new ArrayList(_count);
053:
054: for (int x = 0; x < _count; x++) {
055: _props.add(getProperty(x, buf, start));
056: }
057: }
058:
059: public GenericPropertyNode getProperty(int index) {
060: return (GenericPropertyNode) _props.get(index);
061: }
062:
063: public void addProperty(GenericPropertyNode node) {
064: _props.add(node);
065: }
066:
067: public byte[] toByteArray() {
068: int size = _props.size();
069: int cpBufSize = ((size + 1) * LittleEndian.INT_SIZE);
070: int structBufSize = +(_sizeOfStruct * size);
071: int bufSize = cpBufSize + structBufSize;
072:
073: byte[] buf = new byte[bufSize];
074:
075: GenericPropertyNode node = null;
076: for (int x = 0; x < size; x++) {
077: node = (GenericPropertyNode) _props.get(x);
078:
079: // put the starting offset of the property into the plcf.
080: LittleEndian.putInt(buf, (LittleEndian.INT_SIZE * x), node
081: .getStart());
082:
083: // put the struct into the plcf
084: System.arraycopy(node.getBytes(), 0, buf, cpBufSize
085: + (x * _sizeOfStruct), _sizeOfStruct);
086: }
087: // put the ending offset of the last property into the plcf.
088: LittleEndian.putInt(buf, LittleEndian.INT_SIZE * size, node
089: .getEnd());
090:
091: return buf;
092:
093: }
094:
095: private GenericPropertyNode getProperty(int index, byte[] buf,
096: int offset) {
097: int start = LittleEndian.getInt(buf, offset
098: + getIntOffset(index));
099: int end = LittleEndian.getInt(buf, offset
100: + getIntOffset(index + 1));
101:
102: byte[] struct = new byte[_sizeOfStruct];
103: System.arraycopy(buf, offset + getStructOffset(index), struct,
104: 0, _sizeOfStruct);
105:
106: return new GenericPropertyNode(start, end, struct);
107: }
108:
109: private int getIntOffset(int index) {
110: return index * 4;
111: }
112:
113: /**
114: * returns the number of data structures in this PlexOfCps.
115: *
116: * @return The number of data structures in this PlexOfCps
117: */
118: public int length() {
119: return _count;
120: }
121:
122: /**
123: * Returns the offset, in bytes, from the beginning if this PlexOfCps to
124: * the data structure at index.
125: *
126: * @param index The index of the data structure.
127: *
128: * @return The offset, in bytes, from the beginning if this PlexOfCps to
129: * the data structure at index.
130: */
131: private int getStructOffset(int index) {
132: return (4 * (_count + 1)) + (_sizeOfStruct * index);
133: }
134: }
|