/*
 * svn_temp_serializer.c: implement the tempoary structure serialization API
 *
 * ====================================================================
 *    Licensed to the Apache Software Foundation (ASF) under one
 *    or more contributor license agreements.  See the NOTICE file
 *    distributed with this work for additional information
 *    regarding copyright ownership.  The ASF licenses this file
 *    to you under the Apache License, Version 2.0 (the
 *    "License"); you may not use this file except in compliance
 *    with the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing,
 *    software distributed under the License is distributed on an
 *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *    KIND, either express or implied.  See the License for the
 *    specific language governing permissions and limitations
 *    under the License.
 * ====================================================================
 */

#include <assert.h>
#include "private/svn_temp_serializer.h"
#include "svn_string.h"

/* This is a very efficient serialization and especially efficient
 * deserialization framework. The idea is just to concatenate all sub-
 * structures and strings into a single buffer while preserving proper
 * member alignment. Pointers will be replaced by the respective data
 * offsets in the buffer when that target that it pointed to gets
 * serialized, i.e. appended to the data buffer written so far.
 *
 * Hence, deserialization can be simply done by copying the buffer and
 * adjusting the pointers. No fine-grained allocation and copying is
 * necessary.
 */

/* An element in the structure stack. It contains a pointer to the source
 * structure so that the relative offset of sub-structure or string
 * references can be determined properly. It also contains the corresponding
 * position within the serialized data. Thus, pointers can be serialized
 * as offsets within the target buffer.
 */
typedef struct source_stack_t
{
  /* the source structure passed in to *_init or *_push */
  const void *source_struct;

  /* offset within the target buffer to where the structure got copied */
  apr_size_t target_offset;

  /* parent stack entry. Will be NULL for the root entry.
   * Items in the svn_temp_serializer__context_t recycler will use this
   * to link to the next unused item. */
  struct source_stack_t *upper;
} source_stack_t;

/* Serialization context info. It basically consists of the buffer holding
 * the serialized result and the stack of source structure information.
 */
struct svn_temp_serializer__context_t
{
  /* allocations are made from this pool */
  apr_pool_t *pool;

  /* the buffer holding all serialized data */
  svn_stringbuf_t *buffer;

  /* the stack of structures being serialized. If NULL, the serialization
   * process has been finished. However, it is not necessarily NULL when
   * the application end serialization. */
  source_stack_t *source;

  /* unused stack elements will be put here for later reuse. */
  source_stack_t *recycler;
};

/* Make sure the serialized data len is a multiple of the default alignment,
 * i.e. structures may be appended without violating member alignment
 * guarantees.
 */
static void
align_buffer_end(svn_temp_serializer__context_t *context)
{
  apr_size_t current_len = context->buffer->len;
  apr_size_t aligned_len = APR_ALIGN_DEFAULT(current_len);

  if (aligned_len + 1 > context->buffer->blocksize)
    svn_stringbuf_ensure(context->buffer, aligned_len);

   context->buffer->len = aligned_len;
}

/* Begin the serialization process for the SOURCE_STRUCT and all objects
 * referenced from it. STRUCT_SIZE must match the result of sizeof() of
 * the actual structure. You may suggest a larger initial buffer size
 * in SUGGESTED_BUFFER_SIZE to minimize the number of internal buffer
 * re-allocations during the serialization process. All allocations will
 * be made from POOL.
 */
svn_temp_serializer__context_t *
svn_temp_serializer__init(const void *source_struct,
                          apr_size_t struct_size,
                          apr_size_t suggested_buffer_size,
                          apr_pool_t *pool)
{
  /* select a meaningful initial memory buffer capacity */
  apr_size_t init_size = suggested_buffer_size < struct_size
                       ? struct_size
                       : suggested_buffer_size;

  /* create the serialization context and initialize it */
  svn_temp_serializer__context_t *context = apr_palloc(pool, sizeof(*context));
  context->pool = pool;
  context->buffer = svn_stringbuf_create_ensure(init_size, pool);
  context->recycler = NULL;

  /* If a source struct has been given, make it the root struct. */
  if (source_struct)
    {
      context->source = apr_palloc(pool, sizeof(*context->source));
      context->source->source_struct = source_struct;
      context->source->target_offset = 0;
      context->source->upper = NULL;

      /* serialize, i.e. append, the content of the first structure */
      svn_stringbuf_appendbytes(context->buffer, source_struct, struct_size);
    }
    else
    {
      /* The root struct will be set with the first push() op, or not at all
       * (in case of a plain string). */
      context->source = NULL;
    }

  /* done */
  return context;
}

