Here's my assignment:
Write a program that takes a filename as its only command line argument and prints the results to
std::outformatted as follows:
- The first line of the output should be whether or not the checksum passed ("Checksum passed", "Checksum failed")
- If the checksum passed, the rest of the file will contain the parsed data. Print label value pairs separated by a colon for each field, one per line (all numbers should be represented as decimals).
- An expected output file is provided for the first binary file to demonstrate format.
#File structure (Little Endian):
/*Write a program that takes a filename as its only command line argument and prints the results to std out formatted as follows:
- The first line of the output should be whether or not the checksum passed ("Checksum passed", "Checksum failed")
- If the checksum passed, the rest of the file will contain the parsed data. Print label value pairs separated by a colon for each field, one per line (all numbers should be represented as decimals).
- An expected output file is provided for the first binary file to demonstrate format.
File structure (Little Endian):
size: 4 bytes
entry count: 2 bytes
--- entry ---
first name length: 4 bytes
first name: first name length bytes
last name length: 4 bytes
last name: last name length bytes
flags: 1 byte
* age: 1 byte
* height: 1 byte
-------------
zero padding: x bytes
checksum: 4 bytes
* = optional
Field descriptions:
size: Total number of bytes in the file
entry count: Number of entries in the file
entry:
first name length: Number of characters in the following first name string since it is not NULL terminated
first name: Non-null terminate string
last name length: Number of characters in the following last name string since it is not NULL terminated
last name: Non-null terminate string
flags: Bit mask which indicates presence of either age or height fields. 1: age field present, 2: height field present
age: Age in years. Optional field.
height: Height in inches. Optional field.
zero padding - The file is zero padded to ensure 4 byte alignment.
checksum: This value is calculated by summing every four bytes of the data (not including the actual checksum value) // FileParser.cpp : Defines the entry point for the console application.
*/
* = optional
#Field descriptions:
size: Total number of bytes in the file
entry count: Number of entries in the file
##entry
first name length: Number of characters in the following first name string since it is not NULL terminated
first name: Non-null terminated string
last name length: Number of characters in the following last name string since it is not NULL terminated
last name: Non-null terminated string
flags: Bit mask which indicates presence of either age or height fields.
- age field present
- height field present
age: Age in years. Optional field.
height: Height in inches. Optional field.
zero padding - The file is zero padded to ensure 4 byte alignment.
checksum: This value is calculated by summing every four bytes of the data (not including the actual checksum value)
FileParser.cpp
// FileParser.cpp : Defines the entry point for the console application.
//
#include<iostream>
#include <string>
#include <fstream>
#include <sstream>
void ParseFile(char* dataBuffer);
int main(int argc, char *argv[])
{
std::string inputFileName = argv[1];
std::ifstream inputFile(inputFileName, std::ios::binary | std::ios::ate);
if (inputFile.good())
{
//get File size
std::streamoff size = inputFile.tellg();
char *data = new char[size];
inputFile.seekg(0, std::ios::beg);
inputFile.read(data, size);
inputFile.close();
int checkSum = 0;
for (int i = 4; i <= size - 4; i = i + 4)
{
checkSum += (data[i - 1] << 24) |
(data[i - 2] << 16) |
(data[i - 3] << 8) |
(data[i - 4]);
}
int checksumfromFile = 0;
memcpy(&checksumfromFile, &data[size - 4], sizeof(int));
if (checkSum == checksumfromFile)
{
std::cout << "Checksum passed" << std::endl;
ParseFile(data);
}
else
std::cout << "Checksum Failed" << std::endl;
}
return 0;
}
void ParseFile(char* data)
{
unsigned char sizeinBytes = 4;
unsigned char count = 2;
unsigned char firstNameLength = 4;
unsigned char lastNameLength = 4;
unsigned char flags = 1;
unsigned char age_byte = 1;
unsigned char height_byte = 1;
unsigned char checksum = 4;
int offset = 0;
// size
int size;
memcpy(&size, &data[offset], sizeof(int));
std::cout << "size:" << size << std::endl;
offset += sizeinBytes;
//count of entries
short entryCount;
memcpy(&entryCount, &data[offset], sizeof(short));
std::cout << "entry count::" << entryCount << std::endl;
offset += count;
for (int i = 0; i < entryCount; i++)
{
//firstNameLength
int lengthofFirstName;
memcpy(&lengthofFirstName, &data[offset], sizeof(int));
std::cout << "first name length:" << lengthofFirstName << std::endl;
offset += firstNameLength;
//firstName
char* firstName = new char[lengthofFirstName];
memcpy(firstName, &data[offset], lengthofFirstName);
firstName[lengthofFirstName] = '\0';
std::cout << "first name:" << firstName << std::endl;
offset += lengthofFirstName;
// 4 bytes
int lengthofLastName;
memcpy(&lengthofLastName, &data[offset], sizeof(int));
std::cout << "last name length:" << lengthofLastName << std::endl;
offset += lastNameLength;
char* lastName = new char[lengthofLastName];
memcpy(lastName, &data[offset], lengthofLastName);
lastName[lengthofLastName] = '\0';
std::cout << "last name:" << lastName << std::endl;
offset += lengthofLastName;
char flag = data[offset];
std::cout << "flags:" << (int)flag << std::endl;
offset += flags;
char age;
char height;
if (flag == 3)
{
age = data[offset];
height = data[offset + 1];
offset += age_byte + height_byte;
std::cout << "age:" << (int)age << std::endl;
std::cout << "height:" << (int)height << std::endl;
}
else if (flag == 2)
{
height = data[offset];
offset += height_byte;
std::cout << "height:" << (int)height << std::endl;
}
else if (flag == 1)
{
age = data[offset];
offset += age_byte;
std::cout << "age:" << (int)age << std::endl;
}
}
int checkSum;
memcpy(&checkSum, &data[size - 4], sizeof(int));
std::cout << "checksum:" << checkSum << std::endl;
}