/* 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
  {
    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;
}
