Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

Internet Explorer AdBlock

, 17 Jan 2008
Internet Explorer AdBlock Add-on
ieadblock_src.zip
IE AdBlockPS
IE AdBlockps.def
IE AdBlock
AdBlockBand.rgs
AdBlockBHO.rgs
bin
XListCtrlSSDU.lib
XListCtrlSSRU.lib
IE AdBlock.def
IE AdBlock.rgs
res
bmpToolbar.bmp
checkboxes.bmp
icoSettings.ico
XListCtrl
checkboxes.bmp
//*********************************************************************
// INCLUDES
//*********************************************************************

#include "stdafx.h"
#include "ListData.h"

//*********************************************************************
// INITIALISATION
//*********************************************************************

std::auto_ptr<CListData> CListData::sm_inst;

//*********************************************************************
// CONSTRUCTOR & DESTRUCTOR
//*********************************************************************

CListData::CListData()
{
	// Initialize classes
	m_pBlackList = new CAdList();
	m_pWhiteList = new CAdList();

	m_arrSync[BLACKLIST_DUTCHBLOCK.ArrayIndex] = 0;
	m_arrSync[BLACKLIST_FANBOY.ArrayIndex] = 0;

	m_bListDataLoaded = false;
}

//*********************************************************************
// PUBLIC FUNCTIONS
//*********************************************************************

CListData * CListData::Instance()
{
	if (sm_inst.get() == NULL)
	{
		sm_inst = auto_ptr<CListData>(new CListData);
	}
	return sm_inst.get();

	/* FOLLOWING CODE WORKS ONLY IN VC7
	if(sm_inst.get() == 0)
	sm_inst.reset(new CListData);
	return sm_inst.get();
	*/
}

//=====================================================================

bool CListData::LoadListData(CString sFilename)
{
	// Declare variables
	CMarkup xml;

	// Store filename
	m_sListFile = sFilename;

	// Load filename
	if (!xml.Load(sFilename))
	{
		return false;
	}

	// Make sure xml file is case insensitive
	xml.SetDocFlags(CMarkup::MDF_IGNORECASE);

	// Move into main element
	if (!xml.FindElem(_T("ieadblock")))
	{
		// Failed
		return false;
	}
	xml.IntoElem();

	// Read blacklist
	if (xml.FindElem(_T("blacklist")))
	{
		xml.IntoElem();
		m_pBlackList->Load(xml, true);
		xml.OutOfElem();
	}

	// Reset pointer
	xml.ResetMainPos();

	// Read whitelist
	if (xml.FindElem(_T("whitelist")))
	{
		xml.IntoElem();
		m_pWhiteList->Load(xml, true);
		xml.OutOfElem();
	}

	// List data is loaded
	m_bListDataLoaded = true;

	// Succeeded
	return true;
}

//=====================================================================

bool CListData::StoreListData(CString sFilename /* = _T("") */)
{
	// Get settings filename
	if (sFilename == _T(""))
	{
		// Use stored filename
		sFilename = m_sListFile;
	}

	// Create xml file
	CMarkup xml(_T("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"));

	// Add main element
	xml.AddElem(_T("ieadblock"));

	// Jump into element
	xml.IntoElem();

	// Add blacklist
	xml.AddElem(_T("blacklist"));
	xml.IntoElem();
	m_pBlackList->Store(xml);
	xml.OutOfElem();

	// Add whitelist
	xml.AddElem(_T("whitelist"));
	xml.IntoElem();
	m_pWhiteList->Store(xml);
	xml.OutOfElem();

	// Jump out of element
	xml.OutOfElem();

	// Format xml
	FormatXML(xml);

	// Save to file
	return xml.Save(sFilename);
}

//=====================================================================

CAdList * CListData::GetBlackList()
{
	if (m_pBlackList == NULL)
	{
		m_pBlackList = new CAdList();
	}

	return m_pBlackList;
}

//=====================================================================

CAdList * CListData::GetWhiteList()
{
	if (m_pWhiteList == NULL)
	{
		m_pWhiteList = new CAdList();
	}

	return m_pWhiteList;
}

//=====================================================================

int CListData::GetItemCount()
{
	// Declare variables
	int iCount = 0;

	// Add blacklist
	if (m_pBlackList != NULL)
	{
		iCount += m_pBlackList->GetPatternCount();
		iCount += m_pBlackList->GetRegularExpressionCount();
	}

	// Return result
	return iCount;
}

//=====================================================================

