Quick Links:

bal | bbl | bdl | bsl

Namespaces

Component bdlb_indexspanutil
[Package bdlb]

Provide functions that operate on IndexSpan objects. More...

Namespaces

namespace  bdlb

Detailed Description

Outline
Purpose:
Provide functions that operate on IndexSpan objects.
Classes:
bdlb::IndexSpanUtil namespace for functions that operate on IndexSpan
See also:
Component 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 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;
      bdlb::IndexSpan d_host;

    public:
      // CREATORS
      ParsedUrl(const bslstl::StringRef& url, bdlb::IndexSpan host)
          // Create a 'ParsedUrl' from the specified 'url', and 'host'.
      : d_url(url)
      , d_host(host)
      {
      }

      // ACCESSORS
      bool isIPv6Host() const;
          // Return 'true' if the host part represents an IPv6 address and
          // 'false' otherwise.

      bslstl::StringRef getIPv6Host() 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.
  };
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.)
  bslstl::StringRef bindSpan(const bslstl::StringRef& full,
                             const bdlb::IndexSpan&   part)
      // Return a string reference to the substring of the specified 'full'
      // thing defined by the specified 'part'.
  {
      BSLS_ASSERT(part.position() <= full.length());
      BSLS_ASSERT(part.position() + part.length() <= full.length());

      return bslstl::StringRef(full.data() + part.position(), part.length());
  }
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));
  }
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());