blob: b31568101f2a2d80db1190e38a39cfcd64a300cf [file] [log] [blame]
/*
* Copyright (c) 2022 Project CHIP 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.
*/
#pragma once
#include <lib/core/CHIPError.h>
#include <lib/support/BytesToHex.h>
#include <lib/support/Span.h>
#include <lib/support/logging/CHIPLogging.h>
/**
* Utility for converting a hex string to bytes, with the right error checking
* and allocation size computation.
*
* Takes a functor to allocate the buffer to use for the hex bytes. The functor
* is expected to return uint8_t *. The caller is responsible for cleaning up
* this buffer as needed.
*
* On success, *octetCount is filled with the number of octets placed in the
* buffer. On failure, the value of *octetCount is undefined.
*/
template <typename F>
CHIP_ERROR HexToBytes(chip::CharSpan hex, F bufferAllocator, size_t * octetCount)
{
*octetCount = 0;
if (hex.size() % 2 != 0)
{
ChipLogError(chipTool, "Error while encoding '%.*s' as an octet string: Odd number of characters.",
static_cast<int>(hex.size()), hex.data());
return CHIP_ERROR_INVALID_STRING_LENGTH;
}
const size_t bufferSize = hex.size() / 2;
uint8_t * buffer = bufferAllocator(bufferSize);
if (buffer == nullptr && bufferSize != 0)
{
ChipLogError(chipTool, "Failed to allocate buffer of size: %llu", static_cast<unsigned long long>(bufferSize));
return CHIP_ERROR_NO_MEMORY;
}
size_t byteCount = chip::Encoding::HexToBytes(hex.data(), hex.size(), buffer, bufferSize);
if (byteCount == 0 && hex.size() != 0)
{
ChipLogError(chipTool, "Error while encoding '%.*s' as an octet string.", static_cast<int>(hex.size()), hex.data());
return CHIP_ERROR_INTERNAL;
}
*octetCount = byteCount;
return CHIP_NO_ERROR;
}