return tag;
}
+/* Definitions for recursive get_string */
+
enum bgbvc { ChArray, BvArray, BvVec };
+/* Use this single cookie for state, to keep actual
+ * stack use to the absolute minimum.
+ */
typedef struct bgbvr {
BerElement *ber;
enum bgbvc choice;
} res;
} bgbvr;
+/* Recursive get_string, for decoding a vector of strings. The number
+ * of elements in the vector is limited only by available stack space.
+ * Each invocation consumes 24 bytes of stack on a 32-bit machine.
+ */
ber_tag_t
ber_get_stringbvr( bgbvr *b, int n )
{
*b->res.c = NULL;
return 0;
}
- /* do the allocation */
+ /* Allocate the result vector */
switch (b->choice) {
case ChArray:
*b->res.c = LBER_MALLOC( (n+1) * sizeof( char * ));
(*b->res.bv)[n] = NULL;
break;
}
+ /* Did the malloc succeed? */
+ if ( *b->res.c == NULL )
+ return LBER_DEFAULT;
return 0;
}
+ /* Do all local allocs before the recursion. Then there
+ * cannot possibly be any failures on the return trip.
+ */
if ( b->choice == BvVec )
bvp = LBER_MALLOC( sizeof( struct berval ));
}
b->tag = ber_get_stringbvr( b, n+1 );
+
if ( b->tag == 0 )
{
/* store my result */
break;
}
} else {
+ /* Failure will propagate up and free in reverse
+ * order, which is actually ideal.
+ */
if ( bvp ) LBER_FREE( bvp );
LBER_FREE( bv.bv_val );
}
}
/* Hopefully no one sends vectors with more elements than this */
+/* Don't define this! ber_get_stringbvr works much much better! */
/* #define TMP_SLOTS 1024 */
/* VARARGS */