• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2010 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/win/scoped_bstr.h"
6 
7 #include <stdint.h>
8 
9 #include "base/check.h"
10 #include "base/numerics/safe_conversions.h"
11 #include "base/process/memory.h"
12 #include "base/strings/string_util.h"
13 
14 namespace base {
15 namespace win {
16 
17 namespace {
18 
AllocBstrOrDie(WStringPiece non_bstr)19 BSTR AllocBstrOrDie(WStringPiece non_bstr) {
20   BSTR result = ::SysAllocStringLen(non_bstr.data(),
21                                     checked_cast<UINT>(non_bstr.length()));
22   if (!result) {
23     base::TerminateBecauseOutOfMemory((non_bstr.length() + 1) *
24                                       sizeof(wchar_t));
25   }
26   return result;
27 }
28 
AllocBstrBytesOrDie(size_t bytes)29 BSTR AllocBstrBytesOrDie(size_t bytes) {
30   BSTR result = ::SysAllocStringByteLen(nullptr, checked_cast<UINT>(bytes));
31   if (!result)
32     base::TerminateBecauseOutOfMemory(bytes + sizeof(wchar_t));
33   return result;
34 }
35 
36 }  // namespace
37 
ScopedBstr(WStringPiece non_bstr)38 ScopedBstr::ScopedBstr(WStringPiece non_bstr)
39     : bstr_(AllocBstrOrDie(non_bstr)) {}
40 
~ScopedBstr()41 ScopedBstr::~ScopedBstr() {
42   static_assert(sizeof(ScopedBstr) == sizeof(BSTR), "ScopedBstrSize");
43   ::SysFreeString(bstr_);
44 }
45 
Reset(BSTR bstr)46 void ScopedBstr::Reset(BSTR bstr) {
47   if (bstr != bstr_) {
48     // SysFreeString handles null properly.
49     ::SysFreeString(bstr_);
50     bstr_ = bstr;
51   }
52 }
53 
Release()54 BSTR ScopedBstr::Release() {
55   BSTR bstr = bstr_;
56   bstr_ = nullptr;
57   return bstr;
58 }
59 
Swap(ScopedBstr & bstr2)60 void ScopedBstr::Swap(ScopedBstr& bstr2) {
61   BSTR tmp = bstr_;
62   bstr_ = bstr2.bstr_;
63   bstr2.bstr_ = tmp;
64 }
65 
Receive()66 BSTR* ScopedBstr::Receive() {
67   DCHECK(!bstr_) << "BSTR leak.";
68   return &bstr_;
69 }
70 
Allocate(WStringPiece str)71 BSTR ScopedBstr::Allocate(WStringPiece str) {
72   Reset(AllocBstrOrDie(str));
73   return bstr_;
74 }
75 
AllocateBytes(size_t bytes)76 BSTR ScopedBstr::AllocateBytes(size_t bytes) {
77   Reset(AllocBstrBytesOrDie(bytes));
78   return bstr_;
79 }
80 
SetByteLen(size_t bytes)81 void ScopedBstr::SetByteLen(size_t bytes) {
82   DCHECK(bstr_);
83   uint32_t* data = reinterpret_cast<uint32_t*>(bstr_);
84   data[-1] = checked_cast<uint32_t>(bytes);
85 }
86 
Length() const87 size_t ScopedBstr::Length() const {
88   return ::SysStringLen(bstr_);
89 }
90 
ByteLength() const91 size_t ScopedBstr::ByteLength() const {
92   return ::SysStringByteLen(bstr_);
93 }
94 
95 }  // namespace win
96 }  // namespace base
97