JBoss Data Grid HotRod C++ Client  7.0.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
portable.h
Go to the documentation of this file.
1 #ifndef INFINISPAN_HOTROD_PORTABLE_H
2 #define INFINISPAN_HOTROD_PORTABLE_H
3 
4 #include <cstdlib>
5 #include <cstring>
6 #include <string>
7 #include <vector>
8 #include <map>
10 
18 namespace infinispan {
19 namespace hotrod {
20 namespace portable {
21 
22 #ifdef _MSC_VER
23 # define strncpy_safe strncpy_s
24 #else
25 # ifndef _TRUNCATE
26 # define _TRUNCATE ((size_t)-1)
27 # endif // _TRUNCATE
28 static int strncpy_safe(char *dest, size_t numberOfElements, const char *src, size_t count) {
29  if (!count) return 0;
30  if (!dest || !src || !numberOfElements) return -1;
31  size_t end = count != _TRUNCATE && count < numberOfElements ? count : numberOfElements - 1;
32  size_t i = 0;
33  for (; i < end && src[i]; ++i) {
34  dest[i] = src[i];
35  }
36  if (!src[i] || end == count || count == _TRUNCATE) {
37  dest[i] = '\0';
38  return 0;
39  }
40  dest[0] = '\0';
41  return -1;
42 }
43 #endif
44 
45 #define PORTABLE_STRING_BUF_SIZE 48
46 
48 private:
49  char m_buf[PORTABLE_STRING_BUF_SIZE];
50  char *m_dynamic;
51  size_t m_length;
52 
53  inline void init(const char *str, size_t len)
54  {
55  m_length = len;
56  if (len < PORTABLE_STRING_BUF_SIZE) {
57  strncpy_safe(m_buf, PORTABLE_STRING_BUF_SIZE, str, len);
58  m_dynamic = 0;
59  } else {
60  m_dynamic = new char[len + 1];
61  strncpy_safe(m_dynamic, len + 1, str, len);
62  }
63  }
64 public:
65  string(): m_dynamic(0), m_length(0)
66  {
67  m_buf[0] = 0;
68  }
69 
70  string(const char *str)
71  {
72  init(str, strlen(str));
73  }
74 
75  string(const std::string &str)
76  {
77  init(str.c_str(), str.length());
78  }
79 
80  string(const string &o)
81  {
82  init(o.m_dynamic == 0 ? o.m_buf : o.m_dynamic, o.m_length);
83  }
84 
85  inline string &operator=(const string &o)
86  {
87  if (m_dynamic != 0) delete[] m_dynamic;
88  init(o.m_dynamic == 0 ? o.m_buf : o.m_dynamic, o.m_length);
89  return *this;
90  }
91 
92  inline ~string()
93  {
94  if (m_dynamic != 0) delete[] m_dynamic;
95  }
96 
97  inline string &operator=(const std::string &str)
98  {
99  if (m_dynamic != 0) delete[] m_dynamic;
100  init(str.c_str(), str.length());
101  return *this;
102  }
103 
104  inline const char *c_string() const
105  {
106  return m_dynamic == 0 ? m_buf : m_dynamic;
107  }
108 
109  inline std::string std_string() const
110  {
111  return std::string(m_dynamic == 0 ? m_buf : m_dynamic);
112  }
113 
114  static int cmp(const std::string &other, const string &str)
115  {
116  return cmp(other.c_str(), str);
117  }
118 
119  static int cmp(const char *other, const string &str)
120  {
121  if (str.m_dynamic == 0) {
122  return strncmp(other, str.m_buf, str.m_length);
123  } else {
124  return strncmp(other, str.m_dynamic, str.m_length);
125  }
126  }
127 
128  class convert {
129  public:
130  inline string operator()(const std::string &x)
131  {
132  return string(x);
133  }
134  inline std::string operator()(const string &x)
135  {
136  return x.std_string();
137  }
138  };
139 };
140 
141 template<typename A, typename B> class converter {
142  B operator()(const A &);
143 };
144 
145 template<typename T> class identity {
146 public:
147  T operator()(const T &x) {
148  return x;
149  }
150 };
151 
152 template<typename T> class vector
153 {
154 private:
155  T *m_array;
156  size_t m_size;
157 
158 public:
159  class move_ref {
160  friend class vector;
161  private:
162  vector<T> &m_ref;
163  move_ref(vector<T> &ref): m_ref(ref) {}
164  };
165 
166  vector(): m_array(0), m_size(0) {}
167  vector(T *array, size_t s): m_array(array), m_size(s) {}
168 
169  template<typename Iterable> vector(const Iterable &v)
170  {
171  m_size = v.size();
172  if (v.size() == 0) {
173  m_array = 0;
174  } else {
175  m_array = new T[v.size()];
176  size_t i = 0;
177  for (typename Iterable::const_iterator it = v.begin(); it != v.end(); ++it) {
178  m_array[i++] = *it;
179  }
180  }
181  }
182 
183  template<typename Iterable, typename Converter> vector(const Iterable &v, Converter convert)
184  {
185  m_size = v.size();
186  if (v.size() == 0) {
187  m_array = 0;
188  } else {
189  m_array = new T[v.size()];
190  size_t i = 0;
191  for (typename Iterable::const_iterator it = v.begin(); it != v.end(); ++it) {
192  m_array[i++] = convert(*it);
193  }
194  }
195  }
196 
197  vector(const vector<T> &o)
198  {
199  m_size = o.m_size;
200  if (m_size != 0) {
201  m_array = new T[o.m_size];
202  for (size_t i = 0; i < o.m_size; ++i) {
203  m_array[i] = o.m_array[i];
204  }
205  }
206  }
208  {
209  if (m_size != 0) delete[] m_array;
210  }
211 
213  {
214  if (m_size < o.m_size) {
215  delete[] m_array;
216  m_array = new T[o.m_size];
217  } else if (o.m_size == 0 && m_size != 0) {
218  delete[] m_array;
219  }
220  m_size = o.m_size;
221  for (size_t i = 0; i < o.m_size; ++i) {
222  m_array[i] = o.m_array[i];
223  }
224  return *this;
225  }
226 
227  vector(move_ref mr): m_array(mr.m_ref.m_array), m_size(mr.m_ref.m_size) {}
228  vector<T> &operator=(move_ref mr)
229  {
230  if (m_size != 0) {
231  delete[] m_array;
232  }
233  m_size = mr.m_ref.m_size;
234  m_array = mr.m_ref.m_array;
235  mr.m_ref.m_size = 0;
236  mr.m_ref.m_array = 0;
237  return *this;
238  }
243  move_ref move()
244  {
245  return move_ref(*this);
246  }
247 
248  std::vector<T> std_vector() const
249  {
250  std::vector<T> v;
251  v.reserve(m_size);
252  for (size_t i = 0; i < m_size; ++i) {
253  v.push_back(m_array[i]);
254  }
255  return v;
256  }
257 
258  const T* data() const
259  {
260  return m_array;
261  }
262 
263  size_t size() const
264  {
265  return m_size;
266  }
267 };
268 
269 template<typename K, typename V> class pair {
270 public:
271  K key;
272  V value;
273 };
274 
275 template<typename K, typename V> class map
276 {
277 private:
278  typedef pair<K, V> my_pair;
279 
280  vector<my_pair> m_vec;
281 
282  /*template<typename K2, typename V2>
283  static pair *to_array(const std::map<K2, V2> &m,
284  K (*convertKey)(const K2 &),
285  V (*convertValue)(const V2 &))
286  {
287  my_pair *data = new my_pair[m.size()];
288  my_pair *dp = data;
289  for (std::map<K2, V2>::const_iterator it = m.begin(); it != m.end(); ++it) {
290  dp->key = convertKey(it->first);
291  dp->value = convertValue(it->second);
292  ++dp;
293  }
294  return data;
295  }*/
296 
297  template<typename K2, typename KC, typename V2, typename VC>
298  static my_pair *to_array(const std::map<K2, V2> &m,
299  KC convertKey, VC convertValue)
300  {
301  my_pair *data = new my_pair[m.size()];
302  my_pair *dp = data;
303  for (typename std::map<K2, V2>::const_iterator it = m.begin(); it != m.end(); ++it) {
304  dp->key = convertKey(it->first);
305  dp->value = convertValue(it->second);
306  ++dp;
307  }
308  return data;
309  }
310 
311 public:
312  class move_ref {
313  friend class map;
314  private:
315  map<K, V> &m_ref;
316  move_ref(map<K, V> &ref): m_ref(ref) {}
317  };
318 
319  map() {}
320 
321 /* template<typename K2, typename V2> map(const std::map<K2, V2> &m,
322  K (*convertKey)(const K2 &) = identity<K>,
323  V (*convertValue)(const V2 &) = identity<V>):
324  m_vec(to_array(m, convertKey, convertValue), m.size()) {}*/
325 
326  map(const std::map<K, V> &m):
327  m_vec(to_array(m, identity<K>(), identity<V>()), m.size()) {}
328 
329  template<typename K2, typename KC, typename V2, typename VC>
330  map(const std::map<K2, V2> &m, KC convertKey = identity<K>(), VC convertValue = identity<V>()):
331  m_vec(to_array(m, convertKey, convertValue), m.size()) {}
332 
333  map(const map<K, V> &o)
334  {
335  m_vec = o.m_vec;
336  }
337 
339  {
340  m_vec = o.m_vec;
341  return *this;
342  }
343 
344  map(move_ref mr): m_vec(mr.m_ref.m_vec.move()) {}
346  {
347  m_vec = mr.m_ref.m_vec.move();
348  return *this;
349  }
351  {
352  return move_ref(*this);
353  }
354 
355  std::map<K, V> std_map() const
356  {
357  std::map<K, V> m;
358  for (size_t i = 0; i < m_vec.size(); ++i) {
359  const my_pair *dp = m_vec.data() + i;
360  m[dp->key] = dp->value;
361  }
362  return m;
363  }
364 
365  template<typename K2, typename KC, typename V2, typename VC> std::map<K2, V2> std_map(
366  KC convertKey, VC convertValue) const
367  {
368  std::map<K2, V2> m;
369  for (size_t i = 0; i < m_vec.size(); ++i) {
370  const my_pair *dp = m_vec.data() + i;
371  m[convertKey(dp->key)] = convertValue(dp->value);
372  }
373  return m;
374  }
375 
376  template<typename K2> const my_pair *get(K2 key, int (*cmp)(K2, const K &)) const {
377  for (size_t i = 0; i < m_vec.size(); ++i) {
378  const my_pair *dp = m_vec.data() + i;
379  if (!cmp(key, dp->key)) return dp;
380  }
381  return 0;
382  }
383 
384  const my_pair* data() const
385  {
386  return m_vec.data();
387  }
388 
389  size_t size() const
390  {
391  return m_vec.size();
392  }
393 };
394 
395 /* Invasive reference counting */
396 template<typename T> class counting_ptr;
397 
399 template<typename T> friend class counting_ptr;
400 private:
401  int m_counter;
402 public:
403  counted_object(): m_counter(0) {}
404  virtual ~counted_object() {}
405 };
406 
407 template<typename T> class counted_wrapper: public counted_object {
408 private:
409  T m_object;
410 public:
411  counted_wrapper(const T &o): m_object(o) {}
412  T &operator()() { return m_object; }
413 };
414 
415 template<typename T> class counting_ptr {
416 public:
417  typedef void (*destroy)(T *);
418 private:
419  counted_object *m_ptr;
420  destroy m_destroy;
421 
422  inline void dec_and_destroy() {
423  if (m_ptr != 0 && --(m_ptr->m_counter) == 0) {
424  if (m_destroy == 0) {
425  delete m_ptr;
426  } else {
427  m_destroy((T *)m_ptr);
428  }
429  }
430  }
431 public:
432  counting_ptr(): m_ptr(0), m_destroy(0) {}
433  counting_ptr(T *obj, destroy d = 0): m_ptr(obj), m_destroy(d) {
434  counted_object *rc = obj; // no cast required
435  if (rc != 0) {
436  rc->m_counter++;
437  }
438  }
440  dec_and_destroy();
441  }
442  counting_ptr(const counting_ptr &o): m_ptr(o.m_ptr), m_destroy(o.m_destroy) {
443  if (m_ptr != 0) {
444  m_ptr->m_counter++;
445  }
446  }
448  dec_and_destroy();
449  m_ptr = o.m_ptr;
450  m_destroy = o.m_destroy;
451  if (m_ptr != 0) {
452  m_ptr->m_counter++;
453  }
454  return *this;
455  }
457  return reset(rc, 0);
458  }
460  dec_and_destroy();
461  m_ptr = rc;
462  m_destroy = d;
463  if (rc != 0) {
464  rc->m_counter++;
465  }
466  return *this;
467  }
468  T *get() {
469  return (T *)m_ptr;
470  }
471  const T *get() const {
472  return (T *)m_ptr;
473  }
474  T *operator->() {
475  return (T *)m_ptr;
476  }
477  const T *operator->() const {
478  return (const T *)m_ptr;
479  }
480 };
481 
482 template<typename T> class local_ptr {
483 private:
484  typedef void (*destroy)(T *);
485  T *m_ptr;
486  destroy m_destroy;
487 public:
488  local_ptr(): m_ptr(0), m_destroy(0) {}
489  local_ptr(const local_ptr &): m_ptr(0), m_destroy(0) {} // copying does not persist value
490  local_ptr &operator=(const local_ptr &) { return *this; }
491  ~local_ptr() { if (m_ptr) m_destroy(m_ptr); }
492  const T *get() const { return m_ptr; }
493  T *get() { return m_ptr; }
494  void set(T *ptr, void (*dtor)(T *)) {
495  if (m_ptr) m_destroy(m_ptr);
496  m_ptr = ptr;
497  m_destroy = dtor;
498  }
499 };
500 
501 }}}
502 
503 #endif // INFINISPAN_HOTROD_PORTABLE_H
map(const std::map< K2, V2 > &m, KC convertKey=identity< K >(), VC convertValue=identity< V >())
Definition: portable.h:330
string(const std::string &str)
Definition: portable.h:75
~local_ptr()
Definition: portable.h:491
string operator()(const std::string &x)
Definition: portable.h:130
vector(const Iterable &v)
Definition: portable.h:169
std::map< K, V > std_map() const
Definition: portable.h:355
T & operator()()
Definition: portable.h:412
virtual ~counted_object()
Definition: portable.h:404
const T * operator->() const
Definition: portable.h:477
local_ptr()
Definition: portable.h:488
vector(T *array, size_t s)
Definition: portable.h:167
#define PORTABLE_STRING_BUF_SIZE
Definition: portable.h:45
#define HR_EXTERN
Definition: ImportExport.h:35
vector< T > & operator=(const vector< T > &o)
Definition: portable.h:212
std::string operator()(const string &x)
Definition: portable.h:134
V value
Definition: portable.h:272
size_t size() const
Definition: portable.h:263
string & operator=(const std::string &str)
Definition: portable.h:97
string()
Definition: portable.h:65
map(move_ref mr)
Definition: portable.h:344
local_ptr & operator=(const local_ptr &)
Definition: portable.h:490
map< K, V > & operator=(const map< K, V > &o)
Definition: portable.h:338
Definition: portable.h:275
local_ptr(const local_ptr &)
Definition: portable.h:489
counting_ptr & operator=(T *rc)
Definition: portable.h:456
string(const char *str)
Definition: portable.h:70
counting_ptr(const counting_ptr &o)
Definition: portable.h:442
~counting_ptr()
Definition: portable.h:439
vector(move_ref mr)
Definition: portable.h:227
string & operator=(const string &o)
Definition: portable.h:85
Definition: portable.h:152
const char * c_string() const
Definition: portable.h:104
static int cmp(const char *other, const string &str)
Definition: portable.h:119
size_t size() const
Definition: portable.h:389
std::vector< T > std_vector() const
Definition: portable.h:248
map(const map< K, V > &o)
Definition: portable.h:333
map(const std::map< K, V > &m)
Definition: portable.h:326
vector(const Iterable &v, Converter convert)
Definition: portable.h:183
vector()
Definition: portable.h:166
void set(T *ptr, void(*dtor)(T *))
Definition: portable.h:494
string(const string &o)
Definition: portable.h:80
counting_ptr & reset(T *rc, destroy d)
Definition: portable.h:459
map< K, V > & operator=(move_ref mr)
Definition: portable.h:345
T * operator->()
Definition: portable.h:474
~vector()
Definition: portable.h:207
vector(const vector< T > &o)
Definition: portable.h:197
counting_ptr & operator=(const counting_ptr &o)
Definition: portable.h:447
void(* destroy)(T *)
Definition: portable.h:417
std::map< K2, V2 > std_map(KC convertKey, VC convertValue) const
Definition: portable.h:365
K key
Definition: portable.h:271
T operator()(const T &x)
Definition: portable.h:147
map()
Definition: portable.h:319
counting_ptr(T *obj, destroy d=0)
Definition: portable.h:433
const T * data() const
Definition: portable.h:258
vector< T > & operator=(move_ref mr)
Definition: portable.h:228
counted_object()
Definition: portable.h:403
~string()
Definition: portable.h:92
Definition: portable.h:145
move_ref move()
Definition: portable.h:350
Definition: portable.h:269
std::string std_string() const
Definition: portable.h:109
Definition: portable.h:482
counted_wrapper(const T &o)
Definition: portable.h:411
counting_ptr()
Definition: portable.h:432
Definition: portable.h:141
move_ref move()
Definition: portable.h:243
#define _TRUNCATE
Definition: portable.h:26
Definition: portable.h:47
static int cmp(const std::string &other, const string &str)
Definition: portable.h:114
const my_pair * data() const
Definition: portable.h:384