| // Copyright 2018 The Cobalt Authors. All Rights Reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include "cobalt/overlay_info/overlay_info_registry.h" |
| |
| #include "base/logging.h" |
| #include "base/memory/singleton.h" |
| #include "starboard/common/mutex.h" |
| #include "starboard/common/string.h" |
| |
| namespace cobalt { |
| namespace overlay_info { |
| namespace { |
| |
| const auto kDelimiter = OverlayInfoRegistry::kDelimiter; |
| |
| class OverlayInfoRegistryImpl { |
| public: |
| static OverlayInfoRegistryImpl* GetInstance(); |
| |
| void Disable(); |
| |
| void Register(const char* category, const char* str); |
| void RetrieveAndClear(std::string* infos); |
| |
| private: |
| // Reserve enough data for |infos_| to avoid extra allocations. |
| static const size_t kReservedSize = 4096; |
| |
| OverlayInfoRegistryImpl() = default; |
| |
| // To make our private constructor available to |
| // base::Singleton<OverlayInfoRegistryImpl, |
| // DefaultSingletonTraits<OverlayInfoRegistryImpl>>. |
| friend struct base::DefaultSingletonTraits<OverlayInfoRegistryImpl>; |
| |
| bool enabled_ = true; |
| starboard::Mutex mutex_; |
| std::string infos_; |
| }; |
| |
| // static |
| OverlayInfoRegistryImpl* OverlayInfoRegistryImpl::GetInstance() { |
| return base::Singleton< |
| OverlayInfoRegistryImpl, |
| base::DefaultSingletonTraits<OverlayInfoRegistryImpl>>::get(); |
| } |
| |
| void OverlayInfoRegistryImpl::Disable() { |
| starboard::ScopedLock scoped_lock(mutex_); |
| enabled_ = false; |
| infos_.clear(); |
| } |
| |
| void OverlayInfoRegistryImpl::Register(const char* category, const char* data) { |
| DCHECK(SbStringFindCharacter( |
| category, static_cast<char>(OverlayInfoRegistry::kDelimiter)) == |
| NULL) |
| << "Category " << category |
| << " cannot contain the delimiter:" << OverlayInfoRegistry::kDelimiter; |
| DCHECK(SbStringFindCharacter( |
| data, static_cast<char>(OverlayInfoRegistry::kDelimiter)) == NULL) |
| << "Data " << data |
| << " cannot contain the delimiter:" << OverlayInfoRegistry::kDelimiter; |
| if (!infos_.empty()) { |
| infos_ += kDelimiter; |
| } |
| infos_ += category; |
| infos_ += kDelimiter; |
| infos_ += data; |
| } |
| |
| void OverlayInfoRegistryImpl::RetrieveAndClear(std::string* infos) { |
| DCHECK(infos); |
| |
| starboard::ScopedLock scoped_lock(mutex_); |
| if (enabled_) { |
| infos->swap(infos_); |
| infos_.clear(); |
| infos_.reserve(kReservedSize); |
| } |
| } |
| |
| } // namespace |
| |
| void OverlayInfoRegistry::Disable() { |
| OverlayInfoRegistryImpl::GetInstance()->Disable(); |
| } |
| |
| void OverlayInfoRegistry::Register(const char* category, const char* data) { |
| OverlayInfoRegistryImpl::GetInstance()->Register(category, data); |
| } |
| |
| void OverlayInfoRegistry::Register(const char* category, const void* data, |
| size_t data_size) { |
| const char kHex[] = "0123456789abcdef"; |
| |
| const uint8_t* data_as_bytes = static_cast<const uint8_t*>(data); |
| std::string data_in_hex; |
| |
| data_in_hex.reserve(data_size * 2); |
| |
| while (data_size > 0) { |
| data_in_hex += kHex[*data_as_bytes / 16]; |
| data_in_hex += kHex[*data_as_bytes % 16]; |
| ++data_as_bytes; |
| --data_size; |
| } |
| OverlayInfoRegistryImpl::GetInstance()->Register(category, |
| data_in_hex.c_str()); |
| } |
| |
| void OverlayInfoRegistry::RetrieveAndClear(std::string* infos) { |
| OverlayInfoRegistryImpl::GetInstance()->RetrieveAndClear(infos); |
| } |
| |
| } // namespace overlay_info |
| } // namespace cobalt |