mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 23:31:56 +00:00
Bug 833403 - Integrate libwebvtt into Mozilla. r=ted
- Updated for new build system (2/28/2013) - declaration-after-statement no longer breaking MSVC build - Source files and scripts now contain appropriate license info - media/webvtt/update.sh no longer hiding unexpected/significant errors.
This commit is contained in:
parent
0c4d15256c
commit
1a3621792c
@ -4221,6 +4221,7 @@ MOZ_OMX_PLUGIN=
|
||||
MOZ_VP8=
|
||||
MOZ_VP8_ERROR_CONCEALMENT=
|
||||
MOZ_VP8_ENCODER=
|
||||
MOZ_WEBVTT=1
|
||||
VPX_AS=
|
||||
VPX_ASFLAGS=
|
||||
VPX_AS_DASH_C_FLAG=
|
||||
@ -5700,6 +5701,10 @@ if test -n "$MOZ_OPUS"; then
|
||||
AC_DEFINE(MOZ_OPUS)
|
||||
fi
|
||||
|
||||
if test -n "$MOZ_WEBVTT"; then
|
||||
AC_DEFINE(MOZ_WEBVTT)
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Check alsa availability on Linux if using sydneyaudio
|
||||
dnl ========================================================
|
||||
@ -8827,6 +8832,7 @@ AC_SUBST(MOZ_VORBIS)
|
||||
AC_SUBST(MOZ_TREMOR)
|
||||
AC_SUBST(MOZ_OPUS)
|
||||
AC_SUBST(MOZ_WEBM)
|
||||
AC_SUBST(MOZ_WEBVTT)
|
||||
AC_SUBST(MOZ_DASH)
|
||||
AC_SUBST(MOZ_WMF)
|
||||
AC_SUBST(MOZ_MEDIA_PLUGINS)
|
||||
|
@ -121,6 +121,12 @@ ifdef MOZ_ENABLE_SKIA
|
||||
SHARED_LIBRARY_LIBS += $(MOZ_SKIA_LIBS)
|
||||
endif
|
||||
|
||||
ifdef MOZ_WEBVTT
|
||||
SHARED_LIBRARY_LIBS += \
|
||||
$(DEPTH)/media/webvtt/$(LIB_PREFIX)webvtt.$(LIB_SUFFIX) \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifdef MOZ_WEBRTC
|
||||
ifndef MOZ_WEBRTC_IN_LIBXUL
|
||||
DEFINES += -DMOZ_WEBRTC_GKMEDIA=1
|
||||
|
25
media/webvtt/LICENSE
Normal file
25
media/webvtt/LICENSE
Normal file
@ -0,0 +1,25 @@
|
||||
Copyright (c) 2013 Mozilla Foundation and Contributors
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
- Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
- Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
40
media/webvtt/Makefile.in
Normal file
40
media/webvtt/Makefile.in
Normal file
@ -0,0 +1,40 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DEPTH = @DEPTH@
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = webvtt
|
||||
LIBRARY_NAME = webvtt
|
||||
|
||||
EXPORTS_NAMESPACES = webvtt
|
||||
|
||||
DEFINES += \
|
||||
-DWEBVTT_NO_CONFIG_H=1 \
|
||||
-DWEBVTT_STATIC=1 \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS_webvtt = \
|
||||
include/webvtt/cue.h \
|
||||
include/webvtt/error.h \
|
||||
include/webvtt/parser.h \
|
||||
include/webvtt/string.h \
|
||||
include/webvtt/util.h \
|
||||
$(NULL)
|
||||
|
||||
CSRCS = \
|
||||
alloc.c \
|
||||
cue.c \
|
||||
cuetext.c \
|
||||
error.c \
|
||||
lexer.c \
|
||||
parser.c \
|
||||
string.c \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
7
media/webvtt/README_MOZILLA
Normal file
7
media/webvtt/README_MOZILLA
Normal file
@ -0,0 +1,7 @@
|
||||
These files are from the WebVTT library, and are extracted from rev
|
||||
cd5e95654f1fd6712fcf1941f8936870a484f65e of the git repository at
|
||||
https://github.com/mozilla/webvtt.
|
||||
|
||||
The following CPPFLAGS are used in order to build and link in Mozilla
|
||||
-DWEBVTT_NO_CONFIG_H=1 -- Prevent inclusion of generated headers
|
||||
-DWEBVTT_STATIC=1 -- Compile as a static library
|
114
media/webvtt/alloc.c
Normal file
114
media/webvtt/alloc.c
Normal file
@ -0,0 +1,114 @@
|
||||
/**
|
||||
* Copyright (c) 2013 Mozilla Foundation and Contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <webvtt/util.h>
|
||||
#if ( defined(__APPLE__) && defined(__MACH__) )
|
||||
#include <stdlib.h>
|
||||
#else
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
|
||||
static void *default_alloc( void *unused, webvtt_uint nb );
|
||||
static void default_free( void *unused, void *ptr );
|
||||
|
||||
struct {
|
||||
/**
|
||||
* Number of allocated objects. Forbid changing the allocator if this is not
|
||||
* equal to 0
|
||||
*/
|
||||
webvtt_uint n_alloc;
|
||||
webvtt_alloc_fn_ptr alloc;
|
||||
webvtt_free_fn_ptr free;
|
||||
void *alloc_data;
|
||||
} allocator = { 0, default_alloc, default_free, 0 };
|
||||
|
||||
static void *WEBVTT_CALLBACK
|
||||
default_alloc( void *unused, webvtt_uint nb )
|
||||
{
|
||||
return malloc( nb );
|
||||
}
|
||||
|
||||
static void WEBVTT_CALLBACK
|
||||
default_free( void *unused, void *ptr )
|
||||
{
|
||||
free( ptr );
|
||||
}
|
||||
|
||||
WEBVTT_EXPORT void
|
||||
webvtt_set_allocator( webvtt_alloc_fn_ptr alloc, webvtt_free_fn_ptr free, void *userdata )
|
||||
{
|
||||
/**
|
||||
* TODO:
|
||||
* This really needs a lock. But then, so does all the allocation/free
|
||||
* functions...
|
||||
* that could be a problem.
|
||||
*/
|
||||
if( allocator.n_alloc == 0 ) {
|
||||
if( alloc && free ) {
|
||||
allocator.alloc = alloc;
|
||||
allocator.free = free;
|
||||
allocator.alloc_data = userdata;
|
||||
} else if( !alloc && !free ) {
|
||||
allocator.alloc = &default_alloc;
|
||||
allocator.free = &default_free;
|
||||
allocator.alloc_data = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* public alloc/dealloc functions
|
||||
*/
|
||||
WEBVTT_EXPORT void *
|
||||
webvtt_alloc( webvtt_uint nb )
|
||||
{
|
||||
void *ret = allocator.alloc( allocator.alloc_data, nb );
|
||||
if( ret )
|
||||
{ ++allocator.n_alloc; }
|
||||
return ret;
|
||||
}
|
||||
|
||||
WEBVTT_EXPORT void *
|
||||
webvtt_alloc0( webvtt_uint nb )
|
||||
{
|
||||
void *ret = allocator.alloc( allocator.alloc_data, nb );
|
||||
if( ret ) {
|
||||
++allocator.n_alloc;
|
||||
memset( ret, 0, nb );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
WEBVTT_EXPORT void
|
||||
webvtt_free( void *data )
|
||||
{
|
||||
if( data && allocator.n_alloc ) {
|
||||
allocator.free( allocator.alloc_data, data );
|
||||
--allocator.n_alloc;
|
||||
}
|
||||
}
|
307
media/webvtt/cue.c
Normal file
307
media/webvtt/cue.c
Normal file
@ -0,0 +1,307 @@
|
||||
/**
|
||||
* Copyright (c) 2013 Mozilla Foundation and Contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "parser_internal.h"
|
||||
#include "cue_internal.h"
|
||||
|
||||
WEBVTT_EXPORT webvtt_status
|
||||
webvtt_create_cue( webvtt_cue **pcue )
|
||||
{
|
||||
webvtt_cue *cue;
|
||||
if( !pcue ) {
|
||||
return WEBVTT_INVALID_PARAM;
|
||||
}
|
||||
cue = (webvtt_cue *)webvtt_alloc0( sizeof(*cue) );
|
||||
if( !cue ) {
|
||||
return WEBVTT_OUT_OF_MEMORY;
|
||||
}
|
||||
/**
|
||||
* From http://dev.w3.org/html5/webvtt/#parsing (10/25/2012)
|
||||
*
|
||||
* Let cue's text track cue snap-to-lines flag be true.
|
||||
*
|
||||
* Let cue's text track cue line position be auto.
|
||||
*
|
||||
* Let cue's text track cue text position be 50.
|
||||
*
|
||||
* Let cue's text track cue size be 100.
|
||||
*
|
||||
* Let cue's text track cue alignment be middle alignment.
|
||||
*/
|
||||
webvtt_ref( &cue->refs );
|
||||
webvtt_init_string( &cue->id );
|
||||
cue->from = 0xFFFFFFFFFFFFFFFF;
|
||||
cue->until = 0xFFFFFFFFFFFFFFFF;
|
||||
cue->snap_to_lines = 1;
|
||||
cue->settings.position = 50;
|
||||
cue->settings.size = 100;
|
||||
cue->settings.align = WEBVTT_ALIGN_MIDDLE;
|
||||
cue->settings.line = WEBVTT_AUTO;
|
||||
cue->settings.vertical = WEBVTT_HORIZONTAL;
|
||||
|
||||
*pcue = cue;
|
||||
return WEBVTT_SUCCESS;
|
||||
}
|
||||
|
||||
WEBVTT_EXPORT void
|
||||
webvtt_ref_cue( webvtt_cue *cue )
|
||||
{
|
||||
if( cue ) {
|
||||
webvtt_ref( &cue->refs );
|
||||
}
|
||||
}
|
||||
|
||||
WEBVTT_EXPORT void
|
||||
webvtt_release_cue( webvtt_cue **pcue )
|
||||
{
|
||||
if( pcue && *pcue ) {
|
||||
webvtt_cue *cue = *pcue;
|
||||
*pcue = 0;
|
||||
if( webvtt_deref( &cue->refs ) == 0 ) {
|
||||
webvtt_release_string( &cue->id );
|
||||
webvtt_release_node( &cue->node_head );
|
||||
webvtt_free( cue );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WEBVTT_EXPORT int
|
||||
webvtt_validate_cue( webvtt_cue *cue )
|
||||
{
|
||||
if( cue ) {
|
||||
/**
|
||||
* validate cue-times (Can't do checks against previously parsed cuetimes.
|
||||
* That's the applications responsibility
|
||||
*/
|
||||
if( BAD_TIMESTAMP(cue->from) || BAD_TIMESTAMP(cue->until) ) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
if( cue->until <= cue->from ) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Don't do any payload validation, because this would involve parsing the
|
||||
* payload, which is optional.
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
|
||||
error:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static webvtt_node empty_node = {
|
||||
{ 1 }, /* init ref count */
|
||||
0, /* parent */
|
||||
WEBVTT_EMPTY_NODE /* node kind */
|
||||
};
|
||||
|
||||
WEBVTT_EXPORT void
|
||||
webvtt_ref_node( webvtt_node *node )
|
||||
{
|
||||
if( node ) {
|
||||
webvtt_ref( &node->refs );
|
||||
}
|
||||
}
|
||||
|
||||
WEBVTT_EXPORT void
|
||||
webvtt_init_node( webvtt_node **node )
|
||||
{
|
||||
if( *node != &empty_node ) {
|
||||
if( node && *node ) {
|
||||
webvtt_release_node( node );
|
||||
}
|
||||
*node = &empty_node;
|
||||
webvtt_ref_node( *node );
|
||||
}
|
||||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_create_node( webvtt_node **node, webvtt_node_kind kind, webvtt_node *parent )
|
||||
{
|
||||
webvtt_node *temp_node;
|
||||
|
||||
if( !node ) {
|
||||
return WEBVTT_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if( !( temp_node = (webvtt_node *)webvtt_alloc0(sizeof(*temp_node)) ) )
|
||||
{
|
||||
return WEBVTT_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
webvtt_ref_node( temp_node );
|
||||
temp_node->kind = kind;
|
||||
temp_node->parent = parent;
|
||||
*node = temp_node;
|
||||
|
||||
return WEBVTT_SUCCESS;
|
||||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_create_internal_node( webvtt_node **node, webvtt_node *parent, webvtt_node_kind kind,
|
||||
webvtt_stringlist *css_classes, webvtt_string *annotation )
|
||||
{
|
||||
webvtt_status status;
|
||||
webvtt_internal_node_data *node_data;
|
||||
|
||||
if( WEBVTT_FAILED( status = webvtt_create_node( node, kind, parent ) ) ) {
|
||||
return status;
|
||||
}
|
||||
|
||||
if ( !( node_data = (webvtt_internal_node_data *)webvtt_alloc0( sizeof(*node_data) ) ) )
|
||||
{
|
||||
return WEBVTT_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
webvtt_copy_stringlist( &node_data->css_classes, css_classes );
|
||||
webvtt_copy_string( &node_data->annotation, annotation );
|
||||
node_data->children = NULL;
|
||||
node_data->length = 0;
|
||||
node_data->alloc = 0;
|
||||
|
||||
(*node)->data.internal_data = node_data;
|
||||
|
||||
return WEBVTT_SUCCESS;
|
||||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_create_head_node( webvtt_node **node )
|
||||
{
|
||||
webvtt_status status;
|
||||
webvtt_string temp_annotation;
|
||||
|
||||
webvtt_init_string( &temp_annotation );
|
||||
if( WEBVTT_FAILED( status = webvtt_create_internal_node( node, NULL, WEBVTT_HEAD_NODE, NULL, &temp_annotation ) ) ) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return WEBVTT_SUCCESS;
|
||||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_create_time_stamp_leaf_node( webvtt_node **node, webvtt_node *parent, webvtt_timestamp time_stamp )
|
||||
{
|
||||
webvtt_status status;
|
||||
|
||||
if( WEBVTT_FAILED( status = webvtt_create_node( node, WEBVTT_TIME_STAMP, parent ) ) ) {
|
||||
return status;
|
||||
}
|
||||
|
||||
(*node)->data.timestamp = time_stamp;
|
||||
|
||||
return WEBVTT_SUCCESS;
|
||||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_create_text_leaf_node( webvtt_node **node, webvtt_node *parent, webvtt_string *text )
|
||||
{
|
||||
webvtt_status status;
|
||||
|
||||
if( WEBVTT_FAILED( status = webvtt_create_node( node, WEBVTT_TEXT, parent ) ) ) {
|
||||
return status;
|
||||
}
|
||||
|
||||
webvtt_copy_string( &(*node)->data.text, text );
|
||||
|
||||
return WEBVTT_SUCCESS;
|
||||
|
||||
}
|
||||
|
||||
WEBVTT_EXPORT void
|
||||
webvtt_release_node( webvtt_node **node )
|
||||
{
|
||||
webvtt_uint i;
|
||||
webvtt_node *n;
|
||||
|
||||
if( !node || !*node ) {
|
||||
return;
|
||||
}
|
||||
n = *node;
|
||||
|
||||
if( webvtt_deref( &n->refs ) == 0 ) {
|
||||
if( n->kind == WEBVTT_TEXT ) {
|
||||
webvtt_release_string( &n->data.text );
|
||||
} else if( WEBVTT_IS_VALID_INTERNAL_NODE( n->kind ) && n->data.internal_data ) {
|
||||
webvtt_release_stringlist( &n->data.internal_data->css_classes );
|
||||
webvtt_release_string( &n->data.internal_data->annotation );
|
||||
for( i = 0; i < n->data.internal_data->length; i++ ) {
|
||||
webvtt_release_node( n->data.internal_data->children + i );
|
||||
}
|
||||
webvtt_free( n->data.internal_data->children );
|
||||
webvtt_free( n->data.internal_data );
|
||||
}
|
||||
webvtt_free( n );
|
||||
}
|
||||
*node = 0;
|
||||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_attach_internal_node( webvtt_node *parent, webvtt_node *to_attach )
|
||||
{
|
||||
webvtt_node **next = 0;
|
||||
webvtt_internal_node_data *nd = 0;
|
||||
|
||||
if( !parent || !to_attach || !parent->data.internal_data ) {
|
||||
return WEBVTT_INVALID_PARAM;
|
||||
}
|
||||
nd = parent->data.internal_data;
|
||||
|
||||
if( nd->alloc == 0 ) {
|
||||
next = (webvtt_node **)webvtt_alloc0( sizeof( webvtt_node * ) * 8 );
|
||||
|
||||
if( !next ) {
|
||||
return WEBVTT_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
nd->children = next;
|
||||
nd->alloc = 8;
|
||||
}
|
||||
|
||||
if( nd->length + 1 >= ( nd->alloc / 3 ) * 2 ) {
|
||||
|
||||
next = (webvtt_node **)webvtt_alloc0( sizeof( *next ) * nd->alloc * 2 );
|
||||
|
||||
if( !next ) {
|
||||
return WEBVTT_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
nd->alloc *= 2;
|
||||
memcpy( next, nd->children, nd->length * sizeof( webvtt_node * ) );
|
||||
webvtt_free( nd->children );
|
||||
nd->children = next;
|
||||
}
|
||||
|
||||
nd->children[ nd->length++ ] = to_attach;
|
||||
webvtt_ref_node( to_attach );
|
||||
|
||||
return WEBVTT_SUCCESS;
|
||||
}
|
68
media/webvtt/cue_internal.h
Normal file
68
media/webvtt/cue_internal.h
Normal file
@ -0,0 +1,68 @@
|
||||
/**
|
||||
* Copyright (c) 2013 Mozilla Foundation and Contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __INTERN_CUE_H__
|
||||
# define __INTERN_CUE_H__
|
||||
# include <webvtt/string.h>
|
||||
# include <webvtt/cue.h>
|
||||
|
||||
/**
|
||||
* Routines for creating nodes.
|
||||
*/
|
||||
WEBVTT_INTERN webvtt_status webvtt_create_node( webvtt_node **node, webvtt_node_kind kind, webvtt_node *parent );
|
||||
WEBVTT_INTERN webvtt_status webvtt_create_internal_node( webvtt_node **node, webvtt_node *parent, webvtt_node_kind kind, webvtt_stringlist *css_classes, webvtt_string *annotation );
|
||||
/**
|
||||
* We probably shouldn't have a 'head node' type.
|
||||
* We should just return a list of node trees...
|
||||
*/
|
||||
WEBVTT_INTERN webvtt_status webvtt_create_head_node( webvtt_node **node );
|
||||
WEBVTT_INTERN webvtt_status webvtt_create_time_stamp_leaf_node( webvtt_node **node, webvtt_node *parent, webvtt_timestamp time_stamp );
|
||||
WEBVTT_INTERN webvtt_status webvtt_create_text_leaf_node( webvtt_node **node, webvtt_node *parent, webvtt_string *text );
|
||||
|
||||
/**
|
||||
* Attaches a node to the internal node list of another node.
|
||||
*/
|
||||
WEBVTT_INTERN webvtt_status webvtt_attach_internal_node( webvtt_node *parent, webvtt_node *to_attach );
|
||||
|
||||
/**
|
||||
* Private cue flags
|
||||
*/
|
||||
enum {
|
||||
CUE_HAVE_VERTICAL = (1 << 0),
|
||||
CUE_HAVE_SIZE = (1 << 1),
|
||||
CUE_HAVE_POSITION = (1 << 2),
|
||||
CUE_HAVE_LINE = (1 << 3),
|
||||
CUE_HAVE_ALIGN = (1 << 4),
|
||||
|
||||
CUE_HAVE_SETTINGS = (CUE_HAVE_VERTICAL | CUE_HAVE_SIZE
|
||||
| CUE_HAVE_POSITION | CUE_HAVE_LINE | CUE_HAVE_ALIGN),
|
||||
|
||||
CUE_HAVE_CUEPARAMS = 0x40000000,
|
||||
CUE_HAVE_ID = 0x80000000,
|
||||
};
|
||||
|
||||
#endif
|
790
media/webvtt/cuetext.c
Normal file
790
media/webvtt/cuetext.c
Normal file
@ -0,0 +1,790 @@
|
||||
/**
|
||||
* Copyright (c) 2013 Mozilla Foundation and Contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "parser_internal.h"
|
||||
#include "cuetext_internal.h"
|
||||
#include "cue_internal.h"
|
||||
#include "string_internal.h"
|
||||
|
||||
static void webvtt_skipwhite( webvtt_byte **position );
|
||||
|
||||
#ifdef min
|
||||
# undef min
|
||||
#endif
|
||||
#define min(a,b) ( (a) < (b) ? (a) : (b) )
|
||||
|
||||
/**
|
||||
* ERROR macro used for webvtt_parse_cuetext
|
||||
*/
|
||||
#undef ERROR
|
||||
#define ERROR(code) \
|
||||
do \
|
||||
{ \
|
||||
if( self->error ) \
|
||||
if( self->error( self->userdata, line, col, code ) < 0 ) \
|
||||
return WEBVTT_PARSE_ERROR; \
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* Macros for return statuses based on memory operations.
|
||||
* This is to avoid many if statements checking for multiple memory operation
|
||||
* return statuses in functions.
|
||||
*/
|
||||
#define CHECK_MEMORY_OP(status) \
|
||||
if( status != WEBVTT_SUCCESS ) \
|
||||
return status; \
|
||||
|
||||
#define CHECK_MEMORY_OP_JUMP(status_var, returned_status) \
|
||||
if( returned_status != WEBVTT_SUCCESS) \
|
||||
{ \
|
||||
status_var = returned_status; \
|
||||
goto dealloc; \
|
||||
} \
|
||||
|
||||
/**
|
||||
* This will only work on null-terminated strings, remember that!
|
||||
*/
|
||||
static void
|
||||
webvtt_skipwhite( webvtt_byte **position )
|
||||
{
|
||||
webvtt_byte *p = *position;
|
||||
while( *p && webvtt_iswhite(*p) ) {
|
||||
++p;
|
||||
}
|
||||
*position = p;
|
||||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_create_cuetext_token( webvtt_cuetext_token **token, webvtt_cuetext_token_type token_type )
|
||||
{
|
||||
webvtt_cuetext_token *temp_token = (webvtt_cuetext_token *)webvtt_alloc0( sizeof(*temp_token) );
|
||||
|
||||
if( !temp_token ) {
|
||||
return WEBVTT_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
temp_token->token_type = token_type;
|
||||
*token = temp_token;
|
||||
|
||||
return WEBVTT_SUCCESS;
|
||||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_create_cuetext_start_token( webvtt_cuetext_token **token, webvtt_string *tag_name,
|
||||
webvtt_stringlist *css_classes, webvtt_string *annotation )
|
||||
{
|
||||
webvtt_status status;
|
||||
webvtt_cuetext_start_token_data sd;
|
||||
|
||||
if( WEBVTT_FAILED( status = webvtt_create_cuetext_token( token, START_TOKEN ) ) ) {
|
||||
return status;
|
||||
}
|
||||
|
||||
webvtt_copy_string( &(*token)->tag_name, tag_name );
|
||||
webvtt_copy_stringlist( &sd.css_classes, css_classes );
|
||||
webvtt_copy_string( &sd.annotations, annotation );
|
||||
|
||||
(*token)->start_token_data = sd;
|
||||
|
||||
return WEBVTT_SUCCESS;
|
||||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_create_cuetext_end_token( webvtt_cuetext_token **token, webvtt_string *tag_name )
|
||||
{
|
||||
webvtt_status status;
|
||||
|
||||
if( WEBVTT_FAILED( status = webvtt_create_cuetext_token( token, END_TOKEN ) ) ) {
|
||||
return status;
|
||||
}
|
||||
|
||||
webvtt_copy_string( &(*token)->tag_name, tag_name );
|
||||
|
||||
return WEBVTT_SUCCESS;
|
||||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_create_cuetext_text_token( webvtt_cuetext_token **token, webvtt_string *text )
|
||||
{
|
||||
webvtt_status status;
|
||||
|
||||
if( WEBVTT_FAILED( status = webvtt_create_cuetext_token( token, TEXT_TOKEN ) ) ) {
|
||||
return status;
|
||||
}
|
||||
|
||||
webvtt_copy_string( &(*token)->text, text);
|
||||
|
||||
return WEBVTT_SUCCESS;
|
||||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_create_cuetext_timestamp_token( webvtt_cuetext_token **token, webvtt_timestamp time_stamp )
|
||||
{
|
||||
webvtt_status status;
|
||||
|
||||
if( WEBVTT_FAILED( status = webvtt_create_cuetext_token( token, TIME_STAMP_TOKEN ) ) ) {
|
||||
return status;
|
||||
}
|
||||
|
||||
(*token)->time_stamp = time_stamp;
|
||||
|
||||
return WEBVTT_SUCCESS;
|
||||
}
|
||||
|
||||
WEBVTT_INTERN void
|
||||
webvtt_delete_cuetext_token( webvtt_cuetext_token **token )
|
||||
{
|
||||
webvtt_cuetext_start_token_data data;
|
||||
webvtt_cuetext_token *t;
|
||||
|
||||
if( !token ) {
|
||||
return;
|
||||
}
|
||||
if( !*token ) {
|
||||
return;
|
||||
}
|
||||
t = *token;
|
||||
|
||||
/**
|
||||
* Note that time stamp tokens do not need to free any internal data because
|
||||
* they do not allocate anything.
|
||||
*/
|
||||
switch( t->token_type ) {
|
||||
case START_TOKEN:
|
||||
data = t->start_token_data;
|
||||
webvtt_release_stringlist( &data.css_classes );
|
||||
webvtt_release_string( &data.annotations );
|
||||
webvtt_release_string( &t->tag_name );
|
||||
break;
|
||||
case END_TOKEN:
|
||||
webvtt_release_string( &t->tag_name );
|
||||
break;
|
||||
case TEXT_TOKEN:
|
||||
webvtt_release_string( &t->text );
|
||||
break;
|
||||
}
|
||||
webvtt_free( t );
|
||||
*token = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Definitions for tag names that accept annotationsm
|
||||
*/
|
||||
#define V_TAG_LENGTH 1
|
||||
|
||||
webvtt_byte v_tag[V_TAG_LENGTH] = { UTF8_V };
|
||||
|
||||
WEBVTT_INTERN int
|
||||
tag_accepts_annotation( webvtt_string *tag_name )
|
||||
{
|
||||
return memcmp( webvtt_string_text( tag_name ), v_tag,
|
||||
min(webvtt_string_length( tag_name ), V_TAG_LENGTH) ) == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Definitions for tag tokens that are more then one character long.
|
||||
*/
|
||||
#define RUBY_TAG_LENGTH 4
|
||||
#define RUBY_TEXT_TAG_LENGTH 2
|
||||
|
||||
webvtt_byte ruby_tag[RUBY_TAG_LENGTH] = { UTF8_R, UTF8_U, UTF8_B, UTF8_Y };
|
||||
webvtt_byte rt_tag[RUBY_TEXT_TAG_LENGTH] = { UTF8_R, UTF8_T };
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_get_node_kind_from_tag_name( webvtt_string *tag_name, webvtt_node_kind *kind )
|
||||
{
|
||||
if( !tag_name || !kind ) {
|
||||
return WEBVTT_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if( webvtt_string_length(tag_name) == 1 ) {
|
||||
switch( webvtt_string_text(tag_name)[0] ) {
|
||||
case( UTF8_B ):
|
||||
*kind = WEBVTT_BOLD;
|
||||
break;
|
||||
case( UTF8_I ):
|
||||
*kind = WEBVTT_ITALIC;
|
||||
break;
|
||||
case( UTF8_U ):
|
||||
*kind = WEBVTT_UNDERLINE;
|
||||
break;
|
||||
case( UTF8_C ):
|
||||
*kind = WEBVTT_CLASS;
|
||||
break;
|
||||
case( UTF8_V ):
|
||||
*kind = WEBVTT_VOICE;
|
||||
break;
|
||||
}
|
||||
} else if( memcmp( webvtt_string_text(tag_name), ruby_tag, min(webvtt_string_length(tag_name), RUBY_TAG_LENGTH) ) == 0 ) {
|
||||
*kind = WEBVTT_RUBY;
|
||||
} else if( memcmp( webvtt_string_text(tag_name), rt_tag, min(webvtt_string_length(tag_name), RUBY_TEXT_TAG_LENGTH) ) == 0 ) {
|
||||
*kind = WEBVTT_RUBY_TEXT;
|
||||
} else {
|
||||
return WEBVTT_INVALID_TAG_NAME;
|
||||
}
|
||||
|
||||
return WEBVTT_SUCCESS;
|
||||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_create_node_from_token( webvtt_cuetext_token *token, webvtt_node **node, webvtt_node *parent )
|
||||
{
|
||||
webvtt_node_kind kind;
|
||||
|
||||
if( !token || !node || !parent ) {
|
||||
return WEBVTT_INVALID_PARAM;
|
||||
}
|
||||
|
||||
/**
|
||||
* We've recieved a node that is not null.
|
||||
* In order to prevent memory leaks caused by overwriting a node which the
|
||||
* caller has not released return unsuccessful.
|
||||
*/
|
||||
if( *node ) {
|
||||
return WEBVTT_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
switch ( token->token_type ) {
|
||||
case( TEXT_TOKEN ):
|
||||
return webvtt_create_text_leaf_node( node, parent, &token->text );
|
||||
break;
|
||||
case( START_TOKEN ):
|
||||
|
||||
CHECK_MEMORY_OP( webvtt_get_node_kind_from_tag_name( &token->tag_name, &kind) );
|
||||
|
||||
return webvtt_create_internal_node( node, parent, kind,
|
||||
token->start_token_data.css_classes, &token->start_token_data.annotations );
|
||||
|
||||
break;
|
||||
case ( TIME_STAMP_TOKEN ):
|
||||
return webvtt_create_time_stamp_leaf_node( node, parent, token->time_stamp );
|
||||
break;
|
||||
default:
|
||||
return WEBVTT_INVALID_TOKEN_TYPE;
|
||||
}
|
||||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_cuetext_tokenizer_data_state( webvtt_byte **position,
|
||||
webvtt_cuetext_token_state *token_state, webvtt_string *result )
|
||||
{
|
||||
for ( ; *token_state == DATA; (*position)++ ) {
|
||||
switch( **position ) {
|
||||
case UTF8_AMPERSAND:
|
||||
*token_state = ESCAPE;
|
||||
break;
|
||||
case UTF8_LESS_THAN:
|
||||
if( webvtt_string_length(result) == 0 ) {
|
||||
*token_state = TAG;
|
||||
} else {
|
||||
return WEBVTT_SUCCESS;
|
||||
}
|
||||
break;
|
||||
case UTF8_NULL_BYTE:
|
||||
return WEBVTT_SUCCESS;
|
||||
break;
|
||||
default:
|
||||
CHECK_MEMORY_OP( webvtt_string_putc( result, *position[0] ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return WEBVTT_UNFINISHED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Definitions for valid escape values.
|
||||
* The semicolon is implicit in the comparison.
|
||||
*/
|
||||
#define AMP_ESCAPE_LENGTH 4
|
||||
#define LT_ESCAPE_LENGTH 3
|
||||
#define GT_ESCAPE_LENGTH 3
|
||||
#define RLM_ESCAPE_LENGTH 4
|
||||
#define LRM_ESCAPE_LENGTH 4
|
||||
#define NBSP_ESCAPE_LENGTH 5
|
||||
#define RLM_REPLACE_LENGTH 3
|
||||
#define LRM_REPLACE_LENGTH 3
|
||||
#define NBSP_REPLACE_LENGTH 2
|
||||
|
||||
webvtt_byte amp_escape[AMP_ESCAPE_LENGTH] = { UTF8_AMPERSAND, UTF8_A, UTF8_M, UTF8_P };
|
||||
webvtt_byte lt_escape[LT_ESCAPE_LENGTH] = { UTF8_AMPERSAND, UTF8_L, UTF8_T };
|
||||
webvtt_byte gt_escape[GT_ESCAPE_LENGTH] = { UTF8_AMPERSAND, UTF8_G, UTF8_T };
|
||||
webvtt_byte rlm_escape[RLM_ESCAPE_LENGTH] = { UTF8_AMPERSAND, UTF8_R, UTF8_L, UTF8_M };
|
||||
webvtt_byte lrm_escape[LRM_ESCAPE_LENGTH] = { UTF8_AMPERSAND, UTF8_L, UTF8_R, UTF8_M };
|
||||
webvtt_byte nbsp_escape[NBSP_ESCAPE_LENGTH] = { UTF8_AMPERSAND, UTF8_N, UTF8_B, UTF8_S, UTF8_P };
|
||||
|
||||
webvtt_byte rlm_replace[RLM_REPLACE_LENGTH] = { UTF8_RIGHT_TO_LEFT_1,
|
||||
UTF8_RIGHT_TO_LEFT_2, UTF8_RIGHT_TO_LEFT_3 };
|
||||
webvtt_byte lrm_replace[LRM_REPLACE_LENGTH] = { UTF8_LEFT_TO_RIGHT_1,
|
||||
UTF8_LEFT_TO_RIGHT_2, UTF8_LEFT_TO_RIGHT_3 };
|
||||
webvtt_byte nbsp_replace[NBSP_REPLACE_LENGTH] = { UTF8_NO_BREAK_SPACE_1,
|
||||
UTF8_NO_BREAK_SPACE_2 };
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_cuetext_tokenizer_escape_state( webvtt_byte **position,
|
||||
webvtt_cuetext_token_state *token_state, webvtt_string *result )
|
||||
{
|
||||
webvtt_string buffer;
|
||||
webvtt_status status = WEBVTT_SUCCESS;
|
||||
|
||||
CHECK_MEMORY_OP_JUMP( status, webvtt_create_string( 1, &buffer ) );
|
||||
|
||||
/**
|
||||
* Append ampersand here because the algorithm is not able to add it to the
|
||||
* buffer when it reads it in the DATA state tokenizer.
|
||||
*/
|
||||
CHECK_MEMORY_OP_JUMP( status, webvtt_string_putc( &buffer, UTF8_AMPERSAND ) );
|
||||
|
||||
for( ; *token_state == ESCAPE; (*position)++ ) {
|
||||
/**
|
||||
* We have encountered a token termination point.
|
||||
* Append buffer to result and return success.
|
||||
*/
|
||||
if( **position == UTF8_NULL_BYTE || **position == UTF8_LESS_THAN ) {
|
||||
CHECK_MEMORY_OP_JUMP( status, webvtt_string_append_string( result, &buffer ) );
|
||||
goto dealloc;
|
||||
}
|
||||
/**
|
||||
* This means we have enocuntered a malformed escape character sequence.
|
||||
* This means that we need to add that malformed text to the result and
|
||||
* recreate the buffer to prepare for a new escape sequence.
|
||||
*/
|
||||
else if( **position == UTF8_AMPERSAND ) {
|
||||
CHECK_MEMORY_OP_JUMP( status, webvtt_string_append_string( result, &buffer ) );
|
||||
webvtt_release_string( &buffer );
|
||||
CHECK_MEMORY_OP_JUMP( status, webvtt_create_string( 1, &buffer ) );
|
||||
CHECK_MEMORY_OP_JUMP( status, webvtt_string_putc( &buffer, *position[0] ) );
|
||||
}
|
||||
/**
|
||||
* We've encountered the semicolon which is the end of an escape sequence.
|
||||
* Check if buffer contains a valid escape sequence and if it does append
|
||||
* the interpretation to result and change the state to DATA.
|
||||
*/
|
||||
else if( **position == UTF8_SEMI_COLON ) {
|
||||
if( memcmp( webvtt_string_text(&buffer), amp_escape, min(webvtt_string_length(&buffer), AMP_ESCAPE_LENGTH ) ) == 0 ) {
|
||||
CHECK_MEMORY_OP_JUMP( status, webvtt_string_putc( result, UTF8_AMPERSAND ) );
|
||||
} else if( memcmp( webvtt_string_text(&buffer), lt_escape, min(webvtt_string_length(&buffer), LT_ESCAPE_LENGTH ) ) == 0 ) {
|
||||
CHECK_MEMORY_OP_JUMP( status, webvtt_string_putc( result, UTF8_LESS_THAN ) );
|
||||
} else if( memcmp( webvtt_string_text(&buffer), gt_escape, min(webvtt_string_length(&buffer), GT_ESCAPE_LENGTH) ) == 0 ) {
|
||||
CHECK_MEMORY_OP_JUMP( status, webvtt_string_putc( result, UTF8_GREATER_THAN ) );
|
||||
} else if( memcmp( webvtt_string_text(&buffer), rlm_escape, min(webvtt_string_length(&buffer), RLM_ESCAPE_LENGTH) ) == 0 ) {
|
||||
CHECK_MEMORY_OP_JUMP( status, webvtt_string_append( result, rlm_replace, RLM_REPLACE_LENGTH ) );
|
||||
} else if( memcmp( webvtt_string_text(&buffer), lrm_escape, min(webvtt_string_length(&buffer), LRM_ESCAPE_LENGTH) ) == 0 ) {
|
||||
CHECK_MEMORY_OP_JUMP( status, webvtt_string_append( result, lrm_replace, LRM_REPLACE_LENGTH ) );
|
||||
} else if( memcmp( webvtt_string_text(&buffer), nbsp_escape, min(webvtt_string_length(&buffer), NBSP_ESCAPE_LENGTH) ) == 0 ) {
|
||||
CHECK_MEMORY_OP_JUMP( status, webvtt_string_append( result, nbsp_replace, NBSP_REPLACE_LENGTH ) );
|
||||
} else {
|
||||
CHECK_MEMORY_OP_JUMP( status, webvtt_string_append_string( result, &buffer ) );
|
||||
CHECK_MEMORY_OP_JUMP( status, webvtt_string_putc( result, **position ) );
|
||||
}
|
||||
|
||||
*token_state = DATA;
|
||||
}
|
||||
/**
|
||||
* Character is alphanumeric. This means we are in the body of the escape
|
||||
* sequence.
|
||||
*/
|
||||
else if( webvtt_isalphanum( **position ) ) {
|
||||
CHECK_MEMORY_OP_JUMP( status, webvtt_string_putc( &buffer, **position ) );
|
||||
}
|
||||
/**
|
||||
* If we have not found an alphanumeric character then we have encountered
|
||||
* a malformed escape sequence. Add buffer to result and continue to parse
|
||||
* in DATA state.
|
||||
*/
|
||||
else {
|
||||
CHECK_MEMORY_OP_JUMP( status, webvtt_string_append_string( result, &buffer ) );
|
||||
CHECK_MEMORY_OP_JUMP( status, webvtt_string_putc( result, **position ) );
|
||||
*token_state = DATA;
|
||||
}
|
||||
}
|
||||
|
||||
dealloc:
|
||||
webvtt_release_string( &buffer );
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_cuetext_tokenizer_tag_state( webvtt_byte **position,
|
||||
webvtt_cuetext_token_state *token_state, webvtt_string *result )
|
||||
{
|
||||
for( ; *token_state == TAG; (*position)++ ) {
|
||||
if( **position == UTF8_TAB || **position == UTF8_LINE_FEED ||
|
||||
**position == UTF8_CARRIAGE_RETURN || **position == UTF8_FORM_FEED ||
|
||||
**position == UTF8_SPACE ) {
|
||||
*token_state = START_TAG_ANNOTATION;
|
||||
} else if( webvtt_isdigit( **position ) ) {
|
||||
CHECK_MEMORY_OP( webvtt_string_putc( result, **position ) );
|
||||
*token_state = TIME_STAMP_TAG;
|
||||
} else {
|
||||
switch( **position ) {
|
||||
case UTF8_FULL_STOP:
|
||||
*token_state = START_TAG_CLASS;
|
||||
break;
|
||||
case UTF8_SOLIDUS:
|
||||
*token_state = END_TAG;
|
||||
break;
|
||||
case UTF8_GREATER_THAN:
|
||||
return WEBVTT_SUCCESS;
|
||||
break;
|
||||
case UTF8_NULL_BYTE:
|
||||
return WEBVTT_SUCCESS;
|
||||
break;
|
||||
default:
|
||||
CHECK_MEMORY_OP( webvtt_string_putc( result, **position ) );
|
||||
*token_state = START_TAG;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return WEBVTT_UNFINISHED;
|
||||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_cuetext_tokenizer_start_tag_state( webvtt_byte **position,
|
||||
webvtt_cuetext_token_state *token_state, webvtt_string *result )
|
||||
{
|
||||
for( ; *token_state == START_TAG; (*position)++ ) {
|
||||
if( **position == UTF8_TAB || **position == UTF8_FORM_FEED ||
|
||||
**position == UTF8_SPACE || **position == UTF8_LINE_FEED ||
|
||||
**position == UTF8_CARRIAGE_RETURN ) {
|
||||
*token_state = START_TAG_ANNOTATION;
|
||||
} else {
|
||||
switch( **position ) {
|
||||
case UTF8_TAB:
|
||||
*token_state = START_TAG_ANNOTATION;
|
||||
break;
|
||||
case UTF8_FULL_STOP:
|
||||
*token_state = START_TAG_CLASS;
|
||||
break;
|
||||
case UTF8_GREATER_THAN:
|
||||
return WEBVTT_SUCCESS;
|
||||
break;
|
||||
default:
|
||||
CHECK_MEMORY_OP( webvtt_string_putc( result, **position ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return WEBVTT_UNFINISHED;
|
||||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_cuetext_tokenizer_start_tag_class_state( webvtt_byte **position,
|
||||
webvtt_cuetext_token_state *token_state, webvtt_stringlist *css_classes )
|
||||
{
|
||||
webvtt_string buffer;
|
||||
webvtt_status status = WEBVTT_SUCCESS;
|
||||
|
||||
CHECK_MEMORY_OP( webvtt_create_string( 1, &buffer ) );
|
||||
|
||||
for( ; *token_state == START_TAG_CLASS; (*position)++ ) {
|
||||
if( **position == UTF8_TAB || **position == UTF8_FORM_FEED ||
|
||||
**position == UTF8_SPACE || **position == UTF8_LINE_FEED ||
|
||||
**position == UTF8_CARRIAGE_RETURN) {
|
||||
CHECK_MEMORY_OP_JUMP( status, webvtt_stringlist_push( css_classes, &buffer ) );
|
||||
*token_state = START_TAG_ANNOTATION;
|
||||
return WEBVTT_SUCCESS;
|
||||
} else if( **position == UTF8_GREATER_THAN || **position == UTF8_NULL_BYTE ) {
|
||||
CHECK_MEMORY_OP_JUMP( status, webvtt_stringlist_push( css_classes, &buffer ) );
|
||||
webvtt_release_string( &buffer );
|
||||
return WEBVTT_SUCCESS;
|
||||
} else if( **position == UTF8_FULL_STOP ) {
|
||||
CHECK_MEMORY_OP_JUMP( status, webvtt_stringlist_push( css_classes, &buffer ) );
|
||||
webvtt_release_string( &buffer );
|
||||
CHECK_MEMORY_OP( webvtt_create_string( 1, &buffer ) );
|
||||
} else {
|
||||
CHECK_MEMORY_OP_JUMP( status, webvtt_string_putc( &buffer, **position ) );
|
||||
}
|
||||
}
|
||||
|
||||
dealloc:
|
||||
webvtt_release_string( &buffer );
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_cuetext_tokenizer_start_tag_annotation_state( webvtt_byte **position,
|
||||
webvtt_cuetext_token_state *token_state, webvtt_string *annotation )
|
||||
{
|
||||
for( ; *token_state == START_TAG_ANNOTATION; (*position)++ ) {
|
||||
if( **position == UTF8_NULL_BYTE || **position == UTF8_GREATER_THAN ) {
|
||||
return WEBVTT_SUCCESS;
|
||||
}
|
||||
CHECK_MEMORY_OP( webvtt_string_putc( annotation, **position ) );
|
||||
}
|
||||
|
||||
return WEBVTT_UNFINISHED;
|
||||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_cuetext_tokenizer_end_tag_state( webvtt_byte **position,
|
||||
webvtt_cuetext_token_state *token_state, webvtt_string *result )
|
||||
{
|
||||
for( ; *token_state == END_TAG; (*position)++ ) {
|
||||
if( **position == UTF8_GREATER_THAN || **position == UTF8_NULL_BYTE ) {
|
||||
return WEBVTT_SUCCESS;
|
||||
}
|
||||
CHECK_MEMORY_OP( webvtt_string_putc( result, **position ) );
|
||||
}
|
||||
|
||||
return WEBVTT_UNFINISHED;
|
||||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_cuetext_tokenizer_time_stamp_tag_state( webvtt_byte **position,
|
||||
webvtt_cuetext_token_state *token_state, webvtt_string *result )
|
||||
{
|
||||
for( ; *token_state == TIME_STAMP_TAG; (*position)++ ) {
|
||||
if( **position == UTF8_GREATER_THAN || **position == UTF8_NULL_BYTE ) {
|
||||
return WEBVTT_SUCCESS;
|
||||
}
|
||||
CHECK_MEMORY_OP( webvtt_string_putc( result, **position ) );
|
||||
}
|
||||
|
||||
return WEBVTT_UNFINISHED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Need to set up differently.
|
||||
* Get a status in order to return at end and release memeory.
|
||||
*/
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_cuetext_tokenizer( webvtt_byte **position, webvtt_cuetext_token **token )
|
||||
{
|
||||
webvtt_cuetext_token_state token_state = DATA;
|
||||
webvtt_string result, annotation;
|
||||
webvtt_stringlist *css_classes;
|
||||
webvtt_timestamp time_stamp = 0;
|
||||
webvtt_status status = WEBVTT_UNFINISHED;
|
||||
|
||||
if( !position ) {
|
||||
return WEBVTT_INVALID_PARAM;
|
||||
}
|
||||
|
||||
webvtt_create_string( 10, &result );
|
||||
webvtt_create_string( 10, &annotation );
|
||||
webvtt_create_stringlist( &css_classes );
|
||||
|
||||
/**
|
||||
* Loop while the tokenizer is not finished.
|
||||
* Based on the state of the tokenizer enter a function to handle that
|
||||
* particular tokenizer state. Those functions will loop until they either
|
||||
* change the state of the tokenizer or reach a valid token end point.
|
||||
*/
|
||||
while( status == WEBVTT_UNFINISHED ) {
|
||||
switch( token_state ) {
|
||||
case DATA :
|
||||
status = webvtt_cuetext_tokenizer_data_state( position, &token_state, &result );
|
||||
break;
|
||||
case ESCAPE:
|
||||
status = webvtt_cuetext_tokenizer_escape_state( position, &token_state, &result );
|
||||
break;
|
||||
case TAG:
|
||||
status = webvtt_cuetext_tokenizer_tag_state( position, &token_state, &result );
|
||||
break;
|
||||
case START_TAG:
|
||||
status = webvtt_cuetext_tokenizer_start_tag_state( position, &token_state, &result );
|
||||
break;
|
||||
case START_TAG_CLASS:
|
||||
status = webvtt_cuetext_tokenizer_start_tag_class_state( position, &token_state, css_classes );
|
||||
break;
|
||||
case START_TAG_ANNOTATION:
|
||||
status = webvtt_cuetext_tokenizer_start_tag_annotation_state( position, &token_state, &annotation );
|
||||
break;
|
||||
case END_TAG:
|
||||
status = webvtt_cuetext_tokenizer_end_tag_state( position, &token_state, &result );
|
||||
break;
|
||||
case TIME_STAMP_TAG:
|
||||
status = webvtt_cuetext_tokenizer_time_stamp_tag_state( position, &token_state, &result );
|
||||
break;
|
||||
}
|
||||
|
||||
if( token_state == START_TAG_ANNOTATION ) {
|
||||
webvtt_skipwhite( position );
|
||||
}
|
||||
}
|
||||
|
||||
if( **position == UTF8_GREATER_THAN )
|
||||
{ (*position)++; }
|
||||
|
||||
if( status == WEBVTT_SUCCESS ) {
|
||||
/**
|
||||
* The state that the tokenizer left off on will tell us what kind of token
|
||||
* needs to be made.
|
||||
*/
|
||||
if( token_state == DATA || token_state == ESCAPE ) {
|
||||
status = webvtt_create_cuetext_text_token( token, &result );
|
||||
} else if(token_state == TAG || token_state == START_TAG || token_state == START_TAG_CLASS ||
|
||||
token_state == START_TAG_ANNOTATION) {
|
||||
/**
|
||||
* If the tag does not accept an annotation then release the current
|
||||
* annotation and intialize annotation to a safe empty state
|
||||
*/
|
||||
if( !tag_accepts_annotation( &result ) ) {
|
||||
webvtt_release_string( &annotation );
|
||||
webvtt_init_string( &annotation );
|
||||
}
|
||||
status = webvtt_create_cuetext_start_token( token, &result, css_classes, &annotation );
|
||||
} else if( token_state == END_TAG ) {
|
||||
status = webvtt_create_cuetext_end_token( token, &result );
|
||||
} else if( token_state == TIME_STAMP_TAG ) {
|
||||
parse_timestamp( webvtt_string_text( &result ), &time_stamp );
|
||||
status = webvtt_create_cuetext_timestamp_token( token, time_stamp );
|
||||
} else {
|
||||
status = WEBVTT_INVALID_TOKEN_STATE;
|
||||
}
|
||||
}
|
||||
|
||||
webvtt_release_stringlist( &css_classes );
|
||||
webvtt_release_string( &result );
|
||||
webvtt_release_string( &annotation );
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Currently line and len are not being kept track of.
|
||||
* Don't think pnode_length is needed as nodes track there list count
|
||||
* internally.
|
||||
*/
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_parse_cuetext( webvtt_parser self, webvtt_cue *cue, webvtt_string *payload, int finished )
|
||||
{
|
||||
|
||||
const webvtt_byte *cue_text;
|
||||
webvtt_status status;
|
||||
webvtt_byte *position;
|
||||
webvtt_node *node_head;
|
||||
webvtt_node *current_node;
|
||||
webvtt_node *temp_node;
|
||||
webvtt_cuetext_token *token;
|
||||
webvtt_node_kind kind;
|
||||
|
||||
if( !cue ) {
|
||||
return WEBVTT_INVALID_PARAM;
|
||||
}
|
||||
|
||||
cue_text = webvtt_string_text( payload );
|
||||
|
||||
if( !cue_text ) {
|
||||
return WEBVTT_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if ( WEBVTT_FAILED(status = webvtt_create_head_node( &cue->node_head ) ) ) {
|
||||
return status;
|
||||
}
|
||||
|
||||
position = (webvtt_byte *)cue_text;
|
||||
node_head = cue->node_head;
|
||||
current_node = node_head;
|
||||
temp_node = NULL;
|
||||
token = NULL;
|
||||
|
||||
/**
|
||||
* Routine taken from the W3C specification
|
||||
* http://dev.w3.org/html5/webvtt/#webvtt-cue-text-parsing-rules
|
||||
*/
|
||||
while( *position != UTF8_NULL_BYTE ) {
|
||||
|
||||
webvtt_delete_cuetext_token( &token );
|
||||
|
||||
/* Step 7. */
|
||||
switch( webvtt_cuetext_tokenizer( &position, &token ) ) {
|
||||
case( WEBVTT_UNFINISHED ):
|
||||
/* Error here. */
|
||||
break;
|
||||
/* Step 8. */
|
||||
case( WEBVTT_SUCCESS ):
|
||||
|
||||
/**
|
||||
* If we've found an end token which has a valid end token tag name and
|
||||
* a tag name that is equal to the current node then set current to the
|
||||
* parent of current.
|
||||
*/
|
||||
if( token->token_type == END_TOKEN ) {
|
||||
/**
|
||||
* We have encountered an end token but we are at the top of the list
|
||||
* and thus have not encountered any start tokens yet, throw away the
|
||||
* token.
|
||||
*/
|
||||
if( current_node->kind == WEBVTT_HEAD_NODE ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* We have encountered an end token but it is not in a format that is
|
||||
* supported, throw away the token.
|
||||
*/
|
||||
if( webvtt_get_node_kind_from_tag_name( &token->tag_name, &kind ) == WEBVTT_INVALID_TAG_NAME ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* We have encountered an end token and it matches the start token of
|
||||
* the node that we are currently on. Move back up the list of nodes
|
||||
* and continue parsing.
|
||||
*/
|
||||
if( current_node->kind == kind ) {
|
||||
current_node = current_node->parent;
|
||||
}
|
||||
} else {
|
||||
|
||||
/**
|
||||
* Attempt to create a valid node from the token.
|
||||
* If successful then attach the node to the current nodes list and
|
||||
* also set current to the newly created node if it is an internal
|
||||
* node type.
|
||||
*/
|
||||
if( webvtt_create_node_from_token( token, &temp_node, current_node ) != WEBVTT_SUCCESS ) {
|
||||
/* Do something here? */
|
||||
}
|
||||
else {
|
||||
webvtt_attach_internal_node( current_node, temp_node );
|
||||
|
||||
if( WEBVTT_IS_VALID_INTERNAL_NODE( temp_node->kind ) ) {
|
||||
current_node = temp_node;
|
||||
}
|
||||
|
||||
/* Release the node as attach internal node increases the count. */
|
||||
webvtt_release_node( &temp_node );
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
webvtt_skipwhite( &position );
|
||||
}
|
||||
|
||||
webvtt_delete_cuetext_token( &token );
|
||||
|
||||
return WEBVTT_SUCCESS;
|
||||
}
|
195
media/webvtt/cuetext_internal.h
Normal file
195
media/webvtt/cuetext_internal.h
Normal file
@ -0,0 +1,195 @@
|
||||
/**
|
||||
* Copyright (c) 2013 Mozilla Foundation and Contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __INTERN_CUETEXT_H__
|
||||
# define __INTERN_CUETEXT_H__
|
||||
# include <webvtt/util.h>
|
||||
# include <webvtt/string.h>
|
||||
# include <webvtt/cue.h>
|
||||
|
||||
typedef enum webvtt_cuetext_token_type_t webvtt_cuetext_token_type;
|
||||
typedef enum webvtt_cuetext_token_state_t webvtt_cuetext_token_state;
|
||||
|
||||
typedef struct webvtt_cuetext_token_t webvtt_cuetext_token;
|
||||
typedef struct webvtt_cuetext_start_token_data_t webvtt_cuetext_start_token_data;
|
||||
|
||||
/**
|
||||
* Enumerates token types.
|
||||
*/
|
||||
enum
|
||||
webvtt_cuetext_token_type_t {
|
||||
START_TOKEN, /* Identifies a webvtt_cue_text_start_tag_token. */
|
||||
END_TOKEN, /* Identifies a webvtt_cue_text_end_tag_token. */
|
||||
TIME_STAMP_TOKEN, /* Identifies a webvtt_cue_text_time_stamp_token. */
|
||||
TEXT_TOKEN /* Identifies a webvtt_cue_text_text_token. */
|
||||
};
|
||||
|
||||
/**
|
||||
* Enumerates possible states that the cue text tokenizer can be in.
|
||||
*/
|
||||
enum
|
||||
webvtt_cuetext_token_state_t {
|
||||
DATA, /* Initial state. */
|
||||
ESCAPE, /* Parsing an escape value. */
|
||||
TAG, /* Reached a '<' character, about to start parsing a tag. */
|
||||
START_TAG, /* Parsing the beginning of a tag i.e. the tag name. */
|
||||
START_TAG_CLASS, /* Parsing a tag class. Reached when the tokenizer in the
|
||||
START_TAG
|
||||
state reaches a '.' character. */
|
||||
START_TAG_ANNOTATION, /* Parsing a tag annotation. Reached when the tokenizer
|
||||
in the START_TAG_CLASS state reaches a TAB, SPACE, or
|
||||
FORM FEED character. */
|
||||
END_TAG, /* Parsing an end tag. Reached when a '<' character is follwed by a
|
||||
'/' character. */
|
||||
TIME_STAMP_TAG /* Parsing a time stamp tag. Reached when a '<' character is
|
||||
follwed by an integer character. */
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents a start tag in the cue text.
|
||||
* These take the form of <[TAG_NAME].[CLASSES] [POSSIBLE_ANNOTATION]> in the
|
||||
* cue text.
|
||||
*/
|
||||
struct
|
||||
webvtt_cuetext_start_token_data_t {
|
||||
webvtt_stringlist *css_classes;
|
||||
webvtt_string annotations;
|
||||
};
|
||||
|
||||
/**
|
||||
* Contains a void pointer to a concrete token as well as a token type enum that
|
||||
* identifies what kind of token it is.
|
||||
*/
|
||||
struct
|
||||
webvtt_cuetext_token_t {
|
||||
webvtt_cuetext_token_type token_type;
|
||||
webvtt_string tag_name; // Only used for start token and end token types.
|
||||
union {
|
||||
webvtt_string text;
|
||||
webvtt_timestamp time_stamp;
|
||||
webvtt_cuetext_start_token_data start_token_data;
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Routines for creating cue text tokens.
|
||||
* Sets the passed token to the new token.
|
||||
*/
|
||||
WEBVTT_INTERN webvtt_status webvtt_create_cuetext_token( webvtt_cuetext_token **token, webvtt_cuetext_token_type token_type );
|
||||
WEBVTT_INTERN webvtt_status webvtt_create_cuetext_start_token( webvtt_cuetext_token **token, webvtt_string *tag_name,
|
||||
webvtt_stringlist *css_classes, webvtt_string *annotation );
|
||||
WEBVTT_INTERN webvtt_status webvtt_create_cuetext_end_token( webvtt_cuetext_token **token, webvtt_string *tag_name );
|
||||
WEBVTT_INTERN webvtt_status webvtt_create_cuetext_text_token( webvtt_cuetext_token **token, webvtt_string *text );
|
||||
WEBVTT_INTERN webvtt_status webvtt_create_cuetext_timestamp_token( webvtt_cuetext_token **token,
|
||||
webvtt_timestamp time_stamp );
|
||||
|
||||
/**
|
||||
* Returns true if the passed tag matches a tag name that accepts an annotation.
|
||||
*/
|
||||
WEBVTT_INTERN int tag_accepts_annotation( webvtt_string *tag_name );
|
||||
|
||||
/**
|
||||
* Routines for deleting cue text tokens.
|
||||
*/
|
||||
WEBVTT_INTERN void webvtt_delete_cuetext_token( webvtt_cuetext_token **token );
|
||||
|
||||
/**
|
||||
* Converts the textual representation of a node kind into a particular kind.
|
||||
* I.E. tag_name of 'ruby' would create a ruby kind, etc.
|
||||
* Returns a WEBVTT_NOT_SUPPORTED if it does not find a valid tag name.
|
||||
*/
|
||||
WEBVTT_INTERN webvtt_status webvtt_get_node_kind_from_tag_name( webvtt_string *tag_name, webvtt_node_kind *kind );
|
||||
|
||||
/**
|
||||
* Creates a node from a valid token.
|
||||
* Returns WEBVTT_NOT_SUPPORTED if it does not find a valid tag name.
|
||||
*/
|
||||
WEBVTT_INTERN webvtt_status webvtt_create_node_from_token( webvtt_cuetext_token *token, webvtt_node **node, webvtt_node *parent );
|
||||
|
||||
/**
|
||||
* Tokenizes the cue text into something that can be easily understood by the
|
||||
* cue text parser.
|
||||
* Referenced from - http://dev.w3.org/html5/webvtt/#webvtt-cue-text-tokenizer
|
||||
*/
|
||||
WEBVTT_INTERN webvtt_status webvtt_cuetext_tokenizer( webvtt_byte **position, webvtt_cuetext_token **token );
|
||||
|
||||
/**
|
||||
* Routines that take care of certain states in the webvtt cue text tokenizer.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Referenced from http://dev.w3.org/html5/webvtt/#webvtt-data-state
|
||||
*/
|
||||
WEBVTT_INTERN webvtt_status webvtt_cuetext_tokenizer_data_state( webvtt_byte **position,
|
||||
webvtt_cuetext_token_state *token_state, webvtt_string *result );
|
||||
|
||||
/**
|
||||
* Referenced from http://dev.w3.org/html5/webvtt/#webvtt-escape-state
|
||||
*/
|
||||
WEBVTT_INTERN webvtt_status webvtt_cuetext_tokenizer_escape_state( webvtt_byte **position,
|
||||
webvtt_cuetext_token_state *token_state, webvtt_string *result );
|
||||
|
||||
/**
|
||||
* Referenced from http://dev.w3.org/html5/webvtt/#webvtt-tag-state
|
||||
*/
|
||||
WEBVTT_INTERN webvtt_status webvtt_cuetext_tokenizer_tag_state( webvtt_byte **position,
|
||||
webvtt_cuetext_token_state *token_state, webvtt_string *result );
|
||||
|
||||
/**
|
||||
* Referenced from http://dev.w3.org/html5/webvtt/#webvtt-start-tag-state
|
||||
*/
|
||||
WEBVTT_INTERN webvtt_status webvtt_cuetext_tokenizer_start_tag_state( webvtt_byte **position,
|
||||
webvtt_cuetext_token_state *token_state, webvtt_string *result );
|
||||
|
||||
/**
|
||||
* Referenced from http://dev.w3.org/html5/webvtt/#webvtt-start-tag-class-state
|
||||
*/
|
||||
WEBVTT_INTERN webvtt_status webvtt_cuetext_tokenizer_start_tag_class_state( webvtt_byte **position,
|
||||
webvtt_cuetext_token_state *token_state, webvtt_stringlist *css_classes );
|
||||
|
||||
/**
|
||||
* Referenced from
|
||||
* http://dev.w3.org/html5/webvtt/#webvtt-start-tag-annotation-state
|
||||
*/
|
||||
WEBVTT_INTERN webvtt_status webvtt_cuetext_tokenizer_start_tag_annotation_state( webvtt_byte **position,
|
||||
webvtt_cuetext_token_state *token_state, webvtt_string *annotation );
|
||||
|
||||
/**
|
||||
* Referenced from http://dev.w3.org/html5/webvtt/#webvtt-end-tag-state
|
||||
*/
|
||||
WEBVTT_INTERN webvtt_status webvtt_cuetext_tokenizer_end_tag_state( webvtt_byte **position,
|
||||
webvtt_cuetext_token_state *token_state, webvtt_string *result );
|
||||
|
||||
/**
|
||||
* Referenced from http://dev.w3.org/html5/webvtt/#webvtt-timestamp-tag-state
|
||||
*/
|
||||
WEBVTT_INTERN webvtt_status webvtt_cuetext_tokenizer_time_stamp_tag_state( webvtt_byte **position,
|
||||
webvtt_cuetext_token_state *token_state, webvtt_string *result );
|
||||
|
||||
WEBVTT_INTERN webvtt_status webvtt_parse_cuetext( webvtt_parser self, webvtt_cue *cue, webvtt_string *payload, int finished );
|
||||
|
||||
#endif
|
75
media/webvtt/error.c
Normal file
75
media/webvtt/error.c
Normal file
@ -0,0 +1,75 @@
|
||||
/**
|
||||
* Copyright (c) 2013 Mozilla Foundation and Contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <webvtt/error.h>
|
||||
|
||||
static const char *errstr[] = {
|
||||
/* WEBVTT_ALLOCATION_FAILED */ "error allocating object",
|
||||
/* WEBVTT_MALFORMED_TAG */ "malformed 'WEBVTT' tag",
|
||||
/* WEBVTT_EXPECTED_EOL */ "expected newline",
|
||||
/* WEBVTT_EXPECTED_WHITESPACE */ "expected whitespace",
|
||||
/* WEBVTT_UNEXPECTED_WHITESPACE */ "unexpected whitespace",
|
||||
/* WEBVTT_LONG_COMMENT */ "very long tag-comment",
|
||||
/* WEBVTT_ID_TRUNCATED */ "webvtt-cue-id truncated",
|
||||
/* WEBVTT_MALFORMED_TIMESTAMP */ "malformed webvtt-timestamp",
|
||||
/* WEBVTT_EXPECTED_TIMESTAMP */ "expected webvtt-timestamp",
|
||||
/* WEBVTT_MISSING_CUETIME_SEPARATOR */ "missing webvtt-cuetime-separator `-->'",
|
||||
/* WEBVTT_EXPECTED_CUETIME_SEPARATOR */ "expected webvtt-cuetime-separator `-->'",
|
||||
/* WEBVTT_MISSING_CUESETTING_DELIMITER */ "missing whitespace before webvtt-cuesetting",
|
||||
/* WEBVTT_INVALID_CUESETTING_DELIMITER */ "invalid webvtt-cuesetting key:value delimiter. expected `:'",
|
||||
/* WEBVTT_INVALID_ENDTIME */ "webvtt-cue end-time must have value greater than start-time",
|
||||
/* WEBVTT_INVALID_CUESETTING */ "unrecognized webvtt-cue-setting",
|
||||
/* WEBVTT_UNFINISHED_CUETIMES */ "unfinished webvtt cuetimes. expected 'start-timestamp --> end-timestamp'",
|
||||
/* WEBVTT_MISSING_CUESETTING_KEYWORD */ "missing setting keyword for value",
|
||||
/* WEBVTT_VERTICAL_ALREADY_SET */ "'vertical' cue-setting already used",
|
||||
/* WEBVTT_VERTICAL_BAD_VALUE */ "'vertical' setting must have a value of either 'lr' or 'rl'",
|
||||
/* WEBVTT_LINE_ALREADY_SET */ "'line' cue-setting already used",
|
||||
/* WEBVTT_LINE_BAD_VALUE */ "'line' cue-setting must have a value that is an integer (signed) line number, or percentage (%) from top of video display",
|
||||
/* WEBVTT_POSITION_ALREADY_SET */ "'position' cue-setting already used",
|
||||
/* WEBVTT_POSITION_BAD_VALUE */ "'position' cue-setting must be a percentage (%) value representing the position in the direction orthogonal to the 'line' setting",
|
||||
/* WEBVTT_SIZE_ALREADY_SET */ "'size' cue-setting already used",
|
||||
/* WEBVTT_SIZE_BAD_VALUE */ "'size' cue-setting must have percentage (%) value",
|
||||
/* WEBVTT_ALIGN_ALREADY_SET */ "'align' cue-setting already used",
|
||||
/* WEBVTT_ALIGN_BAD_VALUE */ "'align' cue-setting must have a value of either 'start', 'middle', or 'end'",
|
||||
/* WEBVTT_CUE_CONTAINS_SEPARATOR */ "cue-text line contains unescaped timestamp separator '-->'",
|
||||
/* WEBVTT_CUE_INCOMPLETE */ "cue contains cue-id, but is missing cuetimes or cue text",
|
||||
};
|
||||
|
||||
/**
|
||||
* TODO:
|
||||
* Add i18n localized error strings with support for glibc and msvcrt locale
|
||||
* identifiers
|
||||
* (This might be too much work!)
|
||||
*/
|
||||
WEBVTT_EXPORT const char *
|
||||
webvtt_strerror( webvtt_error errno )
|
||||
{
|
||||
if( errno >= (sizeof(errstr) / sizeof(*errstr)) ) {
|
||||
return "";
|
||||
}
|
||||
return errstr[ errno ];
|
||||
}
|
194
media/webvtt/include/webvtt/cue.h
Normal file
194
media/webvtt/include/webvtt/cue.h
Normal file
@ -0,0 +1,194 @@
|
||||
/**
|
||||
* Copyright (c) 2013 Mozilla Foundation and Contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __WEBVTT_CUE_H__
|
||||
# define __WEBVTT_CUE_H__
|
||||
# include "util.h"
|
||||
# include <webvtt/string.h>
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
#define WEBVTT_CPLUSPLUS 1
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define WEBVTT_AUTO (0xFFFFFFFF)
|
||||
|
||||
typedef enum
|
||||
webvtt_node_kind_t {
|
||||
WEBVTT_NODE_LEAF = 0x80000000,
|
||||
WEBVTT_NODE_INTERNAL = 0x00000000,
|
||||
|
||||
/**
|
||||
* Internal Node objects
|
||||
*/
|
||||
WEBVTT_NODE_INTERNAL_START = 0,
|
||||
WEBVTT_CLASS = 0 | WEBVTT_NODE_INTERNAL,
|
||||
WEBVTT_ITALIC = 1 | WEBVTT_NODE_INTERNAL,
|
||||
WEBVTT_BOLD = 2 | WEBVTT_NODE_INTERNAL,
|
||||
WEBVTT_UNDERLINE = 3 | WEBVTT_NODE_INTERNAL,
|
||||
WEBVTT_RUBY = 4 | WEBVTT_NODE_INTERNAL,
|
||||
WEBVTT_RUBY_TEXT = 5 | WEBVTT_NODE_INTERNAL,
|
||||
WEBVTT_VOICE = 6 | WEBVTT_NODE_INTERNAL,
|
||||
|
||||
/**
|
||||
* This type of node has should not be rendered.
|
||||
* It is the top of the node list and only contains a list of nodes.
|
||||
*/
|
||||
WEBVTT_HEAD_NODE = 7,
|
||||
|
||||
WEBVTT_NODE_INTERNAL_END = 7,
|
||||
|
||||
/**
|
||||
* Leaf Node objects
|
||||
*/
|
||||
WEBVTT_NODE_LEAF_START = 256,
|
||||
WEBVTT_TEXT = 256 | WEBVTT_NODE_LEAF,
|
||||
WEBVTT_TIME_STAMP = 257 | WEBVTT_NODE_LEAF,
|
||||
|
||||
WEBVTT_NODE_LEAF_END = 257,
|
||||
|
||||
/* An empty initial state for a node */
|
||||
WEBVTT_EMPTY_NODE = 258
|
||||
} webvtt_node_kind;
|
||||
|
||||
/**
|
||||
* Macros to assist in validating node kinds, so that C++ compilers don't
|
||||
* complain (as long as they provide reinterpret_cast, which they should)
|
||||
*/
|
||||
#if defined(__cplusplus) || defined(__cplusplus_cli) || defined(__embedded_cplusplus) || defined(c_plusplus)
|
||||
# define WEBVTT_CAST(Type,Val) (reinterpret_cast<Type>(Val))
|
||||
#else
|
||||
# define WEBVTT_CAST(Type,Val) ((Type)(Val))
|
||||
#endif
|
||||
|
||||
#define WEBVTT_IS_LEAF(Kind) ( ((Kind) & WEBVTT_NODE_LEAF) != 0 )
|
||||
#define WEBVTT_NODE_INDEX(Kind) ( (Kind) & ~WEBVTT_NODE_LEAF )
|
||||
#define WEBVTT_IS_VALID_LEAF_NODE(Kind) ( WEBVTT_IS_LEAF(Kind) && (WEBVTT_NODE_INDEX(Kind) >= WEBVTT_NODE_LEAF_START && WEBVTT_NODE_INDEX(Kind) <= WEBVTT_NODE_LEAF_END ) )
|
||||
#define WEBVTT_IS_VALID_INTERNAL_NODE(Kind) ( (!WEBVTT_IS_LEAF(Kind)) && (WEBVTT_NODE_INDEX(Kind) >= WEBVTT_NODE_INTERNAL_START && WEBVTT_NODE_INDEX(Kind) <= WEBVTT_NODE_INTERNAL_END) )
|
||||
#define WEBVTT_IS_VALID_NODE_KIND(Kind) ( WEBVTT_IS_VALID_INTERNAL_NODE(Kind) || WEBVTT_IS_VALID_LEAF_NODE(Kind) )
|
||||
|
||||
/**
|
||||
* Casting helpers
|
||||
*/
|
||||
#define WEBVTT_GET_INTERNAL_NODE(Node) ( WEBVTT_IS_VALID_INTERNAL_NODE(WEBVTT_CAST(webvtt_node,Node)->kind) ? WEBVTT_CAST(webvtt_internal_node,Node) : 0 )
|
||||
#define WEBVTT_GET_LEAF_NODE(Node) ( WEBVTT_IS_VALID_LEAF_NODE((WEBVTT_CAST(webvtt_node,Node))->kind) ? WEBVTT_CAST(webvtt_leaf_node,Node) : 0 )
|
||||
|
||||
struct webvtt_internal_node_data_t;
|
||||
|
||||
typedef enum
|
||||
webvtt_vertical_type_t {
|
||||
WEBVTT_HORIZONTAL = 0,
|
||||
WEBVTT_VERTICAL_LR = 1,
|
||||
WEBVTT_VERTICAL_RL = 2
|
||||
} webvtt_vertical_type;
|
||||
|
||||
typedef enum
|
||||
webvtt_align_type_t {
|
||||
WEBVTT_ALIGN_START = 0,
|
||||
WEBVTT_ALIGN_MIDDLE,
|
||||
WEBVTT_ALIGN_END,
|
||||
|
||||
WEBVTT_ALIGN_LEFT,
|
||||
WEBVTT_ALIGN_RIGHT
|
||||
} webvtt_align_type;
|
||||
|
||||
typedef struct
|
||||
webvtt_node_t {
|
||||
|
||||
struct webvtt_refcount_t refs;
|
||||
/**
|
||||
* The specification asks for uni directional linked list, but we have added
|
||||
* a parent node in order to facilitate an iterative cue text parsing
|
||||
* solution.
|
||||
*/
|
||||
struct webvtt_node_t *parent;
|
||||
webvtt_node_kind kind;
|
||||
|
||||
union {
|
||||
webvtt_string text;
|
||||
webvtt_timestamp timestamp;
|
||||
struct webvtt_internal_node_data_t *internal_data;
|
||||
} data;
|
||||
} webvtt_node;
|
||||
|
||||
typedef struct
|
||||
webvtt_internal_node_data_t {
|
||||
webvtt_string annotation;
|
||||
webvtt_stringlist *css_classes;
|
||||
|
||||
webvtt_uint alloc;
|
||||
webvtt_uint length;
|
||||
webvtt_node **children;
|
||||
} webvtt_internal_node_data;
|
||||
|
||||
WEBVTT_EXPORT void webvtt_init_node( webvtt_node **node );
|
||||
WEBVTT_EXPORT void webvtt_ref_node( webvtt_node *node );
|
||||
WEBVTT_EXPORT void webvtt_release_node( webvtt_node **node );
|
||||
|
||||
typedef struct
|
||||
webvtt_cue_settings_t {
|
||||
webvtt_vertical_type vertical;
|
||||
int line;
|
||||
webvtt_uint position;
|
||||
webvtt_uint size;
|
||||
webvtt_align_type align;
|
||||
} webvtt_cue_settings;
|
||||
|
||||
typedef struct
|
||||
webvtt_cue_t {
|
||||
/**
|
||||
* PRIVATE.
|
||||
* Do not touch, okay?
|
||||
*/
|
||||
struct webvtt_refcount_t refs;
|
||||
webvtt_uint flags;
|
||||
|
||||
/**
|
||||
* PUBLIC:
|
||||
*/
|
||||
webvtt_timestamp from;
|
||||
webvtt_timestamp until;
|
||||
webvtt_cue_settings settings;
|
||||
webvtt_bool snap_to_lines;
|
||||
webvtt_string id;
|
||||
|
||||
/**
|
||||
* Parsed cue-text (NULL if has not been parsed)
|
||||
*/
|
||||
webvtt_node *node_head;
|
||||
} webvtt_cue;
|
||||
|
||||
WEBVTT_EXPORT webvtt_status webvtt_create_cue( webvtt_cue **pcue );
|
||||
WEBVTT_EXPORT void webvtt_ref_cue( webvtt_cue *cue );
|
||||
WEBVTT_EXPORT void webvtt_release_cue( webvtt_cue **pcue );
|
||||
WEBVTT_EXPORT int webvtt_validate_cue( webvtt_cue *cue );
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
113
media/webvtt/include/webvtt/error.h
Normal file
113
media/webvtt/include/webvtt/error.h
Normal file
@ -0,0 +1,113 @@
|
||||
/**
|
||||
* Copyright (c) 2013 Mozilla Foundation and Contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __WEBVTT_ERROR_H__
|
||||
# define __WEBVTT_ERROR_H__
|
||||
# include "util.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum
|
||||
webvtt_error_t
|
||||
{
|
||||
/* There was a problem allocating something */
|
||||
WEBVTT_ALLOCATION_FAILED = 0,
|
||||
/**
|
||||
* 'WEBVTT' is not the first 6 characters in the file
|
||||
* (not counting UTF8 BOM)
|
||||
*/
|
||||
WEBVTT_MALFORMED_TAG,
|
||||
/* An end-of-line sequence was expected, but not found. */
|
||||
WEBVTT_EXPECTED_EOL,
|
||||
/* A string of whitespace was expected, but not found. */
|
||||
WEBVTT_EXPECTED_WHITESPACE,
|
||||
/**
|
||||
* A string of whitespace was found, but was not expected
|
||||
* (Recoverable error)
|
||||
*/
|
||||
WEBVTT_UNEXPECTED_WHITESPACE,
|
||||
/* Long WEBVTT comment, decide whether to abort parsing or not */
|
||||
WEBVTT_LONG_COMMENT,
|
||||
/* A cue-id was too long to fit in the buffer. */
|
||||
WEBVTT_ID_TRUNCATED,
|
||||
/* A timestamp is malformed */
|
||||
WEBVTT_MALFORMED_TIMESTAMP,
|
||||
/* Expected a timestamp, but didn't find one */
|
||||
WEBVTT_EXPECTED_TIMESTAMP,
|
||||
/* Missing timestamp separator */
|
||||
WEBVTT_MISSING_CUETIME_SEPARATOR,
|
||||
/* Were expecting a separator, but got some garbage that we can't
|
||||
recover from instead. */
|
||||
WEBVTT_EXPECTED_CUETIME_SEPARATOR,
|
||||
/* Missing cuesetting delimiter */
|
||||
WEBVTT_MISSING_CUESETTING_DELIMITER,
|
||||
/* Invalid cuesetting delimiter */
|
||||
WEBVTT_INVALID_CUESETTING_DELIMITER,
|
||||
/* End-time is less than or equal to start time */
|
||||
WEBVTT_INVALID_ENDTIME,
|
||||
/* Invalid cue-setting */
|
||||
WEBVTT_INVALID_CUESETTING,
|
||||
/* unfinished cuetimes */
|
||||
WEBVTT_UNFINISHED_CUETIMES,
|
||||
/* valid-looking cuesetting with no keyword */
|
||||
WEBVTT_MISSING_CUESETTING_KEYWORD,
|
||||
/* 'vertical' setting already exists for this cue. */
|
||||
WEBVTT_VERTICAL_ALREADY_SET,
|
||||
/* Bad 'vertical' value */
|
||||
WEBVTT_VERTICAL_BAD_VALUE,
|
||||
/* 'line' setting already exists for this cue. */
|
||||
WEBVTT_LINE_ALREADY_SET,
|
||||
/* Bad 'line' value */
|
||||
WEBVTT_LINE_BAD_VALUE,
|
||||
/* 'position' setting already exists for this cue. */
|
||||
WEBVTT_POSITION_ALREADY_SET,
|
||||
/* Bad 'position' value */
|
||||
WEBVTT_POSITION_BAD_VALUE,
|
||||
/* 'size' setting already exists for this cue. */
|
||||
WEBVTT_SIZE_ALREADY_SET,
|
||||
/* Bad 'size' value */
|
||||
WEBVTT_SIZE_BAD_VALUE,
|
||||
/* 'align' setting already exists for this cue. */
|
||||
WEBVTT_ALIGN_ALREADY_SET,
|
||||
/* Bad 'align' value */
|
||||
WEBVTT_ALIGN_BAD_VALUE,
|
||||
/* A cue-text object contains the string "-->", which needs to be escaped */
|
||||
WEBVTT_CUE_CONTAINS_SEPARATOR,
|
||||
/* A webvtt cue contains only a cue-id, and no cuetimes or payload. */
|
||||
WEBVTT_CUE_INCOMPLETE,
|
||||
};
|
||||
typedef enum webvtt_error_t webvtt_error;
|
||||
|
||||
WEBVTT_EXPORT const char *webvtt_strerror( webvtt_error );
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
58
media/webvtt/include/webvtt/parser.h
Normal file
58
media/webvtt/include/webvtt/parser.h
Normal file
@ -0,0 +1,58 @@
|
||||
/**
|
||||
* Copyright (c) 2013 Mozilla Foundation and Contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __WEBVTT_PARSER_H__
|
||||
# define __WEBVTT_PARSER_H__
|
||||
# include "string.h"
|
||||
# include "cue.h"
|
||||
# include "error.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct webvtt_parser_t *webvtt_parser;
|
||||
|
||||
/**
|
||||
* Allows application to request error reporting
|
||||
*/
|
||||
typedef int ( WEBVTT_CALLBACK *webvtt_error_fn )( void *userdata, webvtt_uint line, webvtt_uint col,
|
||||
webvtt_error error );
|
||||
typedef void ( WEBVTT_CALLBACK *webvtt_cue_fn )( void *userdata, webvtt_cue *cue );
|
||||
|
||||
|
||||
WEBVTT_EXPORT webvtt_status webvtt_create_parser( webvtt_cue_fn on_read, webvtt_error_fn on_error, void *
|
||||
userdata, webvtt_parser *ppout );
|
||||
WEBVTT_EXPORT void webvtt_delete_parser( webvtt_parser parser );
|
||||
WEBVTT_EXPORT webvtt_status webvtt_parse_chunk( webvtt_parser self, const void *buffer, webvtt_uint len );
|
||||
WEBVTT_EXPORT webvtt_status webvtt_finish_parsing( webvtt_parser self );
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
269
media/webvtt/include/webvtt/string.h
Normal file
269
media/webvtt/include/webvtt/string.h
Normal file
@ -0,0 +1,269 @@
|
||||
/**
|
||||
* Copyright (c) 2013 Mozilla Foundation and Contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __WEBVTT_STRING_H__
|
||||
# define __WEBVTT_STRING_H__
|
||||
# include "util.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* webvtt_string - A buffer of utf16 characters
|
||||
*/
|
||||
typedef struct webvtt_string_t webvtt_string;
|
||||
typedef struct webvtt_string_data_t webvtt_string_data;
|
||||
typedef struct webvtt_stringlist_t webvtt_stringlist;
|
||||
struct webvtt_string_data_t;
|
||||
|
||||
struct
|
||||
webvtt_string_t {
|
||||
webvtt_string_data *d;
|
||||
};
|
||||
|
||||
/**
|
||||
* webvtt_init_string
|
||||
*
|
||||
* initialize a string to point to the empty string
|
||||
*/
|
||||
WEBVTT_EXPORT void webvtt_init_string( webvtt_string *result );
|
||||
|
||||
/**
|
||||
* webvtt_string_is_empty
|
||||
*
|
||||
* return whether or not the string is empty
|
||||
* qualifications for it being empty are it equaling &empty_string or its length equaling 0
|
||||
*/
|
||||
WEBVTT_EXPORT webvtt_uint webvtt_string_is_empty( const webvtt_string *str );
|
||||
|
||||
/**
|
||||
* webvtt_create_string
|
||||
*
|
||||
* allocate a new string object with an initial capacity of 'alloc'
|
||||
* (the string data of 'result' is not expected to contain string data,
|
||||
* regardless of its value. be sure to release existing strings before using
|
||||
* webvtt_create_string)
|
||||
*/
|
||||
WEBVTT_EXPORT webvtt_status webvtt_create_string( webvtt_uint32 alloc, webvtt_string *result );
|
||||
|
||||
/**
|
||||
* webvtt_create_init_string
|
||||
*
|
||||
* allocate and initialize a string with the contents of 'init_text' of length
|
||||
* 'len' if 'len' < 0, assume init_text to be null-terminated.
|
||||
*/
|
||||
WEBVTT_EXPORT webvtt_status webvtt_create_string_with_text( webvtt_string *result, const webvtt_byte *init_text, int len );
|
||||
|
||||
/**
|
||||
* webvtt_ref_string
|
||||
*
|
||||
* increase the reference count of--or retain--a string
|
||||
*
|
||||
* when the reference count drops to zero, the string is deallocated.
|
||||
*/
|
||||
WEBVTT_EXPORT void webvtt_ref_string( webvtt_string *str );
|
||||
|
||||
/**
|
||||
* webvtt_release_string
|
||||
*
|
||||
* decrease the reference count of--or release--a string
|
||||
*
|
||||
* when the reference count drops to zero, the string is deallocated.
|
||||
*/
|
||||
WEBVTT_EXPORT void webvtt_release_string( webvtt_string *str );
|
||||
|
||||
/**
|
||||
* webvtt_string_detach
|
||||
*
|
||||
* ensure that the reference count of a string is exactly 1
|
||||
*
|
||||
* if the reference count is greater than 1, allocate a new copy of the string
|
||||
* and return it.
|
||||
*/
|
||||
WEBVTT_EXPORT webvtt_status webvtt_string_detach( webvtt_string *str );
|
||||
|
||||
/**
|
||||
* webvtt_copy_string
|
||||
*
|
||||
* shallow-clone 'right', storing the result in 'left'.
|
||||
*/
|
||||
WEBVTT_EXPORT void webvtt_copy_string( webvtt_string *left, const webvtt_string *right );
|
||||
|
||||
/**
|
||||
* webvtt_string_text
|
||||
*
|
||||
* return the text contents of a string
|
||||
*/
|
||||
WEBVTT_EXPORT const webvtt_byte *webvtt_string_text( const webvtt_string *str );
|
||||
|
||||
/**
|
||||
* webvtt_string_length
|
||||
*
|
||||
* return the length of a strings text
|
||||
*/
|
||||
WEBVTT_EXPORT const webvtt_uint32 webvtt_string_length( const webvtt_string *str );
|
||||
|
||||
/**
|
||||
* webvtt_string_capacity
|
||||
*
|
||||
* return the current capacity of a string
|
||||
*/
|
||||
WEBVTT_EXPORT const webvtt_uint32 webvtt_string_capacity( const webvtt_string *str );
|
||||
|
||||
/**
|
||||
* webvtt_string_getline
|
||||
*
|
||||
* collect a line of text (terminated by CR/LF/CRLF) from a buffer, without
|
||||
* including the terminating character(s)
|
||||
*/
|
||||
WEBVTT_EXPORT int webvtt_string_getline( webvtt_string *str, const webvtt_byte *buffer,
|
||||
webvtt_uint *pos, webvtt_uint len, int *truncate, webvtt_bool finish, webvtt_bool retain_new_line );
|
||||
|
||||
/**
|
||||
* webvtt_string_putc
|
||||
*
|
||||
* append a single byte to a webvtt string
|
||||
*/
|
||||
WEBVTT_EXPORT webvtt_status webvtt_string_putc( webvtt_string *str, webvtt_byte to_append );
|
||||
|
||||
/**
|
||||
* webvtt_string_append
|
||||
*
|
||||
* append a stream of bytes to the string.
|
||||
*
|
||||
* if 'len' is < 0, then buffer is expected to be null-terminated.
|
||||
*/
|
||||
WEBVTT_EXPORT webvtt_status webvtt_string_append( webvtt_string *str, const webvtt_byte *buffer, int len );
|
||||
|
||||
/**
|
||||
* webvtt_string_appendstr
|
||||
*
|
||||
* append the contents of a string object 'other' to a string object 'str'
|
||||
*/
|
||||
WEBVTT_EXPORT webvtt_status webvtt_string_append_string( webvtt_string *str, const webvtt_string *other );
|
||||
|
||||
/**
|
||||
* basic dynamic array of strings
|
||||
*/
|
||||
struct
|
||||
webvtt_stringlist_t {
|
||||
struct webvtt_refcount_t refs;
|
||||
webvtt_uint alloc;
|
||||
webvtt_uint length;
|
||||
webvtt_string *items;
|
||||
};
|
||||
|
||||
/**
|
||||
* webvtt_create_stringlist
|
||||
*
|
||||
* allocate a new, empty stringlist
|
||||
*/
|
||||
WEBVTT_EXPORT webvtt_status webvtt_create_stringlist( webvtt_stringlist **result );
|
||||
|
||||
/**
|
||||
* webvtt_ref_stringlist
|
||||
*
|
||||
* Increase the ref count of the stringlist
|
||||
*/
|
||||
WEBVTT_EXPORT void webvtt_ref_stringlist( webvtt_stringlist *list );
|
||||
|
||||
/**
|
||||
* webvtt_copy_stringlist
|
||||
*
|
||||
* create a copy shallow of right from left
|
||||
*/
|
||||
WEBVTT_EXPORT void webvtt_copy_stringlist( webvtt_stringlist **left, webvtt_stringlist *right );
|
||||
|
||||
/**
|
||||
* webvtt_release_stringlist
|
||||
*
|
||||
* Decrease the ref count of the stringlist and delete it if the ref count is 0
|
||||
*/
|
||||
WEBVTT_EXPORT void webvtt_release_stringlist( webvtt_stringlist **list );
|
||||
|
||||
/**
|
||||
* webvtt_stringlist_push
|
||||
*
|
||||
* add a new string to the end of the stringlist
|
||||
*/
|
||||
WEBVTT_EXPORT webvtt_status webvtt_stringlist_push( webvtt_stringlist *list, webvtt_string *str );
|
||||
|
||||
/**
|
||||
* Helper functions
|
||||
*/
|
||||
|
||||
/**
|
||||
* webvtt_next_utf8
|
||||
*
|
||||
* move the 'begin' pointer to the beginning of the next utf8 character
|
||||
* sequence.
|
||||
*/
|
||||
WEBVTT_EXPORT webvtt_bool webvtt_next_utf8( const webvtt_byte **begin,
|
||||
const webvtt_byte *end );
|
||||
|
||||
/**
|
||||
* webvtt_skip_utf8
|
||||
*
|
||||
* move the 'begin' pointer to the beginning of the utf8 character
|
||||
* 'n_chars' away.
|
||||
*
|
||||
* if 'end' is less than 'begin', will seek backwards.
|
||||
*/
|
||||
WEBVTT_EXPORT webvtt_bool webvtt_skip_utf8( const webvtt_byte **begin,
|
||||
const webvtt_byte *end, int n_chars );
|
||||
|
||||
/**
|
||||
* webvtt_utf8_to_utf16
|
||||
*
|
||||
* return the utf16 value of a given character
|
||||
*/
|
||||
WEBVTT_EXPORT webvtt_uint16 webvtt_utf8_to_utf16( const webvtt_byte *utf8,
|
||||
const webvtt_byte *end, webvtt_uint16 *high_surrogate );
|
||||
|
||||
/**
|
||||
* webvtt_utf8_chcount
|
||||
*
|
||||
* return the number of Unicode characters (as opposed to units)
|
||||
* in a utf8 string
|
||||
*/
|
||||
WEBVTT_EXPORT int webvtt_utf8_chcount( const webvtt_byte *utf8,
|
||||
const webvtt_byte *end );
|
||||
|
||||
/**
|
||||
* webvtt_utf8_length
|
||||
*
|
||||
* if 'utf8' points to a lead byte, return the length of the sequence.
|
||||
* if 'utf8' is null, return 0.
|
||||
* if 'utf8' points to a trail byte, return -1
|
||||
*/
|
||||
WEBVTT_EXPORT int webvtt_utf8_length( const webvtt_byte *utf8 );
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
}
|
||||
#endif
|
||||
#endif
|
250
media/webvtt/include/webvtt/util.h
Normal file
250
media/webvtt/include/webvtt/util.h
Normal file
@ -0,0 +1,250 @@
|
||||
/**
|
||||
* Copyright (c) 2013 Mozilla Foundation and Contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __WEBVTT_UTIL_H__
|
||||
# define __WEBVTT_UTIL_H__
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
# if defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__)
|
||||
# if !WEBVTT_NO_CONFIG_H
|
||||
# include "webvtt-config-win32.h"
|
||||
# endif
|
||||
# define WEBVTT_OS_WIN32 1
|
||||
# if defined(_WIN64)
|
||||
# define WEBVTT_OS_WIN64 1
|
||||
# endif
|
||||
# elif !WEBVTT_NO_CONFIG_H
|
||||
# include <webvtt/webvtt-config.h>
|
||||
# endif
|
||||
|
||||
# if defined(_MSC_VER)
|
||||
# define WEBVTT_CC_MSVC 1
|
||||
# define WEBVTT_CALLBACK __cdecl
|
||||
# if WEBVTT_BUILD_LIBRARY
|
||||
# define WEBVTT_EXPORT __declspec(dllexport)
|
||||
# elif !WEBVTT_STATIC
|
||||
# define WEBVTT_EXPORT __declspec(dllimport)
|
||||
# else
|
||||
# define WEBVTT_EXPORT
|
||||
# endif
|
||||
# if _MSC_VER >= 1600
|
||||
# define WEBVTT_HAVE_STDINT 1
|
||||
# endif
|
||||
# elif defined(__GNUC__)
|
||||
# define WEBVTT_CC_GCC 1
|
||||
# define WEBVTT_HAVE_STDINT 1
|
||||
# if WEBVTT_OS_WIN32
|
||||
# if WEBVTT_BUILD_LIBRARY
|
||||
# define WEBVTT_EXPORT __declspec(dllexport)
|
||||
# elif !WEBVTT_STATIC
|
||||
# define WEBVTT_EXPORT __declspec(dllimport)
|
||||
# else
|
||||
# define WEBVTT_EXPORT
|
||||
# endif
|
||||
# else
|
||||
# if __GNUC__ >= 4
|
||||
# define WEBVTT_EXPORT __attribute__((visibility("default")))
|
||||
# define WEBVTT_INTERN __attribute__((visibility("hidden")))
|
||||
# endif
|
||||
# endif
|
||||
# else
|
||||
# define WEBVTT_CC_UNKNOWN 1
|
||||
# endif
|
||||
|
||||
# ifndef WEBVTT_CALLBACK
|
||||
# define WEBVTT_CALLBACK
|
||||
# endif
|
||||
# ifndef WEBVTT_EXPORT
|
||||
# define WEBVTT_EXPORT
|
||||
# endif
|
||||
# ifndef WEBVTT_INTERN
|
||||
# define WEBVTT_INTERN
|
||||
# endif
|
||||
|
||||
# if defined(__cplusplus) || defined(c_plusplus)
|
||||
# define WEBVTT_INLINE inline
|
||||
# elif WEBVTT_CC_MSVC
|
||||
# define WEBVTT_INLINE __inline
|
||||
# elif WEBVTT_CC_GCC
|
||||
# define WEBVTT_INLINE __inline__
|
||||
# endif
|
||||
|
||||
# if WEBVTT_HAVE_STDINT
|
||||
# include <stdint.h>
|
||||
typedef int8_t webvtt_int8;
|
||||
typedef int16_t webvtt_int16;
|
||||
typedef int32_t webvtt_int32;
|
||||
typedef int64_t webvtt_int64;
|
||||
typedef uint8_t webvtt_uint8;
|
||||
typedef uint16_t webvtt_uint16;
|
||||
typedef uint32_t webvtt_uint32;
|
||||
typedef uint64_t webvtt_uint64;
|
||||
# elif defined(_MSC_VER)
|
||||
typedef signed __int8 webvtt_int8;
|
||||
typedef signed __int16 webvtt_int16;
|
||||
typedef signed __int32 webvtt_int32;
|
||||
typedef signed __int64 webvtt_int64;
|
||||
typedef unsigned __int8 webvtt_uint8;
|
||||
typedef unsigned __int16 webvtt_uint16;
|
||||
typedef unsigned __int32 webvtt_uint32;
|
||||
typedef unsigned __int64 webvtt_uint64;
|
||||
# elif WEBVTT_CC_UNKNOWN
|
||||
# warning "Unknown compiler. Compiler specific int-types probably broken!"
|
||||
typedef signed char webvtt_int8;
|
||||
typedef signed short webvtt_int16;
|
||||
typedef signed long webvtt_int32;
|
||||
typedef signed long long webvtt_int64;
|
||||
typedef unsigned char webvtt_uint8;
|
||||
typedef unsigned short webvtt_uint16;
|
||||
typedef unsigned long webvtt_uint32;
|
||||
typedef unsigned long long webvtt_uint64;
|
||||
# endif
|
||||
|
||||
typedef signed int webvtt_int;
|
||||
typedef signed char webvtt_char;
|
||||
typedef signed short webvtt_short;
|
||||
typedef signed long webvtt_long;
|
||||
typedef signed long long webvtt_longlong;
|
||||
typedef unsigned int webvtt_uint;
|
||||
typedef unsigned char webvtt_uchar;
|
||||
typedef unsigned short webvtt_ushort;
|
||||
typedef unsigned long webvtt_ulong;
|
||||
typedef unsigned long long webvtt_ulonglong;
|
||||
typedef webvtt_uint8 webvtt_byte;
|
||||
typedef webvtt_int webvtt_bool;
|
||||
typedef webvtt_uint32 webvtt_length;
|
||||
typedef webvtt_uint64 webvtt_timestamp;
|
||||
|
||||
/**
|
||||
* Memory allocation callbacks, which allow overriding the allocation strategy.
|
||||
*/
|
||||
typedef void *(WEBVTT_CALLBACK *webvtt_alloc_fn_ptr)( void *userdata, webvtt_uint nbytes );
|
||||
typedef void (WEBVTT_CALLBACK *webvtt_free_fn_ptr)( void *userdata, void *pmem );
|
||||
|
||||
/**
|
||||
* Allocation functions. webvtt_set_allocator() should really be the first
|
||||
* function called. However, it will do nothing (and not report error) if
|
||||
* objects have already been allocated and not freed. Therefore, it is NOT
|
||||
* safe to assume that it worked and use the supplied
|
||||
* function pointers directly.
|
||||
*
|
||||
* Currently, set_allocator (and the other allocation functions) do not use
|
||||
* any locking mechanism, so the library cannot be considered to be
|
||||
* thread-safe at this time if changing the allocator is used.
|
||||
*
|
||||
* I don't believe there is much of a reason to worry about the overhead of
|
||||
* using function pointers for allocation, as it is negligible compared to the
|
||||
* act of allocating memory itself, and having a configurable allocation
|
||||
* strategy could be very useful.
|
||||
*/
|
||||
WEBVTT_EXPORT void *webvtt_alloc( webvtt_uint nb );
|
||||
WEBVTT_EXPORT void *webvtt_alloc0( webvtt_uint nb );
|
||||
WEBVTT_EXPORT void webvtt_free( void *data );
|
||||
WEBVTT_EXPORT void webvtt_set_allocator( webvtt_alloc_fn_ptr alloc, webvtt_free_fn_ptr free, void *userdata );
|
||||
|
||||
enum
|
||||
webvtt_status_t {
|
||||
WEBVTT_SUCCESS = 0,
|
||||
WEBVTT_UNFINISHED = -1,
|
||||
WEBVTT_PARSE_ERROR = -2,
|
||||
WEBVTT_OUT_OF_MEMORY = -3,
|
||||
WEBVTT_INVALID_PARAM = -4,
|
||||
WEBVTT_NOT_SUPPORTED = -5,
|
||||
WEBVTT_UNSUCCESSFUL = -6,
|
||||
WEBVTT_INVALID_TAG_NAME = -7,
|
||||
WEBVTT_INVALID_TOKEN_TYPE = -8,
|
||||
WEBVTT_INVALID_TOKEN_STATE = -9,
|
||||
WEBVTT_FAIL = -10, /* This is not very specific! */
|
||||
|
||||
/**
|
||||
* A failure that requires the parser to completely skip beyond a cue.
|
||||
*/
|
||||
WEBVTT_SKIP_CUE = -11,
|
||||
|
||||
/**
|
||||
* Parser should move to the next cuesetting.
|
||||
*/
|
||||
WEBVTT_NEXT_CUESETTING = -12,
|
||||
};
|
||||
|
||||
typedef enum webvtt_status_t webvtt_status;
|
||||
|
||||
/**
|
||||
* Macros to filter out webvtt status returns.
|
||||
*/
|
||||
# define WEBVTT_FAILED(status) ( (status) != WEBVTT_SUCCESS )
|
||||
|
||||
struct
|
||||
webvtt_refcount_t {
|
||||
# if WEBVTT_OS_WIN32
|
||||
/**
|
||||
* 'long' on windows in order to coincide with
|
||||
* the _Interlocked compiler intrinsics on win32
|
||||
*/
|
||||
long value;
|
||||
# else
|
||||
int value;
|
||||
# endif
|
||||
};
|
||||
|
||||
# ifdef WEBVTT_REF_INIT
|
||||
# undef WEBVTT_REF_INIT
|
||||
# endif
|
||||
# define WEBVTT_REF_INIT(Value) { (Value) }
|
||||
|
||||
/**
|
||||
* TODO: Replace these with atomic instructions for systems that provide it
|
||||
*/
|
||||
# ifndef WEBVTT_ATOMIC_INC
|
||||
# define WEBVTT_ATOMIC_INC(x) ( ++(x) )
|
||||
# endif
|
||||
# ifndef WEBVTT_ATOMIC_DEC
|
||||
# define WEBVTT_ATOMIC_DEC(x) ( --(x) )
|
||||
# endif
|
||||
|
||||
# if defined(WEBVTT_INLINE)
|
||||
static WEBVTT_INLINE int webvtt_ref( struct webvtt_refcount_t *ref )
|
||||
{
|
||||
return WEBVTT_ATOMIC_INC(ref->value);
|
||||
}
|
||||
static WEBVTT_INLINE int webvtt_deref( struct webvtt_refcount_t *ref )
|
||||
{
|
||||
return WEBVTT_ATOMIC_DEC(ref->value);
|
||||
}
|
||||
# else
|
||||
# define webvtt_inc_ref(ref) ( WEBVTT_ATOMIC_INC((ref)->value) )
|
||||
# define webvtt_dec_ref(ref) ( WEBVTT_ATOMIC_DEC((ref)->value) )
|
||||
# endif
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
597
media/webvtt/lexer.c
Normal file
597
media/webvtt/lexer.c
Normal file
@ -0,0 +1,597 @@
|
||||
/**
|
||||
* Copyright (c) 2013 Mozilla Foundation and Contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "parser_internal.h"
|
||||
|
||||
/**
|
||||
* There are probably enough jumps and stack pops here to fill up quite a few caches but it may still
|
||||
* be much smaller than a gigantic table-based solution.
|
||||
*
|
||||
* TODO: Replace all char literals with hex values, just in case compiling on a machine which uses an
|
||||
* incompatible character set
|
||||
*/
|
||||
|
||||
#define U_DIGIT case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: case 0x35: case 0x36: case 0x37: case 0x38: case 0x39:
|
||||
#define U_WHITESPACE case 0x0D: case 0x0A: case 0x20: case 0x09:
|
||||
#define U_SPACE case 0x20:
|
||||
#define U_TAB case 0x09:
|
||||
#define U_CR case 0x0D:
|
||||
#define U_LF case 0x0A:
|
||||
|
||||
#define U_DASH case 0x2D:
|
||||
#define U_PERIOD case 0x2E:
|
||||
#define U_GT case 0x3E:
|
||||
#define U_COLON case 0x3A:
|
||||
#define U_PERCENT case 0x25:
|
||||
|
||||
#define U_0 case 0x30:
|
||||
#define U_1 case 0x31:
|
||||
#define U_2 case 0x32:
|
||||
#define U_3 case 0x33:
|
||||
#define U_4 case 0x34:
|
||||
#define U_5 case 0x35:
|
||||
#define U_6 case 0x36:
|
||||
#define U_7 case 0x37:
|
||||
#define U_8 case 0x38:
|
||||
#define U_9 case 0x39:
|
||||
|
||||
#define U_a case 0x61:
|
||||
#define U_b case 0x62:
|
||||
#define U_c case 0x63:
|
||||
#define U_d case 0x64:
|
||||
#define U_e case 0x65:
|
||||
#define U_f case 0x66:
|
||||
#define U_g case 0x67:
|
||||
#define U_h case 0x68:
|
||||
#define U_i case 0x69:
|
||||
#define U_j case 0x6A:
|
||||
#define U_k case 0x6B:
|
||||
#define U_l case 0x6C:
|
||||
#define U_m case 0x6D:
|
||||
#define U_n case 0x6E:
|
||||
#define U_o case 0x6F:
|
||||
#define U_p case 0x70:
|
||||
#define U_q case 0x71:
|
||||
#define U_r case 0x72:
|
||||
#define U_s case 0x73:
|
||||
#define U_t case 0x74:
|
||||
#define U_u case 0x75:
|
||||
#define U_v case 0x76:
|
||||
#define U_w case 0x77:
|
||||
#define U_x case 0x78:
|
||||
#define U_y case 0x79:
|
||||
#define U_z case 0x7A:
|
||||
|
||||
#define U_A case 0x41:
|
||||
#define U_B case 0x42:
|
||||
#define U_C case 0x43:
|
||||
#define U_D case 0x44:
|
||||
#define U_E case 0x45:
|
||||
#define U_F case 0x46:
|
||||
#define U_G case 0x47:
|
||||
#define U_H case 0x48:
|
||||
#define U_I case 0x49:
|
||||
#define U_J case 0x4A:
|
||||
#define U_K case 0x4B:
|
||||
#define U_L case 0x4C:
|
||||
#define U_M case 0x4D:
|
||||
#define U_N case 0x4E:
|
||||
#define U_O case 0x4F:
|
||||
#define U_P case 0x50:
|
||||
#define U_Q case 0x51:
|
||||
#define U_R case 0x52:
|
||||
#define U_S case 0x53:
|
||||
#define U_T case 0x54:
|
||||
#define U_U case 0x55:
|
||||
#define U_V case 0x56:
|
||||
#define U_W case 0x57:
|
||||
#define U_X case 0x58:
|
||||
#define U_Y case 0x59:
|
||||
#define U_Z case 0x5A:
|
||||
|
||||
#define U_BOM0 case 0xEF:
|
||||
#define U_BOM1 case 0xBB:
|
||||
#define U_BOM2 case 0xBF:
|
||||
|
||||
#define DEFAULT default:
|
||||
|
||||
/**
|
||||
* Just for semantic clarity
|
||||
*/
|
||||
#define OR
|
||||
#define AND
|
||||
|
||||
#define OVERFLOW(X) \
|
||||
if( self->token_pos >= (sizeof(self->token) - 1 ) ) \
|
||||
{ \
|
||||
RETURN(X) \
|
||||
}
|
||||
|
||||
#define BEGIN_STATE(state) case state: { switch(c) {
|
||||
#define END_STATE DEFAULT BACKUP return BADTOKEN; } } break;
|
||||
#define END_STATE_EX } } break;
|
||||
|
||||
#define BACKUP (*pos)--; --self->column; self->token[--self->token_pos] = 0; self->tstate = L_START;
|
||||
#define SET_STATE(X) self->tstate = X; break;
|
||||
#define RETURN(X) self->tstate = L_START; return X;
|
||||
#define SET_NEWLINE self->line++; self->column = 1; RETURN(NEWLINE)
|
||||
#define CONTINUE continue;
|
||||
|
||||
#define RESET self->column = 1; self->bytes = self->token_pos = 0; self->tstate = L_START;
|
||||
#define BREAK break;
|
||||
|
||||
#define CHECK_BROKEN_TIMESTAMP \
|
||||
if(self->token_pos == sizeof(self->token) - 1 ) \
|
||||
{ \
|
||||
ERROR(WEBVTT_MALFORMED_TIMESTAMP); \
|
||||
return BADTOKEN; \
|
||||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_lex_word( webvtt_parser self, webvtt_string *str, const webvtt_byte *buffer, webvtt_uint *ppos, webvtt_uint length, webvtt_bool finish )
|
||||
{
|
||||
webvtt_status status = WEBVTT_SUCCESS;
|
||||
webvtt_uint pos = *ppos;
|
||||
int d = 0;
|
||||
if( !str ) {
|
||||
return WEBVTT_INVALID_PARAM;
|
||||
}
|
||||
|
||||
webvtt_init_string( str );
|
||||
|
||||
# define ASCII_DASH (0x2D)
|
||||
# define ASCII_GT (0x3E)
|
||||
while( pos < length ) {
|
||||
webvtt_uint last_bytes = self->bytes;
|
||||
webvtt_uint last_line = self->line;
|
||||
webvtt_uint last_column = self->column;
|
||||
webvtt_uint last_pos = pos;
|
||||
|
||||
webvtt_token token = webvtt_lex(self, buffer, &pos, length, finish );
|
||||
|
||||
if( token == BADTOKEN ) {
|
||||
if( WEBVTT_FAILED( status = webvtt_string_putc( str, buffer[pos] ) ) ) {
|
||||
webvtt_release_string( str );
|
||||
goto _finished;
|
||||
}
|
||||
++pos;
|
||||
} else {
|
||||
pos = last_pos;
|
||||
self->bytes = last_bytes;
|
||||
self->line = last_line;
|
||||
self->column = last_column;
|
||||
goto _finished;
|
||||
}
|
||||
}
|
||||
|
||||
_finished:
|
||||
*ppos = pos;
|
||||
return status;
|
||||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_token
|
||||
webvtt_lex( webvtt_parser self, const webvtt_byte *buffer, webvtt_uint *pos, webvtt_uint length, webvtt_bool finish )
|
||||
{
|
||||
while( *pos < length ) {
|
||||
webvtt_byte c = buffer[(*pos)++];
|
||||
self->token[ self->token_pos++ ] = c;
|
||||
self->token[ self->token_pos ] = 0;
|
||||
self->column++;
|
||||
self->bytes++;
|
||||
switch( self->tstate ) {
|
||||
BEGIN_STATE(L_START)
|
||||
U_DIGIT { SET_STATE(L_DIGIT0) }
|
||||
U_W { SET_STATE(L_WEBVTT0) }
|
||||
U_DASH { SET_STATE(L_DASH0) }
|
||||
U_BOM0 { SET_STATE(L_BOM0) }
|
||||
U_LF { SET_NEWLINE }
|
||||
U_CR { SET_STATE(L_NEWLINE0) }
|
||||
U_SPACE OR U_TAB { SET_STATE(L_WHITESPACE) }
|
||||
U_PERIOD { RETURN(FULL_STOP) }
|
||||
U_COLON { RETURN(COLON) }
|
||||
U_p { SET_STATE(L_POSITION0) }
|
||||
U_a { SET_STATE(L_ALIGN0) }
|
||||
U_l { SET_STATE(L_L0) }
|
||||
U_v { SET_STATE(L_VERTICAL0) }
|
||||
U_r { SET_STATE(L_RL0) }
|
||||
U_s { SET_STATE(L_S0) }
|
||||
U_m { SET_STATE(L_MIDDLE0) }
|
||||
U_e { SET_STATE(L_END0) }
|
||||
U_N { SET_STATE(L_NOTE1) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_BOM0)
|
||||
U_BOM1 { SET_STATE(L_BOM1) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_BOM1)
|
||||
U_BOM2 {
|
||||
if( self->bytes == 3 ) {
|
||||
RESET
|
||||
BREAK
|
||||
}
|
||||
RETURN(BOM)
|
||||
}
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_WEBVTT0)
|
||||
U_E { SET_STATE(L_WEBVTT1) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_WEBVTT1)
|
||||
U_B { SET_STATE(L_WEBVTT2) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_WEBVTT2)
|
||||
U_V { SET_STATE(L_WEBVTT3) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_WEBVTT3)
|
||||
U_T { SET_STATE(L_WEBVTT4) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_WEBVTT4)
|
||||
U_T { RETURN(WEBVTT) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_DASH0)
|
||||
U_DIGIT { SET_STATE(L_DIGIT0) }
|
||||
U_DASH { SET_STATE(L_SEP1) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_SEP1)
|
||||
U_GT { RETURN(SEPARATOR) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_DIGIT0)
|
||||
U_DIGIT {
|
||||
OVERFLOW(INTEGER)
|
||||
SET_STATE(L_DIGIT0)
|
||||
}
|
||||
U_COLON { SET_STATE(L_TIMESTAMP1) }
|
||||
U_PERCENT { RETURN(PERCENTAGE) }
|
||||
DEFAULT { BACKUP AND RETURN(INTEGER) }
|
||||
END_STATE_EX
|
||||
|
||||
BEGIN_STATE(L_NEWLINE0)
|
||||
U_LF { SET_NEWLINE }
|
||||
DEFAULT { BACKUP AND SET_NEWLINE }
|
||||
END_STATE_EX
|
||||
|
||||
BEGIN_STATE(L_WHITESPACE)
|
||||
U_SPACE OR U_TAB { OVERFLOW(WHITESPACE) SET_STATE(L_WHITESPACE) }
|
||||
DEFAULT { BACKUP RETURN(WHITESPACE) }
|
||||
END_STATE_EX
|
||||
|
||||
BEGIN_STATE(L_POSITION0)
|
||||
U_o { SET_STATE(L_POSITION1) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_POSITION1)
|
||||
U_s { SET_STATE(L_POSITION2) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_POSITION2)
|
||||
U_i { SET_STATE(L_POSITION3) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_POSITION3)
|
||||
U_t { SET_STATE(L_POSITION4) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_POSITION4)
|
||||
U_i { SET_STATE(L_POSITION5) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_POSITION5)
|
||||
U_o { SET_STATE(L_POSITION6) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_POSITION6)
|
||||
U_n { RETURN(POSITION) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_ALIGN0)
|
||||
U_l { SET_STATE(L_ALIGN1) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_ALIGN1)
|
||||
U_i { SET_STATE(L_ALIGN2) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_ALIGN2)
|
||||
U_g { SET_STATE(L_ALIGN3) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_ALIGN3)
|
||||
U_n { RETURN(ALIGN) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_L0)
|
||||
U_r { RETURN(LR) }
|
||||
U_i { SET_STATE(L_LINE1) }
|
||||
U_e { SET_STATE(L_LEFT1) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_LINE1)
|
||||
U_n { SET_STATE(L_LINE2) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_LINE2)
|
||||
U_e { RETURN(LINE) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_LEFT1)
|
||||
U_f { SET_STATE(L_LEFT2) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_LEFT2)
|
||||
U_t { RETURN(LEFT) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_VERTICAL0)
|
||||
U_e { SET_STATE(L_VERTICAL1) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_VERTICAL1)
|
||||
U_r { SET_STATE(L_VERTICAL2) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_VERTICAL2)
|
||||
U_t { SET_STATE(L_VERTICAL3) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_VERTICAL3)
|
||||
U_i { SET_STATE(L_VERTICAL4) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_VERTICAL4)
|
||||
U_c { SET_STATE(L_VERTICAL5) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_VERTICAL5)
|
||||
U_a { SET_STATE(L_VERTICAL6) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_VERTICAL6)
|
||||
U_l { RETURN(VERTICAL) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_RL0)
|
||||
U_l { RETURN(RL) }
|
||||
U_i { SET_STATE(L_RIGHT1) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_RIGHT1)
|
||||
U_g { SET_STATE(L_RIGHT2) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_RIGHT2)
|
||||
U_h { SET_STATE(L_RIGHT3) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_RIGHT3)
|
||||
U_t { RETURN(RIGHT) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_S0)
|
||||
U_t { SET_STATE(L_START1) }
|
||||
U_i { SET_STATE(L_SIZE1) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_SIZE1)
|
||||
U_z { SET_STATE(L_SIZE2) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_SIZE2)
|
||||
U_e { RETURN(SIZE) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_START1)
|
||||
U_a { SET_STATE(L_START2) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_START2)
|
||||
U_r { SET_STATE(L_START3) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_START3)
|
||||
U_t { RETURN(START) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_MIDDLE0)
|
||||
U_i { SET_STATE(L_MIDDLE1) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_MIDDLE1)
|
||||
U_d { SET_STATE(L_MIDDLE2) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_MIDDLE2)
|
||||
U_d { SET_STATE(L_MIDDLE3) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_MIDDLE3)
|
||||
U_l { SET_STATE(L_MIDDLE4) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_MIDDLE4)
|
||||
U_e { RETURN(MIDDLE) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_END0)
|
||||
U_n { SET_STATE(L_END1) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_END1)
|
||||
U_d { RETURN(END) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_TIMESTAMP1)
|
||||
U_DIGIT {
|
||||
OVERFLOW(BADTOKEN)
|
||||
SET_STATE(L_TIMESTAMP1)
|
||||
}
|
||||
U_COLON {
|
||||
OVERFLOW(BADTOKEN)
|
||||
SET_STATE(L_TIMESTAMP2)
|
||||
}
|
||||
U_PERIOD {
|
||||
OVERFLOW(BADTOKEN)
|
||||
SET_STATE(L_TIMESTAMP3)
|
||||
}
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_TIMESTAMP2)
|
||||
U_DIGIT {
|
||||
OVERFLOW(BADTOKEN)
|
||||
SET_STATE(L_TIMESTAMP2)
|
||||
}
|
||||
U_PERIOD {
|
||||
OVERFLOW(BADTOKEN)
|
||||
SET_STATE(L_TIMESTAMP3)
|
||||
}
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_TIMESTAMP3)
|
||||
U_DIGIT {
|
||||
OVERFLOW(TIMESTAMP)
|
||||
BREAK
|
||||
}
|
||||
DEFAULT {
|
||||
BACKUP
|
||||
RETURN(TIMESTAMP)
|
||||
BREAK
|
||||
}
|
||||
END_STATE_EX
|
||||
|
||||
BEGIN_STATE(L_NOTE1)
|
||||
U_O { SET_STATE(L_NOTE2) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_NOTE2)
|
||||
U_T { SET_STATE(L_NOTE3) }
|
||||
END_STATE
|
||||
|
||||
BEGIN_STATE(L_NOTE3)
|
||||
U_E { RETURN(NOTE) }
|
||||
END_STATE
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If we got here, we've reached the end of the buffer.
|
||||
* We therefore can attempt to finish up
|
||||
*/
|
||||
if( finish && self->token_pos ) {
|
||||
switch( self->tstate ) {
|
||||
case L_DIGIT0:
|
||||
RETURN(INTEGER)
|
||||
case L_TIMESTAMP3:
|
||||
RETURN(TIMESTAMP)
|
||||
case L_WHITESPACE:
|
||||
RETURN(WHITESPACE)
|
||||
default:
|
||||
RESET
|
||||
return BADTOKEN;
|
||||
}
|
||||
}
|
||||
return *pos == length || self->token_pos ? UNFINISHED : BADTOKEN;
|
||||
}
|
||||
/**
|
||||
* token states
|
||||
L_START + 'W' = L_WEBVTT0
|
||||
L_START + '-' = L_DASH0
|
||||
L_START + {D} = L_DIGIT0
|
||||
L_START + CR = L_NEWLINE0
|
||||
L_START + LF = *NEWLINE
|
||||
L_START + SP = L_WHITESPACE
|
||||
L_START + TB = L_WHITESPACE
|
||||
L_START + FS = *FULL_STOP
|
||||
L_START + 'p' = L_POSITION0
|
||||
L_START + 'a' = L_ALIGN0
|
||||
L_START + 'l' = L_L0
|
||||
L_START + 'v' = L_VERTICAL0
|
||||
L_START + 'r' = L_RL0
|
||||
L_START + 's' = L_S0
|
||||
L_START + 'm' = L_MIDDLE0
|
||||
L_START + 'e' = L_END0
|
||||
L_WEBVTT0 + 'E' = L_WEBVTT1
|
||||
L_WEBVTT1 + 'B' = L_WEBVTT2
|
||||
L_WEBVTT2 + 'V' = L_WEBVTT3
|
||||
L_WEBVTT3 + 'T' = L_WEBVTT4
|
||||
L_WEBVTT4 + 'T' = *WEBVTT
|
||||
L_DASH0 + {D} = L_DIGIT0
|
||||
L_DASH0 + '-' = L_SEP1
|
||||
L_SEP1 + '>' = *SEPARATOR
|
||||
L_DIGIT0 + {D} = L_DIGIT0
|
||||
L_NEWLINE0 + LF = *NEWLINE
|
||||
L_WHITESPACE + TB = L_WHITESPACE
|
||||
L_WHITESPACE + SP = L_WHITESPACE
|
||||
L_POSITION0 + 'o' = L_POSITION1
|
||||
L_POSITION1 + 's' = L_POSITION2
|
||||
L_POSITION2 + 'i' = L_POSITION3
|
||||
L_POSITION3 + 't' = L_POSITION4
|
||||
L_POSITION4 + 'i' = L_POSITION5
|
||||
L_POSITION5 + 'o' = L_POSITION6
|
||||
L_POSITION6 + 'n' = L_POSITION7
|
||||
L_POSITION7 + ':' = *POSITION
|
||||
L_ALIGN0 + 'l' = L_ALIGN1
|
||||
L_ALIGN1 + 'i' = L_ALIGN2
|
||||
L_ALIGN2 + 'g' = L_ALIGN3
|
||||
L_ALIGN3 + 'n' = L_ALIGN4
|
||||
L_ALIGN4 + ':' = *ALIGN
|
||||
L0 + 'r' = *LR
|
||||
L0 + 'i' = L_LINE1
|
||||
L_LINE1 + 'n' = L_LINE2
|
||||
L_LINE2 + 'e' = L_LINE3
|
||||
L_LINE3 + ':' = *LINE
|
||||
L_VERTICAL0 + 'e' = L_VERTICAL1
|
||||
L_VERTICAL1 + 'r' = L_VERTICAL2
|
||||
L_VERTICAL2 + 't' = L_VERTICAL3
|
||||
L_VERTICAL3 + 'i' = L_VERTICAL4
|
||||
L_VERTICAL4 + 'c' = L_VERTICAL5
|
||||
L_VERTICAL5 + 'a' = L_VERTICAL6
|
||||
L_VERTICAL6 + 'l' = L_VERTICAL7
|
||||
L_VERTICAL7 + ':' = *VERTICAL
|
||||
L_RL0 + 'l' = *RL
|
||||
L_S0 + 't' = L_START1
|
||||
L_S0 + 'i' = L_SIZE1
|
||||
L_SIZE1 + 'z' = L_SIZE2
|
||||
L_SIZE2 + 'e' = L_SIZE3
|
||||
L_SIZE3 + ':' = *SIZE
|
||||
L_START1 + 'a' = L_START2
|
||||
L_START2 + 'r' = L_START3
|
||||
L_START3 + 't' = *START
|
||||
L_MIDDLE0 + 'i' = L_MIDDLE1
|
||||
L_MIDDLE1 + 'd' = L_MIDDLE2
|
||||
L_MIDDLE2 + 'd' = L_MIDDLE3
|
||||
L_MIDDLE3 + 'l' = L_MIDDLE4
|
||||
L_MIDDLE4 + 'e' = *MIDDLE
|
||||
L_END0 + 'n' = L_END1
|
||||
L_END1 + 'd' = *END
|
||||
*/
|
26
media/webvtt/moz.build
Normal file
26
media/webvtt/moz.build
Normal file
@ -0,0 +1,26 @@
|
||||
# vim: set filetype=python:
|
||||
# Copyright (c) 2013 Mozilla Foundation and Contributors
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# - Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# - Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
1387
media/webvtt/parser.c
Normal file
1387
media/webvtt/parser.c
Normal file
File diff suppressed because it is too large
Load Diff
236
media/webvtt/parser_internal.h
Normal file
236
media/webvtt/parser_internal.h
Normal file
@ -0,0 +1,236 @@
|
||||
/**
|
||||
* Copyright (c) 2013 Mozilla Foundation and Contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __INTERN_PARSER_H__
|
||||
# define __INTERN_PARSER_H__
|
||||
# include <webvtt/parser.h>
|
||||
# include "string_internal.h"
|
||||
|
||||
typedef enum
|
||||
webvtt_token_t {
|
||||
BADTOKEN = -2,
|
||||
UNFINISHED = -1, /* not-token */
|
||||
BOM,
|
||||
WEBVTT, /* 'WEBVTT' */
|
||||
NOTE, /* 'NOTE' */
|
||||
INTEGER, /* /-?\d+/ */
|
||||
NEWLINE, /* /[\r\n]|(\r\n)/ */
|
||||
WHITESPACE, /* /[\t ]/ */
|
||||
FULL_STOP, /* '.' */
|
||||
POSITION, /* 'position:' */
|
||||
ALIGN, /* 'align:' */
|
||||
SIZE, /* 'size:' */
|
||||
LINE, /* 'line:' */
|
||||
VERTICAL, /* 'vertical:' */
|
||||
RL, /* 'rl' */
|
||||
LR, /* 'lr' */
|
||||
START, /* 'start' */
|
||||
MIDDLE, /* 'middle' */
|
||||
END, /* 'end' */
|
||||
LEFT, /* 'left' */
|
||||
RIGHT, /* 'right' */
|
||||
SEPARATOR, /* '-->' */
|
||||
TIMESTAMP,
|
||||
PERCENTAGE, /* '\d+%' */
|
||||
COLON, /* ':' */
|
||||
} webvtt_token;
|
||||
|
||||
typedef enum
|
||||
webvtt_state_value_type_t {
|
||||
V_NONE,
|
||||
V_POINTER,
|
||||
V_INTEGER,
|
||||
V_CUE,
|
||||
V_TEXT,
|
||||
V_LNODE,
|
||||
V_INODE,
|
||||
V_TOKEN,
|
||||
} webvtt_state_value_type;
|
||||
|
||||
typedef enum
|
||||
webvtt_parse_mode_t {
|
||||
M_WEBVTT = 0,
|
||||
M_CUETEXT,
|
||||
M_SKIP_CUE,
|
||||
M_READ_LINE,
|
||||
} webvtt_parse_mode;
|
||||
|
||||
|
||||
typedef enum
|
||||
webvtt_parse_state_t {
|
||||
/**
|
||||
* WEBVTT parse states
|
||||
*/
|
||||
T_INITIAL = 0,
|
||||
T_TAG,
|
||||
T_TAGCOMMENT,
|
||||
T_EOL,
|
||||
T_BODY,
|
||||
|
||||
T_CUEREAD, /* Read a line of text for a cue */
|
||||
T_CUE, /* T_CUEID T_CUEPARAMS T_CUETEXT NEWLINE */
|
||||
T_CUEID, /* T_LINE !~ SEPARATOR && LINE !~ ^NOTE NEWLINE */
|
||||
T_CUEPARAMS, /* TIMESTAMP WHITESPACE? SEPARATOR WHITESPACE? T_CUESETTING* NEWLINE */
|
||||
T_CUETEXT, /* T_LINE !~ SEPARATOR NEWLINE NEWLINE */
|
||||
|
||||
T_TIMESTAMP, /* This looked like a timestamp to the lexer, may or may not be valid. */
|
||||
|
||||
/**
|
||||
* NOTE comments
|
||||
*/
|
||||
T_COMMENT,
|
||||
|
||||
/**
|
||||
* Cue times
|
||||
*/
|
||||
T_FROM,
|
||||
T_SEP_LEFT,
|
||||
T_SEP,
|
||||
T_SEP_RIGHT,
|
||||
T_UNTIL,
|
||||
|
||||
/**
|
||||
* Cue settings
|
||||
*/
|
||||
T_PRECUESETTING,
|
||||
T_CUESETTING,
|
||||
T_CUESETTING_DELIMITER,
|
||||
T_CUESETTING_VALUE,
|
||||
T_SKIP_SETTING /* We have to skip a cue-setting because of an error. */
|
||||
|
||||
/**
|
||||
* Cue text parse states
|
||||
*/
|
||||
} webvtt_parse_state;
|
||||
|
||||
/**
|
||||
* lexer state
|
||||
*/
|
||||
typedef enum
|
||||
webvtt_lexer_state_t {
|
||||
L_START = 0, L_BOM0, L_BOM1, L_WEBVTT0, L_WEBVTT1, L_WEBVTT2, L_WEBVTT3, L_WEBVTT4, L_WEBVTT5, L_DASH0, L_SEP1,
|
||||
L_DIGIT0, L_NEWLINE0, L_WHITESPACE, L_POSITION0, L_POSITION1, L_POSITION2, L_POSITION3, L_POSITION4, L_POSITION5,
|
||||
L_POSITION6, L_ALIGN0, L_ALIGN1, L_ALIGN2, L_ALIGN3, L_L0, L_LINE1, L_LINE2, L_LINE3,
|
||||
L_VERTICAL0, L_VERTICAL1, L_VERTICAL2, L_VERTICAL3, L_VERTICAL4, L_VERTICAL5, L_VERTICAL6, L_RL0,
|
||||
L_S0, L_SIZE1, L_SIZE2, L_START1, L_START2, L_START3, L_MIDDLE0, L_MIDDLE1, L_MIDDLE2, L_MIDDLE3,
|
||||
L_MIDDLE4, L_END0, L_END1, L_TIMESTAMP1, L_TIMESTAMP2, L_TIMESTAMP3, L_RIGHT1, L_RIGHT2,
|
||||
L_RIGHT3, L_NOTE1, L_NOTE2, L_NOTE3, L_LEFT1, L_LEFT2,
|
||||
} webvtt_lexer_state;
|
||||
|
||||
typedef struct
|
||||
webvtt_state {
|
||||
webvtt_parse_state state;
|
||||
webvtt_token token;
|
||||
webvtt_state_value_type type;
|
||||
webvtt_uint back;
|
||||
webvtt_uint line;
|
||||
webvtt_uint column;
|
||||
union {
|
||||
/**
|
||||
* cue value
|
||||
*/
|
||||
webvtt_cue *cue;
|
||||
|
||||
/**
|
||||
* string value
|
||||
*/
|
||||
webvtt_string text;
|
||||
|
||||
/**
|
||||
* The cuetext parser is not currently using the state stack, and
|
||||
* because of this, 'node' is never actually used.
|
||||
*
|
||||
* It is here if the cuetext parser begins to use the/a state stack
|
||||
* in the future.
|
||||
*/
|
||||
webvtt_node *node;
|
||||
|
||||
/**
|
||||
* unsigned integer value
|
||||
*/
|
||||
webvtt_uint value;
|
||||
} v;
|
||||
} webvtt_state;
|
||||
|
||||
struct
|
||||
webvtt_parser_t {
|
||||
webvtt_uint state;
|
||||
webvtt_uint bytes; /* number of bytes read. */
|
||||
webvtt_uint line;
|
||||
webvtt_uint column;
|
||||
webvtt_cue_fn read;
|
||||
webvtt_error_fn error;
|
||||
void *userdata;
|
||||
webvtt_bool finished;
|
||||
|
||||
/**
|
||||
* 'mode' can have several states, it is not boolean.
|
||||
*/
|
||||
webvtt_parse_mode mode;
|
||||
|
||||
webvtt_state *top; /* Top parse state */
|
||||
webvtt_state astack[0x100];
|
||||
webvtt_state *stack; /* dynamically allocated stack, if 'astack' fills up */
|
||||
webvtt_uint stack_alloc; /* item capacity in 'stack' */
|
||||
webvtt_bool popped;
|
||||
|
||||
/**
|
||||
* line (cue payload also stored here)
|
||||
*/
|
||||
int truncate;
|
||||
webvtt_uint line_pos;
|
||||
webvtt_string line_buffer;
|
||||
|
||||
/**
|
||||
* tokenizer
|
||||
*/
|
||||
webvtt_lexer_state tstate;
|
||||
webvtt_uint token_pos;
|
||||
webvtt_byte token[0x100];
|
||||
};
|
||||
|
||||
WEBVTT_INTERN webvtt_token webvtt_lex( webvtt_parser self, const webvtt_byte *buffer, webvtt_uint *pos, webvtt_uint length, webvtt_bool finish );
|
||||
WEBVTT_INTERN webvtt_status webvtt_lex_word( webvtt_parser self, webvtt_string *pba, const webvtt_byte *buffer, webvtt_uint *pos, webvtt_uint length, webvtt_bool finish );
|
||||
WEBVTT_INTERN int parse_timestamp( const webvtt_byte *b, webvtt_timestamp *result );
|
||||
|
||||
#define BAD_TIMESTAMP(ts) ( ( ts ) == 0xFFFFFFFFFFFFFFFF )
|
||||
|
||||
#define ERROR(Code) \
|
||||
do \
|
||||
{ \
|
||||
if( !self->error || self->error(self->userdata,self->line,self->column,Code) < 0 ) \
|
||||
return WEBVTT_PARSE_ERROR; \
|
||||
} while(0)
|
||||
|
||||
#define ERROR_AT_COLUMN(Code,Column) \
|
||||
do \
|
||||
{ \
|
||||
if( !self->error || self->error(self->userdata,self->line,(Column),Code) < 0 ) \
|
||||
return WEBVTT_PARSE_ERROR; \
|
||||
} while(0)
|
||||
|
||||
#endif
|
695
media/webvtt/string.c
Normal file
695
media/webvtt/string.c
Normal file
@ -0,0 +1,695 @@
|
||||
/**
|
||||
* Copyright (c) 2013 Mozilla Foundation and Contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "string_internal.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
static webvtt_string_data empty_string = {
|
||||
{ 1 }, /* init refcount */
|
||||
0, /* length */
|
||||
0, /* capacity */
|
||||
empty_string.array, /* text */
|
||||
{ '\0' } /* array */
|
||||
};
|
||||
|
||||
WEBVTT_EXPORT void
|
||||
webvtt_init_string( webvtt_string *result )
|
||||
{
|
||||
if( result ) {
|
||||
result->d = &empty_string;
|
||||
webvtt_ref( &result->d->refs );
|
||||
}
|
||||
}
|
||||
|
||||
WEBVTT_EXPORT webvtt_uint
|
||||
webvtt_string_is_empty( const webvtt_string *str ) {
|
||||
return str->d == &empty_string || webvtt_string_length( str ) == 0 ? 1 : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allocate new string.
|
||||
*/
|
||||
WEBVTT_EXPORT webvtt_status
|
||||
webvtt_create_string( webvtt_uint32 alloc, webvtt_string *result )
|
||||
{
|
||||
webvtt_string_data *d;
|
||||
|
||||
if( !result ) {
|
||||
return WEBVTT_INVALID_PARAM;
|
||||
}
|
||||
|
||||
d = ( webvtt_string_data * )webvtt_alloc( sizeof( webvtt_string_data ) + ( alloc * sizeof( webvtt_byte ) ) );
|
||||
|
||||
if( !d ) {
|
||||
return WEBVTT_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
d->refs.value = 1;
|
||||
d->alloc = alloc;
|
||||
d->length = 0;
|
||||
d->text = d->array;
|
||||
d->text[0] = 0;
|
||||
|
||||
result->d = d;
|
||||
|
||||
return WEBVTT_SUCCESS;
|
||||
}
|
||||
|
||||
WEBVTT_EXPORT webvtt_status
|
||||
webvtt_create_string_with_text( webvtt_string *result, const webvtt_byte *init_text, int len )
|
||||
{
|
||||
webvtt_uint pos = 0;
|
||||
|
||||
if( !result ) {
|
||||
return WEBVTT_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if( !init_text ) {
|
||||
webvtt_init_string( result );
|
||||
return WEBVTT_SUCCESS;
|
||||
}
|
||||
|
||||
if( len < 0 ) {
|
||||
len = strlen( ( const char * )init_text );
|
||||
}
|
||||
|
||||
if( len == 0 ) {
|
||||
webvtt_init_string( result );
|
||||
return WEBVTT_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* initialize the string by referencing empty_string
|
||||
*/
|
||||
webvtt_init_string( result );
|
||||
|
||||
/**
|
||||
* append the appropriate data to the empty string
|
||||
*/
|
||||
return webvtt_string_append( result, init_text, len );
|
||||
}
|
||||
|
||||
/**
|
||||
* reference counting
|
||||
*/
|
||||
WEBVTT_EXPORT void
|
||||
webvtt_ref_string( webvtt_string *str )
|
||||
{
|
||||
if( str ) {
|
||||
webvtt_ref( &str->d->refs );
|
||||
}
|
||||
}
|
||||
|
||||
WEBVTT_EXPORT void
|
||||
webvtt_release_string( webvtt_string *str )
|
||||
{
|
||||
/**
|
||||
* pulls the string data out of the string container, decreases the string
|
||||
*/
|
||||
if( str ) {
|
||||
webvtt_string_data *d = str->d;
|
||||
str->d = 0;
|
||||
if( d && webvtt_deref( &d->refs ) == 0 ) {
|
||||
webvtt_free( d );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* "Detach" a shared string, so that it's safely mutable
|
||||
*/
|
||||
WEBVTT_EXPORT webvtt_status
|
||||
webvtt_string_detach( /* in, out */ webvtt_string *str )
|
||||
{
|
||||
webvtt_string_data *d, *q;
|
||||
|
||||
if( !str ) {
|
||||
return WEBVTT_INVALID_PARAM;
|
||||
}
|
||||
|
||||
q = str->d;
|
||||
|
||||
if( q->refs.value == 1 ) {
|
||||
return WEBVTT_SUCCESS;
|
||||
}
|
||||
|
||||
d = ( webvtt_string_data * )webvtt_alloc( sizeof( webvtt_string_data ) + ( sizeof( webvtt_byte ) * str->d->alloc ) );
|
||||
|
||||
d->refs.value = 1;
|
||||
d->text = d->array;
|
||||
d->alloc = q->alloc;
|
||||
d->length = q->length;
|
||||
memcpy( d->text, q->text, q->length );
|
||||
|
||||
str->d = d;
|
||||
|
||||
if( webvtt_deref( &q->refs ) == 0 ) {
|
||||
webvtt_free( q );
|
||||
}
|
||||
|
||||
return WEBVTT_SUCCESS;
|
||||
}
|
||||
|
||||
WEBVTT_EXPORT void
|
||||
webvtt_copy_string( webvtt_string *left, const webvtt_string *right )
|
||||
{
|
||||
if( left ) {
|
||||
webvtt_string_data *d = left->d;
|
||||
if( right && right->d ) {
|
||||
left->d = right->d;
|
||||
} else {
|
||||
left->d = &empty_string;
|
||||
}
|
||||
webvtt_ref( &left->d->refs );
|
||||
}
|
||||
}
|
||||
|
||||
WEBVTT_EXPORT const webvtt_byte *
|
||||
webvtt_string_text(const webvtt_string *str)
|
||||
{
|
||||
if( !str || !str->d )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return str->d->text;
|
||||
}
|
||||
|
||||
WEBVTT_EXPORT const webvtt_uint32
|
||||
webvtt_string_length(const webvtt_string *str)
|
||||
{
|
||||
if( !str || !str->d )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return str->d->length;
|
||||
}
|
||||
|
||||
WEBVTT_EXPORT const webvtt_uint32
|
||||
webvtt_string_capacity(const webvtt_string *str)
|
||||
{
|
||||
if( !str || !str->d )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return str->d->alloc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reallocate string.
|
||||
* Grow to at least 'need' characters. Power of 2 growth.
|
||||
*/
|
||||
static webvtt_status
|
||||
grow( webvtt_string *str, webvtt_uint need )
|
||||
{
|
||||
static const webvtt_uint page = 0x1000;
|
||||
webvtt_uint32 n;
|
||||
webvtt_string_data *p, *d;
|
||||
webvtt_uint32 grow;
|
||||
|
||||
if( !str )
|
||||
{
|
||||
return WEBVTT_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if( ( str->d->length + need ) <= str->d->alloc )
|
||||
{
|
||||
return WEBVTT_SUCCESS;
|
||||
}
|
||||
|
||||
p = d = str->d;
|
||||
grow = sizeof( *d ) + ( sizeof( webvtt_byte ) * ( d->length + need ) );
|
||||
|
||||
if( grow < page ) {
|
||||
n = page;
|
||||
do {
|
||||
n = n / 2;
|
||||
} while( n > grow );
|
||||
if( n < 1 << 6 ) {
|
||||
n = 1 << 6;
|
||||
} else {
|
||||
n = n * 2;
|
||||
}
|
||||
} else {
|
||||
n = page;
|
||||
do {
|
||||
n = n * 2;
|
||||
} while ( n < grow );
|
||||
}
|
||||
|
||||
p = ( webvtt_string_data * )webvtt_alloc( n );
|
||||
|
||||
if( !p ) {
|
||||
return WEBVTT_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
p->refs.value = 1;
|
||||
p->alloc = ( n - sizeof( *p ) ) / sizeof( webvtt_byte );
|
||||
p->length = d->length;
|
||||
p->text = p->array;
|
||||
memcpy( p->text, d->text, sizeof( webvtt_byte ) * p->length );
|
||||
p->text[ p->length ] = 0;
|
||||
str->d = p;
|
||||
|
||||
if( webvtt_deref( &d->refs ) == 0 ) {
|
||||
webvtt_free( d );
|
||||
}
|
||||
|
||||
return WEBVTT_SUCCESS;
|
||||
}
|
||||
|
||||
WEBVTT_EXPORT int
|
||||
webvtt_string_getline( webvtt_string *src, const webvtt_byte *buffer,
|
||||
webvtt_uint *pos, webvtt_uint len, int *truncate, webvtt_bool finish, webvtt_bool retain_new_line )
|
||||
{
|
||||
int ret = 0;
|
||||
webvtt_string *str = src;
|
||||
webvtt_string_data *d = 0;
|
||||
const webvtt_byte *s = buffer + *pos;
|
||||
const webvtt_byte *p = s;
|
||||
const webvtt_byte *n = buffer + len;
|
||||
|
||||
/**
|
||||
*if this is public now, maybe we should return webvtt_status so we can
|
||||
* differentiate between WEBVTT_OUT_OF_MEMORY and WEBVTT_INVALID_PARAM
|
||||
*/
|
||||
if( !str ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* This had better be a valid string_data, or else NULL. */
|
||||
d = str->d;
|
||||
if( !str->d ) {
|
||||
if(WEBVTT_FAILED(webvtt_create_string( 0x100, str ))) {
|
||||
return -1;
|
||||
}
|
||||
d = str->d;
|
||||
}
|
||||
|
||||
while( p < n && *p != UTF8_CARRIAGE_RETURN && *p != UTF8_LINE_FEED ) {
|
||||
++p;
|
||||
}
|
||||
/* Retain the new line character. */
|
||||
if( p < n && retain_new_line ) {
|
||||
p++;
|
||||
}
|
||||
|
||||
if( p < n || finish ) {
|
||||
ret = 1; /* indicate that we found EOL */
|
||||
}
|
||||
len = (webvtt_uint)( p - s );
|
||||
*pos += len;
|
||||
if( d->length + len + 1 >= d->alloc ) {
|
||||
if( truncate && d->alloc >= WEBVTT_MAX_LINE ) {
|
||||
/* truncate. */
|
||||
(*truncate)++;
|
||||
} else {
|
||||
if( grow( str, len ) == WEBVTT_OUT_OF_MEMORY ) {
|
||||
ret = -1;
|
||||
}
|
||||
d = str->d;
|
||||
}
|
||||
}
|
||||
|
||||
/* Copy everything in */
|
||||
if( len && ret >= 0 && d->length + len < d->alloc ) {
|
||||
memcpy( d->text + d->length, s, len );
|
||||
d->length += len;
|
||||
d->text[ d->length ] = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
WEBVTT_EXPORT webvtt_status
|
||||
webvtt_string_putc( webvtt_string *str, webvtt_byte to_append )
|
||||
{
|
||||
webvtt_status result;
|
||||
|
||||
if( !str ) {
|
||||
return WEBVTT_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if( WEBVTT_FAILED( result = webvtt_string_detach( str ) ) ) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if( !WEBVTT_FAILED( result = grow( str, 1 ) ) )
|
||||
{
|
||||
str->d->text[ str->d->length++ ] = to_append;
|
||||
str->d->text[ str->d->length ] = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
WEBVTT_EXPORT webvtt_status
|
||||
webvtt_string_append( webvtt_string *str, const webvtt_byte *buffer, int len )
|
||||
{
|
||||
webvtt_status result;
|
||||
|
||||
if( !str || !buffer ) {
|
||||
return WEBVTT_INVALID_PARAM;
|
||||
}
|
||||
if( !str->d ) {
|
||||
webvtt_init_string( str );
|
||||
}
|
||||
|
||||
if( len < 0 ) {
|
||||
len = strlen( ( const char * )buffer );
|
||||
}
|
||||
|
||||
if( len == 0 ) {
|
||||
return WEBVTT_SUCCESS;
|
||||
}
|
||||
|
||||
if( !WEBVTT_FAILED( result = grow( str, str->d->length + len ) ) ) {
|
||||
memcpy( str->d->text + str->d->length, buffer, len );
|
||||
str->d->length += len;
|
||||
/* null-terminate string */
|
||||
str->d->text[ str->d->length ] = 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
WEBVTT_EXPORT webvtt_status
|
||||
webvtt_string_append_string( webvtt_string *str, const webvtt_string *other )
|
||||
{
|
||||
if( !str || !other ) {
|
||||
return WEBVTT_INVALID_PARAM;
|
||||
}
|
||||
|
||||
return webvtt_string_append( str, other->d->text, other->d->length );
|
||||
}
|
||||
|
||||
/**
|
||||
* String lists
|
||||
*/
|
||||
WEBVTT_EXPORT webvtt_status
|
||||
webvtt_create_stringlist( webvtt_stringlist **result )
|
||||
{
|
||||
webvtt_stringlist *list;
|
||||
|
||||
if( !result ) {
|
||||
return WEBVTT_INVALID_PARAM;
|
||||
}
|
||||
|
||||
list = ( webvtt_stringlist * )webvtt_alloc0( sizeof( *list ) );
|
||||
|
||||
if( !list ) {
|
||||
return WEBVTT_OUT_OF_MEMORY;
|
||||
}
|
||||
list->alloc = 0;
|
||||
list->length = 0;
|
||||
webvtt_ref_stringlist( list );
|
||||
|
||||
*result = list;
|
||||
|
||||
return WEBVTT_SUCCESS;
|
||||
}
|
||||
|
||||
WEBVTT_EXPORT void
|
||||
webvtt_ref_stringlist( webvtt_stringlist *list )
|
||||
{
|
||||
if( list ) {
|
||||
webvtt_ref( &list->refs );
|
||||
}
|
||||
}
|
||||
|
||||
WEBVTT_EXPORT void
|
||||
webvtt_copy_stringlist( webvtt_stringlist **left, webvtt_stringlist *right )
|
||||
{
|
||||
if( !left || !right ) {
|
||||
return;
|
||||
}
|
||||
*left = right;
|
||||
webvtt_ref_stringlist( *left );
|
||||
}
|
||||
WEBVTT_EXPORT void
|
||||
webvtt_release_stringlist( webvtt_stringlist **list )
|
||||
{
|
||||
webvtt_stringlist *l;
|
||||
webvtt_uint i;
|
||||
|
||||
if( !list || !*list ) {
|
||||
return;
|
||||
}
|
||||
l = *list;
|
||||
|
||||
if( webvtt_deref( &l->refs ) == 0 ) {
|
||||
if( l->items ) {
|
||||
for( i = 0; i < l->length; i++ ) {
|
||||
webvtt_release_string( &l->items[ i ] );
|
||||
}
|
||||
webvtt_free( l->items );
|
||||
}
|
||||
webvtt_free( l );
|
||||
}
|
||||
*list = 0;
|
||||
}
|
||||
|
||||
WEBVTT_EXPORT webvtt_status
|
||||
webvtt_stringlist_push( webvtt_stringlist *list, webvtt_string *str )
|
||||
{
|
||||
if( !list || !str ) {
|
||||
return WEBVTT_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if( list->length + 1 >= ( ( list->alloc / 3 ) * 2 ) ) {
|
||||
webvtt_string *arr, *old;
|
||||
|
||||
list->alloc = list->alloc == 0 ? 8 : list->alloc * 2;
|
||||
arr = ( webvtt_string * )webvtt_alloc0( sizeof( webvtt_string ) * list->alloc );
|
||||
|
||||
if( !arr ) {
|
||||
return WEBVTT_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
memcpy( arr, list->items, sizeof( webvtt_string ) * list->length );
|
||||
old = list->items;
|
||||
list->items = arr;
|
||||
|
||||
webvtt_free( old );
|
||||
}
|
||||
|
||||
list->items[list->length].d = str->d;
|
||||
webvtt_ref_string( list->items + list->length++ );
|
||||
|
||||
return WEBVTT_SUCCESS;
|
||||
}
|
||||
|
||||
WEBVTT_EXPORT webvtt_bool
|
||||
webvtt_next_utf8( const webvtt_byte **begin, const webvtt_byte *end )
|
||||
{
|
||||
int c;
|
||||
const webvtt_byte *p;
|
||||
if( !begin || !*begin || !**begin || ( end && ( end <= *begin ) ) ) {
|
||||
/* Either begin is null, or end is null, or end <= begin */
|
||||
return 0;
|
||||
}
|
||||
|
||||
p = *begin;
|
||||
|
||||
if( !end ) {
|
||||
end = p + strlen( ( const char * )p );
|
||||
}
|
||||
|
||||
c = webvtt_utf8_length( p );
|
||||
if( c > 0 ) {
|
||||
p += c;
|
||||
} else if( ( *p & 0xC0 ) == 0x80 ) {
|
||||
const webvtt_byte *pc = p + 1;
|
||||
while( pc < end && ( ( *pc & 0xC0 ) == 0x80 ) ) {
|
||||
++pc;
|
||||
}
|
||||
if( pc <= end ) {
|
||||
p = pc;
|
||||
}
|
||||
}
|
||||
|
||||
if( *begin != p && p <= end ) {
|
||||
*begin = p;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
WEBVTT_EXPORT webvtt_bool
|
||||
webvtt_skip_utf8( const webvtt_byte **begin, const webvtt_byte *end, int n_chars )
|
||||
{
|
||||
const webvtt_byte *first;
|
||||
if( !begin || !*begin ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( n_chars < 0 ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
first = *begin;
|
||||
if( !end ) {
|
||||
end = first + strlen( ( const char * )first );
|
||||
}
|
||||
|
||||
if( end > first ) {
|
||||
/* forwards */
|
||||
while( n_chars && end > *begin ) {
|
||||
if( webvtt_next_utf8( begin, end ) ) {
|
||||
--n_chars;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return n_chars == 0;
|
||||
}
|
||||
|
||||
WEBVTT_EXPORT webvtt_uint16
|
||||
webvtt_utf8_to_utf16( const webvtt_byte *utf8, const webvtt_byte *end,
|
||||
webvtt_uint16 *high_surrogate )
|
||||
{
|
||||
int need = 0, min = 0;
|
||||
webvtt_uint32 uc = 0;
|
||||
|
||||
/* We're missing our pointers */
|
||||
if( !utf8 ) {
|
||||
return 0;
|
||||
}
|
||||
if( !end ) {
|
||||
end = utf8 + strlen( ( const char * )utf8 );
|
||||
}
|
||||
if( utf8 >= end ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If we are returning a surrogate pair, initialize it to 0 */
|
||||
if( high_surrogate ) {
|
||||
*high_surrogate = 0;
|
||||
}
|
||||
|
||||
/* We're not at the start of a character */
|
||||
if( ( *utf8 & 0xC0 ) == 0x80 ) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( *utf8 < 0x80 ) {
|
||||
return ( webvtt_uint32 )( *utf8 );
|
||||
}
|
||||
while( utf8 < end ) {
|
||||
webvtt_byte ch = *utf8;
|
||||
utf8++;
|
||||
if( need ) {
|
||||
if( ( ch & 0xC0 ) == 0x80 ) {
|
||||
uc = ( uc << 6 ) | ( ch & 0x3F );
|
||||
if (!--need) {
|
||||
int nc;
|
||||
if ( !( nc = UTF_IS_NONCHAR( uc ) ) && uc > 0xFFFF && uc < 0x110000) {
|
||||
/* Surrogate pair */
|
||||
if( high_surrogate ) {
|
||||
*high_surrogate = UTF_HIGH_SURROGATE( uc );
|
||||
}
|
||||
return UTF_LOW_SURROGATE( uc );
|
||||
} else if ( ( uc < min ) || ( uc >= 0xD800 && uc <= 0xDFFF ) || nc || uc >= 0x110000) {
|
||||
/* Non-character, overlong sequence, or utf16 surrogate */
|
||||
return 0xFFFD;
|
||||
} else {
|
||||
/* Non-surrogate */
|
||||
return uc;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ( ( ch & 0xE0 ) == 0xC0 ) {
|
||||
uc = ch & 0x1f;
|
||||
need = 1;
|
||||
min = 0x80;
|
||||
} else if ( ( ch & 0xF0 ) == 0xE0 ) {
|
||||
uc = ch & 0x0f;
|
||||
need = 2;
|
||||
min = 0x800;
|
||||
} else if ( ( ch & 0xF8 ) == 0xF0 ) {
|
||||
uc = ch & 0x07;
|
||||
need = 3;
|
||||
min = 0x10000;
|
||||
} else {
|
||||
/* TODO This should deal with 5-7 byte sequences */
|
||||
/* return the replacement character in other cases */
|
||||
return 0xFFFD;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
WEBVTT_EXPORT int
|
||||
webvtt_utf8_chcount( const webvtt_byte *utf8, const webvtt_byte *end )
|
||||
{
|
||||
int n = 0;
|
||||
const webvtt_byte *p;
|
||||
if( !utf8 || !*utf8 || ( end != 0 && end < utf8 ) ) {
|
||||
return 0;
|
||||
}
|
||||
if( !end ) {
|
||||
end = utf8 + strlen( ( const char * )utf8 );
|
||||
}
|
||||
|
||||
for( p = utf8; p < end; ++n ) {
|
||||
int c = webvtt_utf8_length( p );
|
||||
if( c < 1 ) {
|
||||
break;
|
||||
}
|
||||
p += c;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
WEBVTT_EXPORT int
|
||||
webvtt_utf8_length( const webvtt_byte *utf8 )
|
||||
{
|
||||
webvtt_byte ch;
|
||||
if( !utf8 ) {
|
||||
return 0;
|
||||
}
|
||||
ch = *utf8;
|
||||
if( ch < 0x80 ) {
|
||||
return 1;
|
||||
} else if( ( ch & 0xE0 ) == 0xC0 ) {
|
||||
return 2;
|
||||
} else if( ( ch & 0xF0 ) == 0xE0 ) {
|
||||
return 3;
|
||||
} else if( ( ch & 0xF8 ) == 0xF0 ) {
|
||||
return 4;
|
||||
} else if( ( ch & 0xFE ) == 0xFC ) {
|
||||
return 5;
|
||||
}
|
||||
return -1;
|
||||
}
|
143
media/webvtt/string_internal.h
Normal file
143
media/webvtt/string_internal.h
Normal file
@ -0,0 +1,143 @@
|
||||
/**
|
||||
* Copyright (c) 2013 Mozilla Foundation and Contributors
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* - Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __INTERN_STRING_H__
|
||||
# define __INTERN_STRING_H__
|
||||
# include <webvtt/string.h>
|
||||
|
||||
# define UTF8_AMPERSAND (0x26)
|
||||
# define UTF8_LESS_THAN (0x3C)
|
||||
# define UTF8_GREATER_THAN (0x3E)
|
||||
# define UTF8_HYPHEN_MINUS (0x2D)
|
||||
# define UTF8_LEFT_TO_RIGHT_1 (0xE2)
|
||||
# define UTF8_LEFT_TO_RIGHT_2 (0x80)
|
||||
# define UTF8_LEFT_TO_RIGHT_3 (0x8E)
|
||||
# define UTF8_RIGHT_TO_LEFT_1 (0xE2)
|
||||
# define UTF8_RIGHT_TO_LEFT_2 (0x80)
|
||||
# define UTF8_RIGHT_TO_LEFT_3 (0x8F)
|
||||
# define UTF8_NO_BREAK_SPACE_1 (0xC2)
|
||||
# define UTF8_NO_BREAK_SPACE_2 (0xA0)
|
||||
# define UTF8_NULL_BYTE (0x00)
|
||||
# define UTF8_COLON (0x3A)
|
||||
# define UTF8_SEMI_COLON (0x3B)
|
||||
# define UTF8_TAB (0x09)
|
||||
# define UTF8_FORM_FEED (0x0C)
|
||||
# define UTF8_LINE_FEED (0x0A)
|
||||
# define UTF8_CARRIAGE_RETURN (0x0D)
|
||||
# define UTF8_FULL_STOP (0x2E)
|
||||
# define UTF8_SOLIDUS (0x2F)
|
||||
# define UTF8_SPACE (0x20)
|
||||
# define UTF8_DIGIT_ZERO (0x30)
|
||||
# define UTF8_DIGIT_NINE (0x39)
|
||||
|
||||
# define UTF8_CAPITAL_A (0x41)
|
||||
# define UTF8_CAPITAL_Z (0x5A)
|
||||
|
||||
# define UTF8_A (0x61)
|
||||
# define UTF8_B (0x62)
|
||||
# define UTF8_C (0x63)
|
||||
# define UTF8_D (0x64)
|
||||
# define UTF8_E (0x65)
|
||||
# define UTF8_F (0x66)
|
||||
# define UTF8_G (0x67)
|
||||
# define UTF8_H (0x68)
|
||||
# define UTF8_I (0x69)
|
||||
# define UTF8_J (0x6A)
|
||||
# define UTF8_K (0x6B)
|
||||
# define UTF8_L (0x6C)
|
||||
# define UTF8_M (0x6D)
|
||||
# define UTF8_N (0x6E)
|
||||
# define UTF8_O (0x6F)
|
||||
# define UTF8_P (0x70)
|
||||
# define UTF8_Q (0x71)
|
||||
# define UTF8_R (0x72)
|
||||
# define UTF8_S (0x73)
|
||||
# define UTF8_T (0x74)
|
||||
# define UTF8_U (0x75)
|
||||
# define UTF8_V (0x76)
|
||||
# define UTF8_W (0x77)
|
||||
# define UTF8_X (0x78)
|
||||
# define UTF8_Y (0x79)
|
||||
# define UTF8_Z (0x7A)
|
||||
|
||||
/**
|
||||
* Taken from ICU
|
||||
* http://source.icu-project.org/repos/icu/icu/trunk/source/common/unicode/utf.h
|
||||
*/
|
||||
# define UTF_IS_NONCHAR( C ) \
|
||||
( ( C )>=0xFDD0 && \
|
||||
( ( webvtt_uint32 )( C ) <= 0xfdef || ( ( C ) & 0xFFFE)==0xFFFE) && \
|
||||
( webvtt_uint32 )( C ) <= 0x10FFFF )
|
||||
|
||||
# define UTF_HIGH_SURROGATE( C ) ( webvtt_uint16 )( ( ( C ) >> 10 ) + 0xD7C0 )
|
||||
# define UTF_LOW_SURROGATE( C ) ( webvtt_uint16 )( ( ( C ) & 0x3FF ) | 0xDC00 )
|
||||
|
||||
# ifndef WEBVTT_MAX_LINE
|
||||
# define WEBVTT_MAX_LINE 0x10000
|
||||
# endif
|
||||
|
||||
# ifdef WEBVTT_INLINE
|
||||
# define __WEBVTT_STRING_INLINE WEBVTT_INLINE
|
||||
# else
|
||||
# define __WEBVTT_STRING_INLINE
|
||||
# endif
|
||||
|
||||
struct
|
||||
webvtt_string_data_t {
|
||||
struct webvtt_refcount_t refs;
|
||||
webvtt_uint32 alloc;
|
||||
webvtt_uint32 length;
|
||||
webvtt_byte *text;
|
||||
webvtt_byte array[1];
|
||||
};
|
||||
|
||||
static __WEBVTT_STRING_INLINE int
|
||||
webvtt_isalpha( webvtt_byte ch )
|
||||
{
|
||||
return ( ( ( ch >= UTF8_CAPITAL_A ) && ( ch <= UTF8_CAPITAL_Z ) ) || ( ( ch >= UTF8_A ) && ( ch <= UTF8_Z ) ) );
|
||||
}
|
||||
static __WEBVTT_STRING_INLINE int
|
||||
webvtt_isdigit( webvtt_byte ch )
|
||||
{
|
||||
return ( ( ch >= UTF8_DIGIT_ZERO ) && ( ch <= UTF8_DIGIT_NINE ) );
|
||||
}
|
||||
|
||||
static __WEBVTT_STRING_INLINE int
|
||||
webvtt_isalphanum( webvtt_byte ch )
|
||||
{
|
||||
return ( webvtt_isalpha( ch ) || webvtt_isdigit( ch ) );
|
||||
}
|
||||
|
||||
static __WEBVTT_STRING_INLINE int
|
||||
webvtt_iswhite( webvtt_byte ch )
|
||||
{
|
||||
return ( ( ch == UTF8_CARRIAGE_RETURN ) || ( ch == UTF8_LINE_FEED ) || ( ch == UTF8_FORM_FEED )
|
||||
|| ( ch == UTF8_TAB ) || ( ch == UTF8_SPACE ) ) ;
|
||||
}
|
||||
|
||||
# undef __WEBVTT_STRING_INLINE
|
||||
#endif
|
79
media/webvtt/update.sh
Normal file
79
media/webvtt/update.sh
Normal file
@ -0,0 +1,79 @@
|
||||
#!/bin/sh
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
# Usage: ./update.sh <webvtt_git_repository> <optional revision/branch/refspec>
|
||||
#
|
||||
# Copies the needed files from a directory containing the original
|
||||
# libwebvtt source, and applies any local patches we're carrying.
|
||||
|
||||
function die() {
|
||||
echo "error: $1"
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [ $# -lt 1 ]; then
|
||||
die "Usage: update.sh /path/to/webvtt-repository/ commit/remote/branch (default HEAD)"
|
||||
fi
|
||||
|
||||
git --version 2>&1 >/dev/null #executable not found? ok.
|
||||
have_git=$?
|
||||
hg --version 2>&1 >/dev/null #executable not found? ok.
|
||||
have_hg=$?
|
||||
if [ ${have_git} -ne 0 ]; then
|
||||
die "Git does not seem to be installed"
|
||||
fi
|
||||
|
||||
start_dir=$PWD
|
||||
webvtt_branch=HEAD
|
||||
if [ $# -gt 1 ]; then
|
||||
webvtt_branch="$2"
|
||||
fi
|
||||
|
||||
webvtt_dir=$(dirname $0)
|
||||
webvtt_remote=$1
|
||||
repo_dir=${webvtt_dir}/libwebvtt
|
||||
|
||||
cd ${webvtt_remote}
|
||||
webvtt_isrepo=$(git rev-parse --is-inside-work-tree)
|
||||
if [ "x${webvtt_isrepo}" != "xtrue" ]; then
|
||||
cd ${start_dir}
|
||||
die "$1 does not seem to be a git repository"
|
||||
fi
|
||||
|
||||
webvtt_revision=$(git rev-parse ${webvtt_branch})
|
||||
echo "Updating media/webvtt to revision ${webvtt_branch} (${webvtt_revision})"
|
||||
|
||||
#Ensure that ${repo_dir} is not present to prevent mkdir from failing
|
||||
#Error hidden because most of the time it shouldn't be present anyways, so an
|
||||
#error is generally expected.
|
||||
rm -rf ${start_dir}/${repo_dir} 2>/dev/null
|
||||
|
||||
#Try to create temporary directory for repo archive. If this fails,
|
||||
#print error and exit.
|
||||
mkdir ${start_dir}/${repo_dir} || exit 1
|
||||
git archive --format=tar ${webvtt_revision} | tar -C ${start_dir}/${repo_dir} -xf -
|
||||
cd ${start_dir}
|
||||
|
||||
sed -e "s/^[a-z0-9]\{40,40\}/${webvtt_revision}/" \
|
||||
${webvtt_dir}/README_MOZILLA > ${webvtt_dir}/README_MOZILLA.sed
|
||||
mv ${webvtt_dir}/README_MOZILLA.sed ${webvtt_dir}/README_MOZILLA \
|
||||
|| die "Failed to overwrite README_MOZILLA"
|
||||
|
||||
rm -rf ${webvtt_dir}/include ${webvtt_dir}/*.c ${webvtt_dir}/*.h
|
||||
#Create directories
|
||||
mkdir ${webvtt_dir}/include ${webvtt_dir}/include/webvtt
|
||||
|
||||
#Copy C headers, excluding 'webvtt-config' files (hence [^w])
|
||||
find ${repo_dir}/include/webvtt -type f -name '[^w]*.h' -exec cp '{}' \
|
||||
${webvtt_dir}/include/webvtt/ \; #Copy C sources
|
||||
find ${repo_dir}/src/libwebvtt -type f -name '*.[ch]' -exec cp '{}' \
|
||||
${webvtt_dir}/ \;
|
||||
cp ${repo_dir}/LICENSE ${webvtt_dir}/
|
||||
rm -rf ${repo_dir}
|
||||
|
||||
# addremove automatically if mercurial is used
|
||||
if [ ${have_hg} -eq 0 -a -d ${start_dir}/.hg ]; then
|
||||
hg addremove ${webvtt_dir}/
|
||||
fi
|
@ -141,6 +141,12 @@ tier_platform_dirs += \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifdef MOZ_WEBVTT
|
||||
tier_platform_dirs += \
|
||||
media/webvtt \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
ifdef MOZ_SYDNEYAUDIO
|
||||
tier_platform_dirs += \
|
||||
media/libsydneyaudio \
|
||||
|
@ -82,6 +82,9 @@ if CONFIG['MOZ_OPUS']:
|
||||
if CONFIG['MOZ_WEBM']:
|
||||
add_tier_dir('platform', 'media/libnestegg')
|
||||
|
||||
if CONFIG['MOZ_WEBVTT']:
|
||||
add_tier_dir('platform', 'media/webvtt')
|
||||
|
||||
if CONFIG['MOZ_VP8'] and not CONFIG['MOZ_NATIVE_LIBVPX']:
|
||||
add_tier_dir('platform', 'media/libvpx')
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user