Comment #2 on issue 689 by narayan....@gmail.com: Repeated fields do not serialize the 'size' into the file. Hence deserialize of repeated expects an unending sequence of repeated fields
https://code.google.com/p/protobuf/issues/detail?id=689

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;
    }
}

--------------------------


--
You received this message because this project is configured to send all issue notifications to this address.
You may adjust your notification preferences at:
https://code.google.com/hosting/settings

--
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.
For more options, visit https://groups.google.com/d/optout.

Reply via email to