15#ifndef ACTIONENGINE_MSGPACK_ARRAY_H 
   16#define ACTIONENGINE_MSGPACK_ARRAY_H 
   18#include "actionengine/msgpack/core_helpers.h" 
   20namespace act::msgpack {
 
   23absl::StatusOr<uint32_t> EgltMsgpackGetExtent(
const LookupPointer& data,
 
   24                                              std::vector<T>* absl_nullable) {
 
   25  const auto [pos, end, _] = data;
 
   29  auto elements_pos = 
const_cast<Byte*
>(pos);
 
   31  if (*pos >= 0x90 && *pos <= 0x9F) {
 
   37  if (*pos == FormatSignature::kArray16) {
 
   39      return GetInsufficientDataError(data, 
"std::vector<T>");
 
   41    length = FromBigEndianBytes<uint16_t>(pos + 1);
 
   46  if (*pos == FormatSignature::kArray32) {
 
   48      return GetInsufficientDataError(data, 
"std::vector<T>");
 
   50    length = FromBigEndianBytes<uint32_t>(pos + 1);
 
   56    return GetInvalidFormatSignatureError(pos, 
"std::vector<T>", data.begin);
 
   59  if (elements_pos >= end) {
 
   60    return GetInsufficientDataError(data, 
"std::vector<T> elements");
 
   63  for (uint32_t i = 0; i < length; ++i) {
 
   64    if (elements_pos >= end) {
 
   65      return GetInsufficientDataError(data, 
"std::vector<T> elements");
 
   67    auto element_extent = GetExtent<T>(elements_pos, end);
 
   68    if (!element_extent.ok()) {
 
   69      return element_extent.status();
 
   71    extent += *element_extent;
 
   72    elements_pos += *element_extent;
 
   79absl::Status EgltMsgpackSerialize(
const std::vector<T>& value,
 
   80                                  const InsertInfo& insert) {
 
   81  SerializedBytesVector result, encoded_size;
 
   83  if (value.size() <= 15) {
 
   85        static_cast<Byte
>(FormatSignature::kFixArray + value.size())};
 
   86  } 
else if (value.size() <= 65535) {
 
   87    encoded_size = ToBigEndianBytes<uint16_t>(value.size(), 1);
 
   88    encoded_size[0] = FormatSignature::kArray16;
 
   90    encoded_size = ToBigEndianBytes<uint32_t>(value.size(), 1);
 
   91    encoded_size[0] = FormatSignature::kArray32;
 
   96  result.reserve(encoded_size.size() + value.size() * 
sizeof(T));
 
   97  result.insert(result.end(), encoded_size.begin(), encoded_size.end());
 
   99  for (
const auto& element : value) {
 
  100    auto serialized_element = Serialize(element);
 
  101    if (!serialized_element.ok()) {
 
  102      return serialized_element.status();
 
  104    result.insert(result.end(), serialized_element->begin(),
 
  105                  serialized_element->end());
 
  108  insert.bytes->insert(insert.at, result.begin(), result.end());
 
  109  return absl::OkStatus();
 
  113absl::StatusOr<uint32_t> EgltMsgpackDeserialize(
 
  114    const LookupPointer& data, std::vector<T>* absl_nonnull output) {
 
  115  const auto [pos, end, _] = data;
 
  117  uint32_t length = -1;
 
  118  auto elements_pos = 
const_cast<Byte*
>(pos);
 
  120  if (*pos >= 0x90 && *pos <= 0x9F) {
 
  121    length = *pos - 0x90;  
 
  125  if (*pos == FormatSignature::kArray16) {
 
  127      return GetInsufficientDataError(data, 
"std::vector<T>");
 
  129    length = FromBigEndianBytes<uint16_t>(pos + 1);
 
  133  if (*pos == FormatSignature::kArray32) {
 
  135      return GetInsufficientDataError(data, 
"std::vector<T>");
 
  137    length = FromBigEndianBytes<uint32_t>(pos + 1);
 
  142    return GetInvalidFormatSignatureError(pos, 
"std::vector<T>", data.begin);
 
  145  if (elements_pos >= end) {
 
  146    return GetInsufficientDataError(data, 
"std::vector<T> elements");
 
  149  output->reserve(output->size() + length);
 
  150  for (uint32_t i = 0; i < length; ++i) {
 
  151    if (elements_pos >= end) {
 
  152      return GetInsufficientDataError(data, 
"std::vector<T> elements");
 
  154    auto expected_element_extent =
 
  155        EgltMsgpackGetExtent(LookupPointer(elements_pos, end),
 
  156                             static_cast<std::vector<T>*
>(
nullptr));
 
  157    if (!expected_element_extent.ok()) {
 
  158      return expected_element_extent.status();
 
  160    auto element = Deserialize<T>(LookupPointer(elements_pos, end));
 
  162      return element.status();
 
  164    output->push_back(std::move(element->value));
 
  165    DCHECK(*expected_element_extent == element->extent)
 
  166        << 
"Expected extent: " << *expected_element_extent
 
  167        << 
", actual extent: " << element->extent;
 
  168    elements_pos += element->extent;
 
  171  return elements_pos - pos;