comparison src/ls-mat5.cc @ 5089:3db2b2762491

[project @ 2004-12-03 04:06:05 by jwe]
author jwe
date Fri, 03 Dec 2004 04:06:05 +0000
parents 11bea7392e69
children 57077d0ddc8e
comparison
equal deleted inserted replaced
5088:7830f271a53f 5089:3db2b2762491
84 mxINT8_CLASS, // 8 bit signed integer 84 mxINT8_CLASS, // 8 bit signed integer
85 mxUINT8_CLASS, // 8 bit unsigned integer 85 mxUINT8_CLASS, // 8 bit unsigned integer
86 mxINT16_CLASS, // 16 bit signed integer 86 mxINT16_CLASS, // 16 bit signed integer
87 mxUINT16_CLASS, // 16 bit unsigned integer 87 mxUINT16_CLASS, // 16 bit unsigned integer
88 mxINT32_CLASS, // 32 bit signed integer 88 mxINT32_CLASS, // 32 bit signed integer
89 mxUINT32_CLASS // 32 bit unsigned integer 89 mxUINT32_CLASS, // 32 bit unsigned integer
90 mxINT64_CLASS, // 64 bit signed integer
91 mxUINT64_CLASS, // 64 bit unsigned integer
92 mxFUNCTION_CLASS // Function handle
90 }; 93 };
91 94
92 // Read COUNT elements of data from IS in the format specified by TYPE, 95 // Read COUNT elements of data from IS in the format specified by TYPE,
93 // placing the result in DATA. If SWAP is TRUE, swap the bytes of 96 // placing the result in DATA. If SWAP is TRUE, swap the bytes of
94 // each element before copying to DATA. FLT_FMT specifies the format 97 // each element before copying to DATA. FLT_FMT specifies the format
157 default: 160 default:
158 break; 161 break;
159 } 162 }
160 } 163 }
161 164
165 template <class T>
166 void
167 read_mat5_integer_data (std::istream& is, T &m, int count, bool swap,
168 mat5_data_type type)
169 {
170
171 #define READ_INTEGER_DATA(TYPE, swap, data, size, len, stream) \
172 do \
173 { \
174 if (len > 0) \
175 { \
176 volatile TYPE *ptr = X_CAST (volatile TYPE *, data); \
177 stream.read (X_CAST (char *, ptr), size * len); \
178 if (swap) \
179 swap_bytes< size > (ptr, len); \
180 TYPE tmp = ptr[0]; \
181 for (int i = len - 1; i > 0; i--) \
182 data[i] = ptr[i]; \
183 data[0] = tmp; \
184 } \
185 } \
186 while (0)
187
188 switch (type)
189 {
190 case miINT8:
191 READ_INTEGER_DATA (signed char, swap, m.fortran_vec (), 1,
192 count, is);
193 break;
194
195 case miUINT8:
196 READ_INTEGER_DATA (unsigned char, swap, m.fortran_vec (), 1,
197 count, is);
198 break;
199
200 case miINT16:
201 READ_INTEGER_DATA (signed TWO_BYTE_INT, swap, m.fortran_vec (), 2,
202 count, is);
203 break;
204
205 case miUINT16:
206 READ_INTEGER_DATA (unsigned TWO_BYTE_INT, swap, m.fortran_vec (), 2,
207 count, is);
208 break;
209
210 case miINT32:
211 READ_INTEGER_DATA (signed FOUR_BYTE_INT, swap, m.fortran_vec (), 4,
212 count, is);
213 break;
214
215 case miUINT32:
216 READ_INTEGER_DATA (unsigned FOUR_BYTE_INT, swap, m.fortran_vec (), 4,
217 count, is);
218 break;
219
220 case miSINGLE:
221 case miRESERVE1:
222 case miDOUBLE:
223 case miRESERVE2:
224 case miRESERVE3:
225 break;
226
227 case miINT64:
228 #ifdef EIGHT_BYTE_INT
229 READ_INTEGER_DATA (signed EIGHT_BYTE_INT, swap, m.fortran_vec (), 8,
230 count, is);
231 #endif
232 break;
233
234 case miUINT64:
235 #ifdef EIGHT_BYTE_INT
236 READ_INTEGER_DATA (unsigned EIGHT_BYTE_INT, swap, m.fortran_vec (), 8,
237 count, is);
238 #endif
239 break;
240
241 case miMATRIX:
242 default:
243 break;
244 }
245
246 #undef READ_INTEGER_DATA
247
248 }
249
250 template void read_mat5_integer_data (std::istream& is, int8NDArray &m,
251 int count, bool swap,
252 mat5_data_type type);
253 template void read_mat5_integer_data (std::istream& is, int16NDArray &m,
254 int count, bool swap,
255 mat5_data_type type);
256 template void read_mat5_integer_data (std::istream& is, int32NDArray &m,
257 int count, bool swap,
258 mat5_data_type type);
259 template void read_mat5_integer_data (std::istream& is, int64NDArray &m,
260 int count, bool swap,
261 mat5_data_type type);
262 template void read_mat5_integer_data (std::istream& is, uint8NDArray &m,
263 int count, bool swap,
264 mat5_data_type type);
265 template void read_mat5_integer_data (std::istream& is, uint16NDArray &m,
266 int count, bool swap,
267 mat5_data_type type);
268 template void read_mat5_integer_data (std::istream& is, uint32NDArray &m,
269 int count, bool swap,
270 mat5_data_type type);
271 template void read_mat5_integer_data (std::istream& is, uint64NDArray &m,
272 int count, bool swap,
273 mat5_data_type type);
274
275 #define OCTAVE_MAT5_INTEGER_READ(TYP) \
276 { \
277 TYP re (dims); \
278 \
279 std::streampos tmp_pos; \
280 \
281 if (read_mat5_tag (is, swap, type, len)) \
282 { \
283 error ("load: reading matrix data for `%s'", retval.c_str ()); \
284 goto data_read_error; \
285 } \
286 \
287 int n = re.length (); \
288 tmp_pos = is.tellg (); \
289 read_mat5_integer_data (is, re, n, swap, \
290 (enum mat5_data_type) type); \
291 \
292 if (! is || error_state) \
293 { \
294 error ("load: reading matrix data for `%s'", retval.c_str ()); \
295 goto data_read_error; \
296 } \
297 \
298 is.seekg (tmp_pos + static_cast<std::streamoff> (PAD (len))); \
299 \
300 if (imag) \
301 { \
302 /* We don't handle imag integer types, convert to an array */ \
303 NDArray im (dims); \
304 \
305 if (read_mat5_tag (is, swap, type, len)) \
306 { \
307 error ("load: reading matrix data for `%s'", \
308 retval.c_str ()); \
309 goto data_read_error; \
310 } \
311 \
312 n = im.length (); \
313 read_mat5_binary_data (is, im.fortran_vec (), n, swap, \
314 (enum mat5_data_type) type, flt_fmt); \
315 \
316 if (! is || error_state) \
317 { \
318 error ("load: reading imaginary matrix data for `%s'", \
319 retval.c_str ()); \
320 goto data_read_error; \
321 } \
322 \
323 ComplexNDArray ctmp (dims); \
324 \
325 for (int i = 0; i < n; i++) \
326 ctmp(i) = Complex (double (re(i)), im(i)); \
327 \
328 tc = ctmp; \
329 } \
330 else \
331 tc = re; \
332 }
333
162 // Read one element tag from stream IS, 334 // Read one element tag from stream IS,
163 // place the type code in TYPE and the byte count in BYTES 335 // place the type code in TYPE and the byte count in BYTES
164 // return nonzero on error 336 // return nonzero on error
165 static int 337 static int
166 read_mat5_tag (std::istream& is, bool swap, int& type, int& bytes) 338 read_mat5_tag (std::istream& is, bool swap, int& type, int& bytes)
222 394
223 // These are initialized here instead of closer to where they are 395 // These are initialized here instead of closer to where they are
224 // first used to avoid errors from gcc about goto crossing 396 // first used to avoid errors from gcc about goto crossing
225 // initialization of variable. 397 // initialization of variable.
226 398
227 NDArray re;
228 oct_mach_info::float_format flt_fmt = oct_mach_info::flt_fmt_unknown; 399 oct_mach_info::float_format flt_fmt = oct_mach_info::flt_fmt_unknown;
229 int type = 0; 400 int type = 0;
230 bool imag; 401 bool imag;
231 bool logicalvar; 402 bool logicalvar;
232 enum arrayclasstype arrayclass; 403 enum arrayclasstype arrayclass;
295 { 466 {
296 FOUR_BYTE_INT n; 467 FOUR_BYTE_INT n;
297 read_int (is, swap, n); 468 read_int (is, swap, n);
298 dims(i) = n; 469 dims(i) = n;
299 } 470 }
300 re.resize (dims);
301 471
302 std::streampos tmp_pos = is.tellg (); 472 std::streampos tmp_pos = is.tellg ();
303 is.seekg (tmp_pos + static_cast<std::streamoff> (PAD (dim_len) - dim_len)); 473 is.seekg (tmp_pos + static_cast<std::streamoff> (PAD (dim_len) - dim_len));
304 } 474 }
305 475
360 warning ("load: objects are not implemented"); 530 warning ("load: objects are not implemented");
361 goto skip_ahead; 531 goto skip_ahead;
362 532
363 case mxSPARSE_CLASS: 533 case mxSPARSE_CLASS:
364 warning ("load: sparse arrays are not implemented"); 534 warning ("load: sparse arrays are not implemented");
535 goto skip_ahead;
536
537 case mxFUNCTION_CLASS:
538 warning ("load: function handles are not implemented");
365 goto skip_ahead; 539 goto skip_ahead;
366 540
367 case mxSTRUCT_CLASS: 541 case mxSTRUCT_CLASS:
368 { 542 {
369 Octave_map m; 543 Octave_map m;
444 618
445 tc = m; 619 tc = m;
446 } 620 }
447 break; 621 break;
448 622
623 case mxINT8_CLASS:
624 OCTAVE_MAT5_INTEGER_READ (int8NDArray);
625 break;
626
627 case mxUINT8_CLASS:
628 OCTAVE_MAT5_INTEGER_READ (uint8NDArray);
629 break;
630
631 case mxINT16_CLASS:
632 OCTAVE_MAT5_INTEGER_READ (int16NDArray);
633 break;
634
635 case mxUINT16_CLASS:
636 OCTAVE_MAT5_INTEGER_READ (uint16NDArray);
637 break;
638
639 case mxINT32_CLASS:
640 OCTAVE_MAT5_INTEGER_READ (int32NDArray);
641 break;
642
643 case mxUINT32_CLASS:
644 OCTAVE_MAT5_INTEGER_READ (uint32NDArray);
645 break;
646
647 case mxINT64_CLASS:
648 OCTAVE_MAT5_INTEGER_READ (int64NDArray);
649 break;
650
651 case mxUINT64_CLASS:
652 OCTAVE_MAT5_INTEGER_READ (uint64NDArray);
653 break;
654
449 case mxCHAR_CLASS: 655 case mxCHAR_CLASS:
450 // handle as a numerical array to start with 656 // handle as a numerical array to start with
451 657
452 case mxDOUBLE_CLASS: 658 case mxDOUBLE_CLASS:
453 case mxSINGLE_CLASS: 659 case mxSINGLE_CLASS:
454 case mxINT8_CLASS:
455 case mxUINT8_CLASS:
456 case mxINT16_CLASS:
457 case mxUINT16_CLASS:
458 case mxINT32_CLASS:
459 case mxUINT32_CLASS:
460 default: 660 default:
461 // handle all these numerical formats as double arrays 661 {
662 NDArray re (dims);
462 663
463 // real data subelement 664 // real data subelement
464 { 665
465 std::streampos tmp_pos; 666 std::streampos tmp_pos;
466 667
467 if (read_mat5_tag (is, swap, type, len)) 668 if (read_mat5_tag (is, swap, type, len))
468 { 669 {
469 error ("load: reading matrix data for `%s'", retval.c_str ()); 670 error ("load: reading matrix data for `%s'", retval.c_str ());
470 goto data_read_error; 671 goto data_read_error;
471 } 672 }
480 error ("load: reading matrix data for `%s'", retval.c_str ()); 681 error ("load: reading matrix data for `%s'", retval.c_str ());
481 goto data_read_error; 682 goto data_read_error;
482 } 683 }
483 684
484 is.seekg (tmp_pos + static_cast<std::streamoff> (PAD (len))); 685 is.seekg (tmp_pos + static_cast<std::streamoff> (PAD (len)));
686
687 // imaginary data subelement
688 if (imag)
689 {
690 NDArray im (dims);
691
692 if (read_mat5_tag (is, swap, type, len))
693 {
694 error ("load: reading matrix data for `%s'", retval.c_str ());
695 goto data_read_error;
696 }
697
698 n = im.length ();
699 read_mat5_binary_data (is, im.fortran_vec (), n, swap,
700 (enum mat5_data_type) type, flt_fmt);
701
702 if (! is || error_state)
703 {
704 error ("load: reading imaginary matrix data for `%s'",
705 retval.c_str ());
706 goto data_read_error;
707 }
708
709 ComplexNDArray ctmp (dims);
710
711 for (int i = 0; i < n; i++)
712 ctmp(i) = Complex (re(i), im(i));
713
714 tc = ctmp;
715 }
716 else
717 tc = re;
718
719 if (arrayclass == mxCHAR_CLASS)
720 tc = tc.convert_to_str (false, true);
485 } 721 }
486
487 // imaginary data subelement
488 if (imag)
489 {
490 NDArray im (dims);
491
492 if (read_mat5_tag (is, swap, type, len))
493 {
494 error ("load: reading matrix data for `%s'", retval.c_str ());
495 goto data_read_error;
496 }
497
498 int n = im.length ();
499 read_mat5_binary_data (is, im.fortran_vec (), n, swap,
500 (enum mat5_data_type) type, flt_fmt);
501
502 if (! is || error_state)
503 {
504 error ("load: reading imaginary matrix data for `%s'",
505 retval.c_str ());
506 goto data_read_error;
507 }
508
509 ComplexNDArray ctmp (dims);
510
511 for (int i = 0; i < n; i++)
512 ctmp(i) = Complex (re(i), im(i));
513
514 tc = ctmp;
515 }
516 else
517 tc = re;
518
519 if (arrayclass == mxCHAR_CLASS)
520 tc = tc.convert_to_str (false, true);
521 } 722 }
522 723
523 is.seekg (pos + static_cast<std::streamoff> (element_length)); 724 is.seekg (pos + static_cast<std::streamoff> (element_length));
524 725
525 if (is.eof ()) 726 if (is.eof ())
708 static char buf[9]="\x00\x00\x00\x00\x00\x00\x00\x00"; 909 static char buf[9]="\x00\x00\x00\x00\x00\x00\x00\x00";
709 os.write (buf, PAD (len) - len); 910 os.write (buf, PAD (len) - len);
710 } 911 }
711 } 912 }
712 913
914 template <class T>
915 void
916 write_mat5_integer_data (std::ostream& os, const T& m, int size)
917 {
918 int nel = m.nelem ();
919 mat5_data_type mst;
920 unsigned len;
921
922 switch (size)
923 {
924 case 1:
925 mst = miUINT8;
926 break;
927 case 2:
928 mst = miUINT16;
929 break;
930 case 3:
931 mst = miUINT32;
932 break;
933 case 4:
934 mst = miUINT64;
935 break;
936 case -1:
937 mst = miINT8;
938 size = - size;
939 break;
940 case -2:
941 mst = miINT16;
942 size = - size;
943 break;
944 case -3:
945 mst = miINT32;
946 size = - size;
947 break;
948 case -4:
949 default:
950 mst = miINT64;
951 size = - size;
952 break;
953 }
954
955 len = nel*size;
956 write_mat5_tag (os, mst, len);
957
958 os.write (X_CAST(char *, m.data ()), len);
959
960 if (PAD (len) > len)
961 {
962 static char buf[9]="\x00\x00\x00\x00\x00\x00\x00\x00";
963 os.write (buf, PAD (len) - len);
964 }
965 }
966
967 template void write_mat5_integer_data (std::ostream& os,
968 const int8NDArray &m, int size);
969 template void write_mat5_integer_data (std::ostream& os,
970 const int16NDArray &m, int size);
971 template void write_mat5_integer_data (std::ostream& os,
972 const int32NDArray &m, int size);
973 template void write_mat5_integer_data (std::ostream& os,
974 const int64NDArray &m, int size);
975 template void write_mat5_integer_data (std::ostream& os,
976 const uint8NDArray &m, int size);
977 template void write_mat5_integer_data (std::ostream& os,
978 const uint16NDArray &m, int size);
979 template void write_mat5_integer_data (std::ostream& os,
980 const uint32NDArray &m, int size);
981 template void write_mat5_integer_data (std::ostream& os,
982 const uint64NDArray &m, int size);
983
713 // Write out cell element values in the cell array to OS, preceded by 984 // Write out cell element values in the cell array to OS, preceded by
714 // the appropriate tag. 985 // the appropriate tag.
715 986
716 static bool 987 static bool
717 write_mat5_cell_array (std::ostream& os, const Cell& cell, 988 write_mat5_cell_array (std::ostream& os, const Cell& cell,
740 bool mark_as_global, bool save_as_floats) 1011 bool mark_as_global, bool save_as_floats)
741 { 1012 {
742 FOUR_BYTE_INT flags=0; 1013 FOUR_BYTE_INT flags=0;
743 FOUR_BYTE_INT junk=0; 1014 FOUR_BYTE_INT junk=0;
744 std::streampos fixup, contin; 1015 std::streampos fixup, contin;
1016 std::string cname = tc.class_name ();
745 1017
746 // element type and length 1018 // element type and length
747 fixup = os.tellp (); 1019 fixup = os.tellp ();
748 write_mat5_tag (os, miMATRIX, 99); // we don't know the real length yet 1020 write_mat5_tag (os, miMATRIX, 99); // we don't know the real length yet
749 1021
756 if (tc.is_complex_scalar () || tc.is_complex_matrix ()) 1028 if (tc.is_complex_scalar () || tc.is_complex_matrix ())
757 flags |= 0x0800; 1029 flags |= 0x0800;
758 1030
759 if (tc.is_string ()) 1031 if (tc.is_string ())
760 flags |= mxCHAR_CLASS; 1032 flags |= mxCHAR_CLASS;
1033 else if (cname == "int8")
1034 flags |= mxINT8_CLASS;
1035 else if (cname == "int16")
1036 flags |= mxINT16_CLASS;
1037 else if (cname == "int32")
1038 flags |= mxINT32_CLASS;
1039 else if (cname == "int64")
1040 flags |= mxINT64_CLASS;
1041 else if (cname == "uint8")
1042 flags |= mxUINT8_CLASS;
1043 else if (cname == "uint16")
1044 flags |= mxUINT16_CLASS;
1045 else if (cname == "uint32")
1046 flags |= mxUINT32_CLASS;
1047 else if (cname == "uint64")
1048 flags |= mxUINT64_CLASS;
761 else if (tc.is_real_scalar ()) 1049 else if (tc.is_real_scalar ())
762 flags |= mxDOUBLE_CLASS; 1050 flags |= mxDOUBLE_CLASS;
763 else if (tc.is_real_matrix () || tc.is_range ()) 1051 else if (tc.is_real_matrix () || tc.is_range ())
764 flags |= mxDOUBLE_CLASS; 1052 flags |= mxDOUBLE_CLASS;
765 else if (tc.is_complex_scalar ()) 1053 else if (tc.is_complex_scalar ())
838 os.write ((char *)buf, nr*nc*2); 1126 os.write ((char *)buf, nr*nc*2);
839 1127
840 if (paddedlength > len) 1128 if (paddedlength > len)
841 os.write ((char *)buf, paddedlength - len); 1129 os.write ((char *)buf, paddedlength - len);
842 } 1130 }
1131 else if (cname == "int8")
1132 {
1133 int8NDArray m = tc.int8_array_value ();
1134
1135 write_mat5_integer_data (os, m, -1);
1136 }
1137 else if (cname == "int16")
1138 {
1139 int16NDArray m = tc.int16_array_value ();
1140
1141 write_mat5_integer_data (os, m, -2);
1142 }
1143 else if (cname == "int32")
1144 {
1145 int32NDArray m = tc.int32_array_value ();
1146
1147 write_mat5_integer_data (os, m, -4);
1148 }
1149 else if (cname == "int64")
1150 {
1151 int64NDArray m = tc.int64_array_value ();
1152
1153 write_mat5_integer_data (os, m, -8);
1154 }
1155 else if (cname == "uint8")
1156 {
1157 uint8NDArray m = tc.uint8_array_value ();
1158
1159 write_mat5_integer_data (os, m, 1);
1160 }
1161 else if (cname == "uint16")
1162 {
1163 uint16NDArray m = tc.uint16_array_value ();
1164
1165 write_mat5_integer_data (os, m, 2);
1166 }
1167 else if (cname == "uint32")
1168 {
1169 uint32NDArray m = tc.uint32_array_value ();
1170
1171 write_mat5_integer_data (os, m, 4);
1172 }
1173 else if (cname == "uint64")
1174 {
1175 uint64NDArray m = tc.uint64_array_value ();
1176
1177 write_mat5_integer_data (os, m, 8);
1178 }
843 else if (tc.is_real_scalar () || tc.is_real_matrix () || tc.is_range ()) 1179 else if (tc.is_real_scalar () || tc.is_real_matrix () || tc.is_range ())
844 { 1180 {
845 NDArray m = tc.array_value (); 1181 NDArray m = tc.array_value ();
846 1182
847 write_mat5_array (os, m, save_as_floats); 1183 write_mat5_array (os, m, save_as_floats);