+class SContainer {
+public:
+ /** Type of string lengths (sizes) and positions (indexes). */
+ typedef size_t lenpos_t;
+ /** Out of bounds value indicating that the string argument should be measured. */
+ enum { measure_length=0xffffffffU};
+
+protected:
+ char *s; ///< The C string
+ lenpos_t sSize; ///< The size of the buffer, less 1: ie. the maximum size of the string
+
+ SContainer() : s(0), sSize(0) {}
+ ~SContainer() {
+ delete []s; // Suppose it was allocated using StringAllocate
+ s = 0;
+ sSize = 0;
+ }
+ /** Size of buffer. */
+ lenpos_t size() const {
+ if (s) {
+ return sSize;
+ } else {
+ return 0;
+ }
+ }
+public:
+ /**
+ * Allocate uninitialized memory big enough to fit a string of the given length.
+ * @return the pointer to the new string
+ */
+ static char *StringAllocate(lenpos_t len);
+ /**
+ * Duplicate a buffer/C string.
+ * Allocate memory of the given size, or big enough to fit the string if length isn't given;
+ * then copy the given string in the allocated memory.
+ * @return the pointer to the new string
+ */
+ static char *StringAllocate(
+ const char *s, ///< The string to duplicate
+ lenpos_t len=measure_length); ///< The length of memory to allocate. Optional.
+};
+
+
+/**
+ * @brief A string buffer class.
+ *
+ * Main use is to ask an API the length of a string it can provide,
+ * then to allocate a buffer of the given size, and to provide this buffer
+ * to the API to put the string.
+ * This class is intended to be shortlived, to be transformed as SString
+ * as soon as it holds the string, so it has little members.
+ * Note: we assume the buffer is filled by the API. If the length can be shorter,
+ * we should set sLen to strlen(sb.ptr()) in related SString constructor and assignment.
+ */
+class SBuffer : protected SContainer {
+public:
+ SBuffer(lenpos_t len) {
+ s = StringAllocate(len);
+ if (s) {
+ *s = '\0';
+ sSize = len;
+ } else {
+ sSize = 0;
+ }
+ }
+private:
+ /// Copy constructor
+ // Here only to be on the safe size, user should avoid returning SBuffer values.
+ SBuffer(const SBuffer &source) : SContainer() {
+ s = StringAllocate(source.s, source.sSize);
+ sSize = (s) ? source.sSize : 0;
+ }
+ /// Default assignment operator
+ // Same here, shouldn't be used
+ SBuffer &operator=(const SBuffer &source) {
+ if (this != &source) {
+ delete []s;
+ s = StringAllocate(source.s, source.sSize);
+ sSize = (s) ? source.sSize : 0;
+ }
+ return *this;
+ }
+public:
+ /** Provide direct read/write access to buffer. */
+ char *ptr() {
+ return s;
+ }
+ /** Ownership of the buffer have been taken, so release it. */
+ void reset() {
+ s = 0;
+ sSize = 0;
+ }
+ /** Size of buffer. */
+ lenpos_t size() const {
+ return SContainer::size();
+ }
+};
+