mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-06 17:27:55 +00:00
Alphabet class for base58 conversions, Validators work
This commit is contained in:
@@ -269,15 +269,19 @@ public:
|
||||
//
|
||||
void addStatic (Source* source)
|
||||
{
|
||||
m_journal.info << "Addding static source '" << source->name() << "'";
|
||||
m_journal.info << "Addding static " << source->name();
|
||||
|
||||
ScopedPointer <Source> object (source);
|
||||
Source::Result result (object->fetch (m_journal));
|
||||
Source::Result result;
|
||||
object->fetch (result, m_journal);
|
||||
|
||||
if (result.success)
|
||||
{
|
||||
SharedState::Access state (m_state);
|
||||
merge (result.list, source, state);
|
||||
std::size_t const numAdded (
|
||||
merge (result.list, source, state));
|
||||
m_journal.info << "Added " << numAdded
|
||||
<< " trusted validators from " << source->name();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -289,7 +293,7 @@ public:
|
||||
//
|
||||
void add (Source* source)
|
||||
{
|
||||
m_journal.info << "Adding source '" << source->name() << "'";
|
||||
m_journal.info << "Adding " << source->name();
|
||||
|
||||
{
|
||||
SharedState::Access state (m_state);
|
||||
@@ -303,13 +307,13 @@ public:
|
||||
// Add each entry in the list to the map, incrementing the
|
||||
// reference count if it already exists, and updating fields.
|
||||
//
|
||||
void merge (Array <Source::Info> const& list,
|
||||
std::size_t merge (std::vector <Source::Info> const& list,
|
||||
Source* source, SharedState::Access& state)
|
||||
{
|
||||
std::size_t numAdded (0);
|
||||
for (std::size_t i = 0; i < list.size (); ++i)
|
||||
{
|
||||
Source::Info const& info (list.getReference (i));
|
||||
Source::Info const& info (list [i]);
|
||||
std::pair <MapType::iterator, bool> result (
|
||||
state->map.emplace (info.publicKey, Validator ()));
|
||||
Validator& validatorInfo (result.first->second);
|
||||
@@ -322,20 +326,19 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
m_journal.info << "Added " << numAdded
|
||||
<< " trusted validators from '" << source->name() << "'";
|
||||
return numAdded;
|
||||
}
|
||||
|
||||
// Decrement the reference count of each item in the list
|
||||
// in the map.
|
||||
//
|
||||
void remove (Array <Source::Info> const& list,
|
||||
std::size_t remove (std::vector <Source::Info> const& list,
|
||||
Source* source, SharedState::Access& state)
|
||||
{
|
||||
std::size_t numRemoved (0);
|
||||
for (std::size_t i = 0; i < list.size (); ++i)
|
||||
{
|
||||
Source::Info const& info (list.getReference (i));
|
||||
Source::Info const& info (list [i]);
|
||||
MapType::iterator iter (state->map.find (info.publicKey));
|
||||
bassert (iter != state->map.end ());
|
||||
Validator& validatorInfo (iter->second);
|
||||
@@ -348,8 +351,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
m_journal.info << "Removed " << numRemoved
|
||||
<< " trusted validators from '" << source->name() << "'";
|
||||
return numRemoved;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
@@ -410,9 +412,12 @@ public:
|
||||
/** Perform a fetch on the source. */
|
||||
void fetch (SourceDesc& desc)
|
||||
{
|
||||
m_journal.info << "fetch " << desc.source->name();
|
||||
Source* const source (desc.source);
|
||||
|
||||
Source::Result result (desc.source->fetch (m_journal));
|
||||
m_journal.info << "fetch " << source->name();
|
||||
|
||||
Source::Result result;
|
||||
source->fetch (result, m_journal);
|
||||
|
||||
// Reset fetch timer for the source.
|
||||
desc.whenToFetch = Time::getCurrentTime () +
|
||||
@@ -423,13 +428,22 @@ public:
|
||||
SharedState::Access state (m_state);
|
||||
|
||||
// Add the new source info to the map
|
||||
merge (result.list, desc.source, state);
|
||||
std::size_t const numAdded (
|
||||
merge (result.list, source, state));
|
||||
|
||||
// Swap lists
|
||||
desc.result.swapWith (result);
|
||||
|
||||
// Remove the old source info from the map
|
||||
remove (result.list, desc.source, state);
|
||||
std::size_t const numRemoved (
|
||||
remove (result.list, source, state));
|
||||
|
||||
if (numAdded > numRemoved)
|
||||
m_journal.info << "Added " << (numAdded - numRemoved) <<
|
||||
" trusted validators from " << source->name();
|
||||
else if (numRemoved > numAdded)
|
||||
m_journal.info << "Removed " << (numRemoved - numAdded) <<
|
||||
" trusted validators from " << source->name();
|
||||
|
||||
// See if we need to rebuild
|
||||
checkChosen ();
|
||||
|
||||
@@ -188,14 +188,19 @@ public:
|
||||
|
||||
void addStrings (String name, StringArray const& stringArray)
|
||||
{
|
||||
addStaticSource (SourceStrings::New (
|
||||
name, stringArray));
|
||||
if (stringArray.size() > 0)
|
||||
{
|
||||
addStaticSource (SourceStrings::New (name, stringArray));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_journal.debug << "Static source '" << name << "' is empty.";
|
||||
}
|
||||
}
|
||||
|
||||
void addFile (File const& file)
|
||||
{
|
||||
//addStaticSource (SourceFile::New (file));
|
||||
addSource (SourceFile::New (file));
|
||||
addStaticSource (SourceFile::New (file));
|
||||
}
|
||||
|
||||
void addURL (URL const& url)
|
||||
|
||||
@@ -30,7 +30,7 @@ void Source::Result::swapWith (Result& other)
|
||||
{
|
||||
std::swap (success, other.success);
|
||||
std::swap (message, other.message);
|
||||
list.swapWith (other.list);
|
||||
list.swap (other.list);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ public:
|
||||
|
||||
String name ()
|
||||
{
|
||||
return "File :'" + m_file.getFullPathName () + "'";
|
||||
return "File: '" + m_file.getFullPathName () + "'";
|
||||
}
|
||||
|
||||
String uniqueID ()
|
||||
@@ -48,11 +48,9 @@ public:
|
||||
{
|
||||
return m_file.getFullPathName ();
|
||||
}
|
||||
|
||||
Result fetch (Journal journal)
|
||||
|
||||
void fetch (Result& result, Journal journal)
|
||||
{
|
||||
Result result;
|
||||
|
||||
int64 const fileSize (m_file.getSize ());
|
||||
|
||||
if (fileSize != 0)
|
||||
@@ -68,6 +66,8 @@ public:
|
||||
|
||||
if (amountRead == fileSize)
|
||||
{
|
||||
Utilities::ParseResultLine lineFunction (result, journal);
|
||||
Utilities::processLines (buffer.begin(), buffer.end(), lineFunction);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -79,8 +79,6 @@ public:
|
||||
{
|
||||
// file doesn't exist
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -51,11 +51,9 @@ public:
|
||||
return String::empty;
|
||||
}
|
||||
|
||||
Result fetch (Journal journal)
|
||||
void fetch (Result& result, Journal journal)
|
||||
{
|
||||
Result result;
|
||||
|
||||
result.list.ensureStorageAllocated (m_strings.size ());
|
||||
result.list.reserve (m_strings.size ());
|
||||
|
||||
for (int i = 0; i < m_strings.size (); ++i)
|
||||
{
|
||||
@@ -65,7 +63,6 @@ public:
|
||||
|
||||
result.success = result.list.size () > 0;
|
||||
result.expirationTime = Time::getCurrentTime () + RelativeTime::hours (24);
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -49,17 +49,22 @@ public:
|
||||
return m_url.full();
|
||||
}
|
||||
|
||||
Result fetch (Journal journal)
|
||||
void fetch (Result& result, Journal journal)
|
||||
{
|
||||
Result result;
|
||||
|
||||
ScopedPointer <HTTPClientBase> client (HTTPClientBase::New ());
|
||||
|
||||
HTTPClientBase::result_type httpResult (client->get (m_url));
|
||||
|
||||
if (httpResult.first == 0)
|
||||
{
|
||||
//Logger::outputDebugString (httpResult.second->toString ());
|
||||
#if 0
|
||||
journal.debug << std::endl << httpResult.second->toString ();
|
||||
journal.debug << std::endl << httpResult.second->body().to_string();
|
||||
#endif
|
||||
|
||||
Utilities::ParseResultLine lineFunction (result, journal);
|
||||
std::string const s (httpResult.second->body().to_string());
|
||||
Utilities::processLines (s.begin(), s.end(), lineFunction);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -67,8 +72,6 @@ public:
|
||||
"HTTP GET to " << m_url.full().toStdString() <<
|
||||
" failed: '" << httpResult.first.message () << "'";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -80,10 +83,7 @@ private:
|
||||
SourceURL* SourceURL::New (
|
||||
URL const& url)
|
||||
{
|
||||
ScopedPointer <SourceURL> object (
|
||||
new SourceURLImp (url));
|
||||
|
||||
return object.release ();
|
||||
return new SourceURLImp (url);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -36,6 +36,9 @@ Error StoreSqdb::open (File const& file)
|
||||
if (!error)
|
||||
error = init ();
|
||||
|
||||
if (!error)
|
||||
error = update ();
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -116,20 +119,16 @@ void StoreSqdb::update (SourceDesc& desc, bool updateFetchResults)
|
||||
if (! error && updateFetchResults)
|
||||
{
|
||||
// Delete the previous data set
|
||||
{
|
||||
sqdb::statement st = (m_session.prepare <<
|
||||
"DELETE FROM ValidatorsSourceInfo WHERE "
|
||||
" sourceID = ?; "
|
||||
,sqdb::use (sourceID)
|
||||
);
|
||||
|
||||
st.execute_and_fetch (error);
|
||||
}
|
||||
m_session.once (error) <<
|
||||
"DELETE FROM ValidatorsSourceInfo WHERE "
|
||||
" sourceID = ?; "
|
||||
,sqdb::use (sourceID)
|
||||
;
|
||||
|
||||
// Insert the new data set
|
||||
if (! error)
|
||||
{
|
||||
std::string publicKey;
|
||||
std::string publicKeyString;
|
||||
String label;
|
||||
|
||||
sqdb::statement st = (m_session.prepare <<
|
||||
@@ -141,15 +140,15 @@ void StoreSqdb::update (SourceDesc& desc, bool updateFetchResults)
|
||||
" ?, ?, ? "
|
||||
");"
|
||||
,sqdb::use (sourceID)
|
||||
,sqdb::use (publicKey)
|
||||
,sqdb::use (publicKeyString)
|
||||
,sqdb::use (label)
|
||||
);
|
||||
|
||||
Array <Source::Info>& list (desc.result.list);
|
||||
std::vector <Source::Info>& list (desc.result.list);
|
||||
for (std::size_t i = 0; ! error && i < list.size(); ++i)
|
||||
{
|
||||
Source::Info& info (list.getReference(i));
|
||||
publicKey = Utilities::publicKeyToString (info.publicKey);
|
||||
Source::Info& info (list [i]);
|
||||
publicKeyString = info.publicKey.to_string ();
|
||||
label = list[i].label;
|
||||
st.execute_and_fetch (error);
|
||||
}
|
||||
@@ -255,11 +254,11 @@ void StoreSqdb::selectList (SourceDesc& desc)
|
||||
bassert (desc.result.list.size() == 0);
|
||||
|
||||
// Pre-allocate some storage
|
||||
desc.result.list.ensureStorageAllocated (count);
|
||||
desc.result.list.reserve (count);
|
||||
|
||||
// Prepare the select
|
||||
{
|
||||
std::string publicKey;
|
||||
std::string publicKeyString;
|
||||
std::string label;
|
||||
sqdb::statement st = (m_session.prepare <<
|
||||
"SELECT "
|
||||
@@ -267,7 +266,7 @@ void StoreSqdb::selectList (SourceDesc& desc)
|
||||
" label "
|
||||
"FROM ValidatorsSourceInfo WHERE "
|
||||
" sourceID = ? "
|
||||
,sqdb::into (publicKey)
|
||||
,sqdb::into (publicKeyString)
|
||||
,sqdb::into (label)
|
||||
,sqdb::use (sourceID)
|
||||
);
|
||||
@@ -278,9 +277,20 @@ void StoreSqdb::selectList (SourceDesc& desc)
|
||||
do
|
||||
{
|
||||
Source::Info info;
|
||||
info.publicKey = Utilities::stringToPublicKey (publicKey);
|
||||
info.label = label;
|
||||
desc.result.list.add (info);
|
||||
std::pair <RipplePublicKey, bool> result (
|
||||
RipplePublicKey::from_string (publicKeyString));
|
||||
if (result.second)
|
||||
{
|
||||
bassert (result.first.to_string() == publicKeyString);
|
||||
info.publicKey = result.first;
|
||||
info.label = label;
|
||||
desc.result.list.push_back (info);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_journal.error << "Invalid public key '" <<
|
||||
publicKeyString << "' found in database";
|
||||
}
|
||||
}
|
||||
while (st.fetch (error));
|
||||
}
|
||||
@@ -294,6 +304,81 @@ void StoreSqdb::selectList (SourceDesc& desc)
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
// Update the database for the current schema
|
||||
Error StoreSqdb::update ()
|
||||
{
|
||||
Error error;
|
||||
|
||||
sqdb::transaction tr (m_session);
|
||||
|
||||
// Get the version from the database
|
||||
int version (0);
|
||||
if (! error)
|
||||
{
|
||||
m_session.once (error) <<
|
||||
"SELECT "
|
||||
" version "
|
||||
"FROM SchemaVersion WHERE "
|
||||
" name = 'Validators' "
|
||||
,sqdb::into (version)
|
||||
;
|
||||
|
||||
if (! m_session.got_data ())
|
||||
{
|
||||
// pre-dates the "SchemaVersion" table
|
||||
version = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (! error && version != currentSchemaVersion)
|
||||
{
|
||||
m_journal.info << "Updating old database version " << version;
|
||||
}
|
||||
|
||||
// Update database based on version
|
||||
if (! error && version < 1)
|
||||
{
|
||||
// Delete all the old data since its likely wrong
|
||||
m_session.once (error) <<
|
||||
"DELETE FROM ValidatorsSource";
|
||||
|
||||
if (! error)
|
||||
{
|
||||
m_session.once (error) <<
|
||||
"DELETE FROM ValidatorsSourceInfo";
|
||||
}
|
||||
}
|
||||
|
||||
// Update the version to the current version
|
||||
if (! error)
|
||||
{
|
||||
int const version (currentSchemaVersion);
|
||||
|
||||
m_session.once (error) <<
|
||||
"INSERT OR REPLACE INTO SchemaVersion ( "
|
||||
" name, "
|
||||
" version "
|
||||
") VALUES ( "
|
||||
" 'Validators', ? "
|
||||
"); "
|
||||
,sqdb::use (version)
|
||||
;
|
||||
}
|
||||
|
||||
if (! error)
|
||||
{
|
||||
error = tr.commit();
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
tr.rollback ();
|
||||
report (error, __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
Error StoreSqdb::init ()
|
||||
{
|
||||
Error error;
|
||||
@@ -342,6 +427,23 @@ Error StoreSqdb::init ()
|
||||
;
|
||||
}
|
||||
|
||||
if (! error)
|
||||
{
|
||||
// This table maps component names like "Validators" to their
|
||||
// corresponding schema version number. This method allows us
|
||||
// to keep all logic data in one database, or each in its own
|
||||
// database, or in any grouping of databases, while still being
|
||||
// able to let an individual component know what version of its
|
||||
// schema it is opening.
|
||||
//
|
||||
m_session.once (error) <<
|
||||
"CREATE TABLE IF NOT EXISTS SchemaVersion ( "
|
||||
" name TEXT PRIMARY KEY, "
|
||||
" version INTEGER"
|
||||
");"
|
||||
;
|
||||
}
|
||||
|
||||
if (! error)
|
||||
{
|
||||
error = tr.commit();
|
||||
|
||||
@@ -29,6 +29,12 @@ class StoreSqdb
|
||||
, public LeakChecked <StoreSqdb>
|
||||
{
|
||||
public:
|
||||
enum
|
||||
{
|
||||
// This affects the format of the data!
|
||||
currentSchemaVersion = 1
|
||||
};
|
||||
|
||||
explicit StoreSqdb (Journal journal = Journal());
|
||||
|
||||
~StoreSqdb ();
|
||||
@@ -45,6 +51,7 @@ private:
|
||||
bool select (SourceDesc& desc);
|
||||
void selectList (SourceDesc& desc);
|
||||
|
||||
Error update ();
|
||||
Error init ();
|
||||
|
||||
Journal m_journal;
|
||||
|
||||
@@ -121,23 +121,19 @@ public:
|
||||
return String::empty;
|
||||
}
|
||||
|
||||
Result fetch (Journal)
|
||||
void fetch (Result& result, Journal)
|
||||
{
|
||||
Result result;
|
||||
|
||||
result.success = true;
|
||||
result.message = String::empty;
|
||||
result.list.ensureStorageAllocated (numberOfTestValidators);
|
||||
result.list.reserve (numberOfTestValidators);
|
||||
|
||||
for (uint32 i = m_start ; i < m_end; ++i)
|
||||
{
|
||||
Info info;
|
||||
info.publicKey = RipplePublicKey::createFromInteger (i);
|
||||
info.label = String::fromNumber (i);
|
||||
result.list.add (info);
|
||||
result.list.push_back (info);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
String m_name;
|
||||
|
||||
@@ -24,22 +24,25 @@ struct Utilities::Helpers
|
||||
{
|
||||
// Matches a validator info line.
|
||||
//
|
||||
static boost::regex& reInfo ()
|
||||
static boost::regex const& reInfo ()
|
||||
{
|
||||
// e.g.
|
||||
//
|
||||
// n9KorY8QtTdRx7TVDpwnG9NvyxsDwHUKUEeDLY3AkiGncVaSXZi5 Comment Text
|
||||
//
|
||||
static boost::regex re (
|
||||
"^" // start of line
|
||||
"(?:\\h*)" // horiz-white (optional)
|
||||
"([^\\h\\v]+)" // [1] non-white run
|
||||
"(?:\\h*)" // horiz-white (optional)
|
||||
"([^\\h\\v]*)" // [2] any text (optional)
|
||||
"$" // end of line
|
||||
"\\G" // end of last match (or start)
|
||||
"(?:[\\v\\h]*)" // white (optional)
|
||||
"([^\\h\\v]+)" // [1] non-white run
|
||||
"(?:\\h*)" // horiz-white (optional)
|
||||
"([^\\v]*?)" // [2] non vert-white text (optional)
|
||||
"(?:\\h*)" // white run (optional)
|
||||
"(?:\\v*)" // vert-white (optional)
|
||||
|
||||
, boost::regex::perl |
|
||||
boost::regex_constants::match_flags::match_not_dot_null
|
||||
//"(?:\\')" // buffer boundary
|
||||
|
||||
, boost::regex::perl
|
||||
//| boost::regex_constants::match_flags::match_not_dot_newline
|
||||
);
|
||||
|
||||
return re;
|
||||
@@ -47,7 +50,7 @@ struct Utilities::Helpers
|
||||
|
||||
// Matches a comment or whitespace line.
|
||||
//
|
||||
static boost::regex& reComment ()
|
||||
static boost::regex const& reComment ()
|
||||
{
|
||||
// e.g.
|
||||
//
|
||||
@@ -87,23 +90,18 @@ bool Utilities::parseInfoLine (
|
||||
|
||||
RippleAddress deprecatedPublicKey;
|
||||
|
||||
// VFALCO NOTE These bool return values are poorlydocumented
|
||||
//
|
||||
if (deprecatedPublicKey.setSeedGeneric (encodedKey))
|
||||
{
|
||||
// expected a domain or public key but got a generic seed?
|
||||
// log?
|
||||
}
|
||||
else if (deprecatedPublicKey.setNodePublic (encodedKey))
|
||||
if (deprecatedPublicKey.setNodePublic (encodedKey))
|
||||
{
|
||||
// We got a public key.
|
||||
RipplePublicKey publicKey (deprecatedPublicKey);
|
||||
info.label = commentText;
|
||||
info.publicKey = publicKey;
|
||||
success = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Some other junk.
|
||||
// log?
|
||||
journal.error << "Invalid RipplePublicKey: '" << encodedKey << "'";
|
||||
}
|
||||
}
|
||||
else if (boost::regex_match (line, match, Helpers::reComment ()))
|
||||
@@ -113,54 +111,9 @@ bool Utilities::parseInfoLine (
|
||||
else
|
||||
{
|
||||
// Log a warning about a parsing error
|
||||
journal.error << "Invalid Validators source line:" << std::endl << line;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static boost::regex reReferral ("\\`\\s*(\\S+)(?:\\s+(.+))?\\s*\\'");
|
||||
|
||||
if (!boost::regex_match (strReferral, smMatch, reReferral))
|
||||
{
|
||||
WriteLog (lsWARNING, UniqueNodeList) << str (boost::format ("Bad validator: syntax error: %s: %s") % strSite % strReferral);
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string strRefered = smMatch[1];
|
||||
std::string strComment = smMatch[2];
|
||||
RippleAddress naValidator;
|
||||
|
||||
if (naValidator.setSeedGeneric (strRefered))
|
||||
{
|
||||
|
||||
WriteLog (lsWARNING, UniqueNodeList) << str (boost::format ("Bad validator: domain or public key required: %s %s") % strRefered % strComment);
|
||||
}
|
||||
else if (naValidator.setNodePublic (strRefered))
|
||||
{
|
||||
// A public key.
|
||||
// XXX Schedule for CAS lookup.
|
||||
nodeAddPublic (naValidator, vsWhy, strComment);
|
||||
|
||||
WriteLog (lsINFO, UniqueNodeList) << str (boost::format ("Node Public: %s %s") % strRefered % strComment);
|
||||
|
||||
if (naNodePublic.isValid ())
|
||||
vstrValues.push_back (str (boost::format ("('%s',%d,'%s')") % strNodePublic % iValues % naValidator.humanNodePublic ()));
|
||||
|
||||
iValues++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// A domain: need to look it up.
|
||||
nodeAddDomain (strRefered, vsWhy, strComment);
|
||||
|
||||
WriteLog (lsINFO, UniqueNodeList) << str (boost::format ("Node Domain: %s %s") % strRefered % strComment);
|
||||
|
||||
if (naNodePublic.isValid ())
|
||||
vstrValues.push_back (str (boost::format ("('%s',%d,%s)") % strNodePublic % iValues % sqlEscape (strRefered)));
|
||||
|
||||
iValues++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
@@ -171,15 +124,13 @@ void Utilities::parseResultLine (
|
||||
std::string const& line,
|
||||
Journal journal)
|
||||
{
|
||||
bool success = false;
|
||||
Source::Info info;
|
||||
|
||||
if (! success)
|
||||
bool success = parseInfoLine (info, line, journal);
|
||||
if (success)
|
||||
{
|
||||
Source::Info info;
|
||||
|
||||
success = parseInfoLine (info, line, journal);
|
||||
if (success)
|
||||
result.list.add (info);
|
||||
result.list.push_back (info);
|
||||
result.success = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -249,19 +200,6 @@ Time Utilities::stringToTime (String s)
|
||||
return Time (0);
|
||||
}
|
||||
|
||||
std::string Utilities::publicKeyToString (RipplePublicKey const& publicKey)
|
||||
{
|
||||
std::string s (RipplePublicKey::size, ' ');
|
||||
std::copy (publicKey.cbegin(), publicKey.cend(), s.begin());
|
||||
return s;
|
||||
}
|
||||
|
||||
RipplePublicKey Utilities::stringToPublicKey (std::string const& s)
|
||||
{
|
||||
bassert (s.size() == RipplePublicKey::size);
|
||||
return RipplePublicKey ();
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
@@ -23,31 +23,93 @@
|
||||
namespace ripple {
|
||||
namespace Validators {
|
||||
|
||||
/** Common code for Validators classes.
|
||||
*/
|
||||
/** Common code for Validators classes. */
|
||||
class Utilities
|
||||
{
|
||||
public:
|
||||
typedef std::vector <std::string> Strings;
|
||||
|
||||
#if 0
|
||||
/** Parse a ConstBufferSequence of newline delimited text into strings.
|
||||
This works incrementally.
|
||||
*/
|
||||
template <typename ConstBufferSequence>
|
||||
static void parseLines (Strings& lines, ConstBufferSequence const& buffers)
|
||||
/** A suitable LineFunction for parsing items into a fetch result. */
|
||||
class ParseResultLine
|
||||
{
|
||||
for (typename ConstBufferSequence::const_iterator iter = buffers.begin ();
|
||||
iter != buffers.end (); ++iter)
|
||||
parserLines (lines, *iter);
|
||||
}
|
||||
public:
|
||||
ParseResultLine (Source::Result& result, Journal journal)
|
||||
: m_result (&result)
|
||||
, m_journal (journal)
|
||||
{ }
|
||||
|
||||
/** Turn a linear buffer of newline delimited text into strings.
|
||||
This can be called incrementally, i.e. successive calls with
|
||||
multiple buffer segments.
|
||||
template <typename BidirectionalIterator>
|
||||
void operator() (BidirectionalIterator first, BidirectionalIterator last)
|
||||
{
|
||||
std::string s (first, last);
|
||||
Utilities::parseResultLine (*m_result, s, m_journal);
|
||||
}
|
||||
|
||||
private:
|
||||
Source::Result* m_result;
|
||||
Journal m_journal;
|
||||
};
|
||||
|
||||
/** UnaryPredicate for breaking up lines.
|
||||
This returns `true` for the first non-vertical whitespace character that
|
||||
follows a vertical whitespace character.
|
||||
*/
|
||||
static void parseLines (Strings& lines, char const* buf, std::size_t bytes);
|
||||
#endif
|
||||
class FollowingVerticalWhite
|
||||
{
|
||||
public:
|
||||
FollowingVerticalWhite ()
|
||||
: m_gotWhite (false)
|
||||
{
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
static bool isVerticalWhitespace (CharT c)
|
||||
{
|
||||
return c == '\r' || c == '\n';
|
||||
}
|
||||
|
||||
template <typename CharT>
|
||||
bool operator() (CharT c)
|
||||
{
|
||||
if (isVerticalWhitespace (c))
|
||||
{
|
||||
m_gotWhite = true;
|
||||
return false;
|
||||
}
|
||||
else if (m_gotWhite)
|
||||
{
|
||||
m_gotWhite = false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_gotWhite;
|
||||
};
|
||||
|
||||
/** Call LineFunction for each newline-separated line in the input.
|
||||
LineFunction will be called with this signature:
|
||||
@code
|
||||
void LineFunction (BidirectionalIterator first, BidirectionalIterator last)
|
||||
@endcode
|
||||
Where first and last mark the beginning and ending of the line.
|
||||
The last line in the input may or may not contain the trailing newline.
|
||||
*/
|
||||
template <typename BidirectionalIterator, typename LineFunction>
|
||||
static void processLines (BidirectionalIterator first,
|
||||
BidirectionalIterator last, LineFunction f)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
BidirectionalIterator split (std::find_if (
|
||||
first, last, FollowingVerticalWhite ()));
|
||||
f (first, split);
|
||||
if (split == last)
|
||||
break;
|
||||
first = split;
|
||||
}
|
||||
}
|
||||
|
||||
/** Parse a string into the Source::Result.
|
||||
Invalid or comment lines will be skipped.
|
||||
@@ -67,10 +129,6 @@ public:
|
||||
static String timeToString (Time const& t);
|
||||
static Time stringToTime (String s);
|
||||
|
||||
// conversion between RipplePublicKey and String
|
||||
static std::string publicKeyToString (RipplePublicKey const& publicKey);
|
||||
static RipplePublicKey stringToPublicKey (std::string const& s);
|
||||
|
||||
struct Helpers;
|
||||
|
||||
/** Parse a string into a Source::Info.
|
||||
|
||||
Reference in New Issue
Block a user