/* GStreamer EBML I/O
 * (c) 2003 Ronald Bultje <rbultje@ronald.bitfreak.net>
 *
 * ebml-read.c: read EBML data from file/stream
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <string.h>

#include "ebml-read.h"
#include "ebml-ids.h"

#include <math.h>

/* NAN is supposed to be in math.h, Microsoft defines it in xmath.h
 * However, starting iwth Visual Studio 8, NAN is defined by default */
#if defined (_MSC_VER) && _MSC_VER < 1500
#include <xmath.h>
#endif

/* If everything goes wrong try 0.0/0.0 which should be NAN */
#ifndef NAN
#define NAN (0.0 / 0.0)
#endif

GST_DEBUG_CATEGORY (ebmlread_debug);
#define GST_CAT_DEFAULT ebmlread_debug

/* Peeks following element id and element length in datastream provided
 * by @peek with @ctx as user data.
 * Returns GST_FLOW_EOS if not enough data to read id and length.
 * Otherwise, @needed provides the prefix length (id + length), and
 * @length provides element length.
 *
 * @object and @offset are provided for informative messaging/debug purposes.
 */
GstFlowReturn
gst_ebml_peek_id_length (guint32 * _id, guint64 * _length, guint * _needed,
    GstPeekData peek, gpointer * ctx, GstElement * el, guint64 offset)
{
  guint needed;
  const guint8 *buf;
  gint len_mask = 0x80, read = 1, n = 1, num_ffs = 0;
  guint64 total;
  guint8 b;
  GstFlowReturn ret;

  g_return_val_if_fail (_id != NULL, GST_FLOW_ERROR);
  g_return_val_if_fail (_length != NULL, GST_FLOW_ERROR);
  g_return_val_if_fail (_needed != NULL, GST_FLOW_ERROR);

  /* well ... */
  *_id = (guint32) GST_EBML_SIZE_UNKNOWN;
  *_length = GST_EBML_SIZE_UNKNOWN;

  /* read element id */
  needed = 2;
  ret = peek (ctx, needed, &buf);
  if (ret != GST_FLOW_OK)
    goto peek_error;
  b = GST_READ_UINT8 (buf);
  total = (guint64) b;
  while (read <= 4 && !(total & len_mask)) {
    read++;
    len_mask >>= 1;
  }
  if (G_UNLIKELY (read > 4))
    goto invalid_id;

  /* need id and at least something for subsequent length */
  needed = read + 1;
  ret = peek (ctx, needed, &buf);
  if (ret != GST_FLOW_OK)
    goto peek_error;
  while (n < read) {
    b = GST_READ_UINT8 (buf + n);
    total = (total << 8) | b;
    ++n;
  }
  *_id = (guint32) total;

  /* read element length */
  b = GST_READ_UINT8 (buf + n);
  total = (guint64) b;
  len_mask = 0x80;
  read = 1;
  while (read <= 8 && !(total & len_mask)) {
    read++;
    len_mask >>= 1;
  }
  if (G_UNLIKELY (read > 8))
    goto invalid_length;
  if ((total &= (len_mask - 1)) == len_mask - 1)
    num_ffs++;

  needed += read - 1;
  ret = peek (ctx, needed, &buf);
  if (ret != GST_FLOW_OK)
    goto peek_error;
  buf += (needed - read);
  n = 1;
  while (n < read) {
    guint8 b = GST_READ_UINT8 (buf + n);

    if (G_UNLIKELY (b == 0xff))
      num_ffs++;
    total = (total << 8) | b;
    ++n;
  }

  if (G_UNLIKELY (read == num_ffs))
    *_length = G_MAXUINT64;
  else
    *_length = total;

  *_needed = needed;

  return GST_FLOW_OK;

  /* ERRORS */
peek_error:
  {
    if (ret != GST_FLOW_FLUSHING)
      GST_WARNING_OBJECT (el, "peek failed, ret = %s", gst_flow_get_name (ret));
    else
      GST_DEBUG_OBJECT (el, "peek failed, ret = %s", gst_flow_get_name (ret));
    *_needed = needed;
    return ret;
  }
invalid_id:
  {
    GST_ERROR_OBJECT (el,
        "Invalid EBML ID size tag (0x%x) at position %" G_GUINT64_FORMAT " (0x%"
        G_GINT64_MODIFIER "x)", (guint) b, offset, offset);
    return GST_FLOW_ERROR;
  }
invalid_length:
  {
    GST_ERROR_OBJECT (el,
        "Invalid EBML length size tag (0x%x) at position %" G_GUINT64_FORMAT
        " (0x%" G_GINT64_MODIFIER "x)", (guint) b, offset, offset);
    return GST_FLOW_ERROR;
  }
}

