diff options
author | Jeff Garzik <jgarzik@bitpay.com> | 2014-06-23 23:16:33 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@bitpay.com> | 2014-07-29 11:13:27 -0400 |
commit | b2aeaa79393608132104183eba117fcbf583148e (patch) | |
tree | 98bc68b1a815c0afe644e56e6fa6eb47297fe355 /src/core_read.cpp | |
parent | ae775b5b311982a3d932a9e34ddc94ce597dcaaf (diff) |
Move ParseScript() helper, becoming accessible outside src/test/
Diffstat (limited to 'src/core_read.cpp')
-rw-r--r-- | src/core_read.cpp | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/src/core_read.cpp b/src/core_read.cpp index 937dcd9c12..d5d3cca480 100644 --- a/src/core_read.cpp +++ b/src/core_read.cpp @@ -3,8 +3,85 @@ #include "core_io.h" #include "core.h" #include "serialize.h" +#include "script.h" + +#include <boost/assign/list_of.hpp> +#include <boost/algorithm/string/classification.hpp> +#include <boost/algorithm/string/predicate.hpp> +#include <boost/algorithm/string/split.hpp> +#include <boost/algorithm/string/replace.hpp> using namespace std; +using namespace boost; +using namespace boost::algorithm; + +CScript ParseScript(std::string s) +{ + CScript result; + + static map<string, opcodetype> mapOpNames; + + if (mapOpNames.size() == 0) + { + for (int op = 0; op <= OP_NOP10; op++) + { + // Allow OP_RESERVED to get into mapOpNames + if (op < OP_NOP && op != OP_RESERVED) + continue; + + const char* name = GetOpName((opcodetype)op); + if (strcmp(name, "OP_UNKNOWN") == 0) + continue; + string strName(name); + mapOpNames[strName] = (opcodetype)op; + // Convenience: OP_ADD and just ADD are both recognized: + replace_first(strName, "OP_", ""); + mapOpNames[strName] = (opcodetype)op; + } + } + + vector<string> words; + split(words, s, is_any_of(" \t\n"), token_compress_on); + + BOOST_FOREACH(string w, words) + { + if (w.size() == 0) + { + // Empty string, ignore. (boost::split given '' will return one word) + } + else if (all(w, is_digit()) || + (starts_with(w, "-") && all(string(w.begin()+1, w.end()), is_digit()))) + { + // Number + int64_t n = atoi64(w); + result << n; + } + else if (starts_with(w, "0x") && IsHex(string(w.begin()+2, w.end()))) + { + // Raw hex data, inserted NOT pushed onto stack: + std::vector<unsigned char> raw = ParseHex(string(w.begin()+2, w.end())); + result.insert(result.end(), raw.begin(), raw.end()); + } + else if (w.size() >= 2 && starts_with(w, "'") && ends_with(w, "'")) + { + // Single-quoted string, pushed as data. NOTE: this is poor-man's + // parsing, spaces/tabs/newlines in single-quoted strings won't work. + std::vector<unsigned char> value(w.begin()+1, w.end()-1); + result << value; + } + else if (mapOpNames.count(w)) + { + // opcode, e.g. OP_ADD or ADD: + result << mapOpNames[w]; + } + else + { + throw runtime_error("script parse error"); + } + } + + return result; +} bool DecodeHexTx(CTransaction& tx, const std::string& strHexTx) { |