1 19 20 package jxl.write.biff; 21 22 import java.io.OutputStream ; 23 import java.io.IOException ; 24 import java.util.ArrayList ; 25 import java.util.Iterator ; 26 import java.util.HashMap ; 27 28 import common.Assert; 29 import common.Logger; 30 import jxl.biff.BaseCompoundFile; 31 import jxl.biff.IntegerHelper; 32 import jxl.read.biff.BiffException; 33 34 46 final class CompoundFile extends BaseCompoundFile 47 { 48 51 private static Logger logger = Logger.getLogger(CompoundFile.class); 52 53 56 private OutputStream out; 57 60 private byte[] excelData; 61 62 65 private int size; 66 67 71 private int requiredSize; 72 73 76 private int numBigBlockDepotBlocks; 77 78 81 private int numSmallBlockDepotChainBlocks; 82 83 86 private int numSmallBlockDepotBlocks; 87 88 92 private int numExtensionBlocks; 93 94 97 private int extensionBlock; 98 99 102 private int excelDataBlocks; 103 104 107 private int rootStartBlock; 108 109 112 private int excelDataStartBlock; 113 114 117 private int bbdStartBlock; 118 119 122 private int sbdStartBlockChain; 123 124 127 private int sbdStartBlock; 128 129 132 private int additionalPropertyBlocks; 133 134 137 private int numSmallBlocks; 138 139 142 private int numPropertySets; 143 144 148 private int numRootEntryBlocks; 149 150 153 private ArrayList additionalPropertySets; 154 155 158 private HashMap readPropertySets; 159 160 163 private int[] standardPropertySetMappings; 164 165 private ReadPropertyStorage rootEntryPropertySet; 166 167 170 private static final class ReadPropertyStorage 171 { 172 PropertyStorage propertyStorage; 173 byte[] data; 174 int number; 175 176 ReadPropertyStorage(PropertyStorage ps, byte[] d, int n) 177 { 178 propertyStorage = ps; 179 data = d; 180 number = n; 181 } 182 } 183 184 185 191 private int bbdPos; 192 193 196 private byte[] bigBlockDepot; 197 198 199 207 public CompoundFile(byte[] data, int l, OutputStream os, 208 jxl.read.biff.CompoundFile rcf) 209 throws CopyAdditionalPropertySetsException, IOException 210 { 211 super(); 212 size = l; 213 excelData = data; 214 215 readAdditionalPropertySets(rcf); 216 217 numRootEntryBlocks = 1; 218 numPropertySets = 4 + 219 (additionalPropertySets != null ? additionalPropertySets.size() : 0); 220 221 222 if (additionalPropertySets != null) 223 { 224 numSmallBlockDepotChainBlocks = getBigBlocksRequired(numSmallBlocks * 4); 225 numSmallBlockDepotBlocks = getBigBlocksRequired 226 (numSmallBlocks * SMALL_BLOCK_SIZE); 227 228 numRootEntryBlocks += getBigBlocksRequired 229 (additionalPropertySets.size() * PROPERTY_STORAGE_BLOCK_SIZE); 230 } 231 232 233 int blocks = getBigBlocksRequired(l); 234 235 if (l < SMALL_BLOCK_THRESHOLD) 238 { 239 requiredSize = SMALL_BLOCK_THRESHOLD; 240 } 241 else 242 { 243 requiredSize = blocks * BIG_BLOCK_SIZE; 244 } 245 246 out = os; 247 248 249 excelDataBlocks = requiredSize/BIG_BLOCK_SIZE; 251 numBigBlockDepotBlocks = 1; 252 253 int blockChainLength = (BIG_BLOCK_SIZE - BIG_BLOCK_DEPOT_BLOCKS_POS)/4; 254 255 int startTotalBlocks = excelDataBlocks + 256 8 + 8 + additionalPropertyBlocks + 259 numSmallBlockDepotBlocks + 260 numSmallBlockDepotChainBlocks + 261 numRootEntryBlocks; 262 263 int totalBlocks = startTotalBlocks + numBigBlockDepotBlocks; 264 265 numBigBlockDepotBlocks = (int) Math.ceil( (double) totalBlocks / 267 (double) (BIG_BLOCK_SIZE/4)); 268 269 totalBlocks = startTotalBlocks + numBigBlockDepotBlocks; 271 272 numBigBlockDepotBlocks = (int) Math.ceil( (double) totalBlocks / 274 (double) (BIG_BLOCK_SIZE/4)); 275 276 totalBlocks = startTotalBlocks + numBigBlockDepotBlocks; 278 279 if (numBigBlockDepotBlocks > blockChainLength - 1 ) 282 { 283 extensionBlock = 0; 286 287 int bbdBlocksLeft = numBigBlockDepotBlocks - blockChainLength + 1; 289 290 numExtensionBlocks = (int) Math.ceil((double) bbdBlocksLeft / 291 (double) (BIG_BLOCK_SIZE/4 - 1)); 292 293 totalBlocks = startTotalBlocks + 296 numExtensionBlocks + 297 numBigBlockDepotBlocks; 298 numBigBlockDepotBlocks = (int) Math.ceil( (double) totalBlocks / 299 (double) (BIG_BLOCK_SIZE/4)); 300 301 totalBlocks = startTotalBlocks + 303 numExtensionBlocks + 304 numBigBlockDepotBlocks; 305 } 306 else 307 { 308 extensionBlock = -2; 309 numExtensionBlocks = 0; 310 } 311 312 excelDataStartBlock = numExtensionBlocks; 315 316 sbdStartBlock = -2; 318 if (additionalPropertySets != null) 319 { 320 sbdStartBlock = excelDataStartBlock + 321 excelDataBlocks + 322 additionalPropertyBlocks + 323 16; 324 } 325 326 sbdStartBlockChain = -2; 329 330 if (sbdStartBlock != -2) 331 { 332 sbdStartBlockChain = sbdStartBlock + numSmallBlockDepotBlocks; 333 } 334 335 if (sbdStartBlockChain != -2) 337 { 338 bbdStartBlock = sbdStartBlockChain + 339 numSmallBlockDepotChainBlocks; 340 } 341 else 342 { 343 bbdStartBlock = excelDataStartBlock + 344 excelDataBlocks + 345 additionalPropertyBlocks + 346 16; 347 } 348 349 rootStartBlock = bbdStartBlock + 351 numBigBlockDepotBlocks; 352 353 354 if (totalBlocks != rootStartBlock + numRootEntryBlocks) 355 { 356 logger.warn("Root start block and total blocks are inconsistent " + 357 " generated file may be corrupt"); 358 logger.warn("RootStartBlock " + rootStartBlock + " totalBlocks " + totalBlocks); 359 } 360 } 361 362 367 private void readAdditionalPropertySets 368 (jxl.read.biff.CompoundFile readCompoundFile) 369 throws CopyAdditionalPropertySetsException, IOException 370 { 371 if (readCompoundFile == null) 372 { 373 return; 374 } 375 376 additionalPropertySets = new ArrayList (); 377 readPropertySets = new HashMap (); 378 379 String [] psnames = readCompoundFile.getPropertySetNames(); 380 int blocksRequired = 0; 381 standardPropertySetMappings = new int[STANDARD_PROPERTY_SETS.length]; 382 383 for (int i = 0 ; i < psnames.length ; i++) 384 { 385 PropertyStorage ps = readCompoundFile.getPropertySet(psnames[i]); 387 388 boolean standard = false; 391 for (int j = 0 ; j < STANDARD_PROPERTY_SETS.length && !standard ; j++) 392 { 393 if (psnames[i].equalsIgnoreCase(STANDARD_PROPERTY_SETS[j])) 394 { 395 standard = true; 396 ReadPropertyStorage rps = new ReadPropertyStorage(ps, null, i); 397 readPropertySets.put(psnames[i], rps); 398 } 399 } 400 401 if (!standard) 402 { 403 try 404 { 405 byte[] data = null; 406 if (ps.size > 0 ) 407 { 408 data = readCompoundFile.getStream(ps.name); 409 } 410 else 411 { 412 data = new byte[0]; 413 } 414 ReadPropertyStorage rps = new ReadPropertyStorage(ps, data, i); 415 readPropertySets.put(psnames[i], rps); 416 additionalPropertySets.add(rps); 417 418 if (data.length > SMALL_BLOCK_THRESHOLD) 419 { 420 int blocks = getBigBlocksRequired(data.length); 421 blocksRequired += blocks; 422 } 423 else 424 { 425 int blocks = getSmallBlocksRequired(data.length); 426 numSmallBlocks += blocks; 427 } 428 } 429 catch (BiffException e) 430 { 431 logger.error(e); 432 throw new CopyAdditionalPropertySetsException(); 433 } 434 } 435 } 436 437 additionalPropertyBlocks = blocksRequired; 438 } 439 440 441 446 public void write() throws IOException 447 { 448 writeHeader(); 449 writeExcelData(); 450 writeDocumentSummaryData(); 451 writeSummaryData(); 452 writeAdditionalPropertySets(); 453 writeSmallBlockDepot(); 454 writeSmallBlockDepotChain(); 455 writeBigBlockDepot(); 456 writePropertySets(); 457 458 } 461 462 465 private void writeAdditionalPropertySets() throws IOException 466 { 467 if (additionalPropertySets == null) 468 { 469 return; 470 } 471 472 for (Iterator i = additionalPropertySets.iterator(); i.hasNext() ;) 473 { 474 ReadPropertyStorage rps = (ReadPropertyStorage) i.next(); 475 byte[] data = rps.data; 476 477 if (data.length > SMALL_BLOCK_THRESHOLD) 478 { 479 int numBlocks = getBigBlocksRequired(data.length); 480 int requiredSize = numBlocks * BIG_BLOCK_SIZE; 481 482 out.write(data, 0, data.length); 483 484 byte[] padding = new byte[requiredSize - data.length]; 485 out.write(padding, 0, padding.length); 486 } 487 } 488 489 498 } 499 500 507 private void writeExcelData() throws IOException 508 { 509 out.write(excelData, 0, size); 510 511 byte[] padding = new byte[requiredSize - size]; 512 out.write(padding); 513 } 514 515 520 private void writeDocumentSummaryData() throws IOException 521 { 522 byte[] padding = new byte[SMALL_BLOCK_THRESHOLD]; 523 524 out.write(padding); 526 } 527 528 533 private void writeSummaryData() throws IOException 534 { 535 byte[] padding = new byte[SMALL_BLOCK_THRESHOLD]; 536 537 out.write(padding); 539 } 540 541 546 private void writeHeader() throws IOException 547 { 548 byte[] headerBlock = new byte[BIG_BLOCK_SIZE]; 550 byte[] extensionBlockData = new byte[BIG_BLOCK_SIZE * numExtensionBlocks]; 551 552 System.arraycopy(IDENTIFIER, 0, headerBlock, 0, IDENTIFIER.length); 554 555 headerBlock[0x18] = 0x3e; 557 headerBlock[0x1a] = 0x3; 558 headerBlock[0x1c] = (byte) 0xfe; 559 headerBlock[0x1d] = (byte) 0xff; 560 headerBlock[0x1e] = 0x9; 561 headerBlock[0x20] = 0x6; 562 headerBlock[0x39] = 0x10; 563 564 IntegerHelper.getFourBytes(numBigBlockDepotBlocks, 566 headerBlock, 567 NUM_BIG_BLOCK_DEPOT_BLOCKS_POS); 568 569 IntegerHelper.getFourBytes(sbdStartBlockChain, 571 headerBlock, 572 SMALL_BLOCK_DEPOT_BLOCK_POS); 573 574 IntegerHelper.getFourBytes(numSmallBlockDepotChainBlocks, 576 headerBlock, 577 NUM_SMALL_BLOCK_DEPOT_BLOCKS_POS); 578 579 IntegerHelper.getFourBytes(extensionBlock, 581 headerBlock, 582 EXTENSION_BLOCK_POS); 583 584 IntegerHelper.getFourBytes(numExtensionBlocks, 586 headerBlock, 587 NUM_EXTENSION_BLOCK_POS); 588 589 IntegerHelper.getFourBytes(rootStartBlock, 591 headerBlock, 592 ROOT_START_BLOCK_POS); 593 594 int pos = BIG_BLOCK_DEPOT_BLOCKS_POS; 597 598 int blocksToWrite = Math.min(numBigBlockDepotBlocks, 600 (BIG_BLOCK_SIZE - 601 BIG_BLOCK_DEPOT_BLOCKS_POS)/4); 602 int extensionBlock = 0; 603 int blocksWritten = 0; 604 605 for (int i = 0 ; i < blocksToWrite; i++) 606 { 607 IntegerHelper.getFourBytes(bbdStartBlock + i, 608 headerBlock, 609 pos); 610 pos += 4; 611 blocksWritten++; 612 } 613 614 for (int i = pos; i < BIG_BLOCK_SIZE; i++) 616 { 617 headerBlock[i] = (byte) 0xff; 618 } 619 620 out.write(headerBlock); 621 622 pos = 0; 624 625 for (int extBlock = 0; extBlock < numExtensionBlocks; extBlock++) 626 { 627 blocksToWrite = Math.min(numBigBlockDepotBlocks - blocksWritten, 628 BIG_BLOCK_SIZE/4 -1); 629 630 for(int j = 0 ; j < blocksToWrite; j++) 631 { 632 IntegerHelper.getFourBytes(bbdStartBlock + blocksWritten + j, 633 extensionBlockData, 634 pos); 635 pos += 4; 636 } 637 638 blocksWritten += blocksToWrite; 639 640 int nextBlock = (blocksWritten == numBigBlockDepotBlocks) ? 642 -2 : extBlock+1 ; 643 IntegerHelper.getFourBytes(nextBlock, extensionBlockData, pos); 644 pos +=4; 645 } 646 647 if (numExtensionBlocks > 0) 648 { 649 for (int i = pos; i < extensionBlockData.length; i++) 651 { 652 extensionBlockData[i] = (byte) 0xff; 653 } 654 655 out.write(extensionBlockData); 656 } 657 } 658 659 665 private void checkBbdPos() throws IOException 666 { 667 if (bbdPos >= BIG_BLOCK_SIZE) 668 { 669 out.write(bigBlockDepot); 671 672 bigBlockDepot = new byte[BIG_BLOCK_SIZE]; 674 bbdPos = 0; 675 } 676 } 677 678 685 private void writeBlockChain(int startBlock, int numBlocks) 686 throws IOException 687 { 688 int blocksToWrite = numBlocks - 1; 689 int blockNumber = startBlock + 1; 690 691 while (blocksToWrite > 0) 692 { 693 int bbdBlocks = Math.min(blocksToWrite, (BIG_BLOCK_SIZE - bbdPos)/4); 694 695 for (int i = 0 ; i < bbdBlocks; i++) 696 { 697 IntegerHelper.getFourBytes(blockNumber, bigBlockDepot, bbdPos); 698 bbdPos +=4 ; 699 blockNumber++; 700 } 701 702 blocksToWrite -= bbdBlocks; 703 checkBbdPos(); 704 } 705 706 IntegerHelper.getFourBytes(-2, bigBlockDepot, bbdPos); 708 bbdPos += 4; 709 checkBbdPos(); 710 } 711 712 717 private void writeAdditionalPropertySetBlockChains() throws IOException 718 { 719 if (additionalPropertySets == null) 720 { 721 return; 722 } 723 724 int blockNumber = excelDataStartBlock + excelDataBlocks + 16; 725 for (Iterator i = additionalPropertySets.iterator(); i.hasNext() ; ) 726 { 727 ReadPropertyStorage rps = (ReadPropertyStorage) i.next(); 728 if (rps.data.length > SMALL_BLOCK_THRESHOLD) 729 { 730 String psname = rps.propertyStorage.name; 731 int numBlocks = getBigBlocksRequired(rps.data.length); 732 733 writeBlockChain(blockNumber, numBlocks); 734 blockNumber += numBlocks; 735 } 736 } 737 } 738 739 742 private void writeSmallBlockDepotChain() throws IOException 743 { 744 if (sbdStartBlockChain == -2) 745 { 746 return; 747 } 748 749 byte[] smallBlockDepotChain = 750 new byte[numSmallBlockDepotChainBlocks * BIG_BLOCK_SIZE]; 751 752 int pos = 0; 753 int sbdBlockNumber = 1; 754 755 for (Iterator i = additionalPropertySets.iterator(); i.hasNext() ; ) 756 { 757 ReadPropertyStorage rps = (ReadPropertyStorage) i.next(); 758 759 if (rps.data.length <= SMALL_BLOCK_THRESHOLD && 760 rps.data.length != 0) 761 { 762 int numSmallBlocks = getSmallBlocksRequired(rps.data.length); 763 for (int j = 0 ; j < numSmallBlocks - 1 ; j++) 764 { 765 IntegerHelper.getFourBytes(sbdBlockNumber, 766 smallBlockDepotChain, 767 pos); 768 pos += 4; 769 sbdBlockNumber++; 770 } 771 772 IntegerHelper.getFourBytes(-2, smallBlockDepotChain, pos); 774 pos += 4; 775 sbdBlockNumber++; 776 } 777 } 778 779 out.write(smallBlockDepotChain); 780 } 781 782 787 private void writeSmallBlockDepot() throws IOException 788 { 789 if (additionalPropertySets == null) 790 { 791 return; 792 } 793 794 byte[] smallBlockDepot = 795 new byte[numSmallBlockDepotBlocks * BIG_BLOCK_SIZE]; 796 797 int pos = 0; 798 799 805 806 for (Iterator i = additionalPropertySets.iterator() ; i.hasNext() ; ) 807 { 808 ReadPropertyStorage rps = (ReadPropertyStorage) i.next(); 809 810 if (rps.data.length <= SMALL_BLOCK_THRESHOLD) 811 { 812 int smallBlocks = getSmallBlocksRequired(rps.data.length); 813 int length = smallBlocks * SMALL_BLOCK_SIZE; 814 System.arraycopy(rps.data, 0, smallBlockDepot, pos, rps.data.length); 815 pos += length; 816 } 817 } 818 819 out.write(smallBlockDepot); 820 } 821 822 827 private void writeBigBlockDepot() throws IOException 828 { 829 bigBlockDepot = new byte[BIG_BLOCK_SIZE]; 832 bbdPos = 0; 833 834 for (int i = 0 ; i < numExtensionBlocks; i++) 836 { 837 IntegerHelper.getFourBytes(-3, bigBlockDepot, bbdPos); 838 bbdPos += 4; 839 checkBbdPos(); 840 } 841 842 writeBlockChain(excelDataStartBlock, excelDataBlocks); 843 844 846 int summaryInfoBlock = excelDataStartBlock + 848 excelDataBlocks + 849 additionalPropertyBlocks; 850 851 for (int i = summaryInfoBlock; i < summaryInfoBlock + 7; i++) 852 { 853 IntegerHelper.getFourBytes(i + 1, bigBlockDepot, bbdPos); 854 bbdPos +=4 ; 855 checkBbdPos(); 856 } 857 858 IntegerHelper.getFourBytes(-2, bigBlockDepot, bbdPos); 860 bbdPos += 4; 861 checkBbdPos(); 862 863 for (int i = summaryInfoBlock + 8; i < summaryInfoBlock + 15; i++) 865 { 866 IntegerHelper.getFourBytes(i + 1, bigBlockDepot, bbdPos); 867 bbdPos +=4 ; 868 checkBbdPos(); 869 } 870 871 IntegerHelper.getFourBytes(-2, bigBlockDepot, bbdPos); 873 bbdPos += 4; 874 checkBbdPos(); 875 876 writeAdditionalPropertySetBlockChains(); 878 879 if (sbdStartBlock != -2) 880 { 881 writeBlockChain(sbdStartBlock, numSmallBlockDepotBlocks); 883 884 writeBlockChain(sbdStartBlockChain, numSmallBlockDepotChainBlocks); 886 } 887 888 for (int i = 0; i < numBigBlockDepotBlocks; i++) 891 { 892 IntegerHelper.getFourBytes(-3, bigBlockDepot, bbdPos); 893 bbdPos += 4; 894 checkBbdPos(); 895 } 896 897 writeBlockChain(rootStartBlock, numRootEntryBlocks); 899 900 if (bbdPos != 0) 902 { 903 for (int i = bbdPos; i < BIG_BLOCK_SIZE; i++) 904 { 905 bigBlockDepot[i] = (byte) 0xff; 906 } 907 out.write(bigBlockDepot); 908 } 909 } 910 911 918 private int getBigBlocksRequired(int length) 919 { 920 int blocks = length / BIG_BLOCK_SIZE; 921 922 return (length % BIG_BLOCK_SIZE > 0 )? blocks + 1 : blocks; 923 } 924 925 932 private int getSmallBlocksRequired(int length) 933 { 934 int blocks = length / SMALL_BLOCK_SIZE; 935 936 return (length % SMALL_BLOCK_SIZE > 0 )? blocks + 1 : blocks; 937 } 938 939 944 private void writePropertySets() throws IOException 945 { 946 byte[] propertySetStorage = new byte[BIG_BLOCK_SIZE * numRootEntryBlocks]; 947 948 int pos = 0; 949 int[] mappings = null; 950 951 if (additionalPropertySets != null) 953 { 954 mappings = new int[numPropertySets]; 955 956 for (int i = 0 ; i < STANDARD_PROPERTY_SETS.length ; i++) 958 { 959 ReadPropertyStorage rps = (ReadPropertyStorage) 960 readPropertySets.get(STANDARD_PROPERTY_SETS[i]); 961 mappings[rps.number] = i; 962 } 963 964 int newMapping = STANDARD_PROPERTY_SETS.length; 966 for (Iterator i = additionalPropertySets.iterator(); i.hasNext(); ) 967 { 968 ReadPropertyStorage rps = (ReadPropertyStorage) i.next(); 969 mappings[rps.number] = newMapping; 970 newMapping++; 971 } 972 } 973 974 int child = 0; 975 int previous = 0; 976 int next = 0; 977 978 int size = 0; 980 981 if (additionalPropertySets != null) 982 { 983 size += getBigBlocksRequired(requiredSize) * BIG_BLOCK_SIZE; 985 986 size += getBigBlocksRequired(SMALL_BLOCK_THRESHOLD) * BIG_BLOCK_SIZE; 988 size += getBigBlocksRequired(SMALL_BLOCK_THRESHOLD) * BIG_BLOCK_SIZE; 989 990 for (Iterator i = additionalPropertySets.iterator(); i.hasNext(); ) 992 { 993 ReadPropertyStorage rps = (ReadPropertyStorage) i.next(); 994 if (rps.propertyStorage.type != 1) 995 { 996 if (rps.propertyStorage.size >= SMALL_BLOCK_THRESHOLD) 997 { 998 size += getBigBlocksRequired(rps.propertyStorage.size) * 999 BIG_BLOCK_SIZE; 1000 } 1001 else 1002 { 1003 size += getSmallBlocksRequired(rps.propertyStorage.size) * 1004 SMALL_BLOCK_SIZE; 1005 } 1006 } 1007 } 1008 } 1009 1010 PropertyStorage ps = new PropertyStorage(ROOT_ENTRY_NAME); 1012 ps.setType(5); 1013 ps.setStartBlock(sbdStartBlock); 1014 ps.setSize(size); 1015 ps.setPrevious(-1); 1016 ps.setNext(-1); 1017 ps.setColour(0); 1018 1019 child = 1; 1020 if (additionalPropertySets != null) 1021 { 1022 ReadPropertyStorage rps = (ReadPropertyStorage) 1023 readPropertySets.get(ROOT_ENTRY_NAME); 1024 child = mappings[rps.propertyStorage.child]; 1025 } 1026 ps.setChild(child); 1027 1028 System.arraycopy(ps.data, 0, 1029 propertySetStorage, pos, 1030 PROPERTY_STORAGE_BLOCK_SIZE); 1031 pos += PROPERTY_STORAGE_BLOCK_SIZE; 1032 1033 1034 ps = new PropertyStorage(WORKBOOK_NAME); 1036 ps.setType(2); 1037 ps.setStartBlock(excelDataStartBlock); 1038 ps.setSize(requiredSize); 1040 1043 previous = 3; 1044 next = -1; 1045 1046 if (additionalPropertySets != null) 1047 { 1048 ReadPropertyStorage rps = (ReadPropertyStorage) 1049 readPropertySets.get(WORKBOOK_NAME); 1050 previous = rps.propertyStorage.previous != -1 ? 1051 mappings[rps.propertyStorage.previous] : -1; 1052 next = rps.propertyStorage.next != -1 ? 1053 mappings[rps.propertyStorage.next] : -1 ; 1054 } 1055 1056 ps.setPrevious(previous); 1057 ps.setNext(next); 1058 ps.setChild(-1); 1059 1060 System.arraycopy(ps.data, 0, 1061 propertySetStorage, pos, 1062 PROPERTY_STORAGE_BLOCK_SIZE); 1063 pos += PROPERTY_STORAGE_BLOCK_SIZE; 1064 1065 ps = new PropertyStorage(SUMMARY_INFORMATION_NAME); 1067 ps.setType(2); 1068 ps.setStartBlock(excelDataStartBlock + excelDataBlocks); 1069 ps.setSize(SMALL_BLOCK_THRESHOLD); 1070 1071 previous = 1; 1072 next = 3; 1073 1074 if (additionalPropertySets != null) 1075 { 1076 ReadPropertyStorage rps = (ReadPropertyStorage) 1077 readPropertySets.get(SUMMARY_INFORMATION_NAME); 1078 1079 previous = rps.propertyStorage.previous != - 1 ? 1080 mappings[rps.propertyStorage.previous] : -1 ; 1081 next = rps.propertyStorage.next != - 1 ? 1082 mappings[rps.propertyStorage.next] : -1 ; 1083 } 1084 1085 ps.setPrevious(previous); 1086 ps.setNext(next); 1087 ps.setChild(-1); 1088 1089 System.arraycopy(ps.data, 0, 1090 propertySetStorage, pos, 1091 PROPERTY_STORAGE_BLOCK_SIZE); 1092 pos += PROPERTY_STORAGE_BLOCK_SIZE; 1093 1094 ps = new PropertyStorage(DOCUMENT_SUMMARY_INFORMATION_NAME); 1096 ps.setType(2); 1097 ps.setStartBlock(excelDataStartBlock + excelDataBlocks + 8); 1098 ps.setSize(SMALL_BLOCK_THRESHOLD); 1099 ps.setPrevious(-1); 1100 ps.setNext(-1); 1101 ps.setChild(-1); 1102 1103 System.arraycopy(ps.data, 0, 1104 propertySetStorage, pos, 1105 PROPERTY_STORAGE_BLOCK_SIZE); 1106 pos += PROPERTY_STORAGE_BLOCK_SIZE; 1107 1108 1109 1110 if (additionalPropertySets == null) 1112 { 1113 out.write(propertySetStorage); 1114 return; 1115 } 1116 1117 int bigBlock = excelDataStartBlock + excelDataBlocks + 16; 1118 int smallBlock = 0; 1119 int sz = 0; 1120 1121 for (Iterator i = additionalPropertySets.iterator() ; i.hasNext(); ) 1122 { 1123 ReadPropertyStorage rps = (ReadPropertyStorage) i.next(); 1124 1125 int block = rps.data.length > SMALL_BLOCK_THRESHOLD ? 1126 bigBlock : smallBlock; 1127 1128 ps = new PropertyStorage(rps.propertyStorage.name); 1129 ps.setType(rps.propertyStorage.type); 1130 ps.setStartBlock(block); 1131 ps.setSize(rps.propertyStorage.size); 1132 1134 previous = rps.propertyStorage.previous != -1 ? 1135 mappings[rps.propertyStorage.previous] : -1; 1136 next = rps.propertyStorage.next != -1 ? 1137 mappings[rps.propertyStorage.next] : -1; 1138 child = rps.propertyStorage.child != -1 ? 1139 mappings[rps.propertyStorage.child] : -1; 1140 1141 ps.setPrevious(previous); 1142 ps.setNext(next); 1143 ps.setChild(child); 1144 1145 System.arraycopy(ps.data, 0, 1146 propertySetStorage, pos, 1147 PROPERTY_STORAGE_BLOCK_SIZE); 1148 pos += PROPERTY_STORAGE_BLOCK_SIZE; 1149 1150 if (rps.data.length > SMALL_BLOCK_THRESHOLD) 1151 { 1152 bigBlock += getBigBlocksRequired(rps.data.length); 1153 } 1154 else 1155 { 1156 smallBlock += getSmallBlocksRequired(rps.data.length); 1157 } 1158 } 1159 1160 out.write(propertySetStorage); 1161 } 1162} 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 | Popular Tags |