📄 emfdb.c
字号:
/* * Make sure that this table exists */ tid = dbGetTableId(0, table); a_assert(tid >= 0); if (tid < 0) { return DB_ERR_TABLE_NOT_FOUND; } pTable = dbListTables[tid]; if (pTable) {/* * Make sure that the column exists */ colIndex = GetColumnIndex(tid, column); a_assert(colIndex >= 0); if (colIndex >= 0) {/* * Make sure that the row exists */ a_assert((row >= 0) && (row < pTable->nRows)); if ((row >= 0) && (row < pTable->nRows)) { pRow = pTable->rows[row]; if (pRow) { pRow[colIndex] = iData; return 0; } return DB_ERR_ROW_DELETED; } return DB_ERR_ROW_NOT_FOUND; } return DB_ERR_COL_NOT_FOUND; } return DB_ERR_TABLE_DELETED;}/******************************************************************************//* * The dbWriteStr function writes a string value into a table at a given row * and column. The existence of the row and column is verified before the * write. The column is also checked to confirm it is a string field. * 0 is returned on succes, -1 is returned on error. */int dbWriteStr(int did, char_t *table, char_t *column, int row, char_t *s){ int tid, colIndex; int *pRow; char_t *ptr; dbTable_t *pTable; a_assert(table); a_assert(column); tid = dbGetTableId(0, table); a_assert(tid >= 0); if (tid < 0) { return DB_ERR_TABLE_NOT_FOUND; }/* * Make sure that this table exists */ pTable = dbListTables[tid]; a_assert(pTable); if (!pTable) { return DB_ERR_TABLE_DELETED; }/* * Make sure that this column exists */ colIndex = GetColumnIndex(tid, column); if (colIndex < 0) { return DB_ERR_COL_NOT_FOUND; }/* * Make sure that this column is a string column */ if (pTable->columnTypes[colIndex] != T_STRING) { return DB_ERR_BAD_FORMAT; }/* * Make sure that the row exists */ a_assert((row >= 0) && (row < pTable->nRows)); if ((row >= 0) && (row < pTable->nRows)) { pRow = pTable->rows[row]; } else { return DB_ERR_ROW_NOT_FOUND; } if (!pRow) { return DB_ERR_ROW_DELETED; }/* * If the column already has a value, be sure to delete it to prevent * memory leaks. */ if (pRow[colIndex]) { bfree(B_L, (char_t *) pRow[colIndex]); }/* * Make sure we make a copy of the string to write into the column. * This allocated string will be deleted when the row is deleted. */ ptr = bstrdup(B_L, s); pRow[colIndex] = (int)ptr; return 0;}/******************************************************************************//* * Print a key-value pair to a file */static int dbWriteKeyValue(int fd, char_t *key, char_t *value){ int rc; int len; char_t *pLineOut; a_assert(key && *key); a_assert(value); fmtAlloc(&pLineOut, BUF_MAX, T("%s=%s\n"), key, value); if (pLineOut) { len = gstrlen(pLineOut);#if CE rc = writeUniToAsc(fd, pLineOut, len);#else rc = gwrite(fd, pLineOut, len);#endif bfree(B_L, pLineOut); } else { rc = -1; } return rc;}/******************************************************************************//* * Persist a database to a file */int dbSave(int did, char_t *filename, int flags){ int row, column, nColumns, nRows, fd, rc; int *colTypes, *pRow, nRet, tid; char_t *path, *tmpFile, *tmpNum; char_t **colNames; dbTable_t *pTable; trace(5, T("DB: About to save database to file\n")); a_assert(dbMaxTables > 0);/* * First write to a temporary file, then switch around later. */ fmtAlloc(&tmpFile, FNAMESIZE, T("%s/data.tmp"), basicGetProductDir()); if ((fd = gopen(tmpFile, O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, 0666)) < 0) { trace(1, T("WARNING: Failed to open file %s\n"), tmpFile); bfree(B_L, tmpFile); return -1; } nRet = 0; for (tid = 0; (tid < dbMaxTables) && (nRet != -1); tid++) { pTable = dbListTables[tid]; if (pTable) {/* * Print the TABLE=tableName directive to the file */ rc = dbWriteKeyValue(fd, KEYWORD_TABLE, pTable->name); nColumns = pTable->nColumns; nRows = pTable->nRows; for (row = 0; (row < nRows) && (nRet == 0); row++) { pRow = pTable->rows[row];/* * if row is NULL, the row has been deleted, so don't * write it out. */ if ((pRow == NULL) || (pRow[0] == '\0') || (*(char_t *)(pRow[0]) == '\0')) { continue; }/* * Print the ROW=rowNumber directive to the file */ fmtAlloc(&tmpNum, 20, T("%d"), row); rc = dbWriteKeyValue(fd, KEYWORD_ROW, tmpNum); bfreeSafe(B_L, tmpNum); colNames = pTable->columnNames; colTypes = pTable->columnTypes;/* * Print the key-value pairs (COLUMN=value) for data cells */ for (column = 0; (column < nColumns) && (rc >= 0); column++, colNames++, colTypes++) { if (*colTypes == T_STRING) { rc = dbWriteKeyValue(fd, *colNames, (char_t *)(pRow[column])); } else { fmtAlloc(&tmpNum, 20, T("%d"), pRow[column]); rc = dbWriteKeyValue(fd, *colNames, tmpNum); bfreeSafe(B_L, tmpNum); } } if (rc < 0) { trace(1, T("WARNING: Failed to write to file %s\n"), tmpFile); nRet = -1; } } } } gclose(fd);/* * Replace the existing file with the temporary file, if no errors */ if (nRet == 0) { fmtAlloc(&path, FNAMESIZE, T("%s/%s"), basicGetProductDir(), filename); gunlink(path); if (grename(tmpFile, path) != 0) { trace(1, T("WARNING: Failed to rename %s to %s\n"), tmpFile, path); nRet = -1; } bfree(B_L, path); } bfree(B_L, tmpFile); return nRet;}/******************************************************************************//* * Crack a keyword=value string into keyword and value. We can change buf. */static int crack(char_t *buf, char_t **key, char_t **val){ char_t *ptr; if ((ptr = gstrrchr(buf, '\n')) != NULL || (ptr = gstrrchr(buf, '\r')) != NULL) { *ptr = '\0'; }/* * Find the = sign. It must exist. */ if ((ptr = gstrstr(buf, T("="))) == NULL) { return -1; } *ptr++ = '\0'; *key = trim(buf); *val = trim(ptr); return 0;}/******************************************************************************//* * Parse the file. These files consist of key-value pairs, separated by the * "=" sign. Parsing of tables starts with the "TABLE=value" pair, and rows * are parsed starting with the "ROW=value" pair. */int dbLoad(int did, char_t *filename, int flags){ gstat_t sbuf; char_t *buf, *keyword, *value, *path, *ptr; char_t *tablename; int fd, tid, row; dbTable_t *pTable; a_assert(did >= 0); fmtAlloc(&path, FNAMESIZE, T("%s/%s"), basicGetProductDir(), filename); trace(4, T("DB: About to read data file <%s>\n"), path); if (gstat(path, &sbuf) < 0) { trace(3, T("DB: Failed to stat persistent data file.\n")); bfree(B_L, path); return -1; } fd = gopen(path, O_RDONLY | O_BINARY, 0666); bfree(B_L, path); if (fd < 0) { trace(3, T("DB: No persistent data file present.\n")); return -1; } if (sbuf.st_size <= 0) { trace(3, T("DB: Persistent data file is empty.\n")); gclose(fd); return -1; }/* * Read entire file into temporary buffer */ buf = balloc(B_L, sbuf.st_size + 1);#if CE if (readAscToUni(fd, &buf, sbuf.st_size) != (int)sbuf.st_size) {#else if (gread(fd, buf, sbuf.st_size) != (int)sbuf.st_size) {#endif trace(3, T("DB: Persistent data read failed.\n")); bfree(B_L, buf); gclose(fd); return -1; } gclose(fd); *(buf + sbuf.st_size) = '\0'; row = -1; tid = -1; pTable = NULL; ptr = gstrtok(buf, T("\n")); tablename = NULL; do { if (crack(ptr, &keyword, &value) < 0) { trace(5, T("DB: Failed to crack line %s\n"), ptr); continue; } a_assert(keyword && *keyword); if (gstrcmp(keyword, KEYWORD_TABLE) == 0) {/* * Table name found, check to see if it's registered */ if (tablename) { bfree(B_L, tablename); } tablename = bstrdup(B_L, value); tid = dbGetTableId(did, tablename); if (tid >= 0) { pTable = dbListTables[tid]; } else { pTable = NULL; } } else if (gstrcmp(keyword, KEYWORD_ROW) == 0) {/* * Row/Record indicator found, add a new row to table */ if (tid >= 0) { int nRows = dbGetTableNrow(did, tablename); if (dbSetTableNrow(did, tablename, nRows + 1) == 0) { row = nRows; } } } else if (row != -1) {/* * some other data found, assume it's a COLUMN=value */ int nColumn = GetColumnIndex(tid, keyword); if ((nColumn >= 0) && (pTable != NULL)) { int nColumnType = pTable->columnTypes[nColumn]; if (nColumnType == T_STRING) { dbWriteStr(did, tablename, keyword, row, value); } else { dbWriteInt(did, tablename, keyword, row, gstrtoi(value)); } } } } while ((ptr = gstrtok(NULL, T("\n"))) != NULL); if (tablename) { bfree(B_L, tablename); } bfree(B_L, buf); return 0;}/******************************************************************************//* * Return a table id given the table name */int dbGetTableId(int did, char_t *tablename){ int tid; dbTable_t *pTable; a_assert(tablename); for (tid = 0; (tid < dbMaxTables); tid++) { if ((pTable = dbListTables[tid]) != NULL) { if (gstrcmp(tablename, pTable->name) == 0) { return tid; } } } return -1;}/******************************************************************************//* * Return a pointer to the table name, given its ID */char_t *dbGetTableName(int did, int tid){ if ((tid >= 0) && (tid < dbMaxTables) && (dbListTables[tid] != NULL)) { return (dbListTables[tid])->name; } return NULL;}/******************************************************************************//* * Trim leading white space. */static char_t *trim(char_t *str){ while (isspace((int)*str)) { str++; } return str;}/******************************************************************************//* * Return a column index given the column name */static int GetColumnIndex(int tid, char_t *colName) { int column; dbTable_t *pTable; a_assert(colName); if ((tid >= 0) && (tid < dbMaxTables) && (dbListTables[tid] != NULL)) { pTable = dbListTables[tid]; for (column = 0; (column < pTable->nColumns); column++) { if (gstrcmp(colName, pTable->columnNames[column]) == 0) return column; } } return -1;}/******************************************************************************//* * Set the prefix-directory */void basicSetProductDir(char_t *proddir){ int len; if (basicProdDir != NULL) { bfree(B_L, basicProdDir); } basicProdDir = bstrdup(B_L, proddir);/* * Make sure that prefix-directory doesn't end with a '/' */ len = gstrlen(basicProdDir); if ((len > 0) && *(basicProdDir + len - 1) == '/') { *(basicProdDir+len-1) = '\0'; }}/******************************************************************************//* * Return the prefix-directory */char_t *basicGetProductDir(){ if (basicProdDir) { return basicProdDir; } else { return basicDefaultDir; }}/******************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -