/** \brief Returns a human-readable string representation of the entry. * * This function transforms the basic information of the entry in a * string. Note that most of the information is lost as the function * is likely to only display the filename and the size of the file, * nothing more. * * \return A human-readable string representation of the entry. */ std::string FileEntry::toString() const { OutputStringStream sout; sout << m_filename; if(isDirectory()) { sout << " (directory)"; } else { sout << " (" << m_uncompressed_size << " byte" << (m_uncompressed_size == 1 ? "" : "s"); size_t const compressed_size(getCompressedSize()); if(compressed_size != m_uncompressed_size) { // this is not currently accessible since only the // ZipLocalEntry and ZipCentralDirectoryEntry have // a compressed size sout << ", " // LCOV_EXCL_LINE << compressed_size << " byte" // LCOV_EXCL_LINE << (compressed_size == 1 ? "" : "s") // LCOV_EXCL_LINE << " compressed"; // LCOV_EXCL_LINE } sout << ")"; } return sout.str(); }
int InflateInputStreambuf::underflow() { // If not underflow don't fill buffer if ( gptr() < egptr() ) return static_cast< unsigned char >( *gptr() ) ; // Prepare _outvec and get array pointers _zs.avail_out = _outvecsize ; _zs.next_out = reinterpret_cast< unsigned char * >( &( _outvec[ 0 ] ) ) ; // Inflate until _outvec is full // eof (or I/O prob) on _inbuf will break out of loop too. int err = Z_OK ; while ( _zs.avail_out > 0 && err == Z_OK ) { if ( _zs.avail_in == 0 ) { // fill _invec int bc = static_cast< int >( _inbuf->sgetn( &(_invec[ 0 ] ) , _invecsize ) ) ; // FIXME: handle i/o problems. _zs.next_in = reinterpret_cast< unsigned char * >( &( _invec[0] ) ) ; _zs.avail_in = bc ; // If we could not read any new data (bc == 0) and inflate isn't // done it will return Z_BUF_ERROR and thus breaks out of the // loop. This means we don't have to respond to the situation // where we can't read more bytes here. } err = inflate( &_zs, Z_NO_FLUSH ) ; } // Normally the number of inflated bytes will be the // full length of the output buffer, but if we can't read // more input from the _inbuf streambuf, we end up with // less. int inflated_bytes = _outvecsize - _zs.avail_out ; setg( &( _outvec[ 0 ] ), &( _outvec[ 0 ] ), &( _outvec[ 0 ] ) + inflated_bytes ) ; // FIXME: look at the error returned from inflate here, if there is // some way to report it to the InflateInputStreambuf user. // Until I find out I'll just print a warning to stdout. if( err != Z_OK && err != Z_STREAM_END ) { #if defined (HAVE_STD_IOSTREAM) && defined (USE_STD_IOSTREAM) // Throw an exception to make istream set badbit OutputStringStream msgs ; msgs << "InflateInputStreambuf: inflate failed" ; #ifdef HAVE_ZERROR msgs << ": " << zError( err ) ; #endif throw IOException( msgs.str() ) ; #endif // If HAVE_STD_IOSTREAM not defined we just return eof // if no output is produced, and that happens anyway } if (inflated_bytes > 0 ) return static_cast< unsigned char >( *gptr() ) ; else return EOF ; // traits_type::eof() ; }
inline String print( ArgP&&... args ) { OutputStringStream stream; // Ensure stream does not flush after every output operation stream.flags(stream.flags() & ~ios::unitbuf); write<format>( stream, std::forward<ArgP>(args)... ); return stream.str(); }
/** \brief Clean up the InflateInputStreambuf object. * * The destructor makes sure all allocated resources get cleaned up. */ InflateInputStreambuf::~InflateInputStreambuf() { // Dealloc z_stream stuff int const err(inflateEnd(&m_zs)); if(err != Z_OK) { // in a destructor we cannot throw... OutputStringStream msgs; // LCOV_EXCL_LINE msgs << "InflateInputStreambuf::~InflateInputStreambuf(): inflateEnd() failed" // LCOV_EXCL_LINE << ": " << zError(err); // LCOV_EXCL_LINE /** \TODO * Write an error callback interface and call that instead of * using std::cerr... */ std::cerr << msgs.str() << std::endl; // LCOV_EXCL_LINE } }
TEST(Document, AcceptWriter) { Document doc; doc.Parse(" { \"hello\" : \"world\", \"t\" : true , \"f\" : false, \"n\": null, \"i\":123, \"pi\": 3.1416, \"a\":[1, 2, 3, 4] } "); OutputStringStream os; Writer<OutputStringStream> writer(os); doc.Accept(writer); EXPECT_EQ("{\"hello\":\"world\",\"t\":true,\"f\":false,\"n\":null,\"i\":123,\"pi\":3.1416,\"a\":[1,2,3,4]}", os.str()); }
/** \brief Called when more data is required. * * The function ensures that at least one byte is available * in the input area by updating the pointers to the input area * and reading more data in from the input sequence if required. * * This function actually passes the data through the zlib library * to decompress it. * * \return The value of that character on success or * std::streambuf::traits_type::eof() on failure. */ std::streambuf::int_type InflateInputStreambuf::underflow() { // If not really underflow do not fill buffer // (is that really possible?!) if(gptr() < egptr()) { return traits_type::to_int_type(*gptr()); // LCOV_EXCL_LINE } // Prepare _outvec and get array pointers m_zs.avail_out = getBufferSize(); m_zs.next_out = reinterpret_cast<unsigned char *>(&m_outvec[0]); // Inflate until _outvec is full // eof (or I/O prob) on _inbuf will break out of loop too. int err(Z_OK); while(m_zs.avail_out > 0 && err == Z_OK) { if(m_zs.avail_in == 0) { // fill m_invec std::streamsize const bc(m_inbuf->sgetn(&m_invec[0], getBufferSize())); /** \FIXME * Add I/O error handling while inflating data from a file. */ m_zs.next_in = reinterpret_cast<unsigned char *>(&m_invec[0]); m_zs.avail_in = bc; // If we could not read any new data (bc == 0) and inflate is not // done it will return Z_BUF_ERROR and thus breaks out of the // loop. This means we do not have to respond to the situation // where we cannot read more bytes here. } err = inflate(&m_zs, Z_NO_FLUSH); } // Normally the number of inflated bytes will be the // full length of the output buffer, but if we can't read // more input from the _inbuf streambuf, we end up with // less. offset_t const inflated_bytes = getBufferSize() - m_zs.avail_out; setg(&m_outvec[0], &m_outvec[0], &m_outvec[0] + inflated_bytes); /** \FIXME * Look at the error returned from inflate here, if there is * some way to report it to the InflateInputStreambuf user. * Until I find out I'll just print a warning to stdout. * This at least throws, we probably want to create a log * mechanism that the end user can connect to with a callback. */ if(err != Z_OK && err != Z_STREAM_END) { OutputStringStream msgs; msgs << "InflateInputStreambuf::underflow(): inflate failed" << ": " << zError(err); // Throw an exception to immediately exit to the read() or similar // function and make istream set badbit throw IOException(msgs.str()); } if(inflated_bytes > 0) { return traits_type::to_int_type(*gptr()); } return traits_type::eof(); }
string BasicEntry::toString() const { OutputStringStream sout ; sout << _filename << " (" << _size << " bytes)" ; return sout.str() ; }