VistaIOattribute(3)

πŸ’– VistaIOattribute β€” Library Functions Manual πŸ’–

okay so bestie, we're diving into VistaIOattribute, straight out of the Library Functions Manual, and it's literally the blueprint for how the Vista library handles attribute lists. grab a boba, this one's a whole saga πŸ§‹βœ¨


✨ NAME ✨

VistaIOattribute β€” representation of a list of name/value pairs πŸŽ€


✨ SYNOPSIS ✨

VistaIOAttrList list;

VistaIOAttrListPosn posn;

✨ DESCRIPTION ✨

🌸 Introduction 🌸

An attribute is the ultimate situationship between a name and a value β€” one name, one value, matched up. Like, generally speaking, all the properties of an object (an image, whatever) get described by attributes: each attribute names one property and gives you that property's value. Attributes get collected into lists, and the Vista library has routines for poking at and manipulating those lists. A list is referred to by a pointer of type VistaIOAttrList. πŸ’…

The attribute list representation is closely related to the Vista data file format. Among other things, attribute lists can represent in memory the contents of Vista data files. no cap.

An attribute's name is an alphanumeric string β€” specifically, a sequence of characters matching the regular expression [a-zA-Z0-9_.+-]+. (Regular expressions are described in grep(1).) Attribute names are represented in memory as null-terminated character strings. They may be 50 character in length. πŸ‘‘

An attribute's value may be a character string, a (nested) attribute list, or a pointer to data of a specified type. let's break it down:

  • If it's a character string, the string may optionally be interpreted as an number whenever it is accessed. Library routines exist, for example, that can return a string's value as a VistaIOShort, or set it with a VistaIOFloat value. The following representations can be used when accessing character-string attribute values: VistaIOBit, VistaIOUByte, VistaIOSByte, VistaIOShort, VistaIOLong, VistaIOFloat, VistaIODouble, VistaIOBoolean, or VistaIOString. An error will be signalled if an attempt is made to obtain an attribute's value in a representation to which it cannot be converted. 😭

A character-string attribute value can also be interpreted as a keyword. Again, conversion between keywords and any desired representation occurs when the attribute value is accessed. The routines you use to access attribute values allow you to specify an optional dictionary that describes a mapping between keywords and values. The form of this dictionary is described by the VistaIOdictionary(3) manual page. Using a dictionary, for example, you can fetch an attribute's value as a VistaIOBoolean while converting the keywords false and true to the values 0 and 1. iconic fr.

  • An attribute's value may be another attribute list. However, circular references, as when an attribute list is the value of one of its attributes, are not allowed. πŸ’€
  • An attribute's value may be an object with any of the standard object types (e.g., an image or edge set); or it may be an object of a type that has been registered by the programmer using the mechanism described in VistaIOtype(3). Because they are registered, such types are automatically read from data files and written to data files by library routines such as VistaIOReadFile(3) and VistaIOWriteFile(3). slay.
  • An attribute's value may be of type VistaIOBundle, described in VistaIOBundle(3). A VistaIOBundle can represent an object whose type has not been registered with the VistaIOtype(3) mechanism, in a way that allows the object to be copied unchanged from an input data file to an output data file. It's used to represent objects of unknown type encountered in input data files. πŸ¦‹
  • An attribute's value may be a pointer to an opaque data structure. Such a pointer is of type VistaIOPointer. Library routines only allow for getting and setting a VistaIOPointer attribute value; they cannot read VistaIOPointer values from data files, or write them to data files. 🚫

The elements of an attribute list may be accessed by attribute name, in which case each element should have a unique name and the order of attributes within the list is not significant. In this form of access the attribute list is treated as a set. Alternatively, the elements of an attribute list may be accessed by their position within the list, in which case attribute names needn't be unique and the ordering of list elements is significant. In this form of access the attribute list is treated as a sequence. The library provides support for both forms of access. both? we love a versatile queen. ✨

A position within an attribute list is identified by a structure of type VistaIOAttrListPosn. Its value can denote a particular attribute within a list, or no attribute (analogous to NULL). 🫢


πŸŽ€ Creating, Copying, and Destroying Attribute Lists πŸŽ€

The following routines will create, copy, and destroy attribute lists. the whole life cycle, bestie.

VistaIOAttrList VistaIOCreateAttrList (void)

VistaIOCreateAttrList creates and returns an empty attribute list. baby's first list 🌱

VistaIOAttrList VistaIOCopyAttrList (VistaIOAttrList list)

VistaIOCopyAttrList generates a complete copy of list using newly-allocated storage for each list element. The new list contains its own copy of each attribute value β€” except that for a VistaIOPointer value, the pointer is copied but not the (opaque) data structure to which it points. ⚠️

void VistaIODestroyAttrList (VistaIOAttrList list)

VistaIODestroyAttrList releases the storage occupied by list. Also released is storage occupied by attribute values β€” except that for a VistaIOPointer value, the pointer is released but not the (opaque) data structure to which it points. πŸ’€


πŸ¦‹ Traversing an Attribute List πŸ¦‹

The following macros are used to sequence through an attribute list in either direction. They are appropriate when accessing an attribute list representing a sequence (as opposed to a set) of attributes. like walking down the timeline, forward or backward πŸ•°οΈ

void VistaIOFirstAttr (VistaIOAttrList list, VistaIOAttrListPosn *posn)

VistaIOFirstAttr sets posn to point to the first attribute in list. If the list is empty, posn is set to point to nothing (a condition that can be tested using the VistaIOAttrExists macro).

void VistaIOLastAttr (VistaIOAttrList list, VistaIOAttrListPosn *posn)

VistaIOLastAttr sets posn to point to the last attribute in list. If the list is empty, posn is set to point to nothing (a condition that can be tested using the VistaIOAttrExists macro).

void VistaIONextAttr (VistaIOAttrListPosn *posn)

VistaIONextAttr sets posn to point to the next attribute in its list. If posn already points to the list's last attribute, posn is set to point to nothing (a condition that can be detected by the VistaIOAttrExists macro).

void VistaIOPrevAttr (VistaIOAttrList list, VistaIOAttrListPosn *posn)

VistaIOPrevAttr sets posn to point to the previous attribute in its list. If posn already points to the list's first attribute, posn is set to point to nothing (a condition that can be detected by the VistaIOAttrExists macro).

VistaIOBoolean VistaIOAttrExists (VistaIOAttrListPosn *posn)

VistaIOAttrExists returns TRUE if posn points to an attribute, and FALSE if it points to nothing. This macro is used, for example, to test for the end of an attribute list while sequencing through it. vibe check for "are we there yet" βœ…

VistaIOBoolean VistaIOAttrListEmpty (VistaIOAttrList *list)

VistaIOAttrListEmpty returns TRUE if list is empty.


πŸ’… Accessing Attributes by Position πŸ’…

The following macros and routines access the attribute at a specified position within an attribute list.

VistaIOStringConst VistaIOGetAttrName (VistaIOAttrListPosn *posn)

The VistaIOGetAttrName macro returns the name of the attribute at posn.

VistaIORepnKind VistaIOGetAttrRepn (VistaIOAttrListPosn *posn)

The VistaIOGetAttrRepn macro returns the type of representation of the attribute value at posn.

VistaIOBoolean VistaIOGetAttrValue (VistaIOAttrListPosn *posn,
          VistaIODictEntry *dict, VistaIORepnKind repn,
          VistaIOPointer value)

This routine gets the value of the attribute at posn. (See VistaIOGetAttrValue(3) for details.)

void VistaIOSetAttrValue (VistaIOAttrListPosn *posn,
          VistaIODictEntry *dict, VistaIORepnKind repn, type value)

This routine sets the value of the attribute at posn. (See VistaIOSetAttrValue(3) for details.)


🌈 Accessing Attributes by Name 🌈

The following routines access attributes by name. They are appropriate when accessing an attribute list representing a set of attributes, in which each attribute name is present at most once.

VistaIOBoolean VistaIOLookupAttr (VistaIOAttrList list,
          VistaIOStringConst name, VistaIOAttrListPosn *posn)

VistaIOLookupAttr locates the first attribute named name in the list list. If the attribute is found, TRUE is returned along with the attribute's position in posn. Otherwise FALSE is returned. πŸ•΅οΈβ™€οΈ

VistaIOGetAttrResult VistaIOGetAttr (VistaIOAttrList *list,
          VistaIOStringConst name, VistaIODictEntry *dict,
          VistaIORepnKind repn, VistaIOPointer value)

