Pioneer
StringRange.h
Go to the documentation of this file.
1 // Copyright © 2008-2023 Pioneer Developers. See AUTHORS.txt for details
2 // Licensed under the terms of the GPL v3. See licenses/GPL-3.txt
3 
4 #ifndef _STRINGRANGE_H
5 #define _STRINGRANGE_H
6 
7 #include <cassert>
8 #include <cctype>
9 #include <string>
10 
11 struct StringRange {
13  begin(0),
14  end(0) {}
15  StringRange(const char *begin_, const char *end_) :
16  begin(begin_),
17  end(end_)
18  {
19  assert(begin_ && end_);
20  assert((end_ - begin_) >= 0);
21  }
22  StringRange(const char *begin_, size_t size) :
23  begin(begin_),
24  end(begin_ + size)
25  {
26  assert(begin_);
27  }
28 
29  const char *begin;
30  const char *end;
31 
32  bool Empty() const { return (begin == end); }
33  size_t Size() const { return (end - begin); }
34 
35  const char &operator[](size_t idx) const { return begin[idx]; }
36  const char &operator*() const { return *begin; }
37  std::string ToString() const { return begin ? std::string(begin, Size()) : std::string(); }
38 
39  int Compare(const char *b) const;
40 
41  friend bool operator==(const StringRange &a, const char *b) { return (a.Compare(b) == 0); }
42  friend bool operator!=(const StringRange &a, const char *b) { return (a.Compare(b) != 0); }
43  friend bool operator<=(const StringRange &a, const char *b) { return (a.Compare(b) <= 0); }
44  friend bool operator>=(const StringRange &a, const char *b) { return (a.Compare(b) >= 0); }
45  friend bool operator<(const StringRange &a, const char *b) { return (a.Compare(b) < 0); }
46  friend bool operator>(const StringRange &a, const char *b) { return (a.Compare(b) > 0); }
47 
48  friend bool operator==(const char *a, const StringRange &b) { return (b.Compare(a) == 0); }
49  friend bool operator!=(const char *a, const StringRange &b) { return (b.Compare(a) != 0); }
50  friend bool operator<=(const char *a, const StringRange &b) { return (b.Compare(a) >= 0); }
51  friend bool operator>=(const char *a, const StringRange &b) { return (b.Compare(a) <= 0); }
52  friend bool operator<(const char *a, const StringRange &b) { return (b.Compare(a) > 0); }
53  friend bool operator>(const char *a, const StringRange &b) { return (b.Compare(a) < 0); }
54 
55  const char *FindChar(char c) const;
56  const char *RFindChar(char c) const;
57 
58  const char *FindSpace() const;
59  const char *RFindSpace() const;
60 
61  const char *FindNewline() const;
62 
63  const char *FindNonSpace() const;
64  const char *RFindNonSpace() const;
65 
66  const char *FindNextLine() const;
67 
68  StringRange StripUTF8BOM() const;
69  StringRange StripSpace() const;
70 
72 
73 private:
74  static bool is_space(char c)
75  {
76  // MSVC's isspace() apparently asserts if you give it non-ASCII chars
77  // (maybe changing locale would help)
78  return (c == ' ') || (c == '\t') || (c == '\v') || (c == '\r') || (c == '\n');
79  }
80 };
81 
83 {
85  begin = line.end;
86  return line;
87 }
88 
89 inline int StringRange::Compare(const char *b) const
90 {
91  const char *a = begin;
92  while (a != end && *b && *a == *b) {
93  ++a;
94  ++b;
95  }
96  if (a != end && *b) {
97  return (*a < *b ? -1 : 1);
98  }
99  if (a != end) {
100  return 1;
101  }
102  if (*b) {
103  return -1;
104  }
105  return 0;
106 }
107 
108 inline const char *StringRange::FindChar(char c) const
109 {
110  const char *x = begin, *y = end;
111  while ((x != y) && (*x != c))
112  ++x;
113  return x;
114 }
115 
116 inline const char *StringRange::RFindChar(char c) const
117 {
118  const char *x = begin, *y = end;
119  while ((x != y) && (*--y != c)) {
120  }
121  return y;
122 }
123 
124 inline const char *StringRange::FindSpace() const
125 {
126  const char *x = begin, *y = end;
127  while ((x != y) && !isspace(*x))
128  ++x;
129  return x;
130 }
131 
132 inline const char *StringRange::RFindSpace() const
133 {
134  const char *x = begin, *y = end;
135  while ((x != y) && !isspace(*--y)) {
136  }
137  return y;
138 }
139 
140 inline const char *StringRange::FindNewline() const
141 {
142  const char *x = begin, *y = end;
143  while ((x != y) && (*x != '\r') && (*x != '\n'))
144  ++x;
145  return x;
146 }
147 
148 inline const char *StringRange::FindNextLine() const
149 {
150  const char *x = FindNewline(), *y = end;
151  if ((x != y) && (*x == '\r')) ++x;
152  if ((x != y) && (*x == '\n')) ++x;
153  return x;
154 }
155 
156 inline const char *StringRange::FindNonSpace() const
157 {
158  const char *x = begin, *y = end;
159  while ((x != y) && is_space(*x))
160  ++x;
161  return x;
162 }
163 
164 inline const char *StringRange::RFindNonSpace() const
165 {
166  const char *x = begin, *y = end;
167  while ((x != y) && is_space(*--y)) {
168  }
169  return (y == end ? y : y + 1);
170 }
171 
173 {
174  if (Size() >= 3 && begin[0] == '\xEF' && begin[1] == '\xBB' && begin[2] == '\xBF')
175  return StringRange(begin + 3, end);
176  else
177  return *this;
178 }
179 
181 {
182  // can't just do StringRange(FindNonSpace(), RFindNonSpace())
183  // because if the string is *all* space then that will break the
184  // invariant that begin <= end
186  ss.end = ss.RFindNonSpace();
187  return ss;
188 }
189 
190 #endif
Definition: StringRange.h:11
friend bool operator<(const StringRange &a, const char *b)
Definition: StringRange.h:45
const char * RFindChar(char c) const
Definition: StringRange.h:116
const char * RFindSpace() const
Definition: StringRange.h:132
friend bool operator<=(const char *a, const StringRange &b)
Definition: StringRange.h:50
StringRange(const char *begin_, size_t size)
Definition: StringRange.h:22
const char * FindNextLine() const
Definition: StringRange.h:148
size_t Size() const
Definition: StringRange.h:33
friend bool operator>(const StringRange &a, const char *b)
Definition: StringRange.h:46
const char & operator*() const
Definition: StringRange.h:36
friend bool operator<(const char *a, const StringRange &b)
Definition: StringRange.h:52
friend bool operator==(const StringRange &a, const char *b)
Definition: StringRange.h:41
friend bool operator!=(const char *a, const StringRange &b)
Definition: StringRange.h:49
const char * FindNewline() const
Definition: StringRange.h:140
const char * end
Definition: StringRange.h:30
StringRange ReadLine()
Definition: StringRange.h:82
const char * begin
Definition: StringRange.h:29
const char * RFindNonSpace() const
Definition: StringRange.h:164
const char * FindNonSpace() const
Definition: StringRange.h:156
friend bool operator>=(const StringRange &a, const char *b)
Definition: StringRange.h:44
const char * FindChar(char c) const
Definition: StringRange.h:108
friend bool operator>=(const char *a, const StringRange &b)
Definition: StringRange.h:51
StringRange StripUTF8BOM() const
Definition: StringRange.h:172
const char & operator[](size_t idx) const
Definition: StringRange.h:35
std::string ToString() const
Definition: StringRange.h:37
StringRange(const char *begin_, const char *end_)
Definition: StringRange.h:15
friend bool operator>(const char *a, const StringRange &b)
Definition: StringRange.h:53
friend bool operator!=(const StringRange &a, const char *b)
Definition: StringRange.h:42
StringRange()
Definition: StringRange.h:12
int Compare(const char *b) const
Definition: StringRange.h:89
const char * FindSpace() const
Definition: StringRange.h:124
bool Empty() const
Definition: StringRange.h:32
friend bool operator==(const char *a, const StringRange &b)
Definition: StringRange.h:48
StringRange StripSpace() const
Definition: StringRange.h:180
friend bool operator<=(const StringRange &a, const char *b)
Definition: StringRange.h:43