void CListData::Sync(BlackList oBlackList)
{
	// Declare variables
	CPath * pPath = CPath::Instance();
	CString sDestination = _T(""), sLine = _T("");
	HRESULT hr = S_OK;
	CStdioFile oFile;
	CArray<CString> arrItems;

	// Set up destination path
	sDestination.Format(_T("%s%s"), pPath->GetPathAdBlockTemp(), oBlackList.TempFile);

	// Download the file
	hr = URLDownloadToFile(NULL, oBlackList.URL, sDestination, 0, NULL);

	// Check if we succeeded
	if (FAILED(hr))
	{
		// Failed, exit function
		return;
	}

	// Open file
	if (!oFile.Open(sDestination, CFile::modeRead | CFile::shareDenyNone))
	{
		// Failed, exit function
		return;
	}

	// Initialize array
	arrItems.SetSize(0, 32);

	// Fill array list
	while (oFile.ReadString(sLine))
	{	
		arrItems.Add(sLine);
	}

	// We are at 10 % now
	m_arrSync[oBlackList.ArrayIndex] = 10;

	// Parse data
	ParseAdBlockList(&arrItems, oBlackList);

	// Close file
	oFile.Close();

	// Store list data
	StoreListData();

	// We are at 100 % now
	m_arrSync[oBlackList.ArrayIndex] = 100;
}

//=====================================================================

int CListData::GetSyncProgress(BlackList oBlackList)
{
	return m_arrSync[oBlackList.ArrayIndex];
}

//=====================================================================

void CListData::CleanUp()
{
	delete m_pBlackList;
	m_pBlackList = NULL;
	delete m_pWhiteList;
	m_pWhiteList = NULL;

	m_bListDataLoaded = false;
}

//=====================================================================

bool CListData::ListDataLoaded()
{
	return m_bListDataLoaded;
}

//*********************************************************************
// PRIVATE FUNCTIONS
//*********************************************************************

void CListData::ParseAdBlockList(CArray<CString> * pFileData,
								 BlackList oBlackList)
{
	// Declare variables
	CString sItem = _T("");
	bool bSkip = false, bSortAutomaticallyBlackList = true, bSortAutomaticallyWhiteList = true;
	int iCount = 0, iProgress = 0;

	// Don't sort for the moment for performance reasons
	bSortAutomaticallyBlackList = m_pBlackList->GetKeepSorted();
	m_pBlackList->SetKeepSorted(false);	
	bSortAutomaticallyWhiteList = m_pBlackList->GetKeepSorted();
	m_pWhiteList->SetKeepSorted(false);	

	// Loop all items in array
	iCount = (int)pFileData->GetCount();
	for (int i = 0; i < iCount; i++)
	{
		// Don't skip by default
		bSkip = false;

		// Get item
		sItem = pFileData->GetAt(i);

		// Is line beginning with a [ or ! => garbage
		if (((sItem.GetAt(0) == _T('[')) || (sItem.GetAt(0) == _T('!'))) && (!bSkip))
		{
			// Just some useless information, skip
			bSkip = true;
		}

		// Is this an exception? => whitelist item
		if ((sItem.Find(_T("@@")) == 0) && (!bSkip))
		{
			// Strip the @@
			sItem.Delete(0, 2);

			// Is line beginning and ending with a / => regular expression
			if ((sItem.GetAt(0) == _T('/')) && (sItem.GetAt(sItem.GetLength() - 1) == _T('/')))
			{
				m_pWhiteList->AddRegularExpression(sItem);
			}
			else
			{
				m_pWhiteList->AddPattern(sItem);
			}

			// We can now skip the item
			bSkip = true;
		}

		// Is line beginning and ending with a / => regular expression
		if ((sItem.GetAt(0) == _T('/')) && (sItem.GetAt(sItem.GetLength() - 1) == _T('/')) && (!bSkip))
		{
			// Add item to blacklist
			m_pBlackList->AddRegularExpression(sItem);

			// We can now skip the item
			bSkip = true;
		}

		// Should we still add the line?
		if (!bSkip)
		{
			// Add item to blacklist
			m_pBlackList->AddPattern(sItem);
		}

		// We worked out another item
		iProgress = (100 * i) / iCount;
		iProgress = (80 * iProgress) / 100;
		if (iProgress > 80)
		{
			iProgress = 80;
		}
		m_arrSync[oBlackList.ArrayIndex] = iProgress + 10;
	}

	// Restore automatically sort state
	m_pBlackList->SetKeepSorted(bSortAutomaticallyBlackList);
	m_pWhiteList->SetKeepSorted(bSortAutomaticallyBlackList);
}

//=====================================================================

