Alex 'AdUser' Z
11 years ago
8 changed files with 271 additions and 52 deletions
@ -0,0 +1,193 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation; either version 2 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU Library General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program; if not, write to the Free Software |
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA |
||||
*/ |
||||
|
||||
#include "main.h" |
||||
#include "database.h" |
||||
|
||||
#define DB_SEEK(db, offset) \ |
||||
errno = 0; \
|
||||
if (lseek((db)->fd, (offset), SEEK_SET) == -1) { \
|
||||
(db)->errstr = strerror(errno); \
|
||||
return -1; \
|
||||
} |
||||
|
||||
#define DB_READ(db, buf, len) \ |
||||
errno = 0; \
|
||||
memset((buf), 0x0, (len)); \
|
||||
bytes = read((db)->fd, (buf), (len)); \
|
||||
if (errno) { \
|
||||
(db)->errstr = strerror(errno); \
|
||||
return -1; \
|
||||
} |
||||
|
||||
#define DB_WRITE(db, buf, len) \ |
||||
errno = 0; \
|
||||
bytes = write((db)->fd, (buf), (len)); \
|
||||
if (errno) { \
|
||||
(db)->errstr = strerror(errno); \
|
||||
return -1; \
|
||||
} |
||||
|
||||
int db_open(db_t *db, const char *path) |
||||
{ |
||||
int init = 0; |
||||
ssize_t bytes = 0; |
||||
struct stat st; |
||||
char buf[REC_LEN] = "\0"; |
||||
|
||||
assert(db != NULL); |
||||
assert(path != NULL); |
||||
|
||||
memset(db, 0x0, sizeof(db_t)); |
||||
db->fd = -1; |
||||
|
||||
errno = 0; |
||||
if (stat(path, &st) == -1 && errno == ENOENT) { |
||||
init = 1; |
||||
} |
||||
|
||||
errno = 0; |
||||
if ((db->fd = open(path, OPEN_FLAGS, 0644)) == -1) { |
||||
db->errstr = strerror(errno); |
||||
return -1; |
||||
} |
||||
|
||||
db->path = path; |
||||
|
||||
if (init) { |
||||
memset(buf, 0x0, REC_LEN); |
||||
snprintf((char *) buf, REC_LEN, "DB of image fingerprints (vers %d)", DB_VERSION); |
||||
DB_SEEK(db, 0); |
||||
DB_WRITE(db, buf, REC_LEN); |
||||
|
||||
return bytes / REC_LEN; |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int db_close(db_t *db) |
||||
{ |
||||
assert(db != NULL); |
||||
|
||||
errno = 0; |
||||
if (close(db->fd) != 0) { |
||||
db->errstr = strerror(errno); |
||||
return -1; |
||||
} |
||||
db->fd = -1; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
int db_rd_rec(db_t *db, rec_t *rec) |
||||
{ |
||||
ssize_t bytes = 0; |
||||
|
||||
assert(db != NULL); |
||||
assert(rec != NULL); |
||||
assert(rec->num > 0); |
||||
|
||||
DB_SEEK(db, rec->num * REC_LEN); |
||||
DB_READ(db, rec->data, REC_LEN); |
||||
|
||||
return bytes / REC_LEN; |
||||
} |
||||
|
||||
int db_wr_rec(db_t *db, rec_t *rec) |
||||
{ |
||||
ssize_t bytes = 0; |
||||
|
||||
assert(db != NULL); |
||||
assert(rec != NULL); |
||||
assert(rec->num > 0); |
||||
|
||||
DB_SEEK(db, rec->num * REC_LEN); |
||||
DB_WRITE(db, rec->data, REC_LEN); |
||||
|
||||
return bytes / REC_LEN; |
||||
} |
||||
|
||||
int db_rd_blk(db_t *db, uint64_t start, size_t len, rec_t *list) |
||||
{
|
||||
rec_t *r = NULL; |
||||
ssize_t bytes = 0; |
||||
unsigned int i = 0; |
||||
unsigned char *buf; |
||||
unsigned char *p = NULL; |
||||
|
||||
assert(db != NULL); |
||||
assert(list != NULL); |
||||
assert(len > 0); |
||||
|
||||
CALLOC(buf, len, REC_LEN); |
||||
DB_SEEK(db, start * REC_LEN); |
||||
DB_READ(db, buf, len * REC_LEN); |
||||
|
||||
p = buf; |
||||
r = list; |
||||
len = bytes / REC_LEN; |
||||
for (i = 0; i < len; i++, r++, p += REC_LEN) { |
||||
r->num = start + i; |
||||
memcpy(r->data, p, REC_LEN); |
||||
} |
||||
|
||||
FREE(buf); |
||||
|
||||
return len; |
||||
} |
||||
|
||||
int db_rd_list(db_t *db, rec_t *list, size_t list_len) |
||||
{ |
||||
rec_t *r = NULL; |
||||
ssize_t bytes; |
||||
unsigned int i = 0; |
||||
unsigned int processed = 0; |
||||
|
||||
assert(db != NULL); |
||||
assert(list != NULL); |
||||
assert(list_len > 0); |
||||
|
||||
r = list; |
||||
for (i = 0; i < list_len; i++, r++) { |
||||
DB_SEEK(db, r->num * REC_LEN); |
||||
DB_READ(db, r->data, REC_LEN); |
||||
if (bytes == REC_LEN) { processed++; } |
||||
} |
||||
|
||||
return processed; |
||||
} |
||||
|
||||
int db_wr_list(db_t *db, rec_t *list, size_t list_len) |
||||
{ |
||||
rec_t *r = NULL; |
||||
ssize_t bytes; |
||||
unsigned int i = 0; |
||||
unsigned int processed = 0; |
||||
|
||||
assert(db != NULL); |
||||
assert(list != NULL); |
||||
assert(list_len > 0); |
||||
|
||||
r = list; |
||||
for (i = 0; i < list_len; i++, r++) { |
||||
DB_SEEK(db, r->num * REC_LEN); |
||||
DB_WRITE(db, r->data, REC_LEN); |
||||
if (bytes == REC_LEN) { processed++; } |
||||
} |
||||
|
||||
return processed; |
||||
} |
@ -0,0 +1,31 @@
|
||||
#ifndef HAS_DATABASE_H |
||||
|
||||
#define REC_LEN 48 |
||||
#define DB_VERSION 1 |
||||
#define OPEN_FLAGS O_CREAT | O_RDWR |
||||
|
||||
typedef struct { |
||||
int fd; |
||||
const char *path; |
||||
const char *errstr; |
||||
} db_t; |
||||
|
||||
typedef struct { |
||||
uint64_t num; |
||||
unsigned char data[REC_LEN]; |
||||
} rec_t; |
||||
|
||||
extern int db_open(db_t *db, const char *path); |
||||
extern int db_close(db_t *db); |
||||
|
||||
extern int db_rd_rec(db_t *db, rec_t *rec); |
||||
extern int db_wr_rec(db_t *db, rec_t *rec); |
||||
|
||||
extern int db_rd_blk(db_t *db, uint64_t start, size_t len, rec_t *list); |
||||
extern int db_wr_blk(db_t *db, uint64_t start, size_t len, rec_t *list); |
||||
|
||||
extern int db_rd_list(db_t *db, rec_t *list, size_t list_len); |
||||
extern int db_wr_list(db_t *db, rec_t *list, size_t list_len); |
||||
|
||||
#endif |
||||
#define HAS_DATABASE_H 1 |
@ -1,34 +0,0 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation; either version 2 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU Library General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program; if not, write to the Free Software |
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301, USA |
||||
*/ |
||||
|
||||
#include "main.h" |
||||
#include <gdbm.h> |
||||
|
||||
#define DB_BLOCKSIZE 256 * 1024 |
||||
|
||||
GDBM_FILE dbf; |
||||
|
||||
int db_open(char *samples, char *files) |
||||
{ |
||||
dbf = gdbm_open(samples, DB_BLOCKSIZE, GDBM_WRCREAT, 0644, 0); |
||||
|
||||
if (!dbf) { |
||||
printf("Can't open database: %s\n", gdbm_strerror(gdbm_errno)); |
||||
return 0; |
||||
} |
||||
|
||||
return 1; |
||||
} |
@ -1,13 +1,14 @@
|
||||
all: test-bitmap |
||||
TESTS=test-bitmap test-database
|
||||
|
||||
all: $(TESTS) |
||||
|
||||
CFLAGS=-Wall -Wextra -O0 -g -ggdb -pedantic
|
||||
|
||||
%.o: %.c |
||||
gcc $(CFLAGS) $< -o $@
|
||||
gcc $(CFLAGS) -o $@ $<
|
||||
|
||||
SRC=../src/bitmap.c bitmap.c
|
||||
test-bitmap: |
||||
gcc $(CFLAGS) $(SRC) -o $@
|
||||
test-%: ../src/%.c %.c |
||||
gcc $(CFLAGS) $(SRC) -o $@ $^
|
||||
|
||||
clean: |
||||
rm -f test-bitmap
|
||||
rm -f $(TESTS)
|
||||
|
@ -0,0 +1,31 @@
|
||||
#include "../src/main.h" |
||||
#include "../src/database.h" |
||||
|
||||
int main(int argc, char **argv) |
||||
{ |
||||
db_t db; |
||||
rec_t rec[2]; |
||||
char *path = "test.db"; |
||||
|
||||
unlink(path); |
||||
assert(db_open(&db, path) == 1); |
||||
|
||||
rec[0].num = 1; |
||||
assert(db_rd_rec(&db, rec) == 0); |
||||
|
||||
memset(rec[0].data, 0xAA, REC_LEN); |
||||
assert(db_wr_rec(&db, rec) == 1); |
||||
|
||||
assert(db_rd_rec(&db, rec) == 1); |
||||
|
||||
assert(db_rd_blk(&db, 1, 1, rec) == 1); |
||||
assert(db_rd_blk(&db, 1, 2, rec) == 1); |
||||
|
||||
rec[0].num = 1; |
||||
rec[1].num = 3; |
||||
assert(db_rd_list(&db, rec, 2) == 1); |
||||
|
||||
assert(db_close(&db) == 0); |
||||
|
||||
return 0; |
||||
} |
Loading…
Reference in new issue