2023-02-03 14:50:10 -05:00
|
|
|
#include "pair.h"
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <errno.h>
|
2023-02-04 01:00:55 -05:00
|
|
|
#include <assert.h>
|
2023-02-03 14:50:10 -05:00
|
|
|
|
|
|
|
/** @return Constructs `a` and `b` as a pair. */
|
|
|
|
struct pair pair(const char *const a, const char *const b) {
|
|
|
|
struct pair p;
|
|
|
|
p.a = a, p.b = b;
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** Doesn't check anything.
|
|
|
|
@return Whether it was able to parse unsigned `p` to `n`. */
|
|
|
|
int pair_to_natural(const char *s, const char *const e, uint32_t *const n) {
|
|
|
|
uint32_t accum = 0;
|
|
|
|
while(s < e) {
|
|
|
|
unsigned next = accum * 10 + (unsigned)(*s - '0');
|
|
|
|
if(accum >= next) return errno = ERANGE, 0;
|
|
|
|
accum = next;
|
|
|
|
s++;
|
|
|
|
}
|
|
|
|
*n = accum;
|
|
|
|
return 1;
|
|
|
|
}
|
2023-02-04 01:00:55 -05:00
|
|
|
|
|
|
|
int pair_is_equal(struct pair x, struct pair y) {
|
|
|
|
assert(x.a <= x.b && y.a <= y.b);
|
|
|
|
if(!x.a) return !y.a;
|
|
|
|
if(x.b - x.a != y.b - y.a) return 0;
|
|
|
|
while(x.a < x.b) { if(*x.a != *y.a) return 0; x.a++, y.a++; }
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2023-02-04 22:06:43 -05:00
|
|
|
int pair_is_string(struct pair x, const char *y) {
|
|
|
|
assert(x.a <= x.b);
|
|
|
|
if(!x.a) return !y;
|
|
|
|
while(x.a < x.b) { if(*x.a != *y || !*y) return 0; x.a++, y++; }
|
|
|
|
return !*y;
|
|
|
|
}
|
|
|
|
|
2023-02-04 01:00:55 -05:00
|
|
|
/** djb2 <http://www.cse.yorku.ca/~oz/hash.html> */
|
|
|
|
uint32_t pair_djb2(struct pair p) {
|
|
|
|
uint32_t hash = 5381, c;
|
|
|
|
while(p.a < p.b) {
|
|
|
|
c = (unsigned char)*p.a++;
|
|
|
|
hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
|
|
|
|
}
|
|
|
|
return hash;
|
|
|
|
}
|