AMPS C/C++ Client Class Reference
AMPS C/C++ Client Version 5.3.0.5
Field.hpp
Go to the documentation of this file.
1 //
3 // Copyright (c) 2010-2020 60East Technologies Inc., All Rights Reserved.
4 //
5 // This computer software is owned by 60East Technologies Inc. and is
6 // protected by U.S. copyright laws and other laws and by international
7 // treaties. This computer software is furnished by 60East Technologies
8 // Inc. pursuant to a written license agreement and may be used, copied,
9 // transmitted, and stored only in accordance with the terms of such
10 // license agreement and with the inclusion of the above copyright notice.
11 // This computer software or any other copies thereof may not be provided
12 // or otherwise made available to any other person.
13 //
14 // U.S. Government Restricted Rights. This computer software: (a) was
15 // developed at private expense and is in all respects the proprietary
16 // information of 60East Technologies Inc.; (b) was not developed with
17 // government funds; (c) is a trade secret of 60East Technologies Inc.
18 // for all purposes of the Freedom of Information Act; and (d) is a
19 // commercial item and thus, pursuant to Section 12.212 of the Federal
20 // Acquisition Regulations (FAR) and DFAR Supplement Section 227.7202,
21 // Government's use, duplication or disclosure of the computer software
22 // is subject to the restrictions set forth by 60East Technologies Inc..
23 //
25 #ifndef __AMPS_FIELD_HPP__
26 #define __AMPS_FIELD_HPP__
27 
28 #include <algorithm>
29 #include <string>
30 #include <string.h>
31 
32 #define AMPS_TIMESTAMP_LEN 16
33 #define AMPS_MAX_BOOKMARK_LEN 42
34 // Used in bookmark store recovery to look for corruption, NOT FIXED IN AMPS
35 #define AMPS_MAX_SUBID_LEN 1048576 // 1MB, NOT FIXED IN AMPS
36 
37 namespace AMPS {
38 
39 using std::string;
40 
44 
51 
52 class Field
53 {
54  const char* _data;
55  size_t _len;
56 public:
57  Field() : _data(NULL), _len(0) {;}
58  Field(const char *data_)
59  {
60  _data = data_;
61  _len = ::strlen(data_);
62  }
63  Field(const char *data_,size_t len_)
64  {
65  _data = data_;
66  _len = len_;
67  }
68  Field(const Field& rhs)
69  {
70  _data = rhs._data;
71  _len = rhs._len;
72  }
73  Field& operator=(const Field& rhs)
74  {
75  _data = rhs._data;
76  _len = rhs._len;
77  return *this;
78  }
79  Field(const std::string& string_)
80  {
81  _data = string_.c_str();
82  _len = string_.length();
83  }
84 
85  bool contains(const char* searchString, size_t len) const
86  {
87  const char *dataEnd = _data+_len;
88  return std::search(_data,dataEnd,searchString,searchString+len) != dataEnd;
89  }
90 
93  bool empty () const
94  {
95  return _len == 0;
96  }
97 
101  operator std::string () const
102  {
103  return _len?std::string(_data, _len):std::string();
104  }
105 
111  bool operator==(const Field& rhs_) const
112  {
113  if ( _len == rhs_._len )
114  return ::memcmp(_data, rhs_._data, _len) == 0;
115  return false;
116  }
117 
123  bool operator==(const char* rhs_) const
124  {
125  if (!_data || !rhs_)
126  {
127  return (!_data && !rhs_);
128  }
129  return ::strncmp(_data, rhs_, _len) == 0 && rhs_[_len] == '\0';
130  }
131 
132  bool operator<(const Field& rhs) const;
138  bool operator!=(const char* rhs_) const
139  {
140  return strncmp(_data, rhs_, _len) != 0 || rhs_[_len] != '\0';
141  }
142 
143 
149  bool operator!=(const std::string& rhs_) const
150  {
151  return rhs_.compare(0, rhs_.length(), _data, _len) != 0;
152  }
153 
159  bool operator==(const std::string& rhs_) const
160  {
161  return rhs_.compare(0, rhs_.length(), _data, _len) == 0;
162  }
163 
167  void deepCopy(const Field& orig_)
168  {
169  delete[] _data;
170  if (orig_._len > 0)
171  {
172  _data = new char[orig_._len];
173  ::memcpy(static_cast<void*>(const_cast<char*>(_data)),
174  orig_._data, orig_._len);
175  _len = orig_._len;
176  }
177  else
178  {
179  _data = NULL;
180  _len = 0;
181  }
182  }
183 
186  Field deepCopy() const
187  {
188  Field newField;
189  newField.deepCopy(*this);
190  return newField;
191  }
192 
196  void clear()
197  {
198  if (!_data || !_len) return;
199  delete[] _data;
200  _len = 0;
201  _data = NULL;
202  }
203 
206  const char* data() const
207  {
208  return _data;
209  }
210 
213  size_t len() const
214  {
215  return _len;
216  }
217 
218  // assign a new range into this Message::Field
219  void assign(const char*ptr, size_t len)
220  {
221  _data = ptr;
222  _len = len;
223  }
224 
225  // compute a hash value
226  inline size_t hash_function() const
227  {
228  size_t n_ = _len;
229  const char* p_ = _data;
230  size_t h = 0,c;
231  while (n_ != 0)
232  {
233  c = (unsigned long)*p_;
234  h += (h << 5) + c;
235  ++p_,--n_;
236  }
237  return h;
238  }
239 
240  struct FieldHash
241  {
242  size_t operator()(const Field& f) const
243  {
244  return f.hash_function();
245  }
246 
247  bool operator()(const Field& f1, const Field& f2) const
248  {
249  if (f1.len() < f2.len()) return true;
250  if (f1.len() > f2.len()) return false;
251  // Length is the same, don't compare empty
252  if (f1.len() == 0) return true;
253  return ::memcmp(f1.data(), f2.data(), f2.len())<0;
254  }
255  };
256 
257  // Get sequence number from a Field that is a bookmark
258  static void parseBookmark(const Field& field_,
259  amps_uint64_t& publisherId_,
260  amps_uint64_t& sequenceNumber_)
261  {
262  publisherId_ = sequenceNumber_ = (amps_uint64_t)0;
263  const char* data = field_.data();
264  size_t len = field_.len();
265  // Can't parse a timestamp
266  if (len == AMPS_TIMESTAMP_LEN &&
267  data[AMPS_TIMESTAMP_LEN-1] == 'Z' &&
268  data[8] == 'T') return;
269  size_t i=0;
270  for( ; i<len; ++i)
271  {
272  if(data[i] == '|')
273  {
274  break;
275  }
276  publisherId_ *= 10;
277  publisherId_ += (amps_uint64_t)(data[i] - '0');
278  }
279  for(i=i+1; i<len; ++i)
280  {
281  if(data[i] == '|')
282  {
283  break;
284  }
285  sequenceNumber_ *= 10;
286  sequenceNumber_ += (amps_uint64_t)(data[i] - '0');
287  }
288  }
289 
290 };
291 
292 }
293 
294 #endif
295 
bool operator==(const char *rhs_) const
String comparison operator Returns `true&#39; if self and rhs are equivalent, `false&#39; otherwise...
Definition: Field.hpp:123
bool operator!=(const std::string &rhs_) const
String comparison operator Returns `true&#39; if self and rhs are not equivalent.
Definition: Field.hpp:149
bool operator==(const Field &rhs_) const
Comparison operator Returns `true&#39; if self and rhs are equivalent, `false&#39; otherwise.
Definition: Field.hpp:111
void clear()
Deletes the data associated with this Field, should only be used on Fields that were created as deepC...
Definition: Field.hpp:196
const char * data() const
Returns the (non-null-terminated) data underlying this field.
Definition: Field.hpp:206
bool empty() const
Returns &#39;true&#39; if empty, &#39;false&#39; otherwise.
Definition: Field.hpp:93
size_t len() const
Returns the length of the data underlying this field.
Definition: Field.hpp:213
bool operator!=(const char *rhs_) const
String comparison operator Returns true if self and rhs are not equivalent.
Definition: Field.hpp:138
Field represents the value of a single field in a Message.
Definition: Field.hpp:52
void deepCopy(const Field &orig_)
Makes self a deep copy of the original field.
Definition: Field.hpp:167
Definition: ampsplusplus.hpp:136
bool operator==(const std::string &rhs_) const
String comparison operator Returns `true&#39; if self and rhs are equivalent.
Definition: Field.hpp:159
Field deepCopy() const
Makes a deep copy of self, returns it.
Definition: Field.hpp:186