REVISION
Definition in file db.c.
#include "../SYSTEM/sys_hardware.h"
#include "db.h"
#include "db_assert.h"
Include dependency graph for db.c:

Go to the source code of this file.
Functions | |
| BOOL | DB_unmount (DB_ID id) |
| Function unmounts specified database. | |
| void | DB_setSyncMark (const char *drive) |
| Function sets the DB sync mark. | |
| BOOL | DB_checkSyncMark (const char *drive) |
| Function checks the DB sync mark. | |
| BOOL | DB_removeRecord (DB_ID childId, DB_ENTRY childEntry, DB_ENTRY paiEntry) |
| Function removes specified record reference from the child database. | |
| DB_HDL | DB_queryFirst (DB_ID id, DB_FIELDIDX fldIdx, DB_ENTRY fldEntry, DB_ENTRY dbEntry, DB_DATA *pData) |
| Function queries the specified database and sets up query controls. | |
| BOOL | DB_queryNext (DB_HDL hdl, DB_ENTRY entry, DB_DATA *pData) |
| Function queries database through specified database handle. | |
| BOOL | DB_queryClose (DB_HDL hdl) |
| Function closes the specified database query operation and releases corresponding control data object. | |
| DB_ID | DB_mount (const DB_FNAME name) |
| Function mounts the specified database . | |
| BOOL | DB_insertRecord (DB_ID id, const DB_DATA *pData) |
| Function inserts a record to specified root database. | |
| short | DB__compare (const DB_DATA *pRecord1, const DB_DATA *pRecord2) |
| Function compares two DB record. | |
| DB_MDBOFFSET | DB__insert2leaf (DB_ID id, DB_ID parentId, DB_MDBOFFSET parentMdb, const DB_DATA *pParentRecord, const DB_DATA *pRecord, DB_RECLEN len, BOOL bAlwaysInsert) |
| Function inserts a record to specified leaf database. | |
| BOOL | DB__addChildIdx (DB_DATA *pRecord, DB_FIELDIDX fldidx, DB_MDBOFFSET childMdb) |
| Function adds a child DB index to parent record. | |
| BOOL | DB_init (void) |
| Function initializes DB controls. | |
| st_DBINFO * | DB_info (DB_HDL hdl) |
| Function returns information of specified database. | |
| BOOL | DB__info (DB_ID id, st_DBINFO *pInfo) |
| Function returns information of specified database, this function is only available internally to DB module. | |
| DB_ID | DB_childID (DB_ID rootID, DB_FIELDIDX fldIdx) |
| Function returns child DB ID givent the child field index. | |
| DB_ID | DB_parentID (DB_ID id) |
| Function returns parent DB ID of the givent the child DB. | |
| DB_ID | DB__rootID (DB_ID id) |
| Function returns root DB ID of specified child ID. | |
| DB_ENTRY | DB_getSaiByMdb (ULONG mdb, DB_ID id) |
| Function calculates SAI entry based on MDB offset. | |
| DB_MDBOFFSET | DB_getMdbByRecord (DB_ID id, const unsigned short *pData) |
| Function checks return the MDB offset by record data. | |
| DB_FIELDLEN | DB_getField (const DB_DATA *pRecord, DB_FIELDIDX fldIdx, DB_DATA *pData, st_DBINFO *pInfo) |
| Function gets interpreted data of the specified record field out of given record. | |
| DB_FIELDLEN | DB__getField (const DB_DATA *pRecord, DB_FIELDIDX fldIdx, DB_DATA *pData) |
| Function gets data of the specified record field out of given record with all escape/delimiter characters stripped. | |
| DB_DSPDATALEN | DB_dspData (DB_ID id, DB_DSPDATA pData, DB_DSPDATAIDX idx) |
| Function reads back the database display data and returns data length in words. | |
| BOOL | DB_deleteRecord (DB_ID id, DB_ENTRY entry) |
| Function deletes specified record from the root database, it also updtes all corresponding child database. | |
| BOOL | DB_deleteRecordByMdb (DB_ID id, DB_MDBOFFSET mdb) |
| Function deletes specified record indexed by root offset from the root database, it also updtes all corresponding child database. | |
| BOOL | DB__deleteChildRecord (DB_ID id, DB_ENTRY entry) |
| Function deletes an entry form a child DB. | |
| BOOL | DB_creator (BOOL force2create) |
| Function checks to create all default device database. | |
| BOOL | DB_add2child (DB_MDBOFFSET rootMdb, DB_ID childID, const DB_DATA *childRecord) |
| Function adds specified record to given child DB. | |
| BOOL | DB__removePAIentry (DB_ID id, DB_MDBOFFSET entry, DB_PAIOFFSET pai, unsigned short *pEntryNum) |
| Function removes specified PAI entry. | |
| DB_ID | DB__register (const DB_FNAME name, st_DBIDNODE *parent, st_DBIDNODE *prev) |
| Function registers the specified DB to system. | |
| BOOL | DB__recordPosition (DB_ID id, DB_ENTRY *pPosition, const DB_DATA *pRecord, BOOL bIgnoreRule) |
| Function checks to see if specified record exists in DB. | |
| DB_RECLEN | DB__recordLen (const DB_DATA *pRecord) |
| Function returns length in words of the specified record field. | |
| DB_FNAME | DB__name (DB_ID id, DB_FEXTNAME ext) |
| Function returns the database header file name. | |
| DB_DATA * | DB__locateField (const DB_DATA *pRecord, DB_FIELDIDX fldIdx) |
| Function locates position of the specified field. | |
| BOOL | DB__getRecord (File *file, DB_DATA *pData) |
| Function reads back a record from specified file. | |
| DB_FIELDIDX | DB__fieldIndex (DB_ID id) |
| Function returns field index of given child database under its parent. | |
| BOOL | DB__cdDBdir (const DB_FNAME name) |
| Function changes directory to corresponding root DB directory. | |
| BOOL | DB__addSAIentry (DB_ID id, DB_ENTRY entry, DB_MDBOFFSET mdb, DB_PAIOFFSET pai) |
| Function adds a new SAI entry. | |
Variables | |
| const char | strDBDIR [] = "WOID_DB" |
| GLOBAL DATA. | |
|
||||||||||||||||
|
Function adds a child DB index to parent record.
Definition at line 1322 of file db.c. References DB__locateField(), and DB__recordLen(). Referenced by DB_add2child(). 01325 {
01326 unsigned short ii;
01327 DB_RECLEN len;
01328 BOOL bFOUND;
01329 unsigned short * pD;
01330 unsigned short * pT;
01331 unsigned short * pS;
01332 unsigned long mdb;
01333 unsigned short buf[4];
01334
01335 pD = DB__locateField(pRecord, fldidx);
01336 len = DB__recordLen(pRecord);
01337
01338 bFOUND = FALSE;
01339 while(1)
01340 {
01341 if(*pD == DB_ESCCHAR) pD++;
01342 else if( (*pD==DB_RECDLMT) ||(*pD==DB_FLDDLMT) ) break;
01343
01344 mdb = (unsigned long)(*pD++)<<16;
01345
01346 if(*pD == DB_ESCCHAR) pD++;
01347 else if( (*pD==DB_RECDLMT) ||(*pD==DB_FLDDLMT) ) break;
01348
01349 mdb |= (unsigned long)(*pD);
01350
01351 if( mdb == childMdb) return TRUE;
01352
01353 else if( (mdb == 0L)&&(bFOUND == FALSE) )
01354 {
01355 pT = pD-1;
01356 bFOUND = TRUE;
01357 }
01358
01359 pD++;
01360 }
01361
01362
01363 pS = buf;
01364 ii = (unsigned long)childMdb>>16;
01365 if( (ii == DB_FLDDLMT)||(ii == DB_RECDLMT)||(ii == DB_BAGDLMT)||(ii == DB_ESCCHAR) )
01366 {
01367 *pS++ = DB_ESCCHAR;
01368 }
01369 *pS++ = ii;
01370 ii = childMdb&0x0ffff;
01371 if( (ii == DB_FLDDLMT)||(ii == DB_RECDLMT)||(ii == DB_BAGDLMT)||(ii == DB_ESCCHAR) )
01372 {
01373 *pS++ = DB_ESCCHAR;
01374 }
01375 *pS++ = ii;
01376 ii = pS-buf;
01377
01378 if( (bFOUND == TRUE)&&(ii == 2) )
01379 {
01380 *pT++ = (unsigned long)childMdb>>16;
01381 *pT = childMdb&0x0ffff;
01382 return TRUE;
01383 }
01384
01385 // Insert to end of field anyway.
01386 memmove( pD+ii, pD, len-(pD -(unsigned short *)pRecord)+1);
01387 pS = buf;
01388 while(ii--) *pD++ = *pS++;
01389
01390 return TRUE;
01391 }
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
Function adds a new SAI entry.
Definition at line 3459 of file db.c. References DB__name(), FAT_fclose(), FAT_finsert(), FAT_fopen(), FAT_fread(), FAT_fseek(), FAT_fwrite(), r_b, SEEK_HEAD, SEEK_MID, and File::size. Referenced by DB__insert2leaf(), and DB_insertRecord(). 03463 {
03464
03465 unsigned long offset[2];
03466 unsigned long fsize;
03467 unsigned short entryNum;
03468 File * idxfile;
03469
03470 /* Update record number. */
03471 idxfile = FAT_fopen(DB__name(id, SAI), r_b);
03472 fsize = idxfile->size;
03473
03474 FAT_fseek(idxfile, DB_SAIENTRYNUMOFFSET, SEEK_HEAD);
03475 FAT_fread(idxfile, &entryNum, 1);
03476
03477 entryNum++;
03478
03479 FAT_fseek(idxfile, -1, SEEK_MID);
03480 FAT_fwrite(idxfile, &entryNum, 1);
03481
03482
03483 /* Load buffer. */
03484 offset[0] = mdb;
03485 offset[1] = pai;
03486
03487 /* Check to see if there is any free entries. */
03488 if((long)fsize >= (long)((unsigned long)(entryNum + DB_SAIFIRSTENTRY + 1)<<2) ){
03489
03490 FAT_finsert( idxfile,
03491 ( (unsigned long)entry << 2),
03492 (unsigned short *)offset,
03493 4, fsize);
03494 }
03495 else
03496 {
03497 FAT_finsert(idxfile,
03498 ( (unsigned long)entry << 2),
03499 (unsigned short *)offset,
03500 4, 0L);
03501 }
03502
03503 FAT_fclose(idxfile);
03504
03505 return TRUE;
03506 }
|
Here is the call graph for this function:

|
|
Function changes directory to corresponding root DB directory.
Definition at line 3423 of file db.c. References FAT_cd(), and strDBDIR. Referenced by DB__info(), DB_add2child(), DB_deleteRecord(), DB_deleteRecordByMdb(), DB_dspData(), DB_getField(), DB_getMdbByRecord(), DB_getSaiByMdb(), DB_mount(), and DB_removeRecord(). 03424 {
03425 char dir[DB_MAXLFN];
03426 char * pD = &dir[0];
03427 const char * pC = name;
03428
03429 // DB always resides in NAND flash.
03430 FAT_cd(strDISKD);
03431
03432 // Always load DB from database directory.
03433 if( FAT_cd(strDBDIR) == FALSE ) return FALSE;
03434
03435 while(*pC != '.')
03436 {
03437 *pD++ = *pC++;
03438 }
03439 *pD = 0;
03440
03441 return(FAT_cd(dir));
03442 }
|
Here is the call graph for this function:

|
||||||||||||
|
Function compares two DB record. Comparation is done on a field base.
Definition at line 950 of file db.c. Referenced by DB__insert2leaf(), and DB__recordPosition(). 00951 {
00952 const unsigned short * p1;
00953 const unsigned short * p2;
00954 unsigned short value1;
00955 unsigned short value2;
00956 #ifdef SPECIAL_CHAR_FIX
00957 unsigned short byte1H, byte1L, byte2H, byte2L;
00958 #endif
00959
00960 p1 = (const unsigned short *) pRecord1;
00961 p2 = (const unsigned short *) pRecord2;
00962
00963 while( 1 )
00964 {
00965 if(*p1 == DB_ESCCHAR) p1++;
00966 if(*p2 == DB_ESCCHAR) p2++;
00967
00968 if( (*p1 == DB_RECDLMT) || (*p1 == DB_FLDDLMT) )
00969 {
00970 if( (*p2 == DB_RECDLMT) || (*p2 == DB_FLDDLMT) ) return 0;
00971 else return -1;
00972 }
00973
00974 if( (*p2 == DB_RECDLMT) || (*p2 == DB_FLDDLMT) )
00975 {
00976 if( (*p1 == DB_RECDLMT) || (*p1 == DB_FLDDLMT) ) return 0;
00977 else return 1;
00978 }
00979
00980 #ifdef SPECIAL_CHAR_FIX
00981 byte1L = *p1 & 0xFF;
00982 if ( byte1L < TABLE_SIZE ) byte1L = _2lower(byte1L);
00983 byte1H = (*p1 >> 8) & 0xFF;
00984
00985 if ( byte1H < TABLE_SIZE ) byte1H = _2lower(byte1H);
00986 value1 = (byte1H<<8) | byte1L;
00987
00988 byte2L = *p2 & 0xFF;
00989 if ( byte2L < TABLE_SIZE ) byte2L = _2lower(byte2L);
00990 byte2H = (*p2 >> 8) & 0xFF;
00991
00992 if ( byte2H < TABLE_SIZE ) byte2H = _2lower(byte2H);
00993 value2 = (byte2H<<8) | byte2L;
00994 #else
00995 value1 = _2lower(*p1);
00996 value2 = _2lower(*p2);
00997 #endif
00998
00999 if(value1 > value2) return 1;
01000 else if(value1 < value2) return -1;
01001 else
01002 {
01003 /* Points to next data. */
01004 p1++;
01005 p2++;
01006 }
01007 }
01008 }
|
|
||||||||||||
|
Function deletes an entry form a child DB. It is the caller's responsibility to make sure the PAI entries are all cleared or it is deleted from root, in which case there is no PAI at all. Function deletes the child DB entry and updates all its children if any.
Definition at line 2079 of file db.c. References DB__getField(), DB__getRecord(), DB__name(), DB__removePAIentry(), FAT_fclose(), FAT_fopen(), FAT_fread(), FAT_fseek(), FAT_fwrite(), st_DBIDTREE::node, r_b, rb, SEEK_HEAD, and SEEK_MID. Referenced by DB_deleteRecord(), DB_deleteRecordByMdb(), and DB_removeRecord(). 02080 {
02081 DB_ID childID;
02082 st_DBIDNODE * node;
02083 DB_MDBOFFSET offset;
02084 DB_PAIOFFSET pai;
02085 unsigned short entryNum;
02086 unsigned short entryLeft;
02087 File * idxfile;
02088 File * dbfile;
02089 DB_SAIOFFSET sai;
02090 DB_FIELDIDX fldidx;
02091 USHORT fldlen;
02092 USHORT usTmp, usLen;
02093 USHORT buf[DB_MAXRECLEN];
02094 unsigned long fld[32];// Assuming that one field could hold up to
02095 // 32 valid offset values.
02096
02097 // Get MDB offset from SAI file.
02098 idxfile = FAT_fopen(DB__name(id, SAI), r_b);
02099 FAT_fseek(idxfile, (unsigned long)(entry+DB_SAIFIRSTENTRY)<<2, SEEK_HEAD);
02100 FAT_fread(idxfile, (unsigned short *)&offset, 2);
02101
02102 // Remove SAI entry.
02103 FAT_fseek(idxfile, DB_SAIENTRYNUMOFFSET, SEEK_HEAD);
02104 FAT_fread(idxfile, &entryNum, 1);
02105
02106 DB_assert(entryNum, DB__DELETECHILDRECORD);
02107
02108 /* Decrement entry number. */
02109 FAT_fseek(idxfile, -1, SEEK_MID);
02110 entryNum--;
02111 FAT_fwrite(idxfile, &entryNum, 1);
02112
02113 /* Process the rest of the entries. */
02114 usTmp = (unsigned long)(entryNum - entry)<<2;
02115 FAT_fseek(idxfile, (unsigned long)(entry + DB_SAIFIRSTENTRY) << 2, SEEK_HEAD);
02116 while(usTmp)
02117 {
02118 /* Skip the current entry which should be deleted. */
02119 FAT_fseek(idxfile, 4, SEEK_MID);
02120
02121 if(usTmp > DB_MAXRECLEN ) usLen = DB_MAXRECLEN;
02122 else usLen = (unsigned short)usTmp;
02123
02124 FAT_fread(idxfile, (unsigned short *)buf, usLen);
02125 FAT_fseek(idxfile, (long)((long)(-4) - usLen ), SEEK_MID);
02126 FAT_fwrite(idxfile, (unsigned short *)buf, usLen);
02127 usTmp -= usLen;
02128 }
02129
02130 buf[0] = buf[1] = buf[2] = buf[3] = 0;
02131
02132 /* Zero out last entry. */
02133 FAT_fwrite(idxfile, (unsigned short *)buf, 4);
02134 FAT_fclose(idxfile);
02135
02136 /* Mark entry as deleted. */
02137 dbfile = FAT_fopen(DB__name(id, MDB), r_b);
02138
02139 // Read back the entire record here.
02140 FAT_fseek(dbfile, offset, SEEK_HEAD);
02141 DB__getRecord(dbfile, (DB_DATA *)buf);
02142
02143 FAT_fseek(dbfile, offset, SEEK_HEAD);
02144 FAT_fread(dbfile, (unsigned short *)&usTmp, 1);
02145 usTmp |= RECORD_DELETED;
02146 FAT_fseek(dbfile, -1, SEEK_MID);
02147 FAT_fwrite(dbfile, (unsigned short *)&usTmp, 1);
02148 FAT_fclose(dbfile);
02149
02150
02151 /* Check all the children database. */
02152 node = &DB_idtree.node[id];
02153 fldidx = 0;
02154
02155 if(node->child)
02156 {
02157 node = node->child;
02158
02159 while(node->next)
02160 {
02161 node = node->next;
02162 childID = node->id;
02163
02164 fldidx++;
02165
02166 fldlen = DB__getField(buf, fldidx, fld)>>1;
02167
02168 // Sort all SAIs in field if any.
02169 _sortSAI(fld, fldlen);
02170
02171 idxfile = FAT_fopen(DB__name(childID, SAI), rb);
02172 FAT_fseek(idxfile, DB_SAIENTRYNUMOFFSET, SEEK_HEAD);
02173 FAT_fread(idxfile, &entryNum, 1);
02174
02175 // Note that entry has to be checked from the end of file to
02176 // support recursively deleting.
02177 while( (entryNum) && (fldlen) )
02178 {
02179 entryNum--;
02180 FAT_fseek(idxfile, ((unsigned long)(entryNum + DB_SAIFIRSTENTRY)<<2), SEEK_HEAD);
02181 FAT_fread(idxfile, (unsigned short *)&sai, 2);
02182 FAT_fread(idxfile, (unsigned short *)&pai, 2);
02183
02184 if( sai == fld[fldlen-1])
02185 {
02186 fldlen--;
02187
02188 // If pai == 0, there is no PAI entries available, does
02189 // NOT need to check.
02190 if(pai) DB__removePAIentry(childID, offset, pai, &entryLeft);
02191 }
02192
02193 else continue;
02194
02195 // if( (sai != fld[fldlen-1]) || (pai == 0) ) continue;
02196 // fldlen may have been post decremented already.
02197 if(pai == 0) continue;
02198
02199 if(entryLeft == 0)
02200 {
02201 /* Close file before deleting SAI entry. */
02202 FAT_fclose(idxfile);
02203
02204 // The first entry always(?) points to the default empty record,
02205 // do not delete it even when it is empty since it defaults to
02206 // have at least one virtual record.
02207 if(entryNum != 0)
02208 {
02209 DB__deleteChildRecord(childID, entryNum);
02210 }
02211
02212 /* Reopen SAI file after deleting. */
02213 idxfile = FAT_fopen(DB__name(childID, SAI), rb);
02214 }
02215 }
02216
02217 /* Close file before return. */
02218 FAT_fclose(idxfile);
02219 }
02220 }
02221
02222 return TRUE;
02223 }
|
Here is the call graph for this function:

|
|
Function returns field index of given child database under its parent.
Definition at line 3396 of file db.c. References st_DBIDTREE::node. Referenced by DB_add2child(), and DB_removeRecord(). 03397 {
03398 st_DBIDNODE * node;
03399 DB_FIELDIDX fldidx;
03400
03401 fldidx = 0;
03402 node = &DB_idtree.node[id];
03403
03404 /* The very first child does not have previous node. */
03405 while(node->prev)
03406 {
03407 fldidx++;
03408 node = node->prev;
03409 }
03410
03411 return fldidx;
03412 }
|
|
||||||||||||||||
|
Function gets data of the specified record field out of given record with all escape/delimiter characters stripped.
Definition at line 1911 of file db.c. References DB__locateField(). Referenced by DB__deleteChildRecord(), DB_getField(), and DB_getMdbByRecord(). 01914 {
01915 const unsigned short * pSrc;
01916 unsigned short * pDst;
01917
01918 pSrc = (const unsigned short *)DB__locateField(pRecord, fldIdx);
01919
01920 if( NULL == pSrc )
01921 {
01922 /* Unable to locate the specified field. */
01923 return 0;
01924 }
01925
01926
01927 if( (*pSrc == DB_RECDLMT)||(*pSrc == DB_FLDDLMT) )
01928 {
01929 /* Empty record. */
01930 return 0;
01931 }
01932
01933
01934 pDst = (unsigned short *)pData;
01935 /* Start to fetch field. */
01936 while(1)
01937 {
01938 if( *pSrc == DB_ESCCHAR)
01939 {
01940 pSrc++;
01941 *pDst++ = *pSrc++;
01942 }
01943 else{
01944 *pDst++ = *pSrc++;
01945 }
01946
01947 if( (*pSrc == DB_RECDLMT)||(*pSrc == DB_FLDDLMT) ) break;
01948 }
01949
01950 return (pDst - (unsigned short *)pData);
01951 }
|
Here is the call graph for this function:

