changeset 2317:8c09c04f7747

[project @ 1996-07-14 22:30:15 by jwe]
author jwe
date Sun, 14 Jul 1996 22:40:35 +0000
parents fbc76f6e4893
children 31e7eb125d89
files liboctave/dMatrix.cc liboctave/dMatrix.h liboctave/data-conv.cc liboctave/data-conv.h liboctave/mach-info.cc liboctave/mach-info.h src/oct-fstrm.cc src/oct-fstrm.h src/oct-iostrm.h src/oct-prcstrm.cc src/oct-prcstrm.h src/oct-stdstrm.cc src/oct-stdstrm.h src/oct-stream.cc src/oct-stream.h src/oct-strstrm.h src/pr-output.cc src/sysdep.cc src/sysdep.h
diffstat 19 files changed, 941 insertions(+), 756 deletions(-) [+]
line wrap: on
line diff
--- a/liboctave/dMatrix.cc
+++ b/liboctave/dMatrix.cc
@@ -30,13 +30,10 @@
 #endif
 
 #include <cfloat>
-#include <cstdio>
-#include <cstring>
 
 #include <iostream.h>
 
-#include <sys/types.h>  // XXX FIXME XXX
-
+#include "byte-swap.h"
 #include "dbleAEPBAL.h"
 #include "dbleDET.h"
 #include "dbleSCHUR.h"
@@ -2521,164 +2518,497 @@
   return is;
 }
 
-// Read an array of data from a file in binary format.
+template <class T>
+static void
+read_int (istream& is, bool swap_bytes, T& val)
+{
+  is.read ((char *) &val, sizeof (T));
+
+  if (swap_bytes)
+    {
+      switch (sizeof (T))
+	{
+	case 1:
+	  break;
+
+	case 2:
+	  swap_2_bytes ((char *) &val);
+	  break;
+
+	case 4:
+	  swap_4_bytes ((char *) &val);
+	  break;
+
+	case 8:
+	  swap_8_bytes ((char *) &val);
+	  break;
+
+	default:
+	  (*current_liboctave_error_handler)
+	    ("read_int: unrecognized data format!");
+	}
+    }
+}
+
+template void read_int (istream&, bool, char&);
+template void read_int (istream&, bool, signed char&);
+template void read_int (istream&, bool, unsigned char&);
+template void read_int (istream&, bool, short&);
+template void read_int (istream&, bool, unsigned short&);
+template void read_int (istream&, bool, int&);
+template void read_int (istream&, bool, unsigned int&);
+template void read_int (istream&, bool, long&);
+template void read_int (istream&, bool, unsigned long&);
+
+static inline bool
+do_read (istream& is, oct_data_conv::data_type dt, 
+	 oct_mach_info::float_format flt_fmt, bool swap_bytes,
+	 bool do_float_conversion, double& val)
+{
+  bool retval = true;
+
+  switch (dt)
+    {
+    case oct_data_conv::dt_char:
+      {
+	char tmp;
+	read_int (is, swap_bytes, tmp);
+	val = tmp;
+      }
+      break;
+
+    case oct_data_conv::dt_schar:
+      {
+	signed char tmp;
+	read_int (is, swap_bytes, tmp);
+	val = tmp;
+      }
+      break;
+
+    case oct_data_conv::dt_uchar:
+      {
+	unsigned char tmp;
+	read_int (is, swap_bytes, tmp);
+	val = tmp;
+      }
+      break;
+
+    case oct_data_conv::dt_short:
+      {
+	short tmp;
+	read_int (is, swap_bytes, tmp);
+	val = tmp;
+      }
+      break;
+
+    case oct_data_conv::dt_ushort:
+      {
+	unsigned short tmp;
+	read_int (is, swap_bytes, tmp);
+	val = tmp;
+      }
+      break;
+
+    case oct_data_conv::dt_int:
+      {
+	int tmp;
+	read_int (is, swap_bytes, tmp);
+	val = tmp;
+      }
+      break;
+
+    case oct_data_conv::dt_uint:
+      {
+	unsigned int tmp;
+	read_int (is, swap_bytes, tmp);
+	val = tmp;
+      }
+      break;
+
+    case oct_data_conv::dt_long:
+      {
+	long tmp;
+	read_int (is, swap_bytes, tmp);
+	val = tmp;
+      }
+      break;
+
+    case oct_data_conv::dt_ulong:
+      {
+	unsigned long tmp;
+	read_int (is, swap_bytes, tmp);
+	val = tmp;
+      }
+      break;
+
+    case oct_data_conv::dt_float:
+      {
+	float f;
+
+	is.read ((char *) &f, sizeof (float));
+
+	if (do_float_conversion)
+	  do_float_format_conversion (&f, 1, flt_fmt);
+
+	val = f;
+      }
+      break;
+
+    case oct_data_conv::dt_double:
+      {
+	is.read ((char *) &val, sizeof (double));
+
+	if (do_float_conversion)
+	  do_double_format_conversion (&val, 1, flt_fmt);
+      }
+      break;
+
+    default:
+      retval = false;
+      (*current_liboctave_error_handler)
+	("read: invalid type specification");
+      break;
+    }
+
+  return retval;
+}
 
 int
-Matrix::read (FILE *fptr, const char *type)
+Matrix::read (istream& is, int nr, int nc,
+	      oct_data_conv::data_type dt, int skip,
+	      oct_mach_info::float_format flt_fmt)
 {
-  // Allocate buffer pointers.
-
-  union
-    {
-      void *vd;
-      char *ch;
-      u_char *uc;
-      short *sh;
-      u_short *us;
-      int *in;
-      u_int *ui;
-      long *ln;
-      u_long *ul;
-      float *fl;
-      double *db;
-    }
-  buf;
-
-  // Convert data to double.
-
-  if (! type)
+  int retval = -1;
+
+  bool ok = true;
+
+  int count = 0;
+
+  double *data = 0;
+  int max_size = 0;
+
+  int final_nr = 0;
+  int final_nc = 0;
+
+  if (nr > 0)
     {
-      (*current_liboctave_error_handler)
-	("fread: invalid NULL type parameter");
-      return 0;
-    }    
-
-  int count;
-  int nitems = length ();
-
-  double *d = fortran_vec (); // Ensures only one reference to my privates!
-
-#define DO_FREAD(TYPE,ELEM) \
-  do \
-    { \
-      size_t size = sizeof (TYPE); \
-      buf.ch = new char [size * nitems]; \
-      count = fread (buf.ch, size, nitems, fptr); \
-      for (int k = 0; k < count; k++) \
-	d[k] = buf.ELEM[k]; \
-      delete [] buf.ch; \
-    } \
-  while (0)
-
-  if (strcasecmp (type, "double") == 0)
-    DO_FREAD (double, db);
-  else if (strcasecmp (type, "char") == 0)
-    DO_FREAD (char, ch);
-  else if (strcasecmp (type, "uchar") == 0)
-    DO_FREAD (u_char, uc);
-  else if (strcasecmp (type, "short") == 0)
-    DO_FREAD (short, sh);
-  else if (strcasecmp (type, "ushort") == 0)
-    DO_FREAD (u_short, us);
-  else if (strcasecmp (type, "int") == 0)
-    DO_FREAD (int, in);
-  else if (strcasecmp (type, "uint") == 0)
-    DO_FREAD (u_int, ui);
-  else if (strcasecmp (type, "long") == 0)
-    DO_FREAD (long, ul);
-  else if (strcasecmp (type, "float") == 0)
-    DO_FREAD (float, fl);
+      if (nc > 0)
+	{
+	  resize (nr, nc, 0.0);
+	  data = fortran_vec ();
+	  max_size = nr * nc;
+	}
+      else
+	{
+	  resize (nr, 32, 0.0);
+	  data = fortran_vec ();
+	  max_size = nr * 32;
+	}
+    }
   else
     {
-      (*current_liboctave_error_handler)
-	("fread: invalid NULL type parameter");
-      return 0;
+      resize (32, 1, 0.0);
+      data = fortran_vec ();
+      max_size = 32;
+    }
+
+  oct_mach_info::float_format native_flt_fmt
+    = oct_mach_info::float_format ();
+
+  bool do_float_conversion = (flt_fmt != native_flt_fmt);
+
+  // XXX FIXME XXX -- byte order for Cray?
+
+  bool swap_bytes = false;
+
+  if (oct_mach_info::words_big_endian ())
+    swap_bytes = (flt_fmt == oct_mach_info::ieee_little_endian
+		 || flt_fmt == oct_mach_info::vax_g
+		 || flt_fmt == oct_mach_info::vax_g);
+  else
+    swap_bytes = (flt_fmt == oct_mach_info::ieee_big_endian);
+
+  for (;;)
+    {
+      // XXX FIXME XXX -- maybe there should be a special case for
+      // skip == 0.
+
+      if (is)
+	{
+	  if (nr > 0 && nc > 0 && count == max_size)
+	    {
+	      final_nr = nr;
+	      final_nc = nc;
+
+	      break;
+	    }
+
+	  if (skip != 0)
+	    is.seekg (skip, ios::cur);
+
+	  if (is)
+	    {
+	      double tmp = 0.0;
+
+	      ok = do_read (is, dt, flt_fmt, swap_bytes,
+			    do_float_conversion, tmp);
+
+	      if (ok)
+		{
+		  if (is)
+		    {
+		      if (count == max_size)
+			{
+			  max_size *= 2;
+
+			  if (nr > 0)
+			    resize (nr, max_size / 2, 0.0);
+			  else
+			    resize (max_size, 1, 0.0);
+
+			  data = fortran_vec ();
+			}
+
+		      data[count++] = tmp;
+		    }
+		  else
+		    {
+		      if (is.eof ())
+			{
+			  if (nr > 0)
+			    {
+			      if (count > nr)
+				{
+				  final_nr = nr;
+				  final_nc = (count - 1) / nr + 1;
+				}
+			      else
+				{
+				  final_nr = count;
+				  final_nc = 1;
+				}
+			    }
+			  else
+			    {
+			      final_nr = count;
+			      final_nc = 1;
+			    }
+			}
+
+		      break;
+		    }
+		}
+	      else
+		break;
+	    }
+	  else
+	    {
+	      ok = false;
+	      break;
+	    }
+	}
+      else
+	{
+	  ok = false;
+	  break;
+	}
+    }
+
+  if (ok)
+    {
+      resize (final_nr, final_nc, 0.0);
+
+      retval = count;
     }
 
