Index: /trunk/include/iprt/asn1-generator-init.h
===================================================================
--- /trunk/include/iprt/asn1-generator-init.h	(revision 64887)
+++ /trunk/include/iprt/asn1-generator-init.h	(revision 64888)
@@ -34,3 +34,5 @@
 #define RTASN1TMPL_PASS                 RTASN1TMPL_PASS_SETTERS_2
 #include <iprt/asn1-generator-pass.h>
+#define RTASN1TMPL_PASS                 RTASN1TMPL_PASS_ARRAY
+#include <iprt/asn1-generator-pass.h>
 
Index: /trunk/include/iprt/asn1-generator-pass.h
===================================================================
--- /trunk/include/iprt/asn1-generator-pass.h	(revision 64887)
+++ /trunk/include/iprt/asn1-generator-pass.h	(revision 64888)
@@ -78,4 +78,5 @@
 #define RTASN1TMPL_PASS_SETTERS_1      18
 #define RTASN1TMPL_PASS_SETTERS_2      19
+#define RTASN1TMPL_PASS_ARRAY          20
 
 #define RTASN1TMPL_PASS_DECODE         24
@@ -905,9 +906,109 @@
 } RTASN1TMPL_SEMICOLON_DUMMY()
 
-#define RTASN1TMPL_END_PCHOICE() RTASN1TMPL_SEMICOLON_DUMMY()
+# define RTASN1TMPL_END_PCHOICE() RTASN1TMPL_SEMICOLON_DUMMY()
 
 
 # define RTASN1TMPL_SEQ_OF(a_ItemType, a_ItemApi)   RTASN1TMPL_SEMICOLON_DUMMY()
 # define RTASN1TMPL_SET_OF(a_ItemType, a_ItemApi)   RTASN1TMPL_SEMICOLON_DUMMY()
