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