Fixing content type ordering when content_type is not defined.
[akelos.git] / vendor / Excel / oleread.php
blobac6f56a5946d5798c35a8791e02764365a6a159a
1 <?php
2 define('NUM_BIG_BLOCK_DEPOT_BLOCKS_POS', 0x2c);
3 define('SMALL_BLOCK_DEPOT_BLOCK_POS', 0x3c);
4 define('ROOT_START_BLOCK_POS', 0x30);
5 define('BIG_BLOCK_SIZE', 0x200);
6 define('SMALL_BLOCK_SIZE', 0x40);
7 define('EXTENSION_BLOCK_POS', 0x44);
8 define('NUM_EXTENSION_BLOCK_POS', 0x48);
9 define('PROPERTY_STORAGE_BLOCK_SIZE', 0x80);
10 define('BIG_BLOCK_DEPOT_BLOCKS_POS', 0x4c);
11 define('SMALL_BLOCK_THRESHOLD', 0x1000);
12 // property storage offsets
13 define('SIZE_OF_NAME_POS', 0x40);
14 define('TYPE_POS', 0x42);
15 define('START_BLOCK_POS', 0x74);
16 define('SIZE_POS', 0x78);
17 define('IDENTIFIER_OLE', pack("CCCCCCCC",0xd0,0xcf,0x11,0xe0,0xa1,0xb1,0x1a,0xe1));
19 //echo 'ROOT_START_BLOCK_POS = '.ROOT_START_BLOCK_POS."\n";
21 //echo bin2hex($data[ROOT_START_BLOCK_POS])."\n";
22 //echo "a=";
23 //echo $data[ROOT_START_BLOCK_POS];
24 //function log
26 function GetInt4d($data, $pos) {
27 return ord($data[$pos]) | (ord($data[$pos+1]) << 8) | (ord($data[$pos+2]) << 16) | (ord($data[$pos+3]) << 24);
31 class OLERead {
32 var $data = '';
35 function OLERead(){
40 function read($sFileName){
42 // check if file exist and is readable (Darko Miljanovic)
43 if(!is_readable($sFileName)) {
44 $this->error = 1;
45 return false;
48 $this->data = @file_get_contents($sFileName);
49 if (!$this->data) {
50 $this->error = 1;
51 return false;
53 //echo IDENTIFIER_OLE;
54 //echo 'start';
55 if (substr($this->data, 0, 8) != IDENTIFIER_OLE) {
56 $this->error = 1;
57 return false;
59 $this->numBigBlockDepotBlocks = GetInt4d($this->data, NUM_BIG_BLOCK_DEPOT_BLOCKS_POS);
60 $this->sbdStartBlock = GetInt4d($this->data, SMALL_BLOCK_DEPOT_BLOCK_POS);
61 $this->rootStartBlock = GetInt4d($this->data, ROOT_START_BLOCK_POS);
62 $this->extensionBlock = GetInt4d($this->data, EXTENSION_BLOCK_POS);
63 $this->numExtensionBlocks = GetInt4d($this->data, NUM_EXTENSION_BLOCK_POS);
66 echo $this->numBigBlockDepotBlocks." ";
67 echo $this->sbdStartBlock." ";
68 echo $this->rootStartBlock." ";
69 echo $this->extensionBlock." ";
70 echo $this->numExtensionBlocks." ";
72 //echo "sbdStartBlock = $this->sbdStartBlock\n";
73 $bigBlockDepotBlocks = array();
74 $pos = BIG_BLOCK_DEPOT_BLOCKS_POS;
75 // echo "pos = $pos";
76 $bbdBlocks = $this->numBigBlockDepotBlocks;
78 if ($this->numExtensionBlocks != 0) {
79 $bbdBlocks = (BIG_BLOCK_SIZE - BIG_BLOCK_DEPOT_BLOCKS_POS)/4;
82 for ($i = 0; $i < $bbdBlocks; $i++) {
83 $bigBlockDepotBlocks[$i] = GetInt4d($this->data, $pos);
84 $pos += 4;
88 for ($j = 0; $j < $this->numExtensionBlocks; $j++) {
89 $pos = ($this->extensionBlock + 1) * BIG_BLOCK_SIZE;
90 $blocksToRead = min($this->numBigBlockDepotBlocks - $bbdBlocks, BIG_BLOCK_SIZE / 4 - 1);
92 for ($i = $bbdBlocks; $i < $bbdBlocks + $blocksToRead; $i++) {
93 $bigBlockDepotBlocks[$i] = GetInt4d($this->data, $pos);
94 $pos += 4;
97 $bbdBlocks += $blocksToRead;
98 if ($bbdBlocks < $this->numBigBlockDepotBlocks) {
99 $this->extensionBlock = GetInt4d($this->data, $pos);
103 // var_dump($bigBlockDepotBlocks);
105 // readBigBlockDepot
106 $pos = 0;
107 $index = 0;
108 $this->bigBlockChain = array();
110 for ($i = 0; $i < $this->numBigBlockDepotBlocks; $i++) {
111 $pos = ($bigBlockDepotBlocks[$i] + 1) * BIG_BLOCK_SIZE;
112 //echo "pos = $pos";
113 for ($j = 0 ; $j < BIG_BLOCK_SIZE / 4; $j++) {
114 $this->bigBlockChain[$index] = GetInt4d($this->data, $pos);
115 $pos += 4 ;
116 $index++;
120 //var_dump($this->bigBlockChain);
121 //echo '=====2';
122 // readSmallBlockDepot();
123 $pos = 0;
124 $index = 0;
125 $sbdBlock = $this->sbdStartBlock;
126 $this->smallBlockChain = array();
128 while ($sbdBlock != -2) {
130 $pos = ($sbdBlock + 1) * BIG_BLOCK_SIZE;
132 for ($j = 0; $j < BIG_BLOCK_SIZE / 4; $j++) {
133 $this->smallBlockChain[$index] = GetInt4d($this->data, $pos);
134 $pos += 4;
135 $index++;
138 $sbdBlock = $this->bigBlockChain[$sbdBlock];
142 // readData(rootStartBlock)
143 $block = $this->rootStartBlock;
144 $pos = 0;
145 $this->entry = $this->__readData($block);
148 while ($block != -2) {
149 $pos = ($block + 1) * BIG_BLOCK_SIZE;
150 $this->entry = $this->entry.substr($this->data, $pos, BIG_BLOCK_SIZE);
151 $block = $this->bigBlockChain[$block];
154 //echo '==='.$this->entry."===";
155 $this->__readPropertySets();
159 function __readData($bl) {
160 $block = $bl;
161 $pos = 0;
162 $data = '';
164 while ($block != -2) {
165 $pos = ($block + 1) * BIG_BLOCK_SIZE;
166 $data = $data.substr($this->data, $pos, BIG_BLOCK_SIZE);
167 //echo "pos = $pos data=$data\n";
168 $block = $this->bigBlockChain[$block];
170 return $data;
173 function __readPropertySets(){
174 $offset = 0;
175 //var_dump($this->entry);
176 while ($offset < strlen($this->entry)) {
177 $d = substr($this->entry, $offset, PROPERTY_STORAGE_BLOCK_SIZE);
179 $nameSize = ord($d[SIZE_OF_NAME_POS]) | (ord($d[SIZE_OF_NAME_POS+1]) << 8);
181 $type = ord($d[TYPE_POS]);
182 //$maxBlock = strlen($d) / BIG_BLOCK_SIZE - 1;
184 $startBlock = GetInt4d($d, START_BLOCK_POS);
185 $size = GetInt4d($d, SIZE_POS);
187 $name = '';
188 for ($i = 0; $i < $nameSize ; $i++) {
189 $name .= $d[$i];
192 $name = str_replace("\x00", "", $name);
194 $this->props[] = array (
195 'name' => $name,
196 'type' => $type,
197 'startBlock' => $startBlock,
198 'size' => $size);
200 if (($name == "Workbook") || ($name == "Book")) {
201 $this->wrkbook = count($this->props) - 1;
204 if ($name == "Root Entry") {
205 $this->rootentry = count($this->props) - 1;
208 //echo "name ==$name=\n";
211 $offset += PROPERTY_STORAGE_BLOCK_SIZE;
217 function getWorkBook(){
218 if ($this->props[$this->wrkbook]['size'] < SMALL_BLOCK_THRESHOLD){
219 // getSmallBlockStream(PropertyStorage ps)
221 $rootdata = $this->__readData($this->props[$this->rootentry]['startBlock']);
223 $streamData = '';
224 $block = $this->props[$this->wrkbook]['startBlock'];
225 //$count = 0;
226 $pos = 0;
227 while ($block != -2) {
228 $pos = $block * SMALL_BLOCK_SIZE;
229 $streamData .= substr($rootdata, $pos, SMALL_BLOCK_SIZE);
231 $block = $this->smallBlockChain[$block];
234 return $streamData;
237 }else{
239 $numBlocks = $this->props[$this->wrkbook]['size'] / BIG_BLOCK_SIZE;
240 if ($this->props[$this->wrkbook]['size'] % BIG_BLOCK_SIZE != 0) {
241 $numBlocks++;
244 if ($numBlocks == 0) return '';
246 //echo "numBlocks = $numBlocks\n";
247 //byte[] streamData = new byte[numBlocks * BIG_BLOCK_SIZE];
248 //print_r($this->wrkbook);
249 $streamData = '';
250 $block = $this->props[$this->wrkbook]['startBlock'];
251 //$count = 0;
252 $pos = 0;
253 //echo "block = $block";
254 while ($block != -2) {
255 $pos = ($block + 1) * BIG_BLOCK_SIZE;
256 $streamData .= substr($this->data, $pos, BIG_BLOCK_SIZE);
257 $block = $this->bigBlockChain[$block];
259 //echo 'stream'.$streamData;
260 return $streamData;