forked from datastax/cpp-driver
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathabstract_data.hpp
180 lines (142 loc) · 4.4 KB
/
abstract_data.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/*
Copyright (c) 2014-2016 DataStax
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#ifndef __CASS_ABSTRACT_DATA_HPP_INCLUDED__
#define __CASS_ABSTRACT_DATA_HPP_INCLUDED__
#include "buffer.hpp"
#include "collection.hpp"
#include "data_type.hpp"
#include "encode.hpp"
#include "hash_table.hpp"
#include "request.hpp"
#include "string_ref.hpp"
#include "types.hpp"
#define CASS_CHECK_INDEX_AND_TYPE(Index, Value) do { \
CassError rc = check(Index, Value); \
if (rc != CASS_OK) return rc; \
} while(0)
namespace cass {
class Tuple;
class UserTypeValue;
class AbstractData {
public:
class Element {
public:
enum Type {
UNSET,
NUL,
BUFFER,
COLLECTION
};
Element()
: type_(UNSET) { }
Element(CassNull value)
: type_(NUL)
, buf_(cass::encode_with_length(value)) { }
Element(const Buffer& buf)
: type_(BUFFER)
, buf_(buf) { }
Element(const Collection* collection)
: type_(COLLECTION)
, collection_(collection) { }
bool is_unset() const {
return type_ == UNSET || (type_ == BUFFER && buf_.size() == 0);
}
bool is_null() const {
return type_ == NUL;
}
size_t get_size(int version) const;
size_t copy_buffer(int version, size_t pos, Buffer* buf) const;
Buffer get_buffer_cached(int version, Request::EncodingCache* cache, bool add_to_cache) const;
private:
Type type_;
Buffer buf_;
SharedRefPtr<const Collection> collection_;
};
typedef std::vector<Element> ElementVec;
public:
AbstractData(size_t count)
: elements_(count) { }
virtual ~AbstractData() { }
const ElementVec& elements() const { return elements_; }
size_t elements_count() const { return elements_.size(); }
void reset(size_t count) {
elements_.clear();
elements_.resize(count);
}
#define SET_TYPE(Type) \
CassError set(size_t index, const Type value) { \
CASS_CHECK_INDEX_AND_TYPE(index, value); \
elements_[index] = cass::encode_with_length(value); \
return CASS_OK; \
}
SET_TYPE(cass_int8_t)
SET_TYPE(cass_int16_t)
SET_TYPE(cass_int32_t)
SET_TYPE(cass_uint32_t)
SET_TYPE(cass_int64_t)
SET_TYPE(cass_float_t)
SET_TYPE(cass_double_t)
SET_TYPE(cass_bool_t)
SET_TYPE(CassString)
SET_TYPE(CassBytes)
SET_TYPE(CassCustom)
SET_TYPE(CassUuid)
SET_TYPE(CassInet)
SET_TYPE(CassDecimal)
#undef SET_TYPE
CassError set(size_t index, CassNull value);
CassError set(size_t index, const Collection* value);
CassError set(size_t index, const Tuple* value);
CassError set(size_t index, const UserTypeValue* value);
template<class T>
CassError set(StringRef name, const T value) {
IndexVec indices;
if (get_indices(name, &indices) == 0) {
return CASS_ERROR_LIB_NAME_DOES_NOT_EXIST;
}
for (IndexVec::const_iterator it = indices.begin(),
end = indices.end(); it != end; ++it) {
size_t index = *it;
CassError rc = set(index, value);
if (rc != CASS_OK) return rc;
}
return CASS_OK;
}
Buffer encode() const;
Buffer encode_with_length() const;
protected:
virtual size_t get_indices(StringRef name,
IndexVec* indices) = 0;
virtual const DataType::ConstPtr& get_type(size_t index) const = 0;
private:
template <class T>
CassError check(size_t index, const T value) {
if (index >= elements_.size()) {
return CASS_ERROR_LIB_INDEX_OUT_OF_BOUNDS;
}
IsValidDataType<T> is_valid_type;
DataType::ConstPtr data_type(get_type(index));
if (data_type && !is_valid_type(value, data_type)) {
return CASS_ERROR_LIB_INVALID_VALUE_TYPE;
}
return CASS_OK;
}
size_t get_buffers_size() const;
void encode_buffers(size_t pos, Buffer* buf) const;
private:
ElementVec elements_;
private:
DISALLOW_COPY_AND_ASSIGN(AbstractData);
};
} // namespace cass
#endif