imgtools/romtools/rofsbuild/src/cache/cache.cpp
changeset 600 6d08f4a05d93
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/imgtools/romtools/rofsbuild/src/cache/cache.cpp	Fri Jun 25 18:11:34 2010 +0800
@@ -0,0 +1,242 @@
+/*
+* Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+
+#include <new>
+#include <cstring>
+#include <string>
+#include <iostream>
+#include <fstream>
+#include <queue>
+#include <map>
+
+#include "e32image.h"
+
+#include <filesystem.hpp>
+#include <thread/thread.hpp>
+#include <thread/mutex.hpp>
+#include <thread/condition_variable.hpp>
+
+#include "cache/cacheexception.hpp"
+#include "cache/cacheentry.hpp"
+#include "cache/cacheablelist.hpp"
+#include "cache/cache.hpp"
+#include "cache/cachegenerator.hpp"
+#include "cache/cachevalidator.hpp"
+#include "cache/cachemanager.hpp"
+#include <malloc.h>
+#ifdef __LINUX__
+#define _alloca alloca
+#endif
+
+Cache* Cache::Only = (Cache*)0;
+
+
+Cache* Cache::GetInstance(void) throw (CacheException)
+{
+	if(! Cache::Only)
+	{
+		Cache::Only = new (std::nothrow) Cache();
+		if(! Cache::Only)
+			throw CacheException(CacheException::RESOURCE_ALLOCATION_FAILURE);
+	}
+
+	return Cache::Only;
+}
+
+
+void Cache::Initialize(void) throw (CacheException)
+{
+	//create and open cache meta data file.
+	 
+	 
+	metafile = CacheManager::GetInstance()->GetCacheRoot();
+	metafile +=  "/.rofsmeta"; 
+	boost::filesystem::path metafilepath(metafile.c_str());
+	if(!exists(metafilepath))
+	{
+		//create cache root directory if it's not present.
+		boost::filesystem::path createcacheroot(CacheManager::GetInstance()->GetCacheRoot());
+		create_directory(createcacheroot);
+
+		//create cache index file.
+		ofstream openmetafile(metafilepath.file_string().c_str(), ios_base::app | ios_base::out);
+		if(! openmetafile.is_open())
+			throw CacheException(CacheException::CACHE_INVALID);
+		openmetafile.close();
+	}
+	printf("Loading cache meta file : %s\r\n", metafilepath.file_string().c_str());
+	ifstream metafileref(metafilepath.file_string().c_str(), ios_base::in);
+	if(! metafileref.is_open())
+		throw CacheException(CacheException::HARDDRIVE_FAILURE);
+
+	//read ROFS meta file and construct entry map.
+	string inboundbuffer;
+	while(getline(metafileref, inboundbuffer))
+	{
+		//validate cache index record.
+		if(! ValidateEntry(inboundbuffer))
+			throw CacheException(CacheException::CACHE_INVALID);
+
+		//instantiate a new instance of class CacheEntry.
+		CacheEntry* entryref = new (nothrow) CacheEntry();
+		if(!entryref)
+			throw CacheException(CacheException::RESOURCE_ALLOCATION_FAILURE);
+
+		//set entry's attributes.
+		
+		char* attrwalker  = (char*)_alloca(inboundbuffer.length() + 1);
+		memcpy(attrwalker,inboundbuffer.c_str(),inboundbuffer.length() + 1);
+		 
+		char* start = attrwalker ;
+		while(*start != ';')
+			start++;
+		*start++ = 0;
+		entryref->SetOriginalFilename(attrwalker);
+		attrwalker = start;
+		while(*start != ';')
+			start++;
+		*start++ = 0;
+		entryref->SetOriginalFileCreateTime(attrwalker);
+		attrwalker = start;
+		while(*start != ';')
+			start++;
+		*start++ = 0;
+		entryref->SetOriginalFileCompression(attrwalker);
+		attrwalker = start;
+		while(*start != ';')
+			start++;
+		*start++ = 0;
+		entryref->SetCachedFilename(attrwalker);
+		attrwalker = start;
+		entryref->SetCachedFileCompression(attrwalker);
+
+		//add newly created entry into entry-map.
+		string newentrystring(entryref->GetOriginalFilename());
+		CacheEntry* existentryref = entrymap[newentrystring];
+		if(existentryref) {
+			while(existentryref->GetNextEntry())
+				existentryref = existentryref->GetNextEntry();
+			existentryref->AppendEntry(entryref);
+		}
+		else {
+			entrymap[newentrystring] = entryref;
+		}
+
+		//reinitialize inbound buffer.
+		inboundbuffer.clear(); 
+	}
+
+	return;
+}
+
+
+CacheEntry* Cache::GetEntryList(const char* OriginalFilename)
+{
+	//retrieval could be performed concurrently.
+	boost::lock_guard<boost::mutex> lock(cachemutex);
+	string originalfile(OriginalFilename);
+	CacheEntry* resultentries = entrymap[originalfile];
+
+	return resultentries;
+}
+
+
+void Cache::AddEntry(const char* OriginalFilename, CacheEntry* EntryRef)
+{
+	string originalfile(OriginalFilename);
+
+	//addtions could be performed concurrently.
+	boost::lock_guard<boost::mutex> lock(cachemutex);
+
+	entrymap[originalfile] = EntryRef;
+
+	return;
+}
+
+
+void Cache::CloseCache(void) throw (CacheException)
+{
+	//open up the cache meta file.
+	boost::filesystem::path metafilepath(metafile);
+	ofstream metafileref;
+	if(! exists(metafilepath))
+		metafileref.open(metafilepath.file_string().c_str(), ios_base::out | ios_base::app);
+	else
+		metafileref.open(metafilepath.file_string().c_str(), ios_base::out | ios_base::trunc);
+	if(! metafileref.is_open())
+		throw CacheException(CacheException::HARDDRIVE_FAILURE);
+
+	//save cache meta onto hard drive along with changed cache files.
+	char* delimiter = ";";
+	map<string, CacheEntry*>::iterator mapitem;
+	for(mapitem=entrymap.begin(); mapitem != entrymap.end(); mapitem++)
+	{
+		CacheEntry* concreteentryref = (*mapitem).second;
+		while(concreteentryref)
+		{
+			metafileref.write(concreteentryref->GetOriginalFilename(), strlen(concreteentryref->GetOriginalFilename()));
+			metafileref.write(delimiter, strlen(delimiter));
+			metafileref.write(concreteentryref->GetOriginalFileCreateTime(), strlen(concreteentryref->GetOriginalFileCreateTime()));
+			metafileref.write(delimiter, strlen(delimiter));
+			metafileref.write(concreteentryref->GetOriginalFileCompressionID(), strlen(concreteentryref->GetOriginalFileCompressionID()));
+			metafileref.write(delimiter, strlen(delimiter));
+			metafileref.write(concreteentryref->GetCachedFilename(), strlen(concreteentryref->GetCachedFilename()));
+			metafileref.write(delimiter, strlen(delimiter));
+			metafileref.write(concreteentryref->GetCachedFileCompressionID(), strlen(concreteentryref->GetCachedFileCompressionID()));
+			metafileref.write("\n", strlen("\n"));
+
+//			CacheEntry* tobedeletedentryref = concreteentryref;
+			concreteentryref = concreteentryref->GetNextEntry();
+//			delete tobedeletedentryref;
+		}
+	}
+
+	//close cache meta file.
+	metafileref.close();
+
+	return;
+}
+
+
+bool Cache::ValidateEntry(string& EntryRawText)
+{
+	//an entry is formed as original_filename;original_file_create_time;original_file_compression_id;cached_filename;cached_file_compression_id(end of line - '\n')
+
+	//format validation.
+	int    semicolon         = 0;
+	size_t semicolonposition = 0;
+	while(1) {
+		semicolonposition = EntryRawText.find(';', semicolonposition);
+		if(semicolonposition != string::npos) {
+			semicolonposition++;
+			semicolon++;
+		}
+		else
+			break;
+	}
+	if(semicolon != 4)
+		return false;
+
+	return true;
+}
+
+
+Cache::Cache(void)
+{
+	 return;
+}
+