From 05345016f1c62fbd02e3eb8302f1798ccdb425e9 Mon Sep 17 00:00:00 2001 From: peterb12 Date: Tue, 17 Apr 2007 15:00:59 +0000 Subject: First cut at db/flat text file based descriptions. git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@1331 c06c8d41-db1a-0410-9941-cceddc491573 --- crawl-ref/source/database.cc | 139 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 crawl-ref/source/database.cc (limited to 'crawl-ref/source/database.cc') diff --git a/crawl-ref/source/database.cc b/crawl-ref/source/database.cc new file mode 100644 index 0000000000..71927f6b8e --- /dev/null +++ b/crawl-ref/source/database.cc @@ -0,0 +1,139 @@ +/* + * database.cc + * Crawl + * + * Created by Peter Berger on 4/15/07. + * Copyright 2007 __MyCompanyName__. All rights reserved. + * + */ + +#ifdef UNIX +#include +#include +#include +#include +#include +#endif +#include +#include "database.h" +#include "files.h" + +// Convenience functions for (read-only) access to generic +// berkeley DB databases. + +#define nil 0 + +static bool databaseIsInitted = false; +dbList_t *openDBList; +DBM *descriptionDB; + +struct dbList_s { + DBM *dbPtr; + dbList_s *next; +} dbList_s; + + +void databaseSystemInit() { + if (!databaseIsInitted) { + databaseIsInitted = true; + openDBList = nil; + std::string descriptionPath = datafile_path("descriptions.db"); + descriptionPath.erase(descriptionPath.length() - 3, descriptionPath.length()); + descriptionDB = openDB(descriptionPath.c_str()); + } +} + +void databaseSystemShutdown() { + if (!databaseIsInitted) { + // All done. + return; + } + dbList_t *current = openDBList; + dbList_t *prev = nil; + while (current) { + dbm_close(current->dbPtr); + prev = current; + current = current->next; + free(prev); + } +} + +// This is here, and is external, just for future expansion -- if we +// want to allow external modules to manage their own DB, they can +// use this for the sake of convenience. It's arguable that it's +// morally wrong to have the database module manage the memory here. +// But hey, life is hard and you can write your own berkeley DB +// calls if you like. +DBM *openDB(const char *dbFilename) { + if (!databaseIsInitted) { + return nil; + } + DBM *dbToReturn = dbm_open(dbFilename, O_RDONLY, 0660); + if (dbToReturn) { + if (openDBList) { + dbList_t *endOfDBList = openDBList; + while (openDBList->next) { + endOfDBList = openDBList->next; + } + endOfDBList->next = (dbList_t *)malloc(sizeof(dbList_t)); + endOfDBList = endOfDBList->next; + endOfDBList->next = nil; + endOfDBList->dbPtr = dbToReturn; + + } else { + openDBList = (dbList_t *)malloc(sizeof(dbList_t)); + openDBList->next = nil; + openDBList->dbPtr = dbToReturn; + } + } else { + dbToReturn = nil; + } + return dbToReturn; +} + +datum database_fetch(DBM *database, const char *key) { + datum result; + result.dptr = nil; + result.dsize = 0; + if (!databaseIsInitted) { + return result; + } + datum dbKey; + + dbKey.dptr = (void *)key; + dbKey.dsize = strlen(key); + + result = dbm_fetch(database, dbKey); + + return result; +} + +char *private_strlwr(char *string) { + int i; + for (i = 0; string[i]; i++) { + string[i] = tolower(string[i]); + } + return string; +} + +std::string getLongDescription(const char *key) { + if (!databaseIsInitted) { + return nil; + } + // We have to canonicalize the key (in case the user typed it + // in and got the case wrong. + int len = strlen(key); + char *lowercaseKey = (char *)malloc(len+1); + (void) strncpy(lowercaseKey, key, len+1); + lowercaseKey = private_strlwr(lowercaseKey); + + // Query the DB. + datum result = database_fetch(descriptionDB, (const char *)lowercaseKey); + + // Cons up a (C++) string to return. The caller must release it. + std::string stringToReturn((const char *)result.dptr, result.dsize); + // free the result... + free(lowercaseKey); + + return stringToReturn; +} -- cgit v1.2.3-54-g00ecf