/* Continue the serialization process of the SOURCE_STRUCT that has already
 * been serialized to BUFFER but contains references to new objects yet to
 * serialize. The current size of the serialized data is given in
 * CURRENTLY_USED. If the allocated data buffer is actually larger, you may
 * specify that in CURRENTLY_ALLOCATED to prevent unnecessary allocations.
 * Otherwise, set it to 0. All allocations will be made from POOl.
 */
svn_temp_serializer__context_t *
svn_temp_serializer__init_append(void *buffer,
                                 void *source_struct,
                                 apr_size_t currently_used,
                                 apr_size_t currently_allocated,
                                 apr_pool_t *pool)
{
  /* determine the current memory buffer capacity */
  apr_size_t init_size = currently_allocated < currently_used
                       ? currently_used
                       : currently_allocated;

  /* create the serialization context and initialize it */
  svn_temp_serializer__context_t *context = apr_palloc(pool, sizeof(*context));
  context->pool = pool;

  /* use BUFFER as serialization target */
  context->buffer = svn_stringbuf_create_ensure(0, pool);
  context->buffer->data = buffer;
  context->buffer->len = currently_used;
  context->buffer->blocksize = init_size;

  /* SOURCE_STRUCT is our serialization root */
  context->source = apr_palloc(pool, sizeof(*context->source));
  context->source->source_struct = source_struct;
  context->source->target_offset = (char *)source_struct - (char *)buffer;
  context->source->upper = NULL;

  /* initialize the RECYCLER */
  context->recycler = NULL;

  /* done */
  return context;
}

/* Utility function replacing the serialized pointer corresponding to
 * *SOURCE_POINTER with the offset that it will be put when being append
 * right after this function call.
 */
static void
store_current_end_pointer(svn_temp_serializer__context_t *context,
                          const void * const * source_pointer)
{
  apr_size_t ptr_offset;
  apr_size_t *target_ptr;

  /* if *source_pointer is the root struct, there will be no parent structure
   * to relate it to */
  if (context->source == NULL)
    return;

  /* position of the serialized pointer relative to the begin of the buffer */
  ptr_offset = (const char *)source_pointer
             - (const char *)context->source->source_struct
             + context->source->target_offset;

  /* the offset must be within the serialized data. Otherwise, you forgot
   * to serialize the respective sub-struct. */
  assert(context->buffer->len > ptr_offset);

  /* use the serialized pointer as a storage for the offset */
  target_ptr = (apr_size_t*)(context->buffer->data + ptr_offset);

  /* store the current buffer length because that's where we will append
   * the serialized data of the sub-struct or string */
  *target_ptr = *source_pointer == NULL
              ? 0
              : context->buffer->len - context->source->target_offset;
}

/* Begin serialization of a referenced sub-structure within the
 * serialization CONTEXT. SOURCE_STRUCT must be a reference to the pointer
 * in the original parent structure so that the correspondence in the
 * serialized structure can be established. STRUCT_SIZE must match the
 * result of sizeof() of the actual structure.
 */
void
svn_temp_serializer__push(svn_temp_serializer__context_t *context,
                          const void * const * source_struct,
                          apr_size_t struct_size)
{
  const void *source = *source_struct;
  source_stack_t *new;

  /* recycle an old entry or create a new one for the structure stack */
  if (context->recycler)
    {
      new = context->recycler;
      context->recycler = new->upper;
    }
  else
    new = apr_palloc(context->pool, sizeof(*new));

  /* the serialized structure must be properly aligned */
  if (source)
    align_buffer_end(context);

  /* Store the offset at which the struct data that will the appended.
   * Write 0 for NULL pointers. */
  store_current_end_pointer(context, source_struct);

  /* store source and target information */
  new->source_struct = source;
  new->target_offset = context->buffer->len;

  /* put the new entry onto the stack*/
  new->upper = context->source;
  context->source = new;

  /* finally, actually append the new struct
   * (so we can now manipulate pointers within it) */
  if (*source_struct)
    svn_stringbuf_appendbytes(context->buffer, source, struct_size);
}