+
+
+#elif RTASN1TMPL_PASS == RTASN1TMPL_PASS_ARRAY
+/*
+ *
+ * Array operations.
+ *
+ */
+# define RTASN1TMPL_BEGIN_SEQCORE()                                                 RTASN1TMPL_SEMICOLON_DUMMY()
+# define RTASN1TMPL_BEGIN_SETCORE()                                                 RTASN1TMPL_SEMICOLON_DUMMY()
+# define RTASN1TMPL_MEMBER_EX(a_Name, a_Type, a_Api, a_Constraints)                     RTASN1TMPL_SEMICOLON_DUMMY()
+# define RTASN1TMPL_MEMBER_DYN_BEGIN(a_enmType, a_enmMembNm, a_Allocation)              RTASN1TMPL_SEMICOLON_DUMMY()
+# define RTASN1TMPL_MEMBER_DYN_END(a_enmType, a_enmMembNm, a_Allocation)                RTASN1TMPL_SEMICOLON_DUMMY()
+# define RTASN1TMPL_END_SEQCORE()                                                   RTASN1TMPL_SEMICOLON_DUMMY()
+# define RTASN1TMPL_END_SETCORE()                                                   RTASN1TMPL_SEMICOLON_DUMMY()
+# define RTASN1TMPL_BEGIN_PCHOICE()                                                 RTASN1TMPL_SEMICOLON_DUMMY()
+# define RTASN1TMPL_PCHOICE_ITAG_EX(a_uTag, a_enmChoice, a_PtrName, a_Name, a_Type, a_Api, a_fClue, a_Constraints) \
+                                                                                    RTASN1TMPL_SEMICOLON_DUMMY()
+# define RTASN1TMPL_PCHOICE_XTAG_EX(a_uTag, a_enmChoice, a_PtrTnNm, a_CtxTagN, a_Name, a_Type, a_Api, a_Constraints) \
+                                                                                    RTASN1TMPL_SEMICOLON_DUMMY()
+# define RTASN1TMPL_END_PCHOICE()                                                   RTASN1TMPL_SEMICOLON_DUMMY()
+
+# define RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi) \
+    RTASN1TMPL_DECL(int) RT_CONCAT(RTASN1TMPL_EXT_NAME,_Erase)(RT_CONCAT(P,RTASN1TMPL_TYPE) pThis, uint32_t iPosition) \
+    { \
+        /* Check and adjust iPosition. */ \
+        uint32_t const cItems = pThis->cItems; \
+        if (iPosition < cItems) \
+        { /* likely */ } \
+        else \
+        { \
+            AssertReturn(iPosition == UINT32_MAX, VERR_OUT_OF_RANGE); \
+            AssertReturn(cItems > 0, VERR_OUT_OF_RANGE); \
+            iPosition = cItems - 1; \
+        } \
+        \
+        /* Delete the entry instance. */ \
+        RT_CONCAT(P, a_ItemType) pErased = pThis->papItems[iPosition]; \
+        if (RT_CONCAT(a_ItemApi,_IsPresent)(pErased)) \
+            RT_CONCAT(a_ItemApi,_Delete)(pErased); \
+        \
+        /* If not the final entry, shift the other entries up and place the erased on at the end. */ \
+        if (iPosition < cItems - 1) \
+        { \
+            memmove(&pThis->papItems[iPosition], &pThis->papItems[iPosition + 1], (cItems - iPosition - 1) * sizeof(void *)); \
+            pThis->papItems[cItems - 1] = pErased; \
+        } \
+        /* Commit the new array size. */ \
+        pThis->cItems = cItems - 1; \
+        \
+        /* Call the allocator to resize the array (ignore return). */ \
+        RTAsn1MemResizeArray(&pThis->Allocation, (void ***)&pThis->papItems, cItems - 1, cItems); \
+        return VINF_SUCCESS; \
+    } \
+    \
+    RTASN1TMPL_DECL(int) RT_CONCAT(RTASN1TMPL_EXT_NAME,_InsertEx)(RT_CONCAT(P,RTASN1TMPL_TYPE) pThis, uint32_t iPosition, \
+                                                                  RT_CONCAT(PC, a_ItemType) pToClone, \
+                                                                  PCRTASN1ALLOCATORVTABLE pAllocator, uint32_t *piActualPos) \
+    { \
+        /* Check and adjust iPosition. */ \
+        uint32_t const cItems = pThis->cItems; \
+        if (iPosition <= cItems) \
+        { /* likely */ } \
+        else \
+        { \
+            AssertReturn(iPosition == UINT32_MAX, VERR_OUT_OF_RANGE); \
+            iPosition = cItems; \
+        } \
+        \
+        /* Ensure we've got space in the array. */ \
+        int rc = RTAsn1MemResizeArray(&pThis->Allocation, (void ***)&pThis->papItems, cItems, cItems + 1); \
+        if (RT_SUCCESS(rc)) \
+        { \
+            /* Initialize the new entry (which is currently at the end of the array) either with defaults or as a clone. */ \
+            RT_CONCAT(P,a_ItemType) pInserted = pThis->papItems[cItems]; \
+            if (RT_CONCAT(a_ItemApi,_IsPresent)(pToClone)) \
+                rc = RT_CONCAT(a_ItemApi,_Clone)(pInserted, pToClone, pAllocator); \
+            else \
+                rc = RT_CONCAT(a_ItemApi,_Init)(pInserted, pAllocator); \
+            if (RT_SUCCESS(rc)) \
+            { \
+                /* If not inserting at the end of the array, shift existing items out of the way and insert the new as req. */ \
+                if (iPosition != cItems) \
+                { \
+                    memmove(&pThis->papItems[iPosition + 1], &pThis->papItems[iPosition], (cItems - iPosition) * sizeof(void *)); \
+                    pThis->papItems[iPosition] = pInserted; \
+                } \
+                \
+                /* Done! */ \
+                if (piActualPos) \
+                    *piActualPos = iPosition; \
+                return VINF_SUCCESS; \
+            } \
+            RTAsn1MemResizeArray(&pThis->Allocation, (void ***)&pThis->papItems, cItems + 1, cItems); \
+        } \
+        return rc; \
+    } RTASN1TMPL_SEMICOLON_DUMMY()
+
+# define RTASN1TMPL_SEQ_OF(a_ItemType, a_ItemApi)   RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi)
+# define RTASN1TMPL_SET_OF(a_ItemType, a_ItemApi)   RTASN1TMPL_SET_SEQ_OF_COMMON(a_ItemType, a_ItemApi)
 
 
Index: /trunk/include/iprt/asn1.h
===================================================================
--- /trunk/include/iprt/asn1.h	(revision 64887)
+++ /trunk/include/iprt/asn1.h	(revision 64888)
@@ -738,10 +738,11 @@
 
 
-/** Defines the typedefs and prototypes for a generic sequence-of type. */
-#define RTASN1_IMPL_GEN_SEQ_OF_TYPEDEFS_AND_PROTOS(a_SeqOfType, a_ItemType, a_DeclMacro, a_ImplExtNm) \
-    typedef struct a_SeqOfType \
+/** Defines the typedefs and prototypes for a generic sequence-of/set-of type. */
+#define RTASN1_IMPL_GEN_SEQ_OR_SET_OF_TYPEDEFS_AND_PROTOS(a_CoreType, a_CoreMember, \
+                                                          a_ThisType, a_ItemType, a_DeclMacro, a_ImplExtNm) \
+    typedef struct a_ThisType \
     { \
-        /** Sequence core. */ \
-        RTASN1SEQUENCECORE          SeqCore; \
+        /** Sequence/set core. */ \
+        a_CoreType                  a_CoreMember; \
         /** The array allocation tracker. */ \
         RTASN1ARRAYALLOCATION       Allocation; \
@@ -750,8 +751,25 @@
         /** Array. */ \
         RT_CONCAT(P,a_ItemType)    *papItems; \
-    } a_SeqOfType; \
-    typedef a_SeqOfType *RT_CONCAT(P,a_SeqOfType); \
-    typedef a_SeqOfType const *RT_CONCAT(PC,a_SeqOfType); \
-    RTASN1TYPE_STANDARD_PROTOTYPES(a_SeqOfType, a_DeclMacro, a_ImplExtNm, SeqCore.Asn1Core)
+    } a_ThisType; \
+    typedef a_ThisType *RT_CONCAT(P,a_ThisType); \
+    typedef a_ThisType const *RT_CONCAT(PC,a_ThisType); \
+    a_DeclMacro(int)  RT_CONCAT(a_ImplExtNm,_Erase)(RT_CONCAT(P,a_ThisType) pThis, uint32_t iPosition); \
+    a_DeclMacro(int)  RT_CONCAT(a_ImplExtNm,_InsertEx)(RT_CONCAT(P,a_ThisType) pThis, uint32_t iPosition, \
+                                                       RT_CONCAT(PC,a_ItemType) pToClone, \
+                                                       PCRTASN1ALLOCATORVTABLE pAllocator, uint32_t *piActualPos); \
+    /** Appends entry with default content, returns index or negative error code. */ \
+    DECLINLINE(int32_t) RT_CONCAT(a_ImplExtNm,_Append)(RT_CONCAT(P,a_ThisType) pThis) \
+    { \
+        uint32_t uPos = pThis->cItems; \
+        int rc = RT_CONCAT(a_ImplExtNm,_InsertEx)(pThis, uPos, NULL /*pToClone*/, pThis->Allocation.pAllocator, &uPos); \
+        if (RT_SUCCESS(rc)) \
+            return uPos; \
+        return rc; \
+    } \
+    RTASN1TYPE_STANDARD_PROTOTYPES(a_ThisType, a_DeclMacro, a_ImplExtNm, a_CoreMember.Asn1Core)
+
+/** Defines the typedefs and prototypes for a generic sequence-of type. */
+#define RTASN1_IMPL_GEN_SEQ_OF_TYPEDEFS_AND_PROTOS(a_SeqOfType, a_ItemType, a_DeclMacro, a_ImplExtNm) \
+    RTASN1_IMPL_GEN_SEQ_OR_SET_OF_TYPEDEFS_AND_PROTOS(RTASN1SEQUENCECORE, SeqCore, a_SeqOfType, a_ItemType, a_DeclMacro, a_ImplExtNm)
 
 
@@ -796,18 +814,5 @@
 /** Defines the typedefs and prototypes for a generic set-of type. */
 #define RTASN1_IMPL_GEN_SET_OF_TYPEDEFS_AND_PROTOS(a_SetOfType, a_ItemType, a_DeclMacro, a_ImplExtNm) \
