diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/cutils/klog.h | 2 | ||||
-rw-r--r-- | include/cutils/list.h | 24 | ||||
-rw-r--r-- | include/log/log.h | 23 | ||||
-rw-r--r-- | include/log/log_read.h | 79 | ||||
-rw-r--r-- | include/log/logger.h | 131 | ||||
-rw-r--r-- | include/log/uio.h | 6 | ||||
-rw-r--r-- | include/private/android_filesystem_config.h | 2 | ||||
-rw-r--r-- | include/system/audio.h | 47 | ||||
-rw-r--r-- | include/utils/LruCache.h | 2 | ||||
-rw-r--r-- | include/utils/UniquePtr.h | 239 |
10 files changed, 271 insertions, 284 deletions
diff --git a/include/cutils/klog.h b/include/cutils/klog.h index ba728ac..3953904 100644 --- a/include/cutils/klog.h +++ b/include/cutils/klog.h @@ -23,7 +23,7 @@ __BEGIN_DECLS void klog_init(void); void klog_set_level(int level); -void klog_close(void); +/* TODO: void klog_close(void); - and make klog_fd users thread safe. */ void klog_write(int level, const char *fmt, ...) __attribute__ ((format(printf, 2, 3))); diff --git a/include/cutils/list.h b/include/cutils/list.h index 72395f4..945729a 100644 --- a/include/cutils/list.h +++ b/include/cutils/list.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 The Android Open Source Project + * Copyright (C) 2008-2013 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. @@ -49,9 +49,25 @@ struct listnode node != (list); \ node = next, next = node->next) -void list_init(struct listnode *list); -void list_add_tail(struct listnode *list, struct listnode *item); -void list_remove(struct listnode *item); +static inline void list_init(struct listnode *node) +{ + node->next = node; + node->prev = node; +} + +static inline void list_add_tail(struct listnode *head, struct listnode *item) +{ + item->next = head; + item->prev = head->prev; + head->prev->next = item; + head->prev = item; +} + +static inline void list_remove(struct listnode *item) +{ + item->next->prev = item->prev; + item->prev->next = item->next; +} #define list_empty(list) ((list) == (list)->next) #define list_head(list) ((list)->next) diff --git a/include/log/log.h b/include/log/log.h index 7faddea..7f952ff 100644 --- a/include/log/log.h +++ b/include/log/log.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005 The Android Open Source Project + * Copyright (C) 2005-2014 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. @@ -28,17 +28,16 @@ #ifndef _LIBS_LOG_LOG_H #define _LIBS_LOG_LOG_H -#include <stdio.h> -#include <time.h> #include <sys/types.h> -#include <unistd.h> #ifdef HAVE_PTHREADS #include <pthread.h> #endif #include <stdarg.h> - -#include <log/uio.h> +#include <stdio.h> +#include <time.h> +#include <unistd.h> #include <log/logd.h> +#include <log/uio.h> #ifdef __cplusplus extern "C" { @@ -470,7 +469,8 @@ typedef enum { EVENT_TYPE_STRING = 2, EVENT_TYPE_LIST = 3, } AndroidEventLogType; - +#define sizeof_AndroidEventLogType sizeof(typeof_AndroidEventLogType) +#define typeof_AndroidEventLogType unsigned char #ifndef LOG_EVENT_INT #define LOG_EVENT_INT(_tag, _value) { \ @@ -540,7 +540,9 @@ typedef enum { #define android_logToFile(tag, file) (0) #define android_logToFd(tag, fd) (0) -typedef enum { +typedef enum log_id { + LOG_ID_MIN = 0, + LOG_ID_MAIN = 0, LOG_ID_RADIO = 1, LOG_ID_EVENTS = 2, @@ -548,6 +550,8 @@ typedef enum { LOG_ID_MAX } log_id_t; +#define sizeof_log_id_t sizeof(typeof_log_id_t) +#define typeof_log_id_t unsigned char /* * Send a simple string to the log. @@ -555,9 +559,8 @@ typedef enum { int __android_log_buf_write(int bufID, int prio, const char *tag, const char *text); int __android_log_buf_print(int bufID, int prio, const char *tag, const char *fmt, ...); - #ifdef __cplusplus } #endif -#endif // _LIBS_CUTILS_LOG_H +#endif /* _LIBS_LOG_LOG_H */ diff --git a/include/log/log_read.h b/include/log/log_read.h new file mode 100644 index 0000000..861c192 --- /dev/null +++ b/include/log/log_read.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2013-2014 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_LOG_LOG_READ_H +#define _LIBS_LOG_LOG_READ_H + +#include <time.h> + +#define NS_PER_SEC 1000000000ULL +#ifdef __cplusplus +struct log_time : public timespec { +public: + log_time(timespec &T) + { + tv_sec = T.tv_sec; + tv_nsec = T.tv_nsec; + } + log_time(void) + { + } + log_time(clockid_t id) + { + clock_gettime(id, (timespec *) this); + } + log_time(const char *T) + { + const uint8_t *c = (const uint8_t *) T; + tv_sec = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24); + tv_nsec = c[4] | (c[5] << 8) | (c[6] << 16) | (c[7] << 24); + } + bool operator== (const timespec &T) const + { + return (tv_sec == T.tv_sec) && (tv_nsec == T.tv_nsec); + } + bool operator!= (const timespec &T) const + { + return !(*this == T); + } + bool operator< (const timespec &T) const + { + return (tv_sec < T.tv_sec) + || ((tv_sec == T.tv_sec) && (tv_nsec < T.tv_nsec)); + } + bool operator>= (const timespec &T) const + { + return !(*this < T); + } + bool operator> (const timespec &T) const + { + return (tv_sec > T.tv_sec) + || ((tv_sec == T.tv_sec) && (tv_nsec > T.tv_nsec)); + } + bool operator<= (const timespec &T) const + { + return !(*this > T); + } + uint64_t nsec(void) const + { + return static_cast<uint64_t>(tv_sec) * NS_PER_SEC + tv_nsec; + } +}; +#else +typedef struct timespec log_time; +#endif + +#endif /* define _LIBS_LOG_LOG_READ_H */ diff --git a/include/log/logger.h b/include/log/logger.h index 04f3fb0..966397a 100644 --- a/include/log/logger.h +++ b/include/log/logger.h @@ -1,16 +1,21 @@ -/* utils/logger.h -** -** Copyright 2007, The Android Open Source Project +/* +** +** Copyright 2007-2014, 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 +#ifndef _LIBS_LOG_LOGGER_H +#define _LIBS_LOG_LOGGER_H #include <stdint.h> +#include <log/log.h> + +#ifdef __cplusplus +extern "C" { +#endif /* * The userspace structure for version 1 of the logger_entry ABI. @@ -43,11 +48,6 @@ struct logger_entry_v2 { 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_LOG_SYSTEM "log/system" - /* * The maximum size of the log entry payload that can be * written to the kernel logger driver. An attempt to write @@ -63,19 +63,108 @@ struct logger_entry_v2 { */ #define LOGGER_ENTRY_MAX_LEN (5*1024) -#ifdef HAVE_IOCTL +#define NS_PER_SEC 1000000000ULL + +struct log_msg { + union { + unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1]; + struct logger_entry_v2 entry; + struct logger_entry_v2 entry_v2; + struct logger_entry entry_v1; + struct { + unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1]; + log_id_t id; + } extra; + } __attribute__((aligned(4))); +#ifdef __cplusplus + /* Matching log_time operators */ + bool operator== (const log_msg &T) const + { + return (entry.sec == T.entry.sec) && (entry.nsec == T.entry.nsec); + } + bool operator!= (const log_msg &T) const + { + return !(*this == T); + } + bool operator< (const log_msg &T) const + { + return (entry.sec < T.entry.sec) + || ((entry.sec == T.entry.sec) + && (entry.nsec < T.entry.nsec)); + } + bool operator>= (const log_msg &T) const + { + return !(*this < T); + } + bool operator> (const log_msg &T) const + { + return (entry.sec > T.entry.sec) + || ((entry.sec == T.entry.sec) + && (entry.nsec > T.entry.nsec)); + } + bool operator<= (const log_msg &T) const + { + return !(*this > T); + } + uint64_t nsec(void) const + { + return static_cast<uint64_t>(entry.sec) * NS_PER_SEC + entry.nsec; + } + + /* packet methods */ + log_id_t id(void) + { + return extra.id; + } + char *msg(void) + { + return entry.hdr_size ? (char *) buf + entry.hdr_size : entry_v1.msg; + } + unsigned int len(void) + { + return (entry.hdr_size ? entry.hdr_size : sizeof(entry_v1)) + entry.len; + } +#endif +}; -#include <sys/ioctl.h> +struct logger; -#define __LOGGERIO 0xAE +log_id_t android_logger_get_id(struct logger *logger); -#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 */ -#define LOGGER_GET_VERSION _IO(__LOGGERIO, 5) /* abi version */ -#define LOGGER_SET_VERSION _IO(__LOGGERIO, 6) /* abi version */ +int android_logger_clear(struct logger *logger); +int android_logger_get_log_size(struct logger *logger); +int android_logger_get_log_readable_size(struct logger *logger); +int android_logger_get_log_version(struct logger *logger); + +struct logger_list; + +struct logger_list *android_logger_list_alloc(int mode, + unsigned int tail, + pid_t pid); +void android_logger_list_free(struct logger_list *logger_list); +/* In the purest sense, the following two are orthogonal interfaces */ +int android_logger_list_read(struct logger_list *logger_list, + struct log_msg *log_msg); + +/* Multiple log_id_t opens */ +struct logger *android_logger_open(struct logger_list *logger_list, + log_id_t id); +#define android_logger_close android_logger_free +/* Single log_id_t open */ +struct logger_list *android_logger_list_open(log_id_t id, + int mode, + unsigned int tail, + pid_t pid); +#define android_logger_list_close android_logger_list_free + +/* + * log_id_t helpers + */ +log_id_t android_name_to_log_id(const char *logName); +const char *android_log_id_to_name(log_id_t log_id); -#endif // HAVE_IOCTL +#ifdef __cplusplus +} +#endif -#endif /* _UTILS_LOGGER_H */ +#endif /* _LIBS_LOG_LOGGER_H */ diff --git a/include/log/uio.h b/include/log/uio.h index 01a74d2..a71f515 100644 --- a/include/log/uio.h +++ b/include/log/uio.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2007 The Android Open Source Project + * Copyright (C) 2007-2014 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. @@ -31,8 +31,8 @@ extern "C" { #include <stddef.h> struct iovec { - const void* iov_base; - size_t iov_len; + void* iov_base; + size_t iov_len; }; extern int readv( int fd, struct iovec* vecs, int count ); diff --git a/include/private/android_filesystem_config.h b/include/private/android_filesystem_config.h index 0ed0d78..e3568ae 100644 --- a/include/private/android_filesystem_config.h +++ b/include/private/android_filesystem_config.h @@ -247,6 +247,7 @@ static const struct fs_path_config android_files[] = { /* the following files have enhanced capabilities and ARE included in user builds. */ { 00750, AID_ROOT, AID_SHELL, (1 << CAP_SETUID) | (1 << CAP_SETGID), "system/bin/run-as" }, + { 00750, AID_ROOT, AID_ROOT, 0, "system/bin/uncrypt" }, { 00755, AID_ROOT, AID_SHELL, 0, "system/bin/*" }, { 00755, AID_ROOT, AID_ROOT, 0, "system/lib/valgrind/*" }, { 00755, AID_ROOT, AID_SHELL, 0, "system/xbin/*" }, @@ -255,7 +256,6 @@ static const struct fs_path_config android_files[] = { { 00750, AID_ROOT, AID_SHELL, 0, "sbin/*" }, { 00755, AID_ROOT, AID_ROOT, 0, "bin/*" }, { 00750, AID_ROOT, AID_SHELL, 0, "init*" }, - { 00750, AID_ROOT, AID_SHELL, 0, "charger*" }, { 00750, AID_ROOT, AID_SHELL, 0, "sbin/fs_mgr" }, { 00640, AID_ROOT, AID_SHELL, 0, "fstab.*" }, { 00644, AID_ROOT, AID_ROOT, 0, 0 }, diff --git a/include/system/audio.h b/include/system/audio.h index aa7ac02..2424baf 100644 --- a/include/system/audio.h +++ b/include/system/audio.h @@ -34,11 +34,17 @@ __BEGIN_DECLS /* device address used to refer to the standard remote submix */ #define AUDIO_REMOTE_SUBMIX_DEVICE_ADDRESS "0" +/* AudioFlinger and AudioPolicy services use I/O handles to identify audio sources and sinks */ typedef int audio_io_handle_t; +#define AUDIO_IO_HANDLE_NONE 0 /* Audio stream types */ typedef enum { + /* These values must kept in sync with + * frameworks/base/media/java/android/media/AudioSystem.java + */ AUDIO_STREAM_DEFAULT = -1, + AUDIO_STREAM_MIN = 0, AUDIO_STREAM_VOICE_CALL = 0, AUDIO_STREAM_SYSTEM = 1, AUDIO_STREAM_RING = 2, @@ -55,7 +61,9 @@ typedef enum { } audio_stream_type_t; /* Do not change these values without updating their counterparts - * in media/java/android/media/MediaRecorder.java! + * in frameworks/base/media/java/android/media/MediaRecorder.java, + * frameworks/av/services/audioflinger/AudioPolicyService.cpp, + * and system/media/audio_effects/include/audio_effects/audio_effects_conf.h! */ typedef enum { AUDIO_SOURCE_DEFAULT = 0, @@ -93,6 +101,13 @@ typedef enum { * (value must be 0) */ AUDIO_SESSION_OUTPUT_MIX = 0, + + /* application does not specify an explicit session ID to be used, + * and requests a new session ID to be allocated + * TODO use unique values for AUDIO_SESSION_OUTPUT_MIX and AUDIO_SESSION_ALLOCATE, + * after all uses have been updated from 0 to the appropriate symbol, and have been tested. + */ + AUDIO_SESSION_ALLOCATE = 0, } audio_session_t; /* Audio sub formats (see enum audio_format). */ @@ -103,8 +118,11 @@ typedef enum { AUDIO_FORMAT_PCM_SUB_8_BIT = 0x2, /* DO NOT CHANGE - PCM unsigned 8 bits */ AUDIO_FORMAT_PCM_SUB_32_BIT = 0x3, /* PCM signed .31 fixed point */ AUDIO_FORMAT_PCM_SUB_8_24_BIT = 0x4, /* PCM signed 7.24 fixed point */ + AUDIO_FORMAT_PCM_SUB_FLOAT = 0x5, /* PCM single-precision floating point */ } audio_format_pcm_sub_fmt_t; +/* The audio_format_*_sub_fmt_t declarations are not currently used */ + /* MP3 sub format field definition : can use 11 LSBs in the same way as MP3 * frame header to specify bit rate, stereo mode, version... */ @@ -129,7 +147,7 @@ typedef enum { AUDIO_FORMAT_VORBIS_SUB_NONE = 0x0, } audio_format_vorbis_sub_fmt_t; -/* Audio format consists in a main format field (upper 8 bits) and a sub format +/* Audio format consists of a main format field (upper 8 bits) and a sub format * field (lower 24 bits). * * The main format indicates the main codec type. The sub format field @@ -153,14 +171,18 @@ typedef enum { AUDIO_FORMAT_SUB_MASK = 0x00FFFFFFUL, /* Aliases */ + /* note != AudioFormat.ENCODING_PCM_16BIT */ AUDIO_FORMAT_PCM_16_BIT = (AUDIO_FORMAT_PCM | AUDIO_FORMAT_PCM_SUB_16_BIT), + /* note != AudioFormat.ENCODING_PCM_8BIT */ AUDIO_FORMAT_PCM_8_BIT = (AUDIO_FORMAT_PCM | AUDIO_FORMAT_PCM_SUB_8_BIT), AUDIO_FORMAT_PCM_32_BIT = (AUDIO_FORMAT_PCM | AUDIO_FORMAT_PCM_SUB_32_BIT), AUDIO_FORMAT_PCM_8_24_BIT = (AUDIO_FORMAT_PCM | AUDIO_FORMAT_PCM_SUB_8_24_BIT), + AUDIO_FORMAT_PCM_FLOAT = (AUDIO_FORMAT_PCM | + AUDIO_FORMAT_PCM_SUB_FLOAT), } audio_format_t; enum { @@ -266,6 +288,15 @@ enum { typedef uint32_t audio_channel_mask_t; +/* Expresses the convention when stereo audio samples are stored interleaved + * in an array. This should improve readability by allowing code to use + * symbolic indices instead of hard-coded [0] and [1]. + */ +enum { + AUDIO_INTERLEAVE_LEFT = 0, + AUDIO_INTERLEAVE_RIGHT = 1, +}; + typedef enum { AUDIO_MODE_INVALID = -2, AUDIO_MODE_CURRENT = -1, @@ -278,7 +309,9 @@ typedef enum { AUDIO_MODE_MAX = AUDIO_MODE_CNT - 1, } audio_mode_t; +/* This enum is deprecated */ typedef enum { + AUDIO_IN_ACOUSTICS_NONE = 0, AUDIO_IN_ACOUSTICS_AGC_ENABLE = 0x0001, AUDIO_IN_ACOUSTICS_AGC_DISABLE = 0, AUDIO_IN_ACOUSTICS_NS_ENABLE = 0x0002, @@ -304,9 +337,12 @@ enum { AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 0x100, AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER = 0x200, AUDIO_DEVICE_OUT_AUX_DIGITAL = 0x400, + /* uses an analog connection (multiplexed over the USB connector pins for instance) */ AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET = 0x800, AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET = 0x1000, + /* USB accessory mode: your Android device is a USB device and the dock is a USB host */ AUDIO_DEVICE_OUT_USB_ACCESSORY = 0x2000, + /* USB host mode: your Android device is a USB host and the dock is a USB device */ AUDIO_DEVICE_OUT_USB_DEVICE = 0x4000, AUDIO_DEVICE_OUT_REMOTE_SUBMIX = 0x8000, AUDIO_DEVICE_OUT_DEFAULT = AUDIO_DEVICE_BIT_DEFAULT, @@ -522,7 +558,7 @@ static inline bool audio_is_output_channel(audio_channel_mask_t channel) */ static inline audio_channel_mask_t audio_channel_out_mask_from_count(uint32_t channel_count) { - switch(channel_count) { + switch (channel_count) { case 1: return AUDIO_CHANNEL_OUT_MONO; case 2: @@ -562,7 +598,7 @@ static inline bool audio_is_valid_format(audio_format_t format) switch (format & AUDIO_FORMAT_MAIN_MASK) { case AUDIO_FORMAT_PCM: if (format != AUDIO_FORMAT_PCM_16_BIT && - format != AUDIO_FORMAT_PCM_8_BIT) { + format != AUDIO_FORMAT_PCM_8_BIT && format != AUDIO_FORMAT_PCM_FLOAT) { return false; } case AUDIO_FORMAT_MP3: @@ -598,6 +634,9 @@ static inline size_t audio_bytes_per_sample(audio_format_t format) case AUDIO_FORMAT_PCM_8_BIT: size = sizeof(uint8_t); break; + case AUDIO_FORMAT_PCM_FLOAT: + size = sizeof(float); + break; default: break; } diff --git a/include/utils/LruCache.h b/include/utils/LruCache.h index 053bfaf..fa8f03f 100644 --- a/include/utils/LruCache.h +++ b/include/utils/LruCache.h @@ -17,8 +17,8 @@ #ifndef ANDROID_UTILS_LRU_CACHE_H #define ANDROID_UTILS_LRU_CACHE_H +#include <UniquePtr.h> #include <utils/BasicHashtable.h> -#include <utils/UniquePtr.h> namespace android { diff --git a/include/utils/UniquePtr.h b/include/utils/UniquePtr.h deleted file mode 100644 index bc62fe6..0000000 --- a/include/utils/UniquePtr.h +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright (C) 2010 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. - */ - -/* === NOTE === NOTE === NOTE === NOTE === NOTE === NOTE === NOTE === NOTE === - * - * THIS IS A COPY OF libcore/include/UniquePtr.h AND AS SUCH THAT IS THE - * CANONICAL SOURCE OF THIS FILE. PLEASE KEEP THEM IN SYNC. - * - * === NOTE === NOTE === NOTE === NOTE === NOTE === NOTE === NOTE === NOTE === - */ - -#ifndef UNIQUE_PTR_H_included -#define UNIQUE_PTR_H_included - -#include <cstdlib> // For NULL. - -// Default deleter for pointer types. -template <typename T> -struct DefaultDelete { - enum { type_must_be_complete = sizeof(T) }; - DefaultDelete() {} - void operator()(T* p) const { - delete p; - } -}; - -// Default deleter for array types. -template <typename T> -struct DefaultDelete<T[]> { - enum { type_must_be_complete = sizeof(T) }; - void operator()(T* p) const { - delete[] p; - } -}; - -// A smart pointer that deletes the given pointer on destruction. -// Equivalent to C++0x's std::unique_ptr (a combination of boost::scoped_ptr -// and boost::scoped_array). -// Named to be in keeping with Android style but also to avoid -// collision with any other implementation, until we can switch over -// to unique_ptr. -// Use thus: -// UniquePtr<C> c(new C); -template <typename T, typename D = DefaultDelete<T> > -class UniquePtr { -public: - // Construct a new UniquePtr, taking ownership of the given raw pointer. - explicit UniquePtr(T* ptr = NULL) : mPtr(ptr) { - } - - ~UniquePtr() { - reset(); - } - - // Accessors. - T& operator*() const { return *mPtr; } - T* operator->() const { return mPtr; } - T* get() const { return mPtr; } - - // Returns the raw pointer and hands over ownership to the caller. - // The pointer will not be deleted by UniquePtr. - T* release() __attribute__((warn_unused_result)) { - T* result = mPtr; - mPtr = NULL; - return result; - } - - // Takes ownership of the given raw pointer. - // If this smart pointer previously owned a different raw pointer, that - // raw pointer will be freed. - void reset(T* ptr = NULL) { - if (ptr != mPtr) { - D()(mPtr); - mPtr = ptr; - } - } - -private: - // The raw pointer. - T* mPtr; - - // Comparing unique pointers is probably a mistake, since they're unique. - template <typename T2> bool operator==(const UniquePtr<T2>& p) const; - template <typename T2> bool operator!=(const UniquePtr<T2>& p) const; - - // Disallow copy and assignment. - UniquePtr(const UniquePtr&); - void operator=(const UniquePtr&); -}; - -// Partial specialization for array types. Like std::unique_ptr, this removes -// operator* and operator-> but adds operator[]. -template <typename T, typename D> -class UniquePtr<T[], D> { -public: - explicit UniquePtr(T* ptr = NULL) : mPtr(ptr) { - } - - ~UniquePtr() { - reset(); - } - - T& operator[](size_t i) const { - return mPtr[i]; - } - T* get() const { return mPtr; } - - T* release() __attribute__((warn_unused_result)) { - T* result = mPtr; - mPtr = NULL; - return result; - } - - void reset(T* ptr = NULL) { - if (ptr != mPtr) { - D()(mPtr); - mPtr = ptr; - } - } - -private: - T* mPtr; - - // Disallow copy and assignment. - UniquePtr(const UniquePtr&); - void operator=(const UniquePtr&); -}; - -#if UNIQUE_PTR_TESTS - -// Run these tests with: -// g++ -g -DUNIQUE_PTR_TESTS -x c++ UniquePtr.h && ./a.out - -#include <stdio.h> - -static void assert(bool b) { - if (!b) { - fprintf(stderr, "FAIL\n"); - abort(); - } - fprintf(stderr, "OK\n"); -} -static int cCount = 0; -struct C { - C() { ++cCount; } - ~C() { --cCount; } -}; -static bool freed = false; -struct Freer { - void operator()(int* p) { - assert(*p == 123); - free(p); - freed = true; - } -}; - -int main(int argc, char* argv[]) { - // - // UniquePtr<T> tests... - // - - // Can we free a single object? - { - UniquePtr<C> c(new C); - assert(cCount == 1); - } - assert(cCount == 0); - // Does release work? - C* rawC; - { - UniquePtr<C> c(new C); - assert(cCount == 1); - rawC = c.release(); - } - assert(cCount == 1); - delete rawC; - // Does reset work? - { - UniquePtr<C> c(new C); - assert(cCount == 1); - c.reset(new C); - assert(cCount == 1); - } - assert(cCount == 0); - - // - // UniquePtr<T[]> tests... - // - - // Can we free an array? - { - UniquePtr<C[]> cs(new C[4]); - assert(cCount == 4); - } - assert(cCount == 0); - // Does release work? - { - UniquePtr<C[]> c(new C[4]); - assert(cCount == 4); - rawC = c.release(); - } - assert(cCount == 4); - delete[] rawC; - // Does reset work? - { - UniquePtr<C[]> c(new C[4]); - assert(cCount == 4); - c.reset(new C[2]); - assert(cCount == 2); - } - assert(cCount == 0); - - // - // Custom deleter tests... - // - assert(!freed); - { - UniquePtr<int, Freer> i(reinterpret_cast<int*>(malloc(sizeof(int)))); - *i = 123; - } - assert(freed); - return 0; -} -#endif - -#endif // UNIQUE_PTR_H_included |