Browse Source

* database.[ch]

master
Alex 'AdUser' Z 10 years ago
parent
commit
1ef515e77a
  1. 8
      src/Makefile
  2. 193
      src/database.c
  3. 31
      src/database.h
  4. 34
      src/main.c
  5. 10
      src/main.h
  6. 3
      src/test-image.c
  7. 13
      tests/Makefile
  8. 31
      tests/database.c

8
src/Makefile

@ -1,15 +1,9 @@
CFLAGS=-Wall -Wextra -O0 -g -ggdb -pedantic
all: test-image
%.c: %.h
all: *.o
%.o: %.c
gcc -O0 -Wall -Wextra -pedantic -ggdb $< -o $@
clean:
rm -f *.o
rm -f test-image
test-image: image.c test-image.c
gcc $(CFLAGS) -lmagic -lgd image.c test-image.c -o $@

193
src/database.c

@ -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;
}

31
src/database.h

@ -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

34
src/main.c

@ -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;
}

10
src/main.h

@ -7,10 +7,13 @@
#include <string.h>
#include <unistd.h>
#include <assert.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <limits.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <db.h>
#define FREE(ptr) \
free((ptr)); (ptr) = NULL;
@ -21,10 +24,9 @@
#define STRNDUP(ptr, str, len) \
assert(((ptr) = strndup((str), (len))) != NULL);
extern int db_open(char *samples, char *files);
extern int db_close(void);
extern int image_add(uint64_t, char *path);
extern int image_del(uint64_t);
extern int image_exists(uint64_t);
/*extern int image_find(uint64_t, rec_t **data, size_t limit);*/
/*
extern int image_search(uint64_t, rec_t **data, size_t limit);
*/

3
src/test-image.c

@ -4,7 +4,8 @@
#include "bitmap.h"
#include "image.h"
int main(int argc, char **argv) {
int main(int argc, char **argv)
{
image_t *img = NULL;
const char *err = NULL;

13
tests/Makefile

@ -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)

31
tests/database.c

@ -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…
Cancel
Save