Commit e581690d5d4e10d97fb876aac21f16c5beccd475
1 parent
574171f0
Exists in
master
and in
112 other branches
Fix VOtable convertion error for floats and longs.
Showing
1 changed file
with
71 additions
and
22 deletions
Show diff stats
php/classes/VOTableMgr.php
... | ... | @@ -13,6 +13,7 @@ class VOTableMgr { |
13 | 13 | private $logVotable; // The log file. |
14 | 14 | private $stream; // The stream in the VOTable |
15 | 15 | private $c; // Current character position on the stream |
16 | + private $is_little_endian; | |
16 | 17 | |
17 | 18 | function __construct() |
18 | 19 | { |
... | ... | @@ -28,6 +29,7 @@ class VOTableMgr { |
28 | 29 | |
29 | 30 | function load($fileName) { |
30 | 31 | $this->addLog("File name" . $fileName); |
32 | + $this->is_little_endian = array_values(unpack('L1L', pack('V', 1)))[0] == 1; | |
31 | 33 | |
32 | 34 | // see http://php.net/manual/en/domdocument.load.php#91384 |
33 | 35 | $opts = array( |
... | ... | @@ -212,9 +214,14 @@ class VOTableMgr { |
212 | 214 | return $desc->item(0)->nodeValue; |
213 | 215 | } |
214 | 216 | |
215 | - private function get_block_size($data_type) { | |
216 | - switch($data_type) { | |
217 | - case 'boolean': | |
217 | + private function get_row_size($field_node) { | |
218 | + $datatype = $field_node->getAttribute("datatype"); | |
219 | + | |
220 | + if($datatype == 'boolean') { | |
221 | + return 1; | |
222 | + } | |
223 | + | |
224 | + switch($datatype) { | |
218 | 225 | case 'unsignedByte': |
219 | 226 | case 'char': |
220 | 227 | $block_size = 1; |
... | ... | @@ -233,24 +240,16 @@ class VOTableMgr { |
233 | 240 | $block_size = 8; |
234 | 241 | break; |
235 | 242 | case 'double_complex': |
236 | - $block_size = 8; | |
237 | - break; | |
243 | + $block_size = 16; | |
238 | 244 | default: |
239 | 245 | $block_size = 0; |
240 | 246 | break; |
241 | 247 | } |
242 | - return $block_size; | |
243 | - } | |
244 | 248 | |
245 | - private function get_row_size($field_node) { | |
246 | - $datatype = $field_node->getAttribute("datatype"); | |
247 | - $block_size = $this->get_block_size($datatype); | |
248 | 249 | if($field_node->getAttribute("arraysize") == NULL) { |
249 | 250 | $array_size = $block_size; |
250 | 251 | } else if("*" == $field_node->getAttribute("arraysize")) { |
251 | - // echo "substr: " . json_encode(substr($this->stream, $this->c, 4)) . "\n"; | |
252 | 252 | $array_size = unpack("Ns", substr($this->stream, $this->c, 4))["s"] * $block_size; |
253 | - // echo "array_size: $array_size\n"; | |
254 | 253 | $this->c+=4; |
255 | 254 | } else { |
256 | 255 | $array_size = (int)($field_node->getAttribute("arraysize")) * $block_size; |
... | ... | @@ -270,7 +269,6 @@ class VOTableMgr { |
270 | 269 | if($query_stream == NULL) |
271 | 270 | return NULL; |
272 | 271 | $this->stream = base64_decode($query_stream->textContent); |
273 | - // echo "stream: " . json_encode($this->stream) . "\n"; | |
274 | 272 | $stream_len = strlen($this->stream); |
275 | 273 | if($stream_len == 0) |
276 | 274 | return NULL; |
... | ... | @@ -293,34 +291,85 @@ class VOTableMgr { |
293 | 291 | return $data; |
294 | 292 | } |
295 | 293 | |
294 | + private function JDTodate($jd) { | |
295 | + list($month, $day, $year) = split('/', JDToGregorian($jd)); | |
296 | + return "$day/$month/$year"; | |
297 | + } | |
298 | + | |
299 | + # because unpack for floats is hardware dependant | |
300 | + // private function big_endian_unpack ($format, $data) { | |
301 | + // $ar = unpack ($format, $data); | |
302 | + // $vals = array_values ($ar); | |
303 | + // echo "vals: " . json_encode($vals) . "\n"; | |
304 | + // $f = explode ('/', $format); | |
305 | + // $i = 0; | |
306 | + // foreach ($f as $f_k => $f_v) { | |
307 | + // $repeater = intval (substr ($f_v, 1)); | |
308 | + // | |
309 | + // if ($repeater == 0) { | |
310 | + // $repeater = 1; | |
311 | + // } | |
312 | + // if ($f_v{1} == '*') { | |
313 | + // $repeater = count ($ar) - $i; | |
314 | + // } | |
315 | + // if ($f_v{0} != 'd') { | |
316 | + // $i += $repeater; continue; | |
317 | + // } | |
318 | + // $j = $i + $repeater; | |
319 | + // | |
320 | + // for ($a = $i; $a < $j; ++$a) { | |
321 | + // $p = pack ('d', $vals[$i]); | |
322 | + // $p = strrev ($p); | |
323 | + // ++$i; | |
324 | + // } | |
325 | + // } | |
326 | + // $a = 0; | |
327 | + // foreach ($ar as $ar_k => $ar_v) { | |
328 | + // $ar[$ar_k] = $vals[$a]; | |
329 | + // ++$a; | |
330 | + // } | |
331 | + // return $ar; | |
332 | + // } | |
333 | + | |
296 | 334 | private function process_datablock($field_node) { |
297 | 335 | $data_type = $field_node->getAttribute("datatype"); |
298 | 336 | $row_size = $this->get_row_size($field_node); |
299 | - // echo "datatype: " . $field_node->getAttribute("datatype") . "\n"; | |
300 | - // echo "Row size: $row_size\n"; | |
337 | + $substr = substr($this->stream, $this->c, $row_size); | |
338 | + | |
301 | 339 | switch ($data_type) { |
302 | 340 | case 'boolean': |
303 | 341 | case 'unsignedByte': |
304 | - $res = $this->stream[$this->c] == "T" || $this->stream[$this->c] == "t" || $this->stream[$this->c] == "1"; | |
342 | + $b = $substr; | |
343 | + $res = $b == "T" || $b == "t" || $b == "1"; | |
305 | 344 | break; |
306 | 345 | case 'char': |
307 | 346 | case 'unicodeChar': |
308 | - $res = $row_size !=0 ? substr($this->stream, $this->c, $row_size) : NULL; | |
347 | + $res = $row_size!=0 ? $substr : NULL; | |
309 | 348 | break; |
310 | 349 | case 'short': |
311 | - $res = unpack("ss", substr($this->stream, $this->c, 2))["s"]; | |
350 | + $res = unpack("ss", $substr)["s"]; | |
312 | 351 | break; |
313 | 352 | case 'int': |
314 | - $res = unpack("Ns", substr($this->stream, $this->c, 4))["s"]; | |
353 | + $res = unpack("Ns", $substr)["s"]; | |
315 | 354 | break; |
316 | 355 | case 'long': |
317 | - $res = unpack("Js", substr($this->stream, $this->c, 8))["s"]; // /!\ J -> PHP 5.6 only | |
356 | + $res = unpack("Js", $substr)["s"]; // /!\ J -> PHP 5.6 only | |
318 | 357 | break; |
319 | 358 | case 'float': |
320 | - $res = unpack("fs", substr($this->stream, $this->c, 4))["s"]; | |
359 | + $res = unpack("fs", $substr)["s"]; | |
360 | + | |
361 | + // If machine is little endian: | |
362 | + if($this->is_little_endian) { | |
363 | + $res = unpack('f1f', strrev(pack('f', $res)))["f"]; | |
364 | + } | |
321 | 365 | break; |
322 | 366 | case 'double': |
323 | - $res = unpack("ds", substr($this->stream, $this->c, 8))["s"]; | |
367 | + $res = unpack("ds", $substr)["s"]; | |
368 | + | |
369 | + // If machine is little endian: | |
370 | + if($this->is_little_endian) { | |
371 | + $res = unpack('d1d', strrev(pack('d', $res)))["d"]; | |
372 | + } | |
324 | 373 | break; |
325 | 374 | default: |
326 | 375 | $res = NULL; |
... | ... |