summaryrefslogtreecommitdiffstats
path: root/crypto/objects
diff options
context:
space:
mode:
authorRichard Levitte <levitte@openssl.org>2003-04-29 20:25:21 +0000
committerRichard Levitte <levitte@openssl.org>2003-04-29 20:25:21 +0000
commitea5240a5edceccc6c6410a56b68ec4d8038da4bb (patch)
tree8acc293734ca922da2458c2fc0e8144daca1193a /crypto/objects
parenteec7968f18bf16034ff924cd56ce07611fb188da (diff)
Add an extended variant of OBJ_bsearch() that can be given a few
flags.
Diffstat (limited to 'crypto/objects')
-rw-r--r--crypto/objects/obj_dat.c35
-rw-r--r--crypto/objects/objects.h7
2 files changed, 33 insertions, 9 deletions
diff --git a/crypto/objects/obj_dat.c b/crypto/objects/obj_dat.c
index 5d983e3ed4..adab7a7343 100644
--- a/crypto/objects/obj_dat.c
+++ b/crypto/objects/obj_dat.c
@@ -556,8 +556,14 @@ static int obj_cmp(const void *ap, const void *bp)
const char *OBJ_bsearch(const char *key, const char *base, int num, int size,
int (*cmp)(const void *, const void *))
{
+ return OBJ_bsearch_ex(key, base, num, size, cmp, 0);
+ }
+
+const char *OBJ_bsearch_ex(const char *key, const char *base, int num,
+ int size, int (*cmp)(const void *, const void *), int flags)
+ {
int l,h,i,c;
- const char *p;
+ const char *p = NULL;
if (num == 0) return(NULL);
l=0;
@@ -572,20 +578,33 @@ const char *OBJ_bsearch(const char *key, const char *base, int num, int size,
else if (c > 0)
l=i+1;
else
- return(p);
+ break;
}
#ifdef CHARSET_EBCDIC
/* THIS IS A KLUDGE - Because the *_obj is sorted in ASCII order, and
* I don't have perl (yet), we revert to a *LINEAR* search
* when the object wasn't found in the binary search.
*/
- for (i=0; i<num; ++i) {
- p= &(base[i*size]);
- if ((*cmp)(key,p) == 0)
- return p;
- }
+ if (c != 0)
+ {
+ for (i=0; i<num; ++i)
+ {
+ p= &(base[i*size]);
+ c = (*cmp)(key,p);
+ if (c == 0 || (c < 0 && (flags & OBJ_BSEARCH_VALUE_ON_NOMATCH)))
+ return p;
+ }
+ }
#endif
- return(NULL);
+ if (c != 0 && !(flags & OBJ_BSEARCH_VALUE_ON_NOMATCH))
+ p = NULL;
+ else if (c == 0 && (flags & OBJ_BSEARCH_FIRST_VALUE_ON_MATCH))
+ {
+ while(i > 0 && (*cmp)(key,&(base[(i-1)*size])) == 0)
+ i--;
+ p = &(base[i*size]);
+ }
+ return(p);
}
int OBJ_create_objects(BIO *in)
diff --git a/crypto/objects/objects.h b/crypto/objects/objects.h
index de10532813..8b509516fc 100644
--- a/crypto/objects/objects.h
+++ b/crypto/objects/objects.h
@@ -966,7 +966,10 @@
#define OBJ_NAME_TYPE_COMP_METH 0x04
#define OBJ_NAME_TYPE_NUM 0x05
-#define OBJ_NAME_ALIAS 0x8000
+#define OBJ_NAME_ALIAS 0x8000
+
+#define OBJ_BSEARCH_VALUE_ON_NOMATCH 0x01
+#define OBJ_BSEARCH_FIRST_VALUE_ON_MATCH 0x02
#ifdef __cplusplus
@@ -1010,6 +1013,8 @@ int OBJ_sn2nid(const char *s);
int OBJ_cmp(const ASN1_OBJECT *a,const ASN1_OBJECT *b);
const char * OBJ_bsearch(const char *key,const char *base,int num,int size,
int (*cmp)(const void *, const void *));
+const char * OBJ_bsearch_ex(const char *key,const char *base,int num,
+ int size, int (*cmp)(const void *, const void *), int flags);
int OBJ_new_nid(int num);
int OBJ_add_object(const ASN1_OBJECT *obj);