Browse Source

* error return codes

* add a lot of #define's
  * add imdb_error() for converting error code to detailed description
master
Alex 'AdUser' Z 8 years ago
parent
commit
5ec2a80866
  1. 41
      src/database.c
  2. 26
      src/database.h
  3. 2
      tests/database.c

41
src/database.c

@ -24,7 +24,7 @@
bytes = pread((db)->fd, (buf), (len), (off)); \ bytes = pread((db)->fd, (buf), (len), (off)); \
if (errno) { \ if (errno) { \
strncpy((db)->error, strerror(errno), sizeof(db->error)); \ strncpy((db)->error, strerror(errno), sizeof(db->error)); \
return -1; \ return IMDB_ERR_SYSTEM; \
} }
#define DB_WRITE(db, buf, len, off) \ #define DB_WRITE(db, buf, len, off) \
@ -32,7 +32,7 @@
bytes = pwrite((db)->fd, (buf), (len), (off)); \ bytes = pwrite((db)->fd, (buf), (len), (off)); \
if (errno) { \ if (errno) { \
strncpy((db)->error, strerror(errno), sizeof(db->error)); \ strncpy((db)->error, strerror(errno), sizeof(db->error)); \
return -1; \ return IMDB_ERR_SYSTEM; \
} }
const char *imdb_hdr_fmt = "IMDB v%02u, CAPS: %s;"; const char *imdb_hdr_fmt = "IMDB v%02u, CAPS: %s;";
@ -74,31 +74,31 @@ imdb_open(const char *path, int mode, int *error) {
assert(error != NULL); assert(error != NULL);
if (stat(path, &st) < 0) { if (stat(path, &st) < 0) {
*error = -1; *error = IMDB_ERR_SYSTEM;
return NULL; return NULL;
} }
if ((fd = open(path, (mode & IMDB_FLAG_WRITE) ? O_RDWR : O_RDONLY)) < 0) { if ((fd = open(path, (mode & IMDB_FLAG_WRITE) ? O_RDWR : O_RDONLY)) < 0) {
*error = -1; *error = IMDB_ERR_SYSTEM;
return NULL; return NULL;
} }
errno = 0; errno = 0;
bytes = pread(fd, buf, IMDB_REC_LEN, 0); bytes = pread(fd, buf, IMDB_REC_LEN, 0);
if (bytes < IMDB_REC_LEN) { if (bytes < IMDB_REC_LEN) {
*error = errno ? -1 : -3; /* empty file, damaged database or IO error */ *error = errno ? IMDB_ERR_SYSTEM : IMDB_ERR_CORRUPTDB;
return NULL; return NULL;
} }
p = buf + 0; p = buf + 0;
if (memcmp("IMDB", p, 4) != 0) { if (memcmp("IMDB", p, 4) != 0) {
*error = -3; /* Not a database file */ *error = IMDB_ERR_CORRUPTDB;
return NULL; return NULL;
} }
p = buf + 6; p = buf + 6;
if (atoi(p) != IMDB_VERSION) { if (atoi(p) != IMDB_VERSION) {
*error = -4; /* Database version mismatch */ *error = IMDB_ERR_WRONGVERS;
return NULL; return NULL;
} }
@ -114,7 +114,7 @@ imdb_open(const char *path, int mode, int *error) {
/* all seems to be ok */ /* all seems to be ok */
if ((db = calloc(1, sizeof(imdb_db_t))) == NULL) { if ((db = calloc(1, sizeof(imdb_db_t))) == NULL) {
*error = -2; /* out of memory */ *error = IMDB_ERR_OOM;
return NULL; return NULL;
} }
@ -146,6 +146,22 @@ imdb_close(imdb_db_t *db)
close(db->fd); close(db->fd);
} }
const char *
imdb_error(int error) {
if (error == IMDB_SUCCESS) {
return "success";
} else if (error == IMDB_ERR_SYSTEM) {
return strerror(errno);
} else if (error == IMDB_ERR_OOM) {
return "can't allocate memory";
} else if (error == IMDB_ERR_CORRUPTDB) {
return "database corrupted";
} else if (error == IMDB_ERR_WRONGVERS) {
return "database version differs from library version";
}
return "unknown error";
}
int imdb_read_rec(imdb_db_t *db, imdb_rec_t *rec) int imdb_read_rec(imdb_db_t *db, imdb_rec_t *rec)
{ {
ssize_t bytes = 0; ssize_t bytes = 0;
@ -157,7 +173,7 @@ int imdb_read_rec(imdb_db_t *db, imdb_rec_t *rec)
DB_READ(db, rec->data, IMDB_REC_LEN, rec->num * IMDB_REC_LEN); DB_READ(db, rec->data, IMDB_REC_LEN, rec->num * IMDB_REC_LEN);
if (bytes != IMDB_REC_LEN) if (bytes != IMDB_REC_LEN)
return -1; return errno ? IMDB_ERR_SYSTEM : 0;
if (rec->data[0] != 0xFF) if (rec->data[0] != 0xFF)
return 0; return 0;
@ -176,7 +192,7 @@ int imdb_write_rec(imdb_db_t *db, imdb_rec_t *rec)
DB_WRITE(db, rec->data, IMDB_REC_LEN, rec->num * IMDB_REC_LEN); DB_WRITE(db, rec->data, IMDB_REC_LEN, rec->num * IMDB_REC_LEN);
if (bytes != IMDB_REC_LEN) if (bytes != IMDB_REC_LEN)
return -1; return IMDB_ERR_SYSTEM;
return 1; return 1;
} }
@ -235,6 +251,7 @@ imdb_search(imdb_db_t * const db,
unsigned char *p = NULL; unsigned char *p = NULL;
float ratio_s = 0.0; /* source */ float ratio_s = 0.0; /* source */
float ratio_t = 0.0; /* tested */ float ratio_t = 0.0; /* tested */
int ret = 0;
assert(db != NULL); assert(db != NULL);
assert(sample != NULL); assert(sample != NULL);
@ -248,9 +265,9 @@ imdb_search(imdb_db_t * const db,
blk.start = 1; blk.start = 1;
blk.records = blk_size; blk.records = blk_size;
if (imdb_read_rec(db, sample) < 1) { if ((ret = imdb_read_rec(db, sample)) < 1) {
strncpy(db->error, "Can't read source sample", sizeof(db->error)); strncpy(db->error, "Can't read source sample", sizeof(db->error));
return -1; return ret;
} }
if (search->limit == 0) if (search->limit == 0)

26
src/database.h

@ -13,6 +13,13 @@
#define IMDB_CAP_RATIO 1 << (8 + 2) #define IMDB_CAP_RATIO 1 << (8 + 2)
/* 3 used, 5 reserved */ /* 3 used, 5 reserved */
#define IMDB_SUCCESS 0
/* database errors */
#define IMDB_ERR_SYSTEM -1 /* see errno for details */
#define IMDB_ERR_OOM -2 /* can't allocate memory */
#define IMDB_ERR_CORRUPTDB -3 /* empty or currupted database */
#define IMDB_ERR_WRONGVERS -4 /* database version mismatch */
typedef struct { typedef struct {
int fd; int fd;
int flags; int flags;
@ -92,8 +99,7 @@ typedef struct {
} imdb_match_t; } imdb_match_t;
/** /**
* @return 1 on success, 0 if record not used * @returns 1 on success, 0 if record missing and <0 on error
* and -1 if record number not exists,
*/ */
int imdb_read_rec (imdb_db_t *db, imdb_rec_t *rec); int imdb_read_rec (imdb_db_t *db, imdb_rec_t *rec);
int imdb_write_rec(imdb_db_t *db, imdb_rec_t *rec); int imdb_write_rec(imdb_db_t *db, imdb_rec_t *rec);
@ -116,10 +122,7 @@ bool imdb_create(const char *path);
* @param mode Database open modes. See IMDB_FLAG_* defines above * @param mode Database open modes. See IMDB_FLAG_* defines above
* @param error Pointer to error code storage * @param error Pointer to error code storage
* @returns Pointer to database handle on success, NULL on error * @returns Pointer to database handle on success, NULL on error
* -1 -- system error, see @a errno for details * @note use @a imdb_error() to get error description
* -2 -- malloc() failed
* -3 -- damaged database
* -4 -- database version mismatch
*/ */
imdb_db_t * imdb_open(const char *path, int mode, int *error); imdb_db_t * imdb_open(const char *path, int mode, int *error);
@ -129,14 +132,17 @@ imdb_db_t * imdb_open(const char *path, int mode, int *error);
*/ */
void imdb_close(imdb_db_t *db); void imdb_close(imdb_db_t *db);
/**
* @brief Get error desctiption by error code
* @param error Error code, see IMDB_ERR_* defines above
*/
const char * imdb_error(int code);
float float
ratio_from_rec_data(unsigned char * const data); ratio_from_rec_data(unsigned char * const data);
/** /**
@returns: @returns: >0 if found some matches, 0 if nothing found, <0 on error
-1 on error
0 if nothing found
>0 if found some matches
*/ */
int int
imdb_search(imdb_db_t * const db, imdb_search(imdb_db_t * const db,

2
tests/database.c

@ -24,7 +24,7 @@ int main()
rec[0].num = 1; rec[0].num = 1;
err = imdb_read_rec(db, rec); err = imdb_read_rec(db, rec);
assert(err < 0); /* no such record */ assert(err == 0); /* no such record */
memset(rec[0].data, 0xAA, IMDB_REC_LEN); memset(rec[0].data, 0xAA, IMDB_REC_LEN);
memset(rec[0].data, 0xFF, 1); /* record is used */ memset(rec[0].data, 0xFF, 1); /* record is used */

Loading…
Cancel
Save