зеркало из https://github.com/mozilla/gecko-dev.git
Bug 887463 - remove webvtt parser library. r=cpearce.
This commit is contained in:
Родитель
4fe061150b
Коммит
ccaf62a7df
2
CLOBBER
2
CLOBBER
|
@ -17,4 +17,4 @@
|
|||
#
|
||||
# Modifying this file will now automatically clobber the buildbot machines \o/
|
||||
#
|
||||
Bug 848491 - Skia update.
|
||||
Bug 887463 - Remove webvtt parser.
|
||||
|
|
|
@ -38,7 +38,6 @@
|
|||
#include "nsStyleConsts.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsVideoFrame.h"
|
||||
#include "webvtt/parser.h"
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
static PRLogModuleInfo* gTrackElementLog;
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
|
@ -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.
|
||||
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -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, "&", 4 ) ) {
|
||||
CHECK_MEMORY_OP_JUMP( status, webvtt_string_putc( result, '&' ) );
|
||||
} else if( webvtt_string_is_equal( &buffer, "<", 3 ) ) {
|
||||
CHECK_MEMORY_OP_JUMP( status, webvtt_string_putc( result, '<' ) );
|
||||
} else if( webvtt_string_is_equal( &buffer, ">", 3 ) ) {
|
||||
CHECK_MEMORY_OP_JUMP( status, webvtt_string_putc( result, '>' ) );
|
||||
} else if( webvtt_string_is_equal( &buffer, "&rlm", 4 ) ) {
|
||||
CHECK_MEMORY_OP_JUMP( status, webvtt_string_append( result, rlm_replace,
|
||||
RLM_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, " ", 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;
|
||||
}
|
|
@ -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
|
|
@ -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 ];
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
*/
|
|
@ -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'
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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}
|
|
@ -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')
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче