# API

[TOC]

## Example

This example shows how to use **Get-Printer-Attributes** operation to get value
of **printer-make-and-model** from the printer:

```c++
std::string url = "ipp://my.printer/ipp";
std::vector<uint8_t> frame; // this is a buffer for IPP frames

ipp::Frame request(ipp::Operation::Get_Printer_Attributes);
request.Groups(ipp::GroupTag::operation_attributes)[0].AddAttr("printer-uri", ipp::ValueTag::uri, url);

frame = ipp::BuildBinaryFrame(request)

// ... Now you have to send the content of frame as a payload in HTTP POST
// ... request with content-type set to application/ipp.
// ... Then you have to retrieve a payload from obtained HTTP response and
// ... save it to the buffer frame. Remember to check for HTTP errors.

ipp::SimpleParserLog log;
ipp::Frame response = ipp::Parse(frame.data(), frame.size(), log);
if (!log.CriticalErrors().empty()) {
  // critical parsing error
  return false;
}
auto coll = response.Groups(ipp::GroupTag::operation_attributes)[0];
auto it = coll.GetAttr("printer-make-and-model");
if (it == coll.end()) {
  std::cout << "Not included in the response :(\n";
} else {
  std::string mam;
  it->GetValue(&mam);
  std::cout << mam << "\n";
}
```

In `ipp_test.cc` in tests `example1`-`example9` you can find more examples how
to build IPP frames.

> NOTE: The following attributes from the group **operation-attributes** are set
> automatically:
>
> *   **attributes-charset**: set to `"utf-8"`
> *   **attributes-natural-language**: set to `"en-us"`.


> WARNING: If the method `SimpleParserLog::CriticalErrors()` returns a non-empty
> vector it means that the parser did not finish parsing because of an error
> in the input data. In this case, returned `Frame` object contains only parsed
> part of the frame; in the worst-case scenario the returned object may be
> empty. If the parser was able to parse the whole frame the method
> `SimpleParserLog::CriticalErrors()` returns an empty vector. Even then, the
> method `SimpleParserLog::Errors()` can return a non-empty vector with some
> errors. This is because the parser can recover from many local errors in IPP
> frames by skipping incorrect values or attributes. These non-critical errors
> are also logged to `ParserLog`, but they do not abort parsing. Unfortunately,
> there is significant amount of printers that return IPP frames with this kind
> of non-critical errors.

## Parser

The parser function is declared in the header `parser.h`.

```c++
// Parse the frame of `size` bytes saved in `buffer`. Errors detected by the
// parser are saved to `log`. The returned object is always valid. In the
// worst case scenario (nothing was parsed), the returned frame is empty
// and has all basic parameters set to zeroes like after Frame() constructor.
// In case of parsing errors, some groups or attributes from the input buffer
// may be omitted. You should examine the content of ParserLog to make sure
// that the whole input frame was parsed.
Frame Parse(const uint8_t* buffer, size_t size, ParserLog& log);
```

The function takes as an input a buffer of `size` bytes with an IPP frame (this
is probably a payload of a HTTP request), tries to parse it and returns parsed
content as a `Frame` object.
Errors detected by the parser are saved to `log` which implements the following
interface:

```c++
class ParserLog {
  /* ... */
  ParserLog(const ParserLog&) = delete;
  ParserLog& operator=(const ParserLog&) = delete;
  /* ... */

  // Reports an `error` when parsing an element pointed by `path`.
  virtual void AddParserError(const AttrPath& path, ParserCode error) = 0;

  // Reports that parsing was finished successfully. Calling it means that the
  // parser reached the marker of the end of the frame and the parsed structure
  // is valid. It is be called even if some minor errors were reported earlier.
  virtual void ReportSuccessfulEndOfParsing() = 0;
};
```

There is a predefined class `SimpleParserLog` that implements this interface and
allows to browse reported errors:

```c++
class SimpleParserLog : public ParserLog {
  /* ... */
  struct Entry {
    AttrPath path;
    ParserCode error;
    /* ... */
  };
  explicit SimpleParserLog(size_t max_entries_count = 100);
  /* ... */

  // Returns all entries added by AddParserError() in the same order they were
  // added. The log is truncated <=> the number of entries reached the value
  // `max_entries_count` passed to the constructor.
  const std::vector<Entry>& Entries() const;

  // Returns true <=> ReportSuccessfulEndOfParsing() was called.
  bool ParserFinishSuccessfully() const;
  ...
};
```