-    typedef struct a_SetOfType \
-    { \
-        /** Set core. */ \
-        RTASN1SETCORE               SetCore; \
-        /** The array allocation tracker. */ \
-        RTASN1ARRAYALLOCATION       Allocation; \
-        /** Items in the array. */ \
-        uint32_t                    cItems; \
-        /** Array. */ \
-        RT_CONCAT(P,a_ItemType)    *papItems; \
-    } a_SetOfType; \
-    typedef a_SetOfType *RT_CONCAT(P,a_SetOfType); \
-    typedef a_SetOfType const *RT_CONCAT(PC,a_SetOfType); \
-    RTASN1TYPE_STANDARD_PROTOTYPES(a_SetOfType, a_DeclMacro, a_ImplExtNm, SetCore.Asn1Core)
+    RTASN1_IMPL_GEN_SEQ_OR_SET_OF_TYPEDEFS_AND_PROTOS(RTASN1SETCORE, SetCore, a_SetOfType, a_ItemType, a_DeclMacro, a_ImplExtNm)
 
 
Index: /trunk/include/iprt/mangling.h
===================================================================
--- /trunk/include/iprt/mangling.h	(revision 64887)
+++ /trunk/include/iprt/mangling.h	(revision 64888)
@@ -3378,4 +3378,75 @@
 # define RTErrConvertFromDarwinKern                     RT_MANGLER(RTErrConvertFromDarwinKern)
 
