CernVM-FS  2.13.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
shortstring.h
Go to the documentation of this file.
1 
9 #ifndef CVMFS_SHORTSTRING_H_
10 #define CVMFS_SHORTSTRING_H_
11 
12 #include <algorithm>
13 #include <cstring>
14 #include <string>
15 
16 #include "util/atomic.h"
17 
18 #ifdef CVMFS_NAMESPACE_GUARD
19 namespace CVMFS_NAMESPACE_GUARD {
20 #endif
21 
22 const unsigned char kDefaultMaxName = 25;
23 const unsigned char kDefaultMaxLink = 25;
24 const unsigned char kDefaultMaxPath = 200;
25 
26 template<unsigned char StackSize, char Type>
27 class ShortString {
28  public:
29  ShortString() : long_string_(NULL), length_(0) {
30 #ifdef DEBUGMSG
31  atomic_inc64(&num_instances_);
32 #endif
33  }
34  ShortString(const ShortString &other) : long_string_(NULL) {
35 #ifdef DEBUGMSG
36  atomic_inc64(&num_instances_);
37 #endif
38  Assign(other);
39  }
40  ShortString(const char *chars, const unsigned length) : long_string_(NULL) {
41 #ifdef DEBUGMSG
42  atomic_inc64(&num_instances_);
43 #endif
44  Assign(chars, length);
45  }
46  explicit ShortString(const std::string &std_string) : long_string_(NULL) {
47 #ifdef DEBUGMSG
48  atomic_inc64(&num_instances_);
49 #endif
50  Assign(std_string.data(), std_string.length());
51  }
52 
54  if (this != &other)
55  Assign(other);
56  return *this;
57  }
58 
59  ~ShortString() { delete long_string_; }
60 
61  void Assign(const char *chars, const unsigned length) {
62  delete long_string_;
63  long_string_ = NULL;
64  this->length_ = length;
65  if (length > StackSize) {
66 #ifdef DEBUGMSG
67  atomic_inc64(&num_overflows_);
68 #endif
69  long_string_ = new std::string(chars, length);
70  } else {
71  if (length)
72  memcpy(stack_, chars, length);
73  }
74  }
75 
76  void Assign(const ShortString &other) {
77  Assign(other.GetChars(), other.GetLength());
78  }
79 
80  void Append(const char *chars, const unsigned length) {
81  if (long_string_) {
82  long_string_->append(chars, length);
83  return;
84  }
85 
86  const unsigned new_length = this->length_ + length;
87  if (new_length > StackSize) {
88 #ifdef DEBUGMSG
89  atomic_inc64(&num_overflows_);
90 #endif
91  long_string_ = new std::string();
92  long_string_->reserve(new_length);
93  long_string_->assign(stack_, length_);
94  long_string_->append(chars, length);
95  return;
96  }
97  if (length > 0)
98  memcpy(&stack_[this->length_], chars, length);
99  this->length_ = new_length;
100  }
101 
108  void Truncate(unsigned new_length) {
109  assert(new_length <= this->GetLength());
110  if (long_string_) {
111  long_string_->erase(new_length);
112  return;
113  }
114  this->length_ = new_length;
115  }
116 
117  void Clear() {
118  delete long_string_;
119  long_string_ = NULL;
120  length_ = 0;
121  }
122 
123  const char *GetChars() const {
124  if (long_string_) {
125  return long_string_->data();
126  } else {
127  return stack_;
128  }
129  }
130 
131  unsigned GetLength() const {
132  if (long_string_)
133  return long_string_->length();
134  return length_;
135  }
136 
137  bool IsEmpty() const { return GetLength() == 0; }
138 
139  std::string ToString() const {
140  return std::string(this->GetChars(), this->GetLength());
141  }
142 
143  const char *c_str() const {
144  if (long_string_)
145  return long_string_->c_str();
146 
147  char *c = const_cast<char *>(stack_) + length_;
148  *c = '\0';
149  return stack_;
150  }
151 
152  bool operator==(const ShortString &other) const {
153  const unsigned this_length = this->GetLength();
154  const unsigned other_length = other.GetLength();
155  if (this_length != other_length)
156  return false;
157  if (this_length == 0)
158  return true;
159 
160  return memcmp(this->GetChars(), other.GetChars(), this_length) == 0;
161  }
162 
163  bool operator!=(const ShortString &other) const { return !(*this == other); }
164 
165  bool operator<(const ShortString &other) const {
166  const unsigned this_length = this->GetLength();
167  const unsigned other_length = other.GetLength();
168 
169  if (this_length < other_length)
170  return true;
171  if (this_length > other_length)
172  return false;
173 
174  const char *this_chars = this->GetChars();
175  const char *other_chars = other.GetChars();
176  for (unsigned i = 0; i < this_length; ++i) {
177  if (this_chars[i] < other_chars[i])
178  return true;
179  if (this_chars[i] > other_chars[i])
180  return false;
181  }
182  return false;
183  }
184 
185  bool StartsWith(const ShortString &other) const {
186  const unsigned this_length = this->GetLength();
187  const unsigned other_length = other.GetLength();
188  if (this_length < other_length)
189  return false;
190 
191  return memcmp(this->GetChars(), other.GetChars(), other_length) == 0;
192  }
193 
194  ShortString Suffix(const unsigned start_at) const {
195  const unsigned length = this->GetLength();
196  if (start_at >= length)
197  return ShortString("", 0);
198 
199  return ShortString(this->GetChars() + start_at, length - start_at);
200  }
201 
202  static uint64_t num_instances() { return atomic_read64(&num_instances_); }
203  static uint64_t num_overflows() { return atomic_read64(&num_overflows_); }
204 
205  private:
206  std::string *long_string_;
207  char stack_[StackSize + 1]; // +1 to add a final '\0' if necessary
208  unsigned char length_;
211 }; // class ShortString
212 
216 
217 template<unsigned char StackSize, char Type>
219 template<unsigned char StackSize, char Type>
221 
222 // See posix.cc for the std::string counterparts
223 PathString GetParentPath(const PathString &path);
224 NameString GetFileName(const PathString &path);
225 
226 
227 #ifdef CVMFS_NAMESPACE_GUARD
228 } // namespace CVMFS_NAMESPACE_GUARD
229 #endif
230 
231 #endif // CVMFS_SHORTSTRING_H_
ShortString< kDefaultMaxName, 1 > NameString
Definition: shortstring.h:214
int64_t atomic_int64
Definition: atomic.h:18
unsigned char length_
Definition: shortstring.h:208
NameString GetFileName(const PathString &path)
Definition: shortstring.cc:28
ShortString Suffix(const unsigned start_at) const
Definition: shortstring.h:194
bool operator!=(const ShortString &other) const
Definition: shortstring.h:163
void Assign(const char *chars, const unsigned length)
Definition: shortstring.h:61
void Truncate(unsigned new_length)
Definition: shortstring.h:108
const unsigned char kDefaultMaxName
Definition: shortstring.h:22
assert((mem||(size==0))&&"Out Of Memory")
bool operator<(const ShortString &other) const
Definition: shortstring.h:165
void Clear()
Definition: shortstring.h:117
std::string * long_string_
Definition: shortstring.h:206
static uint64_t num_instances()
Definition: shortstring.h:202
const unsigned char kDefaultMaxPath
Definition: shortstring.h:24
ShortString(const std::string &std_string)
Definition: shortstring.h:46
void Append(const char *chars, const unsigned length)
Definition: shortstring.h:80
static atomic_int64 num_overflows_
Definition: shortstring.h:209
void Assign(const ShortString &other)
Definition: shortstring.h:76
const unsigned char kDefaultMaxLink
Definition: shortstring.h:23
std::string ToString() const
Definition: shortstring.h:139
bool IsEmpty() const
Definition: shortstring.h:137
ShortString< kDefaultMaxLink, 2 > LinkString
Definition: shortstring.h:215
ShortString< kDefaultMaxPath, 0 > PathString
Definition: shortstring.h:213
PathString GetParentPath(const PathString &path)
Definition: shortstring.cc:14
ShortString(const char *chars, const unsigned length)
Definition: shortstring.h:40
bool StartsWith(const ShortString &other) const
Definition: shortstring.h:185
unsigned GetLength() const
Definition: shortstring.h:131
ShortString & operator=(const ShortString &other)
Definition: shortstring.h:53
ShortString(const ShortString &other)
Definition: shortstring.h:34
static uint64_t num_overflows()
Definition: shortstring.h:203
const char * c_str() const
Definition: shortstring.h:143
const char * GetChars() const
Definition: shortstring.h:123
bool operator==(const ShortString &other) const
Definition: shortstring.h:152
static atomic_int64 num_instances_
Definition: shortstring.h:210