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 <string_view> 10 11 #include "base/check.h" 12 #include "base/numerics/safe_conversions.h" 13 #include "base/process/memory.h" 14 #include "base/strings/string_util.h" 15 16 namespace base { 17 namespace win { 18 19 namespace { 20 AllocBstrOrDie(std::wstring_view non_bstr)21BSTR AllocBstrOrDie(std::wstring_view non_bstr) { 22 BSTR result = ::SysAllocStringLen(non_bstr.data(), 23 checked_cast<UINT>(non_bstr.length())); 24 if (!result) { 25 base::TerminateBecauseOutOfMemory((non_bstr.length() + 1) * 26 sizeof(wchar_t)); 27 } 28 return result; 29 } 30 AllocBstrBytesOrDie(size_t bytes)31BSTR AllocBstrBytesOrDie(size_t bytes) { 32 BSTR result = ::SysAllocStringByteLen(nullptr, checked_cast<UINT>(bytes)); 33 if (!result) 34 base::TerminateBecauseOutOfMemory(bytes + sizeof(wchar_t)); 35 return result; 36 } 37 38 } // namespace 39 ScopedBstr(std::wstring_view non_bstr)40ScopedBstr::ScopedBstr(std::wstring_view non_bstr) 41 : bstr_(AllocBstrOrDie(non_bstr)) {} 42 ~ScopedBstr()43ScopedBstr::~ScopedBstr() { 44 static_assert(sizeof(ScopedBstr) == sizeof(BSTR), "ScopedBstrSize"); 45 ::SysFreeString(bstr_); 46 } 47 Reset(BSTR bstr)48void ScopedBstr::Reset(BSTR bstr) { 49 if (bstr != bstr_) { 50 // SysFreeString handles null properly. 51 ::SysFreeString(bstr_); 52 bstr_ = bstr; 53 } 54 } 55 Release()56BSTR ScopedBstr::Release() { 57 BSTR bstr = bstr_; 58 bstr_ = nullptr; 59 return bstr; 60 } 61 Swap(ScopedBstr & bstr2)62void ScopedBstr::Swap(ScopedBstr& bstr2) { 63 BSTR tmp = bstr_; 64 bstr_ = bstr2.bstr_; 65 bstr2.bstr_ = tmp; 66 } 67 Receive()68BSTR* ScopedBstr::Receive() { 69 DCHECK(!bstr_) << "BSTR leak."; 70 return &bstr_; 71 } 72 Allocate(std::wstring_view str)73BSTR ScopedBstr::Allocate(std::wstring_view str) { 74 Reset(AllocBstrOrDie(str)); 75 return bstr_; 76 } 77 AllocateBytes(size_t bytes)78BSTR ScopedBstr::AllocateBytes(size_t bytes) { 79 Reset(AllocBstrBytesOrDie(bytes)); 80 return bstr_; 81 } 82 SetByteLen(size_t bytes)83void ScopedBstr::SetByteLen(size_t bytes) { 84 DCHECK(bstr_); 85 uint32_t* data = reinterpret_cast<uint32_t*>(bstr_); 86 data[-1] = checked_cast<uint32_t>(bytes); 87 } 88 Length() const89size_t ScopedBstr::Length() const { 90 return ::SysStringLen(bstr_); 91 } 92 ByteLength() const93size_t ScopedBstr::ByteLength() const { 94 return ::SysStringByteLen(bstr_); 95 } 96 97 } // namespace win 98 } // namespace base 99