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

Detailed Description

Outline

Purpose

Provide a representation of a 128-bit int for bitwise operations.

Classes

See also
bsl::bitset

Description

This component provides a value-semantic type, bdldfp::Uint128, that is used to represent a 128-bit unsigned integer having host-native byte order. This component also provides a set of useful bitwise manipulation operators for this type.

Usage

This section illustrates intended use of this component.

Example 1: Representing a 128 bit pattern for IPv6

Starting in 1996, the world's TCP/IP infrastructure started the move to a 128-bit addressing scheme, IPv6. IPv4 had a useful quality in that it could be represented by a single 32-bit machine word for internal routing purposes. With IPv6, the need arises to manipulate 128-bit values representing IPv6 addresses for similar routing purposes.

Suppose we need to write a function that needs to take 128-bit addresses indicating downstream routers in our network.

First, we forward declare the "addRouter" function that takes an IPv6 address indicating a router, and an IPv6 network address (a partial IP address, with trailing 0's) that the router covers:

void addRouter(bdldfp::Uint128 router, bdldfp::Uint128 network);
Definition bdldfp_uint128.h:175

Now we create a function that loads a set of networks and routers:

void setupNetwork()
{
bdldfp::Uint128 network;
network.setHigh(0x4242000042420000L);
network.setLow(0x0);
bdldfp::Uint128 router(0x000012345678ABCDL, 0xDCBA000087654321L);
void setLow(bsls::Types::Uint64 value)
Set the low order bits of this integer to the specified value.
Definition bdldfp_uint128.h:404
void setHigh(bsls::Types::Uint64 value)
Set the high order bits of this integer to the specified value.
Definition bdldfp_uint128.h:398

Finally we invoke addRouter, on our network and router.

addRouter(router, network);
}

Notice that Uint128 values can be created from high/low pairs.

Example 2: Checking a 128-bit IPv6 Network Mask

In networks, checking a network mask is a fundamental operation. A 128-bit mask can be used to indicate if an address is in a network, and where in the network an address is.

Suppose we need to decide if an address is within a network, and extract the sub-address from the IPv6 address.

First, we define a function that checks a passed IPv6 address and indicates the sub-address, and network membership:

bool checkNetworkAddress(bdldfp::Uint128 *subAddress,
bdldfp::Uint128 network,
int maskLength
bdldfp::Uint128 address)
{

Then, we compute a net mask for the specified maskLength:

bdldfp::Uint128 netMask;
for (int i = 0; i < maskLength; ++i) {
netMask |= 1;
if (i != maskLength - 1) {
netMask <<= 1;
}
}

Notice that it is possible to shift Uint128 values as if they were a native type. Meaning that it is possible to shift a Uint128 by 64-bits, or more, in single operation, because Uint128 functions just like a built-in 128-bit integer type would.

Next, we calculate whether the passed address is within the network:

bool inNetwork = network == (address & ~netMask);

Then, we compute the subAddress, if the address is in the network:

if (inNetwork) {
*subAddress = address & netMask;
}

Now, we return whether the address is in the network, and close the function:

return inNetwork
}

Finally, we call checkNetworkAddress on a test network and address:

bdldfp::Uint128 subAddress;
assert(checkNetworkAddress(
&subAddress,
bdldfp::Uint128(0xABCD424200001234L,0x22FF12345678L),
bdldfp::Uint128(0xABCD424200001234L,0x22FF00000000L),
32); // The network has a 32-bit internal address mask.
assert(subAddress == 0x12345678L);

Notice that primitive 64-bit words can be promoted to 128-bit addresses.