| /* |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you 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 DATASTAX_INTERNAL_ABSTRACT_DATA_HPP |
| #define DATASTAX_INTERNAL_ABSTRACT_DATA_HPP |
| |
| #include "allocated.hpp" |
| #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" |
| #include "vector.hpp" |
| |
| #define CASS_CHECK_INDEX_AND_TYPE(Index, Value) \ |
| do { \ |
| CassError rc = check(Index, Value); \ |
| if (rc != CASS_OK) return rc; \ |
| } while (0) |
| |
| namespace datastax { namespace internal { namespace core { |
| |
| class Tuple; |
| class UserTypeValue; |
| |
| class AbstractData : public Allocated { |
| public: |
| class Element { |
| public: |
| enum Type { UNSET, NUL, BUFFER, COLLECTION }; |
| |
| Element() |
| : type_(UNSET) {} |
| |
| Element(CassNull value) |
| : type_(NUL) |
| , buf_(core::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() const; |
| size_t copy_buffer(size_t pos, Buffer* buf) const; |
| Buffer get_buffer() const; |
| |
| private: |
| Type type_; |
| Buffer buf_; |
| SharedRefPtr<const Collection> collection_; |
| }; |
| |
| typedef Vector<Element> ElementVec; |
| |
| public: |
| AbstractData(size_t count) |
| : elements_(count) {} |
| |
| virtual ~AbstractData() {} |
| |
| const ElementVec& elements() const { return elements_; } |
| |
| 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] = core::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) |
| SET_TYPE(CassDuration) |
| |
| #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 datastax::internal::core |
| |
| #endif |