| 1 | /* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */ |
| 2 | #ident "$Id$" |
| 3 | /*====== |
| 4 | This file is part of PerconaFT. |
| 5 | |
| 6 | |
| 7 | Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved. |
| 8 | |
| 9 | PerconaFT is free software: you can redistribute it and/or modify |
| 10 | it under the terms of the GNU General Public License, version 2, |
| 11 | as published by the Free Software Foundation. |
| 12 | |
| 13 | PerconaFT is distributed in the hope that it will be useful, |
| 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 16 | GNU General Public License for more details. |
| 17 | |
| 18 | You should have received a copy of the GNU General Public License |
| 19 | along with PerconaFT. If not, see <http://www.gnu.org/licenses/>. |
| 20 | |
| 21 | ---------------------------------------- |
| 22 | |
| 23 | PerconaFT is free software: you can redistribute it and/or modify |
| 24 | it under the terms of the GNU Affero General Public License, version 3, |
| 25 | as published by the Free Software Foundation. |
| 26 | |
| 27 | PerconaFT is distributed in the hope that it will be useful, |
| 28 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 29 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 30 | GNU Affero General Public License for more details. |
| 31 | |
| 32 | You should have received a copy of the GNU Affero General Public License |
| 33 | along with PerconaFT. If not, see <http://www.gnu.org/licenses/>. |
| 34 | ======= */ |
| 35 | |
| 36 | #ident "Copyright (c) 2006, 2015, Percona and/or its affiliates. All rights reserved." |
| 37 | |
| 38 | #pragma once |
| 39 | |
| 40 | #include <cassert> |
| 41 | #include <iterator> |
| 42 | #include <memory> |
| 43 | |
| 44 | #include <db.h> |
| 45 | |
| 46 | namespace ftcxx { |
| 47 | |
| 48 | class Slice { |
| 49 | public: |
| 50 | Slice() |
| 51 | : _data(nullptr), |
| 52 | _size(0) |
| 53 | {} |
| 54 | |
| 55 | explicit Slice(size_t sz) |
| 56 | : _buf(new char[sz], std::default_delete<char[]>()), |
| 57 | _data(_buf.get()), |
| 58 | _size(sz) |
| 59 | {} |
| 60 | |
| 61 | Slice(const char *p, size_t sz) |
| 62 | : _data(p), |
| 63 | _size(sz) |
| 64 | {} |
| 65 | |
| 66 | explicit Slice(const DBT &d) |
| 67 | : _data(reinterpret_cast<char *>(d.data)), |
| 68 | _size(d.size) |
| 69 | {} |
| 70 | |
| 71 | explicit Slice(const std::string &str) |
| 72 | : _data(str.c_str()), |
| 73 | _size(str.size()) |
| 74 | {} |
| 75 | |
| 76 | Slice(const Slice &other) |
| 77 | : _buf(other._buf), |
| 78 | _data(other._data), |
| 79 | _size(other._size) |
| 80 | {} |
| 81 | |
| 82 | Slice& operator=(const Slice &other) { |
| 83 | _buf = other._buf; |
| 84 | _data = other._data; |
| 85 | _size = other._size; |
| 86 | return *this; |
| 87 | } |
| 88 | |
| 89 | Slice(Slice&& other) |
| 90 | : _buf(), |
| 91 | _data(nullptr), |
| 92 | _size(0) |
| 93 | { |
| 94 | std::swap(_buf, other._buf); |
| 95 | std::swap(_data, other._data); |
| 96 | std::swap(_size, other._size); |
| 97 | } |
| 98 | |
| 99 | Slice& operator=(Slice&& other) { |
| 100 | std::swap(_buf, other._buf); |
| 101 | std::swap(_data, other._data); |
| 102 | std::swap(_size, other._size); |
| 103 | return *this; |
| 104 | } |
| 105 | |
| 106 | template<typename T> |
| 107 | static Slice slice_of(const T &v) { |
| 108 | return Slice(reinterpret_cast<const char *>(&v), sizeof v); |
| 109 | } |
| 110 | |
| 111 | template<typename T> |
| 112 | T as() const { |
| 113 | assert(size() == sizeof(T)); |
| 114 | const T *p = reinterpret_cast<const T *>(data()); |
| 115 | return *p; |
| 116 | } |
| 117 | |
| 118 | const char *data() const { return _data; } |
| 119 | |
| 120 | char *mutable_data() const { |
| 121 | assert(_buf); |
| 122 | return _buf.get(); |
| 123 | } |
| 124 | |
| 125 | size_t size() const { return _size; } |
| 126 | |
| 127 | bool empty() const { return size() == 0; } |
| 128 | |
| 129 | char operator[](size_t n) const { |
| 130 | assert(n < size()); |
| 131 | return _data[n]; |
| 132 | } |
| 133 | |
| 134 | char *begin() { return mutable_data(); } |
| 135 | char *end() { return mutable_data() + size(); } |
| 136 | char *rbegin() { return end(); } |
| 137 | char *rend() { return begin(); } |
| 138 | const char *begin() const { return data(); } |
| 139 | const char *end() const { return data() + size(); } |
| 140 | const char *rbegin() const { return end(); } |
| 141 | const char *rend() const { return begin(); } |
| 142 | const char *cbegin() const { return data(); } |
| 143 | const char *cend() const { return data() + size(); } |
| 144 | const char *crbegin() const { return end(); } |
| 145 | const char *crend() const { return begin(); } |
| 146 | |
| 147 | Slice copy() const { |
| 148 | Slice s(size()); |
| 149 | std::copy(begin(), end(), s.begin()); |
| 150 | return s; |
| 151 | } |
| 152 | |
| 153 | Slice owned() const { |
| 154 | if (_buf) { |
| 155 | return *this; |
| 156 | } else { |
| 157 | return copy(); |
| 158 | } |
| 159 | } |
| 160 | |
| 161 | DBT dbt() const { |
| 162 | DBT d; |
| 163 | d.data = const_cast<void *>(static_cast<const void *>(data())); |
| 164 | d.size = size(); |
| 165 | d.ulen = size(); |
| 166 | d.flags = 0; |
| 167 | return d; |
| 168 | } |
| 169 | |
| 170 | private: |
| 171 | std::shared_ptr<char> _buf; |
| 172 | const char *_data; |
| 173 | size_t _size; |
| 174 | }; |
| 175 | |
| 176 | } // namespace ftcxx |
| 177 | |
| 178 | namespace std { |
| 179 | |
| 180 | template<> |
| 181 | class iterator_traits<ftcxx::Slice> { |
| 182 | typedef typename std::iterator_traits<const char *>::difference_type difference_type; |
| 183 | typedef typename std::iterator_traits<const char *>::value_type value_type; |
| 184 | typedef typename std::iterator_traits<const char *>::pointer pointer; |
| 185 | typedef typename std::iterator_traits<const char *>::reference reference; |
| 186 | typedef typename std::iterator_traits<const char *>::iterator_category iterator_category; |
| 187 | }; |
| 188 | |
| 189 | } // namespace std |
| 190 | |