OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / frameworks / base / include / utils / Asset.h
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 //
18 // Class providing access to a read-only asset.  Asset objects are NOT
19 // thread-safe, and should not be shared across threads.
20 //
21 #ifndef __LIBS_ASSET_H
22 #define __LIBS_ASSET_H
23
24 #include <stdio.h>
25 #include <sys/types.h>
26 #include "FileMap.h"
27 #include "String8.h"
28 #include "Errors.h"
29
30 namespace android {
31
32 /*
33  * Instances of this class provide read-only operations on a byte stream.
34  *
35  * Access may be optimized for streaming, random, or whole buffer modes.  All
36  * operations are supported regardless of how the file was opened, but some
37  * things will be less efficient.  [pass that in??]
38  *
39  * "Asset" is the base class for all types of assets.  The classes below
40  * provide most of the implementation.  The AssetManager uses one of the
41  * static "create" functions defined here to create a new instance.
42  */
43 class Asset {
44 public:
45     virtual ~Asset(void);
46
47     static int32_t getGlobalCount();
48     static String8 getAssetAllocations();
49     
50     /* used when opening an asset */
51     typedef enum AccessMode {
52         ACCESS_UNKNOWN = 0,
53
54         /* read chunks, and seek forward and backward */
55         ACCESS_RANDOM,
56
57         /* read sequentially, with an occasional forward seek */
58         ACCESS_STREAMING,
59
60         /* caller plans to ask for a read-only buffer with all data */
61         ACCESS_BUFFER,
62     } AccessMode;
63
64     /*
65      * Read data from the current offset.  Returns the actual number of
66      * bytes read, 0 on EOF, or -1 on error.
67      */
68     virtual ssize_t read(void* buf, size_t count) = 0;
69
70     /*
71      * Seek to the specified offset.  "whence" uses the same values as
72      * lseek/fseek.  Returns the new position on success, or (off_t) -1
73      * on failure.
74      */
75     virtual off_t seek(off_t offset, int whence) = 0;
76
77     /*
78      * Close the asset, freeing all associated resources.
79      */
80     virtual void close(void) = 0;
81
82     /*
83      * Get a pointer to a buffer with the entire contents of the file.
84      */
85     virtual const void* getBuffer(bool wordAligned) = 0;
86
87     /*
88      * Get the total amount of data that can be read.
89      */
90     virtual off_t getLength(void) const = 0;
91
92     /*
93      * Get the total amount of data that can be read from the current position.
94      */
95     virtual off_t getRemainingLength(void) const = 0;
96
97     /*
98      * Open a new file descriptor that can be used to read this asset.
99      * Returns -1 if you can not use the file descriptor (for example if the
100      * asset is compressed).
101      */
102     virtual int openFileDescriptor(off_t* outStart, off_t* outLength) const = 0;
103     
104     /*
105      * Return whether this asset's buffer is allocated in RAM (not mmapped).
106      * Note: not virtual so it is safe to call even when being destroyed.
107      */
108     virtual bool isAllocated(void) const { return false; }
109     
110     /*
111      * Get a string identifying the asset's source.  This might be a full
112      * path, it might be a colon-separated list of identifiers.
113      *
114      * This is NOT intended to be used for anything except debug output.
115      * DO NOT try to parse this or use it to open a file.
116      */
117     const char* getAssetSource(void) const { return mAssetSource.string(); }
118
119 protected:
120     Asset(void);        // constructor; only invoked indirectly
121
122     /* handle common seek() housekeeping */
123     off_t handleSeek(off_t offset, int whence, off_t curPosn, off_t maxPosn);
124
125     /* set the asset source string */
126     void setAssetSource(const String8& path) { mAssetSource = path; }
127
128     AccessMode getAccessMode(void) const { return mAccessMode; }
129
130 private:
131     /* these operations are not implemented */
132     Asset(const Asset& src);
133     Asset& operator=(const Asset& src);
134
135     /* AssetManager needs access to our "create" functions */
136     friend class AssetManager;
137
138     /*
139      * Create the asset from a named file on disk.
140      */
141     static Asset* createFromFile(const char* fileName, AccessMode mode);
142
143     /*
144      * Create the asset from a named, compressed file on disk (e.g. ".gz").
145      */
146     static Asset* createFromCompressedFile(const char* fileName,
147         AccessMode mode);
148
149 #if 0
150     /*
151      * Create the asset from a segment of an open file.  This will fail
152      * if "offset" and "length" don't fit within the bounds of the file.
153      *
154      * The asset takes ownership of the file descriptor.
155      */
156     static Asset* createFromFileSegment(int fd, off_t offset, size_t length,
157         AccessMode mode);
158
159     /*
160      * Create from compressed data.  "fd" should be seeked to the start of
161      * the compressed data.  This could be inside a gzip file or part of a
162      * Zip archive.
163      *
164      * The asset takes ownership of the file descriptor.
165      *
166      * This may not verify the validity of the compressed data until first
167      * use.
168      */
169     static Asset* createFromCompressedData(int fd, off_t offset,
170         int compressionMethod, size_t compressedLength,
171         size_t uncompressedLength, AccessMode mode);
172 #endif
173
174     /*
175      * Create the asset from a memory-mapped file segment.
176      *
177      * The asset takes ownership of the FileMap.
178      */
179     static Asset* createFromUncompressedMap(FileMap* dataMap, AccessMode mode);
180
181     /*
182      * Create the asset from a memory-mapped file segment with compressed
183      * data.  "method" is a Zip archive compression method constant.
184      *
185      * The asset takes ownership of the FileMap.
186      */
187     static Asset* createFromCompressedMap(FileMap* dataMap, int method,
188         size_t uncompressedLen, AccessMode mode);
189
190
191     /*
192      * Create from a reference-counted chunk of shared memory.
193      */
194     // TODO
195
196     AccessMode  mAccessMode;        // how the asset was opened
197     String8    mAssetSource;       // debug string
198     
199     Asset*              mNext;                          // linked list.
200     Asset*              mPrev;
201 };
202
203
204 /*
205  * ===========================================================================
206  *
207  * Innards follow.  Do not use these classes directly.
208  */
209
210 /*
211  * An asset based on an uncompressed file on disk.  It may encompass the
212  * entire file or just a piece of it.  Access is through fread/fseek.
213  */
214 class _FileAsset : public Asset {
215 public:
216     _FileAsset(void);
217     virtual ~_FileAsset(void);
218
219     /*
220      * Use a piece of an already-open file.
221      *
222      * On success, the object takes ownership of "fd".
223      */
224     status_t openChunk(const char* fileName, int fd, off_t offset, size_t length);
225
226     /*
227      * Use a memory-mapped region.
228      *
229      * On success, the object takes ownership of "dataMap".
230      */
231     status_t openChunk(FileMap* dataMap);
232
233     /*
234      * Standard Asset interfaces.
235      */
236     virtual ssize_t read(void* buf, size_t count);
237     virtual off_t seek(off_t offset, int whence);
238     virtual void close(void);
239     virtual const void* getBuffer(bool wordAligned);
240     virtual off_t getLength(void) const { return mLength; }
241     virtual off_t getRemainingLength(void) const { return mLength-mOffset; }
242     virtual int openFileDescriptor(off_t* outStart, off_t* outLength) const;
243     virtual bool isAllocated(void) const { return mBuf != NULL; }
244
245 private:
246     off_t       mStart;         // absolute file offset of start of chunk
247     off_t       mLength;        // length of the chunk
248     off_t       mOffset;        // current local offset, 0 == mStart
249     FILE*       mFp;            // for read/seek
250     char*       mFileName;      // for opening
251
252     /*
253      * To support getBuffer() we either need to read the entire thing into
254      * a buffer or memory-map it.  For small files it's probably best to
255      * just read them in.
256      */
257     enum { kReadVsMapThreshold = 4096 };
258
259     FileMap*    mMap;           // for memory map
260     unsigned char* mBuf;        // for read
261     
262     const void* ensureAlignment(FileMap* map);
263 };
264
265
266 /*
267  * An asset based on compressed data in a file.
268  */
269 class _CompressedAsset : public Asset {
270 public:
271     _CompressedAsset(void);
272     virtual ~_CompressedAsset(void);
273
274     /*
275      * Use a piece of an already-open file.
276      *
277      * On success, the object takes ownership of "fd".
278      */
279     status_t openChunk(int fd, off_t offset, int compressionMethod,
280         size_t uncompressedLen, size_t compressedLen);
281
282     /*
283      * Use a memory-mapped region.
284      *
285      * On success, the object takes ownership of "fd".
286      */
287     status_t openChunk(FileMap* dataMap, int compressionMethod,
288         size_t uncompressedLen);
289
290     /*
291      * Standard Asset interfaces.
292      */
293     virtual ssize_t read(void* buf, size_t count);
294     virtual off_t seek(off_t offset, int whence);
295     virtual void close(void);
296     virtual const void* getBuffer(bool wordAligned);
297     virtual off_t getLength(void) const { return mUncompressedLen; }
298     virtual off_t getRemainingLength(void) const { return mUncompressedLen-mOffset; }
299     virtual int openFileDescriptor(off_t* outStart, off_t* outLength) const { return -1; }
300     virtual bool isAllocated(void) const { return mBuf != NULL; }
301
302 private:
303     off_t       mStart;         // offset to start of compressed data
304     off_t       mCompressedLen; // length of the compressed data
305     off_t       mUncompressedLen; // length of the uncompressed data
306     off_t       mOffset;        // current offset, 0 == start of uncomp data
307
308     FileMap*    mMap;           // for memory-mapped input
309     int         mFd;            // for file input
310
311     class StreamingZipInflater* mZipInflater;  // for streaming large compressed assets
312
313     unsigned char*  mBuf;       // for getBuffer()
314 };
315
316 // need: shared mmap version?
317
318 }; // namespace android
319
320 #endif // __LIBS_ASSET_H