scoped_bstr.cc 2.1 KB

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