-  return count;
+  return retval;
+}
+
+template <class T>
+static void
+write_int (ostream& os, bool swap_bytes, T val)
+{
+  if (swap_bytes)
+    {
+      switch (sizeof (T))
+	{
+	case 1:
+	  break;
+
+	case 2:
+	  swap_2_bytes ((char *) &val);
+	  break;
+
+	case 4:
+	  swap_4_bytes ((char *) &val);
+	  break;
+
+	case 8:
+	  swap_8_bytes ((char *) &val);
+	  break;
+
+	default:
+	  (*current_liboctave_error_handler)
+	    ("write_int: unrecognized data format!");
+	}
+    }
+
+  os.write ((char *) &val, sizeof (T));
 }
 
-// Write the data array to a file in binary format.
+template void write_int (ostream&, bool, char);
+template void write_int (ostream&, bool, signed char);
+template void write_int (ostream&, bool, unsigned char);
+template void write_int (ostream&, bool, short);
+template void write_int (ostream&, bool, unsigned short);
+template void write_int (ostream&, bool, int);
+template void write_int (ostream&, bool, unsigned int);
+template void write_int (ostream&, bool, long);
+template void write_int (ostream&, bool, unsigned long);
+
+static inline bool
+do_write (ostream& os, double d, oct_data_conv::data_type dt,
+	  oct_mach_info::float_format flt_fmt, bool swap_bytes,
+	  bool do_float_conversion)
+{
+  bool retval = true;
+
+  switch (dt)
+    {
+    case oct_data_conv::dt_char:
+      write_int (os, swap_bytes, (char) d);
+      break;
+
+    case oct_data_conv::dt_schar:
+      write_int (os, swap_bytes, (signed char) d);
+      break;
+
+    case oct_data_conv::dt_uchar:
+      write_int (os, swap_bytes, (unsigned char) d);
+      break;
+
+    case oct_data_conv::dt_short:
+      write_int (os, swap_bytes, (short) d);
+      break;
+
+    case oct_data_conv::dt_ushort:
+      write_int (os, swap_bytes, (unsigned short) d);
+      break;
+
+    case oct_data_conv::dt_int:
+      write_int (os, swap_bytes, (int) d);
+      break;
+
+    case oct_data_conv::dt_uint:
+      write_int (os, swap_bytes, (unsigned int) d);
+      break;
+
+    case oct_data_conv::dt_long:
+      write_int (os, swap_bytes, (long) d);
+      break;
+
+    case oct_data_conv::dt_ulong:
+      write_int (os, swap_bytes, (unsigned long) d);
+      break;
+
+    case oct_data_conv::dt_float:
+      {
+	float f = (float) d;
+
+	if (do_float_conversion)
+	  do_float_format_conversion (&f, 1, flt_fmt);
+
+	os.write ((char *) &f, sizeof (float));
+      }
+      break;
+
+    case oct_data_conv::dt_double:
+      {
+	if (do_float_conversion)
+	  do_double_format_conversion (&d, 1, flt_fmt);
+
+	os.write ((char *) &d, sizeof (double));
+      }
+      break;
+
+    default:
+      retval = false;
+      (*current_liboctave_error_handler)
+	("write: invalid type specification");
+      break;
+    }
+
+  return retval;
+}
 
 int
-Matrix::write (FILE *fptr, const char *type)
+Matrix::write (ostream& os, oct_data_conv::data_type dt, int skip,
+	       oct_mach_info::float_format flt_fmt)
 {
-  // Allocate buffer pointers.
-
-  union
-    {
-      void *vd;
-      char *ch;
-      u_char *uc;
-      short *sh;
-      u_short *us;
-      int *in;
-      u_int *ui;
-      long *ln;
-      u_long *ul;
-      float *fl;
-      double *db;
-    }
-  buf;
-
-  int nitems = length ();
-
-  double *d = fortran_vec ();
-
-  // Convert from double to correct size.
-
-  if (! type)
+  int retval = -1;
+
+  bool ok = true;
+
+  int count = 0;
+
+  const double *d = data ();
+
+  int n = length ();
+
+  oct_mach_info::float_format native_flt_fmt
+    = oct_mach_info::float_format ();
+
+  bool do_float_conversion = (flt_fmt != native_flt_fmt);
+
+  // XXX FIXME XXX -- byte order for Cray?
+
+  bool swap_bytes = false;
+
+  if (oct_mach_info::words_big_endian ())
+    swap_bytes = (flt_fmt == oct_mach_info::ieee_little_endian
+		 || flt_fmt == oct_mach_info::vax_g
+		 || flt_fmt == oct_mach_info::vax_g);
+  else
+    swap_bytes = (flt_fmt == oct_mach_info::ieee_big_endian);
+
+  for (int i = 0; i < n; i++)
     {
-      (*current_liboctave_error_handler)
-	("fwrite: invalid NULL type parameter");
-      return 0;
-    }    
-
-  size_t size;
-  int count;
-
-#define DO_FWRITE(TYPE,ELEM) \
-  do \
-    { \
-      size = sizeof (TYPE); \
-      buf.ELEM = new TYPE [nitems]; \
-      for (int k = 0; k < nitems; k++) \
-	buf.ELEM[k] = (TYPE) d[k]; \
-      count = fwrite (buf.ELEM, size, nitems, fptr); \
-      delete [] buf.ELEM; \
-    } \
-  while (0)
-
-  if (strcasecmp (type, "double") == 0)
-    DO_FWRITE (double, db);
-  else if (strcasecmp (type, "char") == 0)
-    DO_FWRITE (char, ch);
-  else if (strcasecmp (type, "uchar") == 0)
-    DO_FWRITE (u_char, uc);
-  else if (strcasecmp (type, "short") == 0)
-    DO_FWRITE (short, sh);
-  else if (strcasecmp (type, "ushort") == 0)
-    DO_FWRITE (u_short, us);
-  else if (strcasecmp (type, "int") == 0)
-    DO_FWRITE (int, in);
-  else if (strcasecmp (type, "uint") == 0)
-    DO_FWRITE (u_int, ui);
-  else if (strcasecmp (type, "long") == 0)
-    DO_FWRITE (long, ln);
-  else if (strcasecmp (type, "ulong") == 0)
-    DO_FWRITE (u_long, ul);
-  else if (strcasecmp (type, "float") == 0)
-    DO_FWRITE (float, fl);
-  else
-    {
-      (*current_liboctave_error_handler)
-	("fwrite: unrecognized type parameter %s", type);
-      return 0;
+      if (os)
+	{
+	  if (skip != 0)
+	    os.seekp (skip, ios::cur);
+
+	  if (os)
+	    {
+	      ok = do_write (os, d[i], dt, flt_fmt, swap_bytes,
+			     do_float_conversion);
+
+	      if (os && ok)
+		count++;
+	      else
+		break;
+	    }
+	  else
+	    {
+	      ok = false;
+	      break;
+	    }
+	}
+      else
+	{
+	  ok = false;
+	  break;
+	}
     }
 
-  return count;
+  if (ok)
+    retval = count;
+
+  return retval;
 }
 
