Home | History | Annotate | Download | only in aapt
      1 //
      2 // Copyright 2011 The Android Open Source Project
      3 //
      4 // Abstraction of calls to system to make directories and delete files and
      5 // wrapper to image processing.
      6 
      7 #ifndef CACHE_UPDATER_H
      8 #define CACHE_UPDATER_H
      9 
     10 #include <utils/String8.h>
     11 #include <sys/types.h>
     12 #include <sys/stat.h>
     13 #include <stdio.h>
     14 #include "Images.h"
     15 
     16 using namespace android;
     17 
     18 /** CacheUpdater
     19  *  This is a pure virtual class that declares abstractions of functions useful
     20  *  for managing a cache files. This manager is set up to be used in a
     21  *  mirror cache where the source tree is duplicated and filled with processed
     22  *  images. This class is abstracted to allow for dependency injection during
     23  *  unit testing.
     24  *  Usage:
     25  *      To update/add a file to the cache, call processImage
     26  *      To remove a file from the cache, call deleteFile
     27  */
     28 class CacheUpdater {
     29 public:
     30     // Make sure all the directories along this path exist
     31     virtual void ensureDirectoriesExist(String8 path) = 0;
     32 
     33     // Delete a file
     34     virtual void deleteFile(String8 path) = 0;
     35 
     36     // Process an image from source out to dest
     37     virtual void processImage(String8 source, String8 dest) = 0;
     38 private:
     39 };
     40 
     41 /** SystemCacheUpdater
     42  * This is an implementation of the above virtual cache updater specification.
     43  * This implementations hits the filesystem to manage a cache and calls out to
     44  * the PNG crunching in images.h to process images out to its cache components.
     45  */
     46 class SystemCacheUpdater : public CacheUpdater {
     47 public:
     48     // Constructor to set bundle to pass to preProcessImage
     49     SystemCacheUpdater (Bundle* b)
     50         : bundle(b) { };
     51 
     52     // Make sure all the directories along this path exist
     53     virtual void ensureDirectoriesExist(String8 path)
     54     {
     55         // Check to see if we're dealing with a fully qualified path
     56         String8 existsPath;
     57         String8 toCreate;
     58         String8 remains;
     59         struct stat s;
     60 
     61         // Check optomistically to see if all directories exist.
     62         // If something in the path doesn't exist, then walk the path backwards
     63         // and find the place to start creating directories forward.
     64         if (stat(path.string(),&s) == -1) {
     65             // Walk backwards to find place to start creating directories
     66             existsPath = path;
     67             do {
     68                 // As we remove the end of existsPath add it to
     69                 // the string of paths to create.
     70                 toCreate = existsPath.getPathLeaf().appendPath(toCreate);
     71                 existsPath = existsPath.getPathDir();
     72             } while (stat(existsPath.string(),&s) == -1);
     73 
     74             // Walk forwards and build directories as we go
     75             do {
     76                 // Advance to the next segment of the path
     77                 existsPath.appendPath(toCreate.walkPath(&remains));
     78                 toCreate = remains;
     79 #ifdef HAVE_MS_C_RUNTIME
     80                 _mkdir(existsPath.string());
     81 #else
     82                 mkdir(existsPath.string(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP);
     83 #endif
     84             } while (remains.length() > 0);
     85         } //if
     86     };
     87 
     88     // Delete a file
     89     virtual void deleteFile(String8 path)
     90     {
     91         if (remove(path.string()) != 0)
     92             fprintf(stderr,"ERROR DELETING %s\n",path.string());
     93     };
     94 
     95     // Process an image from source out to dest
     96     virtual void processImage(String8 source, String8 dest)
     97     {
     98         // Make sure we're trying to write to a directory that is extant
     99         ensureDirectoriesExist(dest.getPathDir());
    100 
    101         preProcessImageToCache(bundle, source, dest);
    102     };
    103 private:
    104     Bundle* bundle;
    105 };
    106 
    107 #endif // CACHE_UPDATER_H