Beispiel #1
0
WEBVTT_INTERN webvtt_status
webvtt_create_bytearray_nt( const webvtt_byte *text, webvtt_uint32 alloc, webvtt_bytearray *pba )
{
	webvtt_uint n = 0;
	webvtt_status status;
	webvtt_bytearray s;
	webvtt_byte b;
	if( !pba )
	{
		return WEBVTT_INVALID_PARAM;
	}
	s = (webvtt_bytearray)webvtt_alloc0( sizeof(struct webvtt_bytearray_t) + (alloc*sizeof(webvtt_byte)) );
	if( !s )
	{
		return WEBVTT_OUT_OF_MEMORY;
	}
	s->alloc = alloc;
	s->length = 0;
	s->text = s->array;
	s->text[0] = 0;

	while( (alloc--) && (b = text[n++]) )
	{
		if( WEBVTT_FAILED( status = webvtt_bytearray_putc( &s, b ) ) )
		{
			webvtt_delete_bytearray( &s );
			return status;
		}
	}
	*pba = s;
	return WEBVTT_SUCCESS;
}
Beispiel #2
0
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;
}
Beispiel #3
0
WEBVTT_INTERN int
webvtt_bytearray_getline( webvtt_bytearray *pba, const webvtt_byte *buffer,
	webvtt_uint *pos, webvtt_uint len, int *truncate, webvtt_bool finish )
{
	int ret = 0;
	webvtt_bytearray ba = *pba;
	const webvtt_byte *s = buffer + *pos;
	const webvtt_byte *p = s;
	const webvtt_byte *n = buffer + len;
	if( !ba )
	{
		if(WEBVTT_FAILED(webvtt_create_bytearray( 0x100, pba )))
		{
			return -1;
		}
		ba = *pba;
	}

	while( p < n && *p != CR && *p != LF ) 
	{
		++p;
	}

	if( p < n || finish )
	{
		ret = 1; /* indicate that we found EOL */
	}
	len = (webvtt_uint)( p - s );
	*pos += len;
	if( ba->length + len + 1 >= ba->alloc )
	{
		if( truncate && ba->alloc >= WEBVTT_MAX_LINE )
		{
			/* truncate. */
			(*truncate)++;
		}
		else
		{
			if( grow( pba, len ) == WEBVTT_OUT_OF_MEMORY )
			{
				ret = -1;
			}
			ba = *pba;
		}
	}

	/* Copy everything in */
	if( len && ret >= 0 && ba->length + len < ba->alloc )
	{
		memcpy( ba->text + ba->length, s, len );
		ba->length += len;
		ba->text[ ba->length ] = 0;
	}
	return ret;
}
Beispiel #4
0
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;
}
Beispiel #5
0
WEBVTT_INTERN webvtt_status
webvtt_create_timestamp_token( webvtt_cuetext_token **token, webvtt_timestamp time_stamp )
{
  webvtt_status status;

  if( WEBVTT_FAILED( status = webvtt_create_token( token, TIME_STAMP_TOKEN ) ) ) {
    return status;
  }

  (*token)->time_stamp = time_stamp;

  return WEBVTT_SUCCESS;
}
Beispiel #6
0
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;
}
Beispiel #7
0
WEBVTT_INTERN webvtt_status
webvtt_create_text_token( webvtt_cuetext_token **token, webvtt_string *text )
{
  webvtt_status status;

  if( WEBVTT_FAILED( status = webvtt_create_token( token, TEXT_TOKEN ) ) ) {
    return status;
  }

  webvtt_copy_string( &(*token)->text, text);

  return WEBVTT_SUCCESS;
}
Beispiel #8
0
WEBVTT_INTERN webvtt_status
webvtt_create_end_token( webvtt_cuetext_token **token, webvtt_string *tag_name )
{
  webvtt_status status;

  if( WEBVTT_FAILED( status = webvtt_create_token( token, END_TOKEN ) ) ) {
    return status;
  }

  webvtt_copy_string( &(*token)->tag_name, tag_name );
  
  return WEBVTT_SUCCESS;
}
Beispiel #9
0
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;

}
Beispiel #10
0
WEBVTT_INTERN webvtt_status
webvtt_create_start_token( webvtt_cuetext_token **token, webvtt_string *tag_name,
    webvtt_stringlist *css_classes, webvtt_string *annotation )
{
  webvtt_status status;
  webvtt_start_token_data sd;
  
  if( WEBVTT_FAILED( status = webvtt_create_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;
}
Beispiel #11
0
WEBVTT_EXPORT webvtt_status
webvtt_cue_validate_set_settings( webvtt_parser self, webvtt_cue *cue,
                                  const webvtt_string *settings )
{
  int line = 1;
  int column = 0;
  int length;
  const char *eol;
  int position = 0;
  webvtt_status s;
  if( !cue || !settings ) {
    return WEBVTT_INVALID_PARAM;
  }
  length = (int)webvtt_string_length( settings );
  if( ( eol = strchr( webvtt_string_text( settings ), '\r' ) )
      || ( eol = strchr( webvtt_string_text( settings ), '\n' ) ) ) {
    length = (int)( eol - webvtt_string_text( settings ) );
  }

  if( self ) {
    line = self->line;
    column = self->column;
  }

  /**
   * http://www.w3.org/html/wg/drafts/html/master/single-page.html#split-a-string-on-spaces
   * 4. Skip whitespace
   */
  column += webvtt_string_skip_whitespace( settings, &position );

  while( position < length ) {
    webvtt_string word;
    const char *keyword;
    const char *end;
    int nwhite, ncol;
    /* Collect word (sequence of non-space characters terminated by space) */
    if( WEBVTT_FAILED( webvtt_string_collect_word( settings, &word,
                       &position ) ) ) {
      return WEBVTT_OUT_OF_MEMORY;
    }
    /* skip trailing whitespace */
    nwhite = webvtt_string_skip_whitespace( settings, &position );
    /* Get the word text */
    keyword = webvtt_string_text( &word );
    /* Get pointer to end of the word. (for chcount()) */
    end = keyword + webvtt_string_length( &word );
    /* Get the column count that needs to be skipped. */
    ncol = webvtt_utf8_chcount( keyword, end );
    if( WEBVTT_FAILED( s = webvtt_cue_set_setting_from_string( cue,
                       keyword ) ) ) {
      if( self ) {
        /* Figure out which error to emit */
        webvtt_error error;
        if( webvtt_error_for_status( s, &error ) ) {
          /* There is no non-recoverable cue-setting error.
             Therefore we do not want to abort the loop, regardless
             of the return value from the error handler. */
          WARNING_AT( error, line, column );
        }
      }
    }
    /* Move column pointer beyond word and trailing whitespace */
    column += ncol + nwhite;
    webvtt_release_string( &word );
  }

  if( self ) {
    self->column = column;
  }
  return WEBVTT_SUCCESS;
}
Beispiel #12
0
/**
 * 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_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_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_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_token( &token );
  
  return WEBVTT_SUCCESS;
}
Beispiel #13
0
/**
 * 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;

  /**
   *  TODO: Use these parameters! 'finished' isn't really important
   * here, but 'self' certainly is as it lets us report syntax errors.
   *
   * However, for the time being we can trick the compiler into not
   * warning us about unused variables by doing this.
   */
  ( void )self;
  ( void )finished;

  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 != '\0' ) {
    webvtt_status status = WEBVTT_SUCCESS; 
    webvtt_delete_token( &token );

    /* Step 7. */
    if( WEBVTT_FAILED( status = webvtt_cuetext_tokenizer( &position, 
                                                          &token ) ) ) {
      /* Error here. */
    } else {
      /* Succeeded... Process token */
      if( token->token_type == END_TOKEN ) {
        /**
         * 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( current_node->kind == WEBVTT_HEAD_NODE ) {
          /**
           * 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.
           */
          continue;
        }

        if( webvtt_node_kind_from_tag_name( &token->tag_name, &kind ) == WEBVTT_INVALID_TAG_NAME ) {
          /**
           * We have encountered an end token but it is not in a format that is
           * supported, throw away the token.
           */
          continue;
        }

        if( current_node->kind == kind ) {
          /**
           * 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.
           */
          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_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 );
        }
      }
    }
  }
  
  webvtt_delete_token( &token );
  
  return WEBVTT_SUCCESS;
}
Beispiel #14
0
 virtual void SetUp() {
   ASSERT_FALSE( WEBVTT_FAILED( webvtt_create_parser( &dummyread, &dummyerr,
                                                      0, &self ) ) )
     << "Failed to create parser";
 }