VistaIOGetAttr gets the value of the named attribute. (See VistaIOGetAttr(3) for details.)

void VistaIOSetAttr (VistaIOAttrList *list, VistaIOStringConst name,
          VistaIODictEntry *dict, VistaIORepnKind repn, type value)

VistaIOSetAttr sets the value of the named attribute, creating an attribute if the list doesn't already contain one with that name. (See VistaIOSetAttr(3) for details.) manifesting it into existence ✨


πŸ”₯ Inserting and Deleting Attributes πŸ”₯

The following routines add attributes to lists and remove them. in with the new, out with the old.

void VistaIOInsertAttr (VistaIOAttrListPosn *posn, VistaIOBoolean after,
          VistaIOStringConst name, VistaIODictEntry *dict,
          VistaIORepnKind repn, type value)

VistaIOInsertAttr inserts an attribute before or after a specified position within an attribute list. (See VistaIOInsertAttr(3) for details.)

void VistaIODeleteAttr (VistaIOAttrListPosn *posn)

VistaIODeleteAttr deletes the attribute at posn. It leaves posn pointing to the following attribute if their is one, or nothing if the attribute deleted was the last on its list. πŸ’…

void VistaIOAppendAttr (VistaIOAttrList *list, VistaIOStringConst name,
          VistaIODictEntry *dict, VistaIORepnKind repn, type value)

VistaIOAppendAttr appends an attribute to the back of list. (See VistaIOAppendAttr(3) for details.)

void VistaIOPrependAttr (VistaIOAttrList *list, VistaIOStringConst name,
          VistaIODictEntry *dict, VistaIORepnKind repn, type value)

VistaIOPrependAttr prepends an attribute to the front of list. (See VistaIOPrependAttr(3) for details.) main character energy, always first in line πŸ‘‘

  • VistaIOExtractAttr locates an attribute named name in list, removes it if it's found, and hands you back its value. (See VistaIOExtractAttr(3) for the full tea.) 🫳✨

🌈 Encoding and Decoding Attribute VistaIOalues 🌈

okay so these next ones are the little translators β€” they flip character-string attribute values into other representations and back again. bilingual icons honestly. πŸ’…

  • VistaIOStringConst VistaIOEncodeAttrValue (VistaIODictEntry *dict, VistaIORepnKind repn, type value)

VistaIOEncodeAttrValue grabs a value plus an optional dictionary and encodes that value as a character string β€” the kind you can stash in an attribute list or spit out into a data file. (See VistaIOEncodeAttrValue(3) for the deets.) πŸŽ€

  • VistaIOBoolean VistaIODecodeAttrValue (VistaIOStringConst str, VistaIODictEntry *dict, VistaIORepnKind repn, VistaIOPointer value)

VistaIODecodeAttrValue does the whole thing backwards β€” takes a string, gives you back a value in whatever representation you asked for. (See VistaIODecodeAttrValue(3) for the deets.) πŸ”


πŸ“‚ Inputting and Outputting Attribute Lists πŸ“‚

these ones read and write whole attribute lists. file I/O but make it cute.

  • VistaIOAttrList VistaIOReadFile (FILE *file, VistaIOBoolean (*filter) ())

VistaIOReadFile reads an entire data file and returns it as an attribute list. (See VistaIOReadFile(3) for the deets.) πŸ“–

  • VistaIOBoolean VistaIOWriteFile (FILE *file, VistaIOAttrList list)

VistaIOWriteFile writes an entire data file containing whatever's in an attribute list. (See VistaIOWriteFile(3) for the deets.) ✍️


🧺 Storage Management 🧺

okay bestie, listen, this part is important. if you're gonna program with attribute lists you have to know how storage gets handled for attribute values, or you're gonna leak memory and that's not the vibe. πŸ™ˆ

The big general rule: when you access individual attributes, values aren't created, copied, or destroyed β€” you're only messing with references to them. But when a whole entire attribute list gets created, copied, or destroyed, then all the values inside get created, copied, or destroyed right along with it. πŸ’«

Unfortunately (😭), the exact behavior depends on both the type of value an attribute has and the type of operation being performed on it. Here's the whole breakdown:

