home *** CD-ROM | disk | FTP | other *** search
/ vis-ftp.cs.umass.edu / vis-ftp.cs.umass.edu.tar / vis-ftp.cs.umass.edu / pub / Software / ASCENDER / umass_foa.tar / mdt_NEW / ISRhdrs / Isrstream.cc < prev    next >
C/C++ Source or Header  |  1995-01-11  |  17KB  |  759 lines

  1. #include <Token.h>
  2. #include <Isrstream.h>
  3.  
  4. /*******************************************************************
  5. * Isrostream                                                       *
  6. *    Isrostream is a subclass of ofstream that extends ofstream to *
  7. * binary as well as ASCII files. Since we are working on UNIX, the *
  8. * underlying file types are the same, the question is whether a    *
  9. * float, for example, is printed as four chars or a string of      *
  10. * decimal chars (e.g. "0.356786"). ASCII files are written as dec. *
  11. * chars, binary as the more compact but unreadable four char       *
  12. * sequence. The same distinctions hold for ints, doubles, etc.     *
  13. *                                                                  *
  14. *    The only oddity is that binary streams are set up to print    *
  15. * nothing if handed a constant char *, but to print the character  *
  16. * string if handed a regular char *. (Constant strings are usually *
  17. * padding for human eyes, and since they are constant they do need *
  18. * to be stored: the reading program can re-insert them.)           *
  19. *                                                                  *
  20. *    This file is organized as:                                    *
  21. *      1) initialization functions                                 *
  22. *      2) primitive datatype <<'s                                  *
  23. *******************************************************************/
  24.  
  25. static int supply_warnings = 1;
  26.  
  27. /* A helper function to verify legal format and type values. 
  28.    Returns 0 if everything is OK, -1 if illegal format, -2 
  29.    if illegal type. */
  30. int check_format_and_type(int format, int type)
  31. {
  32.   if ((format != BINARY) && (format != ASCII)) {
  33.     cerr << "Unknown stream format: " << format << endl;
  34.     return(-1);
  35.   }
  36.   if ((type != ISR) && (type != FORIEGN)) {
  37.     cerr << "Unknown stream type: " << type << endl;
  38.     return(-2);
  39.   }
  40.   return(0);
  41. }
  42.  
  43.  
  44. Isrostream::Isrostream(int stream_format/* = BINARY*/, int stream_type/* = ISR*/)
  45. {
  46.   /* check that stream_type is valid */
  47.   if (0 != check_format_and_type(stream_format, stream_type)) exit(-1);
  48.   format = stream_format;
  49.   type = stream_type;
  50.   name = NULL;
  51.   state = Closed;
  52.   str = new ofstream;
  53. }
  54.  
  55. Isrostream::Isrostream(char *filename, int stream_format/* = BINARY*/, int stream_type/* = ISR*/)
  56. {
  57.   /* check that stream_type is valid */
  58.   if (0 != check_format_and_type(stream_format, stream_type)) exit(-1);
  59.   format = stream_format;
  60.   type = stream_type;
  61.   name = filename;
  62.   str = new ofstream(filename, ios::out);
  63.   state = Open;
  64. }
  65.  
  66. Isrostream::~Isrostream()
  67. {
  68.   str->close();
  69.   delete str;
  70. }
  71.  
  72. Isristream::Isristream(int stream_format/* = BINARY*/, int stream_type/* = ISR*/)
  73. {
  74.   /* check that stream_type is valid */
  75.   if (0 != check_format_and_type(stream_format, stream_type)) exit(-1);
  76.   format = stream_format;
  77.   type = stream_type;
  78.   name = NULL;
  79.   str = new ifstream;
  80.   state = Closed;
  81.   tokentype_table = NULL;
  82.   fileVersion = 0;
  83.   byteSwapNeeded = ISR_FALSE;
  84. }
  85.  
  86. Isristream::Isristream(char *filename, int stream_format/* = BINARY*/, int stream_type/* = ISR*/)
  87. {
  88.   /* check that stream_type is valid */
  89.   if (0 != check_format_and_type(stream_format, stream_type)) exit(-1);
  90.   format = stream_format;
  91.   type = stream_type;
  92.   tokentype_table = NULL;
  93.   name = filename;
  94.   str = new ifstream(filename, ios::in);
  95.   state = Open;
  96.   fileVersion = 0;
  97.   byteSwapNeeded = ISR_FALSE;
  98. }
  99.  
  100. Isristream::~Isristream()
  101. {
  102.   str->close();
  103.   delete str;
  104. }
  105. /*************************************************************/
  106.  
  107. void Isristream::read_tokentype_table(int tokentype_count, int max_tokentype)
  108. {
  109.   int i, index;
  110.   char *namestring;
  111.  
  112.   tokentype_table = new TypeDirectory(max_tokentype);
  113.  
  114.   for(i=0; i < tokentype_count; i++) {
  115.     *this >> index;
  116.  
  117.     namestring = read_string(MAX_TOKENTYPE_NAME_LENGTH);
  118.  
  119.     if ((0 > index) || (index > max_tokentype)) {
  120.       cerr << "tokentype index out of bounds\n";
  121.       exit(-1);
  122.     }
  123.     if (namestring[0] == '\0') {
  124.       cerr << "unable to read tokentype name\n";
  125.       exit(-1);
  126.     }
  127.     if (0 > tokentype_table->add_entry(index, namestring)) {
  128.       cerr << "file contains tokentype " << &namestring << " not otherwise known to system\n";
  129.       exit(-1);
  130.     }
  131.   }
  132. }
  133.  
  134. /*************************************************************/
  135.  
  136. Isrostream& operator << (Isrostream& os, const short val)
  137. {
  138.   if (os.format == ASCII) {
  139.     *os.str << val;
  140.   }
  141.   else {
  142.     char *ptr;
  143.     unsigned int i;
  144.  
  145.     for (i = 0, ptr = (char *)&val; i < sizeof(short); i++, ptr++) {
  146.       os.str->put(*ptr);
  147.     }
  148.   }
  149.   return os;
  150. }
  151.  
  152. Isrostream& operator << (Isrostream& os, const unsigned short val)
  153. {
  154.   if (os.format == ASCII) {
  155.     *os.str << val;
  156.   }
  157.   else {
  158.     char *ptr;
  159.     unsigned int i;
  160.  
  161.     for (i = 0, ptr = (char *)&val; i < sizeof(unsigned short); i++, ptr++) {
  162.       os.str->put(*ptr);
  163.     }
  164.   }
  165.   return os;
  166. }
  167.  
  168. Isrostream& operator << (Isrostream& os, const int val)
  169. {
  170.   if (os.format == ASCII) {
  171.     *os.str << val;
  172.   }
  173.   else {
  174.     char *ptr;
  175.     unsigned int i;
  176.  
  177.     for (i = 0, ptr = (char *)&val; i < sizeof(int); i++, ptr++) {
  178.       os.str->put(*ptr);
  179.     }
  180.   }
  181.   return os;
  182. }
  183.  
  184. Isrostream& operator << (Isrostream& os, const unsigned int val)
  185. {
  186.   if (os.format == ASCII) {
  187.     *os.str << val;
  188.   }
  189.   else {
  190.     char *ptr;
  191.     unsigned int i;
  192.  
  193.     for (i = 0, ptr = (char *)&val; i < sizeof(unsigned int); i++, ptr++) {
  194.       os.str->put(*ptr);
  195.     }
  196.   }
  197.   return os;
  198. }
  199.  
  200. Isrostream& operator << (Isrostream& os, const long val)
  201. {
  202.   if (os.format == ASCII) {
  203.     *os.str << val;
  204.   }
  205.   else {
  206.     char *ptr;
  207.     unsigned int i;
  208.  
  209.     for (i = 0, ptr = (char *)&val; i < sizeof(long); i++, ptr++) {
  210.       os.str->put(*ptr);
  211.     }
  212.   }
  213.   return os;
  214. }
  215.  
  216. Isrostream& operator << (Isrostream& os, const unsigned long val)
  217. {
  218.   if (os.format == ASCII) {
  219.     *os.str << val;
  220.   }
  221.   else {
  222.     char *ptr;
  223.     unsigned int i;
  224.  
  225.     for (i = 0, ptr = (char *)&val; i < sizeof(unsigned long); i++, ptr++) {
  226.       os.str->put(*ptr);
  227.     }
  228.   }
  229.   return os;
  230. }
  231.  
  232. Isrostream& operator << (Isrostream& os, const float val)
  233. {
  234.   if (os.format == ASCII) {
  235.     *os.str << val;
  236.   }
  237.   else {
  238.     char *ptr;
  239.     unsigned int i;
  240.  
  241.     for (i = 0, ptr = (char *)&val; i < sizeof(float); i++, ptr++) {
  242.       os.str->put(*ptr);
  243.     }
  244.   }
  245.   return os;
  246. }
  247.  
  248. Isrostream& operator << (Isrostream& os, const double val)
  249. {
  250.   if (os.format == ASCII) {
  251.     *os.str << val;
  252.   }
  253.   else {
  254.     char *ptr;
  255.     unsigned int i;
  256.  
  257.     for (i = 0, ptr = (char *)&val; i < sizeof(double); i++, ptr++) {
  258.       os.str->put(*ptr);
  259.     }
  260.   }
  261.   return os;
  262. }
  263.  
  264.  
  265. Isrostream& operator << (Isrostream& os, const char *string)
  266. {
  267.   if (os.format == ASCII) {
  268.     *os.str << string;
  269.   }
  270.   /* if stream is binary, do nothing! */
  271.   return os;
  272. }
  273.  
  274. Isrostream& operator << (Isrostream& os, const char ch)
  275. {
  276.   os.str->put(ch);
  277.   return os;
  278. }
  279.  
  280. /* for printing strings, even to binary files. */
  281. void Isrostream::print_string(char *string)
  282. {
  283.   *str  << string;
  284.   if (format == ASCII) *str << " ";
  285.   else str->put('\0');
  286. }
  287.  
  288. int operator! (Isrostream& os)
  289. {
  290.   return !(*os.str);
  291. }
  292.  
  293. Isrostream& Isrostream::write(const char *s, int n)
  294. {
  295.   str->write(s, n);
  296.   return *this;
  297. }
  298.  
  299. void Isrostream::open (char *filename, int mode)
  300. {
  301.   if (state == Closed) {
  302.     name = filename;
  303.     str->open(filename, mode);
  304.     state = Open;
  305.   }
  306. }
  307.   
  308.  
  309. void Isrostream::close()
  310. {
  311.   if (state == Open) {
  312.     str->close();
  313.     state = Closed;
  314.   }
  315. }
  316.  
  317. /************************************************************/
  318.  
  319. char *Isristream::read_string(int max_size)
  320. {
  321.   char *string = (char *)malloc(max_size * sizeof(char));
  322.   if (NULL == string) {
  323.     cerr << "Error: unable to allocate memory for string.\n";
  324.     return NULL;
  325.   }
  326.  
  327.   if (format == ASCII) {
  328.     *str >> string;  /* add limiter against overflow */
  329.     return string;
  330.   }
  331.   else {
  332.     for (int i=0; i < max_size; i++) {
  333.       string[i] = str->get();
  334.       if (string[i] == '\0') return string;
  335.     }
  336.     cerr << "string longer than alloted length\n";
  337.     return NULL;
  338.   }
  339. }
  340.  
  341. Isristream& operator >> (Isristream& is, short& val)
  342. {
  343.   if (is.format == ASCII) {
  344.     *is.str >> val;
  345.   }
  346.   else {
  347.     char *ptr;
  348.     unsigned int i;
  349.  
  350.     if (is.byteSwapNeeded)
  351.     {
  352.       for (i = 0, ptr = ((char *)&val)+sizeof(short)-1;
  353.        i < sizeof(short); i++, ptr--) {
  354.         is.str->get(*ptr);
  355.       }
  356.     } else
  357.     {    
  358.       for (i = 0, ptr = (char *)&val; i < sizeof(short); i++, ptr++) {
  359.         is.str->get(*ptr);
  360.       }
  361.     }
  362.   }
  363.   return is;
  364. }
  365.  
  366. Isristream& operator >> (Isristream& is, unsigned short& val)
  367. {
  368.   if (is.format == ASCII) {
  369.     *is.str >> val;
  370.   }
  371.   else {
  372.     char *ptr;
  373.     unsigned int i;
  374.  
  375.     if (is.byteSwapNeeded)
  376.     {
  377.       for (i = 0, ptr = ((char *)&val)+sizeof(unsigned short)-1;
  378.        i < sizeof(unsigned short); i++, ptr--) {
  379.         is.str->get(*ptr);
  380.       }
  381.     } else
  382.     {
  383.       for (i = 0, ptr = (char *)&val; i < sizeof(unsigned short); i++, ptr++) {
  384.         is.str->get(*ptr);
  385.       }
  386.     }
  387.   }
  388.   return is;
  389. }
  390.  
  391. Isristream& operator >> (Isristream& is, int& val)
  392. {
  393.   if (is.format == ASCII) {
  394.     *is.str >> val;
  395.   }
  396.   else {
  397.     char *ptr;
  398.     unsigned int i;
  399.  
  400.     if (is.byteSwapNeeded)
  401.     {
  402.       for (i = 0, ptr = ((char *)&val)+sizeof(int)-1; i < sizeof(int); i++, ptr++) {
  403.         is.str->get(*ptr);
  404.       }
  405.     } else
  406.     {
  407.       for (i = 0, ptr = (char *)&val; i < sizeof(int); i++, ptr++) {
  408.     is.str->get(*ptr);
  409.       }
  410.     }
  411.   }
  412.   return is;
  413. }
  414.  
  415. Isristream& operator >> (Isristream& is, unsigned int& val)
  416. {
  417.   if (is.format == ASCII) {
  418.     *is.str >> val;
  419.   }
  420.   else {
  421.     char *ptr;
  422.     unsigned int i;
  423.  
  424.     if (is.byteSwapNeeded)
  425.     {
  426.         for (i = 0, ptr = ((char *)&val)+sizeof(unsigned int)-1; i < sizeof(unsigned int); i++, ptr--) {
  427.       is.str->get(*ptr);
  428.     }
  429.     } else
  430.     {
  431.         for (i = 0, ptr = (char *)&val; i < sizeof(unsigned int); i++, ptr++) {
  432.       is.str->get(*ptr);
  433.     }
  434.     }
  435.   }
  436.   return is;
  437. }
  438.  
  439.  
  440. Isristream& operator >> (Isristream& is, long& val)
  441. {
  442.   if (is.format == ASCII) {
  443.     *is.str >> val;
  444.   }
  445.   else {
  446.     char *ptr;
  447.     unsigned int i;
  448.  
  449.     if (is.byteSwapNeeded)
  450.     {
  451.         for (i = 0, ptr = ((char *)&val)+sizeof(long)-1; i < sizeof(long); i++, ptr--) {
  452.       is.str->get(*ptr);
  453.     }
  454.     } else
  455.     {
  456.         for (i = 0, ptr = (char *)&val; i < sizeof(long); i++, ptr++) {
  457.       is.str->get(*ptr);
  458.     }
  459.     }
  460.   }
  461.   return is;
  462. }
  463.  
  464. Isristream& operator >> (Isristream& is, unsigned long& val)
  465. {
  466.   if (is.format == ASCII) {
  467.     *is.str >> val;
  468.   }
  469.   else {
  470.     char *ptr;
  471.     unsigned int i;
  472.  
  473.     if (is.byteSwapNeeded)
  474.     {
  475.         for (i = 0, ptr = ((char *)&val)+sizeof(unsigned long)-1; i < sizeof(unsigned long); i++, ptr--) {
  476.       is.str->get(*ptr);
  477.     }
  478.     } else
  479.     {
  480.         for (i = 0, ptr = (char *)&val; i < sizeof(unsigned long); i++, ptr++) {
  481.       is.str->get(*ptr);
  482.     }
  483.     }
  484.   }
  485.   return is;
  486. }
  487.  
  488. /* read_cstring : a helper function that returns True and advances the filepointer
  489.    if the next item in the file is cstring, but doesn't alter the file otherwise. 
  490.    It is different from using >> to read a constant string because 1) it does not
  491.    print warnings and 2) it first clears the stream state (assuming that it had
  492.    failed trying to read a float) and then returns the resulting state. */
  493. int Isristream::read_cstring (const char *cstring)
  494. {
  495.   supply_warnings = 0;
  496.   str->clear();
  497.   *this >> cstring;
  498.   supply_warnings = 1;
  499.   return str->good();
  500. }
  501.  
  502.  
  503. Isristream& operator >> (Isristream& is, float& val)
  504. {
  505.   if (!is) return is;
  506.  
  507.   if (is.format == ASCII) {
  508.     *is.str >> val;
  509.     if (is.str->fail()) {
  510.       if (is.str->bad()) return is;
  511.       if (is.read_cstring("NaN")) val = (float) Token::NaN_Value.d;
  512.       else if (is.read_cstring("Infinity")) val = (float) Token::PosInf_Value.d;
  513.       else if (is.read_cstring("-Infinity")) val = (float) Token::NegInf_Value.d;
  514.     }
  515.   }
  516.   else {
  517.     char *ptr;
  518.     unsigned int i;
  519.  
  520.     if (is.byteSwapNeeded)
  521.     {
  522.         for (i = 0, ptr = ((char *)&val)+sizeof(float)-1; i < sizeof(float); i++, ptr--) {
  523.       is.str->get(*ptr);
  524.     }
  525.     } else
  526.     {
  527.         for (i = 0, ptr = (char *)&val; i < sizeof(float); i++, ptr++) {
  528.       is.str->get(*ptr);
  529.     }
  530.     }
  531.   }
  532.   return is;
  533. }
  534.  
  535. Isristream& operator >> (Isristream& is, double& val)
  536. {
  537.   if (is.format == ASCII) {
  538.     *is.str >> val;
  539.     if (is.str->fail()) {
  540.       if (is.str->bad()) return is;
  541.       if (is.read_cstring("NaN")) val = Token::NaN_Value.d;
  542.       else if (is.read_cstring("Infinity")) val = Token::PosInf_Value.d;
  543.       else if (is.read_cstring("-Infinity")) val = Token::NegInf_Value.d;
  544.     }
  545.   }
  546.   else {
  547.     char *ptr;
  548.     unsigned int i;
  549.  
  550.     if (is.byteSwapNeeded)
  551.     {
  552.         for (i = 0, ptr = ((char *)&val)+sizeof(double)-1; i < sizeof(double); i++, ptr--) {
  553.       is.str->get(*ptr);
  554.     }
  555.     } else
  556.     {
  557.         for (i = 0, ptr = (char *)&val; i < sizeof(double); i++, ptr++) {
  558.       is.str->get(*ptr);
  559.     }
  560.     }
  561.   }
  562.   return is;
  563. }
  564.  
  565. Isristream& operator >> (Isristream& is, const char *string)
  566. {
  567.   int ctr;
  568.   if (!is) return is;
  569.  
  570.   if (is.format == ASCII) {
  571.     char *strptr;
  572.     char ch;
  573.  
  574.     /* strip off leading whitespace from constant string */
  575.     strptr = (char *)string;
  576.     while(isspace(*strptr)) strptr++;
  577.     if (*strptr == '\0') return is;
  578.  
  579.     /* strip off leading whitespace from file */
  580.     ch = is.str->get();
  581.     while (isspace(ch))
  582.       ch = is.str->get();
  583.     if (ch == EOF) return is;
  584.     is.str->putback(ch);
  585.  
  586.     /* compare constant and I/O stream strings */
  587.     for(ctr = 0; '\0' != *strptr; strptr++, ctr++) {
  588.       ch = is.str->get();
  589.       if (ch != *strptr) {
  590.     is.str->putback(ch);
  591.     for (; ctr > 0; ctr--) {
  592.       strptr--;
  593.       is.str->putback(*strptr);
  594.     }
  595.     if (supply_warnings) {
  596.       cerr << "warning: ASCII input did not match constant string\n";
  597.       cerr << "   looking for " << string << "; next char is " << ch << endl;
  598.     }
  599.         /* was ios::badbit */
  600.     is.str->clear(ios::failbit | is.str->rdstate() );
  601.     return is;
  602.       }
  603.     }
  604.   }
  605.   return is;
  606. }
  607.     
  608. Isristream& operator >> (Isristream& is, const char ch)
  609. {
  610.   char file_ch;
  611.  
  612.   if (!is) return is;
  613.   if (isspace(ch)) return is;
  614.  
  615.   /* strip off leading whitespace from file */
  616.   file_ch = is.str->get();
  617.   while (isspace(file_ch))
  618.     file_ch = is.str->get();
  619.   if (file_ch == EOF) return is;
  620.  
  621.   if (file_ch != ch) {
  622.     cerr << "warning: ASCII input character did not match expected character\n";
  623.     cerr << "   looking for " << ch << "; next char is " << file_ch << endl;
  624.     is.str->clear(ios::badbit | is.str->rdstate() );
  625.   }
  626.  
  627.   return is;
  628. }
  629.  
  630.   
  631.  
  632. int operator! (Isristream& is)
  633. {
  634.   return !(*is.str);
  635. }
  636.  
  637. void Isristream::putback(char ch)
  638. {
  639.   str->putback(ch);
  640. }
  641.  
  642. char Isristream::get()
  643. {
  644.   return str->get();
  645. }
  646.  
  647. Isristream& Isristream::read(char *s, int n)
  648. {
  649.   str->read(s, n);
  650.   return *this;
  651. }
  652.  
  653. void Isristream::open(char *filename, int mode)
  654. {
  655.   if (state == Closed) {
  656.     name = filename;
  657.     str->open(filename, mode);
  658.     state = Open;
  659.   }
  660. }
  661.  
  662. void Isristream::close ()
  663. {
  664.   if (state == Closed) {
  665.     str->close();
  666.     state = Closed;
  667.   }
  668. }
  669.  
  670. void Isristream::read_magic_header()
  671. {
  672.   if (format == ASCII)
  673.   {
  674.     if (read_cstring(MagicASCII))
  675.     {
  676.       *this >> " fileVersion: ";
  677.       *this >> fileVersion;
  678.     } else
  679.     {
  680.       str->clear();
  681.       fileVersion = 0;
  682.     }
  683.   } else {
  684.     int ctr = 0;
  685.     char ch;
  686.     for (char *p = MagicB1;*p != '\0';p++,ctr++)
  687.     {
  688.       ch = str->get();
  689.       if (ch != *p) break;
  690.     }
  691.     if (*p != '\0')
  692.     {
  693.       str->putback(ch);
  694.       for (; ctr > 0; ctr--)
  695.       {
  696.           p--;
  697.           str->putback(*p);
  698.       }
  699.       fileVersion = 0;
  700.       byteSwapNeeded = ISR_FALSE;
  701.       return;
  702.     }
  703.     unsigned short int test;
  704.     byteSwapNeeded = ISR_FALSE;
  705.     *this >> test;
  706.     if (test == MagicB2) byteSwapNeeded = ISR_FALSE;
  707.     else byteSwapNeeded = ISR_TRUE;
  708.     *this >> fileVersion;
  709.   }
  710. }
  711.  
  712. void Isrostream::write_magic_header()
  713. {
  714.   if (format == ASCII)
  715.   {
  716.     *this << MagicASCII;
  717.     *this << " fileVersion: ";
  718.     *this << (unsigned short int)FileVersion;
  719.     *this << " ";
  720.   } else
  721.   {
  722.     unsigned short bsw_test = (unsigned short int)MagicB2,
  723.                fileVersion = (unsigned short int)FileVersion;
  724.     *str  << MagicB1;
  725.     *this << bsw_test;
  726.     *this << fileVersion;
  727.   }
  728. }
  729.     
  730.  
  731.  
  732.  
  733. /**************************************************************
  734. int match_stream_to_filename(Isrstream& stream, char *filename)
  735. {
  736.   if (NULL != strstr(filename, ".isrb")) {
  737.     stream.format = BINARY;
  738.     stream.type = ISR;
  739.     return(0);
  740.   }
  741.   if (NULL != strstr(filename, ".isra")) {
  742.     stream.format = ASCII;
  743.     stream.type = ISR;
  744.     return(0);
  745.   }
  746.   if (NULL != strstr(filename, ".plane")) {
  747.     stream.format = BINARY;
  748.     stream.type = FORIEGN;
  749.     return(0);
  750.   }
  751.   if (NULL != strstr(filename, ".viff")) {
  752.     stream.format = BINARY;
  753.     stream.type = VIFF;
  754.     return(0);
  755.   }
  756.   return(-1);
  757. }
  758. *************************************************/
  759.