Mercurial > octave-nkf
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); |