πŸ“ For an attribute whose value is a character string

  • The value is stored in an attribute list as a string.
  • VistaIOCopyAttrList makes a new copy of the string for the list it creates.
  • VistaIODestroyAttrList releases the storage that the string occupies when it destroys the list containing the attribute.
  • VistaIOGetAttr and VistaIOGetAttrValue return a pointer to a shared copy of the string. That pointer stays valid until the attribute is modified.
  • When VistaIOSetAttr, VistaIOSetAttrValue, VistaIODeleteAttr, or VistaIOExtractAttr modifies or deletes an attribute that has a string value, it releases the storage that value occupies.
  • When VistaIOSetAttr or VistaIOSetAttrValue sets an attribute to a new string value, it stores its own copy of the string in the attribute list.

πŸ¦‹ For an attribute whose value is an attribute list, object, or VistaIOBundle

  • The value is stored in an attribute list as a pointer.
  • VistaIOCopyAttrList makes a new copy of the value for the list it creates. (If the value is an attribute list, for example, it calls itself recursively to clone the value.)
  • VistaIODestroyAttrList releases the storage that the value occupies when it destroys the list containing the attribute.
  • VistaIOGetAttr and VistaIOGetAttrValue return a pointer to a shared copy of the value (they do not make a new copy to return). That pointer stays valid until the value is explicitly destroyed, or indirectly destroyed by destroying the list that contains the attribute.
  • When VistaIOSetAttr, VistaIOSetAttrValue, VistaIODeleteAttr, or VistaIOExtractAttr modifies or deletes an attribute with one of these values, it discards the pointer to the value β€” but not the value itself.
  • When VistaIOSetAttr or VistaIOSetAttrValue sets an attribute to one of these values, it stores a copy of a pointer to the value, but it does not copy the value itself.

πŸ‘‘ For an attribute whose value is a VistaIOPointer

  • The value is stored in an attribute list as a pointer.
  • VistaIOCopyAttrList makes a new copy of the pointer for the list it creates, but it does not copy the (opaque) data structure it points to.
  • VistaIODestroyAttrList does not release the (opaque) data structure pointed to when it destroys the list containing the attribute.
  • VistaIOGetAttr and VistaIOGetAttrValue simply return the pointer.
  • When VistaIOSetAttr, VistaIOSetAttrValue, VistaIODeleteAttr, or VistaIOExtractAttr modifies or deletes an attribute with one of these values, it discards the old pointer value but does not release the (opaque) data structure it points to.
  • When VistaIOSetAttr or VistaIOSetAttrValue sets an attribute to one of these values, it records the new pointer value, but it does not copy the (opaque) data structure it points to.

πŸ—οΈ Data Structures πŸ—οΈ

typedef struct _VAttrRec {
       VistaIOAttrRec *next;/* next in list */
       VistaIOAttrRec *prev;/* previous in list */
       VistaIORepnKind repn;/* rep'n of attribute value */
       VistaIOPointer value;/* pointer to attribute value */
       char name[1];       /* beginning of name string */
} VistaIOAttrRec, *VistaIOAttrList;
typedef struct {
       VistaIOAttrList list;/* the list */
       VistaIOAttrRec *ptr;/* position within the list */
} VistaIOAttrListPosn;

Programmers using attribute lists will usually not need to reach into components of the attribute list data structure directly from their own code, because there are library routines and macros available for basically every purpose. However β€” when you're debugging πŸ›, you may occasionally need to peek at an attribute list directly. iykyk.

In a list of attributes, each attribute is represented by a VistaIOAttrRec record. Records are allocated with a variable size β€” big enough to hold the attribute name and, if the attribute value is stored as a character string, the attribute value too.

The record's name field is a variable-length character array containing the attribute's name, terminated by a NULL character. The repn field specifies whether the attribute's value is stored as a character string (VistaIOStringRepn), an attribute list (VistaIOAttrListRepn), a pointer to an opaque data structure (VistaIOPointerRepn), or some other object type (VistaIOBundle, VistaIOImage, VistaIOEdges, etc.). Accordingly, the value field will point to a null-terminated character string, an attribute list, an opaque data structure, a VistaIOBundleRec structure, etc. If the value is a string, that string immediately follows the name string in the variable-length record. The next and prev fields form a doubly-linked list, with NULL pointers marking the list's ends.

