tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

scoped_bstr_win.h (5234B)


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