ipc_utils.h 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. // Copyright (c) 2010 Google Inc.
  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. #ifndef SIMPLE_IPC_UTLIS_H_
  15. #define SIMPLE_IPC_UTLIS_H_
  16. #include <string.h>
  17. #include <wchar.h>
  18. #include <new>
  19. #if !defined(countof)
  20. template <typename T, size_t N>
  21. char ( &_ArraySizeHelperX( T (&arr)[N] ))[N];
  22. #define countof(arr) (sizeof(_ArraySizeHelperX(arr)))
  23. #endif
  24. #if !defined(swap)
  25. template <typename T>
  26. void swap(T& a, T& b) { T t(a); a = b; b = t; }
  27. #endif
  28. namespace memdet {
  29. template <typename T> T* new_impl(size_t n) {
  30. return new T[n];
  31. }
  32. template <typename T> void delete_impl(T* o) {
  33. delete[] o;
  34. }
  35. } // namespace memdet
  36. namespace ipc {
  37. // The following classes are necessary because in some enviroments where this
  38. // library is used STL is forbidden. In particular HolderString is designed
  39. // to have the same functional interface as std::basic_string for the methods
  40. // that the ipc library uses.
  41. // This container class is an array-like which contains enough functionality
  42. // to replace vector<WireType> in the channel template. This is the only class
  43. // here that supports T to be non-pod and also T does not need a default ctor.
  44. template <typename T, size_t N>
  45. class FixedArray {
  46. public:
  47. FixedArray() : index_(0) {}
  48. ~FixedArray() {
  49. clear();
  50. }
  51. bool push_back(const T& ob) {
  52. if (index_ == N)
  53. return false;
  54. new(as_obj(index_)) T(ob);
  55. ++index_;
  56. return true;
  57. }
  58. T& operator[](size_t ix) {
  59. return *as_obj(ix);
  60. }
  61. size_t max_size() const { return N; }
  62. size_t size() const { return index_; }
  63. void clear() {
  64. for (size_t ix = 0; ix != index_; ++ix) {
  65. as_obj(ix)->~T();
  66. }
  67. index_ = 0;
  68. }
  69. private:
  70. T* as_obj(size_t ix) {
  71. return reinterpret_cast<T*>(&v_[ix * sizeof(T)]);
  72. }
  73. size_t index_;
  74. char v_[N * sizeof(T)];
  75. FixedArray(const FixedArray&);
  76. FixedArray& operator=(const FixedArray&);
  77. };
  78. // We don't support generic iterators but we define this magic two
  79. // types to support insertion to the end and erasure at the beggining.
  80. class IteratorEnd {};
  81. class IteratorBegin {};
  82. template <typename T>
  83. T operator+(const IteratorBegin&, T d) {
  84. return d;
  85. }
  86. // This container is the backing store of HoldeString and a generic
  87. // vector of plain-old-data. Caveat: Don't use this if your PoD does
  88. // not have an aceptable default value of 0 as in all bytes equal to
  89. // zero.
  90. template <typename T>
  91. class PodVector {
  92. public:
  93. typedef T value_type;
  94. PodVector() : capa_(0), size_(0), buf_(0) {}
  95. ~PodVector() {
  96. clear();
  97. }
  98. const IteratorBegin begin() const { return IteratorBegin(); }
  99. const IteratorEnd end() const { return IteratorEnd(); }
  100. T* get() const { return buf_; }
  101. size_t size() const { return size_; }
  102. size_t capacity() const { return capa_; }
  103. T& operator[](size_t ix) {
  104. return buf_[ix];
  105. }
  106. const T& operator[](size_t ix) const {
  107. return buf_[ix];
  108. }
  109. void clear() {
  110. memdet::delete_impl(buf_);
  111. size_ = 0;
  112. capa_ = 0;
  113. buf_ = 0;
  114. }
  115. void resize(size_t n) {
  116. if (n < size_) {
  117. size_ = n;
  118. return;
  119. }
  120. Add(0, n - size_);
  121. }
  122. void reserve(size_t n) {
  123. if (n <= capa_)
  124. return;
  125. size_t old_s = size_;
  126. Add(0, n - capa_);
  127. size_ = old_s;
  128. }
  129. void push_back(const T& v) {
  130. Add(&v, 1);
  131. }
  132. // We only support insertions at the end so here we are
  133. void insert(const IteratorEnd&, const T* begin, const T* end) {
  134. size_t d = end - begin;
  135. if (d > 0)
  136. Add(begin, end - begin);
  137. }
  138. void erase(const IteratorBegin&, size_t n) {
  139. RemoveFront(n);
  140. }
  141. // when |inp| is null then we don't copy, we just set
  142. // the new memory to zeros.
  143. void Add(const T* inp, size_t n) {
  144. if (!n)
  145. return;
  146. T* newb = NewAlloc(n);
  147. if (newb) {
  148. memcpy(newb, buf_, size_ * sizeof(T));
  149. memdet::delete_impl(buf_);
  150. buf_ = newb;
  151. }
  152. if (inp) {
  153. memcpy(&buf_[size_], inp, n * sizeof(T));
  154. } else {
  155. memset(&buf_[size_], 0, n * sizeof(T));
  156. }
  157. size_ += n;
  158. }
  159. void RemoveFront(size_t n) {
  160. if ((0 == size_) || (n > size_))
  161. return;
  162. size_t newsz = size_ - n;
  163. memmove(buf_, &buf_[n], newsz);
  164. size_ = newsz;
  165. }
  166. void Set(const T* inp, size_t n) {
  167. size_ = 0;
  168. Add(inp, n);
  169. }
  170. void Set(const PodVector<T>& other) {
  171. Set(other.buf_, other.size_);
  172. }
  173. void Swap(PodVector<T>& other) {
  174. swap(buf_, other.buf_);
  175. swap(size_, other.size_);
  176. swap(capa_, other.capa_);
  177. }
  178. void DecSize() {
  179. --size_;
  180. }
  181. private:
  182. T* NewAlloc(size_t n) {
  183. size_t rem = capa_ - size_;
  184. if (n < rem) {
  185. return 0;
  186. }
  187. size_t new_a = n + (size_ * 2) + 1;
  188. capa_ = (new_a < 16)? 16 : new_a;
  189. return memdet::new_impl<T>(capa_);
  190. }
  191. PodVector(const PodVector&);
  192. PodVector& operator=(const PodVector&);
  193. size_t capa_;
  194. size_t size_;
  195. T* buf_;
  196. };
  197. // Groups common functionality to the specializations of HolderString below.
  198. // One trick one should be aware on this class is that leverages the fact that
  199. // PodVector overallocates always. So it is safe to write to str_[size_] for
  200. // example to null terminate.
  201. template <typename Ct, typename Derived>
  202. class StringBase {
  203. public:
  204. typedef Ct value_type;
  205. StringBase(const StringBase& rhs) {
  206. assign(rhs.str_.get(), rhs.str_.size());
  207. }
  208. StringBase<Ct, Derived>& operator=(const StringBase<Ct, Derived>& rhs) {
  209. assign(rhs.str_.get(), rhs.str_.size());
  210. return *this;
  211. }
  212. void assign(const Ct* str, size_t size) {
  213. str_.Set(str, size);
  214. if (size)
  215. str_[size] = Ct(0);
  216. }
  217. size_t size() const {
  218. return str_.size();
  219. }
  220. void swap(StringBase<Ct, Derived>& other) {
  221. str_.Swap(other.str_);
  222. }
  223. bool operator==(const Ct* rhs) const {
  224. return (0 == static_cast<const Derived*>(this)->Compare(rhs));
  225. }
  226. bool operator!=(const Ct* rhs) const {
  227. return (0 != static_cast<const Derived*>(this)->Compare(rhs));
  228. }
  229. Ct& operator[](size_t ix) {
  230. return str_[ix];
  231. }
  232. const Ct& operator[](size_t ix) const {
  233. return str_[ix];
  234. }
  235. size_t capacity() const { return str_.capacity(); }
  236. protected:
  237. StringBase() {}
  238. PodVector<Ct> str_;
  239. };
  240. template <typename Ct>
  241. class HolderString;
  242. // Two specializations of HolderString for char and wchar_t that
  243. // have enough functionality to replace (if desired) the use of the
  244. // standard basic_string.
  245. template <>
  246. class HolderString<char> : public StringBase<char, HolderString<char> > {
  247. public:
  248. HolderString() {}
  249. HolderString(const char* str) {
  250. operator=(str);
  251. }
  252. void operator=(const char* str) {
  253. assign(str, strlen(str));
  254. }
  255. void append(const char* str) {
  256. str_.Add(str, strlen(str) + 1);
  257. str_.DecSize();
  258. }
  259. const char* c_str() const {
  260. if (!str_.get())
  261. return "";
  262. return str_.get();
  263. }
  264. int Compare(const char* str) const {
  265. return strcmp(c_str(), str);
  266. }
  267. };
  268. template <>
  269. class HolderString<wchar_t> : public StringBase<wchar_t, HolderString<wchar_t> > {
  270. public:
  271. HolderString() {}
  272. HolderString(const wchar_t* str) {
  273. operator=(str);
  274. }
  275. void operator=(const wchar_t* str) {
  276. assign(str, wcslen(str));
  277. }
  278. void append(const wchar_t* str) {
  279. str_.Add(str, wcslen(str) + 1);
  280. str_.DecSize();
  281. }
  282. const wchar_t* c_str() const {
  283. if (!str_.get())
  284. return L"";
  285. return str_.get();
  286. }
  287. int Compare(const wchar_t* str) const {
  288. return wcscmp(c_str(), str);
  289. }
  290. };
  291. } // namespace ipc.
  292. #endif // SIMPLE_IPC_UTLIS_H_