/* setup for parsing @buf at position @offset on behalf of @el.
 * Takes ownership of @buf. */
void
gst_ebml_read_init (GstEbmlRead * ebml, GstElement * el, GstBuffer * buf,
    guint64 offset)
{
  GstEbmlMaster m;

  g_return_if_fail (el);
  g_return_if_fail (buf);

  ebml->el = el;
  ebml->offset = offset;
  ebml->buf = buf;
  gst_buffer_map (buf, &ebml->map, GST_MAP_READ);
  ebml->readers = g_array_sized_new (FALSE, FALSE, sizeof (GstEbmlMaster), 10);
  m.offset = ebml->offset;
  gst_byte_reader_init (&m.br, ebml->map.data, ebml->map.size);
  g_array_append_val (ebml->readers, m);
}

void
gst_ebml_read_clear (GstEbmlRead * ebml)
{
  if (ebml->readers)
    g_array_free (ebml->readers, TRUE);
  ebml->readers = NULL;
  if (ebml->buf) {
    gst_buffer_unmap (ebml->buf, &ebml->map);
    gst_buffer_unref (ebml->buf);
  }
  ebml->buf = NULL;
  ebml->el = NULL;
}

static GstFlowReturn
gst_ebml_read_peek (GstByteReader * br, guint peek, const guint8 ** data)
{
  if (G_LIKELY (gst_byte_reader_peek_data (br, peek, data)))
    return GST_FLOW_OK;
  else
    return GST_FLOW_EOS;
}

static GstFlowReturn
gst_ebml_peek_id_full (GstEbmlRead * ebml, guint32 * id, guint64 * length,
    guint * prefix)
{
  GstFlowReturn ret;

  ret = gst_ebml_peek_id_length (id, length, prefix,
      (GstPeekData) gst_ebml_read_peek, (gpointer) gst_ebml_read_br (ebml),
      ebml->el, gst_ebml_read_get_pos (ebml));
  if (ret != GST_FLOW_OK)
    return ret;

  GST_LOG_OBJECT (ebml->el, "id 0x%x at offset 0x%" G_GINT64_MODIFIER "x"
      " of length %" G_GUINT64_FORMAT ", prefix %d", *id,
      gst_ebml_read_get_pos (ebml), *length, *prefix);

#ifndef GST_DISABLE_GST_DEBUG
  if (ebmlread_debug->threshold >= GST_LEVEL_LOG) {
    const guint8 *data = NULL;
    GstByteReader *br = gst_ebml_read_br (ebml);
    guint size = gst_byte_reader_get_remaining (br);

    if (gst_byte_reader_peek_data (br, size, &data)) {

      GST_LOG_OBJECT (ebml->el, "current br %p; remaining %d", br, size);
      if (data)
        GST_MEMDUMP_OBJECT (ebml->el, "element", data, MIN (size, *length));
    }
  }
#endif

  return ret;
}

GstFlowReturn
gst_ebml_peek_id (GstEbmlRead * ebml, guint32 * id)
{
  guint64 length;
  guint needed;

  return gst_ebml_peek_id_full (ebml, id, &length, &needed);
}

/*
 * Read the next element, the contents are supposed to be sub-elements which
 * can be read separately.  A new bytereader is setup for doing so.
 */
