Добавил:
Kaz
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:
#include "stdafx.h"
#include "PhoneDB.h"
#include "delimstrings.h"
#define PHONE_DB_MAP_OBJECT_NAME TEXT("Osisp_lab4, PhoneDB. Tsar Art & Turuta Sa 851002")
// must be NULL if db is not opened!
static HANDLE g_hFileMapping = NULL;
static const char *g_DbBeginPtr = NULL;
static const char *g_DbLimitPtr = NULL;
static BOOL g_DatabaseOpened = FALSE;
static int g_CountOfRecords = 0;
BOOL APIENTRY
DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved )
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
if (g_DatabaseOpened)
CloseDatabase();
break;
}
return TRUE;
}
PHONEDB_API const char*
OpenDatabase(const TCHAR *filename, int *cRecordsPtr)
#define RETURN(ret)\
do {\
if (ret == NULL)\
g_DatabaseOpened = FALSE;\
else\
g_DatabaseOpened = TRUE;\
g_DbBeginPtr = ret;\
return ret;\
} while(0)
{
if (g_DatabaseOpened)
return NULL; //do nothing, so don't use RETURN macro
HANDLE hFile = CreateFile(
filename,
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile == INVALID_HANDLE_VALUE)
RETURN(NULL);
LARGE_INTEGER fileSize;
if (GetFileSizeEx(hFile, &fileSize) == FALSE) {
CloseHandle(hFile);
RETURN(NULL);
}
g_hFileMapping = CreateFileMapping(
hFile,
NULL,
PAGE_READONLY,
fileSize.HighPart, fileSize.LowPart,
PHONE_DB_MAP_OBJECT_NAME);
if (g_hFileMapping == NULL) {
CloseHandle(hFile);
RETURN(NULL);
}
const char *retval;
retval = (const char*)MapViewOfFile(
g_hFileMapping,
FILE_MAP_READ,
0, 0, 0);
if (retval == NULL) {
CloseHandle(g_hFileMapping);
g_hFileMapping = NULL;
CloseHandle(hFile);
} else {
g_DbBeginPtr = retval;
g_DbLimitPtr = (const char*)((char*)g_DbBeginPtr + fileSize.LowPart);
g_CountOfRecords = 0;
for (const char *c = g_DbBeginPtr; c < g_DbLimitPtr; c++)
if (*c == '\n')
g_CountOfRecords++;
if (cRecordsPtr)
*cRecordsPtr = g_CountOfRecords;
}
RETURN(retval);
#undef RETURN
}
PHONEDB_API BOOL
CloseDatabase(void)
{
if (!g_DatabaseOpened)
return FALSE;
if (UnmapViewOfFile(g_DbBeginPtr) == FALSE)
return FALSE;
CloseHandle(g_hFileMapping);
g_hFileMapping = NULL;
g_DbBeginPtr = NULL;
g_DbLimitPtr = NULL;
g_DatabaseOpened = NULL;
g_CountOfRecords = 0;
return TRUE;
}
PHONEDB_API BOOL
SearchInDatabase(PHONE_DB_RECORD *foundRecordPtr,
const PHONE_DB_RECORD *templateRecordPtr,
int cEqualFieldsNeed)
#define MAKE_COPY(field_name)\
cchCpied = DelimStrCpy(foundRecordPtr->field_name, searchPos, ";\n\r",\
g_DbLimitPtr, _countof(foundRecordPtr->field_name));\
\
foundRecordPtr->field_name[cchCpied-1] = '\0';\
if (cchCpied == 0)\
return FALSE;\
\
searchPos += cchCpied;\
if (searchPos[-1] == '\n')\
goto end_of_record_reached;
{
static const char *searchEndPos = NULL;
if (foundRecordPtr == NULL) {
searchEndPos = g_DbBeginPtr;
return TRUE;
}
if (searchEndPos == NULL)
searchEndPos = g_DbBeginPtr;
foundRecordPtr->phone[0] = '\0';
foundRecordPtr->lastname[0] = '\0';
foundRecordPtr->name[0] = '\0';
foundRecordPtr->patronym[0] = '\0';
foundRecordPtr->street[0] = '\0';
foundRecordPtr->house[0] = '\0';
foundRecordPtr->housing[0] = '\0';
foundRecordPtr->apartment[0] = '\0';
const char *searchPos = searchEndPos;
BOOL retval = FALSE;
while (searchPos < g_DbLimitPtr) {
int cchCpied;
MAKE_COPY(phone);
MAKE_COPY(lastname);
MAKE_COPY(name);
MAKE_COPY(patronym);
MAKE_COPY(street);
MAKE_COPY(house);
MAKE_COPY(housing);
MAKE_COPY(apartment);
for (; *searchPos != '\n' && searchPos < g_DbLimitPtr; searchPos++)
;
end_of_record_reached:
int cEqualFields = 0;
#define MAKE_COMPARE(field_name)\
if (templateRecordPtr->field_name[0] != '\0')\
cEqualFields += !lstrcmpiA(foundRecordPtr->field_name, templateRecordPtr->field_name)
MAKE_COMPARE(phone);
MAKE_COMPARE(lastname);
MAKE_COMPARE(name);
MAKE_COMPARE(street);
MAKE_COMPARE(patronym);
MAKE_COMPARE(house);
MAKE_COMPARE(housing);
MAKE_COMPARE(apartment);
#undef MAKE_COMPARE
if (cEqualFields >= cEqualFieldsNeed) {
retval = TRUE;
break;
}
}
searchEndPos = searchPos;
return retval;
#undef MAKE_COPY
}
inline void FillRecordField(char *dest, const char *src, int maxFieldCch)
{
if (src != NULL) {
strncpy(dest, src, maxFieldCch);
dest[maxFieldCch-1] = '\0';
} else
dest[0] = '\0';
}
PHONEDB_API void
FillDatabaseRecord(
PHONE_DB_RECORD *recordPtr,
const char *phone,
const char *lastname,
const char *name,
const char *patronym,
const char *street,
const char *house,
const char *housing,
const char *apartment)
#define FILL_FIELD(field_name)\
FillRecordField(recordPtr->field_name,\
field_name,\
_countof(recordPtr->field_name))
{
FILL_FIELD(phone);
FILL_FIELD(lastname);
FILL_FIELD(name);
FILL_FIELD(patronym);
FILL_FIELD(street);
FILL_FIELD(house);
FILL_FIELD(housing);
FILL_FIELD(apartment);
#undef FILL_FIELD
}
Соседние файлы в папке PhoneDB