我有这样的代码:
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 :(得分:1)
是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这样的指针 在上一个问题中?
Write是在第187行定义的类。write()是在第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}}。
答案 1 :(得分: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 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);
使用remyable向我解释的所有内容我删除了宏用法,因为据我所知,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;
评论/意见?