GstFlowReturn
gst_ebml_read_master (GstEbmlRead * ebml, guint32 * id)
{
  guint64 length;
  guint prefix;
  const guint8 *data = NULL;
  GstFlowReturn ret;
  GstEbmlMaster m;

  ret = gst_ebml_peek_id_full (ebml, id, &length, &prefix);
  if (ret != GST_FLOW_OK)
    return ret;

  /* we just at least peeked the id */
  if (!gst_byte_reader_skip (gst_ebml_read_br (ebml), prefix))
    return GST_FLOW_ERROR;      /* FIXME: do proper error handling */

  m.offset = gst_ebml_read_get_pos (ebml);
  if (!gst_byte_reader_get_data (gst_ebml_read_br (ebml), length, &data))
    return GST_FLOW_PARSE;

  GST_LOG_OBJECT (ebml->el, "pushing level %d at offset %" G_GUINT64_FORMAT,
      ebml->readers->len, m.offset);
  gst_byte_reader_init (&m.br, data, length);
  g_array_append_val (ebml->readers, m);

  return GST_FLOW_OK;
}

/* explicitly pop a bytereader from stack.  Usually invoked automagically. */
GstFlowReturn
gst_ebml_read_pop_master (GstEbmlRead * ebml)
{
  g_return_val_if_fail (ebml->readers, GST_FLOW_ERROR);

  /* never remove initial bytereader */
  if (ebml->readers->len > 1) {
    GST_LOG_OBJECT (ebml->el, "popping level %d", ebml->readers->len - 1);
    g_array_remove_index (ebml->readers, ebml->readers->len - 1);
  }

  return GST_FLOW_OK;
}

/*
 * Skip the next element.
 */

GstFlowReturn
gst_ebml_read_skip (GstEbmlRead * ebml)
{
  guint64 length;
  guint32 id;
  guint prefix;
  GstFlowReturn ret;

  ret = gst_ebml_peek_id_full (ebml, &id, &length, &prefix);
  if (ret != GST_FLOW_OK)
    return ret;

  if (!gst_byte_reader_skip (gst_ebml_read_br (ebml), length + prefix))
    return GST_FLOW_PARSE;

  return ret;
}

/*
 * Read the next element as a GstBuffer (binary).
 */

GstFlowReturn
gst_ebml_read_buffer (GstEbmlRead * ebml, guint32 * id, GstBuffer ** buf)
{
  guint64 length;
  guint prefix;
  GstFlowReturn ret;

  ret = gst_ebml_peek_id_full (ebml, id, &length, &prefix);
  if (ret != GST_FLOW_OK)
    return ret;

  /* we just at least peeked the id */
  if (!gst_byte_reader_skip (gst_ebml_read_br (ebml), prefix))
    return GST_FLOW_ERROR;      /* FIXME: do proper error handling */

  if (G_LIKELY (length > 0)) {
    guint offset;

    offset = gst_ebml_read_get_pos (ebml) - ebml->offset;
    if (G_LIKELY (gst_byte_reader_skip (gst_ebml_read_br (ebml), length))) {
      *buf = gst_buffer_copy_region (ebml->buf, GST_BUFFER_COPY_ALL,
          offset, length);
    } else {
      *buf = NULL;
      return GST_FLOW_PARSE;
    }
  } else {
    *buf = gst_buffer_new ();
  }

  return ret;
}

/*
 * Read the next element, return a pointer to it and its size.
 */

static GstFlowReturn
gst_ebml_read_bytes (GstEbmlRead * ebml, guint32 * id, const guint8 ** data,
    guint * size)
{
  guint64 length;
  guint prefix;
  GstFlowReturn ret;

  *size = 0;

  ret = gst_ebml_peek_id_full (ebml, id, &length, &prefix);
  if (ret != GST_FLOW_OK)
    return ret;

  /* we just at least peeked the id */
  if (!gst_byte_reader_skip (gst_ebml_read_br (ebml), prefix))
    return GST_FLOW_ERROR;      /* FIXME: do proper error handling */

  *data = NULL;
  if (G_LIKELY (length > 0)) {
    if (!gst_byte_reader_get_data (gst_ebml_read_br (ebml), length, data))
      return GST_FLOW_PARSE;
  }

  *size = length;

  return ret;
}

