106f6ba60Sopenharmony_ci/* 206f6ba60Sopenharmony_ci * Copyright (c) Huawei Technologies Co., Ltd. 2023. All rights reserved. 306f6ba60Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 406f6ba60Sopenharmony_ci * you may not use this file except in compliance with the License. 506f6ba60Sopenharmony_ci * You may obtain a copy of the License at 606f6ba60Sopenharmony_ci * 706f6ba60Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 806f6ba60Sopenharmony_ci * 906f6ba60Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 1006f6ba60Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 1106f6ba60Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1206f6ba60Sopenharmony_ci * See the License for the specific language governing permissions and 1306f6ba60Sopenharmony_ci * limitations under the License. 1406f6ba60Sopenharmony_ci */ 1506f6ba60Sopenharmony_ci#ifndef VARINT_ENCODE_H 1606f6ba60Sopenharmony_ci#define VARINT_ENCODE_H 1706f6ba60Sopenharmony_ci#include <cinttypes> 1806f6ba60Sopenharmony_ci#include <cstddef> 1906f6ba60Sopenharmony_ci#include <type_traits> 2006f6ba60Sopenharmony_ci#include <cstdint> 2106f6ba60Sopenharmony_ci 2206f6ba60Sopenharmony_cinamespace OHOS { 2306f6ba60Sopenharmony_cinamespace Developtools { 2406f6ba60Sopenharmony_cinamespace Profiler { 2506f6ba60Sopenharmony_cinamespace ProtoEncoder { 2606f6ba60Sopenharmony_ciconstexpr uint32_t VARINT32_SIZE = 4; 2706f6ba60Sopenharmony_ciconstexpr uint32_t VARINT32_ENCODE_SIZE = 5; 2806f6ba60Sopenharmony_ciconstexpr uint32_t VARINT64_SIZE = 8; 2906f6ba60Sopenharmony_ciconstexpr uint32_t VARINT64_ENCODE_SIZE = 10; 3006f6ba60Sopenharmony_ciconstexpr uint32_t VARINT_ENCODE_MAX_SIZE = VARINT64_ENCODE_SIZE; 3106f6ba60Sopenharmony_ci 3206f6ba60Sopenharmony_ciconstexpr uint32_t VARINT_MAX_1BYTE = (1u << (7 * 1)) - 1; 3306f6ba60Sopenharmony_ciconstexpr uint32_t VARINT_MAX_2BYTE = (1u << (7 * 2)) - 1; 3406f6ba60Sopenharmony_ciconstexpr uint32_t VARINT_MAX_3BYTE = (1u << (7 * 3)) - 1; 3506f6ba60Sopenharmony_ciconstexpr uint32_t VARINT_MAX_4BYTE = (1u << (7 * 4)) - 1; 3606f6ba60Sopenharmony_ci 3706f6ba60Sopenharmony_ciconstexpr uint8_t VARINT_PAYLOAD_BITS = 7; 3806f6ba60Sopenharmony_ciconstexpr uint8_t VARINT_MASK_PAYLOAD = 0x7F; 3906f6ba60Sopenharmony_ciconstexpr uint8_t VARINT_MASK_MSB = 0x80; 4006f6ba60Sopenharmony_ci 4106f6ba60Sopenharmony_ciinline uint32_t GetPackedVarintLenSize(uint32_t itemCount, uint32_t itemSize, uint32_t& len) 4206f6ba60Sopenharmony_ci{ 4306f6ba60Sopenharmony_ci len = itemCount; 4406f6ba60Sopenharmony_ci if (itemSize == VARINT32_SIZE) { 4506f6ba60Sopenharmony_ci len = itemCount * VARINT32_ENCODE_SIZE; 4606f6ba60Sopenharmony_ci } else if (itemSize == VARINT64_SIZE) { 4706f6ba60Sopenharmony_ci len = itemCount * VARINT64_ENCODE_SIZE; 4806f6ba60Sopenharmony_ci } // else bool is 1 byte 4906f6ba60Sopenharmony_ci 5006f6ba60Sopenharmony_ci const uint32_t one = 1; 5106f6ba60Sopenharmony_ci const uint32_t two = 2; 5206f6ba60Sopenharmony_ci const uint32_t three = 3; 5306f6ba60Sopenharmony_ci const uint32_t four = 4; 5406f6ba60Sopenharmony_ci if (len <= VARINT_MAX_1BYTE) { 5506f6ba60Sopenharmony_ci return one; 5606f6ba60Sopenharmony_ci } else if (len <= VARINT_MAX_2BYTE) { 5706f6ba60Sopenharmony_ci return two; 5806f6ba60Sopenharmony_ci } else if (len <= VARINT_MAX_3BYTE) { 5906f6ba60Sopenharmony_ci return three; 6006f6ba60Sopenharmony_ci } else if (len <= VARINT_MAX_4BYTE) { 6106f6ba60Sopenharmony_ci return four; 6206f6ba60Sopenharmony_ci } 6306f6ba60Sopenharmony_ci 6406f6ba60Sopenharmony_ci return 0; // illegal, too large 6506f6ba60Sopenharmony_ci} 6606f6ba60Sopenharmony_ci 6706f6ba60Sopenharmony_citemplate<typename T> 6806f6ba60Sopenharmony_ciinline typename std::make_unsigned<T>::type EncodeZigZag(T v) 6906f6ba60Sopenharmony_ci{ 7006f6ba60Sopenharmony_ci if (v >= 0) { 7106f6ba60Sopenharmony_ci return ((typename std::make_unsigned<T>::type)(v) << 1); 7206f6ba60Sopenharmony_ci } 7306f6ba60Sopenharmony_ci 7406f6ba60Sopenharmony_ci return ((typename std::make_unsigned<T>::type)(~v) << 1) + 1; 7506f6ba60Sopenharmony_ci} 7606f6ba60Sopenharmony_ci 7706f6ba60Sopenharmony_citemplate<typename T> 7806f6ba60Sopenharmony_ciinline uint32_t EncodeVarint(uint8_t* buf, T v) 7906f6ba60Sopenharmony_ci{ 8006f6ba60Sopenharmony_ci // https://developers.google.com/protocol-buffers/docs/encoding 8106f6ba60Sopenharmony_ci // Unsigned Integers and Signed Integers(intN) 8206f6ba60Sopenharmony_ci uint64_t value = static_cast<uint64_t>(v); 8306f6ba60Sopenharmony_ci uint32_t size = 0; 8406f6ba60Sopenharmony_ci while (value > static_cast<uint64_t>(VARINT_MAX_1BYTE)) { 8506f6ba60Sopenharmony_ci buf[size] = (VARINT_MASK_PAYLOAD & value) | VARINT_MASK_MSB; 8606f6ba60Sopenharmony_ci size++; 8706f6ba60Sopenharmony_ci value >>= VARINT_PAYLOAD_BITS; 8806f6ba60Sopenharmony_ci } 8906f6ba60Sopenharmony_ci buf[size] = (VARINT_MASK_PAYLOAD & value); 9006f6ba60Sopenharmony_ci size++; 9106f6ba60Sopenharmony_ci 9206f6ba60Sopenharmony_ci return size; 9306f6ba60Sopenharmony_ci} 9406f6ba60Sopenharmony_ci 9506f6ba60Sopenharmony_citemplate<typename T> 9606f6ba60Sopenharmony_ciinline uint32_t EncodeZigZagVarint(uint8_t* buf, T v) 9706f6ba60Sopenharmony_ci{ 9806f6ba60Sopenharmony_ci return EncodeVarint(buf, EncodeZigZag(v)); 9906f6ba60Sopenharmony_ci} 10006f6ba60Sopenharmony_ci 10106f6ba60Sopenharmony_citemplate<typename T> 10206f6ba60Sopenharmony_ciinline void EncodeVarintPadding(uint8_t* buf, T v, uint32_t paddingSize) 10306f6ba60Sopenharmony_ci{ 10406f6ba60Sopenharmony_ci uint32_t size = 0; 10506f6ba60Sopenharmony_ci paddingSize--; 10606f6ba60Sopenharmony_ci while (size < paddingSize) { 10706f6ba60Sopenharmony_ci buf[size] = (VARINT_MASK_PAYLOAD & v) | VARINT_MASK_MSB; 10806f6ba60Sopenharmony_ci size++; 10906f6ba60Sopenharmony_ci v >>= VARINT_PAYLOAD_BITS; 11006f6ba60Sopenharmony_ci } 11106f6ba60Sopenharmony_ci buf[size] = (VARINT_MASK_PAYLOAD & v); 11206f6ba60Sopenharmony_ci} 11306f6ba60Sopenharmony_ci} // namespace ProtoEncoder 11406f6ba60Sopenharmony_ci} // namespace Profiler 11506f6ba60Sopenharmony_ci} // namespace Developtools 11606f6ba60Sopenharmony_ci} // namespace OHOS 11706f6ba60Sopenharmony_ci#endif // VARINT_ENCODE_H 118