首先先说一下版本
protoc --version
2.5.0
然后说一下bug是什么,就是在把一个对象序列化成一个ostringstream后,如果再把另一个对象序列化到同一个ostringstream后,会发现第二个对象变成了两个对象。
即使ostringstream.clear() 后一样会有问题
先上协议文件, 标准的example
package lm;
message helloworld
{
required int32 id = 1; // ID
required string str = 2; // str
optional int32 opt = 3; //optional field
repeated int32 value = 4;
}
然后再上测试代码,
#include <iostream>
#include <sstream>
#include <stdio.h>
#include <string.h>
#include "helloworld.pb.h"
using namespace std;
using namespace lm;
using namespace google::protobuf;
int main()
{
helloworld hello;
hello.set_id( 100 );
hello.set_str( "this is a test ");
hello.set_opt( 200 );
for( int i=0; i<100; ++i)
{
hello.add_value( i );
}
ostringstream ss;
hello.SerializeToOstream( &ss );
string data = ss.str();
cout << data.length() << endl;;
cout << data << endl;
ss.flush(); //even flush is not work
ss.clear(); // attention:we have clear the stream
helloworld hello2;
hello2.set_id( 100 );
hello2.set_str( "this is a test ");
hello2.set_opt( 200 );
for( int i=0; i<100; ++i)
{
hello2.add_value( i );
}
hello2.SerializeToOstream( &ss );
string data2 = ss.str();
cout << data2 <<endl;
cout << data2.length() << endl;
return 0;
}
结果是
222
dthis is a test �
! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c
dthis is a test �
! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b dthis is a test �
! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c
444
显然,两个同样的hello对象连在一起了.
我一开始觉得这应该是protobuf的一个bug, 因为按照正常的stream使用标准,在我们clear,flush后,不应该在流中保留已有的东西。
为了验证我的想法,我马上又写了一个小test, 来排除是stringstream的问题。
代码如下,
#include <sstream>
#include <iostream>
#include <string>
using namespace std;
int main()
{
ostringstream ss;
ss.str("haha");
string data = ss.str();
cout << data.length() << endl;
ss.clear();
data = ss.str();
cout << data.length() << endl;
return 0;
}
我以为输出应该是4,0,但是很意外结果是4,4
这说明了,不是protobuf的问题,而是stringstream的问题,在clear,flush之后,并没有清空流。
最后上google搜了一下,为什么stringstream.clear 不起作用。
发现有大把人跟我遇到过一样的问题啊
在clear之前,加一句 ss.str( string() );
即设置一个空的string,通过这种方式来清空流。即,需要同时清空流,以及流中的string
做到这里先告一段落,后续我需要看看stringstream的原码,看看为什么不置空string就达不到清空流的目的!