704 lines
19 KiB
C++
704 lines
19 KiB
C++
/*
|
|
* This is the source code of tgnet library v. 1.1
|
|
* It is licensed under GNU GPL v. 2 or later.
|
|
* You should have received a copy of the license in this archive (see LICENSE).
|
|
*
|
|
* Copyright Nikolai Kudashov, 2015-2018.
|
|
*/
|
|
|
|
#include <memory.h>
|
|
#include <stdlib.h>
|
|
#include "NativeByteBuffer.h"
|
|
#include "FileLog.h"
|
|
#include "ByteArray.h"
|
|
#include "ConnectionsManager.h"
|
|
#include "BuffersStorage.h"
|
|
|
|
NativeByteBuffer::NativeByteBuffer(uint32_t size) {
|
|
#ifdef ANDROID
|
|
if (jclass_ByteBuffer != nullptr) {
|
|
JNIEnv *env = 0;
|
|
if (javaVm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) {
|
|
if (LOGS_ENABLED) DEBUG_E("can't get jnienv");
|
|
exit(1);
|
|
}
|
|
javaByteBuffer = env->CallStaticObjectMethod(jclass_ByteBuffer, jclass_ByteBuffer_allocateDirect, size);
|
|
if (javaByteBuffer == nullptr) {
|
|
if (LOGS_ENABLED) DEBUG_E("can't create javaByteBuffer");
|
|
exit(1);
|
|
}
|
|
jobject globalRef = env->NewGlobalRef(javaByteBuffer);
|
|
env->DeleteLocalRef(javaByteBuffer);
|
|
javaByteBuffer = globalRef;
|
|
buffer = (uint8_t *) env->GetDirectBufferAddress(javaByteBuffer);
|
|
bufferOwner = false;
|
|
} else {
|
|
#endif
|
|
buffer = new uint8_t[size];
|
|
bufferOwner = true;
|
|
#ifdef ANDROID
|
|
}
|
|
#endif
|
|
if (buffer == nullptr) {
|
|
if (LOGS_ENABLED) DEBUG_E("can't allocate NativeByteBuffer buffer");
|
|
exit(1);
|
|
}
|
|
_limit = _capacity = size;
|
|
}
|
|
|
|
NativeByteBuffer::NativeByteBuffer(bool calculate) {
|
|
calculateSizeOnly = calculate;
|
|
}
|
|
|
|
NativeByteBuffer::NativeByteBuffer(uint8_t *buff, uint32_t length) {
|
|
buffer = buff;
|
|
sliced = true;
|
|
_limit = _capacity = length;
|
|
}
|
|
|
|
NativeByteBuffer::~NativeByteBuffer() {
|
|
#ifdef ANDROID
|
|
if (javaByteBuffer != nullptr) {
|
|
JNIEnv *env = 0;
|
|
if (javaVm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) {
|
|
if (LOGS_ENABLED) DEBUG_E("can't get jnienv");
|
|
exit(1);
|
|
}
|
|
env->DeleteGlobalRef(javaByteBuffer);
|
|
javaByteBuffer = nullptr;
|
|
}
|
|
#endif
|
|
if (bufferOwner && !sliced && buffer != nullptr) {
|
|
delete[] buffer;
|
|
buffer = nullptr;
|
|
}
|
|
}
|
|
|
|
uint32_t NativeByteBuffer::position() {
|
|
return _position;
|
|
}
|
|
|
|
void NativeByteBuffer::position(uint32_t position) {
|
|
if (position > _limit) {
|
|
return;
|
|
}
|
|
_position = position;
|
|
}
|
|
|
|
uint32_t NativeByteBuffer::capacity() {
|
|
return _capacity;
|
|
}
|
|
|
|
uint32_t NativeByteBuffer::limit() {
|
|
return _limit;
|
|
}
|
|
|
|
uint32_t NativeByteBuffer::remaining() {
|
|
return _limit - _position;
|
|
}
|
|
|
|
void NativeByteBuffer::clearCapacity() {
|
|
if (!calculateSizeOnly) {
|
|
return;
|
|
}
|
|
_capacity = 0;
|
|
}
|
|
|
|
void NativeByteBuffer::limit(uint32_t limit) {
|
|
if (limit > _capacity) {
|
|
return;
|
|
}
|
|
if (_position > limit) {
|
|
_position = limit;
|
|
}
|
|
_limit = limit;
|
|
}
|
|
|
|
void NativeByteBuffer::flip() {
|
|
_limit = _position;
|
|
_position = 0;
|
|
}
|
|
|
|
void NativeByteBuffer::clear() {
|
|
_position = 0;
|
|
_limit = _capacity;
|
|
}
|
|
|
|
uint8_t *NativeByteBuffer::bytes() {
|
|
return buffer;
|
|
}
|
|
|
|
void NativeByteBuffer::rewind() {
|
|
_position = 0;
|
|
}
|
|
|
|
void NativeByteBuffer::compact() {
|
|
if (_position == _limit) {
|
|
return;
|
|
}
|
|
memmove(buffer, buffer + _position, sizeof(uint8_t) * (_limit - _position));
|
|
_position = (_limit - _position);
|
|
_limit = _capacity;
|
|
}
|
|
|
|
bool NativeByteBuffer::hasRemaining() {
|
|
return _position < _limit;
|
|
}
|
|
|
|
void NativeByteBuffer::skip(uint32_t length) {
|
|
if (!calculateSizeOnly) {
|
|
if (_position + length > _limit) {
|
|
return;
|
|
}
|
|
_position += length;
|
|
} else {
|
|
_capacity += length;
|
|
}
|
|
}
|
|
|
|
void NativeByteBuffer::writeInt32(int32_t x, bool *error) {
|
|
if (!calculateSizeOnly) {
|
|
if (_position + 4 > _limit) {
|
|
if (error != nullptr) {
|
|
*error = true;
|
|
}
|
|
if (LOGS_ENABLED) DEBUG_E("write int32 error");
|
|
return;
|
|
}
|
|
buffer[_position++] = (uint8_t) x;
|
|
buffer[_position++] = (uint8_t) (x >> 8);
|
|
buffer[_position++] = (uint8_t) (x >> 16);
|
|
buffer[_position++] = (uint8_t) (x >> 24);
|
|
} else {
|
|
_capacity += 4;
|
|
}
|
|
}
|
|
|
|
void NativeByteBuffer::writeInt64(int64_t x, bool *error) {
|
|
if (!calculateSizeOnly) {
|
|
if (_position + 8 > _limit) {
|
|
if (error != nullptr) {
|
|
*error = true;
|
|
}
|
|
if (LOGS_ENABLED) DEBUG_E("write int64 error");
|
|
return;
|
|
}
|
|
buffer[_position++] = (uint8_t) x;
|
|
buffer[_position++] = (uint8_t) (x >> 8);
|
|
buffer[_position++] = (uint8_t) (x >> 16);
|
|
buffer[_position++] = (uint8_t) (x >> 24);
|
|
buffer[_position++] = (uint8_t) (x >> 32);
|
|
buffer[_position++] = (uint8_t) (x >> 40);
|
|
buffer[_position++] = (uint8_t) (x >> 48);
|
|
buffer[_position++] = (uint8_t) (x >> 56);
|
|
} else {
|
|
_capacity += 8;
|
|
}
|
|
}
|
|
|
|
void NativeByteBuffer::writeBool(bool value, bool *error) {
|
|
if (!calculateSizeOnly) {
|
|
if (value) {
|
|
writeInt32(0x997275b5, error);
|
|
} else {
|
|
writeInt32(0xbc799737, error);
|
|
}
|
|
} else {
|
|
_capacity += 4;
|
|
}
|
|
}
|
|
|
|
void NativeByteBuffer::writeBytes(uint8_t *b, uint32_t length, bool *error) {
|
|
if (!calculateSizeOnly) {
|
|
if (_position + length > _limit) {
|
|
if (error != nullptr) {
|
|
*error = true;
|
|
}
|
|
if (LOGS_ENABLED) DEBUG_E("write bytes error");
|
|
return;
|
|
}
|
|
writeBytesInternal(b, 0, length);
|
|
} else {
|
|
_capacity += length;
|
|
}
|
|
}
|
|
|
|
void NativeByteBuffer::writeBytes(uint8_t *b, uint32_t offset, uint32_t length, bool *error) {
|
|
if (!calculateSizeOnly) {
|
|
if (_position + length > _limit) {
|
|
if (error != nullptr) {
|
|
*error = true;
|
|
}
|
|
if (LOGS_ENABLED) DEBUG_E("write bytes error");
|
|
return;
|
|
}
|
|
writeBytesInternal(b, offset, length);
|
|
} else {
|
|
_capacity += length;
|
|
}
|
|
}
|
|
|
|
void NativeByteBuffer::writeBytes(NativeByteBuffer *b, bool *error) {
|
|
uint32_t length = b->_limit - b->_position;
|
|
if (length == 0) {
|
|
return;
|
|
}
|
|
if (!calculateSizeOnly) {
|
|
if (_position + length > _limit) {
|
|
if (error != nullptr) {
|
|
*error = true;
|
|
}
|
|
if (LOGS_ENABLED) DEBUG_E("write bytes error");
|
|
return;
|
|
}
|
|
writeBytesInternal(b->buffer + b->_position, 0, length);
|
|
b->position(b->limit());
|
|
} else {
|
|
_capacity += length;
|
|
}
|
|
}
|
|
|
|
void NativeByteBuffer::writeBytes(ByteArray *b, bool *error) {
|
|
if (!calculateSizeOnly) {
|
|
if (_position + b->length > _limit) {
|
|
if (error != nullptr) {
|
|
*error = true;
|
|
}
|
|
if (LOGS_ENABLED) DEBUG_E("write bytes error");
|
|
return;
|
|
}
|
|
writeBytesInternal(b->bytes, 0, b->length);
|
|
} else {
|
|
_capacity += b->length;
|
|
}
|
|
}
|
|
|
|
void NativeByteBuffer::writeBytesInternal(uint8_t *b, uint32_t offset, uint32_t length) {
|
|
memcpy(buffer + _position, b + offset, sizeof(uint8_t) * length);
|
|
_position += length;
|
|
}
|
|
|
|
void NativeByteBuffer::writeByte(uint8_t i, bool *error) {
|
|
if (!calculateSizeOnly) {
|
|
if (_position + 1 > _limit) {
|
|
if (error != nullptr) {
|
|
*error = true;
|
|
}
|
|
if (LOGS_ENABLED) DEBUG_E("write byte error");
|
|
return;
|
|
}
|
|
buffer[_position++] = i;
|
|
} else {
|
|
_capacity += 1;
|
|
}
|
|
}
|
|
|
|
void NativeByteBuffer::writeString(std::string s, bool *error) {
|
|
writeByteArray((uint8_t *) s.c_str(), (uint32_t) s.length(), error);
|
|
}
|
|
|
|
void NativeByteBuffer::writeByteArray(uint8_t *b, uint32_t offset, uint32_t length, bool *error) {
|
|
if (length <= 253) {
|
|
if (!calculateSizeOnly) {
|
|
if (_position + 1 > _limit) {
|
|
if (error != nullptr) {
|
|
*error = true;
|
|
}
|
|
if (LOGS_ENABLED) DEBUG_E("write byte array error");
|
|
return;
|
|
}
|
|
buffer[_position++] = (uint8_t) length;
|
|
} else {
|
|
_capacity += 1;
|
|
}
|
|
} else {
|
|
if (!calculateSizeOnly) {
|
|
if (_position + 4 > _limit) {
|
|
if (error != nullptr) {
|
|
*error = true;
|
|
}
|
|
if (LOGS_ENABLED) DEBUG_E("write byte array error");
|
|
return;
|
|
}
|
|
buffer[_position++] = (uint8_t) 254;
|
|
buffer[_position++] = (uint8_t) length;
|
|
buffer[_position++] = (uint8_t) (length >> 8);
|
|
buffer[_position++] = (uint8_t) (length >> 16);
|
|
} else {
|
|
_capacity += 4;
|
|
}
|
|
}
|
|
if (!calculateSizeOnly) {
|
|
if (_position + length > _limit) {
|
|
if (error != nullptr) {
|
|
*error = true;
|
|
}
|
|
if (LOGS_ENABLED) DEBUG_E("write byte array error");
|
|
return;
|
|
}
|
|
writeBytesInternal(b, offset, length);
|
|
} else {
|
|
_capacity += length;
|
|
}
|
|
uint32_t addition = (length + (length <= 253 ? 1 : 4)) % 4;
|
|
if (addition != 0) {
|
|
addition = 4 - addition;
|
|
}
|
|
if (!calculateSizeOnly && _position + addition > _limit) {
|
|
if (error != nullptr) {
|
|
*error = true;
|
|
}
|
|
if (LOGS_ENABLED) DEBUG_E("write byte array error");
|
|
return;
|
|
}
|
|
for (uint32_t a = 0; a < addition; a++) {
|
|
if (!calculateSizeOnly) {
|
|
buffer[_position++] = (uint8_t) 0;
|
|
} else {
|
|
_capacity += 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
void NativeByteBuffer::writeByteArray(uint8_t *b, uint32_t length, bool *error) {
|
|
writeByteArray(b, 0, length, error);
|
|
}
|
|
|
|
void NativeByteBuffer::writeByteArray(NativeByteBuffer *b, bool *error) {
|
|
b->rewind();
|
|
writeByteArray(b->buffer, 0, b->limit(), error);
|
|
}
|
|
|
|
void NativeByteBuffer::writeByteArray(ByteArray *b, bool *error) {
|
|
writeByteArray(b->bytes, 0, b->length, error);
|
|
}
|
|
|
|
void NativeByteBuffer::writeDouble(double d, bool *error) {
|
|
int64_t value;
|
|
memcpy(&value, &d, sizeof(int64_t));
|
|
writeInt64(value, error);
|
|
}
|
|
|
|
void NativeByteBuffer::writeInt32(int32_t x) {
|
|
writeInt32(x, nullptr);
|
|
}
|
|
|
|
void NativeByteBuffer::writeInt64(int64_t x) {
|
|
writeInt64(x, nullptr);
|
|
}
|
|
|
|
void NativeByteBuffer::writeBool(bool value) {
|
|
writeBool(value, nullptr);
|
|
}
|
|
|
|
void NativeByteBuffer::writeBytes(uint8_t *b, uint32_t length) {
|
|
writeBytes(b, length, nullptr);
|
|
}
|
|
|
|
void NativeByteBuffer::writeBytes(uint8_t *b, uint32_t offset, uint32_t length) {
|
|
writeBytes(b, offset, length, nullptr);
|
|
}
|
|
|
|
void NativeByteBuffer::writeBytes(ByteArray *b) {
|
|
writeBytes(b, nullptr);
|
|
}
|
|
|
|
void NativeByteBuffer::writeBytes(NativeByteBuffer *b) {
|
|
writeBytes(b, nullptr);
|
|
}
|
|
|
|
void NativeByteBuffer::writeByte(uint8_t i) {
|
|
writeByte(i, nullptr);
|
|
}
|
|
|
|
void NativeByteBuffer::writeString(std::string s) {
|
|
writeString(s, nullptr);
|
|
}
|
|
|
|
void NativeByteBuffer::writeByteArray(uint8_t *b, uint32_t offset, uint32_t length) {
|
|
writeByteArray(b, offset, length, nullptr);
|
|
}
|
|
|
|
void NativeByteBuffer::writeByteArray(uint8_t *b, uint32_t length) {
|
|
writeByteArray(b, length, nullptr);
|
|
}
|
|
|
|
void NativeByteBuffer::writeByteArray(NativeByteBuffer *b) {
|
|
writeByteArray(b, nullptr);
|
|
}
|
|
|
|
void NativeByteBuffer::writeByteArray(ByteArray *b) {
|
|
writeByteArray(b->bytes, b->length, nullptr);
|
|
}
|
|
|
|
void NativeByteBuffer::writeDouble(double d) {
|
|
writeDouble(d, nullptr);
|
|
}
|
|
|
|
int32_t NativeByteBuffer::readInt32(bool *error) {
|
|
if (_position + 4 > _limit) {
|
|
if (error != nullptr) {
|
|
*error = true;
|
|
}
|
|
if (LOGS_ENABLED) DEBUG_E("read int32 error");
|
|
return 0;
|
|
}
|
|
int32_t result = ((buffer[_position] & 0xff)) |
|
|
((buffer[_position + 1] & 0xff) << 8) |
|
|
((buffer[_position + 2] & 0xff) << 16) |
|
|
((buffer[_position + 3] & 0xff) << 24);
|
|
_position += 4;
|
|
return result;
|
|
}
|
|
|
|
uint32_t NativeByteBuffer::readUint32(bool *error) {
|
|
return (uint32_t) readInt32(error);
|
|
}
|
|
|
|
uint64_t NativeByteBuffer::readUint64(bool *error) {
|
|
return (uint64_t) readInt64(error);
|
|
}
|
|
|
|
int32_t NativeByteBuffer::readBigInt32(bool *error) {
|
|
if (_position + 4 > _limit) {
|
|
if (error != nullptr) {
|
|
*error = true;
|
|
}
|
|
if (LOGS_ENABLED) DEBUG_E("read big int32 error");
|
|
return 0;
|
|
}
|
|
int32_t result = ((buffer[_position] & 0xff) << 24) |
|
|
((buffer[_position + 1] & 0xff) << 16) |
|
|
((buffer[_position + 2] & 0xff) << 8) |
|
|
((buffer[_position + 3] & 0xff));
|
|
_position += 4;
|
|
return result;
|
|
}
|
|
|
|
int64_t NativeByteBuffer::readInt64(bool *error) {
|
|
if (_position + 8 > _limit) {
|
|
if (error != nullptr) {
|
|
*error = true;
|
|
}
|
|
if (LOGS_ENABLED) DEBUG_E("read int64 error");
|
|
return 0;
|
|
}
|
|
int64_t result = ((int64_t) (buffer[_position] & 0xff)) |
|
|
((int64_t) (buffer[_position + 1] & 0xff) << 8) |
|
|
((int64_t) (buffer[_position + 2] & 0xff) << 16) |
|
|
((int64_t) (buffer[_position + 3] & 0xff) << 24) |
|
|
((int64_t) (buffer[_position + 4] & 0xff) << 32) |
|
|
((int64_t) (buffer[_position + 5] & 0xff) << 40) |
|
|
((int64_t) (buffer[_position + 6] & 0xff) << 48) |
|
|
((int64_t) (buffer[_position + 7] & 0xff) << 56);
|
|
_position += 8;
|
|
return result;
|
|
}
|
|
|
|
uint8_t NativeByteBuffer::readByte(bool *error) {
|
|
if (_position + 1 > _limit) {
|
|
if (error != nullptr) {
|
|
*error = true;
|
|
}
|
|
if (LOGS_ENABLED) DEBUG_E("read byte error");
|
|
return 0;
|
|
}
|
|
return buffer[_position++];
|
|
}
|
|
|
|
bool NativeByteBuffer::readBool(bool *error) {
|
|
uint32_t consructor = readUint32(error);
|
|
if (consructor == 0x997275b5) {
|
|
return true;
|
|
} else if (consructor == 0xbc799737) {
|
|
return false;
|
|
}
|
|
if (error != nullptr) {
|
|
*error = true;
|
|
if (LOGS_ENABLED) DEBUG_E("read bool error");
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void NativeByteBuffer::readBytes(uint8_t *b, uint32_t length, bool *error) {
|
|
if (length > _limit - _position) {
|
|
if (error != nullptr) {
|
|
*error = true;
|
|
}
|
|
if (LOGS_ENABLED) DEBUG_E("read bytes error");
|
|
return;
|
|
}
|
|
memcpy(b, buffer + _position, length);
|
|
_position += length;
|
|
}
|
|
|
|
ByteArray *NativeByteBuffer::readBytes(uint32_t length, bool *error) {
|
|
if (length > _limit - _position) {
|
|
if (error != nullptr) {
|
|
*error = true;
|
|
}
|
|
if (LOGS_ENABLED) DEBUG_E("read bytes error");
|
|
return nullptr;
|
|
}
|
|
ByteArray *byteArray = new ByteArray(length);
|
|
memcpy(byteArray->bytes, buffer + _position, sizeof(uint8_t) * length);
|
|
_position += length;
|
|
return byteArray;
|
|
}
|
|
|
|
std::string NativeByteBuffer::readString(bool *error) {
|
|
uint32_t sl = 1;
|
|
if (_position + 1 > _limit) {
|
|
if (error != nullptr) {
|
|
*error = true;
|
|
}
|
|
if (LOGS_ENABLED) DEBUG_E("read string error");
|
|
return std::string("");
|
|
}
|
|
uint32_t l = buffer[_position++];
|
|
if (l >= 254) {
|
|
if (_position + 3 > _limit) {
|
|
if (error != nullptr) {
|
|
*error = true;
|
|
}
|
|
if (LOGS_ENABLED) DEBUG_E("read string error");
|
|
return std::string("");
|
|
}
|
|
l = buffer[_position] | (buffer[_position + 1] << 8) | (buffer[_position + 2] << 16);
|
|
_position += 3;
|
|
sl = 4;
|
|
}
|
|
uint32_t addition = (l + sl) % 4;
|
|
if (addition != 0) {
|
|
addition = 4 - addition;
|
|
}
|
|
if (_position + l + addition > _limit) {
|
|
if (error != nullptr) {
|
|
*error = true;
|
|
}
|
|
if (LOGS_ENABLED) DEBUG_E("read string error");
|
|
return std::string("");
|
|
}
|
|
std::string result = std::string((const char *) (buffer + _position), l);
|
|
_position += l + addition;
|
|
return result;
|
|
}
|
|
|
|
ByteArray *NativeByteBuffer::readByteArray(bool *error) {
|
|
uint32_t sl = 1;
|
|
if (_position + 1 > _limit) {
|
|
if (error != nullptr) {
|
|
*error = true;
|
|
}
|
|
if (LOGS_ENABLED) DEBUG_E("read byte array error");
|
|
return nullptr;
|
|
}
|
|
uint32_t l = buffer[_position++];
|
|
if (l >= 254) {
|
|
if (_position + 3 > _limit) {
|
|
if (error != nullptr) {
|
|
*error = true;
|
|
}
|
|
if (LOGS_ENABLED) DEBUG_E("read byte array error");
|
|
return nullptr;
|
|
}
|
|
l = buffer[_position] | (buffer[_position + 1] << 8) | (buffer[_position + 2] << 16);
|
|
_position += 3;
|
|
sl = 4;
|
|
}
|
|
uint32_t addition = (l + sl) % 4;
|
|
if (addition != 0) {
|
|
addition = 4 - addition;
|
|
}
|
|
if (_position + l + addition > _limit) {
|
|
if (error != nullptr) {
|
|
*error = true;
|
|
}
|
|
if (LOGS_ENABLED) DEBUG_E("read byte array error");
|
|
return nullptr;
|
|
}
|
|
ByteArray *result = new ByteArray(l);
|
|
memcpy(result->bytes, buffer + _position, sizeof(uint8_t) * l);
|
|
_position += l + addition;
|
|
return result;
|
|
}
|
|
|
|
NativeByteBuffer *NativeByteBuffer::readByteBuffer(bool copy, bool *error) {
|
|
uint32_t sl = 1;
|
|
if (_position + 1 > _limit) {
|
|
if (error != nullptr) {
|
|
*error = true;
|
|
}
|
|
if (LOGS_ENABLED) DEBUG_E("read byte buffer error");
|
|
return nullptr;
|
|
}
|
|
uint32_t l = buffer[_position++];
|
|
if (l >= 254) {
|
|
if (_position + 3 > _limit) {
|
|
if (error != nullptr) {
|
|
*error = true;
|
|
}
|
|
if (LOGS_ENABLED) DEBUG_E("read byte buffer error");
|
|
return nullptr;
|
|
}
|
|
l = buffer[_position] | (buffer[_position + 1] << 8) | (buffer[_position + 2] << 16);
|
|
_position += 3;
|
|
sl = 4;
|
|
}
|
|
uint32_t addition = (l + sl) % 4;
|
|
if (addition != 0) {
|
|
addition = 4 - addition;
|
|
}
|
|
if (_position + l + addition > _limit) {
|
|
if (error != nullptr) {
|
|
*error = true;
|
|
}
|
|
if (LOGS_ENABLED) DEBUG_E("read byte buffer error");
|
|
return nullptr;
|
|
}
|
|
NativeByteBuffer *result = nullptr;
|
|
if (copy) {
|
|
result = BuffersStorage::getInstance().getFreeBuffer(l);
|
|
memcpy(result->buffer, buffer + _position, sizeof(uint8_t) * l);
|
|
} else {
|
|
result = new NativeByteBuffer(buffer + _position, l);
|
|
}
|
|
_position += l + addition;
|
|
return result;
|
|
}
|
|
|
|
double NativeByteBuffer::readDouble(bool *error) {
|
|
double value;
|
|
int64_t value2 = readInt64(error);
|
|
memcpy(&value, &value2, sizeof(double));
|
|
return value;
|
|
}
|
|
|
|
void NativeByteBuffer::reuse() {
|
|
if (sliced) {
|
|
return;
|
|
}
|
|
BuffersStorage::getInstance().reuseFreeBuffer(this);
|
|
}
|
|
|
|
#ifdef ANDROID
|
|
jobject NativeByteBuffer::getJavaByteBuffer() {
|
|
if (javaByteBuffer == nullptr && javaVm != nullptr) {
|
|
JNIEnv *env = 0;
|
|
if (javaVm->GetEnv((void **) &env, JNI_VERSION_1_6) != JNI_OK) {
|
|
if (LOGS_ENABLED) DEBUG_E("can't get jnienv");
|
|
exit(1);
|
|
}
|
|
javaByteBuffer = env->NewDirectByteBuffer(buffer, _capacity);
|
|
if (javaByteBuffer == nullptr) {
|
|
if (LOGS_ENABLED) DEBUG_E("can't allocate NativeByteBuffer buffer");
|
|
exit(1);
|
|
}
|
|
jobject globalRef = env->NewGlobalRef(javaByteBuffer);
|
|
env->DeleteLocalRef(javaByteBuffer);
|
|
javaByteBuffer = globalRef;
|
|
}
|
|
return javaByteBuffer;
|
|
}
|
|
#endif
|