Having tried your example code I also get 'readsome' returning zero. That's with BCB5 (Rogue Wave's STL). However, reading the whole file into a char array works fine with crc::process_bytes. Really I only needed an example of handling the crc part. The file IO part I can do in many different ways. I really know nothing of CRC, only that it's useful and complicated in equal measure. Thanks for creating the library and for donating it to boost! Alex
-----Original Message----- From: Daryle Walker [mailto:darylew@mac.com] Sent: 11 June 2003 02:24 To: Boost-Users@yahoogroups.com Subject: [Boost-Users] Re: [crc] Simple example please
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
#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
Info: http://www.boost.org Wiki: http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl Unsubscribe: mailto:boost-users-unsubscribe@yahoogroups.com
Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/