blob: 13413740f8c8f3b445c4ebf9b8f2140d64306607 [file] [log] [blame]
// 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 allcations.
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