<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.openssl.org/index.php?action=history&amp;feed=atom&amp;title=STACK_API</id>
	<title>STACK API - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.openssl.org/index.php?action=history&amp;feed=atom&amp;title=STACK_API"/>
	<link rel="alternate" type="text/html" href="https://wiki.openssl.org/index.php?title=STACK_API&amp;action=history"/>
	<updated>2026-04-09T22:31:14Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.35.13</generator>
	<entry>
		<id>https://wiki.openssl.org/index.php?title=STACK_API&amp;diff=1407&amp;oldid=prev</id>
		<title>Vincent: page creation; must add functions description</title>
		<link rel="alternate" type="text/html" href="https://wiki.openssl.org/index.php?title=STACK_API&amp;diff=1407&amp;oldid=prev"/>
		<updated>2014-01-14T00:07:23Z</updated>

		<summary type="html">&lt;p&gt;page creation; must add functions description&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;The stack library provides a generic way to handle collections of objects in OpenSSL. A comparison function can be registered to sort the collection.&lt;br /&gt;
&lt;br /&gt;
Interface is split in two headers, &amp;lt;openssl/stack.h&amp;gt; and &amp;lt;openssl/safestack.h&amp;gt;. The former declares the C functions that will execute the insert, delete, pop, push, and other operations on the stack, while the latter declares a bunch of macros to enforce some type-checking by the compiler; these macros are mostly auto-generated by mkstack.pl.&lt;br /&gt;
&lt;br /&gt;
It is highly discouraged to use the C functions declared in &amp;lt;openssl/stack.h&amp;gt;. Rather, use the macros defined in &amp;lt;openssl/safestack.h&amp;gt; for OpenSSL built-in  stacks, and declare your own type-checking wrappers for your custom stacks.&lt;br /&gt;
&lt;br /&gt;
==Basic Use==&lt;br /&gt;
&lt;br /&gt;
A stack type is defined with the DECLARE_STACK_OF() macro and its instances are declared with the STACK_OF() macro.&lt;br /&gt;
&lt;br /&gt;
Example from &amp;lt;openssl/x509.h&amp;gt;:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* a sequence of these are used */&lt;br /&gt;
typedef struct x509_attributes_st&lt;br /&gt;
        {&lt;br /&gt;
        ASN1_OBJECT *object;&lt;br /&gt;
        int single; /* 0 for a set, 1 for a single item (which is wrong) */&lt;br /&gt;
        union   {&lt;br /&gt;
                char            *ptr;&lt;br /&gt;
/* 0 */         STACK_OF(ASN1_TYPE) *set;&lt;br /&gt;
/* 1 */         ASN1_TYPE       *single;&lt;br /&gt;
                } value;&lt;br /&gt;
        } X509_ATTRIBUTE;&lt;br /&gt;
&lt;br /&gt;
DECLARE_STACK_OF(X509_ATTRIBUTE)&lt;br /&gt;
DECLARE_ASN1_SET_OF(X509_ATTRIBUTE)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
typedef struct X509_req_info_st&lt;br /&gt;
        {&lt;br /&gt;
        ASN1_ENCODING enc;&lt;br /&gt;
        ASN1_INTEGER *version;&lt;br /&gt;
        X509_NAME *subject;&lt;br /&gt;
        X509_PUBKEY *pubkey;&lt;br /&gt;
        /*  d=2 hl=2 l=  0 cons: cont: 00 */&lt;br /&gt;
        STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */&lt;br /&gt;
        } X509_REQ_INFO;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For each kind of stack, a set of macros is available to manipulate its state and contents. Here is an example with the BIO object:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/* allocate &amp;amp; free */&lt;br /&gt;
#define sk_BIO_new(cmp)                 SKM_sk_new(BIO, (cmp))&lt;br /&gt;
#define sk_BIO_new_null()               SKM_sk_new_null(BIO)&lt;br /&gt;
#define sk_BIO_free(st)                 SKM_sk_free(BIO, (st))&lt;br /&gt;
#define sk_BIO_pop_free(st, free_func)  SKM_sk_pop_free(BIO, (st), (free_func))&lt;br /&gt;
#define sk_BIO_dup(st)                  SKM_sk_dup(BIO, st)&lt;br /&gt;
&lt;br /&gt;
/* get &amp;amp; set */&lt;br /&gt;
#define sk_BIO_num(st)                  SKM_sk_num(BIO, (st))&lt;br /&gt;
#define sk_BIO_value(st, i)             SKM_sk_value(BIO, (st), (i))&lt;br /&gt;
#define sk_BIO_set(st, i, val)          SKM_sk_set(BIO, (st), (i), (val))&lt;br /&gt;
&lt;br /&gt;
/* add value */&lt;br /&gt;
#define sk_BIO_insert(st, val, i)       SKM_sk_insert(BIO, (st), (val), (i))&lt;br /&gt;
#define sk_BIO_push(st, val)            SKM_sk_push(BIO, (st), (val))&lt;br /&gt;
#define sk_BIO_unshift(st, val)         SKM_sk_unshift(BIO, (st), (val))&lt;br /&gt;
&lt;br /&gt;
/* sort &amp;amp; find */&lt;br /&gt;
#define sk_BIO_set_cmp_func(st, cmp)    SKM_sk_set_cmp_func(BIO, (st), (cmp))&lt;br /&gt;
#define sk_BIO_sort(st)                 SKM_sk_sort(BIO, (st))&lt;br /&gt;
#define sk_BIO_is_sorted(st)            SKM_sk_is_sorted(BIO, (st))&lt;br /&gt;
#define sk_BIO_find(st, val)            SKM_sk_find(BIO, (st), (val))&lt;br /&gt;
#define sk_BIO_find_ex(st, val)         SKM_sk_find_ex(BIO, (st), (val))&lt;br /&gt;
&lt;br /&gt;
/* delete value */&lt;br /&gt;
#define sk_BIO_delete(st, i)            SKM_sk_delete(BIO, (st), (i))&lt;br /&gt;
#define sk_BIO_delete_ptr(st, ptr)      SKM_sk_delete_ptr(BIO, (st), (ptr))&lt;br /&gt;
#define sk_BIO_pop(st)                  SKM_sk_pop(BIO, (st))&lt;br /&gt;
#define sk_BIO_shift(st)                SKM_sk_shift(BIO, (st))&lt;br /&gt;
#define sk_BIO_zero(st)                 SKM_sk_zero(BIO, (st))&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Vincent</name></author>
	</entry>
</feed>