#include <iostream>
#include <fstream>
#include <cstring>
#include <string>
int str2num(const char* str) {
int num = 0;
for (int i = 0; str[i] != '\0'; ++i) {
num = num * 10 + str[i] - '0';
}
return num;
}
std::string num2str(int num) {
std::string str;
if (num == 0) {
str = "0";
} else {
while (num > 0) {
str += num % 10 + '0';
num /= 10;
}
}
while (str.size() < 2) {
str += '0';
}
for (int i = 0; i < (int)str.size()/2; ++i) {
std::swap(str[i], str[(int)str.size()-1-i]);
}
return str;
}
void getFileName(const std::string& path, std::string& fileName) {
int pos = (int)path.size() - 1;
for (; pos >= 0; --pos) {
if (path[pos] == '/') {
break;
}
}
fileName = path.substr(pos+1);
}
void formatDirPath(std::string& dirPath) {
if (!dirPath.empty() || dirPath.back() != '/') {
dirPath += '/';
}
}
int getFileSize(std::ifstream& fin) {
fin.seekg(0, fin.end);
int fileSize = fin.tellg();
fin.seekg(0);
return fileSize;
}
void readBinFile(const std::string& path, int& bufferSize, char*& buffer) {
std::ifstream fin(path, std::ios::binary);
if (!fin.is_open()) {
std::cout << "Cannot open " << path << '\n';
return;
}
bufferSize = getFileSize(fin);
buffer = new char[bufferSize];
fin.read(buffer, bufferSize);
fin.close();
}
void writeBinFile(const std::string& path, int bufferSize, int start, int maxchar, char* buffer) {
std::ofstream fout(path, std::ios::binary);
if (!fout.is_open()) {
std::cout << "Cannot open " << path << '\n';
return;
}
fout.write(buffer+start, std::min(maxchar, bufferSize - start));
fout.close();
}
int main(int argc, char** argv) {
std::string filePath;
std::string outDir;
int numPart = -1;
int sizePart = -1;
const int numArg = 7;
if (argc != numArg) {
std::cout << "Invalid arguments\n";
return 0;
} else {
for (int i = 1; i < numArg; i+=2) {
if (strcmp(argv[i], "-s") == 0) {
filePath = argv[i+1];
} else if (strcmp(argv[i], "-d") == 0) {
outDir = argv[i+1];
} else if (strcmp(argv[i], "-numpart") == 0) {
numPart = str2num(argv[i+1]);
} else if (strcmp(argv[i], "-sizeapart") == 0) {
sizePart = str2num(argv[i+1]);
}
}
if (filePath.empty()) {
std::cout << "Source file not found in arguments!\n";
return 0;
}
if (outDir.empty()) {
std::cout << "Destination not found in arguments!\n";
return 0;
}
if (numPart == -1 && sizePart == -1) {
std::cout << "numpart and sizeapart not found in arguments!\n";
return 0;
}
}
std::ifstream fin(filePath, std::ios::binary);
if (!fin.is_open()) {
std::cout << "Cannot open " << filePath << '\n';
return 0;
}
if (numPart == -1) {
numPart = (getFileSize(fin) + sizePart - 1) / sizePart;
} else {
sizePart = (getFileSize(fin) + numPart - 1) / numPart;
}
fin.close();
std::string fileName;
getFileName(filePath, fileName);
formatDirPath(outDir);
int bufferSize;
char* buffer = nullptr;
readBinFile(filePath, bufferSize, buffer);
for (int i = 1; i <= numPart; ++i) {
std::string outPath = outDir + fileName + ".part" + num2str(i);
writeBinFile(outPath, bufferSize, sizePart * (i-1), sizePart, buffer);
}
delete[] buffer;
return 0;
}