/* Remove the latest structure from the stack.
 */
void
svn_temp_serializer__pop(svn_temp_serializer__context_t *context)
{
  source_stack_t *old = context->source;

  /* we may pop the original struct but not further */
  assert(context->source);

  /* one level up the structure stack */
  context->source = context->source->upper;

  /* put the old stack element into the recycler for later reuse */
  old->upper = context->recycler;
  context->recycler = old;
}

void
svn_temp_serializer__add_leaf(svn_temp_serializer__context_t *context,
                              const void * const * source_struct,
                              apr_size_t struct_size)
{
  const void *source = *source_struct;

  /* the serialized structure must be properly aligned */
  if (source)
    align_buffer_end(context);

  /* Store the offset at which the struct data that will the appended.
   * Write 0 for NULL pointers. */
  store_current_end_pointer(context, source_struct);

  /* finally, actually append the struct contents */
  if (*source_struct)
    svn_stringbuf_appendbytes(context->buffer, source, struct_size);
}

/* Serialize a string referenced from the current structure within the
 * serialization CONTEXT. S must be a reference to the char* pointer in
 * the original structure so that the correspondence in the serialized
 * structure can be established.
 */
void
svn_temp_serializer__add_string(svn_temp_serializer__context_t *context,
                                const char * const * s)
{
  const char *string = *s;

  /* Store the offset at which the string data that will the appended.
   * Write 0 for NULL pointers. Strings don't need special alignment. */
  store_current_end_pointer(context, (const void *const *)s);

  /* append the string data */
  if (string)
    svn_stringbuf_appendbytes(context->buffer, string, strlen(string) + 1);
}

/* Set the serialized representation of the pointer PTR inside the current
 * structure within the serialization CONTEXT to NULL. This is particularly
 * useful if the pointer is not NULL in the source structure.
 */
void
svn_temp_serializer__set_null(svn_temp_serializer__context_t *context,
                              const void * const * ptr)
{
  apr_size_t offset;

  /* there must be a parent structure */
  assert(context->source);

  /* position of the serialized pointer relative to the begin of the buffer */
  offset = (const char *)ptr
         - (const char *)context->source->source_struct
         + context->source->target_offset;

  /* the offset must be within the serialized data. Otherwise, you forgot
   * to serialize the respective sub-struct. */
  assert(context->buffer->len > offset);

  /* use the serialized pointer as a storage for the offset */
  *(apr_size_t*)(context->buffer->data + offset) = 0;
}

/* Return the number of bytes currently used in the serialization buffer
 * of the given serialization CONTEXT.*/
apr_size_t
svn_temp_serializer__get_length(svn_temp_serializer__context_t *context)
{
  return context->buffer->len;
}

/* Return the data buffer that receives the serialized data from
 * the given serialization CONTEXT.
 */
svn_stringbuf_t *
svn_temp_serializer__get(svn_temp_serializer__context_t *context)
{
  return context->buffer;
}

/* Replace the deserialized pointer value at PTR inside BUFFER with a
 * proper pointer value.
 */
void
svn_temp_deserializer__resolve(const void *buffer, void **ptr)
{
  /* All pointers are stored as offsets to the buffer start
   * (of the respective serialized sub-struct). */
  apr_size_t ptr_offset = *(apr_size_t *)ptr;
  if (ptr_offset)
    {
      /* Reconstruct the original pointer value */
      const char *target = (const char *)buffer + ptr_offset;

      /* All sub-structs are written _after_ their respective parent.
       * Thus, all offsets are > 0. If the following assertion is not met,
       * the data is either corrupt or you tried to resolve the pointer
       * more than once. */
      assert(target > (const char *)buffer);

      /* replace the PTR_OFFSET in *ptr with the pointer to TARGET */
      (*(const char **)ptr) = target;
    }
  else
    {
      /* NULL pointers are stored as 0 which might have a different
       * binary representation. */
      *ptr = NULL;
    }
}

const void *
svn_temp_deserializer__ptr(const void *buffer, const void *const *ptr)
{
  return (apr_size_t)*ptr == 0
      ? NULL
      : (const char*)buffer + (apr_size_t)*ptr;
}
