Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
michael@0 | 2 | // Use of this source code is governed by a BSD-style license that can be |
michael@0 | 3 | // found in the LICENSE file. |
michael@0 | 4 | |
michael@0 | 5 | #ifndef BASE_SCOPED_BSTR_WIN_H_ |
michael@0 | 6 | #define BASE_SCOPED_BSTR_WIN_H_ |
michael@0 | 7 | |
michael@0 | 8 | #include "base/basictypes.h" // needed to pick up OS_WIN |
michael@0 | 9 | |
michael@0 | 10 | #include "base/logging.h" |
michael@0 | 11 | |
michael@0 | 12 | #include <windows.h> |
michael@0 | 13 | #include <oleauto.h> |
michael@0 | 14 | |
michael@0 | 15 | // Manages a BSTR string pointer. |
michael@0 | 16 | // The class interface is based on scoped_ptr. |
michael@0 | 17 | class ScopedBstr { |
michael@0 | 18 | public: |
michael@0 | 19 | ScopedBstr() : bstr_(NULL) { |
michael@0 | 20 | } |
michael@0 | 21 | |
michael@0 | 22 | // Constructor to create a new BSTR. |
michael@0 | 23 | // NOTE: Do not pass a BSTR to this constructor expecting ownership to |
michael@0 | 24 | // be transferred - even though it compiles! ;-) |
michael@0 | 25 | explicit ScopedBstr(const wchar_t* non_bstr); |
michael@0 | 26 | ~ScopedBstr(); |
michael@0 | 27 | |
michael@0 | 28 | // Give ScopedBstr ownership over an already allocated BSTR or NULL. |
michael@0 | 29 | // If you need to allocate a new BSTR instance, use |allocate| instead. |
michael@0 | 30 | void Reset(BSTR bstr = NULL); |
michael@0 | 31 | |
michael@0 | 32 | // Releases ownership of the BSTR to the caller. |
michael@0 | 33 | BSTR Release(); |
michael@0 | 34 | |
michael@0 | 35 | // Creates a new BSTR from a wide string. |
michael@0 | 36 | // If you already have a BSTR and want to transfer ownership to the |
michael@0 | 37 | // ScopedBstr instance, call |reset| instead. |
michael@0 | 38 | // Returns a pointer to the new BSTR, or NULL if allocation failed. |
michael@0 | 39 | BSTR Allocate(const wchar_t* wide_str); |
michael@0 | 40 | |
michael@0 | 41 | // Allocates a new BSTR with the specified number of bytes. |
michael@0 | 42 | // Returns a pointer to the new BSTR, or NULL if allocation failed. |
michael@0 | 43 | BSTR AllocateBytes(int bytes); |
michael@0 | 44 | |
michael@0 | 45 | // Sets the allocated length field of the already-allocated BSTR to be |
michael@0 | 46 | // |bytes|. This is useful when the BSTR was preallocated with e.g. |
michael@0 | 47 | // SysAllocStringLen or SysAllocStringByteLen (call |AllocateBytes|) and |
michael@0 | 48 | // then not all the bytes are being used. |
michael@0 | 49 | // Note that if you want to set the length to a specific number of characters, |
michael@0 | 50 | // you need to multiply by sizeof(wchar_t). Oddly, there's no public API to |
michael@0 | 51 | // set the length, so we do this ourselves by hand. |
michael@0 | 52 | // |
michael@0 | 53 | // NOTE: The actual allocated size of the BSTR MUST be >= bytes. |
michael@0 | 54 | // That responsibility is with the caller. |
michael@0 | 55 | void SetByteLen(uint32_t bytes); |
michael@0 | 56 | |
michael@0 | 57 | // Swap values of two ScopedBstr's. |
michael@0 | 58 | void Swap(ScopedBstr& bstr2); |
michael@0 | 59 | |
michael@0 | 60 | // Retrieves the pointer address. |
michael@0 | 61 | // Used to receive BSTRs as out arguments (and take ownership). |
michael@0 | 62 | // The function DCHECKs on the current value being NULL. |
michael@0 | 63 | // Usage: GetBstr(bstr.Receive()); |
michael@0 | 64 | BSTR* Receive(); |
michael@0 | 65 | |
michael@0 | 66 | // Returns number of chars in the BSTR. |
michael@0 | 67 | uint32_t Length() const; |
michael@0 | 68 | |
michael@0 | 69 | // Returns the number of bytes allocated for the BSTR. |
michael@0 | 70 | uint32_t ByteLength() const; |
michael@0 | 71 | |
michael@0 | 72 | operator BSTR() const { |
michael@0 | 73 | return bstr_; |
michael@0 | 74 | } |
michael@0 | 75 | |
michael@0 | 76 | protected: |
michael@0 | 77 | BSTR bstr_; |
michael@0 | 78 | |
michael@0 | 79 | private: |
michael@0 | 80 | // Forbid comparison of ScopedBstr types. You should never have the same |
michael@0 | 81 | // BSTR owned by two different scoped_ptrs. |
michael@0 | 82 | bool operator==(const ScopedBstr& bstr2) const; |
michael@0 | 83 | bool operator!=(const ScopedBstr& bstr2) const; |
michael@0 | 84 | DISALLOW_COPY_AND_ASSIGN(ScopedBstr); |
michael@0 | 85 | }; |
michael@0 | 86 | |
michael@0 | 87 | // Template class to generate a BSTR from a static wide string |
michael@0 | 88 | // without touching the heap. Use this class via the StackBstrVar and |
michael@0 | 89 | // StackBstr macros. |
michael@0 | 90 | template <uint32_t string_bytes> |
michael@0 | 91 | class StackBstrT { |
michael@0 | 92 | public: |
michael@0 | 93 | // Try to stay as const as we can in an attempt to avoid someone |
michael@0 | 94 | // using the class incorrectly (e.g. by supplying a variable instead |
michael@0 | 95 | // of a verbatim string. We also have an assert in the constructor |
michael@0 | 96 | // as an extra runtime check since the const-ness only catches one case. |
michael@0 | 97 | explicit StackBstrT(const wchar_t* const str) { |
michael@0 | 98 | // The BSTR API uses UINT, but we prefer uint32_t. |
michael@0 | 99 | // Make sure we'll know about it if these types don't match. |
michael@0 | 100 | COMPILE_ASSERT(sizeof(uint32_t) == sizeof(UINT), UintToUint32); |
michael@0 | 101 | COMPILE_ASSERT(sizeof(wchar_t) == sizeof(OLECHAR), WcharToOlechar); |
michael@0 | 102 | |
michael@0 | 103 | // You shouldn't pass string pointers to this constructor since |
michael@0 | 104 | // there's no way for the compiler to calculate the length of the |
michael@0 | 105 | // string (string_bytes will be equal to pointer size in those cases). |
michael@0 | 106 | DCHECK(lstrlenW(str) == (string_bytes / sizeof(bstr_.str_[0])) - 1) << |
michael@0 | 107 | "not expecting a string pointer"; |
michael@0 | 108 | memcpy(bstr_.str_, str, string_bytes); |
michael@0 | 109 | bstr_.len_ = string_bytes - sizeof(wchar_t); |
michael@0 | 110 | } |
michael@0 | 111 | |
michael@0 | 112 | operator BSTR() { |
michael@0 | 113 | return bstr_.str_; |
michael@0 | 114 | } |
michael@0 | 115 | |
michael@0 | 116 | protected: |
michael@0 | 117 | struct BstrInternal { |
michael@0 | 118 | uint32_t len_; |
michael@0 | 119 | wchar_t str_[string_bytes / sizeof(wchar_t)]; |
michael@0 | 120 | } bstr_; |
michael@0 | 121 | }; |
michael@0 | 122 | |
michael@0 | 123 | // Use this macro to generate an inline BSTR from a wide string. |
michael@0 | 124 | // This is about 6 times faster than using the SysAllocXxx functions to |
michael@0 | 125 | // allocate a BSTR and helps with keeping heap fragmentation down. |
michael@0 | 126 | // Example: |
michael@0 | 127 | // DoBstrStuff(StackBstr(L"This is my BSTR")); |
michael@0 | 128 | // Where DoBstrStuff is: |
michael@0 | 129 | // HRESULT DoBstrStuff(BSTR bstr) { ... } |
michael@0 | 130 | #define StackBstr(str) \ |
michael@0 | 131 | static_cast<BSTR>(StackBstrT<sizeof(str)>(str)) |
michael@0 | 132 | |
michael@0 | 133 | // If you need a named BSTR variable that's based on a fixed string |
michael@0 | 134 | // (e.g. if the BSTR is used inside a loop or more than one place), |
michael@0 | 135 | // use StackBstrVar to declare a variable. |
michael@0 | 136 | // Example: |
michael@0 | 137 | // StackBstrVar(L"my_property", myprop); |
michael@0 | 138 | // for (int i = 0; i < objects.length(); ++i) |
michael@0 | 139 | // ProcessValue(objects[i].GetProp(myprop)); // GetProp accepts BSTR |
michael@0 | 140 | #define StackBstrVar(str, var) \ |
michael@0 | 141 | StackBstrT<sizeof(str)> var(str) |
michael@0 | 142 | |
michael@0 | 143 | #endif // BASE_SCOPED_BSTR_WIN_H_ |