-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add a new serialized type: STNumber #5121
base: develop
Are you sure you want to change the base?
Changes from 7 commits
38290f3
68aeacf
0153615
55e2aa7
f63762d
dfa71e7
208fc55
23a4df4
551e7cf
ff31929
ec6b7e9
2d64b66
986c406
b74bdb0
e9786ff
65dd773
529edc1
168c081
2758f4c
3f4254b
9f3b082
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
//------------------------------------------------------------------------------ | ||
/* | ||
This file is part of rippled: https://github.com/ripple/rippled | ||
Copyright (c) 2024 Ripple Labs Inc. | ||
|
||
Permission to use, copy, modify, and/or distribute this software for any | ||
purpose with or without fee is hereby granted, provided that the above | ||
copyright notice and this permission notice appear in all copies. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
*/ | ||
//============================================================================== | ||
|
||
#ifndef XRPL_PROTOCOL_STNUMBER_H_INCLUDED | ||
#define XRPL_PROTOCOL_STNUMBER_H_INCLUDED | ||
|
||
#include <xrpl/basics/CountedObject.h> | ||
#include <xrpl/basics/Number.h> | ||
#include <xrpl/protocol/STBase.h> | ||
|
||
namespace ripple { | ||
|
||
class STNumber final : public STBase, | ||
thejohnfreeman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
public CountedObject<STNumber>, | ||
public Number | ||
{ | ||
public: | ||
STNumber() = default; | ||
explicit STNumber(SField const& n, Number const& v = Number()); | ||
STNumber(SerialIter& sit, SField const& name); | ||
thejohnfreeman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
using Number::operator=; | ||
|
||
thejohnfreeman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
SerializedTypeID | ||
getSType() const override; | ||
std::string | ||
getText() const override; | ||
Json::Value getJson(JsonOptions) const override; | ||
void | ||
add(Serializer& s) const override; | ||
|
||
Number const& | ||
value() const; | ||
void | ||
setValue(Number const& v); | ||
thejohnfreeman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
STBase* | ||
copy(std::size_t n, void* buf) const override; | ||
thejohnfreeman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
STBase* | ||
move(std::size_t n, void* buf) override; | ||
|
||
bool | ||
isEquivalent(STBase const& t) const override; | ||
bool | ||
isDefault() const override; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should add overload for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Won't it just use the existing overload for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's ambiguous because both |
||
}; | ||
|
||
} // namespace ripple | ||
|
||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
//------------------------------------------------------------------------------ | ||
/* | ||
This file is part of rippled: https://github.com/ripple/rippled | ||
Copyright (c) 2023 Ripple Labs Inc. | ||
|
||
Permission to use, copy, modify, and/or distribute this software for any | ||
purpose with or without fee is hereby granted, provided that the above | ||
copyright notice and this permission notice appear in all copies. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
*/ | ||
//============================================================================== | ||
|
||
#include <xrpl/protocol/STNumber.h> | ||
|
||
#include <xrpl/protocol/SField.h> | ||
|
||
namespace ripple { | ||
|
||
STNumber::STNumber(SField const& n, Number const& v) : STBase(n), Number(v) | ||
{ | ||
} | ||
|
||
STNumber::STNumber(SerialIter& sit, SField const& name) : STBase(name) | ||
{ | ||
// We must call these methods in separate statements | ||
// to guarantee their order of execution. | ||
auto mantissa = sit.geti64(); | ||
auto exponent = sit.geti32(); | ||
*this = Number{mantissa, exponent}; | ||
} | ||
|
||
SerializedTypeID | ||
STNumber::getSType() const | ||
{ | ||
return STI_NUMBER; | ||
} | ||
|
||
std::string | ||
STNumber::getText() const | ||
{ | ||
return to_string(*this); | ||
} | ||
|
||
Json::Value STNumber::getJson(JsonOptions) const | ||
{ | ||
// TODO: come up with a string representation. | ||
thejohnfreeman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return to_string(*this); | ||
} | ||
|
||
void | ||
STNumber::add(Serializer& s) const | ||
{ | ||
assert(getFName().isBinary()); | ||
assert(getFName().fieldType == getSType()); | ||
s.addi64(this->mantissa()); | ||
s.addi32(this->exponent()); | ||
} | ||
|
||
Number const& | ||
STNumber::value() const | ||
{ | ||
return *this; | ||
} | ||
|
||
void | ||
STNumber::setValue(Number const& v) | ||
{ | ||
*this = v; | ||
} | ||
|
||
STBase* | ||
STNumber::copy(std::size_t n, void* buf) const | ||
{ | ||
return emplace(n, buf, *this); | ||
} | ||
|
||
STBase* | ||
STNumber::move(std::size_t n, void* buf) | ||
{ | ||
return emplace(n, buf, std::move(*this)); | ||
} | ||
|
||
bool | ||
STNumber::isEquivalent(STBase const& t) const | ||
{ | ||
assert(t.getSType() == this->getSType()); | ||
Number const& v = dynamic_cast<Number const&>(t); | ||
return *this == v; | ||
} | ||
|
||
bool | ||
STNumber::isDefault() const | ||
{ | ||
return *this == Number(); | ||
} | ||
|
||
} // namespace ripple |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,7 @@ | |
#include <xrpl/basics/contract.h> | ||
#include <xrpl/protocol/Serializer.h> | ||
#include <xrpl/protocol/digest.h> | ||
#include <boost/endian/conversion.hpp> | ||
thejohnfreeman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
#include <type_traits> | ||
|
||
namespace ripple { | ||
|
@@ -71,6 +72,32 @@ | |
return ret; | ||
} | ||
|
||
int | ||
Serializer::addi32(std::int32_t i) | ||
thejohnfreeman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider adding a private common (template?) function for 32 and 64 bit serialization. They are practically the same except for the most significant byte handling. |
||
int ret = mData.size(); | ||
mData.push_back(static_cast<unsigned char>((i >> 24) & 0xff)); | ||
mData.push_back(static_cast<unsigned char>((i >> 16) & 0xff)); | ||
mData.push_back(static_cast<unsigned char>((i >> 8) & 0xff)); | ||
mData.push_back(static_cast<unsigned char>(i & 0xff)); | ||
return ret; | ||
} | ||
|
||
int | ||
Serializer::addi64(std::int64_t i) | ||
{ | ||
int ret = mData.size(); | ||
mData.push_back(static_cast<unsigned char>((i >> 56) & 0xff)); | ||
mData.push_back(static_cast<unsigned char>((i >> 48) & 0xff)); | ||
mData.push_back(static_cast<unsigned char>((i >> 40) & 0xff)); | ||
mData.push_back(static_cast<unsigned char>((i >> 32) & 0xff)); | ||
mData.push_back(static_cast<unsigned char>((i >> 24) & 0xff)); | ||
mData.push_back(static_cast<unsigned char>((i >> 16) & 0xff)); | ||
mData.push_back(static_cast<unsigned char>((i >> 8) & 0xff)); | ||
mData.push_back(static_cast<unsigned char>(i & 0xff)); | ||
return ret; | ||
} | ||
|
||
template <> | ||
int | ||
Serializer::addInteger(unsigned char i) | ||
|
@@ -410,6 +437,30 @@ | |
(std::uint64_t(t[6]) << 8) + std::uint64_t(t[7]); | ||
} | ||
|
||
std::int32_t | ||
SerialIter::geti32() | ||
{ | ||
if (remain_ < 4) | ||
Throw<std::runtime_error>("invalid SerialIter geti32"); | ||
auto t = p_; | ||
p_ += 4; | ||
used_ += 4; | ||
remain_ -= 4; | ||
return boost::endian::load_big_s32(t); | ||
} | ||
|
||
std::int64_t | ||
SerialIter::geti64() | ||
{ | ||
if (remain_ < 8) | ||
Throw<std::runtime_error>("invalid SerialIter geti64"); | ||
auto t = p_; | ||
p_ += 8; | ||
used_ += 8; | ||
remain_ -= 8; | ||
return boost::endian::load_big_s64(t); | ||
} | ||
|
||
void | ||
SerialIter::getFieldID(int& type, int& name) | ||
{ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a brief description of the class.