CacheUpdater.h revision 3fd340028fc24198edb23ddf5eb5a0a100bab745
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 HAVE_MS_C_RUNTIME
16#include <direct.h>
17#endif
18
19using 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 */
31class CacheUpdater {
32public:
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
44    virtual ~CacheUpdater() {}
45private:
46};
47
48/** SystemCacheUpdater
49 * This is an implementation of the above virtual cache updater specification.
50 * This implementations hits the filesystem to manage a cache and calls out to
51 * the PNG crunching in images.h to process images out to its cache components.
52 */
53class SystemCacheUpdater : public CacheUpdater {
54public:
55    // Constructor to set bundle to pass to preProcessImage
56    SystemCacheUpdater (Bundle* b)
57        : bundle(b) { };
58
59    // Make sure all the directories along this path exist
60    virtual void ensureDirectoriesExist(String8 path)
61    {
62        // Check to see if we're dealing with a fully qualified path
63        String8 existsPath;
64        String8 toCreate;
65        String8 remains;
66        struct stat s;
67
68        // Check optomistically to see if all directories exist.
69        // If something in the path doesn't exist, then walk the path backwards
70        // and find the place to start creating directories forward.
71        if (stat(path.string(),&s) == -1) {
72            // Walk backwards to find place to start creating directories
73            existsPath = path;
74            do {
75                // As we remove the end of existsPath add it to
76                // the string of paths to create.
77                toCreate = existsPath.getPathLeaf().appendPath(toCreate);
78                existsPath = existsPath.getPathDir();
79            } while (stat(existsPath.string(),&s) == -1);
80
81            // Walk forwards and build directories as we go
82            do {
83                // Advance to the next segment of the path
84                existsPath.appendPath(toCreate.walkPath(&remains));
85                toCreate = remains;
86#ifdef HAVE_MS_C_RUNTIME
87                _mkdir(existsPath.string());
88#else
89                mkdir(existsPath.string(), S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP);
90#endif
91            } while (remains.length() > 0);
92        } //if
93    };
94
95    // Delete a file
96    virtual void deleteFile(String8 path)
97    {
98        if (remove(path.string()) != 0)
99            fprintf(stderr,"ERROR DELETING %s\n",path.string());
100    };
101
102    // Process an image from source out to dest
103    virtual void processImage(String8 source, String8 dest)
104    {
105        // Make sure we're trying to write to a directory that is extant
106        ensureDirectoriesExist(dest.getPathDir());
107
108        preProcessImageToCache(bundle, source, dest);
109    };
110private:
111    Bundle* bundle;
112};
113
114#endif // CACHE_UPDATER_H
115