зеркало из https://github.com/mozilla/gecko-dev.git
Bug 849189 - Update webvtt to recent upstream version. r=rillian
This commit is contained in:
Родитель
d81b1e261e
Коммит
8523227c6b
|
@ -22,6 +22,7 @@ DEFINES += \
|
|||
EXPORTS_webvtt = \
|
||||
include/webvtt/cue.h \
|
||||
include/webvtt/error.h \
|
||||
include/webvtt/node.h \
|
||||
include/webvtt/parser.h \
|
||||
include/webvtt/string.h \
|
||||
include/webvtt/util.h \
|
||||
|
@ -33,6 +34,7 @@ CSRCS = \
|
|||
cuetext.c \
|
||||
error.c \
|
||||
lexer.c \
|
||||
node.c \
|
||||
parser.c \
|
||||
string.c \
|
||||
$(NULL)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
These files are from the WebVTT library, and are extracted from rev
|
||||
cd5e95654f1fd6712fcf1941f8936870a484f65e of the git repository at
|
||||
6b637c9f30911433e6d5a5be5d8512317a0d8a14 of the git repository at
|
||||
https://github.com/mozilla/webvtt.
|
||||
|
||||
The following CPPFLAGS are used in order to build and link in Mozilla
|
||||
|
|
|
@ -26,11 +26,7 @@
|
|||
*/
|
||||
|
||||
#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 );
|
||||
|
|
|
@ -25,8 +25,6 @@
|
|||
* 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"
|
||||
|
||||
|
@ -117,191 +115,3 @@ webvtt_validate_cue( webvtt_cue *cue )
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -27,27 +27,8 @@
|
|||
|
||||
#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
|
||||
*/
|
||||
|
@ -63,6 +44,12 @@ enum {
|
|||
|
||||
CUE_HAVE_CUEPARAMS = 0x40000000,
|
||||
CUE_HAVE_ID = 0x80000000,
|
||||
CUE_HEADER_MASK = CUE_HAVE_CUEPARAMS|CUE_HAVE_ID,
|
||||
};
|
||||
|
||||
static webvtt_bool
|
||||
cue_is_incomplete( const webvtt_cue *cue ) {
|
||||
return !cue || ( cue->flags & CUE_HEADER_MASK ) == CUE_HAVE_ID;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -81,7 +81,7 @@ webvtt_skipwhite( webvtt_byte **position )
|
|||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_create_cuetext_token( webvtt_cuetext_token **token, webvtt_cuetext_token_type token_type )
|
||||
webvtt_create_token( webvtt_cuetext_token **token, webvtt_token_type token_type )
|
||||
{
|
||||
webvtt_cuetext_token *temp_token = (webvtt_cuetext_token *)webvtt_alloc0( sizeof(*temp_token) );
|
||||
|
||||
|
@ -96,13 +96,13 @@ webvtt_create_cuetext_token( webvtt_cuetext_token **token, webvtt_cuetext_token_
|
|||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_create_cuetext_start_token( webvtt_cuetext_token **token, webvtt_string *tag_name,
|
||||
webvtt_create_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;
|
||||
webvtt_start_token_data sd;
|
||||
|
||||
if( WEBVTT_FAILED( status = webvtt_create_cuetext_token( token, START_TOKEN ) ) ) {
|
||||
if( WEBVTT_FAILED( status = webvtt_create_token( token, START_TOKEN ) ) ) {
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -116,11 +116,11 @@ webvtt_create_cuetext_start_token( webvtt_cuetext_token **token, webvtt_string *
|
|||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_create_cuetext_end_token( webvtt_cuetext_token **token, webvtt_string *tag_name )
|
||||
webvtt_create_end_token( webvtt_cuetext_token **token, webvtt_string *tag_name )
|
||||
{
|
||||
webvtt_status status;
|
||||
|
||||
if( WEBVTT_FAILED( status = webvtt_create_cuetext_token( token, END_TOKEN ) ) ) {
|
||||
if( WEBVTT_FAILED( status = webvtt_create_token( token, END_TOKEN ) ) ) {
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -130,11 +130,11 @@ webvtt_create_cuetext_end_token( webvtt_cuetext_token **token, webvtt_string *ta
|
|||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_create_cuetext_text_token( webvtt_cuetext_token **token, webvtt_string *text )
|
||||
webvtt_create_text_token( webvtt_cuetext_token **token, webvtt_string *text )
|
||||
{
|
||||
webvtt_status status;
|
||||
|
||||
if( WEBVTT_FAILED( status = webvtt_create_cuetext_token( token, TEXT_TOKEN ) ) ) {
|
||||
if( WEBVTT_FAILED( status = webvtt_create_token( token, TEXT_TOKEN ) ) ) {
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -144,11 +144,11 @@ webvtt_create_cuetext_text_token( webvtt_cuetext_token **token, webvtt_string *t
|
|||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_create_cuetext_timestamp_token( webvtt_cuetext_token **token, webvtt_timestamp time_stamp )
|
||||
webvtt_create_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 ) ) ) {
|
||||
if( WEBVTT_FAILED( status = webvtt_create_token( token, TIME_STAMP_TOKEN ) ) ) {
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -158,9 +158,9 @@ webvtt_create_cuetext_timestamp_token( webvtt_cuetext_token **token, webvtt_time
|
|||
}
|
||||
|
||||
WEBVTT_INTERN void
|
||||
webvtt_delete_cuetext_token( webvtt_cuetext_token **token )
|
||||
webvtt_delete_token( webvtt_cuetext_token **token )
|
||||
{
|
||||
webvtt_cuetext_start_token_data data;
|
||||
webvtt_start_token_data data;
|
||||
webvtt_cuetext_token *t;
|
||||
|
||||
if( !token ) {
|
||||
|
@ -193,31 +193,14 @@ webvtt_delete_cuetext_token( webvtt_cuetext_token **token )
|
|||
*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;
|
||||
return webvtt_string_is_equal( tag_name, "v", 1 );
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 )
|
||||
webvtt_node_kind_from_tag_name( webvtt_string *tag_name, webvtt_node_kind *kind )
|
||||
{
|
||||
if( !tag_name || !kind ) {
|
||||
return WEBVTT_INVALID_PARAM;
|
||||
|
@ -241,9 +224,9 @@ webvtt_get_node_kind_from_tag_name( webvtt_string *tag_name, webvtt_node_kind *k
|
|||
*kind = WEBVTT_VOICE;
|
||||
break;
|
||||
}
|
||||
} else if( memcmp( webvtt_string_text(tag_name), ruby_tag, min(webvtt_string_length(tag_name), RUBY_TAG_LENGTH) ) == 0 ) {
|
||||
} else if( webvtt_string_is_equal( tag_name, "ruby", 4 ) ) {
|
||||
*kind = WEBVTT_RUBY;
|
||||
} else if( memcmp( webvtt_string_text(tag_name), rt_tag, min(webvtt_string_length(tag_name), RUBY_TEXT_TAG_LENGTH) ) == 0 ) {
|
||||
} else if( webvtt_string_is_equal( tag_name, "rt", 2 ) ) {
|
||||
*kind = WEBVTT_RUBY_TEXT;
|
||||
} else {
|
||||
return WEBVTT_INVALID_TAG_NAME;
|
||||
|
@ -272,18 +255,18 @@ webvtt_create_node_from_token( webvtt_cuetext_token *token, webvtt_node **node,
|
|||
|
||||
switch ( token->token_type ) {
|
||||
case( TEXT_TOKEN ):
|
||||
return webvtt_create_text_leaf_node( node, parent, &token->text );
|
||||
return webvtt_create_text_node( node, parent, &token->text );
|
||||
break;
|
||||
case( START_TOKEN ):
|
||||
|
||||
CHECK_MEMORY_OP( webvtt_get_node_kind_from_tag_name( &token->tag_name, &kind) );
|
||||
CHECK_MEMORY_OP( webvtt_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 );
|
||||
return webvtt_create_timestamp_node( node, parent, token->time_stamp );
|
||||
break;
|
||||
default:
|
||||
return WEBVTT_INVALID_TOKEN_TYPE;
|
||||
|
@ -291,8 +274,8 @@ webvtt_create_node_from_token( webvtt_cuetext_token *token, webvtt_node **node,
|
|||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_cuetext_tokenizer_data_state( webvtt_byte **position,
|
||||
webvtt_cuetext_token_state *token_state, webvtt_string *result )
|
||||
webvtt_data_state( webvtt_byte **position, webvtt_token_state *token_state,
|
||||
webvtt_string *result )
|
||||
{
|
||||
for ( ; *token_state == DATA; (*position)++ ) {
|
||||
switch( **position ) {
|
||||
|
@ -319,26 +302,12 @@ webvtt_cuetext_tokenizer_data_state( webvtt_byte **position,
|
|||
}
|
||||
|
||||
/**
|
||||
* Definitions for valid escape values.
|
||||
* The semicolon is implicit in the comparison.
|
||||
* Definitions for escape sequence replacement strings.
|
||||
*/
|
||||
#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,
|
||||
|
@ -347,8 +316,8 @@ 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_escape_state( webvtt_byte **position, webvtt_token_state *token_state,
|
||||
webvtt_string *result )
|
||||
{
|
||||
webvtt_string buffer;
|
||||
webvtt_status status = WEBVTT_SUCCESS;
|
||||
|
@ -387,17 +356,17 @@ webvtt_cuetext_tokenizer_escape_state( webvtt_byte **position,
|
|||
* 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 ) {
|
||||
if( webvtt_string_is_equal( &buffer, "&", 4 ) ) {
|
||||
CHECK_MEMORY_OP_JUMP( status, webvtt_string_putc( result, '&' ) );
|
||||
} else if( webvtt_string_is_equal( &buffer, "<", 3 ) ) {
|
||||
CHECK_MEMORY_OP_JUMP( status, webvtt_string_putc( result, '<' ) );
|
||||
} else if( webvtt_string_is_equal( &buffer, ">", 3 ) ) {
|
||||
CHECK_MEMORY_OP_JUMP( status, webvtt_string_putc( result, '>' ) );
|
||||
} else if( webvtt_string_is_equal( &buffer, "&rlm", 4 ) ) {
|
||||
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 ) {
|
||||
} else if( webvtt_string_is_equal( &buffer, "&lrm", 4 ) ) {
|
||||
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 ) {
|
||||
} else if( webvtt_string_is_equal( &buffer, " ", 5 ) ) {
|
||||
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 ) );
|
||||
|
@ -405,6 +374,7 @@ webvtt_cuetext_tokenizer_escape_state( webvtt_byte **position,
|
|||
}
|
||||
|
||||
*token_state = DATA;
|
||||
status = WEBVTT_UNFINISHED;
|
||||
}
|
||||
/**
|
||||
* Character is alphanumeric. This means we are in the body of the escape
|
||||
|
@ -421,6 +391,7 @@ webvtt_cuetext_tokenizer_escape_state( webvtt_byte **position,
|
|||
else {
|
||||
CHECK_MEMORY_OP_JUMP( status, webvtt_string_append_string( result, &buffer ) );
|
||||
CHECK_MEMORY_OP_JUMP( status, webvtt_string_putc( result, **position ) );
|
||||
status = WEBVTT_UNFINISHED;
|
||||
*token_state = DATA;
|
||||
}
|
||||
}
|
||||
|
@ -432,8 +403,8 @@ dealloc:
|
|||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_cuetext_tokenizer_tag_state( webvtt_byte **position,
|
||||
webvtt_cuetext_token_state *token_state, webvtt_string *result )
|
||||
webvtt_tag_state( webvtt_byte **position, webvtt_token_state *token_state,
|
||||
webvtt_string *result )
|
||||
{
|
||||
for( ; *token_state == TAG; (*position)++ ) {
|
||||
if( **position == UTF8_TAB || **position == UTF8_LINE_FEED ||
|
||||
|
@ -468,8 +439,8 @@ webvtt_cuetext_tokenizer_tag_state( webvtt_byte **position,
|
|||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_cuetext_tokenizer_start_tag_state( webvtt_byte **position,
|
||||
webvtt_cuetext_token_state *token_state, webvtt_string *result )
|
||||
webvtt_start_tag_state( webvtt_byte **position, webvtt_token_state *token_state,
|
||||
webvtt_string *result )
|
||||
{
|
||||
for( ; *token_state == START_TAG; (*position)++ ) {
|
||||
if( **position == UTF8_TAB || **position == UTF8_FORM_FEED ||
|
||||
|
@ -498,8 +469,8 @@ webvtt_cuetext_tokenizer_start_tag_state( webvtt_byte **position,
|
|||
}
|
||||
|
||||
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_class_state( webvtt_byte **position, webvtt_token_state *token_state,
|
||||
webvtt_stringlist *css_classes )
|
||||
{
|
||||
webvtt_string buffer;
|
||||
webvtt_status status = WEBVTT_SUCCESS;
|
||||
|
@ -533,8 +504,8 @@ dealloc:
|
|||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_cuetext_tokenizer_start_tag_annotation_state( webvtt_byte **position,
|
||||
webvtt_cuetext_token_state *token_state, webvtt_string *annotation )
|
||||
webvtt_annotation_state( webvtt_byte **position, webvtt_token_state *token_state,
|
||||
webvtt_string *annotation )
|
||||
{
|
||||
for( ; *token_state == START_TAG_ANNOTATION; (*position)++ ) {
|
||||
if( **position == UTF8_NULL_BYTE || **position == UTF8_GREATER_THAN ) {
|
||||
|
@ -547,8 +518,8 @@ webvtt_cuetext_tokenizer_start_tag_annotation_state( webvtt_byte **position,
|
|||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_cuetext_tokenizer_end_tag_state( webvtt_byte **position,
|
||||
webvtt_cuetext_token_state *token_state, webvtt_string *result )
|
||||
webvtt_end_tag_state( webvtt_byte **position, webvtt_token_state *token_state,
|
||||
webvtt_string *result )
|
||||
{
|
||||
for( ; *token_state == END_TAG; (*position)++ ) {
|
||||
if( **position == UTF8_GREATER_THAN || **position == UTF8_NULL_BYTE ) {
|
||||
|
@ -561,8 +532,8 @@ webvtt_cuetext_tokenizer_end_tag_state( webvtt_byte **position,
|
|||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_cuetext_tokenizer_time_stamp_tag_state( webvtt_byte **position,
|
||||
webvtt_cuetext_token_state *token_state, webvtt_string *result )
|
||||
webvtt_timestamp_state( webvtt_byte **position, webvtt_token_state *token_state,
|
||||
webvtt_string *result )
|
||||
{
|
||||
for( ; *token_state == TIME_STAMP_TAG; (*position)++ ) {
|
||||
if( **position == UTF8_GREATER_THAN || **position == UTF8_NULL_BYTE ) {
|
||||
|
@ -581,7 +552,7 @@ webvtt_cuetext_tokenizer_time_stamp_tag_state( webvtt_byte **position,
|
|||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_cuetext_tokenizer( webvtt_byte **position, webvtt_cuetext_token **token )
|
||||
{
|
||||
webvtt_cuetext_token_state token_state = DATA;
|
||||
webvtt_token_state token_state = DATA;
|
||||
webvtt_string result, annotation;
|
||||
webvtt_stringlist *css_classes;
|
||||
webvtt_timestamp time_stamp = 0;
|
||||
|
@ -604,28 +575,28 @@ webvtt_cuetext_tokenizer( webvtt_byte **position, webvtt_cuetext_token **token )
|
|||
while( status == WEBVTT_UNFINISHED ) {
|
||||
switch( token_state ) {
|
||||
case DATA :
|
||||
status = webvtt_cuetext_tokenizer_data_state( position, &token_state, &result );
|
||||
status = webvtt_data_state( position, &token_state, &result );
|
||||
break;
|
||||
case ESCAPE:
|
||||
status = webvtt_cuetext_tokenizer_escape_state( position, &token_state, &result );
|
||||
status = webvtt_escape_state( position, &token_state, &result );
|
||||
break;
|
||||
case TAG:
|
||||
status = webvtt_cuetext_tokenizer_tag_state( position, &token_state, &result );
|
||||
status = webvtt_tag_state( position, &token_state, &result );
|
||||
break;
|
||||
case START_TAG:
|
||||
status = webvtt_cuetext_tokenizer_start_tag_state( position, &token_state, &result );
|
||||
status = webvtt_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 );
|
||||
status = webvtt_class_state( position, &token_state, css_classes );
|
||||
break;
|
||||
case START_TAG_ANNOTATION:
|
||||
status = webvtt_cuetext_tokenizer_start_tag_annotation_state( position, &token_state, &annotation );
|
||||
status = webvtt_annotation_state( position, &token_state, &annotation );
|
||||
break;
|
||||
case END_TAG:
|
||||
status = webvtt_cuetext_tokenizer_end_tag_state( position, &token_state, &result );
|
||||
status = webvtt_end_tag_state( position, &token_state, &result );
|
||||
break;
|
||||
case TIME_STAMP_TAG:
|
||||
status = webvtt_cuetext_tokenizer_time_stamp_tag_state( position, &token_state, &result );
|
||||
status = webvtt_timestamp_state( position, &token_state, &result );
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -643,7 +614,7 @@ webvtt_cuetext_tokenizer( webvtt_byte **position, webvtt_cuetext_token **token )
|
|||
* needs to be made.
|
||||
*/
|
||||
if( token_state == DATA || token_state == ESCAPE ) {
|
||||
status = webvtt_create_cuetext_text_token( token, &result );
|
||||
status = webvtt_create_text_token( token, &result );
|
||||
} else if(token_state == TAG || token_state == START_TAG || token_state == START_TAG_CLASS ||
|
||||
token_state == START_TAG_ANNOTATION) {
|
||||
/**
|
||||
|
@ -654,12 +625,12 @@ webvtt_cuetext_tokenizer( webvtt_byte **position, webvtt_cuetext_token **token )
|
|||
webvtt_release_string( &annotation );
|
||||
webvtt_init_string( &annotation );
|
||||
}
|
||||
status = webvtt_create_cuetext_start_token( token, &result, css_classes, &annotation );
|
||||
status = webvtt_create_start_token( token, &result, css_classes, &annotation );
|
||||
} else if( token_state == END_TAG ) {
|
||||
status = webvtt_create_cuetext_end_token( token, &result );
|
||||
status = webvtt_create_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 );
|
||||
status = webvtt_create_timestamp_token( token, time_stamp );
|
||||
} else {
|
||||
status = WEBVTT_INVALID_TOKEN_STATE;
|
||||
}
|
||||
|
@ -716,7 +687,7 @@ webvtt_parse_cuetext( webvtt_parser self, webvtt_cue *cue, webvtt_string *payloa
|
|||
*/
|
||||
while( *position != UTF8_NULL_BYTE ) {
|
||||
|
||||
webvtt_delete_cuetext_token( &token );
|
||||
webvtt_delete_token( &token );
|
||||
|
||||
/* Step 7. */
|
||||
switch( webvtt_cuetext_tokenizer( &position, &token ) ) {
|
||||
|
@ -745,7 +716,7 @@ webvtt_parse_cuetext( webvtt_parser self, webvtt_cue *cue, webvtt_string *payloa
|
|||
* 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 ) {
|
||||
if( webvtt_node_kind_from_tag_name( &token->tag_name, &kind ) == WEBVTT_INVALID_TAG_NAME ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -769,7 +740,7 @@ webvtt_parse_cuetext( webvtt_parser self, webvtt_cue *cue, webvtt_string *payloa
|
|||
/* Do something here? */
|
||||
}
|
||||
else {
|
||||
webvtt_attach_internal_node( current_node, temp_node );
|
||||
webvtt_attach_node( current_node, temp_node );
|
||||
|
||||
if( WEBVTT_IS_VALID_INTERNAL_NODE( temp_node->kind ) ) {
|
||||
current_node = temp_node;
|
||||
|
@ -784,7 +755,7 @@ webvtt_parse_cuetext( webvtt_parser self, webvtt_cue *cue, webvtt_string *payloa
|
|||
webvtt_skipwhite( &position );
|
||||
}
|
||||
|
||||
webvtt_delete_cuetext_token( &token );
|
||||
webvtt_delete_token( &token );
|
||||
|
||||
return WEBVTT_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -31,17 +31,17 @@
|
|||
# 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 enum webvtt_token_type_t webvtt_token_type;
|
||||
typedef enum webvtt_token_state_t webvtt_token_state;
|
||||
|
||||
typedef struct webvtt_cuetext_token_t webvtt_cuetext_token;
|
||||
typedef struct webvtt_cuetext_start_token_data_t webvtt_cuetext_start_token_data;
|
||||
typedef struct webvtt_start_token_data_t webvtt_start_token_data;
|
||||
|
||||
/**
|
||||
* Enumerates token types.
|
||||
*/
|
||||
enum
|
||||
webvtt_cuetext_token_type_t {
|
||||
webvtt_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. */
|
||||
|
@ -52,7 +52,7 @@ webvtt_cuetext_token_type_t {
|
|||
* Enumerates possible states that the cue text tokenizer can be in.
|
||||
*/
|
||||
enum
|
||||
webvtt_cuetext_token_state_t {
|
||||
webvtt_token_state_t {
|
||||
DATA, /* Initial state. */
|
||||
ESCAPE, /* Parsing an escape value. */
|
||||
TAG, /* Reached a '<' character, about to start parsing a tag. */
|
||||
|
@ -75,7 +75,7 @@ webvtt_cuetext_token_state_t {
|
|||
* cue text.
|
||||
*/
|
||||
struct
|
||||
webvtt_cuetext_start_token_data_t {
|
||||
webvtt_start_token_data_t {
|
||||
webvtt_stringlist *css_classes;
|
||||
webvtt_string annotations;
|
||||
};
|
||||
|
@ -86,12 +86,12 @@ webvtt_cuetext_start_token_data_t {
|
|||
*/
|
||||
struct
|
||||
webvtt_cuetext_token_t {
|
||||
webvtt_cuetext_token_type token_type;
|
||||
webvtt_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;
|
||||
webvtt_start_token_data start_token_data;
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -99,12 +99,12 @@ webvtt_cuetext_token_t {
|
|||
* 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_INTERN webvtt_status webvtt_create_token( webvtt_cuetext_token **token, webvtt_token_type token_type );
|
||||
WEBVTT_INTERN webvtt_status webvtt_create_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_INTERN webvtt_status webvtt_create_end_token( webvtt_cuetext_token **token, webvtt_string *tag_name );
|
||||
WEBVTT_INTERN webvtt_status webvtt_create_text_token( webvtt_cuetext_token **token, webvtt_string *text );
|
||||
WEBVTT_INTERN webvtt_status webvtt_create_timestamp_token( webvtt_cuetext_token **token,
|
||||
webvtt_timestamp time_stamp );
|
||||
|
||||
/**
|
||||
|
@ -115,14 +115,14 @@ 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 );
|
||||
WEBVTT_INTERN void webvtt_delete_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 );
|
||||
WEBVTT_INTERN webvtt_status webvtt_node_kind_from_tag_name( webvtt_string *tag_name, webvtt_node_kind *kind );
|
||||
|
||||
/**
|
||||
* Creates a node from a valid token.
|
||||
|
@ -135,7 +135,7 @@ WEBVTT_INTERN webvtt_status webvtt_create_node_from_token( webvtt_cuetext_token
|
|||
* 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 );
|
||||
WEBVTT_INTERN webvtt_status webvtt_tokenizer( webvtt_byte **position, webvtt_cuetext_token **token );
|
||||
|
||||
/**
|
||||
* Routines that take care of certain states in the webvtt cue text tokenizer.
|
||||
|
@ -144,51 +144,51 @@ WEBVTT_INTERN webvtt_status webvtt_cuetext_tokenizer( webvtt_byte **position, we
|
|||
/**
|
||||
* 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 );
|
||||
WEBVTT_INTERN webvtt_status webvtt_data_state( webvtt_byte **position,
|
||||
webvtt_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 );
|
||||
WEBVTT_INTERN webvtt_status webvtt_escape_state( webvtt_byte **position,
|
||||
webvtt_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 );
|
||||
WEBVTT_INTERN webvtt_status webvtt_tag_state( webvtt_byte **position,
|
||||
webvtt_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 );
|
||||
WEBVTT_INTERN webvtt_status webvtt_start_tag_state( webvtt_byte **position,
|
||||
webvtt_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 );
|
||||
WEBVTT_INTERN webvtt_status webvtt_class_state( webvtt_byte **position,
|
||||
webvtt_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 );
|
||||
WEBVTT_INTERN webvtt_status webvtt_annotation_state( webvtt_byte **position,
|
||||
webvtt_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 );
|
||||
WEBVTT_INTERN webvtt_status webvtt_end_tag_state( webvtt_byte **position,
|
||||
webvtt_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_timestamp_state( webvtt_byte **position,
|
||||
webvtt_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 );
|
||||
|
||||
|
|
|
@ -66,10 +66,10 @@ static const char *errstr[] = {
|
|||
* (This might be too much work!)
|
||||
*/
|
||||
WEBVTT_EXPORT const char *
|
||||
webvtt_strerror( webvtt_error errno )
|
||||
webvtt_strerror( webvtt_error err )
|
||||
{
|
||||
if( errno >= (sizeof(errstr) / sizeof(*errstr)) ) {
|
||||
if( err >= (sizeof(errstr) / sizeof(*errstr)) ) {
|
||||
return "";
|
||||
}
|
||||
return errstr[ errno ];
|
||||
return errstr[ err ];
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
# define __WEBVTT_CUE_H__
|
||||
# include "util.h"
|
||||
# include <webvtt/string.h>
|
||||
# include <webvtt/node.h>
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
#define WEBVTT_CPLUSPLUS 1
|
||||
|
@ -37,68 +38,6 @@ extern "C" {
|
|||
|
||||
#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,
|
||||
|
@ -116,39 +55,6 @@ webvtt_align_type_t {
|
|||
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;
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
/**
|
||||
* 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_NODE_H__
|
||||
# define __WEBVTT_NODE_H__
|
||||
# include <webvtt/string.h>
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
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;
|
||||
|
||||
#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) )
|
||||
|
||||
struct webvtt_internal_node_data_t;
|
||||
|
||||
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 );
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -151,6 +151,15 @@ WEBVTT_EXPORT int webvtt_string_getline( webvtt_string *str, const webvtt_byte *
|
|||
*/
|
||||
WEBVTT_EXPORT webvtt_status webvtt_string_putc( webvtt_string *str, webvtt_byte to_append );
|
||||
|
||||
|
||||
/**
|
||||
* webvtt_string_is_equal
|
||||
*
|
||||
* compare a string's text to a byte array
|
||||
*
|
||||
*/
|
||||
WEBVTT_EXPORT webvtt_bool webvtt_string_is_equal( webvtt_string *str, webvtt_byte *to_compare, webvtt_uint len );
|
||||
|
||||
/**
|
||||
* webvtt_string_append
|
||||
*
|
||||
|
|
|
@ -192,6 +192,17 @@ extern "C" {
|
|||
* Parser should move to the next cuesetting.
|
||||
*/
|
||||
WEBVTT_NEXT_CUESETTING = -12,
|
||||
|
||||
/*
|
||||
* Match is not found in a search query
|
||||
*/
|
||||
WEBVTT_NO_MATCH_FOUND = -13,
|
||||
|
||||
/**
|
||||
* Thrown when assertions fail and FATAL_ASSERTION
|
||||
* is not defined.
|
||||
*/
|
||||
WEBVTT_FAILED_ASSERTION = -14,
|
||||
};
|
||||
|
||||
typedef enum webvtt_status_t webvtt_status;
|
||||
|
|
|
@ -0,0 +1,218 @@
|
|||
/**
|
||||
* 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.h>
|
||||
#include <stdlib.h>
|
||||
#include "node_internal.h"
|
||||
|
||||
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_timestamp_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_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_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;
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* 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_NODE_INTERNAL_H__
|
||||
# define __WEBVTT_NODE_INTERNAL_H__
|
||||
# include <webvtt/node.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_timestamp_node( webvtt_node **node, webvtt_node *parent, webvtt_timestamp time_stamp );
|
||||
WEBVTT_INTERN webvtt_status webvtt_create_text_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_node( webvtt_node *parent, webvtt_node *to_attach );
|
||||
|
||||
#endif
|
|
@ -42,9 +42,13 @@ static const webvtt_byte separator[] = {
|
|||
#define BUFFER (self->buffer + self->position)
|
||||
#define MALFORMED_TIME ((webvtt_timestamp_t)-1.0)
|
||||
|
||||
static int find_bytes( const webvtt_byte *buffer, webvtt_uint len, const webvtt_byte *sbytes, webvtt_uint slen );
|
||||
static webvtt_status find_bytes( const webvtt_byte *buffer, webvtt_uint len, const webvtt_byte *sbytes, webvtt_uint slen );
|
||||
static webvtt_status webvtt_skipwhite( const webvtt_byte *buffer, webvtt_uint *pos, webvtt_uint len );
|
||||
static webvtt_int64 parse_int( const webvtt_byte **pb, int *pdigits );
|
||||
static void skip_spacetab( const webvtt_byte *text, webvtt_uint *pos,
|
||||
webvtt_uint len, webvtt_uint *column );
|
||||
static void skip_until_white( const webvtt_byte *text, webvtt_uint *pos,
|
||||
webvtt_uint len, webvtt_uint *column );
|
||||
|
||||
WEBVTT_EXPORT webvtt_status
|
||||
webvtt_create_parser( webvtt_cue_fn on_read,
|
||||
|
@ -229,6 +233,45 @@ find_newline( const webvtt_byte *buffer, webvtt_uint *pos, webvtt_uint len )
|
|||
return -1;
|
||||
}
|
||||
|
||||
static void
|
||||
skip_spacetab( const webvtt_byte *text, webvtt_uint *pos, webvtt_uint len,
|
||||
webvtt_uint *column )
|
||||
{
|
||||
webvtt_uint c = 0;
|
||||
if( !column ) {
|
||||
column = &c;
|
||||
}
|
||||
while( *pos < len ) {
|
||||
webvtt_byte ch = text[ *pos ];
|
||||
if( ch == 0x20 || ch == 0x09 ) {
|
||||
++( *pos );
|
||||
++( *column );
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
skip_until_white( const webvtt_byte *text, webvtt_uint *pos, webvtt_uint len,
|
||||
webvtt_uint *column )
|
||||
{
|
||||
webvtt_uint c = 0;
|
||||
if( !column ) {
|
||||
column = &c;
|
||||
}
|
||||
while( *pos < len ) {
|
||||
webvtt_byte ch = text[ *pos ];
|
||||
if( ch == 0x20 || ch == 0x09 || ch == 0x0A || ch == 0x0D ) {
|
||||
break;
|
||||
} else {
|
||||
int length = webvtt_utf8_length( text + *pos );
|
||||
*pos += length;
|
||||
++( *column );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static webvtt_status
|
||||
webvtt_skipwhite( const webvtt_byte *buffer, webvtt_uint *pos, webvtt_uint len )
|
||||
{
|
||||
|
@ -259,25 +302,25 @@ find_next_whitespace( const webvtt_byte *buffer, webvtt_uint *ppos, webvtt_uint
|
|||
/**
|
||||
* basic strnstr-ish routine
|
||||
*/
|
||||
static int
|
||||
static webvtt_status
|
||||
find_bytes( const webvtt_byte *buffer, webvtt_uint len,
|
||||
const webvtt_byte *sbytes, webvtt_uint slen )
|
||||
{
|
||||
webvtt_uint slen2;
|
||||
// check params for integrity
|
||||
if( !buffer || len < 1 || !sbytes || slen < 1 ) {
|
||||
return 0;
|
||||
return WEBVTT_INVALID_PARAM;
|
||||
}
|
||||
|
||||
slen2 = slen - 1;
|
||||
while( len-- >= slen && *buffer ){
|
||||
if( *buffer == *sbytes && memcmp( buffer + 1, sbytes + 1, slen2 ) == 0 ) {
|
||||
return 1;
|
||||
return WEBVTT_SUCCESS;
|
||||
}
|
||||
buffer++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return WEBVTT_NO_MATCH_FOUND;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -355,6 +398,243 @@ do \
|
|||
} while(0)
|
||||
#define POPBACK() do_pop(self)
|
||||
|
||||
static webvtt_status
|
||||
webvtt_parse_cuesetting( webvtt_parser self, const webvtt_byte *text,
|
||||
webvtt_uint *pos, webvtt_uint len, webvtt_error bv, webvtt_token
|
||||
keyword, webvtt_token values[], webvtt_uint *value_column ) {
|
||||
enum webvtt_param_mode
|
||||
{
|
||||
P_KEYWORD,
|
||||
P_COLON,
|
||||
P_VALUE
|
||||
};
|
||||
int i;
|
||||
webvtt_bool precws = 0;
|
||||
webvtt_bool prevws = 0;
|
||||
static const webvtt_token value_tokens[] = {
|
||||
INTEGER, RL, LR, START, MIDDLE, END, LEFT, RIGHT, PERCENTAGE, 0
|
||||
};
|
||||
static const webvtt_token keyword_tokens[] = {
|
||||
ALIGN, SIZE, LINE, POSITION, VERTICAL, 0
|
||||
};
|
||||
enum webvtt_param_mode mode = P_KEYWORD;
|
||||
webvtt_uint keyword_column = 0;
|
||||
while( *pos < len ) {
|
||||
webvtt_uint last_line = self->line;
|
||||
webvtt_uint last_column = self->column;
|
||||
webvtt_uint last_pos = *pos;
|
||||
webvtt_token tk = webvtt_lex( self, text, pos, len, 1 );
|
||||
webvtt_uint tp = self->token_pos;
|
||||
self->token_pos = 0;
|
||||
|
||||
switch( mode ) {
|
||||
case P_KEYWORD:
|
||||
switch( tk ) {
|
||||
case ALIGN:
|
||||
case SIZE:
|
||||
case POSITION:
|
||||
case VERTICAL:
|
||||
case LINE:
|
||||
if( tk != keyword ) {
|
||||
*pos -= tp;
|
||||
self->column -= tp;
|
||||
return WEBVTT_NEXT_CUESETTING;
|
||||
}
|
||||
if( *pos < len ) {
|
||||
webvtt_uint column = last_column;
|
||||
webvtt_byte ch = text[ *pos ];
|
||||
if( ch != 0x3A ) {
|
||||
webvtt_error e = WEBVTT_INVALID_CUESETTING;
|
||||
if( ch == 0x20 || ch == 0x09 ) {
|
||||
column = self->column;
|
||||
e = WEBVTT_UNEXPECTED_WHITESPACE;
|
||||
skip_spacetab( text, pos, len, &self->column );
|
||||
if( text[ *pos ] == 0x3A ) {
|
||||
skip_until_white( text, pos, len, &self->column );
|
||||
}
|
||||
} else {
|
||||
skip_until_white( text, pos, len, &self->column );
|
||||
}
|
||||
ERROR_AT_COLUMN( e, column );
|
||||
} else {
|
||||
mode = P_COLON;
|
||||
keyword_column = last_column;
|
||||
}
|
||||
} else {
|
||||
ERROR_AT_COLUMN( WEBVTT_INVALID_CUESETTING, last_column );
|
||||
}
|
||||
break;
|
||||
case WHITESPACE:
|
||||
break;
|
||||
case NEWLINE:
|
||||
return WEBVTT_SUCCESS;
|
||||
break;
|
||||
default:
|
||||
ERROR_AT( WEBVTT_INVALID_CUESETTING, last_line,
|
||||
last_column );
|
||||
*pos = *pos + tp + 1;
|
||||
skip_param:
|
||||
while( *pos < len && text[ *pos ] != 0x20
|
||||
&& text[ *pos ] != 0x09 ) {
|
||||
if( text[ *pos ] == 0x0A || text[ *pos ] == 0x0D ) {
|
||||
return WEBVTT_SUCCESS;
|
||||
}
|
||||
++( *pos );
|
||||
++self->column;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case P_COLON:
|
||||
if( tk == WHITESPACE && !precws ) {
|
||||
ERROR_AT( WEBVTT_UNEXPECTED_WHITESPACE, last_line,
|
||||
last_column
|
||||
);
|
||||
precws = 1;
|
||||
} else if( tk == COLON ) {
|
||||
mode = P_VALUE;
|
||||
} else if( token_in_list( tk, value_tokens ) ) {
|
||||
ERROR_AT( WEBVTT_MISSING_CUESETTING_DELIMITER, last_line,
|
||||
last_column );
|
||||
mode = P_VALUE;
|
||||
goto get_value;
|
||||
} else if( token_in_list( tk, keyword_tokens ) ) {
|
||||
ERROR_AT( WEBVTT_INVALID_CUESETTING, last_line,
|
||||
keyword_column );
|
||||
} else {
|
||||
ERROR_AT( WEBVTT_INVALID_CUESETTING_DELIMITER, last_line,
|
||||
last_column );
|
||||
*pos = last_pos + tp + 1;
|
||||
}
|
||||
break;
|
||||
case P_VALUE:
|
||||
get_value:
|
||||
if( tk == WHITESPACE && !prevws ) {
|
||||
ERROR_AT( WEBVTT_UNEXPECTED_WHITESPACE, last_line,
|
||||
last_column );
|
||||
} else if( ( i = find_token( tk, values ) ) >= 0 ) {
|
||||
webvtt_token t = values[ i ] & TF_TOKEN_MASK;
|
||||
int flags = values[ i ] & TF_FLAGS_MASK;
|
||||
*value_column = last_column;
|
||||
if( *pos < len ) {
|
||||
webvtt_byte ch = text[ *pos ];
|
||||
if( ch != 0x20 && ch != 0x09
|
||||
&& ch != 0x0D && ch != 0x0A ) {
|
||||
goto bad_value;
|
||||
}
|
||||
}
|
||||
switch( t ) {
|
||||
case INTEGER:
|
||||
case PERCENTAGE:
|
||||
if( ( flags & TF_SIGN_MASK ) != TF_SIGN_MASK ) {
|
||||
const webvtt_byte p = self->token[ 0 ];
|
||||
if( ( ( flags & TF_NEGATIVE ) && p != UTF8_HYPHEN_MINUS )
|
||||
|| ( ( flags & TF_POSITIVE ) && p == UTF8_HYPHEN_MINUS
|
||||
) ) {
|
||||
goto bad_value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return i + 1;
|
||||
} else {
|
||||
bad_value:
|
||||
ERROR_AT( bv, last_line, last_column );
|
||||
bad_value_eol:
|
||||
while( *pos < len && text[ *pos ] != 0x20
|
||||
&& text[ *pos ] != 0x09 ) {
|
||||
if( text[ *pos ] == 0x0A || text[ *pos ] == 0x0D ) {
|
||||
return WEBVTT_SUCCESS;
|
||||
}
|
||||
++( *pos );
|
||||
++self->column;
|
||||
}
|
||||
if( *pos >= len ) {
|
||||
return WEBVTT_SUCCESS;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( mode == P_VALUE && *pos >= len ) {
|
||||
ERROR( bv );
|
||||
goto bad_value_eol;
|
||||
}
|
||||
return WEBVTT_NEXT_CUESETTING;
|
||||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_parse_align( webvtt_parser self, webvtt_cue *cue, const
|
||||
webvtt_byte *text,
|
||||
webvtt_uint *pos, webvtt_uint len )
|
||||
{
|
||||
webvtt_uint last_line = self->line;
|
||||
webvtt_uint last_column = self->column;
|
||||
webvtt_status v;
|
||||
webvtt_uint vc;
|
||||
webvtt_token values[] = { START, MIDDLE, END, LEFT, RIGHT, 0 };
|
||||
if( ( v = webvtt_parse_cuesetting( self, text, pos, len,
|
||||
WEBVTT_ALIGN_BAD_VALUE, ALIGN, values, &vc ) ) > 0 ) {
|
||||
if( cue->flags & CUE_HAVE_ALIGN ) {
|
||||
ERROR_AT( WEBVTT_ALIGN_ALREADY_SET, last_line, last_column );
|
||||
}
|
||||
cue->flags |= CUE_HAVE_ALIGN;
|
||||
switch( values[ v - 1 ] ) {
|
||||
case START: cue->settings.align = WEBVTT_ALIGN_START; break;
|
||||
case MIDDLE: cue->settings.align = WEBVTT_ALIGN_MIDDLE; break;
|
||||
case END: cue->settings.align = WEBVTT_ALIGN_END; break;
|
||||
case LEFT: cue->settings.align = WEBVTT_ALIGN_LEFT; break;
|
||||
case RIGHT: cue->settings.align = WEBVTT_ALIGN_RIGHT; break;
|
||||
}
|
||||
}
|
||||
return v >= 0 ? WEBVTT_SUCCESS : v;
|
||||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_status
|
||||
webvtt_parse_line( webvtt_parser self, webvtt_cue *cue, const
|
||||
webvtt_byte *text,
|
||||
webvtt_uint *pos, webvtt_uint len )
|
||||
{
|
||||
webvtt_uint last_line = self->line;
|
||||
webvtt_uint last_column = self->column;
|
||||
webvtt_status v;
|
||||
webvtt_uint vc;
|
||||
webvtt_bool first_flag = 0;
|
||||
webvtt_token values[] = { INTEGER, PERCENTAGE|TF_POSITIVE, 0 };
|
||||
if( ( v = webvtt_parse_cuesetting( self, text, pos, len,
|
||||
WEBVTT_LINE_BAD_VALUE, LINE, values, &vc ) ) > 0 ) {
|
||||
webvtt_uint digits;
|
||||
webvtt_int64 value;
|
||||
const webvtt_byte *t = self->token;
|
||||
if( cue->flags & CUE_HAVE_LINE ) {
|
||||
ERROR_AT( WEBVTT_LINE_ALREADY_SET, last_line, last_column );
|
||||
} else {
|
||||
first_flag = 1;
|
||||
}
|
||||
cue->flags |= CUE_HAVE_LINE;
|
||||
value = parse_int( &t, &digits );
|
||||
switch( values[ v - 1 ] & TF_TOKEN_MASK ) {
|
||||
case INTEGER: {
|
||||
cue->snap_to_lines = 1;
|
||||
cue->settings.line = ( int )value;
|
||||
}
|
||||
break;
|
||||
|
||||
case PERCENTAGE: {
|
||||
if( value < 0 || value > 100 ) {
|
||||
if( first_flag ) {
|
||||
cue->flags &= ~CUE_HAVE_LINE;
|
||||
}
|
||||
ERROR_AT_COLUMN( WEBVTT_LINE_BAD_VALUE, vc );
|
||||
return WEBVTT_SUCCESS;
|
||||
}
|
||||
cue->snap_to_lines = 0;
|
||||
cue->settings.line = ( int )value;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
return v >= 0 ? WEBVTT_SUCCESS : v;
|
||||
}
|
||||
|
||||
WEBVTT_INTERN int
|
||||
parse_cueparams( webvtt_parser self, const webvtt_byte *buffer,
|
||||
webvtt_uint len, webvtt_cue *cue )
|
||||
|
@ -365,6 +645,8 @@ parse_cueparams( webvtt_parser self, const webvtt_byte *buffer,
|
|||
webvtt_uint baddelim = 0;
|
||||
webvtt_uint pos = 0;
|
||||
webvtt_token last_token = 0;
|
||||
webvtt_uint last_line = self->line;
|
||||
|
||||
enum cp_state {
|
||||
CP_T1, CP_T2, CP_T3, CP_T4, CP_T5, /* 'start' cuetime, whitespace1,
|
||||
'separator', whitespace2, 'end' cuetime */
|
||||
|
@ -396,6 +678,8 @@ parse_cueparams( webvtt_parser self, const webvtt_byte *buffer,
|
|||
while( pos < len ) {
|
||||
webvtt_uint last_column = self->column;
|
||||
webvtt_token token = webvtt_lex( self, buffer, &pos, len, 1 );
|
||||
webvtt_uint tlen = self->token_pos;
|
||||
self->token_pos = 0;
|
||||
_recheck:
|
||||
switch( state ) {
|
||||
/* start timestamp */
|
||||
|
@ -409,7 +693,7 @@ _recheck:
|
|||
( BAD_TIMESTAMP( cue->from )
|
||||
? WEBVTT_EXPECTED_TIMESTAMP
|
||||
: WEBVTT_MALFORMED_TIMESTAMP ), last_column );
|
||||
if( !webvtt_isdigit( self->token[self->token_pos - 1] ) ) {
|
||||
if( self->token_pos && !webvtt_isdigit( self->token[self->token_pos - 1] ) ) {
|
||||
while( pos < len && buffer[pos] != 0x09 && buffer[pos] != 0x20 ) { ++pos; }
|
||||
}
|
||||
if( BAD_TIMESTAMP( cue->from ) )
|
||||
|
@ -513,9 +797,6 @@ else if( !have_ws ) \
|
|||
case WHITESPACE:
|
||||
have_ws = last_column;
|
||||
break;
|
||||
case COLON:
|
||||
ERROR_AT_COLUMN( WEBVTT_MISSING_CUESETTING_KEYWORD, last_column );
|
||||
break;
|
||||
case VERTICAL:
|
||||
CHKDELIM have_ws = 0;
|
||||
SETST( CP_V1 );
|
||||
|
@ -525,21 +806,35 @@ else if( !have_ws ) \
|
|||
SETST( CP_P1 );
|
||||
break;
|
||||
case ALIGN:
|
||||
CHKDELIM have_ws = 0;
|
||||
SETST( CP_A1 );
|
||||
{
|
||||
webvtt_status status;
|
||||
pos -= tlen; /* Required for parse_align() */
|
||||
self->column = last_column; /* Reset for parse_align() */
|
||||
status = webvtt_parse_align( self, cue, buffer, &pos, len );
|
||||
if( status == WEBVTT_PARSE_ERROR ) {
|
||||
return WEBVTT_PARSE_ERROR;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SIZE:
|
||||
CHKDELIM have_ws = 0;
|
||||
SETST( CP_S1 );
|
||||
break;
|
||||
case LINE:
|
||||
CHKDELIM have_ws = 0;
|
||||
SETST( CP_L1 );
|
||||
{
|
||||
webvtt_status status;
|
||||
pos -= tlen; /* Required for parse_align() */
|
||||
self->column = last_column; /* Reset for parse_align() */
|
||||
status = webvtt_parse_line( self, cue, buffer, &pos, len );
|
||||
if( status == WEBVTT_PARSE_ERROR ) {
|
||||
return WEBVTT_PARSE_ERROR;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if( have_ws ) {
|
||||
ERROR_AT_COLUMN( WEBVTT_INVALID_CUESETTING, last_column );
|
||||
while( pos < len && buffer[pos] != 0x09 && buffer[pos] != 0x20 ) { ++pos; }
|
||||
} else if( token == BADTOKEN ) {
|
||||
/* it was a bad delimiter... */
|
||||
if( !baddelim ) {
|
||||
|
@ -547,6 +842,9 @@ else if( !have_ws ) \
|
|||
}
|
||||
++pos;
|
||||
}
|
||||
while( pos < len && buffer[pos] != 0x09 && buffer[pos] != 0x20 ) {
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
break;
|
||||
#define CS1(S) \
|
||||
|
@ -1018,6 +1316,13 @@ _recheck:
|
|||
webvtt_state *st = FRAMEUP( 1 );
|
||||
webvtt_string text = st->v.text;
|
||||
|
||||
/* FIXME: guard inconsistent state */
|
||||
if (!cue) {
|
||||
ERROR( WEBVTT_PARSE_ERROR );
|
||||
status = WEBVTT_PARSE_ERROR;
|
||||
goto _finish;
|
||||
}
|
||||
|
||||
st->type = V_NONE;
|
||||
st->v.cue = NULL;
|
||||
|
||||
|
@ -1027,7 +1332,7 @@ _recheck:
|
|||
* TODO: Add debug assertion
|
||||
*/
|
||||
if( find_bytes( webvtt_string_text( &text ), webvtt_string_length( &text ), separator,
|
||||
sizeof( separator ) ) ) {
|
||||
sizeof( separator ) ) == WEBVTT_SUCCESS) {
|
||||
/* It's not a cue id, we found '-->'. It can't be a second
|
||||
cueparams line, because if we had it, we would be in
|
||||
a different state. */
|
||||
|
@ -1051,7 +1356,7 @@ _recheck:
|
|||
}
|
||||
} else {
|
||||
/* It is a cue-id */
|
||||
if( cue->flags & CUE_HAVE_ID ) {
|
||||
if( cue && cue->flags & CUE_HAVE_ID ) {
|
||||
/**
|
||||
* This isn't actually a cue-id, because we already
|
||||
* have one. It seems to be cuetext, which is occurring
|
||||
|
@ -1122,24 +1427,17 @@ read_cuetext( webvtt_parser self, const webvtt_byte *b, webvtt_uint
|
|||
goto _finish;
|
||||
}
|
||||
|
||||
if( self->line_buffer.d->length > 1 && self->line_buffer.d->text[ self->line_buffer.d->length - 1 ] == UTF8_LINE_FEED ) {
|
||||
/**
|
||||
* We've encountered a line without any cuetext on it, i.e. there is no
|
||||
* newline character and len is 0 or there is and len is 1, therefore,
|
||||
* the cue text is finished.
|
||||
*/
|
||||
if( self->line_buffer.d->length <= 1 ) {
|
||||
/**
|
||||
* finished
|
||||
*/
|
||||
finished = 1;
|
||||
}
|
||||
webvtt_string_putc( &self->line_buffer, UTF8_LINE_FEED );
|
||||
|
||||
if( pos < len ) {
|
||||
if( b[pos] == UTF8_CARRIAGE_RETURN ) {
|
||||
if( len - pos >= 2 && b[pos + 1] == UTF8_LINE_FEED ) {
|
||||
++pos;
|
||||
}
|
||||
++pos;
|
||||
} else {
|
||||
++pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
} while( pos < len && !finished );
|
||||
_finish:
|
||||
|
@ -1385,3 +1683,31 @@ _malformed:
|
|||
*result = 0xFFFFFFFFFFFFFFFF;
|
||||
return 0;
|
||||
}
|
||||
|
||||
WEBVTT_INTERN webvtt_bool
|
||||
token_in_list( webvtt_token token, const webvtt_token list[] )
|
||||
{
|
||||
int i = 0;
|
||||
webvtt_token t;
|
||||
while( ( t = list[ i++ ] ) != 0 ) {
|
||||
if( token == t ) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
WEBVTT_INTERN int
|
||||
find_token( webvtt_token token, const webvtt_token list[] )
|
||||
{
|
||||
int i = 0;
|
||||
webvtt_token t;
|
||||
while( ( t = list[ i ] ) != 0 ) {
|
||||
webvtt_token masked = t & TF_TOKEN_MASK;
|
||||
if( token == masked ) {
|
||||
return i;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,18 @@
|
|||
# define __INTERN_PARSER_H__
|
||||
# include <webvtt/parser.h>
|
||||
# include "string_internal.h"
|
||||
# ifndef NDEBUG
|
||||
# define NDEBUG
|
||||
# endif
|
||||
|
||||
# if defined(FATAL_ASSERTION)
|
||||
# undef NDEBUG
|
||||
# include <assert.h>
|
||||
# else
|
||||
# if defined(BREAK_ON_ASSERTION) && !WEBVTT_OS_WIN32
|
||||
static void break_on_assert();
|
||||
# endif
|
||||
# endif
|
||||
|
||||
typedef enum
|
||||
webvtt_token_t {
|
||||
|
@ -217,20 +229,102 @@ WEBVTT_INTERN webvtt_token webvtt_lex( webvtt_parser self, const webvtt_byte *bu
|
|||
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 );
|
||||
|
||||
/**
|
||||
* Flags which can apply additional meaning to a token. find_token() will
|
||||
* test for only the actual token and ignore the additional flags.
|
||||
*/
|
||||
typedef
|
||||
enum webvtt_token_flags_t
|
||||
{
|
||||
/* Number can be positive */
|
||||
TF_POSITIVE = 0x80000000,
|
||||
|
||||
/* Number can be negative */
|
||||
TF_NEGATIVE = 0x40000000,
|
||||
/* (token & TF_SIGN_MASK) == combination of TF_POSITIVE and
|
||||
TF_NEGATIVE, which indicate what values a number token is allowed
|
||||
to be */
|
||||
TF_SIGN_MASK = ( TF_POSITIVE | TF_NEGATIVE ),
|
||||
|
||||
/* (token & TF_FLAGS_MASK) == webvtt_token_flags value
|
||||
that is being asked for */
|
||||
TF_FLAGS_MASK = TF_SIGN_MASK,
|
||||
|
||||
/* (token & TF_TOKEN_MASK) == webvtt_token value */
|
||||
TF_TOKEN_MASK = ( 0xFFFFFFFF & ~TF_FLAGS_MASK ),
|
||||
} webvtt_token_flags;
|
||||
|
||||
/**
|
||||
* Return non-zero if a token is found in a NULL-terminated array of tokens, or
|
||||
* zero if not.
|
||||
*
|
||||
* Unlike find_token(), token_in_list() does not make use of
|
||||
* webvtt_token_flags and thus requiers an exact match.
|
||||
*/
|
||||
WEBVTT_INTERN webvtt_bool token_in_list( webvtt_token search_for,
|
||||
const webvtt_token token_list[] );
|
||||
|
||||
/**
|
||||
* Return the index of a token in a NULL-terminated array of tokens,
|
||||
* or -1 if the token is not found.
|
||||
*
|
||||
* find_token() will search for an occurrence of `token' in a list
|
||||
* where webvtt_token_flags are used. For instance, if the list of
|
||||
* tokens contains { TF_POSITIVE | INTEGER, TF_POSITIVE | PERCENTAGE,
|
||||
* 0 }, find_token() will return a match for INTEGER or PERCENTAGE if
|
||||
* either is searched for.
|
||||
*/
|
||||
WEBVTT_INTERN int find_token( webvtt_token search_for,
|
||||
const webvtt_token token_list[] );
|
||||
|
||||
#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)
|
||||
|
||||
#ifdef FATAL_ASSERTION
|
||||
# define SAFE_ASSERT(condition) assert(condition)
|
||||
# define DIE_IF(condition) assert( !(condition) )
|
||||
#else
|
||||
# ifdef BREAK_ON_ASSERTION
|
||||
static void
|
||||
break_on_assert(void) {
|
||||
#if WEBVTT_OS_WIN32
|
||||
/* __declspec(dllimport) should work for cross compiling gcc as well */
|
||||
__declspec(dllimport) void __stdcall DebugBreak( void );
|
||||
DebugBreak();
|
||||
#else
|
||||
volatile int *ptr = (volatile int *)0;
|
||||
*ptr = 1;
|
||||
#endif
|
||||
}
|
||||
# define SAFE_ASSERT(condition) \
|
||||
if( !(condition) ) { \
|
||||
break_on_assert(); \
|
||||
return WEBVTT_FAILED_ASSERTION; \
|
||||
}
|
||||
# define DIE_IF(condition) \
|
||||
if( (condition) ) { \
|
||||
break_on_assert(); \
|
||||
}
|
||||
# else
|
||||
# define SAFE_ASSERT(condition) \
|
||||
if( !(condition) ) { \
|
||||
return WEBVTT_FAILED_ASSERTION; \
|
||||
}
|
||||
# define DIE_IF(condition)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define ERROR_AT(errno, line, column) \
|
||||
do \
|
||||
{ \
|
||||
if( !self->error \
|
||||
|| self->error( (self->userdata), (line), (column), (errno) ) < 0 ) { \
|
||||
return WEBVTT_PARSE_ERROR; \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define ERROR(error) \
|
||||
ERROR_AT( (error), (self->line), (self->column) )
|
||||
|
||||
#define ERROR_AT_COLUMN(error, column) \
|
||||
ERROR_AT( (error), (self->line), (column) )
|
||||
#endif
|
||||
|
|
|
@ -180,7 +180,6 @@ 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 {
|
||||
|
@ -332,7 +331,7 @@ webvtt_string_getline( webvtt_string *src, const webvtt_byte *buffer,
|
|||
/* truncate. */
|
||||
(*truncate)++;
|
||||
} else {
|
||||
if( grow( str, len ) == WEBVTT_OUT_OF_MEMORY ) {
|
||||
if( grow( str, len + 1 ) == WEBVTT_OUT_OF_MEMORY ) {
|
||||
ret = -1;
|
||||
}
|
||||
d = str->d;
|
||||
|
@ -371,6 +370,15 @@ webvtt_string_putc( webvtt_string *str, webvtt_byte to_append )
|
|||
return result;
|
||||
}
|
||||
|
||||
WEBVTT_EXPORT webvtt_bool
|
||||
webvtt_string_is_equal( webvtt_string *str, webvtt_byte *to_compare, webvtt_uint len )
|
||||
{
|
||||
if( !str || !to_compare || webvtt_string_length( str ) != len ) {
|
||||
return 0;
|
||||
}
|
||||
return memcmp( webvtt_string_text( str ), to_compare, len ) == 0;
|
||||
}
|
||||
|
||||
WEBVTT_EXPORT webvtt_status
|
||||
webvtt_string_append( webvtt_string *str, const webvtt_byte *buffer, int len )
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче