• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
2 
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6 
7     http://www.apache.org/licenses/LICENSE-2.0
8 
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15 
16 // StringPiece is a simple structure containing a pointer into some external
17 // storage and a size.  The user of a StringPiece must ensure that the slice
18 // is not used after the corresponding external storage has been
19 // deallocated.
20 //
21 // Multiple threads can invoke const methods on a StringPiece without
22 // external synchronization, but if any of the threads may call a
23 // non-const method, all threads accessing the same StringPiece must use
24 // external synchronization.
25 
26 #ifndef TENSORFLOW_LIB_CORE_STRINGPIECE_H_
27 #define TENSORFLOW_LIB_CORE_STRINGPIECE_H_
28 
29 #include <assert.h>
30 #include <stddef.h>
31 #include <string.h>
32 #include <iosfwd>
33 #include <string>
34 #include "tensorflow/core/platform/types.h"
35 
36 namespace tensorflow {
37 
38 struct StringPieceHasher;
39 
40 class StringPiece {
41  public:
42   typedef size_t size_type;
43 
44   // Create an empty slice.
StringPiece()45   StringPiece() : data_(nullptr), size_(0) {}
46 
47   // Create a slice that refers to d[0,n-1].
StringPiece(const char * d,size_t n)48   StringPiece(const char* d, size_t n) : data_(d), size_(n) {}
49 
50   // Create a slice that refers to the contents of "s"
StringPiece(const string & s)51   StringPiece(const string& s) : data_(s.data()), size_(s.size()) {}
52 
53   // Create a slice that refers to s[0,strlen(s)-1]
StringPiece(const char * s)54   StringPiece(const char* s) : data_(s), size_(strlen(s)) {}
55 
56   // Return a pointer to the beginning of the referenced data
data()57   const char* data() const { return data_; }
58 
59   // Return the length (in bytes) of the referenced data
size()60   size_t size() const { return size_; }
61 
62   // Return true iff the length of the referenced data is zero
empty()63   bool empty() const { return size_ == 0; }
64 
65   typedef const char* const_iterator;
66   typedef const char* iterator;
begin()67   iterator begin() const { return data_; }
end()68   iterator end() const { return data_ + size_; }
69 
70   static const size_t npos;
71 
72   // Return the ith byte in the referenced data.
73   // REQUIRES: n < size()
74   char operator[](size_t n) const {
75     assert(n < size());
76     return data_[n];
77   }
78 
79   // Drop the first "n" bytes from this slice.
remove_prefix(size_t n)80   void remove_prefix(size_t n) {
81     assert(n <= size());
82     data_ += n;
83     size_ -= n;
84   }
85 
remove_suffix(size_t n)86   void remove_suffix(size_t n) {
87     assert(size_ >= n);
88     size_ -= n;
89   }
90 
91   size_t find(char c, size_t pos = 0) const;
92   size_t rfind(char c, size_t pos = npos) const;
93   bool contains(StringPiece s) const;
94 
95   // Checks whether StringPiece starts with x and if so advances the beginning
96   // of it to past the match.  It's basically a shortcut for starts_with
97   // followed by remove_prefix.
Consume(StringPiece x)98   bool Consume(StringPiece x) {
99     if (starts_with(x)) {
100       remove_prefix(x.size_);
101       return true;
102     }
103     return false;
104   }
105 
106   StringPiece substr(size_t pos, size_t n = npos) const;
107 
108   // Return a string that contains the copy of the referenced data.
ToString()109   std::string ToString() const { return std::string(data_, size_); }
110 
111   // Three-way comparison.  Returns value:
112   //   <  0 iff "*this" <  "b",
113   //   == 0 iff "*this" == "b",
114   //   >  0 iff "*this" >  "b"
115   int compare(StringPiece b) const;
116 
117   // Return true iff "x" is a prefix of "*this"
starts_with(StringPiece x)118   bool starts_with(StringPiece x) const {
119     return ((size_ >= x.size_) && (memcmp(data_, x.data_, x.size_) == 0));
120   }
121   // Return true iff "x" is a suffix of "*this"
ends_with(StringPiece x)122   bool ends_with(StringPiece x) const {
123     return ((size_ >= x.size_) &&
124             (memcmp(data_ + (size_ - x.size_), x.data_, x.size_) == 0));
125   }
126 
127  private:
128   const char* data_;
129   size_t size_;
130 
131   // Intentionally copyable
132 };
133 
134 struct StringPieceHasher {
135   size_t operator()(StringPiece s) const;
136 };
137 
138 inline bool operator==(StringPiece x, StringPiece y) {
139   return ((x.size() == y.size()) &&
140           (memcmp(x.data(), y.data(), x.size()) == 0));
141 }
142 
143 inline bool operator!=(StringPiece x, StringPiece y) { return !(x == y); }
144 
145 inline bool operator<(StringPiece x, StringPiece y) { return x.compare(y) < 0; }
146 inline bool operator>(StringPiece x, StringPiece y) { return x.compare(y) > 0; }
147 inline bool operator<=(StringPiece x, StringPiece y) {
148   return x.compare(y) <= 0;
149 }
150 inline bool operator>=(StringPiece x, StringPiece y) {
151   return x.compare(y) >= 0;
152 }
153 
compare(StringPiece b)154 inline int StringPiece::compare(StringPiece b) const {
155   const size_t min_len = (size_ < b.size_) ? size_ : b.size_;
156   int r = memcmp(data_, b.data_, min_len);
157   if (r == 0) {
158     if (size_ < b.size_)
159       r = -1;
160     else if (size_ > b.size_)
161       r = +1;
162   }
163   return r;
164 }
165 
166 // allow StringPiece to be logged
167 extern std::ostream& operator<<(std::ostream& o, tensorflow::StringPiece piece);
168 
169 }  // namespace tensorflow
170 
171 #endif  // TENSORFLOW_LIB_CORE_STRINGPIECE_H_
172