// Copyright (c) 2010, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// map_serializers_inl.h: implementation for serializing std::map and its
// wrapper classes.
//
// See map_serializers.h for documentation.
//
// Author: Siyang Xie (lambxsy@google.com)

#ifndef PROCESSOR_MAP_SERIALIZERS_INL_H__
#define PROCESSOR_MAP_SERIALIZERS_INL_H__

#include <map>
#include <string>

#include "processor/map_serializers.h"
#include "processor/simple_serializer.h"

#include "processor/address_map-inl.h"
#include "processor/range_map-inl.h"
#include "processor/contained_range_map-inl.h"

#include "processor/logging.h"

namespace google_breakpad {

template<typename Key, typename Value>
size_t StdMapSerializer<Key, Value>::SizeOf(
    const std::map<Key, Value> &m) const {
  size_t size = 0;
  size_t header_size = (1 + m.size()) * sizeof(uint32_t);
  size += header_size;

  typename std::map<Key, Value>::const_iterator iter;
  for (iter = m.begin(); iter != m.end(); ++iter) {
    size += key_serializer_.SizeOf(iter->first);
    size += value_serializer_.SizeOf(iter->second);
  }
  return size;
}

template<typename Key, typename Value>
char *StdMapSerializer<Key, Value>::Write(const std::map<Key, Value> &m,
                                          char *dest) const {
  if (!dest) {
    BPLOG(ERROR) << "StdMapSerializer failed: write to NULL address.";
    return NULL;
  }
  char *start_address = dest;

  // Write header:
  // Number of nodes.
  dest = SimpleSerializer<uint32_t>::Write(m.size(), dest);
  // Nodes offsets.
  uint32_t *offsets = reinterpret_cast<uint32_t*>(dest);
  dest += sizeof(uint32_t) * m.size();

  char *key_address = dest;
  dest += sizeof(Key) * m.size();

  // Traverse map.
  typename std::map<Key, Value>::const_iterator iter;
  int index = 0;
  for (iter = m.begin(); iter != m.end(); ++iter, ++index) {
    offsets[index] = static_cast<uint32_t>(dest - start_address);
    key_address = key_serializer_.Write(iter->first, key_address);
    dest = value_serializer_.Write(iter->second, dest);
  }
  return dest;
}

template<typename Key, typename Value>
char *StdMapSerializer<Key, Value>::Serialize(
    const std::map<Key, Value> &m, unsigned int *size) const {
  // Compute size of memory to be allocated.
  unsigned int size_to_alloc = SizeOf(m);
  // Allocate memory.
  char *serialized_data = new char[size_to_alloc];
  if (!serialized_data) {
    BPLOG(INFO) << "StdMapSerializer memory allocation failed.";
    if (size) *size = 0;
    return NULL;
  }
  // Write serialized data into memory.
  Write(m, serialized_data);

  if (size) *size = size_to_alloc;
  return serialized_data;
}

template<typename Address, typename Entry>
size_t RangeMapSerializer<Address, Entry>::SizeOf(
    const RangeMap<Address, Entry> &m) const {
  size_t size = 0;
  size_t header_size = (1 + m.map_.size()) * sizeof(uint32_t);
  size += header_size;

  typename std::map<Address, Range>::const_iterator iter;
  for (iter = m.map_.begin(); iter != m.map_.end(); ++iter) {
    // Size of key (high address).
    size += address_serializer_.SizeOf(iter->first);
    // Size of base (low address).
    size += address_serializer_.SizeOf(iter->second.base());
    // Size of entry.
    size += entry_serializer_.SizeOf(iter->second.entry());
  }
  return size;
}

template<typename Address, typename Entry>
char *RangeMapSerializer<Address, Entry>::Write(
    const RangeMap<Address, Entry> &m, char *dest) const {
  if (!dest) {
    BPLOG(ERROR) << "RangeMapSerializer failed: write to NULL address.";
    return NULL;
  }
  char *start_address = dest;

  // Write header:
  // Number of nodes.
  dest = SimpleSerializer<uint32_t>::Write(m.map_.size(), dest);
  // Nodes offsets.
  uint32_t *offsets = reinterpret_cast<uint32_t*>(dest);
  dest += sizeof(uint32_t) * m.map_.size();

  char *key_address = dest;
  dest += sizeof(Address) * m.map_.size();

  // Traverse map.
  typename std::map<Address, Range>::const_iterator iter;
  int index = 0;
  for (iter = m.map_.begin(); iter != m.map_.end(); ++iter, ++index) {
    offsets[index] = static_cast<uint32_t>(dest - start_address);
    key_address = address_serializer_.Write(iter->first, key_address);
    dest = address_serializer_.Write(iter->second.base(), dest);
    dest = entry_serializer_.Write(iter->second.entry(), dest);
  }
  return dest;
}

template<typename Address, typename Entry>
char *RangeMapSerializer<Address, Entry>::Serialize(
    const RangeMap<Address, Entry> &m, unsigned int *size) const {
  // Compute size of memory to be allocated.
  unsigned int size_to_alloc = SizeOf(m);
  // Allocate memory.
  char *serialized_data = new char[size_to_alloc];
  if (!serialized_data) {
    BPLOG(INFO) << "RangeMapSerializer memory allocation failed.";
    if (size) *size = 0;
    return NULL;
  }

  // Write serialized data into memory.
  Write(m, serialized_data);

  if (size) *size = size_to_alloc;
  return serialized_data;
}


template<class AddrType, class EntryType>
size_t ContainedRangeMapSerializer<AddrType, EntryType>::SizeOf(
    const ContainedRangeMap<AddrType, EntryType> *m) const {
  size_t size = 0;
  size_t header_size = addr_serializer_.SizeOf(m->base_)
                       + entry_serializer_.SizeOf(m->entry_)
                       + sizeof(uint32_t);
  size += header_size;
  // In case m.map_ == NULL, we treat it as an empty map:
  size += sizeof(uint32_t);
  if (m->map_) {
    size += m->map_->size() * sizeof(uint32_t);
    typename Map::const_iterator iter;
    for (iter = m->map_->begin(); iter != m->map_->end(); ++iter) {
      size += addr_serializer_.SizeOf(iter->first);
      // Recursive calculation of size:
      size += SizeOf(iter->second);
    }
  }
  return size;
}

template<class AddrType, class EntryType>
char *ContainedRangeMapSerializer<AddrType, EntryType>::Write(
    const ContainedRangeMap<AddrType, EntryType> *m, char *dest) const {
  if (!dest) {
    BPLOG(ERROR) << "StdMapSerializer failed: write to NULL address.";
    return NULL;
  }
  dest = addr_serializer_.Write(m->base_, dest);
  dest = SimpleSerializer<uint32_t>::Write(entry_serializer_.SizeOf(m->entry_),
                                            dest);
  dest = entry_serializer_.Write(m->entry_, dest);

  // Write map<<AddrType, ContainedRangeMap*>:
  char *map_address = dest;
  if (m->map_ == NULL) {
    dest = SimpleSerializer<uint32_t>::Write(0, dest);
  } else {
    dest = SimpleSerializer<uint32_t>::Write(m->map_->size(), dest);
    uint32_t *offsets = reinterpret_cast<uint32_t*>(dest);
    dest += sizeof(uint32_t) * m->map_->size();

    char *key_address = dest;
    dest += sizeof(AddrType) * m->map_->size();

    // Traverse map.
    typename Map::const_iterator iter;
    int index = 0;
    for (iter = m->map_->begin(); iter != m->map_->end(); ++iter, ++index) {
      offsets[index] = static_cast<uint32_t>(dest - map_address);
      key_address = addr_serializer_.Write(iter->first, key_address);
      // Recursively write.
      dest = Write(iter->second, dest);
    }
  }
  return dest;
}

template<class AddrType, class EntryType>
char *ContainedRangeMapSerializer<AddrType, EntryType>::Serialize(
    const ContainedRangeMap<AddrType, EntryType> *m, unsigned int *size) const {
  unsigned int size_to_alloc = SizeOf(m);
  // Allocating memory.
  char *serialized_data = new char[size_to_alloc];
  if (!serialized_data) {
    BPLOG(INFO) << "ContainedRangeMapSerializer memory allocation failed.";
    if (size) *size = 0;
    return NULL;
  }
  Write(m, serialized_data);
  if (size) *size = size_to_alloc;
  return serialized_data;
}

}  // namespace google_breakpad

#endif  // PROCESSOR_MAP_SERIALIZERS_INL_H__