/*
 * Read the next element as an unsigned int.
 */

GstFlowReturn
gst_ebml_read_uint (GstEbmlRead * ebml, guint32 * id, guint64 * num)
{
  const guint8 *data;
  guint size;
  GstFlowReturn ret;

  ret = gst_ebml_read_bytes (ebml, id, &data, &size);
  if (ret != GST_FLOW_OK)
    return ret;

  if (size > 8) {
    GST_ERROR_OBJECT (ebml->el,
        "Invalid integer element size %d at position %" G_GUINT64_FORMAT " (0x%"
        G_GINT64_MODIFIER "x)", size, gst_ebml_read_get_pos (ebml) - size,
        gst_ebml_read_get_pos (ebml) - size);
    return GST_FLOW_ERROR;
  }

  if (size == 0) {
    *num = 0;
    return ret;
  }

  *num = 0;
  while (size > 0) {
    *num = (*num << 8) | *data;
    size--;
    data++;
  }

  return ret;
}

/*
 * Read the next element as a signed int.
 */

GstFlowReturn
gst_ebml_read_sint (GstEbmlRead * ebml, guint32 * id, gint64 * num)
{
  const guint8 *data;
  guint size;
  gboolean negative = 0;
  GstFlowReturn ret;

  ret = gst_ebml_read_bytes (ebml, id, &data, &size);
  if (ret != GST_FLOW_OK)
    return ret;

  if (size > 8) {
    GST_ERROR_OBJECT (ebml->el,
        "Invalid integer element size %d at position %" G_GUINT64_FORMAT " (0x%"
        G_GINT64_MODIFIER "x)", size, gst_ebml_read_get_pos (ebml) - size,
        gst_ebml_read_get_pos (ebml) - size);
    return GST_FLOW_ERROR;
  }

  if (size == 0) {
    *num = 0;
    return ret;
  }

  *num = 0;
  if (*data & 0x80) {
    negative = 1;
    *num = *data & ~0x80;
    size--;
    data++;
  }

  while (size > 0) {
    *num = (*num << 8) | *data;
    size--;
    data++;
  }

  /* make signed */
  if (negative) {
    *num = 0 - *num;
  }

  return ret;
}

/* Convert 80 bit extended precision float in big endian format to double.
 * Code taken from libavutil/intfloat_readwrite.c from ffmpeg,
 * licensed under LGPL */

struct _ext_float
{
  guint8 exponent[2];
  guint8 mantissa[8];
};

static gdouble
_ext2dbl (const guint8 * data)
{
  struct _ext_float ext;
  guint64 m = 0;
  gint e, i;

  memcpy (&ext.exponent, data, 2);
  memcpy (&ext.mantissa, data + 2, 8);

  for (i = 0; i < 8; i++)
    m = (m << 8) + ext.mantissa[i];
  e = (((gint) ext.exponent[0] & 0x7f) << 8) | ext.exponent[1];
  if (e == 0x7fff && m)
    return NAN;
  e -= 16383 + 63;              /* In IEEE 80 bits, the whole (i.e. 1.xxxx)
                                 * mantissa bit is written as opposed to the
                                 * single and double precision formats */
  if (ext.exponent[0] & 0x80)
    m = -m;
  return ldexp (m, e);
}

/*
 * Read the next element as a float.
 */

