00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00043 #include "../SYSTEM/sys_hardware.h"
00044 #include "db.h"
00045 #include "db_assert.h"
00046
00050 static BOOL _removeChildIdx(DB_DATA *,DB_FIELDIDX,DB_MDBOFFSET);
00051 static DB_HDL _query(DB_ID, DB_ENTRY, DB_DATA *, DB_HDL);
00052 #define DB_MAXDBNODES 8
00053
00054 static st_DBDINODE * _copyTree(st_DBDINODE *, const st_DBIDNODE *);
00055 static const DB_DATA * _formDataTree(st_DBDINODE *, const DB_DATA *);
00056 static BOOL _insert2child(st_DBDINODE *);
00057 #define RETURN_ERROR {FAT_fclose(file);return FALSE;}
00058 #define RETURN_ERROR_DB {FAT_fclose(file);return DB_INVALID_ID;}
00059 static void _sortSAI (unsigned long *, USHORT);
00060 static BOOL _genFile ( ULONG, const char *);
00061 static BOOL _createDB ( ULONG, const char *, BOOL);
00062 static BOOL _replacePAI(DB_ID,DB_MDBOFFSET,DB_MDBOFFSET);
00063 #define DB_MAXPAIBUFLEN 64
00064 static DB_PAIOFFSET _checkPAI(DB_ID,DB_PAIOFFSET,DB_MDBOFFSET);
00065 static DB_PAIOFFSET _createPAIentry(DB_ID,DB_MDBOFFSET);
00066 #define SPECIAL_CHAR_FIX
00067
00068 #define TABLE_SIZE 130
00069 const unsigned char _char_sorting_table[TABLE_SIZE] =
00070 {
00071
00072 0x00, 0x06, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
00073
00074 0x0E, 0x01, 0x02, 0x24, 0x25, 0x03, 0x0F, 0x10,
00075
00076
00077 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
00078
00079 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20,
00080
00081
00082 0x04, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x22,
00083
00084 0x2C, 0x2D, 0x2E, 0x40, 0x2F, 0x23, 0x30, 0x31,
00085
00086
00087 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B,
00088
00089 0x4C, 0x4D, 0x32, 0x33, 0x41, 0x42, 0x33, 0x34,
00090
00091
00092 0x35, 0x4E, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5A,
00093
00094 0x5C, 0x5E, 0x60, 0x62, 0x64, 0x66, 0x68, 0x6A,
00095
00096
00097 0x6C, 0x6E, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7A,
00098
00099 0x7C, 0x7E, 0x80, 0x36, 0x37, 0x38, 0x39, 0x3A,
00100
00101
00102 0x3B, 0x4E, 0x50, 0x52, 0x54, 0x56, 0x58, 0x5A,
00103
00104 0x5C, 0x5E, 0x60, 0x61, 0x64, 0x66, 0x68, 0x6A,
00105
00106
00107 0x6C, 0x6E, 0x70, 0x72, 0x74, 0x76, 0x78, 0x7A,
00108
00109 0x7C, 0x7E, 0x80, 0x3C, 0x3D, 0x3E, 0x3F, 0x21,
00110
00111
00112 0x05, 0x07
00113 };
00114
00115 #ifdef SPECIAL_CHAR_FIX
00116 #define _2lower(x) (((_char_sorting_table[((x)>>8)&0xff])<<8) |(_char_sorting_table[(x)&0xff]) )
00117 #else
00118 #define _2lower(x) _char_sorting_table[(x)]
00119 #endif
00120
00124
00128 #ifdef BACKUP_DATABASE
00129 const char strDBBUPDIR[] = "BAK_DB";
00130 #endif
00131 const char strDBDIR[] = "WOID_DB";
00132 const char strAUDIODIR[] = "audio";
00133 const char strAUDIO[] = "audio.mdb";
00134 const char strPCAUDIO[] = "pcaudio.mdb";
00135 const char strFAILEDHISI[] = "failedhisi.mdb";
00136 const char strIDEDHISI[] = "idedhisi.mdb";
00137 const char strUNIDEDHISI[] = "unidedhisi.mdb";
00138 st_DBREGIST DB_registration[DB_MAX_ID];
00139 st_DBIDTREE DB_idtree;
00140 st_DBQUERYCTL DB_qctl[DB_OPENMAX];
00141 st_DBINFO DB_qinfo[DB_OPENMAX];
00142
00143 st_DBNAV DBnav;
00144
00145
00146 extern void AUDIO_MDB_INIT_TABLE ( void );
00147 extern void PCAUDIO_MDB_INIT_TABLE ( void );
00148 extern void UNIDHISI_MDB_INIT_TABLE ( void );
00149 extern void IDEDHISI_MDB_INIT_TABLE ( void );
00150 extern void FAILHISI_MDB_INIT_TABLE ( void );
00151
00155 #pragma CODE_SECTION (DB_unmount, ".dbinit_code")
00167 BOOL DB_unmount(DB_ID id)
00168 {
00169 return TRUE;
00170 }
00171
00172
00173 #pragma CODE_SECTION (DB_setSyncMark, ".dbinit_code")
00181 void DB_setSyncMark( const char * drive )
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 }
00206
00207 #pragma CODE_SECTION (DB_checkSyncMark, ".dbinit_code")
00216 BOOL DB_checkSyncMark( const char * drive )
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 }
00241
00242 #pragma CODE_SECTION(DB_removeRecord, ".db_code")
00255 BOOL DB_removeRecord(DB_ID childId, DB_ENTRY childEntry, DB_ENTRY paiEntry)
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
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
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
00298 DB__removePAIentry(childId, root, pai, &entryNum);
00299
00300 if(entryNum == 0)
00301 {
00302
00303 DB__deleteChildRecord(childId, childEntry);
00304 }
00305
00306 return TRUE;
00307 }
00308
00309 #pragma CODE_SECTION(_removeChildIdx, ".db_code")
00322 static BOOL _removeChildIdx(DB_DATA * pRecord,
00323 DB_FIELDIDX fldidx,
00324 DB_MDBOFFSET childMdb)
00325 {
00326 unsigned long mdb;
00327 unsigned short * pD;
00328 unsigned short * pT;
00329
00330 pD = (unsigned short *)DB__locateField(pRecord, fldidx);
00331
00332 while(1)
00333 {
00334 if(*pD == DB_ESCCHAR) pD++;
00335 else if( (*pD==DB_RECDLMT) ||(*pD==DB_FLDDLMT) ) break;
00336
00337 mdb = (unsigned long)(*pD)<<16;
00338 pT = pD++;
00339
00340 if(*pD == DB_ESCCHAR) pD++;
00341 else if( (*pD==DB_RECDLMT) ||(*pD==DB_FLDDLMT) ) break;
00342
00343 mdb |= (unsigned long)(*pD);
00344
00345 if( mdb == childMdb)
00346 {
00347 *pT = 0;
00348 *pD = 0;
00349 }
00350
00351 pD++;
00352 }
00353
00354 return TRUE;
00355 }
00356
00357
00358 #pragma CODE_SECTION(DB_queryFirst, ".sram0_resident")
00377 DB_HDL DB_queryFirst( DB_ID id,
00378 DB_FIELDIDX fldIdx,
00379 DB_ENTRY fldEntry,
00380 DB_ENTRY dbEntry,
00381 DB_DATA * pData)
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
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
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
00411 node = &DB_idtree.node[id];
00412
00413
00414
00415 if(pInfo->bVirtual == TRUE)
00416 {
00417
00418 node = node->parent;
00419 return( _query(node->id, dbEntry, pData, hdl) );
00420 }
00421
00422
00423
00424 if( (fldIdx == 0)||(fldIdx == 0xffff) )
00425 {
00426
00427 return( _query(id, dbEntry, pData, hdl) );
00428 }
00429
00430
00431
00432
00433
00434 if( fldIdx >= pInfo->numOfKeys )
00435 {
00436 pCtl->free = TRUE;
00437 return DB_INVALID_HDL;
00438 }
00439
00440
00441 node = node->child;
00442 for(ii = 0; ii < fldIdx; ii++ ) node = node->next;
00443
00444 tmpid = node->id;
00445
00446
00447 hdl = _query(tmpid, fldEntry, pData, hdl);
00448 if(hdl == DB_INVALID_HDL) return hdl;
00449
00450
00451
00452
00453 FAT_fclose(pCtl->dbfile);
00454
00455
00456 FAT_fclose(pCtl->idxfile);
00457
00458
00459
00460 pCtl->dbfile = FAT_fopen(DB__name(id, MDB), rb);
00461
00462
00463 pCtl->idxfile = FAT_fopen(DB__name(tmpid, PAI), rb);
00464
00465 if( pCtl->pai == 0)
00466 {
00467
00468 pCtl->free = TRUE;
00469
00470 FAT_fclose(pCtl->idxfile);
00471 FAT_fclose(pCtl->dbfile);
00472 return DB_INVALID_HDL;
00473 }
00474
00475
00476 pCtl->step = 1;
00477
00478
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
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
00497
00498
00499
00500
00501
00502
00503 pCtl->idx -= 2;
00504 #endif
00505
00506
00507 FAT_fseek(pCtl->idxfile, pCtl->idx + (dbEntry << 1), SEEK_HEAD);
00508 FAT_fread(pCtl->idxfile, (unsigned short *)&pCtl->pai, 2);
00509
00510
00511 FAT_fseek(pCtl->dbfile, pCtl->pai, SEEK_HEAD);
00512
00513
00514 if( DB__getRecord(pCtl->dbfile, pData) == FALSE )
00515 {
00516
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 }
00525
00526 #pragma CODE_SECTION(DB_queryNext, ".db_code")
00539 BOOL DB_queryNext(DB_HDL hdl, DB_ENTRY entry, DB_DATA * pData)
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
00549 if( mdb == 0 ) return FALSE;
00550
00551
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 }
00562
00563
00564 #pragma CODE_SECTION(DB_queryClose, ".db_code")
00574 BOOL DB_queryClose(DB_HDL hdl)
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 }
00589
00590
00591 #pragma CODE_SECTION(_query, ".db_code")
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606 static DB_HDL _query(DB_ID id, DB_ENTRY dbEntry, DB_DATA * pData, DB_HDL hdl)
00607 {
00608 DB_MDBOFFSET mdb;
00609 USHORT * pD = (USHORT*)pData;
00610 unsigned short entryNum;
00611 unsigned short ii;
00612 unsigned long signature;
00613 st_DBQUERYCTL * pCtl;
00614 st_DBINFO * pInfo;
00615
00616 pCtl = &DB_qctl[hdl];
00617 pInfo = &DB_qinfo[hdl];
00618
00619
00620 pCtl->step = 2;
00621
00622
00623
00624 if(DB__cdDBdir(DB__name(DB__rootID(id), MDB)) == FALSE)
00625 {
00626 pCtl->free = TRUE;
00627 return DB_INVALID_HDL;
00628 }
00629
00630
00631
00632 pCtl->idxfile = FAT_fopen(DB__name(id, SAI), rb);
00633
00634
00635 FAT_fread(pCtl->idxfile, (unsigned short *)&signature, 2);
00636
00637 if( signature != DB_SAI_SIGNATURE )
00638 {
00639
00640 pCtl->free = TRUE;
00641 FAT_fclose(pCtl->idxfile);
00642 return DB_INVALID_HDL;
00643 }
00644
00645
00646
00647 FAT_fseek(pCtl->idxfile, DB_SAIENTRYNUMOFFSET, SEEK_HEAD);
00648 FAT_fread(pCtl->idxfile, &entryNum, 1);
00649 pInfo->numOfSAIent = entryNum;
00650 if((long)entryNum <= (long)dbEntry)
00651 {
00652
00653 pCtl->free = TRUE;
00654 FAT_fclose(pCtl->idxfile);
00655 return DB_INVALID_HDL;
00656 }
00657
00658
00659
00660 pCtl->idx = (long)DB_SAIFIRSTENTRY<<2;
00661
00662
00663 FAT_fseek(pCtl->idxfile, (long)(dbEntry + DB_SAIFIRSTENTRY)<<2, SEEK_HEAD);
00664 FAT_fread(pCtl->idxfile, (unsigned short *)&mdb, 2);
00665
00666
00667 FAT_fread(pCtl->idxfile, (unsigned short *)&pCtl->pai, 2);
00668
00669 if( mdb == 0)
00670 {
00671
00672 pCtl->free = TRUE;
00673 FAT_fclose(pCtl->idxfile);
00674 return DB_INVALID_HDL;
00675 }
00676
00677
00678 pCtl->dbfile = FAT_fopen(DB__name(id, MDB), rb);
00679
00680
00681 FAT_fseek(pCtl->dbfile, mdb, SEEK_HEAD);
00682
00683 if(pD)
00684 {
00685 *(USHORT*)pD++ = mdb>>16;
00686 *(USHORT*)pD++ = mdb&0xffff;
00687 }
00688
00689
00690 if( DB__getRecord(pCtl->dbfile, pD) == FALSE )
00691 {
00692
00693 pCtl->free = TRUE;
00694 FAT_fclose(pCtl->idxfile);
00695 FAT_fclose(pCtl->dbfile);
00696 return DB_INVALID_HDL;
00697 }
00698
00699 return hdl;
00700 }
00701
00702
00703 #pragma CODE_SECTION (DB_mount, ".dbinit_code")
00714 DB_ID DB_mount(const DB_FNAME name)
00715 {
00716
00717 if(DB__cdDBdir(name) == FALSE ) return DB_INVALID_ID;
00718
00719 return( DB__register(name, NULL, NULL) );
00720 }
00721
00722 #pragma CODE_SECTION(DB_insertRecord, ".db_code")
00733 BOOL DB_insertRecord(DB_ID id, const DB_DATA * pData)
00734 {
00735 st_DBINFO info;
00736 st_DBDINODE * node;
00737 st_DBDINODE ditree[DB_MAXDBNODES];
00738 DB_ENTRY entry;
00739 DB_PAIOFFSET pai;
00740 DB_MDBOFFSET mdb;
00741 File * dbfile;
00742
00743
00744 if( DB__info(id, &info) == FALSE ) return FALSE;
00745 if( !(info.attribute & DB_ROOT) )
00746 {
00747
00748 return FALSE;
00749 }
00750
00751
00752
00753 ditree[0].parent =
00754 ditree[0].prev = NULL;
00755
00756
00757 _copyTree(ditree, &DB_idtree.node[id]);
00758
00759
00760
00761 _formDataTree(ditree, pData);
00762
00763
00764
00765 if( DB__recordPosition(id, &entry, *(unsigned short **)pData, FALSE) == TRUE )
00766 {
00767
00768 return FALSE;
00769 }
00770
00771
00772
00773 dbfile = FAT_fopen(DB__name(id, MDB), rb);
00774 mdb = dbfile->size;
00775 FAT_fclose(dbfile);
00776
00777
00778
00779 pai = 0L;
00780
00781
00782 DB__addSAIentry(id, entry, mdb, pai);
00783
00784
00785
00786 ditree[0].mdb = mdb;
00787
00788
00789
00790 if( info.numOfKeys > 1)
00791 {
00792
00793 node = ditree[0].child;
00794
00795 while(node->next)
00796 {
00797 _insert2child(node->next);
00798 node = node->next;
00799 }
00800 }
00801
00802
00803
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 }
00811
00812 #pragma CODE_SECTION(_copyTree, ".db_code")
00823 static st_DBDINODE * _copyTree(st_DBDINODE * pDstTree, const st_DBIDNODE * pSrcTree)
00824 {
00825 st_DBDINODE * next = pDstTree + 1;
00826
00827 pDstTree->id = pSrcTree->id;
00828
00829
00830 if ( pSrcTree->child )
00831 {
00832 pDstTree->child = next;
00833 next->parent = pDstTree;
00834 next->prev = NULL;
00835 next = _copyTree(next, pSrcTree->child );
00836 }
00837 else pDstTree->child = NULL;
00838
00839
00840
00841
00842 #ifndef USE_DATABASE_HACKS
00843
00844
00845 if ( pSrcTree->next )
00846 {
00847 pDstTree->next = next;
00848 next->prev = pDstTree;
00849 next->parent = pDstTree->parent;
00850 next = _copyTree(next, pSrcTree->next );
00851 }
00852 else pDstTree->next = NULL;
00853
00854 #else
00855
00856
00857 while ( pSrcTree->next )
00858 {
00859 pDstTree->next = next;
00860 next->prev = pDstTree;
00861 next->parent = pDstTree->parent;
00862
00863 pDstTree = next;
00864
00865 next++;
00866 pSrcTree = pSrcTree->next;
00867
00868
00869
00870
00871
00872
00873
00874
00875
00876
00877
00878
00879
00880 {
00881 pDstTree->id = pSrcTree->id;
00882 pDstTree->child = NULL;
00883 }
00884 }
00885
00886 pDstTree->next = NULL;
00887 #endif
00888
00889 return(next);
00890 }
00891
00892 #pragma CODE_SECTION(_formDataTree, ".db_code")
00904 static const DB_DATA * _formDataTree(st_DBDINODE * pTree, const DB_DATA * pData)
00905 {
00906 unsigned short ** p;
00907
00908 p = (unsigned short **)pData;
00909
00910 pTree->data = *p;
00911 pTree->len = DB__recordLen(*p);
00912
00913 p++;
00914
00915
00916 if ( pTree->child )
00917 {
00918 p = (unsigned short **)_formDataTree(pTree->child->next, p);
00919 }
00920
00921
00922 while( pTree->next )
00923 {
00924 pTree = pTree->next;
00925 pTree->data = *p;
00926 pTree->len = DB__recordLen(*p);
00927
00928 p++;
00929
00930 if(pTree->child)
00931 {
00932 p = (unsigned short **)_formDataTree(pTree->child->next, p);
00933 }
00934 }
00935
00936 return ((const DB_DATA *)p);
00937 }
00938 #pragma CODE_SECTION(DB__compare, ".db_code")
00950 short DB__compare(const DB_DATA * pRecord1, const DB_DATA * pRecord2)
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
01004 p1++;
01005 p2++;
01006 }
01007 }
01008 }
01009
01010 #pragma CODE_SECTION(DB__insert2leaf, ".db_code")
01033 DB_MDBOFFSET DB__insert2leaf( DB_ID id,
01034 DB_ID parentId,
01035 DB_MDBOFFSET parentMdb,
01036 const DB_DATA * pParentRecord,
01037 const DB_DATA * pRecord,
01038 DB_RECLEN len,
01039 BOOL bAlwaysInsert)
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
01067 if( DB__recordPosition(id, &entry, pRecord, FALSE) == FALSE)
01068 {
01069
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
01077 leafPai = _createPAIentry(id, parentMdb);
01078
01079
01080 DB__addSAIentry(id, entry, leafMdb, leafPai);
01081
01082 return leafMdb;
01083 }
01084
01085
01086
01087
01088
01089
01090
01091
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
01101 leafPai = _createPAIentry(id, parentMdb);
01102
01103
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
01114
01115
01116 if( bAlwaysInsert == FALSE )
01117 {
01118
01119 if( _checkPAI(id, leafPai, parentMdb) )
01120 {
01121
01122 return leafMdb;
01123 }
01124 }
01125
01126
01127
01128
01129
01130
01131
01132 idxfile = FAT_fopen(DB__name(id, PAI), r_b);
01133
01134
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
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155 for(ii = 0; ii < DB_MINPAILEN; ii++) buf.pai.clear[ii] = 0;
01156
01157 newPaiStart = idxfile->size;
01158
01159
01160
01161
01162 if(newPaiStart == leafPai - sizeof(st_DBPAICTL) + control.dlen)
01163 {
01164
01165 control.dlen += DB_MINPAILEN;
01166
01167
01168 FAT_fseek(idxfile, -(long)sizeof(st_DBPAICTL), SEEK_MID);
01169 FAT_fwrite(idxfile, (unsigned short *)&control.dlen, 1);
01170
01171
01172
01173 FAT_fseek(idxfile, newPaiStart, SEEK_HEAD);
01174 FAT_fwrite(idxfile, buf.pai.clear, DB_MINPAILEN);
01175 }
01176
01177 else
01178 {
01179
01180
01181
01182
01183 paiOffset =
01184 newPai = newPaiStart + sizeof(st_DBPAICTL);;
01185
01186 FAT_fseek(idxfile, leafPai - sizeof(st_DBPAICTL), SEEK_HEAD);
01187
01188
01189 FAT_fread(idxfile, buf.pai.pai, DB_MINPAILEN);
01190 FAT_fseek(idxfile, (long)(-DB_MINPAILEN), SEEK_MID);
01191
01192
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
01201 buf.pai.clear[0] = 0;
01202 buf.pai.clear[1] = 0;
01203
01204
01205
01206 buf.pai.pai[0] = control.dlen + DB_MINPAILEN;
01207
01208
01209 moduleLen = buf.pai.pai[0];
01210
01211
01212
01213
01214
01215
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
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
01254 control.dlen = (unsigned short)moduleLen;
01255
01256
01257
01258 idxfile = FAT_fopen(DB__name(id, PAI), r_b);
01259 }
01260 }
01261
01262
01263
01264
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
01272 if( bAlwaysInsert == FALSE )
01273 {
01274
01275 dbfile = FAT_fopen(DB__name(parentId, MDB), rb);
01276
01277
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;
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 }
01308
01309 #pragma CODE_SECTION(DB__addChildIdx, ".db_code")
01322 BOOL DB__addChildIdx(DB_DATA * pRecord,
01323 DB_FIELDIDX fldidx,
01324 DB_MDBOFFSET childMdb)
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
01386 memmove( pD+ii, pD, len-(pD -(unsigned short *)pRecord)+1);
01387 pS = buf;
01388 while(ii--) *pD++ = *pS++;
01389
01390 return TRUE;
01391 }
01392
01393 #pragma CODE_SECTION(_insert2child, ".db_code")
01402 static BOOL _insert2child(st_DBDINODE * node)
01403 {
01404 DB_MDBOFFSET childMdb;
01405 DB_ENTRY entry;
01406 DB_FIELDIDX fldidx;
01407 st_DBDINODE * tmpNode;
01408 File * file;
01409
01410 if(node->child)
01411 {
01412
01413
01414
01415 if( DB__recordPosition(node->id, &entry, node->data, FALSE) == TRUE )
01416 {
01417
01418 file = FAT_fopen(DB__name(node->id, SAI), rb);
01419 FAT_fseek(file, (long)entry<<2, SEEK_HEAD);
01420 FAT_fread(file, (unsigned short *)&node->mdb, 2);
01421 FAT_fclose(file);
01422 }
01423 else
01424 {
01425
01426 file = FAT_fopen(DB__name(node->id, MDB), rb);
01427
01428
01429 node->mdb = file->size;
01430 FAT_fclose(file);
01431 }
01432
01433 tmpNode = node->child;
01434
01435 while(tmpNode->next)
01436 {
01437 _insert2child(tmpNode->next);
01438 tmpNode = tmpNode->next;
01439 }
01440
01441
01442 childMdb = DB__insert2leaf( node->id,
01443 node->parent->id,
01444 node->parent->mdb,
01445 node->parent->data,
01446 node->data,
01447 node->len,
01448 FALSE);
01449
01450 fldidx = DB__fieldIndex(node->id);
01451
01452
01453 DB__addChildIdx(node->parent->data, fldidx, childMdb);
01454 }
01455 else
01456 {
01457
01458 childMdb = DB__insert2leaf( node->id,
01459 node->parent->id,
01460 node->parent->mdb,
01461 node->parent->data,
01462 node->data,
01463 node->len,
01464 FALSE);
01465
01466 fldidx = DB__fieldIndex(node->id);
01467
01468
01469
01470 DB__addChildIdx(node->parent->data, fldidx, childMdb);
01471
01472
01473 node->parent->len = DB__recordLen(node->parent->data);
01474 }
01475
01476 return TRUE;
01477 }
01478
01479
01480 #pragma CODE_SECTION(DB_init, ".dbinit_code")
01487 BOOL DB_init(void)
01488 {
01489 unsigned short ii;
01490
01491
01492 for ( ii = 0; ii < DB_MAX_ID; ii++ ) DB_registration[ii].fname = NULL;
01493
01494
01495 DB_idtree.counter = 0;
01496
01497
01498 for( ii = 0; ii < DB_OPENMAX; ii++ ) DB_qctl[ii].free = TRUE;
01499
01500
01501
01502
01503 return TRUE;
01504 }
01505
01506
01507 #pragma CODE_SECTION(DB_info, ".db_code")
01508 #if 1
01517 st_DBINFO * DB_info(DB_HDL hdl)
01518 {
01519 return(&DB_qinfo[hdl]);
01520 }
01521
01522 #else
01533 BOOL DB_info(DB_ID id, st_DBINFO * pInfo)
01534 {
01535 File * file;
01536
01537 pInfo->id = id;
01538
01539
01540 if( DB_registration[id].fname == NULL )
01541 {
01542 pInfo->bVirtual = TRUE;
01543
01544
01545 id = DB_idtree.node[id].parent->id;
01546 }
01547 else pInfo->bVirtual = FALSE;
01548
01549
01550 if( DB__info(id, pInfo) == TRUE )
01551 {
01552
01553 if( (file = FAT_fopen(DB__name(id, SAI), rb) ) == NULL ) return FALSE;
01554
01555 FAT_fseek(file, DB_SAIENTRYNUMOFFSET, SEEK_HEAD);
01556 FAT_fread(file, &pInfo->numOfSAIent, 1);
01557 FAT_fclose(file);
01558 return TRUE;
01559 }
01560 else return FALSE;
01561 }
01562 #endif
01563
01564
01565 #pragma CODE_SECTION(DB__info, ".db_code")
01577 BOOL DB__info(DB_ID id, st_DBINFO * pInfo)
01578 {
01579 File * file;
01580 st_DBHEADER header;
01581 unsigned long signature;
01582
01583 #if 1
01584 pInfo->id = id;
01585
01586
01587 if( DB_registration[id].fname == NULL )
01588 {
01589 pInfo->bVirtual = TRUE;
01590
01591
01592 id = DB_idtree.node[id].parent->id;
01593 }
01594 else pInfo->bVirtual = FALSE;
01595 #endif
01596
01597
01598
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
01610 if( signature != DB_HEADER_SIGNATURE ) RETURN_ERROR;
01611
01612
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 }
01623
01624 #pragma CODE_SECTION(DB_childID, ".db_code")
01635 DB_ID DB_childID(DB_ID rootID, DB_FIELDIDX fldIdx)
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 }
01649
01650 #pragma CODE_SECTION(DB_parentID, ".db_code")
01659 DB_ID DB_parentID(DB_ID id)
01660 {
01661 st_DBIDNODE * node;
01662
01663 node = &DB_idtree.node[id];
01664
01665
01666 if(node->parent) node = node->parent;
01667
01668 return node->id;
01669 }
01670
01671 #pragma CODE_SECTION(DB__rootID, ".db_code")
01680 DB_ID DB__rootID(DB_ID id)
01681 {
01682 st_DBIDNODE * node;
01683
01684 node = &DB_idtree.node[id];
01685
01686
01687 while(node->parent) node = node->parent;
01688
01689 return node->id;
01690 }
01691
01692 #pragma CODE_SECTION(DB_getSaiByMdb, ".db_code")
01703 DB_ENTRY DB_getSaiByMdb(ULONG mdb, DB_ID id)
01704 {
01705 File * idxfile;
01706 unsigned long signature;
01707 DB_ENTRY entry;
01708 unsigned short entryNum;
01709 ULONG mdbEnt[2];
01710
01711
01712 if(DB__cdDBdir(DB__name(DB__rootID(id), MDB)) == FALSE)
01713 {
01714 return DB_INVALID_ENTRY;
01715 }
01716
01717
01718
01719 idxfile = FAT_fopen(DB__name(id, SAI), rb);
01720
01721
01722 FAT_fread(idxfile, (unsigned short *)&signature, 2);
01723
01724 if( signature != DB_SAI_SIGNATURE )
01725 {
01726
01727 FAT_fclose(idxfile);
01728 return DB_INVALID_ENTRY;
01729 }
01730
01731
01732
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 }
01752
01753 #pragma CODE_SECTION(DB_getMdbByRecord, ".db_code")
01763 DB_MDBOFFSET DB_getMdbByRecord(DB_ID id, const unsigned short * pData)
01764 {
01765 unsigned short field[DB_MAXFIELDLEN];
01766 DB_ENTRY entry;
01767 DB_MDBOFFSET offset;
01768 File * idxfile;
01769 File * dbfile;
01770
01771 if(DB__cdDBdir(DB__name(DB__rootID(id), MDB)) == FALSE) return 0;
01772
01773
01774 idxfile = FAT_fopen(DB__name(id, SAI), rb);
01775 dbfile = FAT_fopen(DB__name(id, MDB), rb);
01776
01777
01778
01779 entry = DB_SAIFIRSTENTRY;
01780
01781
01782
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
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
01807 FAT_fclose(idxfile);
01808 FAT_fclose(dbfile);
01809
01810 return offset;
01811 }
01812 }
01813
01814 entry++;
01815
01816
01817 FAT_fseek(idxfile, 2, SEEK_MID);
01818 FAT_fread(idxfile, (unsigned short *)&offset, 2);
01819 }
01820
01821
01822
01823 FAT_fclose(idxfile);
01824 FAT_fclose(dbfile);
01825
01826
01827 return 0L;
01828 }
01829 #pragma CODE_SECTION(DB_getField, ".db_code")
01845
01846 DB_FIELDLEN DB_getField( const DB_DATA * pRecord,
01847 DB_FIELDIDX fldIdx,
01848 DB_DATA * pData,
01849 st_DBINFO * pInfo)
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
01866
01867
01868
01870 childMdb = ((unsigned long)(*(unsigned short *)pData)<<16)|(*((unsigned short *)pData+1));
01871
01872
01873
01874
01875
01876
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
01885 file = FAT_fopen(DB__name(tmpid, MDB), rb);
01886
01887
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 }
01895
01896
01897 #pragma CODE_SECTION(DB__getField, ".db_code")
01911 DB_FIELDLEN DB__getField( const DB_DATA * pRecord,
01912 DB_FIELDIDX fldIdx,
01913 DB_DATA * pData)
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
01923 return 0;
01924 }
01925
01926
01927 if( (*pSrc == DB_RECDLMT)||(*pSrc == DB_FLDDLMT) )
01928 {
01929
01930 return 0;
01931 }
01932
01933
01934 pDst = (unsigned short *)pData;
01935
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 }
01952
01953 #pragma CODE_SECTION(DB_dspData, ".db_code")
01966 DB_DSPDATALEN DB_dspData(DB_ID id, DB_DSPDATA pData, DB_DSPDATAIDX idx )
01967 {
01968 File * file;
01969 unsigned long pName;
01970 unsigned short len;
01971
01972
01973 if(DB__cdDBdir(DB__name(DB__rootID(id), MDB)) == FALSE) return 0;
01974
01975
01976 if( DB_registration[id].fname == NULL )
01977 {
01978
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 }
01998
01999 #pragma CODE_SECTION(DB_deleteRecord, ".sram0_resident")
02011 BOOL DB_deleteRecord(DB_ID id, DB_ENTRY entry)
02012 {
02013 if(DB__cdDBdir(DB__name(DB__rootID(id), MDB)) == FALSE) return FALSE;
02014 return DB__deleteChildRecord(id, entry);
02015 }
02016
02017 #pragma CODE_SECTION(DB_deleteRecordByMdb, ".db_code")
02029 BOOL DB_deleteRecordByMdb(DB_ID id, DB_MDBOFFSET mdb)
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
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
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 }
02064
02065 #pragma CODE_SECTION(DB__deleteChildRecord, ".db_code")
02079 BOOL DB__deleteChildRecord(DB_ID id, DB_ENTRY entry)
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];
02095
02096
02097
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
02103 FAT_fseek(idxfile, DB_SAIENTRYNUMOFFSET, SEEK_HEAD);
02104 FAT_fread(idxfile, &entryNum, 1);
02105
02106 DB_assert(entryNum, DB__DELETECHILDRECORD);
02107
02108
02109 FAT_fseek(idxfile, -1, SEEK_MID);
02110 entryNum--;
02111 FAT_fwrite(idxfile, &entryNum, 1);
02112
02113
02114 usTmp = (unsigned long)(entryNum - entry)<<2;
02115 FAT_fseek(idxfile, (unsigned long)(entry + DB_SAIFIRSTENTRY) << 2, SEEK_HEAD);
02116 while(usTmp)
02117 {
02118
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
02133 FAT_fwrite(idxfile, (unsigned short *)buf, 4);
02134 FAT_fclose(idxfile);
02135
02136
02137 dbfile = FAT_fopen(DB__name(id, MDB), r_b);
02138
02139
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
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
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
02176
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
02189
02190 if(pai) DB__removePAIentry(childID, offset, pai, &entryLeft);
02191 }
02192
02193 else continue;
02194
02195
02196
02197 if(pai == 0) continue;
02198
02199 if(entryLeft == 0)
02200 {
02201
02202 FAT_fclose(idxfile);
02203
02204
02205
02206
02207 if(entryNum != 0)
02208 {
02209 DB__deleteChildRecord(childID, entryNum);
02210 }
02211
02212
02213 idxfile = FAT_fopen(DB__name(childID, SAI), rb);
02214 }
02215 }
02216
02217
02218 FAT_fclose(idxfile);
02219 }
02220 }
02221
02222 return TRUE;
02223 }
02224
02225 #pragma CODE_SECTION(_sortSAI, ".db_code")
02234 static void _sortSAI ( unsigned long * pSAI, USHORT numOfSAI )
02235 {
02236
02237 #ifdef USE_DATABASE_HACKS
02238 BOOL bSortPending = TRUE;
02239 USHORT ii;
02240 unsigned long sai;
02241
02242 if( numOfSAI < 2 ) return;
02243
02244 while( bSortPending == TRUE )
02245 {
02246 ii = numOfSAI;
02247 bSortPending = FALSE;
02248
02249 while(ii > 1)
02250 {
02251 ii--;
02252
02253 if( (*(pSAI+ii)) < (*(pSAI+ii-1)) )
02254 {
02255
02256 sai = *(pSAI+ii);
02257 *(pSAI+ii) = *(pSAI+ii-1);
02258 *(pSAI+ii-1) = sai;
02259 bSortPending = TRUE;
02260 }
02261 }
02262 }
02263 #endif
02264 }
02265
02266 #pragma CODE_SECTION (DB_creator, ".dbinit_code")
02276
02277 BOOL DB_creator( BOOL force2create )
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
02289 ret = _createDB((ULONG)AUDIO_MDB_INIT_TABLE, strAUDIO, force2create);
02290
02291
02292 if( ret == TRUE )
02293 {
02294 ret = _createDB((ULONG)PCAUDIO_MDB_INIT_TABLE, strPCAUDIO, force2create);
02295 }
02296
02297
02298 if( ret == TRUE )
02299 {
02300 ret = _createDB((ULONG)IDEDHISI_MDB_INIT_TABLE, strIDEDHISI, force2create);
02301 }
02302
02303
02304 if( ret == TRUE )
02305 {
02306 ret = _createDB((ULONG)UNIDHISI_MDB_INIT_TABLE, strUNIDEDHISI, force2create);
02307 }
02308
02309
02310 if( ret == TRUE )
02311 {
02312 ret = _createDB((ULONG)FAILHISI_MDB_INIT_TABLE, strFAILEDHISI, force2create);
02313 }
02314
02315 return ret;
02316 }
02317
02318
02319 #pragma CODE_SECTION (_createDB, ".dbinit_code")
02333 static BOOL _createDB( ULONG dptr,
02334 const char * name,
02335 BOOL force2create )
02336 {
02337 ULONG addr;
02338 int ii;
02339 int numOfDB;
02340 char dir[22];
02341 char fname[22];
02342 char * pC;
02343 File * file;
02344
02345
02346 ii = strlen(name) - 4;
02347 memcpy(dir, name, ii);
02348 dir[ii] = 0;
02349
02350 if( FAT_cd(dir) == FALSE )
02351 {
02352 if( FAT_mkdir(dir) == FALSE) return FALSE;
02353 if( FAT_cd(dir) == FALSE ) return FALSE;
02354 }
02355
02356 file = FAT_fopen(name, rb);
02357 if( (file == NULL) || ( force2create == TRUE ) )
02358 {
02359 if(file) FAT_fclose(file);
02360
02361
02362 dptr++;
02363
02364 GEN_rdSRAM(dptr++, (USHORT*)&numOfDB, 1);
02365 while(numOfDB--)
02366 {
02367
02368 GEN_readXdata(dptr, (USHORT *)&addr, 2);
02369 dptr += 2;
02370
02371
02372 GEN_readXdata(addr, (USHORT *)fname, 10);
02373
02374
02375 GEN_strUnpack((UINT16 *)fname, 10);
02376
02377
02378 if(_genFile(dptr, fname) == FALSE) return FALSE;
02379
02380 dptr += 4;
02381
02382
02383 ii = strlen(fname);
02384 pC = fname+ii-1;
02385 *pC-- = 'i';
02386 *pC-- = 'a';
02387 *pC = 's';
02388
02389 if(_genFile(dptr, fname) == FALSE) return FALSE;
02390 dptr += 4;
02391
02392
02393 *pC = 'p';
02394
02395 if(_genFile(dptr, fname) == FALSE) return FALSE;
02396 dptr += 4;
02397 }
02398 }
02399
02400 if(file) FAT_fclose(file);
02401
02402
02403 FAT_cd(strDOTDOT);
02404
02405 return TRUE;
02406 }
02407
02408
02409 #pragma CODE_SECTION (_genFile, ".dbinit_code")
02420 static BOOL _genFile( ULONG dptr, const char * name)
02421 {
02422 BOOL ret = TRUE;
02423 File * file;
02424 unsigned short buf[360];
02425 ULONG addr;
02426 int len;
02427
02428
02429 GEN_readXdata(dptr, (USHORT *)&addr, 2);
02430 if(addr == 0) return TRUE;
02431
02432 dptr += 3;
02433
02434
02435 GEN_readXdata(dptr, (USHORT *)&len, 1);
02436
02437 DB_assert(len<360, DB_CREATOR);
02438
02439 file = FAT_fopen(name, wb);
02440 if(file == NULL) return FALSE;
02441
02442 GEN_readXdata(addr, buf, len);
02443 if( FAT_fwrite(file, buf, len) != len ) ret = FALSE;
02444
02445 FAT_fclose(file);
02446 return ret;
02447 }
02448 #pragma CODE_SECTION(DB_add2child, ".db_code")
02461 BOOL DB_add2child( DB_MDBOFFSET rootMdb,
02462 DB_ID childID,
02463 const DB_DATA * childRecord)
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
02479
02480
02481 rootID = DB__rootID(childID);
02482
02483 if(DB__cdDBdir(DB__name(rootID, MDB)) == FALSE) return FALSE;
02484
02485
02486
02487
02488
02489
02490
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
02498
02499
02500
02501
02502
02503
02504
02505
02506
02507
02508
02509
02510 fldidx = DB__fieldIndex(childID);
02511
02512 originalLen = DB__recordLen(record);
02513 childLen = DB__recordLen(childRecord);
02514
02515
02516 childMdb = DB__insert2leaf( childID,
02517 rootID,
02518 rootMdb,
02519 record,
02520 childRecord,
02521 childLen,
02522 TRUE);
02523
02524
02525 DB__addChildIdx(record, fldidx, childMdb);
02526
02527 newLen = DB__recordLen(record);
02528
02529
02530
02531
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
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
02559 FAT_fseek(dbfile, newOffset, SEEK_HEAD);
02560 FAT_fwrite(dbfile, (unsigned short *)record, newLen);
02561 FAT_fclose(dbfile);
02562
02563
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
02578 FAT_fread(idxfile, (unsigned short*)&tmpMdb, 2);
02579 }
02580 FAT_fclose(idxfile);
02581
02582
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 }
02595
02596 #pragma CODE_SECTION(_replacePAI, ".db_code")
02609 static BOOL _replacePAI( DB_ID id,
02610 DB_MDBOFFSET oldOffset,
02611 DB_MDBOFFSET newOffset)
02612 {
02613 DB_MDBOFFSET mdb;
02614 DB_PAIOFFSET offset;
02615 st_DBPAICTL control;
02616 File * idxfile;
02617
02618 idxfile = FAT_fopen(DB__name(id, PAI), r_b);
02619
02620 offset = DB_PAIHEADERLEN;
02621
02622 while(1)
02623 {
02624 FAT_fseek(idxfile, offset, SEEK_HEAD);
02625
02626 if( FAT_fread(idxfile, (unsigned short *)&control, sizeof(st_DBPAICTL)) == 0 ) break;
02627
02628
02629 while(control.entryNum--)
02630 {
02631 FAT_fread(idxfile, (unsigned short *)&mdb, 2);
02632
02633 if(oldOffset == mdb)
02634 {
02635 FAT_fseek(idxfile, -2, SEEK_MID);
02636 FAT_fwrite(idxfile, (unsigned short *)&newOffset, 2);
02637 }
02638 }
02639
02640 offset += control.dlen;
02641 }
02642
02643 FAT_fclose(idxfile);
02644
02645 return TRUE;
02646 }
02647 #pragma CODE_SECTION(DB__removePAIentry, ".db_code")
02662 BOOL DB__removePAIentry( DB_ID id,
02663 DB_MDBOFFSET entry,
02664 DB_PAIOFFSET pai,
02665 unsigned short * pEntryNum)
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
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
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
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 }
02765
02766 #pragma CODE_SECTION (DB__register, ".dbinit_code")
02779 DB_ID DB__register(const DB_FNAME name, st_DBIDNODE * parent, st_DBIDNODE * prev )
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];
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
02804 if( FAT_fread(file, (unsigned short *)&header, sizeof(st_DBHEADER))
02805 != sizeof(st_DBHEADER) ) RETURN_ERROR_DB;
02806
02807
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
02814 #ifdef DB_REGIST2SRAM
02815
02816
02817 ii = strlen(name);
02818 dname = GEN_malloc( ii + 1 );
02819 GEN_wrSRAM(dname, (unsigned short *)name, ii+1);
02820
02821
02822 id = DB_idtree.node[DB_idtree.counter].id = DB_idtree.counter;
02823
02824
02825 if(id >= DB_MAX_ID)
02826 {
02827 SYS_die(DB__REGISTER);
02828 }
02829
02830
02831 DB_registration[id].fname = dname;
02832 DB_registration[id].len = ii;
02833
02834 #else
02835
02836 dname = (DB_FNAME)malloc( strlen(name) + 1 );
02837 strcpy((char *)dname, (char *)name);
02838
02839
02840 id = DB_idtree.node[DB_idtree.counter].id = DB_idtree.counter;
02841
02842
02843 DB_registration[id].fname = dname;
02844 DB_registration[id].len = strlen(dname);
02845 #endif
02846
02847 DB_idtree.counter++;
02848
02849
02850 DB_idtree.node[id].next = NULL;
02851
02852
02853 DB_idtree.node[id].parent = parent;
02854
02855
02856 DB_idtree.node[id].prev = prev;
02857
02858 if( prev ) prev->next = &DB_idtree.node[id];
02859
02860
02861 DB_idtree.node[id].child = NULL;
02862
02863
02864
02865 if(header.numOfKeys > 1 )
02866 {
02867
02868 DB_idtree.node[id].child = &DB_idtree.node[id+1];
02869
02870
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
02880 DB_idtree.node[id+1].next = NULL;
02881
02882
02883 DB_idtree.node[id+1].parent = &DB_idtree.node[id];
02884
02885
02886 DB_idtree.node[id+1].prev = NULL;
02887
02888
02889 DB_idtree.node[id+1].child = NULL;
02890
02891
02892 prevnode = &DB_idtree.node[id+1];;
02893
02894
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
02910 pp += 5;
02911
02912
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
02924 *pC++ = tmp >> 8;
02925
02926 *pC++ = tmp & 0x00FF;
02927
02928 if( (tmp & 0x00FF) == 0 ) break;
02929
02930
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
02944 pp += 2;
02945 }
02946 }
02947 }
02948
02949
02950 FAT_fclose(file);
02951
02952
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 }
02962
02963 #pragma CODE_SECTION(DB__recordPosition, ".db_code")
02979 BOOL DB__recordPosition( DB_ID id,
02980 DB_ENTRY * pPosition,
02981 const DB_DATA * pRecord,
02982 BOOL bIgnoreRule )
02983 {
02984 unsigned short field[DB_MAXFIELDLEN];
02985 DB_ENTRY entry;
02986 DB_MDBOFFSET offset;
02987 short comp;
02988 File * idxfile;
02989 File * dbfile;
02990
02991
02992 idxfile = FAT_fopen(DB__name(id, SAI), rb);
02993 dbfile = FAT_fopen(DB__name(id, MDB), rb);
02994
02995
02996
02997 entry = DB_SAIFIRSTENTRY;
02998
02999
03000
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
03010 comp = DB__compare(field, (unsigned short *)pRecord );
03011
03012 if( comp == 0)
03013 {
03014
03015 FAT_fclose(idxfile);
03016 FAT_fclose(dbfile);
03017
03018 *pPosition = entry;
03019 return TRUE;
03020 }
03021 else if (comp < 0)
03022 {
03023
03024
03025
03026
03027
03028 entry++;
03029
03030
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
03043 FAT_fseek(idxfile, 2, SEEK_MID);
03044 FAT_fread(idxfile, (unsigned short *)&offset, 2);
03045 }
03046 }
03047 }
03048
03049
03050
03051 FAT_fclose(idxfile);
03052 FAT_fclose(dbfile);
03053
03054
03055
03056 *pPosition = entry;
03057
03058 return FALSE;
03059 }
03060
03061 #pragma CODE_SECTION(DB__recordLen, ".db_code")
03070 DB_RECLEN DB__recordLen(const DB_DATA * pRecord)
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 }
03090
03091 #pragma CODE_SECTION(DB__name, ".db_code")
03101 DB_FNAME DB__name(DB_ID id, DB_FEXTNAME ext)
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 }
03140 #pragma CODE_SECTION(DB__locateField, ".db_code")
03151 DB_DATA * DB__locateField(const DB_DATA * pRecord, DB_FIELDIDX fldIdx)
03152 {
03153
03154 const unsigned short * pSrc;
03155 unsigned short count;
03156
03157 count = 0;
03158
03159
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
03171 return NULL;
03172 }
03173
03174 if(*pSrc == DB_FLDDLMT)
03175 {
03176
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 }
03192
03193
03194 #pragma CODE_SECTION(_checkPAI, ".db_code")
03208 static DB_PAIOFFSET _checkPAI( DB_ID id,
03209 DB_PAIOFFSET pai,
03210 DB_MDBOFFSET mdb )
03211 {
03212
03213 DB_PAIOFFSET matchPai;
03214 DB_MDBOFFSET matchMdb;
03215 File * idxfile;
03216
03217 matchPai = pai;
03218
03219 idxfile = FAT_fopen(DB__name(id, PAI), rb);
03220 FAT_fseek(idxfile, pai, SEEK_HEAD);
03221 FAT_fread(idxfile, (unsigned short *)&matchMdb, 2);
03222
03223 while(matchMdb)
03224 {
03225 if(matchMdb == mdb)
03226 {
03227 FAT_fclose(idxfile);
03228 return matchPai;
03229 }
03230 else matchPai += 2;
03231
03232 FAT_fread(idxfile, (unsigned short *)&matchMdb, 2);
03233 }
03234
03235 FAT_fclose(idxfile);
03236
03237
03238 return 0L;
03239 }
03240
03241 #pragma CODE_SECTION(_createPAIentry, ".db_code")
03252 static DB_PAIOFFSET _createPAIentry( DB_ID id,
03253 DB_MDBOFFSET parentMdb )
03254 {
03255 File * file;
03256 unsigned long offset;
03257 unsigned short tmp[DB_MINPAILEN];
03258 unsigned short len;
03259 unsigned short flag;
03260 unsigned short ii;
03261
03262 file = FAT_fopen(DB__name(id, PAI), r_b);
03263
03264 offset = (long)DB_PAIHEADERLEN;
03265
03266
03267 while(1)
03268 {
03269
03270 FAT_fseek(file, offset, SEEK_HEAD);
03271
03272 if(FAT_fread(file, &len, 1) == 0)
03273 {
03274
03275 break;
03276 }
03277
03278 FAT_fread(file, &flag, 1);
03279 if( flag & PAI_FREE)
03280 {
03281
03282
03283
03284 flag &= ~PAI_FREE;
03285
03286 FAT_fseek(file, -1, SEEK_MID);
03287 FAT_fwrite(file, &flag, 1);
03288
03289
03290 tmp[0] = 1;
03291
03292 FAT_fwrite(file, tmp, 1);
03293
03294
03295
03296
03297 FAT_fseek(file, 3, SEEK_MID);
03298
03299
03300 FAT_fwrite(file, (unsigned short *)&parentMdb, 2);
03301 FAT_fclose(file);
03302
03303 return (offset + sizeof(st_DBPAICTL));
03304 }
03305 offset += len;
03306 }
03307
03308
03309
03310 FAT_fseek(file, offset, SEEK_HEAD);
03311
03312
03313
03314 for( ii = 0; ii < DB_MINPAILEN; ii++) tmp[ii] = 0;
03315
03316 tmp[0] = DB_MINPAILEN;
03317
03318 tmp[2] = 1;
03319
03320 tmp[sizeof(st_DBPAICTL)] = (unsigned short)((long)parentMdb >> 16);
03321
03322 tmp[sizeof(st_DBPAICTL) + 1] = (unsigned short)(parentMdb & 0xFFFF);
03323
03324 FAT_fwrite(file, tmp, DB_MINPAILEN);
03325 FAT_fclose(file);
03326
03327 return (offset + sizeof(st_DBPAICTL));
03328 }
03329
03330 #pragma CODE_SECTION(DB__getRecord, ".db_code")
03343 BOOL DB__getRecord(File * file, DB_DATA * pData)
03344 {
03345 unsigned short * p;
03346 unsigned short len;
03347
03348
03349 if(pData == NULL) return TRUE;
03350
03351
03352
03353
03354 p = (unsigned short *)pData;
03355 len = FAT_fread(file, p, DB_MAXRECLEN/2);
03356
03357
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
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
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 }
03387
03388 #pragma CODE_SECTION(DB__fieldIndex, ".db_code")
03396 DB_FIELDIDX DB__fieldIndex(DB_ID id)
03397 {
03398 st_DBIDNODE * node;
03399 DB_FIELDIDX fldidx;
03400
03401 fldidx = 0;
03402 node = &DB_idtree.node[id];
03403
03404
03405 while(node->prev)
03406 {
03407 fldidx++;
03408 node = node->prev;
03409 }
03410
03411 return fldidx;
03412 }
03413
03414 #pragma CODE_SECTION(DB__cdDBdir, ".db_code")
03423 BOOL DB__cdDBdir(const DB_FNAME name)
03424 {
03425 char dir[DB_MAXLFN];
03426 char * pD = &dir[0];
03427 const char * pC = name;
03428
03429
03430 FAT_cd(strDISKD);
03431
03432
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 }
03443
03444 #pragma CODE_SECTION(DB__addSAIentry, ".db_code")
03459 BOOL DB__addSAIentry(DB_ID id,
03460 DB_ENTRY entry,
03461 DB_MDBOFFSET mdb,
03462 DB_PAIOFFSET pai)
03463 {
03464
03465 unsigned long offset[2];
03466 unsigned long fsize;
03467 unsigned short entryNum;
03468 File * idxfile;
03469
03470
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
03484 offset[0] = mdb;
03485 offset[1] = pai;
03486
03487
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 }
03507
03508