blob: bbf28f6fc9ee5e43cca09a8120e334954fa38adc [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 <cstring>
#include <ignite/ignite_error.h>
#include "ignite/impl/interop//interop_output_stream.h"
/**
* Common macro to write a single value.
*/
#define IGNITE_INTEROP_OUT_WRITE(val, type, len) { \
EnsureCapacity(pos + len); \
*reinterpret_cast<type*>(data + pos) = val; \
Shift(len); \
}
/**
* Common macro to write an array.
*/
#define IGNITE_INTEROP_OUT_WRITE_ARRAY(val, len) { \
CopyAndShift(reinterpret_cast<const int8_t*>(val), 0, len); \
}
namespace ignite
{
namespace impl
{
namespace interop
{
InteropOutputStream::InteropOutputStream(InteropMemory* mem)
{
this->mem = mem;
data = mem->Data();
cap = mem->Capacity();
pos = 0;
}
void InteropOutputStream::WriteInt8(const int8_t val)
{
IGNITE_INTEROP_OUT_WRITE(val, int8_t, 1);
}
void InteropOutputStream::WriteInt8(const int8_t val, const int32_t pos)
{
EnsureCapacity(pos + 1);
*(data + pos) = val;
}
void InteropOutputStream::WriteInt8Array(const int8_t* val, const int32_t len)
{
IGNITE_INTEROP_OUT_WRITE_ARRAY(val, len);
}
void InteropOutputStream::WriteBool(const bool val)
{
WriteInt8(val ? 1 : 0);
}
void InteropOutputStream::WriteBoolArray(const bool* val, const int32_t len)
{
for (int i = 0; i < len; i++)
WriteBool(*(val + i));
}
void InteropOutputStream::WriteInt16(const int16_t val)
{
IGNITE_INTEROP_OUT_WRITE(val, int16_t, 2);
}
void InteropOutputStream::WriteInt16(const int32_t pos, const int16_t val)
{
EnsureCapacity(pos + 2);
*reinterpret_cast<int16_t*>(data + pos) = val;
}
void InteropOutputStream::WriteInt16Array(const int16_t* val, const int32_t len)
{
IGNITE_INTEROP_OUT_WRITE_ARRAY(val, len << 1);
}
void InteropOutputStream::WriteUInt16(const uint16_t val)
{
IGNITE_INTEROP_OUT_WRITE(val, uint16_t, 2);
}
void InteropOutputStream::WriteUInt16Array(const uint16_t* val, const int32_t len)
{
IGNITE_INTEROP_OUT_WRITE_ARRAY(val, len << 1);
}
void InteropOutputStream::WriteInt32(const int32_t val)
{
IGNITE_INTEROP_OUT_WRITE(val, int32_t, 4);
}
void InteropOutputStream::WriteInt32(const int32_t pos, const int32_t val)
{
EnsureCapacity(pos + 4);
*reinterpret_cast<int32_t*>(data + pos) = val;
}
void InteropOutputStream::WriteInt32Array(const int32_t* val, const int32_t len)
{
IGNITE_INTEROP_OUT_WRITE_ARRAY(val, len << 2);
}
void InteropOutputStream::WriteInt64(const int64_t val)
{
IGNITE_INTEROP_OUT_WRITE(val, int64_t, 8);
}
void InteropOutputStream::WriteInt64(const int32_t pos, const int64_t val)
{
EnsureCapacity(pos + 8);
*reinterpret_cast<int64_t*>(data + pos) = val;
}
void InteropOutputStream::WriteInt64Array(const int64_t* val, const int32_t len)
{
IGNITE_INTEROP_OUT_WRITE_ARRAY(val, len << 3);
}
void InteropOutputStream::WriteFloat(const float val)
{
BinaryFloatInt32 u;
u.f = val;
WriteInt32(u.i);
}
void InteropOutputStream::WriteFloatArray(const float* val, const int32_t len)
{
for (int i = 0; i < len; i++)
WriteFloat(*(val + i));
}
void InteropOutputStream::WriteDouble(const double val)
{
BinaryDoubleInt64 u;
u.d = val;
WriteInt64(u.i);
}
void InteropOutputStream::WriteDoubleArray(const double* val, const int32_t len)
{
for (int i = 0; i < len; i++)
WriteDouble(*(val + i));
}
int32_t InteropOutputStream::Position() const
{
return pos;
}
void InteropOutputStream::Position(const int32_t val)
{
EnsureCapacity(val);
pos = val;
}
int32_t InteropOutputStream::Reserve(int32_t num)
{
EnsureCapacity(pos + num);
int32_t res = pos;
Shift(num);
return res;
}
void InteropOutputStream::Synchronize()
{
mem->Length(pos);
}
InteropMemory* InteropOutputStream::GetMemory()
{
return mem;
}
void InteropOutputStream::EnsureCapacity(int32_t reqCap) {
if (reqCap > cap) {
int newCap = cap << 1;
if (newCap < reqCap)
newCap = reqCap;
mem->Reallocate(newCap);
data = mem->Data();
cap = newCap;
}
}
void InteropOutputStream::Shift(int32_t cnt) {
pos += cnt;
}
void InteropOutputStream::CopyAndShift(const int8_t* src, int32_t off, int32_t len) {
EnsureCapacity(pos + len);
memcpy(data + pos, src + off, len);
Shift(len);
}
}
}
}