+
+
 Matrix
 Givens (double x, double y)
 {
--- a/liboctave/dMatrix.h
+++ b/liboctave/dMatrix.h
@@ -27,14 +27,14 @@
 #pragma interface
 #endif
 
-// For FILE...
-#include <cstdio>
-
 #include "MArray2.h"
 #include "MDiagArray2.h"
 
 #include "mx-defs.h"
 
+#include "data-conv.h"
+#include "mach-info.h"
+
 class Matrix : public MArray2<double>
 {
 friend class ComplexMatrix;
@@ -237,8 +237,11 @@
   friend ostream& operator << (ostream& os, const Matrix& a);
   friend istream& operator >> (istream& is, Matrix& a);
 
-  int read (FILE *fptr, const char *type);
-  int write (FILE *fptr, const char *type);
+  int read (istream& is, int nr, int nc, oct_data_conv::data_type dt,
+	    int skip, oct_mach_info::float_format flt_fmt);
+
+  int write (ostream& os, oct_data_conv::data_type dt, int skip,
+	     oct_mach_info::float_format flt_fmt);
 
 private:
 
--- a/liboctave/data-conv.cc
+++ b/liboctave/data-conv.cc
@@ -24,12 +24,83 @@
 #include <config.h>
 #endif
 
+#include <cctype>
+
 #include <iostream.h>
 
 #include "byte-swap.h"
 #include "data-conv.h"
 #include "lo-error.h"
 
+oct_data_conv::data_type
+oct_data_conv::string_to_data_type (const string& str)
+{
+  data_type retval = dt_unknown;
+
+    // XXX FIXME XXX -- finish implementing this.
+
+  // XXX FIXME XXX -- before checking s, need to strip spaces and downcase.
+
+  int n = str.length ();
+
+  int k = 0;
+
+  string s (n, ' ');
+
+  for (int i = 0; i < n; i++)
+    if (! isspace (str[i]))
+      s[k++] = tolower (str[i]);
+
+  s.resize (k);
+
+  if (s == "char" || s == "char*1" || s == "integer*1" || s == "int8")
+    retval = dt_char;
+  else if (s == "schar" || s == "signedchar")
+    retval = dt_schar;
+  else if (s == "uchar" || s == "unsignedchar")
+    retval = dt_uchar;
+  else if (s == "short")
+    retval = dt_short;
+  else if (s == "ushort" || s == "unsignedshort")
+    retval = dt_ushort;
+  else if (s == "int")
+    retval = dt_int;
+  else if (s == "uint" || s == "unsignedint")
+    retval = dt_uint;
+  else if (s == "long")
+    retval = dt_long;
+  else if (s == "ulong" || s == "unsignedlong")
+    retval = dt_ulong;
+  else if (s == "float" || s == "float32" || s == "real*4")
+    retval = dt_float;
+  else if (s == "double" || s == "float64" || s == "real*8")
+    retval = dt_double;
+  else if (s == "int16" || s == "integer*2")
+    {
+      if (sizeof (short) == 2)
+	retval = dt_short;
+      else if (sizeof (int) == 2)
+	retval = dt_int;
+      else
+	(*current_liboctave_error_handler)
+	  ("unable to find matching native data type for %s", s.c_str ());
+    }
+  else if (s == "int32" || s == "integer*4")
+    {
+      if (sizeof (int) == 4)
+	retval = dt_int;
+      else if (sizeof (long) == 4)
+	retval = dt_long;
+      else
+	(*current_liboctave_error_handler)
+	  ("unable to find matching native data type for %s", s.c_str ());
+    }
+  else
+    (*current_liboctave_error_handler) ("invalid data type specified");
+
+  return retval;
+}
+
 #define swap_1_bytes(x, y)
 
 #define LS_DO_READ(TYPE,swap,data,size,len,stream) \
@@ -281,29 +352,29 @@
 
 void
 do_double_format_conversion (double *data, int len,
-			     floating_point_format fmt)
+			     oct_mach_info::float_format fmt)
 {
-  switch (native_float_format)
+  switch (oct_mach_info::native_float_format ())
     {
-    case OCTAVE_IEEE_LITTLE:
+    case oct_mach_info::ieee_little_endian:
       switch (fmt)
 	{
-	case OCTAVE_IEEE_LITTLE:
+	case oct_mach_info::ieee_little_endian:
 	  break;
 
-	case OCTAVE_IEEE_BIG:
+	case oct_mach_info::ieee_big_endian:
 	  IEEE_big_double_to_IEEE_little_double (data, len);
 	  break;
 
-	case OCTAVE_VAX_D:
+	case oct_mach_info::vax_d:
 	  VAX_D_double_to_IEEE_little_double (data, len);
 	  break;
 
-	case OCTAVE_VAX_G:
+	case oct_mach_info::vax_g:
 	  VAX_G_double_to_IEEE_little_double (data, len);
 	  break;
 
-	case OCTAVE_CRAY:
+	case oct_mach_info::cray:
 	  Cray_to_IEEE_little_double (data, len);
 	  break;
 
@@ -313,25 +384,25 @@
 	}
       break;
 
-    case OCTAVE_IEEE_BIG:
+    case oct_mach_info::ieee_big_endian:
       switch (fmt)
 	{
-	case OCTAVE_IEEE_LITTLE:
+	case oct_mach_info::ieee_little_endian:
 	  IEEE_little_double_to_IEEE_big_double (data, len);
 	  break;
 
-	case OCTAVE_IEEE_BIG:
+	case oct_mach_info::ieee_big_endian:
 	  break;
 
-	case OCTAVE_VAX_D:
+	case oct_mach_info::vax_d:
 	  VAX_D_double_to_IEEE_big_double (data, len);
 	  break;
 
-	case OCTAVE_VAX_G:
+	case oct_mach_info::vax_g:
 	  VAX_G_double_to_IEEE_big_double (data, len);
 	  break;
 
-	case OCTAVE_CRAY:
+	case oct_mach_info::cray:
 	  Cray_to_IEEE_big_double (data, len);
 	  break;
 
@@ -341,25 +412,25 @@
 	}
       break;
 
-    case OCTAVE_VAX_D:
+    case oct_mach_info::vax_d:
       switch (fmt)
 	{
-	case OCTAVE_IEEE_LITTLE:
+	case oct_mach_info::ieee_little_endian:
 	  IEEE_little_double_to_VAX_D_double (data, len);
 	  break;
 
-	case OCTAVE_IEEE_BIG:
+	case oct_mach_info::ieee_big_endian:
 	  IEEE_big_double_to_VAX_D_double (data, len);
 	  break;
 
-	case OCTAVE_VAX_D:
+	case oct_mach_info::vax_d:
 	  break;
 
-	case OCTAVE_VAX_G:
+	case oct_mach_info::vax_g:
 	  VAX_G_double_to_VAX_D_double (data, len);
 	  break;
 
-	case OCTAVE_CRAY:
+	case oct_mach_info::cray:
 	  Cray_to_VAX_D_double (data, len);
 	  break;
 
@@ -369,25 +440,25 @@
 	}
       break;
 
-    case OCTAVE_VAX_G:
+    case oct_mach_info::vax_g:
       switch (fmt)
 	{
-	case OCTAVE_IEEE_LITTLE:
+	case oct_mach_info::ieee_little_endian:
 	  IEEE_little_double_to_VAX_G_double (data, len);
 	  break;
 
-	case OCTAVE_IEEE_BIG:
+	case oct_mach_info::ieee_big_endian:
 	  IEEE_big_double_to_VAX_G_double (data, len);
 	  break;
 
-	case OCTAVE_VAX_D:
+	case oct_mach_info::vax_d:
 	  VAX_D_double_to_VAX_G_double (data, len);
 	  break;
 
-	case OCTAVE_VAX_G:
+	case oct_mach_info::vax_g:
 	  break;
 
-	case OCTAVE_CRAY:
+	case oct_mach_info::cray:
 	  Cray_to_VAX_G_double (data, len);
 	  break;
 
@@ -407,29 +478,29 @@
 
 void
 do_float_format_conversion (float *data, int len,
-			    floating_point_format fmt)
+			    oct_mach_info::float_format fmt)
 {
-  switch (native_float_format)
+  switch (oct_mach_info::native_float_format ())
     {
-    case OCTAVE_IEEE_LITTLE:
+    case oct_mach_info::ieee_little_endian:
       switch (fmt)
 	{
-	case OCTAVE_IEEE_LITTLE:
+	case oct_mach_info::ieee_little_endian:
 	  break;
 
-	case OCTAVE_IEEE_BIG:
+	case oct_mach_info::ieee_big_endian:
 	  IEEE_big_float_to_IEEE_little_float (data, len);
 	  break;
 
-	case OCTAVE_VAX_D:
+	case oct_mach_info::vax_d:
 	  VAX_D_float_to_IEEE_little_float (data, len);
 	  break;
 
-	case OCTAVE_VAX_G:
+	case oct_mach_info::vax_g:
 	  VAX_G_float_to_IEEE_little_float (data, len);
 	  break;
 
-	case OCTAVE_CRAY:
+	case oct_mach_info::cray:
 	  Cray_to_IEEE_little_float (data, len);
 	  break;
 
@@ -439,25 +510,25 @@
 	}
       break;
 
-    case OCTAVE_IEEE_BIG:
+    case oct_mach_info::ieee_big_endian:
       switch (fmt)
 	{
-	case OCTAVE_IEEE_LITTLE:
+	case oct_mach_info::ieee_little_endian:
 	  IEEE_little_float_to_IEEE_big_float (data, len);
 	  break;
 
-	case OCTAVE_IEEE_BIG:
+	case oct_mach_info::ieee_big_endian:
 	  break;
 
-	case OCTAVE_VAX_D:
+	case oct_mach_info::vax_d:
 	  VAX_D_float_to_IEEE_big_float (data, len);
 	  break;
 
-	case OCTAVE_VAX_G:
+	case oct_mach_info::vax_g:
 	  VAX_G_float_to_IEEE_big_float (data, len);
 	  break;
 
-	case OCTAVE_CRAY:
+	case oct_mach_info::cray:
 	  Cray_to_IEEE_big_float (data, len);
 	  break;
 
@@ -467,25 +538,25 @@
 	}
       break;
 
-    case OCTAVE_VAX_D:
+    case oct_mach_info::vax_d:
       switch (fmt)
 	{
-	case OCTAVE_IEEE_LITTLE:
+	case oct_mach_info::ieee_little_endian:
 	  IEEE_little_float_to_VAX_D_float (data, len);
 	  break;
 
-	case OCTAVE_IEEE_BIG:
+	case oct_mach_info::ieee_big_endian:
 	  IEEE_big_float_to_VAX_D_float (data, len);
 	  break;
 
-	case OCTAVE_VAX_D:
+	case oct_mach_info::vax_d:
 	  break;
 
-	case OCTAVE_VAX_G:
+	case oct_mach_info::vax_g:
 	  VAX_G_float_to_VAX_D_float (data, len);
 	  break;
 
-	case OCTAVE_CRAY:
+	case oct_mach_info::cray:
 	  Cray_to_VAX_D_float (data, len);
 	  break;
 
@@ -495,25 +566,25 @@
 	}
       break;
 
-    case OCTAVE_VAX_G:
+    case oct_mach_info::vax_g:
       switch (fmt)
 	{
-	case OCTAVE_IEEE_LITTLE:
+	case oct_mach_info::ieee_little_endian:
 	  IEEE_little_float_to_VAX_G_float (data, len);
 	  break;
 
-	case OCTAVE_IEEE_BIG:
+	case oct_mach_info::ieee_big_endian:
 	  IEEE_big_float_to_VAX_G_float (data, len);
 	  break;
 
-	case OCTAVE_VAX_D:
+	case oct_mach_info::vax_d:
 	  VAX_D_float_to_VAX_G_float (data, len);
 	  break;
 
-	case OCTAVE_VAX_G:
+	case oct_mach_info::vax_g:
 	  break;
 
-	case OCTAVE_CRAY:
+	case oct_mach_info::cray:
 	  Cray_to_VAX_G_float (data, len);
 	  break;
 
@@ -533,7 +604,7 @@
 
 void
 read_doubles (istream& is, double *data, save_type type, int len,
-	      int swap, floating_point_format fmt)
+	      int swap, oct_mach_info::float_format fmt)
 {
   switch (type)
     {
--- a/liboctave/data-conv.h
+++ b/liboctave/data-conv.h
@@ -25,7 +25,7 @@
 
 #include <climits>
 
-#include "float-fmt.h"
+#include "mach-info.h"
 
 // Not all of the following are currently used.
 
@@ -49,6 +49,32 @@
 #error "No 4 byte integer type found!"
 #endif
 
+class
+oct_data_conv
+{
+public:
+
+  enum data_type
+    {
+      dt_unknown,
+      dt_char,
+      dt_schar,
+      dt_uchar,
+      dt_short,
+      dt_ushort,
+      dt_int,
+      dt_uint,
+      dt_long,
+      dt_ulong,
+      dt_float,
+      dt_double,
+      dt_float_complex,
+      dt_double_complex
+    };
+
+  static data_type string_to_data_type (const string& s);
+};
+
 enum save_type
   {
     LS_U_CHAR,
@@ -62,14 +88,16 @@
   };
 
 extern void
-do_double_format_conversion (double *data, int len, floating_point_format fmt);
+do_double_format_conversion (double *data, int len,
+			     oct_mach_info::float_format fmt);
 
 extern void
-do_float_format_conversion (float *data, int len, floating_point_format fmt);
+do_float_format_conversion (float *data, int len,
+			    oct_mach_info::float_format fmt);
 
 extern void
 read_doubles (istream& is, double *data, save_type type, int len,
-	      int swap, floating_point_format fmt);
+	      int swap, oct_mach_info::float_format fmt);
 extern void
 write_doubles (ostream& os, const double *data, save_type type, int len);
 
--- a/liboctave/mach-info.cc
+++ b/liboctave/mach-info.cc
@@ -25,15 +25,15 @@
 #endif
 
 #include "f77-fcn.h"
-#include "float-fmt.h"
+#include "lo-error.h"
+#include "mach-info.h"
 
 extern "C"
 {
   double F77_FCN (d1mach, D1MACH) (const int&);
 }
 
-// The floating point format on this system.
-floating_point_format native_float_format = OCTAVE_UNKNOWN_FLT_FMT;
+oct_mach_info *oct_mach_info::instance = 0;
 
 union equiv
 {
@@ -44,7 +44,7 @@
 struct
 float_params
 {
-  floating_point_format fp_fmt;
+  oct_mach_info::float_format fp_fmt;
   equiv fp_par[4];
 };
 
@@ -69,36 +69,36 @@
   return 1;
 }
 
-int
-float_format_init (void)
+void
+oct_mach_info::init_float_format (void)
 {
   float_params fp[5];
 
-  INIT_FLT_PAR (fp[0], OCTAVE_IEEE_BIG,
+  INIT_FLT_PAR (fp[0], oct_mach_info::ieee_big_endian,
 		   1048576,  0,
 		2146435071, -1,
 		1017118720,  0,
 		1018167296,  0);
 
-  INIT_FLT_PAR (fp[1], OCTAVE_IEEE_LITTLE,
+  INIT_FLT_PAR (fp[1], oct_mach_info::ieee_little_endian,
 		 0,    1048576,
 		-1, 2146435071,
 		 0, 1017118720,
 		 0, 1018167296);
 
-  INIT_FLT_PAR (fp[2], OCTAVE_VAX_D,
+  INIT_FLT_PAR (fp[2], oct_mach_info::vax_d,
 		   128,  0,
 		-32769, -1,
 		  9344,  0,
 		  9344,  0);
 
-  INIT_FLT_PAR (fp[3], OCTAVE_VAX_G,
+  INIT_FLT_PAR (fp[3], oct_mach_info::vax_g,
 		    16,  0,
 		-32769, -1,
 		 15552,  0,
 		 15552,  0);
 
-  INIT_FLT_PAR (fp[4], OCTAVE_UNKNOWN_FLT_FMT,
+  INIT_FLT_PAR (fp[4], oct_mach_info::unknown,
 		0, 0,
 		0, 0,
 		0, 0,
@@ -116,13 +116,124 @@
     {
       if (equiv_compare (fp[i].fp_par, mach_fp_par, 4))
 	{
-	  native_float_format = fp[i].fp_fmt;
+	  native_float_fmt = fp[i].fp_fmt;
 	  break;
 	}
     }
-  while (fp[++i].fp_fmt != OCTAVE_UNKNOWN_FLT_FMT);
+  while (fp[++i].fp_fmt != oct_mach_info::unknown);
+}
+
+void
+oct_mach_info::ten_little_endians (void)
+{
+  // Are we little or big endian?  From Harbison & Steele.
+
+  union
+  {
+    long l;
+    char c[sizeof (long)];
+  } u;
+
+  u.l = 1;
+
+  big_chief = (u.c[sizeof (long) - 1] == 1);
+}
+
+oct_mach_info::oct_mach_info (void)
+{
+  init_float_format ();
+  ten_little_endians ();
+}
+
+oct_mach_info::float_format
+oct_mach_info::native_float_format (void)
+{
+  if (! instance)
+    instance = new oct_mach_info ();
+
+  return instance->native_float_fmt;
+}
+
+bool
+oct_mach_info::words_big_endian (void)
+{
+  if (! instance)
+    instance = new oct_mach_info ();
+
+  return instance->big_chief;
+}
+
+bool
+oct_mach_info::words_little_endian (void)
+{
+  if (! instance)
+    instance = new oct_mach_info ();
+
+  return ! instance->big_chief;
+}
+
+oct_mach_info::float_format
+oct_mach_info::string_to_float_format (const string& s)
+{
+  oct_mach_info::float_format retval = oct_mach_info::unknown;
 
-  return (native_float_format != OCTAVE_UNKNOWN_FLT_FMT);
+  if (s == "native" || s == "n")
+    retval = oct_mach_info::native;
+  else if (s == "ieee-be" || s == "b")
+    retval = oct_mach_info::ieee_big_endian;
+  else if (s == "ieee-le" || s == "l")
+    retval = oct_mach_info::ieee_little_endian;
+  else if (s == "vaxd" || s == "d")
+    retval = oct_mach_info::vax_d;
+  else if (s == "vax_g" || s == "g")
+    retval = oct_mach_info::vax_g;
+  else if (s == "cray" || s == "c")
+    retval = oct_mach_info::cray;
+  else if (s == "unknown")
+    retval = oct_mach_info::unknown;
+  else
+    (*current_liboctave_error_handler)
+      ("invalid architecture type specified");
+
+  return retval;
+}
+
+string
+oct_mach_info::float_format_as_string (float_format flt_fmt)
+{
+  string retval = "unknown";
+
+  switch (flt_fmt)
+    {
+    case native:
+      retval = "native";
+      break;
+
+    case ieee_big_endian:
+      retval = "ieee_big_endian";
+      break;
+
+    case ieee_little_endian:
+      retval = "ieee_little_endian";
+      break;
+
+    case vax_d:
+      retval = "vax_d_float";
+      break;
+
+    case vax_g:
+      retval = "vax_g_float";
+      break;
+
+    case cray:
+      retval = "cray";
+      break;
+
+    default:
+      break;
+    }
+
+  return retval;
 }
 
 /*
--- a/liboctave/mach-info.h
+++ b/liboctave/mach-info.h
@@ -20,25 +20,59 @@
 
 */
 
-#if !defined (octave_float_fmt_h)
-#define octave_float_fmt_h 1
+#if !defined (octave_mach_info_h)
+#define octave_mach_info_h 1
+
+#include <string>
+
+class
+oct_mach_info
+{
+public:
+
+  enum float_format
+    {
+      native,
+      unknown,
+      ieee_little_endian,
+      ieee_big_endian,
+      vax_d,
+      vax_g,
+      cray
+    };
+
+  oct_mach_info (void);
+
+  static float_format native_float_format (void);
+
+  static bool words_big_endian (void);
 
-enum floating_point_format
-  {
-    OCTAVE_IEEE_LITTLE,
-    OCTAVE_IEEE_BIG,
-    OCTAVE_VAX_D,
-    OCTAVE_VAX_G,
-    OCTAVE_CRAY,
-    OCTAVE_UNKNOWN_FLT_FMT
-  };
+  static bool words_little_endian (void);
+
+  static float_format string_to_float_format (const string&);
+
+  static string float_format_as_string (float_format);
+
+private:
+
+  static oct_mach_info *instance;
+
+  void init_float_format (void);
 
-// The floating point format on this system.
-extern floating_point_format native_float_format;
+  void ten_little_endians (void);
+
+  // The floating point format for the current machine.
+  float_format native_float_fmt;
 
-// Initializes the value of native_float_format.  Maybe this should be
-// done automatically using a class with a static member.  Hmm...
-extern int float_format_init (void);
+  // TRUE if the byte order on this system is big endian.
+  bool big_chief;
+
+  // No copying!
+
+  oct_mach_info (const oct_mach_info&);
+
+  oct_mach_info& operator = (const oct_mach_info&);
+};
 
 #endif
 
--- a/src/oct-fstrm.cc
+++ b/src/oct-fstrm.cc
@@ -32,8 +32,8 @@
 
 octave_fstream::octave_fstream (const string& nm_arg,
 				ios::openmode md = ios::in|ios::out,
-				octave_base_stream::arch_type at)
-  : octave_base_stream (md, at), nm (nm_arg)
+				oct_mach_info::float_format flt_fmt)
+  : octave_base_stream (md, flt_fmt), nm (nm_arg)
 {
   // Override default protection of 0664 so that umask will appear to
   // do the right thing.
--- a/src/oct-fstrm.h
+++ b/src/oct-fstrm.h
@@ -34,7 +34,8 @@
 
   octave_fstream (const string& nm_arg,
 		  ios::openmode md = ios::in|ios::out,
-		  octave_base_stream::arch_type at = at_native);
+		  oct_mach_info::float_format flt_fmt =
+		  oct_mach_info::native);
 
   ~octave_fstream (void) { }
 
--- a/src/oct-iostrm.h
+++ b/src/oct-iostrm.h
@@ -35,8 +35,9 @@
 
   octave_base_iostream (const string& n = string (),
 			ios::openmode md = ios::in|ios::out,
-			octave_base_stream::arch_type at = at_native)
-    : octave_base_stream (md, at), nm (n) { }
+			oct_mach_info::float_format flt_fmt =
+			oct_mach_info::native)
+    : octave_base_stream (md, flt_fmt), nm (n) { }
 
   ~octave_base_iostream (void) { }
 
@@ -79,7 +80,7 @@
 public:
 
   octave_istream (istream *arg = 0, const string& nm = string ())
-    : octave_base_iostream (nm, ios::in, octave_base_stream::at_native),
+    : octave_base_iostream (nm, ios::in, oct_mach_info::native),
       is (arg) { }
 
   ~octave_istream (void) { }
@@ -107,7 +108,7 @@
 public:
 
   octave_ostream (ostream *arg, const string& nm = string ())
-    : octave_base_iostream (nm, ios::out, octave_base_stream::at_native),
+    : octave_base_iostream (nm, ios::out, oct_mach_info::native),
       os (arg) { }
 
   ~octave_ostream (void) { }
--- a/src/oct-prcstrm.cc
+++ b/src/oct-prcstrm.cc
@@ -30,8 +30,8 @@
 
 octave_iprocstream::octave_iprocstream (const string& n,
 					ios::openmode arg_md,
-					arch_type arg_at)
-  : octave_istdiostream (n, 0, arg_md, arg_at)
+					oct_mach_info::float_format flt_fmt)
+  : octave_istdiostream (n, 0, arg_md, flt_fmt)
 {
   fp = popen (n.c_str (), "r");
 
@@ -53,8 +53,8 @@
 
 octave_oprocstream::octave_oprocstream (const string& n,
 					ios::openmode arg_md,
-					arch_type arg_at)
-  : octave_ostdiostream (n, 0, arg_md, arg_at)
+					oct_mach_info::float_format flt_fmt)
+  : octave_ostdiostream (n, 0, arg_md, flt_fmt)
 {
   fp = popen (n.c_str (), "w");
 
--- a/src/oct-prcstrm.h
+++ b/src/oct-prcstrm.h
@@ -32,7 +32,8 @@
 
   octave_iprocstream (const string& n,
 		      ios::openmode arg_md = ios::in,
-		      arch_type arg_at = at_native);
+		      oct_mach_info::float_format flt_fmt =
+		      oct_mach_info::native);
 
   ~octave_iprocstream (void);
 
@@ -51,8 +52,9 @@
 public:
 
   octave_oprocstream (const string& n,
-		       ios::openmode arg_md = ios::out,
-		       arch_type arg_at = at_native);
+		      ios::openmode arg_md = ios::out,
+		      oct_mach_info::float_format flt_fmt =
+		      oct_mach_info::native);
 
   ~octave_oprocstream (void);
 
--- a/src/oct-stdstrm.cc
+++ b/src/oct-stdstrm.cc
@@ -85,8 +85,8 @@
 
 octave_istdiostream::octave_istdiostream (const string& n, FILE *f,
 					  ios::openmode arg_md,
-					  arch_type arg_at)
-  : octave_base_stdiostream (n, f, arg_md, arg_at), is (0)
+					  oct_mach_info::float_format flt_fmt)
+  : octave_base_stdiostream (n, f, arg_md, flt_fmt), is (0)
 {
   if (f)
     is = new istdiostream (f);
@@ -99,8 +99,8 @@
 
 octave_ostdiostream::octave_ostdiostream (const string& n, FILE *f,
 					  ios::openmode arg_md,
-					  arch_type arg_at)
-  : octave_base_stdiostream (n, f, arg_md, arg_at), os (0)
+					  oct_mach_info::float_format flt_fmt)
+  : octave_base_stdiostream (n, f, arg_md, flt_fmt), os (0)
 {
   if (f)
     os = new ostdiostream (f);
--- a/src/oct-stdstrm.h
+++ b/src/oct-stdstrm.h
@@ -34,8 +34,9 @@
 
   octave_base_stdiostream (const string& n, FILE *f,
 			   ios::openmode arg_md = ios::in|ios::out,
-			   arch_type arg_at = at_native)
-    : octave_base_stream (arg_md, arg_at), nm (n), fp (f) { }
+			   oct_mach_info::float_format flt_fmt =
+			   oct_mach_info::native)
+    : octave_base_stream (arg_md, flt_fmt), nm (n), fp (f) { }
 
   ~octave_base_stdiostream (void);
 
@@ -77,7 +78,8 @@
 
   octave_istdiostream (const string& n, FILE *f = 0,
 		       ios::openmode arg_md = ios::in,
-		       arch_type arg_at = at_native);
+		       oct_mach_info::float_format flt_fmt =
+		       oct_mach_info::native);
 
   ~octave_istdiostream (void);
 
@@ -121,7 +123,8 @@
 
   octave_ostdiostream (const string& n, FILE *f = 0,
 		       ios::openmode arg_md = ios::out,
-		       arch_type arg_at = at_native);
+		       oct_mach_info::float_format flt_fmt =
+		       oct_mach_info::native);
 
   ~octave_ostdiostream (void);
 
--- a/src/oct-stream.cc
+++ b/src/oct-stream.cc
@@ -817,218 +817,38 @@
   return do_gets (max_len, err, false, "fgets");
 }
 
-// XXX FIXME XXX -- need to handle architecture type conversions.
-
-#define do_read_elem(is, type, val) \
-  do \
-    { \
-      type tmp_val; \
-      is.read ((char *) &tmp_val, sizeof (type)); \
-      val = tmp_val; \
-    } \
-  while (0)
-
 octave_value
-octave_base_stream::do_read (int nr, int nc, data_type dt, int skip,
-			     arch_type at, int& count)
+octave_base_stream::read (const Matrix& size,
+			  oct_data_conv::data_type dt, int skip,
+			  oct_mach_info::float_format flt_fmt, int& count)
 {
+  Matrix retval;
+
   count = 0;
 
-  octave_value retval = Matrix ();
-
   istream *isp = input_stream ();
 
-  Matrix mval;
-  double *data = 0;
-  int max_size = 0;
-
-  int final_nr = 0;
-  int final_nc = 0;
-
-  if (nr > 0)
-    {
-      if (nc > 0)
-	{
-	  mval.resize (nr, nc, 0.0);
-	  data = mval.fortran_vec ();
-	  max_size = nr * nc;
-	}
-      else
-	{
-	  mval.resize (nr, 32, 0.0);
-	  data = mval.fortran_vec ();
-	  max_size = nr * 32;
-	}
-    }
-  else
-    {
-      mval.resize (32, 1, 0.0);
-      data = mval.fortran_vec ();
-      max_size = 32;
-    }
-
   if (isp)
     {
       istream& is = *isp;
 
-      for (;;)
-	{
-	  // XXX FIXME XXX -- maybe there should be a special case for
-	  // skip == 0.
-
-	  if (is)
-	    {
-	      if (nr > 0 && nc > 0 && count == max_size)
-		{
-		  final_nr = nr;
-		  final_nc = nc;
-
-		  break;
-		}
-
-	      if (skip != 0)
-		seek (skip, ios::cur);
-
-	      if (is)
-		{
-		  double tmp = 0.0;
-
-		  switch (dt)
-		    {
-		    case dt_char:
-		      do_read_elem (is, char, tmp);
-		      break;
-
-		    case dt_schar:
-		      do_read_elem (is, signed char, tmp);
-		      break;
-
-		    case dt_uchar:
-		      do_read_elem (is, unsigned char, tmp);
-		      break;
-
-		    case dt_short:
-		      do_read_elem (is, short, tmp);
-		      break;
-
-		    case dt_ushort:
-		      do_read_elem (is, unsigned short, tmp);
-		      break;
-
-		    case dt_int:
-		      do_read_elem (is, int, tmp);
-		      break;
-
-		    case dt_uint:
-		      do_read_elem (is, unsigned int, tmp);
-		      break;
-
-		    case dt_long:
-		      do_read_elem (is, long, tmp);
-		      break;
-
-		    case dt_ulong:
-		      do_read_elem (is, unsigned long, tmp);
-		      break;
-
-		    case dt_float:
-		      do_read_elem (is, float, tmp);
-		      break;
-
-		    case dt_double:
-		      do_read_elem (is, double, tmp);
-		      break;
-
-		    default:
-		      error ("fread: invalid type specification");
-		    }
-
-		  if (is && ok ())
-		    {
-		      if (count == max_size)
-			{
-			  max_size *= 2;
-
-			  if (nr > 0)
-			    mval.resize (nr, max_size / 2, 0.0);
-			  else
-			    mval.resize (max_size, 1, 0.0);
-
-			  data = mval.fortran_vec ();
-			}
-
-		      data[count++] = tmp;
-		    }
-		  else
-		    {
-		      if (is.eof ())
-			{
-			  if (nr > 0)
-			    {
-			      if (count > nr)
-				{
-				  final_nr = nr;
-				  final_nc = (count - 1) / nr + 1;
-				}
-			      else
-				{
-				  final_nr = count;
-				  final_nc = 1;
-				}
-			    }
-			  else
-			    {
-			      final_nr = count;
-			      final_nc = 1;
-			    }
-			}
-
-		      break;
-		    }
-		}
-	      else
-		{
-		  error ("fread: read error");
-		  break;
-		}
-	    }
-	  else
-	    {
-	      error ("fread: read error");
-	      break;
-	    }
-	}
-    }
-
-  if (ok ())
-    {
-      mval.resize (final_nr, final_nc, 0.0);
-
-      retval = mval;
-    }
-
-  return retval;
-}
-
-octave_value
-octave_base_stream::read (const Matrix& size, data_type dt, int skip,
-			  arch_type at, int& count)
-{
-  octave_value retval;
-
-  count = 0;
-
-  istream *is = input_stream ();
-
-  if (is)
-    {
       int nr = -1;
       int nc = -1;
 
       get_size (size, nr, nc, "fread");
 
       if (! error_state)
-	retval = do_read (nr, nc, dt, skip, at, count);
+	{
+	  if (flt_fmt == oct_mach_info::unknown)
+	    flt_fmt = float_format ();
+
+	  int tmp = retval.read (is, nr, nc, dt, skip, flt_fmt);
+
+	  if (tmp < 0)
+	    error ("fread: read error");
+	  else
+	    count = tmp;
+	}
     }
   else
     invalid_operation ("fread", "reading");
@@ -1628,138 +1448,32 @@
   return retval;
 }
 
-// XXX FIXME XXX -- need to handle architecture type conversions.
-
-#define do_write_elem(os, type, val) \
-  do \
-    { \
-      type tmp_val = (type) val; \
-      os.write ((char *) &tmp_val, sizeof (type)); \
-    } \
-  while (0)
-
 int
-octave_base_stream::do_write (const double *data, int n, data_type dt,
-			      int skip, arch_type at)
+octave_base_stream::write (const octave_value& data,
+			   oct_data_conv::data_type dt, int skip,
+			   oct_mach_info::float_format flt_fmt)
 {
   int retval = -1;
 
-  int count = 0;
-
   ostream *osp = output_stream ();
 
   if (osp)
     {
       ostream& os = *osp;
 
-      // XXX FIXME XXX -- maybe there should be a special case for
-      // skip == 0.
-
-      for (int i = 0; i < n; i++)
-	{
-	  if (os)
-	    {
-	      if (skip != 0)
-		seek (skip, ios::cur);
-
-	      if (os)
-		{
-		  double tmp = data[i];
-
-		  switch (dt)
-		    {
-		    case dt_char:
-		      do_write_elem (os, char, tmp);
-		      break;
-
-		    case dt_schar:
-		      do_write_elem (os, signed char, tmp);
-		      break;
-
-		    case dt_uchar:
-		      do_write_elem (os, unsigned char, tmp);
-		      break;
-
-		    case dt_short:
-		      do_write_elem (os, short, tmp);
-		      break;
-
-		    case dt_ushort:
-		      do_write_elem (os, unsigned short, tmp);
-		      break;
-
-		    case dt_int:
-		      do_write_elem (os, int, tmp);
-		      break;
-
-		    case dt_uint:
-		      do_write_elem (os, unsigned int, tmp);
-		      break;
-
-		    case dt_long:
-		      do_write_elem (os, long, tmp);
-		      break;
-
-		    case dt_ulong:
-		      do_write_elem (os, unsigned long, tmp);
-		      break;
-
-		    case dt_float:
-		      do_write_elem (os, float, tmp);
-		      break;
-
-		    case dt_double:
-		      do_write_elem (os, double, tmp);
-		      break;
-
-		    default:
-		      error ("fwrite: invalid type specification");
-		    }
-
-		  if (os && ok ())
-		    count++;
-		  else
-		    break;
-		}
-	      else
-		{
-		  error ("fwrite: write error");
-		  break;
-		}
-	    }
-	  else
-	    {
-	      error ("fwrite: write error");
-	      break;
-	    }
-	}
-    }
-
-  if (ok ())
-    retval = count;
-
-  return retval;
-}
-
-int
-octave_base_stream::write (const octave_value& data, data_type dt,
-			   int skip, arch_type at)
-{
-  int retval = -1;
-
-  ostream *os = output_stream ();
-
-  if (os)
-    {
       Matrix mval = data.matrix_value ();
 
       if (! error_state)
 	{
-	  int n = mval.length ();
-
-	  const double *d = mval.data ();
-
-	  retval = octave_base_stream::do_write (d, n, dt, skip, at);
+	  if (flt_fmt == oct_mach_info::unknown)
+	    flt_fmt = float_format ();
+
+	  int tmp = mval.write (os, dt, skip, flt_fmt);
+
+	  if (tmp < 0)
+	    error ("fwrite: write error");
+	  else
+	    retval = tmp;
 	}
     }
   else
@@ -2368,26 +2082,26 @@
 
 octave_value
 octave_stream::read (const Matrix& size,
-		     octave_base_stream::data_type dt, int skip,
-		     octave_base_stream::arch_type at, int& count)
+		     oct_data_conv::data_type dt, int skip,
+		     oct_mach_info::float_format flt_fmt, int& count)
 {
   octave_value retval;
 
   if (stream_ok ("fread"))
-    retval = rep->read (size, dt, skip, at, count);
+    retval = rep->read (size, dt, skip, flt_fmt, count);
 
   return retval;
 }
 
 int
 octave_stream::write (const octave_value& data,
-		      octave_base_stream::data_type dt, int skip,
-		      octave_base_stream::arch_type at)
+		      oct_data_conv::data_type dt, int skip,
+		      oct_mach_info::float_format flt_fmt)
 {
   int retval = -1;
 
   if (stream_ok ("fwrite"))
-    retval = rep->write (data, dt, skip, at);
+    retval = rep->write (data, dt, skip, flt_fmt);
 
   return retval;
 }
@@ -2498,13 +2212,13 @@
   return retval;
 }
 
-octave_base_stream::arch_type
-octave_stream::architecture (void)
+oct_mach_info::float_format
+octave_stream::float_format (void)
 {
-  octave_base_stream::arch_type retval = octave_base_stream::at_unknown;
-
-  if (stream_ok ("architecture"))
-    retval = rep->architecture ();
+  oct_mach_info::float_format retval = oct_mach_info::unknown;
+
+  if (stream_ok ("float_format"))
+    retval = rep->float_format ();
 
   return retval;
 }
@@ -2573,80 +2287,6 @@
   return retval;
 }
 
-string
-octave_stream::arch_as_string (octave_base_stream::arch_type at)
-{
-  string retval = "unknown";
-
-  switch (at)
-    {
-    case octave_base_stream::at_native:
-      retval = "native";
-      break;
-
-    default:
-      break;
-    }
-
-  return retval;
-}
-
-octave_base_stream::data_type
-octave_stream::string_to_data_type (const string& s)
-{
-  octave_base_stream::data_type retval = octave_base_stream::dt_unknown;
-
-  // XXX FINISHME XXX
-
-  /*
-    int16
-    integer*2
-    int32
-    integer*4 */
-
-  // XXX FIXME XXX -- before checking s, need to strip spaces and downcase.
-
-  if (s == "char" || s == "char*1" || s == "integer*1" || s == "int8")
-    retval = octave_base_stream::dt_char;
-  else if (s == "schar" || s == "signedchar")
-    retval = octave_base_stream::dt_schar;
-  else if (s == "uchar" || s == "unsignedchar")
-    retval = octave_base_stream::dt_uchar;
-  else if (s == "short")
-    retval = octave_base_stream::dt_short;
-  else if (s == "ushort" || s == "unsignedshort")
-    retval = octave_base_stream::dt_ushort;
-  else if (s == "int")
-    retval = octave_base_stream::dt_int;
-  else if (s == "uint" || s == "unsignedint")
-    retval = octave_base_stream::dt_uint;
-  else if (s == "long")
-    retval = octave_base_stream::dt_long;
-  else if (s == "ulong" || s == "unsignedlong")
-    retval = octave_base_stream::dt_ulong;
-  else if (s == "float" || s == "float32" || s == "real*4")
-    retval = octave_base_stream::dt_float;
-  else if (s == "double" || s == "float64" || s == "real**")
-    retval = octave_base_stream::dt_double;
-  else
-    ::error ("invalid data type specified");
-
-  return retval;
-}
-
-octave_base_stream::arch_type
-octave_stream::string_to_arch_type (const string& s)
-{
-  octave_base_stream::arch_type retval = octave_base_stream::at_unknown;
-
-  if (s == "native")
-    retval = octave_base_stream::at_native;
-  else
-    ::error ("invalid architecture type specified");
-
-  return retval;
-}
-
 void
 octave_stream::invalid_stream_error (const char *op) const
 {
@@ -2856,7 +2496,7 @@
 
       retval(0) = os->name ();
       retval(1) = octave_stream::mode_as_string (os->mode ());
-      retval(2) = octave_stream::arch_as_string (os->architecture ());
+      retval(2) = oct_mach_info::float_format_as_string (os->float_format ());
     }
   else
     ::error ("invalid file id");
@@ -2923,7 +2563,10 @@
       if (os)
 	{
 	  string mode = octave_stream::mode_as_string (os->mode ());
-	  string arch = octave_stream::arch_as_string (os->architecture ());
+
+	  string arch =
+	    oct_mach_info::float_format_as_string (os->float_format ());
+
 	  string name = os->name ();
 
 	  buf.form ("  %4d     %-3s  %-9s  %s\n",
--- a/src/oct-stream.h
+++ b/src/oct-stream.h
@@ -29,6 +29,8 @@
 #include <strstream.h>
 
 #include "Array.h"
+#include "data-conv.h"
+#include "mach-info.h"
 
 #include "oct-obj.h"
 #include "str-vec.h"
@@ -215,33 +217,9 @@
 
 public:
 
-  enum arch_type
-    {
-      at_unknown,
-      at_native
-    };
-
-  enum data_type
-    {
-      dt_unknown,
-      dt_char,
-      dt_schar,
-      dt_uchar,
-      dt_short,
-      dt_ushort,
-      dt_int,
-      dt_uint,
-      dt_long,
-      dt_ulong,
-      dt_float,
-      dt_double,
-      dt_float_complex,
-      dt_double_complex
-    };
-
   octave_base_stream (ios::openmode arg_md = ios::in|ios::out,
-		      arch_type arg_at = at_native)
-    : md (arg_md), at (arg_at), fail (false) { }
+		      oct_mach_info::float_format ff = oct_mach_info::native)
+    : md (arg_md), flt_fmt (ff), fail (false) { }
 
   virtual ~octave_base_stream (void) { }
 
@@ -286,7 +264,7 @@
 
   int mode (void) { return md; }
 
-  arch_type architecture (void) { return at; }
+  oct_mach_info::float_format float_format (void) { return flt_fmt; }
 
   // Set current error state and set fail to TRUE.
 
@@ -303,7 +281,7 @@
   int md;
 
   // Data format.
-  arch_type at;
+  oct_mach_info::float_format flt_fmt;
 
   // TRUE if an error has occurred.
   bool fail;
@@ -314,16 +292,19 @@
   // Functions that are defined for all input streams (input streams
   // are those that define is).
 
-  string do_gets (int max_len, bool& err, bool strip_newline, const char *fcn);
+  string do_gets (int max_len, bool& err, bool strip_newline,
+		  const char *fcn);
 
   string getl (int max_len, bool& err);
   string gets (int max_len, bool& err);
 
-  octave_value do_read (int nr, int nc, data_type dt, int skip,
-			arch_type at, int& count);
+  octave_value do_read (int nr, int nc, oct_data_conv::data_type dt,
+			int skip, oct_mach_info::float_format flt_fmt,
+			int& count);
 
-  octave_value read (const Matrix& size, data_type dt, int skip,
-		     arch_type at, int& count);
+  octave_value read (const Matrix& size, oct_data_conv::data_type dt,
+		     int skip, oct_mach_info::float_format flt_fmt,
+		     int& count);
 
   octave_value do_char_scanf (scanf_format_list& fmt_list,
 			      int nr, int nc, int& count);
@@ -345,11 +326,11 @@
 
   int flush (void);
 
-  int do_write (const double *d, int n, data_type dt, int skip,
-		arch_type at);
+  int do_write (const Matrix& m, oct_data_conv::data_type dt, int skip,
+		oct_mach_info::float_format flt_fmt);
 
-  int write (const octave_value& data, data_type dt, int skip,
-	     arch_type at);
+  int write (const octave_value& data, oct_data_conv::data_type dt,
+	     int skip, oct_mach_info::float_format flt_fmt);
 
   int do_printf (printf_format_list& fmt_list, const octave_value_list& args);
 
@@ -400,14 +381,12 @@
 
   int rewind (void);
 
-  octave_value read (const Matrix& size,
-		     octave_base_stream::data_type dt,
-		     int skip, octave_base_stream::arch_type at,
+  octave_value read (const Matrix& size, oct_data_conv::data_type dt,
+		     int skip, oct_mach_info::float_format flt_fmt,
 		     int& count);
 
-  int write (const octave_value& data,
-	     octave_base_stream::data_type dt, int skip,
-	     octave_base_stream::arch_type at);
+  int write (const octave_value& data, oct_data_conv::data_type dt,
+	     int skip, oct_mach_info::float_format flt_fmt);
 
   octave_value scanf (const string& fmt, const Matrix& size, int& count);
 
@@ -436,15 +415,10 @@
 
   int mode (void);
 
-  octave_base_stream::arch_type architecture (void);
+  oct_mach_info::float_format float_format (void);
 
   static string mode_as_string (int mode);
 
-  static string arch_as_string (octave_base_stream::arch_type at);
-
-  static octave_base_stream::data_type string_to_data_type (const string& s);
-  static octave_base_stream::arch_type string_to_arch_type (const string& s);
-
 private:
 
   // The actual representation of this stream.
--- a/src/oct-strstrm.h
+++ b/src/oct-strstrm.h
@@ -34,8 +34,9 @@
 public:
 
   octave_base_strstream (ios::openmode arg_md = ios::out,
-			 arch_type arg_at = at_native)
-    : octave_base_stream (arg_md, arg_at) { }
+			 oct_mach_info::float_format flt_fmt =
+			 oct_mach_info::native)
+    : octave_base_stream (arg_md, flt_fmt) { }
 
   ~octave_base_strstream (void) { }
 
@@ -73,13 +74,15 @@
 
   octave_istrstream (const char *data,
 		     ios::openmode arg_md = ios::out,
-		     arch_type arg_at = at_native)
-    : octave_base_strstream (arg_md, arg_at), is (data) { }
+		     oct_mach_info::float_format flt_fmt =
+		     oct_mach_info::native)
+    : octave_base_strstream (arg_md, flt_fmt), is (data) { }
 
   octave_istrstream (const string& data,
 		     ios::openmode arg_md = ios::out,
-		     arch_type arg_at = at_native)
-    : octave_base_strstream (arg_md, arg_at), is (data.c_str ()) { }
+		     oct_mach_info::float_format flt_fmt =
+		     oct_mach_info::native)
+    : octave_base_strstream (arg_md, flt_fmt), is (data.c_str ()) { }
 
   ~octave_istrstream (void) { }
 
