Exemple #1
0
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;
}
Exemple #2
0
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);
}
Exemple #4
0
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;
}
Exemple #5
0
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);
	}
}
Exemple #6
0
// 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;
}
Exemple #7
0
//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;
}
Exemple #8
0
/*-------------------------------------------------------------------------
 * 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;
}
Exemple #10
0
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);
}
Exemple #11
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();
}
Exemple #14
0
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 );
	}
}
Exemple #16
0
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;
}
Exemple #17
0
/*-------------------------------------------------------------------------
 * 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();
	}
}
Exemple #19
0
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 {
Exemple #20
0
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;
}
Exemple #21
0
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;
}
Exemple #22
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;
}
Exemple #23
0
void CDb3Mmap::WriteSignature(DBSignature &sign)
{
	memcpy(&m_dbHeader.signature, &sign, sizeof(DBSignature));
	DBWrite(0, &sign, sizeof(DBSignature));
}
Exemple #24
0
/*-------------------------------------------------------------------------
 * 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;
}
Exemple #25
0
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);
}
Exemple #26
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;
}
Exemple #27
0
/*-------------------------------------------------------------------------
 * 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;
}
Exemple #28
0
/*-------------------------------------------------------------------------
 * 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;
}
Exemple #29
0
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;
}
Exemple #30
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;
}