Bug 887463 - remove webvtt parser library. r=cpearce.

This commit is contained in:
Ralph Giles 2013-07-09 17:02:00 -07:00
parent 438a15498e
commit 2ec3570c84
36 changed files with 33 additions and 6964 deletions

View File

@ -17,4 +17,4 @@
#
# Modifying this file will now automatically clobber the buildbot machines \o/
#
Bug 848491 - Skia update.
Bug 887463 - Remove webvtt parser.

View File

@ -38,7 +38,6 @@
#include "nsStyleConsts.h"
#include "nsThreadUtils.h"
#include "nsVideoFrame.h"
#include "webvtt/parser.h"
#ifdef PR_LOGGING
static PRLogModuleInfo* gTrackElementLog;

View File

@ -6,9 +6,6 @@
#ifndef mozilla_dom_HTMLTrackElement_h
#define mozilla_dom_HTMLTrackElement_h
#define WEBVTT_NO_CONFIG_H 1
#define WEBVTT_STATIC 1
#include "mozilla/Attributes.h"
#include "mozilla/dom/HTMLMediaElement.h"
#include "mozilla/dom/TextTrack.h"

View File

@ -10,7 +10,9 @@
#include "nsIFrame.h"
#include "nsTextNode.h"
#include "nsVideoFrame.h"
#include "webvtt/cue.h"
// Alternate value for the 'auto' keyword.
#define WEBVTT_AUTO -1
namespace mozilla {
namespace dom {
@ -69,8 +71,7 @@ TextTrackCue::TextTrackCue(nsISupports* aGlobal,
, mHead(head)
, mReset(false)
{
// Use the webvtt library's reference counting.
webvtt_ref_node(mHead);
// Ref mHead here.
SetDefaultCueSettings();
MOZ_ASSERT(aGlobal);
SetIsDOMBinding();
@ -79,8 +80,7 @@ TextTrackCue::TextTrackCue(nsISupports* aGlobal,
TextTrackCue::~TextTrackCue()
{
if (mHead) {
// Release our reference and null mHead.
webvtt_release_node(&mHead);
// Release mHead here.
}
}
@ -173,88 +173,19 @@ struct WebVTTNodeParentPair
{}
};
static void
PushChildren(nsTArray<WebVTTNodeParentPair> &aNodeParentPairStack,
webvtt_node* aNode, nsIContent* aParentContent)
{
// Push on in reverse order so we process the nodes in the correct
// order -- left to right.
for (int i = aNode->data.internal_data->length; i > 0; i--) {
WebVTTNodeParentPair nodeParentPair(
aNode->data.internal_data->children[i - 1],
aParentContent);
aNodeParentPairStack.AppendElement(nodeParentPair);
}
}
static WebVTTNodeParentPair
PopChild(nsTArray<WebVTTNodeParentPair> &aNodeParentPairStack) {
WebVTTNodeParentPair temp =
aNodeParentPairStack.LastElement();
aNodeParentPairStack.RemoveElementAt(aNodeParentPairStack.Length() - 1);
return temp;
}
void
TextTrackCue::ConvertNodeTreeToDOMTree(nsIContent* aParentContent)
{
nsTArray<WebVTTNodeParentPair> nodeParentPairStack;
// mHead should actually be the head of a node tree.
if (!mHead || mHead->kind != WEBVTT_HEAD_NODE) {
return;
}
// Seed the stack for traversal.
PushChildren(nodeParentPairStack, mHead, aParentContent);
while (!nodeParentPairStack.IsEmpty()) {
WebVTTNodeParentPair nodeParentPair = PopChild(nodeParentPairStack);
nsCOMPtr<nsIContent> content;
if (WEBVTT_IS_VALID_LEAF_NODE(nodeParentPair.mNode->kind)) {
content = ConvertLeafNodeToContent(nodeParentPair.mNode);
} else if (WEBVTT_IS_VALID_INTERNAL_NODE(nodeParentPair.mNode->kind)) {
content = ConvertInternalNodeToContent(nodeParentPair.mNode);
// Push the children of the current node onto the stack for traversal.
PushChildren(nodeParentPairStack, nodeParentPair.mNode, content);
}
if (content && nodeParentPair.mParent) {
ErrorResult rv;
nodeParentPair.mParent->AppendChild(*content, rv);
}
}
}
already_AddRefed<nsIContent>
TextTrackCue::ConvertInternalNodeToContent(const webvtt_node* aWebVTTNode)
{
nsIAtom* atom;
switch (aWebVTTNode->kind) {
case WEBVTT_BOLD:
atom = nsGkAtoms::b;
break;
case WEBVTT_ITALIC:
atom = nsGkAtoms::i;
break;
case WEBVTT_UNDERLINE:
atom = nsGkAtoms::u;
break;
case WEBVTT_RUBY:
atom = nsGkAtoms::ruby;
break;
case WEBVTT_RUBY_TEXT:
atom = nsGkAtoms::rt;
break;
case WEBVTT_VOICE:
atom = nsGkAtoms::span;
break;
case WEBVTT_CLASS:
atom = nsGkAtoms::span;
break;
default:
return nullptr;
break;
}
nsIAtom* atom = nsGkAtoms::span;
nsCOMPtr<nsIContent> cueTextContent;
nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(mGlobal));
@ -268,37 +199,6 @@ TextTrackCue::ConvertInternalNodeToContent(const webvtt_node* aWebVTTNode)
document->CreateElem(nsDependentAtomString(atom), nullptr,
kNameSpaceID_XHTML,
getter_AddRefs(cueTextContent));
if (aWebVTTNode->kind == WEBVTT_VOICE) {
const char* text =
webvtt_string_text(&aWebVTTNode->data.internal_data->annotation);
if (text) {
nsGenericHTMLElement* genericHtmlElement =
static_cast<nsGenericHTMLElement*>(cueTextContent.get());
genericHtmlElement->SetTitle(NS_ConvertUTF8toUTF16(text));
}
}
webvtt_stringlist* classes = aWebVTTNode->data.internal_data->css_classes;
if (classes && classes->items && classes->length > 0) {
nsAutoString classString;
const char *text = webvtt_string_text(classes->items);
if (text) {
AppendUTF8toUTF16(text, classString);
for (uint32_t i = 1; i < classes->length; i++) {
text = webvtt_string_text(classes->items + i);
if (text) {
classString.Append(' ');
AppendUTF8toUTF16(text, classString);
}
}
}
nsGenericHTMLElement* genericHtmlElement =
static_cast<nsGenericHTMLElement*>(cueTextContent.get());
genericHtmlElement->SetClassName(classString);
}
return cueTextContent.forget();
}
@ -314,30 +214,6 @@ TextTrackCue::ConvertLeafNodeToContent(const webvtt_node* aWebVTTNode)
if(!document) {
return nullptr;
}
nsNodeInfoManager* nimgr = document->NodeInfoManager();
switch (aWebVTTNode->kind) {
case WEBVTT_TEXT:
{
cueTextContent = new nsTextNode(nimgr);
const char* text = webvtt_string_text(&aWebVTTNode->data.text);
if (text) {
cueTextContent->SetText(NS_ConvertUTF8toUTF16(text), false);
}
break;
}
case WEBVTT_TIME_STAMP:
{
nsAutoString timeStamp;
timeStamp.AppendInt(aWebVTTNode->data.timestamp);
cueTextContent =
NS_NewXMLProcessingInstruction(nimgr, NS_LITERAL_STRING("timestamp"),
timeStamp);
break;
}
default:
return nullptr;
break;
}
return cueTextContent.forget();
}

View File

@ -7,15 +7,13 @@
#ifndef mozilla_dom_TextTrackCue_h
#define mozilla_dom_TextTrackCue_h
#define WEBVTT_NO_CONFIG_H 1
#define WEBVTT_STATIC 1
#include "mozilla/dom/DocumentFragment.h"
#include "mozilla/dom/TextTrack.h"
#include "mozilla/dom/TextTrackCueBinding.h"
#include "nsCycleCollectionParticipant.h"
#include "nsDOMEventTargetHelper.h"
#include "webvtt/node.h"
struct webvtt_node;
namespace mozilla {
namespace dom {

View File

@ -58,18 +58,7 @@ WebVTTLoadListener::LoadResource()
LOG("Loading text track resource.");
webvtt_parser_t* parser = nullptr;
webvtt_status status = webvtt_create_parser(&OnParsedCueWebVTTCallBack,
&OnReportErrorWebVTTCallBack,
this, &parser);
if (status != WEBVTT_SUCCESS) {
NS_ENSURE_TRUE(status != WEBVTT_OUT_OF_MEMORY,
NS_ERROR_OUT_OF_MEMORY);
NS_ENSURE_TRUE(status != WEBVTT_INVALID_PARAM,
NS_ERROR_INVALID_ARG);
return NS_ERROR_FAILURE;
}
// Create parser here.
mParser.own(parser);
NS_ENSURE_TRUE(mParser != nullptr, NS_ERROR_FAILURE);
@ -89,7 +78,7 @@ WebVTTLoadListener::OnStopRequest(nsIRequest* aRequest,
nsISupports* aContext,
nsresult aStatus)
{
webvtt_finish_parsing(mParser);
// Flush parser here.
if(mElement->mReadyState != HTMLTrackElement::ERROR) {
mElement->mReadyState = HTMLTrackElement::LOADED;
}
@ -141,10 +130,10 @@ WebVTTLoadListener::ParseChunk(nsIInputStream* aInStream, void* aClosure,
const char* aFromSegment, uint32_t aToOffset,
uint32_t aCount, uint32_t* aWriteCount)
{
WebVTTLoadListener* loadListener = static_cast<WebVTTLoadListener*>(aClosure);
if (WEBVTT_FAILED(webvtt_parse_chunk(loadListener->mParser, aFromSegment,
aCount))) {
//WebVTTLoadListener* loadListener = static_cast<WebVTTLoadListener*>(aClosure);
// Call parser incrementally on new data.
if (1) {
LOG("WebVTT parser disabled.");
LOG("Unable to parse chunk of WEBVTT text. Aborting.");
*aWriteCount = 0;
return NS_ERROR_FAILURE;
@ -156,58 +145,9 @@ WebVTTLoadListener::ParseChunk(nsIInputStream* aInStream, void* aClosure,
void
WebVTTLoadListener::OnParsedCue(webvtt_cue* aCue)
{
const char* text = webvtt_string_text(&aCue->body);
nsRefPtr<TextTrackCue> textTrackCue =
new TextTrackCue(mElement->OwnerDoc()->GetParentObject(),
MS_TO_SECONDS(aCue->from), MS_TO_SECONDS(aCue->until),
NS_ConvertUTF8toUTF16(text), mElement,
aCue->node_head);
text = webvtt_string_text(&aCue->id);
textTrackCue->SetId(NS_ConvertUTF8toUTF16(text));
textTrackCue->SetSnapToLines(aCue->snap_to_lines);
textTrackCue->SetSize(aCue->settings.size);
textTrackCue->SetPosition(aCue->settings.position);
textTrackCue->SetLine(aCue->settings.line);
nsAutoString vertical;
switch (aCue->settings.vertical) {
case WEBVTT_VERTICAL_LR:
vertical = NS_LITERAL_STRING("lr");
break;
case WEBVTT_VERTICAL_RL:
vertical = NS_LITERAL_STRING("rl");
break;
case WEBVTT_HORIZONTAL:
// TODO: https://bugzilla.mozilla.org/show_bug.cgi?id=865407
// Will be handled in the processing model.
break;
}
textTrackCue->SetVertical(vertical);
TextTrackCueAlign align;
switch (aCue->settings.align) {
case WEBVTT_ALIGN_START:
align = TextTrackCueAlign::Start;
break;
case WEBVTT_ALIGN_MIDDLE:
align = TextTrackCueAlign::Middle;
case WEBVTT_ALIGN_END:
align = TextTrackCueAlign::End;
case WEBVTT_ALIGN_LEFT:
align = TextTrackCueAlign::Left;
break;
case WEBVTT_ALIGN_RIGHT:
align = TextTrackCueAlign::Right;
break;
default:
align = TextTrackCueAlign::Start;
break;
}
textTrackCue->SetAlign(align);
nsRefPtr<TextTrackCue> textTrackCue;
// Create a new textTrackCue here.
// Copy settings from the parsed cue here.
mElement->mTrack->AddCue(*textTrackCue);
}
@ -223,46 +163,10 @@ WebVTTLoadListener::OnReportError(uint32_t aLine, uint32_t aCol,
NS_ConvertUTF16toUTF8 file(wideFile);
const char* error = "parser error";
if (aError >= 0) {
error = webvtt_strerror(aError);
}
LOG("error: %s(%d:%d) - %s\n", file.get(), aLine, aCol, error);
#endif
switch(aError) {
// Non-recoverable errors require us to abort parsing:
case WEBVTT_MALFORMED_TAG:
mElement->mReadyState = HTMLTrackElement::ERROR;
return -1;
// Errors which should result in dropped cues
// if the return value is negative:
case WEBVTT_MALFORMED_TIMESTAMP:
return -1;
// By default, we can safely ignore other errors
// or else parsing the document will be aborted regardless
// of the return value.
default:
return 0;
}
}
void WEBVTT_CALLBACK
WebVTTLoadListener::OnParsedCueWebVTTCallBack(void* aUserData, webvtt_cue* aCue)
{
WebVTTLoadListener* self = static_cast<WebVTTLoadListener*>(aUserData);
self->OnParsedCue(aCue);
}
int WEBVTT_CALLBACK
WebVTTLoadListener::OnReportErrorWebVTTCallBack(void* aUserData, uint32_t aLine,
uint32_t aCol,
webvtt_error aError)
{
WebVTTLoadListener* self = static_cast<WebVTTLoadListener*>(aUserData);
return self->OnReportError(aLine, aCol, aError);
return 0;
}
} // namespace dom

View File

@ -14,14 +14,18 @@
#include "nsAutoRef.h"
#include "nsCycleCollectionParticipant.h"
#include "mozilla/dom/HTMLTrackElement.h"
#include "webvtt/parser.h"
#include "webvtt/util.h"
struct webvtt_parser_t;
struct webvtt_cue;
typedef int webvtt_error;
template <>
class nsAutoRefTraits<webvtt_parser_t> : public nsPointerRefTraits<webvtt_parser_t>
{
public:
static void Release(webvtt_parser_t* aParser) { webvtt_delete_parser(aParser); }
static void Release(webvtt_parser_t* aParser) {
// Call parser dtor here.
}
};
namespace mozilla {
@ -75,13 +79,6 @@ private:
void OnParsedCue(webvtt_cue* aCue);
int OnReportError(uint32_t aLine, uint32_t aCol, webvtt_error aError);
static void WEBVTT_CALLBACK OnParsedCueWebVTTCallBack(void* aUserData,
webvtt_cue* aCue);
static int WEBVTT_CALLBACK OnReportErrorWebVTTCallBack(void* aUserData,
uint32_t aLine,
uint32_t aCol,
webvtt_error aError);
};

View File

@ -34,12 +34,14 @@ SpecialPowers.pushPrefEnv({"set": [["media.webvtt.enabled", true]]},
setTimeout(run_tests, 0);
return;
}
is(trackElement.readyState, 2, "Track::ReadyState should be set to LOADED.");
todo_is(trackElement.readyState, 2, "Track::ReadyState should be set to LOADED.");
var cueList = trackElement.track.cues;
is(cueList.length, 4, "Cue list length should be 4.");
todo_is(cueList.length, 4, "Cue list length should be 4.");
// Check if first cue was parsed correctly.
// FIXME: disabled by bug 887463.
if (false) {
var cue = cueList[0];
is(cue.id, "1", "Cue's ID should be 1.");
is(cue.startTime, 0.5, "Cue's start time should be 0.5.");
@ -91,6 +93,9 @@ SpecialPowers.pushPrefEnv({"set": [["media.webvtt.enabled", true]]},
// to 4 -- https://bugzilla.mozilla.org/show_bug.cgi?id=867823
todo_is(cueList.length, 4, "Cue list length should be 4.");
// FIXME: end of bug 887463 disable.
}
var exceptionHappened = false;
try {
// We should not be able to remove a cue that is not in the list.

View File

@ -113,10 +113,6 @@ ifdef MOZ_ENABLE_SKIA
SHARED_LIBRARY_LIBS += $(MOZ_SKIA_LIBS)
endif
SHARED_LIBRARY_LIBS += \
$(DEPTH)/media/webvtt/$(LIB_PREFIX)webvtt.$(LIB_SUFFIX) \
$(NULL)
ifdef MOZ_WEBRTC
ifndef MOZ_WEBRTC_IN_LIBXUL
DEFINES += -DMOZ_WEBRTC_GKMEDIA=1

View File

@ -580,11 +580,3 @@ hb_unicode_funcs_set_eastasian_width_func
hb_unicode_funcs_set_general_category_func
hb_unicode_funcs_set_mirroring_func
hb_unicode_funcs_set_script_func
webvtt_create_parser
webvtt_delete_parser
webvtt_finish_parsing
webvtt_parse_chunk
webvtt_ref_node
webvtt_release_node
webvtt_strerror
webvtt_string_text

View File

@ -1,61 +0,0 @@
# HG changeset patch
# User Caitlin Potter <snowball@defpixel.com>
# Date 1367954476 14400
# Node ID 2becb21900559e271175e08d7ec33ed35b034967
# Parent 41ff3b67b69232297191c8f8ef78e5facc1c1d19
Bug 868629 - webvtt no longer needs -DWEBVTT_NO_CONFIG_H. r=rillian
diff --git a/media/webvtt/include/webvtt/util.h b/media/webvtt/include/webvtt/util.h
--- a/media/webvtt/include/webvtt/util.h
+++ b/media/webvtt/include/webvtt/util.h
@@ -32,16 +32,21 @@
extern "C" {
#endif
-# if defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) || defined(__WINDOWS__)
-# if !WEBVTT_NO_CONFIG_H
-# include "webvtt-config-win32.h"
-# endif
+# if !defined(_MSC_VER) || _MSC_VER >= 1600
+/**
+ * For non-MSVC compilers, or MSVC2010 or later, assume we have
+ * stdint.h
+ */
+# define WEBVTT_HAVE_STDINT 1
+# include <stdint.h>
+# endif
+
+# if defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) ||\
+ defined(__WINDOWS__)
# define WEBVTT_OS_WIN32 1
# if defined(_WIN64)
# define WEBVTT_OS_WIN64 1
# endif
-# elif !WEBVTT_NO_CONFIG_H
-# include <webvtt/webvtt-config.h>
# endif
# if defined(_MSC_VER)
@@ -54,12 +59,8 @@
# else
# define WEBVTT_EXPORT
# endif
-# if _MSC_VER >= 1600
-# define WEBVTT_HAVE_STDINT 1
-# endif
# elif defined(__GNUC__)
# define WEBVTT_CC_GCC 1
-# define WEBVTT_HAVE_STDINT 1
# if WEBVTT_OS_WIN32
# if WEBVTT_BUILD_LIBRARY
# define WEBVTT_EXPORT __declspec(dllexport)
@@ -96,8 +97,7 @@
# define WEBVTT_INLINE __inline__
# endif
-# if WEBVTT_HAVE_STDINT
-# include <stdint.h>
+# ifdef WEBVTT_HAVE_STDINT
typedef int8_t webvtt_int8;
typedef int16_t webvtt_int16;
typedef int32_t webvtt_int32;

View File

@ -1,25 +0,0 @@
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.

View File

@ -1,27 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DEPTH = @DEPTH@
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
DEFINES += \
-DWEBVTT_STATIC=1 \
$(NULL)
CSRCS = \
alloc.c \
cue.c \
cuetext.c \
error.c \
lexer.c \
node.c \
parser.c \
string.c \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -1,6 +0,0 @@
These files are from the WebVTT library, and are extracted from rev
aca1a4cc860141ea4759c87ecd906b365ffd89f0 of the git repository at
https://github.com/mozilla/webvtt.
The following CPPFLAGS are used in order to build and link in Mozilla
-DWEBVTT_STATIC=1 -- Compile as a static library

View File

@ -1,113 +0,0 @@
/**
* Copyright (c) 2013 Mozilla Foundation and Contributors
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <webvtt/util.h>
#include <stdlib.h>
#include <string.h>
static void *default_alloc( void *unused, webvtt_uint nb );
static void default_free( void *unused, void *ptr );
struct {
/**
* Number of allocated objects. Forbid changing the allocator if this is not
* equal to 0
*/
webvtt_uint n_alloc;
webvtt_alloc_fn_ptr alloc;
webvtt_free_fn_ptr free;
void *alloc_data;
} allocator = { 0, default_alloc, default_free, 0 };
static void *WEBVTT_CALLBACK
default_alloc( void *unused, webvtt_uint nb )
{
(void)unused;
return malloc( nb );
}
static void WEBVTT_CALLBACK
default_free( void *unused, void *ptr )
{
(void)unused;
free( ptr );
}
WEBVTT_EXPORT void
webvtt_set_allocator( webvtt_alloc_fn_ptr alloc, webvtt_free_fn_ptr free,
void *userdata )
{
/**
* TODO:
* This really needs a lock. But then, so does all the allocation/free
* functions...
* that could be a problem.
*/
if( allocator.n_alloc == 0 ) {
if( alloc && free ) {
allocator.alloc = alloc;
allocator.free = free;
allocator.alloc_data = userdata;
} else if( !alloc && !free ) {
allocator.alloc = &default_alloc;
allocator.free = &default_free;
allocator.alloc_data = 0;
}
}
}
/**
* public alloc/dealloc functions
*/
WEBVTT_EXPORT void *
webvtt_alloc( webvtt_uint nb )
{
void *ret = allocator.alloc( allocator.alloc_data, nb );
if( ret )
{ ++allocator.n_alloc; }
return ret;
}
WEBVTT_EXPORT void *
webvtt_alloc0( webvtt_uint nb )
{
void *ret = allocator.alloc( allocator.alloc_data, nb );
if( ret ) {
++allocator.n_alloc;
memset( ret, 0, nb );
}
return ret;
}
WEBVTT_EXPORT void
webvtt_free( void *data )
{
if( data && allocator.n_alloc ) {
allocator.free( allocator.alloc_data, data );
--allocator.n_alloc;
}
}

View File

@ -1,125 +0,0 @@
/**
* Copyright (c) 2013 Mozilla Foundation and Contributors
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "parser_internal.h"
#include "cue_internal.h"
WEBVTT_EXPORT webvtt_status
webvtt_create_cue( webvtt_cue **pcue )
{
webvtt_cue *cue;
if( !pcue ) {
return WEBVTT_INVALID_PARAM;
}
cue = (webvtt_cue *)webvtt_alloc0( sizeof(*cue) );
if( !cue ) {
return WEBVTT_OUT_OF_MEMORY;
}
/**
* From http://dev.w3.org/html5/webvtt/#parsing (10/25/2012)
*
* Let cue's text track cue snap-to-lines flag be true.
*
* Let cue's text track cue line position be auto.
*
* Let cue's text track cue text position be 50.
*
* Let cue's text track cue size be 100.
*
* Let cue's text track cue alignment be middle alignment.
*/
webvtt_ref( &cue->refs );
webvtt_init_string( &cue->id );
webvtt_init_string( &cue->body );
cue->from = 0xFFFFFFFFFFFFFFFF;
cue->until = 0xFFFFFFFFFFFFFFFF;
cue->snap_to_lines = 1;
cue->settings.position = 50;
cue->settings.size = 100;
cue->settings.align = WEBVTT_ALIGN_MIDDLE;
cue->settings.line = WEBVTT_AUTO;
cue->settings.vertical = WEBVTT_HORIZONTAL;
*pcue = cue;
return WEBVTT_SUCCESS;
}
WEBVTT_EXPORT void
webvtt_ref_cue( webvtt_cue *cue )
{
if( cue ) {
webvtt_ref( &cue->refs );
}
}
WEBVTT_EXPORT void
webvtt_release_cue( webvtt_cue **pcue )
{
if( pcue && *pcue ) {
webvtt_cue *cue = *pcue;
*pcue = 0;
if( webvtt_deref( &cue->refs ) == 0 ) {
webvtt_release_string( &cue->id );
webvtt_release_string( &cue->body );
webvtt_release_node( &cue->node_head );
webvtt_free( cue );
}
}
}
WEBVTT_EXPORT int
webvtt_validate_cue( webvtt_cue *cue )
{
if( cue ) {
/**
* validate cue-times (Can't do checks against previously parsed cuetimes.
* That's the applications responsibility
*/
if( BAD_TIMESTAMP(cue->from) || BAD_TIMESTAMP(cue->until) ) {
goto error;
}
if( cue->until <= cue->from ) {
goto error;
}
/**
* Don't do any payload validation, because this would involve parsing the
* payload, which is optional.
*/
return 1;
}
error:
return 0;
}
WEBVTT_INTERN webvtt_bool
cue_is_incomplete( const webvtt_cue *cue ) {
return !cue || ( cue->flags & CUE_HEADER_MASK ) == CUE_HAVE_ID;
}

View File

@ -1,53 +0,0 @@
/**
* Copyright (c) 2013 Mozilla Foundation and Contributors
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __INTERN_CUE_H__
# define __INTERN_CUE_H__
# include <webvtt/cue.h>
/**
* Private cue flags
*/
enum {
CUE_HAVE_VERTICAL = (1 << 0),
CUE_HAVE_SIZE = (1 << 1),
CUE_HAVE_POSITION = (1 << 2),
CUE_HAVE_LINE = (1 << 3),
CUE_HAVE_ALIGN = (1 << 4),
CUE_HAVE_SETTINGS = (CUE_HAVE_VERTICAL | CUE_HAVE_SIZE
| CUE_HAVE_POSITION | CUE_HAVE_LINE | CUE_HAVE_ALIGN),
CUE_HAVE_CUEPARAMS = 0x40000000,
CUE_HAVE_ID = 0x80000000,
CUE_HEADER_MASK = CUE_HAVE_CUEPARAMS|CUE_HAVE_ID,
};
WEBVTT_INTERN webvtt_bool
cue_is_incomplete( const webvtt_cue *cue );
#endif

View File

@ -1,814 +0,0 @@
/**
* Copyright (c) 2013 Mozilla Foundation and Contributors
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdlib.h>
#include <string.h>
#include "parser_internal.h"
#include "cuetext_internal.h"
#include "node_internal.h"
#include "cue_internal.h"
#include "string_internal.h"
#ifdef min
# undef min
#endif
#define min(a,b) ( (a) < (b) ? (a) : (b) )
/**
* ERROR macro used for webvtt_parse_cuetext
*/
#undef ERROR
#define ERROR(code) \
do \
{ \
if( self->error ) \
if( self->error( self->userdata, line, col, code ) < 0 ) \
return WEBVTT_PARSE_ERROR; \
} while(0)
/**
* Macros for return statuses based on memory operations.
* This is to avoid many if statements checking for multiple memory operation
* return statuses in functions.
*/
#define CHECK_MEMORY_OP(status) \
if( status != WEBVTT_SUCCESS ) \
return status; \
#define CHECK_MEMORY_OP_JUMP(status_var, returned_status) \
if( returned_status != WEBVTT_SUCCESS) \
{ \
status_var = returned_status; \
goto dealloc; \
} \
WEBVTT_INTERN webvtt_status
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) );
if( !temp_token ) {
return WEBVTT_OUT_OF_MEMORY;
}
temp_token->token_type = token_type;
*token = temp_token;
return WEBVTT_SUCCESS;
}
WEBVTT_INTERN webvtt_status
webvtt_create_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;
}
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;
}
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;
}
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;
}
WEBVTT_INTERN void
webvtt_delete_token( webvtt_cuetext_token **token )
{
webvtt_start_token_data data;
webvtt_cuetext_token *t;
if( !token ) {
return;
}
if( !*token ) {
return;
}
t = *token;
/**
* Note that time stamp tokens do not need to free any internal data because
* they do not allocate anything.
*/
if( t->token_type == START_TOKEN ) {
data = t->start_token_data;
webvtt_release_stringlist( &data.css_classes );
webvtt_release_string( &data.annotations );
webvtt_release_string( &t->tag_name );
} else if( t->token_type == END_TOKEN ) {
webvtt_release_string( &t->tag_name );
} else if( t->token_type == TEXT_TOKEN ) {
webvtt_release_string( &t->text );
}
webvtt_free( t );
*token = 0;
}
WEBVTT_INTERN int
tag_accepts_annotation( webvtt_string *tag_name )
{
return webvtt_string_is_equal( tag_name, "v", 1 ) ||
webvtt_string_is_equal( tag_name, "lang", 4 );
}
WEBVTT_INTERN webvtt_status
webvtt_node_kind_from_tag_name( webvtt_string *tag_name,
webvtt_node_kind *kind )
{
if( !tag_name || !kind ) {
return WEBVTT_INVALID_PARAM;
}
if( webvtt_string_length(tag_name) == 1 ) {
switch( webvtt_string_text(tag_name)[0] ) {
case 'b':
*kind = WEBVTT_BOLD;
break;
case 'i':
*kind = WEBVTT_ITALIC;
break;
case 'u':
*kind = WEBVTT_UNDERLINE;
break;
case 'c':
*kind = WEBVTT_CLASS;
break;
case 'v':
*kind = WEBVTT_VOICE;
break;
}
} else if( webvtt_string_is_equal( tag_name, "ruby", 4 ) ) {
*kind = WEBVTT_RUBY;
} else if( webvtt_string_is_equal( tag_name, "rt", 2 ) ) {
*kind = WEBVTT_RUBY_TEXT;
} else if ( webvtt_string_is_equal( tag_name, "lang", 4 ) ) {
*kind = WEBVTT_LANG;
} else {
return WEBVTT_INVALID_TAG_NAME;
}
return WEBVTT_SUCCESS;
}
WEBVTT_INTERN webvtt_status
webvtt_create_node_from_token( webvtt_cuetext_token *token, webvtt_node **node,
webvtt_node *parent )
{
webvtt_node_kind kind;
if( !token || !node || !parent ) {
return WEBVTT_INVALID_PARAM;
}
/**
* We've recieved a node that is not null.
* In order to prevent memory leaks caused by overwriting a node which the
* caller has not released return unsuccessful.
*/
if( *node ) {
return WEBVTT_UNSUCCESSFUL;
}
switch ( token->token_type ) {
case TEXT_TOKEN:
return webvtt_create_text_node( node, parent, &token->text );
break;
case START_TOKEN:
CHECK_MEMORY_OP( webvtt_node_kind_from_tag_name( &token->tag_name,
&kind) );
if( kind == WEBVTT_LANG ) {
return webvtt_create_lang_node( node, parent,
token->start_token_data.css_classes,
&token->start_token_data.annotations );
}
else {
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_timestamp_node( node, parent, token->time_stamp );
break;
default:
return WEBVTT_INVALID_TOKEN_TYPE;
}
}
WEBVTT_INTERN webvtt_status
webvtt_data_state( const char **position, webvtt_token_state *token_state,
webvtt_string *result )
{
for ( ; *token_state == DATA; (*position)++ ) {
switch( **position ) {
case '&':
*token_state = ESCAPE;
break;
case '<':
if( webvtt_string_length(result) == 0 ) {
*token_state = TAG;
} else {
return WEBVTT_SUCCESS;
}
break;
case '\0':
return WEBVTT_SUCCESS;
break;
default:
CHECK_MEMORY_OP( webvtt_string_putc( result, *position[0] ) );
break;
}
}
return WEBVTT_UNFINISHED;
}
/**
* Definitions for escape sequence replacement strings.
*/
#define RLM_LENGTH 3
#define LRM_LENGTH 3
#define NBSP_LENGTH 2
char rlm_replace[RLM_LENGTH] = { UTF8_RIGHT_TO_LEFT_1, UTF8_RIGHT_TO_LEFT_2,
UTF8_RIGHT_TO_LEFT_3 };
char lrm_replace[LRM_LENGTH] = { UTF8_LEFT_TO_RIGHT_1, UTF8_LEFT_TO_RIGHT_2,
UTF8_LEFT_TO_RIGHT_3 };
char nbsp_replace[NBSP_LENGTH] = { UTF8_NO_BREAK_SPACE_1,
UTF8_NO_BREAK_SPACE_2 };
WEBVTT_INTERN webvtt_status
webvtt_escape_state( const char **position, webvtt_token_state *token_state,
webvtt_string *result )
{
webvtt_string buffer;
webvtt_status status = WEBVTT_SUCCESS;
CHECK_MEMORY_OP_JUMP( status, webvtt_create_string( 1, &buffer ) );
/**
* Append ampersand here because the algorithm is not able to add it to the
* buffer when it reads it in the DATA state tokenizer.
*/
CHECK_MEMORY_OP_JUMP( status, webvtt_string_putc( &buffer, '&' ) );
for( ; *token_state == ESCAPE; (*position)++ ) {
/**
* We have encountered a token termination point.
* Append buffer to result and return success.
*/
if( **position == '\0' || **position == '<' ) {
CHECK_MEMORY_OP_JUMP( status, webvtt_string_append_string( result,
&buffer ) );
goto dealloc;
}
/**
* This means we have enocuntered a malformed escape character sequence.
* This means that we need to add that malformed text to the result and
* recreate the buffer to prepare for a new escape sequence.
*/
else if( **position == '&' ) {
CHECK_MEMORY_OP_JUMP( status, webvtt_string_append_string( result,
&buffer ) );
webvtt_release_string( &buffer );
CHECK_MEMORY_OP_JUMP( status, webvtt_create_string( 1, &buffer ) );
CHECK_MEMORY_OP_JUMP( status, webvtt_string_putc( &buffer,
*position[0] ) );
}
/**
* We've encountered the semicolon which is the end of an escape sequence.
* Check if buffer contains a valid escape sequence and if it does append
* the interpretation to result and change the state to DATA.
*/
else if( **position == ';' ) {
if( webvtt_string_is_equal( &buffer, "&amp", 4 ) ) {
CHECK_MEMORY_OP_JUMP( status, webvtt_string_putc( result, '&' ) );
} else if( webvtt_string_is_equal( &buffer, "&lt", 3 ) ) {
CHECK_MEMORY_OP_JUMP( status, webvtt_string_putc( result, '<' ) );
} else if( webvtt_string_is_equal( &buffer, "&gt", 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_LENGTH ) );
} else if( webvtt_string_is_equal( &buffer, "&lrm", 4 ) ) {
CHECK_MEMORY_OP_JUMP( status, webvtt_string_append( result, lrm_replace,
LRM_LENGTH ) );
} else if( webvtt_string_is_equal( &buffer, "&nbsp", 5 ) ) {
CHECK_MEMORY_OP_JUMP( status, webvtt_string_append( result,
nbsp_replace,
NBSP_LENGTH ) );
} else {
CHECK_MEMORY_OP_JUMP( status, webvtt_string_append_string( result,
&buffer ) );
CHECK_MEMORY_OP_JUMP( status, webvtt_string_putc( result,
**position ) );
}
*token_state = DATA;
status = WEBVTT_UNFINISHED;
}
/**
* Character is alphanumeric. This means we are in the body of the escape
* sequence.
*/
else if( webvtt_isalphanum( **position ) ) {
CHECK_MEMORY_OP_JUMP( status, webvtt_string_putc( &buffer, **position ) );
}
/**
* If we have not found an alphanumeric character then we have encountered
* a malformed escape sequence. Add buffer to result and continue to parse
* in DATA state.
*/
else {
CHECK_MEMORY_OP_JUMP( status, webvtt_string_append_string( result,
&buffer ) );
CHECK_MEMORY_OP_JUMP( status, webvtt_string_putc( result,
**position ) );
status = WEBVTT_UNFINISHED;
*token_state = DATA;
}
}
dealloc:
webvtt_release_string( &buffer );
return status;
}
WEBVTT_INTERN webvtt_status
webvtt_tag_state( const char **position, webvtt_token_state *token_state,
webvtt_string *result )
{
for( ; *token_state == TAG; (*position)++ ) {
if( **position == '\t' || **position == '\n' ||
**position == '\r' || **position == '\f' ||
**position == ' ' ) {
*token_state = START_TAG_ANNOTATION;
} else if( webvtt_isdigit( **position ) ) {
CHECK_MEMORY_OP( webvtt_string_putc( result, **position ) );
*token_state = TIME_STAMP_TAG;
} else {
switch( **position ) {
case '.':
*token_state = START_TAG_CLASS;
break;
case '/':
*token_state = END_TAG;
break;
case '>':
return WEBVTT_SUCCESS;
break;
case '\0':
return WEBVTT_SUCCESS;
break;
default:
CHECK_MEMORY_OP( webvtt_string_putc( result, **position ) );
*token_state = START_TAG;
}
}
}
return WEBVTT_UNFINISHED;
}
WEBVTT_INTERN webvtt_status
webvtt_start_tag_state( const char **position, webvtt_token_state *token_state,
webvtt_string *result )
{
for( ; *token_state == START_TAG; (*position)++ ) {
if( **position == '\t' || **position == '\f' ||
**position == ' ' || **position == '\n' ||
**position == '\r' ) {
*token_state = START_TAG_ANNOTATION;
} else {
switch( **position ) {
case '.':
*token_state = START_TAG_CLASS;
break;
case '\0':
return WEBVTT_SUCCESS;
case '>':
return WEBVTT_SUCCESS;
break;
default:
CHECK_MEMORY_OP( webvtt_string_putc( result, **position ) );
break;
}
}
}
return WEBVTT_UNFINISHED;
}
WEBVTT_INTERN webvtt_status
webvtt_class_state( const char **position, webvtt_token_state *token_state,
webvtt_stringlist *css_classes )
{
webvtt_string buffer;
webvtt_status status = WEBVTT_SUCCESS;
CHECK_MEMORY_OP( webvtt_create_string( 1, &buffer ) );
for( ; *token_state == START_TAG_CLASS; (*position)++ ) {
if( **position == '\t' || **position == '\f' ||
**position == ' ' || **position == '\n' ||
**position == '\r') {
if( webvtt_string_length( &buffer ) > 0 ) {
CHECK_MEMORY_OP_JUMP( status, webvtt_stringlist_push( css_classes,
&buffer ) );
}
*token_state = START_TAG_ANNOTATION;
webvtt_release_string( &buffer );
return WEBVTT_SUCCESS;
} else if( **position == '>' || **position == '\0' ) {
CHECK_MEMORY_OP_JUMP( status, webvtt_stringlist_push( css_classes,
&buffer ) );
webvtt_release_string( &buffer );
return WEBVTT_SUCCESS;
} else if( **position == '.' ) {
CHECK_MEMORY_OP_JUMP( status, webvtt_stringlist_push( css_classes,
&buffer ) );
webvtt_release_string( &buffer );
CHECK_MEMORY_OP( webvtt_create_string( 1, &buffer ) );
} else {
CHECK_MEMORY_OP_JUMP( status, webvtt_string_putc( &buffer, **position ) );
}
}
dealloc:
webvtt_release_string( &buffer );
return status;
}
WEBVTT_INTERN webvtt_status
webvtt_annotation_state( const char **position, webvtt_token_state *token_state,
webvtt_string *annotation )
{
for( ; *token_state == START_TAG_ANNOTATION; (*position)++ ) {
if( **position == '\0' || **position == '>' ) {
return WEBVTT_SUCCESS;
}
CHECK_MEMORY_OP( webvtt_string_putc( annotation, **position ) );
}
return WEBVTT_UNFINISHED;
}
WEBVTT_INTERN webvtt_status
webvtt_end_tag_state( const char **position, webvtt_token_state *token_state,
webvtt_string *result )
{
for( ; *token_state == END_TAG; (*position)++ ) {
if( **position == '>' || **position == '\0' ) {
return WEBVTT_SUCCESS;
}
CHECK_MEMORY_OP( webvtt_string_putc( result, **position ) );
}
return WEBVTT_UNFINISHED;
}
WEBVTT_INTERN webvtt_status
webvtt_timestamp_state( const char **position, webvtt_token_state *token_state,
webvtt_string *result )
{
for( ; *token_state == TIME_STAMP_TAG; (*position)++ ) {
if( **position == '>' || **position == '\0' ) {
return WEBVTT_SUCCESS;
}
CHECK_MEMORY_OP( webvtt_string_putc( result, **position ) );
}
return WEBVTT_UNFINISHED;
}
/**
* Need to set up differently.
* Get a status in order to return at end and release memeory.
*/
WEBVTT_INTERN webvtt_status
webvtt_cuetext_tokenizer( const char **position, webvtt_cuetext_token **token )
{
webvtt_token_state token_state = DATA;
webvtt_string result, annotation;
webvtt_stringlist *css_classes;
webvtt_timestamp time_stamp = 0;
webvtt_status status = WEBVTT_UNFINISHED;
if( !position ) {
return WEBVTT_INVALID_PARAM;
}
webvtt_create_string( 10, &result );
webvtt_create_string( 10, &annotation );
webvtt_create_stringlist( &css_classes );
/**
* Loop while the tokenizer is not finished.
* Based on the state of the tokenizer enter a function to handle that
* particular tokenizer state. Those functions will loop until they either
* change the state of the tokenizer or reach a valid token end point.
*/
while( status == WEBVTT_UNFINISHED ) {
switch( token_state ) {
case DATA :
status = webvtt_data_state( position, &token_state, &result );
break;
case ESCAPE:
status = webvtt_escape_state( position, &token_state, &result );
break;
case TAG:
status = webvtt_tag_state( position, &token_state, &result );
break;
case START_TAG:
status = webvtt_start_tag_state( position, &token_state, &result );
break;
case START_TAG_CLASS:
status = webvtt_class_state( position, &token_state, css_classes );
break;
case START_TAG_ANNOTATION:
status = webvtt_annotation_state( position, &token_state, &annotation );
break;
case END_TAG:
status = webvtt_end_tag_state( position, &token_state, &result );
break;
case TIME_STAMP_TAG:
status = webvtt_timestamp_state( position, &token_state, &result );
break;
}
}
if( **position == '>' )
{ (*position)++; }
if( status == WEBVTT_SUCCESS ) {
/**
* The state that the tokenizer left off on will tell us what kind of token
* needs to be made.
*/
if( token_state == DATA || token_state == ESCAPE ) {
status = webvtt_create_text_token( token, &result );
} else if( token_state == TAG || token_state == START_TAG ||
token_state == START_TAG_CLASS ||
token_state == START_TAG_ANNOTATION) {
/**
* If the tag does not accept an annotation then release the current
* annotation and intialize annotation to a safe empty state
*/
if( !tag_accepts_annotation( &result ) ) {
webvtt_release_string( &annotation );
webvtt_init_string( &annotation );
}
status = webvtt_create_start_token( token, &result, css_classes,
&annotation );
} else if( token_state == END_TAG ) {
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_timestamp_token( token, time_stamp );
} else {
status = WEBVTT_INVALID_TOKEN_STATE;
}
}
webvtt_release_stringlist( &css_classes );
webvtt_release_string( &result );
webvtt_release_string( &annotation );
return status;
}
/**
* Currently line and len are not being kept track of.
* Don't think pnode_length is needed as nodes track there list count
* internally.
*/
WEBVTT_INTERN webvtt_status
webvtt_parse_cuetext( webvtt_parser self, webvtt_cue *cue,
webvtt_string *payload, int finished )
{
const char *cue_text;
webvtt_status status;
const char *position;
webvtt_node *node_head;
webvtt_node *current_node;
webvtt_node *temp_node;
webvtt_cuetext_token *token;
webvtt_node_kind kind;
webvtt_stringlist *lang_stack;
webvtt_string temp;
/**
* 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 = cue_text;
node_head = cue->node_head;
current_node = node_head;
temp_node = NULL;
token = NULL;
webvtt_create_stringlist( &lang_stack );
/**
* 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 ||
( current_node->kind == WEBVTT_RUBY_TEXT
&& kind == WEBVTT_RUBY ) ) {
/**
* We have encountered a valid end tag to our current tag. Move back
* up the tree of nodes and continue parsing.
*/
current_node = current_node->parent;
if( kind == WEBVTT_LANG ) {
webvtt_stringlist_pop( lang_stack, &temp );
webvtt_release_string( &temp );
}
}
} 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 {
/**
* If the parsed node is ruby text and we are not currently on a ruby
* node then do not attach the ruby text node.
*/
if( temp_node->kind == WEBVTT_RUBY_TEXT &&
current_node->kind != WEBVTT_RUBY ) {
webvtt_release_node( &temp_node );
continue;
}
webvtt_attach_node( current_node, temp_node );
/**
* If the child node is a leaf node then we are done.
*/
if( WEBVTT_IS_VALID_LEAF_NODE( temp_node->kind ) ) {
webvtt_release_node( &temp_node );
continue;
}
if( temp_node->kind == WEBVTT_LANG ) {
webvtt_stringlist_push( lang_stack,
&temp_node->data.internal_data->lang );
} else if( lang_stack->length >= 1 ) {
webvtt_release_string( &temp_node->data.internal_data->lang );
webvtt_copy_string( &temp_node->data.internal_data->lang,
lang_stack->items + lang_stack->length - 1 );
}
current_node = temp_node;
/* Release the node as attach internal node increases the count. */
webvtt_release_node( &temp_node );
}
}
}
}
webvtt_delete_token( &token );
webvtt_release_stringlist( &lang_stack );
return WEBVTT_SUCCESS;
}