> WARNING: The log is truncated when the number of entries reach the threshold
> specified in the constructor.

## Builder

The header `builder.h` contains the following functions:

```c++
// Return the size of the binary representation of the frame in bytes.
size_t CalculateLengthOfBinaryFrame(const Frame& frame);

// Save the binary representation of the frame to the given buffer. Use
// CalculateLengthOfBinaryFrame() function before calling this method to make
// sure that the given buffer is large enough. The method returns the number of
// bytes written to `buffer` or 0 when `buffer_length` is smaller than binary
// representation of the frame.
size_t BuildBinaryFrame(const Frame& frame, uint8_t* buffer, size_t buffer_length);

// Return the binary representation of the frame as a vector.
std::vector<uint8_t> BuildBinaryFrame(const Frame& frame);
```

Function `BuildBinaryFrame()` returns binary representation of the given frame
that is ready to be sent as a payload in a HTTP frame.

## Validator

Validator checks if the values contained in the given `Frame` object meet the
criteria required by IPP standard.
All frames sent to other parties should pass the validator without producing any
errors to ensure full compatibility.
Errors detected by the validator in incoming frames may be logged for
informational purposes.

To use the validator you have to include the header `validator.h`.
It contains the following declarations:

```c++
// Validates all groups in the `frame`. All detected errors are saved in `log`
// in the order they occur in the original frame. The function returns true <=>
// no errors were detected.
// For string types only the basic features are validated, there is no UTF-8
// parsing or type-specific parsing like URL or MIME types.
bool Validate(const Frame& frame, ErrorsLog& log);
```

The `log` is the abstract interface:

```c++
class ErrorsLog {
 public:
  ErrorsLog(const ErrorsLog&) = delete;
  ErrorsLog& operator=(const ErrorsLog&) = delete;
  /* ... */

  // Reports an `error` for the attribute at `path`. The errors are reported in
  // the same order as they occurred in the frame. Return false if do not want
  // to get any more AddValidationError() calls.
  virtual bool AddValidationError(const AttrPath& path, AttrError error) = 0;
};
```

A simple implementation of this interface is also provided:

```c++
// Simple implementation of the ErrorsLog interface. It just saves the first
// `max_entries_count` (see the constructor) errors in the frame.
class SimpleLog : public ErrorsLog {
 public:
  struct Entry {
    AttrPath path;
    AttrError error;
  };
  explicit SimpleLog(size_t max_entries_count = 100);
  bool AddValidationError(const AttrPath& path, AttrError error) override;
  const std::vector<Entry>& Entries() const;
};
```

## Frame class

The `Frame` class represents an IPP frame.
The instance of this class may be obtained by calling the `Parse` function
described above or by using one of the constructors:

```c++
class Frame {
  /* ... */

  // Constructor. Create an empty frame with all basic parameters set to 0.
  Frame();

  // Constructor. Create a frame and set basic parameters for IPP request.
  // If `set_localization_en_us` is true (default) the Group Operation
  // Attributes is added to the frame with two attributes:
  //   * "attributes-charset"="utf-8"
  //   * "attributes-natural-language"="en-us"
  // If `set_localization_en_us` equals false, you have to add the Group
  // Operation Attributes with these two attributes by hand since they are
  // required to be the first attributes in the frame (see section 4.1.4 from
  // RFC 8011).
  explicit Frame(Operation operation_id,
                 Version version_number = Version::_1_1,
                 int32_t request_id = 1,
                 bool set_localization_en_us = true);

  // Constructor. The same as the previous constructor but for IPP response.
  // There is no differences between frames created with this and the previous
  // constructor. IPP requests and IPP responses have the same structure.
  // Values of operation_id and status_code are saved in the same variable,
  // they are just casted to different enums with static_cast<>(). The parameter
  // `set_localization_en_us_and_status_message` works in similar way as the
  // parameter `set_localization_en_us` in the constructor above but also adds
  // the attribute "status-message" to the Group Operation Attributes. The value
  // of the attribute is set to a string representation of the `status_code`.
  // The attribute "status-message" is defined in the section 4.1.6.2 from
  // RFC 8011.
  explicit Frame(Status status_code,
                 Version version_number = Version::_1_1,
                 int32_t request_id = 1,
                 bool set_localization_en_us_and_status_message = true);

  /* ... */
};
```

