Strange Behavior

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



 
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.


[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux