0

我有这样的代码:

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()

InByteArray::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 行。

它的形状不同,因为我已经应用了肮脏的技巧(效果不佳)。

4

2 回答 2

1

是 ret.resize(MAX(body_left,tmp_read.size())); 分配最高 body_left 或 tmp_read.size() 的 ByteArray?

MAX最有可能的是返回两个参数中较大的一个的宏。该行ret.resize(MAX(body_left,tmp_read.size()));确保ret对于可能发生的任何写入操作都足够大。

在 ByteArray::Write r = tmp_read.write(); r 是否成为指向空间中将用于写入数据的位置的指针?

在 ByteArray::Write w = ret.write(); 中,w 会不会变成像上一个问题中的 r 一样的指针?

Write是在第 187 行定义的类。write()是在第 209 行定义的函数,它返回一个Write对象,而不是指针。因此randw从来都不是指针。

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_fromto的内容m_toget_partial_data输入要读入的数量rec,该数量被传递给copymemas m_count

于 2014-08-21T02:17:34.490 回答
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;

评论/意见?

于 2014-08-21T14:57:53.570 回答