initial commit

This commit is contained in:
Michael Krayer 2021-02-16 17:35:07 +01:00
commit e724e21f9e
3 changed files with 131 additions and 0 deletions

10
README.md Normal file
View File

@ -0,0 +1,10 @@
patialdump
---
Extracts a given number of bytes from a file at a given offset.
Usage:
```bash
partialdump [-j nbytes] [-N nbytes] file
-j nbytes number of bytes to skip from the beginning of file (default: 0)
-N nbytes number of bytes to read (default: -1, until EOF)
```

2
build Executable file
View File

@ -0,0 +1,2 @@
#!/bin/bash
g++ -o partialdump src/partialdump.cc

119
src/partialdump.cc Normal file
View File

@ -0,0 +1,119 @@
#include <iostream>
#include <algorithm>
#include <fstream>
#include <string>
using namespace std;
const long IO_BUFFSIZE=(long)1024*1024; // read 1 KiB at a time
/*
* Command line parsing routines
* https://stackoverflow.com/questions/865668/parsing-command-line-arguments-in-c
*/
char* getCmdOption(char** begin, char** end, const std::string& option){
char ** itr = std::find(begin, end, option);
if(itr!=end && ++itr!=end)
{
return *itr;
}
return 0;
}
bool cmdOptionExists(char** begin, char** end, const std::string& option){
return std::find(begin,end,option)!=end;
}
void print_usage(char* argv[]){
cerr << "Usage: " << argv[0] << " [-j nbytes] [-N nbytes] file" << endl;
cerr << "Extracts a given number of bytes from a file at a given offset." << endl;
cerr << " -j nbytes number of bytes to skip from the beginning of file (default: 0)" << endl;
cerr << " -N nbytes number of bytes to read (default: -1, until EOF)" << endl;
return;
}
/*
* Main program
*/
int main(int argc,char *argv[]){
int iblock;
char* buffer = new char[IO_BUFFSIZE];
long filesize, iosize;
if(argc==1){
print_usage(argv);
return 0;
}
// We expect the following command line arguments
// -h print help
// -j nbytes skip the first nbytes
// -N nbytes read nbytes
// 1 positional argument: filename
int argc_opt = argc-1;
if(cmdOptionExists(argv,argv+argc,"-h")){
print_usage(argv);
return 0;
}
char* arg_jump = getCmdOption(argv,argv+argc_opt,"-j");
char* arg_size = getCmdOption(argv,argv+argc_opt,"-N");
long ijump=0, isize=-1;
if(arg_jump){
try{
ijump = stol(arg_jump);
}
catch(const invalid_argument& ia){
cerr << "Invalid argument to " << ia.what() << ": " << arg_jump << endl;
return 2;
}
}
if(arg_size){
try{
isize = stol(arg_size);
}
catch(const invalid_argument& ia){
cerr << "Invalid argument to " << ia.what() << ": " << arg_size << endl;
return 2;
}
}
string filename=argv[argc-1];
ifstream file(filename,ios::in|ios::binary);
if(!file){
cerr << "Cannot open file: " << filename << endl;
return 3;
}
// If we are supposed to read until the end of file, determine
// the file size.
if(isize==-1){
file.seekg(0,ios::end);
filesize = (long)file.tellg();
isize = filesize-ijump;
}
// Seek to beginning of partition to read
file.seekg(ijump,ios::beg);
// Read block by block
iblock=0;
bool trunc = false;
while(!trunc){
trunc = (isize-iblock*IO_BUFFSIZE)<IO_BUFFSIZE;
if(trunc)
iosize = isize-iblock*IO_BUFFSIZE;
else
iosize = IO_BUFFSIZE;
file.read(buffer,iosize);
if(file.fail()){
cerr << "I/O Error: " << filename << " @ " << file.tellg() << endl;
break;
}
fwrite(buffer,1,iosize,stdout);
iblock++;
}
fflush(stdout);
file.close();
delete[] buffer;
return 0;
}