Skip to content

Commit

Permalink
Updates from working with HTTP Replay. (#8)
Browse files Browse the repository at this point in the history
* Fix IPMask inline.

* Fix IP parsing, linking.

* Move files.

* Fix IP formatting issues.

* Fix port byte order problem.

* Fix another port byte order problem in formatting.

* TextView: Special check on memcmp and strcasecmp for identical views.

* TextView: Tweak constructor overloads.

* BWF: Split "Optional" in to "Optional" for possibly null strings, and "If" for flag based formatting.

* BWF: Fix overload problem with in_addr_t.

* BW: Add aux_span method.

* Add Scons/Parts build files

* swoc_file: Add parent_path().

* Fix ContextNames to be thread safe in normal use.

* Prep for release 1.0.5
  • Loading branch information
SolidWallOfCode authored Apr 17, 2019
1 parent 516f8a0 commit bd0a607
Show file tree
Hide file tree
Showing 30 changed files with 738 additions and 236 deletions.
4 changes: 4 additions & 0 deletions Sconstruct
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from parts import *

Part("swoc++/swoc++.part")
Part("unit_tests/unit_tests.part")
2 changes: 1 addition & 1 deletion doc/Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ PROJECT_NAME = "LibSWOC++"
# could be handy for archiving the generated documentation or if some version
# control system is used.

PROJECT_NUMBER = "1.0.4"
PROJECT_NUMBER = "1.0.5"

# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
Expand Down
2 changes: 1 addition & 1 deletion doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
copyright = u'{}, [email protected]'.format(date.today().year)

# The full version, including alpha/beta/rc tags.
release = "1.0.4"
release = "1.0.5"
# The short X.Y version.
version = '.'.join(release.split('.', 2)[:2])

Expand Down
6 changes: 5 additions & 1 deletion swoc++/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ set(CMAKE_CXX_STANDARD 17)
include(GNUInstallDirs)

set(HEADER_FILES
include/swoc/swoc_version.h
include/swoc/BufferWriter.h
include/swoc/bwf_base.h
include/swoc/bwf_std.h
Expand All @@ -20,7 +21,8 @@ set(HEADER_FILES
include/swoc/TextView.h
include/swoc/swoc_file.h
include/swoc/swoc_meta.h
include/swoc/bwf_ip.h include/swoc/swoc_version.h)
include/swoc/bwf_ip.h
)

# These are external but required.
set(EXTERNAL_HEADER_FILES
Expand All @@ -29,9 +31,11 @@ set(EXTERNAL_HEADER_FILES

set(CC_FILES
src/bw_format.cc
src/bw_ip_format.cc
src/Errata.cc
src/swoc_ip.cc
src/MemArena.cc
src/RBTree.cc
src/swoc_file.cc
src/TextView.cc
)
Expand Down
13 changes: 13 additions & 0 deletions swoc++/include/swoc/BufferWriter.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,19 @@ class BufferWriter
/// @return The number of bytes which have not yet been written.
size_t remaining() const;

/** A memory span of the unused bytes.
*
* @return A span of the unused bytes.
*
* This is a convenience method that is identical to
* @code
* BufferWriter w;
* // ...
* MemSpan<char>{ w.aux_data(), w.remaining() };
* @endcode
*/
MemSpan<char> aux_span();

/** Increase the extent by @a n bytes.
*
* @param n Number of bytes to consume.
Expand Down
2 changes: 2 additions & 0 deletions swoc++/include/swoc/IntrusiveHashMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,8 @@ IntrusiveHashMap<H>::Bucket::clear()
_v = nullptr;
_count = 0;
_mixed_p = false;
// Need to clear these, or they persist after an expansion which breaks the active bucket list.
_link._next = _link._prev = nullptr;
}

template <typename H>
Expand Down
File renamed without changes.
22 changes: 17 additions & 5 deletions swoc++/include/swoc/TextView.h
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,6 @@ class TextView : public std::string_view
/// @cond OVERLOAD
// These methods are all overloads of other methods, defined in order to make the API more
// convenient to use. Mostly these overload @c int for @c size_t so naked numbers work as expected.
constexpr TextView(const char *ptr, int n);
self_type prefix(int n) const;
self_type take_suffix(int n);
self_type split_prefix(int n);
Expand Down Expand Up @@ -807,10 +806,6 @@ inline constexpr TextView::TextView(super_type const &that) : super_type(that) {
template <size_t N> constexpr TextView::TextView(const char (&s)[N]) : super_type(s, s[N - 1] ? N : N - 1) {}
template <size_t N> constexpr TextView::TextView(const char (&s)[N], size_t n) : super_type(s, n) {}

/// @cond OVERLOAD
inline constexpr TextView::TextView(const char *ptr, int n) : super_type(ptr, n < 0 ? 0 : n) {}
/// @endcond

inline void
TextView::init_delimiter_set(std::string_view const &delimiters, std::bitset<256> &set)
{
Expand Down Expand Up @@ -1643,6 +1638,11 @@ transform_view_of(V const &v)
}
/// @endcond

/** User literals for TextView.
*
* - _tv : TextView
* - _sv : std::string_view
*/
namespace literals
{
/** Literal constructor for @c std::string_view.
Expand All @@ -1656,6 +1656,18 @@ namespace literals
* so hopefully someday this can be removed.
*/
constexpr std::string_view operator"" _sv(const char *s, size_t n) { return {s, n}; }

/** Literal constructor for @c swoc::TextView.
*
* @param s The source string.
* @param n Size of the source string.
* @return A @c string_view
*
* @internal This is provided because the STL one does not support @c constexpr which seems
* rather bizarre to me, but there it is. Update: this depends on the version of the compiler,
* so hopefully someday this can be removed.
*/
constexpr swoc::TextView operator"" _tv(const char *s, size_t n) { return {s, n}; }
} // namespace literals

}; // namespace swoc
Expand Down
71 changes: 48 additions & 23 deletions swoc++/include/swoc/bwf_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,8 @@ namespace bwf
* @tparam F The function signature for generators in this container.
*
* This is a base class used by different types of name containers. It is not expected to be used
* directly. The subclass should provide a function type @a F that is suitable for its particular
* generators.
* directly. A subclass should inherit from this by providing a function type @a F that is
* suitable for the subclass generators.
*/
template <typename F> class NameMap
{
Expand Down Expand Up @@ -340,15 +340,8 @@ namespace bwf
* @a context will be the context for the binding passed to the formatter.
*
* This is used by the formatting logic by calling the @c bind method with a context object.
*
* This class doubles as a @c NameBinding, such that it passes itself to the formatting logic.
* In actual use that is more convenient for external code to overload name dispatch, which can
* then be done by subclassing this class and overriding the function operator. Otherwise most
* of the class would need to be duplicated in order to override a nested or associated binding
* class.
*
*/
template <typename T> class ContextNames : public NameMap<BufferWriter &(BufferWriter &, const Spec &, T &)>, public NameBinding
template <typename T> class ContextNames : public NameMap<BufferWriter &(BufferWriter &, const Spec &, T &)>
{
private:
using self_type = ContextNames; ///< self reference type.
Expand All @@ -364,6 +357,33 @@ namespace bwf

using super_type::super_type; // inherit @c super_type constructors.

class Binding : public NameBinding
{
public:
/** Override of virtual method to provide an implementation.
*
* @param w Output.
* @param spec Format specifier for output.
* @return @a w
*
* This is called from the formatting logic to generate output for a named specifier. Subclasses
* that need to handle name dispatch differently need only override this method.
*/
BufferWriter &
operator()(BufferWriter &w, const Spec &spec) const override
{
return _names(w, spec, _ctx);
}

protected:
Binding(ContextNames const &names, context_type &ctx) : _names(names), _ctx(ctx) {}

context_type &_ctx; ///< Context for generators.
ContextNames const &_names; ///< Base set of names.

friend ContextNames;
};

/** Assign the external generator @a bg to @a name.
*
* This is used for generators in the namespace that do not use the context.
Expand Down Expand Up @@ -391,21 +411,21 @@ namespace bwf
*
* This is used when passing the context name map to the formatter.
*/
const NameBinding &bind(context_type &context);
Binding bind(context_type &context);

protected:
/** Override of virtual method to provide an implementation.
/** Generate output based on the name in @a spec.
*
* @param w Output.
* @param spec Format specifier for output.
* @param ctx The context object.
* @return @a w
*
* This is called from the formatting logic to generate output for a named specifier. Subclasses
* that need to handle name dispatch differently need only override this method.
* that need to handle name dispatch differently should override this method. This method
* performs a name lookup in the local nameset.
*/
BufferWriter &operator()(BufferWriter &w, const Spec &spec) const override;

context_type *_ctx = nullptr; ///< Context for generators.
virtual BufferWriter &operator()(BufferWriter &w, const Spec &spec, context_type &ctx) const;
};

/** Default global names.
Expand Down Expand Up @@ -501,22 +521,21 @@ namespace bwf
}

template <typename T>
inline const NameBinding &
ContextNames<T>::bind(context_type &ctx)
inline auto
ContextNames<T>::bind(context_type &ctx) -> Binding
{
_ctx = &ctx;
return *this;
return {*this, ctx};
}

template <typename T>
BufferWriter &
ContextNames<T>::operator()(BufferWriter &w, const Spec &spec) const
ContextNames<T>::operator()(BufferWriter &w, const Spec &spec, context_type &ctx) const
{
if (!spec._name.empty()) {
if (auto spot = super_type::_map.find(spec._name); spot != super_type::_map.end()) {
spot->second(w, spec, *_ctx);
spot->second(w, spec, ctx);
} else {
this->err_invalid_name(w, spec);
NameBinding::err_invalid_name(w, spec);
}
}
return w;
Expand Down Expand Up @@ -832,6 +851,12 @@ BufferWriter::print_n(Binding const &names, TextView const &fmt)
return print_nfv(names, bwf::Format::bind(fmt), std::make_tuple());
}

inline MemSpan<char>
BufferWriter::aux_span()
{
return {this->aux_data(), this->remaining()};
}

// ---- Formatting for specific types.

// Must be first because it is used by other formatters, and is not inline.
Expand Down
6 changes: 3 additions & 3 deletions swoc++/include/swoc/bwf_ex.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,15 +134,15 @@ namespace bwf
* extra tag with delimiters, e.g. "[tag]", was to be generated, this could be done with
*
* @code
* w.print("Some other text{}.", bwf::Optional(flag, " [{}]", tag));
* w.print("Some other text{}.", bwf::If(flag, " [{}]", tag));
* @endcode
*
* @internal To disambiguate overloads, this is enabled only if there is at least one argument
* to be passed to the format string.
*/
template <typename... Args>
auto
Optional(bool flag, TextView const &fmt, Args &&... args) -> typename std::enable_if<sizeof...(Args), SubText<Args...>>::type
SubText<Args...>
If(bool flag, TextView const &fmt, Args &&... args)
{
return SubText<Args...>(flag ? fmt : TextView{}, std::forward_as_tuple(args...));
}
Expand Down
10 changes: 9 additions & 1 deletion swoc++/include/swoc/bwf_ip.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,20 @@
#pragma once

#include "swoc/bwf_base.h"
#include "swoc/swoc_ip.h"
#include <netinet/in.h>

namespace swoc
{
BufferWriter &bwformat(BufferWriter &w, bwf::Spec const &spec, sockaddr const *addr);
BufferWriter &bwformat(BufferWriter &w, bwf::Spec const &spec, in_addr_t addr);
BufferWriter &bwformat(BufferWriter &w, bwf::Spec const &spec, in_addr const &addr);
BufferWriter &bwformat(BufferWriter &w, bwf::Spec const &spec, in6_addr const &addr);
BufferWriter &bwformat(BufferWriter &w, bwf::Spec const &spec, IPAddr const &addr);
BufferWriter &bwformat(BufferWriter &w, bwf::Spec const &spec, sockaddr const *addr);
inline BufferWriter &
bwformat(BufferWriter &w, bwf::Spec const &spec, IPEndpoint const &addr)
{
return bwformat(w, spec, &addr.sa);
}

} // namespace swoc
1 change: 1 addition & 0 deletions swoc++/include/swoc/bwf_std.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#pragma once

#include <atomic>
#include <chrono>
#include "swoc/bwf_base.h"

namespace std
Expand Down
2 changes: 2 additions & 0 deletions swoc++/include/swoc/swoc_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ namespace file
/// Check if the path is not absolute.
bool is_relative() const;

self_type parent_path() const;

/// Access the path explicitly.
char const *c_str() const;

Expand Down
Loading

0 comments on commit bd0a607

Please sign in to comment.