/* * Copyright (C) 2023 Huawei Device Co., Ltd. * 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 #include #include "PropertyTools/property_api_impl.h" CORE_BEGIN_NAMESPACE() template PropertyApiImpl::PropertyApiImpl() {} template PropertyApiImpl::PropertyApiImpl(BlockType* data, BASE_NS::array_view aProps) : data_(data), componentMetadata_(aProps) { // Create a typeid by hashing the metadata information. typeHash_ = 0; for (auto& t : aProps) { typeHash_ = BASE_NS::FNV1aHash(t.offset, typeHash_); typeHash_ = BASE_NS::FNV1aHash(t.count, typeHash_); typeHash_ = BASE_NS::FNV1aHash(t.type.compareHash, typeHash_); typeHash_ = BASE_NS::FNV1aHash(t.type.typeHash, typeHash_); typeHash_ = BASE_NS::FNV1aHash(t.hash, typeHash_); typeHash_ = BASE_NS::FNV1aHash(t.size, typeHash_); } } template size_t PropertyApiImpl::PropertyCount() const { if (owner_) { return owner_->PropertyCount(); } return componentMetadata_.size(); } // Metadata for property template const Property* PropertyApiImpl::MetaData(size_t aIndex) const { if (owner_) { return owner_->MetaData(aIndex); } return &componentMetadata_[aIndex]; } // Metadata for properties template BASE_NS::array_view PropertyApiImpl::MetaData() const { if (owner_) { return owner_->MetaData(); } return componentMetadata_; } template bool PropertyApiImpl::Clone(IPropertyHandle& dst, const IPropertyHandle& src) const { if (&src == &dst) { return true; } if ((src.Owner() != this) || (dst.Owner() != this)) { return false; } bool result = false; void* wdata = dst.WLock(); if (wdata) { const BlockType* rdata = (const BlockType*)src.RLock(); if (rdata) { ::new (wdata) BlockType(*rdata); result = true; } src.RUnlock(); } dst.WUnlock(); return true; } template void PropertyApiImpl::Destroy(IPropertyHandle& dst) const { if (dst.Owner() == this) { // call destructor. auto dstPtr = (BlockType*)dst.WLock(); if (dstPtr) { dstPtr->~BlockType(); } dst.WUnlock(); } } template IPropertyHandle* PropertyApiImpl::Create() const { auto ret = new PropertyApiImpl(); ret->owner_ = Owner(); ret->typeHash_ = Type(); ret->data_ = new BlockType(); return ret; } template IPropertyHandle* PropertyApiImpl::Clone(const IPropertyHandle* src) const { if (src->Owner() == this) { auto* h = static_cast*>(src); auto* ret = new PropertyApiImpl(); ret->owner_ = Owner(); ret->typeHash_ = Type(); ret->data_ = new BlockType(); *ret->data_ = *h->data_; return ret; } return nullptr; } template void PropertyApiImpl::Release(IPropertyHandle* dst) const { if (dst) { if (dst->Owner() == Owner()) { // we can only destroy things we "own" (know) auto* handle = static_cast*>(dst); if (handle->owner_) { // and only the ones that own the data.. delete handle; } } } } template uint32_t PropertyApiImpl::GetGeneration() const { return generationCount_; } template IPropertyHandle* PropertyApiImpl::GetData() { return this; } template const IPropertyHandle* PropertyApiImpl::GetData() const { return this; } template const IPropertyApi* PropertyApiImpl::Owner() const { if (owner_) { return owner_; } return this; } template size_t PropertyApiImpl::Size() const { return sizeof(BlockType); } template const void* PropertyApiImpl::RLock() const { CORE_ASSERT(!wLocked_); rLocked_++; return data_; } template void PropertyApiImpl::RUnlock() const { CORE_ASSERT(rLocked_ > 0); rLocked_--; } template void* PropertyApiImpl::WLock() { CORE_ASSERT(rLocked_ <= 1 && !wLocked_); wLocked_ = true; return data_; } template void PropertyApiImpl::WUnlock() { CORE_ASSERT(wLocked_); wLocked_ = false; generationCount_++; } template uint64_t PropertyApiImpl::Type() const { return typeHash_; } template<> inline size_t PropertyApiImpl::Size() const { return 0; } template<> inline bool PropertyApiImpl::Clone(IPropertyHandle& dst, const IPropertyHandle& src) const { return true; } template<> inline void PropertyApiImpl::Destroy(IPropertyHandle& dst) const {} template<> inline IPropertyHandle* PropertyApiImpl::Create() const { auto ret = new PropertyApiImpl(); ret->owner_ = owner_; ret->data_ = nullptr; return ret; } template<> inline IPropertyHandle* PropertyApiImpl::Clone(const IPropertyHandle* src) const { if (src->Owner() == this) { auto* h = static_cast*>(src); auto* ret = new PropertyApiImpl(); ret->owner_ = owner_; return ret; } return nullptr; } template<> inline void PropertyApiImpl::Release(IPropertyHandle* dst) const { if (dst) { if (dst->Owner() == this) { // we can only destroy things we "own" (know) auto* handle = static_cast*>(dst); delete handle; } } } CORE_END_NAMESPACE()