- 
          
- 
                Notifications
    You must be signed in to change notification settings 
- Fork 750
Add buffer stream #269
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add buffer stream #269
Conversation
         A2va
  
      
      
      commented
      
            A2va
  
      
      
      commented
        Nov 25, 2024 
      
    
  
- Before adding new features and new modules, please go to issues to submit the relevant feature description first.
- Write good commit messages and use the same coding conventions as the rest of the project.
- Please commit code to dev branch and we will merge into master branch in feature
- Ensure your edited codes with four spaces instead of TAB.
- 增加新特性和新模块之前,请先到issues提交相关特性说明,经过讨论评估确认后,再进行相应的代码提交,避免做无用工作。
- 编写友好可读的提交信息,并使用与工程代码相同的代码规范,代码请用4个空格字符代替tab缩进。
- 请提交代码到dev分支,如果通过,我们会在特定时间合并到master分支上。
- 为了规范化提交日志的格式,commit消息,不要用中文,请用英文描述。
| error: buffer.c | 
| 目前这个实现,tb_stream_exit时会连带buffer一起销毁。 建议不要连带buffer一起销毁。 理由如下: 如果我在函数 f 中产生一个buffer,并通过stream向其中写入了一些东西,然后我想返回这个buffer。 我看了一下,可能是个bug:     case TB_STREAM_CTRL_BUFF_SET_BUFFER:
        {
            // exit buffer first if exists
            if (stream_buffer->buffer && !stream_buffer->bref) tb_buffer_exit(stream_buffer->buffer);
            stream_buffer->buffer = (tb_buffer_ref_t)tb_va_arg(args, tb_buffer_ref_t);
            stream_buffer->head  = 0;
            stream_buffer->bref = tb_false;    // 此处应赋值为tb_true
            return tb_true;
        } | 
| 
 In this implementation, tb_stream_exit will be destroyed together with buffer. It is recommended not to destroy buffers together. The reasons are as follows: If I produce a buffer in function f and write something to it via stream, then I want to return this buffer. | 
| I think you're right. My implementation is based off the data stream, where bref is true in this case, I don't recall if there was some reasoning to be false. | 
| 
 
 right, you can open a pr to fix it. | 
| I have fixed it. | 
| 这是否一个bug,请确认一下:     // 因为这个包裹的载荷大小不固定,所以先将其在内存缓冲区中构造出来
    tb_buffer_ref_t parcel_buf = tb_malloc0_type(tb_buffer_t);
    tb_buffer_init(parcel_buf);
    tb_stream_ref_t ostream_to_parcel_buf = tb_stream_init_from_buffer(parcel_buf);
    tb_stream_open(ostream_to_parcel_buf);
    logger_print("debug:buffer size1:%d", tb_buffer_size(parcel_buf));   // 输出0
    // 载荷大小此时尚不能确定,先跳过
    // tb_stream_skip(ostream_to_parcel_buf, 4); // 由于tb_stream_skip的内部实现,写位置无法超过缓冲区当前大小
    tb_stream_bwrit_s32_be(ostream_to_parcel_buf, 0); // 只能通过写入无效数据来达到效果
 
    // 继续通过流向缓冲区中写入其他字段
   // 省略若干行
    // 此时载荷大小可以确定了,跳到包裹头部(偏移量:0)写入载荷大小
    logger_print("debug:buffer size5:%d", tb_buffer_size(parcel_buf)); // 输出428
    tb_stream_seek(ostream_to_parcel_buf, 0);
    logger_print("debug:buffer size6:%d", tb_buffer_size(parcel_buf)); // 输出428
    tb_stream_bwrit_s32_be(ostream_to_parcel_buf, 2+4+data_len);  // 这个函数最终会调用tb_stream_buffer_writ
    logger_print("debug:buffer size7:%d", tb_buffer_size(parcel_buf)); // 输出4 (令人意外)
       我看了一下源码 static tb_long_t tb_stream_buffer_writ(tb_stream_ref_t stream, tb_byte_t const* data, tb_size_t size)
{
    tb_stream_buffer_t* stream_buffer = tb_stream_buffer_cast(stream);
    tb_assert_and_check_return_val(stream_buffer && stream_buffer->buffer, -1);
    tb_check_return_val(data, -1);
    tb_check_return_val(size, 0);
    if (size) tb_buffer_memncpyp(stream_buffer->buffer, stream_buffer->head, data, size);  // 注意此处,head为0,size为4
    stream_buffer->head += size;
    return size;
}而tb_buffer_memncpyp调用了tb_buffer_resize,这个函数会把缓冲区缩小 tb_byte_t* tb_buffer_memncpyp(tb_buffer_ref_t buffer, tb_size_t p, tb_byte_t const* b, tb_size_t n)
{
    // check
    tb_assert_and_check_return_val(buffer && b, tb_null);
    // check
    tb_check_return_val(n, tb_buffer_data(buffer));
    // resize
    tb_byte_t* d = tb_buffer_resize(buffer, p + n);  // 注意此处,p为0,n为4
    tb_assert_and_check_return_val(d, tb_null);
    // copy it
    tb_memcpy(d + p, b, n);
    // ok
    return d;
}感觉有点反直觉。 | 
| tb_buffer_memncpyp 是覆盖重写 buffer 所以每次调用,都是会重新计算当前的实际大小 这里得用 tb_buffer_resize + tb_memcpy 来做。你可以提 pr 改进下 | 
| 
 tb_buffer_memncpyp overwrites and rewrites buffer, so every time it is called, the current actual size will be recalculated. You have to use tb_buffer_resize + tb_memcpy to do this. You can submit a PR to improve it |