aboutsummaryrefslogtreecommitdiff
path: root/contrib/epee
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/epee')
-rw-r--r--contrib/epee/include/misc_language.h17
-rw-r--r--contrib/epee/include/net/abstract_tcp_server2.inl3
-rw-r--r--contrib/epee/include/net/levin_protocol_handler_async.h24
-rw-r--r--contrib/epee/include/storages/portable_storage.h206
-rw-r--r--contrib/epee/include/storages/portable_storage_base.h2
-rw-r--r--contrib/epee/include/storages/portable_storage_from_json.h1
-rw-r--r--contrib/epee/include/storages/portable_storage_template_helper.h1
-rw-r--r--contrib/epee/include/storages/portable_storage_to_bin.h1
-rw-r--r--contrib/epee/include/storages/portable_storage_val_converters.h7
-rw-r--r--contrib/epee/src/CMakeLists.txt7
-rw-r--r--contrib/epee/src/misc_language.cpp44
-rw-r--r--contrib/epee/src/portable_storage.cpp215
-rw-r--r--contrib/epee/src/readline_buffer.cpp18
13 files changed, 321 insertions, 225 deletions
diff --git a/contrib/epee/include/misc_language.h b/contrib/epee/include/misc_language.h
index a04c63231..5ccfe6fcc 100644
--- a/contrib/epee/include/misc_language.h
+++ b/contrib/epee/include/misc_language.h
@@ -28,9 +28,11 @@
#pragma once
-#include <limits>
-#include <boost/thread.hpp>
#include <boost/utility/value_init.hpp>
+#include <boost/shared_ptr.hpp>
+#include <limits>
+#include <functional>
+#include <vector>
namespace epee
{
#define STD_TRY_BEGIN() try {
@@ -95,16 +97,7 @@ namespace misc_utils
return memcmp(&_Left, &_Right, sizeof(_Left)) < 0;
}
-
- inline
- bool sleep_no_w(long ms )
- {
- boost::this_thread::sleep(
- boost::get_system_time() +
- boost::posix_time::milliseconds( std::max<long>(ms,0) ) );
-
- return true;
- }
+ bool sleep_no_w(long ms );
template <typename T>
T get_mid(const T &a, const T &b)
diff --git a/contrib/epee/include/net/abstract_tcp_server2.inl b/contrib/epee/include/net/abstract_tcp_server2.inl
index cb1388f3b..b03a03cad 100644
--- a/contrib/epee/include/net/abstract_tcp_server2.inl
+++ b/contrib/epee/include/net/abstract_tcp_server2.inl
@@ -40,6 +40,7 @@
#include <boost/date_time/posix_time/posix_time.hpp> // TODO
#include <boost/thread/condition_variable.hpp> // TODO
#include <boost/make_shared.hpp>
+#include <boost/thread.hpp>
#include "warnings.h"
#include "string_tools.h"
#include "misc_language.h"
@@ -269,8 +270,6 @@ PRAGMA_WARNING_DISABLE_VS(4355)
//_dbg3("[sock " << socket().native_handle() << "] add_ref, m_peer_number=" << mI->m_peer_number);
CRITICAL_REGION_LOCAL(self->m_self_refs_lock);
//_dbg3("[sock " << socket().native_handle() << "] add_ref 2, m_peer_number=" << mI->m_peer_number);
- if(m_was_shutdown)
- return false;
++m_reference_count;
m_self_ref = std::move(self);
return true;
diff --git a/contrib/epee/include/net/levin_protocol_handler_async.h b/contrib/epee/include/net/levin_protocol_handler_async.h
index 5f2ee4719..635876589 100644
--- a/contrib/epee/include/net/levin_protocol_handler_async.h
+++ b/contrib/epee/include/net/levin_protocol_handler_async.h
@@ -861,12 +861,22 @@ template<class t_connection_context> template<class callback_t>
bool async_protocol_handler_config<t_connection_context>::foreach_connection(const callback_t &cb)
{
CRITICAL_REGION_LOCAL(m_connects_lock);
- for(auto& c: m_connects)
- {
- async_protocol_handler<t_connection_context>* aph = c.second;
- if(!cb(aph->get_context_ref()))
+ std::vector<typename connections_map::mapped_type> conn;
+ conn.reserve(m_connects.size());
+
+ auto scope_exit_handler = misc_utils::create_scope_leave_handler([&conn]{
+ for (auto &aph: conn)
+ aph->finish_outer_call();
+ });
+
+ for (auto &e: m_connects)
+ if (e.second->start_outer_call())
+ conn.push_back(e.second);
+
+ for (auto &aph: conn)
+ if (!cb(aph->get_context_ref()))
return false;
- }
+
return true;
}
//------------------------------------------------------------------------------------------
@@ -877,6 +887,10 @@ bool async_protocol_handler_config<t_connection_context>::for_connection(const b
async_protocol_handler<t_connection_context>* aph = find_connection(connection_id);
if (!aph)
return false;
+ if (!aph->start_outer_call())
+ return false;
+ auto scope_exit_handler = misc_utils::create_scope_leave_handler(
+ boost::bind(&async_protocol_handler<t_connection_context>::finish_outer_call, aph));
if(!cb(aph->get_context_ref()))
return false;
return true;
diff --git a/contrib/epee/include/storages/portable_storage.h b/contrib/epee/include/storages/portable_storage.h
index f77e89cb6..c5d0c48ee 100644
--- a/contrib/epee/include/storages/portable_storage.h
+++ b/contrib/epee/include/storages/portable_storage.h
@@ -24,20 +24,12 @@
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
-
-
#pragma once
-#include <type_traits>
-
-#include "misc_language.h"
#include "portable_storage_base.h"
-#include "portable_storage_from_bin.h"
-#include "portable_storage_to_json.h"
-#include "portable_storage_from_json.h"
#include "portable_storage_val_converters.h"
+#include "misc_log_ex.h"
#include "span.h"
-#include "int-util.h"
namespace epee
{
@@ -92,7 +84,7 @@ namespace epee
//-------------------------------------------------------------------------------
bool store_to_binary(byte_slice& target, std::size_t initial_buffer_size = 8192);
bool load_from_binary(const epee::span<const uint8_t> target, const limits_t *limits = NULL);
- bool load_from_binary(const std::string& target, const limits_t *limits = NULL) { return load_from_binary(epee::strspan<uint8_t>(target), limits); }
+ bool load_from_binary(const std::string& target, const limits_t *limits = NULL);
template<class trace_policy>
bool dump_as_xml(std::string& targetObj, const std::string& root_name = "");
bool dump_as_json(std::string& targetObj, size_t indent = 0, bool insert_newlines = true);
@@ -117,85 +109,13 @@ namespace epee
};
#pragma pack(pop)
};
- inline
- bool portable_storage::dump_as_json(std::string& buff, size_t indent, bool insert_newlines)
- {
- TRY_ENTRY();
- std::stringstream ss;
- epee::serialization::dump_as_json(ss, m_root, indent, insert_newlines);
- buff = ss.str();
- return true;
- CATCH_ENTRY("portable_storage::dump_as_json", false)
- }
- inline
- bool portable_storage::load_from_json(const std::string& source)
- {
- TRY_ENTRY();
- return json::load_from_json(source, *this);
- CATCH_ENTRY("portable_storage::load_from_json", false)
- }
-
+
template<class trace_policy>
bool portable_storage::dump_as_xml(std::string& targetObj, const std::string& root_name)
{
return false;//TODO: don't think i ever again will use xml - ambiguous and "overtagged" format
- }
- inline
- bool portable_storage::load_from_binary(const epee::span<const uint8_t> source, const limits_t *limits)
- {
- m_root.m_entries.clear();
- if(source.size() < sizeof(storage_block_header))
- {
- LOG_ERROR("portable_storage: wrong binary format, packet size = " << source.size() << " less than expected sizeof(storage_block_header)=" << sizeof(storage_block_header));
- return false;
- }
- storage_block_header* pbuff = (storage_block_header*)source.data();
- if(pbuff->m_signature_a != SWAP32LE(PORTABLE_STORAGE_SIGNATUREA) ||
- pbuff->m_signature_b != SWAP32LE(PORTABLE_STORAGE_SIGNATUREB)
- )
- {
- LOG_ERROR("portable_storage: wrong binary format - signature mismatch");
- return false;
- }
- if(pbuff->m_ver != PORTABLE_STORAGE_FORMAT_VER)
- {
- LOG_ERROR("portable_storage: wrong binary format - unknown format ver = " << pbuff->m_ver);
- return false;
- }
- TRY_ENTRY();
- throwable_buffer_reader buf_reader(source.data()+sizeof(storage_block_header), source.size()-sizeof(storage_block_header));
- if (limits)
- buf_reader.set_limits(limits->n_objects, limits->n_fields, limits->n_strings);
- buf_reader.read(m_root);
- return true;//TODO:
- CATCH_ENTRY("portable_storage::load_from_binary", false);
- }
- //---------------------------------------------------------------------------------------------------------------
- inline
- hsection portable_storage::open_section(const std::string& section_name, hsection hparent_section, bool create_if_notexist)
- {
- TRY_ENTRY();
- hparent_section = hparent_section ? hparent_section:&m_root;
- storage_entry* pentry = find_storage_entry(section_name, hparent_section);
- if(!pentry)
- {
- if(!create_if_notexist)
- return nullptr;
- return insert_new_section(section_name, hparent_section);
- }
- CHECK_AND_ASSERT(pentry , nullptr);
- //check that section_entry we find is real "CSSection"
- if(pentry->type() != typeid(section))
- {
- if(create_if_notexist)
- *pentry = storage_entry(section());//replace
- else
- return nullptr;
- }
- return &boost::get<section>(*pentry);
- CATCH_ENTRY("portable_storage::open_section", nullptr);
- }
- //---------------------------------------------------------------------------------------------------------------
+ }
+
template<class to_type>
struct get_value_visitor: boost::static_visitor<void>
{
@@ -221,20 +141,6 @@ namespace epee
//CATCH_ENTRY("portable_storage::template<>get_value", false);
}
//---------------------------------------------------------------------------------------------------------------
- inline
- bool portable_storage::get_value(const std::string& value_name, storage_entry& val, hsection hparent_section)
- {
- //TRY_ENTRY();
- if(!hparent_section) hparent_section = &m_root;
- storage_entry* pentry = find_storage_entry(value_name, hparent_section);
- if(!pentry)
- return false;
-
- val = *pentry;
- return true;
- //CATCH_ENTRY("portable_storage::template<>get_value", false);
- }
- //---------------------------------------------------------------------------------------------------------------
template<class t_value>
bool portable_storage::set_value(const std::string& value_name, t_value&& v, hsection hparent_section)
{
@@ -256,19 +162,6 @@ namespace epee
CATCH_ENTRY("portable_storage::template<>set_value", false);
}
//---------------------------------------------------------------------------------------------------------------
- inline
- storage_entry* portable_storage::find_storage_entry(const std::string& pentry_name, hsection psection)
- {
- TRY_ENTRY();
- CHECK_AND_ASSERT(psection, nullptr);
- auto it = psection->m_entries.find(pentry_name);
- if(it == psection->m_entries.end())
- return nullptr;
-
- return &it->second;
- CATCH_ENTRY("portable_storage::find_storage_entry", nullptr);
- }
- //---------------------------------------------------------------------------------------------------------------
template<class entry_type>
storage_entry* portable_storage::insert_new_entry_get_storage_entry(const std::string& pentry_name, hsection psection, entry_type&& entry)
{
@@ -281,16 +174,6 @@ namespace epee
CATCH_ENTRY("portable_storage::insert_new_entry_get_storage_entry", nullptr);
}
//---------------------------------------------------------------------------------------------------------------
- inline
- hsection portable_storage::insert_new_section(const std::string& pentry_name, hsection psection)
- {
- TRY_ENTRY();
- storage_entry* pse = insert_new_entry_get_storage_entry(pentry_name, psection, section());
- if(!pse) return nullptr;
- return &boost::get<section>(*pse);
- CATCH_ENTRY("portable_storage::insert_new_section", nullptr);
- }
- //---------------------------------------------------------------------------------------------------------------
template<class to_type>
struct get_first_value_visitor: boost::static_visitor<bool>
{
@@ -344,7 +227,6 @@ namespace epee
}
};
-
template<class t_value>
bool portable_storage::get_next_value(harray hval_array, t_value& target)
{
@@ -402,83 +284,5 @@ namespace epee
return true;
CATCH_ENTRY("portable_storage::insert_next_value", false);
}
- //---------------------------------------------------------------------------------------------------------------
- //sections
- inline
- harray portable_storage::get_first_section(const std::string& sec_name, hsection& h_child_section, hsection hparent_section)
- {
- TRY_ENTRY();
- if(!hparent_section) hparent_section = &m_root;
- storage_entry* pentry = find_storage_entry(sec_name, hparent_section);
- if(!pentry)
- return nullptr;
- if(pentry->type() != typeid(array_entry))
- return nullptr;
- array_entry& ar_entry = boost::get<array_entry>(*pentry);
- if(ar_entry.type() != typeid(array_entry_t<section>))
- return nullptr;
- array_entry_t<section>& sec_array = boost::get<array_entry_t<section>>(ar_entry);
- section* psec = sec_array.get_first_val();
- if(!psec)
- return nullptr;
- h_child_section = psec;
- return &ar_entry;
- CATCH_ENTRY("portable_storage::get_first_section", nullptr);
- }
- //---------------------------------------------------------------------------------------------------------------
- inline
- bool portable_storage::get_next_section(harray hsec_array, hsection& h_child_section)
- {
- TRY_ENTRY();
- CHECK_AND_ASSERT(hsec_array, false);
- if(hsec_array->type() != typeid(array_entry_t<section>))
- return false;
- array_entry_t<section>& sec_array = boost::get<array_entry_t<section>>(*hsec_array);
- h_child_section = sec_array.get_next_val();
- if(!h_child_section)
- return false;
- return true;
- CATCH_ENTRY("portable_storage::get_next_section", false);
- }
- //---------------------------------------------------------------------------------------------------------------
- inline
- harray portable_storage::insert_first_section(const std::string& sec_name, hsection& hinserted_childsection, hsection hparent_section)
- {
- TRY_ENTRY();
- if(!hparent_section) hparent_section = &m_root;
- storage_entry* pentry = find_storage_entry(sec_name, hparent_section);
- if(!pentry)
- {
- pentry = insert_new_entry_get_storage_entry(sec_name, hparent_section, array_entry(array_entry_t<section>()));
- if(!pentry)
- return nullptr;
- }
- if(pentry->type() != typeid(array_entry))
- *pentry = storage_entry(array_entry(array_entry_t<section>()));
-
- array_entry& ar_entry = boost::get<array_entry>(*pentry);
- if(ar_entry.type() != typeid(array_entry_t<section>))
- ar_entry = array_entry(array_entry_t<section>());
-
- array_entry_t<section>& sec_array = boost::get<array_entry_t<section>>(ar_entry);
- hinserted_childsection = &sec_array.insert_first_val(section());
- return &ar_entry;
- CATCH_ENTRY("portable_storage::insert_first_section", nullptr);
- }
- //---------------------------------------------------------------------------------------------------------------
- inline
- bool portable_storage::insert_next_section(harray hsec_array, hsection& hinserted_childsection)
- {
- TRY_ENTRY();
- CHECK_AND_ASSERT(hsec_array, false);
- CHECK_AND_ASSERT_MES(hsec_array->type() == typeid(array_entry_t<section>),
- false, "unexpected type(not 'section') in insert_next_section, type: " << hsec_array->type().name());
-
- array_entry_t<section>& sec_array = boost::get<array_entry_t<section>>(*hsec_array);
- hinserted_childsection = &sec_array.insert_next_value(section());
- return true;
- CATCH_ENTRY("portable_storage::insert_next_section", false);
- }
- //---------------------------------------------------------------------------------------------------------------
}
}
diff --git a/contrib/epee/include/storages/portable_storage_base.h b/contrib/epee/include/storages/portable_storage_base.h
index 1676f41fb..ae0be6a34 100644
--- a/contrib/epee/include/storages/portable_storage_base.h
+++ b/contrib/epee/include/storages/portable_storage_base.h
@@ -29,10 +29,10 @@
#pragma once
#include <boost/variant.hpp>
-#include <boost/any.hpp>
#include <string>
#include <vector>
#include <deque>
+#include <map>
#define PORTABLE_STORAGE_SIGNATUREA 0x01011101
#define PORTABLE_STORAGE_SIGNATUREB 0x01020101 // bender's nightmare
diff --git a/contrib/epee/include/storages/portable_storage_from_json.h b/contrib/epee/include/storages/portable_storage_from_json.h
index 2b2dc7ff9..3021598f5 100644
--- a/contrib/epee/include/storages/portable_storage_from_json.h
+++ b/contrib/epee/include/storages/portable_storage_from_json.h
@@ -26,6 +26,7 @@
#pragma once
#include <boost/lexical_cast.hpp>
+#include <boost/utility/string_ref.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include "parserse_base_utils.h"
#include "file_io_utils.h"
diff --git a/contrib/epee/include/storages/portable_storage_template_helper.h b/contrib/epee/include/storages/portable_storage_template_helper.h
index 16dd565ec..e7250e895 100644
--- a/contrib/epee/include/storages/portable_storage_template_helper.h
+++ b/contrib/epee/include/storages/portable_storage_template_helper.h
@@ -32,6 +32,7 @@
#include "parserse_base_utils.h"
#include "portable_storage.h"
#include "file_io_utils.h"
+#include "span.h"
namespace epee
{
diff --git a/contrib/epee/include/storages/portable_storage_to_bin.h b/contrib/epee/include/storages/portable_storage_to_bin.h
index 49a7be185..b82cf532b 100644
--- a/contrib/epee/include/storages/portable_storage_to_bin.h
+++ b/contrib/epee/include/storages/portable_storage_to_bin.h
@@ -32,6 +32,7 @@
#include "misc_language.h"
#include "portable_storage_base.h"
#include "portable_storage_bin_utils.h"
+#include "misc_log_ex.h"
namespace epee
{
diff --git a/contrib/epee/include/storages/portable_storage_val_converters.h b/contrib/epee/include/storages/portable_storage_val_converters.h
index e54cda828..96b0c024c 100644
--- a/contrib/epee/include/storages/portable_storage_val_converters.h
+++ b/contrib/epee/include/storages/portable_storage_val_converters.h
@@ -28,12 +28,17 @@
#pragma once
-#include <time.h>
#include <boost/regex.hpp>
#include "misc_language.h"
#include "portable_storage_base.h"
+#include "parserse_base_utils.h"
#include "warnings.h"
+#include "misc_log_ex.h"
+
+#include <boost/lexical_cast.hpp>
+#include <typeinfo>
+#include <iomanip>
namespace epee
{
diff --git a/contrib/epee/src/CMakeLists.txt b/contrib/epee/src/CMakeLists.txt
index 5e101a86a..641d4718e 100644
--- a/contrib/epee/src/CMakeLists.txt
+++ b/contrib/epee/src/CMakeLists.txt
@@ -29,7 +29,9 @@
add_library(epee STATIC byte_slice.cpp byte_stream.cpp hex.cpp abstract_http_client.cpp http_auth.cpp mlog.cpp net_helper.cpp net_utils_base.cpp string_tools.cpp
wipeable_string.cpp levin_base.cpp memwipe.c connection_basic.cpp network_throttle.cpp network_throttle-detail.cpp mlocker.cpp buffer.cpp net_ssl.cpp
- int-util.cpp portable_storage.cpp)
+ int-util.cpp portable_storage.cpp
+ misc_language.cpp
+ )
if (USE_READLINE AND (GNU_READLINE_FOUND OR (DEPENDS AND NOT MINGW)))
add_library(epee_readline STATIC readline_buffer.cpp)
@@ -71,3 +73,6 @@ if (USE_READLINE AND (GNU_READLINE_FOUND OR (DEPENDS AND NOT MINGW)))
PRIVATE
${GNU_READLINE_LIBRARY})
endif()
+
+target_include_directories(epee PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/../include")
+
diff --git a/contrib/epee/src/misc_language.cpp b/contrib/epee/src/misc_language.cpp
new file mode 100644
index 000000000..6e8f2daef
--- /dev/null
+++ b/contrib/epee/src/misc_language.cpp
@@ -0,0 +1,44 @@
+// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the Andrey N. Sabelnikov nor the
+// names of its contributors may be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#include "misc_language.h"
+
+#include <boost/thread.hpp>
+
+namespace epee
+{
+namespace misc_utils
+{
+ bool sleep_no_w(long ms )
+ {
+ boost::this_thread::sleep(
+ boost::get_system_time() +
+ boost::posix_time::milliseconds( std::max<long>(ms,0) ) );
+
+ return true;
+ }
+}
+}
diff --git a/contrib/epee/src/portable_storage.cpp b/contrib/epee/src/portable_storage.cpp
index 4534deff3..c3c9ccc02 100644
--- a/contrib/epee/src/portable_storage.cpp
+++ b/contrib/epee/src/portable_storage.cpp
@@ -1,10 +1,43 @@
+// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// * Neither the name of the Andrey N. Sabelnikov nor the
+// names of its contributors may be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY
+// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
#include "byte_slice.h"
#include "byte_stream.h"
#include "misc_log_ex.h"
#include "span.h"
#include "storages/portable_storage.h"
+#include "storages/portable_storage_to_json.h"
+#include "storages/portable_storage_from_json.h"
#include "storages/portable_storage_to_bin.h"
+#include "storages/portable_storage_from_bin.h"
+
+#include <boost/utility/string_ref.hpp>
+
+#include <string>
+#include <sstream>
namespace epee
{
@@ -25,5 +58,187 @@ namespace serialization
return true;
CATCH_ENTRY("portable_storage::store_to_binary", false)
}
+
+ bool portable_storage::dump_as_json(std::string& buff, size_t indent, bool insert_newlines)
+ {
+ TRY_ENTRY();
+ std::stringstream ss;
+ epee::serialization::dump_as_json(ss, m_root, indent, insert_newlines);
+ buff = ss.str();
+ return true;
+ CATCH_ENTRY("portable_storage::dump_as_json", false)
+ }
+
+ bool portable_storage::load_from_json(const std::string& source)
+ {
+ TRY_ENTRY();
+ return json::load_from_json(source, *this);
+ CATCH_ENTRY("portable_storage::load_from_json", false)
+ }
+
+ bool portable_storage::load_from_binary(const std::string& target, const limits_t *limits)
+ {
+ return load_from_binary(epee::strspan<uint8_t>(target), limits);
+ }
+
+ bool portable_storage::load_from_binary(const epee::span<const uint8_t> source, const limits_t *limits)
+ {
+ m_root.m_entries.clear();
+ if(source.size() < sizeof(storage_block_header))
+ {
+ LOG_ERROR("portable_storage: wrong binary format, packet size = " << source.size() << " less than expected sizeof(storage_block_header)=" << sizeof(storage_block_header));
+ return false;
+ }
+ storage_block_header* pbuff = (storage_block_header*)source.data();
+ if(pbuff->m_signature_a != SWAP32LE(PORTABLE_STORAGE_SIGNATUREA) ||
+ pbuff->m_signature_b != SWAP32LE(PORTABLE_STORAGE_SIGNATUREB)
+ )
+ {
+ LOG_ERROR("portable_storage: wrong binary format - signature mismatch");
+ return false;
+ }
+ if(pbuff->m_ver != PORTABLE_STORAGE_FORMAT_VER)
+ {
+ LOG_ERROR("portable_storage: wrong binary format - unknown format ver = " << pbuff->m_ver);
+ return false;
+ }
+ TRY_ENTRY();
+ throwable_buffer_reader buf_reader(source.data()+sizeof(storage_block_header), source.size()-sizeof(storage_block_header));
+ if (limits)
+ buf_reader.set_limits(limits->n_objects, limits->n_fields, limits->n_strings);
+ buf_reader.read(m_root);
+ return true;//TODO:
+ CATCH_ENTRY("portable_storage::load_from_binary", false);
+ }
+
+ hsection portable_storage::open_section(const std::string& section_name, hsection hparent_section, bool create_if_notexist)
+ {
+ TRY_ENTRY();
+ hparent_section = hparent_section ? hparent_section:&m_root;
+ storage_entry* pentry = find_storage_entry(section_name, hparent_section);
+ if(!pentry)
+ {
+ if(!create_if_notexist)
+ return nullptr;
+ return insert_new_section(section_name, hparent_section);
+ }
+ CHECK_AND_ASSERT(pentry , nullptr);
+ //check that section_entry we find is real "CSSection"
+ if(pentry->type() != typeid(section))
+ {
+ if(create_if_notexist)
+ *pentry = storage_entry(section());//replace
+ else
+ return nullptr;
+ }
+ return &boost::get<section>(*pentry);
+ CATCH_ENTRY("portable_storage::open_section", nullptr);
+ }
+
+ bool portable_storage::get_value(const std::string& value_name, storage_entry& val, hsection hparent_section)
+ {
+ //TRY_ENTRY();
+ if(!hparent_section) hparent_section = &m_root;
+ storage_entry* pentry = find_storage_entry(value_name, hparent_section);
+ if(!pentry)
+ return false;
+
+ val = *pentry;
+ return true;
+ //CATCH_ENTRY("portable_storage::template<>get_value", false);
+ }
+
+ storage_entry* portable_storage::find_storage_entry(const std::string& pentry_name, hsection psection)
+ {
+ TRY_ENTRY();
+ CHECK_AND_ASSERT(psection, nullptr);
+ auto it = psection->m_entries.find(pentry_name);
+ if(it == psection->m_entries.end())
+ return nullptr;
+
+ return &it->second;
+ CATCH_ENTRY("portable_storage::find_storage_entry", nullptr);
+ }
+
+ hsection portable_storage::insert_new_section(const std::string& pentry_name, hsection psection)
+ {
+ TRY_ENTRY();
+ storage_entry* pse = insert_new_entry_get_storage_entry(pentry_name, psection, section());
+ if(!pse) return nullptr;
+ return &boost::get<section>(*pse);
+ CATCH_ENTRY("portable_storage::insert_new_section", nullptr);
+ }
+
+ harray portable_storage::get_first_section(const std::string& sec_name, hsection& h_child_section, hsection hparent_section)
+ {
+ TRY_ENTRY();
+ if(!hparent_section) hparent_section = &m_root;
+ storage_entry* pentry = find_storage_entry(sec_name, hparent_section);
+ if(!pentry)
+ return nullptr;
+ if(pentry->type() != typeid(array_entry))
+ return nullptr;
+ array_entry& ar_entry = boost::get<array_entry>(*pentry);
+ if(ar_entry.type() != typeid(array_entry_t<section>))
+ return nullptr;
+ array_entry_t<section>& sec_array = boost::get<array_entry_t<section>>(ar_entry);
+ section* psec = sec_array.get_first_val();
+ if(!psec)
+ return nullptr;
+ h_child_section = psec;
+ return &ar_entry;
+ CATCH_ENTRY("portable_storage::get_first_section", nullptr);
+ }
+
+ bool portable_storage::get_next_section(harray hsec_array, hsection& h_child_section)
+ {
+ TRY_ENTRY();
+ CHECK_AND_ASSERT(hsec_array, false);
+ if(hsec_array->type() != typeid(array_entry_t<section>))
+ return false;
+ array_entry_t<section>& sec_array = boost::get<array_entry_t<section>>(*hsec_array);
+ h_child_section = sec_array.get_next_val();
+ if(!h_child_section)
+ return false;
+ return true;
+ CATCH_ENTRY("portable_storage::get_next_section", false);
+ }
+
+ harray portable_storage::insert_first_section(const std::string& sec_name, hsection& hinserted_childsection, hsection hparent_section)
+ {
+ TRY_ENTRY();
+ if(!hparent_section) hparent_section = &m_root;
+ storage_entry* pentry = find_storage_entry(sec_name, hparent_section);
+ if(!pentry)
+ {
+ pentry = insert_new_entry_get_storage_entry(sec_name, hparent_section, array_entry(array_entry_t<section>()));
+ if(!pentry)
+ return nullptr;
+ }
+ if(pentry->type() != typeid(array_entry))
+ *pentry = storage_entry(array_entry(array_entry_t<section>()));
+
+ array_entry& ar_entry = boost::get<array_entry>(*pentry);
+ if(ar_entry.type() != typeid(array_entry_t<section>))
+ ar_entry = array_entry(array_entry_t<section>());
+
+ array_entry_t<section>& sec_array = boost::get<array_entry_t<section>>(ar_entry);
+ hinserted_childsection = &sec_array.insert_first_val(section());
+ return &ar_entry;
+ CATCH_ENTRY("portable_storage::insert_first_section", nullptr);
+ }
+
+ bool portable_storage::insert_next_section(harray hsec_array, hsection& hinserted_childsection)
+ {
+ TRY_ENTRY();
+ CHECK_AND_ASSERT(hsec_array, false);
+ CHECK_AND_ASSERT_MES(hsec_array->type() == typeid(array_entry_t<section>),
+ false, "unexpected type(not 'section') in insert_next_section, type: " << hsec_array->type().name());
+
+ array_entry_t<section>& sec_array = boost::get<array_entry_t<section>>(*hsec_array);
+ hinserted_childsection = &sec_array.insert_next_value(section());
+ return true;
+ CATCH_ENTRY("portable_storage::insert_next_section", false);
+ }
}
}
diff --git a/contrib/epee/src/readline_buffer.cpp b/contrib/epee/src/readline_buffer.cpp
index bcf499963..1047d1696 100644
--- a/contrib/epee/src/readline_buffer.cpp
+++ b/contrib/epee/src/readline_buffer.cpp
@@ -6,6 +6,7 @@
#include <boost/thread/lock_guard.hpp>
#include <boost/algorithm/string.hpp>
+static bool same_as_last_line(const std::string&);
static void install_line_handler();
static void remove_line_handler();
@@ -175,8 +176,11 @@ static void handle_line(char* line)
boost::trim_right(test_line);
if(!test_line.empty())
{
- add_history(test_line.c_str());
- history_set_pos(history_length);
+ if (!same_as_last_line(test_line))
+ {
+ add_history(test_line.c_str());
+ history_set_pos(history_length);
+ }
if (test_line == "exit" || test_line == "q")
exit = true;
}
@@ -192,6 +196,16 @@ static void handle_line(char* line)
return;
}
+// same_as_last_line returns true, if the last line in the history is
+// equal to test_line.
+static bool same_as_last_line(const std::string& test_line)
+{
+ // Note that state->offset == state->length, when a new line was entered.
+ HISTORY_STATE* state = history_get_history_state();
+ return state->length > 0
+ && test_line.compare(state->entries[state->length-1]->line) == 0;
+}
+
static char* completion_matches(const char* text, int state)
{
static size_t list_index;