GstFlowReturn
gst_ebml_read_float (GstEbmlRead * ebml, guint32 * id, gdouble * num)
{
  const guint8 *data;
  guint size;
  GstFlowReturn ret;

  ret = gst_ebml_read_bytes (ebml, id, &data, &size);
  if (ret != GST_FLOW_OK)
    return ret;

  if (size != 0 && size != 4 && size != 8 && size != 10) {
    GST_ERROR_OBJECT (ebml->el,
        "Invalid float element size %d at position %" G_GUINT64_FORMAT " (0x%"
        G_GINT64_MODIFIER "x)", size, gst_ebml_read_get_pos (ebml) - size,
        gst_ebml_read_get_pos (ebml) - size);
    return GST_FLOW_ERROR;
  }

  if (size == 4) {
    gfloat f;

    memcpy (&f, data, 4);
    f = GFLOAT_FROM_BE (f);

    *num = f;
  } else if (size == 8) {
    gdouble d;

    memcpy (&d, data, 8);
    d = GDOUBLE_FROM_BE (d);

    *num = d;
  } else if (size == 10) {
    *num = _ext2dbl (data);
  } else {
    /* size == 0 means a value of 0.0 */
    *num = 0.0;
  }

  return ret;
}

/*
 * Read the next element as a C string.
 */

static GstFlowReturn
gst_ebml_read_string (GstEbmlRead * ebml, guint32 * id, gchar ** str)
{
  const guint8 *data;
  guint size;
  GstFlowReturn ret;

  ret = gst_ebml_read_bytes (ebml, id, &data, &size);
  if (ret != GST_FLOW_OK)
    return ret;

  *str = g_malloc (size + 1);
  memcpy (*str, data, size);
  (*str)[size] = '\0';

  return ret;
}

/*
 * Read the next element as an ASCII string.
 */

GstFlowReturn
gst_ebml_read_ascii (GstEbmlRead * ebml, guint32 * id, gchar ** str_out)
{
  GstFlowReturn ret;
  gchar *str;
  gchar *iter;

#ifndef GST_DISABLE_GST_DEBUG
  guint64 oldoff = ebml->offset;
#endif

  ret = gst_ebml_read_string (ebml, id, &str);
  if (ret != GST_FLOW_OK)
    return ret;

  for (iter = str; *iter != '\0'; iter++) {
    if (G_UNLIKELY (*iter & 0x80)) {
      GST_ERROR_OBJECT (ebml,
          "Invalid ASCII string at offset %" G_GUINT64_FORMAT, oldoff);
      g_free (str);
      return GST_FLOW_ERROR;
    }
  }

  *str_out = str;
  return ret;
}

/*
 * Read the next element as a UTF-8 string.
 */

GstFlowReturn
gst_ebml_read_utf8 (GstEbmlRead * ebml, guint32 * id, gchar ** str)
{
  GstFlowReturn ret;

#ifndef GST_DISABLE_GST_DEBUG
  guint64 oldoff = gst_ebml_read_get_pos (ebml);
#endif

  ret = gst_ebml_read_string (ebml, id, str);
  if (ret != GST_FLOW_OK)
    return ret;

  if (str != NULL && *str != NULL && **str != '\0' &&
      !g_utf8_validate (*str, -1, NULL)) {
    GST_WARNING_OBJECT (ebml->el,
        "Invalid UTF-8 string at offset %" G_GUINT64_FORMAT, oldoff);
  }

  return ret;
}

/*
 * Read the next element as a date.
 * Returns the seconds since the unix epoch.
 */

GstFlowReturn
gst_ebml_read_date (GstEbmlRead * ebml, guint32 * id, gint64 * date)
{
  gint64 ebml_date;
  GstFlowReturn ret;

  ret = gst_ebml_read_sint (ebml, id, &ebml_date);
  if (ret != GST_FLOW_OK)
    return ret;

  *date = (ebml_date / GST_SECOND) + GST_EBML_DATE_OFFSET;

  return ret;
}

/*
 * Read the next element as binary data.
 */

GstFlowReturn
gst_ebml_read_binary (GstEbmlRead * ebml,
    guint32 * id, guint8 ** binary, guint64 * length)
{
  const guint8 *data;
  guint size;
  GstFlowReturn ret;

  ret = gst_ebml_read_bytes (ebml, id, &data, &size);
  if (ret != GST_FLOW_OK)
    return ret;

  *length = size;
  *binary = g_memdup (data, size);

  return GST_FLOW_OK;
}
