Datasets

## Datasets Datasets — manipulating a tag identifier and its associated value |

## Synopsis

                        IptcDataSet;
    IptcDataSet*        iptc_dataset_new                    (void);
    IptcDataSet*        iptc_dataset_new_mem                (IptcMem *mem);
    IptcDataSet*        iptc_dataset_copy                   (IptcDataSet *dataset);
    void                iptc_dataset_ref                    (IptcDataSet *dataset);
    void                iptc_dataset_unref                  (IptcDataSet *dataset);
    void                iptc_dataset_free                   (IptcDataSet *dataset);

    IptcFormat          iptc_dataset_get_format             (IptcDataSet *dataset);
    int                 iptc_dataset_get_data               (IptcDataSet *dataset,
                                                             unsigned char *buf,
                                                             unsigned int size);
    unsigned int        iptc_dataset_get_value              (IptcDataSet *dataset);
    int                 iptc_dataset_get_date               (IptcDataSet *dataset,
                                                             int *year,
                                                             int *month,
                                                             int *day);
    int                 iptc_dataset_get_time               (IptcDataSet *dataset,
                                                             int *hour,
                                                             int *min,
                                                             int *sec,
                                                             int *tz);

    void                iptc_dataset_set_tag                (IptcDataSet *dataset,
                                                             IptcRecord record,
                                                             IptcTag tag);
    enum                IptcValidate;
    int                 iptc_dataset_set_data               (IptcDataSet *dataset,
                                                             unsigned char *buf,
                                                             unsigned int size,
                                                             IptcValidate validate);
    int                 iptc_dataset_set_value              (IptcDataSet *dataset,
                                                             unsigned int value,
                                                             IptcValidate validate);
    int                 iptc_dataset_set_date               (IptcDataSet *dataset,
                                                             int year,
                                                             int month,
                                                             int day,
                                                             IptcValidate validate);
    int                 iptc_dataset_set_time               (IptcDataSet *dataset,
                                                             int hour,
                                                             int min,
                                                             int sec,
                                                             int tz,
                                                             IptcValidate validate);

    const char*         iptc_dataset_get_as_str             (IptcDataSet *dataset,
                                                             char *buf,
                                                             unsigned int size);
    void                iptc_dataset_dump                   (IptcDataSet *dataset,
                                                             unsigned int indent);

## Description

The IptcDataSet object contains a record number, dataset number, and data. The record and dataset (tag) number uniquely define the purpose of the dataset according to the IPTC IIM specification. The data is the contents of the tag.

## Details

### IptcDataSet

    typedef struct {
    	IptcRecord record;
            IptcTag tag;
            const IptcTagInfo * info;

            unsigned char *data;
            unsigned int size;

    	/* Data containing this dataset */
    	IptcData *parent;

    	IptcDataSetPrivate *priv;
    } IptcDataSet;

An IPTC dataset, which associates a record/tag pair with a value.

IptcRecord `record`; | the record number
IptcTag `tag`; | the dataset number
const IptcTagInfo *`info`; | information about the tag from the IPTC IIM specification
unsigned char *`data`; | the value of the tag
unsigned int `size`; | the length of `data` in bytes
IptcData *`parent`; | the IptcData object that contains this dataset or NULL if it is not contained
IptcDataSetPrivate *`priv`; | private data

### iptc_dataset_new ()

    IptcDataSet*        iptc_dataset_new                    (void);

Allocates a new dataset, which is initialized to be empty (undefined tag and empty value). The default memory allocation functions (malloc, etc.) are used. If you need custom memory management functions, use `iptc_dataset_new_mem()` instead. This allocation will set the IptcDataSet refcount to 1, so use `iptc_dataset_unref()` when finished with the pointer.

Returns : | pointer to the new IptcDataSet object, NULL on error

### iptc_dataset_new_mem ()

    IptcDataSet*        iptc_dataset_new_mem                (IptcMem *mem);

Allocates a new dataset, which is initialized to be empty (undefined tag and empty value), using custom memory management functions. This allocation will set the IptcDataSet refcount to 1, so use `iptc_dataset_unref()` when finished with the pointer.

`mem` : | Pointer to an IptcMem object that defines custom memory managment functions. The refcount of `mem` will be incremented. It is decremented when the returned IptcDataSet object is freed.
Returns : | pointer to the new IptcDataSet object, NULL on error

### iptc_dataset_copy ()

    IptcDataSet*        iptc_dataset_copy                   (IptcDataSet *dataset);

