Skip to content
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

Charset, auto annotation, IPAddr fix. #91

Merged
merged 3 commits into from
Nov 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
94 changes: 82 additions & 12 deletions code/include/swoc/Errata.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#include "swoc/MemSpan.h"
#include "swoc/MemArena.h"
#include "swoc/bwf_base.h"
#include "swoc/bwf_std.h"
#include "swoc/IntrusiveDList.h"

namespace swoc { inline namespace SWOC_VERSION_NS {
Expand Down Expand Up @@ -85,6 +86,10 @@ class Errata {
/// This defaults to zero and no filtering is done unless it is overwritten.
static Severity FILTER_SEVERITY;

static inline TextView AUTOTEXT_SEVERITY = "{}"; ///< Format for auto generated annotation with severity.
static inline TextView AUTOTEXT_CODE = "{}"; ///< Format for auto generated annotation with error code.
static inline TextView AUTOTEXT_SEVERITY_CODE = "{}: {}"; ///< Format for auto generate annotation with error code and severity.

/// Mapping of severity to string.
/// Values larger than the span size will be rendered as numbers.
/// Defaults to an empty span, meaning all severities will be printed as integers.
Expand Down Expand Up @@ -195,29 +200,79 @@ class Errata {
TextView _indent_text = DEFAULT_INDENT_TEXT;
bool _glue_final_p = true; ///< Add glue after the last annotation?

std::optional<Severity> _severity; ///< Severity.
code_type _code{Errata::DEFAULT_CODE}; ///< Message code / ID
Container _notes; ///< The message stack.
swoc::MemArena _arena; ///< Annotation text storage.
std::optional<Severity> _severity; ///< Severity.
code_type _code{DEFAULT_CODE}; ///< Message code / ID
Container _notes; ///< The message stack.
swoc::MemArena _arena; ///< Annotation text storage.
};

public:
/// Used to indicate automatically generated annotation text.
static constexpr struct AutoText {
} AUTO{};

/// Default constructor - empty errata, very fast.
Errata() = default;
Errata(self_type const &that) = delete; ///< No constant copy construction.
Errata(self_type const &that) = delete; ///< No copy construction.
Errata(self_type &&that) noexcept; ///< Move constructor.
self_type &operator=(self_type const &that) = delete; // no copy assignemnt.
self_type &operator=(self_type const &that) = delete; // no copy assignment.
self_type &operator=(self_type &&that); ///< Move assignment.
~Errata(); ///< Destructor.

/** Construct with an error code.
*
* @param ec Error code
*
* No annotation is created.
*/
explicit Errata(code_type const &ec);

/** Construct with an error code and generated annotation.
*
* @param ec Error code
*
* An annotation is created using the format @c AUTOTEXT_CODE with @a ec as the argument.
* @see AUTOTEXT_CODE
*/
explicit Errata(code_type const &ec, AutoText);

/** Construct with a severity.
*
* @param severity Severity.
*
* No annotations are created.
* No annotation is created.
*/
explicit Errata(Severity severity);

/** Construct with a severity.
*
* @param severity Severity.
*
* An annotation is created using the format @c AUTO_TEXT_SEVERITY with @a severity as the argument.
* @see AUTOTEXT_SEVERITY
*/
explicit Errata(Severity severity, AutoText);

/** Construct with error code and severity.
*
* @param ec Error code.
* @param severity Severity.
*
* No annotation is created.
*/
Errata(code_type const &ec, Severity severity);

/** Construct with a severity and error code.
*
* @param severity Severity.
* @param ec Error code.
* @param auto_text If present, generate an annotation.
*
* The annotation uses the format @c AUTOTEXT_SEVERITY_CODE with arguments @a severity , @a ec
* @see AUTOTEXT_SEVERITY_CODE
*/
explicit Errata(code_type const &ec, Severity severity, AutoText auto_text);

/** Constructor.
*
* @param code Error code.
Expand Down Expand Up @@ -613,9 +668,6 @@ class Errata {
std::ostream &write(std::ostream &out) const;

protected:
/// Construct with code and severity, but no annotations.
Errata(code_type const &code, Severity severity);

/// Implementation instance.
/// @internal Because this is used with a self-containing @c MemArena standard smart pointers do not
/// work correctly. Instead the @c clear method must be used to release the memory.
Expand Down Expand Up @@ -979,14 +1031,32 @@ inline Errata::Errata(self_type &&that) noexcept {
std::swap(_data, that._data);
}

inline Errata::Errata(code_type const &ec) {
this->data()->_code = ec;
}

inline Errata::Errata(Severity severity) {
this->data()->_severity = severity;
}

inline Errata::Errata(const code_type &code, Severity severity) {
inline Errata::Errata(const code_type &ec, Severity severity) {
auto d = this->data();
d->_severity = severity;
d->_code = code;
d->_code = ec;
}

inline Errata::Errata(code_type const &ec, AutoText) {
this->data()->_code = ec;
this->note(AUTOTEXT_CODE, ec);
}

inline Errata::Errata(Severity severity, AutoText) {
this->data()->_severity = severity;
this->note(AUTOTEXT_SEVERITY, severity);
}

inline Errata::Errata(const code_type &ec, Severity severity, AutoText) : Errata(ec, severity) {
this->note(AUTOTEXT_SEVERITY_CODE, severity, ec);
}

inline Errata::Errata(const code_type &code, Severity severity, const std::string_view &text) : Errata(code, severity) {
Expand Down
2 changes: 1 addition & 1 deletion code/include/swoc/IPAddr.h
Original file line number Diff line number Diff line change
Expand Up @@ -579,7 +579,7 @@ class IPAddr {
* @param sa Destination.
* @return @a sa
*/
sockaddr *copy_to(sockaddr *sa);
sockaddr *copy_to(sockaddr *sa) const;

/** Parse a string and load the result in @a this.
*
Expand Down
91 changes: 70 additions & 21 deletions code/include/swoc/TextView.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,23 @@ namespace swoc { inline namespace SWOC_VERSION_NS {

class TextView;

/** A set of characters.
*
*/
class CharSet {
using self_type = CharSet;

public:
constexpr CharSet(TextView const &chars);
bool
operator()(u_char idx) const {
return _chars[idx];
}

protected:
std::bitset<256> _chars;
};

/** A read only view of a contiguous piece of memory.

A @c TextView does not own the memory to which it refers, it is simply a view of part of some
Expand Down Expand Up @@ -324,6 +341,12 @@ class TextView : public std::string_view {
*/
self_type &ltrim(char c);

/** Remove bytes from the start of the view that are in @a delimiters.
*
* @return @a this
*/
self_type &ltrim(CharSet const &delimiters);

/** Remove bytes from the start of the view that are in @a delimiters.
*
* @return @a this
Expand All @@ -350,6 +373,12 @@ class TextView : public std::string_view {
*/
self_type &rtrim(char c);

/** Remove bytes from the end of the view that are in @a delimiters.
*
* @return @a this
*/
self_type &rtrim(CharSet const &delimiters);

/** Remove bytes from the end of the view that are in @a delimiters.
* @return @a this
*/
Expand All @@ -369,6 +398,11 @@ class TextView : public std::string_view {
*/
self_type &trim(char c);

/** Remove bytes from the start and end of the view that are in @a delimiters.
* @return @a this
*/
self_type &trim(CharSet const &delimiters);

/** Remove bytes from the start and end of the view that are in @a delimiters.
* @return @a this
*/
Expand Down Expand Up @@ -1052,6 +1086,12 @@ double svtod(TextView text, TextView *parsed = nullptr);
// simpler plain @c TextView ? Because otherwise Doxygen can't match up the declaration and
// definition and the reference documentation is messed up. Sigh.

inline constexpr CharSet::CharSet(TextView const &chars) {
for (auto c : chars) {
_chars[u_char(c)] = true;
}
}

// === TextView Implementation ===
/// @cond TextView_INTERNAL
// Doxygen doesn't match these up well due to various type and template issues.
Expand Down Expand Up @@ -1474,62 +1514,71 @@ TextView::trim(char c) {
}

inline TextView &
TextView::ltrim(std::string_view const &delimiters) {
std::bitset<256> valid;
this->init_delimiter_set(delimiters, valid);
const char *spot;
const char *limit;
TextView::ltrim(CharSet const &delimiters) {
const char *spot = this->data();
const char *limit = this->data_end();

for (spot = this->data(), limit = this->data_end(); spot < limit && valid[static_cast<uint8_t>(*spot)]; ++spot)
;
while (spot < limit && delimiters(*spot)) {
++spot;
}
this->remove_prefix(spot - this->data());

return *this;
}

inline TextView &
TextView::ltrim(std::string_view const &delimiters) {
return this->ltrim(CharSet(delimiters));
}

inline TextView &
TextView::ltrim(const char *delimiters) {
return this->ltrim(std::string_view(delimiters));
return this->ltrim(CharSet(delimiters));
}

inline TextView &
TextView::rtrim(std::string_view const &delimiters) {
std::bitset<256> valid;
this->init_delimiter_set(delimiters, valid);
TextView::rtrim(CharSet const &delimiters) {
const char *spot = this->data_end();
const char *limit = this->data();

while (limit < spot-- && valid[static_cast<uint8_t>(*spot)])
;
while (limit < spot-- && delimiters(*spot)) {
}

this->remove_suffix(this->data_end() - (spot + 1));
return *this;
}

inline TextView &
TextView::trim(std::string_view const &delimiters) {
std::bitset<256> valid;
this->init_delimiter_set(delimiters, valid);
TextView::rtrim(std::string_view const &delimiters) {
return this->rtrim(CharSet(delimiters));
}

inline TextView &
TextView::trim(CharSet const &delimiters) {
const char *spot;
const char *limit;

// Do this explicitly, so we don't have to initialize the character set twice.
for (spot = this->data(), limit = this->data_end(); spot < limit && valid[static_cast<uint8_t>(*spot)]; ++spot)
for (spot = this->data(), limit = this->data_end(); spot < limit && delimiters(*spot); ++spot)
;
this->remove_prefix(spot - this->data());

spot = this->data_end();
limit = this->data();
while (limit < spot-- && valid[static_cast<uint8_t>(*spot)])
;
while (limit < spot-- && delimiters(*spot)) {
}
this->remove_suffix(this->data_end() - (spot + 1));

return *this;
}

inline TextView &
TextView::trim(std::string_view const &delimiters) {
return this->trim(CharSet(delimiters));
}

inline TextView &
TextView::trim(const char *delimiters) {
return this->trim(std::string_view(delimiters));
return this->trim(CharSet(delimiters));
}

template <typename F>
Expand Down
4 changes: 1 addition & 3 deletions code/src/bw_format.cc
Original file line number Diff line number Diff line change
Expand Up @@ -905,8 +905,7 @@ bwformat(BufferWriter &w, bwf::Spec const &spec, std::error_code const &ec) {

// This provides convenient safe access to the errno short name array.
static const swoc::bwf::Format number_fmt{"[{}]"_sv}; // numeric value format.
if (spec.has_numeric_type()) {
// if numeric type, print just the numeric part.
if (spec.has_numeric_type()) { // if numeric type, print just the numeric part.
bwformat(w, spec, ec.value());
} else {
if ((&ec.category() == G_CAT || &ec.category() == S_CAT) && swoc::ERRNO_RANGE.contains(ec.value())) {
Expand All @@ -915,7 +914,6 @@ bwformat(BufferWriter &w, bwf::Spec const &spec, std::error_code const &ec) {
w.write(ec.message());
}
if (spec._type != 's' && spec._type != 'S') {
bwformat(w, spec, ec.value());
w.write(' ').write('[').format(spec, ec.value()).write(']');
}
}
Expand Down
2 changes: 1 addition & 1 deletion code/src/swoc_ip.cc
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ IPAddr::operator=(IPEndpoint const &addr) {
}

sockaddr *
IPAddr::copy_to(sockaddr *sa) {
IPAddr::copy_to(sockaddr *sa) const {
if (this->is_ip4()) {
_addr._ip4.copy_to(sa);
} else if (this->is_ip6()) {
Expand Down
Loading