|
||||||||||||
|
Function reads back a record from specified file. It is the caller's responsibility to make sure buffer is long enough to hold the record with maximum length.
Definition at line 3343 of file db.c. References DB_MAXRECLEN, and FAT_fread(). Referenced by DB__deleteChildRecord(), DB_add2child(), DB_getField(), DB_queryFirst(), DB_queryNext(), and DB_removeRecord(). 03344 {
03345 unsigned short * p;
03346 unsigned short len;
03347
03348 // This is from queryFirst.
03349 if(pData == NULL) return TRUE;
03350
03351 // Let's split it to speed up, since normally record will be
03352 // 256 words less.
03353
03354 p = (unsigned short *)pData;
03355 len = FAT_fread(file, p, DB_MAXRECLEN/2);
03356
03357 // check for record delimiter, for safe?.
03358 while( 1 )
03359 {
03360 if( *p == DB_RECDLMT )
03361 {
03362 if( *(p-1) != DB_ESCCHAR ) return TRUE;
03363 }
03364 p++;
03365 if ( (p-(unsigned short *)pData) >= len ) break;
03366 }
03367
03368 // Second attempt.
03369 if( len != DB_MAXRECLEN/2) return FALSE;
03370
03371 p = (unsigned short *)pData+DB_MAXRECLEN/2;
03372 len = FAT_fread(file, p, DB_MAXRECLEN/2);
03373
03374 // check for record delimiter, for safe?.
03375 while( 1 )
03376 {
03377 if( *p == DB_RECDLMT )
03378 {
03379 if( *(p-1) != DB_ESCCHAR ) return TRUE;
03380 }
03381 p++;
03382 if ( (p-(unsigned short *)pData) == len ) break;
03383 }
03384
03385 return TRUE;
03386 }
|
Here is the call graph for this function:

|
||||||||||||
|
Function returns information of specified database, this function is only available internally to DB module.
Definition at line 1577 of file db.c. References st_DBINFO::attribute, st_DBINFO::bVirtual, DB__cdDBdir(), DB__name(), DB__rootID(), FAT_fclose(), FAT_fopen(), FAT_fread(), FAT_fseek(), st_DBREGIST::fname, st_DBINFO::id, st_DBIDTREE::node, st_DBINFO::numOfFields, st_DBINFO::numOfKeys, st_DBINFO::ptrXIM, rb, SEEK_HEAD, and st_DBINFO::status. Referenced by DB_insertRecord(), and DB_queryFirst(). 01578 {
01579 File * file;
01580 st_DBHEADER header;
01581 unsigned long signature;
01582
01583 #if 1
01584 pInfo->id = id;
01585
01586 /* Check to see if id points to a virtual DB. */
01587 if( DB_registration[id].fname == NULL )
01588 {
01589 pInfo->bVirtual = TRUE;
01590
01591 /* Virtual DB, access through its parent. */
01592 id = DB_idtree.node[id].parent->id;
01593 }
01594 else pInfo->bVirtual = FALSE;
01595 #endif
01596
01597 // Change to corresponding root DB directory. all files contained
01598 // in this directory.
01599 if(DB__cdDBdir(DB__name(DB__rootID(id), MDB)) == FALSE) return FALSE;
01600
01601 if( (file = FAT_fopen(DB__name(id, MDB), rb) ) == NULL ) return FALSE;
01602
01603 if( FAT_fread(file, (unsigned short *)&header, sizeof(st_DBHEADER))
01604 != sizeof(st_DBHEADER) ) RETURN_ERROR;
01605
01606 FAT_fseek(file, header.len - 2, SEEK_HEAD);
01607 FAT_fread(file, (unsigned short *)&signature, 2);
01608
01609 /* Check signature here for safe. */
01610 if( signature != DB_HEADER_SIGNATURE ) RETURN_ERROR;
01611
01612 /* Copy information over. */
01613 pInfo->attribute = header.attribute;
01614 pInfo->numOfFields = header.numOfFields;
01615 pInfo->numOfKeys = header.numOfKeys;
01616 pInfo->status = header.status;
01617 pInfo->ptrXIM = ((long)header.ptrXIMhi<<16)|header.ptrXIMlo;
01618
01619 FAT_fclose(file);
01620
01621 return TRUE;
01622 }
|
Here is the call graph for this function:

|
||||||||||||||||||||||||||||||||
|
Function inserts a record to specified leaf database. Function returns the child database MDB data offset. It is the caller's responsibility to maintain id integrity.
Definition at line 1033 of file db.c. References ab, DB__addSAIentry(), DB__compare(), DB__name(), DB__recordPosition(), DB_MAXFIELDLEN, FAT_fclose(), FAT_finsert(), FAT_fopen(), FAT_fread(), FAT_fseek(), FAT_fwrite(), r_b, rb, SEEK_HEAD, SEEK_MID, and File::size. Referenced by DB_add2child(). 01040 {
01041 DB_MDBOFFSET leafMdb;
01042 DB_MDBOFFSET leafPai;
01043 DB_PAIOFFSET newPaiStart;
01044 DB_PAIOFFSET newPai;
01045 DB_ENTRY entry;
01046 DB_PAIOFFSET rdStart;
01047 unsigned short moduleLen;
01048
01049 union
01050 {
01051 unsigned short field[DB_MAXFIELDLEN];
01052
01053 struct
01054 {
01055 unsigned short pai[DB_MINPAILEN];
01056 unsigned short clear[DB_MINPAILEN];
01057 } pai;
01058 } buf;
01059
01060 DB_PAIOFFSET paiOffset;
01061 st_DBPAICTL control;
01062 unsigned short ii;
01063 File * idxfile;
01064 File * dbfile;
01065
01066 /* First round, check if record already exists. */
01067 if( DB__recordPosition(id, &entry, pRecord, FALSE) == FALSE)
01068 {
01069 /* Record does not exits, append to MDB file. */
01070 dbfile = FAT_fopen(DB__name(id, MDB), ab);
01071
01072 leafMdb = dbfile->size;
01073 FAT_fwrite(dbfile, (unsigned short *)pRecord, len);
01074 FAT_fclose(dbfile);
01075
01076 /* Create a new entry to PAI file. */
01077 leafPai = _createPAIentry(id, parentMdb);
01078
01079 /* Add entry to SAI file. */
01080 DB__addSAIentry(id, entry, leafMdb, leafPai);
01081
01082 return leafMdb;
01083 }
01084
01085
01086 /* Record exists, all we need to do here is to update the
01087 ** PAI entry if it exists, or create new PAI if it does not
01088 ** exist.
01089 */
01090
01091 /* Fetch PAI entry index. */
01092 idxfile = FAT_fopen(DB__name(id, SAI), r_b);
01093
01094 FAT_fseek(idxfile, ((unsigned long)entry << 2), SEEK_HEAD);
01095 FAT_fread(idxfile, (unsigned short *)&leafMdb, 2);
01096 FAT_fread(idxfile, (unsigned short *)&leafPai, 2);
01097
01098 if( leafPai == 0L )
01099 {
01100 /* PAI does not exist, add a new entry to PAI file. */
01101 leafPai = _createPAIentry(id, parentMdb);
01102
01103 /* Update PAI entry in SAI file. */
01104 FAT_fseek(idxfile, -2, SEEK_MID);
01105 FAT_fwrite(idxfile, (unsigned short *)&leafPai, 2);
01106 FAT_fclose(idxfile);
01107
01108 return leafMdb;
01109 }
01110 FAT_fclose(idxfile);
01111
01112
01113 /* Record exists and SAI contains a valid PAI entry. We'll check
01114 ** to insert into the existed PAI module.
01115 */
01116 if( bAlwaysInsert == FALSE )
01117 {
01118 /* Check to see if PAI already exists. */
01119 if( _checkPAI(id, leafPai, parentMdb) )
01120 {
01121 /* Everything matches, do NOT update. */
01122 return leafMdb;
01123 }
01124 }
01125
01126
01127 /* Now to check PAI entry number to see if a new module needs to
01128 ** be created.
01129 */
01130
01131 /* Read back control data of the current module. */
01132 idxfile = FAT_fopen(DB__name(id, PAI), r_b);
01133
01134 /* Points to control data. */
01135 FAT_fseek(idxfile, leafPai - sizeof(st_DBPAICTL), SEEK_HEAD);
01136 FAT_fread(idxfile, (unsigned short *)&control, sizeof(st_DBPAICTL));
01137
01138 paiOffset =
01139 newPai = leafPai;
01140
01141
01142 if(control.entryNum == ( (control.dlen - sizeof(st_DBPAICTL) - 2)>>1 ) )
01143 {
01144 /* Entry full, free this entry and move it to the end of file.
01145 **
01146 ** NOTE:
01147 ** There might be a TRAP here, ideally we need to search
01148 ** throught the PAI to see if there is any available entry
01149 ** with a size bigger than the current one. Here we just
01150 ** choose not to search and directly create a new moudle
01151 ** at the end of the PAI file.
01152 */
01153
01154 /* Set up PAI clear buffer. */
01155 for(ii = 0; ii < DB_MINPAILEN; ii++) buf.pai.clear[ii] = 0;
01156
01157 newPaiStart = idxfile->size;
01158
01159 /* Check if current module is at the file end. If it is, we'll expand
01160 ** current module instead of allocating a new one.
01161 */
01162 if(newPaiStart == leafPai - sizeof(st_DBPAICTL) + control.dlen)
01163 {
01164 /* At the end of the file. */
01165 control.dlen += DB_MINPAILEN;
01166
01167 /* Update module length before moving it. */
01168 FAT_fseek(idxfile, -(long)sizeof(st_DBPAICTL), SEEK_MID);
01169 FAT_fwrite(idxfile, (unsigned short *)&control.dlen, 1);
01170
01171
01172 /* Clear all the newly-added entries. */
01173 FAT_fseek(idxfile, newPaiStart, SEEK_HEAD);
01174 FAT_fwrite(idxfile, buf.pai.clear, DB_MINPAILEN);
01175 }
01176
01177 else
01178 {
01179 /* We'll have to allocate a new module. To prevent PAI
01180 ** file gets too much fragmented, set up a flag here to
01181 ** do defragmentation( NOT SUPPORTED. ).
01182 */
01183 paiOffset =
01184 newPai = newPaiStart + sizeof(st_DBPAICTL);;
01185
01186 FAT_fseek(idxfile, leafPai - sizeof(st_DBPAICTL), SEEK_HEAD);
01187
01188 /* Read back first block. */
01189 FAT_fread(idxfile, buf.pai.pai, DB_MINPAILEN);
01190 FAT_fseek(idxfile, (long)(-DB_MINPAILEN), SEEK_MID);
01191
01192 /* Mark this module to be free. */
01193 buf.pai.clear[0] = control.dlen;
01194 buf.pai.clear[1] = PAI_FREE;
01195
01196
01197 FAT_fwrite(idxfile, buf.pai.clear, DB_MINPAILEN);
01198
01199
01200 /* Restore clear buffer. */
01201 buf.pai.clear[0] = 0;
01202 buf.pai.clear[1] = 0;
01203
01204
01205 /* Sets up new entry length. */
01206 buf.pai.pai[0] = control.dlen + DB_MINPAILEN;
01207
01208 /* Reserve control.dlen. */
01209 moduleLen = buf.pai.pai[0];
01210
01211
01212 /* To use the same code as that of direct insertion. We'll
01213 ** NOT update the entry number here.
01214 */
01215 //buf.pai.pai[2] = control.entryNum + 1;
01216
01217 FAT_fseek(idxfile, newPaiStart, SEEK_HEAD);
01218 FAT_fwrite(idxfile, buf.pai.pai, DB_MINPAILEN);
01219
01220 newPaiStart += DB_MINPAILEN;
01221
01222 rdStart = leafPai - sizeof(st_DBPAICTL) + DB_MINPAILEN;
01223
01224 control.dlen -= DB_MINPAILEN;
01225
01226 while(control.dlen)
01227 {
01228 FAT_fseek(idxfile, rdStart, SEEK_HEAD);
01229 FAT_fread(idxfile, buf.pai.pai, DB_MINPAILEN);
01230
01231 FAT_fseek(idxfile, (long)(-DB_MINPAILEN), SEEK_MID);
01232 FAT_fwrite(idxfile, buf.pai.clear, DB_MINPAILEN);
01233
01234 FAT_fseek(idxfile, newPaiStart, SEEK_HEAD);
01235 FAT_fwrite(idxfile, buf.pai.pai, DB_MINPAILEN);
01236
01237 rdStart += DB_MINPAILEN;
01238 newPaiStart += DB_MINPAILEN;
01239
01240 control.dlen -= DB_MINPAILEN;
01241 }
01242
01243 FAT_fseek(idxfile, newPaiStart, SEEK_HEAD);
01244 FAT_fwrite(idxfile, buf.pai.clear, DB_MINPAILEN);
01245 FAT_fclose(idxfile);
01246
01247 /* Update the SAI file. */
01248 idxfile = FAT_fopen(DB__name(id, SAI), r_b);
01249 FAT_fseek(idxfile, ((unsigned long)entry<<2) + 2, SEEK_HEAD);
01250 FAT_fwrite(idxfile, (unsigned short *)&newPai, 2);
01251 FAT_fclose(idxfile);
01252
01253 /* Restore control.dlen. */
01254 control.dlen = (unsigned short)moduleLen;
01255
01256
01257 /* Reopen the PAI file. */
01258 idxfile = FAT_fopen(DB__name(id, PAI), r_b);
01259 }
01260 }
01261
01262 /* Let's insert the record PAI here. */
01263
01264 /* Update entryNum first. */
01265 FAT_fseek(idxfile, newPai - sizeof(st_DBPAICTL) + 2, SEEK_HEAD);
01266
01267 control.entryNum++;
01268
01269 FAT_fwrite(idxfile, (unsigned short *)&control.entryNum, 1);
01270
01271 // If add2child, always append.
01272 if( bAlwaysInsert == FALSE )
01273 {
01274 // This has to be an insertion to root DB.
01275 dbfile = FAT_fopen(DB__name(parentId, MDB), rb);
01276
01277 /* Check to insert. */
01278 FAT_fseek(idxfile, newPai, SEEK_HEAD);
01279
01280 while(1)
01281 {
01282 FAT_fread(idxfile, (unsigned short *)&rdStart, 2);
01283
01284 if(rdStart == 0L) break;
01285
01286 FAT_fseek(dbfile, rdStart, SEEK_HEAD);
01287 FAT_fread(dbfile, buf.field, DB_MAXFIELDLEN);
01288
01289 if(DB__compare(buf.field, pParentRecord) < 0)
01290 {
01291 newPai += 2;
01292 }
01293 else break;
01294 }
01295
01296 FAT_fclose(dbfile);
01297 }
01298 else newPai += (control.entryNum-1)*2; // Append.
01299
01300 FAT_finsert(idxfile, newPai,
01301 (unsigned short *)&parentMdb, 2,
01302 paiOffset + control.dlen - sizeof(st_DBPAICTL) );
01303
01304 FAT_fclose(idxfile);
01305
01306 return(leafMdb);
01307 }
|
Here is the call graph for this function:

