Using Data

The Data class encapsulates a buffer of bytes. It is similar in functionality to many common string classes, except that it operates on collections of bytes instead of collections of characters. In particular, Data is meant to operate on buffers that may or may not contain binary data. That said, there are a number of operations on Data which are written with manipulation of text in mind, and many methods go out of their way to ensure that the buffer is often null-terminated. It's a bit schizophrenic that way. (ed.: the null termination is useful when rooting about in the debugger).

At any given time, a Data is associated with a single buffer which contains the bytes inside the Data. This buffer may be owned by the Data object itself, or owned by an external party. Additionally, data owned by an external party can be considered changeable or unchangeable.

Sharing Style

Buffer Ownership

Buffer Mutable?

Share

External to Data class

No

Borrow

External to Data class

Yes

Take

Owned by Data class

Yes

If a Data containing an immutable buffer (i.e. Sharing Mode is Share) is changed, then a new buffer is allocated by the Data, the contents of the existing (immutable) buffer are copied into it, and the modification is performed on the new buffer. This newly allocated buffer is owned by the Data.

If a modification is performed on a Data which requires more space than is available in the underlying buffer, then a larger buffer is allocated, the existing bytes are copied into the new buffer, and the modification is performed on the new buffer. If the old buffer was owned by the Data, it will be deallocated.

Note that all deallocation performed by the Data uses delete[]; consequently, any data owned by the Data (e.g. Sharing Mode is Take) must be allocated from the normal heap using new[], lest you anger the portability gods.

Finally, users of Data should note that a Data created from a buffer with Share or Borrow sharing must not outlive the buffer itself.

Data conveniently has fifteen non-deprecated constructors for your creation pleasure. The default constructor will ultimately cause the Data to allocate its own internal memory. The copy constuctor does pretty much what you expect it to do.

If none of the preceding methods give you the tools that you need to convert from another data type, you can use the "Data::from" class method to create the Data you want. The only requirement is that the type that you're creating the Data from has an associated streaming operator. This is particularly useful if you want to create a Data from a non-primitive data type.

The easiest way to create a Data from an existing buffer is to pass in a buffer and the number of bytes of meaningful data that exist in the buffer. This constructor operates in "Take" mode -- the Data will copy the passed-in buffer immediately.

Alternately, you can explicitly indicate the sharing mode desired; once again, the length indictated is the number of meaninful bytes already present in the buffer, not the total length of the buffer. No constructor yet exists which allows you to indicate both the number of meaningful bytes and the total length of the buffer; if you have a need for such a constructor, though, it should be easy to add one. (ed. allocate the desired size buffer and append the bytes you want)

If you are creating a Data from a c-style null-terminated string, you are given the option of indicating a sharing mode also. Be very, very careful that your c-style string is null terminated if you use this constructor.

Converts from any type T that supports the insertion operator<< to Data. This construct is used chiefly for debugging. Conversions like this can usually be handled more efficiently with direct use of DataStream.

These methods are used by Data to generate hash values for use in hash tables. The methods are publically available to aid the creation of custom hashes on other types with contiguous bytes. There are slightly faster hash functions, but these are quite fast, have provable good distribution properties, and can be varied for security purposes.