/* 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 */
#ifdef _MSC_VER
#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;
}