Allocates a new dataset and copies the contents of an existing dataset into the new one. Copied data includes record, tag, and the data payload. This is a "deep copy" so that a new copy of the data payload is created, not just a pointer duplication. The new dataset has no parent collection, regardless of the parent of the copied dataset. This allocation will set the IptcDataSet refcount to 1, so use `iptc_dataset_unref()` when finished with the pointer.

`dataset` : | the dataset to duplicate
Returns : | pointer to the new IptcDataSet object, NULL on error

### iptc_dataset_ref ()

    void                iptc_dataset_ref                    (IptcDataSet *dataset);

Increments the reference count of an IptcDataSet object. This function should be called whenever a copy of a pointer is made by the application. `iptc_dataset_unref()` can then be used when the pointer is no longer needed to ensure that the object is freed once the object is completely unused.

`dataset` : | the referenced pointer

### iptc_dataset_unref ()

    void                iptc_dataset_unref                  (IptcDataSet *dataset);

Decrements the reference count of an IptcDataSet object. The object will automatically be freed when the count reaches 0. This function should be called whenever a pointer is no longer needed by an application. It is also good practice to set the local copy of the pointer to NULL to shield against accidently reusing the value.

`dataset` : | the unreferenced pointer

### iptc_dataset_free ()

    void                iptc_dataset_free                   (IptcDataSet *dataset);

Frees an IptcDataSet object and its contained data. This function should be used only for error handling since `iptc_dataset_unref()` provides a safer mechanism for freeing that allows multiple components to have access to an object.

`dataset` : | the object to free

### iptc_dataset_get_format ()

    IptcFormat          iptc_dataset_get_format             (IptcDataSet *dataset);

Retrieves the data format of a dataset tag according to the IPTC specification.

`dataset` : | pointer to an IptcDataSet
Returns : | the format of the tag which will be `IPTC_FORMAT_UNKNOWN` if the tag number has not been set or the tag is not in the specification

### iptc_dataset_get_data ()

    int                 iptc_dataset_get_data               (IptcDataSet *dataset,
                                                             unsigned char *buf,
                                                             unsigned int size);

Copies the value of a dataset into a buffer. If the buffer has extra space, the data will be NULL-terminated to assist in dealing with strings.

`dataset` : | pointer to an IptcDataSet
`buf` : | buffer to which the data will be copied
`size` : | maximum size of the buffer
Returns : | the number of bytes copied, or -1 on failure

### iptc_dataset_get_value ()

    unsigned int        iptc_dataset_get_value              (IptcDataSet *dataset);

Gets the value of a dataset as an unsigned integer. This function is meant to be used when the format of a tag is a byte, short, or long. Undefined results occur when this function is used on a tag containing data in another format.

`dataset` : | pointer to an IptcDataSet
Returns : | value contained in the dataset

### iptc_dataset_get_date ()

    int                 iptc_dataset_get_date               (IptcDataSet *dataset,
                                                             int *year,
                                                             int *month,
                                                             int *day);

Interprets the contents of the dataset as an IPTC date and parses the year, month, and day into the given output variables. If any variable is NULL, that value is skipped. IPTC dates are stored as a string in the format YYYYMMDD.

`dataset` : | pointer to an IptcDataSet
`year` : | output variable to store the year (0-9999)
`month` : | output variable to store the month (1-12)
`day` : | output variable to store the day of the month (1-31)
Returns : | 0 on success; -1 on failure

### iptc_dataset_get_time ()

    int                 iptc_dataset_get_time               (IptcDataSet *dataset,
                                                             int *hour,
                                                             int *min,
                                                             int *sec,
                                                             int *tz);

Interprets the contents of the dataset as an IPTC time and parses the hour, minute, second, and timezone into the given output variables. If any variable is NULL, that value is skipped. IPTC times are stored as a string in the format HHMMSS±HHMM.

`dataset` : | pointer to an IptcDataSet
`hour` : | output variable to store the hour (0-23)
`min` : | output variable to store the minute (0-59)
`sec` : | output variable to store the second (0-59)
`tz` : | output variable to store the timezone (offset in minutes from GMT)
Returns : | 0 on success; -1 on failure

### iptc_dataset_set_tag ()

    void                iptc_dataset_set_tag                (IptcDataSet *dataset,
                                                             IptcRecord record,
                                                             IptcTag tag);

Sets the record and tag number for a dataset object. Each record/tag pair is assigned a specific meaning by the IPTC IIM specification. This function allows any value to be set for the dataset object, regardless of its meaning. This function can also be used to change the record/tag number in place even if it has been already set.

`dataset` : | dataset for which the record/tag numbers should be set
`record` : | record number of the dataset
`tag` : | tag (dataset number) of the dataset

