bloom_filter_alloc bloom_filter_alloc::internal_deserialize_or_wrap()

in filters/include/bloom_filter_impl.hpp [329:401]


bloom_filter_alloc<A> bloom_filter_alloc<A>::internal_deserialize_or_wrap(void* bytes,
                                                                          size_t length_bytes,
                                                                          bool read_only,
                                                                          bool wrap,
                                                                          const A& allocator)
{
  ensure_minimum_memory(length_bytes, 8);
  if (bytes == nullptr) {
    throw std::invalid_argument("Input data is null or empty");
  }
  const uint8_t* ptr = static_cast<const uint8_t*>(bytes);
  const uint8_t* end_ptr = ptr + length_bytes;
  const uint8_t prelongs = *ptr++;
  const uint8_t ser_ver = *ptr++;
  const uint8_t family = *ptr++;
  const uint8_t flags = *ptr++;

  if (prelongs < PREAMBLE_LONGS_EMPTY || prelongs > PREAMBLE_LONGS_STANDARD) {
    throw std::invalid_argument("Possible corruption: Incorrect number of preamble bytes specified in header");
  }
  if (ser_ver != SER_VER) {
    throw std::invalid_argument("Possible corruption: Unrecognized serialization version: " + std::to_string(ser_ver));
  }
  if (family != FAMILY_ID) {
    throw std::invalid_argument("Possible corruption: Incorrect Family ID for bloom filter. Found: " + std::to_string(family));
  }

  const bool is_empty = (flags & EMPTY_FLAG_MASK) != 0;

  ensure_minimum_memory(length_bytes, prelongs * sizeof(uint64_t));

  uint16_t num_hashes;
  ptr += copy_from_mem(ptr, num_hashes);
  ptr += sizeof(uint16_t); // 16 bits unused after num_hashes
  uint64_t seed;
  ptr += copy_from_mem(ptr, seed);

  uint32_t num_longs;
  ptr += copy_from_mem(ptr, num_longs); // sized in java longs
  ptr += sizeof(uint32_t); // unused 32 bits follow

  // if empty, stop reading
  if (wrap && is_empty && !read_only) {
    throw std::invalid_argument("Cannot wrap an empty filter for writing");
  } else if (is_empty) {
    return bloom_filter_alloc<A>(num_longs << 6, num_hashes, seed, allocator);
  }

  uint64_t num_bits_set;
  ptr += copy_from_mem(ptr, num_bits_set);
  const bool is_dirty = (num_bits_set == DIRTY_BITS_VALUE);

  uint8_t* bit_array;
  uint8_t* memory;
  if (wrap) {
    memory = static_cast<uint8_t*>(bytes);
    bit_array = memory + BIT_ARRAY_OFFSET_BYTES;
  } else {
    // allocate memory
    memory = nullptr;
    const uint64_t num_bytes = num_longs << 3;
    ensure_minimum_memory(end_ptr - ptr, num_bytes);
    AllocUint8 alloc(allocator);
    bit_array = alloc.allocate(num_bytes);
    if (bit_array == nullptr) {
      throw std::bad_alloc();
    }
    copy_from_mem(ptr, bit_array, num_bytes);
  }

  // pass to constructor -- !wrap == is_owned_
  return bloom_filter_alloc<A>(seed, num_hashes, is_dirty, !wrap, read_only, num_longs << 6, num_bits_set, bit_array, memory, allocator);
}