/******************************************************************************
 *  This program writes 1+2^k+2^22 for k=0...9 to a binary file. It then
 *  reads the values back using an 'unsigned' variable, displaying the results 
 *  in binary. Next, it reads the values in 'char' sized pieces, showing that 
 *  the 'unsigned' values were actually stored from least significant byte to
 *  most significant byte.
 * **************************************************************************/

#include<iostream>
#include<cstdlib>
#include<fstream>
#include<iomanip>
using namespace std;

void displayBytes(unsigned value) /* Display the binary representation for
				     an 'unsigned' value.
				   */
{
	int SHIFT=sizeof(unsigned)*8-1;
	unsigned MASK=1<<SHIFT;/* Create an 'unsigned' with a 1 in the most 
				  significant bit and 0's elsewhere.
				  */
	for(int i=0; i!=SHIFT+1; i++)
	{
		if(i%8==0)
			cout<<" ";
		cout<<(value & MASK?'1':'0');
		value<<=1;/* Move the next bit in 'value' to line up with 
			     the 1 in MASK.
			     */
	}
	cout<<endl;
}

void displayBytes(char value) /* Display the binary representation for 
				 a 'char' value.
				 */
{
	int SHIFT=sizeof(char)*8-1;
	unsigned MASK=1<<SHIFT;
	for(int i=0; i!=SHIFT+1; i++)
	{
		cout<<(value & MASK?'1':'0');
		value<<=1;
	}
	cout<<" ";
}
int main()
{
	
	unsigned x, y;
	char aByte;
	ofstream outFile("myBits.txt", ios::binary);
	if(!outFile)
	{
		cout<<"\nUnable to open myBits.txt.";
		exit(1);
	}
/** Load 'unsigned' values with binary representations that have a 1 in the 
 ** 23rd bit, and otherwise the bits for  2^k+1 for k=0 to 9.
 **/ 
	for(x=1;x<1024;x*=2)
	{
		y=x+1+4194304;
		outFile.write(reinterpret_cast<const char *>(&y),sizeof(unsigned));
	}
	outFile.close();

	ifstream inFile("myBits.txt", ios::binary);
	if(!inFile)
	{
		cout<<"\nUnable to open myBits.txt.";
		exit(1);
	}
	
/** Read the file back in binary, using 'unsigned'-sized pieces. **/	
	inFile.read(reinterpret_cast<char *>(&x),sizeof(unsigned));
	while(inFile && !inFile.eof())
	{
	displayBytes(x);
	inFile.read(reinterpret_cast<char *>(&x),sizeof(unsigned));
	}
	cout<<endl;
	inFile.clear();
	inFile.seekg(0);
	
/** Read the file back in binary, using 'char'-sized pieces. **/
	inFile.read(reinterpret_cast<char *>(&aByte),sizeof(char));
	int counter=0;
	while(inFile && !inFile.eof())
	{
	displayBytes(aByte);
	counter++;
	if(counter%4==0)
		cout<<endl;
	inFile.read(reinterpret_cast<char *>(&aByte),sizeof(char));
	}
	inFile.close();
		
	return 0;
}
