123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703 |
- /*
- * 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
|