void CListData::FormatXML(CMarkup & xml)
{
	// Process document to align elements, comments, processing instructions
	// Each of these kinds of nodes goes on a separate line except in mixed content
	// (mixed content is sensed by a text or CDATA Section in an element)
	// A new document is created from the old
	// The old is only replaced if there is a difference
	CMarkup xmlNew;

	// Indentation
	const bool bIndent = TRUE;
	const int nIndentSize = 2;

	// In depth first traversal, keep array of status of each unfinished level
	// Use the following bit flags to indicate status of level
	enum { LV_NEED_CRLF=1, LV_HAS_TEXT=2, LV_HAS_ELEM=4 };
	CUIntArray aFlags;
	aFlags.Add( 0 );
	int nLevel = 0;

	// Loop until we come out of the root node
	xml.ResetPos();
	int nAttrib;
	CString csSp;
	while ( 1 )
	{
		int nType = xml.FindNode();
		if ( ! nType )
		{
			if ( ! xml.OutOfElem() )
				break;

			// Indent end tag if contained elements and not mixed content
			if ( aFlags[nLevel] & LV_HAS_ELEM && ! (aFlags[nLevel] & LV_HAS_TEXT) )
			{
				csSp.Empty();
				if ( aFlags[nLevel] & LV_NEED_CRLF )
					csSp = "\r\n";
				if ( bIndent && nLevel - 1 > 0 )
				csSp += CString(' ',nIndentSize*(nLevel-1));
				if ( csSp.GetLength() )
					xmlNew.AddNode( xmlNew.MNT_WHITESPACE, csSp );
			}

			aFlags.RemoveAt( nLevel );
			--nLevel;
			xmlNew.OutOfElem();

			if ( aFlags[nLevel] & LV_NEED_CRLF )
			{
				csSp = "\r\n";
				xmlNew.AddNode( xmlNew.MNT_WHITESPACE, csSp );
				aFlags[nLevel] ^= LV_NEED_CRLF;
			}
		}
		else if ( nType == xml.MNT_WHITESPACE )
		{
			if ( aFlags[nLevel] & LV_HAS_TEXT )
				xmlNew.AddNode( nType, xml.GetData() );
		}
		else if ( nType & (xml.MNT_TEXT | xml.MNT_CDATA_SECTION) )
		{
			xmlNew.AddNode( nType, xml.GetData() );
		}
		else
		{
			csSp.Empty();
			if ( aFlags[nLevel] & LV_NEED_CRLF )
				csSp = "\r\n";
			if ( bIndent && nLevel && ! (aFlags[nLevel] & LV_HAS_TEXT) )
				csSp += CString(' ',nIndentSize*nLevel);
			if ( csSp.GetLength() )
				xmlNew.AddNode( xmlNew.MNT_WHITESPACE, csSp );

			if ( nType == xml.MNT_ELEMENT )
			{
				if ( ! (aFlags[nLevel] & LV_HAS_TEXT) )
					aFlags[nLevel] |= LV_NEED_CRLF;
				aFlags[nLevel] |= LV_HAS_ELEM;
				xmlNew.AddNode( nType, xml.GetTagName() );
				for ( nAttrib=0; ; ++nAttrib )
				{
					CString csAttrib = xml.GetAttribName( nAttrib );
					if ( csAttrib.IsEmpty() )
						break;
					xmlNew.SetAttrib( csAttrib, xml.GetAttrib(csAttrib) );
				}
				xml.IntoElem();

				// Scan for mixed content
				UINT nNewFlag = LV_NEED_CRLF;
				while ( xml.FindNode() )
				{
					if ( xml.GetNodeType() & (xml.MNT_TEXT | xml.MNT_CDATA_SECTION) )
					{
						nNewFlag = LV_HAS_TEXT;
						break;
					}
				}
				xml.ResetMainPos();

				xmlNew.IntoElem();
				aFlags.Add( nNewFlag );
				++nLevel;
			}
			else // COMMENT, PROCESSING_INSTRUCTION, DOCUMENT_TYPE
			{
				aFlags[nLevel] &= ~LV_NEED_CRLF;
				xmlNew.AddNode( nType, xml.GetData() );
				xmlNew.FindNode(); // position to trailing whitespace
			}
		}
	}

	xml = xmlNew;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)

Share

About the Author

Geert van Horrik
Software Developer CatenaLogic
Netherlands Netherlands
I am Geert van Horrik, and I have studied Computer Science in the Netherlands.
 
I love to write software using .NET (especially the combination of WPF and C#). I am also the lead developer of Catel, an open-source application development framework for WPF, Silverlight, WP7 and WinRT with the focus on MVVM.
 
I have my own company since January 1st 2007, called CatenaLogic. This company develops commercial and non-commercial software.
 
To download (or buy) applications I have written, visit my website: http://www.catenalogic.com
Follow on   Twitter

| Advertise | Privacy | Mobile
Web01 | 2.8.140827.1 | Last Updated 17 Jan 2008
Article Copyright 2008 by Geert van Horrik
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid