bool readFile(std::list<RollbackAction> &dst) { // Load whole file to memory std::ifstream f(m_filepath.c_str(), std::ios::in); if(!f.good()){ errorstream<<"RollbackManager::readFile(): Could not open " <<"file for reading: \""<<m_filepath<<"\""<<std::endl; return false; } for(;;){ if(f.eof() || !f.good()) break; std::string line; std::getline(f, line); line = trim(line); if(line == "") continue; std::istringstream is(line); try{ std::string action_time_raw; std::getline(is, action_time_raw, ' '); std::string action_actor; try{ action_actor = deSerializeJsonString(is); }catch(SerializationError &e){ errorstream<<"RollbackManager: Error deserializing actor: " <<e.what()<<std::endl; throw e; } RollbackAction action; action.unix_time = stoi(action_time_raw); action.actor = action_actor; int c = is.get(); if(c != ' '){ is.putback(c); throw SerializationError("readFile(): second ' ' not found"); } action.fromStream(is); /*infostream<<"RollbackManager::readFile(): Action from disk: " <<action.toString()<<std::endl;*/ dst.push_back(action); } catch(SerializationError &e){ errorstream<<"RollbackManager: Error on line: "<<line<<std::endl; errorstream<<"RollbackManager: ^ error: "<<e.what()<<std::endl; } } return true; }
// Parses a string serialized by serializeJsonStringIfNeeded. static std::string deSerializeJsonStringIfNeeded(std::istream &is) { std::ostringstream tmp_os; bool expect_initial_quote = true; bool is_json = false; bool was_backslash = false; for(;;) { char c = is.get(); if(is.eof()) break; if(expect_initial_quote && c == '"') { tmp_os << c; is_json = true; } else if(is_json) { tmp_os << c; if(was_backslash) was_backslash = false; else if(c == '\\') was_backslash = true; else if(c == '"') break; // Found end of string } else { if(c == ' ') { // Found end of word is.unget(); break; } else { tmp_os << c; } } expect_initial_quote = false; } if(is_json) { std::istringstream tmp_is(tmp_os.str(), std::ios::binary); return deSerializeJsonString(tmp_is); } else return tmp_os.str(); }
void TestSerialization::testSerializeJsonString() { // Test blank string UASSERT(serializeJsonString("") == "\"\""); // Test basic string UASSERT(serializeJsonString("Hello world!") == "\"Hello world!\""); // MSVC fails when directly using "\\\\" std::string backslash = "\\"; UASSERT(serializeJsonString(teststring2) == mkstr("\"") + "\\u0000\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007" + "\\b\\t\\n\\u000b\\f\\r\\u000e\\u000f" + "\\u0010\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017" + "\\u0018\\u0019\\u001a\\u001b\\u001c\\u001d\\u001e\\u001f" + " !\\\"" + teststring2.substr(0x23, 0x2f-0x23) + "\\/" + teststring2.substr(0x30, 0x5c-0x30) + backslash + backslash + teststring2.substr(0x5d, 0x7f-0x5d) + "\\u007f" + "\\u0080\\u0081\\u0082\\u0083\\u0084\\u0085\\u0086\\u0087" + "\\u0088\\u0089\\u008a\\u008b\\u008c\\u008d\\u008e\\u008f" + "\\u0090\\u0091\\u0092\\u0093\\u0094\\u0095\\u0096\\u0097" + "\\u0098\\u0099\\u009a\\u009b\\u009c\\u009d\\u009e\\u009f" + "\\u00a0\\u00a1\\u00a2\\u00a3\\u00a4\\u00a5\\u00a6\\u00a7" + "\\u00a8\\u00a9\\u00aa\\u00ab\\u00ac\\u00ad\\u00ae\\u00af" + "\\u00b0\\u00b1\\u00b2\\u00b3\\u00b4\\u00b5\\u00b6\\u00b7" + "\\u00b8\\u00b9\\u00ba\\u00bb\\u00bc\\u00bd\\u00be\\u00bf" + "\\u00c0\\u00c1\\u00c2\\u00c3\\u00c4\\u00c5\\u00c6\\u00c7" + "\\u00c8\\u00c9\\u00ca\\u00cb\\u00cc\\u00cd\\u00ce\\u00cf" + "\\u00d0\\u00d1\\u00d2\\u00d3\\u00d4\\u00d5\\u00d6\\u00d7" + "\\u00d8\\u00d9\\u00da\\u00db\\u00dc\\u00dd\\u00de\\u00df" + "\\u00e0\\u00e1\\u00e2\\u00e3\\u00e4\\u00e5\\u00e6\\u00e7" + "\\u00e8\\u00e9\\u00ea\\u00eb\\u00ec\\u00ed\\u00ee\\u00ef" + "\\u00f0\\u00f1\\u00f2\\u00f3\\u00f4\\u00f5\\u00f6\\u00f7" + "\\u00f8\\u00f9\\u00fa\\u00fb\\u00fc\\u00fd\\u00fe\\u00ff" + "\""); // Test deserialize std::istringstream is(serializeJsonString(teststring2), std::ios::binary); UASSERT(deSerializeJsonString(is) == teststring2); UASSERT(!is.eof()); is.get(); UASSERT(is.eof()); }
NodeMetadata* FurnaceNodeMetadata::create(std::istream &is, IGameDef *gamedef) { FurnaceNodeMetadata *d = new FurnaceNodeMetadata(gamedef); d->m_inventory = new Inventory(gamedef->idef()); d->m_inventory->deSerialize(is); int temp = 0; is>>temp; d->m_fuel_totaltime = (float)temp/10; temp = 0; is>>temp; d->m_fuel_time = (float)temp/10; temp = 0; is>>temp; d->m_src_totaltime = (float)temp/10; temp = 0; is>>temp; d->m_src_time = (float)temp/10; if(is.eof()) { // Old furnaces didn't serialize src_totaltime and src_time d->m_src_totaltime = 0; d->m_src_time = 0; d->m_infotext = ""; } else { // New furnaces also serialize the infotext (so that the // client doesn't need to have the list of cooking recipes). d->m_infotext = deSerializeJsonString(is); } return d; }
void RollbackManager::migrate(const std::string & file_path) { std::cout << "Migrating from rollback.txt to rollback.sqlite." << std::endl; std::ifstream fh(file_path.c_str(), std::ios::in | std::ios::ate); if (!fh.good()) { throw FileNotGoodException("Unable to open rollback.txt"); } std::streampos file_size = fh.tellg(); if (file_size < 10) { errorstream << "Empty rollback log." << std::endl; return; } fh.seekg(0); sqlite3_stmt *stmt_begin; sqlite3_stmt *stmt_commit; SQLOK(sqlite3_prepare_v2(db, "BEGIN", -1, &stmt_begin, NULL)); SQLOK(sqlite3_prepare_v2(db, "COMMIT", -1, &stmt_commit, NULL)); std::string bit; int i = 0; time_t start = time(0); time_t t = start; SQLRES(sqlite3_step(stmt_begin), SQLITE_DONE); sqlite3_reset(stmt_begin); do { ActionRow row; row.id = 0; // Get the timestamp std::getline(fh, bit, ' '); bit = trim(bit); if (!atoi(bit.c_str())) { std::getline(fh, bit); continue; } row.timestamp = atoi(bit.c_str()); // Get the actor row.actor = getActorId(deSerializeJsonString(fh)); // Get the action type std::getline(fh, bit, '['); std::getline(fh, bit, ' '); if (bit == "modify_inventory_stack") { row.type = RollbackAction::TYPE_MODIFY_INVENTORY_STACK; row.location = trim(deSerializeJsonString(fh)); std::getline(fh, bit, ' '); row.list = trim(deSerializeJsonString(fh)); std::getline(fh, bit, ' '); std::getline(fh, bit, ' '); row.index = atoi(trim(bit).c_str()); std::getline(fh, bit, ' '); row.add = (int)(trim(bit) == "add"); row.stack.deSerialize(deSerializeJsonString(fh)); row.stack.id = getNodeId(row.stack.name); std::getline(fh, bit); } else if (bit == "set_node") { row.type = RollbackAction::TYPE_SET_NODE; std::getline(fh, bit, '('); std::getline(fh, bit, ','); row.x = atoi(trim(bit).c_str()); std::getline(fh, bit, ','); row.y = atoi(trim(bit).c_str()); std::getline(fh, bit, ')'); row.z = atoi(trim(bit).c_str()); std::getline(fh, bit, ' '); row.oldNode = getNodeId(trim(deSerializeJsonString(fh))); std::getline(fh, bit, ' '); std::getline(fh, bit, ' '); row.oldParam1 = atoi(trim(bit).c_str()); std::getline(fh, bit, ' '); row.oldParam2 = atoi(trim(bit).c_str()); row.oldMeta = trim(deSerializeJsonString(fh)); std::getline(fh, bit, ' '); row.newNode = getNodeId(trim(deSerializeJsonString(fh))); std::getline(fh, bit, ' '); std::getline(fh, bit, ' '); row.newParam1 = atoi(trim(bit).c_str()); std::getline(fh, bit, ' '); row.newParam2 = atoi(trim(bit).c_str()); row.newMeta = trim(deSerializeJsonString(fh)); std::getline(fh, bit, ' '); std::getline(fh, bit, ' '); std::getline(fh, bit); row.guessed = (int)(trim(bit) == "actor_is_guess"); } else { errorstream << "Unrecognized rollback action type \"" << bit << "\"!" << std::endl; continue; } registerRow(row); ++i; if (time(0) - t >= 1) { SQLRES(sqlite3_step(stmt_commit), SQLITE_DONE); sqlite3_reset(stmt_commit); t = time(0); std::cout << " Done: " << static_cast<int>((static_cast<float>(fh.tellg()) / static_cast<float>(file_size)) * 100) << "%" << " Speed: " << i / (t - start) << "/second \r" << std::flush; SQLRES(sqlite3_step(stmt_begin), SQLITE_DONE); sqlite3_reset(stmt_begin); } } while (fh.good()); SQLRES(sqlite3_step(stmt_commit), SQLITE_DONE); sqlite3_reset(stmt_commit); SQLOK(sqlite3_finalize(stmt_begin)); SQLOK(sqlite3_finalize(stmt_commit)); std::cout << " Done: 100% " << std::endl << "Now you can delete the old rollback.txt file." << std::endl; }
void RollbackAction::fromStream(std::istream &is) throw(SerializationError) { int c = is.get(); if(c != '['){ is.putback(c); throw SerializationError("RollbackAction: starting [ not found"); } std::string id; std::getline(is, id, ' '); if(id == "set_node") { c = is.get(); if(c != '('){ is.putback(c); throw SerializationError("RollbackAction: starting ( not found"); } // Position std::string px_raw; std::string py_raw; std::string pz_raw; std::getline(is, px_raw, ','); std::getline(is, py_raw, ','); std::getline(is, pz_raw, ')'); c = is.get(); if(c != ' '){ is.putback(c); throw SerializationError("RollbackAction: after-p ' ' not found"); } v3s16 loaded_p(stoi(px_raw), stoi(py_raw), stoi(pz_raw)); // Old node std::string old_name; try{ old_name = deSerializeJsonString(is); }catch(SerializationError &e){ errorstream<<"Serialization error in RollbackAction::fromStream(): " <<"old_name: "<<e.what()<<std::endl; throw e; } c = is.get(); if(c != ' '){ is.putback(c); throw SerializationError("RollbackAction: after-old_name ' ' not found"); } std::string old_p1_raw; std::string old_p2_raw; std::getline(is, old_p1_raw, ' '); std::getline(is, old_p2_raw, ' '); int old_p1 = stoi(old_p1_raw); int old_p2 = stoi(old_p2_raw); std::string old_meta; try{ old_meta = deSerializeJsonString(is); }catch(SerializationError &e){ errorstream<<"Serialization error in RollbackAction::fromStream(): " <<"old_meta: "<<e.what()<<std::endl; throw e; } c = is.get(); if(c != ' '){ is.putback(c); throw SerializationError("RollbackAction: after-old_meta ' ' not found"); } // New node std::string new_name; try{ new_name = deSerializeJsonString(is); }catch(SerializationError &e){ errorstream<<"Serialization error in RollbackAction::fromStream(): " <<"new_name: "<<e.what()<<std::endl; throw e; } c = is.get(); if(c != ' '){ is.putback(c); throw SerializationError("RollbackAction: after-new_name ' ' not found"); } std::string new_p1_raw; std::string new_p2_raw; std::getline(is, new_p1_raw, ' '); std::getline(is, new_p2_raw, ' '); int new_p1 = stoi(new_p1_raw); int new_p2 = stoi(new_p2_raw); std::string new_meta; try{ new_meta = deSerializeJsonString(is); }catch(SerializationError &e){ errorstream<<"Serialization error in RollbackAction::fromStream(): " <<"new_meta: "<<e.what()<<std::endl; throw e; } c = is.get(); if(c != ']'){ is.putback(c); throw SerializationError("RollbackAction: after-new_meta ] not found"); } // Set values type = TYPE_SET_NODE; p = loaded_p; n_old.name = old_name; n_old.param1 = old_p1; n_old.param2 = old_p2; n_old.meta = old_meta; n_new.name = new_name; n_new.param1 = new_p1; n_new.param2 = new_p2; n_new.meta = new_meta; } else if(id == "modify_inventory_stack") { // Location std::string location; try{ location = deSerializeJsonString(is); }catch(SerializationError &e){ errorstream<<"Serialization error in RollbackAction::fromStream(): " <<"location: "<<e.what()<<std::endl; throw e; } c = is.get(); if(c != ' '){ is.putback(c); throw SerializationError("RollbackAction: after-loc ' ' not found"); } // List std::string listname; try{ listname = deSerializeJsonString(is); }catch(SerializationError &e){ errorstream<<"Serialization error in RollbackAction::fromStream(): " <<"listname: "<<e.what()<<std::endl; throw e; } c = is.get(); if(c != ' '){ is.putback(c); throw SerializationError("RollbackAction: after-list ' ' not found"); } // Index std::string index_raw; std::getline(is, index_raw, ' '); // add/remove std::string addremove; std::getline(is, addremove, ' '); if(addremove != "add" && addremove != "remove"){ throw SerializationError("RollbackAction: addremove is not add or remove"); } // Itemstring std::string stack; try{ stack = deSerializeJsonString(is); }catch(SerializationError &e){ errorstream<<"Serialization error in RollbackAction::fromStream(): " <<"stack: "<<e.what()<<std::endl; throw e; } // Set values type = TYPE_MODIFY_INVENTORY_STACK; inventory_location = location; inventory_list = listname; inventory_index = stoi(index_raw); inventory_add = (addremove == "add"); inventory_stack = stack; } else { throw SerializationError("RollbackAction: Unknown id"); } }