/* write mode */ void xdb_nput(xdb_t x, void *value, unsigned int vlen, const char *key, int len) { xrec_st rec; if (x == NULL || x->fd < 0 || key == NULL || len > XDB_MAXKLEN) return; /* not found, return the poff(for write) */ _xdb_rec_find(x, key, len, &rec); if (rec.value.len > 0 && vlen <= rec.value.len) { /* just replace */ if (vlen > 0) { lseek(x->fd, rec.value.off, SEEK_SET); write(x->fd, value, vlen); } if (vlen < rec.value.len) { vlen += rec.me.len - rec.value.len; lseek(x->fd, rec.poff + 4, SEEK_SET); write(x->fd, &vlen, sizeof(vlen)); } } else if (vlen > 0) { /* insert for new data */ unsigned char buf[512]; xptr_st pnew; pnew.off = x->fsize; memset(buf, 0, sizeof(buf)); pnew.len = rec.me.len - rec.value.len; if (pnew.len > 0) { _xdb_read_data(x, buf, rec.me.off, pnew.len); } else { buf[16] = len; // key len strncpy(buf + 17, key, len); pnew.len = 17 + len; } lseek(x->fd, pnew.off, SEEK_SET); write(x->fd, buf, pnew.len); write(x->fd, value, vlen); pnew.len += vlen; x->fsize += pnew.len; /* update noff & vlen -> poff */ lseek(x->fd, rec.poff, SEEK_SET); write(x->fd, &pnew, sizeof(pnew)); } }
/* read mode (value require free by user) */ void *xdb_nget(xdb_t x, const char *key, int len, unsigned int *vlen) { xrec_st rec; void *value = NULL; if (x == NULL || key == NULL || len > XDB_MAXKLEN) return NULL; /* not found, return the poff(for write) */ _xdb_rec_find(x, key, len, &rec); if (rec.value.len > 0) { /* auto append one byte with '\0' */ value = malloc(rec.value.len + 1); if (vlen != NULL) *vlen = rec.value.len; _xdb_read_data(x, value, rec.value.off, rec.value.len); } return value; }