1/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2#ident "$Id$"
3/*======
4This file is part of PerconaFT.
5
6
7Copyright (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
46namespace 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
178namespace 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