* Copyright (c) 2025 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.
*/
#ifndef ECMASCRIPT_CACHED_EXTERNAL_STRING_H
#define ECMASCRIPT_CACHED_EXTERNAL_STRING_H
#include "ecmascript/string/base_string.h"
namespace panda::ecmascript {
using ExternalStringResourceCallback = void (*)(void* data, void* hint);
class ExternalNonMovableStringResource {
public:
ExternalNonMovableStringResource(void* hint, ExternalStringResourceCallback callback)
: hint_(hint), callback_(callback) {}
static void FreeResource([[maybe_unused]] void* env, void* rec, void* data)
{
auto* resource = reinterpret_cast<ExternalNonMovableStringResource*>(rec);
if (resource->callback_ != nullptr) {
std::invoke(resource->callback_, data, resource->hint_);
}
delete resource;
}
private:
void* hint_;
ExternalStringResourceCallback callback_;
};
+--------------------------------------------+ <-- offset 0
| BaseObject fields |
+--------------------------------------------+ <-- offset = BaseObjectSize()
| Padding (uint64_t) |
+--------------------------------------------+
| LengthAndFlags (uint32_t) |
+--------------------------------------------+
| RawHashcode (uint32_t) |
+--------------------------------------------+ <-- offset = BaseString::SIZE
| Resource (ExternalNonMovableStringResource)| <-- RESOURCE_OFFSET
+--------------------------------------------+
| CachedResourceData (uint8_t/uint16_t)* | <-- CACHED_RESOURCE_DATA_OFFSET
+--------------------------------------------+ <-- SIZE
*/
* @class CacheExternalString
* @brief CacheExternalString represents the wrapper for external data.
*
* ExternalStringResource should be immutable and non-movable, so we can simply cache the data pointer.
*/
class CachedExternalString : public BaseString {
public:
STRING_CAST_CHECK(CachedExternalString, IsCachedExternalString);
NO_MOVE_SEMANTIC_CC(CachedExternalString);
NO_COPY_SEMANTIC_CC(CachedExternalString);
static constexpr size_t RESOURCE_OFFSET = BaseString::SIZE;
PRIMITIVE_FIELD(Resource, ExternalNonMovableStringResource*, RESOURCE_OFFSET, CACHE_RESOURCE_DATA_OFFSET)
PRIMITIVE_FIELD(CachedResourceData, void*, CACHE_RESOURCE_DATA_OFFSET, SIZE)
* @brief Retrieve string's raw UTF-8 data.
* @return Pointer to UTF-8 buffer.
*/
const uint8_t *GetDataUtf8() const;
* @brief Retrieve string's raw UTF-16 data.
* @return Pointer to UTF-16 buffer.
*/
const uint16_t *GetDataUtf16() const;
* @brief Get character at specific index.
* @tparam VERIFY Whether bounds checking should be performed.
* @param index Index into the character buffer.
* @return UTF-16 code unit at the given index.
*/
template <bool VERIFY = true>
uint16_t Get(int32_t index) const;
* @brief Create a CachedExternalString instance.
* @tparam Allocator Callable allocator.
* @param allocator Allocator object.
* @param length String length in code units.
* @param compressed Whether to use UTF-8 compression.
* @return CachedExternalString pointer.
*/
template <typename Allocator, panda::objects_traits::enable_if_is_allocate<Allocator, BaseObject *> = 0>
static CachedExternalString *Create(Allocator &&allocator, ExternalNonMovableStringResource* resource,
void* data, size_t length, bool compressed);
};
inline const uint8_t *CachedExternalString::GetDataUtf8() const
{
DCHECK_CC(IsUtf8() && "BaseString: Read data as utf8 for utf16 string");
return reinterpret_cast<uint8_t *>(GetCachedResourceData());
}
inline const uint16_t *CachedExternalString::GetDataUtf16() const
{
DCHECK_CC(IsUtf16() && "BaseString: Read data as utf16 for utf8 string");
return reinterpret_cast<uint16_t *>(GetCachedResourceData());
}
}
#endif