Пример #1
0
/*
 * Read an EBML header.
 */
char *ebml_read_header(stream_t *s, int *version)
{
    uint64_t length, l, num;
    uint32_t id;
    char *str = NULL;

    if (ebml_read_master(s, &length) != EBML_ID_HEADER)
        return 0;

    if (version)
        *version = 1;

    while (length > 0) {
        id = ebml_read_id(s, NULL);
        if (id == EBML_ID_INVALID)
            return NULL;
        length -= 2;

        switch (id) {
            /* is our read version uptodate? */
        case EBML_ID_EBMLREADVERSION:
            num = ebml_read_uint(s, &l);
            if (num != EBML_VERSION)
                return NULL;
            break;

            /* we only handle 8 byte lengths at max */
        case EBML_ID_EBMLMAXSIZELENGTH:
            num = ebml_read_uint(s, &l);
            if (num != sizeof(uint64_t))
                return NULL;
            break;

            /* we handle 4 byte IDs at max */
        case EBML_ID_EBMLMAXIDLENGTH:
            num = ebml_read_uint(s, &l);
            if (num != sizeof(uint32_t))
                return NULL;
            break;

        case EBML_ID_DOCTYPE:
            str = ebml_read_ascii(s, &l);
            if (str == NULL)
                return NULL;
            break;

        case EBML_ID_DOCTYPEREADVERSION:
            num = ebml_read_uint(s, &l);
            if (num == EBML_UINT_INVALID)
                return NULL;
            if (version)
                *version = num;
            break;

            /* we ignore these two, they don't tell us anything we care about */
        case EBML_ID_VOID:
        case EBML_ID_EBMLVERSION:
        case EBML_ID_DOCTYPEVERSION:
        default:
            if (ebml_read_skip(s, &l))
                return NULL;
            break;
        }
        length -= l;
    }

    return str;
}
Пример #2
0
int ebml_check_header(ebml_parser_t *ebml) {
  uint32_t next_level;
  ebml_elem_t master;

  if (!ebml_read_elem_head(ebml, &master)) {
    xprintf(ebml->xine, XINE_VERBOSITY_LOG,
            "ebml: invalid master element\n");
    return 0;
  }

  if (master.id != EBML_ID_EBML) {
    xprintf(ebml->xine, XINE_VERBOSITY_LOG,
            "ebml: invalid master element\n");
    return 0;
  }

  if (!ebml_read_master (ebml, &master))
    return 0;

  next_level = 1;
  while (next_level == 1) {
    ebml_elem_t elem;

    if (!ebml_read_elem_head(ebml, &elem))
      return 0;

    switch (elem.id) {
      case EBML_ID_EBMLVERSION: {
        uint64_t num;

        if (!ebml_read_uint (ebml, &elem, &num))
          return 0;
        lprintf("ebml_version: %" PRIu64 "\n", num);
        ebml->version = num;
        break;
      }

      case EBML_ID_EBMLREADVERSION: {
        uint64_t num;

        if (!ebml_read_uint (ebml, &elem, &num))
          return 0;
        lprintf("ebml_read_version: %" PRIu64 "\n", num);
        if (num != EBML_VERSION)
          return 0;
        ebml->read_version = num;
        break;
      }

      case EBML_ID_EBMLMAXIDLENGTH: {
        uint64_t num;

        if (!ebml_read_uint (ebml, &elem, &num))
          return 0;
        lprintf("ebml_max_id_length: %" PRIu64 "\n", num);
        ebml->max_id_len = num;
        break;
      }

      case EBML_ID_EBMLMAXSIZELENGTH: {
        uint64_t num;

        if (!ebml_read_uint (ebml, &elem, &num))
          return 0;
        lprintf("ebml_max_size_length: %" PRIu64 "\n", num);
        ebml->max_size_len = num;
        break;
      }

      case EBML_ID_DOCTYPE: {
        char *text = ebml_alloc_read_ascii (ebml, &elem);
        if (!text)
          return 0;

        lprintf("doctype: %s\n", text);
        if (ebml->doctype)
          free (ebml->doctype);
        ebml->doctype = text;
        break;
      }

      case EBML_ID_DOCTYPEVERSION: {
        uint64_t num;

        if (!ebml_read_uint (ebml, &elem, &num))
          return 0;
        lprintf("doctype_version: %" PRIu64 "\n", num);
        ebml->doctype_version = num;
        break;
      }

      case EBML_ID_DOCTYPEREADVERSION: {
        uint64_t num;

        if (!ebml_read_uint (ebml, &elem, &num))
          return 0;
        lprintf("doctype_read_version: %" PRIu64 "\n", num);
        ebml->doctype_read_version = num;
        break;
      }

      default:
        xprintf(ebml->xine, XINE_VERBOSITY_LOG,
                "ebml: Unknown data type 0x%x in EBML header (ignored)\n", elem.id);
	ebml_skip(ebml, &elem);
    }
    next_level = ebml_get_next_level(ebml, &elem);
  }

  return 1;
}