You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

173 lines
5.6 KiB

25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
25 years ago
  1. // Strings.
  2. #ifndef _CL_STRING_H
  3. #define _CL_STRING_H
  4. #include "cln/object.h"
  5. #include "cln/io.h"
  6. #include "cln/abort.h"
  7. #include <cstring>
  8. namespace cln {
  9. struct cl_string;
  10. // General, reference counted and garbage collected strings.
  11. struct cl_heap_string : public cl_heap {
  12. private:
  13. unsigned long length; // length (in characters)
  14. char data[1]; // the characters, plus a '\0' at the end
  15. // Standard allocation disabled.
  16. void* operator new (size_t size) { (void)size; cl_abort(); return (void*)1; }
  17. // Standard deallocation disabled.
  18. void operator delete (void* ptr) { (void)ptr; cl_abort(); }
  19. // No default constructor.
  20. cl_heap_string ();
  21. private:
  22. // Friend declarations. They are for the compiler. Just ignore them.
  23. friend class cl_string;
  24. friend cl_heap_string* cl_make_heap_string (unsigned long len);
  25. friend cl_heap_string* cl_make_heap_string (const char * s);
  26. friend cl_heap_string* cl_make_heap_string (const char * ptr, unsigned long len);
  27. friend const cl_string operator+ (const cl_string& str1, const cl_string& str2);
  28. friend const cl_string operator+ (const char* str1, const cl_string& str2);
  29. friend const cl_string operator+ (const cl_string& str1, const char* str2);
  30. };
  31. struct cl_string : public cl_gcpointer {
  32. public:
  33. // Conversion to simple string.
  34. // NOTE! The resulting pointer is valid only as long as the string
  35. // is live, i.e. you must keep the string in a variable until you
  36. // are done with the pointer to the characters.
  37. const char * asciz () const
  38. {
  39. return &((cl_heap_string*)pointer)->data[0];
  40. }
  41. // Return the length (number of characters).
  42. unsigned long length () const
  43. {
  44. return ((cl_heap_string*)pointer)->length;
  45. }
  46. // Return a specific character.
  47. char operator[] (unsigned long i) const
  48. {
  49. if (!(i < length())) cl_abort(); // Range check.
  50. return ((cl_heap_string*)pointer)->data[i];
  51. }
  52. // New ANSI C++ compilers also want the following.
  53. char operator[] (unsigned int i) const
  54. { return operator[]((unsigned long)i); }
  55. char operator[] (long i) const
  56. { return operator[]((unsigned long)i); }
  57. char operator[] (int i) const
  58. { return operator[]((unsigned long)i); }
  59. // Constructors.
  60. cl_string ();
  61. cl_string (const cl_string&);
  62. cl_string (const char * s);
  63. cl_string (const char * ptr, unsigned long len);
  64. // Assignment operators.
  65. cl_string& operator= (const cl_string&);
  66. cl_string& operator= (const char *);
  67. // Private pointer manipulations.
  68. operator cl_heap_string* () const;
  69. cl_string (cl_heap_string* str) { pointer = str; }
  70. cl_string (cl_private_thing p) : cl_gcpointer (p) {}
  71. };
  72. CL_DEFINE_COPY_CONSTRUCTOR2(cl_string,cl_gcpointer)
  73. CL_DEFINE_ASSIGNMENT_OPERATOR(cl_string,cl_string)
  74. inline cl_string::cl_string (const char * s)
  75. {
  76. extern cl_heap_string* cl_make_heap_string (const char *);
  77. pointer = cl_make_heap_string(s);
  78. }
  79. inline cl_string& cl_string::operator= (const char * s)
  80. {
  81. extern cl_heap_string* cl_make_heap_string (const char *);
  82. cl_heap_string* tmp = cl_make_heap_string(s);
  83. cl_dec_refcount(*this);
  84. pointer = tmp;
  85. return *this;
  86. }
  87. // Length.
  88. inline unsigned long strlen (const cl_string& str)
  89. {
  90. return str.length();
  91. }
  92. // Conversion to `const char *'.
  93. inline const char * asciz (const char * s) { return s; }
  94. inline const char * asciz (const cl_string& s) { return s.asciz(); }
  95. // Comparison.
  96. inline bool equal (const cl_string& str1, const cl_string& str2)
  97. {
  98. return str1.length() == str2.length()
  99. && !strcmp(str1.asciz(), str2.asciz());
  100. }
  101. inline bool equal (const char * str1, const cl_string& str2)
  102. {
  103. return !strcmp(str1, str2.asciz());
  104. }
  105. inline bool equal (const cl_string& str1, const char * str2)
  106. {
  107. return !strcmp(str1.asciz(), str2);
  108. }
  109. // Private pointer manipulations. Never throw away a `struct cl_heap_string *'!
  110. inline cl_string::operator cl_heap_string* () const
  111. {
  112. cl_heap_string* hpointer = (cl_heap_string*)pointer;
  113. cl_inc_refcount(*this);
  114. return hpointer;
  115. }
  116. inline cl_string::cl_string ()
  117. {
  118. extern const cl_string cl_null_string;
  119. pointer = (cl_heap_string*) cl_null_string;
  120. }
  121. CL_REQUIRE(cl_st_null)
  122. // Hash code.
  123. extern unsigned long hashcode (const cl_string& str);
  124. // Output.
  125. extern void fprint (std::ostream& stream, const cl_string& str);
  126. CL_DEFINE_PRINT_OPERATOR(cl_string)
  127. // Input.
  128. // Reads a line. Up to delim. The delimiter character is not placed in the
  129. // resulting string. The delimiter character is kept in the input stream.
  130. // If EOF is encountered, the stream's eofbit is set.
  131. extern const cl_string cl_fget (std::istream& stream, char delim = '\n');
  132. // Reads a line. Up to delim. The delimiter character is not placed in the
  133. // resulting string. The delimiter character is extracted from the input stream.
  134. // If EOF is encountered, the stream's eofbit is set.
  135. extern const cl_string cl_fgetline (std::istream& stream, char delim = '\n');
  136. // Like above, but only up to n-1 characters. If n-1 characters were read
  137. // before the delimiter character was seen, the stream's failbit is set.
  138. extern const cl_string cl_fget (std::istream& stream, int n, char delim = '\n');
  139. extern const cl_string cl_fgetline (std::istream& stream, int n, char delim = '\n');
  140. // Skips whitespace and then reads a non-whitespace string.
  141. // If stream.width() is greater than 0, at most stream.width()-1 non-whitespace
  142. // characters are read. When done, stream.width(0) is called.
  143. // If EOF is encountered, the stream's eofbit is set.
  144. extern std::istream& operator>> (std::istream& stream, cl_string& str);
  145. // Runtime typing support.
  146. extern cl_class cl_class_string;
  147. // Debugging support.
  148. #ifdef CL_DEBUG
  149. extern int cl_string_debug_module;
  150. CL_FORCE_LINK(cl_string_debug_dummy, cl_string_debug_module)
  151. #endif
  152. } // namespace cln
  153. #endif /* _CL_STRING_H */