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)19BSTR 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)29BSTR 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)38ScopedBstr::ScopedBstr(WStringPiece non_bstr) 39 : bstr_(AllocBstrOrDie(non_bstr)) {} 40 ~ScopedBstr()41ScopedBstr::~ScopedBstr() { 42 static_assert(sizeof(ScopedBstr) == sizeof(BSTR), "ScopedBstrSize"); 43 ::SysFreeString(bstr_); 44 } 45 Reset(BSTR bstr)46void ScopedBstr::Reset(BSTR bstr) { 47 if (bstr != bstr_) { 48 // SysFreeString handles null properly. 49 ::SysFreeString(bstr_); 50 bstr_ = bstr; 51 } 52 } 53 Release()54BSTR ScopedBstr::Release() { 55 BSTR bstr = bstr_; 56 bstr_ = nullptr; 57 return bstr; 58 } 59 Swap(ScopedBstr & bstr2)60void ScopedBstr::Swap(ScopedBstr& bstr2) { 61 BSTR tmp = bstr_; 62 bstr_ = bstr2.bstr_; 63 bstr2.bstr_ = tmp; 64 } 65 Receive()66BSTR* ScopedBstr::Receive() { 67 DCHECK(!bstr_) << "BSTR leak."; 68 return &bstr_; 69 } 70 Allocate(WStringPiece str)71BSTR ScopedBstr::Allocate(WStringPiece str) { 72 Reset(AllocBstrOrDie(str)); 73 return bstr_; 74 } 75 AllocateBytes(size_t bytes)76BSTR ScopedBstr::AllocateBytes(size_t bytes) { 77 Reset(AllocBstrBytesOrDie(bytes)); 78 return bstr_; 79 } 80 SetByteLen(size_t bytes)81void 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() const87size_t ScopedBstr::Length() const { 88 return ::SysStringLen(bstr_); 89 } 90 ByteLength() const91size_t ScopedBstr::ByteLength() const { 92 return ::SysStringByteLen(bstr_); 93 } 94 95 } // namespace win 96 } // namespace base 97