static INT_PTR AddContact(WPARAM wParam,LPARAM lParam) { struct DBContact dbc; DWORD ofsNew; log0("add contact"); EnterCriticalSection(&csDbAccess); ofsNew=CreateNewSpace(sizeof(struct DBContact)); dbc.signature=DBCONTACT_SIGNATURE; dbc.eventCount=0; dbc.ofsFirstEvent=dbc.ofsLastEvent=0; dbc.ofsFirstSettings=0; dbc.ofsNext=dbHeader.ofsFirstContact; dbc.ofsFirstUnreadEvent=0; dbc.timestampFirstUnread=0; dbHeader.ofsFirstContact=ofsNew; dbHeader.contactCount++; DBWrite(ofsNew,&dbc,sizeof(struct DBContact)); DBWrite(0,&dbHeader,sizeof(dbHeader)); DBFlush(0); AddToCachedContactList((HANDLE)ofsNew, -1); LeaveCriticalSection(&csDbAccess); NotifyEventHooks(hContactAddedEvent,(WPARAM)ofsNew,0); return (INT_PTR)ofsNew; }
STDMETHODIMP_(MCONTACT) CDb3Mmap::AddContact() { DWORD ofsNew; log0("add contact"); DBContact dbc = { 0 }; dbc.signature = DBCONTACT_SIGNATURE; { mir_cslock lck(m_csDbAccess); ofsNew = CreateNewSpace(sizeof(DBContact)); dbc.ofsNext = m_dbHeader.ofsFirstContact; dbc.dwContactID = m_dwMaxContactId++; m_dbHeader.ofsFirstContact = ofsNew; m_dbHeader.contactCount++; DBWrite(ofsNew, &dbc, sizeof(DBContact)); DBWrite(0, &m_dbHeader, sizeof(m_dbHeader)); DBFlush(0); } DBCachedContact *cc = m_cache->AddContactToCache(dbc.dwContactID); cc->dwDriverData = ofsNew; NotifyEventHooks(hContactAddedEvent, dbc.dwContactID, 0); return dbc.dwContactID; }
void DeleteSpace(DWORD ofs,int bytes) { PBYTE buf; log2("deletespace %d@%08x",bytes,ofs); dbHeader.slackSpace+=bytes; DBWrite(0,&dbHeader,sizeof(dbHeader)); buf=(PBYTE)mir_alloc(bytes); memset(buf,0,bytes); DBWrite(ofs,buf,bytes); mir_free(buf); }
STDMETHODIMP_(BOOL) CDb3Mmap::MarkEventRead(MCONTACT contactID, HANDLE hDbEvent) { DBCachedContact *cc; if (contactID) { if ((cc = m_cache->GetCachedContact(contactID)) == NULL) return -1; if (cc->IsSub()) if ((cc = m_cache->GetCachedContact(cc->parentID)) == NULL) return -1; } else cc = NULL; mir_cslockfull lck(m_csDbAccess); DWORD ofsContact = (cc) ? cc->dwDriverData : m_dbHeader.ofsUser; DBContact dbc = *(DBContact*)DBRead(ofsContact, sizeof(DBContact), NULL); DBEvent *dbe = (DBEvent*)DBRead((DWORD)hDbEvent, sizeof(DBEvent), NULL); if (dbe->signature != DBEVENT_SIGNATURE || dbc.signature != DBCONTACT_SIGNATURE) return -1; if (dbe->markedRead()) return dbe->flags; // log1("mark read @ %08x", hContact); dbe->flags |= DBEF_READ; DBWrite((DWORD)hDbEvent, dbe, sizeof(DBEvent)); BOOL ret = dbe->flags; if (dbc.ofsFirstUnread == (DWORD)hDbEvent) { for (;;) { if (dbe->ofsNext == 0) { dbc.ofsFirstUnread = 0; dbc.tsFirstUnread = 0; break; } DWORD ofsThis = dbe->ofsNext; dbe = (DBEvent*)DBRead(ofsThis, sizeof(DBEvent), NULL); if (!dbe->markedRead()) { dbc.ofsFirstUnread = ofsThis; dbc.tsFirstUnread = dbe->timestamp; break; } } } DBWrite(ofsContact, &dbc, sizeof(DBContact)); DBFlush(0); lck.unlock(); NotifyEventHooks(hEventMarkedRead, contactID, (LPARAM)hDbEvent); return ret; }
void EncodeDBWrite(DWORD ofs, void * src, size_t size) { if(bEncoding) { BYTE * buf; buf = (BYTE*)GlobalAlloc(GPTR, sizeof(BYTE)*size); EncodeCopyMemory(buf, src, size); DBWrite(ofs, buf, (int)size); GlobalFree(buf); } else { DBWrite(ofs, src, (int)size); } }
// will create the offset if it needs to DWORD CDb3Mmap::GetModuleNameOfs(const char *szName) { DWORD ofsExisting = FindExistingModuleNameOfs(szName); if (ofsExisting) return ofsExisting; if (m_bReadOnly) return 0; int nameLen = (int)mir_strlen(szName); // need to create the module name DWORD ofsNew = CreateNewSpace(nameLen + offsetof(struct DBModuleName, name)); DBModuleName dbmn; dbmn.signature = DBMODULENAME_SIGNATURE; dbmn.cbName = nameLen; dbmn.ofsNext = m_dbHeader.ofsModuleNames; m_dbHeader.ofsModuleNames = ofsNew; DBWrite(ofsNew, &dbmn, offsetof(struct DBModuleName, name)); DBWrite(ofsNew + offsetof(struct DBModuleName, name), (PVOID)szName, nameLen); DBWrite(0, &m_dbHeader, sizeof(m_dbHeader)); DBFlush(0); // add to cache char *mod = (char*)HeapAlloc(m_hModHeap, 0, nameLen + 1); mir_strcpy(mod, szName); AddToList(mod, ofsNew); // quit return ofsNew; }
//will create the offset if it needs to DWORD GetModuleNameOfs(const char *szName) { struct DBModuleName dbmn; int nameLen; DWORD ofsNew,ofsExisting; char *mod; ofsExisting=FindExistingModuleNameOfs(szName); if(ofsExisting) return ofsExisting; nameLen = (int)strlen(szName); //need to create the module name ofsNew=CreateNewSpace(nameLen+offsetof(struct DBModuleName,name)); dbmn.signature=DBMODULENAME_SIGNATURE; dbmn.cbName=nameLen; dbmn.ofsNext=dbHeader.ofsFirstModuleName; dbHeader.ofsFirstModuleName=ofsNew; DBWrite(0,&dbHeader,sizeof(dbHeader)); DBWrite(ofsNew,&dbmn,offsetof(struct DBModuleName,name)); DBWrite(ofsNew+offsetof(struct DBModuleName,name),(PVOID)szName,nameLen); DBFlush(0); //add to cache mod = (char*)HeapAlloc(hModHeap,0,nameLen+1); strcpy(mod,szName); AddToList(mod, nameLen, ofsNew); //quit return ofsNew; }
/*------------------------------------------------------------------------- * Function: test_write_bad * * Purpose: Try writing to an existing data but using an incompatible * size or data type. * * Return: Success: 0 * * Failure: number of errors. * * Programmer: Robb Matzke * Tuesday, February 9, 1999 * * Modifications: * Robb Matzke, 2000-01-12 * Changed hyphens to underscores in object names because silo * now fails when underscores are present in the name. *------------------------------------------------------------------------- */ static int test_write_bad(DBfile *dbfile) { int i, data[TEST_NELMTS], dims[4], nerrors=0; #ifdef HAVE_HDF5_H H5E_BEGIN_TRY { #endif puts("=== Error conditions ==="); for (i=0; i<TEST_NELMTS; i++) data[i] = 911; /* Write to "3d_int" but supply only 1 dimension */ dims[0] = TEST_NELMTS; if (DBWrite(dbfile, "3d_int", data, dims, 1, DB_INT)>=0) { puts("DBWrite() to 3d_int with 1d data should have failed"); nerrors++; } /* Write to "3d_int" but with the wrong sizes */ dims[0] = 3; dims[2] = 4; dims[1] = TEST_NELMTS/(dims[0]*dims[2]); if (DBWrite(dbfile, "3d_int", data, dims, 3, DB_INT)>=0) { puts("DBWrite() to 3d_int with wrong dims should have faild"); nerrors++; } /* Write to "4d_float" but with integer data */ DBForceSingle(TRUE); dims[0] = 6; dims[1] = 5; dims[2] = 4; dims[3] = TEST_NELMTS/(dims[0]*dims[1]*dims[2]); if (DBWrite(dbfile, "4d_float", data, dims, 4, DB_INT)>=0) { puts("DBWrite() to 4d_float with integer data should have failed"); nerrors++; } DBForceSingle(FALSE); #ifdef HAVE_HDF5_H } H5E_END_TRY; #endif return nerrors; }
DWORD CDb3Base::CreateNewSpace(int bytes) { DWORD ofsNew = m_dbHeader.ofsFileEnd; m_dbHeader.ofsFileEnd += bytes; DBWrite(0, &m_dbHeader, sizeof(m_dbHeader)); log2("newspace %d@%08x", bytes, ofsNew); return ofsNew; }
void CDb3Mmap::ConvertEvents() { DBContact dbc = *(DBContact*)DBRead(m_dbHeader.ofsUser, sizeof(DBContact), NULL); ConvertContactEvents(&dbc); DBWrite(m_dbHeader.ofsUser, &dbc, sizeof(dbc)); for (DWORD dwOffset = m_dbHeader.ofsFirstContact; dwOffset != 0;) { DBContact dbc = *(DBContact*)DBRead(dwOffset, sizeof(DBContact), NULL); ConvertContactEvents(&dbc); DBWrite(dwOffset, &dbc, sizeof(dbc)); if (m_contactsMap.find((ConvertedContact*)&dbc.dwContactID) == NULL) m_contactsMap.insert(new ConvertedContact(dwOffset, dbc.dwContactID)); dwOffset = dbc.ofsNext; } FlushViewOfFile(m_pDbCache, 0); }
DWORD CDb3Mmap::CreateNewSpace(int bytes) { DWORD ofsNew = m_dbHeader.ofsFileEnd; m_dbHeader.ofsFileEnd += bytes; if (m_dbHeader.ofsFileEnd > m_dwFileSize) ReMap(m_dbHeader.ofsFileEnd - m_dwFileSize); DBWrite(0, &m_dbHeader, sizeof(m_dbHeader)); log2("newspace %d@%08x", bytes, ofsNew); return ofsNew; }
DWORD CreateNewSpace(int bytes) { DWORD ofsNew; ofsNew=dbHeader.ofsFileEnd; dbHeader.ofsFileEnd+=bytes; DBWrite(0,&dbHeader,sizeof(dbHeader)); log2("newspace %d@%08x",bytes,ofsNew); return ofsNew; }
void DBMoveChunk(DWORD ofsDest,DWORD ofsSource,int bytes) { DWORD bytesRead; PBYTE buf; log3("move %d %08x->%08x",bytes,ofsSource,ofsDest); buf=(PBYTE)mir_alloc(bytes); SetFilePointer(hDbFile,ofsSource,NULL,FILE_BEGIN); ReadFile(hDbFile,buf,bytes,&bytesRead,NULL); DBWrite(ofsDest,buf,bytes); mir_free(buf); logg(); }
void CDb3Mmap::DeleteSpace(DWORD ofs, int bytes) { if (ofs + bytes == m_dbHeader.ofsFileEnd) { log2("freespace %d@%08x", bytes, ofs); m_dbHeader.ofsFileEnd = ofs; } else { log2("deletespace %d@%08x", bytes, ofs); m_dbHeader.slackSpace += bytes; } DBWrite(0, &m_dbHeader, sizeof(m_dbHeader)); DBFill(ofs, bytes); }
void CSchemaItem::SerializeDatabaseItem( ATTRIBUTEIDTODATAMAP &valuesMap, IArchive &ar ) { if( valuesMap.find( m_hszLabel.GetUniqueID() ) == valuesMap.end() || valuesMap[m_hszLabel.GetUniqueID()] == NULL ) { valuesMap[m_hszLabel.GetUniqueID()] = new DATABASEDATA( m_DefaultValue ); } DATABASEDATA *value = valuesMap[m_hszLabel.GetUniqueID()]; TCHAR *tag = (TCHAR*)m_hszLabel.GetString(); if( ar.IsReading() ) { DBRead( value, &ar, tag ); } else { DBWrite( value, &ar, tag ); } }
DWORD CDb3Mmap::ReallocSpace(DWORD ofs, int oldSize, int newSize) { if (oldSize >= newSize) return ofs; DWORD ofsNew; if (ofs + oldSize == m_dbHeader.ofsFileEnd) { ofsNew = ofs; m_dbHeader.ofsFileEnd += newSize - oldSize; DBWrite(0, &m_dbHeader, sizeof(m_dbHeader)); log3("adding newspace %d@%08x+%d", newSize, ofsNew, oldSize); } else { ofsNew = CreateNewSpace(newSize); DBMoveChunk(ofsNew, ofs, oldSize); DeleteSpace(ofs, oldSize); } return ofsNew; }
/*------------------------------------------------------------------------- * Function: test_type_conv * * Purpose: If we call DBWrite() for an existing variable but the memory * data type is different than what was previously registered * then a type conversion should occur. * * Return: Success: 0 * * Failure: number of errors. * * Programmer: Robb Matzke * Tuesday, February 9, 1999 * * Modifications: * Robb Matzke, 2000-01-12 * Changed hyphens to underscores in object names because silo * now fails when underscores are present in the name. *------------------------------------------------------------------------- */ static int test_type_conv(DBfile *dbfile) { char cdata_out[TEST_NELMTS]; int i, dims[3], nerrors=0, idata_in[TEST_NELMTS]; puts("=== Type conversions ==="); /* Initialize output arrays */ for (i=0; i<TEST_NELMTS; i++, cntr_g++) { idata_g[i] = cdata_out[i] = cntr_g%128; } /* Write char data to the 3d_int array */ puts("DBWrite()"); puts(" 3d_int"); dims[0] = 12; dims[1] = 30; dims[2] = TEST_NELMTS/(dims[0]*dims[1]); if (DBWrite(dbfile, "3d_int", cdata_out, dims, 3, DB_CHAR)<0) { puts(" failed"); nerrors++; } /* Read integer data back out */ puts("DBRead()"); puts(" 3d_int"); memset(idata_in, 0xff, sizeof idata_in); if (DBReadVar(dbfile, "3d_int", idata_in)<0) { puts(" failed"); nerrors++; } else { for (i=0; i<TEST_NELMTS; i++) { if (idata_g[i]!=idata_in[i]) { printf(" failed at i=%d: out=%d, in=%d\n", i, idata_g[i], idata_in[i]); } } } return nerrors; }
void CSchemaItem::Serialize( IArchive &ar ) { if( ar.IsReading() ) { StdString name; // Dummy variable to read the name. It should already be stored as CObjectTemplate StdString type; StdString attributeClass; ar.Read( m_fVersion, _T("Version") ); ar.Read( name, _T("Name") ); ar.Read( type, _T("Type") ); ar.Read( attributeClass, _T("Class") ); m_hszLabel.Init( name ); m_hszType.Init( type ); m_hszClass.Init( attributeClass ); DBRead( &m_DefaultValue, &ar, _T("Default") ); // IMPORTANT: DBRead is dependent on m_hszType. Make sure m_hszType has been initialized before calling DBRead. // NOTE: We are assuming the order in which schema items are instantiated will be // the order in which to read data items. if( m_Schema != NULL ) { m_Schema->RegisterSchemaItem( this ); } } else { ar.StartClass(_T("CSchemaItem")); ar.Write( m_fVersion, _T("Version") ); ar.Write( m_hszLabel.GetString(), _T("Name") ); ar.Write( m_hszType.GetString(), _T("Type") ); ar.Write( m_hszClass.GetString(), _T("Class") ); DBWrite( &m_DefaultValue, &ar, _T("Default") ); ar.EndClass(); } }
static INT_PTR WriteContactSetting(WPARAM wParam, LPARAM lParam) { DBCONTACTWRITESETTING *dbcws=(DBCONTACTWRITESETTING*)lParam; DBCONTACTWRITESETTING tmp; struct DBContact dbc; DWORD ofsModuleName; struct DBContactSettings dbcs; PBYTE pBlob; int settingNameLen=0; int moduleNameLen=0; int settingDataLen=0; int bytesRequired,bytesRemaining; DWORD ofsContact,ofsSettingsGroup,ofsBlobPtr; if (dbcws == NULL || dbcws->szSetting==NULL || dbcws->szModule==NULL ) return 1; // the db format can't tolerate more than 255 bytes of space (incl. null) for settings+module name settingNameLen=(int)strlen(dbcws->szSetting); moduleNameLen=(int)strlen(dbcws->szModule); if ( settingNameLen > 0xFE ) { #ifdef _DEBUG OutputDebugStringA("WriteContactSetting() got a > 255 setting name length. \n"); #endif return 1; } if ( moduleNameLen > 0xFE ) { #ifdef _DEBUG OutputDebugStringA("WriteContactSetting() got a > 255 module name length. \n"); #endif return 1; } tmp = *dbcws; if (tmp.value.type == DBVT_WCHAR) { if (tmp.value.pszVal != NULL) { char* val = mir_utf8encodeW(tmp.value.pwszVal); if ( val == NULL ) return 1; tmp.value.pszVal = ( char* )_malloca( strlen( val )+1 ); strcpy( tmp.value.pszVal, val ); mir_free(val); tmp.value.type = DBVT_UTF8; } else return 1; } if(tmp.value.type!=DBVT_BYTE && tmp.value.type!=DBVT_WORD && tmp.value.type!=DBVT_DWORD && tmp.value.type!=DBVT_ASCIIZ && tmp.value.type!=DBVT_UTF8 && tmp.value.type!=DBVT_BLOB) return 1; if ((!tmp.szModule) || (!tmp.szSetting) || ((tmp.value.type == DBVT_ASCIIZ || tmp.value.type == DBVT_UTF8 )&& tmp.value.pszVal == NULL) || (tmp.value.type == DBVT_BLOB && tmp.value.pbVal == NULL) ) return 1; // the db can not tolerate strings/blobs longer than 0xFFFF since the format writes 2 lengths switch( tmp.value.type ) { case DBVT_ASCIIZ: case DBVT_BLOB: case DBVT_UTF8: { size_t len = ( tmp.value.type != DBVT_BLOB ) ? (int)strlen(tmp.value.pszVal) : tmp.value.cpbVal; if ( len >= 0xFFFF ) { #ifdef _DEBUG OutputDebugStringA("WriteContactSetting() writing huge string/blob, rejecting ( >= 0xFFFF ) \n"); #endif return 1; } } } EnterCriticalSection(&csDbAccess); { char* szCachedSettingName = GetCachedSetting(tmp.szModule, tmp.szSetting, moduleNameLen, settingNameLen); if ( tmp.value.type != DBVT_BLOB ) { DBVARIANT* pCachedValue = GetCachedValuePtr((HANDLE)wParam, szCachedSettingName, 1); if ( pCachedValue != NULL ) { BOOL bIsIdentical = FALSE; if ( pCachedValue->type == tmp.value.type ) { switch(tmp.value.type) { case DBVT_BYTE: bIsIdentical = pCachedValue->bVal == tmp.value.bVal; break; case DBVT_WORD: bIsIdentical = pCachedValue->wVal == tmp.value.wVal; break; case DBVT_DWORD: bIsIdentical = pCachedValue->dVal == tmp.value.dVal; break; case DBVT_UTF8: case DBVT_ASCIIZ: bIsIdentical = strcmp( pCachedValue->pszVal, tmp.value.pszVal ) == 0; break; } if ( bIsIdentical ) { LeaveCriticalSection(&csDbAccess); return 0; } } SetCachedVariant(&tmp.value, pCachedValue); } if ( szCachedSettingName[-1] != 0 ) { LeaveCriticalSection(&csDbAccess); NotifyEventHooks(hSettingChangeEvent,wParam,(LPARAM)&tmp); return 0; } } else GetCachedValuePtr((HANDLE)wParam, szCachedSettingName, -1); } ofsModuleName=GetModuleNameOfs(tmp.szModule); if(wParam==0) ofsContact=dbHeader.ofsUser; else ofsContact=wParam; dbc=*(struct DBContact*)DBRead(ofsContact,sizeof(struct DBContact),NULL); if(dbc.signature!=DBCONTACT_SIGNATURE) { LeaveCriticalSection(&csDbAccess); return 1; } log0("write setting"); //make sure the module group exists ofsSettingsGroup=GetSettingsGroupOfsByModuleNameOfs(&dbc,ofsModuleName); if(ofsSettingsGroup==0) { //module group didn't exist - make it if(tmp.value.type&DBVTF_VARIABLELENGTH) { if(tmp.value.type==DBVT_ASCIIZ || tmp.value.type==DBVT_UTF8) bytesRequired = (int)strlen(tmp.value.pszVal)+2; else if(tmp.value.type==DBVT_BLOB) bytesRequired=tmp.value.cpbVal+2; } else bytesRequired=tmp.value.type; bytesRequired+=2+settingNameLen; bytesRequired+=(DB_SETTINGS_RESIZE_GRANULARITY-(bytesRequired%DB_SETTINGS_RESIZE_GRANULARITY))%DB_SETTINGS_RESIZE_GRANULARITY; ofsSettingsGroup=CreateNewSpace(bytesRequired+offsetof(struct DBContactSettings,blob)); dbcs.signature=DBCONTACTSETTINGS_SIGNATURE; dbcs.ofsNext=dbc.ofsFirstSettings; dbcs.ofsModuleName=ofsModuleName; dbcs.cbBlob=bytesRequired; dbcs.blob[0]=0; dbc.ofsFirstSettings=ofsSettingsGroup; DBWrite(ofsContact,&dbc,sizeof(struct DBContact)); DBWrite(ofsSettingsGroup,&dbcs,sizeof(struct DBContactSettings)); ofsBlobPtr=ofsSettingsGroup+offsetof(struct DBContactSettings,blob); pBlob=(PBYTE)DBRead(ofsBlobPtr,1,&bytesRemaining); } else {
static INT_PTR AddEvent(WPARAM wParam,LPARAM lParam) { DBEVENTINFO *dbei=(DBEVENTINFO*)lParam; struct DBContact dbc; struct DBEvent dbe,*dbeTest; DWORD ofsNew,ofsModuleName,ofsContact,ofsThis; if(dbei==NULL||dbei->cbSize!=sizeof(DBEVENTINFO)) return 0; if(dbei->timestamp==0) return 0; if (NotifyEventHooks(hEventFilterAddedEvent,wParam,lParam)) { return 0; } EnterCriticalSection(&csDbAccess); if(wParam==0) ofsContact=dbHeader.ofsUser; else ofsContact=wParam; dbc=*(struct DBContact*)DBRead(ofsContact,sizeof(struct DBContact),NULL); if(dbc.signature!=DBCONTACT_SIGNATURE) { LeaveCriticalSection(&csDbAccess); return 0; } ofsNew=CreateNewSpace(offsetof(struct DBEvent,blob)+dbei->cbBlob); ofsModuleName=GetModuleNameOfs(dbei->szModule); dbe.signature=DBEVENT_SIGNATURE; dbe.ofsModuleName=ofsModuleName; dbe.timestamp=dbei->timestamp; dbe.flags=dbei->flags; dbe.eventType=dbei->eventType; dbe.cbBlob=dbei->cbBlob; //find where to put it - sort by timestamp if(dbc.eventCount==0) { dbe.ofsPrev=wParam; dbe.ofsNext=0; dbe.flags|=DBEF_FIRST; dbc.ofsFirstEvent=dbc.ofsLastEvent=ofsNew; } else { dbeTest=(struct DBEvent*)DBRead(dbc.ofsFirstEvent,sizeof(struct DBEvent),NULL); // Should new event be placed before first event in chain? if (dbei->timestamp < dbeTest->timestamp) { dbe.ofsPrev=wParam; dbe.ofsNext=dbc.ofsFirstEvent; dbe.flags|=DBEF_FIRST; dbc.ofsFirstEvent=ofsNew; dbeTest=(struct DBEvent*)DBRead(dbe.ofsNext,sizeof(struct DBEvent),NULL); dbeTest->flags&=~DBEF_FIRST; dbeTest->ofsPrev=ofsNew; DBWrite(dbe.ofsNext,dbeTest,sizeof(struct DBEvent)); } else { // Loop through the chain, starting at the end ofsThis = dbc.ofsLastEvent; dbeTest = (struct DBEvent*)DBRead(ofsThis, sizeof(struct DBEvent), NULL); for(;;) { // If the new event's timesstamp is equal to or greater than the // current dbevent, it will be inserted after. If not, continue // with the previous dbevent in chain. if (dbe.timestamp >= dbeTest->timestamp) { dbe.ofsPrev = ofsThis; dbe.ofsNext = dbeTest->ofsNext; dbeTest->ofsNext = ofsNew; DBWrite(ofsThis, dbeTest, sizeof(struct DBEvent)); if (dbe.ofsNext == 0) dbc.ofsLastEvent = ofsNew; else { dbeTest = (struct DBEvent*)DBRead(dbe.ofsNext, sizeof(struct DBEvent), NULL); dbeTest->ofsPrev = ofsNew; DBWrite(dbe.ofsNext, dbeTest, sizeof(struct DBEvent)); } break; } ofsThis = dbeTest->ofsPrev; dbeTest = (struct DBEvent*)DBRead(ofsThis, sizeof(struct DBEvent), NULL); } } } dbc.eventCount++; if(!(dbe.flags&(DBEF_READ|DBEF_SENT))) { if(dbe.timestamp<dbc.timestampFirstUnread || dbc.timestampFirstUnread==0) { dbc.timestampFirstUnread=dbe.timestamp; dbc.ofsFirstUnreadEvent=ofsNew; } } DBWrite(ofsContact,&dbc,sizeof(struct DBContact)); DBWrite(ofsNew,&dbe,offsetof(struct DBEvent,blob)); DBWrite(ofsNew+offsetof(struct DBEvent,blob),dbei->pBlob,dbei->cbBlob); DBFlush(0); LeaveCriticalSection(&csDbAccess); log1("add event @ %08x",ofsNew); NotifyEventHooks(hEventAddedEvent,wParam,(LPARAM)ofsNew); return (INT_PTR)ofsNew; }
static INT_PTR DeleteEvent(WPARAM wParam,LPARAM lParam) { struct DBContact dbc; DWORD ofsContact,ofsThis; struct DBEvent dbe,*dbeNext,*dbePrev; EnterCriticalSection(&csDbAccess); if(wParam==0) ofsContact=dbHeader.ofsUser; else ofsContact=wParam; dbc=*(struct DBContact*)DBRead(ofsContact,sizeof(struct DBContact),NULL); dbe=*(struct DBEvent*)DBRead(lParam,sizeof(struct DBEvent),NULL); if(dbc.signature!=DBCONTACT_SIGNATURE || dbe.signature!=DBEVENT_SIGNATURE) { LeaveCriticalSection(&csDbAccess); return 1; } log1("delete event @ %08x",wParam); LeaveCriticalSection(&csDbAccess); //call notifier while outside mutex NotifyEventHooks(hEventDeletedEvent,wParam,lParam); //get back in EnterCriticalSection(&csDbAccess); dbc=*(struct DBContact*)DBRead(ofsContact,sizeof(struct DBContact),NULL); dbe=*(struct DBEvent*)DBRead(lParam,sizeof(struct DBEvent),NULL); //check if this was the first unread, if so, recalc the first unread if(dbc.ofsFirstUnreadEvent==(DWORD)lParam) { dbeNext=&dbe; for(;;) { if(dbeNext->ofsNext==0) { dbc.ofsFirstUnreadEvent=0; dbc.timestampFirstUnread=0; break; } ofsThis=dbeNext->ofsNext; dbeNext=(struct DBEvent*)DBRead(ofsThis,sizeof(struct DBEvent),NULL); if(!(dbeNext->flags&(DBEF_READ|DBEF_SENT))) { dbc.ofsFirstUnreadEvent=ofsThis; dbc.timestampFirstUnread=dbeNext->timestamp; break; } } } //get previous and next events in chain and change offsets if(dbe.flags&DBEF_FIRST) { if(dbe.ofsNext==0) { dbc.ofsFirstEvent=dbc.ofsLastEvent=0; } else { dbeNext=(struct DBEvent*)DBRead(dbe.ofsNext,sizeof(struct DBEvent),NULL); dbeNext->flags|=DBEF_FIRST; dbeNext->ofsPrev=dbe.ofsPrev; DBWrite(dbe.ofsNext,dbeNext,sizeof(struct DBEvent)); dbc.ofsFirstEvent=dbe.ofsNext; } } else { if(dbe.ofsNext==0) { dbePrev=(struct DBEvent*)DBRead(dbe.ofsPrev,sizeof(struct DBEvent),NULL); dbePrev->ofsNext=0; DBWrite(dbe.ofsPrev,dbePrev,sizeof(struct DBEvent)); dbc.ofsLastEvent=dbe.ofsPrev; } else { dbePrev=(struct DBEvent*)DBRead(dbe.ofsPrev,sizeof(struct DBEvent),NULL); dbePrev->ofsNext=dbe.ofsNext; DBWrite(dbe.ofsPrev,dbePrev,sizeof(struct DBEvent)); dbeNext=(struct DBEvent*)DBRead(dbe.ofsNext,sizeof(struct DBEvent),NULL); dbeNext->ofsPrev=dbe.ofsPrev; DBWrite(dbe.ofsNext,dbeNext,sizeof(struct DBEvent)); } } //delete event DeleteSpace(lParam,offsetof(struct DBEvent,blob)+dbe.cbBlob); //decrement event count dbc.eventCount--; DBWrite(ofsContact,&dbc,sizeof(struct DBContact)); DBFlush(0); //quit LeaveCriticalSection(&csDbAccess); return 0; }
STDMETHODIMP_(BOOL) CDb3Mmap::WriteContactSetting(MCONTACT contactID, DBCONTACTWRITESETTING *dbcws) { if (dbcws == NULL || dbcws->szSetting == NULL || dbcws->szModule == NULL || m_bReadOnly) return 1; // the db format can't tolerate more than 255 bytes of space (incl. null) for settings+module name int settingNameLen = (int)mir_strlen(dbcws->szSetting); int moduleNameLen = (int)mir_strlen(dbcws->szModule); if (settingNameLen > 0xFE) { #ifdef _DEBUG OutputDebugStringA("WriteContactSetting() got a > 255 setting name length. \n"); #endif return 1; } if (moduleNameLen > 0xFE) { #ifdef _DEBUG OutputDebugStringA("WriteContactSetting() got a > 255 module name length. \n"); #endif return 1; } // used for notifications DBCONTACTWRITESETTING dbcwNotif = *dbcws; if (dbcwNotif.value.type == DBVT_WCHAR) { if (dbcwNotif.value.pszVal != NULL) { char* val = mir_utf8encodeW(dbcwNotif.value.pwszVal); if (val == NULL) return 1; dbcwNotif.value.pszVal = (char*)alloca(mir_strlen(val) + 1); mir_strcpy(dbcwNotif.value.pszVal, val); mir_free(val); dbcwNotif.value.type = DBVT_UTF8; } else return 1; } if (dbcwNotif.szModule == NULL || dbcwNotif.szSetting == NULL) return 1; DBCONTACTWRITESETTING dbcwWork = dbcwNotif; mir_ptr<BYTE> pEncoded(NULL); bool bIsEncrypted = false; switch (dbcwWork.value.type) { case DBVT_BYTE: case DBVT_WORD: case DBVT_DWORD: break; case DBVT_ASCIIZ: case DBVT_UTF8: bIsEncrypted = m_bEncrypted || IsSettingEncrypted(dbcws->szModule, dbcws->szSetting); LBL_WriteString: if (dbcwWork.value.pszVal == NULL) return 1; dbcwWork.value.cchVal = (WORD)mir_strlen(dbcwWork.value.pszVal); if (bIsEncrypted) { size_t len; BYTE *pResult = m_crypto->encodeString(dbcwWork.value.pszVal, &len); if (pResult != NULL) { pEncoded = dbcwWork.value.pbVal = pResult; dbcwWork.value.cpbVal = (WORD)len; dbcwWork.value.type = DBVT_ENCRYPTED; } } break; case DBVT_UNENCRYPTED: dbcwNotif.value.type = dbcwWork.value.type = DBVT_UTF8; goto LBL_WriteString; case DBVT_BLOB: case DBVT_ENCRYPTED: if (dbcwWork.value.pbVal == NULL) return 1; break; default: return 1; } mir_cslockfull lck(m_csDbAccess); DWORD ofsBlobPtr, ofsContact = GetContactOffset(contactID); if (ofsContact == 0) { _ASSERT(false); // contact doesn't exist? return 2; } char *szCachedSettingName = m_cache->GetCachedSetting(dbcwWork.szModule, dbcwWork.szSetting, moduleNameLen, settingNameLen); log3("set [%08p] %s (%p)", hContact, szCachedSettingName, szCachedSettingName); // we don't cache blobs and passwords if (dbcwWork.value.type != DBVT_BLOB && dbcwWork.value.type != DBVT_ENCRYPTED && !bIsEncrypted) { DBVARIANT *pCachedValue = m_cache->GetCachedValuePtr(contactID, szCachedSettingName, 1); if (pCachedValue != NULL) { bool bIsIdentical = false; if (pCachedValue->type == dbcwWork.value.type) { switch (dbcwWork.value.type) { case DBVT_BYTE: bIsIdentical = pCachedValue->bVal == dbcwWork.value.bVal; break; case DBVT_WORD: bIsIdentical = pCachedValue->wVal == dbcwWork.value.wVal; break; case DBVT_DWORD: bIsIdentical = pCachedValue->dVal == dbcwWork.value.dVal; break; case DBVT_UTF8: case DBVT_ASCIIZ: bIsIdentical = mir_strcmp(pCachedValue->pszVal, dbcwWork.value.pszVal) == 0; break; } if (bIsIdentical) return 0; } m_cache->SetCachedVariant(&dbcwWork.value, pCachedValue); } if (szCachedSettingName[-1] != 0) { lck.unlock(); log2(" set resident as %s (%p)", printVariant(&dbcwWork.value), pCachedValue); NotifyEventHooks(hSettingChangeEvent, contactID, (LPARAM)&dbcwWork); return 0; } } else m_cache->GetCachedValuePtr(contactID, szCachedSettingName, -1); log1(" write database as %s", printVariant(&dbcwWork.value)); DWORD ofsModuleName = GetModuleNameOfs(dbcwWork.szModule); DBContact dbc = *(DBContact*)DBRead(ofsContact, NULL); if (dbc.signature != DBCONTACT_SIGNATURE) return 1; // make sure the module group exists PBYTE pBlob; int bytesRequired, bytesRemaining; DBContactSettings dbcs; DWORD ofsSettingsGroup = GetSettingsGroupOfsByModuleNameOfs(&dbc, ofsModuleName); if (ofsSettingsGroup == 0) { //module group didn't exist - make it switch (dbcwWork.value.type) { case DBVT_ASCIIZ: case DBVT_UTF8: bytesRequired = dbcwWork.value.cchVal + 2; break; case DBVT_BLOB: case DBVT_ENCRYPTED: bytesRequired = dbcwWork.value.cpbVal + 2; break; default: bytesRequired = dbcwWork.value.type; } bytesRequired += 2 + settingNameLen; bytesRequired += (DB_SETTINGS_RESIZE_GRANULARITY - (bytesRequired % DB_SETTINGS_RESIZE_GRANULARITY)) % DB_SETTINGS_RESIZE_GRANULARITY; ofsSettingsGroup = CreateNewSpace(bytesRequired + offsetof(DBContactSettings, blob)); dbcs.signature = DBCONTACTSETTINGS_SIGNATURE; dbcs.ofsNext = dbc.ofsFirstSettings; dbcs.ofsModuleName = ofsModuleName; dbcs.cbBlob = bytesRequired; dbcs.blob[0] = 0; dbc.ofsFirstSettings = ofsSettingsGroup; DBWrite(ofsContact, &dbc, sizeof(DBContact)); DBWrite(ofsSettingsGroup, &dbcs, sizeof(DBContactSettings)); ofsBlobPtr = ofsSettingsGroup + offsetof(DBContactSettings, blob); pBlob = (PBYTE)DBRead(ofsBlobPtr, &bytesRemaining); } else { dbcs = *(DBContactSettings*)DBRead(ofsSettingsGroup, &bytesRemaining); // find if the setting exists ofsBlobPtr = ofsSettingsGroup + offsetof(DBContactSettings, blob); pBlob = (PBYTE)DBRead(ofsBlobPtr, &bytesRemaining); while (pBlob[0]) { NeedBytes(settingNameLen + 1); if (pBlob[0] == settingNameLen && !memcmp(pBlob + 1, dbcwWork.szSetting, settingNameLen)) break; NeedBytes(1); MoveAlong(pBlob[0] + 1); NeedBytes(3); MoveAlong(1 + GetSettingValueLength(pBlob)); NeedBytes(1); } // setting already existed, and up to end of name is in cache if (pBlob[0]) { MoveAlong(1 + settingNameLen); // if different type or variable length and length is different NeedBytes(3); if (pBlob[0] != dbcwWork.value.type || ((pBlob[0] == DBVT_ASCIIZ || pBlob[0] == DBVT_UTF8) && *(PWORD)(pBlob + 1) != dbcwWork.value.cchVal) || ((pBlob[0] == DBVT_BLOB || pBlob[0] == DBVT_ENCRYPTED) && *(PWORD)(pBlob + 1) != dbcwWork.value.cpbVal)) { // bin it NeedBytes(3); int nameLen = 1 + settingNameLen; int valLen = 1 + GetSettingValueLength(pBlob); DWORD ofsSettingToCut = ofsBlobPtr - nameLen; MoveAlong(valLen); NeedBytes(1); while (pBlob[0]) { MoveAlong(pBlob[0] + 1); NeedBytes(3); MoveAlong(1 + GetSettingValueLength(pBlob)); NeedBytes(1); } DBMoveChunk(ofsSettingToCut, ofsSettingToCut + nameLen + valLen, ofsBlobPtr + 1 - ofsSettingToCut); ofsBlobPtr -= nameLen + valLen; pBlob = (PBYTE)DBRead(ofsBlobPtr, &bytesRemaining); } else { // replace existing setting at pBlob MoveAlong(1); // skip data type switch (dbcwWork.value.type) { case DBVT_BYTE: DBWrite(ofsBlobPtr, &dbcwWork.value.bVal, 1); break; case DBVT_WORD: DBWrite(ofsBlobPtr, &dbcwWork.value.wVal, 2); break; case DBVT_DWORD: DBWrite(ofsBlobPtr, &dbcwWork.value.dVal, 4); break; case DBVT_BLOB: DBWrite(ofsBlobPtr + 2, dbcwWork.value.pbVal, dbcwWork.value.cpbVal); break; case DBVT_ENCRYPTED: DBWrite(ofsBlobPtr + 2, dbcwWork.value.pbVal, dbcwWork.value.cpbVal); break; case DBVT_UTF8: case DBVT_ASCIIZ: DBWrite(ofsBlobPtr + 2, dbcwWork.value.pszVal, dbcwWork.value.cchVal); break; } // quit DBFlush(1); lck.unlock(); // notify NotifyEventHooks(hSettingChangeEvent, contactID, (LPARAM)&dbcwNotif); return 0; } } } // cannot do a simple replace, add setting to end of list // pBlob already points to end of list // see if it fits switch (dbcwWork.value.type) { case DBVT_ASCIIZ: case DBVT_UTF8: bytesRequired = dbcwWork.value.cchVal + 2; break; case DBVT_BLOB: case DBVT_ENCRYPTED: bytesRequired = dbcwWork.value.cpbVal + 2; break; default: bytesRequired = dbcwWork.value.type; } bytesRequired += 2 + settingNameLen; bytesRequired += ofsBlobPtr + 1 - (ofsSettingsGroup + offsetof(DBContactSettings, blob)); if ((DWORD)bytesRequired > dbcs.cbBlob) { // doesn't fit: move entire group DBContactSettings *dbcsPrev; DWORD ofsDbcsPrev, ofsNew; InvalidateSettingsGroupOfsCacheEntry(ofsSettingsGroup); bytesRequired += (DB_SETTINGS_RESIZE_GRANULARITY - (bytesRequired % DB_SETTINGS_RESIZE_GRANULARITY)) % DB_SETTINGS_RESIZE_GRANULARITY; // find previous group to change its offset ofsDbcsPrev = dbc.ofsFirstSettings; if (ofsDbcsPrev == ofsSettingsGroup) ofsDbcsPrev = 0; else { dbcsPrev = (DBContactSettings*)DBRead(ofsDbcsPrev, NULL); while (dbcsPrev->ofsNext != ofsSettingsGroup) { if (dbcsPrev->ofsNext == 0) DatabaseCorruption(NULL); ofsDbcsPrev = dbcsPrev->ofsNext; dbcsPrev = (DBContactSettings*)DBRead(ofsDbcsPrev, NULL); } } // create the new one ofsNew = ReallocSpace(ofsSettingsGroup, dbcs.cbBlob + offsetof(DBContactSettings, blob), bytesRequired + offsetof(DBContactSettings, blob)); dbcs.cbBlob = bytesRequired; DBWrite(ofsNew, &dbcs, offsetof(DBContactSettings, blob)); if (ofsDbcsPrev == 0) { dbc.ofsFirstSettings = ofsNew; DBWrite(ofsContact, &dbc, sizeof(DBContact)); } else { dbcsPrev = (DBContactSettings*)DBRead(ofsDbcsPrev, NULL); dbcsPrev->ofsNext = ofsNew; DBWrite(ofsDbcsPrev, dbcsPrev, offsetof(DBContactSettings, blob)); } ofsBlobPtr += ofsNew - ofsSettingsGroup; ofsSettingsGroup = ofsNew; pBlob = (PBYTE)DBRead(ofsBlobPtr, &bytesRemaining); } // we now have a place to put it and enough space: make it DBWrite(ofsBlobPtr, &settingNameLen, 1); DBWrite(ofsBlobPtr + 1, (PVOID)dbcwWork.szSetting, settingNameLen); MoveAlong(1 + settingNameLen); DBWrite(ofsBlobPtr, &dbcwWork.value.type, 1); MoveAlong(1); switch (dbcwWork.value.type) { case DBVT_BYTE: DBWrite(ofsBlobPtr, &dbcwWork.value.bVal, 1); MoveAlong(1); break; case DBVT_WORD: DBWrite(ofsBlobPtr, &dbcwWork.value.wVal, 2); MoveAlong(2); break; case DBVT_DWORD: DBWrite(ofsBlobPtr, &dbcwWork.value.dVal, 4); MoveAlong(4); break; case DBVT_BLOB: DBWrite(ofsBlobPtr, &dbcwWork.value.cpbVal, 2); DBWrite(ofsBlobPtr + 2, dbcwWork.value.pbVal, dbcwWork.value.cpbVal); MoveAlong(2 + dbcwWork.value.cpbVal); break; case DBVT_ENCRYPTED: DBWrite(ofsBlobPtr, &dbcwWork.value.cpbVal, 2); DBWrite(ofsBlobPtr + 2, dbcwWork.value.pbVal, dbcwWork.value.cpbVal); MoveAlong(2 + dbcwWork.value.cpbVal); break; case DBVT_UTF8: case DBVT_ASCIIZ: DBWrite(ofsBlobPtr, &dbcwWork.value.cchVal, 2); DBWrite(ofsBlobPtr + 2, dbcwWork.value.pszVal, dbcwWork.value.cchVal); MoveAlong(2 + dbcwWork.value.cchVal); break; } BYTE zero = 0; DBWrite(ofsBlobPtr, &zero, 1); // quit DBFlush(1); lck.unlock(); // notify NotifyEventHooks(hSettingChangeEvent, contactID, (LPARAM)&dbcwNotif); return 0; }
void CDb3Mmap::WriteSignature(DBSignature &sign) { memcpy(&m_dbHeader.signature, &sign, sizeof(DBSignature)); DBWrite(0, &sign, sizeof(DBSignature)); }
/*------------------------------------------------------------------------- * Function: main * * Purpose: * * Return: 0 * * Programmer: * Thomas R. Treadway, Mon Mar 12 14:13:51 PDT 2007 * Test of HDF5 compression. * * Modifications: * *------------------------------------------------------------------------- */ int main(int argc, char *argv[]) { int nerrors = 0; int verbose = 0; int usefloat = 0; int readonly = 0; int i, j, ndims=1; int fdims[]= {ONE_MEG/sizeof(float)}; int ddims[]= {ONE_MEG/sizeof(double)}; float *fval; float *frval; double *dval; double *drval; int driver=DB_HDF5; char *filename="compression.h5"; char *ptr; char tmpname[64]; DBfile *dbfile; #if !defined(_WIN32) struct timeval tim; double t1, t2; #endif struct stat buffer; off_t fsize; int has_loss = 0; int show_errors = DB_TOP; /* Parse command-line */ for (i=1; i<argc; i++) { if (!strncmp(argv[i], "DB_PDB",6)) { fprintf(stderr, "This test only supported on HDF5 driver\n"); exit(1); } else if (!strncmp(argv[i], "DB_HDF5", 7)) { driver = StringToDriver(argv[i]); filename = "compression.h5"; } else if (!strcmp(argv[i], "compress")) { if ((i+1<argc) && ((ptr=strstr(argv[i+1], "METHOD=")) != NULL)) { DBSetCompression(argv[i+1]); i++; } else DBSetCompression("METHOD=GZIP"); } else if (!strcmp(argv[i], "szip")) { DBSetCompression("METHOD=SZIP"); } else if (!strcmp(argv[i], "gzip")) { DBSetCompression("METHOD=GZIP"); } else if (!strcmp(argv[i], "fpzip")) { DBSetCompression("METHOD=FPZIP"); } else if (!strcmp(argv[i], "single")) { usefloat = 1; } else if (!strcmp(argv[i], "verbose")) { verbose = 1; } else if (!strcmp(argv[i], "lossy1")) { DBSetCompression("METHOD=FPZIP LOSS=1"); has_loss = 1; } else if (!strcmp(argv[i], "lossy2")) { DBSetCompression("METHOD=FPZIP LOSS=2"); has_loss = 1; } else if (!strcmp(argv[i], "lossy3")) { DBSetCompression("METHOD=FPZIP LOSS=3"); has_loss = 1; } else if (!strcmp(argv[i], "minratio1000")) { DBSetCompression("ERRMODE=FAIL MINRATIO=1000 METHOD=FPZIP"); } else if (!strcmp(argv[i], "minratio1001")) { DBSetCompression("ERRMODE=FALLBACK MINRATIO=1000 METHOD=FPZIP"); } else if (!strcmp(argv[i], "readonly")) { readonly = 1; } else if (!strcmp(argv[i], "help")) { printf("Usage: %s [compress [\"METHOD=...\"]|single|verbose|readonly]\n",argv[0]); printf("Where: compress - enables compression, followed by compression information string\n"); printf(" default is compress \"METHOD=GZIP LEVEL=1\"\n"); printf(" single - writes data as floats not doubles\n"); printf(" verbose - displays more feedback\n"); printf(" readonly - checks an existing file (used for cross platform test)\n"); printf(" DB_HDF5 - enable HDF5 driver, the default\n"); return (0); } else if (!strcmp(argv[i], "show-all-errors")) { show_errors = DB_ALL_AND_DRVR; } else if (argv[i][0] != '\0') { fprintf(stderr, "%s: ignored argument `%s'\n", argv[0], argv[i]); } } /* get some temporary memory */ fval = (float*) malloc(ONE_MEG); frval = (float*) malloc(ONE_MEG); dval = (double*) malloc(ONE_MEG); drval = (double*) malloc(ONE_MEG); DBShowErrors(show_errors, 0); if (!readonly) { /* * Create a file that contains a simple variables. */ if (verbose) printf("Creating file: `%s'\n", filename); dbfile = DBCreate(filename, 0, DB_LOCAL, "Compression Test", driver); #if !defined(_WIN32) gettimeofday(&tim, NULL); t1=tim.tv_sec+(tim.tv_usec/1000000.0); #endif if (usefloat) { for (j = 0; j < INTERATE; j++) { if (verbose) if (j % 100 == 0) printf("Iterations %04d to %04d of %04d\n", j,j+100-1,INTERATE); sprintf(tmpname, "compression_%04d", j); for (i = 0; i < fdims[0]; i++) fval[i] = (float) fdims[0] * j + i; if (DBWrite(dbfile, tmpname, fval, fdims, ndims, DB_FLOAT) < 0) { nerrors++; break; } } } else { for (j = 0; j < INTERATE; j++) { if (verbose) if (j % 100 == 0) printf("Iterations %04d to %04d of %04d\n",j,j+100-1,INTERATE); sprintf(tmpname, "compression_%04d", j); for (i = 0; i < ddims[0]; i++) dval[i] = (double) ddims[0] * j + i; if (DBWrite(dbfile, tmpname, dval, ddims, ndims, DB_DOUBLE) < 0) { nerrors++; break; } } } #if !defined(_WIN32) gettimeofday(&tim, NULL); t2=tim.tv_sec+(tim.tv_usec/1000000.0); stat(filename, &buffer); fsize = buffer.st_size; printf("Write took %.6lf seconds and %.6g bytes/second\n", t2-t1,fsize/(t2-t1)); #endif DBClose(dbfile); } else { stat(filename, &buffer); fsize = buffer.st_size; } if (nerrors) return nerrors; /* * Now try opening the file again and verify the simple * variable. */ if (verbose) printf("Reopening `%s'\n", filename); dbfile = DBOpen(filename, driver, DB_READ); if (dbfile == 0) { printf("Unable to Open file for reading\n"); exit(1); } #if !defined(_WIN32) gettimeofday(&tim, NULL); t1=tim.tv_sec+(tim.tv_usec/1000000.0); #endif if (usefloat) { for (j = 0; j < INTERATE; j++) { if (verbose) if (j % 100 == 0) printf("Iterations %04d to %04d of %04d\n", j,j+100-1,INTERATE); sprintf(tmpname, "compression_%04d", j); if (DBReadVar(dbfile, tmpname, frval) < 0) { if (!has_loss) nerrors++; if (!has_loss && nerrors <= 10) printf("DBReadVar for \"%s\" failed\n", tmpname); if (!has_loss && nerrors == 10) printf("Further errors will be suppressed\n"); } for (i = 0; i < fdims[0]; i++) { fval[i] = (float) fdims[0] * j + i; if (fval[i] != frval[i]) { if (!has_loss) nerrors++; if (!has_loss && nerrors <= 10) printf("Read error in \"%s\" at position %04d. Expected %f, got %f\n", tmpname, i, fval[i], frval[i]); if (!has_loss && nerrors == 10) printf("Further errors will be suppressed\n"); break; } } } } else { for (j = 0; j < INTERATE; j++) { if (verbose) if (j % 100 == 0) printf("Iterations %04d to %04d of %04d\n",j,j+100-1,INTERATE); sprintf(tmpname, "compression_%04d", j); if (DBReadVar(dbfile, tmpname, drval) < 0) { if (!has_loss) nerrors++; if (!has_loss && nerrors <= 10) printf("DBReadVar for \"%s\" failed\n", tmpname); if (!has_loss && nerrors == 10) printf("Further errors will be suppressed\n"); } for (i = 0; i < ddims[0]; i++) { dval[i] = (double) ddims[0] * j + i; if (dval[i] != drval[i]) { if (!has_loss) nerrors++; if (!has_loss && nerrors <= 10) printf("Read error in \"%s\" at position %04d. Expected %f, got %f\n", tmpname, i, dval[i], drval[i]); if (!has_loss && nerrors == 10) printf("Further errors will be suppressed\n"); break; } } } } #if !defined(_WIN32) gettimeofday(&tim, NULL); t2=tim.tv_sec+(tim.tv_usec/1000000.0); printf("Read took %.6lf seconds and %.6g bytes/second\n", t2-t1,fsize/(t2-t1)); #endif DBClose(dbfile); free(fval); free(frval); free(dval); free(drval); CleanupDriverStuff(); return nerrors; }
int main(int argc, char *argv[]) { int nerrors = 0; int i, j, ndims=1; int driver=DB_HDF5; char *filename="largefile.h5"; DBfile *dbfile; /* Parse command-line */ for (i=1; i<argc; i++) { if (!strcmp(argv[i], "DB_PDB")) { fprintf(stderr, "This test only supported on HDF5 driver\n"); exit(1); } else if (!strcmp(argv[i], "DB_HDF5")) { driver = DB_HDF5; filename = "largefile.h5"; } else { fprintf(stderr, "%s: ignored argument '%s'\n", argv[0], argv[i]); } } DBShowErrors(DB_TOP, NULL); DBForceSingle(1); /* * Create a file that contains a simple variables. */ printf("Creating file: '%s'\n", filename); dbfile = DBCreate(filename, 0, DB_LOCAL, "Simple Test", driver); for (j = 0; j < 2500; j++) { char tmpname[64]; if (j % 100 == 0) printf("Iterations %04d to %04d of %04d\n", j, j+100-1, 2500); sprintf(tmpname, "simple_%04d", j); for (i = 0; i < dims[0]; i++) val[i] = (float) dims[0] * j + i; if (DBWrite(dbfile, tmpname, val, dims, ndims, DB_FLOAT) != 0) { DBClose(dbfile); exit(1); } } /* * Put some objects VisIt can process at the end of the file */ build_curve(dbfile, driver); DBClose(dbfile); /* * Now try opening the file again and reading the simple * variable. */ printf("Reopening '%s'\n", filename); dbfile = DBOpen(filename, driver, DB_READ); if (dbfile == 0) { printf("Unable to Reopen file for reading\n"); exit(1); } /* * Randomly examine 50 arrays from the first and last 500 */ srand(0xBabeFace); for (j = 0; j < 100; j++) { char tmpname[64]; int n = rand() % 500 + (j >= 50 ? 200 : 0); sprintf(tmpname, "simple_%04d", n); if (DBReadVar(dbfile, tmpname, rval) < 0) { nerrors++; if (nerrors < 10) printf("DBReadVar for \"%s\" failed\n", tmpname); if (nerrors == 10) printf("Further errors will be suppressed\n"); } for (i = 0; i < dims[0]; i++) { val[i] = (float) dims[0] * n + i; if (val[i] != rval[i]) { nerrors++; if (nerrors < 10) printf("Read error in \"%s\" at position %04d. Expected %f, got %f\n", tmpname, i, val[i], rval[i]); if (nerrors == 10) printf("Further errors will be suppressed\n"); break; } } } DBClose(dbfile); exit(nerrors > 0); }
/*------------------------------------------------------------------------- * Function: test_write_all * * Purpose: Write complete arrays from file to disk with DBWrite(). This * only tests that DBWrite() returns success -- it doesn't * attempt to read the data and compare it to what was written. * * Return: Success: 0 * * Failure: number of errors * * Programmer: Robb Matzke * Tuesday, February 9, 1999 * * Modifications: * Robb Matzke, 2000-01-12 * Changed hyphens to underscores in object names because silo * now fails when underscores are present in the name. *------------------------------------------------------------------------- */ static int test_write_all(DBfile *dbfile) { int i, dims[5], nerrors=0; puts("DBWrite():"); /* Initialize output arrays */ for (i=0; i<TEST_NELMTS; i++, cntr_g++) { cdata_g[i] = cntr_g%128; /*`char' has unknown sign so play it safe*/ sdata_g[i] = cntr_g-TEST_NELMTS/2; idata_g[i] = cntr_g-TEST_NELMTS/2; ldata_g[i] = cntr_g-TEST_NELMTS/2; fdata_g[i] = (cntr_g-TEST_NELMTS/2)/10.0; ddata_g[i] = (cntr_g-TEST_NELMTS/2)/10.0; } /* 1d char */ puts(" 1d_char"); dims[0] = TEST_NELMTS; if (DBWrite(dbfile, "1d_char", cdata_g, dims, 1, DB_CHAR)<0) { puts(" DBWrite() failed"); nerrors++; } /* 2d short */ puts(" 2d_short"); dims[0] = 2; dims[1] = TEST_NELMTS/dims[0]; if (DBWrite(dbfile, "2d_short", sdata_g, dims, 2, DB_SHORT)<0) { puts(" DBWrite() failed"); nerrors++; } /* 3d int */ puts(" 3d_int"); dims[0] = 12; dims[1] = 30; dims[2] = TEST_NELMTS/(dims[0]*dims[1]); if (DBWrite(dbfile, "3d_int", idata_g, dims, 3, DB_INT)<0) { puts(" DBWrite() failed"); nerrors++; } /* 3d long */ puts(" 3d_long"); dims[0] = 5; dims[1] = 6; dims[2] = TEST_NELMTS/(dims[0]*dims[1]); if (DBWrite(dbfile, "3d_long", ldata_g, dims, 3, DB_LONG)<0) { puts(" DBWrite() failed"); nerrors++; } /* 4d float */ DBForceSingle(TRUE); puts(" 4d_float"); dims[0] = 6; dims[1] = 5; dims[2] = 4; dims[3] = TEST_NELMTS/(dims[0]*dims[1]*dims[2]); if (DBWrite(dbfile, "4d_float", fdata_g, dims, 4, DB_FLOAT)<0) { puts(" DBWrite() failed"); nerrors++; } DBForceSingle(FALSE); /* 5d double */ puts(" 5d_double"); dims[0] = 3; dims[1] = 2; dims[2] = 6; dims[3] = 5; dims[4] = TEST_NELMTS/(dims[0]*dims[1]*dims[2]*dims[3]); if (DBWrite(dbfile, "5d_double", ddata_g, dims, 5, DB_DOUBLE)<0) { puts(" DBWrite() failed"); nerrors++; } return nerrors; }
/*------------------------------------------------------------------------- * Function: main * * Purpose: * * Return: 0 * * Programmer: * * Modifications: * Robb Matzke, 1999-04-09 * Added argument parsing to control the driver which is used. * * Mark C. Miller, Mon Sep 21 15:20:30 PDT 2009 * Added code to test long long type. * * Mark C. Miller, Wed Sep 23 11:57:24 PDT 2009 * Added logic to test DBInqFile. * * Mark C. Miller, Fri Nov 13 15:40:35 PST 2009 * Test long long on PDB driver too. *------------------------------------------------------------------------- */ int main(int argc, char *argv[]) { int i, j, k; int ndims, dims[3]; float val[NX * NY * NZ]; long long lval[NX * NY * NZ]; int offset[3], length[3], stride[3]; float val2[NX * NY * NZ]; long long *lval2 = 0; int cnt, driver=DB_PDB; char *filename="simple.pdb"; int k1, k2; int err = 0; int inqval; DBfile *dbfile; int show_all_errors = FALSE; /* Parse command-line */ for (i=1; i<argc; i++) { if (!strncmp(argv[i], "DB_PDB", 6)) { driver = StringToDriver(argv[i]); filename = "simple.pdb"; } else if (!strncmp(argv[i], "DB_HDF5", 7)) { driver = StringToDriver(argv[i]); filename = "simple.h5"; } else if (!strcmp(argv[i], "show-all-errors")) { show_all_errors = 1; } else if (argv[i][0] != '\0') { fprintf(stderr, "%s: ignored argument `%s'\n", argv[0], argv[i]); } } DBShowErrors(show_all_errors?DB_ALL_AND_DRVR:DB_TOP, NULL); DBForceSingle(1); /* * Build a simple variables. */ ndims = 3; dims[0] = NZ; dims[1] = NY; dims[2] = NX; for (k = 0; k < NZ; k++) { for (j = 0; j < NY; j++) { for (i = 0; i < NX; i++) { val[i + j * NX + k * NX * NY] = i + j * NX + k * NX * NY; lval[i + j * NX + k * NX * NY] = ((long long) 1 << 35) + i + j * NX + k * NX * NY; } } } /* Test InqFile on a PDB (but not Silo) file */ if (driver == DB_PDB) inqval = DBInqFile("not_a_silo_file.pdb"); else inqval = DBInqFile("not_a_silo_file.h5"); if (inqval < 0) { fprintf(stderr, "Error in InqFile attempting to identify not_a_silo_file"); err = 1; } else if (inqval > 0) { fprintf(stderr, "InqFile incorrectly identified not_a_silo_file"); err = 1; } /* Create empty silo file to test InqFile */ dbfile = DBCreate(filename, 0, DB_LOCAL, "Empty Silo File", driver); DBClose(dbfile); if (DBInqFile(filename) <= 0) { fprintf(stderr, "InqFile says file created via DBCreate is NOT a silo file"); err = 1; } unlink(filename); /* * Create a file that contains a simple variables. */ printf("Creating file: `%s'\n", filename); dbfile = DBCreate(filename, 0, DB_LOCAL, "Simple Test", driver); DBWrite(dbfile, "simple", val, dims, ndims, DB_FLOAT); DBWrite(dbfile, "longlong", lval, dims, ndims, DB_LONG_LONG); DBClose(dbfile); /* * Now try opening the file again and reading the simple * variable. */ printf("Reopening `%s'\n", filename); dbfile = DBOpen(filename, driver, DB_READ); offset[0] = 0; offset[1] = 0; offset[2] = 0; length[0] = NZ2; length[1] = NY2; length[2] = NX2; stride[0] = 1; stride[1] = 1; stride[2] = 1; for (i = 0; i < NX * NY * NZ; i++) val2[i] = 0; DBReadVarSlice(dbfile, "simple", offset, length, stride, ndims, val2); lval2 = DBGetVar(dbfile, "longlong"); DBClose(dbfile); /* * Check the data. */ cnt = 0; for (k = 0; k < NZ2; k++) { for (j = 0; j < NY2; j++) { for (i = 0; i < NX2; i++) { if (val2[i + j * NX2 + k * NX2 * NY2] != val[i + j * NX + k * NX * NY]) cnt++; } } } err += cnt; printf("%d values don't match\n", cnt); cnt = 0; k1 = NX2 * NY2 * NZ2; k2 = NX * NY * NZ; for (i = k1; i < k2; i++) if (val2[i] != 0) cnt++; printf("%d values were overwritten\n", cnt); cnt = 0; for (k = 0; k < NZ && lval2; k++) { for (j = 0; j < NY; j++) { for (i = 0; i < NX; i++) { if (lval2[i + j * NX + k * NX * NY] != lval[i + j * NX + k * NX * NY]) cnt++; } } } err += cnt; printf("%d long long values don't match\n", cnt); if (lval2) free(lval2); CleanupDriverStuff(); return err; }
/*------------------------------------------------------------------------- * Function: test_dirs * * Purpose: Test directory operations * * Return: Success: 0 * * Failure: number of errors * * Programmer: Robb Matzke * Wednesday, February 10, 1999 * * Modifications: * Robb Matzke, 2000-01-12 * Changed hyphens to underscores in object names because silo * now fails when underscores are present in the name. *------------------------------------------------------------------------- */ static int test_dirs(DBfile *dbfile) { int nerrors=0; char curdir[1024]; static int in[1]={911}, value[1]={0}; static int dims[1]={1}; puts("=== Directories ==="); /* Make some directories */ if (DBMkDir(dbfile, "dir1")<0) { puts("DBMkDir(dir1) failed"); nerrors++; } if (DBMkDir(dbfile, "dir1/d1a")<0) { puts("DBMkDir(dir1/d1a) failed"); nerrors++; } if (DBMkDir(dbfile, "/dir1/d1b")<0) { puts("DBMkDir(dir1/d1b) failed"); nerrors++; } if (DBMkDir(dbfile, "/dir1/d1c/")<0) { puts("DBMkDir(dir1/d1c) failed"); nerrors++; } if (DBMkdir(dbfile, "//dir2//")<0) { puts("DBMkDir(dir2) failed"); nerrors++; } /* Set the CWD to /dir1/d1c and write a variable */ if (DBSetDir(dbfile, "//dir1//d1c//")<0) { puts("DBSetDir(/dir1/d1c) failed"); nerrors++; } if (DBWrite(dbfile, "d1c_A", value, dims, 1, DB_INT)<0) { puts("DBWrite(d1c_A) failed"); nerrors++; } if (DBGetDir(dbfile, curdir)<0 || strcmp(curdir, "/dir1/d1c")) { puts("DBGetDir() failed"); nerrors++; } if (DBReadVar(dbfile, "../d1c/..//..////dir1/d1c//d1c_A", in)<0 || in[0]!=value[0]) { puts("DBReadVar(d1c_A) failed"); nerrors++; } /* Test table of contents */ if (NULL==DBGetToc(dbfile)) { puts("DBGetToc() failed"); nerrors++; } /* Set CWD to top */ if (DBSetDir(dbfile, "/")<0) { puts("DBSetDir(/) failed"); nerrors++; } if (DBGetDir(dbfile, curdir)<0 || strcmp(curdir, "/")) { puts("DBetDir() failed"); nerrors++; } return nerrors; }
static INT_PTR DeleteContact(WPARAM wParam,LPARAM lParam) { struct DBContact *dbc,*dbcPrev; DWORD ofsThis,ofsNext,ofsFirstEvent; struct DBContactSettings *dbcs; struct DBEvent *dbe; int index; if((HANDLE)wParam==NULL) return 1; EnterCriticalSection(&csDbAccess); dbc=(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL); if(dbc->signature!=DBCONTACT_SIGNATURE) { LeaveCriticalSection(&csDbAccess); return 1; } if ( (HANDLE)wParam == (HANDLE)dbHeader.ofsUser ) { LeaveCriticalSection(&csDbAccess); log0("FATAL: del of user chain attempted."); return 1; } log0("del contact"); LeaveCriticalSection(&csDbAccess); //call notifier while outside mutex NotifyEventHooks(hContactDeletedEvent,wParam,0); //get back in EnterCriticalSection(&csDbAccess); { DBCachedContactValueList VLtemp; VLtemp.hContact = (HANDLE)wParam; if ( li.List_GetIndex(&lContacts,&VLtemp,&index)) { DBCachedContactValueList *VL = ( DBCachedContactValueList* )lContacts.items[index]; DBCachedContactValue* V = VL->first; while ( V != NULL ) { DBCachedContactValue* V1 = V->next; FreeCachedVariant(&V->value); HeapFree( hCacheHeap, 0, V ); V = V1; } HeapFree( hCacheHeap, 0, VL ); if (VLtemp.hContact == hLastCachedContact) hLastCachedContact = NULL; li.List_Remove(&lContacts,index); } } dbc=(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL); //delete settings chain ofsThis=dbc->ofsFirstSettings; ofsFirstEvent=dbc->ofsFirstEvent; while(ofsThis) { dbcs=(struct DBContactSettings*)DBRead(ofsThis,sizeof(struct DBContactSettings),NULL); ofsNext=dbcs->ofsNext; DeleteSpace(ofsThis,offsetof(struct DBContactSettings,blob)+dbcs->cbBlob); ofsThis=ofsNext; } //delete event chain ofsThis=ofsFirstEvent; while(ofsThis) { dbe=(struct DBEvent*)DBRead(ofsThis,sizeof(struct DBEvent),NULL); ofsNext=dbe->ofsNext; DeleteSpace(ofsThis,offsetof(struct DBEvent,blob)+dbe->cbBlob); ofsThis=ofsNext; } //find previous contact in chain and change ofsNext dbc=(struct DBContact*)DBRead(wParam,sizeof(struct DBContact),NULL); if(dbHeader.ofsFirstContact==wParam) { dbHeader.ofsFirstContact=dbc->ofsNext; DBWrite(0,&dbHeader,sizeof(dbHeader)); } else { ofsNext=dbc->ofsNext; ofsThis=dbHeader.ofsFirstContact; dbcPrev=(struct DBContact*)DBRead(ofsThis,sizeof(struct DBContact),NULL); while(dbcPrev->ofsNext!=wParam) { if(dbcPrev->ofsNext==0) DatabaseCorruption(NULL); ofsThis=dbcPrev->ofsNext; dbcPrev=(struct DBContact*)DBRead(ofsThis,sizeof(struct DBContact),NULL); } dbcPrev->ofsNext=ofsNext; DBWrite(ofsThis,dbcPrev,sizeof(struct DBContact)); { DBCachedContactValueList VLtemp; VLtemp.hContact = (HANDLE)ofsThis; if ( li.List_GetIndex(&lContacts,&VLtemp,&index)) { DBCachedContactValueList *VL = ( DBCachedContactValueList* )lContacts.items[index]; VL->hNext = ( HANDLE )ofsNext; } } } //delete contact DeleteSpace(wParam,sizeof(struct DBContact)); //decrement contact count dbHeader.contactCount--; DBWrite(0,&dbHeader,sizeof(dbHeader)); DBFlush(0); //quit LeaveCriticalSection(&csDbAccess); return 0; }
STDMETHODIMP_(HANDLE) CDb3Mmap::AddEvent(MCONTACT contactID, DBEVENTINFO *dbei) { if (dbei == NULL || dbei->cbSize != sizeof(DBEVENTINFO)) return 0; if (dbei->timestamp == 0) return 0; DBEvent dbe; dbe.signature = DBEVENT_SIGNATURE; dbe.contactID = contactID; // store native or subcontact's id dbe.timestamp = dbei->timestamp; dbe.flags = dbei->flags; dbe.wEventType = dbei->eventType; dbe.cbBlob = dbei->cbBlob; BYTE *pBlob = dbei->pBlob; MCONTACT contactNotifyID = contactID; DBCachedContact *ccSub = NULL; if (contactID != 0) { DBCachedContact *cc = m_cache->GetCachedContact(contactID); if (cc == NULL) return NULL; if (cc->IsSub()) { ccSub = cc; // set default sub to the event's source db_mc_setDefault(cc->parentID, contactID, false); contactID = cc->parentID; // and add an event to a metahistory if (db_mc_isEnabled()) contactNotifyID = contactID; } } if (NotifyEventHooks(hEventFilterAddedEvent, contactNotifyID, (LPARAM)dbei)) return NULL; mir_ptr<BYTE> pCryptBlob; if (m_bEncrypted) { size_t len; BYTE *pResult = m_crypto->encodeBuffer(pBlob, dbe.cbBlob, &len); if (pResult != NULL) { pCryptBlob = pBlob = pResult; dbe.cbBlob = (DWORD)len; dbe.flags |= DBEF_ENCRYPTED; } } bool neednotify; mir_cslockfull lck(m_csDbAccess); DWORD ofsContact = GetContactOffset(contactID); DBContact dbc = *(DBContact*)DBRead(ofsContact, sizeof(DBContact), NULL); if (dbc.signature != DBCONTACT_SIGNATURE) return NULL; DWORD ofsNew = CreateNewSpace(offsetof(DBEvent, blob) + dbe.cbBlob); dbe.ofsModuleName = GetModuleNameOfs(dbei->szModule); // find where to put it - sort by timestamp if (dbc.eventCount == 0) { dbe.ofsPrev = dbe.ofsNext = 0; dbc.ofsFirstEvent = dbc.ofsLastEvent = ofsNew; } else { DBEvent *dbeTest = (DBEvent*)DBRead(dbc.ofsFirstEvent, sizeof(DBEvent), NULL); // Should new event be placed before first event in chain? if (dbe.timestamp < dbeTest->timestamp) { dbe.ofsPrev = 0; dbe.ofsNext = dbc.ofsFirstEvent; dbc.ofsFirstEvent = ofsNew; dbeTest = (DBEvent*)DBRead(dbe.ofsNext, sizeof(DBEvent), NULL); dbeTest->ofsPrev = ofsNew; DBWrite(dbe.ofsNext, dbeTest, sizeof(DBEvent)); } else { // Loop through the chain, starting at the end DWORD ofsThis = dbc.ofsLastEvent; dbeTest = (DBEvent*)DBRead(ofsThis, sizeof(DBEvent), NULL); for (;;) { // If the new event's timesstamp is equal to or greater than the // current dbevent, it will be inserted after. If not, continue // with the previous dbevent in chain. if (dbe.timestamp >= dbeTest->timestamp) { dbe.ofsPrev = ofsThis; dbe.ofsNext = dbeTest->ofsNext; dbeTest->ofsNext = ofsNew; DBWrite(ofsThis, dbeTest, sizeof(DBEvent)); if (dbe.ofsNext == 0) dbc.ofsLastEvent = ofsNew; else { dbeTest = (DBEvent*)DBRead(dbe.ofsNext, sizeof(DBEvent), NULL); dbeTest->ofsPrev = ofsNew; DBWrite(dbe.ofsNext, dbeTest, sizeof(DBEvent)); } break; } ofsThis = dbeTest->ofsPrev; dbeTest = (DBEvent*)DBRead(ofsThis, sizeof(DBEvent), NULL); } } } dbc.eventCount++; if (!(dbe.flags & (DBEF_READ | DBEF_SENT))) { if (dbe.timestamp < dbc.tsFirstUnread || dbc.tsFirstUnread == 0) { dbc.tsFirstUnread = dbe.timestamp; dbc.ofsFirstUnread = ofsNew; } neednotify = true; } else neednotify = m_safetyMode; if (ccSub != NULL) { DBContact *pSub = (DBContact*)DBRead(ccSub->dwDriverData, sizeof(DBContact), NULL); pSub->eventCount++; } DBWrite(ofsContact, &dbc, sizeof(DBContact)); DBWrite(ofsNew, &dbe, offsetof(DBEvent, blob)); DBWrite(ofsNew + offsetof(DBEvent, blob), pBlob, dbe.cbBlob); DBFlush(0); lck.unlock(); log1("add event @ %08x", ofsNew); // Notify only in safe mode or on really new events if (neednotify) NotifyEventHooks(hEventAddedEvent, contactNotifyID, (LPARAM)ofsNew); return (HANDLE)ofsNew; }