View File

@ -1,220 +0,0 @@
/**
* Copyright (c) 2013 Mozilla Foundation and Contributors
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __INTERN_CUETEXT_H__
# define __INTERN_CUETEXT_H__
# include <webvtt/util.h>
# include <webvtt/string.h>
# include <webvtt/cue.h>
typedef struct webvtt_cuetext_token_t webvtt_cuetext_token;
typedef struct webvtt_start_token_data_t webvtt_start_token_data;
/**
* Enumerates token types.
*/
typedef enum {
START_TOKEN, /* Identifies a webvtt_cue_text_start_tag_token. */
END_TOKEN, /* Identifies a webvtt_cue_text_end_tag_token. */
TIME_STAMP_TOKEN, /* Identifies a webvtt_cue_text_time_stamp_token. */
TEXT_TOKEN /* Identifies a webvtt_cue_text_text_token. */
} webvtt_token_type;
/**
* Enumerates possible states that the cue text tokenizer can be in.
*/
typedef enum {
DATA, /* Initial state. */
ESCAPE, /* Parsing an escape value. */
TAG, /* Reached a '<' character, about to start parsing a tag. */
START_TAG, /* Parsing the beginning of a tag i.e. the tag name. */
START_TAG_CLASS, /* Parsing a tag class. Reached when the tokenizer in the
START_TAG
state reaches a '.' character. */
START_TAG_ANNOTATION, /* Parsing a tag annotation. Reached when the tokenizer
in the START_TAG_CLASS state reaches a TAB, SPACE, or
FORM FEED character. */
END_TAG, /* Parsing an end tag. Reached when a '<' character is follwed by a
'/' character. */
TIME_STAMP_TAG /* Parsing a time stamp tag. Reached when a '<' character is
follwed by an integer character. */
} webvtt_token_state;
/**
* Represents a start tag in the cue text.
* These take the form of <[TAG_NAME].[CLASSES] [POSSIBLE_ANNOTATION]> in the
* cue text.
*/
struct
webvtt_start_token_data_t {
webvtt_stringlist *css_classes;
webvtt_string annotations;
};
/**
* Contains a void pointer to a concrete token as well as a token type enum that
* identifies what kind of token it is.
*/
struct
webvtt_cuetext_token_t {
webvtt_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_start_token_data start_token_data;
};
};
/**
* Routines for creating cue text tokens.
* Sets the passed token to the new token.
*/
WEBVTT_INTERN webvtt_status
webvtt_create_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_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 );
/**
* Returns true if the passed tag matches a tag name that accepts an annotation.
*/
WEBVTT_INTERN int
tag_accepts_annotation( webvtt_string *tag_name );
/**
* Routines for deleting cue text tokens.
*/
WEBVTT_INTERN void
webvtt_delete_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_node_kind_from_tag_name( webvtt_string *tag_name,
webvtt_node_kind *kind );
/**
* Creates a node from a valid token.
* Returns WEBVTT_NOT_SUPPORTED if it does not find a valid tag name.
*/
WEBVTT_INTERN webvtt_status
webvtt_create_node_from_token( webvtt_cuetext_token *token, webvtt_node **node,
webvtt_node *parent );
/**
* Tokenizes the cue text into something that can be easily understood by the
* cue text parser.
* Referenced from - http://dev.w3.org/html5/webvtt/#webvtt-cue-text-tokenizer
*/
WEBVTT_INTERN webvtt_status
webvtt_tokenizer( const char **position, webvtt_cuetext_token **token );
/**
* Routines that take care of certain states in the webvtt cue text tokenizer.
*/
/**
* Referenced from http://dev.w3.org/html5/webvtt/#webvtt-data-state
*/
WEBVTT_INTERN webvtt_status
webvtt_data_state( const char **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_escape_state( const char **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_tag_state( const char **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_start_tag_state( const char **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_class_state( const char **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_annotation_state( const char **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_end_tag_state( const char **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_timestamp_state( const char **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 );
#endif

View File

@ -1,75 +0,0 @@
/**
* Copyright (c) 2013 Mozilla Foundation and Contributors
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <webvtt/error.h>
static const char *errstr[] = {
/* WEBVTT_ALLOCATION_FAILED */ "error allocating object",
/* WEBVTT_MALFORMED_TAG */ "malformed 'WEBVTT' tag",
/* WEBVTT_EXPECTED_EOL */ "expected newline",
/* WEBVTT_EXPECTED_WHITESPACE */ "expected whitespace",
/* WEBVTT_UNEXPECTED_WHITESPACE */ "unexpected whitespace",
/* WEBVTT_LONG_COMMENT */ "very long tag-comment",
/* WEBVTT_ID_TRUNCATED */ "webvtt-cue-id truncated",
/* WEBVTT_MALFORMED_TIMESTAMP */ "malformed webvtt-timestamp",
/* WEBVTT_EXPECTED_TIMESTAMP */ "expected webvtt-timestamp",
/* WEBVTT_MISSING_CUETIME_SEPARATOR */ "missing webvtt-cuetime-separator `-->'",
/* WEBVTT_EXPECTED_CUETIME_SEPARATOR */ "expected webvtt-cuetime-separator `-->'",
/* WEBVTT_MISSING_CUESETTING_DELIMITER */ "missing whitespace before webvtt-cuesetting",
/* WEBVTT_INVALID_CUESETTING_DELIMITER */ "invalid webvtt-cuesetting key:value delimiter. expected `:'",
/* WEBVTT_INVALID_ENDTIME */ "webvtt-cue end-time must have value greater than start-time",
/* WEBVTT_INVALID_CUESETTING */ "unrecognized webvtt-cue-setting",
/* WEBVTT_UNFINISHED_CUETIMES */ "unfinished webvtt cuetimes. expected 'start-timestamp --> end-timestamp'",
/* WEBVTT_MISSING_CUESETTING_KEYWORD */ "missing setting keyword for value",
/* WEBVTT_VERTICAL_ALREADY_SET */ "'vertical' cue-setting already used",
/* WEBVTT_VERTICAL_BAD_VALUE */ "'vertical' setting must have a value of either 'lr' or 'rl'",
/* WEBVTT_LINE_ALREADY_SET */ "'line' cue-setting already used",
/* WEBVTT_LINE_BAD_VALUE */ "'line' cue-setting must have a value that is an integer (signed) line number, or percentage (%) from top of video display",
/* WEBVTT_POSITION_ALREADY_SET */ "'position' cue-setting already used",
/* WEBVTT_POSITION_BAD_VALUE */ "'position' cue-setting must be a percentage (%) value representing the position in the direction orthogonal to the 'line' setting",
/* WEBVTT_SIZE_ALREADY_SET */ "'size' cue-setting already used",
/* WEBVTT_SIZE_BAD_VALUE */ "'size' cue-setting must have percentage (%) value",
/* WEBVTT_ALIGN_ALREADY_SET */ "'align' cue-setting already used",
/* WEBVTT_ALIGN_BAD_VALUE */ "'align' cue-setting must have a value of either 'start', 'middle', or 'end'",
/* WEBVTT_CUE_CONTAINS_SEPARATOR */ "cue-text line contains unescaped timestamp separator '-->'",
/* WEBVTT_CUE_INCOMPLETE */ "cue contains cue-id, but is missing cuetimes or cue text",
};
/**
* TODO:
* Add i18n localized error strings with support for glibc and msvcrt locale
* identifiers
* (This might be too much work!)
*/
WEBVTT_EXPORT const char *
webvtt_strerror( webvtt_error err )
{
if( err >= (sizeof(errstr) / sizeof(*errstr)) ) {
return "";
}
return errstr[ err ];
}

View File

@ -1,108 +0,0 @@
/**
* Copyright (c) 2013 Mozilla Foundation and Contributors
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __WEBVTT_CUE_H__
# define __WEBVTT_CUE_H__
# include "util.h"
# include <webvtt/string.h>
# include <webvtt/node.h>
#if defined(__cplusplus) || defined(c_plusplus)
#define WEBVTT_CPLUSPLUS 1
extern "C" {
#endif
#define WEBVTT_AUTO (0xFFFFFFFF)
typedef enum
webvtt_vertical_type_t {
WEBVTT_HORIZONTAL = 0,
WEBVTT_VERTICAL_LR = 1,
WEBVTT_VERTICAL_RL = 2
} webvtt_vertical_type;
typedef enum
webvtt_align_type_t {
WEBVTT_ALIGN_START = 0,
WEBVTT_ALIGN_MIDDLE,
WEBVTT_ALIGN_END,
WEBVTT_ALIGN_LEFT,
WEBVTT_ALIGN_RIGHT
} webvtt_align_type;
typedef struct
webvtt_cue_settings_t {
webvtt_vertical_type vertical;
int line;
webvtt_uint position;
webvtt_uint size;
webvtt_align_type align;
} webvtt_cue_settings;
typedef struct
webvtt_cue_t {
/**
* PRIVATE.
* Do not touch, okay?
*/
struct webvtt_refcount_t refs;
webvtt_uint flags;
/**
* PUBLIC:
*/
webvtt_timestamp from;
webvtt_timestamp until;
webvtt_cue_settings settings;
webvtt_bool snap_to_lines;
webvtt_string id;
webvtt_string body;
/**
* Parsed cue-text (NULL if has not been parsed)
*/
webvtt_node *node_head;
} webvtt_cue;
WEBVTT_EXPORT webvtt_status
webvtt_create_cue( webvtt_cue **pcue );
WEBVTT_EXPORT void
webvtt_ref_cue( webvtt_cue *cue );
WEBVTT_EXPORT void
webvtt_release_cue( webvtt_cue **pcue );
WEBVTT_EXPORT int
webvtt_validate_cue( webvtt_cue *cue );
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
#endif

View File

@ -1,113 +0,0 @@
/**
* Copyright (c) 2013 Mozilla Foundation and Contributors
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __WEBVTT_ERROR_H__
# define __WEBVTT_ERROR_H__
# include "util.h"
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
enum
webvtt_error_t
{
/* There was a problem allocating something */
WEBVTT_ALLOCATION_FAILED = 0,
/**
* 'WEBVTT' is not the first 6 characters in the file
* (not counting UTF8 BOM)
*/
WEBVTT_MALFORMED_TAG,
/* An end-of-line sequence was expected, but not found. */
WEBVTT_EXPECTED_EOL,
/* A string of whitespace was expected, but not found. */
WEBVTT_EXPECTED_WHITESPACE,
/**
* A string of whitespace was found, but was not expected
* (Recoverable error)
*/
WEBVTT_UNEXPECTED_WHITESPACE,
/* Long WEBVTT comment, decide whether to abort parsing or not */
WEBVTT_LONG_COMMENT,
/* A cue-id was too long to fit in the buffer. */
WEBVTT_ID_TRUNCATED,
/* A timestamp is malformed */
WEBVTT_MALFORMED_TIMESTAMP,
/* Expected a timestamp, but didn't find one */
WEBVTT_EXPECTED_TIMESTAMP,
/* Missing timestamp separator */
WEBVTT_MISSING_CUETIME_SEPARATOR,
/* Were expecting a separator, but got some garbage that we can't
recover from instead. */
WEBVTT_EXPECTED_CUETIME_SEPARATOR,
/* Missing cuesetting delimiter */
WEBVTT_MISSING_CUESETTING_DELIMITER,
/* Invalid cuesetting delimiter */
WEBVTT_INVALID_CUESETTING_DELIMITER,
/* End-time is less than or equal to start time */
WEBVTT_INVALID_ENDTIME,
/* Invalid cue-setting */
WEBVTT_INVALID_CUESETTING,
/* unfinished cuetimes */
WEBVTT_UNFINISHED_CUETIMES,
/* valid-looking cuesetting with no keyword */
WEBVTT_MISSING_CUESETTING_KEYWORD,
/* 'vertical' setting already exists for this cue. */
WEBVTT_VERTICAL_ALREADY_SET,
/* Bad 'vertical' value */
WEBVTT_VERTICAL_BAD_VALUE,
/* 'line' setting already exists for this cue. */
WEBVTT_LINE_ALREADY_SET,
/* Bad 'line' value */
WEBVTT_LINE_BAD_VALUE,
/* 'position' setting already exists for this cue. */
WEBVTT_POSITION_ALREADY_SET,
/* Bad 'position' value */
WEBVTT_POSITION_BAD_VALUE,
/* 'size' setting already exists for this cue. */
WEBVTT_SIZE_ALREADY_SET,
/* Bad 'size' value */
WEBVTT_SIZE_BAD_VALUE,
/* 'align' setting already exists for this cue. */
WEBVTT_ALIGN_ALREADY_SET,
/* Bad 'align' value */
WEBVTT_ALIGN_BAD_VALUE,
/* A cue-text object contains the string "-->", which needs to be escaped */
WEBVTT_CUE_CONTAINS_SEPARATOR,
/* A webvtt cue contains only a cue-id, and no cuetimes or payload. */
WEBVTT_CUE_INCOMPLETE,
};
typedef enum webvtt_error_t webvtt_error;
WEBVTT_EXPORT const char *webvtt_strerror( webvtt_error );
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
#endif

View File

@ -1,135 +0,0 @@
/**
* 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,
WEBVTT_LANG = 7 | 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 = 8,
WEBVTT_NODE_INTERNAL_END = 8,
/**
* 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_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_string lang;
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

View File

@ -1,69 +0,0 @@
/**
* Copyright (c) 2013 Mozilla Foundation and Contributors
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __WEBVTT_PARSER_H__
# define __WEBVTT_PARSER_H__
# include "string.h"
# include "cue.h"
# include "error.h"
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
typedef struct webvtt_parser_t *webvtt_parser;
/**
* Allows application to request error reporting
*/
typedef int ( WEBVTT_CALLBACK *webvtt_error_fn )( void *userdata,
webvtt_uint line,
webvtt_uint col,
webvtt_error error );
typedef void ( WEBVTT_CALLBACK *webvtt_cue_fn )( void *userdata,
webvtt_cue *cue );
WEBVTT_EXPORT webvtt_status
webvtt_create_parser( webvtt_cue_fn on_read, webvtt_error_fn on_error,
void * userdata, webvtt_parser *ppout );
WEBVTT_EXPORT void
webvtt_delete_parser( webvtt_parser parser );
WEBVTT_EXPORT webvtt_status
webvtt_parse_chunk( webvtt_parser self, const void *buffer, webvtt_uint len );
WEBVTT_EXPORT webvtt_status
webvtt_finish_parsing( webvtt_parser self );
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
#endif

View File

@ -1,331 +0,0 @@
/**
* Copyright (c) 2013 Mozilla Foundation and Contributors
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __WEBVTT_STRING_H__
# define __WEBVTT_STRING_H__
# include "util.h"
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
/**
* webvtt_string - A buffer of utf16 characters
*/
typedef struct webvtt_string_t webvtt_string;
typedef struct webvtt_string_data_t webvtt_string_data;
typedef struct webvtt_stringlist_t webvtt_stringlist;
struct webvtt_string_data_t;
struct
webvtt_string_t {
webvtt_string_data *d;
};
/**
* webvtt_init_string
*
* initialize a string to point to the empty string
*/
WEBVTT_EXPORT void
webvtt_init_string( webvtt_string *result );
/**
* webvtt_string_is_empty
*
* return whether or not the string is empty
* qualifications for it being empty are it equaling &empty_string or its
* length equaling 0
*/
WEBVTT_EXPORT webvtt_uint
webvtt_string_is_empty( const webvtt_string *str );
/**
* webvtt_create_string
*
* allocate a new string object with an initial capacity of 'alloc'
* (the string data of 'result' is not expected to contain string data,
* regardless of its value. be sure to release existing strings before using
* webvtt_create_string)
*/
WEBVTT_EXPORT webvtt_status
webvtt_create_string( webvtt_uint32 alloc, webvtt_string *result );
/**
* webvtt_create_init_string
*
* allocate and initialize a string with the contents of 'init_text' of length
* 'len' if 'len' < 0, assume init_text to be null-terminated.
*/
WEBVTT_EXPORT webvtt_status
webvtt_create_string_with_text( webvtt_string *out, const char *init_text,
int len );
/**
* webvtt_ref_string
*
* increase the reference count of--or retain--a string
*
* when the reference count drops to zero, the string is deallocated.
*/
WEBVTT_EXPORT void
webvtt_ref_string( webvtt_string *str );
/**
* webvtt_release_string
*
* decrease the reference count of--or release--a string
*
* when the reference count drops to zero, the string is deallocated.
*/
WEBVTT_EXPORT void
webvtt_release_string( webvtt_string *str );
/**
* webvtt_string_detach
*
* ensure that the reference count of a string is exactly 1
*
* if the reference count is greater than 1, allocate a new copy of the string
* and return it.
*/
WEBVTT_EXPORT webvtt_status
webvtt_string_detach( webvtt_string *str );
/**
* webvtt_copy_string
*
* shallow-clone 'right', storing the result in 'left'.
*/
WEBVTT_EXPORT void
webvtt_copy_string( webvtt_string *left, const webvtt_string *right );
/**
* webvtt_string_text
*
* return the text contents of a string
*/
WEBVTT_EXPORT const char *
webvtt_string_text( const webvtt_string *str );
/**
* webvtt_string_length
*
* return the length of a strings text
*/
WEBVTT_EXPORT webvtt_uint32
webvtt_string_length( const webvtt_string *str );
/**
* webvtt_string_capacity
*
* return the current capacity of a string
*/
WEBVTT_EXPORT webvtt_uint32
webvtt_string_capacity( const webvtt_string *str );
/**
* webvtt_string_getline
*
* collect a line of text (terminated by CR/LF/CRLF) from a buffer, without
* including the terminating character(s)
*/
WEBVTT_EXPORT int
webvtt_string_getline( webvtt_string *str, const char *buffer,
webvtt_uint *pos, int len, int *truncate,
webvtt_bool finish );
/**
* webvtt_string_putc
*
* append a single byte to a webvtt string
*/
WEBVTT_EXPORT webvtt_status
webvtt_string_putc( webvtt_string *str, char to_append );
/**
* webvtt_string_replace
*
* replace first instance of substring with replacement string.
*/
WEBVTT_EXPORT webvtt_status
webvtt_string_replace( webvtt_string *str, const char *search, int search_len,
const char *replace, int replace_len );
/**
* webvtt_string_replace_all
*
* replace all instances of substring with replacement string
*/
WEBVTT_EXPORT webvtt_status
webvtt_string_replace_all( webvtt_string *str, const char *search,
int search_len, const char *replace,
int replace_len );
/**
* webvtt_string_is_equal
*
* compare a string's text to a byte array
*
*/
WEBVTT_EXPORT webvtt_bool
webvtt_string_is_equal( const webvtt_string *str, const char *to_compare,
int len );
/**
* webvtt_string_append
*
* append a stream of bytes to the string.
*
* if 'len' is < 0, then buffer is expected to be null-terminated.
*/
WEBVTT_EXPORT webvtt_status
webvtt_string_append( webvtt_string *str, const char *buffer, int len );
/**
* webvtt_string_appendstr
*
* if 'len' is < 0 then the max length of the string will be taken to be the
* first occurence of a null byte character
*/
WEBVTT_EXPORT webvtt_status
webvtt_string_append_string( webvtt_string *str, const webvtt_string *other );
/**
* basic dynamic array of strings
*/
struct
webvtt_stringlist_t {
struct webvtt_refcount_t refs;
webvtt_uint alloc;
webvtt_uint length;
webvtt_string *items;
};
/**
* webvtt_create_stringlist
*
* allocate a new, empty stringlist
*/
WEBVTT_EXPORT webvtt_status
webvtt_create_stringlist( webvtt_stringlist **result );
/**
* webvtt_ref_stringlist
*
* Increase the ref count of the stringlist
*/
WEBVTT_EXPORT void
webvtt_ref_stringlist( webvtt_stringlist *list );
/**
* webvtt_copy_stringlist
*
* create a copy shallow of right from left
*/
WEBVTT_EXPORT void
webvtt_copy_stringlist( webvtt_stringlist **left, webvtt_stringlist *right );
/**
* webvtt_release_stringlist
*
* Decrease the ref count of the stringlist and delete it if the ref count is 0
*/
WEBVTT_EXPORT void
webvtt_release_stringlist( webvtt_stringlist **list );
/**
* webvtt_stringlist_push
*
* add a new string to the end of the stringlist
*/
WEBVTT_EXPORT webvtt_status
webvtt_stringlist_push( webvtt_stringlist *list, webvtt_string *str );
/**
* webvtt_stringlist_pop
*
* pop the top of the string list
*/
WEBVTT_EXPORT webvtt_bool
webvtt_stringlist_pop( webvtt_stringlist *list, webvtt_string *out );
/**
* Helper functions
*/
/**
* webvtt_next_utf8
*
* move the 'begin' pointer to the beginning of the next utf8 character
* sequence.
*/
WEBVTT_EXPORT webvtt_bool
webvtt_next_utf8( const char **begin, const char *end );
/**
* webvtt_skip_utf8
*
* move the 'begin' pointer to the beginning of the utf8 character
* 'n_chars' away.
*
* if 'end' is less than 'begin', will seek backwards.
*/
WEBVTT_EXPORT webvtt_bool
webvtt_skip_utf8( const char **begin, const char *end, int n_chars );
/**
* webvtt_utf8_to_utf16
*
* return the utf16 value of a given character
*/
WEBVTT_EXPORT webvtt_uint16
webvtt_utf8_to_utf16( const char *utf8, const char *end, webvtt_uint16 *high );
/**
* webvtt_utf8_chcount
*
* return the number of Unicode characters (as opposed to units)
* in a utf8 string
*/
WEBVTT_EXPORT int
webvtt_utf8_chcount( const char *utf8, const char *end );
/**
* webvtt_utf8_length
*
* if 'utf8' points to a lead byte, return the length of the sequence.
* if 'utf8' is null, return 0.
* if 'utf8' points to a trail byte, return -1
*/
WEBVTT_EXPORT int
webvtt_utf8_length( const char *utf8 );
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
#endif

View File

@ -1,269 +0,0 @@
/**
* Copyright (c) 2013 Mozilla Foundation and Contributors
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __WEBVTT_UTIL_H__
# define __WEBVTT_UTIL_H__
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
/**
* Assuming that libc provides stdint.h unless we have a good reason to believe
* it doesn't... MSVC does not ship stdint.h prior to MSVC2010.
*/
# if !defined(_MSC_VER) || _MSC_VER >= 1600
# define WEBVTT_HAVE_STDINT 1
# include <stdint.h>
# endif
# if defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) || \
defined(__WINDOWS__)
# define WEBVTT_OS_WIN32 1
# if defined(_WIN64)
# define WEBVTT_OS_WIN64 1
# endif
# endif
# if defined(_MSC_VER)
# define WEBVTT_CC_MSVC 1
# define WEBVTT_CALLBACK __cdecl
# if WEBVTT_BUILD_LIBRARY
# define WEBVTT_EXPORT __declspec(dllexport)
# elif !WEBVTT_STATIC
# define WEBVTT_EXPORT __declspec(dllimport)
# else
# define WEBVTT_EXPORT
# endif
# elif defined(__GNUC__)
# define WEBVTT_CC_GCC 1
# if WEBVTT_OS_WIN32
# if WEBVTT_BUILD_LIBRARY
# define WEBVTT_EXPORT __declspec(dllexport)
# elif !WEBVTT_STATIC
# define WEBVTT_EXPORT __declspec(dllimport)
# else
# define WEBVTT_EXPORT
# endif
# else
# if __GNUC__ >= 4
# define WEBVTT_EXPORT __attribute__((visibility("default")))
# define WEBVTT_INTERN __attribute__((visibility("hidden")))
# endif
# endif
# else
# define WEBVTT_CC_UNKNOWN 1
# endif
# ifndef WEBVTT_HAVE_STDINT
# define WEBVTT_HAVE_STDINT 0
# endif
# ifndef WEBVTT_CALLBACK
# define WEBVTT_CALLBACK
# endif
# ifndef WEBVTT_EXPORT
# define WEBVTT_EXPORT
# endif
# ifndef WEBVTT_INTERN
# define WEBVTT_INTERN
# endif
# if defined(__cplusplus) || defined(c_plusplus)
# define WEBVTT_INLINE inline
# elif WEBVTT_CC_MSVC
# define WEBVTT_INLINE __inline
# elif WEBVTT_CC_GCC
# define WEBVTT_INLINE __inline__
# endif
# if WEBVTT_HAVE_STDINT
typedef int8_t webvtt_int8;
typedef int16_t webvtt_int16;
typedef int32_t webvtt_int32;
typedef int64_t webvtt_int64;
typedef uint8_t webvtt_uint8;
typedef uint16_t webvtt_uint16;
typedef uint32_t webvtt_uint32;
typedef uint64_t webvtt_uint64;
# elif defined(_MSC_VER)
typedef signed __int8 webvtt_int8;
typedef signed __int16 webvtt_int16;
typedef signed __int32 webvtt_int32;
typedef signed __int64 webvtt_int64;
typedef unsigned __int8 webvtt_uint8;
typedef unsigned __int16 webvtt_uint16;
typedef unsigned __int32 webvtt_uint32;
typedef unsigned __int64 webvtt_uint64;
# elif WEBVTT_CC_UNKNOWN
# warning "Unknown compiler. Compiler specific int-types probably broken!"
typedef signed char webvtt_int8;
typedef signed short webvtt_int16;
typedef signed long webvtt_int32;
typedef signed long long webvtt_int64;
typedef unsigned char webvtt_uint8;
typedef unsigned short webvtt_uint16;
typedef unsigned long webvtt_uint32;
typedef unsigned long long webvtt_uint64;
# endif
typedef signed int webvtt_int;
typedef signed char webvtt_char;
typedef signed short webvtt_short;
typedef signed long webvtt_long;
typedef signed long long webvtt_longlong;
typedef unsigned int webvtt_uint;
typedef unsigned char webvtt_uchar;
typedef unsigned short webvtt_ushort;
typedef unsigned long webvtt_ulong;
typedef unsigned long long webvtt_ulonglong;
typedef webvtt_int webvtt_bool;
typedef webvtt_uint32 webvtt_length;
typedef webvtt_uint64 webvtt_timestamp;
/**
* Memory allocation callbacks, which allow overriding the allocation
* strategy.
*/
typedef void *(WEBVTT_CALLBACK *webvtt_alloc_fn_ptr)( void *userdata,
webvtt_uint nbytes );
typedef void (WEBVTT_CALLBACK *webvtt_free_fn_ptr)( void *userdata,
void *pmem );
/**
* Allocation functions. webvtt_set_allocator() should really be the first
* function called. However, it will do nothing (and not report error) if
* objects have already been allocated and not freed. Therefore, it is NOT
* safe to assume that it worked and use the supplied
* function pointers directly.
*
* Currently, set_allocator (and the other allocation functions) do not use
* any locking mechanism, so the library cannot be considered to be
* thread-safe at this time if changing the allocator is used.
*
* I don't believe there is much of a reason to worry about the overhead of
* using function pointers for allocation, as it is negligible compared to the
* act of allocating memory itself, and having a configurable allocation
* strategy could be very useful.
*/
WEBVTT_EXPORT void *webvtt_alloc( webvtt_uint nb );
WEBVTT_EXPORT void *webvtt_alloc0( webvtt_uint nb );
WEBVTT_EXPORT void webvtt_free( void *data );
WEBVTT_EXPORT void webvtt_set_allocator( webvtt_alloc_fn_ptr alloc,
webvtt_free_fn_ptr free,
void *userdata );
enum
webvtt_status_t {
WEBVTT_SUCCESS = 0,
WEBVTT_UNFINISHED = -1,
WEBVTT_PARSE_ERROR = -2,
WEBVTT_OUT_OF_MEMORY = -3,
WEBVTT_INVALID_PARAM = -4,
WEBVTT_NOT_SUPPORTED = -5,
WEBVTT_UNSUCCESSFUL = -6,
WEBVTT_INVALID_TAG_NAME = -7,
WEBVTT_INVALID_TOKEN_TYPE = -8,
WEBVTT_INVALID_TOKEN_STATE = -9,
WEBVTT_FAIL = -10, /* This is not very specific! */
/**
* A failure that requires the parser to completely skip beyond a cue.
*/
WEBVTT_SKIP_CUE = -11,
/**
* Parser should move to the next cuesetting.
*/
WEBVTT_NEXT_CUESETTING = -12,
/*
* 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;
/**
* Macros to filter out webvtt status returns.
*/
# define WEBVTT_FAILED(status) ( (status) != WEBVTT_SUCCESS )
struct
webvtt_refcount_t {
# if WEBVTT_OS_WIN32
/**
* 'long' on windows in order to coincide with
* the _Interlocked compiler intrinsics on win32
*/
long value;
# else
int value;
# endif
};
# ifdef WEBVTT_REF_INIT
# undef WEBVTT_REF_INIT
# endif
# define WEBVTT_REF_INIT(Value) { (Value) }
/**
* TODO: Replace these with atomic instructions for systems that provide it
*/
# ifndef WEBVTT_ATOMIC_INC
# define WEBVTT_ATOMIC_INC(x) ( ++(x) )
# endif
# ifndef WEBVTT_ATOMIC_DEC
# define WEBVTT_ATOMIC_DEC(x) ( --(x) )
# endif
# if defined(WEBVTT_INLINE)
static WEBVTT_INLINE int webvtt_ref( struct webvtt_refcount_t *ref )
{
return WEBVTT_ATOMIC_INC(ref->value);
}
static WEBVTT_INLINE int webvtt_deref( struct webvtt_refcount_t *ref )
{
return WEBVTT_ATOMIC_DEC(ref->value);
}
# else
# define webvtt_inc_ref(ref) ( WEBVTT_ATOMIC_INC((ref)->value) )
# define webvtt_dec_ref(ref) ( WEBVTT_ATOMIC_DEC((ref)->value) )
# endif
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
#endif

View File

@ -1,694 +0,0 @@
/**
* Copyright (c) 2013 Mozilla Foundation and Contributors
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "parser_internal.h"
/**
* There are probably enough jumps and stack pops here to fill up quite a few
* caches but it may still
* be much smaller than a gigantic table-based solution.
*
* TODO: Replace all char literals with hex values, just in case compiling on a
* machine which uses an
* incompatible character set
*/
#define U_DIGIT case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: \
case 0x35: case 0x36: case 0x37: case 0x38: case 0x39:
#define U_WHITESPACE case 0x0D: case 0x0A: case 0x20: case 0x09:
#define U_SPACE case 0x20:
#define U_TAB case 0x09:
#define U_CR case 0x0D:
#define U_LF case 0x0A:
#define U_DASH case 0x2D:
#define U_PERIOD case 0x2E:
#define U_GT case 0x3E:
#define U_COLON case 0x3A:
#define U_PERCENT case 0x25:
#define U_0 case 0x30:
#define U_1 case 0x31:
#define U_2 case 0x32:
#define U_3 case 0x33:
#define U_4 case 0x34:
#define U_5 case 0x35:
#define U_6 case 0x36:
#define U_7 case 0x37:
#define U_8 case 0x38:
#define U_9 case 0x39:
#define U_a case 0x61:
#define U_b case 0x62:
#define U_c case 0x63:
#define U_d case 0x64:
#define U_e case 0x65:
#define U_f case 0x66:
#define U_g case 0x67:
#define U_h case 0x68:
#define U_i case 0x69:
#define U_j case 0x6A:
#define U_k case 0x6B:
#define U_l case 0x6C:
#define U_m case 0x6D:
#define U_n case 0x6E:
#define U_o case 0x6F:
#define U_p case 0x70:
#define U_q case 0x71:
#define U_r case 0x72:
#define U_s case 0x73:
#define U_t case 0x74:
#define U_u case 0x75:
#define U_v case 0x76:
#define U_w case 0x77:
#define U_x case 0x78:
#define U_y case 0x79:
#define U_z case 0x7A:
#define U_A case 0x41:
#define U_B case 0x42:
#define U_C case 0x43:
#define U_D case 0x44:
#define U_E case 0x45:
#define U_F case 0x46:
#define U_G case 0x47:
#define U_H case 0x48:
#define U_I case 0x49:
#define U_J case 0x4A:
#define U_K case 0x4B:
#define U_L case 0x4C:
#define U_M case 0x4D:
#define U_N case 0x4E:
#define U_O case 0x4F:
#define U_P case 0x50:
#define U_Q case 0x51:
#define U_R case 0x52:
#define U_S case 0x53:
#define U_T case 0x54:
#define U_U case 0x55:
#define U_V case 0x56:
#define U_W case 0x57:
#define U_X case 0x58:
#define U_Y case 0x59:
#define U_Z case 0x5A:
#define U_BOM0 case 0xEF:
#define U_BOM1 case 0xBB:
#define U_BOM2 case 0xBF:
#define DEFAULT default:
/**
* Just for semantic clarity
*/
#define OR
#define AND
#define IF_OVERFLOW(X) \
if( self->token_pos >= (sizeof(self->token) - 1 ) ) \
{ \
RETURN(X) \
}
#define BEGIN_STATE(state) case state: { switch(c) {
#define END_STATE DEFAULT BACKUP return BADTOKEN; } } break;
#define END_STATE_EX } } break;
#define SET_STATE(X) self->tstate = X; break;
#define RETURN(X) self->tstate = L_START; return X;
#define SET_NEWLINE self->line++; self->column = 1; RETURN(NEWLINE)
#define CONTINUE continue;
#define BREAK break;
#define BACKUP (*pos)--; \
--self->column; \
self->token[--self->token_pos] = 0; \
self->tstate = L_START;
#define RESET self->column = 1; \
self->bytes = self->token_pos = 0; \
self->tstate = L_START;
#define CHECK_BROKEN_TIMESTAMP \
if(self->token_pos == sizeof(self->token) - 1 ) \
{ \
ERROR(WEBVTT_MALFORMED_TIMESTAMP); \
return BADTOKEN; \
}
WEBVTT_INTERN webvtt_status
webvtt_lex_word( webvtt_parser self, webvtt_string *str, const char *buffer,
webvtt_uint *ppos, webvtt_uint length, webvtt_bool finish )
{
webvtt_status status = WEBVTT_SUCCESS;
webvtt_uint pos = *ppos;
if( !str ) {
return WEBVTT_INVALID_PARAM;
}
webvtt_init_string( str );
# define ASCII_DASH (0x2D)
# define ASCII_GT (0x3E)
while( pos < length ) {
webvtt_uint last_bytes = self->bytes;
webvtt_uint last_line = self->line;
webvtt_uint last_column = self->column;
webvtt_uint last_pos = pos;
webvtt_token token = webvtt_lex(self, buffer, &pos, length, finish );
if( token == BADTOKEN ) {
if( WEBVTT_FAILED( status = webvtt_string_putc( str, buffer[pos] ) ) ) {
webvtt_release_string( str );
goto _finished;
}
++pos;
} else {
pos = last_pos;
self->bytes = last_bytes;
self->line = last_line;
self->column = last_column;
goto _finished;
}
}
_finished:
*ppos = pos;
return status;
}
/**
* webvtt_lex_newline
*
* Get newline sequence in re-entrant fashion. self->tstate must be
* L_START or L_NEWLINE0 for this function to behave correctly.
*/
WEBVTT_INTERN webvtt_token
webvtt_lex_newline( webvtt_parser self, const
char *buffer, webvtt_uint *pos, webvtt_uint length,
webvtt_bool finish )
{
webvtt_uint p = *pos;
/* Ensure that we've got a valid token-state for this use-case. */
DIE_IF( self->tstate != L_START && self->tstate != L_NEWLINE0 );
while( p < length ) {
unsigned char c = (unsigned char)buffer[ p++ ];
self->token[ self->token_pos++ ] = c;
self->token[ self->token_pos ] = 0;
self->bytes++;
switch( self->tstate ) {
case L_START:
if( c == '\n' ) {
*pos = p;
return NEWLINE;
} else if( c == '\r' ) {
self->tstate = L_NEWLINE0;
} else {
goto backup;
}
break;
case L_NEWLINE0:
if( c == '\n' ) {
*pos = p;
self->tstate = L_START;
return NEWLINE;
} else {
goto backup;
}
break;
default:
/**
* This should never happen if the function is called correctly
* (EG immediately following a successful call to webvtt_string_getline)
*/
goto backup;
}
}
*pos = p;
if( finish && ( p >= length ) ) {
/* If pos >= length, it's and 'finish' is set, it's an automatic EOL */
self->tstate = L_START;
return NEWLINE;
}
if( self->tstate == L_NEWLINE0 ) {
return UNFINISHED;
} else {
/* This branch should never occur, if the function is used properly. */
*pos = --p;
return BADTOKEN;
}
backup:
self->token[ --self->token_pos ] = 0;
--self->bytes;
*pos = --p;
if( self->tstate == L_NEWLINE0 ) {
self->tstate = L_START;
return NEWLINE;
}
return BADTOKEN;
}
WEBVTT_INTERN webvtt_token
webvtt_lex( webvtt_parser self, const char *buffer, webvtt_uint *pos,
webvtt_uint length, webvtt_bool finish )
{
while( *pos < length ) {
unsigned char c = (unsigned char)buffer[(*pos)++];
self->token[ self->token_pos++ ] = c;
self->token[ self->token_pos ] = 0;
self->column++;
self->bytes++;
switch( self->tstate ) {
BEGIN_STATE(L_START)
U_DIGIT { SET_STATE(L_DIGIT0) }
U_W { SET_STATE(L_WEBVTT0) }
U_DASH { SET_STATE(L_DASH0) }
U_BOM0 { SET_STATE(L_BOM0) }
U_LF { SET_NEWLINE }
U_CR { SET_STATE(L_NEWLINE0) }
U_SPACE OR U_TAB { SET_STATE(L_WHITESPACE) }
U_PERIOD { RETURN(FULL_STOP) }
U_COLON { RETURN(COLON) }
U_p { SET_STATE(L_POSITION0) }
U_a { SET_STATE(L_ALIGN0) }
U_l { SET_STATE(L_L0) }
U_v { SET_STATE(L_VERTICAL0) }
U_r { SET_STATE(L_RL0) }
U_s { SET_STATE(L_S0) }
U_m { SET_STATE(L_MIDDLE0) }
U_e { SET_STATE(L_END0) }
U_N { SET_STATE(L_NOTE1) }
END_STATE
BEGIN_STATE(L_BOM0)
U_BOM1 { SET_STATE(L_BOM1) }
END_STATE
BEGIN_STATE(L_BOM1)
U_BOM2 {
if( self->bytes == 3 ) {
RESET
BREAK
}
RETURN(BOM)
}
END_STATE
BEGIN_STATE(L_WEBVTT0)
U_E { SET_STATE(L_WEBVTT1) }
END_STATE
BEGIN_STATE(L_WEBVTT1)
U_B { SET_STATE(L_WEBVTT2) }
END_STATE
BEGIN_STATE(L_WEBVTT2)
U_V { SET_STATE(L_WEBVTT3) }
END_STATE
BEGIN_STATE(L_WEBVTT3)
U_T { SET_STATE(L_WEBVTT4) }
END_STATE
BEGIN_STATE(L_WEBVTT4)
U_T { RETURN(WEBVTT) }
END_STATE
BEGIN_STATE(L_DASH0)
U_DIGIT { SET_STATE(L_DIGIT0) }
U_DASH { SET_STATE(L_SEP1) }
END_STATE
BEGIN_STATE(L_SEP1)
U_GT { RETURN(SEPARATOR) }
END_STATE
BEGIN_STATE(L_DIGIT0)
U_DIGIT {
IF_OVERFLOW(INTEGER)
SET_STATE(L_DIGIT0)
}
U_COLON {
/* Don't return a TIMESTAMP if we start with '-' */
if( self->token[0] == '-' ) {
RETURN(INTEGER);
} else {
SET_STATE(L_TIMESTAMP1)
}
}
U_PERCENT { RETURN(PERCENTAGE) }
DEFAULT { BACKUP AND RETURN(INTEGER) }
END_STATE_EX
BEGIN_STATE(L_NEWLINE0)
U_LF { SET_NEWLINE }
DEFAULT { BACKUP AND SET_NEWLINE }
END_STATE_EX
BEGIN_STATE(L_WHITESPACE)
U_SPACE OR U_TAB { IF_OVERFLOW(WHITESPACE) SET_STATE(L_WHITESPACE) }
DEFAULT { BACKUP RETURN(WHITESPACE) }
END_STATE_EX
BEGIN_STATE(L_POSITION0)
U_o { SET_STATE(L_POSITION1) }
END_STATE
BEGIN_STATE(L_POSITION1)
U_s { SET_STATE(L_POSITION2) }
END_STATE
BEGIN_STATE(L_POSITION2)
U_i { SET_STATE(L_POSITION3) }
END_STATE
BEGIN_STATE(L_POSITION3)
U_t { SET_STATE(L_POSITION4) }
END_STATE
BEGIN_STATE(L_POSITION4)
U_i { SET_STATE(L_POSITION5) }
END_STATE
BEGIN_STATE(L_POSITION5)
U_o { SET_STATE(L_POSITION6) }
END_STATE
BEGIN_STATE(L_POSITION6)
U_n { RETURN(POSITION) }
END_STATE
BEGIN_STATE(L_ALIGN0)
U_l { SET_STATE(L_ALIGN1) }
END_STATE
BEGIN_STATE(L_ALIGN1)
U_i { SET_STATE(L_ALIGN2) }
END_STATE
BEGIN_STATE(L_ALIGN2)
U_g { SET_STATE(L_ALIGN3) }
END_STATE
BEGIN_STATE(L_ALIGN3)
U_n { RETURN(ALIGN) }
END_STATE
BEGIN_STATE(L_L0)
U_r { RETURN(LR) }
U_i { SET_STATE(L_LINE1) }
U_e { SET_STATE(L_LEFT1) }
END_STATE
BEGIN_STATE(L_LINE1)
U_n { SET_STATE(L_LINE2) }
END_STATE
BEGIN_STATE(L_LINE2)
U_e { RETURN(LINE) }
END_STATE
BEGIN_STATE(L_LEFT1)
U_f { SET_STATE(L_LEFT2) }
END_STATE
BEGIN_STATE(L_LEFT2)
U_t { RETURN(LEFT) }
END_STATE
BEGIN_STATE(L_VERTICAL0)
U_e { SET_STATE(L_VERTICAL1) }
END_STATE
BEGIN_STATE(L_VERTICAL1)
U_r { SET_STATE(L_VERTICAL2) }
END_STATE
BEGIN_STATE(L_VERTICAL2)
U_t { SET_STATE(L_VERTICAL3) }
END_STATE
BEGIN_STATE(L_VERTICAL3)
U_i { SET_STATE(L_VERTICAL4) }
END_STATE
BEGIN_STATE(L_VERTICAL4)
U_c { SET_STATE(L_VERTICAL5) }
END_STATE
BEGIN_STATE(L_VERTICAL5)
U_a { SET_STATE(L_VERTICAL6) }
END_STATE
BEGIN_STATE(L_VERTICAL6)
U_l { RETURN(VERTICAL) }
END_STATE
BEGIN_STATE(L_RL0)
U_l { RETURN(RL) }
U_i { SET_STATE(L_RIGHT1) }
END_STATE
BEGIN_STATE(L_RIGHT1)
U_g { SET_STATE(L_RIGHT2) }
END_STATE
BEGIN_STATE(L_RIGHT2)
U_h { SET_STATE(L_RIGHT3) }
END_STATE
BEGIN_STATE(L_RIGHT3)
U_t { RETURN(RIGHT) }
END_STATE
BEGIN_STATE(L_S0)
U_t { SET_STATE(L_START1) }
U_i { SET_STATE(L_SIZE1) }
END_STATE
BEGIN_STATE(L_SIZE1)
U_z { SET_STATE(L_SIZE2) }
END_STATE
BEGIN_STATE(L_SIZE2)
U_e { RETURN(SIZE) }
END_STATE
BEGIN_STATE(L_START1)
U_a { SET_STATE(L_START2) }
END_STATE
BEGIN_STATE(L_START2)
U_r { SET_STATE(L_START3) }
END_STATE
BEGIN_STATE(L_START3)
U_t { RETURN(START) }
END_STATE
BEGIN_STATE(L_MIDDLE0)
U_i { SET_STATE(L_MIDDLE1) }
END_STATE
BEGIN_STATE(L_MIDDLE1)
U_d { SET_STATE(L_MIDDLE2) }
END_STATE
BEGIN_STATE(L_MIDDLE2)
U_d { SET_STATE(L_MIDDLE3) }
END_STATE
BEGIN_STATE(L_MIDDLE3)
U_l { SET_STATE(L_MIDDLE4) }
END_STATE
BEGIN_STATE(L_MIDDLE4)
U_e { RETURN(MIDDLE) }
END_STATE
BEGIN_STATE(L_END0)
U_n { SET_STATE(L_END1) }
END_STATE
BEGIN_STATE(L_END1)
U_d { RETURN(END) }
END_STATE
BEGIN_STATE(L_TIMESTAMP1)
U_DIGIT {
IF_OVERFLOW(BADTOKEN)
SET_STATE(L_TIMESTAMP1)
}
U_COLON {
IF_OVERFLOW(BADTOKEN)
SET_STATE(L_TIMESTAMP2)
}
U_PERIOD {
IF_OVERFLOW(BADTOKEN)
SET_STATE(L_TIMESTAMP3)
}
END_STATE
BEGIN_STATE(L_TIMESTAMP2)
U_DIGIT {
IF_OVERFLOW(BADTOKEN)
SET_STATE(L_TIMESTAMP2)
}
U_PERIOD {
IF_OVERFLOW(BADTOKEN)
SET_STATE(L_TIMESTAMP3)
}
END_STATE
BEGIN_STATE(L_TIMESTAMP3)
U_DIGIT {
IF_OVERFLOW(TIMESTAMP)
BREAK
}
DEFAULT {
BACKUP
/* Don't return a TIMESTAMP if we don't have at least one
millisecond */
if( !webvtt_isdigit( self->token[ self->token_pos - 1 ] ) ) {
RETURN(BADTOKEN);
}
RETURN(TIMESTAMP)
BREAK
}
END_STATE_EX
BEGIN_STATE(L_NOTE1)
U_O { SET_STATE(L_NOTE2) }
END_STATE
BEGIN_STATE(L_NOTE2)
U_T { SET_STATE(L_NOTE3) }
END_STATE
BEGIN_STATE(L_NOTE3)
U_E { RETURN(NOTE) }
END_STATE
}
}
/**
* If we got here, we've reached the end of the buffer.
* We therefore can attempt to finish up
*/
if( finish && self->token_pos ) {
switch( self->tstate ) {
case L_DIGIT0:
RETURN(INTEGER)
case L_TIMESTAMP3:
RETURN(TIMESTAMP)
case L_WHITESPACE:
RETURN(WHITESPACE)
default:
RESET
return BADTOKEN;
}
}
return *pos == length || self->token_pos ? UNFINISHED : BADTOKEN;
}
/**
* token states
L_START + 'W' = L_WEBVTT0
L_START + '-' = L_DASH0
L_START + {D} = L_DIGIT0
L_START + CR = L_NEWLINE0
L_START + LF = *NEWLINE
L_START + SP = L_WHITESPACE
L_START + TB = L_WHITESPACE
L_START + FS = *FULL_STOP
L_START + 'p' = L_POSITION0
L_START + 'a' = L_ALIGN0
L_START + 'l' = L_L0
L_START + 'v' = L_VERTICAL0
L_START + 'r' = L_RL0
L_START + 's' = L_S0
L_START + 'm' = L_MIDDLE0
L_START + 'e' = L_END0
L_WEBVTT0 + 'E' = L_WEBVTT1
L_WEBVTT1 + 'B' = L_WEBVTT2
L_WEBVTT2 + 'V' = L_WEBVTT3
L_WEBVTT3 + 'T' = L_WEBVTT4
L_WEBVTT4 + 'T' = *WEBVTT
L_DASH0 + {D} = L_DIGIT0
L_DASH0 + '-' = L_SEP1
L_SEP1 + '>' = *SEPARATOR
L_DIGIT0 + {D} = L_DIGIT0
L_NEWLINE0 + LF = *NEWLINE
L_WHITESPACE + TB = L_WHITESPACE
L_WHITESPACE + SP = L_WHITESPACE
L_POSITION0 + 'o' = L_POSITION1
L_POSITION1 + 's' = L_POSITION2
L_POSITION2 + 'i' = L_POSITION3
L_POSITION3 + 't' = L_POSITION4
L_POSITION4 + 'i' = L_POSITION5
L_POSITION5 + 'o' = L_POSITION6
L_POSITION6 + 'n' = L_POSITION7
L_POSITION7 + ':' = *POSITION
L_ALIGN0 + 'l' = L_ALIGN1
L_ALIGN1 + 'i' = L_ALIGN2
L_ALIGN2 + 'g' = L_ALIGN3
L_ALIGN3 + 'n' = L_ALIGN4
L_ALIGN4 + ':' = *ALIGN
L0 + 'r' = *LR
L0 + 'i' = L_LINE1
L_LINE1 + 'n' = L_LINE2
L_LINE2 + 'e' = L_LINE3
L_LINE3 + ':' = *LINE
L_VERTICAL0 + 'e' = L_VERTICAL1
L_VERTICAL1 + 'r' = L_VERTICAL2
L_VERTICAL2 + 't' = L_VERTICAL3
L_VERTICAL3 + 'i' = L_VERTICAL4
L_VERTICAL4 + 'c' = L_VERTICAL5
L_VERTICAL5 + 'a' = L_VERTICAL6
L_VERTICAL6 + 'l' = L_VERTICAL7
L_VERTICAL7 + ':' = *VERTICAL
L_RL0 + 'l' = *RL
L_S0 + 't' = L_START1
L_S0 + 'i' = L_SIZE1
L_SIZE1 + 'z' = L_SIZE2
L_SIZE2 + 'e' = L_SIZE3
L_SIZE3 + ':' = *SIZE
L_START1 + 'a' = L_START2
L_START2 + 'r' = L_START3
L_START3 + 't' = *START
L_MIDDLE0 + 'i' = L_MIDDLE1
L_MIDDLE1 + 'd' = L_MIDDLE2
L_MIDDLE2 + 'd' = L_MIDDLE3
L_MIDDLE3 + 'l' = L_MIDDLE4
L_MIDDLE4 + 'e' = *MIDDLE
L_END0 + 'n' = L_END1
L_END1 + 'd' = *END
*/

View File

@ -1,40 +0,0 @@
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
# vim: set filetype=python:
# Copyright (c) 2013 Mozilla Foundation and Contributors
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# - Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# - Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
MODULE = 'webvtt'
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',
]
LIBRARY_NAME = 'webvtt'

View File

@ -1,254 +0,0 @@
/**
* 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 */
{ { 0 } } /* value */
};
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 );
webvtt_init_string( &node_data->lang );
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_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;
}
WEBVTT_INTERN webvtt_status
webvtt_create_head_node( webvtt_node **node )
{
webvtt_status status;
webvtt_string empty_annotation;
webvtt_init_string( &empty_annotation );
if( WEBVTT_FAILED( status =
webvtt_create_internal_node( node, NULL, WEBVTT_HEAD_NODE,
NULL, &empty_annotation ) ) ) {
return status;
}
webvtt_release_string( &empty_annotation );
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->lang );
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;
}

View File

@ -1,71 +0,0 @@
/**
* 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 );
WEBVTT_INTERN webvtt_status
webvtt_create_lang_node( webvtt_node **node, webvtt_node *parent,
webvtt_stringlist *css_classes,
webvtt_string *lang );
/**
* 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

File diff suppressed because it is too large Load Diff

View File

@ -1,391 +0,0 @@
/**
* Copyright (c) 2013 Mozilla Foundation and Contributors
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __INTERN_PARSER_H__
# define __INTERN_PARSER_H__
# include <webvtt/parser.h>
# include "string_internal.h"
# 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 {
BADTOKEN = -2,
UNFINISHED = -1, /* not-token */
BOM,
WEBVTT, /* 'WEBVTT' */
NOTE, /* 'NOTE' */
INTEGER, /* /-?\d+/ */
NEWLINE, /* /[\r\n]|(\r\n)/ */
WHITESPACE, /* /[\t ]/ */
FULL_STOP, /* '.' */
POSITION, /* 'position:' */
ALIGN, /* 'align:' */
SIZE, /* 'size:' */
LINE, /* 'line:' */
VERTICAL, /* 'vertical:' */
RL, /* 'rl' */
LR, /* 'lr' */
START, /* 'start' */
MIDDLE, /* 'middle' */
END, /* 'end' */
LEFT, /* 'left' */
RIGHT, /* 'right' */
SEPARATOR, /* '-->' */
TIMESTAMP,
PERCENTAGE, /* '\d+%' */
COLON, /* ':' */
} webvtt_token;
typedef enum
webvtt_state_value_type_t {
V_NONE,
V_POINTER,
V_INTEGER,
V_CUE,
V_TEXT,
V_LNODE,
V_INODE,
V_TOKEN,
} webvtt_state_value_type;
typedef enum
webvtt_parse_mode_t {
M_WEBVTT = 0,
M_CUETEXT,
M_SKIP_CUE,
} webvtt_parse_mode;
typedef enum
webvtt_parse_state_t {
/**
* WEBVTT parse states
*/
T_INITIAL = 0,
T_TAG,
T_TAGCOMMENT,
T_EOL,
T_BODY,
T_CUEREAD, /* Read a line of text for a cue */
T_CUE, /* T_CUEID T_CUEPARAMS T_CUETEXT NEWLINE */
T_CUEID, /* T_LINE !~ SEPARATOR && LINE !~ ^NOTE NEWLINE */
T_CUEPARAMS, /* TIMESTAMP WHITESPACE? SEPARATOR WHITESPACE?
* T_CUESETTING* NEWLINE
*/
T_CUETEXT, /* T_LINE !~ SEPARATOR NEWLINE NEWLINE */
T_TIMESTAMP, /* This looked like a timestamp to the lexer,
* may or may not be valid.
*/
/**
* NOTE comments
*/
T_COMMENT,
/**
* Cue times
*/
T_FROM,
T_SEP_LEFT,
T_SEP,
T_SEP_RIGHT,
T_UNTIL,
/**
* Cue settings
*/
T_PRECUESETTING,
T_CUESETTING,
T_CUESETTING_DELIMITER,
T_CUESETTING_VALUE,
T_SKIP_SETTING /* We have to skip a cue-setting because of an error. */
/**
* Cue text parse states
*/
} webvtt_parse_state;
/**
* lexer state
*/
typedef enum
webvtt_lexer_state_t {
L_START = 0, L_BOM0, L_BOM1, L_WEBVTT0, L_WEBVTT1, L_WEBVTT2, L_WEBVTT3,
L_WEBVTT4, L_DASH0, L_SEP1, L_DIGIT0, L_NEWLINE0, L_WHITESPACE, L_POSITION0,
L_POSITION1, L_POSITION2, L_POSITION3, L_POSITION4, L_POSITION5, L_POSITION6,
L_ALIGN0, L_ALIGN1, L_ALIGN2, L_ALIGN3, L_L0, L_LINE1, L_LINE2, L_VERTICAL0,
L_VERTICAL1, L_VERTICAL2, L_VERTICAL3, L_VERTICAL4, L_VERTICAL5, L_VERTICAL6,
L_RL0, L_S0, L_SIZE1, L_SIZE2, L_START1, L_START2, L_START3, L_MIDDLE0,
L_MIDDLE1, L_MIDDLE2, L_MIDDLE3, L_MIDDLE4, L_END0, L_END1, L_TIMESTAMP1,
L_TIMESTAMP2, L_TIMESTAMP3, L_RIGHT1, L_RIGHT2, L_RIGHT3, L_NOTE1, L_NOTE2,
L_NOTE3, L_LEFT1, L_LEFT2,
} webvtt_lexer_state;
typedef struct
webvtt_state {
webvtt_parse_state state;
webvtt_uint flags; /* Defaults to 0 when pushed */
webvtt_token token;
webvtt_state_value_type type;
webvtt_uint back;
webvtt_uint line;
webvtt_uint column;
union {
/**
* cue value
*/
webvtt_cue *cue;
/**
* string value
*/
webvtt_string text;
/**
* The cuetext parser is not currently using the state stack, and
* because of this, 'node' is never actually used.
*
* It is here if the cuetext parser begins to use the/a state stack
* in the future.
*/
webvtt_node *node;
/**
* unsigned integer value
*/
webvtt_uint value;
} v;
} webvtt_state;
struct
webvtt_parser_t {
webvtt_uint state;
webvtt_uint bytes; /* number of bytes read. */
webvtt_uint line;
webvtt_uint column;
webvtt_cue_fn read;
webvtt_error_fn error;
void *userdata;
webvtt_bool finished;
webvtt_uint cuetext_line; /* start line of cuetext */
/**
* 'mode' can have several states, it is not boolean.
*/
webvtt_parse_mode mode;
webvtt_state *top; /* Top parse state */
webvtt_state astack[0x100];
webvtt_state *stack; /* dynamically allocated stack, if 'astack' fills up */
webvtt_uint stack_alloc; /* item capacity in 'stack' */
webvtt_bool popped;
/**
* line (cue payload also stored here)
*/
int truncate;
webvtt_uint line_pos;
webvtt_string line_buffer;
/**
* tokenizer
*/
webvtt_lexer_state tstate;
webvtt_uint token_pos;
char token[0x100];
};
WEBVTT_INTERN webvtt_token
webvtt_lex( webvtt_parser self, const char *buffer, webvtt_uint *pos,
webvtt_uint length, webvtt_bool finish );
WEBVTT_INTERN webvtt_status
webvtt_lex_word( webvtt_parser self, webvtt_string *pba, const char *buffer,
webvtt_uint *pos, webvtt_uint length, webvtt_bool finish );
/* Tokenize newline sequence, without incrementing 'self->line'. Returns
* BAD_TOKEN when a newline sequence is not found. */
WEBVTT_INTERN webvtt_token
webvtt_lex_newline( webvtt_parser self, const char *buffer, webvtt_uint *pos,
webvtt_uint length, webvtt_bool finish );
WEBVTT_INTERN webvtt_status
webvtt_proc_cueline( webvtt_parser self, webvtt_cue *cue, webvtt_string *line );
WEBVTT_INTERN webvtt_status
webvtt_parse_align( webvtt_parser self, webvtt_cue *cue, const char *text,
webvtt_uint *pos, webvtt_uint len );
WEBVTT_INTERN webvtt_status
webvtt_parse_line( webvtt_parser self, webvtt_cue *cue, const char *text,
webvtt_uint *pos, webvtt_uint len );
WEBVTT_INTERN webvtt_status
webvtt_parse_position( webvtt_parser self, webvtt_cue *cue, const char *text,
webvtt_uint *pos, webvtt_uint len );
WEBVTT_INTERN webvtt_status
webvtt_parse_size( webvtt_parser self, webvtt_cue *cue, const char *text,
webvtt_uint *pos, webvtt_uint len );
WEBVTT_INTERN webvtt_status
webvtt_parse_vertical( webvtt_parser self, webvtt_cue *cue, const char *text,
webvtt_uint *pos, webvtt_uint len );
WEBVTT_INTERN int
parse_timestamp( const char *b, webvtt_timestamp *result );
WEBVTT_INTERN webvtt_status
do_push( webvtt_parser self, webvtt_uint token, webvtt_uint back,
webvtt_uint state, void *data, webvtt_state_value_type type,
webvtt_uint line, webvtt_uint column );
WEBVTT_INTERN webvtt_status
webvtt_read_cuetext( webvtt_parser self, const char *b, webvtt_uint *ppos,
webvtt_uint len, webvtt_bool finish );
WEBVTT_INTERN webvtt_status
webvtt_proc_cuetext( webvtt_parser self, const char *b, webvtt_uint *ppos,
webvtt_uint len, webvtt_bool finish );
WEBVTT_INTERN int
parse_cueparams( webvtt_parser self, const char *text, webvtt_uint len,
webvtt_cue *cue );
/**
* 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 )
#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

View File

@ -1,832 +0,0 @@
/**
* Copyright (c) 2013 Mozilla Foundation and Contributors
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "string_internal.h"
#include <stdlib.h>
#include <string.h>
/* TODO: Use libc implementation if we have one */
void *
memmem(const void *l, size_t l_len, const void *s, size_t s_len)
{
register char *cur, *last;
const char *cl = ( const char * )l;
const char *cs = ( const char * )s;
/* we need something to compare */
if ( l_len == 0 || s_len == 0 ) {
return NULL;
}
/* "s" must be smaller or equal to "l" */
if ( l_len < s_len ) {
return NULL;
}
/* special case where s_len == 1 */
if ( s_len == 1 ) {
return ( void * )memchr( l, ( int )*cs, l_len );
}
/* the last position where its possible to find "s" in "l" */
last = (char *)cl + l_len - s_len;
for ( cur = ( char * )cl; cur <= last; cur++ ) {
if ( cur[0] == cs[0] && memcmp( cur, cs, s_len ) == 0 ) {
return cur;
}
}
return NULL;
}
static webvtt_string_data empty_string = {
{ 1 }, /* init refcount */
0, /* length */
0, /* capacity */
empty_string.array, /* text */
{ '\0' } /* array */
};
WEBVTT_EXPORT void
webvtt_init_string( webvtt_string *result )
{
if( result ) {
result->d = &empty_string;
webvtt_ref( &result->d->refs );
}
}
WEBVTT_EXPORT webvtt_uint
webvtt_string_is_empty( const webvtt_string *str ) {
return str->d == &empty_string || webvtt_string_length( str ) == 0 ? 1 : 0;
}
/**
* Allocate new string.
*/
WEBVTT_EXPORT webvtt_status
webvtt_create_string( webvtt_uint32 alloc, webvtt_string *result )
{
webvtt_string_data *d;
if( !result ) {
return WEBVTT_INVALID_PARAM;
}
d = ( webvtt_string_data * )webvtt_alloc( sizeof( webvtt_string_data ) +
( alloc * sizeof( char ) ) );
if( !d ) {
return WEBVTT_OUT_OF_MEMORY;
}
d->refs.value = 1;
d->alloc = alloc;
d->length = 0;
d->text = d->array;
d->text[0] = 0;
result->d = d;
return WEBVTT_SUCCESS;
}
WEBVTT_EXPORT webvtt_status
webvtt_create_string_with_text( webvtt_string *out, const char *init_text,
int len )
{
if( !out ) {
return WEBVTT_INVALID_PARAM;
}
if( !init_text ) {
webvtt_init_string( out );
return WEBVTT_SUCCESS;
}
if( len < 0 ) {
len = strlen( init_text );
}
/**
* initialize the string by referencing empty_string
*/
webvtt_init_string( out );
if( len == 0 ) {
return WEBVTT_SUCCESS;
}
/**
* append the appropriate data to the empty string
*/
return webvtt_string_append( out, init_text, len );
}
/**
* reference counting
*/
WEBVTT_EXPORT void
webvtt_ref_string( webvtt_string *str )
{
if( str ) {
webvtt_ref( &str->d->refs );
}
}
WEBVTT_EXPORT void
webvtt_release_string( webvtt_string *str )
{
/**
* pulls the string data out of the string container, decreases the string
*/
if( str ) {
webvtt_string_data *d = str->d;
str->d = 0;
if( d && webvtt_deref( &d->refs ) == 0 ) {
webvtt_free( d );
}
}
}
/**
* "Detach" a shared string, so that it's safely mutable
*/
WEBVTT_EXPORT webvtt_status
webvtt_string_detach( /* in, out */ webvtt_string *str )
{
webvtt_string_data *d, *q;
if( !str ) {
return WEBVTT_INVALID_PARAM;
}
q = str->d;
if( q->refs.value == 1 ) {
return WEBVTT_SUCCESS;
}
d = ( webvtt_string_data * )webvtt_alloc( sizeof( webvtt_string_data ) +
( sizeof( char ) * str->d->alloc ) );
d->refs.value = 1;
d->text = d->array;
d->alloc = q->alloc;
d->length = q->length;
memcpy( d->text, q->text, q->length );
str->d = d;
if( webvtt_deref( &q->refs ) == 0 ) {
webvtt_free( q );
}
return WEBVTT_SUCCESS;
}
WEBVTT_EXPORT void
webvtt_copy_string( webvtt_string *left, const webvtt_string *right )
{
if( left ) {
if( right && right->d ) {
left->d = right->d;
} else {
left->d = &empty_string;
}
webvtt_ref( &left->d->refs );
}
}
WEBVTT_EXPORT const char *
webvtt_string_text(const webvtt_string *str)
{
if( !str || !str->d )
{
return 0;
}
return str->d->text;
}
WEBVTT_EXPORT webvtt_uint32
webvtt_string_length(const webvtt_string *str)
{
if( !str || !str->d )
{
return 0;
}
return str->d->length;
}
WEBVTT_EXPORT webvtt_uint32
webvtt_string_capacity(const webvtt_string *str)
{
if( !str || !str->d )
{
return 0;
}
return str->d->alloc;
}
/**
* Reallocate string.
* Grow to at least 'need' characters. Power of 2 growth.
*/
static webvtt_status
grow( webvtt_string *str, webvtt_uint need )
{
static const webvtt_uint page = 0x1000;
webvtt_uint32 n;
webvtt_string_data *p, *d;
webvtt_uint32 grow;
if( !str )
{
return WEBVTT_INVALID_PARAM;
}
if( ( str->d->length + need ) <= str->d->alloc )
{
return WEBVTT_SUCCESS;
}
p = d = str->d;
grow = sizeof( *d ) + ( sizeof( char ) * ( d->length + need ) );
if( grow < page ) {
n = page;
do {
n = n / 2;
} while( n > grow );
if( n < 1 << 6 ) {
n = 1 << 6;
} else {
n = n * 2;
}
} else {
n = page;
do {
n = n * 2;
} while ( n < grow );
}
p = ( webvtt_string_data * )webvtt_alloc( n );
if( !p ) {
return WEBVTT_OUT_OF_MEMORY;
}
p->refs.value = 1;
p->alloc = ( n - sizeof( *p ) ) / sizeof( char );
p->length = d->length;
p->text = p->array;
memcpy( p->text, d->text, sizeof( char ) * p->length );
p->text[ p->length ] = 0;
str->d = p;
if( webvtt_deref( &d->refs ) == 0 ) {
webvtt_free( d );
}
return WEBVTT_SUCCESS;
}
WEBVTT_EXPORT int
webvtt_string_getline( webvtt_string *src, const char *buffer,
webvtt_uint *pos, int len, int *truncate,
webvtt_bool finish )
{
int ret = 0;
webvtt_string *str = src;
webvtt_string_data *d = 0;
const char *s = buffer + *pos;
const char *p = s;
const char *n;
/**
*if this is public now, maybe we should return webvtt_status so we can
* differentiate between WEBVTT_OUT_OF_MEMORY and WEBVTT_INVALID_PARAM
*/
if( !str ) {
return -1;
}
/* This had better be a valid string_data, or else NULL. */
d = str->d;
if( !str->d ) {
if(WEBVTT_FAILED(webvtt_create_string( 0x100, str ))) {
return -1;
}
d = str->d;
}
if( len < 0 ) {
len = strlen( buffer );
}
n = buffer + len;
while( p < n && *p != '\r' && *p != '\n' ) {
++p;
}
if( p < n || finish ) {
ret = 1; /* indicate that we found EOL */
}
len = (webvtt_uint)( p - s );
*pos += len;
if( d->length + len + 1 >= d->alloc ) {
if( truncate && d->alloc >= WEBVTT_MAX_LINE ) {
/* truncate. */
(*truncate)++;
} else {
if( grow( str, len + 1 ) == WEBVTT_OUT_OF_MEMORY ) {
ret = -1;
}
d = str->d;
}
}
/* Copy everything in */
if( len && ret >= 0 && d->length + len < d->alloc ) {
memcpy( d->text + d->length, s, len );
d->length += len;
d->text[ d->length ] = 0;
}
return ret;
}
WEBVTT_EXPORT webvtt_status
webvtt_string_putc( webvtt_string *str, char to_append )
{
webvtt_status result;
if( !str ) {
return WEBVTT_INVALID_PARAM;
}
if( WEBVTT_FAILED( result = webvtt_string_detach( str ) ) ) {
return result;
}
if( !WEBVTT_FAILED( result = grow( str, 1 ) ) )
{
str->d->text[ str->d->length++ ] = to_append;
str->d->text[ str->d->length ] = 0;
}
return result;
}
WEBVTT_EXPORT webvtt_bool
webvtt_string_is_equal( const webvtt_string *str, const char *to_compare,
int len )
{
if( !str || !to_compare ) {
return 0;
}
if( len < 0 ) {
len = strlen( to_compare );
}
if( str->d->length != (unsigned)len ) {
return 0;
}
return memcmp( webvtt_string_text( str ), to_compare, len ) == 0;
}
WEBVTT_EXPORT webvtt_status
webvtt_string_append( webvtt_string *str, const char *buffer, int len )
{
webvtt_status result;
if( !str || !buffer ) {
return WEBVTT_INVALID_PARAM;
}
if( !str->d ) {
webvtt_init_string( str );
}
if( len < 0 ) {
len = strlen( buffer );
}
if( len == 0 ) {
return WEBVTT_SUCCESS;
}
if( !WEBVTT_FAILED( result = grow( str, str->d->length + len ) ) ) {
memcpy( str->d->text + str->d->length, buffer, len );
str->d->length += len;
/* null-terminate string */
str->d->text[ str->d->length ] = 0;
}
return result;
}
WEBVTT_EXPORT webvtt_status
webvtt_string_append_string( webvtt_string *str, const webvtt_string *other )
{
if( !str || !other ) {
return WEBVTT_INVALID_PARAM;
}
return webvtt_string_append( str, other->d->text, other->d->length );
}
WEBVTT_EXPORT webvtt_status
webvtt_string_replace( webvtt_string *str, const char *search, int search_len,
const char *replace, int replace_len )
{
webvtt_status status = WEBVTT_SUCCESS;
char *p;
if( !str || !search || !replace ) {
return WEBVTT_INVALID_PARAM;
}
if( search_len < 0 ) {
search_len = ( int )strlen( search );
}
if( replace_len < 0 ) {
replace_len = ( int )strlen( replace );
}
if( ( p = (char *)memmem( str->d->text, str->d->length, search,
search_len ) ) ) {
const char *end;
size_t pos = p - str->d->text;
if( WEBVTT_FAILED( status = grow( str, replace_len ) ) ) {
return status;
}
p = str->d->text + pos;
end = str->d->text + str->d->length - 1; /* Don't worry about the NULL
* byte. */
if( search_len != replace_len ) {
memmove( p + replace_len, p + search_len, end - p );
}
memcpy( p, replace, replace_len );
str->d->length = ( str->d->length - search_len ) + replace_len;
str->d->text[ str->d->length ] = 0;
status = ( webvtt_status )1;
}
return status;
}
/**
* webvtt_string_replace_all
*
* replace all instances of substring with replacement string
*/
WEBVTT_EXPORT webvtt_status
webvtt_string_replace_all( webvtt_string *str, const char *search,
int search_len, const char *replace,
int replace_len )
{
webvtt_status status = WEBVTT_SUCCESS;
if( !str || !search || !replace ) {
return WEBVTT_INVALID_PARAM;
}
if( search_len < 0 ) {
search_len = ( int )strlen( search );
}
if( replace_len < 0 ) {
replace_len = ( int )strlen( replace );
}
while( ( status = webvtt_string_replace( str, search, search_len, replace,
replace_len ) ) == 1 );
return status;
}
/**
* String lists
*/
WEBVTT_EXPORT webvtt_status
webvtt_create_stringlist( webvtt_stringlist **result )
{
webvtt_stringlist *list;
if( !result ) {
return WEBVTT_INVALID_PARAM;
}
list = ( webvtt_stringlist * )webvtt_alloc0( sizeof( *list ) );
if( !list ) {
return WEBVTT_OUT_OF_MEMORY;
}
list->alloc = 0;
list->length = 0;
webvtt_ref_stringlist( list );
*result = list;
return WEBVTT_SUCCESS;
}
WEBVTT_EXPORT void
webvtt_ref_stringlist( webvtt_stringlist *list )
{
if( list ) {
webvtt_ref( &list->refs );
}
}
WEBVTT_EXPORT void
webvtt_copy_stringlist( webvtt_stringlist **left, webvtt_stringlist *right )
{
if( !left || !right ) {
return;
}
*left = right;
webvtt_ref_stringlist( *left );
}
WEBVTT_EXPORT void
webvtt_release_stringlist( webvtt_stringlist **list )
{
webvtt_stringlist *l;
webvtt_uint i;
if( !list || !*list ) {
return;
}
l = *list;
if( webvtt_deref( &l->refs ) == 0 ) {
if( l->items ) {
for( i = 0; i < l->length; i++ ) {
webvtt_release_string( &l->items[ i ] );
}
webvtt_free( l->items );
}
webvtt_free( l );
}
*list = 0;
}
WEBVTT_EXPORT webvtt_status
webvtt_stringlist_push( webvtt_stringlist *list, webvtt_string *str )
{
if( !list || !str ) {
return WEBVTT_INVALID_PARAM;
}
if( list->length + 1 >= ( ( list->alloc / 3 ) * 2 ) ) {
webvtt_string *arr, *old;
list->alloc = list->alloc == 0 ? 8 : list->alloc * 2;
arr = ( webvtt_string * )webvtt_alloc0( sizeof( webvtt_string ) *
list->alloc );
if( !arr ) {
return WEBVTT_OUT_OF_MEMORY;
}
memcpy( arr, list->items, sizeof( webvtt_string ) * list->length );
old = list->items;
list->items = arr;
webvtt_free( old );
}
list->items[list->length].d = str->d;
webvtt_ref_string( list->items + list->length++ );
return WEBVTT_SUCCESS;
}
WEBVTT_EXPORT webvtt_bool
webvtt_stringlist_pop( webvtt_stringlist *list, webvtt_string *out )
{
if( !list || !out || list->length < 1 ) {
return 0;
}
list->length--;
webvtt_copy_string( out, list->items + list->length );
webvtt_release_string( list->items + list->length );
return 1;
}
WEBVTT_EXPORT webvtt_bool
webvtt_next_utf8( const char **begin, const char *end )
{
int c;
const char *p;
if( !begin || !*begin || !**begin || ( end && ( end <= *begin ) ) ) {
/* Either begin is null, or end is null, or end <= begin */
return 0;
}
p = *begin;
if( !end ) {
end = p + strlen( p );
}
c = webvtt_utf8_length( p );
if( c > 0 ) {
p += c;
} else if( ( *p & 0xC0 ) == 0x80 ) {
const char *pc = p + 1;
while( pc < end && ( ( *pc & 0xC0 ) == 0x80 ) ) {
++pc;
}
if( pc <= end ) {
p = pc;
}
}
if( *begin != p && p <= end ) {
*begin = p;
return 1;
}
return 0;
}
WEBVTT_EXPORT webvtt_bool
webvtt_skip_utf8( const char **begin, const char *end, int n_chars )
{
const char *first;
if( !begin || !*begin ) {
return 0;
}
if( n_chars < 0 ) {
return 0;
}
first = *begin;
if( !end ) {
end = first + strlen( first );
}
if( end > first ) {
/* forwards */
while( n_chars && end > *begin ) {
if( webvtt_next_utf8( begin, end ) ) {
--n_chars;
}
}
}
return n_chars == 0;
}
WEBVTT_EXPORT webvtt_uint16
webvtt_utf8_to_utf16( const char *utf8, const char *end,
webvtt_uint16 *high_surrogate )
{
int need = 0;
webvtt_uint32 uc = 0, min = 0;
/* We're missing our pointers */
if( !utf8 ) {
return 0;
}
if( !end ) {
end = utf8 + strlen( utf8 );
}
if( utf8 >= end ) {
return 0;
}
/* If we are returning a surrogate pair, initialize it to 0 */
if( high_surrogate ) {
*high_surrogate = 0;
}
/* We're not at the start of a character */
if( ( *utf8 & 0xC0 ) == 0x80 ) {
return 0;
}
if( (unsigned char)*utf8 < 0x80 ) {
return ( webvtt_uint32 )( *utf8 );
}
while( utf8 < end ) {
char ch = *utf8;
utf8++;
if( need ) {
if( ( ch & 0xC0 ) == 0x80 ) {
uc = ( uc << 6 ) | ( ch & 0x3F );
if (!--need) {
int nc;
if ( !( nc = UTF_IS_NONCHAR( uc ) ) && uc > 0xFFFF && uc < 0x110000) {
/* Surrogate pair */
if( high_surrogate ) {
*high_surrogate = UTF_HIGH_SURROGATE( uc );
}
return UTF_LOW_SURROGATE( uc );
} else if ( ( uc < min ) || ( uc >= 0xD800 && uc <= 0xDFFF ) || nc
|| uc >= 0x110000) {
/* Non-character, overlong sequence, or utf16 surrogate */
return 0xFFFD;
} else {
/* Non-surrogate */
return uc;
}
}
}
} else {
if ( ( ch & 0xE0 ) == 0xC0 ) {
uc = ch & 0x1f;
need = 1;
min = 0x80;
} else if ( ( ch & 0xF0 ) == 0xE0 ) {
uc = ch & 0x0f;
need = 2;
min = 0x800;
} else if ( ( ch & 0xF8 ) == 0xF0 ) {
uc = ch & 0x07;
need = 3;
min = 0x10000;
} else {
/* TODO This should deal with 5-7 byte sequences */
/* return the replacement character in other cases */
return 0xFFFD;
}
}
}
return 0;
}
WEBVTT_EXPORT int
webvtt_utf8_chcount( const char *utf8, const char *end )
{
int n = 0;
const char *p;
if( !utf8 || !*utf8 || ( end != 0 && end < utf8 ) ) {
return 0;
}
if( !end ) {
end = utf8 + strlen( utf8 );
}
for( p = utf8; p < end; ++n ) {
int c = webvtt_utf8_length( p );
if( c < 1 ) {
break;
}
p += c;
}
return n;
}
WEBVTT_EXPORT int
webvtt_utf8_length( const char *utf8 )
{
char ch;
if( !utf8 ) {
return 0;
}
ch = *utf8;
if( (unsigned char)ch < 0x80 ) {
return 1;
} else if( ( ch & 0xE0 ) == 0xC0 ) {
return 2;
} else if( ( ch & 0xF0 ) == 0xE0 ) {
return 3;
} else if( ( ch & 0xF8 ) == 0xF0 ) {
return 4;
} else if( ( ch & 0xFE ) == 0xFC ) {
return 5;
}
return -1;
}

