Commit e581690d5d4e10d97fb876aac21f16c5beccd475

Authored by Nathanael Jourdane
1 parent 574171f0

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;
... ...