Closed GoogleCodeExporter closed 9 years ago
This is by design. Protobuf fields are serialized as <tag, value> pairs. The
parsing routine will check the tag to decide whether a value belongs to a
repeated field and act accordingly. There could be a potentially infinite
number of such <tag, value> pairs in an input stream, but in practice, the size
of a message is usually already known before parsing. For example, when you
send a protobuf message over the wire, you'll first send the size of the data
before serialized bytes of the message.
Original comment by xiaof...@google.com
on 10 Mar 2015 at 9:10
Thank you for the response. This is what I am doing - i.e., adding the size
before sending the protobuf on the wire (file descriptor of a file or socket) -
then serializing-to-array and parsing-from-array.
Since there are many protobuf message structures like this in my college
project, I ended up writing a template methods as follows (where T is the type
of the protobuf object and My::Size itself is another protobuf object with a
single int64 field in it, named size).
The request here is : Can we do something better?
---------------------
The template function:
---------------------
namespace My
{
///
/// @brief
/// Handy template to read a protobuf message object
/// along with its byte size from a file descriptor.
///
/// @param[out] rObj
/// Reference to the protobuf object.
///
/// @param[in] iFd
/// The file descriptor.
///
template <class T> void ReadProtobufWithSizeFromFileDescriptor(T &rObj, int iFd)
{
My::Size objSize;
objSize.set_size(0);
char *pByteArray = new char[objSize.ByteSize()];
if (!pByteArray)
{
ERRORprintf("Unable allocate memory.");
MY_THROW("Allocate Error.");
}
int iResult = read(iFd, pByteArray, objSize.ByteSize());
if (iResult < objSize.ByteSize())
{
ERRORprintf("Unable to read from file.");
delete [] pByteArray;
MY_THROW("File Read Error.");
}
// Get the object size first.
bool bResult = objSize.ParseFromArray(pByteArray, objSize.ByteSize());
if (!bResult)
{
ERRORprintf("Unable to read from file.");
MY_THROW("File Read Error.");
}
delete [] pByteArray;
pByteArray = new char[objSize.size()];
if (!pByteArray)
{
ERRORprintf("Unable allocate memory.");
MY_THROW("Allocate Error.");
}
iResult = read(iFd, pByteArray, objSize.size());
if (iResult < objSize.size())
{
ERRORprintf("Unable to read from file.");
delete [] pByteArray;
MY_THROW("File Read Error.");
}
bResult = rObj.ParseFromArray(pByteArray, objSize.size());
if (!bResult)
{
ERRORprintf("Unable to read from file.");
delete [] pByteArray;
MY_THROW("File Read Error.");
}
delete [] pByteArray;
}
///
/// @brief
/// Handy template to read a protobuf message object
/// along with its byte size from a file descriptor.
///
/// @param[out] rObj
/// Reference to the protobuf object.
///
/// @param[in] iFd
/// The file descriptor.
///
template <class T> void WriteProtobufWithSizeToFileDescriptor(T &rObj, int iFd)
{
My::Size objSize;
objSize.set_size(rObj.ByteSize());
char *pByteArray = new char[objSize.ByteSize()];
if (!pByteArray)
{
ERRORprintf("Unable allocate memory.");
MY_THROW("Allocate Error.");
}
// Write the object size first.
bool bResult = objSize.SerializeToArray(pByteArray, objSize.ByteSize());
if (!bResult)
{
ERRORprintf("Unable to write to file.");
MY_THROW("File Write Error.");
}
int iResult = write(iFd, pByteArray, objSize.ByteSize());
if (iResult < objSize.ByteSize())
{
ERRORprintf("Unable to write to file.");
delete [] pByteArray;
MY_THROW("File Write Error.");
}
delete [] pByteArray;
pByteArray = new char[objSize.size()];
if (!pByteArray)
{
ERRORprintf("Unable allocate memory.");
MY_THROW("Allocate Error.");
}
bResult = rObj.SerializeToArray(pByteArray, objSize.size());
if (!bResult)
{
ERRORprintf("Unable to write to file.");
delete [] pByteArray;
MY_THROW("File Write Error.");
}
iResult = write(iFd, pByteArray, objSize.size());
if (iResult < objSize.size())
{
ERRORprintf("Unable to write to file.");
delete [] pByteArray;
MY_THROW("File Write Error.");
}
delete [] pByteArray;
}
}
--------------------------
Original comment by narayan....@gmail.com
on 11 Mar 2015 at 1:33
It sounds like you're looking for the Message.writeDelimitedTo and
Message.parseDelimitedFrom functions. Those are available in Java, but not in
C++ (see issue 472).
Original comment by dwahler@gmail.com
on 11 Mar 2015 at 11:43
Looks likeit.
Original comment by narayan....@gmail.com
on 12 Mar 2015 at 1:18
Original issue reported on code.google.com by
narayan....@gmail.com
on 18 Feb 2015 at 3:12