BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlb_indexspanutil

Detailed Description

Outline

Purpose

Provide functions that operate on IndexSpan objects.

Classes

See also
bdlb_indexspan

Description

This component provides a struct, IndexSpanUtil, that serves as a namespace for utility functions that operate on IndexSpan objects. At the moment the only function provided is shrink, and it creates a new IndexSpan that represents a (possibly) smaller span than the argument.

Usage

This section illustrates intended use of this component.

Example1: Taking a IPv6 address out of a URI

Suppose we have a class that stores a parsed URL using a string to store the full URL and IndexSpan objects to describe the individual parts of the URL, and we want to add accessors that handle the case when the host part of the URL is an IPv6 address, such as "http://[ff:fe:9]/index.html". As observed, an IPv6 address is indicated by the [ and ] characters (the URL is ill formed if the closing ] is not present). We want to implement two methods, one to query if the host part of the URL is IPv6 (isIPv6Host) and another to get the IPv6 address (the part without the square brackets) if the host is actually an IPv6 address (getIPv6Host).

First, let us create a ParsedUrl class. For brevity, the class has only those parts that are needed to implement isIPv6Host and getIPv6Host.

class ParsedUrl {
private:
// DATA
bsl::string d_url;
public:
// CREATORS
/// Create a `ParsedUrl` from the specified `url`, and `host`.
ParsedUrl(const bslstl::StringRef& url, bdlb::IndexSpan host)
: d_url(url)
, d_host(host)
{
}
// ACCESSORS
/// Return `true` if the host part represents an IPv6 address and
/// `false` otherwise.
bool isIPv6Host() const;
/// Return a string reference to the IPv6 address in the host part
/// of this URL. The behavior is undefined unless
/// `isIPv6Host() == true` for this object.
bslstl::StringRef getIPv6Host() const;
};
Definition bdlb_indexspan.h:309
Definition bslstl_string.h:1281
Definition bslstl_stringref.h:372

Next, we implement isIPv6Host.

bool ParsedUrl::isIPv6Host() const
{
return !d_host.isEmpty() && '[' == d_url[d_host.position()];
}

Then, to make the accessors simple (and readable), we implement a helper function that creates a StringRef from a StringRef and an IndexSpan. (Don't do this in real code, use IndexSpanStringUtil::bind that is levelized above this component - so we cannot use it here.)

/// Return a string reference to the substring of the specified `full`
/// thing defined by the specified `part`.
bslstl::StringRef bindSpan(const bslstl::StringRef& full,
const bdlb::IndexSpan& part)
{
BSLS_ASSERT(part.position() <= full.length());
BSLS_ASSERT(part.position() + part.length() <= full.length());
return bslstl::StringRef(full.data() + part.position(), part.length());
}
size_type position() const
Return the position attribute.
Definition bdlb_indexspan.h:448
size_type length() const
Return the length attribute.
Definition bdlb_indexspan.h:442
const CHAR_TYPE * data() const
Definition bslstl_stringref.h:936
size_type length() const
Definition bslstl_stringref.h:958
#define BSLS_ASSERT(X)
Definition bsls_assert.h:1804
StringRefImp< char > StringRef
Definition bslstl_stringref.h:699

Next, we implement getIPv6Host using bdlb::IndexSpanUtil::shrink.

bslstl::StringRef ParsedUrl::getIPv6Host() const
{
BSLS_ASSERT(isIPv6Host());
return bindSpan(d_url, bdlb::IndexSpanUtil::shrink(d_host, 1, 1));
}
static IndexSpan shrink(const IndexSpan &original, IndexSpan::size_type shrinkBegin, IndexSpan::size_type shrinkEnd)
Definition bdlb_indexspanutil.h:188

Finally, we verify the two methods with URLs.

ParsedUrl pu1("https://host/path/", bdlb::IndexSpan(8, 4));
assert(false == pu1.isIPv6Host());
ParsedUrl pu2("https://[12:3:fe:9]/path/", bdlb::IndexSpan(8, 11));
assert(true == pu2.isIPv6Host());
assert("12:3:fe:9" == pu2.getIPv6Host());