// // Copyright 2011 The Android Open Source Project // // Abstraction of calls to system to make directories and delete files and // wrapper to image processing. #ifndef CACHE_UPDATER_H #define CACHE_UPDATER_H #include <utils/String8.h> #include <sys/types.h> #include <sys/stat.h> #include <stdio.h> #include "Images.h" #ifdef HAVE_MS_C_RUNTIME #include <direct.h> #endif using namespace android; /** CacheUpdater * This is a pure virtual class that declares abstractions of functions useful * for managing a cache files. This manager is set up to be used in a * mirror cache where the source tree is duplicated and filled with processed * images. This class is abstracted to allow for dependency injection during * unit testing. * Usage: * To update/add a file to the cache, call processImage * To remove a file from the cache, call deleteFile */ class CacheUpdater { public: virtual ~CacheUpdater() {} // Make sure all the directories along this path exist virtual void ensureDirectoriesExist(String8 path) = 0; // Delete a file virtual void deleteFile(String8 path) = 0; // Process an image from source out to dest virtual void processImage(String8 source, String8 dest) = 0; private: }; /** SystemCacheUpdater * This is an implementation of the above virtual cache updater specification. * This implementations hits the filesystem to manage a cache and calls out to * the PNG crunching in images.h to process images out to its cache components. */ class SystemCacheUpdater : public CacheUpdater { public: // Constructor to set bundle to pass to preProcessImage SystemCacheUpdater (Bundle* b) : bundle(b) { }; // Make sure all the directories along this path exist virtual void ensureDirectoriesExist(String8 path) { // Check to see if we're dealing with a fully qualified path String8 existsPath; String8 toCreate; String8 remains; struct stat s; // Check optomistically to see if all directories exist. // If something in the path doesn't exist, then walk the path backwards // and find the place to start creating directories forward. if (stat(path.string(),&s) == -1) { // Walk backwards to find place to start creating directories existsPath = path; do { // As we remove the end of existsPath add it to // the string of paths to create. toCreate = existsPath.getPathLeaf().appendPath(toCreate); existsPath = existsPath.getPathDir(); } while (stat(existsPath.string(),&s) == -1); // Walk forwards and build directories as we go do { // Advance to the next segment of the path existsPath.appendPath(toCreate.walkPath(&remains)); toCreate = remains; #ifdef HAVE_MS_C_RUNTIME _mkdir(existsPath.string()); #else mkdir(existsPath.string(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP); #endif } while (remains.length() > 0); } //if }; // Delete a file virtual void deleteFile(String8 path) { if (remove(path.string()) != 0) fprintf(stderr,"ERROR DELETING %s\n",path.string()); }; // Process an image from source out to dest virtual void processImage(String8 source, String8 dest) { // Make sure we're trying to write to a directory that is extant ensureDirectoriesExist(dest.getPathDir()); preProcessImageToCache(bundle, source, dest); }; private: Bundle* bundle; }; #endif // CACHE_UPDATER_H