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 */