15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2010 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/scoped_bstr.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base {
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace win {
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedBstr::ScopedBstr(const char16* non_bstr)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : bstr_(SysAllocString(non_bstr)) {
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedBstr::~ScopedBstr() {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  COMPILE_ASSERT(sizeof(ScopedBstr) == sizeof(BSTR), ScopedBstrSize);
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SysFreeString(bstr_);
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ScopedBstr::Reset(BSTR bstr) {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (bstr != bstr_) {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // if |bstr_| is NULL, SysFreeString does nothing.
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SysFreeString(bstr_);
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bstr_ = bstr;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BSTR ScopedBstr::Release() {
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BSTR bstr = bstr_;
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bstr_ = NULL;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return bstr;
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ScopedBstr::Swap(ScopedBstr& bstr2) {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BSTR tmp = bstr_;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bstr_ = bstr2.bstr_;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bstr2.bstr_ = tmp;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BSTR* ScopedBstr::Receive() {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!bstr_) << "BSTR leak.";
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return &bstr_;
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BSTR ScopedBstr::Allocate(const char16* str) {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Reset(SysAllocString(str));
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return bstr_;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BSTR ScopedBstr::AllocateBytes(size_t bytes) {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Reset(SysAllocStringByteLen(NULL, static_cast<UINT>(bytes)));
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return bstr_;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ScopedBstr::SetByteLen(size_t bytes) {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(bstr_ != NULL) << "attempting to modify a NULL bstr";
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32* data = reinterpret_cast<uint32*>(bstr_);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data[-1] = static_cast<uint32>(bytes);
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t ScopedBstr::Length() const {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return SysStringLen(bstr_);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)size_t ScopedBstr::ByteLength() const {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return SysStringByteLen(bstr_);
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace win
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace base
72