View File

@ -1,98 +0,0 @@
/**
* Copyright (c) 2013 Mozilla Foundation and Contributors
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __INTERN_STRING_H__
# define __INTERN_STRING_H__
# include <webvtt/string.h>
# define UTF8_LEFT_TO_RIGHT_1 (0xE2)
# define UTF8_LEFT_TO_RIGHT_2 (0x80)
# define UTF8_LEFT_TO_RIGHT_3 (0x8E)
# define UTF8_RIGHT_TO_LEFT_1 (0xE2)
# define UTF8_RIGHT_TO_LEFT_2 (0x80)
# define UTF8_RIGHT_TO_LEFT_3 (0x8F)
# define UTF8_NO_BREAK_SPACE_1 (0xC2)
# define UTF8_NO_BREAK_SPACE_2 (0xA0)
/**
* Taken from ICU
* http://source.icu-project.org/repos/icu/icu/trunk/source/common/unicode/utf.h
*/
# define UTF_IS_NONCHAR( C ) \
( ( C )>=0xFDD0 && \
( ( webvtt_uint32 )( C ) <= 0xfdef || ( ( C ) & 0xFFFE)==0xFFFE) && \
( webvtt_uint32 )( C ) <= 0x10FFFF )
# define UTF_HIGH_SURROGATE( C ) ( webvtt_uint16 )( ( ( C ) >> 10 ) + 0xD7C0 )
# define UTF_LOW_SURROGATE( C ) ( webvtt_uint16 )( ( ( C ) & 0x3FF ) | 0xDC00 )
# ifndef WEBVTT_MAX_LINE
# define WEBVTT_MAX_LINE 0x10000
# endif
# ifdef WEBVTT_INLINE
# define __WEBVTT_STRING_INLINE WEBVTT_INLINE
# else
# define __WEBVTT_STRING_INLINE
# endif
struct
webvtt_string_data_t {
struct webvtt_refcount_t refs;
webvtt_uint32 alloc;
webvtt_uint32 length;
char *text;
char array[1];
};
static __WEBVTT_STRING_INLINE int
webvtt_isalpha( char ch )
{
return ( ( ( ch >= 'A' ) && ( ch <= 'Z' ) ) || ( ( ch >= 'a' ) &&
( ch <= 'z' ) ) );
}
static __WEBVTT_STRING_INLINE int
webvtt_isdigit( char ch )
{
return ( ( ch >= '0' ) && ( ch <= '9' ) );
}
static __WEBVTT_STRING_INLINE int
webvtt_isalphanum( char ch )
{
return ( webvtt_isalpha( ch ) || webvtt_isdigit( ch ) );
}
static __WEBVTT_STRING_INLINE int
webvtt_iswhite( char ch )
{
return ( ( ch == '\r' ) || ( ch == '\n' ) || ( ch == '\f' )
|| ( ch == '\t' ) || ( ch == ' ' ) ) ;
}
# undef __WEBVTT_STRING_INLINE
#endif

