blob: 072b42198bf347f72bacf8907f9997f444bffefa [file] [log] [blame]
/*
* Copyright (C) 2014 Cable Television Labs Inc. All rights reserved.
* Copyright (C) 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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 APPLE INC. ``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 APPLE INC. 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 "config.h"
#if ENABLE(VIDEO_TRACK)
#include "DataCue.h"
#include "Logging.h"
#include "TextTrack.h"
#include "TextTrackCueList.h"
#include <JavaScriptCore/JSCInlines.h>
#include <JavaScriptCore/Protect.h>
namespace WebCore {
using namespace JSC;
DataCue::DataCue(ScriptExecutionContext& context, const MediaTime& start, const MediaTime& end, ArrayBuffer& data, const String& type)
: TextTrackCue(context, start, end)
, m_type(type)
{
setData(data);
}
DataCue::DataCue(ScriptExecutionContext& context, const MediaTime& start, const MediaTime& end, const void* data, unsigned length)
: TextTrackCue(context, start, end)
, m_data(ArrayBuffer::create(data, length))
{
}
DataCue::DataCue(ScriptExecutionContext& context, const MediaTime& start, const MediaTime& end, RefPtr<SerializedPlatformRepresentation>&& platformValue, const String& type)
: TextTrackCue(context, start, end)
, m_type(type)
, m_platformValue(WTFMove(platformValue))
{
}
DataCue::DataCue(ScriptExecutionContext& context, const MediaTime& start, const MediaTime& end, JSC::JSValue value, const String& type)
: TextTrackCue(context, start, end)
, m_type(type)
, m_value(value)
{
if (m_value)
JSC::gcProtect(m_value);
}
DataCue::~DataCue()
{
if (m_value)
JSC::gcUnprotect(m_value);
}
RefPtr<ArrayBuffer> DataCue::data() const
{
if (m_platformValue)
return m_platformValue->data();
if (!m_data)
return nullptr;
return ArrayBuffer::create(*m_data);
}
void DataCue::setData(ArrayBuffer& data)
{
m_platformValue = nullptr;
if (m_value)
JSC::gcUnprotect(m_value);
m_value = JSC::JSValue();
m_data = ArrayBuffer::create(data);
}
DataCue* toDataCue(TextTrackCue* cue)
{
ASSERT_WITH_SECURITY_IMPLICATION(cue->cueType() == TextTrackCue::Data);
return static_cast<DataCue*>(cue);
}
const DataCue* toDataCue(const TextTrackCue* cue)
{
ASSERT_WITH_SECURITY_IMPLICATION(cue->cueType() == TextTrackCue::Data);
return static_cast<const DataCue*>(cue);
}
bool DataCue::cueContentsMatch(const TextTrackCue& cue) const
{
if (cue.cueType() != TextTrackCue::Data)
return false;
const DataCue* dataCue = toDataCue(&cue);
RefPtr<ArrayBuffer> otherData = dataCue->data();
if ((otherData && !m_data) || (!otherData && m_data))
return false;
if (m_data && m_data->byteLength() != otherData->byteLength())
return false;
if (m_data && m_data->data() && memcmp(m_data->data(), otherData->data(), m_data->byteLength()))
return false;
const SerializedPlatformRepresentation* otherPlatformValue = dataCue->platformValue();
if ((otherPlatformValue && !m_platformValue) || (!otherPlatformValue && m_platformValue))
return false;
if (m_platformValue && !m_platformValue->isEqual(*otherPlatformValue))
return false;
JSC::JSValue thisValue = valueOrNull();
JSC::JSValue otherValue = dataCue->valueOrNull();
if ((otherValue && !thisValue) || (!otherValue && thisValue))
return false;
if (!JSC::JSValue::strictEqual(nullptr, thisValue, otherValue))
return false;
return true;
}
bool DataCue::isEqual(const TextTrackCue& cue, TextTrackCue::CueMatchRules match) const
{
if (!TextTrackCue::isEqual(cue, match))
return false;
if (cue.cueType() != TextTrackCue::Data)
return false;
return cueContentsMatch(cue);
}
bool DataCue::doesExtendCue(const TextTrackCue& cue) const
{
if (!cueContentsMatch(cue))
return false;
return TextTrackCue::doesExtendCue(cue);
}
JSC::JSValue DataCue::value(JSC::ExecState& state) const
{
if (m_platformValue)
return m_platformValue->deserialize(&state);
if (m_value)
return m_value;
return JSC::jsNull();
}
void DataCue::setValue(JSC::ExecState&, JSC::JSValue value)
{
// FIXME: this should use a SerializedScriptValue.
if (m_value)
JSC::gcUnprotect(m_value);
m_value = value;
if (m_value)
JSC::gcProtect(m_value);
m_platformValue = nullptr;
m_data = nullptr;
}
JSValue DataCue::valueOrNull() const
{
if (m_value)
return m_value;
return jsNull();
}
String DataCue::toJSONString() const
{
auto object = JSON::Object::create();
TextTrackCue::toJSON(object.get());
if (!m_type.isEmpty())
object->setString(ASCIILiteral("type"), m_type);
return object->toJSONString();
}
} // namespace WebCore
#endif