Hi,

I tried to use protobuf to write a message to a file, and then read it 
back. But it seems that I cannot read the data back because 
ParseFromCodedStream() returns false. Could any one help me to see if I am 
doing something wrong?  Thanks!

I use coded stream to write messages with length prefix like this:

template<class PBMessage>
void writeCompressedMessageWithDelimiter(const PBMessage& msg)
{
writer_->WriteLittleEndian32(msg.ByteSize());
msg.SerializeWithCachedSizes(writer_.get());
}

And to read back the message like this:

template<class PBMessage>
bool readCompressedMessageWithDelimiter(PBMessage *outMsg)
{
using namespace google::protobuf::io;

uint32_t len;
reader_->ReadLittleEndian32(&len);

assert(len);
 // read only len bytes
auto limit = reader_->PushLimit(len);
bool ret = outMsg->ParseFromCodedStream(reader_.get());
reader_->PopLimit(limit);

assert(ret);

return ret;
}


The message is defined as follow:

message DepthFrameProto {
optional int64 time_stamp = 1;

required uint32 rows = 2;
required uint32 cols = 3;

// in millimeter
repeated uint32 depth_map = 4 [packed=true];
repeated uint32 player_id_map = 5 [packed=true];
}



The whole code is as follow:

// PBFileReader.h

#pragma once

#include <string>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <stdint.h>
#include <io.h>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <fcntl.h>
#include <sys/stat.h>

class PBFileReader
{
public:
PBFileReader(void)
{
file_handle_ = -1;
file_start_pos_ = 0;
}
~PBFileReader(void)
{
close();
}
 bool open(const std::string& fileName)
{
close();

file_handle_ = ::_open(fileName.c_str(), _O_RDONLY);

if(file_handle_ < 0)
{
return false;
}

file_start_pos_ = 0;

setReader();

return true;
}

bool isOpened() const
{
return file_handle_ >= 0;

}
void close()
{
if(isOpened())
{
clearReader();

::close(file_handle_);
file_handle_ = -1;
file_start_pos_ = 0;
}
}

template<class PBMessage>
bool readCompressedMessageWithDelimiter(PBMessage *outMsg)
{
using namespace google::protobuf::io;

uint32_t len;
reader_->ReadLittleEndian32(&len);

assert(len);
 // read only len bytes
auto limit = reader_->PushLimit(len);
bool ret = outMsg->ParseFromCodedStream(reader_.get());
reader_->PopLimit(limit);

assert(ret);

return ret;
}

private:
void clearReader()
{
reader_.reset();
raw_input_.reset();
}
void setReader()
{
using namespace google::protobuf::io;
raw_input_.reset(new FileInputStream(file_handle_));
reader_.reset(new CodedInputStream(raw_input_.get()));
}

private:
boost::shared_ptr<google::protobuf::io::CodedInputStream> reader_;
boost::shared_ptr<google::protobuf::io::FileInputStream> raw_input_;

int file_handle_;

int64_t file_start_pos_;
};

class PBFileWriter
{
public:
PBFileWriter()
{
file_handle_ = -1;
real_pos_ = 0;
}
~PBFileWriter()
{
close();
}

bool open(const std::string& fileName)
{
close();

file_handle_ = ::_open(fileName.c_str(), O_CREAT | O_WRONLY | O_TRUNC, 
_S_IREAD | _S_IWRITE );

if(file_handle_ < 0)
{
return false;
}

real_pos_ = 0;

setCodedStream();

return true;
}

bool isOpened() const
{
return file_handle_ >= 0;
}

void close()
{
if(isOpened())
{
clearCodedStream();

::close(file_handle_);
file_handle_ = -1;

real_pos_ = 0;
}
}

template<class PBMessage>
void writeCompressedMessageWithDelimiter(const PBMessage& msg)
{
writer_->WriteLittleEndian32(msg.ByteSize());

msg.SerializeWithCachedSizes(writer_.get());
}

private:
void setCodedStream()
{
using namespace google::protobuf::io;

file_output_.reset(new FileOutputStream(file_handle_));
writer_.reset(new CodedOutputStream(file_output_.get()));
}

void clearCodedStream()
{
writer_.reset();
file_output_.reset();
}

private:
int file_handle_;

boost::shared_ptr<google::protobuf::io::FileOutputStream> file_output_;
boost::shared_ptr<google::protobuf::io::CodedOutputStream> writer_;

int64_t real_pos_;
};

// TestMain.cpp

#include "PBFileReader.h"
#include "DepthFrame.pb.h"

#include <iostream>

using namespace std;


int _tmain(int argc, _TCHAR* argv[])
{
PBFileWriter writer;
writer.open("testproto_depth_frame.pb");

DepthFrameProto dfp;
dfp.set_rows(320);
dfp.set_cols(240);
dfp.set_time_stamp(34);
// for(int i = 0; i < dfp.rows() * dfp.cols(); i++)
for(int i = 0; i < 26; i++)
{
dfp.add_depth_map(i);
dfp.add_player_id_map(i % 3);
}

writer.writeCompressedMessageWithDelimiter(dfp);

writer.close();

PBFileReader reader;
reader.open("testproto_depth_frame.pb");

DepthFrameProto read_dfp;
reader.readCompressedMessageWithDelimiter(&read_dfp);
reader.close();

assert(dfp.DebugString() == read_dfp.DebugString());

return 0;
}

-- 
You received this message because you are subscribed to the Google Groups 
"Protocol Buffers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to protobuf+unsubscr...@googlegroups.com.
To post to this group, send email to protobuf@googlegroups.com.
Visit this group at http://groups.google.com/group/protobuf?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.


Attachment: TestProtobuf.7z
Description: application/7z-compressed

Reply via email to