CacheUpdater.h revision 8a39da80b33691b0c82458c3b7727e13ff71277e
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
16using 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 */
28class CacheUpdater {
29public:
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;
38private:
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 */
46class SystemCacheUpdater : public CacheUpdater {
47public:
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    };
103private:
104    Bundle* bundle;
105};
106
107#endif // CACHE_UPDATER_H