### Header

Each IPP frame has three fields in the header:

*   **operation-id** (IPP request) or **status-code** (IPP response) of type
    `int16_t`. The two enums below contain predefined values for these fields:

    ```c++
    enum class Operation : int16_t {
      Print_Job = 0x0002,
      Print_URI = 0x0003,
      Validate_Job = 0x0004,
      Create_Job = 0x0005,
      Send_Document = 0x0006,
      Send_URI = 0x0007,
      Cancel_Job = 0x0008,
      Get_Job_Attributes = 0x0009,
      /* ...
        See "operations-supported" in
        https://www.pwg.org/ipp/ipp-registrations.xml for other possible values.
        ... */
      CUPS_Get_Default = 0x4001,
      CUPS_Get_Printers = 0x4002,
      CUPS_Add_Modify_Printer = 0x4003,
      CUPS_Delete_Printer = 0x4004,
      CUPS_Get_Classes = 0x4005,
      CUPS_Add_Modify_Class = 0x4006,
      CUPS_Delete_Class = 0x4007,
      CUPS_Accept_Jobs = 0x4008,
      /* ...
        See "CUPS IPP Operations" in https://www.cups.org/doc/spec-ipp.html for
        other CUPS-specific values.
        ... */
    };

    enum class Status : int16_t {
      successful_ok = 0x0000,
      successful_ok_ignored_or_substituted_attributes = 0x0001,
      successful_ok_conflicting_attributes = 0x0002,
      successful_ok_ignored_subscriptions = 0x0003,
      successful_ok_too_many_events = 0x0005,
      successful_ok_events_complete = 0x0007,
      client_error_bad_request = 0x0400,
      client_error_forbidden = 0x0401,
      /* ...
        See "Status Codes" in
        https://www.pwg.org/ipp/ipp-registrations.xml for other possible values.
        ... */
    };
    ```

*   **version-number** that contains the version of IPP protocol.
    It is coded as two bytes. The following enum contains predefined values:

    ```c++
    enum class Version : uint16_t {
      _1_0 = 0x0100,
      _1_1 = 0x0101,
      _2_0 = 0x0200,
      _2_1 = 0x0201,
      _2_2 = 0x0202
    };
    ```

*   **request-id** - a field of type `int32_t` that should be used to match an
    IPP response to a corresponding IPP request (which is really not necessary
    for HTTP over TCP). This field is expected to have a positive value.

These three fields can also be changed/read with the following methods:

```c++
class Frame {
  /* ... */

  // Access IPP version number.
  Version& VersionNumber();
  Version VersionNumber() const;

  // Access operation id or status code. OperationId() and StatusCode() refer to
  // the same field, they just cast the same value to different enums. The field
  // is interpreted as operation id in IPP request and as status code in IPP
  // responses.
  int16_t& OperationIdOrStatusCode();
  Operation OperationId() const;
  Status StatusCode() const;

  // Access request id.
  int32_t& RequestId();
  int32_t RequestId() const;

  /* ... */
};
```

### **attribute-group** and GroupTag

The frame's header is followed by a sequence of **attribute-group**.
Each **attribute-group** is labeled by a one-byte tag that is represented in
*libipp* by the following enum:

```c++
enum class GroupTag : uint8_t {
  operation_attributes = 0x01,
  job_attributes = 0x02,
  printer_attributes = 0x04,
  unsupported_attributes = 0x05,
  subscription_attributes = 0x06,
  event_notification_attributes = 0x07,
  resource_attributes = 0x08,
  document_attributes = 0x09,
  system_attributes = 0x0a,
};

// The correct values of GroupTag are 0x01, 0x02, 0x04-0x0f. This function
// checks if given GroupTag is valid.
constexpr bool IsValid(GroupTag tag);

// This array contains all valid GroupTag values and may be used in loops like
//   for (GroupTag gt: kGroupTags) ...
constexpr std::array<GroupTag, 14> kGroupTags{ /* ... */ };
```