@@ -114,8 +117,9 @@
 public:
 
   octave_ostrstream (ios::openmode arg_md = ios::out,
-		     arch_type arg_at = at_native)
-    : octave_base_strstream (arg_md, arg_at) { }
+		     oct_mach_info::float_format flt_fmt =
+		     oct_mach_info::native)
+    : octave_base_strstream (arg_md, flt_fmt) { }
 
   ~octave_ostrstream (void) { }
 
--- a/src/pr-output.cc
+++ b/src/pr-output.cc
@@ -35,7 +35,7 @@
 #include "CMatrix.h"
 #include "Range.h"
 #include "dMatrix.h"
-#include "float-fmt.h"
+#include "mach-info.h"
 #include "oct-cmplx.h"
 #include "oct-math.h"
 #include "oct-term.h"
@@ -992,10 +992,13 @@
 	  // XXX FIXME XXX -- is it correct to swap bytes for VAX
 	  // formats and not for Cray?
 
+	  oct_mach_info::float_format flt_fmt =
+	    oct_mach_info::native_float_format ();
+
 	  if (hex_format > 1
-	      || native_float_format == OCTAVE_IEEE_BIG
-	      || native_float_format == OCTAVE_CRAY
-	      || native_float_format == OCTAVE_UNKNOWN_FLT_FMT)
+	      || flt_fmt == oct_mach_info::ieee_big_endian
+	      || flt_fmt == oct_mach_info::cray
+	      || flt_fmt == oct_mach_info::unknown)
 	    {
 	      for (size_t i = 0; i < sizeof (double); i++)
 		os.form ("%02x", (int) tmp.i[i]);
@@ -1017,9 +1020,12 @@
 	  // XXX FIXME XXX -- is it correct to swap bytes for VAX
 	  // formats and not for Cray?
 
-	  if (native_float_format == OCTAVE_IEEE_BIG
-	      || native_float_format == OCTAVE_CRAY
-	      || native_float_format == OCTAVE_UNKNOWN_FLT_FMT)
+	  oct_mach_info::float_format flt_fmt =
+	    oct_mach_info::native_float_format ();
+
+	  if (flt_fmt == oct_mach_info::ieee_big_endian
+	      || flt_fmt == oct_mach_info::cray
+	      || flt_fmt == oct_mach_info::unknown)
 	    {
 	      for (size_t i = 0; i < sizeof (double); i++)
 		PRINT_CHAR_BITS (os, tmp.i[i]);
--- a/src/sysdep.cc
+++ b/src/sysdep.cc
@@ -71,7 +71,7 @@
 extern char *term_clrpag;
 extern "C" void _rl_output_character_function ();
 
-#include "float-fmt.h"
+#include "mach-info.h"
 #include "oct-math.h"
 
 #include "defun.h"
@@ -90,9 +90,6 @@
 #define STDIN_FILENO 1
 #endif
 
-// Nonzero if the machine we are running on is big-endian.
-int octave_words_big_endian;
-
 #ifdef NeXT
 extern "C"
 {
@@ -118,22 +115,6 @@
 }
 #endif
 
-static void
-ten_little_endians (void)
-{
-  // Are we little or big endian?  From Harbison & Steele.
-
-  union
-  {
-    long l;
-    char c[sizeof (long)];
-  } u;
-
-  u.l = 1;
-
-  octave_words_big_endian = (u.c[sizeof (long) - 1] == 1);
-}
-
 #if defined (EXCEPTION_IN_MATH)
 extern "C"
 int
@@ -175,13 +156,6 @@
 #endif
 
   octave_ieee_init ();
-
-  int status = float_format_init ();
-
-  if (status < 0)
-    panic ("unrecognized floating point format!");
-
-  ten_little_endians ();
 }
 
 // Set terminal in raw mode.  From less-177.
@@ -529,8 +503,11 @@
 DEFUN (isieee, , ,
   "isieee (): return 1 if host uses IEEE floating point")
 {
-  return (double) (native_float_format == OCTAVE_IEEE_LITTLE
-		   || native_float_format == OCTAVE_IEEE_BIG);
+  oct_mach_info::float_format flt_fmt =
+    oct_mach_info::native_float_format ();
+
+  return (double) (flt_fmt == oct_mach_info::ieee_little_endian
+		   || flt_fmt == oct_mach_info::ieee_big_endian);
 }
 
 #if !defined (HAVE_GETHOSTNAME) && defined (HAVE_SYS_UTSNAME_H)
--- a/src/sysdep.h
+++ b/src/sysdep.h
@@ -39,9 +39,6 @@
 extern int gethostname (char *, int);
 #endif
 
-// Nonzero if the machine we are running on is big-endian.
-extern int octave_words_big_endian;
-
 extern string oct_tilde_expand (const string&);
 
 #endif