aboutsummaryrefslogtreecommitdiffstats
path: root/skeletons
diff options
context:
space:
mode:
authorLev Walkin <vlm@lionet.info>2004-06-14 08:17:27 +0000
committerLev Walkin <vlm@lionet.info>2004-06-14 08:17:27 +0000
commitc4c6196c40740e67b83aa58708a8e374963eba70 (patch)
treeb7aacce071c8fa72b59a47132b615fc7c67de16b /skeletons
parent46bf935e1eb5b20b3edd427e7b831941f48bb85c (diff)
faster path for common size
Diffstat (limited to 'skeletons')
-rw-r--r--skeletons/OBJECT_IDENTIFIER.c30
-rw-r--r--skeletons/tests/check-OIDs.c5
2 files changed, 28 insertions, 7 deletions
diff --git a/skeletons/OBJECT_IDENTIFIER.c b/skeletons/OBJECT_IDENTIFIER.c
index c4176160..a156d060 100644
--- a/skeletons/OBJECT_IDENTIFIER.c
+++ b/skeletons/OBJECT_IDENTIFIER.c
@@ -91,6 +91,7 @@ OBJECT_IDENTIFIER_constraint(asn1_TYPE_descriptor_t *td, const void *sptr,
return 0;
}
+
int
OBJECT_IDENTIFIER_get_single_arc(uint8_t *arcbuf, unsigned int arclen, signed int add, void *rvbuf, unsigned int rvsize) {
unsigned LE = 1; /* Little endian (x86) */
@@ -130,23 +131,39 @@ OBJECT_IDENTIFIER_get_single_arc(uint8_t *arcbuf, unsigned int arclen, signed in
}
}
+ /* Faster path for common size */
+ if(rvsize == (CHAR_BIT * sizeof(unsigned long))) {
+ unsigned long accum;
+ /* Gather all bits into the accumulator */
+ for(accum = cache; arcbuf < arcend; arcbuf++)
+ accum = (accum << 7) | (*arcbuf & ~0x80);
+ if(accum < (unsigned)-add) {
+ errno = ERANGE; /* Overflow */
+ return -1;
+ }
+ *(unsigned long *)rvbuf = accum + add;
+ return 0;
+ }
+
#ifndef WORDS_BIGENDIAN
if(*(unsigned char *)&LE) { /* Little endian (x86) */
/* "Convert" to big endian */
- rvbuf += rvsize / CHAR_BIT;
+ rvbuf += rvsize / CHAR_BIT - 1;
+ ((unsigned char *)rvstart)--;
inc = -1; /* Descending */
- } else {
- inc = +1; /* Ascending */
- }
+ } else
#endif /* !WORDS_BIGENDIAN */
+ inc = +1; /* Big endian is known [at compile time] */
- { /* Native big endian (Sparc, PPC) */
+ {
unsigned int bits; /* typically no more than 3-4 bits */
+
/* Clear the high unused bits */
for(bits = rvsize - arclen;
bits > CHAR_BIT;
rvbuf += inc, bits -= CHAR_BIT)
*(unsigned char *)rvbuf = 0;
+
/* Fill the body of a value */
for(; arcbuf < arcend; arcbuf++) {
cache = (cache << 7) | (*arcbuf & 0x7f);
@@ -323,8 +340,8 @@ OBJECT_IDENTIFIER_set_arcs_l(OBJECT_IDENTIFIER_t *oid, unsigned long *arcs, unsi
uint8_t *buf;
uint8_t *bp;
unsigned long long first_value;
+ unsigned i;
int size;
- int i;
if(oid == NULL || arcs == NULL || arc_slots < 2) {
errno = EINVAL;
@@ -423,3 +440,4 @@ OBJECT_IDENTIFIER_set_arcs_l(OBJECT_IDENTIFIER_t *oid, unsigned long *arcs, unsi
return 0;
}
+
diff --git a/skeletons/tests/check-OIDs.c b/skeletons/tests/check-OIDs.c
index 472e5536..cea630e0 100644
--- a/skeletons/tests/check-OIDs.c
+++ b/skeletons/tests/check-OIDs.c
@@ -269,7 +269,10 @@ main() {
CHECK_REGEN_OID(12);
CHECK_REGEN_OID(13);
- check_speed();
+ if(getenv("CHECK_SPEED")) {
+ /* Useful for developers only */
+ check_speed();
+ }
return 0;
}