.\" Automatically generated by Pod::Man v1.37, Pod::Parser v1.3 .\" .\" Standard preamble: .\" ======================================================================== .de Sh \" Subsection heading .br .if t .Sp .ne 5 .PP \fB\\$1\fR .PP .. .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. | will give a .\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used to .\" do unbreakable dashes and therefore won't be available. \*(C` and \*(C' .\" expand to `' in nroff, nothing in troff, for use with C<>. .tr \(*W-|\(bv\*(Tr .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` . ds C' 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' 'br\} .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . nr % 0 . rr F .\} .\" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .hy 0 .if n .na .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "al 3" .TH al 3 "OSSP al 0.9.2" "03-Oct-2005" "Assembly Line" .SH "NAME" \&\fBOSSP al\fR \- Assembly Line .SH "VERSION" .IX Header "VERSION" \&\fB\s-1OSSP\s0 al \s-10.9.2 (03-Oct-2005)\s0\fR .SH "SYNOPSIS" .IX Header "SYNOPSIS" .IP "\fBAbstract Data Types\fR:" 4 .IX Item "Abstract Data Types:" al_rc_t, al_t, al_tx_t, al_td_t, al_chunk_t. .IP "\fBAssembly Line Operations\fR:" 4 .IX Item "Assembly Line Operations:" al_create, al_destroy, al_append_bytes, al_prepend_bytes, al_attach_buffer, al_splice, al_setlabel, al_bytes. .IP "\fBTraversal Operations\fR:" 4 .IX Item "Traversal Operations:" al_txalloc, al_txfree, al_traverse, al_traverse_next, al_traverse_end, al_traverse_cb. .IP "\fBConvenience Operations\fR:" 4 .IX Item "Convenience Operations:" al_flatten, al_copy, al_firstlabel, al_spanlabel. .IP "\fBChunk Operations\fR:" 4 .IX Item "Chunk Operations:" al_chunk_len, al_chunk_span, al_chunk_label, al_same_label, al_chunk_ptr. .IP "\fBError Handling\fR:" 4 .IX Item "Error Handling:" al_error. .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\fB\s-1OSSP\s0 al\fR defines an abstract data type of a data buffer that can assemble, move and truncate chunks of data in a stream but avoids actual copying. It was built to deal efficiently with communication streams between software modules. It especially provides flexible semantical data attribution through by-chunk labeling. It also has convenient chunk traversal methods and optional \s-1OSSP\s0 ex based exception handling. .SH "DATA TYPES" .IX Header "DATA TYPES" \&\fB\s-1OSSP\s0 al\fR uses six data types in its \s-1API:\s0 .IP "\fBal_rc_t\fR (Return Code Type)" 4 .IX Item "al_rc_t (Return Code Type)" This is an exported enumerated integer type with the following possible values: .Sp .Vb 5 \& AL_OK Everything Ok \& AL_ERR_ARG Invalid Argument \& AL_ERR_MEM Not Enough Memory \& AL_ERR_EOF End Of Communication \& AL_ERR_INT Internal Error .Ve .IP "\fBal_t\fR (Assembly Line Type)" 4 .IX Item "al_t (Assembly Line Type)" This is an opaque data type representing a data buffer. Only pointers to this abstract data type are used in the \s-1API\s0. .IP "\fBal_label_t\fR (Label Type)" 4 .IX Item "al_label_t (Label Type)" This is an opaque pointer type representing a specific data flavour. You can restrict traversal operations to data that was marked with the specific flavour. Usually you would cast a pointer to the object that maintains the data to \fBal_label_t\fR. You may use \&\s-1NULL\s0 as a label but on traversal \s-1NULL\s0 matches any label. .IP "\fBal_tx_t\fR (Traversal Context Type)" 4 .IX Item "al_tx_t (Traversal Context Type)" This is an opaque data type representing the state of a buffer traversal operation. Only pointers to this abstract data type are used in the \s-1API\s0. .IP "\fBal_td_t\fR (Traversal Direction Type)" 4 .IX Item "al_td_t (Traversal Direction Type)" This is an exported enumerated integer type with the following possible values: .Sp .Vb 4 \& AL_FORWARD traverse assembly line from beginning to end \& AL_BACKWARD traverse assembly line from end to beginning \& AL_FORWARD_SPAN like AL_FORWARD, but stop when label does not match \& AL_BACKWARD_SPAN like AL_BACKWARD, but stop when label does not match .Ve .IP "\fBal_chunk_t\fR (Chunk Type)" 4 .IX Item "al_chunk_t (Chunk Type)" This is an opaque data type representing a chunk of a buffer during a traversal operation. Only pointers to this abstract data type are used in the \s-1API\s0. The \fBal_chunk_t\fR type is used to generate a pointer and byte count to access the data in the buffer. .SH "FUNCTIONS" .IX Header "FUNCTIONS" \&\fB\s-1OSSP\s0 al\fR provides a bunch of \s-1API\s0 functions, all modelled after the same prototype: "\f(CW\*(C`al_rc_t\*(C'\fR \f(CW\*(C`al_\*(C'\fR\fIname\fR\f(CW\*(C`(al_\*(C'\fR[\f(CW\*(C`chunk\*(C'\fR]\f(CW\*(C`_t *,\*(C'\fR \&...\f(CW\*(C`)\*(C'\fR". This means every function returns \f(CW\*(C`al_rc_t\*(C'\fR to indicate its success (\f(CW\*(C`AL_OK\*(C'\fR) or failure (\f(CW\*(C`AL_ERR_XXX\*(C'\fR) by returning a return code (the corresponding describing text can be determined by passing this return code to \f(CW\*(C`al_error\*(C'\fR). Each function name starts with the common prefix \f(CW\*(C`al_\*(C'\fR and receives a \f(CW\*(C`al_t\*(C'\fR (or \f(CW\*(C`al_chunk_t\*(C'\fR) object on which it operates as its first argument. .Sh "Assembly Line Operations" .IX Subsection "Assembly Line Operations" .IP "al_rc_t \fBal_create\fR(al_t **\fIalp\fR);" 4 .IX Item "al_rc_t al_create(al_t **alp);" Create an assembly line abstraction object. The object is stored in \fIalp\fR on success. .Sp Example: \f(CW\*(C`al_t *al; al_create(&al);\*(C'\fR .IP "al_rc_t \fBal_destroy\fR(al_t *\fIal\fR);" 4 .IX Item "al_rc_t al_destroy(al_t *al);" Destroy an assembly line abstraction object. The object \fIal\fR is invalid after this call succeeded. .Sp Example: \f(CW\*(C`al_destroy(al);\*(C'\fR .IP "al_rc_t \fBal_append_bytes\fR(al_t *\fIal\fR, const char *\fIsrc\fR, size_t \fIn\fR, al_label_t \fIlabel\fR);" 4 .IX Item "al_rc_t al_append_bytes(al_t *al, const char *src, size_t n, al_label_t label);" Append \fIn\fR bytes from a storage array at \fIsrc\fR to the assembly line. The bytes are copied, memory is allocated as necessary. The data is tagged with \fIlabel\fR. .Sp Example: \f(CW\*(C`al_append_bytes(al, "Goodbye cruel world\en", 20, NULL);\*(C'\fR .IP "al_rc_t \fBal_prepend_bytes\fR(al_t *\fIal\fR, const char *\fIsrc\fR, size_t \fIn\fR, al_label_t \fIlabel\fR);" 4 .IX Item "al_rc_t al_prepend_bytes(al_t *al, const char *src, size_t n, al_label_t label);" Prepend \fIn\fR bytes from a storage array at \fIsrc\fR to the assembly line. The bytes are copied, memory is allocated as necessary. .Sp Example: \f(CW\*(C`al_prepend_bytes(al, "Hello world\en", 12, NULL);\*(C'\fR .IP "al_rc_t \fBal_attach_buffer\fR(al_t *\fIal\fR, char *\fIp\fR, size_t \fIn\fR, al_label_t \fIlabel\fR, void (*\fIfreemem\fR)(char *, size_t, void *), void *\fIu\fR);" 4 .IX Item "al_rc_t al_attach_buffer(al_t *al, char *p, size_t n, al_label_t label, void (*freemem)(char *, size_t, void *), void *u);" Attach the storage array starting at \fIp\fR with size \fIn\fR at the end of the assembly line. Its content becomes part of the assembly line and is subject to assembly line operations. The storage array must stay in scope until it is no longer referenced by the assembly line. When this happens the function \fIfreemem\fR is called with the original pointer \&\fIp\fR, size \fIn\fR and an arbitrary pointer \fIu\fR. Passing a \s-1NULL\s0 pointer for \fIfreemem\fR is valid, then no callback takes place, which might be appropriate for static buffers. .Sp Example: \f(CW\*(C`char store[] = "foo\en"; al_attach_buffer(al, store, sizeof(store), NULL, NULL, NULL);\*(C'\fR .IP "al_rc_t \fBal_splice\fR(al_t *\fIal\fR, size_t \fIoff\fR, size_t \fIn\fR, al_t *\fInal\fR, al_t *\fItal\fR);" 4 .IX Item "al_rc_t al_splice(al_t *al, size_t off, size_t n, al_t *nal, al_t *tal);" This is the general data move operation modelled after the perl operator \&\fBsplice\fR. .Sp \&\fIoff\fR and \fIn\fR are byte counts that define a span of bytes within the source assembly line \fIal\fR. These bytes are moved to the target assembly line \&\fItal\fR while the content of the new assembly line \fInal\fR is moved to the source to replace the selected span. .Sp There are two deviations from the Perl operator to avoid copying: .Sp The move to the target assembly line \fItal\fR appends the data to its end. The move from the new assembly line \fInal\fR removes the data from its origin. .Sp The target assembly line \fItal\fR may be \fB\s-1NULL\s0\fR, the data bytes that would be moved to the target are then discarded. This avoids creation and destruction of a dummy target. .Sp The new assembly line \fInal\fR may be \fB\s-1NULL\s0\fR, then nothing is inserted into the source. This avoids creation and destruction of an empty assembly line. .Sp Examples: .Sp .Vb 3 \& al_t *source; \& al_t *insertion; \& al_t *buffer; .Ve .Sp .Vb 3 \& al_create(&source); \& al_create(&insertion); \& al_create(&buffer); .Ve .Sp .Vb 2 \& al_append_bytes(source, "Hello world\en", 12, NULL); \& al_append_bytes(insertion, "Goodbye cruel", 13, NULL); .Ve .Sp .Vb 1 \& al_splice(source, 0, 5, insertion, buffer); .Ve .Sp The buffer now holds the string \*(L"Hello\*(R". The source now holds the string \*(L"Goodbye cruel world\en\*(R". The insertion is now empty. .Sp .Vb 2 \& al_append_bytes(insertion, "brave", 5, NULL); \& al_splice(source, 8, 5, insertion, NULL); .Ve .Sp The source now holds the string \*(L"Goodbye brave world\en\*(R". The insertion is now empty. .Sp .Vb 5 \& al_append_bytes(insertion, "B", 1, NULL); \& al_splice(source, 0, 8, NULL, buffer); \& al_splice(source, 0, 1, insertion, NULL); \& al_append_bytes(insertion, "\en", 1, NULL); \& al_splice(buffer, al_bytes(buffer)-1, 1, insertion, NULL), .Ve .Sp The source now holds the string \*(L"Brave world\en\*(R". The buffer now holds the string \*(L"HelloGoodbye\en\*(R". The insertion is empty. .IP "al_rc_t \fBal_setlabel\fR(al_t *\fIal\fR, size_t \fIoff\fR, size_t \fIn\fR, al_label_t oldlabel, al_label_t newlabel);" 4 .IX Item "al_rc_t al_setlabel(al_t *al, size_t off, size_t n, al_label_t oldlabel, al_label_t newlabel);" \&\fIoff\fR and \fIn\fR are byte counts that define a span of bytes within the source assembly line \fIal\fR. The bytes within that span that match \fIoldlabel\fR are tagged with \fInewlabel\fR, any existing labels for these bytes are overwritten. .IP "size_t \fBal_bytes\fR(const al_t *\fIal\fR);" 4 .IX Item "size_t al_bytes(const al_t *al);" Returns the number of bytes stored in the assembly line. .Sp Example: \f(CW\*(C`al_t *al; size_t count; count = al_bytes(al);\*(C'\fR .Sh "Traversal Operations" .IX Subsection "Traversal Operations" .IP "al_rc_t \fBal_txalloc\fR(al_t *\fIal\fR, al_tx_t **txp);" 4 .IX Item "al_rc_t al_txalloc(al_t *al, al_tx_t **txp);" Allocate a traversal context. .Sp Example: \f(CW\*(C`al_tx_t *tx; al_txalloc(&tx);\*(C'\fR .IP "al_rc_t \fBal_txfree\fR(al_t *\fIal\fR, al_tx_t *tx);" 4 .IX Item "al_rc_t al_txfree(al_t *al, al_tx_t *tx);" Free a traversal context. .Sp Example: \f(CW\*(C`al_tx_t *tx; al_txfree(tx);\*(C'\fR .IP "al_rc_t \fBal_traverse\fR(al_t *\fIal\fR, size_t \fIoff\fR, size_t \fIn\fR, al_td_t \fIdir\fR, al_label_t \fIlabel\fR, al_tx_t *\fItx\fR);" 4 .IX Item "al_rc_t al_traverse(al_t *al, size_t off, size_t n, al_td_t dir, al_label_t label, al_tx_t *tx);" Start traversing the assembly line \fIal\fR beginning at byte offset \fIoff\fR for up to \fIn\fR bytes in direction \fIdir\fR. If \fIlabel\fR is not \s-1NULL\s0 then you will see only data that was tagged with \fIlabel\fR. The state of the traversal is stored in the supplied context \fItx\fR. .Sp This function fails when the offset is outside the assembly line bounds. .IP "al_rc_t \fBal_traverse_next\fR(al_t *\fIal\fR, al_tx_t *\fItx\fR, al_chunk_t **\fIalcp\fR);" 4 .IX Item "al_rc_t al_traverse_next(al_t *al, al_tx_t *tx, al_chunk_t **alcp);" Complete a traversal step on the assembly line \fIal\fR using the initialized context \fItx\fR. In each step a chunk descriptor is filled and stored in \&\fIalcp\fR. All bytes of the chunk are guaranteed to be stored in a flat array and can be accessed through the chunk operations described below. .Sp The function returns \s-1AL_ERR_EOF\s0 when it passes the end (or beginning in case of backward traversal) of the assembly line. .IP "al_rc_t \fBal_traverse_end\fR(al_t *\fIal\fR, al_tx_t *\fItx\fR, int final);" 4 .IX Item "al_rc_t al_traverse_end(al_t *al, al_tx_t *tx, int final);" Clean up internal state of traversal. If \fIfinal\fR is zero, you may continue the traversal later by calling \fBal_traverse_next\fR. If \&\fIfinal\fR is non-zero you need to start a new traversal. It is mandatory that every traversal that was started is finished by a call to \fBal_traverse_end\fR with \fIfinal\fR set to a non-zero value. .IP "al_rc_t \fBal_traverse_cb\fR(al_t *\fIal\fR, size_t \fIoff\fR, size_t \fIn\fR, al_td_t \fIdir\fR, al_label_t \fIlabel\fR, al_rc_t (*\fIcb\fR)(al_chunk_t *, void *), void *u);" 4 .IX Item "al_rc_t al_traverse_cb(al_t *al, size_t off, size_t n, al_td_t dir, al_label_t label, al_rc_t (*cb)(al_chunk_t *, void *), void *u);" \&\fBal_traverse_cb\fR is a wrapper function that does a full assembly line traversal in a single call. In every step a chunk descriptor is passed to the callback function \fIcb\fR together with a user supplied pointer \fIu\fR. When the callback function returns \s-1AL_OK\s0 the traversal continues, when it returns \&\s-1AL_ERR_EOF\s0 the traversal is aborted and \s-1AL_OK\s0 is returned to the original caller. Any other return code returned by the callback is passed to the original caller verbatim. .Sh "Convenience Operations" .IX Subsection "Convenience Operations" .IP "al_rc_t \fBal_flatten\fR(al_t *\fIal\fR, size_t \fIoff\fR, size_t \fIn\fR, al_td_t \fIdir\fR, char *\fIdst\fR, size_t *\fIlenp\fR);" 4 .IX Item "al_rc_t al_flatten(al_t *al, size_t off, size_t n, al_td_t dir, char *dst, size_t *lenp);" \&\fIoff\fR and \fIn\fR are byte counts that define a span of bytes with the assembly line \fIal\fR. These bytes are copied to the storage array \fIdst\fR which must be sized appropriately. \&\fIoff\fR must be a valid offset, \fIn\fR must be positive but may exceed the size of the assembly line. The actual number of bytes that is copied to the destination is stored in \fIlenp\fR. If \fIdst\fR is \s-1NULL\s0 then no data is copied but the number of bytes is still counted in \fIlenp\fR. This can be used to precalculate the size of the needed storage array by passing an arbitrary high maximum size as \fIn\fR. If \fIdir\fR denotes a backwards traversal the storage array is filled from its end. .Sp Example: .Sp .Vb 3 \& al_t *al; \& char buffer[42]; \& size_t actual; .Ve .Sp .Vb 1 \& al_flatten(al, 500, 42, AL_FORWARD, buffer, &actual); .Ve .IP "al_rc_t \fBal_copy\fR(al_t *\fIal\fR, size_t \fIoff\fR, size_t \fIn\fR, al_td_t \fIdir\fR, al_t *\fItal\fR);" 4 .IX Item "al_rc_t al_copy(al_t *al, size_t off, size_t n, al_td_t dir, al_t *tal);" \&\fIoff\fR and \fIn\fR are byte counts that define a span of bytes within the assembly line \fIal\fR. These bytes are appended to the target assembly line \fItal\fR, memory is allocated as necessary. \&\fIoff\fR must be a valid offset, \fIn\fR must be positive but may exceed the size of the assembly line. .Sp Example: .Sp .Vb 2 \& al_t *al; \& al_t *tal; .Ve .Sp .Vb 2 \& al_create(&tal); \& al_flatten(al, 500, 42, tal); .Ve .IP "al_rc_t \fBal_firstlabel\fR(al_t *\fIal\fR, size_t \fIoff\fR, size_t \fIn\fR, al_td_t \fIdir\fR, al_label_t *\fIlabelp\fR);" 4 .IX Item "al_rc_t al_firstlabel(al_t *al, size_t off, size_t n, al_td_t dir, al_label_t *labelp);" \&\fIoff\fR and \fIn\fR are byte counts that define a span of bytes within the assembly line \fIal\fR. The label that was attached to the first byte within the defined span is stored in \fIlabelp\fR, otherwise \fBal_firstlabel\fR returns an error. .IP "al_rc_t \fBal_spanlabel\fR(al_t *\fIal\fR, size_t \fIoff\fR, size_t \fIn\fR, al_label_t *\fIlabel\fR, size_t *, size_t *);" 4 .IX Item "al_rc_t al_spanlabel(al_t *al, size_t off, size_t n, al_label_t *label, size_t *, size_t *);" \&\fIoff\fR and \fIn\fR are byte counts that define a span of bytes within the assembly line \fIal\fR. This span is searched for data tagged with the \fIlabel\fR. The absolute byte offset of the first byte matching the label and the length of the span of the same label is returned in \fIoffp\fR and \fIspanp\fR respectively. .Sh "Chunk Operations" .IX Subsection "Chunk Operations" .IP "size_t \fBal_chunk_len\fR(al_chunk_t *\fIalc\fR);" 4 .IX Item "size_t al_chunk_len(al_chunk_t *alc);" Returns the number of bytes in a chunk. .IP "size_t \fBal_chunk_span\fR(al_chunk_t *\fIalc\fR, size_t \fIoff\fR, size_t \fIn\fR);" 4 .IX Item "size_t al_chunk_span(al_chunk_t *alc, size_t off, size_t n);" \&\fIoff\fR and \fIn\fR are byte counts that define a span of bytes. \&\fBal_chunk_span\fR returns the number of bytes that are stored in the chunk. \&\fIoff\fR must be a valid offset, \fIn\fR must be positive but may exceed the size of the chunk. .IP "al_label_t \fBal_chunk_label\fR(al_chunk_t *\fIalc\fR);" 4 .IX Item "al_label_t al_chunk_label(al_chunk_t *alc);" Return the label that was used to tag the data in \fIalc\fR. This can be \s-1NULL\s0. .IP "int \fBal_same_label\fR(al_chunk_t *\fIalc\fR, al_label_t *\fIlabel\fR);" 4 .IX Item "int al_same_label(al_chunk_t *alc, al_label_t *label);" Return true if \fIlabel\fR matches the label that was used to tag the data in \fIalc\fR. A \s-1NULL\s0 \fIlabel\fR matches everything. .IP "char *\fBal_chunk_ptr\fR(al_chunk_t *\fIalc\fR, size_t \fIoff\fR);" 4 .IX Item "char *al_chunk_ptr(al_chunk_t *alc, size_t off);" Returns the pointer to the byte at offset \fIoff\fR within the chunk \fIalc\fR. \&\fIoff\fR must be positive and must not exceed the size of the chunk. Since all bytes of the chunk are guaranteed to be stored in a flat array the pointer can be used to reference every byte within the chunk. .Sp Example: .Sp .Vb 2 \& al_chunk_t *alc; \& char *start, *end; .Ve .Sp .Vb 2 \& start = al_chunk_ptr(alc, 0); \& end = start + al_chunk_len(alc) - 1; .Ve .Sh "Error Handling" .IX Subsection "Error Handling" .IP "const char *\fBal_error\fR(al_rc_t \fIrv\fR);" 4 .IX Item "const char *al_error(al_rc_t rv);" Retrieve a string that describes the return code \fIrv\fR in english. .SH "SEE ALSO" .IX Header "SEE ALSO" .SH "HISTORY" .IX Header "HISTORY" \&\fB\s-1OSSP\s0 al\fR was invented in October 2002 by Michael van Elst under contract with Cable & Wireless Germany for use inside the \s-1OSSP\s0 project . .SH "AUTHORS" .IX Header "AUTHORS" .Vb 2 \& Michael van Elst \& mlelstv@serpens.de .Ve