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