public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Strange Behavior
@ 2007-03-08 20:10 Eric Lemings
  2007-03-08 20:48 ` John Love-Jensen
  0 siblings, 1 reply; 2+ messages in thread
From: Eric Lemings @ 2007-03-08 20:10 UTC (permalink / raw)
  To: gcc-help

 
Greetings,

While writing a generic C++ algoririthm for base64 encoding, I came
across some very strange behavior. If you take the following program
(admittedly verbose for debugging purposes) and test it on some data,
say the logo image from www.google.com, you may notice (depending on
your platform) that the byte at offset 0230 (octal) is either read in
with an incorrect value or is skipped entirely.

	template < class InputItor, class OutputItor >
	OutputItor
	encode (InputItor first, InputItor last,
	        OutputItor out) {
	
	  static const char s [] =
	      "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	      "abcdefghijklmnopqrstuvwxyz"
	      "0123456789+/";
	
	  while (first != last) {
	    unsigned char uc0 = *first++;
	    int i0 = (uc0>>2) & 0x3f;
	    char c0 = s [i0];
	    *out++ = c0;
	
	    unsigned char uc1 = (first == last? 0: *first++);
	    int i1 = ((uc0<<4) + (uc1>>4)) & 0x3f;
	    char c1 = s [i1];
	    *out++ = c1;
	
	    bool eof = (first == last);
	    unsigned char uc2 = (eof? 0: *first++);
	    int i2 = ((uc1<<2) + (uc2>>6)) & 0x3f;
	    char c2 = (eof? '=': s [i2]);
	    *out++ = c2;
	
	    int i3 = uc2 & 0x3f;
	    char c3 = (first == last? '=': s [i3]);
	    *out++ = c3;
	  }
	
	  return out;
	}
	
	#include <algorithm>
	#include <fstream>
	#include <iterator>
	#include <iostream>
	#include <string>
	using namespace std;
	
	extern int
	main () {
	  ifstream in ("logo.gif", ios_base::binary);
	
	  istream_iterator< char > first (in);
	  istream_iterator< char > last;
	  string s;
	  encode (first, last, back_inserter (s));
	
	  cout << s;
	
	  return 0;
	}

You can boil the while loop down to it's basic read operations and still
see the same results.

	  while (first != last) {
	    unsigned char uc0 = *first++;
	    unsigned char uc1 = (first == last? 0: *first++);
	    unsigned char uc2 = (first == last? 0: *first++);
	  }

Just for sake of sanity, I wrote a quick version of the algorithm in C.
Naturally, this program behaves as it should.

	#include <stdio.h>
	#include <stdlib.h>
	
	extern int
	main (int argc, char* argv []) {
	
	  FILE* in = fopen ("logo.gif", "rb");
	  if (in == NULL) {
	    perror (argv[0]);
	    exit (EXIT_FAILURE);
	  }
	
	  const char s [] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	                    "abcdefghijklmnopqrstuvwxyz"
	                    "0123456789+/";
	
	  while (!feof (in)) {
	    unsigned char uc0 = fgetc (in);
	    int i0 = (uc0>>2) & 0x3f;
	    char c0 = s [i0];
	    putc (c0, stdout);
	
	    unsigned char uc1 = (feof (in)? 0: fgetc (in));
	    int i1 = ((uc0<<4) + (uc1>>4)) & 0x3f;
	    char c1 = s [i1];
	    putc (c1, stdout);
	
	    int eof = feof (in);
	    unsigned char uc2 = (eof? 0: fgetc (in));
	    int i2 = ((uc1<<2) + (uc2>>6)) & 0x3f;
	    char c2 = (eof? '=': s [i2]);
	    putc (c2, stdout);
	
	    int i3 = uc2 & 0x3f;
	    char c3 = (feof (in)? '=': s [i3]);
	    putc (c3, stdout);
	  }
	
	  fclose (in);
	
	  return 0;
	}

If anyone can shed some light on the strange behavior in the C++
program,
I would appreciate it very much.

Thanks,
Eric.

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Strange Behavior
  2007-03-08 20:10 Strange Behavior Eric Lemings
@ 2007-03-08 20:48 ` John Love-Jensen
  0 siblings, 0 replies; 2+ messages in thread
From: John Love-Jensen @ 2007-03-08 20:48 UTC (permalink / raw)
  To: Eric Lemings, MSX to GCC

Hi Eric,

The istream_iterator uses >> operator.

You have the std::ios_base::skipws flag set in your ifstream named 'in'
(since the ios_base::skipws is set by default, and you haven't cleared it).

Add a line to your main() to clear the skipws flag:
ifstream in ("logo.gif", ios_base::binary);:
in.unsetf(ios_base::skipws); // <-- Add this line.

The results still differ between your C++ and your C version.

I'm not sure if the bug in your C++ or C version, though.

HTH,
--Eljay

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2007-03-08 20:10 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-03-08 20:10 Strange Behavior Eric Lemings
2007-03-08 20:48 ` John Love-Jensen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).