Question: Start with the 1 2 - bit I / O class ofstream 1 2 and implement the matching input class ifstream 1 2 satisfying the

Start with the 12-bit I/O class ofstream12 and implement the matching input class ifstream12 satisfying the following specification:
#pragma once
#include // std::byte
#include
#include
class ifstream12
{
private:
std::ifstream fIStream;
std::byte* fBuffer; // input buffer
size_t fBufferSize; // input buffer size
size_t fByteCount; // available input bytes
size_t fByteIndex; // current byte index
int fBitIndex; // current bit index (can be negative)
void reset(); // reset buffer
void fetch_data(); // read data, std::optional readBit(); // read next bit
public:
// using C++11's nullptr
ifstream12( const char* aFileName = nullptr, size_t aBufferSize =128); //
~ifstream12(); //
void open( const char* aFileName ); //
void close(); //
bool isOpen() const; //[ mark] bool good() const; //[ marks] bool eof() const; //
ifstream12& operator>>( size_t& aValue ); //
};
The class ifstream12 defines an object adapter for std::ifstream. The corresponding file input stream has to be binary and the data would constitute strings of 0s and 1s. We need to use a physical 8-bit stream to read 12-bit values and we have to employ a buffering mechanism to first collect the bits from the underlying 8-bit input stream and then construct 12-bit values from the bits in the buffer.
Class ifstream12 requires a constructor and a destructor. The constructor has to initialize the object, acquire the necessary buffer memory, and open the input file. The destructor has to close the underlying file and free the buffer memory.
The methods open, close, isOpen, good, and eof correspond to their respective
std::ifstream methods. You should study the features of std::ifstream carefully.
The member function eof returns true, if there are no bytes left in the input stream (i.e., fByteCount ==0). Please note that fByteCount should be 0, if you have never read anything from fIStream. There is a subtle handshake between std::ifstream, ifstream12, and clients of ifstream12 when it comes to the detection of end-of-file. The object adapter ifstream12 has to return true for EOF, if and only if there are no further bits available. A boundary scenario allows the underlying std::ifstream object to be in state EOF while the object adapter ifstream12 is not.
The function readBit implements the mapping process. It returns an optional value 0 or 1. The return type std::optional signifies that readBit can reach EOF while reading the next bit.
The base type of fBuffer is std::byte. Unfortunately, type std::byte offers only a limit set of operations that focus on bit manipulations and make it somewhat difficult to interpret std::byte values as plain integers. For the conversion of bit patterns to a single value, we can use the following declaration:
std::byte lByte = fBuffer[fBufferIndex] & (std::byte{1}<< fBitIndex);
The value of lByte is a bit-mask for the bit at index fBitIndex. It is either 1 or 0. The value lByte is still of type std::byte. You need to apply a type conversion to size_t to interpret the value as integer using the following expression:
std::to_integer(lByte).
If the resulting value is greater than zero, then it denotes the bit 1. Otherwise, it means the bit 0.
The function readBit also triggers fetch_data, if necessary. More precisely, at the start, you must check if fByteCount is 0. In this case, fetch_data must be called (the buffer does not contain any data). You may reach EOF here. In this case, readBit has no value to return.
When fetching the next bit (using the expressions shown above), store the result temporarily, and then advance the indices fByteIndex and fBitIndex to the next position (some additional logic is required that you must devise to make it work). If fBitIndex (which runs from highest to lowest) becomes negative, then you need to switch to the next byte in the buffer. This also means that you have processed a byte. Hence, you need to decrement fByteCount. Once all indices have been properly adjusted, you return the result.
The operator>> implements the read12Bits algorithm as shown in the tutorial. You need to adjust it to incorporate std::optional values. That is, readBit may return no value (when EOF has been reached). In this case, you need to break from the for-loop. In addition. You may need to use a static cast to size_t to set the corresponding bit in the
Writing data. Write 4096 codes Reading data.
Read 4096 codes Done
Files to be used and cant be modified:
//main.cpp
#include "ofstream12.h"
#include "ifstream12.h"
#include
#include
static bool write4096()
{
std::cout << "Write 4096 codes" << std::endl;
ofstream12 lWriter( "sample.lzw");
if (!lWriter.good())
{
std::cerr << "Error: Unable to open output file!" << std::endl;
return false;
}
for ( size_t i =4096; i >0; )
{
lWriter <<--i;
}
return true;

Step by Step Solution

There are 3 Steps involved in it

1 Expert Approved Answer
Step: 1 Unlock blur-text-image
Question Has Been Solved by an Expert!

Get step-by-step solutions from verified subject matter experts

Step: 2 Unlock
Step: 3 Unlock

Students Have Also Explored These Related Programming Questions!