/* {{{ inifile_find_group * if found pos_grp_start points to "[group_name]" */ static int inifile_find_group(inifile *dba, const key_type *key, size_t *pos_grp_start) { int ret = FAILURE; php_stream_flush(dba->fp); php_stream_seek(dba->fp, 0, SEEK_SET); inifile_line_free(&dba->curr); inifile_line_free(&dba->next); if (key->group && strlen(key->group)) { int res; line_type ln = {{NULL,NULL},{NULL}}; res = 1; while(inifile_read(dba, &ln)) { if ((res=inifile_key_cmp(&ln.key, key)) < 2) { ret = SUCCESS; break; } *pos_grp_start = php_stream_tell(dba->fp); } inifile_line_free(&ln); } else { *pos_grp_start = 0; ret = SUCCESS; } if (ret == FAILURE) { *pos_grp_start = php_stream_tell(dba->fp); } return ret; }
/* {{{ inifile_free */ void inifile_free(inifile *dba, int persistent) { if (dba) { inifile_line_free(&dba->curr); inifile_line_free(&dba->next); pefree(dba, persistent); } }
/* {{{ inifile_nextkey */ int inifile_nextkey(inifile *dba) { line_type ln = {{NULL,NULL},{NULL}}; /*inifile_line_free(&dba->next); ??? */ php_stream_seek(dba->fp, dba->curr.pos, SEEK_SET); ln.key.group = estrdup(dba->curr.key.group ? dba->curr.key.group : ""); inifile_read(dba, &ln); inifile_line_free(&dba->curr); dba->curr = ln; return ln.key.group || ln.key.name; }
/* {{{ inifile_findkey */ static int inifile_read(inifile *dba, line_type *ln) { char *fline; char *pos; inifile_val_free(&ln->val); while ((fline = php_stream_gets(dba->fp, NULL, 0)) != NULL) { if (fline) { if (fline[0] == '[') { /* A value name cannot start with '[' * So either we find a ']' or we found an error */ pos = strchr(fline+1, ']'); if (pos) { *pos = '\0'; inifile_key_free(&ln->key); ln->key.group = etrim(fline+1); ln->key.name = estrdup(""); ln->pos = php_stream_tell(dba->fp); efree(fline); return 1; } else { efree(fline); continue; } } else { pos = strchr(fline, '='); if (pos) { *pos = '\0'; /* keep group or make empty if not existent */ if (!ln->key.group) { ln->key.group = estrdup(""); } if (ln->key.name) { efree(ln->key.name); } ln->key.name = etrim(fline); ln->val.value = etrim(pos+1); ln->pos = php_stream_tell(dba->fp); efree(fline); return 1; } else { /* simply ignore lines without '=' * those should be comments */ efree(fline); continue; } } } } inifile_line_free(ln); return 0; }
/* {{{ inifile_fetch */ val_type inifile_fetch(inifile *dba, const key_type *key, int skip) { line_type ln = {{NULL,NULL},{NULL}}; val_type val; int res, grp_eq = 0; if (skip == -1 && dba->next.key.group && dba->next.key.name && !inifile_key_cmp(&dba->next.key, key)) { /* we got position already from last fetch */ php_stream_seek(dba->fp, dba->next.pos, SEEK_SET); ln.key.group = estrdup(dba->next.key.group); } else { /* specific instance or not same key -> restart search */ /* the slow way: restart and seacrch */ php_stream_rewind(dba->fp); inifile_line_free(&dba->next); } if (skip == -1) { skip = 0; } while(inifile_read(dba, &ln)) { if (!(res=inifile_key_cmp(&ln.key, key))) { if (!skip) { val.value = estrdup(ln.val.value ? ln.val.value : ""); /* allow faster access by updating key read into next */ inifile_line_free(&dba->next); dba->next = ln; dba->next.pos = php_stream_tell(dba->fp); return val; } skip--; } else if (res == 1) { grp_eq = 1; } else if (grp_eq) { /* we are leaving group now: that means we cannot find the key */ break; } } inifile_line_free(&ln); dba->next.pos = php_stream_tell(dba->fp); return ln.val; }
/* {{{ inifile_next_group * only valid after a call to inifile_find_group * if any next group is found pos_grp_start points to "[group_name]" or whitespace before that */ static int inifile_next_group(inifile *dba, const key_type *key, size_t *pos_grp_start) { int ret = FAILURE; line_type ln = {{NULL,NULL},{NULL}}; *pos_grp_start = php_stream_tell(dba->fp); ln.key.group = estrdup(key->group); while(inifile_read(dba, &ln)) { if (inifile_key_cmp(&ln.key, key) == 2) { ret = SUCCESS; break; } *pos_grp_start = php_stream_tell(dba->fp); } inifile_line_free(&ln); return ret; }
/* {{{ inifile_filter * copy from to dba while ignoring key name (group must equal) */ static int inifile_filter(inifile *dba, inifile *from, const key_type *key, zend_bool *found) { size_t pos_start = 0, pos_next = 0, pos_curr; int ret = SUCCESS; line_type ln = {{NULL,NULL},{NULL}}; php_stream_seek(from->fp, 0, SEEK_SET); php_stream_seek(dba->fp, 0, SEEK_END); while(inifile_read(from, &ln)) { switch(inifile_key_cmp(&ln.key, key)) { case 0: if (found) { *found = (zend_bool) 1; } pos_curr = php_stream_tell(from->fp); if (pos_start != pos_next) { php_stream_seek(from->fp, pos_start, SEEK_SET); if (SUCCESS != php_stream_copy_to_stream_ex(from->fp, dba->fp, pos_next - pos_start, NULL)) { php_error_docref(NULL, E_WARNING, "Could not copy [%zu - %zu] from temporary stream", pos_next, pos_start); ret = FAILURE; } php_stream_seek(from->fp, pos_curr, SEEK_SET); } pos_next = pos_start = pos_curr; break; case 1: pos_next = php_stream_tell(from->fp); break; case 2: /* the function is meant to process only entries from same group */ assert(0); break; } } if (pos_start != pos_next) { php_stream_seek(from->fp, pos_start, SEEK_SET); if (SUCCESS != php_stream_copy_to_stream_ex(from->fp, dba->fp, pos_next - pos_start, NULL)) { php_error_docref(NULL, E_WARNING, "Could not copy [%zu - %zu] from temporary stream", pos_next, pos_start); ret = FAILURE; } } inifile_line_free(&ln); return ret; }
/* {{{ inifile_firstkey */ int inifile_firstkey(inifile *dba) { inifile_line_free(&dba->curr); dba->curr.pos = 0; return inifile_nextkey(dba); }