return read_u32s(in, l, 1);
}
-static ssize_t buf_freadchars(struct strbuf *buf, FILE *in)
-{
- ssize_t i = 0;
- int ch;
-
- while ((ch = read_char(in))) {
- if (ch == EOF || !strbuf_pushchar(buf, ch))
- return -1;
- i++;
- }
-
- return i;
-}
-
/*
* Index file searching
*/
-struct index_node_f {
+struct index_file {
FILE *file;
+ uint32_t root_offset;
+ char *tmp;
+ size_t tmp_size;
+};
+
+struct index_node_f {
+ struct index_file *idx;
char *prefix; /* path compression */
struct index_value *values;
unsigned char first; /* range of child nodes */
uint32_t children[0];
};
-static struct index_node_f *index_read(FILE *in, uint32_t offset)
+static struct index_node_f *index_read(struct index_file *idx, uint32_t offset)
{
struct index_node_f *node = NULL;
char *prefix = NULL;
size_t child_count = 0;
+ FILE *fp = idx->file;
if ((offset & INDEX_NODE_MASK) == 0)
return NULL;
- if (fseek(in, offset & INDEX_NODE_MASK, SEEK_SET) < 0)
+ if (fseek(fp, offset & INDEX_NODE_MASK, SEEK_SET) < 0)
return NULL;
if (offset & INDEX_NODE_PREFIX) {
- struct strbuf buf;
- strbuf_init(&buf);
- if (buf_freadchars(&buf, in) < 0) {
- strbuf_release(&buf);
+ if (getdelim(&idx->tmp, &idx->tmp_size, '\0', fp) < 0)
return NULL;
- }
- prefix = strbuf_steal(&buf);
+ prefix = strdup(idx->tmp);
} else
prefix = strdup("");
goto err;
if (offset & INDEX_NODE_CHILDS) {
- int first = read_char(in);
- int last = read_char(in);
+ int first = read_char(fp);
+ int last = read_char(fp);
if (first == EOF || last == EOF || first > last)
goto err;
node->first = (unsigned char)first;
node->last = (unsigned char)last;
- if (!read_u32s(in, node->children, child_count))
+ if (!read_u32s(fp, node->children, child_count))
goto err;
} else {
node = malloc(sizeof(struct index_node_f));
node->values = NULL;
if (offset & INDEX_NODE_VALUES) {
uint32_t value_count;
- struct strbuf buf;
- const char *value;
unsigned int priority;
- if (!read_u32(in, &value_count))
+ if (!read_u32(fp, &value_count))
goto err;
- strbuf_init(&buf);
while (value_count--) {
- if (!read_u32(in, &priority) || buf_freadchars(&buf, in) < 0) {
- strbuf_release(&buf);
+ ssize_t n;
+
+ if (!read_u32(fp, &priority))
goto err;
- }
- value = strbuf_str(&buf);
- if (value == NULL) {
- strbuf_release(&buf);
+ n = getdelim(&idx->tmp, &idx->tmp_size, '\0', fp);
+ if (n < 0)
goto err;
- }
- add_value(&node->values, value, buf.used, priority);
- strbuf_clear(&buf);
+ add_value(&node->values, idx->tmp, n, priority);
}
- strbuf_release(&buf);
}
node->prefix = prefix;
- node->file = in;
+ node->idx = idx;
return node;
err:
free(prefix);
free(node);
}
-struct index_file {
- FILE *file;
- uint32_t root_offset;
-};
-
struct index_file *index_file_open(const char *filename)
{
FILE *file;
free(new);
goto err;
}
+ new->tmp = NULL;
+ new->tmp_size = 0;
errno = 0;
return new;
void index_file_close(struct index_file *idx)
{
fclose(idx->file);
+ free(idx->tmp);
free(idx);
}
static struct index_node_f *index_readroot(struct index_file *in)
{
- return index_read(in->file, in->root_offset);
+ return index_read(in, in->root_offset);
}
static struct index_node_f *index_readchild(const struct index_node_f *parent, int ch)
{
if (parent->first <= ch && ch <= parent->last) {
- return index_read(parent->file, parent->children[ch - parent->first]);
+ return index_read(parent->idx, parent->children[ch - parent->first]);
}
return NULL;