Tue, 06 Jan 2015 21:39:09 +0100
Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
michael@0 | 3 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 4 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 5 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 6 | |
michael@0 | 7 | /* Implements a UTF-16 character type. */ |
michael@0 | 8 | |
michael@0 | 9 | #ifndef mozilla_Char16_h |
michael@0 | 10 | #define mozilla_Char16_h |
michael@0 | 11 | |
michael@0 | 12 | #ifdef __cplusplus |
michael@0 | 13 | |
michael@0 | 14 | /* |
michael@0 | 15 | * C++11 introduces a char16_t type and support for UTF-16 string and character |
michael@0 | 16 | * literals. C++11's char16_t is a distinct builtin type. Technically, char16_t |
michael@0 | 17 | * is a 16-bit code unit of a Unicode code point, not a "character". |
michael@0 | 18 | */ |
michael@0 | 19 | |
michael@0 | 20 | #ifdef _MSC_VER |
michael@0 | 21 | /* |
michael@0 | 22 | * C++11 says char16_t is a distinct builtin type, but Windows's yvals.h |
michael@0 | 23 | * typedefs char16_t as an unsigned short. We would like to alias char16_t |
michael@0 | 24 | * to Windows's 16-bit wchar_t so we can declare UTF-16 literals as constant |
michael@0 | 25 | * expressions (and pass char16_t pointers to Windows APIs). We #define |
michael@0 | 26 | * _CHAR16T here in order to prevent yvals.h from overriding our char16_t |
michael@0 | 27 | * typedefs, which we set to wchar_t for C++ code. |
michael@0 | 28 | * |
michael@0 | 29 | * In addition, #defining _CHAR16T will prevent yvals.h from defining a |
michael@0 | 30 | * char32_t type, so we have to undo that damage here and provide our own, |
michael@0 | 31 | * which is identical to the yvals.h type. |
michael@0 | 32 | */ |
michael@0 | 33 | # define MOZ_UTF16_HELPER(s) L##s |
michael@0 | 34 | # define _CHAR16T |
michael@0 | 35 | typedef wchar_t char16_t; |
michael@0 | 36 | typedef unsigned int char32_t; |
michael@0 | 37 | #else |
michael@0 | 38 | /* C++11 has a builtin char16_t type. */ |
michael@0 | 39 | # define MOZ_UTF16_HELPER(s) u##s |
michael@0 | 40 | /** |
michael@0 | 41 | * This macro is used to distinguish when char16_t would be a distinct |
michael@0 | 42 | * typedef from wchar_t. |
michael@0 | 43 | */ |
michael@0 | 44 | # define MOZ_CHAR16_IS_NOT_WCHAR |
michael@0 | 45 | # ifdef WIN32 |
michael@0 | 46 | # define MOZ_USE_CHAR16_WRAPPER |
michael@0 | 47 | # endif |
michael@0 | 48 | #endif |
michael@0 | 49 | |
michael@0 | 50 | #ifdef MOZ_USE_CHAR16_WRAPPER |
michael@0 | 51 | # include <string> |
michael@0 | 52 | /** |
michael@0 | 53 | * Win32 API extensively uses wchar_t, which is represented by a separated |
michael@0 | 54 | * builtin type than char16_t per spec. It's not the case for MSVC, but GCC |
michael@0 | 55 | * follows the spec. We want to mix wchar_t and char16_t on Windows builds. |
michael@0 | 56 | * This class is supposed to make it easier. It stores char16_t const pointer, |
michael@0 | 57 | * but provides implicit casts for wchar_t as well. On other platforms, we |
michael@0 | 58 | * simply use |typedef const char16_t* char16ptr_t|. Here, we want to make |
michael@0 | 59 | * the class as similar to this typedef, including providing some casts that |
michael@0 | 60 | * are allowed by the typedef. |
michael@0 | 61 | */ |
michael@0 | 62 | class char16ptr_t |
michael@0 | 63 | { |
michael@0 | 64 | private: |
michael@0 | 65 | const char16_t* ptr; |
michael@0 | 66 | static_assert(sizeof(char16_t) == sizeof(wchar_t), "char16_t and wchar_t sizes differ"); |
michael@0 | 67 | |
michael@0 | 68 | public: |
michael@0 | 69 | char16ptr_t(const char16_t* p) : ptr(p) {} |
michael@0 | 70 | char16ptr_t(const wchar_t* p) : ptr(reinterpret_cast<const char16_t*>(p)) {} |
michael@0 | 71 | |
michael@0 | 72 | /* Without this, nullptr assignment would be ambiguous. */ |
michael@0 | 73 | constexpr char16ptr_t(decltype(nullptr)) : ptr(nullptr) {} |
michael@0 | 74 | |
michael@0 | 75 | operator const char16_t*() const { |
michael@0 | 76 | return ptr; |
michael@0 | 77 | } |
michael@0 | 78 | operator const wchar_t*() const { |
michael@0 | 79 | return reinterpret_cast<const wchar_t*>(ptr); |
michael@0 | 80 | } |
michael@0 | 81 | operator const void*() const { |
michael@0 | 82 | return ptr; |
michael@0 | 83 | } |
michael@0 | 84 | operator bool() const { |
michael@0 | 85 | return ptr != nullptr; |
michael@0 | 86 | } |
michael@0 | 87 | operator std::wstring() const { |
michael@0 | 88 | return std::wstring(static_cast<const wchar_t*>(*this)); |
michael@0 | 89 | } |
michael@0 | 90 | |
michael@0 | 91 | /* Explicit cast operators to allow things like (char16_t*)str. */ |
michael@0 | 92 | explicit operator char16_t*() const { |
michael@0 | 93 | return const_cast<char16_t*>(ptr); |
michael@0 | 94 | } |
michael@0 | 95 | explicit operator wchar_t*() const { |
michael@0 | 96 | return const_cast<wchar_t*>(static_cast<const wchar_t*>(*this)); |
michael@0 | 97 | } |
michael@0 | 98 | explicit operator int() const { |
michael@0 | 99 | return reinterpret_cast<intptr_t>(ptr); |
michael@0 | 100 | } |
michael@0 | 101 | explicit operator unsigned int() const { |
michael@0 | 102 | return reinterpret_cast<uintptr_t>(ptr); |
michael@0 | 103 | } |
michael@0 | 104 | explicit operator long() const { |
michael@0 | 105 | return reinterpret_cast<intptr_t>(ptr); |
michael@0 | 106 | } |
michael@0 | 107 | explicit operator unsigned long() const { |
michael@0 | 108 | return reinterpret_cast<uintptr_t>(ptr); |
michael@0 | 109 | } |
michael@0 | 110 | explicit operator long long() const { |
michael@0 | 111 | return reinterpret_cast<intptr_t>(ptr); |
michael@0 | 112 | } |
michael@0 | 113 | explicit operator unsigned long long() const { |
michael@0 | 114 | return reinterpret_cast<uintptr_t>(ptr); |
michael@0 | 115 | } |
michael@0 | 116 | |
michael@0 | 117 | /** |
michael@0 | 118 | * Some Windows API calls accept BYTE* but require that data actually be WCHAR*. |
michael@0 | 119 | * Supporting this requires explicit operators to support the requisite explicit |
michael@0 | 120 | * casts. |
michael@0 | 121 | */ |
michael@0 | 122 | explicit operator const char*() const { |
michael@0 | 123 | return reinterpret_cast<const char*>(ptr); |
michael@0 | 124 | } |
michael@0 | 125 | explicit operator const unsigned char*() const { |
michael@0 | 126 | return reinterpret_cast<const unsigned char*>(ptr); |
michael@0 | 127 | } |
michael@0 | 128 | explicit operator unsigned char*() const { |
michael@0 | 129 | return const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>(ptr)); |
michael@0 | 130 | } |
michael@0 | 131 | explicit operator void*() const { |
michael@0 | 132 | return const_cast<char16_t*>(ptr); |
michael@0 | 133 | } |
michael@0 | 134 | |
michael@0 | 135 | /* Some operators used on pointers. */ |
michael@0 | 136 | char16_t operator[](size_t i) const { |
michael@0 | 137 | return ptr[i]; |
michael@0 | 138 | } |
michael@0 | 139 | bool operator==(const char16ptr_t &x) const { |
michael@0 | 140 | return ptr == x.ptr; |
michael@0 | 141 | } |
michael@0 | 142 | bool operator==(decltype(nullptr)) const { |
michael@0 | 143 | return ptr == nullptr; |
michael@0 | 144 | } |
michael@0 | 145 | bool operator!=(const char16ptr_t &x) const { |
michael@0 | 146 | return ptr != x.ptr; |
michael@0 | 147 | } |
michael@0 | 148 | bool operator!=(decltype(nullptr)) const { |
michael@0 | 149 | return ptr != nullptr; |
michael@0 | 150 | } |
michael@0 | 151 | char16ptr_t operator+(int aValue) const { |
michael@0 | 152 | return char16ptr_t(ptr + aValue); |
michael@0 | 153 | } |
michael@0 | 154 | char16ptr_t operator+(unsigned int aValue) const { |
michael@0 | 155 | return char16ptr_t(ptr + aValue); |
michael@0 | 156 | } |
michael@0 | 157 | char16ptr_t operator+(long aValue) const { |
michael@0 | 158 | return char16ptr_t(ptr + aValue); |
michael@0 | 159 | } |
michael@0 | 160 | char16ptr_t operator+(unsigned long aValue) const { |
michael@0 | 161 | return char16ptr_t(ptr + aValue); |
michael@0 | 162 | } |
michael@0 | 163 | char16ptr_t operator+(long long aValue) const { |
michael@0 | 164 | return char16ptr_t(ptr + aValue); |
michael@0 | 165 | } |
michael@0 | 166 | char16ptr_t operator+(unsigned long long aValue) const { |
michael@0 | 167 | return char16ptr_t(ptr + aValue); |
michael@0 | 168 | } |
michael@0 | 169 | ptrdiff_t operator-(const char16ptr_t &other) const { |
michael@0 | 170 | return ptr - other.ptr; |
michael@0 | 171 | } |
michael@0 | 172 | }; |
michael@0 | 173 | |
michael@0 | 174 | inline decltype((char*)0-(char*)0) |
michael@0 | 175 | operator-(const char16_t* x, const char16ptr_t y) { |
michael@0 | 176 | return x - static_cast<const char16_t*>(y); |
michael@0 | 177 | } |
michael@0 | 178 | |
michael@0 | 179 | #else |
michael@0 | 180 | |
michael@0 | 181 | typedef const char16_t* char16ptr_t; |
michael@0 | 182 | |
michael@0 | 183 | #endif |
michael@0 | 184 | |
michael@0 | 185 | /* |
michael@0 | 186 | * Macro arguments used in concatenation or stringification won't be expanded. |
michael@0 | 187 | * Therefore, in order for |MOZ_UTF16(FOO)| to work as expected (which is to |
michael@0 | 188 | * expand |FOO| before doing whatever |MOZ_UTF16| needs to do to it) a helper |
michael@0 | 189 | * macro, |MOZ_UTF16_HELPER| needs to be inserted in between to allow the macro |
michael@0 | 190 | * argument to expand. See "3.10.6 Separate Expansion of Macro Arguments" of the |
michael@0 | 191 | * CPP manual for a more accurate and precise explanation. |
michael@0 | 192 | */ |
michael@0 | 193 | #define MOZ_UTF16(s) MOZ_UTF16_HELPER(s) |
michael@0 | 194 | |
michael@0 | 195 | static_assert(sizeof(char16_t) == 2, "Is char16_t type 16 bits?"); |
michael@0 | 196 | static_assert(char16_t(-1) > char16_t(0), "Is char16_t type unsigned?"); |
michael@0 | 197 | static_assert(sizeof(MOZ_UTF16('A')) == 2, "Is char literal 16 bits?"); |
michael@0 | 198 | static_assert(sizeof(MOZ_UTF16("")[0]) == 2, "Is string char 16 bits?"); |
michael@0 | 199 | |
michael@0 | 200 | #endif |
michael@0 | 201 | |
michael@0 | 202 | #endif /* mozilla_Char16_h */ |