Mercurial > octave-nkf
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++ *** |