1 2 17 18 package org.apache.poi.hpsf; 19 20 import java.io.IOException ; 21 import java.io.InputStream ; 22 import java.io.UnsupportedEncodingException ; 23 import java.util.ArrayList ; 24 import java.util.List ; 25 26 import org.apache.poi.hpsf.wellknown.SectionIDMap; 27 import org.apache.poi.util.LittleEndian; 28 29 63 public class PropertySet 64 { 65 66 69 static final byte[] BYTE_ORDER_ASSERTION = 70 new byte[] {(byte) 0xFE, (byte) 0xFF}; 71 72 76 protected int byteOrder; 77 78 84 public int getByteOrder() 85 { 86 return byteOrder; 87 } 88 89 90 91 94 static final byte[] FORMAT_ASSERTION = 95 new byte[]{(byte) 0x00, (byte) 0x00}; 96 97 101 protected int format; 102 103 109 public int getFormat() 110 { 111 return format; 112 } 113 114 115 116 121 protected int osVersion; 122 123 124 128 public static final int OS_WIN16 = 0x0000; 129 130 134 public static final int OS_MACINTOSH = 0x0001; 135 136 140 public static final int OS_WIN32 = 0x0002; 141 142 148 public int getOSVersion() 149 { 150 return osVersion; 151 } 152 153 154 155 159 protected ClassID classID; 160 161 167 public ClassID getClassID() 168 { 169 return classID; 170 } 171 172 173 174 180 public int getSectionCount() 181 { 182 return sections.size(); 183 } 184 185 186 187 190 protected List sections; 191 192 193 198 public List getSections() 199 { 200 return sections; 201 } 202 203 204 205 213 protected PropertySet() 214 { } 215 216 217 218 240 public PropertySet(final InputStream stream) 241 throws NoPropertySetStreamException, MarkUnsupportedException, 242 IOException , UnsupportedEncodingException 243 { 244 if (isPropertySetStream(stream)) 245 { 246 final int avail = stream.available(); 247 final byte[] buffer = new byte[avail]; 248 stream.read(buffer, 0, buffer.length); 249 init(buffer, 0, buffer.length); 250 } 251 else 252 throw new NoPropertySetStreamException(); 253 } 254 255 256 257 272 public PropertySet(final byte[] stream, final int offset, final int length) 273 throws NoPropertySetStreamException, UnsupportedEncodingException 274 { 275 if (isPropertySetStream(stream, offset, length)) 276 init(stream, offset, length); 277 else 278 throw new NoPropertySetStreamException(); 279 } 280 281 282 283 295 public PropertySet(final byte[] stream) 296 throws NoPropertySetStreamException, UnsupportedEncodingException 297 { 298 this(stream, 0, stream.length); 299 } 300 301 302 303 318 public static boolean isPropertySetStream(final InputStream stream) 319 throws MarkUnsupportedException, IOException 320 { 321 324 final int BUFFER_SIZE = 50; 325 326 331 if (!stream.markSupported()) 332 throw new MarkUnsupportedException(stream.getClass().getName()); 333 stream.mark(BUFFER_SIZE); 334 335 338 final byte[] buffer = new byte[BUFFER_SIZE]; 339 final int bytes = 340 stream.read(buffer, 0, 341 Math.min(buffer.length, stream.available())); 342 final boolean isPropertySetStream = 343 isPropertySetStream(buffer, 0, bytes); 344 stream.reset(); 345 return isPropertySetStream; 346 } 347 348 349 350 361 public static boolean isPropertySetStream(final byte[] src, 362 final int offset, 363 final int length) 364 { 365 366 367 371 int o = offset; 372 final int byteOrder = LittleEndian.getUShort(src, o); 373 o += LittleEndian.SHORT_SIZE; 374 byte[] temp = new byte[LittleEndian.SHORT_SIZE]; 375 LittleEndian.putShort(temp, (short) byteOrder); 376 if (!Util.equal(temp, BYTE_ORDER_ASSERTION)) 377 return false; 378 final int format = LittleEndian.getUShort(src, o); 379 o += LittleEndian.SHORT_SIZE; 380 temp = new byte[LittleEndian.SHORT_SIZE]; 381 LittleEndian.putShort(temp, (short) format); 382 if (!Util.equal(temp, FORMAT_ASSERTION)) 383 return false; 384 o += LittleEndian.INT_SIZE; 386 o += ClassID.LENGTH; 388 final long sectionCount = LittleEndian.getUInt(src, o); 389 o += LittleEndian.INT_SIZE; 390 if (sectionCount < 1) 391 return false; 392 return true; 393 } 394 395 396 397 408 private void init(final byte[] src, final int offset, final int length) 409 throws UnsupportedEncodingException 410 { 411 412 413 416 int o = offset; 417 byteOrder = LittleEndian.getUShort(src, o); 418 o += LittleEndian.SHORT_SIZE; 419 format = LittleEndian.getUShort(src, o); 420 o += LittleEndian.SHORT_SIZE; 421 osVersion = (int) LittleEndian.getUInt(src, o); 422 o += LittleEndian.INT_SIZE; 423 classID = new ClassID(src, o); 424 o += ClassID.LENGTH; 425 final int sectionCount = LittleEndian.getInt(src, o); 426 o += LittleEndian.INT_SIZE; 427 if (sectionCount <= 0) 428 throw new HPSFRuntimeException("Section count " + sectionCount + 429 " must be greater than 0."); 430 431 438 443 sections = new ArrayList (sectionCount); 444 445 450 for (int i = 0; i < sectionCount; i++) 451 { 452 final Section s = new Section(src, o); 453 o += ClassID.LENGTH + LittleEndian.INT_SIZE; 454 sections.add(s); 455 } 456 } 457 458 459 460 467 public boolean isSummaryInformation() 468 { 469 return Util.equal(((Section) sections.get(0)).getFormatID().getBytes(), 470 SectionIDMap.SUMMARY_INFORMATION_ID); 471 } 472 473 474 475 482 public boolean isDocumentSummaryInformation() 483 { 484 return Util.equal(((Section) sections.get(0)).getFormatID().getBytes(), 485 SectionIDMap.DOCUMENT_SUMMARY_INFORMATION_ID); 486 } 487 488 489 490 504 public Property[] getProperties() 505 throws NoSingleSectionException 506 { 507 return getSingleSection().getProperties(); 508 } 509 510 511 512 523 protected Object getProperty(final int id) throws NoSingleSectionException 524 { 525 return getSingleSection().getProperty(id); 526 } 527 528 529 530 543 protected boolean getPropertyBooleanValue(final int id) 544 throws NoSingleSectionException 545 { 546 return getSingleSection().getPropertyBooleanValue(id); 547 } 548 549 550 551 563 protected int getPropertyIntValue(final int id) 564 throws NoSingleSectionException 565 { 566 return getSingleSection().getPropertyIntValue(id); 567 } 568 569 570 571 586 public boolean wasNull() throws NoSingleSectionException 587 { 588 return getSingleSection().wasNull(); 589 } 590 591 592 593 599 public Section getSingleSection() 600 { 601 final int sectionCount = getSectionCount(); 602 if (sectionCount != 1) 603 throw new NoSingleSectionException 604 ("Property set contains " + sectionCount + " sections."); 605 return ((Section) sections.get(0)); 606 } 607 608 609 610 619 public boolean equals(final Object o) 620 { 621 if (o == null || !(o instanceof PropertySet)) 622 return false; 623 final PropertySet ps = (PropertySet) o; 624 int byteOrder1 = ps.getByteOrder(); 625 int byteOrder2 = getByteOrder(); 626 ClassID classID1 = ps.getClassID(); 627 ClassID classID2 = getClassID(); 628 int format1 = ps.getFormat(); 629 int format2 = getFormat(); 630 int osVersion1 = ps.getOSVersion(); 631 int osVersion2 = getOSVersion(); 632 int sectionCount1 = ps.getSectionCount(); 633 int sectionCount2 = getSectionCount(); 634 if (byteOrder1 != byteOrder2 || 635 !classID1.equals(classID2) || 636 format1 != format2 || 637 osVersion1 != osVersion2 || 638 sectionCount1 != sectionCount2) 639 return false; 640 641 642 return Util.equals(getSections(), ps.getSections()); 643 } 644 645 646 647 650 public int hashCode() 651 { 652 throw new UnsupportedOperationException ("FIXME: Not yet implemented."); 653 } 654 655 656 657 660 public String toString() 661 { 662 final StringBuffer b = new StringBuffer (); 663 final int sectionCount = getSectionCount(); 664 b.append(getClass().getName()); 665 b.append('['); 666 b.append("byteOrder: "); 667 b.append(getByteOrder()); 668 b.append(", classID: "); 669 b.append(getClassID()); 670 b.append(", format: "); 671 b.append(getFormat()); 672 b.append(", OSVersion: "); 673 b.append(getOSVersion()); 674 b.append(", sectionCount: "); 675 b.append(sectionCount); 676 b.append(", sections: [\n"); 677 final List sections = getSections(); 678 for (int i = 0; i < sectionCount; i++) 679 b.append(((Section) sections.get(i)).toString()); 680 b.append(']'); 681 b.append(']'); 682 return b.toString(); 683 } 684 } 685 | Popular Tags |