/trunk/FreeSpeech/lapackflow/include/f77char.h
# · C++ Header · 107 lines · 62 code · 12 blank · 33 comment · 11 complexity · 1d9e6ef939bd5cd39058a2046e7831d7 MD5 · raw file
- #include <string.h>
- /*
- class CHARACTER
- ===============
- A minimal class used when passing string arguments from C++
- to FORTRAN 77 (received as FORTRAN 77 CHARACTER strings), and
- subsequently returned back to C++ as properly zero terminated
- strings.
- Method used for zero-termination:
- =================================
- When the CHARACTER destructor is activated the zero-termination
- of the c-string is automatically managed. Zero termination is
- also done each time a string array is subscripted using
- CHARACTER::operator()(size_t index)
- FORTRAN Assumptions:
- ====================
- (1) F77 truncates strings when CHARACTER variable is short
- (2) F77 pads variable with blanks when assigned string is short
- (3) F77 represents a string as a pointer followed by a length
- (4) A string array is stored in contiguous memory
- Author: Carsten A. Arnholm, 20-AUG-1995
- Updates:
- 04-MAR-1996 Added features for handling arrays of strings
- 16-MAR-1996 Tested array features, explicit padding included
- 29-JUL-1996 Tested portability to SGI/Unix, moved decl. of destructor
- 04-APR-1997 Using strncpy instead of strcpy in operator=(char* str);
- */
- class CHARACTER {
- public:
- CHARACTER(char* cstring);
- CHARACTER(char* cstring, const size_t lstr);
- ~CHARACTER();
- CHARACTER operator()(size_t index);
- void pad(size_t first,size_t howmany=1);
- void operator=(char* str);
- operator char*();
- public:
- char* rep; // Actual string
- size_t len; // String length
- };
- inline CHARACTER::CHARACTER(char* cstring)
- : rep(cstring), len(strlen(cstring))
- {};
- inline CHARACTER::CHARACTER(char* cstring, const size_t lstr)
- : rep(cstring), len(lstr)
- {
- // find position from where to start padding
- size_t slen = strlen(rep); // upper limit
- size_t actual = (slen < len)? slen : len; // actual <= len.
- for(size_t i=actual;i<len;i++) rep[i]=' '; // Do the padding.
- }
- inline CHARACTER::~CHARACTER() {
- if(rep[len] == '\0') return; // catches string constants
- for(int i=len-1;i>=0;i--) {
- if(rep[i] == '\0') break; // already zero terminated
- if(rep[i] != ' ') { // non-blank discovered, so
- rep[i+1] = '\0'; // zero-terminate and jump out
- break;
- }
- }
- }
- inline CHARACTER CHARACTER::operator()(size_t index)
- {
- // Construct a temporary CHARACTER object for the array element
- // identified by "index" in order to zero-terminate that element
- size_t pos = index*len; // start pos of array element
- CHARACTER element(rep+pos,len); // construct new CHARACTER.
- return element; // destructor called here.
- }
- inline void CHARACTER::pad(size_t first,size_t howmany)
- {
- size_t pos=0,i=0,stop=first+howmany-1;
- for(size_t index=first; index<=stop; index++) {
- pos = index*len;
- size_t slen = strlen(rep+pos); // upper limit
- size_t actual = (slen < len)? slen : len;
- for(i=pos+actual;i<pos+len;i++) rep[i]=' '; // Do the padding.
- }
- }
- inline void CHARACTER::operator=(char* str)
- {
- strncpy(rep,str,len); // this will copy a zero if str < rep
- rep[len-1] = '\0'; // zero terminate in case strncpy did not
- size_t slen = strlen(rep); // upper limit
- size_t actual = (slen < len)? slen : len; // actual <= len.
- for(size_t i=actual;i<len;i++) rep[i]=' '; // Do the padding.
- }
- inline CHARACTER::operator char*()
- {
- return rep;
- }