View File

@ -1,86 +0,0 @@
#!/bin/bash
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# Usage: ./update.sh <webvtt_git_repository> <optional revision/branch/refspec>
#
# Copies the needed files from a directory containing the original
# libwebvtt source, and applies any local patches we're carrying.
function die() {
echo "error: $1"
exit 1
}
if [ $# -lt 1 ]; then
die "Usage: update.sh /path/to/webvtt-repository/ commit/remote/branch (default HEAD)"
fi
git --version 2>&1 >/dev/null #executable not found? ok.
have_git=$?
hg --version 2>&1 >/dev/null #executable not found? ok.
have_hg=$?
if [ ${have_git} -ne 0 ]; then
die "Git does not seem to be installed"
fi
start_dir=$PWD
webvtt_branch=HEAD
if [ $# -gt 1 ]; then
webvtt_branch="$2"
fi
webvtt_dir=$(dirname $0)
webvtt_remote=$1
repo_dir=${webvtt_dir}/libwebvtt
cd ${webvtt_remote}
webvtt_isrepo=$(git rev-parse --is-inside-work-tree)
if [ "x${webvtt_isrepo}" != "xtrue" ]; then
cd ${start_dir}
die "$1 does not seem to be a git repository"
fi
webvtt_revision=$(git rev-parse ${webvtt_branch})
echo "Updating media/webvtt to revision ${webvtt_branch} (${webvtt_revision})"
#Ensure that ${repo_dir} is not present to prevent mkdir from failing
#Error hidden because most of the time it shouldn't be present anyways, so an
#error is generally expected.
rm -rf ${start_dir}/${repo_dir} 2>/dev/null
#Try to create temporary directory for repo archive. If this fails,
#print error and exit.
mkdir ${start_dir}/${repo_dir} || exit 1
git archive --format=tar ${webvtt_revision} | tar -C ${start_dir}/${repo_dir} -xf -
cd ${start_dir}
sed -e "s/^[a-z0-9]\{40,40\}/${webvtt_revision}/" \
${webvtt_dir}/README_MOZILLA > ${webvtt_dir}/README_MOZILLA.sed
mv ${webvtt_dir}/README_MOZILLA.sed ${webvtt_dir}/README_MOZILLA \
|| die "Failed to overwrite README_MOZILLA"
rm -rf ${webvtt_dir}/include ${webvtt_dir}/*.c ${webvtt_dir}/*.h
#Create directories
mkdir ${webvtt_dir}/include ${webvtt_dir}/include/webvtt
#Copy C headers, excluding 'webvtt-config' files (hence [^w])
find ${repo_dir}/include/webvtt -type f -name '[^w]*.h' -exec cp '{}' \
${webvtt_dir}/include/webvtt/ \; #Copy C sources
find ${repo_dir}/src/libwebvtt -type f -name '*.[ch]' -exec cp '{}' \
${webvtt_dir}/ \;
cp ${repo_dir}/LICENSE ${webvtt_dir}/
rm -rf ${repo_dir}
# addremove automatically if mercurial is used
if [ ${have_hg} -eq 0 -a -d ${start_dir}/.hg ]; then
hg addremove ${webvtt_dir}/
fi
# apply patches
cd ${webvtt_dir}
# patches go here
cd ${start_dir}

View File

@ -76,8 +76,6 @@ if CONFIG['MOZ_OPUS']:
if CONFIG['MOZ_WEBM']:
add_tier_dir('platform', 'media/libnestegg')
add_tier_dir('platform', 'media/webvtt')
if CONFIG['MOZ_VP8'] and not CONFIG['MOZ_NATIVE_LIBVPX']:
add_tier_dir('platform', 'media/libvpx')