In the majority of cases a frame contains at most one **attribute-group** for
each `GroupTag` value.
However, the format of IPP frame allows for more than one group with the same
tag.
Some of the IPP operations use this feature and requires responses containing
a sequence of many **attribute-group** with the same `GroupTag`
(e.g.: [**Get-Jobs**](https://www.rfc-editor.org/rfc/rfc8011#section-4.2.6.2)).

### Accessing **attribute-group**

The following methods can be used to browse **attribute-group** in the `Frame`
object:

```c++
class Frame {
  /* ... */

  // Provides access to groups with the given GroupTag. You can iterate over
  // these groups in the following way:
  //   for (Collection& coll: frame.Groups(GroupTag::job_attributes)) {
  //     ...
  //   }
  // or
  //   for (size_t i = 0; i < frame.Groups(GroupTag::job_attributes).size(); ) {
  //     Collection& coll = frame.Groups(GroupTag::job_attributes)[i++];
  //     ...
  //   }
  // The groups are in the same order as they occur in the frame.
  CollsView Groups(GroupTag tag);
  ConstCollsView Groups(GroupTag tag) const;

  /* ... */
};

class CollsView {
  /* ... */

  CollsView(const CollsView& cv);
  iterator begin();
  iterator end();
  const_iterator cbegin() const;
  const_iterator cend() const;
  const_iterator begin() const;
  const_iterator end() const;
  size_t size() const;
  bool empty() const;
  Collection& operator[](size_t index);
  const Collection& operator[](size_t index) const;

  /* ... */
};

class ConstCollsView {
  /* ... */

  ConstCollsView(const ConstCollsView& cv);
  explicit ConstCollsView(const CollsView& cv);
  const_iterator cbegin() const;
  const_iterator cend() const;
  const_iterator begin() const;
  const_iterator end() const;
  size_t size() const;
  bool empty() const;
  const Collection& operator[](size_t index) const;

  /* ... */
};

```

`iterator` and `const_iterator` are bidirectional iterators dereferenceable to
`Collection&` and `const Collection&`, respectively.
Class `Collection` represents a dictionary with attributes and is described in
the next section.

### Adding new **attribute-group**

A new **attribute-group** can be added to the frame with the following method:

```c++
class Frame {
  /* ... */

  // Add a new group of attributes to the frame. The iterator to the new group
  // is saved in `new_group`. The returned iterator is valid in the range
  // returned by Groups(tag).
  // The returned value is one of the following:
  //  * Code::kOK
  //  * Code::kInvalidGroupTag
  //  * Code::kTooManyGroups
  // If the returned value != Code::kOK then `new_group` is not modified.
  Code AddGroup(GroupTag tag, CollsView::iterator& new_group);

  /* ... */
};
```

## Collection class

Instances of this class are containers for objects of `Attribute` class that is
described in the next section.
Attributes belonging to the same `Collection` must have unique names.

### Accessing the attributes

Attributes inside the `Collection` can be accessed with the following methods:

```c++
// To iterate over all attributes in the collection use iterators, e.g.:
//
//    for (Attribute& attr: collection) { ... }
//    for (const Attribute& attr: collection) { ... }
//
// Attributes inside the collection are always in the same order they were added
// to it. They will also appear in the same order in the resultant frame.
class Collection {
 public:
  class const_iterator;
  class iterator
  /* ... */

  // Standard container methods.
  iterator begin();
  iterator end();
  const_iterator cbegin() const;
  const_iterator cend() const;
  const_iterator begin() const;
  const_iterator end() const;
  size_t size() const;
  bool empty() const;

  // Methods return attribute by name. Methods return an iterator end() <=> the
  // collection has no attributes with this name.
  iterator GetAttr(std::string_view name);
  const_iterator GetAttr(std::string_view name) const;

  /* ... */
};
```

`iterator` and `const_iterator` are bidirectional iterators dereferenceable to
`Attribute&` and `const Attribute&`, respectively.

### Adding new attributes

New attributes can be added to the `Collection` object with the following methods:

```c++
class Collection {
  /* ... */

  // Add a new attribute without values. `tag` must be Out-Of-Band (see ValueTag
  // definition). Possible errors:
  //  * kInvalidName
  //  * kNameConflict
  //  * kInvalidValueTag
  //  * kIncompatibleType  (`tag` is not Out-Of-Band)
  //  * kTooManyAttributes.
  Code AddAttr(const std::string& name, ValueTag tag);

  // Add a new attribute with one or more values. `tag` must be compatible with
  // type of the parameter `value`/`values` according to the following rules:
  //  * int32_t: IsInteger(tag) == true
  //  * std::string: IsString(tag) == true OR tag == octetString
  //  * StringWithLanguage: tag == nameWithLanguage OR tag == textWithLanguage
  //  * DateTime: tag == dateTime
  //  * Resolution: tag == resolution
  //  * RangeOfInteger: tag == rangeOfInteger
  // Possible errors:
  //  * kInvalidName
  //  * kNameConflict
  //  * kInvalidValueTag
  //  * kIncompatibleType  (see the rules above)
  //  * kValueOutOfRange   (the vector is empty or one of the value is invalid)
  //  * kTooManyAttributes.
  Code AddAttr(const std::string& name, ValueTag tag, int32_t value);
  Code AddAttr(const std::string& name, ValueTag tag, const std::string& value);
  Code AddAttr(const std::string& name,
               ValueTag tag,
               const StringWithLanguage& value);
  Code AddAttr(const std::string& name, ValueTag tag, DateTime value);
  Code AddAttr(const std::string& name, ValueTag tag, Resolution value);
  Code AddAttr(const std::string& name, ValueTag tag, RangeOfInteger value);
  Code AddAttr(const std::string& name,
               ValueTag tag,
               const std::vector<int32_t>& values);
  Code AddAttr(const std::string& name,
               ValueTag tag,
               const std::vector<std::string>& values);
  Code AddAttr(const std::string& name,
               ValueTag tag,
               const std::vector<StringWithLanguage>& values);
  Code AddAttr(const std::string& name,
               ValueTag tag,
               const std::vector<DateTime>& values);
  Code AddAttr(const std::string& name,
               ValueTag tag,
               const std::vector<Resolution>& values);
  Code AddAttr(const std::string& name,
               ValueTag tag,
               const std::vector<RangeOfInteger>& values);

  // Add a new attribute with one or more values. Tag of the new attribute is
  // deduced from the type of the parameter `value`/`values`.
  // Possible errors:
  //  * kInvalidName
  //  * kNameConflict
  //  * kValueOutOfRange   (the vector is empty)
  //  * kTooManyAttributes.
  Code AddAttr(const std::string& name, bool value);
  Code AddAttr(const std::string& name, int32_t value);
  Code AddAttr(const std::string& name, DateTime value);
  Code AddAttr(const std::string& name, Resolution value);
  Code AddAttr(const std::string& name, RangeOfInteger value);
  Code AddAttr(const std::string& name, const std::vector<bool>& values);
  Code AddAttr(const std::string& name, const std::vector<int32_t>& values);
  Code AddAttr(const std::string& name, const std::vector<DateTime>& values);
  Code AddAttr(const std::string& name, const std::vector<Resolution>& values);
  Code AddAttr(const std::string& name,
               const std::vector<RangeOfInteger>& values);

  // Add a new attribute with one or more collections. The first method creates
  // an attribute with a single collection and returns an iterator to it in the
  // last parameter. The second method creates an attribute with `size`
  // collections and returns a view of them in the last parameter.
  // Possible errors:
  //  * kInvalidName
  //  * kNameConflict
  //  * kValueOutOfRange   (`size` is out of range)
  //  * kTooManyAttributes.
  Code AddAttr(const std::string& name, CollsView::iterator& coll);
  Code AddAttr(const std::string& name, size_t size, CollsView& colls);

  /* ... */
};
```

## Attribute class

Instances of this class can store values defined in IPP specification.

### Tag and name

The type of stored values is defined by one-byte **value-tag** represented by
the following enum:

```c++
// ValueTag defines type of an attribute. It is also called as `syntax` in the
// IPP specification. All valid tags are listed below. Values of attributes with
// these tags are mapped to C++ types.
enum class ValueTag : uint8_t {
  // 0x00-0x0f are invalid.
  // 0x10-0x1f are Out-of-Band tags. Attributes with this tag have no values.
  // All tags from the range 0x10-0x1f are valid.
  unsupported = 0x10,       // [rfc8010]
  unknown = 0x12,           // [rfc8010]
  no_value = 0x13,          // [rfc8010]
  not_settable = 0x15,      // [rfc3380]
  delete_attribute = 0x16,  // [rfc3380]
  admin_define = 0x17,      // [rfc3380]
  // 0x20-0x2f represents integer types.
  // Only the following tags are valid. They map to int32_t.
  integer = 0x21,
  boolean = 0x22,  // maps to both int32_t and bool.
  enum_ = 0x23,
  // 0x30-0x3f are called "octetString types". They map to dedicated types.
  // Only the following tags are valid.
  octetString = 0x30,       // maps to std::string
  dateTime = 0x31,          // maps to DateTime
  resolution = 0x32,        // maps to Resolution
  rangeOfInteger = 0x33,    // maps to RangeOfInteger
  collection = 0x34,        // = begCollection tag [rfc8010], maps to Collection
  textWithLanguage = 0x35,  // maps to StringWithLanguage
  nameWithLanguage = 0x36,  // maps to StringWithLanguage
  // 0x40-0x5f represents 'character-string values'. They map to std::string.
  // All tags from the ranges 0x40-0x49 and 0x4b-0x5f are valid.
  textWithoutLanguage = 0x41,
  nameWithoutLanguage = 0x42,
  keyword = 0x44,
  uri = 0x45,
  uriScheme = 0x46,
  charset = 0x47,
  naturalLanguage = 0x48,
  mimeMediaType = 0x49
  // memberAttrName = 0x4a is invalid.
  // 0x60-0xff are invalid.
};

// Is valid Out-of-Band tag (0x10-0x1f).
constexpr bool IsOutOfBand(ValueTag tag);

// Is valid integer type (0x21-0x23).
constexpr bool IsInteger(ValueTag tag);

// Is valid character-string type (0x40-0x5f without 0x4a).
constexpr bool IsString(ValueTag tag);

// Is valid tag.
constexpr bool IsValid(ValueTag tag);
```

Each instance of the `Attribute` class has assigned exactly one tag (`ValueTag`)
and a name (`std::string`).
They are permanent through the whole lifetime of the object and cannot be
changed.
The tag and the name of the attribute can be checked with the following API:

```c++
class Attribute {
  /* ... */

  // Returns tag of the attribute.
  ValueTag Tag() const;

  // Returns an attribute's name. It is always a non-empty string.
  std::string_view Name() const;

  /* ... */
};
```

### Values

Attributes have also a vector of values whose type is determined by the
attribute's `ValueTag`.
Attributes can be divided into three groups by type:

*   **out-of-band** (`IsOutOfBand(tag) == true`) - these attributes
    cannot have any values, they have only name and tag.
*   standard attributes (`IsOutOfBand(tag) == false && tag != collection`) -
    these attributes always have assigned a non-empty vector of values.
    *libipp* provides dedicated types for some specific tags:

    ```c++
    // It is used to hold name and text values (see [rfc8010]).
    // If language == "" it represents nameWithoutLanguage or textWithoutLanguage,
    // otherwise it represents nameWithLanguage or textWithLanguage.
    struct StringWithLanguage {
      std::string value = "";
      std::string language = "";
    };

    // Represents resolution type from [rfc8010].
    struct Resolution {
      int32_t xres = 0;
      int32_t yres = 0;
      enum Units : int8_t {
        kDotsPerInch = 3,
        kDotsPerCentimeter = 4
      } units = kDotsPerInch;
    };

    // Represents rangeOfInteger type from [rfc8010].
    struct RangeOfInteger {
      int32_t min_value = 0;
      int32_t max_value = 0;
    };

    // Represents dateTime type from [rfc8010,rfc2579].
    struct DateTime {
      uint16_t year = 2000;
      uint8_t month = 1;            // 1..12
      uint8_t day = 1;              // 1..31
      uint8_t hour = 0;             // 0..23
      uint8_t minutes = 0;          // 0..59
      uint8_t seconds = 0;          // 0..60 (60 - leap second :-)
      uint8_t deci_seconds = 0;     // 0..9
      uint8_t UTC_direction = '+';  // '+' / '-'
      uint8_t UTC_hours = 0;        // 0..13
      uint8_t UTC_minutes = 0;      // 0..59
    };
    ```

*   attributes with collections (`tag == collection`) - these attributes
    contains a non-empty vector of `Collection` objects (with
    sub-attributes).

The `Attribute` class has the following interface allowing to get and set the
number of containing values:

```c++
class Attribute {
  /* ... */

  // Returns the current number of elements (values or Collections).
  // It returns 0 <=> IsOutOfBand(Tag()).
  size_t Size() const;

  // Resizes the attribute (changes the number of stored values/collections).
  // When (IsOutOfBand(Tag()) or `new_size` equals 0 this method does nothing.
  void Resize(size_t new_size);

  /* ... */
};
```
Values of standard attributes (`!IsOutOfBand(Tag()) && Tag() != collection`) can
be retrieved and set with the following methods:

```c++
  // Retrieves a single value from the attribute and saves it in `value`.
  // Possible errors:
  //  * kIncompatibleType
  //  * kIndexOutOfRange
  // The second parameter must match the type of the attribute, otherwise the
  // code kIncompatibleType is returned. However, there are a couple of
  // exceptions when the underlying value is silently converted to the type of
  // the given parameter. See the table below for a list of silent conversions:
  //
  //      ValueTag       |  target C++ type
  //  -------------------+--------------------
  //       boolean       |      int32_t  (0 or 1)
  //        enum         |      int32_t
  //       integer       |  RangeOfIntegers  (as range [int,int])
  // nameWithoutLanguage | StringWithLanguage  (language is empty)
  // textWithoutLanguage | StringWithLanguage  (language is empty)
  //
  Code GetValue(size_t index, bool& value) const;
  Code GetValue(size_t index, int32_t& value) const;
  Code GetValue(size_t index, std::string& value) const;
  Code GetValue(size_t index, StringWithLanguage& value) const;
  Code GetValue(size_t index, DateTime& value) const;
  Code GetValue(size_t index, Resolution& value) const;
  Code GetValue(size_t index, RangeOfInteger& value) const;

  // Retrieves values from the attribute. They are copied to the given vector.
  // Possible errors:
  //  * kIncompatibleType
  // These methods follow the same rules for types' conversions as GetValue().
  Code GetValues(std::vector<bool>& values) const;
  Code GetValues(std::vector<int32_t>& values) const;
  Code GetValues(std::vector<std::string>& values) const;
  Code GetValues(std::vector<StringWithLanguage>& values) const;
  Code GetValues(std::vector<DateTime>& values) const;
  Code GetValues(std::vector<Resolution>& values) const;
  Code GetValues(std::vector<RangeOfInteger>& values) const;

  // Set new values for the attribute. Previous values are discarded.
  // Possible errors:
  //  * kIncompatibleType
  //  * kValueOutOfRange
  Code SetValues(bool value);
  Code SetValues(int32_t value);
  Code SetValues(const std::string& value);
  Code SetValues(const StringWithLanguage& value);
  Code SetValues(DateTime value);
  Code SetValues(Resolution value);
  Code SetValues(RangeOfInteger value);
  Code SetValues(const std::vector<bool>& values);
  Code SetValues(const std::vector<int32_t>& values);
  Code SetValues(const std::vector<std::string>& values);
  Code SetValues(const std::vector<StringWithLanguage>& values);
  Code SetValues(const std::vector<DateTime>& values);
  Code SetValues(const std::vector<Resolution>& values);
  Code SetValues(const std::vector<RangeOfInteger>& values);
```

Attributes with collections can be browsed by using the method `Colls()`
returning a view of a vector of `Collection`s.

```c++
  // Provides access to Collection objects. You can iterate over them in the
  // following ways:
  //   for (Collection& coll: attr.Colls()) {
  //     ...
  //   }
  // or
  //   for (size_t i = 0; i < attr.Colls().size(); ) {
  //     Collection& coll = attr.Colls()[i++];
  //     ...
  //   }
  // (Tag() != collection) <=> attr.Colls().empty()
  CollsView Colls();
  ConstCollsView Colls() const;
```
