comparison src/ov-str-mat.cc @ 4805:b0d6da24caeb

[project @ 2004-03-02 03:43:15 by jwe]
author jwe
date Tue, 02 Mar 2004 03:43:15 +0000
parents 14dc2267c343
children 2eb844b27953
comparison
equal deleted inserted replaced
4804:6202d9b75f83 4805:b0d6da24caeb
238 bool 238 bool
239 octave_char_matrix_str::save_ascii (std::ostream& os, 239 octave_char_matrix_str::save_ascii (std::ostream& os,
240 bool& /* infnan_warned */, 240 bool& /* infnan_warned */,
241 bool /* strip_nan_and_inf */) 241 bool /* strip_nan_and_inf */)
242 { 242 {
243 charMatrix chm = char_matrix_value (); 243 dim_vector d = dims ();
244 int elements = chm.rows (); 244 if (d.length () > 2)
245 os << "# elements: " << elements << "\n"; 245 {
246 for (int i = 0; i < elements; i++) 246 charNDArray tmp = char_array_value ();
247 { 247 os << "# ndims: " << d.length () << "\n";
248 unsigned len = chm.cols (); 248 for (int i=0; i < d.length (); i++)
249 os << "# length: " << len << "\n"; 249 os << " " << d (i);
250 std::string tstr = chm.row_as_string (i, false, true);
251 const char *tmp = tstr.data ();
252 if (tstr.length () > len)
253 panic_impossible ();
254 os.write (X_CAST (char *, tmp), len);
255 os << "\n"; 250 os << "\n";
251 os.write (X_CAST (char *, tmp.fortran_vec ()), d.numel ());
252 os << "\n";
253 }
254 else
255 {
256 // Keep this case, rather than use generic code above for
257 // backward compatiability. Makes load_ascii much more complex!!
258 charMatrix chm = char_matrix_value ();
259 int elements = chm.rows ();
260 os << "# elements: " << elements << "\n";
261 for (int i = 0; i < elements; i++)
262 {
263 unsigned len = chm.cols ();
264 os << "# length: " << len << "\n";
265 std::string tstr = chm.row_as_string (i, false, true);
266 const char *tmp = tstr.data ();
267 if (tstr.length () > len)
268 panic_impossible ();
269 os.write (X_CAST (char *, tmp), len);
270 os << "\n";
271 }
256 } 272 }
257 273
258 return true; 274 return true;
259 } 275 }
260 276
261 bool 277 bool
262 octave_char_matrix_str::load_ascii (std::istream& is) 278 octave_char_matrix_str::load_ascii (std::istream& is)
263 { 279 {
264 int elements; 280 int mdims = 0;
265 bool success = true; 281 bool success = true;
266 std::streampos pos = is.tellg (); 282 std::streampos pos = is.tellg ();
267 283
268 if (extract_keyword (is, "elements", elements, true)) 284 if (extract_keyword (is, "ndims", mdims, true))
269 { 285 {
270 286 if (mdims >= 0)
271 if (elements >= 0) 287 {
272 { 288 dim_vector dv;
273 // XXX FIXME XXX -- need to be able to get max length 289 dv.resize (mdims);
274 // before doing anything. 290
275 291 for (int i = 0; i < mdims; i++)
276 charMatrix chm (elements, 0); 292 is >> dv(i);
277 int max_len = 0; 293
278 for (int i = 0; i < elements; i++) 294 charNDArray tmp(dv);
279 { 295 char *ftmp = tmp.fortran_vec ();
280 int len; 296
281 if (extract_keyword (is, "length", len) && len >= 0) 297 // Skip the return line
298 if (! is.read (ftmp, 1))
299 return false;
300
301 if (! is.read (ftmp, dv.numel ()) || !is)
302 {
303 error ("load: failed to load string constant");
304 success = false;
305 }
306 else
307 matrix = tmp;
308 }
309 else
310 {
311 error ("load: failed to extract matrix size");
312 success = false;
313 }
314 }
315 else
316 {
317 int elements;
318
319 // re-read the same line again
320 is.clear ();
321 is.seekg (pos);
322
323 if (extract_keyword (is, "elements", elements, true))
324 {
325
326 if (elements >= 0)
327 {
328 // XXX FIXME XXX -- need to be able to get max length
329 // before doing anything.
330
331 charMatrix chm (elements, 0);
332 int max_len = 0;
333 for (int i = 0; i < elements; i++)
282 { 334 {
283 OCTAVE_LOCAL_BUFFER (char, tmp, len+1); 335 int len;
336 if (extract_keyword (is, "length", len) && len >= 0)
337 {
338 OCTAVE_LOCAL_BUFFER (char, tmp, len+1);
284 339
285 if (len > 0 && ! is.read (X_CAST (char *, tmp), len)) 340 if (len > 0 && !
286 { 341 is.read (X_CAST (char *, tmp), len))
287 error ("load: failed to load string constant"); 342 {
288 success = false; 343 error ("load: failed to load string constant");
289 break; 344 success = false;
345 break;
346 }
347 else
348 {
349 tmp [len] = '\0';
350 if (len > max_len)
351 {
352 max_len = len;
353 chm.resize (elements, max_len, 0);
354 }
355 chm.insert (tmp, i, 0);
356 }
290 } 357 }
291 else 358 else
292 { 359 {
293 tmp [len] = '\0'; 360 error ("load: failed to extract string length for element %d",
294 if (len > max_len) 361 i+1);
295 { 362 success = false;
296 max_len = len;
297 chm.resize (elements, max_len, 0);
298 }
299 chm.insert (tmp, i, 0);
300 } 363 }
364 }
365
366 if (! error_state)
367 matrix = chm;
368
369 }
370 else
371 {
372 error ("load: failed to extract number of string elements");
373 success = false;
374 }
375 }
376 else
377 {
378 // re-read the same line again
379 is.clear ();
380 is.seekg (pos);
381
382 int len;
383
384 if (extract_keyword (is, "length", len) && len >= 0)
385 {
386 // This is cruft for backward compatiability,
387 // but relatively harmless.
388
389 OCTAVE_LOCAL_BUFFER (char, tmp, len+1);
390
391 if (len > 0 && ! is.read (X_CAST (char *, tmp), len))
392 {
393 error ("load: failed to load string constant");
301 } 394 }
302 else 395 else
303 { 396 {
304 error ("load: failed to extract string length for element %d", 397 tmp [len] = '\0';
305 i+1); 398
306 success = false; 399 if (is)
400 matrix = charMatrix (tmp);
401 else
402 error ("load: failed to load string constant");
307 } 403 }
308 }
309
310 if (! error_state)
311 matrix = chm;
312
313 }
314 else
315 {
316 error ("load: failed to extract number of string elements");
317 success = false;
318 }
319 }
320 else
321 {
322 // re-read the same line again
323 is.clear ();
324 is.seekg (pos);
325
326 int len;
327
328 if (extract_keyword (is, "length", len) && len >= 0)
329 {
330 // This is cruft for backward compatiability, but relatively harmless.
331
332 OCTAVE_LOCAL_BUFFER (char, tmp, len+1);
333
334 if (len > 0 && ! is.read (X_CAST (char *, tmp), len))
335 {
336 error ("load: failed to load string constant");
337 }
338 else
339 {
340 tmp [len] = '\0';
341
342 if (is)
343 matrix = charMatrix (tmp);
344 else
345 error ("load: failed to load string constant");
346 } 404 }
347 } 405 }
348 } 406 }
349 407
350 return success; 408 return success;
352 410
353 bool 411 bool
354 octave_char_matrix_str::save_binary (std::ostream& os, 412 octave_char_matrix_str::save_binary (std::ostream& os,
355 bool& /* save_as_floats */) 413 bool& /* save_as_floats */)
356 { 414 {
357 FOUR_BYTE_INT nr = rows (); 415 dim_vector d = dims ();
358 os.write (X_CAST (char *, &nr), 4); 416 if (d.length() < 1)
359 charMatrix chm = char_matrix_value (); 417 return false;
360 for (int i = 0; i < nr; i++) 418
361 { 419 // Use negative value for ndims to differentiate with old format!!
362 FOUR_BYTE_INT len = chm.cols (); 420 FOUR_BYTE_INT tmp = - d.length();
363 os.write (X_CAST (char *, &len), 4); 421 os.write (X_CAST (char *, &tmp), 4);
364 std::string tstr = chm.row_as_string (i); 422 for (int i=0; i < d.length (); i++)
365 const char *btmp = tstr.data (); 423 {
366 os.write (X_CAST (char *, btmp), len); 424 tmp = d(i);
367 } 425 os.write (X_CAST (char *, &tmp), 4);
426 }
427
428 charNDArray m = char_array_value ();
429 os.write (m.fortran_vec (), d.numel ());
368 return true; 430 return true;
369 } 431 }
370 432
371 bool 433 bool
372 octave_char_matrix_str::load_binary (std::istream& is, bool swap, 434 octave_char_matrix_str::load_binary (std::istream& is, bool swap,
375 FOUR_BYTE_INT elements; 437 FOUR_BYTE_INT elements;
376 if (! is.read (X_CAST (char *, &elements), 4)) 438 if (! is.read (X_CAST (char *, &elements), 4))
377 return false; 439 return false;
378 if (swap) 440 if (swap)
379 swap_4_bytes (X_CAST (char *, &elements)); 441 swap_4_bytes (X_CAST (char *, &elements));
380 charMatrix chm (elements, 0); 442
381 int max_len = 0; 443 if (elements < 0)
382 for (int i = 0; i < elements; i++) 444 {
383 { 445 FOUR_BYTE_INT mdims = - elements;
384 FOUR_BYTE_INT len; 446 FOUR_BYTE_INT di;
385 if (! is.read (X_CAST (char *, &len), 4)) 447 dim_vector dv;
448 dv.resize (mdims);
449
450 for (int i = 0; i < mdims; i++)
451 {
452 if (! is.read (X_CAST (char *, &di), 4))
453 return false;
454 if (swap)
455 swap_4_bytes (X_CAST (char *, &di));
456 dv(i) = di;
457 }
458
459 charNDArray m(dv);
460 char *tmp = m.fortran_vec ();
461 is.read (tmp, dv.numel ());
462
463 if (error_state || ! is)
386 return false; 464 return false;
387 if (swap) 465 matrix = m;
388 swap_4_bytes (X_CAST (char *, &len)); 466 }
389 OCTAVE_LOCAL_BUFFER (char, btmp, len+1); 467 else
390 if (! is.read (X_CAST (char *, btmp), len)) 468 {
391 return false; 469 charMatrix chm (elements, 0);
392 if (len > max_len) 470 int max_len = 0;
393 { 471 for (int i = 0; i < elements; i++)
394 max_len = len; 472 {
395 chm.resize (elements, max_len, 0); 473 FOUR_BYTE_INT len;
396 } 474 if (! is.read (X_CAST (char *, &len), 4))
397 btmp [len] = '\0'; 475 return false;
398 chm.insert (btmp, i, 0); 476 if (swap)
399 } 477 swap_4_bytes (X_CAST (char *, &len));
400 478 OCTAVE_LOCAL_BUFFER (char, btmp, len+1);
401 matrix = chm; 479 if (! is.read (X_CAST (char *, btmp), len))
480 return false;
481 if (len > max_len)
482 {
483 max_len = len;
484 chm.resize (elements, max_len, 0);
485 }
486 btmp [len] = '\0';
487 chm.insert (btmp, i, 0);
488 }
489 matrix = chm;
490 }
402 return true; 491 return true;
403 } 492 }
404 493
405 #if defined (HAVE_HDF5) 494 #if defined (HAVE_HDF5)
406 bool 495 bool
407 octave_char_matrix_str::save_hdf5 (hid_t loc_id, const char *name, 496 octave_char_matrix_str::save_hdf5 (hid_t loc_id, const char *name,
408 bool /* save_as_floats */) 497 bool /* save_as_floats */)
409 { 498 {
410 hsize_t dimens[3]; 499 dim_vector d = dims ();
411 hid_t space_hid = -1, type_hid = -1, data_hid = -1; 500 int empty = save_hdf5_empty (loc_id, name, d);
501 if (empty != 0)
502 return (empty > 0);
503
504 int rank = d.length ();
505 hid_t space_hid = -1, data_hid = -1;
412 bool retval = true; 506 bool retval = true;
413 507 charNDArray m = char_array_value ();
414 int nr = rows (); 508
415 charMatrix chm = char_matrix_value (); 509 OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
416 int nc = chm.cols (); 510
417 511 // Octave uses column-major, while HDF5 uses row-major ordering
418 // create datatype for (null-terminated) string to write from: 512 for (int i = 0; i < rank; i++)
419 type_hid = H5Tcopy (H5T_C_S1); H5Tset_size (type_hid, nc + 1); 513 hdims[i] = d (rank-i-1);
420 if (type_hid < 0) return false; 514
421 515 space_hid = H5Screate_simple (rank, hdims, (hsize_t *)0);
422 dimens[0] = nr;
423 space_hid = H5Screate_simple (nr > 0 ? 1 : 0, dimens, (hsize_t*) 0);
424 if (space_hid < 0) 516 if (space_hid < 0)
425 { 517 return false;
426 H5Tclose (type_hid); 518
519 data_hid = H5Dcreate (loc_id, name, H5T_NATIVE_CHAR, space_hid,
520 H5P_DEFAULT);
521 if (data_hid < 0)
522 {
523 H5Sclose (space_hid);
427 return false; 524 return false;
428 } 525 }
429 526
430 data_hid = H5Dcreate (loc_id, name, type_hid, space_hid, H5P_DEFAULT); 527 OCTAVE_LOCAL_BUFFER (char, s, d.numel ());
431 if (data_hid < 0) 528
432 { 529 for (int i = 0; i < d.numel(); ++i)
433 H5Sclose (space_hid); 530 s[i] = m(i);
434 H5Tclose (type_hid); 531
435 return false; 532 retval = H5Dwrite (data_hid, H5T_NATIVE_CHAR, H5S_ALL, H5S_ALL,
436 } 533 H5P_DEFAULT, (void*) s) >= 0;
437
438 OCTAVE_LOCAL_BUFFER (char, s, nr * (nc + 1));
439
440 for (int i = 0; i < nr; ++i)
441 {
442 std::string tstr = chm.row_as_string (i);
443 strcpy (s + i * (nc+1), tstr.c_str ());
444 }
445
446 retval = H5Dwrite (data_hid, type_hid, H5S_ALL, H5S_ALL, H5P_DEFAULT,
447 (void*) s) >= 0;
448 534
449 H5Dclose (data_hid); 535 H5Dclose (data_hid);
450 H5Tclose (type_hid);
451 H5Sclose (space_hid); 536 H5Sclose (space_hid);
452 return retval; 537 return retval;
453 } 538 }
454 539
455 bool 540 bool
456 octave_char_matrix_str::load_hdf5 (hid_t loc_id, const char *name, 541 octave_char_matrix_str::load_hdf5 (hid_t loc_id, const char *name,
457 bool /* have_h5giterate_bug */) 542 bool /* have_h5giterate_bug */)
458 { 543 {
544 dim_vector dv;
545 int empty = load_hdf5_empty (loc_id, name, dv);
546 if (empty > 0)
547 matrix.resize(dv);
548 if (empty != 0)
549 return (empty > 0);
550
459 hid_t data_hid = H5Dopen (loc_id, name); 551 hid_t data_hid = H5Dopen (loc_id, name);
460 hid_t space_hid = H5Dget_space (data_hid); 552 hid_t space_hid = H5Dget_space (data_hid);
461 hsize_t rank = H5Sget_simple_extent_ndims (space_hid); 553 hsize_t rank = H5Sget_simple_extent_ndims (space_hid);
462 hid_t type_hid = H5Dget_type (data_hid); 554 hid_t type_hid = H5Dget_type (data_hid);
463 555 hid_t type_class_hid = H5Tget_class (type_hid);
464 if (rank == 0) 556
465 { 557 if (type_class_hid == H5T_INTEGER)
466 // a single string: 558 {
467 int slen = H5Tget_size (type_hid); 559 bool retval = false;
468 if (slen < 0) 560 if (rank < 1)
469 { 561 {
470 H5Tclose (type_hid); 562 H5Tclose (type_hid);
471 H5Sclose (space_hid); 563 H5Sclose (space_hid);
472 H5Dclose (data_hid); 564 H5Dclose (data_hid);
473 return false; 565 return false;
474 } 566 }
567
568 OCTAVE_LOCAL_BUFFER (hsize_t, hdims, rank);
569 OCTAVE_LOCAL_BUFFER (hsize_t, maxdims, rank);
570
571 H5Sget_simple_extent_dims (space_hid, hdims, maxdims);
572
573 // Octave uses column-major, while HDF5 uses row-major ordering
574 if (rank == 1)
575 {
576 dv.resize (2);
577 dv(0) = 1;
578 dv(1) = hdims[0];
579 }
475 else 580 else
476 { 581 {
477 OCTAVE_LOCAL_BUFFER (char, s, slen); 582 dv.resize (rank);
478 // create datatype for (null-terminated) string 583 for (int i = 0, j = rank - 1; i < (int)rank; i++, j--)
479 // to read into: 584 dv(j) = hdims[i];
480 hid_t st_id = H5Tcopy (H5T_C_S1); 585 }
481 H5Tset_size (st_id, slen); 586
482 if (H5Dread (data_hid, st_id, H5S_ALL, H5S_ALL, 587 charNDArray m (dv);
483 H5P_DEFAULT, (void *) s) < 0) 588 char *str = m.fortran_vec ();
484 { 589 if (H5Dread (data_hid, H5T_NATIVE_CHAR, H5S_ALL, H5S_ALL,
590 H5P_DEFAULT, (void *) str) >= 0)
591 {
592 retval = true;
593 matrix = m;
594 }
595
596 H5Tclose (type_hid);
597 H5Sclose (space_hid);
598 H5Dclose (data_hid);
599 return true;
600 }
601 else
602 {
603 // This is cruft for backward compatiability and easy data
604 // importation
605 if (rank == 0)
606 {
607 // a single string:
608 int slen = H5Tget_size (type_hid);
609 if (slen < 0)
610 {
611 H5Tclose (type_hid);
612 H5Sclose (space_hid);
613 H5Dclose (data_hid);
614 return false;
615 }
616 else
617 {
618 OCTAVE_LOCAL_BUFFER (char, s, slen);
619 // create datatype for (null-terminated) string
620 // to read into:
621 hid_t st_id = H5Tcopy (H5T_C_S1);
622 H5Tset_size (st_id, slen);
623 if (H5Dread (data_hid, st_id, H5S_ALL, H5S_ALL,
624 H5P_DEFAULT, (void *) s) < 0)
625 {
626 H5Tclose (st_id);
627 H5Tclose (type_hid);
628 H5Sclose (space_hid);
629 H5Dclose (data_hid);
630 return false;
631 }
632
633 matrix = charMatrix (s);
634
485 H5Tclose (st_id); 635 H5Tclose (st_id);
486 H5Tclose (type_hid); 636 H5Tclose (type_hid);
487 H5Sclose (space_hid); 637 H5Sclose (space_hid);
488 H5Dclose (data_hid); 638 H5Dclose (data_hid);
639 return true;
640 }
641 }
642 else if (rank == 1)
643 {
644 // string vector
645 hsize_t elements, maxdim;
646 H5Sget_simple_extent_dims (space_hid, &elements, &maxdim);
647 int slen = H5Tget_size (type_hid);
648 if (slen < 0)
649 {
650 H5Tclose (type_hid);
651 H5Sclose (space_hid);
652 H5Dclose (data_hid);
489 return false; 653 return false;
490 } 654 }
491 655 else
492 matrix = charMatrix (s); 656 {
657 // hdf5 string arrays store strings of all the
658 // same physical length (I think), which is
659 // slightly wasteful, but oh well.
493 660
494 H5Tclose (st_id); 661 OCTAVE_LOCAL_BUFFER (char, s, elements * slen);
495 H5Tclose (type_hid); 662
496 H5Sclose (space_hid); 663 // create datatype for (null-terminated) string
497 H5Dclose (data_hid); 664 // to read into:
498 return true; 665 hid_t st_id = H5Tcopy (H5T_C_S1);
499 } 666 H5Tset_size (st_id, slen);
500 } 667
501 else if (rank == 1) 668 if (H5Dread (data_hid, st_id, H5S_ALL, H5S_ALL,
502 { 669 H5P_DEFAULT, (void *) s) < 0)
503 // string vector 670 {
504 hsize_t elements, maxdim; 671 H5Tclose (st_id);
505 H5Sget_simple_extent_dims (space_hid, &elements, &maxdim); 672 H5Tclose (type_hid);
506 int slen = H5Tget_size (type_hid); 673 H5Sclose (space_hid);
507 if (slen < 0) 674 H5Dclose (data_hid);
675 return false;
676 }
677
678 charMatrix chm (elements, slen - 1);
679 for (hsize_t i = 0; i < elements; ++i)
680 {
681 chm.insert (s + i*slen, i, 0);
682 }
683
684 matrix = chm;
685
686 H5Tclose (st_id);
687 H5Tclose (type_hid);
688 H5Sclose (space_hid);
689 H5Dclose (data_hid);
690 return true;
691 }
692 }
693 else
508 { 694 {
509 H5Tclose (type_hid); 695 H5Tclose (type_hid);
510 H5Sclose (space_hid); 696 H5Sclose (space_hid);
511 H5Dclose (data_hid); 697 H5Dclose (data_hid);
512 return false; 698 return false;
513 } 699 }
514 else
515 {
516 // hdf5 string arrays store strings of all the
517 // same physical length (I think), which is
518 // slightly wasteful, but oh well.
519
520 OCTAVE_LOCAL_BUFFER (char, s, elements * slen);
521
522 // create datatype for (null-terminated) string
523 // to read into:
524 hid_t st_id = H5Tcopy (H5T_C_S1);
525 H5Tset_size (st_id, slen);
526
527 if (H5Dread (data_hid, st_id, H5S_ALL, H5S_ALL,
528 H5P_DEFAULT, (void *) s) < 0)
529 {
530 H5Tclose (st_id);
531 H5Tclose (type_hid);
532 H5Sclose (space_hid);
533 H5Dclose (data_hid);
534 return false;
535 }
536
537 charMatrix chm (elements, slen - 1);
538 for (hsize_t i = 0; i < elements; ++i)
539 {
540 chm.insert (s + i*slen, i, 0);
541 }
542
543 matrix = chm;
544
545 H5Tclose (st_id);
546 H5Tclose (type_hid);
547 H5Sclose (space_hid);
548 H5Dclose (data_hid);
549 return true;
550 }
551 }
552 else
553 {
554 H5Tclose (type_hid);
555 H5Sclose (space_hid);
556 H5Dclose (data_hid);
557 return false;
558 } 700 }
559 } 701 }
560 #endif 702 #endif
561 703
562 /* 704 /*