#include "config.h"
#if ENABLE(VIDEO_TRACK)
#include "DataCue.h"
#include "Logging.h"
#include "TextTrack.h"
#include "TextTrackCueList.h"
#include <runtime/Protect.h>
namespace WebCore {
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);
}
#if ENABLE(DATACUE_VALUE)
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);
}
#endif
DataCue::~DataCue()
{
#if ENABLE(DATACUE_VALUE)
if (m_value)
JSC::gcUnprotect(m_value);
#endif
}
RefPtr<ArrayBuffer> DataCue::data() const
{
#if ENABLE(DATACUE_VALUE)
if (m_platformValue)
return m_platformValue->data();
#endif
if (!m_data)
return nullptr;
return ArrayBuffer::create(*m_data);
}
void DataCue::setData(ArrayBuffer& data)
{
#if ENABLE(DATACUE_VALUE)
m_platformValue = nullptr;
if (m_value)
JSC::gcUnprotect(m_value);
m_value = JSC::JSValue();
#endif
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;
#if ENABLE(DATACUE_VALUE)
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 = value(nullptr);
JSC::JSValue otherValue = dataCue->value(nullptr);
if ((otherValue && !thisValue) || (!otherValue && thisValue))
return false;
if (!JSC::JSValue::strictEqual(nullptr, thisValue, otherValue))
return false;
#endif
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);
}
#if ENABLE(DATACUE_VALUE)
JSC::JSValue DataCue::value(JSC::ExecState* exec) const
{
if (exec && m_platformValue)
return m_platformValue->deserialize(exec);
if (m_value)
return m_value;
return JSC::jsNull();
}
void DataCue::setValue(JSC::ExecState*, JSC::JSValue value)
{
if (m_value)
JSC::gcUnprotect(m_value);
m_value = value;
if (m_value)
JSC::gcProtect(m_value);
m_platformValue = nullptr;
m_data = nullptr;
}
#endif
}
#endif