diff --git a/BWXML/BWCommon.cpp b/BWXML/BWCommon.cpp index 33ccd0e..e00f1a5 100644 --- a/BWXML/BWCommon.cpp +++ b/BWXML/BWCommon.cpp @@ -117,5 +117,6 @@ namespace BWPack return rawDataBlock(BW_Blob, B64::Decode(strVal)); } + // fallback return rawDataBlock(BW_String, strVal); }} diff --git a/BWXML/BWCommon.h b/BWXML/BWCommon.h index e104e3e..ac920c5 100644 --- a/BWXML/BWCommon.h +++ b/BWXML/BWCommon.h @@ -21,6 +21,10 @@ limitations under the License. namespace BWPack { + static const int BW_MATRIX_NROWS = 4; + static const int BW_MATRIX_NCOLS = 3; + static const int BW_MATRIX_SIZE = BW_MATRIX_NROWS * BW_MATRIX_NCOLS; + struct rawDataBlock { BigWorld::PackedDataType type; @@ -33,7 +37,8 @@ namespace BWPack { short stringId; rawDataBlock data; - dataBlock(const short _stringId, rawDataBlock& _data) : stringId(_stringId), data(_data) {}; + dataBlock(const short _stringId, rawDataBlock& _data) + : stringId(_stringId), data(_data) {}; }; rawDataBlock PackBuffer(const std::string& strVal); diff --git a/BWXML/BWReader.cpp b/BWXML/BWReader.cpp index 2d2e23d..9652759 100644 --- a/BWXML/BWReader.cpp +++ b/BWXML/BWReader.cpp @@ -33,7 +33,7 @@ namespace BWPack if (magic != PACKED_SECTION_MAGIC) throw std::runtime_error("Wrong header magic"); - unsigned char version = mStream.get(); + unsigned char version = mStream.get(); if (version != 0) throw std::runtime_error("Unsupported file version"); ReadStringTable(); @@ -67,14 +67,16 @@ namespace BWPack switch(descr.typeId()) { case BW_Section: - current_node.swap(ReadSection()); //yay recursion! + current_node = ReadSection(); //yay recursion! break; + case BW_String: contentBuffer << mStream.getString(var_size); if (PackBuffer(contentBuffer.str()).type != BW_String) current_node.put("", "BW_String"); current_node.put_value(contentBuffer.str()); break; + case BW_Int: switch (var_size) { @@ -88,6 +90,7 @@ namespace BWPack current_node.put_value(mStream.get()); break; case 1: + // static_cast'ing to force ptree interprete our 1-byte value as a number, not a character current_node.put_value(static_cast(mStream.get())); break; case 0: @@ -97,20 +100,21 @@ namespace BWPack throw std::runtime_error("Unsupported int size!"); } break; + case BW_Float: assert(var_size % sizeof(float) == 0); contentBuffer << std::fixed << std::setfill('\t'); - if (var_size / sizeof(float) == 12) // we've got a matrix! + if (var_size / sizeof(float) == BW_MATRIX_SIZE) // we've got a matrix! { - for (int i=0; i<4; ++i) // rows + for (int i=0; i(); } - current_node.put("row"+boost::lexical_cast(i), contentBuffer.str()); + current_node.put("row" + boost::lexical_cast(i), contentBuffer.str()); contentBuffer.str(""); // clearing our buffer } break; @@ -124,20 +128,24 @@ namespace BWPack } current_node.put_value(contentBuffer.str()); break; + case BW_Bool: current_node.put_value((var_size != 0)); mStream.getString(var_size); break; + case BW_Blob: current_node.put_value(B64::Encode(mStream.getString(var_size))); break; + case BW_Enc_blob: mStream.getString(var_size); // TBD? current_node.put_value("TYPE_ENCRYPTED_BLOB is (yet) unsupported!"); std::cerr <<"unsupported section TYPE_ENCRYPTED_BLOB!" << std::endl; break; + default: - throw std::runtime_error("Unknown section!"); + throw std::runtime_error("Unsupported section type!"); } } diff --git a/BWXML/BWWriter.cpp b/BWXML/BWWriter.cpp index d1ef77d..2f2c0d4 100644 --- a/BWXML/BWWriter.cpp +++ b/BWXML/BWWriter.cpp @@ -85,17 +85,17 @@ namespace BWPack // 'simple' indicates that we need the node's exact value, even if it has children rawDataBlock BWXMLWriter::serializeNode(const boost::property_tree::ptree& node_value, bool simple) const { - if (node_value.size() == 4) // maybe that's a matrix?.. + if (node_value.size() == BW_MATRIX_NROWS) // maybe that's a matrix?.. { std::vector > rows; - for (int i=0; i<4; ++i) + for (int i=0; i(i)); if (!row) // bad luck. break; rows.push_back(row); } - if (rows.size() == 4) // we've found all 4 required rows + if (rows.size() == BW_MATRIX_NROWS) // we've found all 4 required rows { std::stringstream buffer; for (auto it=rows.begin(); it!=rows.end(); ++it) diff --git a/BWXML/DataStream.cpp b/BWXML/DataStream.cpp index 68951c6..bf33b0a 100644 --- a/BWXML/DataStream.cpp +++ b/BWXML/DataStream.cpp @@ -51,8 +51,8 @@ namespace BWPack std::string StreamReader::getNullTerminatedString() { - char buf[255] = { 0 }; - mInput.getline(buf, 255, '\0'); + char buf[MAX_STRING_LEN] = { 0 }; + mInput.getline(buf, MAX_STRING_LEN, '\0'); return std::string(buf); } diff --git a/BWXML/DataStream.h b/BWXML/DataStream.h index 868137e..76326d7 100644 --- a/BWXML/DataStream.h +++ b/BWXML/DataStream.h @@ -29,6 +29,7 @@ namespace BWPack { class StreamReader { + static const int MAX_STRING_LEN = 255; std::ifstream mInput; public: diff --git a/BWXML/main.cpp b/BWXML/main.cpp index 7ea5e72..c82dceb 100644 --- a/BWXML/main.cpp +++ b/BWXML/main.cpp @@ -45,21 +45,33 @@ std::string FindCommonPrefix(const std::vector& paths) auto lenCmp = [](const path& p1, const path& p2){return p1.string().length() < p2.string().length(); }; s1 = (*std::min_element(paths.begin(), paths.end(), lenCmp)).string(); s2 = (*std::max_element(paths.begin(), paths.end(), lenCmp)).string(); + for (size_t i=0; i()->default_value(boost::thread::hardware_concurrency() + 1), "sets the size of a worker pool. Default = n_cpu_cores + 1") //("key", bpo::value(&encryptionKey)->default_value(10), "encryption key") @@ -71,9 +83,6 @@ int main(int argc, char* argv[]) po.add("input", -1); bpo::variables_map vm; - - std::cout << "BWXML v1.02 by hedger" << std::endl; - try { bpo::store(bpo::command_line_parser(argc, argv). @@ -92,7 +101,11 @@ int main(int argc, char* argv[]) } bool doPack = (vm.count("pack") != 0); +#ifndef _DEBUG bool verbose = (vm.count("verbose") != 0); +#else + bool verbose = true; +#endif bool selfTest = (vm.count("selftest") != 0); auto inputPaths = vm["input"].as< std::vector >(); @@ -109,18 +122,20 @@ int main(int argc, char* argv[]) { path current = path(*it); if (!exists(current)) - std::cout << "Path '" << *it << "' not found or not accessible, skipping" << std::endl; + std::cout << "Path '" << *it << "' is not found or not accessible, skipping" << std::endl; if (is_directory(current)) - std::copy(recursive_directory_iterator(current, symlink_option::recurse), recursive_directory_iterator(), back_inserter(paths)); + std::copy(recursive_directory_iterator(current, symlink_option::recurse), + recursive_directory_iterator(), back_inserter(paths)); if (is_regular_file(current)) paths.push_back(current); } std::cout << "filtering... "; - std::copy_if(paths.begin(), paths.end(), std::back_inserter(valid_paths), [](const path& p){return is_regular_file(p);}); + std::copy_if(paths.begin(), paths.end(), std::back_inserter(valid_paths), + [](const path& p){return is_regular_file(p);}); - std::cout << "done. \nFound " << valid_paths.size() << " files, processing to " << destdir << std::endl; + std::cout << "done. \nFound " << valid_paths.size() << " file(s), processing to " << destdir << std::endl; if (valid_paths.empty()) { @@ -157,7 +172,7 @@ int main(int argc, char* argv[]) convert(target_path, target_path+".test", !doPack); std::cout << "+"; } - catch (std::exception e) + catch (const std::exception& e) { if (verbose) std::cout << "ERROR: " << e.what(); @@ -181,6 +196,7 @@ int main(int argc, char* argv[]) std::cerr << "ERROR: " << e.what() << std::endl; return -1; } + std::cout << std::endl << "Done." << std::endl; return 0; } \ No newline at end of file