int _citrus_lookup_factory_convert(FILE *out, FILE *in) { struct _citrus_db_factory *df; struct _region r; char *line; size_t size; int ret; ret = _db_factory_create(&df, &_db_hash_std, NULL); if (ret) return (ret); while ((line = fgetln(in, &size)) != NULL) if ((ret = convert_line(df, line, size))) { _db_factory_free(df); return (ret); } ret = dump_db(df, &r); _db_factory_free(df); if (ret) return (ret); if (fwrite(_region_head(&r), _region_size(&r), 1, out) != 1) return (errno); return (0); }
static int parse_line(struct parse_arg *pa, struct _region *r) { char buf[20]; struct zone z1, z2; size_t len; len = _region_size(r); z1.begin = _bcs_skip_ws_len(_region_head(r), &len); if (len == 0) return EFTYPE; z1.end = _bcs_skip_nonws_len(z1.begin, &len); if (len == 0) return EFTYPE; z2.begin = _bcs_skip_ws_len(z1.end, &len); if (len == 0) return EFTYPE; z2.end = _bcs_skip_nonws_len(z2.begin, &len); /* z1 : dst name, z2 : norm */ snprintf(pa->dst, sizeof(pa->dst), "%.*s", (int)(z1.end-z1.begin), z1.begin); snprintf(buf, sizeof(buf), "%.*s", (int)(z2.end-z2.begin), z2.begin); pa->norm = _bcs_strtoul(buf, NULL, 0); return 0; }
char * _citrus_lookup_simple(const char *name, const char *key, char *linebuf, size_t linebufsize, int ignore_case) { int ret; struct _citrus_lookup *cl; struct _region data; ret = _citrus_lookup_seq_open(&cl, name, ignore_case); if (ret) return NULL; ret = _citrus_lookup_seq_lookup(cl, key, &data); if (ret) { _citrus_lookup_seq_close(cl); return NULL; } snprintf(linebuf, linebufsize, "%.*s", (int)_region_size(&data), (const char *)_region_head(&data)); _citrus_lookup_seq_close(cl); return linebuf; }
static int get32(struct _region *r, uint32_t *rval) { if (_region_size(r) != 4) return EFTYPE; memcpy(rval, _region_head(r), (size_t)4); *rval = be32toh(*rval); return 0; }
int _citrus_db_lookup_string_by_string(struct _citrus_db *db, const char *key, const char **rdata, struct _citrus_db_locator *dl) { struct _region r; int ret; ret = _citrus_db_lookup_by_string(db, key, &r, dl); if (ret) return (ret); /* check whether the string is null terminated */ if (_region_size(&r) == 0) return (EFTYPE); if (*((const char*)_region_head(&r)+_region_size(&r)-1) != '\0') return (EFTYPE); if (rdata) *rdata = _region_head(&r); return (0); }
int _citrus_db_lookup8_by_string(struct _citrus_db *db, const char *key, uint8_t *rval, struct _citrus_db_locator *dl) { struct _region r; int ret; ret = _citrus_db_lookup_by_string(db, key, &r, dl); if (ret) return (ret); if (_region_size(&r) != 1) return (EFTYPE); if (rval) memcpy(rval, _region_head(&r), 1); return (0); }
uint32_t _citrus_db_hash_std(struct _region *r) { const uint8_t *p; uint32_t hash, tmp; size_t i; hash = 0; p = _region_head(r); for (i = _region_size(r); i > 0; i--) { hash <<= 4; hash += _bcs_tolower(*p); tmp = hash & 0xF0000000; if (tmp != 0) { hash ^= tmp; hash ^= tmp >> 24; } p++; }
static int parse_var(struct _citrus_mapper_646 *m6, struct _memstream *ms, const char *dir) { struct _region r; char path[PATH_MAX]; m6->m6_forward = 1; _memstream_skip_ws(ms); /* whether backward */ if (_memstream_peek(ms) == '!') { _memstream_getc(ms); m6->m6_forward = 0; } /* get description file path */ _memstream_getregion(ms, &r, _memstream_remainder(ms)); snprintf(path, sizeof(path), "%s/%.*s", dir, (int)_region_size(&r), (char *)_region_head(&r)); /* remove trailing white spaces */ path[_bcs_skip_nonws(path)-path] = '\0'; return (parse_file(m6, path)); }
int _citrus_db_lookup32_by_string(struct _citrus_db *db, const char *key, uint32_t *rval, struct _citrus_db_locator *dl) { struct _region r; uint32_t val; int ret; ret = _citrus_db_lookup_by_string(db, key, &r, dl); if (ret) return (ret); if (_region_size(&r) != 4) return (EFTYPE); if (rval) { memcpy(&val, _region_head(&r), 4); *rval = be32toh(val); } return (0); }
int _citrus_db_lookup16_by_string(struct _citrus_db *db, const char *key, uint16_t *rval, struct _citrus_db_locator *dl) { int ret; struct _region r; uint16_t val; ret = _citrus_db_lookup_by_string(db, key, &r, dl); if (ret) return ret; if (_region_size(&r) != 2) return EFTYPE; if (rval) { memcpy(&val, _region_head(&r), 2); *rval = be16toh(val); } return 0; }
/* * _citrus_esdb_get_list: * get esdb entries. */ int _citrus_esdb_get_list(char ***rlist, size_t *rnum, bool sorted) { struct _citrus_lookup *cla, *cld; struct _region key, data; char **list, **q; char buf[PATH_MAX]; size_t num; int ret; num = 0; ret = _lookup_seq_open(&cla, _PATH_ESDB "/" ESDB_ALIAS, _LOOKUP_CASE_IGNORE); if (ret) goto quit0; ret = _lookup_seq_open(&cld, _PATH_ESDB "/" ESDB_DIR, _LOOKUP_CASE_IGNORE); if (ret) goto quit1; /* count number of entries */ num = _lookup_get_num_entries(cla) + _lookup_get_num_entries(cld); _lookup_seq_rewind(cla); _lookup_seq_rewind(cld); /* allocate list pointer space */ list = malloc(num * sizeof(char *)); num = 0; if (list == NULL) { ret = errno; goto quit3; } /* get alias entries */ while ((ret = _lookup_seq_next(cla, &key, &data)) == 0) { if (sorted) snprintf(buf, sizeof(buf), "%.*s/%.*s", (int)_region_size(&data), (const char *)_region_head(&data), (int)_region_size(&key), (const char *)_region_head(&key)); else snprintf(buf, sizeof(buf), "%.*s/%.*s", (int)_region_size(&data), (const char *)_region_head(&data), (int)_region_size(&key), (const char *)_region_head(&key)); _bcs_convert_to_upper(buf); list[num] = strdup(buf); if (list[num] == NULL) { ret = errno; goto quit3; } num++; } if (ret != ENOENT) goto quit3; /* get dir entries */ while ((ret = _lookup_seq_next(cld, &key, &data)) == 0) { if (!sorted) snprintf(buf, sizeof(buf), "%.*s", (int)_region_size(&key), (const char *)_region_head(&key)); else { /* check duplicated entry */ char *p; char buf1[PATH_MAX]; snprintf(buf1, sizeof(buf1), "%.*s", (int)_region_size(&data), (const char *)_region_head(&data)); if ((p = strchr(buf1, '/')) != NULL) memcpy(buf1, p + 1, strlen(p) - 1); if ((p = strstr(buf1, ".esdb")) != NULL) *p = '\0'; snprintf(buf, sizeof(buf), "%s/%.*s", buf1, (int)_region_size(&key), (const char *)_region_head(&key)); } _bcs_convert_to_upper(buf); ret = _lookup_seq_lookup(cla, buf, NULL); if (ret) { if (ret != ENOENT) goto quit3; /* not duplicated */ list[num] = strdup(buf); if (list[num] == NULL) { ret = errno; goto quit3; } num++; } } if (ret != ENOENT) goto quit3; ret = 0; /* XXX: why reallocing the list space posteriorly? shouldn't be done earlier? */ q = realloc(list, num * sizeof(char *)); if (!q) { ret = ENOMEM; goto quit3; } list = q; *rlist = list; *rnum = num; quit3: if (ret) _citrus_esdb_free_list(list, num); _lookup_seq_close(cld); quit1: _lookup_seq_close(cla); quit0: return (ret); }
static int find_best_pivot_pvdb(const char *src, const char *dst, char *pivot, size_t pvlen, unsigned long *rnorm) { int ret, num, i; struct _region fr, r1, r2; struct _citrus_db *db1, *db2, *db3; char buf[LINE_MAX]; unsigned long norm; uint32_t val32; ret = _map_file(&fr, CS_PIVOT ".pvdb"); if (ret) { if (ret == ENOENT) ret = NO_SUCH_FILE; return ret; } ret = _db_open(&db1, &fr, _CITRUS_PIVOT_MAGIC, _db_hash_std, NULL); if (ret) goto quit1; ret = open_subdb(&db2, db1, src); if (ret) goto quit2; num = _db_get_num_entries(db2); *rnorm = ULONG_MAX; for (i = 0; i < num; i++) { /* iterate each pivot */ ret = _db_get_entry(db2, i, &r1, &r2); if (ret) goto quit3; /* r1:pivot name, r2:norm among src and pivot */ ret = get32(&r2, &val32); if (ret) goto quit3; norm = val32; snprintf(buf, sizeof(buf), "%.*s", (int)_region_size(&r1), (char *)_region_head(&r1)); /* buf: pivot name */ ret = open_subdb(&db3, db1, buf); if (ret) goto quit3; if (_db_lookup_by_s(db3, dst, &r2, NULL) != 0) /* don't break the loop, test all src/dst pairs. */ goto quit4; /* r2: norm among pivot and dst */ ret = get32(&r2, &val32); if (ret) goto quit4; norm += val32; /* judge minimum norm */ if (norm < *rnorm) { *rnorm = norm; strlcpy(pivot, buf, pvlen); } quit4: _db_close(db3); if (ret) goto quit3; } quit3: _db_close(db2); quit2: _db_close(db1); quit1: _unmap_file(&fr); if (ret) return ret; if (*rnorm == ULONG_MAX) return ENOENT; return 0; }
int _citrus_db_lookup(struct _citrus_db *db, struct _citrus_region *key, struct _citrus_region *data, struct _citrus_db_locator *dl) { struct _citrus_db_entry_x *dex; struct _citrus_db_header_x *dhx; struct _citrus_region r; struct _memstream ms; uint32_t hashval, num_entries; size_t offset; _memstream_bind(&ms, &db->db_region); dhx = _memstream_getregion(&ms, NULL, sizeof(*dhx)); num_entries = be32toh(dhx->dhx_num_entries); if (num_entries == 0) return (ENOENT); if (dl != NULL && dl->dl_offset>0) { hashval = dl->dl_hashval; offset = dl->dl_offset; if (offset >= _region_size(&db->db_region)) return (ENOENT); } else { hashval = db->db_hashfunc(key)%num_entries; offset = be32toh(dhx->dhx_entry_offset) + hashval * _CITRUS_DB_ENTRY_SIZE; if (dl) dl->dl_hashval = hashval; } do { /* seek to the next entry */ if (_citrus_memory_stream_seek(&ms, offset, SEEK_SET)) return (EFTYPE); /* get the entry record */ dex = _memstream_getregion(&ms, NULL, _CITRUS_DB_ENTRY_SIZE); if (dex == NULL) return (EFTYPE); /* jump to next entry having the same hash value. */ offset = be32toh(dex->dex_next_offset); /* save the current position */ if (dl) { dl->dl_offset = offset; if (offset == 0) dl->dl_offset = _region_size(&db->db_region); } /* compare hash value. */ if (be32toh(dex->dex_hash_value) != hashval) /* not found */ break; /* compare key length */ if (be32toh(dex->dex_key_size) == _region_size(key)) { /* seek to the head of the key. */ if (_memstream_seek(&ms, be32toh(dex->dex_key_offset), SEEK_SET)) return (EFTYPE); /* get the region of the key */ if (_memstream_getregion(&ms, &r, _region_size(key)) == NULL) return (EFTYPE); /* compare key byte stream */ if (memcmp(_region_head(&r), _region_head(key), _region_size(key)) == 0) { /* match */ if (_memstream_seek( &ms, be32toh(dex->dex_data_offset), SEEK_SET)) return (EFTYPE); if (_memstream_getregion( &ms, data, be32toh(dex->dex_data_size)) == NULL) return (EFTYPE); return (0); } } } while (offset != 0); return (ENOENT); }