TokensUtils.h#

Fully qualified name: carb/tokens/TokensUtils.h

File members: carb/tokens/TokensUtils.h

// SPDX-FileCopyrightText: Copyright (c) 2019-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: LicenseRef-NvidiaProprietary
//
// NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
// property and proprietary rights in and to this material, related
// documentation and any modifications thereto. Any use, reproduction,
// disclosure or distribution of this material and related documentation
// without an express license agreement from NVIDIA CORPORATION or
// its affiliates is strictly prohibited.

#pragma once

#include "../InterfaceUtils.h"
#include "../logging/Log.h"
#include "../cpp/StringView.h"
#include "ITokens.h"

#include <omni/Expected.h>

#include <string>
#include <algorithm>

namespace carb::tokens
{

namespace detail
{
inline bool setValue(ITokens* tokens, cpp::string_view name, cpp::string_view value)
{
#if CARB_VERSION_ATLEAST(carb_tokens_ITokens, 2, 0)
    return tokens->setValue(name, value);
#else
    return tokens->setValueS(name, value);
#endif
}

inline bool deleteValue(ITokens* tokens, cpp::string_view name)
{
#if CARB_VERSION_ATLEAST(carb_tokens_ITokens, 2, 0)
    return tokens->deleteValue(name);
#else
    return tokens->deleteValueS(name);
#endif
}

inline bool exists(const ITokens* tokens, cpp::string_view name)
{
#if CARB_VERSION_ATLEAST(carb_tokens_ITokens, 2, 0)
    return tokens->exists(name);
#else
    return tokens->existsS(name);
#endif
}

inline void setInitialValue(ITokens* tokens, cpp::string_view name, cpp::string_view value)
{
#if CARB_VERSION_ATLEAST(carb_tokens_ITokens, 2, 0)
    tokens->setInitialValue(name, value);
#else
    // v1.1 interface
    tokens->setInitialValueS(name, value);
#endif
}

inline omni::expected<omni::string, ResolveError> resolveString(const ITokens* tokens,
                                                                carb::cpp::string_view str,
                                                                ResolveFlags resolveFlags = kResolveFlagNone)
{
    if (!tokens)
        return omni::unexpected(ResolveError::eFailure);
#if CARB_VERSION_ATLEAST(carb_tokens_ITokens, 2, 0)
    return tokens->resolveString(str, resolveFlags);
#else
    ResolveResult result;
    CARB_IGNORE_DEPRECATION_BEGIN
    auto size = tokens->calculateDestinationBufferSize(
        str.data(), str.size(), StringEndingMode::eNoNullTerminator, resolveFlags, &result);
    if (result != ResolveResult::eSuccess)
        return omni::unexpected(result == ResolveResult::eFailure ? ResolveError::eFailure : ResolveError::eTruncated);
    omni::string out(size, '\0');
    if (result = tokens->resolveString(
            str.data(), str.size(), out.data(), out.size(), StringEndingMode::eNoNullTerminator, resolveFlags, &size);
        result != ResolveResult::eSuccess)
        return omni::unexpected(result == ResolveResult::eFailure ? ResolveError::eFailure : ResolveError::eTruncated);
    CARB_IGNORE_DEPRECATION_END
    return out;
#endif
}
} // namespace detail

#if CARB_VERSION_ATLEAST(carb_tokens_ITokens, 2, 0)
inline omni::expected<omni::string, ResolveError> resolveString(const ITokens* tokens,
                                                                carb::cpp::string_view str,
                                                                ResolveFlags resolveFlags = kResolveFlagNone)
{
    return detail::resolveString(tokens, str, resolveFlags);
}

#else
inline std::string resolveString(const ITokens* tokens,
                                 carb::cpp::string_view str,
                                 ResolveFlags resolveFlags = kResolveFlagNone,
                                 ResolveResult* resolveResult = nullptr)
{
    // Defaulting to an error result thus it's possible to just log an error message and return an empty string if
    // anything goes wrong
    ResolveResult dummy;
    if (!resolveResult)
        resolveResult = &dummy;

    if (!tokens)
    {
        *resolveResult = ResolveResult::eFailure;
        return {};
    }

    CARB_IGNORE_DEPRECATION_BEGIN
    auto size = tokens->calculateDestinationBufferSize(
        str.data(), str.size(), StringEndingMode::eNoNullTerminator, resolveFlags, resolveResult);
    if (*resolveResult != ResolveResult::eSuccess)
        return {};

    std::string out(size, '\0');
    *resolveResult = tokens->resolveString(
        str.data(), str.size(), out.data(), out.size(), StringEndingMode::eNoNullTerminator, resolveFlags, &size);
    if (*resolveResult != ResolveResult::eSuccess)
        return {};
    CARB_IGNORE_DEPRECATION_END
    return out;
}
#endif

inline std::string escapeString(carb::cpp::string_view str)
{
    constexpr char kSpecialChar = '$';
    const size_t countSpecials = (size_t)std::count(str.begin(), str.end(), kSpecialChar);
    if (!countSpecials)
    {
        return std::string(str);
    }

    std::string result;
    result.reserve(str.length() + countSpecials);

    for (char curChar : str)
    {
        result.push_back(curChar);
        if (curChar == kSpecialChar)
        {
            result.push_back(kSpecialChar);
        }
    }
    return result;
}

} // namespace carb::tokens