我有这样的代码:
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()));
是否分配最高body_left
或tmp_read.size()
的ByteArray
?
在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行。
它的形状不同,因为我已经应用了dirty hack(效果不太好)。
ret.resize (MAX (body_left tmp_read.size ()));分配的ByteArray的最高body_left或tmp_read.size()?
MAX
很可能是一个宏,返回两个参数中较大的一个。ret.resize(MAX(body_left,tmp_read.size()));
行确保ret
足够大,可以执行任何可能发生的写入操作。
In ByteArray::Write r = tmp_read.write();r变成指针了吗将用于写入数据的空间位置?
在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()来保存数据完好无损,顺序正确吗?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
,然后作为m_count
传递给copymem
。
总结我(我们)所学到的一切:
原代码如下:
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;
评论/意见吗?