Mapping the HTMLTidy library into the Application
Once again, we create a custom STL exception type to represent failure
from the HTMLTidy library. We also create an app
namespace wrapper
for the C tidy_html()
function which is more C++ friendly.
namespace app
{
// Specialise an exception type for tidylib errors
struct tidylib_error : std::system_error
{
// passthrough
using std::system_error::system_error;
tidylib_error() = default;
explicit tidylib_error(int c)
: std::system_error(c, std::generic_category())
{
}
};
// Create a C++ invoking wrapper for the tidylib C API, modifying data with the returned data,
// returing a unique_ptr to release storage on scope exit.
struct call_free
{
template <class T> void operator()(T *p) { ::free(p); }
};
inline outcome<std::unique_ptr<char, call_free>> tidy_html(string_view &data)
{
char *out = nullptr;
size_t outlen = 0;
int errcode = ::tidy_html(&out, &outlen, data.data(), data.size());
if(errcode != 0)
{
// If the error code matches a standard STL exception, throw as that.
BOOST_OUTCOME_V2_NAMESPACE::try_throw_std_exception_from_error(std::error_code(errcode, std::generic_category()));
// Otherwise wrap the error code into a tidylib_error exception throw
return std::make_exception_ptr(tidylib_error(errcode));
}
// Reset input view to tidied html
data = string_view(out, outlen);
// Return a unique ptr to release storage on scope exit
return std::unique_ptr<char, call_free>(out);
}
}