Mercurial > hg > octave-lyh
comparison liboctave/data-conv.cc @ 1960:285a7f683a4c
[project @ 1996-02-16 04:03:01 by jwe]
Initial revision
author | jwe |
---|---|
date | Fri, 16 Feb 1996 04:03:01 +0000 |
parents | |
children | 1b57120c997b |
comparison
equal
deleted
inserted
replaced
1959:9fae6fc592f2 | 1960:285a7f683a4c |
---|---|
1 // data-conv.cc -*- C++ -*- | |
2 /* | |
3 | |
4 Copyright (C) 1996 John W. Eaton | |
5 | |
6 This file is part of Octave. | |
7 | |
8 Octave is free software; you can redistribute it and/or modify it | |
9 under the terms of the GNU General Public License as published by the | |
10 Free Software Foundation; either version 2, or (at your option) any | |
11 later version. | |
12 | |
13 Octave is distributed in the hope that it will be useful, but WITHOUT | |
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 for more details. | |
17 | |
18 You should have received a copy of the GNU General Public License | |
19 along with Octave; see the file COPYING. If not, write to the Free | |
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
21 | |
22 */ | |
23 | |
24 #ifdef HAVE_CONFIG_H | |
25 #include <config.h> | |
26 #endif | |
27 | |
28 #include <iostream.h> | |
29 | |
30 #include "byte-swap.h" | |
31 #include "data-conv.h" | |
32 #include "lo-error.h" | |
33 | |
34 #define swap_1_bytes(x, y) | |
35 | |
36 #define LS_DO_READ(TYPE,swap,data,size,len,stream) \ | |
37 do \ | |
38 { \ | |
39 volatile TYPE *ptr = (TYPE *) data; \ | |
40 stream.read ((TYPE *) ptr, size * len); \ | |
41 if (swap) \ | |
42 swap_ ## size ## _bytes ((char *) ptr, len); \ | |
43 TYPE tmp = ptr[0]; \ | |
44 for (int i = len - 1; i > 0; i--) \ | |
45 data[i] = ptr[i]; \ | |
46 data[0] = tmp; \ | |
47 } \ | |
48 while (0) | |
49 | |
50 // Have to use copy here to avoid writing over data accessed via | |
51 // Matrix::data(). | |
52 | |
53 #define LS_DO_WRITE(TYPE,data,size,len,stream) \ | |
54 do \ | |
55 { \ | |
56 char tmp_type = (char) type; \ | |
57 stream.write (&tmp_type, 1); \ | |
58 TYPE *ptr = new TYPE [len]; \ | |
59 for (int i = 0; i < len; i++) \ | |
60 ptr[i] = (TYPE) data[i]; \ | |
61 stream.write ((TYPE *) ptr, size * len); \ | |
62 delete [] ptr ; \ | |
63 } \ | |
64 while (0) | |
65 | |
66 // Loading variables from files. | |
67 | |
68 static void | |
69 gripe_unrecognized_float_fmt (void) | |
70 { | |
71 (*current_liboctave_error_handler) | |
72 ("unrecognized floating point format requested"); | |
73 } | |
74 | |
75 static void | |
76 gripe_data_conversion (const char *from, const char *to) | |
77 { | |
78 (*current_liboctave_error_handler) | |
79 ("unable to convert from %s to %s format", from, to); | |
80 } | |
81 | |
82 // But first, some data conversion routines. | |
83 | |
84 // Currently, we only handle conversions for the IEEE types. To fix | |
85 // that, make more of the following routines work. | |
86 | |
87 // XXX FIXME XXX -- assumes sizeof (Complex) == 8 | |
88 // XXX FIXME XXX -- assumes sizeof (double) == 8 | |
89 // XXX FIXME XXX -- assumes sizeof (float) == 4 | |
90 | |
91 static void | |
92 IEEE_big_double_to_IEEE_little_double (double *d, int len) | |
93 { | |
94 swap_8_bytes ((char *) d, len); | |
95 } | |
96 | |
97 static void | |
98 VAX_D_double_to_IEEE_little_double (double * /* d */, int /* len */) | |
99 { | |
100 gripe_data_conversion ("VAX D float", "IEEE little endian format"); | |
101 } | |
102 | |
103 static void | |
104 VAX_G_double_to_IEEE_little_double (double * /* d */, int /* len */) | |
105 { | |
106 gripe_data_conversion ("VAX G float", "IEEE little endian format"); | |
107 } | |
108 | |
109 static void | |
110 Cray_to_IEEE_little_double (double * /* d */, int /* len */) | |
111 { | |
112 gripe_data_conversion ("Cray", "IEEE little endian format"); | |
113 } | |
114 | |
115 static void | |
116 IEEE_big_float_to_IEEE_little_float (float *d, int len) | |
117 { | |
118 swap_4_bytes ((char *) d, len); | |
119 } | |
120 | |
121 static void | |
122 VAX_D_float_to_IEEE_little_float (float * /* d */, int /* len */) | |
123 { | |
124 gripe_data_conversion ("VAX D float", "IEEE little endian format"); | |
125 } | |
126 | |
127 static void | |
128 VAX_G_float_to_IEEE_little_float (float * /* d */, int /* len */) | |
129 { | |
130 gripe_data_conversion ("VAX G float", "IEEE little endian format"); | |
131 } | |
132 | |
133 static void | |
134 Cray_to_IEEE_little_float (float * /* d */, int /* len */) | |
135 { | |
136 gripe_data_conversion ("Cray", "IEEE little endian format"); | |
137 } | |
138 | |
139 static void | |
140 IEEE_little_double_to_IEEE_big_double (double *d, int len) | |
141 { | |
142 swap_8_bytes ((char *) d, len); | |
143 } | |
144 | |
145 static void | |
146 VAX_D_double_to_IEEE_big_double (double * /* d */, int /* len */) | |
147 { | |
148 gripe_data_conversion ("VAX D float", "IEEE big endian format"); | |
149 } | |
150 | |
151 static void | |
152 VAX_G_double_to_IEEE_big_double (double * /* d */, int /* len */) | |
153 { | |
154 gripe_data_conversion ("VAX G float", "IEEE big endian format"); | |
155 } | |
156 | |
157 static void | |
158 Cray_to_IEEE_big_double (double * /* d */, int /* len */) | |
159 { | |
160 gripe_data_conversion ("Cray", "IEEE big endian format"); | |
161 } | |
162 | |
163 static void | |
164 IEEE_little_float_to_IEEE_big_float (float *d, int len) | |
165 { | |
166 swap_4_bytes ((char *) d, len); | |
167 } | |
168 | |
169 static void | |
170 VAX_D_float_to_IEEE_big_float (float * /* d */, int /* len */) | |
171 { | |
172 gripe_data_conversion ("VAX D float", "IEEE big endian format"); | |
173 } | |
174 | |
175 static void | |
176 VAX_G_float_to_IEEE_big_float (float * /* d */, int /* len */) | |
177 { | |
178 gripe_data_conversion ("VAX G float", "IEEE big endian format"); | |
179 } | |
180 | |
181 static void | |
182 Cray_to_IEEE_big_float (float * /* d */, int /* len */) | |
183 { | |
184 gripe_data_conversion ("Cray", "IEEE big endian format"); | |
185 } | |
186 | |
187 static void | |
188 IEEE_little_double_to_VAX_D_double (double * /* d */, int /* len */) | |
189 { | |
190 gripe_data_conversion ("IEEE little endian", "VAX D"); | |
191 } | |
192 | |
193 static void | |
194 IEEE_big_double_to_VAX_D_double (double * /* d */, int /* len */) | |
195 { | |
196 gripe_data_conversion ("IEEE big endian", "VAX D"); | |
197 } | |
198 | |
199 static void | |
200 VAX_G_double_to_VAX_D_double (double * /* d */, int /* len */) | |
201 { | |
202 gripe_data_conversion ("VAX G float", "VAX D"); | |
203 } | |
204 | |
205 static void | |
206 Cray_to_VAX_D_double (double * /* d */, int /* len */) | |
207 { | |
208 gripe_data_conversion ("Cray", "VAX D"); | |
209 } | |
210 | |
211 static void | |
212 IEEE_little_float_to_VAX_D_float (float * /* d */, int /* len */) | |
213 { | |
214 gripe_data_conversion ("IEEE little endian", "VAX D"); | |
215 } | |
216 | |
217 static void | |
218 IEEE_big_float_to_VAX_D_float (float * /* d */, int /* len */) | |
219 { | |
220 gripe_data_conversion ("IEEE big endian", "VAX D"); | |
221 } | |
222 | |
223 static void | |
224 VAX_G_float_to_VAX_D_float (float * /* d */, int /* len */) | |
225 { | |
226 gripe_data_conversion ("VAX G float", "VAX D"); | |
227 } | |
228 | |
229 static void | |
230 Cray_to_VAX_D_float (float * /* d */, int /* len */) | |
231 { | |
232 gripe_data_conversion ("Cray", "VAX D"); | |
233 } | |
234 | |
235 static void | |
236 IEEE_little_double_to_VAX_G_double (double * /* d */, int /* len */) | |
237 { | |
238 gripe_data_conversion ("IEEE little endian", "VAX G"); | |
239 } | |
240 | |
241 static void | |
242 IEEE_big_double_to_VAX_G_double (double * /* d */, int /* len */) | |
243 { | |
244 gripe_data_conversion ("IEEE big endian", "VAX G"); | |
245 } | |
246 | |
247 static void | |
248 VAX_D_double_to_VAX_G_double (double * /* d */, int /* len */) | |
249 { | |
250 gripe_data_conversion ("VAX D float", "VAX G"); | |
251 } | |
252 | |
253 static void | |
254 Cray_to_VAX_G_double (double * /* d */, int /* len */) | |
255 { | |
256 gripe_data_conversion ("VAX G float", "VAX G"); | |
257 } | |
258 | |
259 static void | |
260 IEEE_little_float_to_VAX_G_float (float * /* d */, int /* len */) | |
261 { | |
262 gripe_data_conversion ("IEEE little endian", "VAX G"); | |
263 } | |
264 | |
265 static void | |
266 IEEE_big_float_to_VAX_G_float (float * /* d */, int /* len */) | |
267 { | |
268 gripe_data_conversion ("IEEE big endian", "VAX G"); | |
269 } | |
270 | |
271 static void | |
272 VAX_D_float_to_VAX_G_float (float * /* d */, int /* len */) | |
273 { | |
274 gripe_data_conversion ("VAX D float", "VAX G"); | |
275 } | |
276 | |
277 static void | |
278 Cray_to_VAX_G_float (float * /* d */, int /* len */) | |
279 { | |
280 gripe_data_conversion ("VAX G float", "VAX G"); | |
281 } | |
282 | |
283 void | |
284 do_double_format_conversion (double *data, int len, | |
285 floating_point_format fmt) | |
286 { | |
287 switch (native_float_format) | |
288 { | |
289 case OCTAVE_IEEE_LITTLE: | |
290 switch (fmt) | |
291 { | |
292 case OCTAVE_IEEE_LITTLE: | |
293 break; | |
294 | |
295 case OCTAVE_IEEE_BIG: | |
296 IEEE_big_double_to_IEEE_little_double (data, len); | |
297 break; | |
298 | |
299 case OCTAVE_VAX_D: | |
300 VAX_D_double_to_IEEE_little_double (data, len); | |
301 break; | |
302 | |
303 case OCTAVE_VAX_G: | |
304 VAX_G_double_to_IEEE_little_double (data, len); | |
305 break; | |
306 | |
307 case OCTAVE_CRAY: | |
308 Cray_to_IEEE_little_double (data, len); | |
309 break; | |
310 | |
311 default: | |
312 gripe_unrecognized_float_fmt (); | |
313 break; | |
314 } | |
315 break; | |
316 | |
317 case OCTAVE_IEEE_BIG: | |
318 switch (fmt) | |
319 { | |
320 case OCTAVE_IEEE_LITTLE: | |
321 IEEE_little_double_to_IEEE_big_double (data, len); | |
322 break; | |
323 | |
324 case OCTAVE_IEEE_BIG: | |
325 break; | |
326 | |
327 case OCTAVE_VAX_D: | |
328 VAX_D_double_to_IEEE_big_double (data, len); | |
329 break; | |
330 | |
331 case OCTAVE_VAX_G: | |
332 VAX_G_double_to_IEEE_big_double (data, len); | |
333 break; | |
334 | |
335 case OCTAVE_CRAY: | |
336 Cray_to_IEEE_big_double (data, len); | |
337 break; | |
338 | |
339 default: | |
340 gripe_unrecognized_float_fmt (); | |
341 break; | |
342 } | |
343 break; | |
344 | |
345 case OCTAVE_VAX_D: | |
346 switch (fmt) | |
347 { | |
348 case OCTAVE_IEEE_LITTLE: | |
349 IEEE_little_double_to_VAX_D_double (data, len); | |
350 break; | |
351 | |
352 case OCTAVE_IEEE_BIG: | |
353 IEEE_big_double_to_VAX_D_double (data, len); | |
354 break; | |
355 | |
356 case OCTAVE_VAX_D: | |
357 break; | |
358 | |
359 case OCTAVE_VAX_G: | |
360 VAX_G_double_to_VAX_D_double (data, len); | |
361 break; | |
362 | |
363 case OCTAVE_CRAY: | |
364 Cray_to_VAX_D_double (data, len); | |
365 break; | |
366 | |
367 default: | |
368 gripe_unrecognized_float_fmt (); | |
369 break; | |
370 } | |
371 break; | |
372 | |
373 case OCTAVE_VAX_G: | |
374 switch (fmt) | |
375 { | |
376 case OCTAVE_IEEE_LITTLE: | |
377 IEEE_little_double_to_VAX_G_double (data, len); | |
378 break; | |
379 | |
380 case OCTAVE_IEEE_BIG: | |
381 IEEE_big_double_to_VAX_G_double (data, len); | |
382 break; | |
383 | |
384 case OCTAVE_VAX_D: | |
385 VAX_D_double_to_VAX_G_double (data, len); | |
386 break; | |
387 | |
388 case OCTAVE_VAX_G: | |
389 break; | |
390 | |
391 case OCTAVE_CRAY: | |
392 Cray_to_VAX_G_double (data, len); | |
393 break; | |
394 | |
395 default: | |
396 gripe_unrecognized_float_fmt (); | |
397 break; | |
398 } | |
399 break; | |
400 | |
401 default: | |
402 (*current_liboctave_error_handler) | |
403 ("impossible state reached in file `%s' at line %d", | |
404 __FILE__, __LINE__); | |
405 break; | |
406 } | |
407 } | |
408 | |
409 void | |
410 do_float_format_conversion (float *data, int len, | |
411 floating_point_format fmt) | |
412 { | |
413 switch (native_float_format) | |
414 { | |
415 case OCTAVE_IEEE_LITTLE: | |
416 switch (fmt) | |
417 { | |
418 case OCTAVE_IEEE_LITTLE: | |
419 break; | |
420 | |
421 case OCTAVE_IEEE_BIG: | |
422 IEEE_big_float_to_IEEE_little_float (data, len); | |
423 break; | |
424 | |
425 case OCTAVE_VAX_D: | |
426 VAX_D_float_to_IEEE_little_float (data, len); | |
427 break; | |
428 | |
429 case OCTAVE_VAX_G: | |
430 VAX_G_float_to_IEEE_little_float (data, len); | |
431 break; | |
432 | |
433 case OCTAVE_CRAY: | |
434 Cray_to_IEEE_little_float (data, len); | |
435 break; | |
436 | |
437 default: | |
438 gripe_unrecognized_float_fmt (); | |
439 break; | |
440 } | |
441 break; | |
442 | |
443 case OCTAVE_IEEE_BIG: | |
444 switch (fmt) | |
445 { | |
446 case OCTAVE_IEEE_LITTLE: | |
447 IEEE_little_float_to_IEEE_big_float (data, len); | |
448 break; | |
449 | |
450 case OCTAVE_IEEE_BIG: | |
451 break; | |
452 | |
453 case OCTAVE_VAX_D: | |
454 VAX_D_float_to_IEEE_big_float (data, len); | |
455 break; | |
456 | |
457 case OCTAVE_VAX_G: | |
458 VAX_G_float_to_IEEE_big_float (data, len); | |
459 break; | |
460 | |
461 case OCTAVE_CRAY: | |
462 Cray_to_IEEE_big_float (data, len); | |
463 break; | |
464 | |
465 default: | |
466 gripe_unrecognized_float_fmt (); | |
467 break; | |
468 } | |
469 break; | |
470 | |
471 case OCTAVE_VAX_D: | |
472 switch (fmt) | |
473 { | |
474 case OCTAVE_IEEE_LITTLE: | |
475 IEEE_little_float_to_VAX_D_float (data, len); | |
476 break; | |
477 | |
478 case OCTAVE_IEEE_BIG: | |
479 IEEE_big_float_to_VAX_D_float (data, len); | |
480 break; | |
481 | |
482 case OCTAVE_VAX_D: | |
483 break; | |
484 | |
485 case OCTAVE_VAX_G: | |
486 VAX_G_float_to_VAX_D_float (data, len); | |
487 break; | |
488 | |
489 case OCTAVE_CRAY: | |
490 Cray_to_VAX_D_float (data, len); | |
491 break; | |
492 | |
493 default: | |
494 gripe_unrecognized_float_fmt (); | |
495 break; | |
496 } | |
497 break; | |
498 | |
499 case OCTAVE_VAX_G: | |
500 switch (fmt) | |
501 { | |
502 case OCTAVE_IEEE_LITTLE: | |
503 IEEE_little_float_to_VAX_G_float (data, len); | |
504 break; | |
505 | |
506 case OCTAVE_IEEE_BIG: | |
507 IEEE_big_float_to_VAX_G_float (data, len); | |
508 break; | |
509 | |
510 case OCTAVE_VAX_D: | |
511 VAX_D_float_to_VAX_G_float (data, len); | |
512 break; | |
513 | |
514 case OCTAVE_VAX_G: | |
515 break; | |
516 | |
517 case OCTAVE_CRAY: | |
518 Cray_to_VAX_G_float (data, len); | |
519 break; | |
520 | |
521 default: | |
522 gripe_unrecognized_float_fmt (); | |
523 break; | |
524 } | |
525 break; | |
526 | |
527 default: | |
528 (*current_liboctave_error_handler) | |
529 ("impossible state reached in file `%s' at line %d", | |
530 __FILE__, __LINE__); | |
531 break; | |
532 } | |
533 } | |
534 | |
535 void | |
536 read_doubles (istream& is, double *data, save_type type, int len, | |
537 int swap, floating_point_format fmt) | |
538 { | |
539 switch (type) | |
540 { | |
541 case LS_U_CHAR: | |
542 LS_DO_READ (unsigned char, swap, data, 1, len, is); | |
543 break; | |
544 | |
545 case LS_U_SHORT: | |
546 LS_DO_READ (unsigned TWO_BYTE_INT, swap, data, 2, len, is); | |
547 break; | |
548 | |
549 case LS_U_INT: | |
550 LS_DO_READ (unsigned FOUR_BYTE_INT, swap, data, 4, len, is); | |
551 break; | |
552 | |
553 case LS_CHAR: | |
554 LS_DO_READ (signed char, swap, data, 1, len, is); | |
555 break; | |
556 | |
557 case LS_SHORT: | |
558 LS_DO_READ (TWO_BYTE_INT, swap, data, 2, len, is); | |
559 break; | |
560 | |
561 case LS_INT: | |
562 LS_DO_READ (FOUR_BYTE_INT, swap, data, 4, len, is); | |
563 break; | |
564 | |
565 case LS_FLOAT: | |
566 { | |
567 volatile float *ptr = (float *) data; | |
568 is.read (data, 4 * len); | |
569 do_float_format_conversion ((float *) data, len, fmt); | |
570 float tmp = ptr[0]; | |
571 for (int i = len - 1; i > 0; i--) | |
572 data[i] = ptr[i]; | |
573 data[0] = tmp; | |
574 } | |
575 break; | |
576 | |
577 case LS_DOUBLE: | |
578 is.read (data, 8 * len); | |
579 do_double_format_conversion (data, len, fmt); | |
580 break; | |
581 | |
582 default: | |
583 is.clear (ios::failbit|is.rdstate ()); | |
584 break; | |
585 } | |
586 } | |
587 | |
588 void | |
589 write_doubles (ostream& os, const double *data, save_type type, int len) | |
590 { | |
591 switch (type) | |
592 { | |
593 case LS_U_CHAR: | |
594 LS_DO_WRITE (unsigned char, data, 1, len, os); | |
595 break; | |
596 | |
597 case LS_U_SHORT: | |
598 LS_DO_WRITE (unsigned TWO_BYTE_INT, data, 2, len, os); | |
599 break; | |
600 | |
601 case LS_U_INT: | |
602 LS_DO_WRITE (unsigned FOUR_BYTE_INT, data, 4, len, os); | |
603 break; | |
604 | |
605 case LS_CHAR: | |
606 LS_DO_WRITE (signed char, data, 1, len, os); | |
607 break; | |
608 | |
609 case LS_SHORT: | |
610 LS_DO_WRITE (TWO_BYTE_INT, data, 2, len, os); | |
611 break; | |
612 | |
613 case LS_INT: | |
614 LS_DO_WRITE (FOUR_BYTE_INT, data, 4, len, os); | |
615 break; | |
616 | |
617 case LS_FLOAT: | |
618 LS_DO_WRITE (float, data, 4, len, os); | |
619 break; | |
620 | |
621 case LS_DOUBLE: | |
622 { | |
623 char tmp_type = (char) type; | |
624 os.write (&tmp_type, 1); | |
625 os.write (data, 8 * len); | |
626 } | |
627 break; | |
628 | |
629 default: | |
630 (*current_liboctave_error_handler) | |
631 ("unrecognized data format requested"); | |
632 break; | |
633 } | |
634 } | |
635 | |
636 /* | |
637 ;;; Local Variables: *** | |
638 ;;; mode: C++ *** | |
639 ;;; page-delimiter: "^/\\*" *** | |
640 ;;; End: *** | |
641 */ |