Объединение небольших порций данных в один большой раздел памяти

У меня есть такой код:

ByteArray ret;
ret.resize( MAX( body_left, tmp_read.size() ) );
while ( body_left > 0 ) {
ByteArray::Write r = tmp_read.write();
int rec = 0;
err = connection->get_partial_data( r.ptr(), MIN( body_left, tmp_read.size() ), rec );
if ( rec > 0 ) {
ByteArray::Write w = ret.write();
copymem( w.ptr(), r.ptr(), rec );
body_left -= rec;
}
}

Мне сложно понять этот код. Несколько вопросов:

Является ret.resize(MAX(body_left,tmp_read.size())); выделяя ByteArray из самых высоких body_left или же tmp_read.size()?

В ByteArray::Write r = tmp_read.write(); делает r стать указателем на место в пространстве, которое будет использоваться для записи данных?

В ByteArray::Write w = ret.write();делает w стать указателем как r в предыдущем вопросе?

Также в этой строке:

copymem(w.ptr(),r.ptr(),rec);

Как я понимаю в этой строке, все данные, которые собираются по указателю r копируется в местоположение под указателем w, Проблема в том, что они разного размера, как переместить указатель w.ptr() сохранить данные в целости и в правильном порядке? Или w.ptr() является указателем на функцию, и это не должно быть проблемой.


Дополнительный контекст:

метод get_partial_data возвращает фрагменты данных — скажем, 20, 20 и 10 байтов каждый.
переменная ret должен иметь длину 50 байт и объединить эти куски в один ByteArray,

К сожалению, я не могу найти определение ByteArray в этом проекте, так что я думаю, что это часть другой библиотеки (может быть, libGL?).

Я знаю, что этот вопрос не очень точен, и я делаю прыжок веры, но если кто-то может мне помочь, я был бы благодарен.

Исходный класс и проект, этот код был взят из:

https://github.com/okamstudio/godot/blob/master/core/io/http_client.cpp

Линии 503-516.

Это в другой форме, так как я уже применил грязный хак (который не очень хорошо работает).

0

Решение

Ret.resize (MAX (body_left, tmp_read.size ())); выделяя
ByteArray самого высокого body_left или tmp_read.size ()?

MAX скорее всего, это макрос, который возвращает больший из двух аргументов. Линия ret.resize(MAX(body_left,tmp_read.size())); гарантирует, что ret достаточно велика для любых операций записи, которые могут произойти.

В ByteArray :: Write r = tmp_read.write (); становится ли указатель на
место в пространстве, которое будет использоваться для записи данных?

В ByteArray :: Write w = ret.write () ;, w становится указателем как r
в предыдущем вопросе?

Написать это класс, определенный в строке 187. записывать() является функцией, определенной в строке 209, которая возвращает Write объект, а не указатель. Следовательно r а также w никогда не указатели.

class Write {
// ...
};

Write write() {
Write w;
// ...
return w;
}

Также в этой строке:

copymem(w.ptr(),r.ptr(),rec);

Как я понимаю в этой строке, все данные, которые собираются под
указатель r копируется в местоположение под указателем w. Проблема в
что они разного размера, как переместить указатель w.ptr () для сохранения данных
в целости и сохранности? Или w.ptr () — указатель на функцию
и это не должно быть проблемой.

copymem макрос, определенный в строке 36

#define copymem(m_to,m_from,m_count) \
do { \
unsigned char * _from=(unsigned char*)m_from; \
unsigned char * _to=(unsigned char*)m_to; \
int _count=m_count; \
for (int _i=0;_i<_count;_i++) \
_to[_i]=_from[_i]; \
} while (0);

Все, что этот код, похоже, делает, это копирует содержимое m_from в m_to, get_partial_data кормит количество для чтения в rec, который передается copymem как m_count,

1

Другие решения

Чтобы обернуть все, что я (мы) узнали до сих пор:

Оригинальный код был следующим:

    ByteArray::Write r = tmp_read.write();
int rec=0;
err = connection->get_partial_data(r.ptr(),MIN(body_left,tmp_read.size()),rec);
if (rec>0) {
ByteArray ret;
ret.resize(rec);
ByteArray::Write w = ret.write();
copymem(w.ptr(),r.ptr(),rec);
body_left-=rec;
if (body_left==0) {
status=STATUS_CONNECTED;
}
return ret;
}

Где copymem — это макрос, который выглядит следующим образом:

    #define copymem(m_to,m_from,m_count) \
do { \
unsigned char * _from=(unsigned char*)m_from; \
unsigned char * _to=(unsigned char*)m_to; \
int _count=m_count; \
for (int _i=0;_i<_count;_i++) \
_to[_i]=_from[_i]; \
} while (0);

Используя все, что мне объяснили, я отказался от использования макросов, потому что, как я понимаю, w.ptr () возвращает раздел памяти, и макрос всегда начинает копироваться с первого байта этого раздела. Макрос не поддерживает смещение или передачу указателей.

Конечный результат выглядит следующим образом:

    ByteArray ret;
ret.resize(MAX(body_left,tmp_read.size()));
ByteArray::Write w = ret.write();
unsigned char * _to = (unsigned char*) w.ptr();
int _offset = 0;
while (body_left > 0) {
ByteArray::Write r = tmp_read.write();
int rec=0;
err = connection->get_partial_data(r.ptr(),MIN(body_left,tmp_read.size()),rec);
if (rec>0) {
unsigned char * _from=(unsigned char*)r.ptr();
for (int _i=0;_i<rec;_i++)
_to[_offset+_i]=_from[_i];
_offset += rec;
body_left-=rec;
}
}
if (body_left==0) {
status=STATUS_CONNECTED;
}
return ret;

Кто-нибудь может подтвердить, что это жизнеспособное решение или даже предложить улучшение?

Обновить. Я обнаружил, что на самом деле могу переместить w.ptr () по смещению для макроса, альтернативный код выглядит следующим образом:

    ByteArray ret;
ret.resize(MAX(body_left,tmp_read.size()));
ByteArray::Write w = ret.write();
int _offset = 0;
while (body_left > 0) {
ByteArray::Write r = tmp_read.write();
int rec=0;
err = connection->get_partial_data(r.ptr(),MIN(body_left,tmp_read.size()),rec);
if (rec>0) {
copymem(w.ptr()+_offset,r.ptr(),rec);
body_left-=rec;
_offset += rec;
}
}
if (body_left==0) {
status=STATUS_CONNECTED;
}
return ret;

Комментарии / мнение?

0