blob: c41b985a5b4a6c86a98b9631c053d8e4cf9b026d [file] [log] [blame]
/*
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.
*/
#include "tuple.hpp"
#include "collection.hpp"
#include "constants.hpp"
#include "encode.hpp"
#include "external.hpp"
#include "macros.hpp"
#include "user_type_value.hpp"
#include <string.h>
using namespace datastax;
using namespace datastax::internal::core;
extern "C" {
CassTuple* cass_tuple_new(size_t item_count) { return CassTuple::to(new Tuple(item_count)); }
CassTuple* cass_tuple_new_from_data_type(const CassDataType* data_type) {
if (!data_type->is_tuple()) {
return NULL;
}
return CassTuple::to(new Tuple(DataType::ConstPtr(data_type)));
}
void cass_tuple_free(CassTuple* tuple) { delete tuple->from(); }
const CassDataType* cass_tuple_data_type(const CassTuple* tuple) {
return CassDataType::to(tuple->data_type().get());
}
#define CASS_TUPLE_SET(Name, Params, Value) \
CassError cass_tuple_set_##Name(CassTuple* tuple, size_t index Params) { \
return tuple->set(index, Value); \
}
CASS_TUPLE_SET(null, ZERO_PARAMS_(), CassNull())
CASS_TUPLE_SET(int8, ONE_PARAM_(cass_int8_t value), value)
CASS_TUPLE_SET(int16, ONE_PARAM_(cass_int16_t value), value)
CASS_TUPLE_SET(int32, ONE_PARAM_(cass_int32_t value), value)
CASS_TUPLE_SET(uint32, ONE_PARAM_(cass_uint32_t value), value)
CASS_TUPLE_SET(int64, ONE_PARAM_(cass_int64_t value), value)
CASS_TUPLE_SET(float, ONE_PARAM_(cass_float_t value), value)
CASS_TUPLE_SET(double, ONE_PARAM_(cass_double_t value), value)
CASS_TUPLE_SET(bool, ONE_PARAM_(cass_bool_t value), value)
CASS_TUPLE_SET(uuid, ONE_PARAM_(CassUuid value), value)
CASS_TUPLE_SET(inet, ONE_PARAM_(CassInet value), value)
CASS_TUPLE_SET(collection, ONE_PARAM_(const CassCollection* value), value)
CASS_TUPLE_SET(tuple, ONE_PARAM_(const CassTuple* value), value)
CASS_TUPLE_SET(user_type, ONE_PARAM_(const CassUserType* value), value)
CASS_TUPLE_SET(bytes, TWO_PARAMS_(const cass_byte_t* value, size_t value_size),
CassBytes(value, value_size))
CASS_TUPLE_SET(decimal, THREE_PARAMS_(const cass_byte_t* varint, size_t varint_size, int scale),
CassDecimal(varint, varint_size, scale))
CASS_TUPLE_SET(duration, THREE_PARAMS_(cass_int32_t months, cass_int32_t days, cass_int64_t nanos),
CassDuration(months, days, nanos))
#undef CASS_TUPLE_SET
CassError cass_tuple_set_string(CassTuple* tuple, size_t index, const char* value) {
return tuple->set(index, CassString(value, SAFE_STRLEN(value)));
}
CassError cass_tuple_set_string_n(CassTuple* tuple, size_t index, const char* value,
size_t value_length) {
return tuple->set(index, CassString(value, value_length));
}
CassError cass_tuple_set_custom(CassTuple* tuple, size_t index, const char* class_name,
const cass_byte_t* value, size_t value_size) {
return tuple->set(index, CassCustom(StringRef(class_name), value, value_size));
}
CassError cass_tuple_set_custom_n(CassTuple* tuple, size_t index, const char* class_name,
size_t class_name_length, const cass_byte_t* value,
size_t value_size) {
return tuple->set(index, CassCustom(StringRef(class_name, class_name_length), value, value_size));
}
} // extern "C"
CassError Tuple::set(size_t index, CassNull value) {
CASS_TUPLE_CHECK_INDEX_AND_TYPE(index, value);
items_[index] = core::encode_with_length(value);
return CASS_OK;
}
CassError Tuple::set(size_t index, const Tuple* value) {
CASS_TUPLE_CHECK_INDEX_AND_TYPE(index, value);
items_[index] = value->encode_with_length();
return CASS_OK;
}
CassError Tuple::set(size_t index, const Collection* value) {
CASS_TUPLE_CHECK_INDEX_AND_TYPE(index, value);
items_[index] = value->encode_with_length();
return CASS_OK;
}
CassError Tuple::set(size_t index, const UserTypeValue* value) {
CASS_TUPLE_CHECK_INDEX_AND_TYPE(index, value);
items_[index] = value->encode_with_length();
return CASS_OK;
}
Buffer Tuple::encode() const {
Buffer buf(get_buffers_size());
encode_buffers(0, &buf);
return buf;
}
Buffer Tuple::encode_with_length() const {
size_t buffers_size = get_buffers_size();
Buffer buf(sizeof(int32_t) + buffers_size);
size_t pos = buf.encode_int32(0, buffers_size);
encode_buffers(pos, &buf);
return buf;
}
size_t Tuple::get_buffers_size() const {
size_t size = 0;
for (BufferVec::const_iterator i = items_.begin(), end = items_.end(); i != end; ++i) {
if (i->size() != 0) {
size += i->size();
} else {
size += sizeof(int32_t); // null
}
}
return size;
}
void Tuple::encode_buffers(size_t pos, Buffer* buf) const {
for (BufferVec::const_iterator i = items_.begin(), end = items_.end(); i != end; ++i) {
if (i->size() != 0) {
pos = buf->copy(pos, i->data(), i->size());
} else {
pos = buf->encode_int32(pos, -1); // null
}
}
}