Browse Source

More commenting.

Type-safety changes.
cl-refactor
Gav Wood 11 years ago
parent
commit
d4c9328f1e
  1. 31
      CodingStandards.txt
  2. 4
      libethereum/Common.cpp
  3. 67
      libethereum/Common.h

31
CodingStandards.txt

@ -1,7 +1,11 @@
0. Formatting
a. Use tabs for indentation; 4 spaces wide. One indentation level -> exactly one byte (i.e. a tab character) in the source file.
b. Don't worry about having lines > 80-char wide. We're not editing on terminals anymore.
a. Use tabs for indentation!
- 1 tab is 4 spaces wide.
- One indentation level -> exactly one byte (i.e. a tab character) in the source file.
b. Line widths:
- Don't worry about having lines of code > 80-char wide.
- Lines of comments should be formatted according to ease of viewing, but simplicity is to be prefered over beauty.
c. Don't use braces for condition-body one-liners.
d. Never place condition bodies on same line as condition.
e. Space between first paren and keyword, but *not* following first paren or preceeding final paren.
@ -21,7 +25,7 @@ if (a == b[i])
1. Namespaces;
a. No "using" declarations in header files.
a. No "using namespace" declarations in header files.
b. All symbols should be declared in a namespace except for final applications.
c. Preprocessor symbols should be prefixed with the namespace in all-caps and an underscore.
@ -90,6 +94,7 @@ d. Favour declarations close to use; don't habitually declare at top of scope al
e. Always pass non-trivial parameters with a const& suffix.
f. If a function returns multiple values, use std::tuple (std::pair acceptable). Prefer not using */& arguments, except where efficiency requires.
g. Never use a macro where adequate non-preprocessor C++ can be written.
h. Prefer "using NewType = OldType" to "typedef OldType NewType".
(WRONG)
const double d = 0;
@ -125,7 +130,25 @@ e. No implementations with the class declaration, except:
9. Commenting
9. Naming
a. Collection conventions:
- -s means std::vector e.g. using MyTypes = std::vector<MyType>
- -Set means std::set e.g. using MyTypeSet = std::set<MyType>
- -Hash means std::unordered_set e.g. using MyTypeHash = std::unordered_set<MyType>
b. Class conventions:
- -Face means the interface of some shared concept. (e.g. FooFace might be a pure virtual class.)
c. Avoid unpronouncable names;
- If you need to shorten a name favour a pronouncable slice of the original to a scatterred set of consonants.
- e.g. Manager shortens to Man rather than Mgr.
d. Avoid prefixes of initials (e.g. DON'T use IMyInterface, CMyImplementation)
e. A dictionary and thesaurus are your friends.
- Spell correctly.
- Find short, memorable & (at least semi-) descriptive names for commonly used classes or name-fragments.
10. Commenting
a. Comments should be doxygen-compilable, using @notation rather than \notation.

4
libethereum/Common.cpp

@ -106,7 +106,7 @@ bytes eth::toHex(std::string const& _s)
((uint32_t) *((strptr)+1) << 8) | \
((uint32_t) *(strptr)))
u256 eth::ripemd160(bytesConstRef _message)
u160 eth::ripemd160(bytesConstRef _message)
/*
* returns RMD(message)
* message should be a string terminated by '\0'
@ -144,7 +144,7 @@ u256 eth::ripemd160(bytesConstRef _message)
hashcode[i+3] = (MDbuf[i>>2] >> 24);
}
u256 ret = 0;
u160 ret = 0;
for (i = 0; i < RMDsize / 8; ++i)
ret = (ret << 8) | hashcode[i];
return ret;

67
libethereum/Common.h

@ -35,12 +35,13 @@
namespace eth
{
// Binary data types.
using byte = uint8_t;
using bytes = std::vector<byte>;
using bytesRef = vector_ref<byte>;
using bytesConstRef = vector_ref<byte const>;
// Numeric types.
using bigint = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<>>;
using u256 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void>>;
using s256 = boost::multiprecision::number<boost::multiprecision::cpp_int_backend<256, 256, boost::multiprecision::signed_magnitude, boost::multiprecision::unchecked, void>>;
@ -51,13 +52,16 @@ using sint = int64_t;
using u256s = std::vector<u256>;
using u160s = std::vector<u160>;
// Map types.
using StringMap = std::map<std::string, std::string>;
using u256Map = std::map<u256, u256>;
using HexMap = std::map<bytes, std::string>;
// Null/Invalid values for convenience.
static const u256 Invalid256 = ~(u256)0;
static const bytes NullBytes;
/// Converts arbitrary value to string representation using std::stringstream.
template <class _T>
std::string toString(_T const& _t)
{
@ -66,11 +70,22 @@ std::string toString(_T const& _t)
return o.str();
}
/// Converts byte array to a string containing the same (binary) data. Unless
/// the byte array happens to contain ASCII data, this won't be printable.
inline std::string asString(bytes const& _b)
{
return std::string((char const*)_b.data(), (char const*)(_b.data() + _b.size()));
}
/// Converts a string to a byte array containing the string's (byte) data.
inline bytes asBytes(std::string const& _b)
{
return bytes((byte const*)_b.data(), (byte const*)(_b.data() + _b.size()));
}
/// Convert a series of bytes to the corresponding string of hex duplets.
/// @param _w specifies the width of each of the elements. Defaults to two - enough to represent a byte.
/// @example asHex("A\x69") == "4169"
template <class _T>
std::string asHex(_T const& _data, int _w = 2)
{
@ -80,27 +95,51 @@ std::string asHex(_T const& _data, int _w = 2)
return ret.str();
}
/// Trims a given number of elements from the front of a collection.
/// Only works for POD element types.
template <class _T>
void trimFront(_T& _t, uint _elements)
{
static_assert(std::is_pod<typename _T::value_type>::value, "");
memmove(_t.data(), _t.data() + _elements, (_t.size() - _elements) * sizeof(_t[0]));
_t.resize(_t.size() - _elements);
}
/// Pushes an element on to the front of a collection.
/// Only works for POD element types.
template <class _T, class _U>
void pushFront(_T& _t, _U _e)
{
static_assert(std::is_pod<typename _T::value_type>::value, "");
_t.push_back(_e);
memmove(_t.data() + 1, _t.data(), (_t.size() - 1) * sizeof(_e));
_t[0] = _e;
}
/// Creates a random, printable, word.
std::string randomWord();
/// Escapes a string into the C-string representation.
/// @p _all if true will escape all characters, not just the unprintable ones.
std::string escaped(std::string const& _s, bool _all = true);
/// Converts a (printable) ASCII hex character into the correspnding integer value.
/// @example fromHex('A') == 10 && fromHex('f') == 15 && fromHex('5') == 5
int fromHex(char _i);
/// Converts a (printable) ASCII hex string into the corresponding byte stream.
/// @example fromUserHex("41626261") == asBytes("Abba")
bytes fromUserHex(std::string const& _s);
/// Converts a string into the big-endian base-16 stream of integers (NOT ASCII).
/// @example toHex("A")[0] == 4 && toHex("A")[1] == 1
bytes toHex(std::string const& _s);
/// Converts a templated integer value to the big-endian byte-stream represented on a templated collection.
/// The size of the collection object will be unchanged. If it is too small, it will not represent the
/// value properly, if too big then the additional elements will be zeroed out.
/// @a _Out will typically be either std::string or bytes.
/// @a _T will typically by uint, u160, u256 or bigint.
template <class _T, class _Out>
inline void toBigEndian(_T _val, _Out& o_out)
{
@ -109,6 +148,9 @@ inline void toBigEndian(_T _val, _Out& o_out)
o_out[s - 1 - i] = (typename _Out::value_type)(uint8_t)_val;
}
/// Converts a big-endian byte-stream represented on a templated collection to a templated integer value.
/// @a _In will typically be either std::string or bytes.
/// @a _T will typically by uint, u160, u256 or bigint.
template <class _T, class _In>
inline _T fromBigEndian(_In const& _bytes)
{
@ -118,12 +160,14 @@ inline _T fromBigEndian(_In const& _bytes)
return ret;
}
/// Convenience functions for toBigEndian
inline std::string toBigEndianString(u256 _val) { std::string ret(32, '\0'); toBigEndian(_val, ret); return ret; }
inline std::string toBigEndianString(u160 _val) { std::string ret(20, '\0'); toBigEndian(_val, ret); return ret; }
inline bytes toBigEndian(u256 _val) { bytes ret(32); toBigEndian(_val, ret); return ret; }
inline bytes toBigEndian(u160 _val) { bytes ret(20); toBigEndian(_val, ret); return ret; }
/// Convenience function for toBigEndian.
/// @returns a string just big enough to represent @a _val.
template <class _T>
inline std::string toCompactBigEndianString(_T _val)
{
@ -134,6 +178,9 @@ inline std::string toCompactBigEndianString(_T _val)
return ret;
}
/// Determines the length of the common prefix of the two collections given.
/// @returns the number of elements both @a _t and @a _u share, in order, at the beginning.
/// @example commonPrefix("Hello world!", "Hello, world!") == 5
template <class _T, class _U>
uint commonPrefix(_T const& _t, _U const& _u)
{
@ -144,22 +191,24 @@ uint commonPrefix(_T const& _t, _U const& _u)
return s;
}
u256 ripemd160(bytesConstRef _message);
/// Convert the given value into u160 (160-bit unsigned integer) by taking the lowest order 160-bits and discarding the rest.
template <class _T>
inline u160 low160(_T const& _t)
{
return (u160)(_t & ((((_T)1) << 160) - 1));
}
/// Convert the given value safely into u160 (160-bit unsigned integer).
/// @note Currently unsafe.
template <class _T>
inline u160 as160(_T const& _t)
{
return (u160)(_t & ((((_T)1) << 160) - 1));
return low160(_t);
}
/// Concatenate two vectors of elements. _T must be POD.
template <class _T>
inline std::vector<_T>& operator+=(std::vector<_T>& _a, std::vector<_T> const& _b)
inline std::vector<_T>& operator+=(std::vector<typename std::enable_if<std::is_pod<_T>::value, _T>::type>& _a, std::vector<_T> const& _b)
{
auto s = _a.size();
_a.resize(_a.size() + _b.size());
@ -168,11 +217,15 @@ inline std::vector<_T>& operator+=(std::vector<_T>& _a, std::vector<_T> const& _
}
/// Concatenate two vectors of elements. _T must be POD.
template <class _T>
inline std::vector<_T> operator+(std::vector<_T> const& _a, std::vector<_T> const& _b)
inline std::vector<_T> operator+(std::vector<typename std::enable_if<std::is_pod<_T>::value, _T>::type> const& _a, std::vector<_T> const& _b)
{
std::vector<_T> ret(_a);
return ret += _b;
}
/// Calculate RIPEMD-160 hash of the given message.
u160 ripemd160(bytesConstRef _message);
}

Loading…
Cancel
Save