/** * Copyright (C) 2017-2018, U.S. Government */ #include #include #include #include #include #include #include #include #include #include #include #include #include using std::hex; using std::ifstream; using std::ios; using std::ofstream; using std::remove; using std::setfill; using std::setw; using std::string; using std::stringstream; using std::vector; using hirs::exception::HirsRuntimeException; namespace hirs { namespace json_utils { string JSONFieldParser::parseJsonStringField(const std::string &jsonObject, const std::string &jsonFieldName) { stringstream regexPatternStream; regexPatternStream << "(?i)\\\"" << jsonFieldName << "\\\"\\s*:\\s*\\\"(.*)\\\""; string value; if (RE2::PartialMatch(jsonObject, regexPatternStream.str(), &value)) { return value; } else { return ""; } } } // namespace json_utils namespace file_utils { /** * Returns whether or not the argument directory exists. * @return True if the directory exists. False, otherwise. */ bool dirExists(const string& path) { struct stat pathinfo; if (stat(path.c_str(), &pathinfo) != 0) { return false; } else { return (pathinfo.st_mode & S_IFDIR) != 0; } } /** * Returns whether or not the argument file name exists and is a * regular file. * @param filename file to check for existence * @return True if the file exists. False, otherwise. */ bool fileExists(const string& filename) { struct stat buffer; if (stat(filename.c_str(), &buffer) != 0) { return false; } else { return S_ISREG(buffer.st_mode); } } string fileToString(const string& filename) { stringstream ss; ifstream t(filename); if (!t.good()) { ss << "Unable to open file: " << filename; throw HirsRuntimeException(ss.str(), "Utils.cpp::file_utils::fileToString"); } ss << t.rdbuf(); t.close(); return ss.str(); } /** * Reads the contents of an entire file into a string. If * the file can't be opened, the default value is returned. * @param filename the name and path of the file to read. * @param defaultVal the value to return if the file can't be * opened. * @return the contents of the specified file as a string. */ string fileToString(const string& filename, const string& defaultVal) { stringstream ss; ifstream t(filename); if (!t.good()) { return defaultVal; } ss << t.rdbuf(); t.close(); return ss.str(); } string getFileAsOneLineOrEmptyString(const string& filename) { return string_utils::trimNewLines(fileToString(filename, "")); } vector search_directory(const string& directory) { DIR *dr; std::vector files; dr = opendir(directory.c_str()); if (dr) { struct dirent *en; while ((en = readdir(dr)) != NULL) { stringstream ss; ss << directory.c_str(); ss << en->d_name; try { files.push_back(fileToString(ss.str())); } catch (HirsRuntimeException& hirsRuntimeException) { std::cout << hirsRuntimeException.what(); } } // close directory closedir(dr); } return files; } /** * Takes a byte string and writes the contents to a file of the given name. * @param bytes string bytes to write * @param filename file name to be written to */ void writeBinaryFile(const string& bytes, const string& filename) { ofstream file(filename, ios::out | ios::binary); if (file.is_open()) { file.write(bytes.c_str(), bytes.size()); file.close(); } else { throw std::invalid_argument("Cannot write to specified file"); } } int getFileSize(const string& filename) { std::ifstream in(filename, std::ifstream::ate | std::ifstream::binary); return in.tellg(); } // copy portion of file to temp file void splitFile(const string& inFilename, const string& outFilename, int startPos, int readSize) { ifstream inStr(inFilename, ifstream::binary); ofstream outStr(outFilename, ofstream::binary); inStr.seekg(startPos); char* fileBlock = new char[readSize]; inStr.read(fileBlock, readSize); outStr.write(fileBlock, readSize); inStr.close(); outStr.close(); delete[] fileBlock; } /** * Returns the filename from the end of a filesystem path * @param path the filesystem path * @return the filename from the path */ string trimFilenameFromPath(const string& path) { auto lastPathSeparatorIndex = path.find_last_of('/'); // Return path if it wasn't actually a path if (lastPathSeparatorIndex == string::npos) { return path; } return path.substr(lastPathSeparatorIndex + 1); } } // namespace file_utils namespace string_utils { string binaryToHex(const string& bin) { stringstream output; for (int i = 0; i < 20; i++) { stringstream str; str << hex << setfill('0') << setw(2) << static_cast(bin[i]); string dig = str.str(); if (dig.length() > 2) { dig = dig.substr(dig.length() - 2, 2); } output << dig; } return output.str(); } bool contains(const string& str, const string& substring) { return str.find(substring) != string::npos; } string longToHex(const uint32_t& value) { stringstream output; output << "0x" << hex << value; return output.str(); } bool isHexString(const string& str) { bool isHexStringFlag = !str.empty(); if (isHexStringFlag) { auto startIndex = str.begin(); if (str.substr(0, 2) == "0x") { startIndex += 2; } isHexStringFlag = std::all_of(startIndex, str.end(), isxdigit); } return isHexStringFlag; } string hexToBytes(const string& hexString) { // if the string has an odd number of chars, return an empty string if (!isHexString(hexString) || hexString.size() % 2 != 0) { return {}; } vector bytes; for (uint32_t i = 0; i < hexString.length(); i += 2) { string byteString = hexString.substr(i, 2); uint8_t byte = static_cast(strtol(byteString.c_str(), nullptr, 16)); bytes.push_back(byte); } return string(bytes.begin(), bytes.end()); } uint32_t hexToLong(const string& hexString) { uint32_t value; stringstream conversionStream; conversionStream << hexString; conversionStream >> hex >> value; return value; } string trimNewLines(string str) { return trimChar(str, '\n'); } string trimQuotes(string str) { return trimChar(str, '\"'); } string trimChar(string str, char targetChar) { str.erase(remove(str.begin(), str.end(), targetChar), str.end()); return str; } string trimWhitespaceFromLeft(string str) { RE2 pattern("^\\s+"); while (RE2::PartialMatch(str, pattern)) { str = str.erase(0, 1); } return str; } string trimWhitespaceFromRight(string str) { RE2 pattern("\\s+$"); while (RE2::PartialMatch(str, pattern)) { str = str.erase(str.length()-1, 1); } return str; } string trimWhitespaceFromBothEnds(string str) { return trimWhitespaceFromRight(trimWhitespaceFromLeft(str)); } } // namespace string_utils } // namespace hirs