diff options
author | Nat Goodspeed <nat@lindenlab.com> | 2023-10-04 21:46:31 -0400 |
---|---|---|
committer | Nat Goodspeed <nat@lindenlab.com> | 2023-10-04 21:46:31 -0400 |
commit | 01a59bab1a4b7c4645271a21cfaadc3735b6029c (patch) | |
tree | abd2d4035d8e43998b9778f39c8de06bc62a7549 /indra/llcommon | |
parent | 2705e2bb5bb0fbd66958f83987c355e5d3f93c7b (diff) |
DRTVWR-589: Add tests for LLSD-to-Lua round-trip conversions.
Add from_lua() function to run a small Lua script that constructs a specified
Lua object and posts it back to the test program via a temporary LLEventPump.
Call this with a variety of Lua objects, comparing to the expected LLSD.
Add round_trip() function to run another small Lua script that listens for
incoming LLEventPump events and, for each, posts the received Lua data back to
the test program as LLSD. Call this with a variety of LLSD objects, comparing
to the expected LLSD. Also collect these objects into an LLSD array and send
that for a round trip; also collect into an LLSD map and send that.
Sadly, tests currently drive an access violation when trying to convert a
nested Lua table to LLSD.
Add verbose debug logging to lua_tollsd() to identify the context at which we
hit the access violation.
Add comments describing further exceptions to LLSD-to-Lua round trip identity.
Add lua_what() iostream manipulator to stream whatever we can readily
discover about a value at a specified Lua stack index.
Add lua_stack() to report the contents of the Lua stack. Since the stack is
created anew for every call to a C function, this shouldn't usually be
enormous.
Add hexdump.h with iostream manipulators to dump a byte range as hex digits,
or to produce readable text from a mix of printing and nonprinting ASCII
characters.
Diffstat (limited to 'indra/llcommon')
-rwxr-xr-x | indra/llcommon/hexdump.h | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/indra/llcommon/hexdump.h b/indra/llcommon/hexdump.h new file mode 100755 index 0000000000..234168cd61 --- /dev/null +++ b/indra/llcommon/hexdump.h @@ -0,0 +1,106 @@ +/** + * @file hexdump.h + * @author Nat Goodspeed + * @date 2023-10-03 + * @brief iostream manipulators to stream hex, or string with nonprinting chars + * + * $LicenseInfo:firstyear=2023&license=viewerlgpl$ + * Copyright (c) 2023, Linden Research, Inc. + * $/LicenseInfo$ + */ + +#if ! defined(LL_HEXDUMP_H) +#define LL_HEXDUMP_H + +#include <cctype> +#include <iomanip> +#include <iostream> +#include <string_view> + +namespace LL +{ + +// Format a given byte string as 2-digit hex values, no separators +// Usage: std::cout << hexdump(somestring) << ... +class hexdump +{ +public: + hexdump(const std::string_view& data): + hexdump(data.data(), data.length()) + {} + + hexdump(const char* data, size_t len): + hexdump(reinterpret_cast<const unsigned char*>(data), len) + {} + + hexdump(const std::vector<unsigned char>& data): + hexdump(data.data(), data.size()) + {} + + hexdump(const unsigned char* data, size_t len): + mData(data, data + len) + {} + + friend std::ostream& operator<<(std::ostream& out, const hexdump& self) + { + auto oldfmt{ out.flags() }; + auto oldfill{ out.fill() }; + out.setf(std::ios_base::hex, std::ios_base::basefield); + out.fill('0'); + for (auto c : self.mData) + { + out << std::setw(2) << unsigned(c); + } + out.setf(oldfmt, std::ios_base::basefield); + out.fill(oldfill); + return out; + } + +private: + std::vector<unsigned char> mData; +}; + +// Format a given byte string as a mix of printable characters and, for each +// non-printable character, "\xnn" +// Usage: std::cout << hexmix(somestring) << ... +class hexmix +{ +public: + hexmix(const std::string_view& data): + mData(data) + {} + + hexmix(const char* data, size_t len): + mData(data, len) + {} + + friend std::ostream& operator<<(std::ostream& out, const hexmix& self) + { + auto oldfmt{ out.flags() }; + auto oldfill{ out.fill() }; + out.setf(std::ios_base::hex, std::ios_base::basefield); + out.fill('0'); + for (auto c : self.mData) + { + // std::isprint() must be passed an unsigned char! + if (std::isprint(static_cast<unsigned char>(c))) + { + out << c; + } + else + { + out << "\\x" << std::setw(2) << unsigned(c); + } + } + out.setf(oldfmt, std::ios_base::basefield); + out.fill(oldfill); + return out; + } + +private: + std::string mData; +}; + +} // namespace LL + +#endif /* ! defined(LL_HEXDUMP_H) */ |