Initial Contribution
diff --git a/include/utils/AndroidUnicode.h b/include/utils/AndroidUnicode.h
new file mode 100644
index 0000000..563fcd0
--- /dev/null
+++ b/include/utils/AndroidUnicode.h
@@ -0,0 +1,255 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+
+#ifndef ANDROID_UNICODE_H
+#define ANDROID_UNICODE_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#define REPLACEMENT_CHAR (0xFFFD)
+
+// this part of code is copied from umachine.h under ICU
+/**
+ * Define UChar32 as a type for single Unicode code points.
+ * UChar32 is a signed 32-bit integer (same as int32_t).
+ *
+ * The Unicode code point range is 0..0x10ffff.
+ * All other values (negative or >=0x110000) are illegal as Unicode code points.
+ * They may be used as sentinel values to indicate "done", "error"
+ * or similar non-code point conditions.
+ *
+ * @stable ICU 2.4
+ */
+typedef int32_t UChar32;
+
+namespace android {
+
+ class Encoding;
+ /**
+ * \class Unicode
+ *
+ * Helper class for getting properties of Unicode characters. Characters
+ * can have one of the types listed in CharType and each character can have the
+ * directionality of Direction.
+ */
+ class Unicode
+ {
+ public:
+ /**
+ * Directions specified in the Unicode standard. These directions map directly
+ * to java.lang.Character.
+ */
+ enum Direction {
+ DIRECTIONALITY_UNDEFINED = -1,
+ DIRECTIONALITY_LEFT_TO_RIGHT,
+ DIRECTIONALITY_RIGHT_TO_LEFT,
+ DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC,
+ DIRECTIONALITY_EUROPEAN_NUMBER,
+ DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR,
+ DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR,
+ DIRECTIONALITY_ARABIC_NUMBER,
+ DIRECTIONALITY_COMMON_NUMBER_SEPARATOR,
+ DIRECTIONALITY_NONSPACING_MARK,
+ DIRECTIONALITY_BOUNDARY_NEUTRAL,
+ DIRECTIONALITY_PARAGRAPH_SEPARATOR,
+ DIRECTIONALITY_SEGMENT_SEPARATOR,
+ DIRECTIONALITY_WHITESPACE,
+ DIRECTIONALITY_OTHER_NEUTRALS,
+ DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING,
+ DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE,
+ DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING,
+ DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE,
+ DIRECTIONALITY_POP_DIRECTIONAL_FORMAT
+ };
+
+ /**
+ * Character types as specified in the Unicode standard. These map directly to
+ * java.lang.Character.
+ */
+ enum CharType {
+ CHARTYPE_UNASSIGNED = 0,
+ CHARTYPE_UPPERCASE_LETTER,
+ CHARTYPE_LOWERCASE_LETTER,
+ CHARTYPE_TITLECASE_LETTER,
+ CHARTYPE_MODIFIER_LETTER,
+ CHARTYPE_OTHER_LETTER,
+ CHARTYPE_NON_SPACING_MARK,
+ CHARTYPE_ENCLOSING_MARK,
+ CHARTYPE_COMBINING_SPACING_MARK,
+ CHARTYPE_DECIMAL_DIGIT_NUMBER,
+ CHARTYPE_LETTER_NUMBER,
+ CHARTYPE_OTHER_NUMBER,
+ CHARTYPE_SPACE_SEPARATOR,
+ CHARTYPE_LINE_SEPARATOR,
+ CHARTYPE_PARAGRAPH_SEPARATOR,
+ CHARTYPE_CONTROL,
+ CHARTYPE_FORMAT,
+ CHARTYPE_MISSING_VALUE_FOR_JAVA, /* This is the mysterious missing 17 value from the java constants */
+ CHARTYPE_PRIVATE_USE,
+ CHARTYPE_SURROGATE,
+ CHARTYPE_DASH_PUNCTUATION,
+ CHARTYPE_START_PUNCTUATION,
+ CHARTYPE_END_PUNCTUATION,
+ CHARTYPE_CONNECTOR_PUNCTUATION,
+ CHARTYPE_OTHER_PUNCTUATION,
+ CHARTYPE_MATH_SYMBOL,
+ CHARTYPE_CURRENCY_SYMBOL,
+ CHARTYPE_MODIFIER_SYMBOL,
+ CHARTYPE_OTHER_SYMBOL,
+ CHARTYPE_INITIAL_QUOTE_PUNCTUATION,
+ CHARTYPE_FINAL_QUOTE_PUNCTUATION
+ };
+
+ /**
+ * Decomposition types as described by the unicode standard. These values map to
+ * the same values in uchar.h in ICU.
+ */
+ enum DecompositionType {
+ DECOMPOSITION_NONE = 0,
+ DECOMPOSITION_CANONICAL,
+ DECOMPOSITION_COMPAT,
+ DECOMPOSITION_CIRCLE,
+ DECOMPOSITION_FINAL,
+ DECOMPOSITION_FONT,
+ DECOMPOSITION_FRACTION,
+ DECOMPOSITION_INITIAL,
+ DECOMPOSITION_ISOLATED,
+ DECOMPOSITION_MEDIAL,
+ DECOMPOSITION_NARROW,
+ DECOMPOSITION_NOBREAK,
+ DECOMPOSITION_SMALL,
+ DECOMPOSITION_SQUARE,
+ DECOMPOSITION_SUB,
+ DECOMPOSITION_SUPER,
+ DECOMPOSITION_VERTICAL,
+ DECOMPOSITION_WIDE
+ };
+
+ /**
+ * Returns the packed data for java calls
+ * @param c The unicode character.
+ * @return The packed data for the character.
+ *
+ * Copied from java.lang.Character implementation:
+ * 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+ * F E D C B A 9 8 7 6 5 4 3 2 1 0 F E D C B A 9 8 7 6 5 4 3 2 1 0
+ *
+ * 31 types ---------
+ * 18 directionalities ---------
+ * 2 mirroreds -
+ * ----------- 56 toupper diffs
+ * ----------- 48 tolower diffs
+ * --- 4 totitlecase diffs
+ * ------------- 84 numeric values
+ * --------- 24 mirror char diffs
+ */
+ static uint32_t getPackedData(UChar32 c);
+
+ /**
+ * Get the Character type.
+ * @param c The unicode character.
+ * @return The character's type or CHARTYPE_UNASSIGNED if the character is invalid
+ * or has an unassigned class.
+ */
+ static CharType getType(UChar32 c);
+
+ /**
+ * Get the Character's decomposition type.
+ * @param c The unicode character.
+ * @return The character's decomposition type or DECOMPOSITION_NONE is there
+ * is no decomposition.
+ */
+ static DecompositionType getDecompositionType(UChar32 c);
+
+ /**
+ * Returns the digit value of a character or -1 if the character
+ * is not within the specified radix.
+ *
+ * The digit value is computed for integer characters and letters
+ * within the given radix. This function does not handle Roman Numerals,
+ * fractions, or any other characters that may represent numbers.
+ *
+ * @param c The unicode character
+ * @param radix The intended radix.
+ * @return The digit value or -1 if there is no digit value or if the value is outside the radix.
+ */
+ static int getDigitValue(UChar32 c, int radix = 10);
+
+ /**
+ * Return the numeric value of a character
+ *
+ * @param c The unicode character.
+ * @return The numeric value of the character. -1 if the character has no numeric value,
+ * -2 if the character has a numeric value that is not representable by an integer.
+ */
+ static int getNumericValue(UChar32 c);
+
+ /**
+ * Convert the character to lowercase
+ * @param c The unicode character.
+ * @return The lowercase character equivalent of c. If c does not have a lowercase equivalent,
+ * the original character is returned.
+ */
+ static UChar32 toLower(UChar32 c);
+
+ /**
+ * Convert the character to uppercase
+ * @param c The unicode character.
+ * @return The uppercase character equivalent of c. If c does not have an uppercase equivalent,
+ * the original character is returned.
+ */
+ static UChar32 toUpper(UChar32 c);
+
+ /**
+ * Get the directionality of the character.
+ * @param c The unicode character.
+ * @return The direction of the character or DIRECTIONALITY_UNDEFINED.
+ */
+ static Direction getDirectionality(UChar32 c);
+
+ /**
+ * Check if the character is a mirrored character. This means that the character
+ * has an equivalent character that is the mirror image of itself.
+ * @param c The unicode character.
+ * @return True iff c has a mirror equivalent.
+ */
+ static bool isMirrored(UChar32 c);
+
+ /**
+ * Return the mirror of the given character.
+ * @param c The unicode character.
+ * @return The mirror equivalent of c. If c does not have a mirror equivalent,
+ * the original character is returned.
+ * @see isMirrored
+ */
+ static UChar32 toMirror(UChar32 c);
+
+ /**
+ * Convert the character to title case.
+ * @param c The unicode character.
+ * @return The titlecase equivalent of c. If c does not have a titlecase equivalent,
+ * the original character is returned.
+ */
+ static UChar32 toTitle(UChar32 c);
+
+ };
+
+}
+
+#endif
diff --git a/include/utils/Asset.h b/include/utils/Asset.h
new file mode 100644
index 0000000..d8351f5
--- /dev/null
+++ b/include/utils/Asset.h
@@ -0,0 +1,311 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Class providing access to a read-only asset. Asset objects are NOT
+// thread-safe, and should not be shared across threads.
+//
+#ifndef __LIBS_ASSET_H
+#define __LIBS_ASSET_H
+
+#include <stdio.h>
+#include <sys/types.h>
+#include "FileMap.h"
+#include "String8.h"
+#include "Errors.h"
+
+namespace android {
+
+/*
+ * Instances of this class provide read-only operations on a byte stream.
+ *
+ * Access may be optimized for streaming, random, or whole buffer modes. All
+ * operations are supported regardless of how the file was opened, but some
+ * things will be less efficient. [pass that in??]
+ *
+ * "Asset" is the base class for all types of assets. The classes below
+ * provide most of the implementation. The AssetManager uses one of the
+ * static "create" functions defined here to create a new instance.
+ */
+class Asset {
+public:
+ virtual ~Asset(void);
+
+ static int32_t getGlobalCount();
+
+ /* used when opening an asset */
+ typedef enum AccessMode {
+ ACCESS_UNKNOWN = 0,
+
+ /* read chunks, and seek forward and backward */
+ ACCESS_RANDOM,
+
+ /* read sequentially, with an occasional forward seek */
+ ACCESS_STREAMING,
+
+ /* caller plans to ask for a read-only buffer with all data */
+ ACCESS_BUFFER,
+ } AccessMode;
+
+ enum {
+ /* data larger than this does not get uncompressed into a buffer */
+ UNCOMPRESS_DATA_MAX = 1 * 1024 * 1024
+ };
+
+ /*
+ * Read data from the current offset. Returns the actual number of
+ * bytes read, 0 on EOF, or -1 on error.
+ */
+ virtual ssize_t read(void* buf, size_t count) = 0;
+
+ /*
+ * Seek to the specified offset. "whence" uses the same values as
+ * lseek/fseek. Returns the new position on success, or (off_t) -1
+ * on failure.
+ */
+ virtual off_t seek(off_t offset, int whence) = 0;
+
+ /*
+ * Close the asset, freeing all associated resources.
+ */
+ virtual void close(void) = 0;
+
+ /*
+ * Get a pointer to a buffer with the entire contents of the file.
+ */
+ virtual const void* getBuffer(bool wordAligned) = 0;
+
+ /*
+ * Get the total amount of data that can be read.
+ */
+ virtual off_t getLength(void) const = 0;
+
+ /*
+ * Get the total amount of data that can be read from the current position.
+ */
+ virtual off_t getRemainingLength(void) const = 0;
+
+ /*
+ * Open a new file descriptor that can be used to read this asset.
+ * Returns -1 if you can not use the file descriptor (for example if the
+ * asset is compressed).
+ */
+ virtual int openFileDescriptor(off_t* outStart, off_t* outLength) const = 0;
+
+ /*
+ * Get a string identifying the asset's source. This might be a full
+ * path, it might be a colon-separated list of identifiers.
+ *
+ * This is NOT intended to be used for anything except debug output.
+ * DO NOT try to parse this or use it to open a file.
+ */
+ const char* getAssetSource(void) const { return mAssetSource.string(); }
+
+protected:
+ Asset(void); // constructor; only invoked indirectly
+
+ /* handle common seek() housekeeping */
+ off_t handleSeek(off_t offset, int whence, off_t curPosn, off_t maxPosn);
+
+ /* set the asset source string */
+ void setAssetSource(const String8& path) { mAssetSource = path; }
+
+ AccessMode getAccessMode(void) const { return mAccessMode; }
+
+private:
+ /* these operations are not implemented */
+ Asset(const Asset& src);
+ Asset& operator=(const Asset& src);
+
+ /* AssetManager needs access to our "create" functions */
+ friend class AssetManager;
+
+ /*
+ * Create the asset from a named file on disk.
+ */
+ static Asset* createFromFile(const char* fileName, AccessMode mode);
+
+ /*
+ * Create the asset from a named, compressed file on disk (e.g. ".gz").
+ */
+ static Asset* createFromCompressedFile(const char* fileName,
+ AccessMode mode);
+
+#if 0
+ /*
+ * Create the asset from a segment of an open file. This will fail
+ * if "offset" and "length" don't fit within the bounds of the file.
+ *
+ * The asset takes ownership of the file descriptor.
+ */
+ static Asset* createFromFileSegment(int fd, off_t offset, size_t length,
+ AccessMode mode);
+
+ /*
+ * Create from compressed data. "fd" should be seeked to the start of
+ * the compressed data. This could be inside a gzip file or part of a
+ * Zip archive.
+ *
+ * The asset takes ownership of the file descriptor.
+ *
+ * This may not verify the validity of the compressed data until first
+ * use.
+ */
+ static Asset* createFromCompressedData(int fd, off_t offset,
+ int compressionMethod, size_t compressedLength,
+ size_t uncompressedLength, AccessMode mode);
+#endif
+
+ /*
+ * Create the asset from a memory-mapped file segment.
+ *
+ * The asset takes ownership of the FileMap.
+ */
+ static Asset* createFromUncompressedMap(FileMap* dataMap, AccessMode mode);
+
+ /*
+ * Create the asset from a memory-mapped file segment with compressed
+ * data. "method" is a Zip archive compression method constant.
+ *
+ * The asset takes ownership of the FileMap.
+ */
+ static Asset* createFromCompressedMap(FileMap* dataMap, int method,
+ size_t uncompressedLen, AccessMode mode);
+
+
+ /*
+ * Create from a reference-counted chunk of shared memory.
+ */
+ // TODO
+
+ AccessMode mAccessMode; // how the asset was opened
+ String8 mAssetSource; // debug string
+};
+
+
+/*
+ * ===========================================================================
+ *
+ * Innards follow. Do not use these classes directly.
+ */
+
+/*
+ * An asset based on an uncompressed file on disk. It may encompass the
+ * entire file or just a piece of it. Access is through fread/fseek.
+ */
+class _FileAsset : public Asset {
+public:
+ _FileAsset(void);
+ virtual ~_FileAsset(void);
+
+ /*
+ * Use a piece of an already-open file.
+ *
+ * On success, the object takes ownership of "fd".
+ */
+ status_t openChunk(const char* fileName, int fd, off_t offset, size_t length);
+
+ /*
+ * Use a memory-mapped region.
+ *
+ * On success, the object takes ownership of "dataMap".
+ */
+ status_t openChunk(FileMap* dataMap);
+
+ /*
+ * Standard Asset interfaces.
+ */
+ virtual ssize_t read(void* buf, size_t count);
+ virtual off_t seek(off_t offset, int whence);
+ virtual void close(void);
+ virtual const void* getBuffer(bool wordAligned);
+ virtual off_t getLength(void) const { return mLength; }
+ virtual off_t getRemainingLength(void) const { return mLength-mOffset; }
+ virtual int openFileDescriptor(off_t* outStart, off_t* outLength) const;
+
+private:
+ off_t mStart; // absolute file offset of start of chunk
+ off_t mLength; // length of the chunk
+ off_t mOffset; // current local offset, 0 == mStart
+ FILE* mFp; // for read/seek
+ char* mFileName; // for opening
+
+ /*
+ * To support getBuffer() we either need to read the entire thing into
+ * a buffer or memory-map it. For small files it's probably best to
+ * just read them in.
+ */
+ enum { kReadVsMapThreshold = 4096 };
+
+ FileMap* mMap; // for memory map
+ unsigned char* mBuf; // for read
+
+ const void* ensureAlignment(FileMap* map);
+};
+
+
+/*
+ * An asset based on compressed data in a file.
+ */
+class _CompressedAsset : public Asset {
+public:
+ _CompressedAsset(void);
+ virtual ~_CompressedAsset(void);
+
+ /*
+ * Use a piece of an already-open file.
+ *
+ * On success, the object takes ownership of "fd".
+ */
+ status_t openChunk(int fd, off_t offset, int compressionMethod,
+ size_t uncompressedLen, size_t compressedLen);
+
+ /*
+ * Use a memory-mapped region.
+ *
+ * On success, the object takes ownership of "fd".
+ */
+ status_t openChunk(FileMap* dataMap, int compressionMethod,
+ size_t uncompressedLen);
+
+ /*
+ * Standard Asset interfaces.
+ */
+ virtual ssize_t read(void* buf, size_t count);
+ virtual off_t seek(off_t offset, int whence);
+ virtual void close(void);
+ virtual const void* getBuffer(bool wordAligned);
+ virtual off_t getLength(void) const { return mUncompressedLen; }
+ virtual off_t getRemainingLength(void) const { return mUncompressedLen-mOffset; }
+ virtual int openFileDescriptor(off_t* outStart, off_t* outLength) const { return -1; }
+
+private:
+ off_t mStart; // offset to start of compressed data
+ off_t mCompressedLen; // length of the compressed data
+ off_t mUncompressedLen; // length of the uncompressed data
+ off_t mOffset; // current offset, 0 == start of uncomp data
+
+ FileMap* mMap; // for memory-mapped input
+ int mFd; // for file input
+
+ unsigned char* mBuf; // for getBuffer()
+};
+
+// need: shared mmap version?
+
+}; // namespace android
+
+#endif // __LIBS_ASSET_H
diff --git a/include/utils/AssetDir.h b/include/utils/AssetDir.h
new file mode 100644
index 0000000..abf8a35
--- /dev/null
+++ b/include/utils/AssetDir.h
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Access a chunk of the asset hierarchy as if it were a single directory.
+//
+#ifndef __LIBS_ASSETDIR_H
+#define __LIBS_ASSETDIR_H
+
+#include <utils/String8.h>
+#include <utils/Vector.h>
+#include <utils/SortedVector.h>
+#include <utils/misc.h>
+#include <sys/types.h>
+
+namespace android {
+
+/*
+ * This provides vector-style access to a directory. We do this rather
+ * than modeling opendir/readdir access because it's simpler and the
+ * nature of the operation requires us to have all data on hand anyway.
+ *
+ * The list of files will be sorted in ascending order by ASCII value.
+ *
+ * The contents are populated by our friend, the AssetManager.
+ */
+class AssetDir {
+public:
+ AssetDir(void)
+ : mFileInfo(NULL)
+ {}
+ virtual ~AssetDir(void) {
+ delete mFileInfo;
+ }
+
+ /*
+ * Vector-style access.
+ */
+ size_t getFileCount(void) { return mFileInfo->size(); }
+ const String8& getFileName(int idx) {
+ return mFileInfo->itemAt(idx).getFileName();
+ }
+ const String8& getSourceName(int idx) {
+ return mFileInfo->itemAt(idx).getSourceName();
+ }
+
+ /*
+ * Get the type of a file (usually regular or directory).
+ */
+ FileType getFileType(int idx) {
+ return mFileInfo->itemAt(idx).getFileType();
+ }
+
+private:
+ /* these operations are not implemented */
+ AssetDir(const AssetDir& src);
+ const AssetDir& operator=(const AssetDir& src);
+
+ friend class AssetManager;
+
+ /*
+ * This holds information about files in the asset hierarchy.
+ */
+ class FileInfo {
+ public:
+ FileInfo(void) {}
+ FileInfo(const String8& path) // useful for e.g. svect.indexOf
+ : mFileName(path), mFileType(kFileTypeUnknown)
+ {}
+ ~FileInfo(void) {}
+ FileInfo(const FileInfo& src) {
+ copyMembers(src);
+ }
+ const FileInfo& operator= (const FileInfo& src) {
+ if (this != &src)
+ copyMembers(src);
+ return *this;
+ }
+
+ void copyMembers(const FileInfo& src) {
+ mFileName = src.mFileName;
+ mFileType = src.mFileType;
+ mSourceName = src.mSourceName;
+ }
+
+ /* need this for SortedVector; must compare only on file name */
+ bool operator< (const FileInfo& rhs) const {
+ return mFileName < rhs.mFileName;
+ }
+
+ /* used by AssetManager */
+ bool operator== (const FileInfo& rhs) const {
+ return mFileName == rhs.mFileName;
+ }
+
+ void set(const String8& path, FileType type) {
+ mFileName = path;
+ mFileType = type;
+ }
+
+ const String8& getFileName(void) const { return mFileName; }
+ void setFileName(const String8& path) { mFileName = path; }
+
+ FileType getFileType(void) const { return mFileType; }
+ void setFileType(FileType type) { mFileType = type; }
+
+ const String8& getSourceName(void) const { return mSourceName; }
+ void setSourceName(const String8& path) { mSourceName = path; }
+
+ /*
+ * Handy utility for finding an entry in a sorted vector of FileInfo.
+ * Returns the index of the matching entry, or -1 if none found.
+ */
+ static int findEntry(const SortedVector<FileInfo>* pVector,
+ const String8& fileName);
+
+ private:
+ String8 mFileName; // filename only
+ FileType mFileType; // regular, directory, etc
+
+ String8 mSourceName; // currently debug-only
+ };
+
+ /* AssetManager uses this to initialize us */
+ void setFileList(SortedVector<FileInfo>* list) { mFileInfo = list; }
+
+ SortedVector<FileInfo>* mFileInfo;
+};
+
+}; // namespace android
+
+#endif // __LIBS_ASSETDIR_H
diff --git a/include/utils/AssetManager.h b/include/utils/AssetManager.h
new file mode 100644
index 0000000..e94c0e8
--- /dev/null
+++ b/include/utils/AssetManager.h
@@ -0,0 +1,323 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Asset management class. AssetManager objects are thread-safe.
+//
+#ifndef __LIBS_ASSETMANAGER_H
+#define __LIBS_ASSETMANAGER_H
+
+#include <utils/Asset.h>
+#include <utils/AssetDir.h>
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+#include <utils/Vector.h>
+#include <utils/String16.h>
+#include <utils/ZipFileRO.h>
+#include <utils/threads.h>
+
+namespace android {
+
+class Asset; // fwd decl for things that include Asset.h first
+class ResTable;
+struct ResTable_config;
+
+/*
+ * Every application that uses assets needs one instance of this. A
+ * single instance may be shared across multiple threads, and a single
+ * thread may have more than one instance (the latter is discouraged).
+ *
+ * The purpose of the AssetManager is to create Asset objects. To do
+ * this efficiently it may cache information about the locations of
+ * files it has seen. This can be controlled with the "cacheMode"
+ * argument.
+ *
+ * The asset hierarchy may be examined like a filesystem, using
+ * AssetDir objects to peruse a single directory.
+ */
+class AssetManager {
+public:
+ typedef enum CacheMode {
+ CACHE_UNKNOWN = 0,
+ CACHE_OFF, // don't try to cache file locations
+ CACHE_DEFER, // construct cache as pieces are needed
+ //CACHE_SCAN, // scan full(!) asset hierarchy at init() time
+ } CacheMode;
+
+ AssetManager(CacheMode cacheMode = CACHE_OFF);
+ virtual ~AssetManager(void);
+
+ static int32_t getGlobalCount();
+
+ /*
+ * Add a new source for assets. This can be called multiple times to
+ * look in multiple places for assets. It can be either a directory (for
+ * finding assets as raw files on the disk) or a ZIP file. This newly
+ * added asset path will be examined first when searching for assets,
+ * before any that were previously added.
+ *
+ * Returns "true" on success, "false" on failure. If 'cookie' is non-NULL,
+ * then on success, *cookie is set to the value corresponding to the
+ * newly-added asset source.
+ */
+ bool addAssetPath(const String8& path, void** cookie);
+
+ /*
+ * Convenience for adding the standard system assets. Uses the
+ * ANDROID_ROOT environment variable to find them.
+ */
+ bool addDefaultAssets();
+
+ /*
+ * Iterate over the asset paths in this manager. (Previously
+ * added via addAssetPath() and addDefaultAssets().) On first call,
+ * 'cookie' must be NULL, resulting in the first cookie being returned.
+ * Each next cookie will be returned there-after, until NULL indicating
+ * the end has been reached.
+ */
+ void* nextAssetPath(void* cookie) const;
+
+ /*
+ * Return an asset path in the manager. 'which' must be between 0 and
+ * countAssetPaths().
+ */
+ String8 getAssetPath(void* cookie) const;
+
+ /*
+ * Set the current locale and vendor. The locale can change during
+ * the lifetime of an AssetManager if the user updates the device's
+ * language setting. The vendor is less likely to change.
+ *
+ * Pass in NULL to indicate no preference.
+ */
+ void setLocale(const char* locale);
+ void setVendor(const char* vendor);
+
+ /*
+ * Choose screen orientation for resources values returned.
+ */
+ void setConfiguration(const ResTable_config& config, const char* locale = NULL);
+
+ typedef Asset::AccessMode AccessMode; // typing shortcut
+
+ /*
+ * Open an asset.
+ *
+ * This will search through locale-specific and vendor-specific
+ * directories and packages to find the file.
+ *
+ * The object returned does not depend on the AssetManager. It should
+ * be freed by calling Asset::close().
+ */
+ Asset* open(const char* fileName, AccessMode mode);
+
+ /*
+ * Open a non-asset file as an asset.
+ *
+ * This is for opening files that are included in an asset package
+ * but aren't assets. These sit outside the usual "locale/vendor"
+ * path hierarchy, and will not be seen by "AssetDir" or included
+ * in our filename cache.
+ */
+ Asset* openNonAsset(const char* fileName, AccessMode mode);
+
+ /*
+ * Explicit non-asset file. The file explicitly named by the cookie (the
+ * resource set to look in) and fileName will be opened and returned.
+ */
+ Asset* openNonAsset(void* cookie, const char* fileName, AccessMode mode);
+
+ /*
+ * Open a directory within the asset hierarchy.
+ *
+ * The contents of the directory are an amalgam of vendor-specific,
+ * locale-specific, and generic assets stored loosely or in asset
+ * packages. Depending on the cache setting and previous accesses,
+ * this call may incur significant disk overhead.
+ *
+ * To open the top-level directory, pass in "".
+ */
+ AssetDir* openDir(const char* dirName);
+
+ /*
+ * Get the type of a file in the asset hierarchy. They will either
+ * be "regular" or "directory". [Currently only works for "regular".]
+ *
+ * Can also be used as a quick test for existence of a file.
+ */
+ FileType getFileType(const char* fileName);
+
+ /*
+ * Return the complete resource table to find things in the package.
+ */
+ const ResTable& getResources(bool required = true) const;
+
+ /*
+ * Discard cached filename information. This only needs to be called
+ * if somebody has updated the set of "loose" files, and we want to
+ * discard our cached notion of what's where.
+ */
+ void purge(void) { purgeFileNameCacheLocked(); }
+
+ /*
+ * Return true if the files this AssetManager references are all
+ * up-to-date (have not been changed since it was created). If false
+ * is returned, you will need to create a new AssetManager to get
+ * the current data.
+ */
+ bool isUpToDate();
+
+ /**
+ * Get the known locales for this asset manager object.
+ */
+ void getLocales(Vector<String8>* locales) const;
+
+private:
+ struct asset_path
+ {
+ String8 path;
+ FileType type;
+ };
+
+ Asset* openInPathLocked(const char* fileName, AccessMode mode,
+ const asset_path& path);
+ Asset* openNonAssetInPathLocked(const char* fileName, AccessMode mode,
+ const asset_path& path);
+ Asset* openInLocaleVendorLocked(const char* fileName, AccessMode mode,
+ const asset_path& path, const char* locale, const char* vendor);
+ String8 createPathNameLocked(const asset_path& path, const char* locale,
+ const char* vendor);
+ String8 createPathNameLocked(const asset_path& path, const char* rootDir);
+ String8 createZipSourceNameLocked(const String8& zipFileName,
+ const String8& dirName, const String8& fileName);
+
+ ZipFileRO* getZipFileLocked(const asset_path& path);
+ Asset* openAssetFromFileLocked(const String8& fileName, AccessMode mode);
+ Asset* openAssetFromZipLocked(const ZipFileRO* pZipFile,
+ const ZipEntryRO entry, AccessMode mode, const String8& entryName);
+
+ bool scanAndMergeDirLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
+ const asset_path& path, const char* rootDir, const char* dirName);
+ SortedVector<AssetDir::FileInfo>* scanDirLocked(const String8& path);
+ bool scanAndMergeZipLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
+ const asset_path& path, const char* rootDir, const char* dirName);
+ void mergeInfoLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
+ const SortedVector<AssetDir::FileInfo>* pContents);
+
+ void loadFileNameCacheLocked(void);
+ void fncScanLocked(SortedVector<AssetDir::FileInfo>* pMergedInfo,
+ const char* dirName);
+ bool fncScanAndMergeDirLocked(
+ SortedVector<AssetDir::FileInfo>* pMergedInfo,
+ const asset_path& path, const char* locale, const char* vendor,
+ const char* dirName);
+ void purgeFileNameCacheLocked(void);
+
+ const ResTable* getResTable(bool required = true) const;
+ void setLocaleLocked(const char* locale);
+ void updateResourceParamsLocked() const;
+
+ class SharedZip : public RefBase {
+ public:
+ static sp<SharedZip> get(const String8& path);
+
+ ZipFileRO* getZip();
+
+ Asset* getResourceTableAsset();
+ Asset* setResourceTableAsset(Asset* asset);
+
+ bool isUpToDate();
+
+ protected:
+ ~SharedZip();
+
+ private:
+ SharedZip(const String8& path, time_t modWhen);
+ SharedZip(); // <-- not implemented
+
+ String8 mPath;
+ ZipFileRO* mZipFile;
+ time_t mModWhen;
+
+ Asset* mResourceTableAsset;
+
+ static Mutex gLock;
+ static DefaultKeyedVector<String8, wp<SharedZip> > gOpen;
+ };
+
+ /*
+ * Manage a set of Zip files. For each file we need a pointer to the
+ * ZipFile and a time_t with the file's modification date.
+ *
+ * We currently only have two zip files (current app, "common" app).
+ * (This was originally written for 8, based on app/locale/vendor.)
+ */
+ class ZipSet {
+ public:
+ ZipSet(void);
+ ~ZipSet(void);
+
+ /*
+ * Return a ZipFileRO structure for a ZipFileRO with the specified
+ * parameters.
+ */
+ ZipFileRO* getZip(const String8& path);
+
+ Asset* getZipResourceTable(const String8& path);
+ Asset* setZipResourceTable(const String8& path, Asset* asset);
+
+ // generate path, e.g. "common/en-US-noogle.zip"
+ static String8 getPathName(const char* path);
+
+ bool isUpToDate();
+
+ private:
+ void closeZip(int idx);
+
+ int getIndex(const String8& zip) const;
+ mutable Vector<String8> mZipPath;
+ mutable Vector<sp<SharedZip> > mZipFile;
+ };
+
+ // Protect all internal state.
+ mutable Mutex mLock;
+
+ ZipSet mZipSet;
+
+ Vector<asset_path> mAssetPaths;
+ char* mLocale;
+ char* mVendor;
+
+ mutable ResTable* mResources;
+ ResTable_config* mConfig;
+
+ /*
+ * Cached data for "loose" files. This lets us avoid poking at the
+ * filesystem when searching for loose assets. Each entry is the
+ * "extended partial" path, e.g. "default/default/foo/bar.txt". The
+ * full set of files is present, including ".EXCLUDE" entries.
+ *
+ * We do not cache directory names. We don't retain the ".gz",
+ * because to our clients "foo" and "foo.gz" both look like "foo".
+ */
+ CacheMode mCacheMode; // is the cache enabled?
+ bool mCacheValid; // clear when locale or vendor changes
+ SortedVector<AssetDir::FileInfo> mCache;
+};
+
+}; // namespace android
+
+#endif // __LIBS_ASSETMANAGER_H
diff --git a/include/utils/Atomic.h b/include/utils/Atomic.h
new file mode 100644
index 0000000..7eb476c
--- /dev/null
+++ b/include/utils/Atomic.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_UTILS_ATOMIC_H
+#define ANDROID_UTILS_ATOMIC_H
+
+#include <cutils/atomic.h>
+
+#endif // ANDROID_UTILS_ATOMIC_H
diff --git a/include/utils/Binder.h b/include/utils/Binder.h
new file mode 100644
index 0000000..b5b8d98
--- /dev/null
+++ b/include/utils/Binder.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_BINDER_H
+#define ANDROID_BINDER_H
+
+#include <utils/IBinder.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+
+class BBinder : public IBinder
+{
+public:
+ BBinder();
+
+ virtual String16 getInterfaceDescriptor() const;
+ virtual bool isBinderAlive() const;
+ virtual status_t pingBinder();
+ virtual status_t dump(int fd, const Vector<String16>& args);
+
+ virtual status_t transact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+
+ virtual status_t linkToDeath(const sp<DeathRecipient>& recipient,
+ void* cookie = NULL,
+ uint32_t flags = 0);
+
+ virtual status_t unlinkToDeath( const wp<DeathRecipient>& recipient,
+ void* cookie = NULL,
+ uint32_t flags = 0,
+ wp<DeathRecipient>* outRecipient = NULL);
+
+ virtual void attachObject( const void* objectID,
+ void* object,
+ void* cleanupCookie,
+ object_cleanup_func func);
+ virtual void* findObject(const void* objectID) const;
+ virtual void detachObject(const void* objectID);
+
+ virtual BBinder* localBinder();
+
+protected:
+ virtual ~BBinder();
+
+ virtual status_t onTransact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+
+private:
+ BBinder(const BBinder& o);
+ BBinder& operator=(const BBinder& o);
+
+ class Extras;
+
+ Extras* mExtras;
+ void* mReserved0;
+};
+
+// ---------------------------------------------------------------------------
+
+class BpRefBase : public virtual RefBase
+{
+protected:
+ BpRefBase(const sp<IBinder>& o);
+ virtual ~BpRefBase();
+ virtual void onFirstRef();
+ virtual void onLastStrongRef(const void* id);
+ virtual bool onIncStrongAttempted(uint32_t flags, const void* id);
+
+ inline IBinder* remote() { return mRemote; }
+ inline IBinder* remote() const { return mRemote; }
+
+private:
+ BpRefBase(const BpRefBase& o);
+ BpRefBase& operator=(const BpRefBase& o);
+
+ IBinder* const mRemote;
+ RefBase::weakref_type* mRefs;
+ volatile int32_t mState;
+};
+
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_BINDER_H
diff --git a/include/utils/BpBinder.h b/include/utils/BpBinder.h
new file mode 100644
index 0000000..7b96e29
--- /dev/null
+++ b/include/utils/BpBinder.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_BPBINDER_H
+#define ANDROID_BPBINDER_H
+
+#include <utils/IBinder.h>
+#include <utils/KeyedVector.h>
+#include <utils/threads.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+
+class BpBinder : public IBinder
+{
+public:
+ BpBinder(int32_t handle);
+
+ inline int32_t handle() const { return mHandle; }
+
+ virtual String16 getInterfaceDescriptor() const;
+ virtual bool isBinderAlive() const;
+ virtual status_t pingBinder();
+ virtual status_t dump(int fd, const Vector<String16>& args);
+
+ virtual status_t transact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+
+ virtual status_t linkToDeath(const sp<DeathRecipient>& recipient,
+ void* cookie = NULL,
+ uint32_t flags = 0);
+ virtual status_t unlinkToDeath( const wp<DeathRecipient>& recipient,
+ void* cookie = NULL,
+ uint32_t flags = 0,
+ wp<DeathRecipient>* outRecipient = NULL);
+
+ virtual void attachObject( const void* objectID,
+ void* object,
+ void* cleanupCookie,
+ object_cleanup_func func);
+ virtual void* findObject(const void* objectID) const;
+ virtual void detachObject(const void* objectID);
+
+ virtual BpBinder* remoteBinder();
+
+ status_t setConstantData(const void* data, size_t size);
+ void sendObituary();
+
+ class ObjectManager
+ {
+ public:
+ ObjectManager();
+ ~ObjectManager();
+
+ void attach( const void* objectID,
+ void* object,
+ void* cleanupCookie,
+ IBinder::object_cleanup_func func);
+ void* find(const void* objectID) const;
+ void detach(const void* objectID);
+
+ void kill();
+
+ private:
+ ObjectManager(const ObjectManager&);
+ ObjectManager& operator=(const ObjectManager&);
+
+ struct entry_t
+ {
+ void* object;
+ void* cleanupCookie;
+ IBinder::object_cleanup_func func;
+ };
+
+ KeyedVector<const void*, entry_t> mObjects;
+ };
+
+protected:
+ virtual ~BpBinder();
+ virtual void onFirstRef();
+ virtual void onLastStrongRef(const void* id);
+ virtual bool onIncStrongAttempted(uint32_t flags, const void* id);
+
+private:
+ const int32_t mHandle;
+
+ struct Obituary {
+ wp<DeathRecipient> recipient;
+ void* cookie;
+ uint32_t flags;
+ };
+
+ void reportOneDeath(const Obituary& obit);
+
+ mutable Mutex mLock;
+ volatile int32_t mAlive;
+ volatile int32_t mObitsSent;
+ Vector<Obituary>* mObituaries;
+ ObjectManager mObjects;
+ Parcel* mConstantData;
+};
+
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_BPBINDER_H
diff --git a/include/utils/Buffer.h b/include/utils/Buffer.h
new file mode 100644
index 0000000..8e22b0f
--- /dev/null
+++ b/include/utils/Buffer.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __UTILS_BUFFER_H__
+#define __UTILS_BUFFER_H__ 1
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+namespace android {
+
+class Buffer
+{
+private:
+ char *buf;
+ int bufsiz;
+ int used;
+ void ensureCapacity(int len);
+
+ void
+ makeRoomFor(int len)
+ {
+ if (len + used >= bufsiz) {
+ bufsiz = (len + used) * 3/2 + 2;
+ char *blah = new char[bufsiz];
+
+ memcpy(blah, buf, used);
+ delete[] buf;
+ buf = blah;
+ }
+ }
+
+public:
+ Buffer()
+ {
+ bufsiz = 16;
+ buf = new char[bufsiz];
+ clear();
+ }
+
+ ~Buffer()
+ {
+ delete[] buf;
+ }
+
+ void
+ clear()
+ {
+ buf[0] = '\0';
+ used = 0;
+ }
+
+ int
+ length()
+ {
+ return used;
+ }
+
+ void
+ append(const char c)
+ {
+ makeRoomFor(1);
+ buf[used] = c;
+ used++;
+ buf[used] = '\0';
+ }
+
+ void
+ append(const char *s, int len)
+ {
+ makeRoomFor(len);
+
+ memcpy(buf + used, s, len);
+ used += len;
+ buf[used] = '\0';
+ }
+
+ void
+ append(const char *s)
+ {
+ append(s, strlen(s));
+ }
+
+ char *
+ getBytes()
+ {
+ return buf;
+ }
+};
+
+}; // namespace android
+
+#endif
diff --git a/include/utils/BufferedTextOutput.h b/include/utils/BufferedTextOutput.h
new file mode 100644
index 0000000..69c6240
--- /dev/null
+++ b/include/utils/BufferedTextOutput.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_BUFFEREDTEXTOUTPUT_H
+#define ANDROID_BUFFEREDTEXTOUTPUT_H
+
+#include <utils/TextOutput.h>
+#include <utils/threads.h>
+#include <cutils/uio.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+
+class BufferedTextOutput : public TextOutput
+{
+public:
+ //** Flags for constructor */
+ enum {
+ MULTITHREADED = 0x0001
+ };
+
+ BufferedTextOutput(uint32_t flags = 0);
+ virtual ~BufferedTextOutput();
+
+ virtual status_t print(const char* txt, size_t len);
+ virtual void moveIndent(int delta);
+
+ virtual void pushBundle();
+ virtual void popBundle();
+
+protected:
+ virtual status_t writeLines(const struct iovec& vec, size_t N) = 0;
+
+private:
+ struct BufferState;
+ struct ThreadState;
+
+ static ThreadState*getThreadState();
+ static void threadDestructor(void *st);
+
+ BufferState*getBuffer() const;
+
+ uint32_t mFlags;
+ const int32_t mSeq;
+ const int32_t mIndex;
+
+ Mutex mLock;
+ BufferState* mGlobalState;
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_BUFFEREDTEXTOUTPUT_H
diff --git a/include/utils/ByteOrder.h b/include/utils/ByteOrder.h
new file mode 100644
index 0000000..4c06067
--- /dev/null
+++ b/include/utils/ByteOrder.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+
+#ifndef _LIBS_UTILS_BYTE_ORDER_H
+#define _LIBS_UTILS_BYTE_ORDER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#ifdef HAVE_WINSOCK
+#include <winsock2.h>
+#else
+#include <netinet/in.h>
+#endif
+
+/*
+ * These macros are like the hton/ntoh byte swapping macros,
+ * except they allow you to swap to and from the "device" byte
+ * order. The device byte order is the endianness of the target
+ * device -- for the ARM CPUs we use today, this is little endian.
+ *
+ * Note that the byte swapping functions have not been optimized
+ * much; performance is currently not an issue for them since the
+ * intent is to allow us to avoid byte swapping on the device.
+ */
+
+#define DEVICE_BYTE_ORDER LITTLE_ENDIAN
+
+#if BYTE_ORDER == DEVICE_BYTE_ORDER
+
+#define dtohl(x) (x)
+#define dtohs(x) (x)
+#define htodl(x) (x)
+#define htods(x) (x)
+
+#else
+
+static inline uint32_t android_swap_long(uint32_t v)
+{
+ return (v<<24) | ((v<<8)&0x00FF0000) | ((v>>8)&0x0000FF00) | (v>>24);
+}
+
+static inline uint16_t android_swap_short(uint16_t v)
+{
+ return (v<<8) | (v>>8);
+}
+
+#define dtohl(x) (android_swap_long(x))
+#define dtohs(x) (android_swap_short(x))
+#define htodl(x) (android_swap_long(x))
+#define htods(x) (android_swap_short(x))
+
+#endif
+
+#endif // _LIBS_UTILS_BYTE_ORDER_H
diff --git a/include/utils/CallStack.h b/include/utils/CallStack.h
new file mode 100644
index 0000000..c2c8ce5
--- /dev/null
+++ b/include/utils/CallStack.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_CALLSTACK_H
+#define ANDROID_CALLSTACK_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/String8.h>
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+class CallStack
+{
+public:
+ enum {
+ MAX_DEPTH = 31
+ };
+
+ CallStack();
+ CallStack(const CallStack& rhs);
+ ~CallStack();
+
+ CallStack& operator = (const CallStack& rhs);
+
+ bool operator == (const CallStack& rhs) const;
+ bool operator != (const CallStack& rhs) const;
+ bool operator < (const CallStack& rhs) const;
+ bool operator >= (const CallStack& rhs) const;
+ bool operator > (const CallStack& rhs) const;
+ bool operator <= (const CallStack& rhs) const;
+
+ const void* operator [] (int index) const;
+
+ void clear();
+
+ void update(int32_t ignoreDepth=0, int32_t maxDepth=MAX_DEPTH);
+
+ // Dump a stack trace to the log
+ void dump(const char* prefix = 0) const;
+
+ // Return a string (possibly very long) containing the complete stack trace
+ String8 toString(const char* prefix = 0) const;
+
+ size_t size() const { return mCount; }
+
+private:
+ // Internal helper function
+ String8 toStringSingleLevel(const char* prefix, int32_t level) const;
+
+ size_t mCount;
+ const void* mStack[MAX_DEPTH];
+};
+
+}; // namespace android
+
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_CALLSTACK_H
diff --git a/include/utils/Debug.h b/include/utils/Debug.h
new file mode 100644
index 0000000..a662b9c
--- /dev/null
+++ b/include/utils/Debug.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Debugging tools. These should be able to be stripped
+// in release builds.
+//
+#ifndef ANDROID_DEBUG_H
+#define ANDROID_DEBUG_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+namespace android {
+
+template<bool> struct CompileTimeAssert;
+template<> struct CompileTimeAssert<true> {};
+
+const char* stringForIndent(int32_t indentLevel);
+
+typedef void (*debugPrintFunc)(void* cookie, const char* txt);
+
+void printTypeCode(uint32_t typeCode,
+ debugPrintFunc func = 0, void* cookie = 0);
+void printHexData(int32_t indent, const void *buf, size_t length,
+ size_t bytesPerLine=16, int32_t singleLineBytesCutoff=16,
+ size_t alignment=0, bool cArrayStyle=false,
+ debugPrintFunc func = 0, void* cookie = 0);
+
+}; // namespace android
+
+#endif // ANDROID_DEBUG_H
diff --git a/include/utils/Endian.h b/include/utils/Endian.h
new file mode 100644
index 0000000..19f2504
--- /dev/null
+++ b/include/utils/Endian.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Android endian-ness defines.
+//
+#ifndef _LIBS_UTILS_ENDIAN_H
+#define _LIBS_UTILS_ENDIAN_H
+
+#if defined(HAVE_ENDIAN_H)
+
+#include <endian.h>
+
+#else /*not HAVE_ENDIAN_H*/
+
+#define __BIG_ENDIAN 0x1000
+#define __LITTLE_ENDIAN 0x0001
+
+#if defined(HAVE_LITTLE_ENDIAN)
+# define __BYTE_ORDER __LITTLE_ENDIAN
+#else
+# define __BYTE_ORDER __BIG_ENDIAN
+#endif
+
+#endif /*not HAVE_ENDIAN_H*/
+
+#endif /*_LIBS_UTILS_ENDIAN_H*/
diff --git a/include/utils/Errors.h b/include/utils/Errors.h
new file mode 100644
index 0000000..1bf9e6f
--- /dev/null
+++ b/include/utils/Errors.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_ERRORS_H
+#define ANDROID_ERRORS_H
+
+#include <sys/types.h>
+#include <errno.h>
+
+namespace android {
+
+// use this type to return error codes
+#ifdef HAVE_MS_C_RUNTIME
+typedef int status_t;
+#else
+typedef int32_t status_t;
+#endif
+
+/* the MS C runtime lacks a few error codes */
+
+/*
+ * Error codes.
+ * All error codes are negative values.
+ */
+
+// Win32 #defines NO_ERROR as well. It has the same value, so there's no
+// real conflict, though it's a bit awkward.
+#ifdef _WIN32
+# undef NO_ERROR
+#endif
+
+enum {
+ OK = 0, // Everything's swell.
+ NO_ERROR = 0, // No errors.
+
+ UNKNOWN_ERROR = 0x80000000,
+
+ NO_MEMORY = -ENOMEM,
+ INVALID_OPERATION = -ENOSYS,
+ BAD_VALUE = -EINVAL,
+ BAD_TYPE = 0x80000001,
+ NAME_NOT_FOUND = -ENOENT,
+ PERMISSION_DENIED = -EPERM,
+ NO_INIT = -ENODEV,
+ ALREADY_EXISTS = -EEXIST,
+ DEAD_OBJECT = -EPIPE,
+ FAILED_TRANSACTION = 0x80000002,
+ JPARKS_BROKE_IT = -EPIPE,
+#if !defined(HAVE_MS_C_RUNTIME)
+ BAD_INDEX = -EOVERFLOW,
+ NOT_ENOUGH_DATA = -ENODATA,
+ WOULD_BLOCK = -EWOULDBLOCK,
+ TIMED_OUT = -ETIME,
+ UNKNOWN_TRANSACTION = -EBADMSG,
+#else
+ BAD_INDEX = -E2BIG,
+ NOT_ENOUGH_DATA = 0x80000003,
+ WOULD_BLOCK = 0x80000004,
+ TIMED_OUT = 0x80000005,
+ UNKNOWN_TRANSACTION = 0x80000006,
+#endif
+};
+
+// Restore define; enumeration is in "android" namespace, so the value defined
+// there won't work for Win32 code in a different namespace.
+#ifdef _WIN32
+# define NO_ERROR 0L
+#endif
+
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_ERRORS_H
diff --git a/include/utils/FileMap.h b/include/utils/FileMap.h
new file mode 100644
index 0000000..8dfd3be
--- /dev/null
+++ b/include/utils/FileMap.h
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Encapsulate a shared file mapping.
+//
+#ifndef __LIBS_FILE_MAP_H
+#define __LIBS_FILE_MAP_H
+
+#include <sys/types.h>
+
+#ifdef HAVE_WIN32_FILEMAP
+#include <windows.h>
+#endif
+
+namespace android {
+
+/*
+ * This represents a memory-mapped file. It might be the entire file or
+ * only part of it. This requires a little bookkeeping because the mapping
+ * needs to be aligned on page boundaries, and in some cases we'd like to
+ * have multiple references to the mapped area without creating additional
+ * maps.
+ *
+ * This always uses MAP_SHARED.
+ *
+ * TODO: we should be able to create a new FileMap that is a subset of
+ * an existing FileMap and shares the underlying mapped pages. Requires
+ * completing the refcounting stuff and possibly introducing the notion
+ * of a FileMap hierarchy.
+ */
+class FileMap {
+public:
+ FileMap(void);
+
+ /*
+ * Create a new mapping on an open file.
+ *
+ * Closing the file descriptor does not unmap the pages, so we don't
+ * claim ownership of the fd.
+ *
+ * Returns "false" on failure.
+ */
+ bool create(const char* origFileName, int fd,
+ off_t offset, size_t length, bool readOnly);
+
+ /*
+ * Return the name of the file this map came from, if known.
+ */
+ const char* getFileName(void) const { return mFileName; }
+
+ /*
+ * Get a pointer to the piece of the file we requested.
+ */
+ void* getDataPtr(void) const { return mDataPtr; }
+
+ /*
+ * Get the length we requested.
+ */
+ size_t getDataLength(void) const { return mDataLength; }
+
+ /*
+ * Get the data offset used to create this map.
+ */
+ off_t getDataOffset(void) const { return mDataOffset; }
+
+ /*
+ * Get a "copy" of the object.
+ */
+ FileMap* acquire(void) { mRefCount++; return this; }
+
+ /*
+ * Call this when mapping is no longer needed.
+ */
+ void release(void) {
+ if (--mRefCount <= 0)
+ delete this;
+ }
+
+ /*
+ * This maps directly to madvise() values, but allows us to avoid
+ * including <sys/mman.h> everywhere.
+ */
+ enum MapAdvice {
+ NORMAL, RANDOM, SEQUENTIAL, WILLNEED, DONTNEED
+ };
+
+ /*
+ * Apply an madvise() call to the entire file.
+ *
+ * Returns 0 on success, -1 on failure.
+ */
+ int advise(MapAdvice advice);
+
+protected:
+ // don't delete objects; call release()
+ ~FileMap(void);
+
+private:
+ // these are not implemented
+ FileMap(const FileMap& src);
+ const FileMap& operator=(const FileMap& src);
+
+ int mRefCount; // reference count
+ char* mFileName; // original file name, if known
+ void* mBasePtr; // base of mmap area; page aligned
+ size_t mBaseLength; // length, measured from "mBasePtr"
+ off_t mDataOffset; // offset used when map was created
+ void* mDataPtr; // start of requested data, offset from base
+ size_t mDataLength; // length, measured from "mDataPtr"
+#ifdef HAVE_WIN32_FILEMAP
+ HANDLE mFileHandle; // Win32 file handle
+ HANDLE mFileMapping; // Win32 file mapping handle
+#endif
+
+ static long mPageSize;
+};
+
+}; // namespace android
+
+#endif // __LIBS_FILE_MAP_H
diff --git a/include/utils/IBinder.h b/include/utils/IBinder.h
new file mode 100644
index 0000000..7370330
--- /dev/null
+++ b/include/utils/IBinder.h
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_IBINDER_H
+#define ANDROID_IBINDER_H
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/String16.h>
+#include <utils/Vector.h>
+
+
+#define B_PACK_CHARS(c1, c2, c3, c4) \
+ ((((c1)<<24)) | (((c2)<<16)) | (((c3)<<8)) | (c4))
+
+// ---------------------------------------------------------------------------
+namespace android {
+
+class BBinder;
+class BpBinder;
+class IInterface;
+class Parcel;
+
+/**
+ * Base class and low-level protocol for a remotable object.
+ * You can derive from this class to create an object for which other
+ * processes can hold references to it. Communication between processes
+ * (method calls, property get and set) is down through a low-level
+ * protocol implemented on top of the transact() API.
+ */
+class IBinder : public virtual RefBase
+{
+public:
+ enum {
+ FIRST_CALL_TRANSACTION = 0x00000001,
+ LAST_CALL_TRANSACTION = 0x00ffffff,
+
+ PING_TRANSACTION = B_PACK_CHARS('_','P','N','G'),
+ DUMP_TRANSACTION = B_PACK_CHARS('_','D','M','P'),
+ INTERFACE_TRANSACTION = B_PACK_CHARS('_', 'N', 'T', 'F'),
+
+ // Corresponds to tfOneWay -- an asynchronous call.
+ FLAG_ONEWAY = 0x00000001
+ };
+
+ inline IBinder() { }
+
+ /**
+ * Check if this IBinder implements the interface named by
+ * @a descriptor. If it does, the base pointer to it is returned,
+ * which you can safely static_cast<> to the concrete C++ interface.
+ */
+ virtual sp<IInterface> queryLocalInterface(const String16& descriptor);
+
+ /**
+ * Return the canonical name of the interface provided by this IBinder
+ * object.
+ */
+ virtual String16 getInterfaceDescriptor() const = 0;
+
+ virtual bool isBinderAlive() const = 0;
+ virtual status_t pingBinder() = 0;
+ virtual status_t dump(int fd, const Vector<String16>& args) = 0;
+
+ virtual status_t transact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0) = 0;
+
+ /**
+ * This method allows you to add data that is transported through
+ * IPC along with your IBinder pointer. When implementing a Binder
+ * object, override it to write your desired data in to @a outData.
+ * You can then call getConstantData() on your IBinder to retrieve
+ * that data, from any process. You MUST return the number of bytes
+ * written in to the parcel (including padding).
+ */
+ class DeathRecipient : public virtual RefBase
+ {
+ public:
+ virtual void binderDied(const wp<IBinder>& who) = 0;
+ };
+
+ /**
+ * Register the @a recipient for a notification if this binder
+ * goes away. If this binder object unexpectedly goes away
+ * (typically because its hosting process has been killed),
+ * then DeathRecipient::binderDied() will be called with a referene
+ * to this.
+ *
+ * The @a cookie is optional -- if non-NULL, it should be a
+ * memory address that you own (that is, you know it is unique).
+ *
+ * @note You will only receive death notifications for remote binders,
+ * as local binders by definition can't die without you dying as well.
+ * Trying to use this function on a local binder will result in an
+ * INVALID_OPERATION code being returned and nothing happening.
+ *
+ * @note This link always holds a weak reference to its recipient.
+ *
+ * @note You will only receive a weak reference to the dead
+ * binder. You should not try to promote this to a strong reference.
+ * (Nor should you need to, as there is nothing useful you can
+ * directly do with it now that it has passed on.)
+ */
+ virtual status_t linkToDeath(const sp<DeathRecipient>& recipient,
+ void* cookie = NULL,
+ uint32_t flags = 0) = 0;
+
+ /**
+ * Remove a previously registered death notification.
+ * The @a recipient will no longer be called if this object
+ * dies. The @a cookie is optional. If non-NULL, you can
+ * supply a NULL @a recipient, and the recipient previously
+ * added with that cookie will be unlinked.
+ */
+ virtual status_t unlinkToDeath( const wp<DeathRecipient>& recipient,
+ void* cookie = NULL,
+ uint32_t flags = 0,
+ wp<DeathRecipient>* outRecipient = NULL) = 0;
+
+ virtual bool checkSubclass(const void* subclassID) const;
+
+ typedef void (*object_cleanup_func)(const void* id, void* obj, void* cleanupCookie);
+
+ virtual void attachObject( const void* objectID,
+ void* object,
+ void* cleanupCookie,
+ object_cleanup_func func) = 0;
+ virtual void* findObject(const void* objectID) const = 0;
+ virtual void detachObject(const void* objectID) = 0;
+
+ virtual BBinder* localBinder();
+ virtual BpBinder* remoteBinder();
+
+protected:
+ inline virtual ~IBinder() { }
+
+private:
+};
+
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_IBINDER_H
diff --git a/include/utils/IInterface.h b/include/utils/IInterface.h
new file mode 100644
index 0000000..959722a
--- /dev/null
+++ b/include/utils/IInterface.h
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+#ifndef ANDROID_IINTERFACE_H
+#define ANDROID_IINTERFACE_H
+
+#include <utils/Binder.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------
+
+class IInterface : public virtual RefBase
+{
+public:
+ sp<IBinder> asBinder();
+ sp<const IBinder> asBinder() const;
+
+protected:
+ virtual IBinder* onAsBinder() = 0;
+};
+
+// ----------------------------------------------------------------------
+
+template<typename INTERFACE>
+inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
+{
+ return INTERFACE::asInterface(obj);
+}
+
+// ----------------------------------------------------------------------
+
+template<typename INTERFACE>
+class BnInterface : public INTERFACE, public BBinder
+{
+public:
+ virtual sp<IInterface> queryLocalInterface(const String16& _descriptor);
+ virtual String16 getInterfaceDescriptor() const;
+
+protected:
+ virtual IBinder* onAsBinder();
+};
+
+// ----------------------------------------------------------------------
+
+template<typename INTERFACE>
+class BpInterface : public INTERFACE, public BpRefBase
+{
+public:
+ BpInterface(const sp<IBinder>& remote);
+
+protected:
+ virtual IBinder* onAsBinder();
+};
+
+// ----------------------------------------------------------------------
+
+#define DECLARE_META_INTERFACE(INTERFACE) \
+ static const String16 descriptor; \
+ static sp<I##INTERFACE> asInterface(const sp<IBinder>& obj); \
+ virtual String16 getInterfaceDescriptor() const; \
+
+#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \
+ const String16 I##INTERFACE::descriptor(NAME); \
+ String16 I##INTERFACE::getInterfaceDescriptor() const { \
+ return I##INTERFACE::descriptor; \
+ } \
+ sp<I##INTERFACE> I##INTERFACE::asInterface(const sp<IBinder>& obj) \
+ { \
+ sp<I##INTERFACE> intr; \
+ if (obj != NULL) { \
+ intr = static_cast<I##INTERFACE*>( \
+ obj->queryLocalInterface( \
+ I##INTERFACE::descriptor).get()); \
+ if (intr == NULL) { \
+ intr = new Bp##INTERFACE(obj); \
+ } \
+ } \
+ return intr; \
+ } \
+
+// ----------------------------------------------------------------------
+// No user-servicable parts after this...
+
+template<typename INTERFACE>
+inline sp<IInterface> BnInterface<INTERFACE>::queryLocalInterface(
+ const String16& _descriptor)
+{
+ if (_descriptor == INTERFACE::descriptor) return this;
+ return NULL;
+}
+
+template<typename INTERFACE>
+inline String16 BnInterface<INTERFACE>::getInterfaceDescriptor() const
+{
+ return INTERFACE::getInterfaceDescriptor();
+}
+
+template<typename INTERFACE>
+IBinder* BnInterface<INTERFACE>::onAsBinder()
+{
+ return this;
+}
+
+template<typename INTERFACE>
+inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
+ : BpRefBase(remote)
+{
+}
+
+template<typename INTERFACE>
+inline IBinder* BpInterface<INTERFACE>::onAsBinder()
+{
+ return remote();
+}
+
+// ----------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_IINTERFACE_H
diff --git a/include/utils/IMemory.h b/include/utils/IMemory.h
new file mode 100644
index 0000000..35a3fd7
--- /dev/null
+++ b/include/utils/IMemory.h
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_IMEMORY_H
+#define ANDROID_IMEMORY_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/mman.h>
+
+#include <utils/RefBase.h>
+#include <utils/Errors.h>
+#include <utils/IInterface.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+class IMemoryHeap : public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(MemoryHeap);
+
+ // flags returned by getFlags()
+ enum {
+ READ_ONLY = 0x00000001,
+ MAP_ONCE = 0x00000002
+ };
+
+ virtual int getHeapID() const = 0;
+ virtual void* getBase() const = 0;
+ virtual size_t getSize() const = 0;
+ virtual uint32_t getFlags() const = 0;
+
+ // these are there just for backward source compatibility
+ int32_t heapID() const { return getHeapID(); }
+ void* base() const { return getBase(); }
+ size_t virtualSize() const { return getSize(); }
+};
+
+class BnMemoryHeap : public BnInterface<IMemoryHeap>
+{
+public:
+ virtual status_t onTransact(
+ uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------------
+
+class IMemory : public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(Memory);
+
+ virtual sp<IMemoryHeap> getMemory(ssize_t* offset=0, size_t* size=0) const = 0;
+
+ // helpers
+ void* fastPointer(const sp<IBinder>& heap, ssize_t offset) const;
+ void* pointer() const;
+ size_t size() const;
+ ssize_t offset() const;
+};
+
+class BnMemory : public BnInterface<IMemory>
+{
+public:
+ virtual status_t onTransact(
+ uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_IMEMORY_H
diff --git a/include/utils/IPCThreadState.h b/include/utils/IPCThreadState.h
new file mode 100644
index 0000000..47043b8
--- /dev/null
+++ b/include/utils/IPCThreadState.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_IPC_THREAD_STATE_H
+#define ANDROID_IPC_THREAD_STATE_H
+
+#include <utils/Errors.h>
+#include <utils/Parcel.h>
+#include <utils/ProcessState.h>
+
+#ifdef HAVE_WIN32_PROC
+typedef int uid_t;
+#endif
+
+// ---------------------------------------------------------------------------
+namespace android {
+
+class IPCThreadState
+{
+public:
+ static IPCThreadState* self();
+
+ sp<ProcessState> process();
+
+ status_t clearLastError();
+
+ int getCallingPid();
+ int getCallingUid();
+
+ int64_t clearCallingIdentity();
+ void restoreCallingIdentity(int64_t token);
+
+ void flushCommands();
+
+ void joinThreadPool(bool isMain = true);
+
+ // Stop the local process.
+ void stopProcess(bool immediate = true);
+
+ status_t transact(int32_t handle,
+ uint32_t code, const Parcel& data,
+ Parcel* reply, uint32_t flags);
+
+ void incStrongHandle(int32_t handle);
+ void decStrongHandle(int32_t handle);
+ void incWeakHandle(int32_t handle);
+ void decWeakHandle(int32_t handle);
+ status_t attemptIncStrongHandle(int32_t handle);
+ static void expungeHandle(int32_t handle, IBinder* binder);
+ status_t requestDeathNotification( int32_t handle,
+ BpBinder* proxy);
+ status_t clearDeathNotification( int32_t handle,
+ BpBinder* proxy);
+
+ static void shutdown();
+
+private:
+ IPCThreadState();
+ ~IPCThreadState();
+
+ status_t sendReply(const Parcel& reply, uint32_t flags);
+ status_t waitForResponse(Parcel *reply,
+ status_t *acquireResult=NULL);
+ status_t talkWithDriver(bool doReceive=true);
+ status_t writeTransactionData(int32_t cmd,
+ uint32_t binderFlags,
+ int32_t handle,
+ uint32_t code,
+ const Parcel& data,
+ status_t* statusBuffer);
+ status_t executeCommand(int32_t command);
+
+ void clearCaller();
+
+ static void threadDestructor(void *st);
+ static void freeBuffer(Parcel* parcel,
+ const uint8_t* data, size_t dataSize,
+ const size_t* objects, size_t objectsSize,
+ void* cookie);
+
+ const sp<ProcessState> mProcess;
+
+ Parcel mIn;
+ Parcel mOut;
+ status_t mLastError;
+ pid_t mCallingPid;
+ uid_t mCallingUid;
+};
+
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_IPC_THREAD_STATE_H
diff --git a/include/utils/IPermissionController.h b/include/utils/IPermissionController.h
new file mode 100644
index 0000000..cb1dd34
--- /dev/null
+++ b/include/utils/IPermissionController.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+#ifndef ANDROID_IPERMISSION_CONTROLLER_H
+#define ANDROID_IPERMISSION_CONTROLLER_H
+
+#include <utils/IInterface.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------
+
+class IPermissionController : public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(PermissionController);
+
+ virtual bool checkPermission(const String16& permission,
+ int32_t pid, int32_t uid) = 0;
+
+ enum {
+ CHECK_PERMISSION_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION
+ };
+};
+
+// ----------------------------------------------------------------------
+
+class BnPermissionController : public BnInterface<IPermissionController>
+{
+public:
+ virtual status_t onTransact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_IPERMISSION_CONTROLLER_H
+
diff --git a/include/utils/IServiceManager.h b/include/utils/IServiceManager.h
new file mode 100644
index 0000000..e3d99fe
--- /dev/null
+++ b/include/utils/IServiceManager.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+#ifndef ANDROID_ISERVICE_MANAGER_H
+#define ANDROID_ISERVICE_MANAGER_H
+
+#include <utils/IInterface.h>
+#include <utils/IPermissionController.h>
+#include <utils/Vector.h>
+#include <utils/String16.h>
+
+namespace android {
+
+// ----------------------------------------------------------------------
+
+class IServiceManager : public IInterface
+{
+public:
+ DECLARE_META_INTERFACE(ServiceManager);
+
+ /**
+ * Retrieve an existing service, blocking for a few seconds
+ * if it doesn't yet exist.
+ */
+ virtual sp<IBinder> getService( const String16& name) const = 0;
+
+ /**
+ * Retrieve an existing service, non-blocking.
+ */
+ virtual sp<IBinder> checkService( const String16& name) const = 0;
+
+ /**
+ * Register a service.
+ */
+ virtual status_t addService( const String16& name,
+ const sp<IBinder>& service) = 0;
+
+ /**
+ * Return list of all existing services.
+ */
+ virtual Vector<String16> listServices() = 0;
+
+ enum {
+ GET_SERVICE_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION,
+ CHECK_SERVICE_TRANSACTION,
+ ADD_SERVICE_TRANSACTION,
+ LIST_SERVICES_TRANSACTION,
+ };
+};
+
+sp<IServiceManager> defaultServiceManager();
+
+template<typename INTERFACE>
+status_t getService(const String16& name, sp<INTERFACE>* outService)
+{
+ const sp<IServiceManager> sm = defaultServiceManager();
+ if (sm != NULL) {
+ *outService = interface_cast<INTERFACE>(sm->getService(name));
+ if ((*outService) != NULL) return NO_ERROR;
+ }
+ return NAME_NOT_FOUND;
+}
+
+bool checkCallingPermission(const String16& permission);
+bool checkCallingPermission(const String16& permission,
+ int32_t* outPid, int32_t* outUid);
+
+// ----------------------------------------------------------------------
+
+class BnServiceManager : public BnInterface<IServiceManager>
+{
+public:
+ virtual status_t onTransact( uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags = 0);
+};
+
+// ----------------------------------------------------------------------
+
+}; // namespace android
+
+#endif // ANDROID_ISERVICE_MANAGER_H
+
diff --git a/include/utils/KeyedVector.h b/include/utils/KeyedVector.h
new file mode 100644
index 0000000..f4513ee
--- /dev/null
+++ b/include/utils/KeyedVector.h
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_KEYED_VECTOR_H
+#define ANDROID_KEYED_VECTOR_H
+
+#include <assert.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/SortedVector.h>
+#include <utils/TypeHelpers.h>
+#include <utils/Errors.h>
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+template <typename KEY, typename VALUE>
+class KeyedVector
+{
+public:
+ typedef KEY key_type;
+ typedef VALUE value_type;
+
+ inline KeyedVector();
+
+ /*
+ * empty the vector
+ */
+
+ inline void clear() { mVector.clear(); }
+
+ /*!
+ * vector stats
+ */
+
+ //! returns number of items in the vector
+ inline size_t size() const { return mVector.size(); }
+ //! returns wether or not the vector is empty
+ inline bool isEmpty() const { return mVector.isEmpty(); }
+ //! returns how many items can be stored without reallocating the backing store
+ inline size_t capacity() const { return mVector.capacity(); }
+ //! setst the capacity. capacity can never be reduced less than size()
+ inline ssize_t setCapacity(size_t size) { return mVector.setCapacity(size); }
+
+ /*!
+ * accessors
+ */
+ const VALUE& valueFor(const KEY& key) const;
+ const VALUE& valueAt(size_t index) const;
+ const KEY& keyAt(size_t index) const;
+ ssize_t indexOfKey(const KEY& key) const;
+
+ /*!
+ * modifing the array
+ */
+
+ VALUE& editValueFor(const KEY& key);
+ VALUE& editValueAt(size_t index);
+
+ /*!
+ * add/insert/replace items
+ */
+
+ ssize_t add(const KEY& key, const VALUE& item);
+ ssize_t replaceValueFor(const KEY& key, const VALUE& item);
+ ssize_t replaceValueAt(size_t index, const VALUE& item);
+
+ /*!
+ * remove items
+ */
+
+ ssize_t removeItem(const KEY& key);
+ ssize_t removeItemsAt(size_t index, size_t count = 1);
+
+private:
+ SortedVector< key_value_pair_t<KEY, VALUE> > mVector;
+};
+
+// ---------------------------------------------------------------------------
+
+/**
+ * Variation of KeyedVector that holds a default value to return when
+ * valueFor() is called with a key that doesn't exist.
+ */
+template <typename KEY, typename VALUE>
+class DefaultKeyedVector : public KeyedVector<KEY, VALUE>
+{
+public:
+ inline DefaultKeyedVector(const VALUE& defValue = VALUE());
+ const VALUE& valueFor(const KEY& key) const;
+
+private:
+ VALUE mDefault;
+};
+
+// ---------------------------------------------------------------------------
+
+template<typename KEY, typename VALUE> inline
+KeyedVector<KEY,VALUE>::KeyedVector()
+{
+}
+
+template<typename KEY, typename VALUE> inline
+ssize_t KeyedVector<KEY,VALUE>::indexOfKey(const KEY& key) const {
+ return mVector.indexOf( key_value_pair_t<KEY,VALUE>(key) );
+}
+
+template<typename KEY, typename VALUE> inline
+const VALUE& KeyedVector<KEY,VALUE>::valueFor(const KEY& key) const {
+ ssize_t i = indexOfKey(key);
+ assert(i>=0);
+ return mVector.itemAt(i).value;
+}
+
+template<typename KEY, typename VALUE> inline
+const VALUE& KeyedVector<KEY,VALUE>::valueAt(size_t index) const {
+ return mVector.itemAt(index).value;
+}
+
+template<typename KEY, typename VALUE> inline
+const KEY& KeyedVector<KEY,VALUE>::keyAt(size_t index) const {
+ return mVector.itemAt(index).key;
+}
+
+template<typename KEY, typename VALUE> inline
+VALUE& KeyedVector<KEY,VALUE>::editValueFor(const KEY& key) {
+ ssize_t i = indexOfKey(key);
+ assert(i>=0);
+ return mVector.editItemAt(i).value;
+}
+
+template<typename KEY, typename VALUE> inline
+VALUE& KeyedVector<KEY,VALUE>::editValueAt(size_t index) {
+ return mVector.editItemAt(index).value;
+}
+
+template<typename KEY, typename VALUE> inline
+ssize_t KeyedVector<KEY,VALUE>::add(const KEY& key, const VALUE& value) {
+ return mVector.add( key_value_pair_t<KEY,VALUE>(key, value) );
+}
+
+template<typename KEY, typename VALUE> inline
+ssize_t KeyedVector<KEY,VALUE>::replaceValueFor(const KEY& key, const VALUE& value) {
+ key_value_pair_t<KEY,VALUE> pair(key, value);
+ mVector.remove(pair);
+ return mVector.add(pair);
+}
+
+template<typename KEY, typename VALUE> inline
+ssize_t KeyedVector<KEY,VALUE>::replaceValueAt(size_t index, const VALUE& item) {
+ if (index<size()) {
+ mVector.editValueAt(index).value = item;
+ return index;
+ }
+ return BAD_INDEX;
+}
+
+template<typename KEY, typename VALUE> inline
+ssize_t KeyedVector<KEY,VALUE>::removeItem(const KEY& key) {
+ return mVector.remove(key_value_pair_t<KEY,VALUE>(key));
+}
+
+template<typename KEY, typename VALUE> inline
+ssize_t KeyedVector<KEY, VALUE>::removeItemsAt(size_t index, size_t count) {
+ return mVector.removeItemsAt(index, count);
+}
+
+// ---------------------------------------------------------------------------
+
+template<typename KEY, typename VALUE> inline
+DefaultKeyedVector<KEY,VALUE>::DefaultKeyedVector(const VALUE& defValue)
+ : mDefault(defValue)
+{
+}
+
+template<typename KEY, typename VALUE> inline
+const VALUE& DefaultKeyedVector<KEY,VALUE>::valueFor(const KEY& key) const {
+ ssize_t i = indexOfKey(key);
+ return i >= 0 ? KeyedVector<KEY,VALUE>::valueAt(i) : mDefault;
+}
+
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_KEYED_VECTOR_H
diff --git a/include/utils/List.h b/include/utils/List.h
new file mode 100644
index 0000000..1a6be9a
--- /dev/null
+++ b/include/utils/List.h
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Templated list class. Normally we'd use STL, but we don't have that.
+// This class mimics STL's interfaces.
+//
+// Objects are copied into the list with the '=' operator or with copy-
+// construction, so if the compiler's auto-generated versions won't work for
+// you, define your own.
+//
+// The only class you want to use from here is "List". Do not use classes
+// starting with "_" directly.
+//
+#ifndef _LIBS_UTILS_LIST_H
+#define _LIBS_UTILS_LIST_H
+
+namespace android {
+
+/*
+ * One element in the list.
+ */
+template<class T> class _ListNode {
+public:
+ typedef _ListNode<T> _Node;
+
+ _ListNode(const T& val) : mVal(val) {}
+ ~_ListNode(void) {}
+
+ T& getRef(void) { return mVal; }
+ void setVal(const T& val) { mVal = val; }
+
+ _Node* getPrev(void) const { return mpPrev; }
+ void setPrev(_Node* ptr) { mpPrev = ptr; }
+ _Node* getNext(void) const { return mpNext; }
+ void setNext(_Node* ptr) { mpNext = ptr; }
+
+private:
+ T mVal;
+ _Node* mpPrev;
+ _Node* mpNext;
+};
+
+/*
+ * Iterator for walking through the list.
+ */
+template<class T, class Tref> class _ListIterator {
+public:
+ typedef _ListIterator<T,Tref> _Iter;
+ typedef _ListNode<T> _Node;
+
+ _ListIterator(void) {}
+ _ListIterator(_Node* ptr) : mpNode(ptr) {}
+ ~_ListIterator(void) {}
+
+ /*
+ * Dereference operator. Used to get at the juicy insides.
+ */
+ Tref operator*() const { return mpNode->getRef(); }
+
+ /*
+ * Iterator comparison.
+ */
+ bool operator==(const _Iter& right) const { return mpNode == right.mpNode; }
+ bool operator!=(const _Iter& right) const { return mpNode != right.mpNode; }
+
+ /*
+ * Incr/decr, used to move through the list.
+ */
+ _Iter& operator++(void) { // pre-increment
+ mpNode = mpNode->getNext();
+ return *this;
+ }
+ _Iter operator++(int) { // post-increment
+ _Iter tmp = *this;
+ ++*this;
+ return tmp;
+ }
+ _Iter& operator--(void) { // pre-increment
+ mpNode = mpNode->getPrev();
+ return *this;
+ }
+ _Iter operator--(int) { // post-increment
+ _Iter tmp = *this;
+ --*this;
+ return tmp;
+ }
+
+ _Node* getNode(void) const { return mpNode; }
+
+private:
+ _Node* mpNode;
+};
+
+
+/*
+ * Doubly-linked list. Instantiate with "List<MyClass> myList".
+ *
+ * Objects added to the list are copied using the assignment operator,
+ * so this must be defined.
+ */
+template<class T> class List {
+public:
+ typedef _ListNode<T> _Node;
+
+ List(void) {
+ prep();
+ }
+ List(const List<T>& src) { // copy-constructor
+ prep();
+ insert(begin(), src.begin(), src.end());
+ }
+ virtual ~List(void) {
+ clear();
+ delete[] (unsigned char*) mpMiddle;
+ }
+
+ typedef _ListIterator<T,T&> iterator;
+ typedef _ListIterator<T, const T&> const_iterator;
+
+ List<T>& operator=(const List<T>& right);
+
+ /* returns true if the list is empty */
+ bool empty(void) const { return mpMiddle->getNext() == mpMiddle; }
+
+ /* return #of elements in list */
+ unsigned int size(void) const {
+ return distance(begin(), end());
+ }
+
+ /*
+ * Return the first element or one past the last element. The
+ * _ListNode* we're returning is converted to an "iterator" by a
+ * constructor in _ListIterator.
+ */
+ iterator begin() { return mpMiddle->getNext(); }
+ const_iterator begin() const { return mpMiddle->getNext(); }
+ iterator end() { return mpMiddle; }
+ const_iterator end() const { return mpMiddle; }
+
+ /* add the object to the head or tail of the list */
+ void push_front(const T& val) { insert(begin(), val); }
+ void push_back(const T& val) { insert(end(), val); }
+
+ /* insert before the current node; returns iterator at new node */
+ iterator insert(iterator posn, const T& val) {
+ _Node* newNode = new _Node(val); // alloc & copy-construct
+ newNode->setNext(posn.getNode());
+ newNode->setPrev(posn.getNode()->getPrev());
+ posn.getNode()->getPrev()->setNext(newNode);
+ posn.getNode()->setPrev(newNode);
+ return newNode;
+ }
+
+ /* insert a range of elements before the current node */
+ void insert(iterator posn, const_iterator first, const_iterator last) {
+ for ( ; first != last; ++first)
+ insert(posn, *first);
+ }
+
+ /* remove one entry; returns iterator at next node */
+ iterator erase(iterator posn) {
+ _Node* pNext = posn.getNode()->getNext();
+ _Node* pPrev = posn.getNode()->getPrev();
+ pPrev->setNext(pNext);
+ pNext->setPrev(pPrev);
+ delete posn.getNode();
+ return pNext;
+ }
+
+ /* remove a range of elements */
+ iterator erase(iterator first, iterator last) {
+ while (first != last)
+ erase(first++); // don't erase than incr later!
+ return last;
+ }
+
+ /* remove all contents of the list */
+ void clear(void) {
+ _Node* pCurrent = mpMiddle->getNext();
+ _Node* pNext;
+
+ while (pCurrent != mpMiddle) {
+ pNext = pCurrent->getNext();
+ delete pCurrent;
+ pCurrent = pNext;
+ }
+ mpMiddle->setPrev(mpMiddle);
+ mpMiddle->setNext(mpMiddle);
+ }
+
+ /*
+ * Measure the distance between two iterators. On exist, "first"
+ * will be equal to "last". The iterators must refer to the same
+ * list.
+ *
+ * (This is actually a generic iterator function. It should be part
+ * of some other class, possibly an iterator base class. It needs to
+ * know the difference between a list, which has to march through,
+ * and a vector, which can just do pointer math.)
+ */
+ unsigned int distance(iterator first, iterator last) {
+ unsigned int count = 0;
+ while (first != last) {
+ ++first;
+ ++count;
+ }
+ return count;
+ }
+ unsigned int distance(const_iterator first, const_iterator last) const {
+ unsigned int count = 0;
+ while (first != last) {
+ ++first;
+ ++count;
+ }
+ return count;
+ }
+
+private:
+ /*
+ * I want a _ListNode but don't need it to hold valid data. More
+ * to the point, I don't want T's constructor to fire, since it
+ * might have side-effects or require arguments. So, we do this
+ * slightly uncouth storage alloc.
+ */
+ void prep(void) {
+ mpMiddle = (_Node*) new unsigned char[sizeof(_Node)];
+ mpMiddle->setPrev(mpMiddle);
+ mpMiddle->setNext(mpMiddle);
+ }
+
+ /*
+ * This node plays the role of "pointer to head" and "pointer to tail".
+ * It sits in the middle of a circular list of nodes. The iterator
+ * runs around the circle until it encounters this one.
+ */
+ _Node* mpMiddle;
+};
+
+/*
+ * Assignment operator.
+ *
+ * The simplest way to do this would be to clear out the target list and
+ * fill it with the source. However, we can speed things along by
+ * re-using existing elements.
+ */
+template<class T>
+List<T>& List<T>::operator=(const List<T>& right)
+{
+ if (this == &right)
+ return *this; // self-assignment
+ iterator firstDst = begin();
+ iterator lastDst = end();
+ const_iterator firstSrc = right.begin();
+ const_iterator lastSrc = right.end();
+ while (firstSrc != lastSrc && firstDst != lastDst)
+ *firstDst++ = *firstSrc++;
+ if (firstSrc == lastSrc) // ran out of elements in source?
+ erase(firstDst, lastDst); // yes, erase any extras
+ else
+ insert(lastDst, firstSrc, lastSrc); // copy remaining over
+ return *this;
+}
+
+}; // namespace android
+
+#endif // _LIBS_UTILS_LIST_H
diff --git a/include/utils/Log.h b/include/utils/Log.h
new file mode 100644
index 0000000..3c6cc8b
--- /dev/null
+++ b/include/utils/Log.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// C/C++ logging functions. See the logging documentation for API details.
+//
+// We'd like these to be available from C code (in case we import some from
+// somewhere), so this has a C interface.
+//
+// The output will be correct when the log file is shared between multiple
+// threads and/or multiple processes so long as the operating system
+// supports O_APPEND. These calls have mutex-protected data structures
+// and so are NOT reentrant. Do not use LOG in a signal handler.
+//
+#ifndef _LIBS_UTILS_LOG_H
+#define _LIBS_UTILS_LOG_H
+
+#include <cutils/log.h>
+
+#endif // _LIBS_UTILS_LOG_H
diff --git a/include/utils/LogSocket.h b/include/utils/LogSocket.h
new file mode 100644
index 0000000..01fbfb5
--- /dev/null
+++ b/include/utils/LogSocket.h
@@ -0,0 +1,20 @@
+/* utils/LogSocket.h
+**
+** Copyright 2008, The Android Open Source Project
+**
+** This file is dual licensed. It may be redistributed and/or modified
+** under the terms of the Apache 2.0 License OR version 2 of the GNU
+** General Public License.
+*/
+
+#ifndef _UTILS_LOGSOCKET_H
+#define _UTILS_LOGSOCKET_H
+
+#define SOCKET_CLOSE_LOCAL 0
+
+void add_send_stats(int fd, int send);
+void add_recv_stats(int fd, int recv);
+void log_socket_close(int fd, short reason);
+void log_socket_connect(int fd, unsigned int ip, unsigned short port);
+
+#endif /* _UTILS_LOGSOCKET_H */
diff --git a/include/utils/MemoryBase.h b/include/utils/MemoryBase.h
new file mode 100644
index 0000000..eb5a9d2
--- /dev/null
+++ b/include/utils/MemoryBase.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_MEMORY_BASE_H
+#define ANDROID_MEMORY_BASE_H
+
+#include <stdlib.h>
+#include <stdint.h>
+
+#include <utils/IMemory.h>
+
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class MemoryBase : public BnMemory
+{
+public:
+ MemoryBase(const sp<IMemoryHeap>& heap, ssize_t offset, size_t size);
+ virtual ~MemoryBase();
+ virtual sp<IMemoryHeap> getMemory(ssize_t* offset, size_t* size) const;
+
+protected:
+ size_t getSize() const { return mSize; }
+ ssize_t getOffset() const { return mOffset; }
+ const sp<IMemoryHeap>& getHeap() const { return mHeap; }
+
+private:
+ size_t mSize;
+ ssize_t mOffset;
+ sp<IMemoryHeap> mHeap;
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_MEMORY_BASE_H
diff --git a/include/utils/MemoryDealer.h b/include/utils/MemoryDealer.h
new file mode 100644
index 0000000..454b627
--- /dev/null
+++ b/include/utils/MemoryDealer.h
@@ -0,0 +1,238 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_MEMORY_DEALER_H
+#define ANDROID_MEMORY_DEALER_H
+
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/IMemory.h>
+#include <utils/threads.h>
+#include <utils/MemoryHeapBase.h>
+
+namespace android {
+// ----------------------------------------------------------------------------
+class String8;
+
+/*
+ * interface for implementing a "heap". A heap basically provides
+ * the IMemoryHeap interface for cross-process sharing and the
+ * ability to map/unmap pages within the heap.
+ */
+class HeapInterface : public virtual BnMemoryHeap
+{
+public:
+ // all values must be page-aligned
+ virtual sp<IMemory> mapMemory(size_t offset, size_t size) = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+/*
+ * interface for implementing an allocator. An allocator provides
+ * methods for allocating and freeing memory blocks and dumping
+ * its state.
+ */
+class AllocatorInterface : public RefBase
+{
+public:
+ enum {
+ PAGE_ALIGNED = 0x00000001
+ };
+
+ virtual size_t allocate(size_t size, uint32_t flags = 0) = 0;
+ virtual status_t deallocate(size_t offset) = 0;
+ virtual size_t size() const = 0;
+ virtual void dump(const char* what, uint32_t flags = 0) const = 0;
+ virtual void dump(String8& res,
+ const char* what, uint32_t flags = 0) const = 0;
+};
+
+// ----------------------------------------------------------------------------
+
+/*
+ * concrete implementation of HeapInterface on top of mmap()
+ */
+class SharedHeap : public HeapInterface, public MemoryHeapBase
+{
+public:
+ SharedHeap(size_t size, uint32_t flags = 0, char const * name = NULL);
+ virtual ~SharedHeap();
+ virtual sp<IMemory> mapMemory(size_t offset, size_t size);
+};
+
+// ----------------------------------------------------------------------------
+
+/*
+ * A simple templatized doubly linked-list implementation
+ */
+
+template <typename NODE>
+class LinkedList
+{
+ NODE* mFirst;
+ NODE* mLast;
+
+public:
+ LinkedList() : mFirst(0), mLast(0) { }
+ bool isEmpty() const { return mFirst == 0; }
+ NODE const* head() const { return mFirst; }
+ NODE* head() { return mFirst; }
+ NODE const* tail() const { return mLast; }
+ NODE* tail() { return mLast; }
+
+ void insertAfter(NODE* node, NODE* newNode) {
+ newNode->prev = node;
+ newNode->next = node->next;
+ if (node->next == 0) mLast = newNode;
+ else node->next->prev = newNode;
+ node->next = newNode;
+ }
+
+ void insertBefore(NODE* node, NODE* newNode) {
+ newNode->prev = node->prev;
+ newNode->next = node;
+ if (node->prev == 0) mFirst = newNode;
+ else node->prev->next = newNode;
+ node->prev = newNode;
+ }
+
+ void insertHead(NODE* newNode) {
+ if (mFirst == 0) {
+ mFirst = mLast = newNode;
+ newNode->prev = newNode->next = 0;
+ } else {
+ insertBefore(mFirst, newNode);
+ }
+ }
+
+ void insertTail(NODE* newNode) {
+ if (mLast == 0) insertBeginning(newNode);
+ else insertAfter(mLast, newNode);
+ }
+
+ NODE* remove(NODE* node) {
+ if (node->prev == 0) mFirst = node->next;
+ else node->prev->next = node->next;
+ if (node->next == 0) mLast = node->prev;
+ else node->next->prev = node->prev;
+ return node;
+ }
+};
+
+
+/*
+ * concrete implementation of AllocatorInterface using a simple
+ * best-fit allocation scheme
+ */
+class SimpleBestFitAllocator : public AllocatorInterface
+{
+public:
+
+ SimpleBestFitAllocator(size_t size);
+ virtual ~SimpleBestFitAllocator();
+
+ virtual size_t allocate(size_t size, uint32_t flags = 0);
+ virtual status_t deallocate(size_t offset);
+ virtual size_t size() const;
+ virtual void dump(const char* what, uint32_t flags = 0) const;
+ virtual void dump(String8& res,
+ const char* what, uint32_t flags = 0) const;
+
+private:
+
+ struct chunk_t {
+ chunk_t(size_t start, size_t size)
+ : start(start), size(size), free(1), prev(0), next(0) {
+ }
+ size_t start;
+ size_t size : 28;
+ int free : 4;
+ mutable chunk_t* prev;
+ mutable chunk_t* next;
+ };
+
+ ssize_t alloc(size_t size, uint32_t flags);
+ chunk_t* dealloc(size_t start);
+ void dump_l(const char* what, uint32_t flags = 0) const;
+ void dump_l(String8& res, const char* what, uint32_t flags = 0) const;
+
+ static const int kMemoryAlign;
+ mutable Mutex mLock;
+ LinkedList<chunk_t> mList;
+ size_t mHeapSize;
+};
+
+// ----------------------------------------------------------------------------
+
+class MemoryDealer : public RefBase
+{
+public:
+
+ enum {
+ READ_ONLY = MemoryHeapBase::READ_ONLY,
+ PAGE_ALIGNED = AllocatorInterface::PAGE_ALIGNED
+ };
+
+ // creates a memory dealer with the SharedHeap and SimpleBestFitAllocator
+ MemoryDealer(size_t size, uint32_t flags = 0, const char* name = 0);
+
+ // provide a custom heap but use the SimpleBestFitAllocator
+ MemoryDealer(const sp<HeapInterface>& heap);
+
+ // provide both custom heap and allocotar
+ MemoryDealer(
+ const sp<HeapInterface>& heap,
+ const sp<AllocatorInterface>& allocator);
+
+ virtual ~MemoryDealer();
+
+ virtual sp<IMemory> allocate(size_t size, uint32_t flags = 0);
+ virtual void deallocate(size_t offset);
+ virtual void dump(const char* what, uint32_t flags = 0) const;
+
+
+ sp<IMemoryHeap> getMemoryHeap() const { return heap(); }
+ sp<AllocatorInterface> getAllocator() const { return allocator(); }
+
+private:
+ const sp<HeapInterface>& heap() const;
+ const sp<AllocatorInterface>& allocator() const;
+
+ class Allocation : public BnMemory {
+ public:
+ Allocation(const sp<MemoryDealer>& dealer,
+ ssize_t offset, size_t size, const sp<IMemory>& memory);
+ virtual ~Allocation();
+ virtual sp<IMemoryHeap> getMemory(ssize_t* offset, size_t* size) const;
+ private:
+ sp<MemoryDealer> mDealer;
+ ssize_t mOffset;
+ size_t mSize;
+ sp<IMemory> mMemory;
+ };
+
+ sp<HeapInterface> mHeap;
+ sp<AllocatorInterface> mAllocator;
+};
+
+
+// ----------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_MEMORY_DEALER_H
diff --git a/include/utils/MemoryHeapBase.h b/include/utils/MemoryHeapBase.h
new file mode 100644
index 0000000..ff89738
--- /dev/null
+++ b/include/utils/MemoryHeapBase.h
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_MEMORY_HEAP_BASE_H
+#define ANDROID_MEMORY_HEAP_BASE_H
+
+#include <stdlib.h>
+#include <stdint.h>
+
+#include <utils/IMemory.h>
+
+
+namespace android {
+
+// ---------------------------------------------------------------------------
+
+class MemoryHeapBase : public virtual BnMemoryHeap
+{
+public:
+ enum {
+ READ_ONLY = IMemoryHeap::READ_ONLY,
+ MAP_ONCE = IMemoryHeap::MAP_ONCE
+ };
+
+ /*
+ * maps the memory referenced by fd. but DOESN'T take ownership
+ * of the filedescriptor (it makes a copy with dup()
+ */
+ MemoryHeapBase(int fd, size_t size, uint32_t flags = 0);
+
+ /*
+ * maps memory from the given device
+ */
+ MemoryHeapBase(const char* device, size_t size = 0, uint32_t flags = 0);
+
+ /*
+ * maps memory from ashmem, with the given name for debugging
+ */
+ MemoryHeapBase(size_t size, uint32_t flags = 0, char const* name = NULL);
+
+ virtual ~MemoryHeapBase();
+
+ /* implement IMemoryHeap interface */
+ virtual int getHeapID() const;
+ virtual void* getBase() const;
+ virtual size_t getSize() const;
+ virtual uint32_t getFlags() const;
+
+ const char* getDevice() const;
+
+ /* this closes this heap -- use carefully */
+ void dispose();
+
+ /* this is only needed as a workaround, use only if you know
+ * what you are doing */
+ status_t setDevice(const char* device) {
+ if (mDevice == 0)
+ mDevice = device;
+ return mDevice ? NO_ERROR : ALREADY_EXISTS;
+ }
+
+protected:
+ MemoryHeapBase();
+ // init() takes ownership of fd
+ status_t init(int fd, void *base, int size,
+ int flags = 0, const char* device = NULL);
+
+private:
+ status_t mapfd(int fd, size_t size);
+
+ int mFD;
+ size_t mSize;
+ void* mBase;
+ uint32_t mFlags;
+ const char* mDevice;
+ bool mNeedUnmap;
+};
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_MEMORY_HEAP_BASE_H
diff --git a/include/utils/MemoryHeapPmem.h b/include/utils/MemoryHeapPmem.h
new file mode 100644
index 0000000..b694b20
--- /dev/null
+++ b/include/utils/MemoryHeapPmem.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_MEMORY_HEAP_PMEM_H
+#define ANDROID_MEMORY_HEAP_PMEM_H
+
+#include <stdlib.h>
+#include <stdint.h>
+
+#include <utils/MemoryDealer.h>
+#include <utils/MemoryHeapBase.h>
+#include <utils/IMemory.h>
+#include <utils/Vector.h>
+
+namespace android {
+
+class MemoryHeapBase;
+
+// ---------------------------------------------------------------------------
+
+class SubRegionMemory;
+
+class MemoryHeapPmem : public HeapInterface, public MemoryHeapBase
+{
+public:
+ MemoryHeapPmem(const sp<MemoryHeapBase>& pmemHeap,
+ uint32_t flags = IMemoryHeap::MAP_ONCE);
+ ~MemoryHeapPmem();
+
+ /* HeapInterface additions */
+ virtual sp<IMemory> mapMemory(size_t offset, size_t size);
+
+ /* make the whole heap visible (you know who you are) */
+ virtual status_t slap();
+
+ /* hide (revoke) the whole heap (the client will see the garbage page) */
+ virtual status_t unslap();
+
+ /* revoke all allocations made by this heap */
+ virtual void revoke();
+
+private:
+ sp<MemoryHeapBase> mParentHeap;
+ mutable Mutex mLock;
+ Vector< wp<SubRegionMemory> > mAllocations;
+};
+
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_MEMORY_HEAP_PMEM_H
diff --git a/include/utils/Parcel.h b/include/utils/Parcel.h
new file mode 100644
index 0000000..7c451ab
--- /dev/null
+++ b/include/utils/Parcel.h
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_PARCEL_H
+#define ANDROID_PARCEL_H
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/String16.h>
+#include <utils/Vector.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+
+class IBinder;
+class ProcessState;
+class String8;
+class TextOutput;
+
+struct flat_binder_object; // defined in support_p/binder_module.h
+
+class Parcel
+{
+public:
+ Parcel();
+ ~Parcel();
+
+ const uint8_t* data() const;
+ size_t dataSize() const;
+ size_t dataAvail() const;
+ size_t dataPosition() const;
+ size_t dataCapacity() const;
+
+ status_t setDataSize(size_t size);
+ void setDataPosition(size_t pos) const;
+ status_t setDataCapacity(size_t size);
+
+ status_t setData(const uint8_t* buffer, size_t len);
+
+ status_t appendFrom(Parcel *parcel, size_t start, size_t len);
+
+ bool hasFileDescriptors() const;
+
+ status_t writeInterfaceToken(const String16& interface);
+ bool enforceInterface(const String16& interface) const;
+
+ void freeData();
+
+ const size_t* objects() const;
+ size_t objectsCount() const;
+
+ status_t errorCheck() const;
+ void setError(status_t err);
+
+ status_t write(const void* data, size_t len);
+ void* writeInplace(size_t len);
+ status_t writeUnpadded(const void* data, size_t len);
+ status_t writeInt32(int32_t val);
+ status_t writeInt64(int64_t val);
+ status_t writeFloat(float val);
+ status_t writeDouble(double val);
+ status_t writeCString(const char* str);
+ status_t writeString8(const String8& str);
+ status_t writeString16(const String16& str);
+ status_t writeString16(const char16_t* str, size_t len);
+ status_t writeStrongBinder(const sp<IBinder>& val);
+ status_t writeWeakBinder(const wp<IBinder>& val);
+
+ // Place a file descriptor into the parcel. The given fd must remain
+ // valid for the lifetime of the parcel.
+ status_t writeFileDescriptor(int fd);
+
+ // Place a file descriptor into the parcel. A dup of the fd is made, which
+ // will be closed once the parcel is destroyed.
+ status_t writeDupFileDescriptor(int fd);
+
+ status_t writeObject(const flat_binder_object& val, bool nullMetaData);
+
+ void remove(size_t start, size_t amt);
+
+ status_t read(void* outData, size_t len) const;
+ const void* readInplace(size_t len) const;
+ int32_t readInt32() const;
+ status_t readInt32(int32_t *pArg) const;
+ int64_t readInt64() const;
+ status_t readInt64(int64_t *pArg) const;
+ float readFloat() const;
+ status_t readFloat(float *pArg) const;
+ double readDouble() const;
+ status_t readDouble(double *pArg) const;
+
+ const char* readCString() const;
+ String8 readString8() const;
+ String16 readString16() const;
+ const char16_t* readString16Inplace(size_t* outLen) const;
+ sp<IBinder> readStrongBinder() const;
+ wp<IBinder> readWeakBinder() const;
+
+ // Retrieve a file descriptor from the parcel. This returns the raw fd
+ // in the parcel, which you do not own -- use dup() to get your own copy.
+ int readFileDescriptor() const;
+
+ const flat_binder_object* readObject(bool nullMetaData) const;
+
+ // Explicitly close all file descriptors in the parcel.
+ void closeFileDescriptors();
+
+ typedef void (*release_func)(Parcel* parcel,
+ const uint8_t* data, size_t dataSize,
+ const size_t* objects, size_t objectsSize,
+ void* cookie);
+
+ const uint8_t* ipcData() const;
+ size_t ipcDataSize() const;
+ const size_t* ipcObjects() const;
+ size_t ipcObjectsCount() const;
+ void ipcSetDataReference(const uint8_t* data, size_t dataSize,
+ const size_t* objects, size_t objectsCount,
+ release_func relFunc, void* relCookie);
+
+ void print(TextOutput& to, uint32_t flags = 0) const;
+
+private:
+ Parcel(const Parcel& o);
+ Parcel& operator=(const Parcel& o);
+
+ status_t finishWrite(size_t len);
+ void releaseObjects();
+ void acquireObjects();
+ status_t growData(size_t len);
+ status_t restartWrite(size_t desired);
+ status_t continueWrite(size_t desired);
+ void freeDataNoInit();
+ void initState();
+ void scanForFds() const;
+
+ status_t mError;
+ uint8_t* mData;
+ size_t mDataSize;
+ size_t mDataCapacity;
+ mutable size_t mDataPos;
+ size_t* mObjects;
+ size_t mObjectsSize;
+ size_t mObjectsCapacity;
+ mutable size_t mNextObjectHint;
+
+ mutable bool mFdsKnown;
+ mutable bool mHasFds;
+
+ release_func mOwner;
+ void* mOwnerCookie;
+};
+
+// ---------------------------------------------------------------------------
+
+inline TextOutput& operator<<(TextOutput& to, const Parcel& parcel)
+{
+ parcel.print(to);
+ return to;
+}
+
+// ---------------------------------------------------------------------------
+
+// Generic acquire and release of objects.
+void acquire_object(const sp<ProcessState>& proc,
+ const flat_binder_object& obj, const void* who);
+void release_object(const sp<ProcessState>& proc,
+ const flat_binder_object& obj, const void* who);
+
+void flatten_binder(const sp<ProcessState>& proc,
+ const sp<IBinder>& binder, flat_binder_object* out);
+void flatten_binder(const sp<ProcessState>& proc,
+ const wp<IBinder>& binder, flat_binder_object* out);
+status_t unflatten_binder(const sp<ProcessState>& proc,
+ const flat_binder_object& flat, sp<IBinder>* out);
+status_t unflatten_binder(const sp<ProcessState>& proc,
+ const flat_binder_object& flat, wp<IBinder>* out);
+
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_PARCEL_H
diff --git a/include/utils/Pipe.h b/include/utils/Pipe.h
new file mode 100644
index 0000000..6404168
--- /dev/null
+++ b/include/utils/Pipe.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// FIFO I/O.
+//
+#ifndef _LIBS_UTILS_PIPE_H
+#define _LIBS_UTILS_PIPE_H
+
+#ifdef HAVE_ANDROID_OS
+#error DO NOT USE THIS FILE IN THE DEVICE BUILD
+#endif
+
+namespace android {
+
+/*
+ * Simple anonymous unidirectional pipe.
+ *
+ * The primary goal is to create an implementation with minimal overhead
+ * under Linux. Making Windows, Mac OS X, and Linux all work the same way
+ * is a secondary goal. Part of this goal is to have something that can
+ * be fed to a select() call, so that the application can sleep in the
+ * kernel until something interesting happens.
+ */
+class Pipe {
+public:
+ Pipe(void);
+ virtual ~Pipe(void);
+
+ /* Create the pipe */
+ bool create(void);
+
+ /* Create a read-only pipe, using the supplied handle as read handle */
+ bool createReader(unsigned long handle);
+ /* Create a write-only pipe, using the supplied handle as write handle */
+ bool createWriter(unsigned long handle);
+
+ /* Is this object ready to go? */
+ bool isCreated(void);
+
+ /*
+ * Read "count" bytes from the pipe. Returns the amount of data read,
+ * or 0 if no data available and we're non-blocking.
+ * Returns -1 on error.
+ */
+ int read(void* buf, int count);
+
+ /*
+ * Write "count" bytes into the pipe. Returns number of bytes written,
+ * or 0 if there's no room for more data and we're non-blocking.
+ * Returns -1 on error.
+ */
+ int write(const void* buf, int count);
+
+ /* Returns "true" if data is available to read */
+ bool readReady(void);
+
+ /* Enable or disable non-blocking I/O for reads */
+ bool setReadNonBlocking(bool val);
+ /* Enable or disable non-blocking I/O for writes. Only works on Linux. */
+ bool setWriteNonBlocking(bool val);
+
+ /*
+ * Get the handle. Only useful in some platform-specific situations.
+ */
+ unsigned long getReadHandle(void);
+ unsigned long getWriteHandle(void);
+
+ /*
+ * Modify inheritance, i.e. whether or not a child process will get
+ * copies of the descriptors. Systems with fork+exec allow us to close
+ * the descriptors before launching the child process, but Win32
+ * doesn't allow it.
+ */
+ bool disallowReadInherit(void);
+ bool disallowWriteInherit(void);
+
+ /*
+ * Close one side or the other. Useful in the parent after launching
+ * a child process.
+ */
+ bool closeRead(void);
+ bool closeWrite(void);
+
+private:
+ bool mReadNonBlocking;
+ bool mWriteNonBlocking;
+
+ unsigned long mReadHandle;
+ unsigned long mWriteHandle;
+};
+
+}; // android
+
+#endif // _LIBS_UTILS_PIPE_H
diff --git a/include/utils/ProcessState.h b/include/utils/ProcessState.h
new file mode 100644
index 0000000..39584f4
--- /dev/null
+++ b/include/utils/ProcessState.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_PROCESS_STATE_H
+#define ANDROID_PROCESS_STATE_H
+
+#include <utils/IBinder.h>
+#include <utils/KeyedVector.h>
+#include <utils/String8.h>
+#include <utils/String16.h>
+
+#include <utils/threads.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+
+// Global variables
+extern int mArgC;
+extern const char* const* mArgV;
+extern int mArgLen;
+
+class IPCThreadState;
+
+class ProcessState : public virtual RefBase
+{
+public:
+ static sp<ProcessState> self();
+
+ static void setSingleProcess(bool singleProcess);
+
+ void setContextObject(const sp<IBinder>& object);
+ sp<IBinder> getContextObject(const sp<IBinder>& caller);
+
+ void setContextObject(const sp<IBinder>& object,
+ const String16& name);
+ sp<IBinder> getContextObject(const String16& name,
+ const sp<IBinder>& caller);
+
+ bool supportsProcesses() const;
+
+ void startThreadPool();
+
+ typedef bool (*context_check_func)(const String16& name,
+ const sp<IBinder>& caller,
+ void* userData);
+
+ bool isContextManager(void) const;
+ bool becomeContextManager(
+ context_check_func checkFunc,
+ void* userData);
+
+ sp<IBinder> getStrongProxyForHandle(int32_t handle);
+ wp<IBinder> getWeakProxyForHandle(int32_t handle);
+ void expungeHandle(int32_t handle, IBinder* binder);
+
+ void setArgs(int argc, const char* const argv[]);
+ int getArgC() const;
+ const char* const* getArgV() const;
+
+ void setArgV0(const char* txt);
+
+ void spawnPooledThread(bool isMain);
+
+private:
+ friend class IPCThreadState;
+
+ ProcessState();
+ ~ProcessState();
+
+ ProcessState(const ProcessState& o);
+ ProcessState& operator=(const ProcessState& o);
+
+ struct handle_entry {
+ IBinder* binder;
+ RefBase::weakref_type* refs;
+ };
+
+ handle_entry* lookupHandleLocked(int32_t handle);
+
+ int mDriverFD;
+ void* mVMStart;
+
+ mutable Mutex mLock; // protects everything below.
+
+ Vector<handle_entry>mHandleToObject;
+
+ bool mManagesContexts;
+ context_check_func mBinderContextCheckFunc;
+ void* mBinderContextUserData;
+
+ KeyedVector<String16, sp<IBinder> >
+ mContexts;
+
+
+ String8 mRootDir;
+ bool mThreadPoolStarted;
+ volatile int32_t mThreadPoolSeq;
+};
+
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_PROCESS_STATE_H
diff --git a/include/utils/RefBase.h b/include/utils/RefBase.h
new file mode 100644
index 0000000..e37b56f
--- /dev/null
+++ b/include/utils/RefBase.h
@@ -0,0 +1,526 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_REF_BASE_H
+#define ANDROID_REF_BASE_H
+
+#include <utils/TextOutput.h>
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <stdlib.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+
+template<typename T> class wp;
+
+// ---------------------------------------------------------------------------
+
+#define COMPARE(_op_) \
+inline bool operator _op_ (const sp<T>& o) const { \
+ return m_ptr _op_ o.m_ptr; \
+} \
+inline bool operator _op_ (const wp<T>& o) const { \
+ return m_ptr _op_ o.m_ptr; \
+} \
+inline bool operator _op_ (const T* o) const { \
+ return m_ptr _op_ o; \
+} \
+template<typename U> \
+inline bool operator _op_ (const sp<U>& o) const { \
+ return m_ptr _op_ o.m_ptr; \
+} \
+template<typename U> \
+inline bool operator _op_ (const wp<U>& o) const { \
+ return m_ptr _op_ o.m_ptr; \
+} \
+template<typename U> \
+inline bool operator _op_ (const U* o) const { \
+ return m_ptr _op_ o; \
+}
+
+// ---------------------------------------------------------------------------
+
+class RefBase
+{
+public:
+ void incStrong(const void* id) const;
+ void decStrong(const void* id) const;
+
+ void forceIncStrong(const void* id) const;
+
+ //! DEBUGGING ONLY: Get current strong ref count.
+ int32_t getStrongCount() const;
+
+ class weakref_type
+ {
+ public:
+ RefBase* refBase() const;
+
+ void incWeak(const void* id);
+ void decWeak(const void* id);
+
+ bool attemptIncStrong(const void* id);
+
+ //! This is only safe if you have set OBJECT_LIFETIME_FOREVER.
+ bool attemptIncWeak(const void* id);
+
+ //! DEBUGGING ONLY: Get current weak ref count.
+ int32_t getWeakCount() const;
+
+ //! DEBUGGING ONLY: Print references held on object.
+ void printRefs() const;
+
+ //! DEBUGGING ONLY: Enable tracking for this object.
+ // enable -- enable/disable tracking
+ // retain -- when tracking is enable, if true, then we save a stack trace
+ // for each reference and dereference; when retain == false, we
+ // match up references and dereferences and keep only the
+ // outstanding ones.
+
+ void trackMe(bool enable, bool retain);
+ };
+
+ weakref_type* createWeak(const void* id) const;
+
+ weakref_type* getWeakRefs() const;
+
+ //! DEBUGGING ONLY: Print references held on object.
+ inline void printRefs() const { getWeakRefs()->printRefs(); }
+
+ //! DEBUGGING ONLY: Enable tracking of object.
+ inline void trackMe(bool enable, bool retain)
+ {
+ getWeakRefs()->trackMe(enable, retain);
+ }
+
+protected:
+ RefBase();
+ virtual ~RefBase();
+
+ //! Flags for extendObjectLifetime()
+ enum {
+ OBJECT_LIFETIME_WEAK = 0x0001,
+ OBJECT_LIFETIME_FOREVER = 0x0003
+ };
+
+ void extendObjectLifetime(int32_t mode);
+
+ //! Flags for onIncStrongAttempted()
+ enum {
+ FIRST_INC_STRONG = 0x0001
+ };
+
+ virtual void onFirstRef();
+ virtual void onLastStrongRef(const void* id);
+ virtual bool onIncStrongAttempted(uint32_t flags, const void* id);
+ virtual void onLastWeakRef(const void* id);
+
+private:
+ friend class weakref_type;
+ class weakref_impl;
+
+ RefBase(const RefBase& o);
+ RefBase& operator=(const RefBase& o);
+
+ weakref_impl* const mRefs;
+};
+
+// ---------------------------------------------------------------------------
+
+template <typename T>
+class sp
+{
+public:
+ typedef typename RefBase::weakref_type weakref_type;
+
+ inline sp() : m_ptr(0) { }
+
+ sp(T* other);
+ sp(const sp<T>& other);
+ template<typename U> sp(U* other);
+ template<typename U> sp(const sp<U>& other);
+
+ ~sp();
+
+ // Assignment
+
+ sp& operator = (T* other);
+ sp& operator = (const sp<T>& other);
+
+ template<typename U> sp& operator = (const sp<U>& other);
+ template<typename U> sp& operator = (U* other);
+
+ //! Special optimization for use by ProcessState (and nobody else).
+ void force_set(T* other);
+
+ // Reset
+
+ void clear();
+
+ // Accessors
+
+ inline T& operator* () const { return *m_ptr; }
+ inline T* operator-> () const { return m_ptr; }
+ inline T* get() const { return m_ptr; }
+
+ // Operators
+
+ COMPARE(==)
+ COMPARE(!=)
+ COMPARE(>)
+ COMPARE(<)
+ COMPARE(<=)
+ COMPARE(>=)
+
+private:
+ template<typename Y> friend class sp;
+ template<typename Y> friend class wp;
+
+ // Optimization for wp::promote().
+ sp(T* p, weakref_type* refs);
+
+ T* m_ptr;
+};
+
+template <typename T>
+TextOutput& operator<<(TextOutput& to, const sp<T>& val);
+
+// ---------------------------------------------------------------------------
+
+template <typename T>
+class wp
+{
+public:
+ typedef typename RefBase::weakref_type weakref_type;
+
+ inline wp() : m_ptr(0) { }
+
+ wp(T* other);
+ wp(const wp<T>& other);
+ wp(const sp<T>& other);
+ template<typename U> wp(U* other);
+ template<typename U> wp(const sp<U>& other);
+ template<typename U> wp(const wp<U>& other);
+
+ ~wp();
+
+ // Assignment
+
+ wp& operator = (T* other);
+ wp& operator = (const wp<T>& other);
+ wp& operator = (const sp<T>& other);
+
+ template<typename U> wp& operator = (U* other);
+ template<typename U> wp& operator = (const wp<U>& other);
+ template<typename U> wp& operator = (const sp<U>& other);
+
+ void set_object_and_refs(T* other, weakref_type* refs);
+
+ // promotion to sp
+
+ sp<T> promote() const;
+
+ // Reset
+
+ void clear();
+
+ // Accessors
+
+ inline weakref_type* get_refs() const { return m_refs; }
+
+ inline T* unsafe_get() const { return m_ptr; }
+
+ // Operators
+
+ COMPARE(==)
+ COMPARE(!=)
+ COMPARE(>)
+ COMPARE(<)
+ COMPARE(<=)
+ COMPARE(>=)
+
+private:
+ template<typename Y> friend class sp;
+ template<typename Y> friend class wp;
+
+ T* m_ptr;
+ weakref_type* m_refs;
+};
+
+template <typename T>
+TextOutput& operator<<(TextOutput& to, const wp<T>& val);
+
+#undef COMPARE
+
+// ---------------------------------------------------------------------------
+// No user serviceable parts below here.
+
+template<typename T>
+sp<T>::sp(T* other)
+ : m_ptr(other)
+{
+ if (other) other->incStrong(this);
+}
+
+template<typename T>
+sp<T>::sp(const sp<T>& other)
+ : m_ptr(other.m_ptr)
+{
+ if (m_ptr) m_ptr->incStrong(this);
+}
+
+template<typename T> template<typename U>
+sp<T>::sp(U* other) : m_ptr(other)
+{
+ if (other) other->incStrong(this);
+}
+
+template<typename T> template<typename U>
+sp<T>::sp(const sp<U>& other)
+ : m_ptr(other.m_ptr)
+{
+ if (m_ptr) m_ptr->incStrong(this);
+}
+
+template<typename T>
+sp<T>::~sp()
+{
+ if (m_ptr) m_ptr->decStrong(this);
+}
+
+template<typename T>
+sp<T>& sp<T>::operator = (const sp<T>& other) {
+ if (other.m_ptr) other.m_ptr->incStrong(this);
+ if (m_ptr) m_ptr->decStrong(this);
+ m_ptr = other.m_ptr;
+ return *this;
+}
+
+template<typename T>
+sp<T>& sp<T>::operator = (T* other)
+{
+ if (other) other->incStrong(this);
+ if (m_ptr) m_ptr->decStrong(this);
+ m_ptr = other;
+ return *this;
+}
+
+template<typename T> template<typename U>
+sp<T>& sp<T>::operator = (const sp<U>& other)
+{
+ if (other.m_ptr) other.m_ptr->incStrong(this);
+ if (m_ptr) m_ptr->decStrong(this);
+ m_ptr = other.m_ptr;
+ return *this;
+}
+
+template<typename T> template<typename U>
+sp<T>& sp<T>::operator = (U* other)
+{
+ if (other) other->incStrong(this);
+ if (m_ptr) m_ptr->decStrong(this);
+ m_ptr = other;
+ return *this;
+}
+
+template<typename T>
+void sp<T>::force_set(T* other)
+{
+ other->forceIncStrong(this);
+ m_ptr = other;
+}
+
+template<typename T>
+void sp<T>::clear()
+{
+ if (m_ptr) {
+ m_ptr->decStrong(this);
+ m_ptr = 0;
+ }
+}
+
+template<typename T>
+sp<T>::sp(T* p, weakref_type* refs)
+ : m_ptr((p && refs->attemptIncStrong(this)) ? p : 0)
+{
+}
+
+template <typename T>
+inline TextOutput& operator<<(TextOutput& to, const sp<T>& val)
+{
+ to << "sp<>(" << val.get() << ")";
+ return to;
+}
+
+// ---------------------------------------------------------------------------
+
+template<typename T>
+wp<T>::wp(T* other)
+ : m_ptr(other)
+{
+ if (other) m_refs = other->createWeak(this);
+}
+
+template<typename T>
+wp<T>::wp(const wp<T>& other)
+ : m_ptr(other.m_ptr), m_refs(other.m_refs)
+{
+ if (m_ptr) m_refs->incWeak(this);
+}
+
+template<typename T>
+wp<T>::wp(const sp<T>& other)
+ : m_ptr(other.m_ptr)
+{
+ if (m_ptr) {
+ m_refs = m_ptr->createWeak(this);
+ }
+}
+
+template<typename T> template<typename U>
+wp<T>::wp(U* other)
+ : m_ptr(other)
+{
+ if (other) m_refs = other->createWeak(this);
+}
+
+template<typename T> template<typename U>
+wp<T>::wp(const wp<U>& other)
+ : m_ptr(other.m_ptr)
+{
+ if (m_ptr) {
+ m_refs = other.m_refs;
+ m_refs->incWeak(this);
+ }
+}
+
+template<typename T> template<typename U>
+wp<T>::wp(const sp<U>& other)
+ : m_ptr(other.m_ptr)
+{
+ if (m_ptr) {
+ m_refs = m_ptr->createWeak(this);
+ }
+}
+
+template<typename T>
+wp<T>::~wp()
+{
+ if (m_ptr) m_refs->decWeak(this);
+}
+
+template<typename T>
+wp<T>& wp<T>::operator = (T* other)
+{
+ weakref_type* newRefs =
+ other ? other->createWeak(this) : 0;
+ if (m_ptr) m_refs->decWeak(this);
+ m_ptr = other;
+ m_refs = newRefs;
+ return *this;
+}
+
+template<typename T>
+wp<T>& wp<T>::operator = (const wp<T>& other)
+{
+ if (other.m_ptr) other.m_refs->incWeak(this);
+ if (m_ptr) m_refs->decWeak(this);
+ m_ptr = other.m_ptr;
+ m_refs = other.m_refs;
+ return *this;
+}
+
+template<typename T>
+wp<T>& wp<T>::operator = (const sp<T>& other)
+{
+ weakref_type* newRefs =
+ other != NULL ? other->createWeak(this) : 0;
+ if (m_ptr) m_refs->decWeak(this);
+ m_ptr = other.get();
+ m_refs = newRefs;
+ return *this;
+}
+
+template<typename T> template<typename U>
+wp<T>& wp<T>::operator = (U* other)
+{
+ weakref_type* newRefs =
+ other ? other->createWeak(this) : 0;
+ if (m_ptr) m_refs->decWeak(this);
+ m_ptr = other;
+ m_refs = newRefs;
+ return *this;
+}
+
+template<typename T> template<typename U>
+wp<T>& wp<T>::operator = (const wp<U>& other)
+{
+ if (other.m_ptr) other.m_refs->incWeak(this);
+ if (m_ptr) m_refs->decWeak(this);
+ m_ptr = other.m_ptr;
+ m_refs = other.m_refs;
+ return *this;
+}
+
+template<typename T> template<typename U>
+wp<T>& wp<T>::operator = (const sp<U>& other)
+{
+ weakref_type* newRefs =
+ other != NULL ? other->createWeak(this) : 0;
+ if (m_ptr) m_refs->decWeak(this);
+ m_ptr = other.get();
+ m_refs = newRefs;
+ return *this;
+}
+
+template<typename T>
+void wp<T>::set_object_and_refs(T* other, weakref_type* refs)
+{
+ if (other) refs->incWeak(this);
+ if (m_ptr) m_refs->decWeak(this);
+ m_ptr = other;
+ m_refs = refs;
+}
+
+template<typename T>
+sp<T> wp<T>::promote() const
+{
+ return sp<T>(m_ptr, m_refs);
+}
+
+template<typename T>
+void wp<T>::clear()
+{
+ if (m_ptr) {
+ m_refs->decWeak(this);
+ m_ptr = 0;
+ }
+}
+
+template <typename T>
+inline TextOutput& operator<<(TextOutput& to, const wp<T>& val)
+{
+ to << "wp<>(" << val.unsafe_get() << ")";
+ return to;
+}
+
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_REF_BASE_H
diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h
new file mode 100644
index 0000000..31b9aa8
--- /dev/null
+++ b/include/utils/ResourceTypes.h
@@ -0,0 +1,1685 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Definitions of resource data structures.
+//
+#ifndef _LIBS_UTILS_RESOURCE_TYPES_H
+#define _LIBS_UTILS_RESOURCE_TYPES_H
+
+#include <utils/Asset.h>
+#include <utils/ByteOrder.h>
+#include <utils/Errors.h>
+#include <utils/String16.h>
+#include <utils/Vector.h>
+
+#include <utils/threads.h>
+
+#include <stdint.h>
+#include <sys/types.h>
+
+namespace android {
+
+/** ********************************************************************
+ * PNG Extensions
+ *
+ * New private chunks that may be placed in PNG images.
+ *
+ *********************************************************************** */
+
+/**
+ * This chunk specifies how to split an image into segments for
+ * scaling.
+ *
+ * There are J horizontal and K vertical segments. These segments divide
+ * the image into J*K regions as follows (where J=4 and K=3):
+ *
+ * F0 S0 F1 S1
+ * +-----+----+------+-------+
+ * S2| 0 | 1 | 2 | 3 |
+ * +-----+----+------+-------+
+ * | | | | |
+ * | | | | |
+ * F2| 4 | 5 | 6 | 7 |
+ * | | | | |
+ * | | | | |
+ * +-----+----+------+-------+
+ * S3| 8 | 9 | 10 | 11 |
+ * +-----+----+------+-------+
+ *
+ * Each horizontal and vertical segment is considered to by either
+ * stretchable (marked by the Sx labels) or fixed (marked by the Fy
+ * labels), in the horizontal or vertical axis, respectively. In the
+ * above example, the first is horizontal segment (F0) is fixed, the
+ * next is stretchable and then they continue to alternate. Note that
+ * the segment list for each axis can begin or end with a stretchable
+ * or fixed segment.
+ *
+ * The relative sizes of the stretchy segments indicates the relative
+ * amount of stretchiness of the regions bordered by the segments. For
+ * example, regions 3, 7 and 11 above will take up more horizontal space
+ * than regions 1, 5 and 9 since the horizonal segment associated with
+ * the first set of regions is larger than the other set of regions. The
+ * ratios of the amount of horizontal (or vertical) space taken by any
+ * two stretchable slices is exactly the ratio of their corresponding
+ * segment lengths.
+ *
+ * xDivs and yDivs point to arrays of horizontal and vertical pixel
+ * indices. The first pair of Divs (in either array) indicate the
+ * starting and ending points of the first stretchable segment in that
+ * axis. The next pair specifies the next stretchable segment, etc. So
+ * in the above example xDiv[0] and xDiv[1] specify the horizontal
+ * coordinates for the regions labeled 1, 5 and 9. xDiv[2] and
+ * xDiv[3] specify the coordinates for regions 3, 7 and 11. Note that
+ * the leftmost slices always start at x=0 and the rightmost slices
+ * always end at the end of the image. So, for example, the regions 0,
+ * 4 and 8 (which are fixed along the X axis) start at x value 0 and
+ * go to xDiv[0] amd slices 2, 6 and 10 start at xDiv[1] and end at
+ * xDiv[2].
+ *
+ * The array pointed to by the colors field lists contains hints for
+ * each of the regions. They are ordered according left-to-right and
+ * top-to-bottom as indicated above. For each segment that is a solid
+ * color the array entry will contain that color value; otherwise it
+ * will contain NO_COLOR. Segments that are completely transparent
+ * will always have the value TRANSPARENT_COLOR.
+ *
+ * The PNG chunk type is "npTc".
+ */
+struct Res_png_9patch
+{
+ Res_png_9patch() : wasDeserialized(false), xDivs(NULL),
+ yDivs(NULL), colors(NULL) { }
+
+ int8_t wasDeserialized;
+ int8_t numXDivs;
+ int8_t numYDivs;
+ int8_t numColors;
+
+ // These tell where the next section of a patch starts.
+ // For example, the first patch includes the pixels from
+ // 0 to xDivs[0]-1 and the second patch includes the pixels
+ // from xDivs[0] to xDivs[1]-1.
+ // Note: allocation/free of these pointers is left to the caller.
+ int32_t* xDivs;
+ int32_t* yDivs;
+
+ int32_t paddingLeft, paddingRight;
+ int32_t paddingTop, paddingBottom;
+
+ enum {
+ // The 9 patch segment is not a solid color.
+ NO_COLOR = 0x00000001,
+
+ // The 9 patch segment is completely transparent.
+ TRANSPARENT_COLOR = 0x00000000
+ };
+ // Note: allocation/free of this pointer is left to the caller.
+ uint32_t* colors;
+
+ // Convert data from device representation to PNG file representation.
+ void deviceToFile();
+ // Convert data from PNG file representation to device representation.
+ void fileToDevice();
+ // Serialize/Marshall the patch data into a newly malloc-ed block
+ void* serialize();
+ // Serialize/Marshall the patch data
+ void serialize(void* outData);
+ // Deserialize/Unmarshall the patch data
+ static Res_png_9patch* deserialize(const void* data);
+ // Deserialize/Unmarshall the patch data into a newly malloc-ed block
+ static void deserialize(const void* data, Res_png_9patch* outData);
+ // Compute the size of the serialized data structure
+ size_t serializedSize();
+};
+
+/** ********************************************************************
+ * Base Types
+ *
+ * These are standard types that are shared between multiple specific
+ * resource types.
+ *
+ *********************************************************************** */
+
+/**
+ * Header that appears at the front of every data chunk in a resource.
+ */
+struct ResChunk_header
+{
+ // Type identifier for this chunk. The meaning of this value depends
+ // on the containing chunk.
+ uint16_t type;
+
+ // Size of the chunk header (in bytes). Adding this value to
+ // the address of the chunk allows you to find its associated data
+ // (if any).
+ uint16_t headerSize;
+
+ // Total size of this chunk (in bytes). This is the chunkSize plus
+ // the size of any data associated with the chunk. Adding this value
+ // to the chunk allows you to completely skip its contents (including
+ // any child chunks). If this value is the same as chunkSize, there is
+ // no data associated with the chunk.
+ uint32_t size;
+};
+
+enum {
+ RES_NULL_TYPE = 0x0000,
+ RES_STRING_POOL_TYPE = 0x0001,
+ RES_TABLE_TYPE = 0x0002,
+ RES_XML_TYPE = 0x0003,
+
+ // Chunk types in RES_XML_TYPE
+ RES_XML_FIRST_CHUNK_TYPE = 0x0100,
+ RES_XML_START_NAMESPACE_TYPE= 0x0100,
+ RES_XML_END_NAMESPACE_TYPE = 0x0101,
+ RES_XML_START_ELEMENT_TYPE = 0x0102,
+ RES_XML_END_ELEMENT_TYPE = 0x0103,
+ RES_XML_CDATA_TYPE = 0x0104,
+ RES_XML_LAST_CHUNK_TYPE = 0x017f,
+ // This contains a uint32_t array mapping strings in the string
+ // pool back to resource identifiers. It is optional.
+ RES_XML_RESOURCE_MAP_TYPE = 0x0180,
+
+ // Chunk types in RES_TABLE_TYPE
+ RES_TABLE_PACKAGE_TYPE = 0x0200,
+ RES_TABLE_TYPE_TYPE = 0x0201,
+ RES_TABLE_TYPE_SPEC_TYPE = 0x0202
+};
+
+/**
+ * Macros for building/splitting resource identifiers.
+ */
+#define Res_VALIDID(resid) (resid != 0)
+#define Res_CHECKID(resid) ((resid&0xFFFF0000) != 0)
+#define Res_MAKEID(package, type, entry) \
+ (((package+1)<<24) | (((type+1)&0xFF)<<16) | (entry&0xFFFF))
+#define Res_GETPACKAGE(id) ((id>>24)-1)
+#define Res_GETTYPE(id) (((id>>16)&0xFF)-1)
+#define Res_GETENTRY(id) (id&0xFFFF)
+
+#define Res_INTERNALID(resid) ((resid&0xFFFF0000) != 0 && (resid&0xFF0000) == 0)
+#define Res_MAKEINTERNAL(entry) (0x01000000 | (entry&0xFFFF))
+#define Res_MAKEARRAY(entry) (0x02000000 | (entry&0xFFFF))
+
+#define Res_MAXPACKAGE 255
+
+/**
+ * Representation of a value in a resource, supplying type
+ * information.
+ */
+struct Res_value
+{
+ // Number of bytes in this structure.
+ uint16_t size;
+
+ // Always set to 0.
+ uint8_t res0;
+
+ // Type of the data value.
+ enum {
+ // Contains no data.
+ TYPE_NULL = 0x00,
+ // The 'data' holds a ResTable_ref, a reference to another resource
+ // table entry.
+ TYPE_REFERENCE = 0x01,
+ // The 'data' holds an attribute resource identifier.
+ TYPE_ATTRIBUTE = 0x02,
+ // The 'data' holds an index into the containing resource table's
+ // global value string pool.
+ TYPE_STRING = 0x03,
+ // The 'data' holds a single-precision floating point number.
+ TYPE_FLOAT = 0x04,
+ // The 'data' holds a complex number encoding a dimension value,
+ // such as "100in".
+ TYPE_DIMENSION = 0x05,
+ // The 'data' holds a complex number encoding a fraction of a
+ // container.
+ TYPE_FRACTION = 0x06,
+
+ // Beginning of integer flavors...
+ TYPE_FIRST_INT = 0x10,
+
+ // The 'data' is a raw integer value of the form n..n.
+ TYPE_INT_DEC = 0x10,
+ // The 'data' is a raw integer value of the form 0xn..n.
+ TYPE_INT_HEX = 0x11,
+ // The 'data' is either 0 or 1, for input "false" or "true" respectively.
+ TYPE_INT_BOOLEAN = 0x12,
+
+ // Beginning of color integer flavors...
+ TYPE_FIRST_COLOR_INT = 0x1c,
+
+ // The 'data' is a raw integer value of the form #aarrggbb.
+ TYPE_INT_COLOR_ARGB8 = 0x1c,
+ // The 'data' is a raw integer value of the form #rrggbb.
+ TYPE_INT_COLOR_RGB8 = 0x1d,
+ // The 'data' is a raw integer value of the form #argb.
+ TYPE_INT_COLOR_ARGB4 = 0x1e,
+ // The 'data' is a raw integer value of the form #rgb.
+ TYPE_INT_COLOR_RGB4 = 0x1f,
+
+ // ...end of integer flavors.
+ TYPE_LAST_COLOR_INT = 0x1f,
+
+ // ...end of integer flavors.
+ TYPE_LAST_INT = 0x1f
+ };
+ uint8_t dataType;
+
+ // Structure of complex data values (TYPE_UNIT and TYPE_FRACTION)
+ enum {
+ // Where the unit type information is. This gives us 16 possible
+ // types, as defined below.
+ COMPLEX_UNIT_SHIFT = 0,
+ COMPLEX_UNIT_MASK = 0xf,
+
+ // TYPE_DIMENSION: Value is raw pixels.
+ COMPLEX_UNIT_PX = 0,
+ // TYPE_DIMENSION: Value is Device Independent Pixels.
+ COMPLEX_UNIT_DIP = 1,
+ // TYPE_DIMENSION: Value is a Scaled device independent Pixels.
+ COMPLEX_UNIT_SP = 2,
+ // TYPE_DIMENSION: Value is in points.
+ COMPLEX_UNIT_PT = 3,
+ // TYPE_DIMENSION: Value is in inches.
+ COMPLEX_UNIT_IN = 4,
+ // TYPE_DIMENSION: Value is in millimeters.
+ COMPLEX_UNIT_MM = 5,
+
+ // TYPE_FRACTION: A basic fraction of the overall size.
+ COMPLEX_UNIT_FRACTION = 0,
+ // TYPE_FRACTION: A fraction of the parent size.
+ COMPLEX_UNIT_FRACTION_PARENT = 1,
+
+ // Where the radix information is, telling where the decimal place
+ // appears in the mantissa. This give us 4 possible fixed point
+ // representations as defined below.
+ COMPLEX_RADIX_SHIFT = 4,
+ COMPLEX_RADIX_MASK = 0x3,
+
+ // The mantissa is an integral number -- i.e., 0xnnnnnn.0
+ COMPLEX_RADIX_23p0 = 0,
+ // The mantissa magnitude is 16 bits -- i.e, 0xnnnn.nn
+ COMPLEX_RADIX_16p7 = 1,
+ // The mantissa magnitude is 8 bits -- i.e, 0xnn.nnnn
+ COMPLEX_RADIX_8p15 = 2,
+ // The mantissa magnitude is 0 bits -- i.e, 0x0.nnnnnn
+ COMPLEX_RADIX_0p23 = 3,
+
+ // Where the actual value is. This gives us 23 bits of
+ // precision. The top bit is the sign.
+ COMPLEX_MANTISSA_SHIFT = 8,
+ COMPLEX_MANTISSA_MASK = 0xffffff
+ };
+
+ // The data for this item, as interpreted according to dataType.
+ uint32_t data;
+
+ void copyFrom_dtoh(const Res_value& src);
+};
+
+/**
+ * This is a reference to a unique entry (a ResTable_entry structure)
+ * in a resource table. The value is structured as: 0xpptteeee,
+ * where pp is the package index, tt is the type index in that
+ * package, and eeee is the entry index in that type. The package
+ * and type values start at 1 for the first item, to help catch cases
+ * where they have not been supplied.
+ */
+struct ResTable_ref
+{
+ uint32_t ident;
+};
+
+/**
+ * Reference to a string in a string pool.
+ */
+struct ResStringPool_ref
+{
+ // Index into the string pool table (uint32_t-offset from the indices
+ // immediately after ResStringPool_header) at which to find the location
+ // of the string data in the pool.
+ uint32_t index;
+};
+
+/** ********************************************************************
+ * String Pool
+ *
+ * A set of strings that can be references by others through a
+ * ResStringPool_ref.
+ *
+ *********************************************************************** */
+
+/**
+ * Definition for a pool of strings. The data of this chunk is an
+ * array of uint32_t providing indices into the pool, relative to
+ * stringsStart. At stringsStart are all of the UTF-16 strings
+ * concatenated together; each starts with a uint16_t of the string's
+ * length and each ends with a 0x0000 terminator. If a string is >
+ * 32767 characters, the high bit of the length is set meaning to take
+ * those 15 bits as a high word and it will be followed by another
+ * uint16_t containing the low word.
+ *
+ * If styleCount is not zero, then immediately following the array of
+ * uint32_t indices into the string table is another array of indices
+ * into a style table starting at stylesStart. Each entry in the
+ * style table is an array of ResStringPool_span structures.
+ */
+struct ResStringPool_header
+{
+ struct ResChunk_header header;
+
+ // Number of strings in this pool (number of uint32_t indices that follow
+ // in the data).
+ uint32_t stringCount;
+
+ // Number of style span arrays in the pool (number of uint32_t indices
+ // follow the string indices).
+ uint32_t styleCount;
+
+ // Flags.
+ enum {
+ // If set, the string index is sorted by the string values (based
+ // on strcmp16()).
+ SORTED_FLAG = 1<<0
+ };
+ uint32_t flags;
+
+ // Index from header of the string data.
+ uint32_t stringsStart;
+
+ // Index from header of the style data.
+ uint32_t stylesStart;
+};
+
+/**
+ * This structure defines a span of style information associated with
+ * a string in the pool.
+ */
+struct ResStringPool_span
+{
+ enum {
+ END = 0xFFFFFFFF
+ };
+
+ // This is the name of the span -- that is, the name of the XML
+ // tag that defined it. The special value END (0xFFFFFFFF) indicates
+ // the end of an array of spans.
+ ResStringPool_ref name;
+
+ // The range of characters in the string that this span applies to.
+ uint32_t firstChar, lastChar;
+};
+
+/**
+ * Convenience class for accessing data in a ResStringPool resource.
+ */
+class ResStringPool
+{
+public:
+ ResStringPool();
+ ResStringPool(const void* data, size_t size, bool copyData=false);
+ ~ResStringPool();
+
+ status_t setTo(const void* data, size_t size, bool copyData=false);
+
+ status_t getError() const;
+
+ void uninit();
+
+ inline const char16_t* stringAt(const ResStringPool_ref& ref, size_t* outLen) const {
+ return stringAt(ref.index, outLen);
+ }
+ const char16_t* stringAt(size_t idx, size_t* outLen) const;
+
+ const ResStringPool_span* styleAt(const ResStringPool_ref& ref) const;
+ const ResStringPool_span* styleAt(size_t idx) const;
+
+ ssize_t indexOfString(const char16_t* str, size_t strLen) const;
+
+ size_t size() const;
+
+private:
+ status_t mError;
+ void* mOwnedData;
+ const ResStringPool_header* mHeader;
+ size_t mSize;
+ const uint32_t* mEntries;
+ const uint32_t* mEntryStyles;
+ const char16_t* mStrings;
+ uint32_t mStringPoolSize; // number of uint16_t
+ const uint32_t* mStyles;
+ uint32_t mStylePoolSize; // number of uint32_t
+};
+
+/** ********************************************************************
+ * XML Tree
+ *
+ * Binary representation of an XML document. This is designed to
+ * express everything in an XML document, in a form that is much
+ * easier to parse on the device.
+ *
+ *********************************************************************** */
+
+/**
+ * XML tree header. This appears at the front of an XML tree,
+ * describing its content. It is followed by a flat array of
+ * ResXMLTree_node structures; the hierarchy of the XML document
+ * is described by the occurrance of RES_XML_START_ELEMENT_TYPE
+ * and corresponding RES_XML_END_ELEMENT_TYPE nodes in the array.
+ */
+struct ResXMLTree_header
+{
+ struct ResChunk_header header;
+};
+
+/**
+ * Basic XML tree node. A single item in the XML document. Extended info
+ * about the node can be found after header.headerSize.
+ */
+struct ResXMLTree_node
+{
+ struct ResChunk_header header;
+
+ // Line number in original source file at which this element appeared.
+ uint32_t lineNumber;
+
+ // Optional XML comment that was associated with this element; -1 if none.
+ struct ResStringPool_ref comment;
+};
+
+/**
+ * Extended XML tree node for CDATA tags -- includes the CDATA string.
+ * Appears header.headerSize bytes after a ResXMLTree_node.
+ */
+struct ResXMLTree_cdataExt
+{
+ // The raw CDATA character data.
+ struct ResStringPool_ref data;
+
+ // The typed value of the character data if this is a CDATA node.
+ struct Res_value typedData;
+};
+
+/**
+ * Extended XML tree node for namespace start/end nodes.
+ * Appears header.headerSize bytes after a ResXMLTree_node.
+ */
+struct ResXMLTree_namespaceExt
+{
+ // The prefix of the namespace.
+ struct ResStringPool_ref prefix;
+
+ // The URI of the namespace.
+ struct ResStringPool_ref uri;
+};
+
+/**
+ * Extended XML tree node for element start/end nodes.
+ * Appears header.headerSize bytes after a ResXMLTree_node.
+ */
+struct ResXMLTree_endElementExt
+{
+ // String of the full namespace of this element.
+ struct ResStringPool_ref ns;
+
+ // String name of this node if it is an ELEMENT; the raw
+ // character data if this is a CDATA node.
+ struct ResStringPool_ref name;
+};
+
+/**
+ * Extended XML tree node for start tags -- includes attribute
+ * information.
+ * Appears header.headerSize bytes after a ResXMLTree_node.
+ */
+struct ResXMLTree_attrExt
+{
+ // String of the full namespace of this element.
+ struct ResStringPool_ref ns;
+
+ // String name of this node if it is an ELEMENT; the raw
+ // character data if this is a CDATA node.
+ struct ResStringPool_ref name;
+
+ // Byte offset from the start of this structure where the attributes start.
+ uint16_t attributeStart;
+
+ // Size of the ResXMLTree_attribute structures that follow.
+ uint16_t attributeSize;
+
+ // Number of attributes associated with an ELEMENT. These are
+ // available as an array of ResXMLTree_attribute structures
+ // immediately following this node.
+ uint16_t attributeCount;
+
+ // Index (1-based) of the "id" attribute. 0 if none.
+ uint16_t idIndex;
+
+ // Index (1-based) of the "class" attribute. 0 if none.
+ uint16_t classIndex;
+
+ // Index (1-based) of the "style" attribute. 0 if none.
+ uint16_t styleIndex;
+};
+
+struct ResXMLTree_attribute
+{
+ // Namespace of this attribute.
+ struct ResStringPool_ref ns;
+
+ // Name of this attribute.
+ struct ResStringPool_ref name;
+
+ // The original raw string value of this attribute.
+ struct ResStringPool_ref rawValue;
+
+ // Processesd typed value of this attribute.
+ struct Res_value typedValue;
+};
+
+class ResXMLTree;
+
+class ResXMLParser
+{
+public:
+ ResXMLParser(const ResXMLTree& tree);
+
+ enum event_code_t {
+ BAD_DOCUMENT = -1,
+ START_DOCUMENT = 0,
+ END_DOCUMENT = 1,
+
+ FIRST_CHUNK_CODE = RES_XML_FIRST_CHUNK_TYPE,
+
+ START_NAMESPACE = RES_XML_START_NAMESPACE_TYPE,
+ END_NAMESPACE = RES_XML_END_NAMESPACE_TYPE,
+ START_TAG = RES_XML_START_ELEMENT_TYPE,
+ END_TAG = RES_XML_END_ELEMENT_TYPE,
+ TEXT = RES_XML_CDATA_TYPE
+ };
+
+ struct ResXMLPosition
+ {
+ event_code_t eventCode;
+ const ResXMLTree_node* curNode;
+ const void* curExt;
+ };
+
+ void restart();
+
+ event_code_t getEventType() const;
+ // Note, unlike XmlPullParser, the first call to next() will return
+ // START_TAG of the first element.
+ event_code_t next();
+
+ // These are available for all nodes:
+ const int32_t getCommentID() const;
+ const uint16_t* getComment(size_t* outLen) const;
+ const uint32_t getLineNumber() const;
+
+ // This is available for TEXT:
+ const int32_t getTextID() const;
+ const uint16_t* getText(size_t* outLen) const;
+ ssize_t getTextValue(Res_value* outValue) const;
+
+ // These are available for START_NAMESPACE and END_NAMESPACE:
+ const int32_t getNamespacePrefixID() const;
+ const uint16_t* getNamespacePrefix(size_t* outLen) const;
+ const int32_t getNamespaceUriID() const;
+ const uint16_t* getNamespaceUri(size_t* outLen) const;
+
+ // These are available for START_TAG and END_TAG:
+ const int32_t getElementNamespaceID() const;
+ const uint16_t* getElementNamespace(size_t* outLen) const;
+ const int32_t getElementNameID() const;
+ const uint16_t* getElementName(size_t* outLen) const;
+
+ // Remaining methods are for retrieving information about attributes
+ // associated with a START_TAG:
+
+ size_t getAttributeCount() const;
+
+ // Returns -1 if no namespace, -2 if idx out of range.
+ const int32_t getAttributeNamespaceID(size_t idx) const;
+ const uint16_t* getAttributeNamespace(size_t idx, size_t* outLen) const;
+
+ const int32_t getAttributeNameID(size_t idx) const;
+ const uint16_t* getAttributeName(size_t idx, size_t* outLen) const;
+ const uint32_t getAttributeNameResID(size_t idx) const;
+
+ const int32_t getAttributeValueStringID(size_t idx) const;
+ const uint16_t* getAttributeStringValue(size_t idx, size_t* outLen) const;
+
+ int32_t getAttributeDataType(size_t idx) const;
+ int32_t getAttributeData(size_t idx) const;
+ ssize_t getAttributeValue(size_t idx, Res_value* outValue) const;
+
+ ssize_t indexOfAttribute(const char* ns, const char* attr) const;
+ ssize_t indexOfAttribute(const char16_t* ns, size_t nsLen,
+ const char16_t* attr, size_t attrLen) const;
+
+ ssize_t indexOfID() const;
+ ssize_t indexOfClass() const;
+ ssize_t indexOfStyle() const;
+
+ void getPosition(ResXMLPosition* pos) const;
+ void setPosition(const ResXMLPosition& pos);
+
+private:
+ friend class ResXMLTree;
+
+ event_code_t nextNode();
+
+ const ResXMLTree& mTree;
+ event_code_t mEventCode;
+ const ResXMLTree_node* mCurNode;
+ const void* mCurExt;
+};
+
+/**
+ * Convenience class for accessing data in a ResXMLTree resource.
+ */
+class ResXMLTree : public ResXMLParser
+{
+public:
+ ResXMLTree();
+ ResXMLTree(const void* data, size_t size, bool copyData=false);
+ ~ResXMLTree();
+
+ status_t setTo(const void* data, size_t size, bool copyData=false);
+
+ status_t getError() const;
+
+ void uninit();
+
+ const ResStringPool& getStrings() const;
+
+private:
+ friend class ResXMLParser;
+
+ status_t validateNode(const ResXMLTree_node* node) const;
+
+ status_t mError;
+ void* mOwnedData;
+ const ResXMLTree_header* mHeader;
+ size_t mSize;
+ const uint8_t* mDataEnd;
+ ResStringPool mStrings;
+ const uint32_t* mResIds;
+ size_t mNumResIds;
+ const ResXMLTree_node* mRootNode;
+ const void* mRootExt;
+ event_code_t mRootCode;
+};
+
+/** ********************************************************************
+ * RESOURCE TABLE
+ *
+ *********************************************************************** */
+
+/**
+ * Header for a resource table. Its data contains a series of
+ * additional chunks:
+ * * A ResStringPool_header containing all table values.
+ * * One or more ResTable_package chunks.
+ *
+ * Specific entries within a resource table can be uniquely identified
+ * with a single integer as defined by the ResTable_ref structure.
+ */
+struct ResTable_header
+{
+ struct ResChunk_header header;
+
+ // The number of ResTable_package structures.
+ uint32_t packageCount;
+};
+
+/**
+ * A collection of resource data types within a package. Followed by
+ * one or more ResTable_type and ResTable_typeSpec structures containing the
+ * entry values for each resource type.
+ */
+struct ResTable_package
+{
+ struct ResChunk_header header;
+
+ // If this is a base package, its ID. Package IDs start
+ // at 1 (corresponding to the value of the package bits in a
+ // resource identifier). 0 means this is not a base package.
+ uint32_t id;
+
+ // Actual name of this package, \0-terminated.
+ char16_t name[128];
+
+ // Offset to a ResStringPool_header defining the resource
+ // type symbol table. If zero, this package is inheriting from
+ // another base package (overriding specific values in it).
+ uint32_t typeStrings;
+
+ // Last index into typeStrings that is for public use by others.
+ uint32_t lastPublicType;
+
+ // Offset to a ResStringPool_header defining the resource
+ // key symbol table. If zero, this package is inheriting from
+ // another base package (overriding specific values in it).
+ uint32_t keyStrings;
+
+ // Last index into keyStrings that is for public use by others.
+ uint32_t lastPublicKey;
+};
+
+/**
+ * Describes a particular resource configuration.
+ */
+struct ResTable_config
+{
+ // Number of bytes in this structure.
+ uint32_t size;
+
+ union {
+ struct {
+ // Mobile country code (from SIM). 0 means "any".
+ uint16_t mcc;
+ // Mobile network code (from SIM). 0 means "any".
+ uint16_t mnc;
+ };
+ uint32_t imsi;
+ };
+
+ union {
+ struct {
+ // \0\0 means "any". Otherwise, en, fr, etc.
+ char language[2];
+
+ // \0\0 means "any". Otherwise, US, CA, etc.
+ char country[2];
+ };
+ uint32_t locale;
+ };
+
+ enum {
+ ORIENTATION_ANY = 0x0000,
+ ORIENTATION_PORT = 0x0001,
+ ORIENTATION_LAND = 0x0002,
+ ORIENTATION_SQUARE = 0x0002,
+ };
+
+ enum {
+ TOUCHSCREEN_ANY = 0x0000,
+ TOUCHSCREEN_NOTOUCH = 0x0001,
+ TOUCHSCREEN_STYLUS = 0x0002,
+ TOUCHSCREEN_FINGER = 0x0003,
+ };
+
+ enum {
+ DENSITY_ANY = 0
+ };
+
+ union {
+ struct {
+ uint8_t orientation;
+ uint8_t touchscreen;
+ uint16_t density;
+ };
+ uint32_t screenType;
+ };
+
+ enum {
+ KEYBOARD_ANY = 0x0000,
+ KEYBOARD_NOKEYS = 0x0001,
+ KEYBOARD_QWERTY = 0x0002,
+ KEYBOARD_12KEY = 0x0003,
+ };
+
+ enum {
+ NAVIGATION_ANY = 0x0000,
+ NAVIGATION_NONAV = 0x0001,
+ NAVIGATION_DPAD = 0x0002,
+ NAVIGATION_TRACKBALL = 0x0003,
+ NAVIGATION_WHEEL = 0x0004,
+ };
+
+ enum {
+ MASK_KEYSHIDDEN = 0x0003,
+ SHIFT_KEYSHIDDEN = 0,
+ KEYSHIDDEN_ANY = 0x0000,
+ KEYSHIDDEN_NO = 0x0001,
+ KEYSHIDDEN_YES = 0x0002,
+ };
+
+ union {
+ struct {
+ uint8_t keyboard;
+ uint8_t navigation;
+ uint8_t inputFlags;
+ uint8_t pad0;
+ };
+ uint32_t input;
+ };
+
+ enum {
+ SCREENWIDTH_ANY = 0
+ };
+
+ enum {
+ SCREENHEIGHT_ANY = 0
+ };
+
+ union {
+ struct {
+ uint16_t screenWidth;
+ uint16_t screenHeight;
+ };
+ uint32_t screenSize;
+ };
+
+ enum {
+ SDKVERSION_ANY = 0
+ };
+
+ enum {
+ MINORVERSION_ANY = 0
+ };
+
+ union {
+ struct {
+ uint16_t sdkVersion;
+ // For now minorVersion must always be 0!!! Its meaning
+ // is currently undefined.
+ uint16_t minorVersion;
+ };
+ uint32_t version;
+ };
+
+ inline void copyFromDeviceNoSwap(const ResTable_config& o) {
+ const size_t size = dtohl(o.size);
+ if (size >= sizeof(ResTable_config)) {
+ *this = o;
+ } else {
+ memcpy(this, &o, size);
+ memset(((uint8_t*)this)+size, 0, sizeof(ResTable_config)-size);
+ }
+ }
+
+ inline void copyFromDtoH(const ResTable_config& o) {
+ copyFromDeviceNoSwap(o);
+ size = sizeof(ResTable_config);
+ mcc = dtohs(mcc);
+ mnc = dtohs(mnc);
+ density = dtohs(density);
+ screenWidth = dtohs(screenWidth);
+ screenHeight = dtohs(screenHeight);
+ sdkVersion = dtohs(sdkVersion);
+ minorVersion = dtohs(minorVersion);
+ }
+
+ inline void swapHtoD() {
+ size = htodl(size);
+ mcc = htods(mcc);
+ mnc = htods(mnc);
+ density = htods(density);
+ screenWidth = htods(screenWidth);
+ screenHeight = htods(screenHeight);
+ sdkVersion = htods(sdkVersion);
+ minorVersion = htods(minorVersion);
+ }
+
+ inline int compare(const ResTable_config& o) const {
+ int32_t diff = (int32_t)(imsi - o.imsi);
+ if (diff != 0) return diff;
+ diff = (int32_t)(locale - o.locale);
+ if (diff != 0) return diff;
+ diff = (int32_t)(screenType - o.screenType);
+ if (diff != 0) return diff;
+ diff = (int32_t)(input - o.input);
+ if (diff != 0) return diff;
+ diff = (int32_t)(screenSize - o.screenSize);
+ if (diff != 0) return diff;
+ diff = (int32_t)(version - o.version);
+ return (int)diff;
+ }
+
+ // Flags indicating a set of config values. These flag constants must
+ // match the corresponding ones in android.content.pm.ActivityInfo and
+ // attrs_manifest.xml.
+ enum {
+ CONFIG_MCC = 0x0001,
+ CONFIG_MNC = 0x0002,
+ CONFIG_LOCALE = 0x0004,
+ CONFIG_TOUCHSCREEN = 0x0008,
+ CONFIG_KEYBOARD = 0x0010,
+ CONFIG_KEYBOARD_HIDDEN = 0x0020,
+ CONFIG_NAVIGATION = 0x0040,
+ CONFIG_ORIENTATION = 0x0080,
+ CONFIG_DENSITY = 0x0100,
+ CONFIG_SCREEN_SIZE = 0x0200,
+ CONFIG_VERSION = 0x0400
+ };
+
+ // Compare two configuration, returning CONFIG_* flags set for each value
+ // that is different.
+ inline int diff(const ResTable_config& o) const {
+ int diffs = 0;
+ if (mcc != o.mcc) diffs |= CONFIG_MCC;
+ if (mnc != o.mnc) diffs |= CONFIG_MNC;
+ if (locale != o.locale) diffs |= CONFIG_LOCALE;
+ if (orientation != o.orientation) diffs |= CONFIG_ORIENTATION;
+ if (density != o.density) diffs |= CONFIG_DENSITY;
+ if (touchscreen != o.touchscreen) diffs |= CONFIG_TOUCHSCREEN;
+ if (((inputFlags^o.inputFlags)&MASK_KEYSHIDDEN) != 0) diffs |= CONFIG_KEYBOARD_HIDDEN;
+ if (keyboard != o.keyboard) diffs |= CONFIG_KEYBOARD;
+ if (navigation != o.navigation) diffs |= CONFIG_NAVIGATION;
+ if (screenSize != o.screenSize) diffs |= CONFIG_SCREEN_SIZE;
+ if (version != o.version) diffs |= CONFIG_VERSION;
+ return diffs;
+ }
+
+ // Return true if 'this' is more specific than 'o'.
+ inline bool
+ isBetterThan(const ResTable_config& o, const ResTable_config* requested = NULL) const {
+ if (imsi != 0 && (!requested || requested->imsi != 0)) {
+ if (mcc != 0 && (!requested || requested->mcc!= 0)) {
+ if (o.mcc == 0) {
+ return true;
+ }
+ }
+ if (mnc != 0 && (!requested || requested->mnc != 0)) {
+ if (o.mnc == 0) {
+ return true;
+ }
+ }
+ }
+ if (locale != 0 && (!requested || requested->locale != 0)) {
+ if (language[0] != 0 && (!requested || requested->language[0] != 0)) {
+ if (o.language[0] == 0) {
+ return true;
+ }
+ }
+ if (country[0] != 0 && (!requested || requested->country[0] != 0)) {
+ if (o.country[0] == 0) {
+ return true;
+ }
+ }
+ }
+ if (screenType != 0 && (!requested || requested->screenType != 0)) {
+ if (orientation != 0 && (!requested || requested->orientation != 0)) {
+ if (o.orientation == 0) {
+ return true;
+ }
+ }
+ if (density != 0 && (!requested || requested->density != 0)) {
+ if (o.density == 0) {
+ return true;
+ }
+ }
+ if (touchscreen != 0 && (!requested || requested->touchscreen != 0)) {
+ if (o.touchscreen == 0) {
+ return true;
+ }
+ }
+ }
+ if (input != 0 && (!requested || requested->input != 0)) {
+ if ((inputFlags&MASK_KEYSHIDDEN) != 0 && (!requested
+ || (requested->inputFlags&MASK_KEYSHIDDEN) != 0)) {
+ if ((o.inputFlags&MASK_KEYSHIDDEN) == 0) {
+ return true;
+ }
+ }
+ if (keyboard != 0 && (!requested || requested->keyboard != 0)) {
+ if (o.keyboard == 0) {
+ return true;
+ }
+ }
+ if (navigation != 0 && (!requested || requested->navigation != 0)) {
+ if (o.navigation == 0) {
+ return true;
+ }
+ }
+ }
+ if (screenSize != 0 && (!requested || requested->screenSize != 0)) {
+ if (screenWidth != 0 && (!requested || requested->screenWidth != 0)) {
+ if (o.screenWidth == 0) {
+ return true;
+ }
+ }
+ if (screenHeight != 0 && (!requested || requested->screenHeight != 0)) {
+ if (o.screenHeight == 0) {
+ return true;
+ }
+ }
+ }
+ if (version != 0 && (!requested || requested->version != 0)) {
+ if (sdkVersion != 0 && (!requested || requested->sdkVersion != 0)) {
+ if (o.sdkVersion == 0) {
+ return true;
+ }
+ }
+ if (minorVersion != 0 && (!requested || requested->minorVersion != 0)) {
+ if (o.minorVersion == 0) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ // Return true if 'this' matches the parameters in 'settings'.
+ inline bool match(const ResTable_config& settings) const {
+ if (imsi != 0) {
+ if (settings.mcc != 0 && mcc != 0
+ && mcc != settings.mcc) {
+ return false;
+ }
+ if (settings.mnc != 0 && mnc != 0
+ && mnc != settings.mnc) {
+ return false;
+ }
+ }
+ if (locale != 0) {
+ if (settings.language[0] != 0 && language[0] != 0
+ && (language[0] != settings.language[0]
+ || language[1] != settings.language[1])) {
+ return false;
+ }
+ if (settings.country[0] != 0 && country[0] != 0
+ && (country[0] != settings.country[0]
+ || country[1] != settings.country[1])) {
+ return false;
+ }
+ }
+ if (screenType != 0) {
+ if (settings.orientation != 0 && orientation != 0
+ && orientation != settings.orientation) {
+ return false;
+ }
+ if (settings.density != 0 && density != 0
+ && density != settings.density) {
+ return false;
+ }
+ if (settings.touchscreen != 0 && touchscreen != 0
+ && touchscreen != settings.touchscreen) {
+ return false;
+ }
+ }
+ if (input != 0) {
+ const int keysHidden = inputFlags&MASK_KEYSHIDDEN;
+ const int setKeysHidden = settings.inputFlags&MASK_KEYSHIDDEN;
+ if (setKeysHidden != 0 && keysHidden != 0
+ && keysHidden != setKeysHidden) {
+ return false;
+ }
+ if (settings.keyboard != 0 && keyboard != 0
+ && keyboard != settings.keyboard) {
+ return false;
+ }
+ if (settings.navigation != 0 && navigation != 0
+ && navigation != settings.navigation) {
+ return false;
+ }
+ }
+ if (screenSize != 0) {
+ if (settings.screenWidth != 0 && screenWidth != 0
+ && screenWidth != settings.screenWidth) {
+ return false;
+ }
+ if (settings.screenHeight != 0 && screenHeight != 0
+ && screenHeight != settings.screenHeight) {
+ return false;
+ }
+ }
+ if (version != 0) {
+ if (settings.sdkVersion != 0 && sdkVersion != 0
+ && sdkVersion != settings.sdkVersion) {
+ return false;
+ }
+ if (settings.minorVersion != 0 && minorVersion != 0
+ && minorVersion != settings.minorVersion) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ void getLocale(char str[6]) const {
+ memset(str, 0, 6);
+ if (language[0]) {
+ str[0] = language[0];
+ str[1] = language[1];
+ if (country[0]) {
+ str[2] = '_';
+ str[3] = country[0];
+ str[4] = country[1];
+ }
+ }
+ }
+
+ String8 toString() const {
+ char buf[200];
+ sprintf(buf, "imsi=%d/%d lang=%c%c reg=%c%c orient=0x%02x touch=0x%02x dens=0x%02x "
+ "kbd=0x%02x nav=0x%02x input=0x%02x screenW=0x%04x screenH=0x%04x vers=%d.%d",
+ mcc, mnc,
+ language[0] ? language[0] : '-', language[1] ? language[1] : '-',
+ country[0] ? country[0] : '-', country[1] ? country[1] : '-',
+ orientation, touchscreen, density, keyboard, navigation, inputFlags,
+ screenWidth, screenHeight, sdkVersion, minorVersion);
+ return String8(buf);
+ }
+};
+
+/**
+ * A specification of the resources defined by a particular type.
+ *
+ * There should be one of these chunks for each resource type.
+ *
+ * This structure is followed by an array of integers providing the set of
+ * configuation change flags (ResTable_config::CONFIG_*) that have multiple
+ * resources for that configuration. In addition, the high bit is set if that
+ * resource has been made public.
+ */
+struct ResTable_typeSpec
+{
+ struct ResChunk_header header;
+
+ // The type identifier this chunk is holding. Type IDs start
+ // at 1 (corresponding to the value of the type bits in a
+ // resource identifier). 0 is invalid.
+ uint8_t id;
+
+ // Must be 0.
+ uint8_t res0;
+ // Must be 0.
+ uint16_t res1;
+
+ // Number of uint32_t entry configuration masks that follow.
+ uint32_t entryCount;
+
+ enum {
+ // Additional flag indicating an entry is public.
+ SPEC_PUBLIC = 0x40000000
+ };
+};
+
+/**
+ * A collection of resource entries for a particular resource data
+ * type. Followed by an array of uint32_t defining the resource
+ * values, corresponding to the array of type strings in the
+ * ResTable_package::typeStrings string block. Each of these hold an
+ * index from entriesStart; a value of NO_ENTRY means that entry is
+ * not defined.
+ *
+ * There may be multiple of these chunks for a particular resource type,
+ * supply different configuration variations for the resource values of
+ * that type.
+ *
+ * It would be nice to have an additional ordered index of entries, so
+ * we can do a binary search if trying to find a resource by string name.
+ */
+struct ResTable_type
+{
+ struct ResChunk_header header;
+
+ enum {
+ NO_ENTRY = 0xFFFFFFFF
+ };
+
+ // The type identifier this chunk is holding. Type IDs start
+ // at 1 (corresponding to the value of the type bits in a
+ // resource identifier). 0 is invalid.
+ uint8_t id;
+
+ // Must be 0.
+ uint8_t res0;
+ // Must be 0.
+ uint16_t res1;
+
+ // Number of uint32_t entry indices that follow.
+ uint32_t entryCount;
+
+ // Offset from header where ResTable_entry data starts.
+ uint32_t entriesStart;
+
+ // Configuration this collection of entries is designed for.
+ ResTable_config config;
+};
+
+/**
+ * This is the beginning of information about an entry in the resource
+ * table. It holds the reference to the name of this entry, and is
+ * immediately followed by one of:
+ * * A Res_value structures, if FLAG_COMPLEX is -not- set.
+ * * An array of ResTable_map structures, if FLAG_COMPLEX is set.
+ * These supply a set of name/value mappings of data.
+ */
+struct ResTable_entry
+{
+ // Number of bytes in this structure.
+ uint16_t size;
+
+ enum {
+ // If set, this is a complex entry, holding a set of name/value
+ // mappings. It is followed by an array of ResTable_map structures.
+ FLAG_COMPLEX = 0x0001,
+ // If set, this resource has been declared public, so libraries
+ // are allowed to reference it.
+ FLAG_PUBLIC = 0x0002
+ };
+ uint16_t flags;
+
+ // Reference into ResTable_package::keyStrings identifying this entry.
+ struct ResStringPool_ref key;
+};
+
+/**
+ * Extended form of a ResTable_entry for map entries, defining a parent map
+ * resource from which to inherit values.
+ */
+struct ResTable_map_entry : public ResTable_entry
+{
+ // Resource identifier of the parent mapping, or 0 if there is none.
+ ResTable_ref parent;
+ // Number of name/value pairs that follow for FLAG_COMPLEX.
+ uint32_t count;
+};
+
+/**
+ * A single name/value mapping that is part of a complex resource
+ * entry.
+ */
+struct ResTable_map
+{
+ // The resource identifier defining this mapping's name. For attribute
+ // resources, 'name' can be one of the following special resource types
+ // to supply meta-data about the attribute; for all other resource types
+ // it must be an attribute resource.
+ ResTable_ref name;
+
+ // Special values for 'name' when defining attribute resources.
+ enum {
+ // This entry holds the attribute's type code.
+ ATTR_TYPE = Res_MAKEINTERNAL(0),
+
+ // For integral attributes, this is the minimum value it can hold.
+ ATTR_MIN = Res_MAKEINTERNAL(1),
+
+ // For integral attributes, this is the maximum value it can hold.
+ ATTR_MAX = Res_MAKEINTERNAL(2),
+
+ // Localization of this resource is can be encouraged or required with
+ // an aapt flag if this is set
+ ATTR_L10N = Res_MAKEINTERNAL(3),
+
+ // for plural support, see android.content.res.PluralRules#attrForQuantity(int)
+ ATTR_OTHER = Res_MAKEINTERNAL(4),
+ ATTR_ZERO = Res_MAKEINTERNAL(5),
+ ATTR_ONE = Res_MAKEINTERNAL(6),
+ ATTR_TWO = Res_MAKEINTERNAL(7),
+ ATTR_FEW = Res_MAKEINTERNAL(8),
+ ATTR_MANY = Res_MAKEINTERNAL(9)
+
+ };
+
+ // Bit mask of allowed types, for use with ATTR_TYPE.
+ enum {
+ // No type has been defined for this attribute, use generic
+ // type handling. The low 16 bits are for types that can be
+ // handled generically; the upper 16 require additional information
+ // in the bag so can not be handled generically for TYPE_ANY.
+ TYPE_ANY = 0x0000FFFF,
+
+ // Attribute holds a references to another resource.
+ TYPE_REFERENCE = 1<<0,
+
+ // Attribute holds a generic string.
+ TYPE_STRING = 1<<1,
+
+ // Attribute holds an integer value. ATTR_MIN and ATTR_MIN can
+ // optionally specify a constrained range of possible integer values.
+ TYPE_INTEGER = 1<<2,
+
+ // Attribute holds a boolean integer.
+ TYPE_BOOLEAN = 1<<3,
+
+ // Attribute holds a color value.
+ TYPE_COLOR = 1<<4,
+
+ // Attribute holds a floating point value.
+ TYPE_FLOAT = 1<<5,
+
+ // Attribute holds a dimension value, such as "20px".
+ TYPE_DIMENSION = 1<<6,
+
+ // Attribute holds a fraction value, such as "20%".
+ TYPE_FRACTION = 1<<7,
+
+ // Attribute holds an enumeration. The enumeration values are
+ // supplied as additional entries in the map.
+ TYPE_ENUM = 1<<16,
+
+ // Attribute holds a bitmaks of flags. The flag bit values are
+ // supplied as additional entries in the map.
+ TYPE_FLAGS = 1<<17
+ };
+
+ // Enum of localization modes, for use with ATTR_L10N.
+ enum {
+ L10N_NOT_REQUIRED = 0,
+ L10N_SUGGESTED = 1
+ };
+
+ // This mapping's value.
+ Res_value value;
+};
+
+/**
+ * Convenience class for accessing data in a ResTable resource.
+ */
+class ResTable
+{
+public:
+ ResTable();
+ ResTable(const void* data, size_t size, void* cookie,
+ bool copyData=false);
+ ~ResTable();
+
+ status_t add(const void* data, size_t size, void* cookie,
+ bool copyData=false);
+ status_t add(Asset* asset, void* cookie,
+ bool copyData=false);
+
+ status_t getError() const;
+
+ void uninit();
+
+ struct resource_name
+ {
+ const char16_t* package;
+ size_t packageLen;
+ const char16_t* type;
+ size_t typeLen;
+ const char16_t* name;
+ size_t nameLen;
+ };
+
+ bool getResourceName(uint32_t resID, resource_name* outName) const;
+
+ /**
+ * Retrieve the value of a resource. If the resource is found, returns a
+ * value >= 0 indicating the table it is in (for use with
+ * getTableStringBlock() and getTableCookie()) and fills in 'outValue'. If
+ * not found, returns a negative error code.
+ *
+ * Note that this function does not do reference traversal. If you want
+ * to follow references to other resources to get the "real" value to
+ * use, you need to call resolveReference() after this function.
+ *
+ * @param resID The desired resoruce identifier.
+ * @param outValue Filled in with the resource data that was found.
+ *
+ * @return ssize_t Either a >= 0 table index or a negative error code.
+ */
+ ssize_t getResource(uint32_t resID, Res_value* outValue, bool mayBeBag=false,
+ uint32_t* outSpecFlags=NULL) const;
+
+ inline ssize_t getResource(const ResTable_ref& res, Res_value* outValue,
+ uint32_t* outSpecFlags=NULL) const {
+ return getResource(res.ident, outValue, outSpecFlags);
+ }
+
+ ssize_t resolveReference(Res_value* inOutValue,
+ ssize_t blockIndex,
+ uint32_t* outLastRef = NULL,
+ uint32_t* inoutTypeSpecFlags = NULL) const;
+
+ enum {
+ TMP_BUFFER_SIZE = 16
+ };
+ const char16_t* valueToString(const Res_value* value, size_t stringBlock,
+ char16_t tmpBuffer[TMP_BUFFER_SIZE],
+ size_t* outLen);
+
+ struct bag_entry {
+ ssize_t stringBlock;
+ ResTable_map map;
+ };
+
+ /**
+ * Retrieve the bag of a resource. If the resoruce is found, returns the
+ * number of bags it contains and 'outBag' points to an array of their
+ * values. If not found, a negative error code is returned.
+ *
+ * Note that this function -does- do reference traversal of the bag data.
+ *
+ * @param resID The desired resource identifier.
+ * @param outBag Filled inm with a pointer to the bag mappings.
+ *
+ * @return ssize_t Either a >= 0 bag count of negative error code.
+ */
+ ssize_t lockBag(uint32_t resID, const bag_entry** outBag) const;
+
+ void unlockBag(const bag_entry* bag) const;
+
+ void lock() const;
+
+ ssize_t getBagLocked(uint32_t resID, const bag_entry** outBag,
+ uint32_t* outTypeSpecFlags=NULL) const;
+
+ void unlock() const;
+
+ class Theme {
+ public:
+ Theme(const ResTable& table);
+ ~Theme();
+
+ inline const ResTable& getResTable() const { return mTable; }
+
+ status_t applyStyle(uint32_t resID, bool force=false);
+ status_t setTo(const Theme& other);
+
+ /**
+ * Retrieve a value in the theme. If the theme defines this
+ * value, returns a value >= 0 indicating the table it is in
+ * (for use with getTableStringBlock() and getTableCookie) and
+ * fills in 'outValue'. If not found, returns a negative error
+ * code.
+ *
+ * Note that this function does not do reference traversal. If you want
+ * to follow references to other resources to get the "real" value to
+ * use, you need to call resolveReference() after this function.
+ *
+ * @param resID A resource identifier naming the desired theme
+ * attribute.
+ * @param outValue Filled in with the theme value that was
+ * found.
+ *
+ * @return ssize_t Either a >= 0 table index or a negative error code.
+ */
+ ssize_t getAttribute(uint32_t resID, Res_value* outValue,
+ uint32_t* outTypeSpecFlags = NULL) const;
+
+ /**
+ * This is like ResTable::resolveReference(), but also takes
+ * care of resolving attribute references to the theme.
+ */
+ ssize_t resolveAttributeReference(Res_value* inOutValue,
+ ssize_t blockIndex, uint32_t* outLastRef = NULL,
+ uint32_t* inoutTypeSpecFlags = NULL) const;
+
+ void dumpToLog() const;
+
+ private:
+ Theme(const Theme&);
+ Theme& operator=(const Theme&);
+
+ struct theme_entry {
+ ssize_t stringBlock;
+ uint32_t typeSpecFlags;
+ Res_value value;
+ };
+ struct type_info {
+ size_t numEntries;
+ theme_entry* entries;
+ };
+ struct package_info {
+ size_t numTypes;
+ type_info types[];
+ };
+
+ void free_package(package_info* pi);
+ package_info* copy_package(package_info* pi);
+
+ const ResTable& mTable;
+ package_info* mPackages[Res_MAXPACKAGE];
+ };
+
+ void setParameters(const ResTable_config* params);
+ void getParameters(ResTable_config* params) const;
+
+ // Retrieve an identifier (which can be passed to getResource)
+ // for a given resource name. The 'name' can be fully qualified
+ // (<package>:<type>.<basename>) or the package or type components
+ // can be dropped if default values are supplied here.
+ //
+ // Returns 0 if no such resource was found, else a valid resource ID.
+ uint32_t identifierForName(const char16_t* name, size_t nameLen,
+ const char16_t* type = 0, size_t typeLen = 0,
+ const char16_t* defPackage = 0,
+ size_t defPackageLen = 0,
+ uint32_t* outTypeSpecFlags = NULL) const;
+
+ static bool expandResourceRef(const uint16_t* refStr, size_t refLen,
+ String16* outPackage,
+ String16* outType,
+ String16* outName,
+ const String16* defType = NULL,
+ const String16* defPackage = NULL,
+ const char** outErrorMsg = NULL);
+
+ static bool stringToInt(const char16_t* s, size_t len, Res_value* outValue);
+ static bool stringToFloat(const char16_t* s, size_t len, Res_value* outValue);
+
+ // Used with stringToValue.
+ class Accessor
+ {
+ public:
+ inline virtual ~Accessor() { }
+
+ virtual uint32_t getCustomResource(const String16& package,
+ const String16& type,
+ const String16& name) const = 0;
+ virtual uint32_t getCustomResourceWithCreation(const String16& package,
+ const String16& type,
+ const String16& name,
+ const bool createIfNeeded = false) = 0;
+ virtual uint32_t getRemappedPackage(uint32_t origPackage) const = 0;
+ virtual bool getAttributeType(uint32_t attrID, uint32_t* outType) = 0;
+ virtual bool getAttributeMin(uint32_t attrID, uint32_t* outMin) = 0;
+ virtual bool getAttributeMax(uint32_t attrID, uint32_t* outMax) = 0;
+ virtual bool getAttributeEnum(uint32_t attrID,
+ const char16_t* name, size_t nameLen,
+ Res_value* outValue) = 0;
+ virtual bool getAttributeFlags(uint32_t attrID,
+ const char16_t* name, size_t nameLen,
+ Res_value* outValue) = 0;
+ virtual uint32_t getAttributeL10N(uint32_t attrID) = 0;
+ virtual bool getLocalizationSetting() = 0;
+ virtual void reportError(void* accessorCookie, const char* fmt, ...) = 0;
+ };
+
+ // Convert a string to a resource value. Handles standard "@res",
+ // "#color", "123", and "0x1bd" types; performs escaping of strings.
+ // The resulting value is placed in 'outValue'; if it is a string type,
+ // 'outString' receives the string. If 'attrID' is supplied, the value is
+ // type checked against this attribute and it is used to perform enum
+ // evaluation. If 'acccessor' is supplied, it will be used to attempt to
+ // resolve resources that do not exist in this ResTable. If 'attrType' is
+ // supplied, the value will be type checked for this format if 'attrID'
+ // is not supplied or found.
+ bool stringToValue(Res_value* outValue, String16* outString,
+ const char16_t* s, size_t len,
+ bool preserveSpaces, bool coerceType,
+ uint32_t attrID = 0,
+ const String16* defType = NULL,
+ const String16* defPackage = NULL,
+ Accessor* accessor = NULL,
+ void* accessorCookie = NULL,
+ uint32_t attrType = ResTable_map::TYPE_ANY,
+ bool enforcePrivate = true) const;
+
+ // Perform processing of escapes and quotes in a string.
+ static bool collectString(String16* outString,
+ const char16_t* s, size_t len,
+ bool preserveSpaces,
+ const char** outErrorMsg = NULL,
+ bool append = false);
+
+ size_t getBasePackageCount() const;
+ const char16_t* getBasePackageName(size_t idx) const;
+ uint32_t getBasePackageId(size_t idx) const;
+
+ size_t getTableCount() const;
+ const ResStringPool* getTableStringBlock(size_t index) const;
+ void* getTableCookie(size_t index) const;
+
+ // Return the configurations (ResTable_config) that we know about
+ void getConfigurations(Vector<ResTable_config>* configs) const;
+
+ void getLocales(Vector<String8>* locales) const;
+
+#ifndef HAVE_ANDROID_OS
+ void print() const;
+#endif
+
+private:
+ struct Header;
+ struct Type;
+ struct Package;
+ struct PackageGroup;
+ struct bag_set;
+
+ status_t add(const void* data, size_t size, void* cookie,
+ Asset* asset, bool copyData);
+
+ ssize_t getResourcePackageIndex(uint32_t resID) const;
+ ssize_t getEntry(
+ const Package* package, int typeIndex, int entryIndex,
+ const ResTable_config* config,
+ const ResTable_type** outType, const ResTable_entry** outEntry,
+ const Type** outTypeClass) const;
+ status_t parsePackage(
+ const ResTable_package* const pkg, const Header* const header);
+
+ mutable Mutex mLock;
+
+ status_t mError;
+
+ ResTable_config mParams;
+
+ // Array of all resource tables.
+ Vector<Header*> mHeaders;
+
+ // Array of packages in all resource tables.
+ Vector<PackageGroup*> mPackageGroups;
+
+ // Mapping from resource package IDs to indices into the internal
+ // package array.
+ uint8_t mPackageMap[256];
+};
+
+} // namespace android
+
+#endif // _LIBS_UTILS_RESOURCE_TYPES_H
diff --git a/include/utils/SharedBuffer.h b/include/utils/SharedBuffer.h
new file mode 100644
index 0000000..24508b0
--- /dev/null
+++ b/include/utils/SharedBuffer.h
@@ -0,0 +1,146 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SHARED_BUFFER_H
+#define ANDROID_SHARED_BUFFER_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+class SharedBuffer
+{
+public:
+
+ /* flags to use with release() */
+ enum {
+ eKeepStorage = 0x00000001
+ };
+
+ /*! allocate a buffer of size 'size' and acquire() it.
+ * call release() to free it.
+ */
+ static SharedBuffer* alloc(size_t size);
+
+ /*! free the memory associated with the SharedBuffer.
+ * Fails if there are any users associated with this SharedBuffer.
+ * In other words, the buffer must have been release by all its
+ * users.
+ */
+ static ssize_t dealloc(const SharedBuffer* released);
+
+ //! get the SharedBuffer from the data pointer
+ static inline const SharedBuffer* sharedBuffer(const void* data);
+
+ //! access the data for read
+ inline const void* data() const;
+
+ //! access the data for read/write
+ inline void* data();
+
+ //! get size of the buffer
+ inline size_t size() const;
+
+ //! get back a SharedBuffer object from its data
+ static inline SharedBuffer* bufferFromData(void* data);
+
+ //! get back a SharedBuffer object from its data
+ static inline const SharedBuffer* bufferFromData(const void* data);
+
+ //! get the size of a SharedBuffer object from its data
+ static inline size_t sizeFromData(const void* data);
+
+ //! edit the buffer (get a writtable, or non-const, version of it)
+ SharedBuffer* edit() const;
+
+ //! edit the buffer, resizing if needed
+ SharedBuffer* editResize(size_t size) const;
+
+ //! like edit() but fails if a copy is required
+ SharedBuffer* attemptEdit() const;
+
+ //! resize and edit the buffer, loose it's content.
+ SharedBuffer* reset(size_t size) const;
+
+ //! acquire/release a reference on this buffer
+ void acquire() const;
+
+ /*! release a reference on this buffer, with the option of not
+ * freeing the memory associated with it if it was the last reference
+ * returns the previous reference count
+ */
+ int32_t release(uint32_t flags = 0) const;
+
+ //! returns wether or not we're the only owner
+ inline bool onlyOwner() const;
+
+
+private:
+ inline SharedBuffer() { }
+ inline ~SharedBuffer() { }
+ inline SharedBuffer(const SharedBuffer&);
+
+ // 16 bytes. must be sized to preserve correct alingment.
+ mutable int32_t mRefs;
+ size_t mSize;
+ uint32_t mReserved[2];
+};
+
+// ---------------------------------------------------------------------------
+
+const SharedBuffer* SharedBuffer::sharedBuffer(const void* data) {
+ return data ? reinterpret_cast<const SharedBuffer *>(data)-1 : 0;
+}
+
+const void* SharedBuffer::data() const {
+ return this + 1;
+}
+
+void* SharedBuffer::data() {
+ return this + 1;
+}
+
+size_t SharedBuffer::size() const {
+ return mSize;
+}
+
+SharedBuffer* SharedBuffer::bufferFromData(void* data)
+{
+ return ((SharedBuffer*)data)-1;
+}
+
+const SharedBuffer* SharedBuffer::bufferFromData(const void* data)
+{
+ return ((const SharedBuffer*)data)-1;
+}
+
+size_t SharedBuffer::sizeFromData(const void* data)
+{
+ return (((const SharedBuffer*)data)-1)->mSize;
+}
+
+bool SharedBuffer::onlyOwner() const {
+ return (mRefs == 1);
+}
+
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_VECTOR_H
diff --git a/include/utils/Socket.h b/include/utils/Socket.h
new file mode 100644
index 0000000..8b7f406
--- /dev/null
+++ b/include/utils/Socket.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Socket class. Modeled after Java classes.
+//
+#ifndef _RUNTIME_SOCKET_H
+#define _RUNTIME_SOCKET_H
+
+#include <utils/inet_address.h>
+#include <sys/types.h>
+
+namespace android {
+
+/*
+ * Basic socket class, needed to abstract away the differences between
+ * BSD sockets and WinSock. This establishes a streaming network
+ * connection (TCP/IP) to somebody.
+ */
+class Socket {
+public:
+ Socket(void);
+ ~Socket(void);
+
+ // Create a connection to somewhere.
+ // Return 0 on success.
+ int connect(const char* host, int port);
+ int connect(const InetAddress* addr, int port);
+
+
+ // Close the socket. Don't try to use this object again after
+ // calling this. Returns false on failure.
+ bool close(void);
+
+ // If we created the socket without an address, we can use these
+ // to finish the connection. Returns 0 on success.
+ int bind(const SocketAddress& bindPoint);
+ int connect(const SocketAddress& endPoint);
+
+ // Here we deviate from the traditional object-oriented fanciness
+ // and just provide read/write operators instead of getters for
+ // objects that abstract a stream.
+ //
+ // Standard read/write semantics.
+ int read(void* buf, ssize_t len) const;
+ int write(const void* buf, ssize_t len) const;
+
+ // This must be called once, at program startup.
+ static bool bootInit(void);
+ static void finalShutdown(void);
+
+private:
+ // Internal function that establishes a connection.
+ int doConnect(const InetSocketAddress& addr);
+
+ unsigned long mSock; // holds SOCKET or int
+
+ static bool mBootInitialized;
+};
+
+
+// debug -- unit tests
+void TestSockets(void);
+
+}; // namespace android
+
+#endif // _RUNTIME_SOCKET_H
diff --git a/include/utils/SortedVector.h b/include/utils/SortedVector.h
new file mode 100644
index 0000000..c8a6153
--- /dev/null
+++ b/include/utils/SortedVector.h
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_SORTED_VECTOR_H
+#define ANDROID_SORTED_VECTOR_H
+
+#include <assert.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Vector.h>
+#include <utils/VectorImpl.h>
+#include <utils/TypeHelpers.h>
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+template <class TYPE>
+class SortedVector : private SortedVectorImpl
+{
+public:
+ typedef TYPE value_type;
+
+ /*!
+ * Constructors and destructors
+ */
+
+ SortedVector();
+ SortedVector(const SortedVector<TYPE>& rhs);
+ virtual ~SortedVector();
+
+ /*! copy operator */
+ const SortedVector<TYPE>& operator = (const SortedVector<TYPE>& rhs) const;
+ SortedVector<TYPE>& operator = (const SortedVector<TYPE>& rhs);
+
+ /*
+ * empty the vector
+ */
+
+ inline void clear() { VectorImpl::clear(); }
+
+ /*!
+ * vector stats
+ */
+
+ //! returns number of items in the vector
+ inline size_t size() const { return VectorImpl::size(); }
+ //! returns wether or not the vector is empty
+ inline bool isEmpty() const { return VectorImpl::isEmpty(); }
+ //! returns how many items can be stored without reallocating the backing store
+ inline size_t capacity() const { return VectorImpl::capacity(); }
+ //! setst the capacity. capacity can never be reduced less than size()
+ inline ssize_t setCapacity(size_t size) { return VectorImpl::setCapacity(size); }
+
+ /*!
+ * C-style array access
+ */
+
+ //! read-only C-style access
+ inline const TYPE* array() const;
+
+ //! read-write C-style access. BE VERY CAREFUL when modifying the array
+ //! you ust keep it sorted! You usually don't use this function.
+ TYPE* editArray();
+
+ //! finds the index of an item
+ ssize_t indexOf(const TYPE& item) const;
+
+ //! finds where this item should be inserted
+ size_t orderOf(const TYPE& item) const;
+
+
+ /*!
+ * accessors
+ */
+
+ //! read-only access to an item at a given index
+ inline const TYPE& operator [] (size_t index) const;
+ //! alternate name for operator []
+ inline const TYPE& itemAt(size_t index) const;
+ //! stack-usage of the vector. returns the top of the stack (last element)
+ const TYPE& top() const;
+ //! same as operator [], but allows to access the vector backward (from the end) with a negative index
+ const TYPE& mirrorItemAt(ssize_t index) const;
+
+ /*!
+ * modifing the array
+ */
+
+ //! add an item in the right place (and replace the one that is there)
+ ssize_t add(const TYPE& item);
+
+ //! editItemAt() MUST NOT change the order of this item
+ TYPE& editItemAt(size_t index) {
+ return *( static_cast<TYPE *>(VectorImpl::editItemLocation(index)) );
+ }
+
+ //! merges a vector into this one
+ ssize_t merge(const Vector<TYPE>& vector);
+ ssize_t merge(const SortedVector<TYPE>& vector);
+
+ //! removes an item
+ ssize_t remove(const TYPE&);
+
+ //! remove several items
+ inline ssize_t removeItemsAt(size_t index, size_t count = 1);
+ //! remove one item
+ inline ssize_t removeAt(size_t index) { return removeItemsAt(index); }
+
+protected:
+ virtual void do_construct(void* storage, size_t num) const;
+ virtual void do_destroy(void* storage, size_t num) const;
+ virtual void do_copy(void* dest, const void* from, size_t num) const;
+ virtual void do_splat(void* dest, const void* item, size_t num) const;
+ virtual void do_move_forward(void* dest, const void* from, size_t num) const;
+ virtual void do_move_backward(void* dest, const void* from, size_t num) const;
+ virtual int do_compare(const void* lhs, const void* rhs) const;
+};
+
+
+// ---------------------------------------------------------------------------
+// No user serviceable parts from here...
+// ---------------------------------------------------------------------------
+
+template<class TYPE> inline
+SortedVector<TYPE>::SortedVector()
+ : SortedVectorImpl(sizeof(TYPE),
+ ((traits<TYPE>::has_trivial_ctor ? HAS_TRIVIAL_CTOR : 0)
+ |(traits<TYPE>::has_trivial_dtor ? HAS_TRIVIAL_DTOR : 0)
+ |(traits<TYPE>::has_trivial_copy ? HAS_TRIVIAL_COPY : 0)
+ |(traits<TYPE>::has_trivial_assign ? HAS_TRIVIAL_ASSIGN : 0))
+ )
+{
+}
+
+template<class TYPE> inline
+SortedVector<TYPE>::SortedVector(const SortedVector<TYPE>& rhs)
+ : SortedVectorImpl(rhs) {
+}
+
+template<class TYPE> inline
+SortedVector<TYPE>::~SortedVector() {
+ finish_vector();
+}
+
+template<class TYPE> inline
+SortedVector<TYPE>& SortedVector<TYPE>::operator = (const SortedVector<TYPE>& rhs) {
+ SortedVectorImpl::operator = (rhs);
+ return *this;
+}
+
+template<class TYPE> inline
+const SortedVector<TYPE>& SortedVector<TYPE>::operator = (const SortedVector<TYPE>& rhs) const {
+ SortedVectorImpl::operator = (rhs);
+ return *this;
+}
+
+template<class TYPE> inline
+const TYPE* SortedVector<TYPE>::array() const {
+ return static_cast<const TYPE *>(arrayImpl());
+}
+
+template<class TYPE> inline
+TYPE* SortedVector<TYPE>::editArray() {
+ return static_cast<TYPE *>(editArrayImpl());
+}
+
+
+template<class TYPE> inline
+const TYPE& SortedVector<TYPE>::operator[](size_t index) const {
+ assert( index<size() );
+ return *(array() + index);
+}
+
+template<class TYPE> inline
+const TYPE& SortedVector<TYPE>::itemAt(size_t index) const {
+ return operator[](index);
+}
+
+template<class TYPE> inline
+const TYPE& SortedVector<TYPE>::mirrorItemAt(ssize_t index) const {
+ assert( (index>0 ? index : -index)<size() );
+ return *(array() + ((index<0) ? (size()-index) : index));
+}
+
+template<class TYPE> inline
+const TYPE& SortedVector<TYPE>::top() const {
+ return *(array() + size() - 1);
+}
+
+template<class TYPE> inline
+ssize_t SortedVector<TYPE>::add(const TYPE& item) {
+ return SortedVectorImpl::add(&item);
+}
+
+template<class TYPE> inline
+ssize_t SortedVector<TYPE>::indexOf(const TYPE& item) const {
+ return SortedVectorImpl::indexOf(&item);
+}
+
+template<class TYPE> inline
+size_t SortedVector<TYPE>::orderOf(const TYPE& item) const {
+ return SortedVectorImpl::orderOf(&item);
+}
+
+template<class TYPE> inline
+ssize_t SortedVector<TYPE>::merge(const Vector<TYPE>& vector) {
+ return SortedVectorImpl::merge(reinterpret_cast<const VectorImpl&>(vector));
+}
+
+template<class TYPE> inline
+ssize_t SortedVector<TYPE>::merge(const SortedVector<TYPE>& vector) {
+ return SortedVectorImpl::merge(reinterpret_cast<const SortedVectorImpl&>(vector));
+}
+
+template<class TYPE> inline
+ssize_t SortedVector<TYPE>::remove(const TYPE& item) {
+ return SortedVectorImpl::remove(&item);
+}
+
+template<class TYPE> inline
+ssize_t SortedVector<TYPE>::removeItemsAt(size_t index, size_t count) {
+ return VectorImpl::removeItemsAt(index, count);
+}
+
+// ---------------------------------------------------------------------------
+
+template<class TYPE>
+void SortedVector<TYPE>::do_construct(void* storage, size_t num) const {
+ construct_type( reinterpret_cast<TYPE*>(storage), num );
+}
+
+template<class TYPE>
+void SortedVector<TYPE>::do_destroy(void* storage, size_t num) const {
+ destroy_type( reinterpret_cast<TYPE*>(storage), num );
+}
+
+template<class TYPE>
+void SortedVector<TYPE>::do_copy(void* dest, const void* from, size_t num) const {
+ copy_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num );
+}
+
+template<class TYPE>
+void SortedVector<TYPE>::do_splat(void* dest, const void* item, size_t num) const {
+ splat_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(item), num );
+}
+
+template<class TYPE>
+void SortedVector<TYPE>::do_move_forward(void* dest, const void* from, size_t num) const {
+ move_forward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num );
+}
+
+template<class TYPE>
+void SortedVector<TYPE>::do_move_backward(void* dest, const void* from, size_t num) const {
+ move_backward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num );
+}
+
+template<class TYPE>
+int SortedVector<TYPE>::do_compare(const void* lhs, const void* rhs) const {
+ return compare_type( *reinterpret_cast<const TYPE*>(lhs), *reinterpret_cast<const TYPE*>(rhs) );
+}
+
+}; // namespace android
+
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_SORTED_VECTOR_H
diff --git a/include/utils/StopWatch.h b/include/utils/StopWatch.h
new file mode 100644
index 0000000..cc0bebc
--- /dev/null
+++ b/include/utils/StopWatch.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_STOPWATCH_H
+#define ANDROID_STOPWATCH_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Timers.h>
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+class StopWatch
+{
+public:
+ StopWatch( const char *name,
+ int clock = SYSTEM_TIME_MONOTONIC,
+ uint32_t flags = 0);
+ ~StopWatch();
+
+ const char* name() const;
+ nsecs_t lap();
+ nsecs_t elapsedTime() const;
+
+private:
+ const char* mName;
+ int mClock;
+ uint32_t mFlags;
+
+ struct lap_t {
+ nsecs_t soFar;
+ nsecs_t thisLap;
+ };
+
+ nsecs_t mStartTime;
+ lap_t mLaps[8];
+ int mNumLaps;
+};
+
+
+}; // namespace android
+
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_STOPWATCH_H
diff --git a/include/utils/String16.h b/include/utils/String16.h
new file mode 100644
index 0000000..a2d22ee
--- /dev/null
+++ b/include/utils/String16.h
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_STRING16_H
+#define ANDROID_STRING16_H
+
+#include <utils/Errors.h>
+#include <utils/SharedBuffer.h>
+
+#include <stdint.h>
+#include <sys/types.h>
+
+// ---------------------------------------------------------------------------
+
+extern "C" {
+
+typedef uint16_t char16_t;
+
+// Standard string functions on char16 strings.
+int strcmp16(const char16_t *, const char16_t *);
+int strncmp16(const char16_t *s1, const char16_t *s2, size_t n);
+size_t strlen16(const char16_t *);
+size_t strnlen16(const char16_t *, size_t);
+char16_t *strcpy16(char16_t *, const char16_t *);
+char16_t *strncpy16(char16_t *, const char16_t *, size_t);
+
+// Version of comparison that supports embedded nulls.
+// This is different than strncmp() because we don't stop
+// at a nul character and consider the strings to be different
+// if the lengths are different (thus we need to supply the
+// lengths of both strings). This can also be used when
+// your string is not nul-terminated as it will have the
+// equivalent result as strcmp16 (unlike strncmp16).
+int strzcmp16(const char16_t *s1, size_t n1, const char16_t *s2, size_t n2);
+
+// Version of strzcmp16 for comparing strings in different endianness.
+int strzcmp16_h_n(const char16_t *s1H, size_t n1, const char16_t *s2N, size_t n2);
+
+}
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+class String8;
+class TextOutput;
+
+//! This is a string holding UTF-16 characters.
+class String16
+{
+public:
+ String16();
+ String16(const String16& o);
+ String16(const String16& o,
+ size_t len,
+ size_t begin=0);
+ explicit String16(const char16_t* o);
+ explicit String16(const char16_t* o, size_t len);
+ explicit String16(const String8& o);
+ explicit String16(const char* o);
+ explicit String16(const char* o, size_t len);
+
+ ~String16();
+
+ inline const char16_t* string() const;
+ inline size_t size() const;
+
+ inline const SharedBuffer* sharedBuffer() const;
+
+ void setTo(const String16& other);
+ status_t setTo(const char16_t* other);
+ status_t setTo(const char16_t* other, size_t len);
+ status_t setTo(const String16& other,
+ size_t len,
+ size_t begin=0);
+
+ status_t append(const String16& other);
+ status_t append(const char16_t* other, size_t len);
+
+ inline String16& operator=(const String16& other);
+
+ inline String16& operator+=(const String16& other);
+ inline String16 operator+(const String16& other) const;
+
+ status_t insert(size_t pos, const char16_t* chrs);
+ status_t insert(size_t pos,
+ const char16_t* chrs, size_t len);
+
+ ssize_t findFirst(char16_t c) const;
+ ssize_t findLast(char16_t c) const;
+
+ bool startsWith(const String16& prefix) const;
+ bool startsWith(const char16_t* prefix) const;
+
+ status_t makeLower();
+
+ status_t replaceAll(char16_t replaceThis,
+ char16_t withThis);
+
+ status_t remove(size_t len, size_t begin=0);
+
+ inline int compare(const String16& other) const;
+
+ inline bool operator<(const String16& other) const;
+ inline bool operator<=(const String16& other) const;
+ inline bool operator==(const String16& other) const;
+ inline bool operator!=(const String16& other) const;
+ inline bool operator>=(const String16& other) const;
+ inline bool operator>(const String16& other) const;
+
+ inline bool operator<(const char16_t* other) const;
+ inline bool operator<=(const char16_t* other) const;
+ inline bool operator==(const char16_t* other) const;
+ inline bool operator!=(const char16_t* other) const;
+ inline bool operator>=(const char16_t* other) const;
+ inline bool operator>(const char16_t* other) const;
+
+ inline operator const char16_t*() const;
+
+private:
+ const char16_t* mString;
+};
+
+TextOutput& operator<<(TextOutput& to, const String16& val);
+
+// ---------------------------------------------------------------------------
+// No user servicable parts below.
+
+inline int compare_type(const String16& lhs, const String16& rhs)
+{
+ return lhs.compare(rhs);
+}
+
+inline int strictly_order_type(const String16& lhs, const String16& rhs)
+{
+ return compare_type(lhs, rhs) < 0;
+}
+
+inline const char16_t* String16::string() const
+{
+ return mString;
+}
+
+inline size_t String16::size() const
+{
+ return SharedBuffer::sizeFromData(mString)/sizeof(char16_t)-1;
+}
+
+inline const SharedBuffer* String16::sharedBuffer() const
+{
+ return SharedBuffer::bufferFromData(mString);
+}
+
+inline String16& String16::operator=(const String16& other)
+{
+ setTo(other);
+ return *this;
+}
+
+inline String16& String16::operator+=(const String16& other)
+{
+ append(other);
+ return *this;
+}
+
+inline String16 String16::operator+(const String16& other) const
+{
+ String16 tmp;
+ tmp += other;
+ return tmp;
+}
+
+inline int String16::compare(const String16& other) const
+{
+ return strzcmp16(mString, size(), other.mString, other.size());
+}
+
+inline bool String16::operator<(const String16& other) const
+{
+ return strzcmp16(mString, size(), other.mString, other.size()) < 0;
+}
+
+inline bool String16::operator<=(const String16& other) const
+{
+ return strzcmp16(mString, size(), other.mString, other.size()) <= 0;
+}
+
+inline bool String16::operator==(const String16& other) const
+{
+ return strzcmp16(mString, size(), other.mString, other.size()) == 0;
+}
+
+inline bool String16::operator!=(const String16& other) const
+{
+ return strzcmp16(mString, size(), other.mString, other.size()) != 0;
+}
+
+inline bool String16::operator>=(const String16& other) const
+{
+ return strzcmp16(mString, size(), other.mString, other.size()) >= 0;
+}
+
+inline bool String16::operator>(const String16& other) const
+{
+ return strzcmp16(mString, size(), other.mString, other.size()) > 0;
+}
+
+inline bool String16::operator<(const char16_t* other) const
+{
+ return strcmp16(mString, other) < 0;
+}
+
+inline bool String16::operator<=(const char16_t* other) const
+{
+ return strcmp16(mString, other) <= 0;
+}
+
+inline bool String16::operator==(const char16_t* other) const
+{
+ return strcmp16(mString, other) == 0;
+}
+
+inline bool String16::operator!=(const char16_t* other) const
+{
+ return strcmp16(mString, other) != 0;
+}
+
+inline bool String16::operator>=(const char16_t* other) const
+{
+ return strcmp16(mString, other) >= 0;
+}
+
+inline bool String16::operator>(const char16_t* other) const
+{
+ return strcmp16(mString, other) > 0;
+}
+
+inline String16::operator const char16_t*() const
+{
+ return mString;
+}
+
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_STRING16_H
diff --git a/include/utils/String8.h b/include/utils/String8.h
new file mode 100644
index 0000000..c49faf6
--- /dev/null
+++ b/include/utils/String8.h
@@ -0,0 +1,353 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_STRING8_H
+#define ANDROID_STRING8_H
+
+#include <utils/Errors.h>
+
+// Need this for the char16_t type; String8.h should not
+// be depedent on the String16 class.
+#include <utils/String16.h>
+
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+class TextOutput;
+
+//! This is a string holding UTF-8 characters.
+class String8
+{
+public:
+ String8();
+ String8(const String8& o);
+ explicit String8(const char* o);
+ explicit String8(const char* o, size_t numChars);
+
+ explicit String8(const String16& o);
+ explicit String8(const char16_t* o);
+ explicit String8(const char16_t* o, size_t numChars);
+
+ ~String8();
+
+ inline const char* string() const;
+ inline size_t size() const;
+ inline size_t length() const;
+ inline size_t bytes() const;
+
+ inline const SharedBuffer* sharedBuffer() const;
+
+ void setTo(const String8& other);
+ status_t setTo(const char* other);
+ status_t setTo(const char* other, size_t numChars);
+ status_t setTo(const char16_t* other, size_t numChars);
+
+ status_t append(const String8& other);
+ status_t append(const char* other);
+ status_t append(const char* other, size_t numChars);
+
+ inline String8& operator=(const String8& other);
+ inline String8& operator=(const char* other);
+
+ inline String8& operator+=(const String8& other);
+ inline String8 operator+(const String8& other) const;
+
+ inline String8& operator+=(const char* other);
+ inline String8 operator+(const char* other) const;
+
+ inline int compare(const String8& other) const;
+
+ inline bool operator<(const String8& other) const;
+ inline bool operator<=(const String8& other) const;
+ inline bool operator==(const String8& other) const;
+ inline bool operator!=(const String8& other) const;
+ inline bool operator>=(const String8& other) const;
+ inline bool operator>(const String8& other) const;
+
+ inline bool operator<(const char* other) const;
+ inline bool operator<=(const char* other) const;
+ inline bool operator==(const char* other) const;
+ inline bool operator!=(const char* other) const;
+ inline bool operator>=(const char* other) const;
+ inline bool operator>(const char* other) const;
+
+ inline operator const char*() const;
+
+ char* lockBuffer(size_t size);
+ void unlockBuffer();
+ status_t unlockBuffer(size_t size);
+
+ // return the index of the first byte of other in this at or after
+ // start, or -1 if not found
+ ssize_t find(const char* other, size_t start = 0) const;
+
+ void toLower();
+ void toLower(size_t start, size_t numChars);
+ void toUpper();
+ void toUpper(size_t start, size_t numChars);
+
+ /*
+ * These methods operate on the string as if it were a path name.
+ */
+
+ /*
+ * Set the filename field to a specific value.
+ *
+ * Normalizes the filename, removing a trailing '/' if present.
+ */
+ void setPathName(const char* name);
+ void setPathName(const char* name, size_t numChars);
+
+ /*
+ * Get just the filename component.
+ *
+ * "/tmp/foo/bar.c" --> "bar.c"
+ */
+ String8 getPathLeaf(void) const;
+
+ /*
+ * Remove the last (file name) component, leaving just the directory
+ * name.
+ *
+ * "/tmp/foo/bar.c" --> "/tmp/foo"
+ * "/tmp" --> "" // ????? shouldn't this be "/" ???? XXX
+ * "bar.c" --> ""
+ */
+ String8 getPathDir(void) const;
+
+ /*
+ * Retrieve the front (root dir) component. Optionally also return the
+ * remaining components.
+ *
+ * "/tmp/foo/bar.c" --> "tmp" (remain = "foo/bar.c")
+ * "/tmp" --> "tmp" (remain = "")
+ * "bar.c" --> "bar.c" (remain = "")
+ */
+ String8 walkPath(String8* outRemains = NULL) const;
+
+ /*
+ * Return the filename extension. This is the last '.' and up to
+ * four characters that follow it. The '.' is included in case we
+ * decide to expand our definition of what constitutes an extension.
+ *
+ * "/tmp/foo/bar.c" --> ".c"
+ * "/tmp" --> ""
+ * "/tmp/foo.bar/baz" --> ""
+ * "foo.jpeg" --> ".jpeg"
+ * "foo." --> ""
+ */
+ String8 getPathExtension(void) const;
+
+ /*
+ * Return the path without the extension. Rules for what constitutes
+ * an extension are described in the comment for getPathExtension().
+ *
+ * "/tmp/foo/bar.c" --> "/tmp/foo/bar"
+ */
+ String8 getBasePath(void) const;
+
+ /*
+ * Add a component to the pathname. We guarantee that there is
+ * exactly one path separator between the old path and the new.
+ * If there is no existing name, we just copy the new name in.
+ *
+ * If leaf is a fully qualified path (i.e. starts with '/', it
+ * replaces whatever was there before.
+ */
+ String8& appendPath(const char* leaf);
+ String8& appendPath(const String8& leaf) { return appendPath(leaf.string()); }
+
+ /*
+ * Like appendPath(), but does not affect this string. Returns a new one instead.
+ */
+ String8 appendPathCopy(const char* leaf) const
+ { String8 p(*this); p.appendPath(leaf); return p; }
+ String8 appendPathCopy(const String8& leaf) const { return appendPathCopy(leaf.string()); }
+
+ /*
+ * Converts all separators in this string to /, the default path separator.
+ *
+ * If the default OS separator is backslash, this converts all
+ * backslashes to slashes, in-place. Otherwise it does nothing.
+ * Returns self.
+ */
+ String8& convertToResPath();
+
+private:
+ status_t real_append(const char* other, size_t numChars);
+ char* find_extension(void) const;
+
+ const char* mString;
+};
+
+TextOutput& operator<<(TextOutput& to, const String16& val);
+
+// ---------------------------------------------------------------------------
+// No user servicable parts below.
+
+inline int compare_type(const String8& lhs, const String8& rhs)
+{
+ return lhs.compare(rhs);
+}
+
+inline int strictly_order_type(const String8& lhs, const String8& rhs)
+{
+ return compare_type(lhs, rhs) < 0;
+}
+
+inline const char* String8::string() const
+{
+ return mString;
+}
+
+inline size_t String8::length() const
+{
+ return SharedBuffer::sizeFromData(mString)-1;
+}
+
+inline size_t String8::size() const
+{
+ return length();
+}
+
+inline size_t String8::bytes() const
+{
+ return SharedBuffer::sizeFromData(mString)-1;
+}
+
+inline const SharedBuffer* String8::sharedBuffer() const
+{
+ return SharedBuffer::bufferFromData(mString);
+}
+
+inline String8& String8::operator=(const String8& other)
+{
+ setTo(other);
+ return *this;
+}
+
+inline String8& String8::operator=(const char* other)
+{
+ setTo(other);
+ return *this;
+}
+
+inline String8& String8::operator+=(const String8& other)
+{
+ append(other);
+ return *this;
+}
+
+inline String8 String8::operator+(const String8& other) const
+{
+ String8 tmp;
+ tmp += other;
+ return tmp;
+}
+
+inline String8& String8::operator+=(const char* other)
+{
+ append(other);
+ return *this;
+}
+
+inline String8 String8::operator+(const char* other) const
+{
+ String8 tmp;
+ tmp += other;
+ return tmp;
+}
+
+inline int String8::compare(const String8& other) const
+{
+ return strcmp(mString, other.mString);
+}
+
+inline bool String8::operator<(const String8& other) const
+{
+ return strcmp(mString, other.mString) < 0;
+}
+
+inline bool String8::operator<=(const String8& other) const
+{
+ return strcmp(mString, other.mString) <= 0;
+}
+
+inline bool String8::operator==(const String8& other) const
+{
+ return strcmp(mString, other.mString) == 0;
+}
+
+inline bool String8::operator!=(const String8& other) const
+{
+ return strcmp(mString, other.mString) != 0;
+}
+
+inline bool String8::operator>=(const String8& other) const
+{
+ return strcmp(mString, other.mString) >= 0;
+}
+
+inline bool String8::operator>(const String8& other) const
+{
+ return strcmp(mString, other.mString) > 0;
+}
+
+inline bool String8::operator<(const char* other) const
+{
+ return strcmp(mString, other) < 0;
+}
+
+inline bool String8::operator<=(const char* other) const
+{
+ return strcmp(mString, other) <= 0;
+}
+
+inline bool String8::operator==(const char* other) const
+{
+ return strcmp(mString, other) == 0;
+}
+
+inline bool String8::operator!=(const char* other) const
+{
+ return strcmp(mString, other) != 0;
+}
+
+inline bool String8::operator>=(const char* other) const
+{
+ return strcmp(mString, other) >= 0;
+}
+
+inline bool String8::operator>(const char* other) const
+{
+ return strcmp(mString, other) > 0;
+}
+
+inline String8::operator const char*() const
+{
+ return mString;
+}
+
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_STRING8_H
diff --git a/include/utils/SystemClock.h b/include/utils/SystemClock.h
new file mode 100644
index 0000000..7c319be
--- /dev/null
+++ b/include/utils/SystemClock.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_UTILS_SYSTEMCLOCK_H
+#define ANDROID_UTILS_SYSTEMCLOCK_H
+
+#include <stdint.h>
+#include <sys/types.h>
+
+namespace android {
+
+int setCurrentTimeMillis(int64_t millis);
+int64_t uptimeMillis();
+int64_t elapsedRealtime();
+
+}; // namespace android
+
+#endif // ANDROID_UTILS_SYSTEMCLOCK_H
+
diff --git a/include/utils/TextOutput.h b/include/utils/TextOutput.h
new file mode 100644
index 0000000..d8d86ba
--- /dev/null
+++ b/include/utils/TextOutput.h
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_TEXTOUTPUT_H
+#define ANDROID_TEXTOUTPUT_H
+
+#include <utils/Errors.h>
+
+#include <stdint.h>
+#include <string.h>
+
+// ---------------------------------------------------------------------------
+namespace android {
+
+class TextOutput
+{
+public:
+ TextOutput() { }
+ virtual ~TextOutput() { }
+
+ virtual status_t print(const char* txt, size_t len) = 0;
+ virtual void moveIndent(int delta) = 0;
+
+ class Bundle {
+ public:
+ inline Bundle(TextOutput& to) : mTO(to) { to.pushBundle(); }
+ inline ~Bundle() { mTO.popBundle(); }
+ private:
+ TextOutput& mTO;
+ };
+
+ virtual void pushBundle() = 0;
+ virtual void popBundle() = 0;
+};
+
+// ---------------------------------------------------------------------------
+
+// Text output stream for printing to the log (via utils/Log.h).
+extern TextOutput& alog;
+
+// Text output stream for printing to stdout.
+extern TextOutput& aout;
+
+// Text output stream for printing to stderr.
+extern TextOutput& aerr;
+
+typedef TextOutput& (*TextOutputManipFunc)(TextOutput&);
+
+TextOutput& endl(TextOutput& to);
+TextOutput& indent(TextOutput& to);
+TextOutput& dedent(TextOutput& to);
+
+TextOutput& operator<<(TextOutput& to, const char* str);
+TextOutput& operator<<(TextOutput& to, char); // writes raw character
+TextOutput& operator<<(TextOutput& to, bool);
+TextOutput& operator<<(TextOutput& to, int);
+TextOutput& operator<<(TextOutput& to, long);
+TextOutput& operator<<(TextOutput& to, unsigned int);
+TextOutput& operator<<(TextOutput& to, unsigned long);
+TextOutput& operator<<(TextOutput& to, long long);
+TextOutput& operator<<(TextOutput& to, unsigned long long);
+TextOutput& operator<<(TextOutput& to, float);
+TextOutput& operator<<(TextOutput& to, double);
+TextOutput& operator<<(TextOutput& to, TextOutputManipFunc func);
+TextOutput& operator<<(TextOutput& to, const void*);
+
+class TypeCode
+{
+public:
+ inline TypeCode(uint32_t code);
+ inline ~TypeCode();
+
+ inline uint32_t typeCode() const;
+
+private:
+ uint32_t mCode;
+};
+
+TextOutput& operator<<(TextOutput& to, const TypeCode& val);
+
+class HexDump
+{
+public:
+ HexDump(const void *buf, size_t size, size_t bytesPerLine=16);
+ inline ~HexDump();
+
+ inline HexDump& setBytesPerLine(size_t bytesPerLine);
+ inline HexDump& setSingleLineCutoff(int32_t bytes);
+ inline HexDump& setAlignment(size_t alignment);
+ inline HexDump& setCArrayStyle(bool enabled);
+
+ inline const void* buffer() const;
+ inline size_t size() const;
+ inline size_t bytesPerLine() const;
+ inline int32_t singleLineCutoff() const;
+ inline size_t alignment() const;
+ inline bool carrayStyle() const;
+
+private:
+ const void* mBuffer;
+ size_t mSize;
+ size_t mBytesPerLine;
+ int32_t mSingleLineCutoff;
+ size_t mAlignment;
+ bool mCArrayStyle;
+};
+
+TextOutput& operator<<(TextOutput& to, const HexDump& val);
+
+// ---------------------------------------------------------------------------
+// No user servicable parts below.
+
+inline TextOutput& endl(TextOutput& to)
+{
+ to.print("\n", 1);
+ return to;
+}
+
+inline TextOutput& indent(TextOutput& to)
+{
+ to.moveIndent(1);
+ return to;
+}
+
+inline TextOutput& dedent(TextOutput& to)
+{
+ to.moveIndent(-1);
+ return to;
+}
+
+inline TextOutput& operator<<(TextOutput& to, const char* str)
+{
+ to.print(str, strlen(str));
+ return to;
+}
+
+inline TextOutput& operator<<(TextOutput& to, char c)
+{
+ to.print(&c, 1);
+ return to;
+}
+
+inline TextOutput& operator<<(TextOutput& to, TextOutputManipFunc func)
+{
+ return (*func)(to);
+}
+
+inline TypeCode::TypeCode(uint32_t code) : mCode(code) { }
+inline TypeCode::~TypeCode() { }
+inline uint32_t TypeCode::typeCode() const { return mCode; }
+
+inline HexDump::~HexDump() { }
+
+inline HexDump& HexDump::setBytesPerLine(size_t bytesPerLine) {
+ mBytesPerLine = bytesPerLine; return *this;
+}
+inline HexDump& HexDump::setSingleLineCutoff(int32_t bytes) {
+ mSingleLineCutoff = bytes; return *this;
+}
+inline HexDump& HexDump::setAlignment(size_t alignment) {
+ mAlignment = alignment; return *this;
+}
+inline HexDump& HexDump::setCArrayStyle(bool enabled) {
+ mCArrayStyle = enabled; return *this;
+}
+
+inline const void* HexDump::buffer() const { return mBuffer; }
+inline size_t HexDump::size() const { return mSize; }
+inline size_t HexDump::bytesPerLine() const { return mBytesPerLine; }
+inline int32_t HexDump::singleLineCutoff() const { return mSingleLineCutoff; }
+inline size_t HexDump::alignment() const { return mAlignment; }
+inline bool HexDump::carrayStyle() const { return mCArrayStyle; }
+
+// ---------------------------------------------------------------------------
+}; // namespace android
+
+#endif // ANDROID_TEXTOUTPUT_H
diff --git a/include/utils/TimeUtils.h b/include/utils/TimeUtils.h
new file mode 100644
index 0000000..30e5330
--- /dev/null
+++ b/include/utils/TimeUtils.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_TIME_H
+#define ANDROID_TIME_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+#include <utils/String8.h>
+#include <utils/String16.h>
+
+namespace android {
+
+/*
+ * This class is the core implementation of the android.util.Time java
+ * class. It doesn't implement some of the methods that are implemented
+ * in Java. They could be done here, but it's not expected that this class
+ * will be used. If that assumption is incorrect, feel free to update this
+ * file. The reason to do it here is to not mix the implementation of this
+ * class and the jni glue code.
+ */
+class Time
+{
+public:
+ struct tm t;
+
+ // this object doesn't own this string
+ const char *timezone;
+
+ enum {
+ SEC = 1,
+ MIN = 2,
+ HOUR = 3,
+ MDAY = 4,
+ MON = 5,
+ YEAR = 6,
+ WDAY = 7,
+ YDAY = 8
+ };
+
+ static int compare(Time& a, Time& b);
+
+ Time();
+
+ void switchTimezone(const char *timezone);
+ String8 format(const char *format) const;
+ void format2445(short* buf, bool hasTime) const;
+ String8 toString() const;
+ void setToNow();
+ int64_t toMillis(bool ignoreDst);
+ void set(int64_t millis);
+
+ inline void set(int sec, int min, int hour, int mday, int mon, int year,
+ int isdst)
+ {
+ this->t.tm_sec = sec;
+ this->t.tm_min = min;
+ this->t.tm_hour = hour;
+ this->t.tm_mday = mday;
+ this->t.tm_mon = mon;
+ this->t.tm_year = year;
+ this->t.tm_isdst = isdst;
+#ifdef HAVE_TM_GMTOFF
+ this->t.tm_gmtoff = 0;
+#endif
+ this->t.tm_wday = 0;
+ this->t.tm_yday = 0;
+ }
+};
+
+}; // namespace android
+
+#endif // ANDROID_TIME_H
diff --git a/include/utils/TimerProbe.h b/include/utils/TimerProbe.h
new file mode 100644
index 0000000..f2e32b2
--- /dev/null
+++ b/include/utils/TimerProbe.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_TIMER_PROBE_H
+#define ANDROID_TIMER_PROBE_H
+
+#if 0 && defined(HAVE_POSIX_CLOCKS)
+#define ENABLE_TIMER_PROBE 1
+#else
+#define ENABLE_TIMER_PROBE 0
+#endif
+
+#if ENABLE_TIMER_PROBE
+
+#include <time.h>
+#include <sys/time.h>
+#include <utils/Vector.h>
+
+#define TIMER_PROBE(tag) \
+ static int _timer_slot_; \
+ android::TimerProbe probe(tag, &_timer_slot_)
+#define TIMER_PROBE_END() probe.end()
+#else
+#define TIMER_PROBE(tag)
+#define TIMER_PROBE_END()
+#endif
+
+#if ENABLE_TIMER_PROBE
+namespace android {
+
+class TimerProbe {
+public:
+ TimerProbe(const char tag[], int* slot);
+ void end();
+ ~TimerProbe();
+private:
+ struct Bucket {
+ int mStart, mReal, mProcess, mThread, mCount;
+ const char* mTag;
+ int* mSlotPtr;
+ int mIndent;
+ };
+ static Vector<Bucket> gBuckets;
+ static TimerProbe* gExecuteChain;
+ static int gIndent;
+ static timespec gRealBase;
+ TimerProbe* mNext;
+ static uint32_t ElapsedTime(const timespec& start, const timespec& end);
+ void print(const timespec& r, const timespec& p, const timespec& t) const;
+ timespec mRealStart, mPStart, mTStart;
+ const char* mTag;
+ int mIndent;
+ int mBucket;
+};
+
+}; // namespace android
+
+#endif
+#endif
diff --git a/include/utils/Timers.h b/include/utils/Timers.h
new file mode 100644
index 0000000..9610399
--- /dev/null
+++ b/include/utils/Timers.h
@@ -0,0 +1,137 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Timer functions.
+//
+#ifndef _LIBS_UTILS_TIMERS_H
+#define _LIBS_UTILS_TIMERS_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <sys/time.h>
+
+// ------------------------------------------------------------------
+// C API
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef int64_t nsecs_t; // nano-seconds
+
+static inline nsecs_t seconds_to_nanoseconds(nsecs_t secs)
+{
+ return secs*1000000000;
+}
+
+static inline nsecs_t milliseconds_to_nanoseconds(nsecs_t secs)
+{
+ return secs*1000000;
+}
+
+static inline nsecs_t microseconds_to_nanoseconds(nsecs_t secs)
+{
+ return secs*1000;
+}
+
+static inline nsecs_t nanoseconds_to_seconds(nsecs_t secs)
+{
+ return secs/1000000000;
+}
+
+static inline nsecs_t nanoseconds_to_milliseconds(nsecs_t secs)
+{
+ return secs/1000000;
+}
+
+static inline nsecs_t nanoseconds_to_microseconds(nsecs_t secs)
+{
+ return secs/1000;
+}
+
+static inline nsecs_t s2ns(nsecs_t v) {return seconds_to_nanoseconds(v);}
+static inline nsecs_t ms2ns(nsecs_t v) {return milliseconds_to_nanoseconds(v);}
+static inline nsecs_t us2ns(nsecs_t v) {return microseconds_to_nanoseconds(v);}
+static inline nsecs_t ns2s(nsecs_t v) {return nanoseconds_to_seconds(v);}
+static inline nsecs_t ns2ms(nsecs_t v) {return nanoseconds_to_milliseconds(v);}
+static inline nsecs_t ns2us(nsecs_t v) {return nanoseconds_to_microseconds(v);}
+
+static inline nsecs_t seconds(nsecs_t v) { return s2ns(v); }
+static inline nsecs_t milliseconds(nsecs_t v) { return ms2ns(v); }
+static inline nsecs_t microseconds(nsecs_t v) { return us2ns(v); }
+
+enum {
+ SYSTEM_TIME_REALTIME = 0, // system-wide realtime clock
+ SYSTEM_TIME_MONOTONIC = 1, // monotonic time since unspecified starting point
+ SYSTEM_TIME_PROCESS = 2, // high-resolution per-process clock
+ SYSTEM_TIME_THREAD = 3 // high-resolution per-thread clock
+};
+
+// return the system-time according to the specified clock
+#ifdef __cplusplus
+nsecs_t systemTime(int clock = SYSTEM_TIME_MONOTONIC);
+#else
+nsecs_t systemTime(int clock);
+#endif // def __cplusplus
+
+// return the system-time according to the specified clock
+int sleepForInterval(long interval, struct timeval* pNextTick);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+// ------------------------------------------------------------------
+// C++ API
+
+#ifdef __cplusplus
+
+namespace android {
+/*
+ * Time the duration of something.
+ *
+ * Includes some timeval manipulation functions.
+ */
+class DurationTimer {
+public:
+ DurationTimer(void) {}
+ ~DurationTimer(void) {}
+
+ // Start the timer.
+ void start(void);
+ // Stop the timer.
+ void stop(void);
+ // Get the duration in microseconds.
+ long long durationUsecs(void) const;
+
+ // Subtract two timevals. Returns the difference (ptv1-ptv2) in
+ // microseconds.
+ static long long subtractTimevals(const struct timeval* ptv1,
+ const struct timeval* ptv2);
+
+ // Add the specified amount of time to the timeval.
+ static void addToTimeval(struct timeval* ptv, long usec);
+
+private:
+ struct timeval mStartWhen;
+ struct timeval mStopWhen;
+};
+
+}; // android
+#endif // def __cplusplus
+
+#endif // _LIBS_UTILS_TIMERS_H
diff --git a/include/utils/TypeHelpers.h b/include/utils/TypeHelpers.h
new file mode 100644
index 0000000..c04c37f
--- /dev/null
+++ b/include/utils/TypeHelpers.h
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_TYPE_HELPERS_H
+#define ANDROID_TYPE_HELPERS_H
+
+#include <new>
+#include <stdint.h>
+#include <string.h>
+#include <sys/types.h>
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+/*
+ * Types traits
+ */
+
+template <typename T> struct trait_trivial_ctor { enum { value = false }; };
+template <typename T> struct trait_trivial_dtor { enum { value = false }; };
+template <typename T> struct trait_trivial_copy { enum { value = false }; };
+template <typename T> struct trait_trivial_assign{ enum { value = false }; };
+
+template <typename T> struct trait_pointer { enum { value = false }; };
+template <typename T> struct trait_pointer<T*> { enum { value = true }; };
+
+#define ANDROID_BASIC_TYPES_TRAITS( T ) \
+ template<> struct trait_trivial_ctor< T > { enum { value = true }; }; \
+ template<> struct trait_trivial_dtor< T > { enum { value = true }; }; \
+ template<> struct trait_trivial_copy< T > { enum { value = true }; }; \
+ template<> struct trait_trivial_assign< T >{ enum { value = true }; };
+
+#define ANDROID_TYPE_TRAITS( T, ctor, dtor, copy, assign ) \
+ template<> struct trait_trivial_ctor< T > { enum { value = ctor }; }; \
+ template<> struct trait_trivial_dtor< T > { enum { value = dtor }; }; \
+ template<> struct trait_trivial_copy< T > { enum { value = copy }; }; \
+ template<> struct trait_trivial_assign< T >{ enum { value = assign }; };
+
+template <typename TYPE>
+struct traits {
+ enum {
+ is_pointer = trait_pointer<TYPE>::value,
+ has_trivial_ctor = is_pointer || trait_trivial_ctor<TYPE>::value,
+ has_trivial_dtor = is_pointer || trait_trivial_dtor<TYPE>::value,
+ has_trivial_copy = is_pointer || trait_trivial_copy<TYPE>::value,
+ has_trivial_assign = is_pointer || trait_trivial_assign<TYPE>::value
+ };
+};
+
+template <typename T, typename U>
+struct aggregate_traits {
+ enum {
+ is_pointer = false,
+ has_trivial_ctor = traits<T>::has_trivial_ctor && traits<U>::has_trivial_ctor,
+ has_trivial_dtor = traits<T>::has_trivial_dtor && traits<U>::has_trivial_dtor,
+ has_trivial_copy = traits<T>::has_trivial_copy && traits<U>::has_trivial_copy,
+ has_trivial_assign = traits<T>::has_trivial_assign && traits<U>::has_trivial_assign
+ };
+};
+
+// ---------------------------------------------------------------------------
+
+/*
+ * basic types traits
+ */
+
+ANDROID_BASIC_TYPES_TRAITS( void );
+ANDROID_BASIC_TYPES_TRAITS( bool );
+ANDROID_BASIC_TYPES_TRAITS( char );
+ANDROID_BASIC_TYPES_TRAITS( unsigned char );
+ANDROID_BASIC_TYPES_TRAITS( short );
+ANDROID_BASIC_TYPES_TRAITS( unsigned short );
+ANDROID_BASIC_TYPES_TRAITS( int );
+ANDROID_BASIC_TYPES_TRAITS( unsigned int );
+ANDROID_BASIC_TYPES_TRAITS( long );
+ANDROID_BASIC_TYPES_TRAITS( unsigned long );
+ANDROID_BASIC_TYPES_TRAITS( long long );
+ANDROID_BASIC_TYPES_TRAITS( unsigned long long );
+ANDROID_BASIC_TYPES_TRAITS( float );
+ANDROID_BASIC_TYPES_TRAITS( double );
+
+// ---------------------------------------------------------------------------
+
+
+/*
+ * compare and order types
+ */
+
+template<typename TYPE> inline
+int strictly_order_type(const TYPE& lhs, const TYPE& rhs) {
+ return (lhs < rhs) ? 1 : 0;
+}
+
+template<typename TYPE> inline
+int compare_type(const TYPE& lhs, const TYPE& rhs) {
+ return strictly_order_type(rhs, lhs) - strictly_order_type(lhs, rhs);
+}
+
+/*
+ * create, destroy, copy and assign types...
+ */
+
+template<typename TYPE> inline
+void construct_type(TYPE* p, size_t n) {
+ if (!traits<TYPE>::has_trivial_ctor) {
+ while (n--) {
+ new(p++) TYPE;
+ }
+ }
+}
+
+template<typename TYPE> inline
+void destroy_type(TYPE* p, size_t n) {
+ if (!traits<TYPE>::has_trivial_dtor) {
+ while (n--) {
+ p->~TYPE();
+ p++;
+ }
+ }
+}
+
+template<typename TYPE> inline
+void copy_type(TYPE* d, const TYPE* s, size_t n) {
+ if (!traits<TYPE>::has_trivial_copy) {
+ while (n--) {
+ new(d) TYPE(*s);
+ d++, s++;
+ }
+ } else {
+ memcpy(d,s,n*sizeof(TYPE));
+ }
+}
+
+template<typename TYPE> inline
+void assign_type(TYPE* d, const TYPE* s, size_t n) {
+ if (!traits<TYPE>::has_trivial_assign) {
+ while (n--) {
+ *d++ = *s++;
+ }
+ } else {
+ memcpy(d,s,n*sizeof(TYPE));
+ }
+}
+
+template<typename TYPE> inline
+void splat_type(TYPE* where, const TYPE* what, size_t n) {
+ if (!traits<TYPE>::has_trivial_copy) {
+ while (n--) {
+ new(where) TYPE(*what);
+ where++;
+ }
+ } else {
+ while (n--) {
+ *where++ = *what;
+ }
+ }
+}
+
+template<typename TYPE> inline
+void move_forward_type(TYPE* d, const TYPE* s, size_t n = 1) {
+ if (!traits<TYPE>::has_trivial_copy || !traits<TYPE>::has_trivial_dtor) {
+ d += n;
+ s += n;
+ while (n--) {
+ --d, --s;
+ if (!traits<TYPE>::has_trivial_copy) {
+ new(d) TYPE(*s);
+ } else {
+ *d = *s;
+ }
+ if (!traits<TYPE>::has_trivial_dtor) {
+ s->~TYPE();
+ }
+ }
+ } else {
+ memmove(d,s,n*sizeof(TYPE));
+ }
+}
+
+template<typename TYPE> inline
+void move_backward_type(TYPE* d, const TYPE* s, size_t n = 1) {
+ if (!traits<TYPE>::has_trivial_copy || !traits<TYPE>::has_trivial_dtor) {
+ while (n--) {
+ if (!traits<TYPE>::has_trivial_copy) {
+ new(d) TYPE(*s);
+ } else {
+ *d = *s;
+ }
+ if (!traits<TYPE>::has_trivial_dtor) {
+ s->~TYPE();
+ }
+ d++, s++;
+ }
+ } else {
+ memmove(d,s,n*sizeof(TYPE));
+ }
+}
+// ---------------------------------------------------------------------------
+
+/*
+ * a key/value pair
+ */
+
+template <typename KEY, typename VALUE>
+struct key_value_pair_t {
+ KEY key;
+ VALUE value;
+ key_value_pair_t() { }
+ key_value_pair_t(const key_value_pair_t& o) : key(o.key), value(o.value) { }
+ key_value_pair_t(const KEY& k, const VALUE& v) : key(k), value(v) { }
+ key_value_pair_t(const KEY& k) : key(k) { }
+ inline bool operator < (const key_value_pair_t& o) const {
+ return strictly_order_type(key, o.key);
+ }
+};
+
+template<>
+template <typename K, typename V>
+struct trait_trivial_ctor< key_value_pair_t<K, V> >
+{ enum { value = aggregate_traits<K,V>::has_trivial_ctor }; };
+template<>
+template <typename K, typename V>
+struct trait_trivial_dtor< key_value_pair_t<K, V> >
+{ enum { value = aggregate_traits<K,V>::has_trivial_dtor }; };
+template<>
+template <typename K, typename V>
+struct trait_trivial_copy< key_value_pair_t<K, V> >
+{ enum { value = aggregate_traits<K,V>::has_trivial_copy }; };
+template<>
+template <typename K, typename V>
+struct trait_trivial_assign< key_value_pair_t<K, V> >
+{ enum { value = aggregate_traits<K,V>::has_trivial_assign};};
+
+// ---------------------------------------------------------------------------
+
+}; // namespace android
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_TYPE_HELPERS_H
diff --git a/include/utils/Vector.h b/include/utils/Vector.h
new file mode 100644
index 0000000..be365d8
--- /dev/null
+++ b/include/utils/Vector.h
@@ -0,0 +1,359 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_VECTOR_H
+#define ANDROID_VECTOR_H
+
+#include <new>
+#include <stdint.h>
+#include <sys/types.h>
+
+#include <utils/Log.h>
+#include <utils/VectorImpl.h>
+#include <utils/TypeHelpers.h>
+
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+/*!
+ * The main templated vector class ensuring type safety
+ * while making use of VectorImpl.
+ * This is the class users want to use.
+ */
+
+template <class TYPE>
+class Vector : private VectorImpl
+{
+public:
+ typedef TYPE value_type;
+
+ /*!
+ * Constructors and destructors
+ */
+
+ Vector();
+ Vector(const Vector<TYPE>& rhs);
+ virtual ~Vector();
+
+ /*! copy operator */
+ const Vector<TYPE>& operator = (const Vector<TYPE>& rhs) const;
+ Vector<TYPE>& operator = (const Vector<TYPE>& rhs);
+
+ /*
+ * empty the vector
+ */
+
+ inline void clear() { VectorImpl::clear(); }
+
+ /*!
+ * vector stats
+ */
+
+ //! returns number of items in the vector
+ inline size_t size() const { return VectorImpl::size(); }
+ //! returns wether or not the vector is empty
+ inline bool isEmpty() const { return VectorImpl::isEmpty(); }
+ //! returns how many items can be stored without reallocating the backing store
+ inline size_t capacity() const { return VectorImpl::capacity(); }
+ //! setst the capacity. capacity can never be reduced less than size()
+ inline ssize_t setCapacity(size_t size) { return VectorImpl::setCapacity(size); }
+
+ /*!
+ * C-style array access
+ */
+
+ //! read-only C-style access
+ inline const TYPE* array() const;
+ //! read-write C-style access
+ TYPE* editArray();
+
+ /*!
+ * accessors
+ */
+
+ //! read-only access to an item at a given index
+ inline const TYPE& operator [] (size_t index) const;
+ //! alternate name for operator []
+ inline const TYPE& itemAt(size_t index) const;
+ //! stack-usage of the vector. returns the top of the stack (last element)
+ const TYPE& top() const;
+ //! same as operator [], but allows to access the vector backward (from the end) with a negative index
+ const TYPE& mirrorItemAt(ssize_t index) const;
+
+ /*!
+ * modifing the array
+ */
+
+ //! copy-on write support, grants write access to an item
+ TYPE& editItemAt(size_t index);
+ //! grants right acces to the top of the stack (last element)
+ TYPE& editTop();
+
+ /*!
+ * append/insert another vector
+ */
+
+ //! insert another vector at a given index
+ ssize_t insertVectorAt(const Vector<TYPE>& vector, size_t index);
+
+ //! append another vector at the end of this one
+ ssize_t appendVector(const Vector<TYPE>& vector);
+
+
+ /*!
+ * add/insert/replace items
+ */
+
+ //! insert one or several items initialized with their default constructor
+ inline ssize_t insertAt(size_t index, size_t numItems = 1);
+ //! insert on onr several items initialized from a prototype item
+ ssize_t insertAt(const TYPE& prototype_item, size_t index, size_t numItems = 1);
+ //! pop the top of the stack (removes the last element). No-op if the stack's empty
+ inline void pop();
+ //! pushes an item initialized with its default constructor
+ inline void push();
+ //! pushes an item on the top of the stack
+ void push(const TYPE& item);
+ //! same as push() but returns the index the item was added at (or an error)
+ inline ssize_t add();
+ //! same as push() but returns the index the item was added at (or an error)
+ ssize_t add(const TYPE& item);
+ //! replace an item with a new one initialized with its default constructor
+ inline ssize_t replaceAt(size_t index);
+ //! replace an item with a new one
+ ssize_t replaceAt(const TYPE& item, size_t index);
+
+ /*!
+ * remove items
+ */
+
+ //! remove several items
+ inline ssize_t removeItemsAt(size_t index, size_t count = 1);
+ //! remove one item
+ inline ssize_t removeAt(size_t index) { return removeItemsAt(index); }
+
+ /*!
+ * sort (stable) the array
+ */
+
+ typedef int (*compar_t)(const TYPE* lhs, const TYPE* rhs);
+ typedef int (*compar_r_t)(const TYPE* lhs, const TYPE* rhs, void* state);
+
+ inline status_t sort(compar_t cmp);
+ inline status_t sort(compar_r_t cmp, void* state);
+
+protected:
+ virtual void do_construct(void* storage, size_t num) const;
+ virtual void do_destroy(void* storage, size_t num) const;
+ virtual void do_copy(void* dest, const void* from, size_t num) const;
+ virtual void do_splat(void* dest, const void* item, size_t num) const;
+ virtual void do_move_forward(void* dest, const void* from, size_t num) const;
+ virtual void do_move_backward(void* dest, const void* from, size_t num) const;
+};
+
+
+// ---------------------------------------------------------------------------
+// No user serviceable parts from here...
+// ---------------------------------------------------------------------------
+
+template<class TYPE> inline
+Vector<TYPE>::Vector()
+ : VectorImpl(sizeof(TYPE),
+ ((traits<TYPE>::has_trivial_ctor ? HAS_TRIVIAL_CTOR : 0)
+ |(traits<TYPE>::has_trivial_dtor ? HAS_TRIVIAL_DTOR : 0)
+ |(traits<TYPE>::has_trivial_copy ? HAS_TRIVIAL_COPY : 0)
+ |(traits<TYPE>::has_trivial_assign ? HAS_TRIVIAL_ASSIGN : 0))
+ )
+{
+}
+
+template<class TYPE> inline
+Vector<TYPE>::Vector(const Vector<TYPE>& rhs)
+ : VectorImpl(rhs) {
+}
+
+template<class TYPE> inline
+Vector<TYPE>::~Vector() {
+ finish_vector();
+}
+
+template<class TYPE> inline
+Vector<TYPE>& Vector<TYPE>::operator = (const Vector<TYPE>& rhs) {
+ VectorImpl::operator = (rhs);
+ return *this;
+}
+
+template<class TYPE> inline
+const Vector<TYPE>& Vector<TYPE>::operator = (const Vector<TYPE>& rhs) const {
+ VectorImpl::operator = (rhs);
+ return *this;
+}
+
+template<class TYPE> inline
+const TYPE* Vector<TYPE>::array() const {
+ return static_cast<const TYPE *>(arrayImpl());
+}
+
+template<class TYPE> inline
+TYPE* Vector<TYPE>::editArray() {
+ return static_cast<TYPE *>(editArrayImpl());
+}
+
+
+template<class TYPE> inline
+const TYPE& Vector<TYPE>::operator[](size_t index) const {
+ LOG_FATAL_IF( index>=size(),
+ "itemAt: index %d is past size %d", (int)index, (int)size() );
+ return *(array() + index);
+}
+
+template<class TYPE> inline
+const TYPE& Vector<TYPE>::itemAt(size_t index) const {
+ return operator[](index);
+}
+
+template<class TYPE> inline
+const TYPE& Vector<TYPE>::mirrorItemAt(ssize_t index) const {
+ LOG_FATAL_IF( (index>0 ? index : -index)>=size(),
+ "mirrorItemAt: index %d is past size %d",
+ (int)index, (int)size() );
+ return *(array() + ((index<0) ? (size()-index) : index));
+}
+
+template<class TYPE> inline
+const TYPE& Vector<TYPE>::top() const {
+ return *(array() + size() - 1);
+}
+
+template<class TYPE> inline
+TYPE& Vector<TYPE>::editItemAt(size_t index) {
+ return *( static_cast<TYPE *>(editItemLocation(index)) );
+}
+
+template<class TYPE> inline
+TYPE& Vector<TYPE>::editTop() {
+ return *( static_cast<TYPE *>(editItemLocation(size()-1)) );
+}
+
+template<class TYPE> inline
+ssize_t Vector<TYPE>::insertVectorAt(const Vector<TYPE>& vector, size_t index) {
+ return VectorImpl::insertVectorAt(reinterpret_cast<const VectorImpl&>(vector), index);
+}
+
+template<class TYPE> inline
+ssize_t Vector<TYPE>::appendVector(const Vector<TYPE>& vector) {
+ return VectorImpl::appendVector(reinterpret_cast<const VectorImpl&>(vector));
+}
+
+template<class TYPE> inline
+ssize_t Vector<TYPE>::insertAt(const TYPE& item, size_t index, size_t numItems) {
+ return VectorImpl::insertAt(&item, index, numItems);
+}
+
+template<class TYPE> inline
+void Vector<TYPE>::push(const TYPE& item) {
+ return VectorImpl::push(&item);
+}
+
+template<class TYPE> inline
+ssize_t Vector<TYPE>::add(const TYPE& item) {
+ return VectorImpl::add(&item);
+}
+
+template<class TYPE> inline
+ssize_t Vector<TYPE>::replaceAt(const TYPE& item, size_t index) {
+ return VectorImpl::replaceAt(&item, index);
+}
+
+template<class TYPE> inline
+ssize_t Vector<TYPE>::insertAt(size_t index, size_t numItems) {
+ return VectorImpl::insertAt(index, numItems);
+}
+
+template<class TYPE> inline
+void Vector<TYPE>::pop() {
+ VectorImpl::pop();
+}
+
+template<class TYPE> inline
+void Vector<TYPE>::push() {
+ VectorImpl::push();
+}
+
+template<class TYPE> inline
+ssize_t Vector<TYPE>::add() {
+ return VectorImpl::add();
+}
+
+template<class TYPE> inline
+ssize_t Vector<TYPE>::replaceAt(size_t index) {
+ return VectorImpl::replaceAt(index);
+}
+
+template<class TYPE> inline
+ssize_t Vector<TYPE>::removeItemsAt(size_t index, size_t count) {
+ return VectorImpl::removeItemsAt(index, count);
+}
+
+template<class TYPE> inline
+status_t Vector<TYPE>::sort(Vector<TYPE>::compar_t cmp) {
+ return VectorImpl::sort((VectorImpl::compar_t)cmp);
+}
+
+template<class TYPE> inline
+status_t Vector<TYPE>::sort(Vector<TYPE>::compar_r_t cmp, void* state) {
+ return VectorImpl::sort((VectorImpl::compar_r_t)cmp, state);
+}
+
+// ---------------------------------------------------------------------------
+
+template<class TYPE>
+void Vector<TYPE>::do_construct(void* storage, size_t num) const {
+ construct_type( reinterpret_cast<TYPE*>(storage), num );
+}
+
+template<class TYPE>
+void Vector<TYPE>::do_destroy(void* storage, size_t num) const {
+ destroy_type( reinterpret_cast<TYPE*>(storage), num );
+}
+
+template<class TYPE>
+void Vector<TYPE>::do_copy(void* dest, const void* from, size_t num) const {
+ copy_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num );
+}
+
+template<class TYPE>
+void Vector<TYPE>::do_splat(void* dest, const void* item, size_t num) const {
+ splat_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(item), num );
+}
+
+template<class TYPE>
+void Vector<TYPE>::do_move_forward(void* dest, const void* from, size_t num) const {
+ move_forward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num );
+}
+
+template<class TYPE>
+void Vector<TYPE>::do_move_backward(void* dest, const void* from, size_t num) const {
+ move_backward_type( reinterpret_cast<TYPE*>(dest), reinterpret_cast<const TYPE*>(from), num );
+}
+
+}; // namespace android
+
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_VECTOR_H
diff --git a/include/utils/VectorImpl.h b/include/utils/VectorImpl.h
new file mode 100644
index 0000000..2525229
--- /dev/null
+++ b/include/utils/VectorImpl.h
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_VECTOR_IMPL_H
+#define ANDROID_VECTOR_IMPL_H
+
+#include <assert.h>
+#include <stdint.h>
+#include <sys/types.h>
+#include <utils/Errors.h>
+
+// ---------------------------------------------------------------------------
+// No user serviceable parts in here...
+// ---------------------------------------------------------------------------
+
+namespace android {
+
+/*!
+ * Implementation of the guts of the vector<> class
+ * this ensures backward binary compatibility and
+ * reduces code size.
+ * For performance reasons, we expose mStorage and mCount
+ * so these fields are set in stone.
+ *
+ */
+
+class VectorImpl
+{
+public:
+ enum { // flags passed to the ctor
+ HAS_TRIVIAL_CTOR = 0x00000001,
+ HAS_TRIVIAL_DTOR = 0x00000002,
+ HAS_TRIVIAL_COPY = 0x00000004,
+ HAS_TRIVIAL_ASSIGN = 0x00000008
+ };
+
+ VectorImpl(size_t itemSize, uint32_t flags);
+ VectorImpl(const VectorImpl& rhs);
+ virtual ~VectorImpl();
+
+ /*! must be called from subclasses destructor */
+ void finish_vector();
+
+ VectorImpl& operator = (const VectorImpl& rhs);
+
+ /*! C-style array access */
+ inline const void* arrayImpl() const { return mStorage; }
+ void* editArrayImpl();
+
+ /*! vector stats */
+ inline size_t size() const { return mCount; }
+ inline bool isEmpty() const { return mCount == 0; }
+ size_t capacity() const;
+ ssize_t setCapacity(size_t size);
+
+ /*! append/insert another vector */
+ ssize_t insertVectorAt(const VectorImpl& vector, size_t index);
+ ssize_t appendVector(const VectorImpl& vector);
+
+ /*! add/insert/replace items */
+ ssize_t insertAt(size_t where, size_t numItems = 1);
+ ssize_t insertAt(const void* item, size_t where, size_t numItems = 1);
+ void pop();
+ void push();
+ void push(const void* item);
+ ssize_t add();
+ ssize_t add(const void* item);
+ ssize_t replaceAt(size_t index);
+ ssize_t replaceAt(const void* item, size_t index);
+
+ /*! remove items */
+ ssize_t removeItemsAt(size_t index, size_t count = 1);
+ void clear();
+
+ const void* itemLocation(size_t index) const;
+ void* editItemLocation(size_t index);
+
+ typedef int (*compar_t)(const void* lhs, const void* rhs);
+ typedef int (*compar_r_t)(const void* lhs, const void* rhs, void* state);
+ status_t sort(compar_t cmp);
+ status_t sort(compar_r_t cmp, void* state);
+
+protected:
+ size_t itemSize() const;
+ void release_storage();
+
+ virtual void do_construct(void* storage, size_t num) const = 0;
+ virtual void do_destroy(void* storage, size_t num) const = 0;
+ virtual void do_copy(void* dest, const void* from, size_t num) const = 0;
+ virtual void do_splat(void* dest, const void* item, size_t num) const = 0;
+ virtual void do_move_forward(void* dest, const void* from, size_t num) const = 0;
+ virtual void do_move_backward(void* dest, const void* from, size_t num) const = 0;
+
+ // take care of FBC...
+ virtual void reservedVectorImpl1();
+ virtual void reservedVectorImpl2();
+ virtual void reservedVectorImpl3();
+ virtual void reservedVectorImpl4();
+ virtual void reservedVectorImpl5();
+ virtual void reservedVectorImpl6();
+ virtual void reservedVectorImpl7();
+ virtual void reservedVectorImpl8();
+
+private:
+ void* _grow(size_t where, size_t amount);
+ void _shrink(size_t where, size_t amount);
+
+ inline void _do_construct(void* storage, size_t num) const;
+ inline void _do_destroy(void* storage, size_t num) const;
+ inline void _do_copy(void* dest, const void* from, size_t num) const;
+ inline void _do_splat(void* dest, const void* item, size_t num) const;
+ inline void _do_move_forward(void* dest, const void* from, size_t num) const;
+ inline void _do_move_backward(void* dest, const void* from, size_t num) const;
+
+ // These 2 fields are exposed in the inlines below,
+ // so they're set in stone.
+ void * mStorage; // base address of the vector
+ size_t mCount; // number of items
+
+ const uint32_t mFlags;
+ const size_t mItemSize;
+};
+
+
+
+class SortedVectorImpl : public VectorImpl
+{
+public:
+ SortedVectorImpl(size_t itemSize, uint32_t flags);
+ SortedVectorImpl(const VectorImpl& rhs);
+ virtual ~SortedVectorImpl();
+
+ SortedVectorImpl& operator = (const SortedVectorImpl& rhs);
+
+ //! finds the index of an item
+ ssize_t indexOf(const void* item) const;
+
+ //! finds where this item should be inserted
+ size_t orderOf(const void* item) const;
+
+ //! add an item in the right place (or replaces it if there is one)
+ ssize_t add(const void* item);
+
+ //! merges a vector into this one
+ ssize_t merge(const VectorImpl& vector);
+ ssize_t merge(const SortedVectorImpl& vector);
+
+ //! removes an item
+ ssize_t remove(const void* item);
+
+protected:
+ virtual int do_compare(const void* lhs, const void* rhs) const = 0;
+
+ // take care of FBC...
+ virtual void reservedSortedVectorImpl1();
+ virtual void reservedSortedVectorImpl2();
+ virtual void reservedSortedVectorImpl3();
+ virtual void reservedSortedVectorImpl4();
+ virtual void reservedSortedVectorImpl5();
+ virtual void reservedSortedVectorImpl6();
+ virtual void reservedSortedVectorImpl7();
+ virtual void reservedSortedVectorImpl8();
+
+private:
+ ssize_t _indexOrderOf(const void* item, size_t* order = 0) const;
+
+ // these are made private, because they can't be used on a SortedVector
+ // (they don't have an implementation either)
+ ssize_t add();
+ void pop();
+ void push();
+ void push(const void* item);
+ ssize_t insertVectorAt(const VectorImpl& vector, size_t index);
+ ssize_t appendVector(const VectorImpl& vector);
+ ssize_t insertAt(size_t where, size_t numItems = 1);
+ ssize_t insertAt(const void* item, size_t where, size_t numItems = 1);
+ ssize_t replaceAt(size_t index);
+ ssize_t replaceAt(const void* item, size_t index);
+};
+
+}; // namespace android
+
+
+// ---------------------------------------------------------------------------
+
+#endif // ANDROID_VECTOR_IMPL_H
diff --git a/include/utils/ZipEntry.h b/include/utils/ZipEntry.h
new file mode 100644
index 0000000..e4698df
--- /dev/null
+++ b/include/utils/ZipEntry.h
@@ -0,0 +1,345 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Zip archive entries.
+//
+// The ZipEntry class is tightly meshed with the ZipFile class.
+//
+#ifndef __LIBS_ZIPENTRY_H
+#define __LIBS_ZIPENTRY_H
+
+#include "Errors.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+namespace android {
+
+class ZipFile;
+
+/*
+ * ZipEntry objects represent a single entry in a Zip archive.
+ *
+ * You can use one of these to get or set information about an entry, but
+ * there are no functions here for accessing the data itself. (We could
+ * tuck a pointer to the ZipFile in here for convenience, but that raises
+ * the likelihood of using ZipEntry objects after discarding the ZipFile.)
+ *
+ * File information is stored in two places: next to the file data (the Local
+ * File Header, and possibly a Data Descriptor), and at the end of the file
+ * (the Central Directory Entry). The two must be kept in sync.
+ */
+class ZipEntry {
+public:
+ friend class ZipFile;
+
+ ZipEntry(void)
+ : mDeleted(false), mMarked(false)
+ {}
+ ~ZipEntry(void) {}
+
+ /*
+ * Returns "true" if the data is compressed.
+ */
+ bool isCompressed(void) const {
+ return mCDE.mCompressionMethod != kCompressStored;
+ }
+ int getCompressionMethod(void) const { return mCDE.mCompressionMethod; }
+
+ /*
+ * Return the uncompressed length.
+ */
+ off_t getUncompressedLen(void) const { return mCDE.mUncompressedSize; }
+
+ /*
+ * Return the compressed length. For uncompressed data, this returns
+ * the same thing as getUncompresesdLen().
+ */
+ off_t getCompressedLen(void) const { return mCDE.mCompressedSize; }
+
+ /*
+ * Return the absolute file offset of the start of the compressed or
+ * uncompressed data.
+ */
+ off_t getFileOffset(void) const {
+ return mCDE.mLocalHeaderRelOffset +
+ LocalFileHeader::kLFHLen +
+ mLFH.mFileNameLength +
+ mLFH.mExtraFieldLength;
+ }
+
+ /*
+ * Return the data CRC.
+ */
+ unsigned long getCRC32(void) const { return mCDE.mCRC32; }
+
+ /*
+ * Return file modification time in UNIX seconds-since-epoch.
+ */
+ time_t getModWhen(void) const;
+
+ /*
+ * Return the archived file name.
+ */
+ const char* getFileName(void) const { return (const char*) mCDE.mFileName; }
+
+ /*
+ * Application-defined "mark". Can be useful when synchronizing the
+ * contents of an archive with contents on disk.
+ */
+ bool getMarked(void) const { return mMarked; }
+ void setMarked(bool val) { mMarked = val; }
+
+ /*
+ * Some basic functions for raw data manipulation. "LE" means
+ * Little Endian.
+ */
+ static inline unsigned short getShortLE(const unsigned char* buf) {
+ return buf[0] | (buf[1] << 8);
+ }
+ static inline unsigned long getLongLE(const unsigned char* buf) {
+ return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
+ }
+ static inline void putShortLE(unsigned char* buf, short val) {
+ buf[0] = (unsigned char) val;
+ buf[1] = (unsigned char) (val >> 8);
+ }
+ static inline void putLongLE(unsigned char* buf, long val) {
+ buf[0] = (unsigned char) val;
+ buf[1] = (unsigned char) (val >> 8);
+ buf[2] = (unsigned char) (val >> 16);
+ buf[3] = (unsigned char) (val >> 24);
+ }
+
+ /* defined for Zip archives */
+ enum {
+ kCompressStored = 0, // no compression
+ // shrunk = 1,
+ // reduced 1 = 2,
+ // reduced 2 = 3,
+ // reduced 3 = 4,
+ // reduced 4 = 5,
+ // imploded = 6,
+ // tokenized = 7,
+ kCompressDeflated = 8, // standard deflate
+ // Deflate64 = 9,
+ // lib imploded = 10,
+ // reserved = 11,
+ // bzip2 = 12,
+ };
+
+ /*
+ * Deletion flag. If set, the entry will be removed on the next
+ * call to "flush".
+ */
+ bool getDeleted(void) const { return mDeleted; }
+
+protected:
+ /*
+ * Initialize the structure from the file, which is pointing at
+ * our Central Directory entry.
+ */
+ status_t initFromCDE(FILE* fp);
+
+ /*
+ * Initialize the structure for a new file. We need the filename
+ * and comment so that we can properly size the LFH area. The
+ * filename is mandatory, the comment is optional.
+ */
+ void initNew(const char* fileName, const char* comment);
+
+ /*
+ * Initialize the structure with the contents of a ZipEntry from
+ * another file.
+ */
+ status_t initFromExternal(const ZipFile* pZipFile, const ZipEntry* pEntry);
+
+ /*
+ * Add some pad bytes to the LFH. We do this by adding or resizing
+ * the "extra" field.
+ */
+ status_t addPadding(int padding);
+
+ /*
+ * Set information about the data for this entry.
+ */
+ void setDataInfo(long uncompLen, long compLen, unsigned long crc32,
+ int compressionMethod);
+
+ /*
+ * Set the modification date.
+ */
+ void setModWhen(time_t when);
+
+ /*
+ * Return the offset of the local file header.
+ */
+ off_t getLFHOffset(void) const { return mCDE.mLocalHeaderRelOffset; }
+
+ /*
+ * Set the offset of the local file header, relative to the start of
+ * the current file.
+ */
+ void setLFHOffset(off_t offset) {
+ mCDE.mLocalHeaderRelOffset = (long) offset;
+ }
+
+ /* mark for deletion; used by ZipFile::remove() */
+ void setDeleted(void) { mDeleted = true; }
+
+private:
+ /* these are private and not defined */
+ ZipEntry(const ZipEntry& src);
+ ZipEntry& operator=(const ZipEntry& src);
+
+ /* returns "true" if the CDE and the LFH agree */
+ bool compareHeaders(void) const;
+ void copyCDEtoLFH(void);
+
+ bool mDeleted; // set if entry is pending deletion
+ bool mMarked; // app-defined marker
+
+ /*
+ * Every entry in the Zip archive starts off with one of these.
+ */
+ class LocalFileHeader {
+ public:
+ LocalFileHeader(void) :
+ mVersionToExtract(0),
+ mGPBitFlag(0),
+ mCompressionMethod(0),
+ mLastModFileTime(0),
+ mLastModFileDate(0),
+ mCRC32(0),
+ mCompressedSize(0),
+ mUncompressedSize(0),
+ mFileNameLength(0),
+ mExtraFieldLength(0),
+ mFileName(NULL),
+ mExtraField(NULL)
+ {}
+ virtual ~LocalFileHeader(void) {
+ delete[] mFileName;
+ delete[] mExtraField;
+ }
+
+ status_t read(FILE* fp);
+ status_t write(FILE* fp);
+
+ // unsigned long mSignature;
+ unsigned short mVersionToExtract;
+ unsigned short mGPBitFlag;
+ unsigned short mCompressionMethod;
+ unsigned short mLastModFileTime;
+ unsigned short mLastModFileDate;
+ unsigned long mCRC32;
+ unsigned long mCompressedSize;
+ unsigned long mUncompressedSize;
+ unsigned short mFileNameLength;
+ unsigned short mExtraFieldLength;
+ unsigned char* mFileName;
+ unsigned char* mExtraField;
+
+ enum {
+ kSignature = 0x04034b50,
+ kLFHLen = 30, // LocalFileHdr len, excl. var fields
+ };
+
+ void dump(void) const;
+ };
+
+ /*
+ * Every entry in the Zip archive has one of these in the "central
+ * directory" at the end of the file.
+ */
+ class CentralDirEntry {
+ public:
+ CentralDirEntry(void) :
+ mVersionMadeBy(0),
+ mVersionToExtract(0),
+ mGPBitFlag(0),
+ mCompressionMethod(0),
+ mLastModFileTime(0),
+ mLastModFileDate(0),
+ mCRC32(0),
+ mCompressedSize(0),
+ mUncompressedSize(0),
+ mFileNameLength(0),
+ mExtraFieldLength(0),
+ mFileCommentLength(0),
+ mDiskNumberStart(0),
+ mInternalAttrs(0),
+ mExternalAttrs(0),
+ mLocalHeaderRelOffset(0),
+ mFileName(NULL),
+ mExtraField(NULL),
+ mFileComment(NULL)
+ {}
+ virtual ~CentralDirEntry(void) {
+ delete[] mFileName;
+ delete[] mExtraField;
+ delete[] mFileComment;
+ }
+
+ status_t read(FILE* fp);
+ status_t write(FILE* fp);
+
+ // unsigned long mSignature;
+ unsigned short mVersionMadeBy;
+ unsigned short mVersionToExtract;
+ unsigned short mGPBitFlag;
+ unsigned short mCompressionMethod;
+ unsigned short mLastModFileTime;
+ unsigned short mLastModFileDate;
+ unsigned long mCRC32;
+ unsigned long mCompressedSize;
+ unsigned long mUncompressedSize;
+ unsigned short mFileNameLength;
+ unsigned short mExtraFieldLength;
+ unsigned short mFileCommentLength;
+ unsigned short mDiskNumberStart;
+ unsigned short mInternalAttrs;
+ unsigned long mExternalAttrs;
+ unsigned long mLocalHeaderRelOffset;
+ unsigned char* mFileName;
+ unsigned char* mExtraField;
+ unsigned char* mFileComment;
+
+ void dump(void) const;
+
+ enum {
+ kSignature = 0x02014b50,
+ kCDELen = 46, // CentralDirEnt len, excl. var fields
+ };
+ };
+
+ enum {
+ //kDataDescriptorSignature = 0x08074b50, // currently unused
+ kDataDescriptorLen = 16, // four 32-bit fields
+
+ kDefaultVersion = 20, // need deflate, nothing much else
+ kDefaultMadeBy = 0x0317, // 03=UNIX, 17=spec v2.3
+ kUsesDataDescr = 0x0008, // GPBitFlag bit 3
+ };
+
+ LocalFileHeader mLFH;
+ CentralDirEntry mCDE;
+};
+
+}; // namespace android
+
+#endif // __LIBS_ZIPENTRY_H
diff --git a/include/utils/ZipFile.h b/include/utils/ZipFile.h
new file mode 100644
index 0000000..44df5bb
--- /dev/null
+++ b/include/utils/ZipFile.h
@@ -0,0 +1,269 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// General-purpose Zip archive access. This class allows both reading and
+// writing to Zip archives, including deletion of existing entries.
+//
+#ifndef __LIBS_ZIPFILE_H
+#define __LIBS_ZIPFILE_H
+
+#include "ZipEntry.h"
+#include "Vector.h"
+#include "Errors.h"
+#include <stdio.h>
+
+namespace android {
+
+/*
+ * Manipulate a Zip archive.
+ *
+ * Some changes will not be visible in the until until "flush" is called.
+ *
+ * The correct way to update a file archive is to make all changes to a
+ * copy of the archive in a temporary file, and then unlink/rename over
+ * the original after everything completes. Because we're only interested
+ * in using this for packaging, we don't worry about such things. Crashing
+ * after making changes and before flush() completes could leave us with
+ * an unusable Zip archive.
+ */
+class ZipFile {
+public:
+ ZipFile(void)
+ : mZipFp(NULL), mReadOnly(false), mNeedCDRewrite(false)
+ {}
+ ~ZipFile(void) {
+ if (!mReadOnly)
+ flush();
+ if (mZipFp != NULL)
+ fclose(mZipFp);
+ discardEntries();
+ }
+
+ /*
+ * Open a new or existing archive.
+ */
+ typedef enum {
+ kOpenReadOnly = 0x01,
+ kOpenReadWrite = 0x02,
+ kOpenCreate = 0x04, // create if it doesn't exist
+ kOpenTruncate = 0x08, // if it exists, empty it
+ };
+ status_t open(const char* zipFileName, int flags);
+
+ /*
+ * Add a file to the end of the archive. Specify whether you want the
+ * library to try to store it compressed.
+ *
+ * If "storageName" is specified, the archive will use that instead
+ * of "fileName".
+ *
+ * If there is already an entry with the same name, the call fails.
+ * Existing entries with the same name must be removed first.
+ *
+ * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
+ */
+ status_t add(const char* fileName, int compressionMethod,
+ ZipEntry** ppEntry)
+ {
+ return add(fileName, fileName, compressionMethod, ppEntry);
+ }
+ status_t add(const char* fileName, const char* storageName,
+ int compressionMethod, ZipEntry** ppEntry)
+ {
+ return addCommon(fileName, NULL, 0, storageName,
+ ZipEntry::kCompressStored,
+ compressionMethod, ppEntry);
+ }
+
+ /*
+ * Add a file that is already compressed with gzip.
+ *
+ * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
+ */
+ status_t addGzip(const char* fileName, const char* storageName,
+ ZipEntry** ppEntry)
+ {
+ return addCommon(fileName, NULL, 0, storageName,
+ ZipEntry::kCompressDeflated,
+ ZipEntry::kCompressDeflated, ppEntry);
+ }
+
+ /*
+ * Add a file from an in-memory data buffer.
+ *
+ * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
+ */
+ status_t add(const void* data, size_t size, const char* storageName,
+ int compressionMethod, ZipEntry** ppEntry)
+ {
+ return addCommon(NULL, data, size, storageName,
+ ZipEntry::kCompressStored,
+ compressionMethod, ppEntry);
+ }
+
+ /*
+ * Add an entry by copying it from another zip file. If "padding" is
+ * nonzero, the specified number of bytes will be added to the "extra"
+ * field in the header.
+ *
+ * If "ppEntry" is non-NULL, a pointer to the new entry will be returned.
+ */
+ status_t add(const ZipFile* pSourceZip, const ZipEntry* pSourceEntry,
+ int padding, ZipEntry** ppEntry);
+
+ /*
+ * Mark an entry as having been removed. It is not actually deleted
+ * from the archive or our internal data structures until flush() is
+ * called.
+ */
+ status_t remove(ZipEntry* pEntry);
+
+ /*
+ * Flush changes. If mNeedCDRewrite is set, this writes the central dir.
+ */
+ status_t flush(void);
+
+ /*
+ * Expand the data into the buffer provided. The buffer must hold
+ * at least <uncompressed len> bytes. Variation expands directly
+ * to a file.
+ *
+ * Returns "false" if an error was encountered in the compressed data.
+ */
+ //bool uncompress(const ZipEntry* pEntry, void* buf) const;
+ //bool uncompress(const ZipEntry* pEntry, FILE* fp) const;
+ void* uncompress(const ZipEntry* pEntry);
+
+ /*
+ * Get an entry, by name. Returns NULL if not found.
+ *
+ * Does not return entries pending deletion.
+ */
+ ZipEntry* getEntryByName(const char* fileName) const;
+
+ /*
+ * Get the Nth entry in the archive.
+ *
+ * This will return an entry that is pending deletion.
+ */
+ int getNumEntries(void) const { return mEntries.size(); }
+ ZipEntry* getEntryByIndex(int idx) const;
+
+private:
+ /* these are private and not defined */
+ ZipFile(const ZipFile& src);
+ ZipFile& operator=(const ZipFile& src);
+
+ class EndOfCentralDir {
+ public:
+ EndOfCentralDir(void) :
+ mDiskNumber(0),
+ mDiskWithCentralDir(0),
+ mNumEntries(0),
+ mTotalNumEntries(0),
+ mCentralDirSize(0),
+ mCentralDirOffset(0),
+ mCommentLen(0),
+ mComment(NULL)
+ {}
+ virtual ~EndOfCentralDir(void) {
+ delete[] mComment;
+ }
+
+ status_t readBuf(const unsigned char* buf, int len);
+ status_t write(FILE* fp);
+
+ //unsigned long mSignature;
+ unsigned short mDiskNumber;
+ unsigned short mDiskWithCentralDir;
+ unsigned short mNumEntries;
+ unsigned short mTotalNumEntries;
+ unsigned long mCentralDirSize;
+ unsigned long mCentralDirOffset; // offset from first disk
+ unsigned short mCommentLen;
+ unsigned char* mComment;
+
+ enum {
+ kSignature = 0x06054b50,
+ kEOCDLen = 22, // EndOfCentralDir len, excl. comment
+
+ kMaxCommentLen = 65535, // longest possible in ushort
+ kMaxEOCDSearch = kMaxCommentLen + EndOfCentralDir::kEOCDLen,
+
+ };
+
+ void dump(void) const;
+ };
+
+
+ /* read all entries in the central dir */
+ status_t readCentralDir(void);
+
+ /* crunch deleted entries out */
+ status_t crunchArchive(void);
+
+ /* clean up mEntries */
+ void discardEntries(void);
+
+ /* common handler for all "add" functions */
+ status_t addCommon(const char* fileName, const void* data, size_t size,
+ const char* storageName, int sourceType, int compressionMethod,
+ ZipEntry** ppEntry);
+
+ /* copy all of "srcFp" into "dstFp" */
+ status_t copyFpToFp(FILE* dstFp, FILE* srcFp, unsigned long* pCRC32);
+ /* copy all of "data" into "dstFp" */
+ status_t copyDataToFp(FILE* dstFp,
+ const void* data, size_t size, unsigned long* pCRC32);
+ /* copy some of "srcFp" into "dstFp" */
+ status_t copyPartialFpToFp(FILE* dstFp, FILE* srcFp, long length,
+ unsigned long* pCRC32);
+ /* like memmove(), but on parts of a single file */
+ status_t filemove(FILE* fp, off_t dest, off_t src, size_t n);
+ /* compress all of "srcFp" into "dstFp", using Deflate */
+ status_t compressFpToFp(FILE* dstFp, FILE* srcFp,
+ const void* data, size_t size, unsigned long* pCRC32);
+
+ /* get modification date from a file descriptor */
+ time_t getModTime(int fd);
+
+ /*
+ * We use stdio FILE*, which gives us buffering but makes dealing
+ * with files >2GB awkward. Until we support Zip64, we're fine.
+ */
+ FILE* mZipFp; // Zip file pointer
+
+ /* one of these per file */
+ EndOfCentralDir mEOCD;
+
+ /* did we open this read-only? */
+ bool mReadOnly;
+
+ /* set this when we trash the central dir */
+ bool mNeedCDRewrite;
+
+ /*
+ * One ZipEntry per entry in the zip file. I'm using pointers instead
+ * of objects because it's easier than making operator= work for the
+ * classes and sub-classes.
+ */
+ Vector<ZipEntry*> mEntries;
+};
+
+}; // namespace android
+
+#endif // __LIBS_ZIPFILE_H
diff --git a/include/utils/ZipFileCRO.h b/include/utils/ZipFileCRO.h
new file mode 100644
index 0000000..30e0036
--- /dev/null
+++ b/include/utils/ZipFileCRO.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// C API for ead-only access to Zip archives, with minimal heap allocation.
+//
+#ifndef __LIBS_ZIPFILECRO_H
+#define __LIBS_ZIPFILECRO_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Trivial typedef to ensure that ZipFileCRO is not treated as a simple integer.
+ */
+typedef void* ZipFileCRO;
+
+/*
+ * Trivial typedef to ensure that ZipEntryCRO is not treated as a simple
+ * integer. We use NULL to indicate an invalid value.
+ */
+typedef void* ZipEntryCRO;
+
+extern ZipFileCRO ZipFileXRO_open(const char* path);
+
+extern void ZipFileCRO_destroy(ZipFileCRO zip);
+
+extern ZipEntryCRO ZipFileCRO_findEntryByName(ZipFileCRO zip,
+ const char* fileName);
+
+extern bool ZipFileCRO_getEntryInfo(ZipFileCRO zip, ZipEntryCRO entry,
+ int* pMethod, long* pUncompLen,
+ long* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32);
+
+extern bool ZipFileCRO_uncompressEntry(ZipFileCRO zip, ZipEntryCRO entry, int fd);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__LIBS_ZIPFILECRO_H*/
diff --git a/include/utils/ZipFileRO.h b/include/utils/ZipFileRO.h
new file mode 100644
index 0000000..51c4f2f
--- /dev/null
+++ b/include/utils/ZipFileRO.h
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Read-only access to Zip archives, with minimal heap allocation.
+//
+// This is similar to the more-complete ZipFile class, but no attempt
+// has been made to make them interchangeable. This class operates under
+// a very different set of assumptions and constraints.
+//
+#ifndef __LIBS_ZIPFILERO_H
+#define __LIBS_ZIPFILERO_H
+
+#include "Errors.h"
+#include "FileMap.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+namespace android {
+
+/*
+ * Trivial typedef to ensure that ZipEntryRO is not treated as a simple
+ * integer. We use NULL to indicate an invalid value.
+ */
+typedef void* ZipEntryRO;
+
+/*
+ * Open a Zip archive for reading.
+ *
+ * We want "open" and "find entry by name" to be fast operations, and we
+ * want to use as little memory as possible. We memory-map the file,
+ * and load a hash table with pointers to the filenames (which aren't
+ * null-terminated). The other fields are at a fixed offset from the
+ * filename, so we don't need to extract those (but we do need to byte-read
+ * and endian-swap them every time we want them).
+ *
+ * To speed comparisons when doing a lookup by name, we could make the mapping
+ * "private" (copy-on-write) and null-terminate the filenames after verifying
+ * the record structure. However, this requires a private mapping of
+ * every page that the Central Directory touches. Easier to tuck a copy
+ * of the string length into the hash table entry.
+ */
+class ZipFileRO {
+public:
+ ZipFileRO()
+ : mFd(-1), mFileMap(NULL), mHashTableSize(-1), mHashTable(NULL)
+ {}
+ ~ZipFileRO() {
+ free(mHashTable);
+ if (mFileMap)
+ mFileMap->release();
+ if (mFd >= 0)
+ close(mFd);
+ }
+
+ /*
+ * Open an archive.
+ */
+ status_t open(const char* zipFileName);
+
+ /*
+ * Find an entry, by name. Returns the entry identifier, or NULL if
+ * not found.
+ *
+ * If two entries have the same name, one will be chosen at semi-random.
+ */
+ ZipEntryRO findEntryByName(const char* fileName) const;
+
+ /*
+ * Return the #of entries in the Zip archive.
+ */
+ int getNumEntries(void) const {
+ return mNumEntries;
+ }
+
+ /*
+ * Return the Nth entry. Zip file entries are not stored in sorted
+ * order, and updated entries may appear at the end, so anyone walking
+ * the archive needs to avoid making ordering assumptions. We take
+ * that further by returning the Nth non-empty entry in the hash table
+ * rather than the Nth entry in the archive.
+ *
+ * Valid values are [0..numEntries).
+ *
+ * [This is currently O(n). If it needs to be fast we can allocate an
+ * additional data structure or provide an iterator interface.]
+ */
+ ZipEntryRO findEntryByIndex(int idx) const;
+
+ /*
+ * Copy the filename into the supplied buffer. Returns 0 on success,
+ * -1 if "entry" is invalid, or the filename length if it didn't fit. The
+ * length, and the returned string, include the null-termination.
+ */
+ int getEntryFileName(ZipEntryRO entry, char* buffer, int bufLen) const;
+
+ /*
+ * Get the vital stats for an entry. Pass in NULL pointers for anything
+ * you don't need.
+ *
+ * "*pOffset" holds the Zip file offset of the entry's data.
+ *
+ * Returns "false" if "entry" is bogus or if the data in the Zip file
+ * appears to be bad.
+ */
+ bool getEntryInfo(ZipEntryRO entry, int* pMethod, long* pUncompLen,
+ long* pCompLen, off_t* pOffset, long* pModWhen, long* pCrc32) const;
+
+ /*
+ * Create a new FileMap object that maps a subset of the archive. For
+ * an uncompressed entry this effectively provides a pointer to the
+ * actual data, for a compressed entry this provides the input buffer
+ * for inflate().
+ */
+ FileMap* createEntryFileMap(ZipEntryRO entry) const;
+
+ /*
+ * Uncompress the data into a buffer. Depending on the compression
+ * format, this is either an "inflate" operation or a memcpy.
+ *
+ * Use "uncompLen" from getEntryInfo() to determine the required
+ * buffer size.
+ *
+ * Returns "true" on success.
+ */
+ bool uncompressEntry(ZipEntryRO entry, void* buffer) const;
+
+ /*
+ * Uncompress the data to an open file descriptor.
+ */
+ bool uncompressEntry(ZipEntryRO entry, int fd) const;
+
+ /* Zip compression methods we support */
+ enum {
+ kCompressStored = 0, // no compression
+ kCompressDeflated = 8, // standard deflate
+ };
+
+ /*
+ * Utility function: uncompress deflated data, buffer to buffer.
+ */
+ static bool inflateBuffer(void* outBuf, const void* inBuf,
+ long uncompLen, long compLen);
+
+ /*
+ * Utility function: uncompress deflated data, buffer to fd.
+ */
+ static bool inflateBuffer(int fd, const void* inBuf,
+ long uncompLen, long compLen);
+
+ /*
+ * Some basic functions for raw data manipulation. "LE" means
+ * Little Endian.
+ */
+ static inline unsigned short get2LE(const unsigned char* buf) {
+ return buf[0] | (buf[1] << 8);
+ }
+ static inline unsigned long get4LE(const unsigned char* buf) {
+ return buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24);
+ }
+
+private:
+ /* these are private and not defined */
+ ZipFileRO(const ZipFileRO& src);
+ ZipFileRO& operator=(const ZipFileRO& src);
+
+ /* parse the archive, prepping internal structures */
+ bool parseZipArchive(void);
+
+ /* add a new entry to the hash table */
+ void addToHash(const char* str, int strLen, unsigned int hash);
+
+ /* compute string hash code */
+ static unsigned int computeHash(const char* str, int len);
+
+ /* convert a ZipEntryRO back to a hash table index */
+ int entryToIndex(const ZipEntryRO entry) const;
+
+ /*
+ * One entry in the hash table.
+ */
+ typedef struct HashEntry {
+ const char* name;
+ unsigned short nameLen;
+ //unsigned int hash;
+ } HashEntry;
+
+ /* open Zip archive */
+ int mFd;
+
+ /* mapped file */
+ FileMap* mFileMap;
+
+ /* number of entries in the Zip archive */
+ int mNumEntries;
+
+ /*
+ * We know how many entries are in the Zip archive, so we have a
+ * fixed-size hash table. We probe for an empty slot.
+ */
+ int mHashTableSize;
+ HashEntry* mHashTable;
+};
+
+}; // namespace android
+
+#endif /*__LIBS_ZIPFILERO_H*/
diff --git a/include/utils/ZipUtils.h b/include/utils/ZipUtils.h
new file mode 100644
index 0000000..42c42b6
--- /dev/null
+++ b/include/utils/ZipUtils.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Miscellaneous zip/gzip utility functions.
+//
+#ifndef __LIBS_ZIPUTILS_H
+#define __LIBS_ZIPUTILS_H
+
+#include <stdio.h>
+
+namespace android {
+
+/*
+ * Container class for utility functions, primarily for namespace reasons.
+ */
+class ZipUtils {
+public:
+ /*
+ * General utility function for uncompressing "deflate" data from a file
+ * to a buffer.
+ */
+ static bool inflateToBuffer(int fd, void* buf, long uncompressedLen,
+ long compressedLen);
+ static bool inflateToBuffer(FILE* fp, void* buf, long uncompressedLen,
+ long compressedLen);
+
+ /*
+ * Someday we might want to make this generic and handle bzip2 ".bz2"
+ * files too.
+ *
+ * We could declare gzip to be a sub-class of zip that has exactly
+ * one always-compressed entry, but we currently want to treat Zip
+ * and gzip as distinct, so there's no value.
+ *
+ * The zlib library has some gzip utilities, but it has no interface
+ * for extracting the uncompressed length of the file (you do *not*
+ * want to gzseek to the end).
+ *
+ * Pass in a seeked file pointer for the gzip file. If this is a gzip
+ * file, we set our return values appropriately and return "true" with
+ * the file seeked to the start of the compressed data.
+ */
+ static bool examineGzip(FILE* fp, int* pCompressionMethod,
+ long* pUncompressedLen, long* pCompressedLen, unsigned long* pCRC32);
+
+private:
+ ZipUtils() {}
+ ~ZipUtils() {}
+};
+
+}; // namespace android
+
+#endif /*__LIBS_ZIPUTILS_H*/
diff --git a/include/utils/ashmem.h b/include/utils/ashmem.h
new file mode 100644
index 0000000..0854775
--- /dev/null
+++ b/include/utils/ashmem.h
@@ -0,0 +1,41 @@
+/* utils/ashmem.h
+ **
+ ** Copyright 2008 The Android Open Source Project
+ **
+ ** This file is dual licensed. It may be redistributed and/or modified
+ ** under the terms of the Apache 2.0 License OR version 2 of the GNU
+ ** General Public License.
+ */
+
+#ifndef _UTILS_ASHMEM_H
+#define _UTILS_ASHMEM_H
+
+#include <linux/limits.h>
+#include <linux/ioctl.h>
+
+#define ASHMEM_NAME_LEN 256
+
+#define ASHMEM_NAME_DEF "dev/ashmem"
+
+/* Return values from ASHMEM_PIN: Was the mapping purged while unpinned? */
+#define ASHMEM_NOT_REAPED 0
+#define ASHMEM_WAS_REAPED 1
+
+/* Return values from ASHMEM_UNPIN: Is the mapping now pinned or unpinned? */
+#define ASHMEM_NOW_UNPINNED 0
+#define ASHMEM_NOW_PINNED 1
+
+#define __ASHMEMIOC 0x77
+
+#define ASHMEM_SET_NAME _IOW(__ASHMEMIOC, 1, char[ASHMEM_NAME_LEN])
+#define ASHMEM_GET_NAME _IOR(__ASHMEMIOC, 2, char[ASHMEM_NAME_LEN])
+#define ASHMEM_SET_SIZE _IOW(__ASHMEMIOC, 3, size_t)
+#define ASHMEM_GET_SIZE _IO(__ASHMEMIOC, 4)
+#define ASHMEM_SET_PROT_MASK _IOW(__ASHMEMIOC, 5, unsigned long)
+#define ASHMEM_GET_PROT_MASK _IO(__ASHMEMIOC, 6)
+#define ASHMEM_PIN _IO(__ASHMEMIOC, 7)
+#define ASHMEM_UNPIN _IO(__ASHMEMIOC, 8)
+#define ASHMEM_ISPINNED _IO(__ASHMEMIOC, 9)
+#define ASHMEM_PURGE_ALL_CACHES _IO(__ASHMEMIOC, 10)
+
+#endif /* _UTILS_ASHMEM_H */
diff --git a/include/utils/executablepath.h b/include/utils/executablepath.h
new file mode 100644
index 0000000..c979432
--- /dev/null
+++ b/include/utils/executablepath.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _UTILS_EXECUTABLEPATH_H
+#define _UTILS_EXECUTABLEPATH_H
+
+#include <limits.h>
+
+// returns the path to this executable
+#if __cplusplus
+extern "C"
+#endif
+void executablepath(char s[PATH_MAX]);
+
+#endif // _UTILS_EXECUTABLEPATH_H
diff --git a/include/utils/inet_address.h b/include/utils/inet_address.h
new file mode 100644
index 0000000..dbd8672
--- /dev/null
+++ b/include/utils/inet_address.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Internet address classes. Modeled after Java classes.
+//
+#ifndef _RUNTIME_INET_ADDRESS_H
+#define _RUNTIME_INET_ADDRESS_H
+
+#ifdef HAVE_ANDROID_OS
+#error DO NOT USE THIS FILE IN THE DEVICE BUILD
+#endif
+
+
+namespace android {
+
+/*
+ * This class holds Internet addresses. Perhaps more useful is its
+ * ability to look up addresses by name.
+ *
+ * Invoke one of the static factory methods to create a new object.
+ */
+class InetAddress {
+public:
+ virtual ~InetAddress(void);
+
+ // create from w.x.y.z or foo.bar.com notation
+ static InetAddress* getByName(const char* host);
+
+ // copy-construction
+ InetAddress(const InetAddress& orig);
+
+ const void* getAddress(void) const { return mAddress; }
+ int getAddressLength(void) const { return mLength; }
+ const char* getHostName(void) const { return mName; }
+
+private:
+ InetAddress(void);
+ // assignment (private)
+ InetAddress& operator=(const InetAddress& addr);
+
+ // use a void* here so we don't have to expose actual socket headers
+ void* mAddress; // this is really a ptr to sockaddr_in
+ int mLength;
+ char* mName;
+};
+
+
+/*
+ * Base class for socket addresses.
+ */
+class SocketAddress {
+public:
+ SocketAddress() {}
+ virtual ~SocketAddress() {}
+};
+
+
+/*
+ * Internet address class. This combines an InetAddress with a port.
+ */
+class InetSocketAddress : public SocketAddress {
+public:
+ InetSocketAddress() :
+ mAddress(0), mPort(-1)
+ {}
+ ~InetSocketAddress(void) {
+ delete mAddress;
+ }
+
+ // Create an address with a host wildcard (useful for servers).
+ bool create(int port);
+ // Create an address with the specified host and port.
+ bool create(const InetAddress* addr, int port);
+ // Create an address with the specified host and port. Does the
+ // hostname lookup.
+ bool create(const char* host, int port);
+
+ const InetAddress* getAddress(void) const { return mAddress; }
+ const int getPort(void) const { return mPort; }
+ const char* getHostName(void) const { return mAddress->getHostName(); }
+
+private:
+ InetAddress* mAddress;
+ int mPort;
+};
+
+}; // namespace android
+
+#endif // _RUNTIME_INET_ADDRESS_H
diff --git a/include/utils/logger.h b/include/utils/logger.h
new file mode 100644
index 0000000..3a08019
--- /dev/null
+++ b/include/utils/logger.h
@@ -0,0 +1,46 @@
+/* utils/logger.h
+**
+** Copyright 2007, The Android Open Source Project
+**
+** This file is dual licensed. It may be redistributed and/or modified
+** under the terms of the Apache 2.0 License OR version 2 of the GNU
+** General Public License.
+*/
+
+#ifndef _UTILS_LOGGER_H
+#define _UTILS_LOGGER_H
+
+#include <stdint.h>
+
+struct logger_entry {
+ uint16_t len; /* length of the payload */
+ uint16_t __pad; /* no matter what, we get 2 bytes of padding */
+ int32_t pid; /* generating process's pid */
+ int32_t tid; /* generating process's tid */
+ int32_t sec; /* seconds since Epoch */
+ int32_t nsec; /* nanoseconds */
+ char msg[0]; /* the entry's payload */
+};
+
+#define LOGGER_LOG_MAIN "log/main"
+#define LOGGER_LOG_RADIO "log/radio"
+#define LOGGER_LOG_EVENTS "log/events"
+
+#define LOGGER_ENTRY_MAX_LEN (4*1024)
+#define LOGGER_ENTRY_MAX_PAYLOAD \
+ (LOGGER_ENTRY_MAX_LEN - sizeof(struct logger_entry))
+
+#ifdef HAVE_IOCTL
+
+#include <sys/ioctl.h>
+
+#define __LOGGERIO 0xAE
+
+#define LOGGER_GET_LOG_BUF_SIZE _IO(__LOGGERIO, 1) /* size of log */
+#define LOGGER_GET_LOG_LEN _IO(__LOGGERIO, 2) /* used log len */
+#define LOGGER_GET_NEXT_ENTRY_LEN _IO(__LOGGERIO, 3) /* next entry len */
+#define LOGGER_FLUSH_LOG _IO(__LOGGERIO, 4) /* flush log */
+
+#endif // HAVE_IOCTL
+
+#endif /* _UTILS_LOGGER_H */
diff --git a/include/utils/misc.h b/include/utils/misc.h
new file mode 100644
index 0000000..62e84b4
--- /dev/null
+++ b/include/utils/misc.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Handy utility functions and portability code.
+//
+#ifndef _LIBS_UTILS_MISC_H
+#define _LIBS_UTILS_MISC_H
+
+#include <sys/time.h>
+#include "utils/Endian.h"
+
+namespace android {
+
+/* get #of elements in a static array */
+#ifndef NELEM
+# define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
+#endif
+
+/*
+ * Make a copy of the string, using "new[]" instead of "malloc". Free the
+ * string with delete[].
+ *
+ * Returns NULL if "str" is NULL.
+ */
+char* strdupNew(const char* str);
+
+/*
+ * Concatenate an argument vector into a single string. If argc is >= 0
+ * it will be used; if it's < 0 then the last element in the arg vector
+ * must be NULL.
+ *
+ * This inserts a space between each argument.
+ *
+ * This does not automatically add double quotes around arguments with
+ * spaces in them. This practice is necessary for Win32, because Win32's
+ * CreateProcess call is stupid.
+ *
+ * The caller should delete[] the returned string.
+ */
+char* concatArgv(int argc, const char* const argv[]);
+
+/*
+ * Count up the number of arguments in "argv". The count does not include
+ * the final NULL entry.
+ */
+int countArgv(const char* const argv[]);
+
+/*
+ * Some utility functions for working with files. These could be made
+ * part of a "File" class.
+ */
+typedef enum FileType {
+ kFileTypeUnknown = 0,
+ kFileTypeNonexistent, // i.e. ENOENT
+ kFileTypeRegular,
+ kFileTypeDirectory,
+ kFileTypeCharDev,
+ kFileTypeBlockDev,
+ kFileTypeFifo,
+ kFileTypeSymlink,
+ kFileTypeSocket,
+} FileType;
+/* get the file's type; follows symlinks */
+FileType getFileType(const char* fileName);
+/* get the file's modification date; returns -1 w/errno set on failure */
+time_t getFileModDate(const char* fileName);
+
+/*
+ * Round up to the nearest power of 2. Handy for hash tables.
+ */
+unsigned int roundUpPower2(unsigned int val);
+
+void strreverse(char* begin, char* end);
+void k_itoa(int value, char* str, int base);
+char* itoa(int val, int base);
+
+}; // namespace android
+
+#endif // _LIBS_UTILS_MISC_H
diff --git a/include/utils/ported.h b/include/utils/ported.h
new file mode 100644
index 0000000..eb3be01
--- /dev/null
+++ b/include/utils/ported.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Standard functions ported to the current platform. Note these are NOT
+// in the "android" namespace.
+//
+#ifndef _LIBS_UTILS_PORTED_H
+#define _LIBS_UTILS_PORTED_H
+
+#include <sys/time.h> // for timeval
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* library replacement functions */
+#if defined(NEED_GETTIMEOFDAY)
+int gettimeofday(struct timeval* tv, struct timezone* tz);
+#endif
+#if defined(NEED_USLEEP)
+void usleep(unsigned long usec);
+#endif
+#if defined(NEED_PIPE)
+int pipe(int filedes[2]);
+#endif
+#if defined(NEED_SETENV)
+int setenv(const char* name, const char* value, int overwrite);
+void unsetenv(const char* name);
+char* getenv(const char* name);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _LIBS_UTILS_PORTED_H
diff --git a/include/utils/string_array.h b/include/utils/string_array.h
new file mode 100644
index 0000000..ede0644
--- /dev/null
+++ b/include/utils/string_array.h
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2005 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//
+// Sortable array of strings. STL-ish, but STL-free.
+//
+#ifndef _LIBS_UTILS_STRING_ARRAY_H
+#define _LIBS_UTILS_STRING_ARRAY_H
+
+#include <stdlib.h>
+#include <string.h>
+
+namespace android {
+
+//
+// An expanding array of strings. Add, get, sort, delete.
+//
+class StringArray {
+public:
+ StringArray()
+ : mMax(0), mCurrent(0), mArray(NULL)
+ {}
+ virtual ~StringArray() {
+ for (int i = 0; i < mCurrent; i++)
+ delete[] mArray[i];
+ delete[] mArray;
+ }
+
+ //
+ // Add a string. A copy of the string is made.
+ //
+ bool push_back(const char* str) {
+ if (mCurrent >= mMax) {
+ char** tmp;
+
+ if (mMax == 0)
+ mMax = 16; // initial storage
+ else
+ mMax *= 2;
+
+ tmp = new char*[mMax];
+ if (tmp == NULL)
+ return false;
+
+ memcpy(tmp, mArray, mCurrent * sizeof(char*));
+ delete[] mArray;
+ mArray = tmp;
+ }
+
+ int len = strlen(str);
+ mArray[mCurrent] = new char[len+1];
+ memcpy(mArray[mCurrent], str, len+1);
+ mCurrent++;
+
+ return true;
+ }
+
+ //
+ // Delete an entry.
+ //
+ void erase(int idx) {
+ if (idx < 0 || idx >= mCurrent)
+ return;
+ delete[] mArray[idx];
+ if (idx < mCurrent-1) {
+ memmove(&mArray[idx], &mArray[idx+1],
+ (mCurrent-1 - idx) * sizeof(char*));
+ }
+ mCurrent--;
+ }
+
+ //
+ // Sort the array.
+ //
+ void sort(int (*compare)(const void*, const void*)) {
+ qsort(mArray, mCurrent, sizeof(char*), compare);
+ }
+
+ //
+ // Pass this to the sort routine to do an ascending alphabetical sort.
+ //
+ static int cmpAscendingAlpha(const void* pstr1, const void* pstr2) {
+ return strcmp(*(const char**)pstr1, *(const char**)pstr2);
+ }
+
+ //
+ // Get the #of items in the array.
+ //
+ inline int size(void) const { return mCurrent; }
+
+ //
+ // Return entry N.
+ // [should use operator[] here]
+ //
+ const char* getEntry(int idx) const {
+ if (idx < 0 || idx >= mCurrent)
+ return NULL;
+ return mArray[idx];
+ }
+
+private:
+ int mMax;
+ int mCurrent;
+ char** mArray;
+};
+
+}; // namespace android
+
+#endif // _LIBS_UTILS_STRING_ARRAY_H
diff --git a/include/utils/threads.h b/include/utils/threads.h
new file mode 100644
index 0000000..7dca810
--- /dev/null
+++ b/include/utils/threads.h
@@ -0,0 +1,347 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LIBS_UTILS_THREADS_H
+#define _LIBS_UTILS_THREADS_H
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <time.h>
+
+// ------------------------------------------------------------------
+// C API
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void* android_thread_id_t;
+
+typedef int (*android_thread_func_t)(void*);
+
+enum {
+ /*
+ * ***********************************************
+ * ** Keep in sync with android.os.Process.java **
+ * ***********************************************
+ *
+ * This maps directly to the "nice" priorites we use in Android.
+ * A thread priority should be chosen inverse-proportinally to
+ * the amount of work the thread is expected to do. The more work
+ * a thread will do, the less favorable priority it should get so that
+ * it doesn't starve the system. Threads not behaving properly might
+ * be "punished" by the kernel.
+ * Use the levels below when appropriate. Intermediate values are
+ * acceptable, preferably use the {MORE|LESS}_FAVORABLE constants below.
+ */
+ ANDROID_PRIORITY_LOWEST = 19,
+
+ /* use for background tasks */
+ ANDROID_PRIORITY_BACKGROUND = 10,
+
+ /* most threads run at normal priority */
+ ANDROID_PRIORITY_NORMAL = 0,
+
+ /* threads currently running a UI that the user is interacting with */
+ ANDROID_PRIORITY_FOREGROUND = -2,
+
+ /* the main UI thread has a slightly more favorable priority */
+ ANDROID_PRIORITY_DISPLAY = -4,
+
+ /* ui service treads might want to run at a urgent display (uncommon) */
+ ANDROID_PRIORITY_URGENT_DISPLAY = -8,
+
+ /* all normal audio threads */
+ ANDROID_PRIORITY_AUDIO = -16,
+
+ /* service audio threads (uncommon) */
+ ANDROID_PRIORITY_URGENT_AUDIO = -19,
+
+ /* should never be used in practice. regular process might not
+ * be allowed to use this level */
+ ANDROID_PRIORITY_HIGHEST = -20,
+
+ ANDROID_PRIORITY_DEFAULT = ANDROID_PRIORITY_NORMAL,
+ ANDROID_PRIORITY_MORE_FAVORABLE = -1,
+ ANDROID_PRIORITY_LESS_FAVORABLE = +1,
+};
+
+// Create and run a new thread.
+extern int androidCreateThread(android_thread_func_t, void *);
+
+// Create thread with lots of parameters
+extern int androidCreateThreadEtc(android_thread_func_t entryFunction,
+ void *userData,
+ const char* threadName,
+ int32_t threadPriority,
+ size_t threadStackSize,
+ android_thread_id_t *threadId);
+
+// Get some sort of unique identifier for the current thread.
+extern android_thread_id_t androidGetThreadId();
+
+// Low-level thread creation -- never creates threads that can
+// interact with the Java VM.
+extern int androidCreateRawThreadEtc(android_thread_func_t entryFunction,
+ void *userData,
+ const char* threadName,
+ int32_t threadPriority,
+ size_t threadStackSize,
+ android_thread_id_t *threadId);
+
+// Used by the Java Runtime to control how threads are created, so that
+// they can be proper and lovely Java threads.
+typedef int (*android_create_thread_fn)(android_thread_func_t entryFunction,
+ void *userData,
+ const char* threadName,
+ int32_t threadPriority,
+ size_t threadStackSize,
+ android_thread_id_t *threadId);
+
+extern void androidSetCreateThreadFunc(android_create_thread_fn func);
+
+#ifdef __cplusplus
+}
+#endif
+
+// ------------------------------------------------------------------
+// C++ API
+
+#ifdef __cplusplus
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+#include <utils/Timers.h>
+
+namespace android {
+
+typedef android_thread_id_t thread_id_t;
+
+typedef android_thread_func_t thread_func_t;
+
+enum {
+ PRIORITY_LOWEST = ANDROID_PRIORITY_LOWEST,
+ PRIORITY_BACKGROUND = ANDROID_PRIORITY_BACKGROUND,
+ PRIORITY_NORMAL = ANDROID_PRIORITY_NORMAL,
+ PRIORITY_FOREGROUND = ANDROID_PRIORITY_FOREGROUND,
+ PRIORITY_DISPLAY = ANDROID_PRIORITY_DISPLAY,
+ PRIORITY_URGENT_DISPLAY = ANDROID_PRIORITY_URGENT_DISPLAY,
+ PRIORITY_AUDIO = ANDROID_PRIORITY_AUDIO,
+ PRIORITY_URGENT_AUDIO = ANDROID_PRIORITY_URGENT_AUDIO,
+ PRIORITY_HIGHEST = ANDROID_PRIORITY_HIGHEST,
+ PRIORITY_DEFAULT = ANDROID_PRIORITY_DEFAULT,
+ PRIORITY_MORE_FAVORABLE = ANDROID_PRIORITY_MORE_FAVORABLE,
+ PRIORITY_LESS_FAVORABLE = ANDROID_PRIORITY_LESS_FAVORABLE,
+};
+
+// Create and run a new thread.
+inline bool createThread(thread_func_t f, void *a) {
+ return androidCreateThread(f, a) ? true : false;
+}
+
+// Create thread with lots of parameters
+inline bool createThreadEtc(thread_func_t entryFunction,
+ void *userData,
+ const char* threadName = "android:unnamed_thread",
+ int32_t threadPriority = PRIORITY_DEFAULT,
+ size_t threadStackSize = 0,
+ thread_id_t *threadId = 0)
+{
+ return androidCreateThreadEtc(entryFunction, userData, threadName,
+ threadPriority, threadStackSize, threadId) ? true : false;
+}
+
+// Get some sort of unique identifier for the current thread.
+inline thread_id_t getThreadId() {
+ return androidGetThreadId();
+}
+
+/*
+ * Simple mutex class. The implementation is system-dependent.
+ *
+ * The mutex must be unlocked by the thread that locked it. They are not
+ * recursive, i.e. the same thread can't lock it multiple times.
+ */
+class Mutex {
+public:
+ Mutex();
+ Mutex(const char* name);
+ ~Mutex();
+
+ // lock or unlock the mutex
+ status_t lock();
+ void unlock();
+
+ // lock if possible; returns 0 on success, error otherwise
+ status_t tryLock();
+
+ // Manages the mutex automatically. It'll be locked when Autolock is
+ // constructed and released when Autolock goes out of scope.
+ class Autolock {
+ public:
+ inline Autolock(Mutex& mutex) : mpMutex(&mutex) { mutex.lock(); }
+ inline Autolock(Mutex* mutex) : mpMutex(mutex) { mutex->lock(); }
+ inline ~Autolock() { mpMutex->unlock(); }
+ private:
+ Mutex* mpMutex;
+ };
+
+private:
+ friend class Condition;
+
+ // A mutex cannot be copied
+ Mutex(const Mutex&);
+ Mutex& operator = (const Mutex&);
+ void _init();
+
+ void* mState;
+};
+
+/*
+ * Automatic mutex. Declare one of these at the top of a function.
+ * When the function returns, it will go out of scope, and release the
+ * mutex.
+ */
+
+typedef Mutex::Autolock AutoMutex;
+
+
+/*
+ * Condition variable class. The implementation is system-dependent.
+ *
+ * Condition variables are paired up with mutexes. Lock the mutex,
+ * call wait(), then either re-wait() if things aren't quite what you want,
+ * or unlock the mutex and continue. All threads calling wait() must
+ * use the same mutex for a given Condition.
+ */
+class Condition {
+public:
+ Condition();
+ ~Condition();
+ // Wait on the condition variable. Lock the mutex before calling.
+ status_t wait(Mutex& mutex);
+ // Wait on the condition variable until the given time. Lock the mutex
+ // before calling.
+ status_t wait(Mutex& mutex, nsecs_t abstime);
+ // same with relative timeout
+ status_t waitRelative(Mutex& mutex, nsecs_t reltime);
+ // Signal the condition variable, allowing one thread to continue.
+ void signal();
+ // Signal the condition variable, allowing all threads to continue.
+ void broadcast();
+
+private:
+ void* mState;
+};
+
+
+/*
+ * Read/write lock. The resource can have multiple readers or one writer,
+ * but can't be read and written at the same time.
+ *
+ * The same thread should not call a lock function while it already has
+ * a lock. (Should be okay for multiple readers.)
+ */
+class ReadWriteLock {
+public:
+ ReadWriteLock()
+ : mNumReaders(0), mNumWriters(0)
+ {}
+ ~ReadWriteLock() {}
+
+ void lockForRead();
+ bool tryLockForRead();
+ void unlockForRead();
+
+ void lockForWrite();
+ bool tryLockForWrite();
+ void unlockForWrite();
+
+private:
+ int mNumReaders;
+ int mNumWriters;
+
+ Mutex mLock;
+ Condition mReadWaiter;
+ Condition mWriteWaiter;
+#if defined(PRINT_RENDER_TIMES)
+ DurationTimer mDebugTimer;
+#endif
+};
+
+
+/*
+ * This is our spiffy thread object!
+ */
+
+class Thread : virtual public RefBase
+{
+public:
+ // Create a Thread object, but doesn't create or start the associated
+ // thread. See the run() method.
+ Thread(bool canCallJava = true);
+ virtual ~Thread();
+
+ // Start the thread in threadLoop() which needs to be implemented.
+ virtual status_t run( const char* name = 0,
+ int32_t priority = PRIORITY_DEFAULT,
+ size_t stack = 0);
+
+ // Ask this object's thread to exit. This function is asynchronous, when the
+ // function returns the thread might still be running. Of course, this
+ // function can be called from a different thread.
+ virtual void requestExit();
+
+ // Good place to do one-time initializations
+ virtual status_t readyToRun();
+
+ // Call requestExit() and wait until this object's thread exits.
+ // BE VERY CAREFUL of deadlocks. In particular, it would be silly to call
+ // this function from this object's thread. Will return WOULD_BLOCK in
+ // that case.
+ status_t requestExitAndWait();
+
+protected:
+ // exitPending() returns true if requestExit() has been called.
+ bool exitPending() const;
+
+private:
+ // Derived class must implemtent threadLoop(). The thread starts its life
+ // here. There are two ways of using the Thread object:
+ // 1) loop: if threadLoop() returns true, it will be called again if
+ // requestExit() wasn't called.
+ // 2) once: if threadLoop() returns false, the thread will exit upon return.
+ virtual bool threadLoop() = 0;
+
+private:
+ Thread& operator=(const Thread&);
+ static int _threadLoop(void* user);
+ const bool mCanCallJava;
+ thread_id_t mThread;
+ Mutex mLock;
+ Condition mThreadExitedCondition;
+ status_t mStatus;
+ volatile bool mExitPending;
+ volatile bool mRunning;
+ sp<Thread> mHoldSelf;
+};
+
+
+}; // namespace android
+
+#endif // __cplusplus
+
+#endif // _LIBS_UTILS_THREADS_H