Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members

f77char.h

00001 #include <string.h>
00002 
00003 /*
00004      class CHARACTER
00005      ===============
00006      A minimal class used when passing string arguments from C++
00007      to FORTRAN 77 (received as FORTRAN 77 CHARACTER strings), and
00008      subsequently returned back to C++ as properly zero terminated
00009      strings.
00010 
00011      Method used for zero-termination:
00012      =================================
00013      When the CHARACTER destructor is activated the zero-termination
00014      of the c-string is automatically managed. Zero termination is
00015      also done each time a string array is subscripted using
00016      CHARACTER::operator()(size_t index)
00017 
00018      FORTRAN Assumptions:
00019      ====================
00020      (1) F77 truncates strings when CHARACTER variable is short
00021      (2) F77 pads variable with blanks when assigned string is short
00022      (3) F77 represents a string as a pointer followed by a length
00023      (4) A string array is stored in contiguous memory
00024 
00025      Author: Carsten A. Arnholm, 20-AUG-1995
00026 
00027      Updates:
00028          04-MAR-1996 Added features for handling arrays of strings
00029          16-MAR-1996 Tested array features, explicit padding included
00030          29-JUL-1996 Tested portability to SGI/Unix, moved decl. of destructor
00031          04-APR-1997 Using strncpy instead of strcpy in operator=(char* str);
00032    */
00033 
00034 class CHARACTER {
00035   public:
00036    CHARACTER(char* cstring);
00037    CHARACTER(char* cstring, const size_t lstr);
00038    ~CHARACTER();
00039    CHARACTER operator()(size_t index);
00040    void  pad(size_t first,size_t howmany=1);
00041    void  operator=(char* str);
00042    operator char*();
00043   public:
00044    char*   rep;  // Actual string
00045    size_t  len;  // String length
00046 };
00047 
00048 inline CHARACTER::CHARACTER(char* cstring)
00049    : rep(cstring), len(strlen(cstring))
00050 {};
00051 
00052 inline CHARACTER::CHARACTER(char* cstring, const size_t lstr)
00053    : rep(cstring), len(lstr)
00054 {
00055    // find position from where to start padding
00056    size_t slen   = strlen(rep);                // upper limit
00057    size_t actual = (slen < len)? slen : len;   // actual <= len.
00058    for(size_t i=actual;i<len;i++) rep[i]=' ';  // Do the padding.
00059 }
00060 
00061 inline CHARACTER::~CHARACTER() {
00062    if(rep[len] == '\0') return;     // catches string constants
00063 
00064    for(int i=len-1;i>=0;i--) {
00065       if(rep[i] == '\0') break;      // already zero terminated
00066 
00067       if(rep[i] != ' ') {            // non-blank discovered, so
00068          rep[i+1] = '\0';            // zero-terminate and jump out
00069          break;
00070       }
00071    }
00072 }
00073 
00074 inline CHARACTER CHARACTER::operator()(size_t index)
00075 {
00076    // Construct a temporary CHARACTER object for the array element
00077    // identified by "index" in order to zero-terminate that element
00078    size_t pos = index*len;          // start pos of array element
00079    CHARACTER element(rep+pos,len);  // construct new CHARACTER.
00080    return element;                  // destructor called here.
00081 }
00082 
00083 inline void  CHARACTER::pad(size_t first,size_t howmany)
00084 {
00085 
00086    size_t pos=0,i=0,stop=first+howmany-1;
00087    for(size_t index=first; index<=stop; index++) {
00088       pos = index*len;
00089       size_t slen   = strlen(rep+pos);             // upper limit
00090       size_t actual = (slen < len)? slen : len;
00091       for(i=pos+actual;i<pos+len;i++) rep[i]=' ';  // Do the padding.
00092    }
00093 }
00094 
00095 inline void CHARACTER::operator=(char* str)
00096 {
00097    strncpy(rep,str,len);    // this will copy a zero if str < rep
00098    rep[len-1] = '\0';       // zero terminate in case strncpy did not
00099    size_t slen   = strlen(rep);                // upper limit
00100    size_t actual = (slen < len)? slen : len;   // actual <= len.
00101    for(size_t i=actual;i<len;i++) rep[i]=' ';  // Do the padding.
00102 }
00103 
00104 inline CHARACTER::operator char*()
00105 {
00106    return rep;
00107 }

Generated on Wed Oct 5 14:28:55 2005 for FlowDesigner by  doxygen 1.4.4