libutil++  1.9.3
 All Classes Functions Variables
Pointer.cpp
1 /*
2 ** libutil++
3 ** $Id: Pointer.cpp 1702 2016-08-13 23:26:06Z sella $
4 ** Copyright (c) 2011-2016 Digital Genesis, LLC. All Rights Reserved.
5 ** Released under the LGPL Version 2.1 License.
6 ** http://www.digitalgenesis.com
7 */
8 
9 static const char rcsid[] __attribute__((used)) = "$Id: Pointer.cpp 1702 2016-08-13 23:26:06Z sella $";
10 
11 #include "Pointer.h"
12 #include "../util/CommonMacro.h"
13 
14 using namespace sella::variant;
15 
16 Pointer::Pointer() throw () : Nullable(std::make_shared<void*>((void*) NULL)) { }
17 
18 Pointer::Pointer(const std::string &value) throw (TypeCastException) : Nullable() {
19  if (boost::regex_match(value, Pointer::Pattern())) {
20  void* v = 0;
21 
22  if (scanf(value.c_str(), "%p", &v) < 1) {
23  THROW(TypeCastException, "unable to cast '%s' to a pointer value", value.c_str());
24  }
25 
26  this->value = std::make_shared<void*>(v);
27  } else {
28  THROW(TypeCastException, "unable to cast '%s' to a pointer value", value.c_str());
29  }
30 }
31 
32 Pointer::Pointer(void* value) throw () : Nullable(std::make_shared<void*>(value)) { }
33 
34 Pointer::Pointer(const Pointer &other) throw () : Nullable() {
35  if (this != &other) {
36  if (!other.isNull()) {
37  if (isNull()) {
38  this->value = std::make_shared<void*>((void*) other.get());
39  } else {
40  *std::static_pointer_cast<void*>(this->value) = *std::static_pointer_cast<void*>(other.value);
41  }
42  } else {
43  this->value.reset();
44  }
45  }
46 }
47 
48 bool Pointer::operator==(const Pointer &other) const throw () {
49  return (*std::static_pointer_cast<void*>(this->value) == *std::static_pointer_cast<void*>(other.value));
50 }
51 
52 bool Pointer::operator!=(const Pointer &other) const throw () {
53  return !(*this == other);
54 }
55 
56 bool Pointer::operator>(const Pointer &other) const throw () {
57  return (*std::static_pointer_cast<void*>(this->value) > *std::static_pointer_cast<void*>(other.value));
58 }
59 
60 bool Pointer::operator<(const Pointer &other) const throw () {
61  return (*std::static_pointer_cast<void*>(this->value) < *std::static_pointer_cast<void*>(other.value));
62 }
63 
64 bool Pointer::operator!() throw () {
65  return !(*std::static_pointer_cast<void*>(this->value));
66 }
67 
68 Pointer& Pointer::operator=(const Pointer &other) throw () {
69  if (this != &other) {
70  if (!other.isNull()) {
71  if (isNull()) {
72  this->value = std::make_shared<void*>((void*) other.get());
73  } else {
74  *std::static_pointer_cast<void*>(this->value) = *std::static_pointer_cast<void*>(other.value);
75  }
76  } else {
77  this->value.reset();
78  }
79  }
80 
81  return *this;
82 }
83 
84 Pointer& Pointer::operator=(void *other) throw () {
85  if (isNull()) {
86  this->value = std::make_shared<void*>(other);
87  } else {
88  *std::static_pointer_cast<void*>(this->value) = other;
89  }
90 
91  return *this;
92 }
93 
94 Pointer::~Pointer() throw () { }
95 
96 const void*& Pointer::get() const throw (UnsupportedOperatorException) {
97  if (isNull()) {
98  THROW(UnsupportedOperatorException, "unable to take reference of null value");
99  }
100 
101  return *std::static_pointer_cast<const void*>(this->value);
102 }
103 
104 void*& Pointer::get() throw (UnsupportedOperatorException) {
105  if (isNull()) {
106  THROW(UnsupportedOperatorException, "unable to take reference of null value");
107  }
108 
109  return *std::static_pointer_cast<void*>(this->value);
110 }
111 
112 void Pointer::msgpack(sella::util::MessagePack &mpack, uint32_t &offset) const throw (TypeCastException) {
113  uint32_t c;
114 
115  if (this->isNull()) {
116  if ((c = mpack.append(offset)) == 0) {
117  THROW(TypeCastException, "Failed to append '%s' at offset %d (buffer length: %d)", str(JSON).c_str(), offset, mpack.length());
118  }
119  } else {
120  if ((c = mpack.append(offset, (uint64_t) this->get())) == 0) {
121  THROW(TypeCastException, "Failed to append '%s' at offset %d (buffer length: %d)", str(JSON).c_str(), offset, mpack.length());
122  }
123  }
124 
125  offset += c;
126 }
127 
128 void Pointer::msgpackBufferSize(size_t &size) const throw () {
129  if (UNLIKELY(isNull())) {
130  size += 1;
131 
132  return;
133  }
134 
135  size += 9;
136 }
137 
138 std::string Pointer::str(int type) const throw () {
139  if (this->isNull()) {
140  return "null";
141  }
142 
143  char buffer[4096];
144 
145  snprintf(buffer, sizeof(buffer), "%p", this->get());
146 
147  return buffer;
148 }
149 
150 bool Pointer::isType(const char *value, size_t size) throw () {
151  if (size < 2 || value[0] != '0' || value[1] != 'x' || (size - 2) % 8 != 0) { /* Starts with 0x and must be divisible by 8 (minus 0x) */
152  return false;
153  }
154 
155  for (size_t i = 2; i < size; i += 2) {
156  if (!::isxdigit(value[i]) != 0 || !::isxdigit(value[i + 1]) != 0) {
157  return false;
158  }
159  }
160 
161  return true;
162 }
163 
164 /*
165 ** vim: noet ts=3 sw=3
166 */