| 460 | } |
| 461 | |
| 462 | void UserDefault::flush() |
| 463 | { |
| 464 | #if !USER_DEFAULT_PLAIN_MODE |
| 465 | if (_rwmmap) |
| 466 | { |
| 467 | yasio::obstream obs; |
| 468 | obs.write<int>(static_cast<int>(this->_values.size())); |
| 469 | for (auto&& item : this->_values) |
| 470 | { |
| 471 | if (_encryptEnabled) |
| 472 | { |
| 473 | ud_write_v_s(this, obs, item.first); |
| 474 | ud_write_v_s(this, obs, item.second); |
| 475 | } |
| 476 | else |
| 477 | { |
| 478 | obs.write_v(item.first); |
| 479 | obs.write_v(item.second); |
| 480 | } |
| 481 | } |
| 482 | |
| 483 | std::error_code error; |
| 484 | if (obs.length() > _curMapSize) |
| 485 | { |
| 486 | _rwmmap->unmap(); |
| 487 | while (obs.length() > _curMapSize) |
| 488 | _curMapSize <<= 1; // X2 |
| 489 | |
| 490 | if (!_fileStream.resize(_curMapSize)) |
| 491 | AXLOGW("UserDefault::flush failed to truncate '{}'.", _filePath); |
| 492 | |
| 493 | _rwmmap->map(_fileStream.nativeHandle(), 0, _curMapSize, error); |
| 494 | } |
| 495 | |
| 496 | if (!error && _rwmmap->is_mapped()) |
| 497 | { // mapping status is good |
| 498 | ::memcpy(_rwmmap->data(), obs.data(), obs.length()); |
| 499 | _realSize = static_cast<int>(obs.length() - sizeof(udflen_t)); |
| 500 | } |
| 501 | else |
| 502 | { |
| 503 | // close file mapping and do a simple workaround fix to don't do persist later at this time |
| 504 | closeFileMapping(); |
| 505 | ::remove(_filePath.c_str()); |
| 506 | } |
| 507 | } |
| 508 | #else |
| 509 | pugi::xml_document doc; |
| 510 | doc.load_string(R"(<?xml version="1.0" ?> |
| 511 | <r />)"); |
| 512 | auto r = doc.document_element(); |
| 513 | for (auto&& kv : _values) |
| 514 | r.append_child(kv.first.c_str()).append_child(pugi::xml_node_type::node_pcdata).set_value(kv.second.c_str()); |
| 515 | |
| 516 | std::stringstream ss; |
| 517 | doc.save(ss, " "); |
| 518 | FileUtils::getInstance()->writeStringToFile(ss.str(), _filePath); |
| 519 | #endif |