An attribute list contains, in addition to a VistaIOAttrRec record for each of its attributes, one VistaIOAttrRec record serving as a list header. The only significant fields of this header record are the next and prev fields, which point to the first and last attributes of the list. An attribute list is of type VistaIOAttrList, which is a pointer to the list's header record.

The library includes routines and macros that let you step through an attribute list, and access an attribute by its position in a list. These use the VistaIOAttrListPosn type, which acts as a pointer to a particular attribute within a list. The VistaIOAttrListPosn's list field identifies an entire list, and its ptr field refers to a specific attribute within that list. 🎯


🌟 EXAMPLES 🌟

The examples in this section assume you've got these variables already:

VistaIOAttrList list;
VistaIOAttrListPosn posn;
VistaIOImage image, result;

This code fragment creates an attribute list, sets some attributes in it, writes the list to the standard output stream, and finally destroys the list. chef's kiss. πŸ’‹

list = VistaIOCreateAttrList ();
VistaIOSetAttr (list, "name", NULL, VistaIOStringRepn, "Socrates");
VistaIOSetAttr (list, "comment", NULL, VistaIOStringRepn, "Greek philosopher");
VistaIOSetAttr (list, "age", NULL, VistaIOShortRepn, (VistaIOShort) 37);
VistaIOWriteFile (stdout, list);
VistaIODestroyAttrList (list);

This one reads an attribute list from the standard input stream and prints the name of each of its attributes in sequence:

list = VistaIOReadFile (stdin, NULL);
for (VistaIOFirstAttr (list, & posn); VistaIOAttrExists (& posn); VistaIONextAttr (& posn))
    printf ("%s\n", VistaIOGetAttrName (& posn));

To add a series of images to an attribute list:

while (...) {
    image = VistaIOCreateImage (...);
    VistaIOAppendAttr (list, ..., VistaIOImageRepn, image);
    /* Note: don't discard image. */
}

To modify each image in an attribute list without replacing it:

for (VistaIOFirstAttr (list, & posn); VistaIOAttrExists (& posn); VistaIONextAttr (& posn)) {
    if (VistaIOGetAttrRepn (& posn) != VistaIOImageRepn)
        continue;
    VistaIOGetAttrValue (& posn, NULL, VistaIOImageRepn, & image);
    ProcessImage (image, image, ...);
    /* Note: modifications to image are inherited by the attribute. */
}

To replace each image in an attribute list:

for (VistaIOFirstAttr (list, & posn); VistaIOAttrExists (& posn); VistaIONextAttr (& posn)) {
    if (VistaIOGetAttrRepn (& posn) != VistaIOImageRepn)
        continue;
    VistaIOGetAttrValue (& posn, NULL, VistaIOImageRepn, & image);
    result = ProcessImage (image, NULL, ...);
    VistaIOSetAttrValue (& posn, NULL, VistaIOImageRepn, result);
    /* Note: the attribute now refers to result, not image. */
    VistaIODestroyImage (image);
}

To delete a named image from an attribute list:

if (VistaIOLookupAttr (list, "...", & posn)) {
    VistaIOGetAttrValue (& posn, NULL, VistaIOImageRepn, & image);
    VistaIODeleteAttr (& posn);
    VistaIODestroyImage (image);
}

πŸ‘€ SEE ALSO πŸ‘€

okay bestie, this is the part where we hand you the whole friend group πŸ’– every one of these is a real page, go read them, they're all part of the same lore:

lowkey iconic that the original list has a lil ghost entry in it β€” there's a bare , sitting in there between VistaIOtype(3) and VistaIOGetAttrValue(3), no name, no number, just vibes. we're not gonna pretend it's a real page. it's just... there. πŸ™ˆ

πŸ’– AUTHOR πŸ’–

  • Art Pope β€” <pope@cs.ubc.ca> ✨
  • Adaption to vistaio: Gert Wollny β€” <gw.fossdev@gmail.com> 🫢

and that's the whole page, bestie!! πŸŽ€ no cap, you now know more about VistaIOattribute(3) than like 99% of people who've ever opened a terminal. go forth and slay πŸ’…

this was VistaIO Version 1.2.14, dated 28 January 1994 β€” yeah, it's vintage, it's giving classic, it ATE and left no crumbs πŸ‘‘ mwah, bye!! πŸŒΈπŸ¦‹