1 2 17 18 package org.apache.poi.hpsf; 19 20 import java.io.UnsupportedEncodingException ; 21 import java.util.ArrayList ; 22 import java.util.Collections ; 23 import java.util.Iterator ; 24 import java.util.List ; 25 import java.util.Map ; 26 27 import org.apache.poi.hpsf.wellknown.PropertyIDMap; 28 import org.apache.poi.hpsf.wellknown.SectionIDMap; 29 import org.apache.poi.util.LittleEndian; 30 31 40 public class Section 41 { 42 43 47 protected Map dictionary; 48 49 52 protected ClassID formatID; 53 54 55 64 public ClassID getFormatID() 65 { 66 return formatID; 67 } 68 69 70 71 74 protected long offset; 75 76 77 82 public long getOffset() 83 { 84 return offset; 85 } 86 87 88 89 92 protected int size; 93 94 95 100 public int getSize() 101 { 102 return size; 103 } 104 105 106 107 112 public int getPropertyCount() 113 { 114 return properties.length; 115 } 116 117 118 119 122 protected Property[] properties; 123 124 125 130 public Property[] getProperties() 131 { 132 return properties; 133 } 134 135 136 137 140 protected Section() 141 { } 142 143 144 145 155 public Section(final byte[] src, final int offset) 156 throws UnsupportedEncodingException 157 { 158 int o1 = offset; 159 160 163 formatID = new ClassID(src, o1); 164 o1 += ClassID.LENGTH; 165 166 170 this.offset = LittleEndian.getUInt(src, o1); 171 o1 = (int) this.offset; 172 173 176 size = (int) LittleEndian.getUInt(src, o1); 177 o1 += LittleEndian.INT_SIZE; 178 179 182 final int propertyCount = (int) LittleEndian.getUInt(src, o1); 183 o1 += LittleEndian.INT_SIZE; 184 185 209 properties = new Property[propertyCount]; 210 211 212 int pass1Offset = o1; 213 List propertyList = new ArrayList (propertyCount); 214 PropertyListEntry ple; 215 for (int i = 0; i < properties.length; i++) 216 { 217 ple = new PropertyListEntry(); 218 219 220 ple.id = (int) LittleEndian.getUInt(src, pass1Offset); 221 pass1Offset += LittleEndian.INT_SIZE; 222 223 224 ple.offset = (int) LittleEndian.getUInt(src, pass1Offset); 225 pass1Offset += LittleEndian.INT_SIZE; 226 227 228 propertyList.add(ple); 229 } 230 231 232 Collections.sort(propertyList); 233 234 235 for (int i = 0; i < propertyCount - 1; i++) 236 { 237 final PropertyListEntry ple1 = 238 (PropertyListEntry) propertyList.get(i); 239 final PropertyListEntry ple2 = 240 (PropertyListEntry) propertyList.get(i + 1); 241 ple1.length = ple2.offset - ple1.offset; 242 } 243 if (propertyCount > 0) 244 { 245 ple = (PropertyListEntry) propertyList.get(propertyCount - 1); 246 ple.length = size - ple.offset; 247 } 248 249 250 int codepage = -1; 251 for (final Iterator i = propertyList.iterator(); 252 codepage == -1 && i.hasNext();) 253 { 254 ple = (PropertyListEntry) i.next(); 255 256 257 if (ple.id == PropertyIDMap.PID_CODEPAGE) 258 { 259 261 int o = (int) (this.offset + ple.offset); 262 final long type = LittleEndian.getUInt(src, o); 263 o += LittleEndian.INT_SIZE; 264 265 if (type != Variant.VT_I2) 266 throw new HPSFRuntimeException 267 ("Value type of property ID 1 is not VT_I2 but " + 268 type + "."); 269 270 271 codepage = LittleEndian.getUShort(src, o); 272 } 273 } 274 275 277 int i1 = 0; 278 for (final Iterator i = propertyList.iterator(); i.hasNext();) 279 { 280 ple = (PropertyListEntry) i.next(); 281 properties[i1++] = new Property(ple.id, src, 282 this.offset + ple.offset, 283 ple.length, codepage); 284 } 285 286 289 dictionary = (Map ) getProperty(0); 290 } 291 292 293 294 298 class PropertyListEntry implements Comparable 299 { 300 int id; 301 int offset; 302 int length; 303 304 311 public int compareTo(final Object o) 312 { 313 if (!(o instanceof PropertyListEntry)) 314 throw new ClassCastException (o.toString()); 315 final int otherOffset = ((PropertyListEntry) o).offset; 316 if (offset < otherOffset) 317 return -1; 318 else if (offset == otherOffset) 319 return 0; 320 else 321 return 1; 322 } 323 } 324 325 326 327 337 public Object getProperty(final long id) 338 { 339 wasNull = false; 340 for (int i = 0; i < properties.length; i++) 341 if (id == properties[i].getID()) 342 return properties[i].getValue(); 343 wasNull = true; 344 return null; 345 } 346 347 348 349 360 protected int getPropertyIntValue(final long id) 361 { 362 final Long i; 363 final Object o = getProperty(id); 364 if (o == null) 365 return 0; 366 if (!(o instanceof Long )) 367 throw new HPSFRuntimeException 368 ("This property is not an integer type, but " + 369 o.getClass().getName() + "."); 370 i = (Long ) o; 371 return i.intValue(); 372 } 373 374 375 376 387 protected boolean getPropertyBooleanValue(final int id) 388 { 389 final Boolean b = (Boolean ) getProperty(id); 390 if (b != null) 391 return b.booleanValue(); 392 else 393 return false; 394 } 395 396 397 398 403 private boolean wasNull; 404 405 406 419 public boolean wasNull() 420 { 421 return wasNull; 422 } 423 424 425 426 436 public String getPIDString(final long pid) 437 { 438 String s = null; 439 if (dictionary != null) 440 s = (String ) dictionary.get(new Long (pid)); 441 if (s == null) 442 s = SectionIDMap.getPIDString(getFormatID().getBytes(), pid); 443 if (s == null) 444 s = SectionIDMap.UNDEFINED; 445 return s; 446 } 447 448 449 450 474 public boolean equals(final Object o) 475 { 476 if (o == null || !(o instanceof Section)) 477 return false; 478 final Section s = (Section) o; 479 if (!s.getFormatID().equals(getFormatID())) 480 return false; 481 482 484 Property[] pa1 = new Property[getProperties().length]; 485 Property[] pa2 = new Property[s.getProperties().length]; 486 System.arraycopy(getProperties(), 0, pa1, 0, pa1.length); 487 System.arraycopy(s.getProperties(), 0, pa2, 0, pa2.length); 488 489 491 Property p10 = null; 492 Property p20 = null; 493 for (int i = 0; i < pa1.length; i++) 494 { 495 final long id = pa1[i].getID(); 496 if (id == 0) 497 { 498 p10 = pa1[i]; 499 pa1 = remove(pa1, i); 500 i--; 501 } 502 if (id == 1) 503 { 504 pa1 = remove(pa1, i); 506 i--; 507 } 508 } 509 for (int i = 0; i < pa2.length; i++) 510 { 511 final long id = pa2[i].getID(); 512 if (id == 0) 513 { 514 p20 = pa2[i]; 515 pa2 = remove(pa2, i); 516 i--; 517 } 518 if (id == 1) 519 { 520 pa2 = remove(pa2, i); 522 i--; 523 } 524 } 525 526 528 if (pa1.length != pa2.length) 529 return false; 530 531 532 boolean dictionaryEqual = true; 533 if (p10 != null && p20 != null) 534 dictionaryEqual = p10.getValue().equals(p20.getValue()); 535 else if (p10 != null || p20 != null) 536 dictionaryEqual = false; 537 if (!dictionaryEqual) 538 return false; 539 else 540 return Util.equals(pa1, pa2); 541 } 542 543 544 545 549 private Property[] remove(final Property[] pa, final int i) 550 { 551 final Property[] h = new Property[pa.length - 1]; 552 if (i > 0) 553 System.arraycopy(pa, 0, h, 0, i); 554 System.arraycopy(pa, i + 1, h, i, h.length - i); 555 return h; 556 } 557 558 559 560 563 public int hashCode() 564 { 565 long hashCode = 0; 566 hashCode += getFormatID().hashCode(); 567 final Property[] pa = getProperties(); 568 for (int i = 0; i < pa.length; i++) 569 hashCode += pa[i].hashCode(); 570 final int returnHashCode = (int) (hashCode & 0x0ffffffffL); 571 return returnHashCode; 572 } 573 574 575 576 579 public String toString() 580 { 581 final StringBuffer b = new StringBuffer (); 582 final Property[] pa = getProperties(); 583 b.append(getClass().getName()); 584 b.append('['); 585 b.append("formatID: "); 586 b.append(getFormatID()); 587 b.append(", offset: "); 588 b.append(getOffset()); 589 b.append(", propertyCount: "); 590 b.append(getPropertyCount()); 591 b.append(", size: "); 592 b.append(getSize()); 593 b.append(", properties: [\n"); 594 for (int i = 0; i < pa.length; i++) 595 { 596 b.append(pa[i].toString()); 597 b.append(",\n"); 598 } 599 b.append(']'); 600 b.append(']'); 601 return b.toString(); 602 } 603 604 605 606 616 public Map getDictionary() 617 { 618 return dictionary; 619 } 620 621 622 623 628 public int getCodepage() 629 { 630 final Integer codepage = 631 (Integer ) getProperty(PropertyIDMap.PID_CODEPAGE); 632 return codepage != null ? codepage.intValue() : -1; 633 } 634 635 } 636 | Popular Tags |