<commit_before>// This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.

#include "caf/message.hpp"

#include <utility>

#include "caf/actor_system.hpp"
#include "caf/binary_deserializer.hpp"
#include "caf/binary_serializer.hpp"
#include "caf/deserializer.hpp"
#include "caf/detail/meta_object.hpp"
#include "caf/detail/type_id_list_builder.hpp"
#include "caf/message_builder.hpp"
#include "caf/message_handler.hpp"
#include "caf/serializer.hpp"
#include "caf/string_algorithms.hpp"

#define GUARDED(statement)                                                     \
  if (!(statement))                                                            \
  return false

#define STOP(...)                                                              \
  do {                                                                         \
    source.emplace_error(__VA_ARGS__);                                         \
    return false;                                                              \
  } while (false)

namespace caf {

namespace {

bool load(const detail::meta_object& meta, caf::deserializer& source,
          void* obj) {
  return meta.load(source, obj);
}

bool load(const detail::meta_object& meta, caf::binary_deserializer& source,
          void* obj) {
  return meta.load_binary(source, obj);
}

template <class Deserializer>
bool load_data(Deserializer& source, message::data_ptr& data) {
  // For machine-to-machine data formats, we prefix the type information.
  if (!source.has_human_readable_format()) {
    GUARDED(source.begin_object(type_id_v<message>, "message"));
    GUARDED(source.begin_field("types"));
    size_t msg_size = 0;
    GUARDED(source.begin_sequence(msg_size));
    if (msg_size > std::numeric_limits<uint16_t>::max() - 1)
      STOP(sec::invalid_argument, "too many types for message");
    if (msg_size == 0) {
      data.reset();
      return source.end_sequence()           //
             && source.end_field()           //
             && source.begin_field("values") //
             && source.end_field()           //
             && source.end_object();
    }
    detail::type_id_list_builder ids;
    ids.reserve(msg_size);
    for (size_t i = 0; i < msg_size; ++i) {
      type_id_t id = 0;
      GUARDED(source.value(id));
      ids.push_back(id);
    }
    GUARDED(source.end_sequence());
    CAF_ASSERT(ids.size() == msg_size);
    size_t data_size = 0;
    for (auto id : ids) {
      if (auto meta_obj = detail::global_meta_object(id))
        data_size += meta_obj->padded_size;
      else
        STOP(sec::unknown_type);
    }
    intrusive_ptr<detail::message_data> ptr;
    if (auto vptr = malloc(sizeof(detail::message_data) + data_size)) {
      // We don't need to worry about exceptions here: the message_data<commit_msg>Fix sign-compare warning on GCC<commit_after>// This file is part of CAF, the C++ Actor Framework. See the file LICENSE in
// the main distribution directory for license terms and copyright or visit
// https://github.com/actor-framework/actor-framework/blob/master/LICENSE.

#include "caf/message.hpp"

#include <utility>

#include "caf/actor_system.hpp"
#include "caf/binary_deserializer.hpp"
#include "caf/binary_serializer.hpp"
#include "caf/deserializer.hpp"
#include "caf/detail/meta_object.hpp"
#include "caf/detail/type_id_list_builder.hpp"
#include "caf/message_builder.hpp"
#include "caf/message_handler.hpp"
#include "caf/serializer.hpp"
#include "caf/string_algorithms.hpp"

#define GUARDED(statement)                                                     \
  if (!(statement))                                                            \
  return false

#define STOP(...)                                                              \
  do {                                                                         \
    source.emplace_error(__VA_ARGS__);                                         \
    return false;                                                              \
  } while (false)

namespace caf {

namespace {

bool load(const detail::meta_object& meta, caf::deserializer& source,
          void* obj) {
  return meta.load(source, obj);
}

bool load(const detail::meta_object& meta, caf::binary_deserializer& source,
          void* obj) {
  return meta.load_binary(source, obj);
}

template <class Deserializer>
bool load_data(Deserializer& source, message::data_ptr& data) {
  // For machine-to-machine data formats, we prefix the type information.
  if (!source.has_human_readable_format()) {
    GUARDED(source.begin_object(type_id_v<message>, "message"));
    GUARDED(source.begin_field("types"));
    size_t msg_size = 0;
    GUARDED(source.begin_sequence(msg_size));
    using uint16_limits = std::numeric_limits<uint16_t>;
    if (msg_size > static_cast<size_t>(uint16_limits::max() - 1))
      STOP(sec::invalid_argument, "too many types for message");
    if (msg_size == 0) {
      data.reset();
      return source.end_sequence()           //
             && source.end_field()           //
             && source.begin_field("values") //
             && source.end_field()           //
             && source.end_object();
    }
    detail::type_id_list_builder ids;
    ids.reserve(msg_size);
    for (size_t i = 0; i < msg_size; ++i) {
      type_id_t id = 0;
      GUARDED(source.value(id));
      ids.push_back(id);
    }
    GUARDED(source.end_sequence());
    CAF_ASSERT(ids.size() == msg_size);
    size_t data_size = 0;
    for (auto id : ids) {
      if (auto meta_obj = detail::global_meta_object(id))
        data_size += meta_obj->padded_size;
      else
        STOP(sec::unknown_type);
    }
    intrusive_ptr<detail::message_data> ptr;
    if (auto vptr = malloc(sizeof(detail::message_data) + data_size)) {
      // We don't need to worry about exceptions here: the message_data
{'fraction_non_alphanumeric': 0.11911125960574674, 'fraction_numerical': 0.003341129301703976, 'mean_word_length': 2.147739221871714, 'pattern_counts': {'":': 0, '<': 16, '<?xml version=': 0, '>': 18, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 24, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '635908', 'n_tokens_mistral': 1797, 'n_tokens_neox': 1757, 'n_words': 380}