KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > poi > ddf > EscherArrayProperty


1
2 /* ====================================================================
3    Copyright 2002-2004 Apache Software Foundation
4
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    You may obtain a copy of the License at
8
9        http://www.apache.org/licenses/LICENSE-2.0
10
11    Unless required by applicable law or agreed to in writing, software
12    distributed under the License is distributed on an "AS IS" BASIS,
13    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14    See the License for the specific language governing permissions and
15    limitations under the License.
16 ==================================================================== */

17         
18 package org.apache.poi.ddf;
19
20 import org.apache.poi.util.LittleEndian;
21 import org.apache.poi.util.HexDump;
22
23 import java.io.ByteArrayOutputStream JavaDoc;
24 import java.io.IOException JavaDoc;
25
26 /**
27  * Escher array properties are the most wierd construction ever invented
28  * with all sorts of special cases. I'm hopeful I've got them all.
29  *
30  * @author Glen Stampoultzis (glens at superlinksoftware.com)
31  */

32 public class EscherArrayProperty
33         extends EscherComplexProperty
34 {
35     private static final int FIXED_SIZE = 3 * 2;
36
37     public EscherArrayProperty( short id, byte[] complexData )
38     {
39         super( id, checkComplexData(complexData) );
40     }
41
42     public EscherArrayProperty( short propertyNumber, boolean isBlipId, byte[] complexData )
43     {
44         super( propertyNumber, isBlipId, checkComplexData(complexData) );
45     }
46
47     private static byte[] checkComplexData( byte[] complexData )
48     {
49         if (complexData == null || complexData.length == 0)
50             complexData = new byte[6];
51
52         return complexData;
53     }
54
55     public int getNumberOfElementsInArray()
56     {
57         return LittleEndian.getUShort( complexData, 0 );
58     }
59
60     public void setNumberOfElementsInArray( int numberOfElements )
61     {
62         int expectedArraySize = numberOfElements * getActualSizeOfElements(getSizeOfElements()) + FIXED_SIZE;
63         if ( expectedArraySize != complexData.length )
64         {
65             byte[] newArray = new byte[expectedArraySize];
66             System.arraycopy( complexData, 0, newArray, 0, complexData.length );
67             complexData = newArray;
68         }
69         LittleEndian.putShort( complexData, 0, (short) numberOfElements );
70     }
71
72     public int getNumberOfElementsInMemory()
73     {
74         return LittleEndian.getUShort( complexData, 2 );
75     }
76
77     public void setNumberOfElementsInMemory( int numberOfElements )
78     {
79         int expectedArraySize = numberOfElements * getActualSizeOfElements(getSizeOfElements()) + FIXED_SIZE;
80         if ( expectedArraySize != complexData.length )
81         {
82             byte[] newArray = new byte[expectedArraySize];
83             System.arraycopy( complexData, 0, newArray, 0, expectedArraySize );
84             complexData = newArray;
85         }
86         LittleEndian.putShort( complexData, 2, (short) numberOfElements );
87     }
88
89     public short getSizeOfElements()
90     {
91         return LittleEndian.getShort( complexData, 4 );
92     }
93
94     public void setSizeOfElements( int sizeOfElements )
95     {
96         LittleEndian.putShort( complexData, 4, (short) sizeOfElements );
97
98         int expectedArraySize = getNumberOfElementsInArray() * getActualSizeOfElements(getSizeOfElements()) + FIXED_SIZE;
99         if ( expectedArraySize != complexData.length )
100         {
101             // Keep just the first 6 bytes. The rest is no good to us anyway.
102
byte[] newArray = new byte[expectedArraySize];
103             System.arraycopy( complexData, 0, newArray, 0, 6 );
104             complexData = newArray;
105         }
106     }
107
108     public byte[] getElement( int index )
109     {
110         int actualSize = getActualSizeOfElements(getSizeOfElements());
111         byte[] result = new byte[actualSize];
112         System.arraycopy(complexData, FIXED_SIZE + index * actualSize, result, 0, result.length );
113         return result;
114     }
115
116     public void setElement( int index, byte[] element )
117     {
118         int actualSize = getActualSizeOfElements(getSizeOfElements());
119         System.arraycopy( element, 0, complexData, FIXED_SIZE + index * actualSize, actualSize);
120     }
121
122     public String JavaDoc toString()
123     {
124         String JavaDoc nl = System.getProperty("line.separator");
125
126         StringBuffer JavaDoc results = new StringBuffer JavaDoc();
127         results.append(" {EscherArrayProperty:" + nl);
128         results.append(" Num Elements: " + getNumberOfElementsInArray() + nl);
129         results.append(" Num Elements In Memory: " + getNumberOfElementsInMemory() + nl);
130         results.append(" Size of elements: " + getSizeOfElements() + nl);
131         for (int i = 0; i < getNumberOfElementsInArray(); i++)
132         {
133             results.append(" Element " + i + ": " + HexDump.toHex(getElement(i)) + nl);
134         }
135         results.append("}" + nl);
136
137         return "propNum: " + getPropertyNumber()
138                 + ", propName: " + EscherProperties.getPropertyName( getPropertyNumber() )
139                 + ", complex: " + isComplex()
140                 + ", blipId: " + isBlipId()
141                 + ", data: " + nl + results.toString();
142     }
143
144     /**
145      * We have this method because the way in which arrays in escher works
146      * is screwed for seemly arbitary reasons. While most properties are
147      * fairly consistent and have a predictable array size, escher arrays
148      * have special cases.
149      *
150      * @param data The data array containing the escher array information
151      * @param offset The offset into the array to start reading from.
152      * @return the number of bytes used by this complex property.
153      */

154     public int setArrayData( byte[] data, int offset )
155     {
156         short numElements = LittleEndian.getShort(data, offset);
157         short numReserved = LittleEndian.getShort(data, offset + 2);
158         short sizeOfElements = LittleEndian.getShort(data, offset + 4);
159
160         int arraySize = getActualSizeOfElements(sizeOfElements) * numElements;
161         if (arraySize == complexData.length)
162             complexData = new byte[arraySize + 6]; // Calculation missing the header for some reason
163
System.arraycopy(data, offset, complexData, 0, complexData.length );
164         return complexData.length;
165     }
166
167     /**
168      * Sometimes the element size is stored as a negative number. We
169      * negate it and shift it to get the real value.
170      */

171     public static int getActualSizeOfElements(short sizeOfElements)
172     {
173         if (sizeOfElements < 0)
174             return (short) ( ( -sizeOfElements ) >> 2 );
175         else
176             return sizeOfElements;
177     }
178
179 }
180
Popular Tags