diff -r fa7a3cc6effd -r 6d08f4a05d93 imgtools/romtools/rofsbuild/src/cache/cache.cpp --- /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 +#include +#include +#include +#include +#include +#include + +#include "e32image.h" + +#include +#include +#include +#include + +#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 +#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 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 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::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; +} +