Hello, please help with the following problem.
I use CodedOutputStream to write a message's length and message itself to a 
file. 
When I later read from generated file, it turns out that file contains less 
data.

I provide source code for simple test: write 1000 messages to a file and 
then read this file.
Output is the following:
[aagenosov@black build]$ bin/test_coded_stream
written 1000 records, total bytes: 16384
test successfull
total length: 13890, consumed bytes: 13890, messages count: 594

I tried to forcedly flush buffers, but there was no effect.

-- 
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 [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/protobuf.
For more options, visit https://groups.google.com/d/optout.
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <memory>
#include <fcntl.h>
#include <errno.h>

#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>

static const uint32_t records_limit = 1000;

int main()
{
    using namespace google::protobuf::io;
    const char * file_path = "/tmp/coded_stream_test.log";
    {
        int file_handle = open(file_path,
                           O_WRONLY | O_CREAT,
                           S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH
                          );
        if (file_handle == -1)
        {
            std::cerr << "can't create file " << file_path << ", errno: " << errno << std::endl;
            return -1;
        }
        std::auto_ptr<FileOutputStream> file_stream;
        std::auto_ptr<CodedOutputStream> coded_output;
        file_stream.reset(new FileOutputStream(file_handle));
        file_stream->SetCloseOnDelete(true);
        coded_output.reset(new CodedOutputStream(file_stream.get()));
        uint32_t idx = 0;
        for (; idx < records_limit; ++idx)
        {
            std::ostringstream data;
            data << "iteration " << idx;
            const std::string & str = data.str();
            int coded_size = CodedOutputStream::VarintSize32(str.length()) + str.length();
            uint8_t * buffer = coded_output->GetDirectBufferForNBytesAndAdvance(coded_size);
            if (buffer != NULL)
            {
                buffer = CodedOutputStream::WriteVarint32ToArray(str.length(), buffer);
                buffer = CodedOutputStream::WriteRawToArray(str.c_str(), str.length(), buffer);
            }
            else
            {
                coded_output->WriteVarint32(str.length());
                coded_output->WriteString(str);
            }
            if (coded_output->HadError())
            {
                std::cerr << "error on iteration " << idx << std::endl;
                break;
            }
        }
        /*coded_output.reset();
        if (!file_stream->Close())
        {
            std::cerr << "error " << file_stream->GetErrno() << " on close file" << std::endl;
        }*/
        std::cout << "written " << idx << " records, total bytes: " << file_stream->ByteCount() << std::endl;
    }

    std::fstream input_file(file_path, std::ios_base::in | std::ios_base::binary);
    input_file.seekg(0, input_file.end);
    size_t total_length = input_file.tellg();
    input_file.seekg(0, input_file.beg);
    std::auto_ptr<ZeroCopyInputStream> raw_input(new IstreamInputStream(&input_file));
    std::auto_ptr<CodedInputStream> coded_input(new CodedInputStream(raw_input.get()));
    uint32_t message_count = 0;
    int error = 0;
    while (!coded_input->ExpectAtEnd() && static_cast<size_t>(raw_input->ByteCount()) != total_length)
    {
        uint32_t msg_len;
        if (!coded_input->ReadVarint32(&msg_len))
        {
            std::cerr << "failed to get length of next message" << std::endl;
            error = -1;
            break;
        }
            
        CodedInputStream::Limit limit = coded_input->PushLimit(msg_len);
        std::string buf;
        if (!coded_input->ReadString(&buf, msg_len))
        {
            std::cerr << "failed to parse message" << std::endl;
            error = -1;
            break;
        }
        message_count++;
        //std::cout << buf << std::endl;
        coded_input->PopLimit(limit);        
    }
    if (error == 0)
    {
        std::cout << "test successfull" << std::endl;
    }
    std::cout << "total length: " << total_length 
              << ", consumed bytes: " << raw_input->ByteCount()
              << ", messages count: " << message_count
              << std::endl;
    input_file.close();
    return error;
}

Reply via email to