2013-03-08 03:47:00 -08:00
|
|
|
/**
|
|
|
|
* 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.
|
|
|
|
*/
|
2013-05-15 21:10:51 -07:00
|
|
|
|
2013-03-08 03:47:00 -08:00
|
|
|
#include <string.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include "node_internal.h"
|
2013-05-15 21:10:51 -07:00
|
|
|
|
2013-03-08 03:47:00 -08:00
|
|
|
static webvtt_node empty_node = {
|
|
|
|
{ 1 }, /* init ref count */
|
|
|
|
0, /* parent */
|
2013-04-16 15:53:00 -07:00
|
|
|
WEBVTT_EMPTY_NODE, /* node kind */
|
|
|
|
{ { 0 } } /* value */
|
2013-03-08 03:47:00 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
WEBVTT_EXPORT void
|
|
|
|
webvtt_ref_node( webvtt_node *node )
|
|
|
|
{
|
|
|
|
if( node ) {
|
|
|
|
webvtt_ref( &node->refs );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-15 21:10:51 -07:00
|
|
|
WEBVTT_EXPORT void
|
2013-03-08 03:47:00 -08:00
|
|
|
webvtt_init_node( webvtt_node **node )
|
|
|
|
{
|
|
|
|
if( *node != &empty_node ) {
|
2013-05-15 21:10:51 -07:00
|
|
|
if( node && *node ) {
|
2013-03-08 03:47:00 -08:00
|
|
|
webvtt_release_node( node );
|
|
|
|
}
|
|
|
|
*node = &empty_node;
|
|
|
|
webvtt_ref_node( *node );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
WEBVTT_INTERN webvtt_status
|
2013-05-15 21:10:51 -07:00
|
|
|
webvtt_create_node( webvtt_node **node, webvtt_node_kind kind,
|
|
|
|
webvtt_node *parent )
|
2013-03-08 03:47:00 -08:00
|
|
|
{
|
|
|
|
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
|
2013-05-15 21:10:51 -07:00
|
|
|
webvtt_create_internal_node( webvtt_node **node, webvtt_node *parent,
|
|
|
|
webvtt_node_kind kind,
|
|
|
|
webvtt_stringlist *css_classes,
|
|
|
|
webvtt_string *annotation )
|
2013-03-08 03:47:00 -08:00
|
|
|
{
|
|
|
|
webvtt_status status;
|
|
|
|
webvtt_internal_node_data *node_data;
|
|
|
|
|
|
|
|
if( WEBVTT_FAILED( status = webvtt_create_node( node, kind, parent ) ) ) {
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2013-05-15 21:10:51 -07:00
|
|
|
if ( !( node_data =
|
|
|
|
(webvtt_internal_node_data *)webvtt_alloc0( sizeof(*node_data) ) ) )
|
2013-03-08 03:47:00 -08:00
|
|
|
{
|
|
|
|
return WEBVTT_OUT_OF_MEMORY;
|
|
|
|
}
|
|
|
|
|
|
|
|
webvtt_copy_stringlist( &node_data->css_classes, css_classes );
|
|
|
|
webvtt_copy_string( &node_data->annotation, annotation );
|
2013-05-15 21:10:51 -07:00
|
|
|
webvtt_init_string( &node_data->lang );
|
2013-03-08 03:47:00 -08:00
|
|
|
node_data->children = NULL;
|
|
|
|
node_data->length = 0;
|
|
|
|
node_data->alloc = 0;
|
|
|
|
|
|
|
|
(*node)->data.internal_data = node_data;
|
|
|
|
|
|
|
|
return WEBVTT_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2013-05-15 21:10:51 -07:00
|
|
|
WEBVTT_INTERN webvtt_status
|
|
|
|
webvtt_create_lang_node( webvtt_node **node, webvtt_node *parent,
|
|
|
|
webvtt_stringlist *css_classes,
|
|
|
|
webvtt_string *lang )
|
|
|
|
{
|
|
|
|
webvtt_string empty_annotation;
|
|
|
|
webvtt_status status;
|
|
|
|
|
|
|
|
webvtt_init_string( &empty_annotation );
|
|
|
|
status = webvtt_create_internal_node( node, parent, WEBVTT_LANG, css_classes,
|
|
|
|
&empty_annotation );
|
|
|
|
webvtt_release_string( &empty_annotation );
|
|
|
|
|
|
|
|
/* We need to release as create internal node put a default value in. */
|
|
|
|
webvtt_release_string( &(*node)->data.internal_data->lang );
|
|
|
|
webvtt_copy_string( &(*node)->data.internal_data->lang, lang );
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2013-03-08 03:47:00 -08:00
|
|
|
WEBVTT_INTERN webvtt_status
|
|
|
|
webvtt_create_head_node( webvtt_node **node )
|
|
|
|
{
|
|
|
|
webvtt_status status;
|
2013-05-15 21:10:51 -07:00
|
|
|
webvtt_string empty_annotation;
|
2013-03-08 03:47:00 -08:00
|
|
|
|
2013-05-15 21:10:51 -07:00
|
|
|
webvtt_init_string( &empty_annotation );
|
|
|
|
if( WEBVTT_FAILED( status =
|
|
|
|
webvtt_create_internal_node( node, NULL, WEBVTT_HEAD_NODE,
|
|
|
|
NULL, &empty_annotation ) ) ) {
|
2013-03-08 03:47:00 -08:00
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2013-05-15 21:10:51 -07:00
|
|
|
webvtt_release_string( &empty_annotation );
|
2013-03-08 03:47:00 -08:00
|
|
|
return WEBVTT_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
WEBVTT_INTERN webvtt_status
|
2013-05-15 21:10:51 -07:00
|
|
|
webvtt_create_timestamp_node( webvtt_node **node, webvtt_node *parent,
|
|
|
|
webvtt_timestamp time_stamp )
|
2013-03-08 03:47:00 -08:00
|
|
|
{
|
|
|
|
webvtt_status status;
|
|
|
|
|
2013-05-15 21:10:51 -07:00
|
|
|
if( WEBVTT_FAILED( status = webvtt_create_node( node,
|
|
|
|
WEBVTT_TIME_STAMP,
|
|
|
|
parent ) ) ) {
|
2013-03-08 03:47:00 -08:00
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
(*node)->data.timestamp = time_stamp;
|
|
|
|
|
|
|
|
return WEBVTT_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
WEBVTT_INTERN webvtt_status
|
2013-05-15 21:10:51 -07:00
|
|
|
webvtt_create_text_node( webvtt_node **node, webvtt_node *parent,
|
|
|
|
webvtt_string *text )
|
2013-03-08 03:47:00 -08:00
|
|
|
{
|
|
|
|
webvtt_status status;
|
|
|
|
|
2013-05-15 21:10:51 -07:00
|
|
|
if( WEBVTT_FAILED( status = webvtt_create_node( node, WEBVTT_TEXT,
|
|
|
|
parent ) ) ) {
|
2013-03-08 03:47:00 -08:00
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
webvtt_copy_string( &(*node)->data.text, text );
|
|
|
|
|
|
|
|
return WEBVTT_SUCCESS;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2013-05-15 21:10:51 -07:00
|
|
|
WEBVTT_EXPORT void
|
2013-03-08 03:47:00 -08:00
|
|
|
webvtt_release_node( webvtt_node **node )
|
|
|
|
{
|
|
|
|
webvtt_uint i;
|
|
|
|
webvtt_node *n;
|
2013-05-15 21:10:51 -07:00
|
|
|
|
2013-03-08 03:47:00 -08:00
|
|
|
if( !node || !*node ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
n = *node;
|
|
|
|
|
|
|
|
if( webvtt_deref( &n->refs ) == 0 ) {
|
|
|
|
if( n->kind == WEBVTT_TEXT ) {
|
|
|
|
webvtt_release_string( &n->data.text );
|
2013-05-15 21:10:51 -07:00
|
|
|
} else if( WEBVTT_IS_VALID_INTERNAL_NODE( n->kind ) &&
|
|
|
|
n->data.internal_data ) {
|
2013-03-08 03:47:00 -08:00
|
|
|
webvtt_release_stringlist( &n->data.internal_data->css_classes );
|
2013-05-15 21:10:51 -07:00
|
|
|
webvtt_release_string( &n->data.internal_data->lang );
|
2013-03-08 03:47:00 -08:00
|
|
|
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;
|
2013-05-15 21:10:51 -07:00
|
|
|
|
2013-03-08 03:47:00 -08:00
|
|
|
if( !parent || !to_attach || !parent->data.internal_data ) {
|
|
|
|
return WEBVTT_INVALID_PARAM;
|
|
|
|
}
|
|
|
|
nd = parent->data.internal_data;
|
2013-05-15 21:10:51 -07:00
|
|
|
|
2013-03-08 03:47:00 -08:00
|
|
|
if( nd->alloc == 0 ) {
|
|
|
|
next = (webvtt_node **)webvtt_alloc0( sizeof( webvtt_node * ) * 8 );
|
2013-05-15 21:10:51 -07:00
|
|
|
|
2013-03-08 03:47:00 -08:00
|
|
|
if( !next ) {
|
|
|
|
return WEBVTT_OUT_OF_MEMORY;
|
|
|
|
}
|
2013-05-15 21:10:51 -07:00
|
|
|
|
2013-03-08 03:47:00 -08:00
|
|
|
nd->children = next;
|
|
|
|
nd->alloc = 8;
|
|
|
|
}
|
2013-05-15 21:10:51 -07:00
|
|
|
|
2013-03-08 03:47:00 -08:00
|
|
|
if( nd->length + 1 >= ( nd->alloc / 3 ) * 2 ) {
|
|
|
|
|
|
|
|
next = (webvtt_node **)webvtt_alloc0( sizeof( *next ) * nd->alloc * 2 );
|
2013-05-15 21:10:51 -07:00
|
|
|
|
2013-03-08 03:47:00 -08:00
|
|
|
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;
|
|
|
|
}
|