/trunk/FreeSpeech/lapackflow/include/f77char.h

# · C++ Header · 107 lines · 62 code · 12 blank · 33 comment · 11 complexity · 1d9e6ef939bd5cd39058a2046e7831d7 MD5 · raw file

  1. #include <string.h>
  2. /*
  3. class CHARACTER
  4. ===============
  5. A minimal class used when passing string arguments from C++
  6. to FORTRAN 77 (received as FORTRAN 77 CHARACTER strings), and
  7. subsequently returned back to C++ as properly zero terminated
  8. strings.
  9. Method used for zero-termination:
  10. =================================
  11. When the CHARACTER destructor is activated the zero-termination
  12. of the c-string is automatically managed. Zero termination is
  13. also done each time a string array is subscripted using
  14. CHARACTER::operator()(size_t index)
  15. FORTRAN Assumptions:
  16. ====================
  17. (1) F77 truncates strings when CHARACTER variable is short
  18. (2) F77 pads variable with blanks when assigned string is short
  19. (3) F77 represents a string as a pointer followed by a length
  20. (4) A string array is stored in contiguous memory
  21. Author: Carsten A. Arnholm, 20-AUG-1995
  22. Updates:
  23. 04-MAR-1996 Added features for handling arrays of strings
  24. 16-MAR-1996 Tested array features, explicit padding included
  25. 29-JUL-1996 Tested portability to SGI/Unix, moved decl. of destructor
  26. 04-APR-1997 Using strncpy instead of strcpy in operator=(char* str);
  27. */
  28. class CHARACTER {
  29. public:
  30. CHARACTER(char* cstring);
  31. CHARACTER(char* cstring, const size_t lstr);
  32. ~CHARACTER();
  33. CHARACTER operator()(size_t index);
  34. void pad(size_t first,size_t howmany=1);
  35. void operator=(char* str);
  36. operator char*();
  37. public:
  38. char* rep; // Actual string
  39. size_t len; // String length
  40. };
  41. inline CHARACTER::CHARACTER(char* cstring)
  42. : rep(cstring), len(strlen(cstring))
  43. {};
  44. inline CHARACTER::CHARACTER(char* cstring, const size_t lstr)
  45. : rep(cstring), len(lstr)
  46. {
  47. // find position from where to start padding
  48. size_t slen = strlen(rep); // upper limit
  49. size_t actual = (slen < len)? slen : len; // actual <= len.
  50. for(size_t i=actual;i<len;i++) rep[i]=' '; // Do the padding.
  51. }
  52. inline CHARACTER::~CHARACTER() {
  53. if(rep[len] == '\0') return; // catches string constants
  54. for(int i=len-1;i>=0;i--) {
  55. if(rep[i] == '\0') break; // already zero terminated
  56. if(rep[i] != ' ') { // non-blank discovered, so
  57. rep[i+1] = '\0'; // zero-terminate and jump out
  58. break;
  59. }
  60. }
  61. }
  62. inline CHARACTER CHARACTER::operator()(size_t index)
  63. {
  64. // Construct a temporary CHARACTER object for the array element
  65. // identified by "index" in order to zero-terminate that element
  66. size_t pos = index*len; // start pos of array element
  67. CHARACTER element(rep+pos,len); // construct new CHARACTER.
  68. return element; // destructor called here.
  69. }
  70. inline void CHARACTER::pad(size_t first,size_t howmany)
  71. {
  72. size_t pos=0,i=0,stop=first+howmany-1;
  73. for(size_t index=first; index<=stop; index++) {
  74. pos = index*len;
  75. size_t slen = strlen(rep+pos); // upper limit
  76. size_t actual = (slen < len)? slen : len;
  77. for(i=pos+actual;i<pos+len;i++) rep[i]=' '; // Do the padding.
  78. }
  79. }
  80. inline void CHARACTER::operator=(char* str)
  81. {
  82. strncpy(rep,str,len); // this will copy a zero if str < rep
  83. rep[len-1] = '\0'; // zero terminate in case strncpy did not
  84. size_t slen = strlen(rep); // upper limit
  85. size_t actual = (slen < len)? slen : len; // actual <= len.
  86. for(size_t i=actual;i<len;i++) rep[i]=' '; // Do the padding.
  87. }
  88. inline CHARACTER::operator char*()
  89. {
  90. return rep;
  91. }