|
||||||||||||
|
Function locates position of the specified field.
Definition at line 3151 of file db.c. Referenced by DB__addChildIdx(), and DB__getField(). 03152 {
03153
03154 const unsigned short * pSrc;
03155 unsigned short count;
03156
03157 count = 0;
03158
03159 /* Skip the record flag. */
03160 pSrc = (unsigned short *)pRecord + 1;
03161
03162 if( fldIdx != 0 )
03163 {
03164 while( 1 )
03165 {
03166 if(*pSrc == DB_ESCCHAR) pSrc += 2;
03167
03168 if(*pSrc == DB_RECDLMT)
03169 {
03170 /* End of record, field not found. */
03171 return NULL;
03172 }
03173
03174 if(*pSrc == DB_FLDDLMT)
03175 {
03176 /* Field detected. */
03177 count++;
03178
03179 if( count == fldIdx )
03180 {
03181 pSrc++;
03182 break;
03183 }
03184 }
03185
03186 pSrc++;
03187 }
03188 }
03189
03190 return((DB_DATA *)pSrc);
03191 }
|
|
||||||||||||
|
Function returns the database header file name.
Definition at line 3101 of file db.c. References st_DBREGIST::fname, and st_DBREGIST::len. Referenced by DB__addSAIentry(), DB__deleteChildRecord(), DB__info(), DB__insert2leaf(), DB__recordPosition(), DB__removePAIentry(), DB_add2child(), DB_deleteRecord(), DB_deleteRecordByMdb(), DB_dspData(), DB_getField(), DB_getMdbByRecord(), DB_getSaiByMdb(), DB_insertRecord(), DB_queryFirst(), and DB_removeRecord(). 03102 {
03103 unsigned short len = DB_registration[id].len;
03104 #ifdef DB_REGIST2SRAM
03105 static char DBnameBUF[DB_MAXLFN];
03106 char * pC = &DBnameBUF[len-1];
03107 GEN_rdSRAM(DB_registration[id].fname, (unsigned short *)DBnameBUF, len+1);
03108 #else
03109 char * pC = DB_registration[id].fname;
03110 #endif
03111
03112 switch( ext )
03113 {
03114 case MDB:
03115 *pC-- = 'b';
03116 *pC-- = 'd';
03117 *pC = 'm';
03118 break;
03119
03120 case SAI:
03121 *pC-- = 'i';
03122 *pC-- = 'a';
03123 *pC = 's';
03124 break;
03125
03126 case PAI:
03127 *pC-- = 'i';
03128 *pC-- = 'a';
03129 *pC = 'p';
03130 break;
03131 }
03132
03133 #ifdef DB_REGIST2SRAM
03134 return (DB_FNAME)DBnameBUF;
03135 #else
03136 return DB_registration[id].fname;
03137 #endif
03138
03139 }
|
|
|
Function returns length in words of the specified record field.
Definition at line 3070 of file db.c. Referenced by DB__addChildIdx(), DB_add2child(), and DB_removeRecord(). 03071 {
03072 unsigned short * pR;
03073
03074 pR = (unsigned short *) pRecord;
03075
03076 if(*pR == DB_RECDLMT) return 0;
03077
03078 while( 1 )
03079 {
03080 pR++;
03081
03082 if( *pR == DB_RECDLMT )
03083 {
03084 if( *(pR-1) != DB_ESCCHAR ) break;
03085 }
03086 }
03087
03088 return (pR-(unsigned short *)pRecord+1);
03089 }
|
|
||||||||||||||||||||
|
Function checks to see if specified record exists in DB. If it does, function also sets up the record position value, which is the SAI entry. if it does not, function sets up the position value to where it should be.
Definition at line 2979 of file db.c. References DB__compare(), DB__name(), DB_MAXFIELDLEN, FAT_fclose(), FAT_fopen(), FAT_fread(), FAT_fseek(), rb, SEEK_HEAD, and SEEK_MID. Referenced by DB__insert2leaf(), and DB_insertRecord(). 02983 {
02984 unsigned short field[DB_MAXFIELDLEN];
02985 DB_ENTRY entry; /* SAI entry number. */
02986 DB_MDBOFFSET offset; /* File offset in MDB file. */
02987 short comp; /* Field compare result. */
02988 File * idxfile;
02989 File * dbfile;
02990
02991 /* Open MDB and SAI files. */
02992 idxfile = FAT_fopen(DB__name(id, SAI), rb);
02993 dbfile = FAT_fopen(DB__name(id, MDB), rb);
02994
02995
02996 /* Points to the first valid entry. */
02997 entry = DB_SAIFIRSTENTRY;
02998
02999
03000 /* SAI entry takes 64bits, 4 words per entry. */
03001 FAT_fseek(idxfile, (long)entry << 2, SEEK_HEAD);
03002 FAT_fread(idxfile, (unsigned short *)&offset, 2);
03003
03004 while(offset)
03005 {
03006 FAT_fseek(dbfile, offset, SEEK_HEAD);
03007 FAT_fread(dbfile, field, DB_MAXFIELDLEN);
03008
03009 /* Only compare the primary field. */
03010 comp = DB__compare(field, (unsigned short *)pRecord );
03011
03012 if( comp == 0)
03013 {
03014 /* Record found!. */
03015 FAT_fclose(idxfile);
03016 FAT_fclose(dbfile);
03017
03018 *pPosition = entry;
03019 return TRUE;
03020 }
03021 else if (comp < 0)
03022 {
03023 /* ASSUMPTIION:
03024 ** If data under this rule are not presorted, this rule must
03025 ** support multiple record references, which means any record
03026 ** can possibly occur multiple times under this rule.
03027 */
03028 entry++;
03029
03030 /* Skip PAI entry. */
03031 FAT_fseek(idxfile, 2, SEEK_MID);
03032 FAT_fread(idxfile, (unsigned short *)&offset, 2);
03033 }
03034 else
03035 {
03036 if(bIgnoreRule == FALSE) break;
03037
03038 else
03039 {
03040 entry++;
03041
03042 /* Skip PAI entry. */
03043 FAT_fseek(idxfile, 2, SEEK_MID);
03044 FAT_fread(idxfile, (unsigned short *)&offset, 2);
03045 }
03046 }
03047 }
03048
03049
03050 /* Record does not exist. */
03051 FAT_fclose(idxfile);
03052 FAT_fclose(dbfile);
03053
03054
03055 /* Sets up position. */
03056 *pPosition = entry;
03057
03058 return FALSE;
03059 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Function registers the specified DB to system. This is a recursive function.
Definition at line 2779 of file db.c. References st_DBIDTREE::counter, DB__register(), FAT_fclose(), FAT_fopen(), FAT_fread(), FAT_fseek(), FAT_fwrite(), st_DBREGIST::fname, GEN_malloc(), st_DBREGIST::len, st_DBIDTREE::node, r_b, rb, SEEK_HEAD, and SYS_die(). Referenced by DB__register(), and DB_mount(). 02780 {
02781 File * file;
02782 st_DBHEADER header;
02783 DB_ID id, tmpid;
02784 st_DBIDNODE * prevnode;
02785 char tmpname[DB_MAXLFN];
02786 char * pC;
02787 unsigned short tmp;
02788
02789 #ifdef DB_REGIST2SRAM
02790 unsigned long pBuf[64]; // support up to 16 children per DB.
02791 unsigned long * pp;
02792 unsigned long dname;
02793 #else
02794 DB_FNAME dname;
02795 unsigned long * pp;
02796 #endif
02797 unsigned short ii;
02798 unsigned long signature;
02799
02800
02801 if( (file = FAT_fopen(name, rb)) == NULL ) return DB_INVALID_ID;
02802
02803 /* Check header file signature. */
02804 if( FAT_fread(file, (unsigned short *)&header, sizeof(st_DBHEADER))
02805 != sizeof(st_DBHEADER) ) RETURN_ERROR_DB;
02806
02807 /* Seek to fetch signature. */
02808 FAT_fseek(file, header.len - 2, SEEK_HEAD);
02809 FAT_fread(file, (unsigned short *)&signature, 2);
02810 if( signature != DB_HEADER_SIGNATURE ) RETURN_ERROR_DB;
02811
02812
02813 /* Register database and all its children if any, build the ID tree. */
02814 #ifdef DB_REGIST2SRAM
02815
02816 /* Allocate header file name buffer. */
02817 ii = strlen(name);
02818 dname = GEN_malloc( ii + 1 );
02819 GEN_wrSRAM(dname, (unsigned short *)name, ii+1);
02820
02821 /* Register database ID. */
02822 id = DB_idtree.node[DB_idtree.counter].id = DB_idtree.counter;
02823
02824 //DB_assert (id < DB_MAX_ID, DB__REGISTER);
02825 if(id >= DB_MAX_ID)
02826 {
02827 SYS_die(DB__REGISTER);
02828 }
02829
02830 /* Register this id. */
02831 DB_registration[id].fname = dname;
02832 DB_registration[id].len = ii;
02833
02834 #else
02835 /* Allocate header file name buffer. */
02836 dname = (DB_FNAME)malloc( strlen(name) + 1 );
02837 strcpy((char *)dname, (char *)name);
02838
02839 /* Register database ID. */
02840 id = DB_idtree.node[DB_idtree.counter].id = DB_idtree.counter;
02841
02842 /* Register this id. */
02843 DB_registration[id].fname = dname;
02844 DB_registration[id].len = strlen(dname);
02845 #endif
02846
02847 DB_idtree.counter++;
02848
02849 /* Always put the newly-registered at last. */
02850 DB_idtree.node[id].next = NULL;
02851
02852 /* Only register root database here. */
02853 DB_idtree.node[id].parent = parent;
02854
02855 /* Set up previous sibling. */
02856 DB_idtree.node[id].prev = prev;
02857
02858 if( prev ) prev->next = &DB_idtree.node[id];
02859
02860 /* Set up child default to NULL. */
02861 DB_idtree.node[id].child = NULL;
02862
02863
02864 /* Check to see if children available. */
02865 if(header.numOfKeys > 1 )
02866 {
02867 /* First child. */
02868 DB_idtree.node[id].child = &DB_idtree.node[id+1];
02869
02870 /* First child will always be a virtual DB. */
02871 DB_registration[id+1].fname = NULL;
02872
02873 DB_registration[id+1].len = 0;
02874
02875 DB_idtree.node[id+1].id = id+1;
02876
02877 DB_idtree.counter++;
02878
02879 /* Always put the newly-registered at last. */
02880 DB_idtree.node[id+1].next = NULL;
02881
02882 /* Only register root database here. */
02883 DB_idtree.node[id+1].parent = &DB_idtree.node[id];
02884
02885 /* Set up previous sibling. */
02886 DB_idtree.node[id+1].prev = NULL;
02887
02888 /* Set up child default to NULL. */
02889 DB_idtree.node[id+1].child = NULL;
02890
02891 /* Points to first child. */
02892 prevnode = &DB_idtree.node[id+1];;
02893
02894 /* Allocate memory to read back file name pointers. */
02895 ii = (header.numOfKeys+1)<<1;
02896
02897 #ifdef DB_REGIST2SRAM
02898 pp = pBuf;
02899 #else
02900 if ( (pp = (unsigned long *)malloc( ii * sizeof(unsigned long)))
02901 == NULL ) RETURN_ERROR_DB;
02902 #endif
02903
02904 ii <<= 1;
02905
02906 FAT_fseek(file, sizeof(st_DBHEADER), SEEK_HEAD);
02907 if( FAT_fread(file, (unsigned short *)pp, ii ) != ii ) RETURN_ERROR_DB;
02908
02909 /* Skip database name, database parent file name and first child. */
02910 pp += 5;
02911
02912 /* Register all its children if any. */
02913 for( ii = 0; ii < header.numOfKeys - 1; ii++ )
02914 {
02915 pC = tmpname;
02916
02917 FAT_fseek(file, *pp, SEEK_HEAD);
02918
02919 while(1)
02920 {
02921 FAT_fread(file, &tmp, 1);
02922
02923 /* little endian PC data. */
02924 *pC++ = tmp >> 8;
02925
02926 *pC++ = tmp & 0x00FF;
02927
02928 if( (tmp & 0x00FF) == 0 ) break;
02929
02930 // Error handling.
02931 if(pC - tmpname > DB_MAXLFN) RETURN_ERROR_DB;
02932 }
02933
02934 tmpid = DB__register(tmpname, &DB_idtree.node[id], prevnode);
02935
02936 if( tmpid == DB_INVALID_ID )
02937 {
02938 RETURN_ERROR_DB;
02939 }
02940 else
02941 {
02942 prevnode = &DB_idtree.node[tmpid];
02943 /* Points to next key file name. */
02944 pp += 2;
02945 }
02946 }
02947 }
02948
02949 /* Close DB header file before return. */
02950 FAT_fclose(file);
02951
02952 /* Write ID back to header file. */
02953 #if 0
02954 file = FAT_fopen(name, r_b);
02955 FAT_fseek(file, DB_ID_OFFSET, SEEK_HEAD);
02956 FAT_fwrite(file, &id, 1);
02957 FAT_fclose(file);
02958 #endif
02959
02960 return id;
02961 }
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
Function removes specified PAI entry.
Definition at line 2662 of file db.c. References DB__name(), FAT_fclose(), FAT_fopen(), FAT_fread(), FAT_fseek(), FAT_fwrite(), File::flag, r_b, and SEEK_HEAD. Referenced by DB__deleteChildRecord(), and DB_removeRecord(). 02666 {
02667 st_DBPAICTL control;
02668 DB_PAIOFFSET rdstart;
02669 DB_PAIOFFSET wrstart;
02670 unsigned short dataleft;
02671 unsigned short counter;
02672 unsigned short rdlen;
02673 unsigned short wrlen;
02674 unsigned short ii;
02675 DB_MDBOFFSET rdbuf[DB_MAXPAIBUFLEN];
02676 DB_MDBOFFSET wrbuf[DB_MAXPAIBUFLEN];
02677 DB_MDBOFFSET * pWr;
02678 File * idxfile;
02679
02680 idxfile = FAT_fopen(DB__name(id, PAI), r_b);
02681 FAT_fseek(idxfile, pai - sizeof(st_DBPAICTL), SEEK_HEAD);
02682 FAT_fread(idxfile, (unsigned short *)&control, sizeof(st_DBPAICTL));
02683
02684 rdstart = pai;
02685 wrstart = pai;
02686 dataleft = control.entryNum;
02687 *pEntryNum = control.entryNum;
02688
02689 while(dataleft)
02690 {
02691 if(dataleft > DB_MAXPAIBUFLEN) rdlen = DB_MAXPAIBUFLEN << 1;
02692 else rdlen = dataleft << 1;
02693
02694 counter = 0;
02695
02696 FAT_fread(idxfile, (unsigned short *)rdbuf, rdlen);
02697
02698 pWr = wrbuf;
02699
02700 for(ii = 0; ii < (rdlen>>1); ii++)
02701 {
02702 if(rdbuf[ii] != entry) *pWr++ = rdbuf[ii];
02703 else counter++;
02704 }
02705
02706 wrlen = rdlen - (counter<<1);
02707 *pEntryNum -= counter;
02708
02709 FAT_fseek(idxfile, wrstart, SEEK_HEAD);
02710 FAT_fwrite(idxfile, (unsigned short *)wrbuf, wrlen);
02711
02712 wrstart += wrlen;
02713
02714 dataleft -= (rdlen>>1);
02715
02716 rdstart += rdlen;
02717
02718 FAT_fseek(idxfile, rdstart, SEEK_HEAD);
02719 }
02720
02721
02722 /* Zero out all free entries. */
02723 if( control.entryNum > *pEntryNum)
02724 {
02725 wrstart = pai + ( (long)(*pEntryNum) << 1 );
02726
02727 dataleft = (control.entryNum - *pEntryNum) << 1;
02728
02729 for(ii = 0; ii < DB_MAXPAIBUFLEN; ii++) wrbuf[ii] = 0L;
02730
02731 while(dataleft)
02732 {
02733 if(dataleft > (DB_MAXPAIBUFLEN<<1)) wrlen = (DB_MAXPAIBUFLEN<<1);
02734 else wrlen = dataleft;
02735
02736 FAT_fseek(idxfile, wrstart, SEEK_HEAD);
02737 FAT_fwrite(idxfile, (unsigned short *)wrbuf, wrlen);
02738
02739 wrstart += wrlen;
02740 dataleft -= wrlen;
02741 }
02742 }
02743
02744
02745 /* Update entryNum. */
02746 if(*pEntryNum)
02747 {
02748 FAT_fseek(idxfile, pai - sizeof(st_DBPAICTL) + 2, SEEK_HEAD);
02749 FAT_fwrite(idxfile, pEntryNum, 1);
02750 }
02751 else
02752 {
02753 /* Mark this module to be free. */
02754 FAT_fseek(idxfile, pai - sizeof(st_DBPAICTL) + 1, SEEK_HEAD);
02755 control.flag |= PAI_FREE;
02756
02757 FAT_fwrite(idxfile, (unsigned short *)&control.flag, 1);
02758 FAT_fwrite(idxfile, pEntryNum, 1);
02759 }
02760
02761 FAT_fclose(idxfile);
02762
02763 return TRUE;
02764 }
|
Here is the call graph for this function:

|
|
Function returns root DB ID of specified child ID.
Definition at line 1680 of file db.c. References st_DBIDTREE::node. Referenced by DB__info(), DB_add2child(), DB_deleteRecord(), DB_deleteRecordByMdb(), DB_dspData(), DB_getField(), DB_getMdbByRecord(), DB_getSaiByMdb(), and DB_removeRecord(). 01681 {
01682 st_DBIDNODE * node;
01683
01684 node = &DB_idtree.node[id];
01685
01686 /* Traverse to root. */
01687 while(node->parent) node = node->parent;
01688
01689 return node->id;
01690 }
|
|
||||||||||||||||
|
Function adds specified record to given child DB.
Definition at line 2461 of file db.c. References DB__addChildIdx(), DB__cdDBdir(), DB__fieldIndex(), DB__getRecord(), DB__insert2leaf(), DB__name(), DB__recordLen(), DB__rootID(), FAT_fclose(), FAT_fopen(), FAT_fread(), FAT_fseek(), FAT_fwrite(), st_DBIDTREE::node, r_b, rb, SEEK_HEAD, SEEK_MID, and File::size. 02464 {
02465 DB_ID rootID;
02466 st_DBIDNODE * node;
02467 DB_FIELDIDX fldidx;
02468 DB_MDBOFFSET childMdb;
02469 DB_MDBOFFSET newOffset;
02470 DB_MDBOFFSET tmpMdb;
02471 DB_RECLEN originalLen;
02472 DB_RECLEN childLen;
02473 DB_RECLEN newLen;
02474 unsigned short flag;
02475 File * dbfile;
02476 File * idxfile;
02477 unsigned short record[DB_MAXRECLEN];
02478 //unsigned short childRecord[DB_MAXRECLEN];
02479
02480 /* Fetch root MDB entry. */
02481 rootID = DB__rootID(childID);
02482
02483 if(DB__cdDBdir(DB__name(rootID, MDB)) == FALSE) return FALSE;
02484
02485 //idxfile = FAT_fopen(DB__name(rootID, SAI), rb);
02486 //FAT_fseek(idxfile, (unsigned long)(rootEntry+DB_SAIFIRSTENTRY) << 2, SEEK_HEAD);
02487 //FAT_fread(idxfile, (unsigned short *)&mdb, 2);
02488 //FAT_fclose(idxfile);
02489
02490 /* Fetch root record. */
02491 dbfile = FAT_fopen(DB__name(rootID, MDB), rb);
02492 FAT_fseek(dbfile, rootMdb, SEEK_HEAD);
02493 DB__getRecord(dbfile, record);
02494 FAT_fclose(dbfile);
02495
02496
02497 /* Fetch child MDB entry. */
02498 //idxfile = FAT_fopen(DB__name(childID, SAI), rb);
02499 //FAT_fseek(idxfile, (unsigned long)(childEntry+DB_SAIFIRSTENTRY) << 2, SEEK_HEAD);
02500 //FAT_fread(idxfile, (unsigned short *)&newOffset, 2);
02501 //FAT_fclose(idxfile);
02502
02503 /* Fetch child record. */
02504 //dbfile = FAT_fopen(DB__name(childID, MDB), rb);
02505 //FAT_fseek(dbfile, newOffset, SEEK_HEAD);
02506 //DB__getRecord(dbfile, childRecord);
02507 //FAT_fclose(dbfile);
02508
02509 /* ID to field index. */
02510 fldidx = DB__fieldIndex(childID);
02511
02512 originalLen = DB__recordLen(record);
02513 childLen = DB__recordLen(childRecord);
02514
02515 /* Insert to child. */
02516 childMdb = DB__insert2leaf( childID,
02517 rootID,
02518 rootMdb,
02519 record,
02520 childRecord,
02521 childLen,
02522 TRUE);
02523
02524 /* Update root DB field value. */
02525 DB__addChildIdx(record, fldidx, childMdb);
02526
02527 newLen = DB__recordLen(record);
02528
02529 /* If newLen == originalLen, the original is able to hold the new
02530 ** index without extending record length, we'll just write back the
02531 ** new record.
02532 */
02533 if(newLen == originalLen)
02534 {
02535 dbfile = FAT_fopen(DB__name(rootID, MDB), r_b);
02536 FAT_fseek(dbfile, rootMdb, SEEK_HEAD);
02537 FAT_fwrite(dbfile, (unsigned short *)record, newLen);
02538 FAT_fclose(dbfile);
02539
02540 return TRUE;
02541 }
02542
02543 else
02544 {
02545 /* Mark the original as deleted. */
02546 dbfile = FAT_fopen(DB__name(rootID, MDB), r_b);
02547
02548 newOffset = dbfile->size;
02549
02550 FAT_fseek(dbfile, rootMdb, SEEK_HEAD);
02551 FAT_fread(dbfile, (unsigned short *)&flag, 1);
02552
02553 flag |= RECORD_DELETED;
02554
02555 FAT_fseek(dbfile, -1, SEEK_MID);
02556 FAT_fwrite(dbfile, (unsigned short *)&flag, 1);
02557
02558 /* Append new to the end of file. */
02559 FAT_fseek(dbfile, newOffset, SEEK_HEAD);
02560 FAT_fwrite(dbfile, (unsigned short *)record, newLen);
02561 FAT_fclose(dbfile);
02562
02563 /* Search and replace SAI entry. */
02564 idxfile = FAT_fopen(DB__name(rootID, SAI), r_b);
02565 FAT_fseek(idxfile,(unsigned long)(DB_SAIFIRSTENTRY) << 2,SEEK_HEAD);
02566 while(1)
02567 {
02568 FAT_fread(idxfile, (unsigned short*)&tmpMdb, 2);
02569 DB_assert(tmpMdb != 0, DB_ADD2CHILD);
02570
02571 if(tmpMdb == rootMdb)
02572 {
02573 FAT_fseek(idxfile,-2,SEEK_MID);
02574 FAT_fwrite(idxfile, (unsigned short *)&newOffset, 2);
02575 break;
02576 }
02577 // Skip PAI entry.
02578 FAT_fread(idxfile, (unsigned short*)&tmpMdb, 2);
02579 }
02580 FAT_fclose(idxfile);
02581
02582 /* Search and replace all children PAIs. */
02583 node = &DB_idtree.node[rootID];
02584 node = node->child;
02585
02586 while(node->next)
02587 {
02588 _replacePAI(node->next->id, rootMdb, newOffset);
02589
02590 node = node->next;
02591 }
02592 }
02593 return TRUE;
02594 }
|
Here is the call graph for this function:

|
|
Function checks the DB sync mark.
Definition at line 216 of file db.c. References FAT_cd(), FAT_fclose(), FAT_fopen(), FAT_fread(), rb, and strDBDIR. 00217 {
00218 st_DBHEADER header;
00219 BOOL ret = TRUE;
00220 File * file;
00221
00222 FAT_cd(drive);
00223 if( TRUE == FAT_cd(strDBDIR) )
00224 {
00225 if( TRUE == FAT_cd(strAUDIODIR) )
00226 {
00227 if(file = FAT_fopen(strAUDIO, rb))
00228 {
00229 if( FAT_fread(file, (unsigned short *)&header, sizeof(st_DBHEADER))
00230 == sizeof(st_DBHEADER) )
00231 {
00232 if( !(header.status & 0x0002) ) ret = FALSE;
00233 }
00234 FAT_fclose(file);
00235 }
00236 }
00237 }
00238
00239 return ret;
00240 }
|
Here is the call graph for this function:

|
||||||||||||
|
Function returns child DB ID givent the child field index.
Definition at line 1635 of file db.c. References st_DBIDTREE::node. Referenced by MENU__createPresetMenu(), and UI_setupPlayQ(). 01636 {
01637 st_DBIDNODE * node;
01638
01639 node = &DB_idtree.node[rootID];
01640
01641 node = node->child;
01642 while(fldIdx--)
01643 {
01644 node = node->next;
01645 }
01646
01647 return node->id;
01648 }
|
|
|
Function checks to create all default device database.
Definition at line 2277 of file db.c. References FAT_cd(), FAT_mkdir(), and strDBDIR. 02278 {
02279 BOOL ret = TRUE;
02280
02281 FAT_cd(strDISKD);
02282 if( FAT_cd(strDBDIR) == FALSE )
02283 {
02284 if( FAT_mkdir(strDBDIR) == FALSE) return FALSE;
02285 if( FAT_cd(strDBDIR) == FALSE ) return FALSE;
02286 }
02287
02288 /* Check to create audio DB. */
02289 ret = _createDB((ULONG)AUDIO_MDB_INIT_TABLE, strAUDIO, force2create);
02290
02291 /* Check to create PC audio DB. */
02292 if( ret == TRUE )
02293 {
02294 ret = _createDB((ULONG)PCAUDIO_MDB_INIT_TABLE, strPCAUDIO, force2create);
02295 }
02296
02297 /* Check to create identified hisi DB. */
02298 if( ret == TRUE )
02299 {
02300 ret = _createDB((ULONG)IDEDHISI_MDB_INIT_TABLE, strIDEDHISI, force2create);
02301 }
02302
02303 /* Check to create unidentified hisi DB. */
02304 if( ret == TRUE )
02305 {
02306 ret = _createDB((ULONG)UNIDHISI_MDB_INIT_TABLE, strUNIDEDHISI, force2create);
02307 }
02308
02309 /* Check to create unsuccessful hisi DB. */
02310 if( ret == TRUE )
02311 {
02312 ret = _createDB((ULONG)FAILHISI_MDB_INIT_TABLE, strFAILEDHISI, force2create);
02313 }
02314
02315 return ret;
02316 }
|
Here is the call graph for this function:

|
||||||||||||
|
Function deletes specified record from the root database, it also updtes all corresponding child database.
Definition at line 2011 of file db.c. References DB__cdDBdir(), DB__deleteChildRecord(), DB__name(), and DB__rootID(). 02012 {
02013 if(DB__cdDBdir(DB__name(DB__rootID(id), MDB)) == FALSE) return FALSE;
02014 return DB__deleteChildRecord(id, entry);
02015 }
|
Here is the call graph for this function:

|
||||||||||||
|
Function deletes specified record indexed by root offset from the root database, it also updtes all corresponding child database.
Definition at line 2029 of file db.c. References DB__cdDBdir(), DB__deleteChildRecord(), DB__name(), DB__rootID(), FAT_fclose(), FAT_fopen(), FAT_fread(), FAT_fseek(), rb, and SEEK_HEAD. Referenced by UI_PSF_play(). 02030 {
02031 DB_MDBOFFSET offset;
02032 USHORT entryNum;
02033 DB_ENTRY entry = 1;
02034 File * idxfile;
02035 BOOL ret = FALSE;
02036
02037 if(DB__cdDBdir(DB__name(DB__rootID(id), MDB)) == FALSE) return FALSE;
02038
02039 // Fetch entry number from SAI file.
02040 idxfile = FAT_fopen(DB__name(id, SAI), rb);
02041 FAT_fseek(idxfile, DB_SAIENTRYNUMOFFSET, SEEK_HEAD);
02042 FAT_fread(idxfile, &entryNum, 1);
02043
02044 FAT_fseek(idxfile, (unsigned long)(1+DB_SAIFIRSTENTRY)<<2, SEEK_HEAD);
02045 while(entryNum--)
02046 {
02047 if(2!=FAT_fread(idxfile, (unsigned short *)&offset, 2)) break;
02048 if(mdb == offset)
02049 {
02050 ret = TRUE;
02051 break;
02052 }
02053 // Skip the PAI entry.
02054 if(2!=FAT_fread(idxfile, (unsigned short *)&offset, 2)) break;
02055
02056 entry++;
02057 }
02058 FAT_fclose(idxfile);
02059
02060 if(TRUE == ret) return DB__deleteChildRecord(id, entry);
02061
02062 return FALSE;
02063 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Function reads back the database display data and returns data length in words.
Definition at line 1966 of file db.c. References DB__cdDBdir(), DB__name(), DB__rootID(), FAT_fclose(), FAT_fopen(), FAT_fread(), FAT_fseek(), st_DBREGIST::fname, st_DBIDTREE::node, rb, and SEEK_HEAD. 01967 {
01968 File * file;
01969 unsigned long pName;
01970 unsigned short len;
01971
01972 /* Change to corresponding root DB directory. */
01973 if(DB__cdDBdir(DB__name(DB__rootID(id), MDB)) == FALSE) return 0;
01974
01975 /* Check to see if id points to a virtual DB. */
01976 if( DB_registration[id].fname == NULL )
01977 {
01978 /* Virtual DB, access through its parent. */
01979 id = DB_idtree.node[id].parent->id;
01980 }
01981
01982 if( (file = FAT_fopen(DB__name(id, MDB), rb) ) == NULL ) return 0;
01983
01984
01985 FAT_fseek(file, DB_PNAME_OFFSET + ((long)idx << 2), SEEK_HEAD);
01986 FAT_fread(file, (unsigned short *)&pName, 2);
01987
01988 FAT_fseek(file, pName, SEEK_HEAD);
01989 FAT_fread(file, pData, 1);
01990
01991 len = *pData;
01992 FAT_fread(file, pData, len);
01993
01994 FAT_fclose(file);
01995
01996 return len;
01997 }
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
Function gets interpreted data of the specified record field out of given record.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Definition at line 1846 of file db.c. References DB__cdDBdir(), DB__getField(), DB__getRecord(), DB__name(), DB__rootID(), FAT_fclose(), FAT_fopen(), FAT_fseek(), st_DBINFO::id, st_DBIDTREE::node, st_DBINFO::numOfKeys, rb, and SEEK_HEAD. Referenced by UI_interpretAudioRecord(), UI_interpretFailedHisiRecord(), UI_interpretIdentifiedHisiRecord(), UI_interpretUnidentifiedHisiRecord(), and UI_setupPlayQ(). 01850 {
01851 st_DBIDNODE * node;
01852 DB_ID tmpid;
01853 DB_MDBOFFSET childMdb;
01854 File * file;
01855 unsigned short ii;
01856 unsigned short record[DB_MAXRECLEN];
01857
01858 if(NULL == pData) return 0;
01859
01860 ii = DB__getField(pRecord, fldIdx, pData);
01861
01862 if( (0==fldIdx)||(0==ii)||(fldIdx >= pInfo->numOfKeys) ) return ii;
01863
01865 // Currently only the first child MDB in field is fetched, this is
01866 // definitely a hole in algorithm, since there might be more than
01867 // one there. I simply don't worry about it now because this
01868 // feature is not used anyway.
01870 childMdb = ((unsigned long)(*(unsigned short *)pData)<<16)|(*((unsigned short *)pData+1));
01871
01872 // Virtual DB, no data available.
01873 //if(pInfo->bVirtual == TRUE) return 0;
01874
01875 /* Get field DB id. */
01876 //node = DB_idtree.node[pInfo->id].child;
01877 node = DB_idtree.node[DB_rootID(pInfo->id)].child;
01878 for(ii = 0; ii < fldIdx; ii++ ) node = node->next;
01879
01880 tmpid = node->id;
01881
01882 DB__cdDBdir(DB__name(DB__rootID(tmpid), MDB));
01883
01884 /* Open child DB MDB file. */
01885 file = FAT_fopen(DB__name(tmpid, MDB), rb);
01886
01887 /* Seek to offset. */
01888 FAT_fseek(file, childMdb, SEEK_HEAD);
01889
01890 DB__getRecord(file, record);
01891 FAT_fclose(file);
01892
01893 return( DB__getField(record, 0, pData) );
01894 }
|
Here is the call graph for this function:

|
||||||||||||
|
Function checks return the MDB offset by record data.
Definition at line 1763 of file db.c. References DB__cdDBdir(), DB__getField(), DB__name(), DB__rootID(), DB_MAXFIELDLEN, FAT_fclose(), FAT_fopen(), FAT_fread(), FAT_fseek(), rb, SEEK_HEAD, and SEEK_MID. 01764 {
01765 unsigned short field[DB_MAXFIELDLEN];
01766 DB_ENTRY entry; /* SAI entry number. */
01767 DB_MDBOFFSET offset; /* File offset in MDB file. */
01768 File * idxfile;
01769 File * dbfile;
01770
01771 if(DB__cdDBdir(DB__name(DB__rootID(id), MDB)) == FALSE) return 0;
01772
01773 /* Open MDB and SAI files. */
01774 idxfile = FAT_fopen(DB__name(id, SAI), rb);
01775 dbfile = FAT_fopen(DB__name(id, MDB), rb);
01776
01777
01778 /* Points to the first valid entry. */
01779 entry = DB_SAIFIRSTENTRY;
01780
01781
01782 /* SAI entry takes 64bits, 4 words per entry. */
01783 FAT_fseek(idxfile, (long)entry << 2, SEEK_HEAD);
01784 FAT_fread(idxfile, (unsigned short *)&offset, 2);
01785
01786 while(offset)
01787 {
01788 unsigned short len;
01789
01790 FAT_fseek(dbfile, offset, SEEK_HEAD);
01791 FAT_fread(dbfile, field, DB_MAXFIELDLEN);
01792
01793 /* Only compare the primary field. */
01794 if(len = DB__getField(field, 0, field))
01795 {
01796 unsigned short * pS = (unsigned short *)field;
01797 unsigned short * pD = (unsigned short *)pData;
01798 do
01799 {
01800 if(*pS++ != *pD++) break;
01801
01802 } while(--len);
01803
01804 if( 0 == len )
01805 {
01806 /* Record found!. */
01807 FAT_fclose(idxfile);
01808 FAT_fclose(dbfile);
01809
01810 return offset;
01811 }
01812 }
01813
01814 entry++;
01815
01816 /* Skip PAI entry. */
01817 FAT_fseek(idxfile, 2, SEEK_MID);
01818 FAT_fread(idxfile, (unsigned short *)&offset, 2);
01819 }
01820
01821
01822 /* Record does not exist. */
01823 FAT_fclose(idxfile);
01824 FAT_fclose(dbfile);
01825
01826 // Not found.
01827 return 0L;
01828 }
|
Here is the call graph for this function:

|
||||||||||||
|
Function calculates SAI entry based on MDB offset.
Definition at line 1703 of file db.c. References DB__cdDBdir(), DB__name(), DB__rootID(), FAT_fclose(), FAT_fopen(), FAT_fread(), FAT_fseek(), rb, and SEEK_HEAD. Referenced by UI_SF_dbmenu(). 01704 {
01705 File * idxfile;
01706 unsigned long signature;
01707 DB_ENTRY entry;
01708 unsigned short entryNum;
01709 ULONG mdbEnt[2];
01710
01711 /* Change to corresponding root DB directory. */
01712 if(DB__cdDBdir(DB__name(DB__rootID(id), MDB)) == FALSE)
01713 {
01714 return DB_INVALID_ENTRY;
01715 }
01716
01717
01718 /* Open SAI file. */
01719 idxfile = FAT_fopen(DB__name(id, SAI), rb);
01720
01721 /* Check SAI file signature for safe. */
01722 FAT_fread(idxfile, (unsigned short *)&signature, 2);
01723
01724 if( signature != DB_SAI_SIGNATURE )
01725 {
01726 /* Invalid field access. */
01727 FAT_fclose(idxfile);
01728 return DB_INVALID_ENTRY;
01729 }
01730
01731
01732 /* Check if dbEntry is valid. */
01733 FAT_fseek(idxfile, DB_SAIENTRYNUMOFFSET, SEEK_HEAD);
01734 FAT_fread(idxfile, &entryNum, 1);
01735
01736 FAT_fseek(idxfile, (unsigned long)(DB_SAIFIRSTENTRY)<<2, SEEK_HEAD);
01737 entry = 0;
01738 while(entryNum--)
01739 {
01740 FAT_fread(idxfile, (unsigned short *)&mdbEnt, 4);
01741 if(mdbEnt[0] == mdb)
01742 {
01743 FAT_fclose(idxfile);
01744 return entry;
01745 }
01746 entry++;
01747 }
01748
01749 FAT_fclose(idxfile);
01750 return DB_INVALID_ENTRY;
01751 }
|
Here is the call graph for this function:

|
|
Function returns information of specified database.
Definition at line 1517 of file db.c. Referenced by UI_setupPlayQ(). 01518 {
01519 return(&DB_qinfo[hdl]);
01520 }
|
|
|
Function initializes DB controls.
Definition at line 1487 of file db.c. References st_DBIDTREE::counter, st_DBREGIST::fname, and st_DBQUERYCTL::free. 01488 {
01489 unsigned short ii;
01490
01491 /* Clear database regisration table. */
01492 for ( ii = 0; ii < DB_MAX_ID; ii++ ) DB_registration[ii].fname = NULL;
01493
01494 /* Reset database ID tree. */
01495 DB_idtree.counter = 0;
01496
01497 /* Reset all available query controls. */
01498 for( ii = 0; ii < DB_OPENMAX; ii++ ) DB_qctl[ii].free = TRUE;
01499
01500 /* Initialize DB tree globale controls. */
01501 //DB_ctl.actvHdl = DB_INVALID_HDL;
01502
01503 return TRUE;
01504 }
|
|
||||||||||||
|
Function inserts a record to specified root database.
Definition at line 733 of file db.c. References ab, st_DBINFO::attribute, DB__addSAIentry(), DB__info(), DB__name(), DB__recordPosition(), FAT_fclose(), FAT_fopen(), FAT_fwrite(), st_DBIDTREE::node, st_DBINFO::numOfKeys, rb, and File::size. Referenced by UI_insertAudioRecord(), and UI_insertHisiRecord(). 00734 {
00735 st_DBINFO info;
00736 st_DBDINODE * node; /* DB insertion node. */
00737 st_DBDINODE ditree[DB_MAXDBNODES]; /* DB insertion tree */
00738 DB_ENTRY entry;
00739 DB_PAIOFFSET pai;
00740 DB_MDBOFFSET mdb;
00741 File * dbfile;
00742
00743 /* Check DB attributes for safe. */
00744 if( DB__info(id, &info) == FALSE ) return FALSE;
00745 if( !(info.attribute & DB_ROOT) )
00746 {
00747 /* Insertion can only be applied to root DB. */
00748 return FALSE;
00749 }
00750
00751
00752 /* Initialize root node. */
00753 ditree[0].parent =
00754 ditree[0].prev = NULL;
00755
00756 /* Copy DB node tree over. */
00757 _copyTree(ditree, &DB_idtree.node[id]);
00758
00759
00760 /* Form DB insertion data tree. */
00761 _formDataTree(ditree, pData);
00762
00763
00764 /* First to check if record already exists. */
00765 if( DB__recordPosition(id, &entry, *(unsigned short **)pData, FALSE) == TRUE )
00766 {
00767 /* Record already exists, error. */
00768 return FALSE;
00769 }
00770
00771
00772 /* Always append to the end of MDB file. Let's check MDB file size. */
00773 dbfile = FAT_fopen(DB__name(id, MDB), rb);
00774 mdb = dbfile->size;
00775 FAT_fclose(dbfile);
00776
00777
00778 /* Insert record to root SAI. */
00779 pai = 0L;
00780
00781 /* Add entry to SAI file. */
00782 DB__addSAIentry(id, entry, mdb, pai);
00783
00784
00785 /* Set up parent MDB offset. */
00786 ditree[0].mdb = mdb;
00787
00788
00789 /* Update all related children database. */
00790 if( info.numOfKeys > 1)
00791 {
00792 /* Children available, let's do it. */
00793 node = ditree[0].child;
00794
00795 while(node->next)
00796 {
00797 _insert2child(node->next);
00798 node = node->next;
00799 }
00800 }
00801
00802
00803 /* Finally, write root DB data. */
00804
00805 dbfile = FAT_fopen(DB__name(id, MDB), ab);
00806 FAT_fwrite(dbfile, (unsigned short *)ditree[0].data, ditree[0].len);
00807 FAT_fclose(dbfile);
00808
00809 return TRUE;
00810 }
|
Here is the call graph for this function:

|
|
Function mounts the specified database . Function shall check DB integrity and register DB to system. If successed, ID tree will be built/updated to support menu system.
Definition at line 714 of file db.c. References DB__cdDBdir(), and DB__register(). 00715 {
00716 // CD to corresponding sub-directory.
00717 if(DB__cdDBdir(name) == FALSE ) return DB_INVALID_ID;
00718
00719 return( DB__register(name, NULL, NULL) );
00720 }
|
Here is the call graph for this function:

|
|
Function returns parent DB ID of the givent the child DB.
Definition at line 1659 of file db.c. References st_DBIDTREE::node. 01660 {
01661 st_DBIDNODE * node;
01662
01663 node = &DB_idtree.node[id];
01664
01665 /* Traverse to parent. */
01666 if(node->parent) node = node->parent;
01667
01668 return node->id;
01669 }
|
|
|
Function closes the specified database query operation and releases corresponding control data object.
Definition at line 574 of file db.c. References st_DBQUERYCTL::dbfile, FAT_fclose(), st_DBQUERYCTL::free, and st_DBQUERYCTL::idxfile. Referenced by MENU__createPresetMenu(), UI_audioPresetUpdate(), UI_playQreset(), UI_playQshutdown(), UI_presetAudio(), and UI_setupPlayQ(). 00575 {
00576 st_DBQUERYCTL * pCtl;
00577
00578 if(hdl == DB_INVALID_HDL ) return FALSE;
00579 pCtl = &DB_qctl[hdl];
00580 if(pCtl->free == TRUE) return TRUE;
00581
00582 FAT_fclose(pCtl->dbfile);
00583 FAT_fclose(pCtl->idxfile);
00584
00585 pCtl->free = TRUE;
00586
00587 return TRUE;
00588 }
|
Here is the call graph for this function:

|
||||||||||||||||||||||||
|
Function queries the specified database and sets up query controls.
Definition at line 377 of file db.c. References st_DBINFO::bVirtual, DB__getRecord(), DB__info(), DB__name(), st_DBQUERYCTL::dbfile, FAT_fclose(), FAT_fopen(), FAT_fread(), FAT_fseek(), st_DBQUERYCTL::free, st_DBQUERYCTL::idx, st_DBQUERYCTL::idxfile, st_DBIDTREE::node, st_DBINFO::numOfKeys, st_DBINFO::numOfPAIent, st_DBQUERYCTL::pai, rb, SEEK_HEAD, and st_DBQUERYCTL::step. Referenced by MENU__createPresetMenu(), UI_audioPresetUpdate(), UI_playQreset(), UI_presetAudio(), and UI_setupPlayQ(). 00382 {
00383 DB_HDL hdl;
00384 DB_ID tmpid;
00385 USHORT entryNum;
00386 unsigned short ii;
00387 st_DBQUERYCTL * pCtl;
00388 st_DBIDNODE * node;
00389 st_DBINFO * pInfo;
00390
00391 /* Locate first available query control OBJ. */
00392 for( ii = 0; ii < DB_OPENMAX; ii++ )
00393 {
00394 if( DB_qctl[ii].free == TRUE ) break;
00395 }
00396 if ( ii == DB_OPENMAX ) return DB_INVALID_HDL;
00397
00398 /* Valid handle found. */
00399 hdl = ii;
00400 pCtl = &DB_qctl[hdl];
00401 pCtl->free = FALSE;
00402 pInfo = &DB_qinfo[hdl];
00403
00404 if( DB__info(id, pInfo) == FALSE )
00405 {
00406 pCtl->free = TRUE;
00407 return DB_INVALID_HDL;
00408 }
00409
00410 // start querying.
00411 node = &DB_idtree.node[id];
00412
00413 /* Check to see if id points to a virtual DB. */
00414 //if( DB_registration[id].fname == NULL )
00415 if(pInfo->bVirtual == TRUE)
00416 {
00417 /* Virtual DB, access through its parent. */
00418 node = node->parent;
00419 return( _query(node->id, dbEntry, pData, hdl) );
00420 }
00421
00422 /* Check to see if primary key is used to access the database. */
00423 //if( fldIdx == 0 )
00424 if( (fldIdx == 0)||(fldIdx == 0xffff) )
00425 {
00426 /* Primary key detected, query DB directly. */
00427 return( _query(id, dbEntry, pData, hdl) );
00428 }
00429
00430 /* Following code to access DB using specified key. */
00431 /* Check to see if this is a valid key. */
00432 //if( DB__info(id, &info) == FALSE ) return DB_INVALID_HDL;
00433 //if( fldIdx >= info.numOfKeys ) return DB_INVALID_HDL;
00434 if( fldIdx >= pInfo->numOfKeys )
00435 {
00436 pCtl->free = TRUE;
00437 return DB_INVALID_HDL;
00438 }
00439
00440 /* Fetch the access field DB ID. */
00441 node = node->child;
00442 for(ii = 0; ii < fldIdx; ii++ ) node = node->next;
00443
00444 tmpid = node->id;
00445
00446 /* Locate the key. */
00447 hdl = _query(tmpid, fldEntry, pData, hdl);
00448 if(hdl == DB_INVALID_HDL) return hdl;
00449
00450
00451 //pCtl = &DB_qctl[hdl];
00452 /* Close current MDB file. */
00453 FAT_fclose(pCtl->dbfile);
00454
00455 /* Close current SAI file. */
00456 FAT_fclose(pCtl->idxfile);
00457
00458
00459 /* Open MDB file. */
00460 pCtl->dbfile = FAT_fopen(DB__name(id, MDB), rb);
00461
00462 /* Open PAI file. */
00463 pCtl->idxfile = FAT_fopen(DB__name(tmpid, PAI), rb);
00464
00465 if( pCtl->pai == 0)
00466 {
00467 /* Empty PAI entry. */
00468 pCtl->free = TRUE;
00469
00470 FAT_fclose(pCtl->idxfile);
00471 FAT_fclose(pCtl->dbfile);
00472 return DB_INVALID_HDL;
00473 }
00474
00475 /* PAI entry always takes 32 bits. */
00476 pCtl->step = 1;
00477
00478 /* Locate the entry number. */
00479 FAT_fseek(pCtl->idxfile, pCtl->pai - 4, SEEK_HEAD);
00480 FAT_fread(pCtl->idxfile, &entryNum, 1);
00481
00482 pInfo->numOfPAIent = entryNum+1;
00483 if(dbEntry > entryNum)
00484 {
00485 /* Empty PAI entry. */
00486 pCtl->free = TRUE;
00487 FAT_fclose(pCtl->idxfile);
00488 FAT_fclose(pCtl->dbfile);
00489 return DB_INVALID_HDL;
00490 }
00491
00492 pCtl->idx = pCtl->pai;
00493
00494 #if 1
00495 /* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00496 ** I chose the confusing way to ease my UI application. :(
00497 ** Any query via PAI MUST add ONE entry offset, thus the UI
00498 ** can use the same code to query no matter it is via SAI or PAI,
00499 ** since "dbEntry == 0" always points to the default empty entry
00500 ** if we directly query the DB through SAI ( fldIdx == 0 ).
00501 ** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
00502 */
00503 pCtl->idx -= 2;
00504 #endif
00505
00506 /* Locate the record index. */
00507 FAT_fseek(pCtl->idxfile, pCtl->idx + (dbEntry << 1), SEEK_HEAD);
00508 FAT_fread(pCtl->idxfile, (unsigned short *)&pCtl->pai, 2);
00509
00510 /* Locate the record. */
00511 FAT_fseek(pCtl->dbfile, pCtl->pai, SEEK_HEAD);
00512
00513 /* Fetch record. */
00514 if( DB__getRecord(pCtl->dbfile, pData) == FALSE )
00515 {
00516 /* No record available. */
00517 pCtl->free = TRUE;
00518 FAT_fclose(pCtl->idxfile);
00519 FAT_fclose(pCtl->dbfile);
00520 return DB_INVALID_HDL;
00521 }
00522
00523 return hdl;
00524 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Function queries database through specified database handle.
Definition at line 539 of file db.c. References DB__getRecord(), st_DBQUERYCTL::dbfile, FAT_fread(), FAT_fseek(), st_DBQUERYCTL::idx, st_DBQUERYCTL::idxfile, SEEK_HEAD, and st_DBQUERYCTL::step. Referenced by UI_playQprevious(), and UI_setupPlayQ(). 00540 {
00541 DB_MDBOFFSET mdb = 0L;
00542 USHORT * pD = pData;
00543 st_DBQUERYCTL * pCtl = &DB_qctl[hdl];
00544
00545 FAT_fseek(pCtl->idxfile, pCtl->idx + (entry<<pCtl->step),SEEK_HEAD);
00546 FAT_fread(pCtl->idxfile, (unsigned short *)&mdb, 2);
00547
00548 /* Reached top / bottom ? */
00549 if( mdb == 0 ) return FALSE;
00550
00551 /* Locate the record. */
00552 FAT_fseek(pCtl->dbfile, mdb, SEEK_HEAD);
00553
00554 if(pD)
00555 {
00556 *(USHORT*)pD++ = mdb>>16;
00557 *(USHORT*)pD++ = mdb&0xffff;
00558 }
00559
00560 return( DB__getRecord(pCtl->dbfile, pD) );
00561 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Function removes specified record reference from the child database.
Definition at line 255 of file db.c. References DB__cdDBdir(), DB__deleteChildRecord(), DB__fieldIndex(), DB__getRecord(), DB__name(), DB__recordLen(), DB__removePAIentry(), DB__rootID(), FAT_fclose(), FAT_fopen(), FAT_fread(), FAT_fseek(), FAT_fwrite(), r_b, rb, and SEEK_HEAD. 00256 {
00257 unsigned short entryNum;
00258 DB_MDBOFFSET root;
00259 DB_MDBOFFSET child;
00260 DB_PAIOFFSET pai;
00261 DB_FIELDIDX fldidx;
00262 DB_RECLEN len;
00263 File * idxfile;
00264 File * dbfile;
00265 unsigned short record[DB_MAXRECLEN];
00266
00267 if(DB__cdDBdir(DB__name(DB__rootID(childId), MDB)) == FALSE) return FALSE;
00268
00269 fldidx = DB__fieldIndex(childId);
00270
00271 /* Fetch child MDB offset. */
00272 idxfile = FAT_fopen(DB__name(childId, SAI), rb);
00273 FAT_fseek(idxfile, (long)(childEntry + DB_SAIFIRSTENTRY) << 2, SEEK_HEAD);
00274 FAT_fread(idxfile, (unsigned short *)&child, 2);
00275 FAT_fread(idxfile, (unsigned short *)&pai, 2);
00276 FAT_fclose(idxfile);
00277
00278 /* Update root record, remove child index. */
00279 idxfile = FAT_fopen(DB__name(childId, PAI), rb);
00280 FAT_fseek(idxfile, pai+((paiEntry-1)<<1), SEEK_HEAD);
00281 FAT_fread(idxfile, (unsigned short *)&root, 2);
00282 FAT_fclose(idxfile);
00283
00284 dbfile = FAT_fopen(DB__name(DB__rootID(childId), MDB), r_b);
00285 FAT_fseek(dbfile, root, SEEK_HEAD);
00286 DB__getRecord(dbfile, record);
00287
00288 _removeChildIdx(record, fldidx, child);
00289
00290 len = DB__recordLen(record);
00291
00292 FAT_fseek(dbfile, root, SEEK_HEAD);
00293 FAT_fwrite(dbfile, (unsigned short *)record, len);
00294 FAT_fclose(dbfile);
00295
00296
00297 /* Search child PAI to remove specified parent entry. */
00298 DB__removePAIentry(childId, root, pai, &entryNum);
00299
00300 if(entryNum == 0)
00301 {
00302 /* No PAIs left for this entry, delete it. */
00303 DB__deleteChildRecord(childId, childEntry);
00304 }
00305
00306 return TRUE;
00307 }
|
Here is the call graph for this function:

|
|
Function sets the DB sync mark. The mark is set by firmware and cleared by NSM.
Definition at line 181 of file db.c. References FAT_cd(), FAT_fclose(), FAT_fopen(), FAT_fread(), FAT_fseek(), FAT_fwrite(), r_b, SEEK_HEAD, st_DBINFO::status, and strDBDIR. 00182 {
00183 st_DBHEADER header;
00184 File * file;
00185
00186 FAT_cd(drive);
00187 if( TRUE == FAT_cd(strDBDIR) )
00188 {
00189 if( TRUE == FAT_cd(strAUDIODIR) )
00190 {
00191 if(file = FAT_fopen(strAUDIO, r_b))
00192 {
00193 FAT_fseek(file, 0, SEEK_HEAD);
00194 if( FAT_fread(file, (unsigned short *)&header, sizeof(st_DBHEADER))
00195 == sizeof(st_DBHEADER) )
00196 {
00197 header.status |= 0x0002;
00198 }
00199 FAT_fseek(file, 0, SEEK_HEAD);
00200 FAT_fwrite(file, (unsigned short *)&header, sizeof(st_DBHEADER));
00201 FAT_fclose(file);
00202 }
00203 }
00204 }
00205 }
|
Here is the call graph for this function:

|
|
Function unmounts specified database. Function shall check to unmount corresponding child databases if any and update parent database if available. Function will clear corresponding registration entries and release allocated memory.
Definition at line 167 of file db.c. 00168 {
00169 return TRUE;
00170 }
|
1.3.9.1