Beispiel #1
0
void MDatabaseCache::FreeCachedContact(MCONTACT contactID)
{
	mir_cslock lck(m_cs);

	int index = m_lContacts.getIndex((DBCachedContact*)&contactID);
	if (index == -1)
		return;

	DBCachedContact *cc = m_lContacts[index];
	DBCachedContactValue* V = cc->first;
	while (V != NULL) {
		DBCachedContactValue* V1 = V->next;
		FreeCachedVariant(&V->value);
		HeapFree(m_hCacheHeap, 0, V);
		V = V1;
	}

	mir_free(cc->pSubs);
	HeapFree(m_hCacheHeap, 0, cc);

	m_lContacts.remove(index);
}
Beispiel #2
0
static DBVARIANT* GetCachedValuePtr( HANDLE hContact, char* szSetting, int bAllocate )
{
	int index;

	if ( hContact == 0 ) {
		DBCachedGlobalValue Vtemp, *V;
		Vtemp.name = szSetting;
		if ( li.List_GetIndex(&lGlobalSettings,&Vtemp,&index)) {
			V = (DBCachedGlobalValue*)lGlobalSettings.items[index];
			if ( bAllocate == -1 ) {
				FreeCachedVariant( &V->value );
				li.List_Remove(&lGlobalSettings,index);
				HeapFree(hCacheHeap,0,V);
				return NULL;
		}	}
		else {
			if ( bAllocate != 1 )
				return NULL;

			V = (DBCachedGlobalValue*)HeapAlloc(hCacheHeap,HEAP_ZERO_MEMORY,sizeof(DBCachedGlobalValue));
			V->name = szSetting;
			li.List_Insert(&lGlobalSettings,V,index);
		}

		return &V->value;
	}
	else {
		DBCachedContactValue *V, *V1;
		DBCachedContactValueList VLtemp,*VL;

		if (hLastCachedContact==hContact && LastVL) {
			VL = LastVL;
		}
		else {
			VLtemp.hContact=hContact;

			if ( !li.List_GetIndex(&lContacts,&VLtemp,&index))
			{
				if ( bAllocate != 1 )
					return NULL;

				VL = AddToCachedContactList(hContact,index);
			}
			else VL = (DBCachedContactValueList*)lContacts.items[index];

			LastVL = VL;
			hLastCachedContact = hContact;
		}

		for ( V = VL->first; V != NULL; V = V->next)
			if (V->name == szSetting)
				break;

		if ( V == NULL ) {
			if ( bAllocate != 1 )
				return NULL;

			V = HeapAlloc(hCacheHeap,HEAP_ZERO_MEMORY,sizeof(DBCachedContactValue));
			if (VL->last)
				VL->last->next = V;
			else
				VL->first = V;
			VL->last = V;
			V->name = szSetting;
		}
		else if ( bAllocate == -1 ) {
		   LastVL = NULL;
			FreeCachedVariant(&V->value);
			if ( VL->first == V ) {
				VL->first = V->next;
				if (VL->last == V)
					VL->last = V->next; // NULL
			}
			else
				for ( V1 = VL->first; V1 != NULL; V1 = V1->next )
					if ( V1->next == V ) {
						V1->next = V->next;
						if (VL->last == V)
							VL->last = V1;
						break;
					}
			HeapFree(hCacheHeap,0,V);
			return NULL;
		}

		return &V->value;
}	}
Beispiel #3
0
STDMETHODIMP_(DBVARIANT*) MDatabaseCache::GetCachedValuePtr(MCONTACT contactID, char *szSetting, int bAllocate)
{
	// a global setting
	if (contactID == 0) {
		DBCachedGlobalValue Vtemp, *V;
		Vtemp.name = szSetting;
		int index = m_lGlobalSettings.getIndex(&Vtemp);
		if (index != -1) {
			V = m_lGlobalSettings[index];
			if (bAllocate == -1) {
				FreeCachedVariant(&V->value);
				m_lGlobalSettings.remove(index);
				HeapFree(m_hCacheHeap, 0, V);
				return NULL;
			}
		}
		else {
			if (bAllocate != 1)
				return NULL;

			V = (DBCachedGlobalValue*)HeapAlloc(m_hCacheHeap, HEAP_ZERO_MEMORY, sizeof(DBCachedGlobalValue));
			V->name = szSetting;
			m_lGlobalSettings.insert(V);
		}

		return &V->value;
	}

	// a contact setting
	DBCachedContactValue *V, *V1;
	DBCachedContact VLtemp,*VL;

	VLtemp.contactID = contactID;

	int index = m_lContacts.getIndex(&VLtemp);
	if (index == -1) {
		if ( bAllocate != 1 )
			return NULL;

		VL = AddContactToCache(contactID);
	}
	else VL = m_lContacts[index];

	m_lastVL = VL;

	for ( V = VL->first; V != NULL; V = V->next)
		if (V->name == szSetting)
			break;

	if ( V == NULL ) {
		if ( bAllocate != 1 )
			return NULL;

		V = (DBCachedContactValue *)HeapAlloc(m_hCacheHeap, HEAP_ZERO_MEMORY, sizeof(DBCachedContactValue));
		if (VL->last)
			VL->last->next = V;
		else
			VL->first = V;
		VL->last = V;
		V->name = szSetting;
	}
	else if ( bAllocate == -1 ) {
		m_lastVL = NULL;
		FreeCachedVariant(&V->value);
		if ( VL->first == V ) {
			VL->first = V->next;
			if (VL->last == V)
				VL->last = V->next; // NULL
		}
		else
			for ( V1 = VL->first; V1 != NULL; V1 = V1->next )
				if ( V1->next == V ) {
					V1->next = V->next;
					if (VL->last == V)
						VL->last = V1;
					break;
				}
		HeapFree(m_hCacheHeap,0,V);
		return NULL;
	}

	return &V->value;
}
Beispiel #4
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;
}