/** * 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; }
/** * 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; }