Boost logo

Boost Users :

From: Daryle Walker (darylew_at_[hidden])
Date: 2003-06-10 20:24:01


On Tuesday, June 10, 2003, at 9:08 AM, Vladimir Prus wrote:

[SNIP]
> Here's the function that I use for the same purpose. Might not be
> optimal, but works:
>
> unsigned file_crc(const string& name)
> {
> #if defined(__GNUC__) && __GNUC__ < 3
> ifstream ifs(name.c_str(), ios::binary);
> #else
> ifstream ifs(name.c_str(), ios_base::binary);
> #endif
> if (!ifs)
> return 0;
> else {
> using namespace boost;
>
> crc_32_type crc32;
> int c;
> while( (c = ifs.rdbuf()->sbumpc()) != -1)
> crc32.process_byte(char(c));
> return crc32.checksum();
> }
> }
>
>
> I believe some example of this kind should be included... Daryle, what
> do you think?

I'll consider it.

[A few hours pass...]

How about something like this:

//================================================================
#include <cstdlib>
#include <exception>
#include <fstream>
#include <ios>
#include <iostream>
#include <ostream>

#include <boost/crc.hpp>

#ifndef BLOCK_SIZE
#define BLOCK_SIZE 1024
#endif

int
main
(
     int argc,
     char const * argv[]
)
try
{
     boost::crc_32_type result;

     // Loop over each file argument
     for ( int i = 1 ; i < argc ; ++i )
     {
         std::ifstream ifs( argv[i], std::ios_base::binary );
         if ( ifs/*std::ifstream ifs(argv[i],
                 std::ios_base::binary)*/ )
         {
             /*char buffer[ BLOCK_SIZE ];
             std::streamsize len;

             while ( 0 < (len = ifs.readsome( buffer, BLOCK_SIZE )) )
             {
                 result.process_bytes( buffer, len );
             }*/
             char c;
             while ( ifs.get(c) )
             {
                 result.process_byte( c );
             }
         }
         else
         {
             std::cerr << "Failed to open file '" << argv[i]
                         << "'." << std::endl;
         }
     }

     std::cout << std::hex << result.checksum() << std::endl;
     return EXIT_SUCCESS;
}
catch ( std::exception &e )
{
     std::cerr << "Found an exception with '" << e.what()
         << "'." << std::endl;
     return EXIT_FAILURE;
}
catch ( ... )
{
     std::cerr << "Found an unknown exception." << std::endl;
     return EXIT_FAILURE;
}
//================================================================

Note in the "if" statement, I had the construction in it. However,
neither one of my compilers took it! Moving the constructor call
worked, but I thought my original method should be accepted.

One compiler finished after the above 'fix'. The other (a variant of
GCC 3.1) complained about missing symbols at link-time; it could not
create the global objects hidden in Boost.CRC. (I haven't worked on
the code in a long time; there could be quirks on compilers written
after Boost.CRC.)

When I ran the program under the compiler that worked, the "readsome"
function always returned zero! There were no suitable substitutes; the
"read" function doesn't tell you how many characters it read (bad if
the last block isn't full) and the multi-character "get" functions use
delimiters. So this program is stuck at single-character reads at the
moment. Maybe I should switch to the stream-buffer method you used.

Can you try this out to make sure the problems aren't just mine?

Daryle


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net