### enum IptcValidate

    typedef enum {
    	IPTC_DONT_VALIDATE = 0,
    	IPTC_VALIDATE      = 1
    } IptcValidate;

Whether the value of a dataset should be validated to meet the IPTC IIM specification.

`IPTC_DONT_VALIDATE` | do not check the value against the specification
`IPTC_VALIDATE` | check the value against the specification

### iptc_dataset_set_data ()

    int                 iptc_dataset_set_data               (IptcDataSet *dataset,
                                                             unsigned char *buf,
                                                             unsigned int size,
                                                             IptcValidate validate);

Copies bytes from a buffer as the new value for a dataset. This is the correct method for setting a dataset value to a string or raw binary sequence. The length of a string should be specified without the trailing NULL. New memory is allocated for the value and `size` bytes are copied from `buf` into this new memory (which is freed when the dataset is freed or when a new value is set). If `validate` is set to `IPTC_VALIDATE`, the buffer will only be copied if the size does not violate the IPTC specification (it must not be too long or too short). This check is ignored if the dataset's tag is undefined or no information from the specification is available for that tag.

`dataset` : | dataset for which the value should be set
`buf` : | buffer containing the value
`size` : | number of bytes to copy
`validate` : | whether or not the passed value should be validated against the IPTC specification for this dataset's tag.
Returns : | -1 on error, 0 if validation failed, the number of bytes copied on success

### iptc_dataset_set_value ()

    int                 iptc_dataset_set_value              (IptcDataSet *dataset,
                                                             unsigned int value,
                                                             IptcValidate validate);

Sets the value of a dataset as an integer. This is the correct method for setting a dataset value with type byte, short, or long. If `validate` is set to `IPTC_VALIDATE`, the value will only be set if the tag has type byte, short, or long according the IPTC specification. This check is ignored if the dataset's tag is undefined or no information from the specification is available for that tag.

`dataset` : | dataset for which the value should be set
`value` : | value for the dataset
`validate` : | whether or not the passed value should be validated against the IPTC specification for this dataset's tag.
Returns : | -1 on error, 0 if validation failed, the number of bytes copied on success

### iptc_dataset_set_date ()

    int                 iptc_dataset_set_date               (IptcDataSet *dataset,
                                                             int year,
                                                             int month,
                                                             int day,
                                                             IptcValidate validate);

Sets the contents of the dataset to be a date with the specified value. IPTC dates are stored as a string in the format YYYYMMDD.

`dataset` : | pointer to an IptcDataSet
`year` : | the year (0-9999)
`month` : | the month (1-12)
`day` : | the day of the month (1-31)
`validate` : | if set to `IPTC_VALIDATE`, the dataset date will only be set if the IPTC specification says it is of type date.
Returns : | the number of bytes written on success (always 8 in this case); 0 if validation fails; -1 for other failures

### iptc_dataset_set_time ()

    int                 iptc_dataset_set_time               (IptcDataSet *dataset,
                                                             int hour,
                                                             int min,
                                                             int sec,
                                                             int tz,
                                                             IptcValidate validate);

Sets the contents of the dataset to be a time with the specified value. IPTC times are stored as a string in the format HHMMSS±HHMM.

`dataset` : | pointer to an IptcDataSet
`hour` : | the hour (0-23)
`min` : | the minutes (0-59)
`sec` : | the seconds (0-61)
`tz` : | the timezone expressed as the number of minutes offset from GMT. For example, EST is -300 (-5 hours).
`validate` : | if set to `IPTC_VALIDATE`, the dataset time will only be set if the IPTC specification says it is of type time.
Returns : | the number of bytes written on success (always 11 in this case); 0 if validation fails; -1 for other failures

### iptc_dataset_get_as_str ()

    const char*         iptc_dataset_get_as_str             (IptcDataSet *dataset,
                                                             char *buf,
                                                             unsigned int size);

Copies the value of a dataset into a buffer as a printable, NULL-terminated string. For tags of type byte, short, or long, the value will be formatted as a string. For tags of type string (including dates and times), the string will simply be copied into the output buffer. For tags containing binary data, the data will be formatted as a string in hexidecimal.

`dataset` : | pointer to an IptcDataSet
`buf` : | buffer to which the string will be copied
`size` : | maximum size of the buffer
Returns : | the output string on success, or NULL on failure

### iptc_dataset_dump ()

    void                iptc_dataset_dump                   (IptcDataSet *dataset,
                                                             unsigned int indent);

A debugging aid that prints out the contents of a dataset to standard output.

`dataset` : | dataset to print
`indent` : | indentation level of the printout