1 2 17 18 package org.apache.poi.hpsf; 19 20 import java.io.UnsupportedEncodingException ; 21 import java.util.HashMap ; 22 import java.util.Map ; 23 24 import org.apache.poi.util.HexDump; 25 import org.apache.poi.util.LittleEndian; 26 27 56 public class Property 57 { 58 59 60 protected long id; 61 62 63 68 public long getID() 69 { 70 return id; 71 } 72 73 74 75 76 protected long type; 77 78 79 84 public long getType() 85 { 86 return type; 87 } 88 89 90 91 92 protected Object value; 93 94 95 100 public Object getValue() 101 { 102 return value; 103 } 104 105 106 107 121 public Property(final long id, final byte[] src, final long offset, 122 final int length, final int codepage) 123 throws UnsupportedEncodingException 124 { 125 this.id = id; 126 127 131 if (id == 0) 132 { 133 value = readDictionary(src, offset, length, codepage); 134 return; 135 } 136 137 int o = (int) offset; 138 type = LittleEndian.getUInt(src, o); 139 o += LittleEndian.INT_SIZE; 140 141 try 142 { 143 value = VariantSupport.read(src, o, length, (int) type, codepage); 144 } 145 catch (UnsupportedVariantTypeException ex) 146 { 147 VariantSupport.writeUnsupportedTypeMessage(ex); 148 value = ex.getValue(); 149 } 150 } 151 152 153 154 158 protected Property() 159 { } 160 161 162 163 174 protected Map readDictionary(final byte[] src, final long offset, 175 final int length, final int codepage) 176 { 177 178 if (offset < 0 || offset > src.length) 179 throw new HPSFRuntimeException 180 ("Illegal offset " + offset + " while HPSF stream contains " + 181 length + " bytes."); 182 int o = (int) offset; 183 184 187 final long nrEntries = LittleEndian.getUInt(src, o); 188 o += LittleEndian.INT_SIZE; 189 190 final Map m = new HashMap ((int) nrEntries, (float) 1.0); 191 for (int i = 0; i < nrEntries; i++) 192 { 193 194 final Long id = new Long (LittleEndian.getUInt(src, o)); 195 o += LittleEndian.INT_SIZE; 196 197 202 long sLength = LittleEndian.getUInt(src, o); 203 o += LittleEndian.INT_SIZE; 204 205 207 StringBuffer b = new StringBuffer ((int) sLength); 208 for (int j = 0; j < sLength; j++) 209 if (codepage == Constants.CP_UNICODE) 210 { 211 final int i1 = o + (j * 2); 212 final int i2 = i1 + 1; 213 b.append((char) ((src[i2] << 8) + src[i1])); 214 } 215 else 216 b.append((char) src[o + j]); 217 218 219 while (b.length() > 0 && b.charAt(b.length() - 1) == 0x00) 220 b.setLength(b.length() - 1); 221 if (codepage == Constants.CP_UNICODE) 222 { 223 if (sLength % 2 == 1) 224 sLength++; 225 o += (sLength + sLength); 226 } 227 else 228 o += sLength; 229 m.put(id, b.toString()); 230 } 231 return m; 232 } 233 234 235 236 245 protected int getSize() throws WritingNotSupportedException 246 { 247 int length = VariantSupport.getVariantLength(type); 248 if (length >= 0) 249 return length; 250 if (length == -2) 251 252 throw new WritingNotSupportedException(type, null); 253 254 255 final int PADDING = 4; 256 switch ((int) type) 257 { 258 case Variant.VT_LPSTR: 259 { 260 int l = ((String ) value).length() + 1; 261 int r = l % PADDING; 262 if (r > 0) 263 l += PADDING - r; 264 length += l; 265 break; 266 } 267 case Variant.VT_EMPTY: 268 break; 269 default: 270 throw new WritingNotSupportedException(type, value); 271 } 272 return length; 273 } 274 275 276 277 286 public boolean equals(final Object o) 287 { 288 if (!(o instanceof Property)) 289 return false; 290 final Property p = (Property) o; 291 final Object pValue = p.getValue(); 292 final long pId = p.getID(); 293 if (id != pId || (id != 0 && !typesAreEqual(type, p.getType()))) 294 return false; 295 if (value == null && pValue == null) 296 return true; 297 if (value == null || pValue == null) 298 return false; 299 300 301 final Class valueClass = value.getClass(); 302 final Class pValueClass = pValue.getClass(); 303 if (!(valueClass.isAssignableFrom(pValueClass)) && 304 !(pValueClass.isAssignableFrom(valueClass))) 305 return false; 306 307 if (value instanceof byte[]) 308 return Util.equal((byte[]) value, (byte[]) pValue); 309 310 return value.equals(pValue); 311 } 312 313 314 315 private boolean typesAreEqual(final long t1, final long t2) 316 { 317 if (t1 == t2 || 318 (t1 == Variant.VT_LPSTR && t2 == Variant.VT_LPWSTR) || 319 (t2 == Variant.VT_LPSTR && t1 == Variant.VT_LPWSTR)) 320 return true; 321 else 322 return false; 323 } 324 325 326 327 330 public int hashCode() 331 { 332 long hashCode = 0; 333 hashCode += id; 334 hashCode += type; 335 if (value != null) 336 hashCode += value.hashCode(); 337 final int returnHashCode = (int) (hashCode & 0x0ffffffffL ); 338 return returnHashCode; 339 340 } 341 342 343 344 347 public String toString() 348 { 349 final StringBuffer b = new StringBuffer (); 350 b.append(getClass().getName()); 351 b.append('['); 352 b.append("id: "); 353 b.append(getID()); 354 b.append(", type: "); 355 b.append(getType()); 356 final Object value = getValue(); 357 b.append(", value: "); 358 b.append(value.toString()); 359 if (value instanceof String ) 360 { 361 final String s = (String ) value; 362 final int l = s.length(); 363 final byte[] bytes = new byte[l * 2]; 364 for (int i = 0; i < l; i++) 365 { 366 final char c = s.charAt(i); 367 final byte high = (byte) ((c & 0x00ff00) >> 8); 368 final byte low = (byte) ((c & 0x0000ff) >> 0); 369 bytes[i * 2] = high; 370 bytes[i * 2 + 1] = low; 371 } 372 final String hex = HexDump.dump(bytes, 0L, 0); 373 b.append(" ["); 374 b.append(hex); 375 b.append("]"); 376 } 377 b.append(']'); 378 return b.toString(); 379 } 380 381 } 382 | Popular Tags |