+# define RTAsn1BitString_Erase                          RT_MANGLER(RTAsn1BitString_Erase)
+# define RTAsn1BitString_Erase                          RT_MANGLER(RTAsn1BitString_Erase)
+# define RTAsn1BitString_InsertEx                       RT_MANGLER(RTAsn1BitString_InsertEx)
+# define RTAsn1BitString_InsertEx                       RT_MANGLER(RTAsn1BitString_InsertEx)
+# define RTAsn1Boolean_Erase                            RT_MANGLER(RTAsn1Boolean_Erase)
+# define RTAsn1Boolean_Erase                            RT_MANGLER(RTAsn1Boolean_Erase)
+# define RTAsn1Boolean_InsertEx                         RT_MANGLER(RTAsn1Boolean_InsertEx)
+# define RTAsn1Boolean_InsertEx                         RT_MANGLER(RTAsn1Boolean_InsertEx)
+# define RTAsn1Core_Erase                               RT_MANGLER(RTAsn1Core_Erase)
+# define RTAsn1Core_Erase                               RT_MANGLER(RTAsn1Core_Erase)
+# define RTAsn1Core_InsertEx                            RT_MANGLER(RTAsn1Core_InsertEx)
+# define RTAsn1Core_InsertEx                            RT_MANGLER(RTAsn1Core_InsertEx)
+# define RTAsn1Integer_Erase                            RT_MANGLER(RTAsn1Integer_Erase)
+# define RTAsn1Integer_Erase                            RT_MANGLER(RTAsn1Integer_Erase)
+# define RTAsn1Integer_InsertEx                         RT_MANGLER(RTAsn1Integer_InsertEx)
+# define RTAsn1Integer_InsertEx                         RT_MANGLER(RTAsn1Integer_InsertEx)
+# define RTAsn1ObjId_Erase                              RT_MANGLER(RTAsn1ObjId_Erase)
+# define RTAsn1ObjId_Erase                              RT_MANGLER(RTAsn1ObjId_Erase)
+# define RTAsn1ObjId_InsertEx                           RT_MANGLER(RTAsn1ObjId_InsertEx)
+# define RTAsn1ObjId_InsertEx                           RT_MANGLER(RTAsn1ObjId_InsertEx)
+# define RTAsn1OctetString_Erase                        RT_MANGLER(RTAsn1OctetString_Erase)
+# define RTAsn1OctetString_Erase                        RT_MANGLER(RTAsn1OctetString_Erase)
+# define RTAsn1OctetString_InsertEx                     RT_MANGLER(RTAsn1OctetString_InsertEx)
+# define RTAsn1OctetString_InsertEx                     RT_MANGLER(RTAsn1OctetString_InsertEx)
+# define RTAsn1SeqOfObjIds_Erase                        RT_MANGLER(RTAsn1SeqOfObjIds_Erase)
+# define RTAsn1SeqOfObjIds_InsertEx                     RT_MANGLER(RTAsn1SeqOfObjIds_InsertEx)
+# define RTAsn1String_Erase                             RT_MANGLER(RTAsn1String_Erase)
+# define RTAsn1String_Erase                             RT_MANGLER(RTAsn1String_Erase)
+# define RTAsn1String_InsertEx                          RT_MANGLER(RTAsn1String_InsertEx)
+# define RTAsn1String_InsertEx                          RT_MANGLER(RTAsn1String_InsertEx)
+# define RTAsn1Time_Erase                               RT_MANGLER(RTAsn1Time_Erase)
+# define RTAsn1Time_Erase                               RT_MANGLER(RTAsn1Time_Erase)
+# define RTAsn1Time_InsertEx                            RT_MANGLER(RTAsn1Time_InsertEx)
+# define RTAsn1Time_InsertEx                            RT_MANGLER(RTAsn1Time_InsertEx)
+# define RTCrPkcs7Attribute_Erase                       RT_MANGLER(RTCrPkcs7Attribute_Erase)
+# define RTCrPkcs7Attribute_InsertEx                    RT_MANGLER(RTCrPkcs7Attribute_InsertEx)
+# define RTCrPkcs7Cert_Erase                            RT_MANGLER(RTCrPkcs7Cert_Erase)
+# define RTCrPkcs7Cert_InsertEx                         RT_MANGLER(RTCrPkcs7Cert_InsertEx)
+# define RTCrPkcs7ContentInfo_Erase                     RT_MANGLER(RTCrPkcs7ContentInfo_Erase)
+# define RTCrPkcs7ContentInfo_InsertEx                  RT_MANGLER(RTCrPkcs7ContentInfo_InsertEx)
+# define RTCrPkcs7SignedData_Erase                      RT_MANGLER(RTCrPkcs7SignedData_Erase)
+# define RTCrPkcs7SignedData_InsertEx                   RT_MANGLER(RTCrPkcs7SignedData_InsertEx)
+# define RTCrPkcs7SignerInfo_Erase                      RT_MANGLER(RTCrPkcs7SignerInfo_Erase)
+# define RTCrPkcs7SignerInfo_InsertEx                   RT_MANGLER(RTCrPkcs7SignerInfo_InsertEx)
+# define RTCrRsaOtherPrimeInfo_Erase                    RT_MANGLER(RTCrRsaOtherPrimeInfo_Erase)
+# define RTCrRsaOtherPrimeInfo_InsertEx                 RT_MANGLER(RTCrRsaOtherPrimeInfo_InsertEx)
+# define RTCrSpcSerializedObjectAttribute_Erase         RT_MANGLER(RTCrSpcSerializedObjectAttribute_Erase)
+# define RTCrSpcSerializedObjectAttribute_InsertEx      RT_MANGLER(RTCrSpcSerializedObjectAttribute_InsertEx)
+# define RTCrTafTrustAnchorChoice_Erase                 RT_MANGLER(RTCrTafTrustAnchorChoice_Erase)
+# define RTCrTafTrustAnchorChoice_InsertEx              RT_MANGLER(RTCrTafTrustAnchorChoice_InsertEx)
+# define RTCrX509AlgorithmIdentifier_Erase              RT_MANGLER(RTCrX509AlgorithmIdentifier_Erase)
+# define RTCrX509AlgorithmIdentifier_InsertEx           RT_MANGLER(RTCrX509AlgorithmIdentifier_InsertEx)
+# define RTCrX509AttributeTypeAndValue_Erase            RT_MANGLER(RTCrX509AttributeTypeAndValue_Erase)
+# define RTCrX509AttributeTypeAndValue_InsertEx         RT_MANGLER(RTCrX509AttributeTypeAndValue_InsertEx)
+# define RTCrX509Certificate_Erase                      RT_MANGLER(RTCrX509Certificate_Erase)
+# define RTCrX509Certificate_InsertEx                   RT_MANGLER(RTCrX509Certificate_InsertEx)
+# define RTCrX509Extension_Erase                        RT_MANGLER(RTCrX509Extension_Erase)
+# define RTCrX509Extension_InsertEx                     RT_MANGLER(RTCrX509Extension_InsertEx)
+# define RTCrX509GeneralName_Erase                      RT_MANGLER(RTCrX509GeneralName_Erase)
+# define RTCrX509GeneralName_InsertEx                   RT_MANGLER(RTCrX509GeneralName_InsertEx)
+# define RTCrX509GeneralSubtree_Erase                   RT_MANGLER(RTCrX509GeneralSubtree_Erase)
+# define RTCrX509GeneralSubtree_InsertEx                RT_MANGLER(RTCrX509GeneralSubtree_InsertEx)
+# define RTCrX509PolicyInformation_Erase                RT_MANGLER(RTCrX509PolicyInformation_Erase)
+# define RTCrX509PolicyInformation_InsertEx             RT_MANGLER(RTCrX509PolicyInformation_InsertEx)
+# define RTCrX509PolicyMapping_Erase                    RT_MANGLER(RTCrX509PolicyMapping_Erase)
+# define RTCrX509PolicyMapping_InsertEx                 RT_MANGLER(RTCrX509PolicyMapping_InsertEx)
+# define RTCrX509PolicyQualifierInfo_Erase              RT_MANGLER(RTCrX509PolicyQualifierInfo_Erase)
+# define RTCrX509PolicyQualifierInfo_InsertEx           RT_MANGLER(RTCrX509PolicyQualifierInfo_InsertEx)
+# define RTCrX509RelativeDistinguishedName_Erase        RT_MANGLER(RTCrX509RelativeDistinguishedName_Erase)
+# define RTCrX509RelativeDistinguishedName_InsertEx     RT_MANGLER(RTCrX509RelativeDistinguishedName_InsertEx)
+
 /*
  * Stable variables (alphabetical order):
