comparison src/ls-oct-binary.cc @ 4687:e95c86d48732

[project @ 2004-01-06 21:53:34 by jwe]
author jwe
date Tue, 06 Jan 2004 21:53:34 +0000
parents 79fe96966ca0
children 14dc2267c343
comparison
equal deleted inserted replaced
4686:c7ae43dfdea4 4687:e95c86d48732
97 // 97 //
98 // doc string doc_length 98 // doc string doc_length
99 // 99 //
100 // global flag integer 1 100 // global flag integer 1
101 // 101 //
102 // data type integer 1 102 // data type char 1
103 // 103 //
104 // data (one of): 104 // In general "data type" is 255, and in that case the next arguments
105 // 105 // in the data set are
106 // scalar: 106 //
107 // data real 8 107 // object type bytes
108 // 108 // ------ ---- -----
109 // complex scalar: 109 // type_length integer 4
110 // data complex 16 110 //
111 // 111 // type string type_length
112 // matrix: 112 //
113 // rows integer 4 113 // The string "type" is then used with octave_value_typeinfo::lookup_type
114 // columns integer 4 114 // to create an octave_value of the correct type. The specific load/save
115 // data real r*c*8 115 // function is then called.
116 // 116 //
117 // complex matrix: 117 // For backward compatiablity "data type" can also be a value between 1
118 // rows integer 4 118 // and 7, where this defines a hardcoded octave_value of the type
119 // columns integer 4 119 //
120 // data complex r*c*16 120 // data type octave_value
121 // 121 // --------- ------------
122 // string: 122 // 1 scalar
123 // length int 4 123 // 2 matrix
124 // data string length 124 // 3 complex scalar
125 // 125 // 4 complex matrix
126 // range: 126 // 5 string (old style storage)
127 // base real 8 127 // 6 range
128 // limit real 8 128 // 7 string
129 // increment real 8 129 //
130 // 130 // Except for "data type" equal 5 that requires special treatment, these
131 // string array 131 // old style "data type" value also cause the specific load/save functions
132 // elements int 4 132 // to be called. FILENAME is used for error messages.
133 //
134 // for each element:
135 // length int 4
136 // data string length
137 //
138 // FILENAME is used for error messages.
139 133
140 std::string 134 std::string
141 read_binary_data (std::istream& is, bool swap, 135 read_binary_data (std::istream& is, bool swap,
142 oct_mach_info::float_format fmt, 136 oct_mach_info::float_format fmt,
143 const std::string& filename, bool& global, 137 const std::string& filename, bool& global,
189 183
190 tmp = 0; 184 tmp = 0;
191 if (! is.read (X_CAST (char *, &tmp), 1)) 185 if (! is.read (X_CAST (char *, &tmp), 1))
192 goto data_read_error; 186 goto data_read_error;
193 187
188 // All cases except 255 kept for backwards compatibility
194 switch (tmp) 189 switch (tmp)
195 { 190 {
196 case 1: 191 case 1:
197 { 192 tc = octave_value_typeinfo::lookup_type ("scalar");
198 if (! is.read (X_CAST (char *, &tmp), 1))
199 goto data_read_error;
200 double dtmp;
201 read_doubles (is, &dtmp, X_CAST (save_type, tmp), 1, swap, fmt);
202 if (error_state || ! is)
203 goto data_read_error;
204 tc = dtmp;
205 }
206 break; 193 break;
207 194
208 case 2: 195 case 2:
209 { 196 tc = octave_value_typeinfo::lookup_type ("matrix");
210 FOUR_BYTE_INT nr, nc;
211 if (! is.read (X_CAST (char *, &nr), 4))
212 goto data_read_error;
213 if (swap)
214 swap_4_bytes (X_CAST (char *, &nr));
215 if (! is.read (X_CAST (char *, &nc), 4))
216 goto data_read_error;
217 if (swap)
218 swap_4_bytes (X_CAST (char *, &nc));
219 if (! is.read (X_CAST (char *, &tmp), 1))
220 goto data_read_error;
221 Matrix m (nr, nc);
222 double *re = m.fortran_vec ();
223 int len = nr * nc;
224 read_doubles (is, re, X_CAST (save_type, tmp), len, swap, fmt);
225 if (error_state || ! is)
226 goto data_read_error;
227 tc = m;
228 }
229 break; 197 break;
230 198
231 case 3: 199 case 3:
232 { 200 tc = octave_value_typeinfo::lookup_type ("complex scalar");
233 if (! is.read (X_CAST (char *, &tmp), 1))
234 goto data_read_error;
235 Complex ctmp;
236 read_doubles (is, X_CAST (double *, &ctmp),
237 X_CAST (save_type, tmp), 2, swap, fmt);
238 if (error_state || ! is)
239 goto data_read_error;
240 tc = ctmp;
241 }
242 break; 201 break;
243 202
244 case 4: 203 case 4:
245 { 204 tc = octave_value_typeinfo::lookup_type ("complex matrix");
246 FOUR_BYTE_INT nr, nc;
247 if (! is.read (X_CAST (char *, &nr), 4))
248 goto data_read_error;
249 if (swap)
250 swap_4_bytes (X_CAST (char *, &nr));
251 if (! is.read (X_CAST (char *, &nc), 4))
252 goto data_read_error;
253 if (swap)
254 swap_4_bytes (X_CAST (char *, &nc));
255 if (! is.read (X_CAST (char *, &tmp), 1))
256 goto data_read_error;
257 ComplexMatrix m (nr, nc);
258 Complex *im = m.fortran_vec ();
259 int len = nr * nc;
260 read_doubles (is, X_CAST (double *, im),
261 X_CAST (save_type, tmp), 2*len, swap, fmt);
262 if (error_state || ! is)
263 goto data_read_error;
264 tc = m;
265 }
266 break; 205 break;
267 206
268 case 5: 207 case 5:
269 { 208 {
209 // XXX FIXME XXXX
210 // This is cruft, since its for a save type that is old. Maybe
211 // this is taking backward compatability too far!!
270 FOUR_BYTE_INT len; 212 FOUR_BYTE_INT len;
271 if (! is.read (X_CAST (char *, &len), 4)) 213 if (! is.read (X_CAST (char *, &len), 4))
272 goto data_read_error; 214 goto data_read_error;
273 if (swap) 215 if (swap)
274 swap_4_bytes (X_CAST (char *, &len)); 216 swap_4_bytes (X_CAST (char *, &len));
275 OCTAVE_LOCAL_BUFFER (char, s, len+1); 217 OCTAVE_LOCAL_BUFFER (char, s, len+1);
276 if (! is.read (X_CAST (char *, s), len)) 218 if (! is.read (X_CAST (char *, s), len))
277 goto data_read_error; 219 goto data_read_error;
278 s[len] = '\0'; 220 s[len] = '\0';
279 tc = s; 221 tc = s;
222
223 // Early return, since don't want rest of this function
224 return retval;
280 } 225 }
281 break; 226 break;
282 227
283 case 6: 228 case 6:
229 tc = octave_value_typeinfo::lookup_type ("range");
230 break;
231
232 case 7:
233 tc = octave_value_typeinfo::lookup_type ("string");
234 break;
235
236 case 255:
284 { 237 {
285 if (! is.read (X_CAST (char *, &tmp), 1)) 238 // Read the saved variable type
286 goto data_read_error; 239 FOUR_BYTE_INT len;
287 double bas, lim, inc; 240 if (! is.read (X_CAST (char *, &len), 4))
288 if (! is.read (X_CAST (char *, &bas), 8))
289 goto data_read_error; 241 goto data_read_error;
290 if (swap) 242 if (swap)
291 swap_8_bytes (X_CAST (char *, &bas)); 243 swap_4_bytes (X_CAST (char *, &len));
292 if (! is.read (X_CAST (char *, &lim), 8)) 244 OCTAVE_LOCAL_BUFFER (char, s, len+1);
245 if (! is.read (X_CAST (char *, s), len))
293 goto data_read_error; 246 goto data_read_error;
294 if (swap) 247 s[len] = '\0';
295 swap_8_bytes (X_CAST (char *, &lim)); 248 std::string typ = s;
296 if (! is.read (X_CAST (char *, &inc), 8)) 249 tc = octave_value_typeinfo::lookup_type (typ);
297 goto data_read_error;
298 if (swap)
299 swap_8_bytes (X_CAST (char *, &inc));
300 Range r (bas, lim, inc);
301 tc = r;
302 } 250 }
303 break; 251 break;
304
305 case 7:
306 {
307 FOUR_BYTE_INT elements;
308 if (! is.read (X_CAST (char *, &elements), 4))
309 goto data_read_error;
310 if (swap)
311 swap_4_bytes (X_CAST (char *, &elements));
312 charMatrix chm (elements, 0);
313 int max_len = 0;
314 for (int i = 0; i < elements; i++)
315 {
316 FOUR_BYTE_INT len;
317 if (! is.read (X_CAST (char *, &len), 4))
318 goto data_read_error;
319 if (swap)
320 swap_4_bytes (X_CAST (char *, &len));
321 OCTAVE_LOCAL_BUFFER (char, btmp, len+1);
322 if (! is.read (X_CAST (char *, btmp), len))
323 goto data_read_error;
324 if (len > max_len)
325 {
326 max_len = len;
327 chm.resize (elements, max_len, 0);
328 }
329 btmp [len] = '\0';
330 chm.insert (btmp, i, 0);
331 }
332 tc = octave_value (chm, true);
333 }
334 break;
335
336 default: 252 default:
253 goto data_read_error;
254 break;
255 }
256
257 if (!tc.load_binary (is, swap, fmt))
258 {
337 data_read_error: 259 data_read_error:
338 error ("load: trouble reading binary file `%s'", filename.c_str ()); 260 error ("load: trouble reading binary file `%s'", filename.c_str ());
339 break;
340 } 261 }
341 262
342 return retval; 263 return retval;
343 } 264 }
344 265
364 char tmp; 285 char tmp;
365 286
366 tmp = mark_as_global; 287 tmp = mark_as_global;
367 os.write (X_CAST (char *, &tmp), 1); 288 os.write (X_CAST (char *, &tmp), 1);
368 289
369 if (tc.is_string ()) 290 // 255 flags the new binary format
370 { 291 tmp = 255;
371 tmp = 7; 292 os.write (X_CAST (char *, &tmp), 1);
372 os.write (X_CAST (char *, &tmp), 1); 293
373 FOUR_BYTE_INT nr = tc.rows (); 294 // Write the string corresponding to the octave_value type
374 os.write (X_CAST (char *, &nr), 4); 295 std::string typ = tc.type_name ();
375 charMatrix chm = tc.char_matrix_value (); 296 FOUR_BYTE_INT len = typ.length ();
376 for (int i = 0; i < nr; i++) 297 os.write (X_CAST (char *, &len), 4);
377 { 298 const char *btmp = typ.data ();
378 FOUR_BYTE_INT len = chm.cols (); 299 os.write (X_CAST (char *, btmp), len);
379 os.write (X_CAST (char *, &len), 4); 300
380 std::string tstr = chm.row_as_string (i); 301 // The octave_value of tc is const. Make a copy...
381 const char *btmp = tstr.data (); 302 octave_value val = tc;
382 os.write (X_CAST (char *, btmp), len); 303
383 } 304 // Call specific save function
384 } 305 bool success = val.save_binary (os, save_as_floats);
385 else if (tc.is_range ()) 306
386 { 307 return (os && success);
387 tmp = 6;
388 os.write (X_CAST (char *, &tmp), 1);
389 tmp = (char) LS_DOUBLE;
390 os.write (X_CAST (char *, &tmp), 1);
391 Range r = tc.range_value ();
392 double bas = r.base ();
393 double lim = r.limit ();
394 double inc = r.inc ();
395 os.write (X_CAST (char *, &bas), 8);
396 os.write (X_CAST (char *, &lim), 8);
397 os.write (X_CAST (char *, &inc), 8);
398 }
399 else if (tc.is_real_scalar ())
400 {
401 tmp = 1;
402 os.write (X_CAST (char *, &tmp), 1);
403 tmp = (char) LS_DOUBLE;
404 os.write (X_CAST (char *, &tmp), 1);
405 double dtmp = tc.double_value ();
406 os.write (X_CAST (char *, &dtmp), 8);
407 }
408 else if (tc.is_real_matrix ())
409 {
410 tmp = 2;
411 os.write (X_CAST (char *, &tmp), 1);
412 Matrix m = tc.matrix_value ();
413 FOUR_BYTE_INT nr = m.rows ();
414 FOUR_BYTE_INT nc = m.columns ();
415 os.write (X_CAST (char *, &nr), 4);
416 os.write (X_CAST (char *, &nc), 4);
417 int len = nr * nc;
418 save_type st = LS_DOUBLE;
419 if (save_as_floats)
420 {
421 if (m.too_large_for_float ())
422 {
423 warning ("save: some values too large to save as floats --");
424 warning ("save: saving as doubles instead");
425 }
426 else
427 st = LS_FLOAT;
428 }
429 else if (len > 8192) // XXX FIXME XXX -- make this configurable.
430 {
431 double max_val, min_val;
432 if (m.all_integers (max_val, min_val))
433 st = get_save_type (max_val, min_val);
434 }
435 const double *mtmp = m.data ();
436 write_doubles (os, mtmp, st, len);
437 }
438 else if (tc.is_complex_scalar ())
439 {
440 tmp = 3;
441 os.write (X_CAST (char *, &tmp), 1);
442 tmp = (char) LS_DOUBLE;
443 os.write (X_CAST (char *, &tmp), 1);
444 Complex ctmp = tc.complex_value ();
445 os.write (X_CAST (char *, &ctmp), 16);
446 }
447 else if (tc.is_complex_matrix ())
448 {
449 tmp = 4;
450 os.write (X_CAST (char *, &tmp), 1);
451 ComplexMatrix m = tc.complex_matrix_value ();
452 FOUR_BYTE_INT nr = m.rows ();
453 FOUR_BYTE_INT nc = m.columns ();
454 os.write (X_CAST (char *, &nr), 4);
455 os.write (X_CAST (char *, &nc), 4);
456 int len = nr * nc;
457 save_type st = LS_DOUBLE;
458 if (save_as_floats)
459 {
460 if (m.too_large_for_float ())
461 {
462 warning ("save: some values too large to save as floats --");
463 warning ("save: saving as doubles instead");
464 }
465 else
466 st = LS_FLOAT;
467 }
468 else if (len > 4096) // XXX FIXME XXX -- make this configurable.
469 {
470 double max_val, min_val;
471 if (m.all_integers (max_val, min_val))
472 st = get_save_type (max_val, min_val);
473 }
474 const Complex *mtmp = m.data ();
475 write_doubles (os, X_CAST (const double *, mtmp), st, 2*len);
476 }
477 else
478 gripe_wrong_type_arg ("save", tc, false);
479
480 return os;
481 } 308 }
482 309
483 /* 310 /*
484 ;;; Local Variables: *** 311 ;;; Local Variables: ***
485 ;;; mode: C++ *** 312 ;;; mode: C++ ***