1/* 2 * Copyright (C) 2014 Cable Television Labs Inc. All rights reserved. 3 * Copyright (C) 2014 Apple Inc. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27#include "config.h" 28 29#if ENABLE(VIDEO_TRACK) 30#include "DataCue.h" 31 32#include "Logging.h" 33#include "TextTrack.h" 34#include "TextTrackCueList.h" 35#include <runtime/Protect.h> 36 37namespace WebCore { 38 39DataCue::DataCue(ScriptExecutionContext& context, double start, double end, ArrayBuffer* data, const String& type, ExceptionCode& ec) 40 : TextTrackCue(context, start, end) 41 , m_type(type) 42{ 43 setData(data, ec); 44} 45 46DataCue::DataCue(ScriptExecutionContext& context, double start, double end, const void* data, unsigned length) 47 : TextTrackCue(context, start, end) 48{ 49 m_data = ArrayBuffer::create(data, length); 50} 51 52#if ENABLE(DATACUE_VALUE) 53DataCue::DataCue(ScriptExecutionContext& context, double start, double end, PassRefPtr<SerializedPlatformRepresentation> platformValue, const String& type) 54 : TextTrackCue(context, start, end) 55 , m_type(type) 56 , m_platformValue(platformValue) 57{ 58} 59 60DataCue::DataCue(ScriptExecutionContext& context, double start, double end, JSC::JSValue value, const String& type) 61 : TextTrackCue(context, start, end) 62 , m_type(type) 63 , m_value(value) 64{ 65} 66#endif 67 68DataCue::~DataCue() 69{ 70#if ENABLE(DATACUE_VALUE) 71 if (m_value) 72 JSC::gcUnprotect(m_value); 73#endif 74} 75 76PassRefPtr<ArrayBuffer> DataCue::data() const 77{ 78#if ENABLE(DATACUE_VALUE) 79 if (m_platformValue) 80 return m_platformValue->data(); 81#endif 82 83 if (!m_data) 84 return nullptr; 85 86 return ArrayBuffer::create(m_data.get()); 87} 88 89void DataCue::setData(ArrayBuffer* data, ExceptionCode& ec) 90{ 91 if (!data) { 92 ec = TypeError; 93 return; 94 } 95 96#if ENABLE(DATACUE_VALUE) 97 m_platformValue = nullptr; 98 m_value = JSC::JSValue(); 99#endif 100 101 m_data = ArrayBuffer::create(data); 102} 103 104#if !ENABLE(DATACUE_VALUE) 105String DataCue::text(bool& isNull) const 106{ 107 isNull = true; 108 return String(); 109} 110#endif 111 112DataCue* toDataCue(TextTrackCue* cue) 113{ 114 ASSERT_WITH_SECURITY_IMPLICATION(cue->cueType() == TextTrackCue::Data); 115 return static_cast<DataCue*>(cue); 116} 117 118const DataCue* toDataCue(const TextTrackCue* cue) 119{ 120 ASSERT_WITH_SECURITY_IMPLICATION(cue->cueType() == TextTrackCue::Data); 121 return static_cast<const DataCue*>(cue); 122} 123 124bool DataCue::cueContentsMatch(const TextTrackCue& cue) const 125{ 126 if (cue.cueType() != TextTrackCue::Data) 127 return false; 128 129 const DataCue* dataCue = toDataCue(&cue); 130 RefPtr<ArrayBuffer> otherData = dataCue->data(); 131 if ((otherData && !m_data) || (!otherData && m_data)) 132 return false; 133 if (m_data && m_data->byteLength() != otherData->byteLength()) 134 return false; 135 if (m_data && m_data->data() && memcmp(m_data->data(), otherData->data(), m_data->byteLength())) 136 return false; 137 138#if ENABLE(DATACUE_VALUE) 139 RefPtr<SerializedPlatformRepresentation> otherPlatformValue = dataCue->platformValue(); 140 if ((otherPlatformValue && !m_platformValue) || (!otherPlatformValue && m_platformValue)) 141 return false; 142 if (m_platformValue && !m_platformValue->isEqual(*otherPlatformValue.get())) 143 return false; 144 145 JSC::JSValue thisValue = value(nullptr); 146 JSC::JSValue otherValue = dataCue->value(nullptr); 147 if ((otherValue && !thisValue) || (!otherValue && thisValue)) 148 return false; 149 if (!JSC::JSValue::strictEqual(nullptr, thisValue, otherValue)) 150 return false; 151#endif 152 153 return true; 154} 155 156bool DataCue::isEqual(const TextTrackCue& cue, TextTrackCue::CueMatchRules match) const 157{ 158 if (!TextTrackCue::isEqual(cue, match)) 159 return false; 160 161 if (cue.cueType() != TextTrackCue::Data) 162 return false; 163 164 return cueContentsMatch(cue); 165} 166 167bool DataCue::doesExtendCue(const TextTrackCue& cue) const 168{ 169 if (!cueContentsMatch(cue)) 170 return false; 171 172 return TextTrackCue::doesExtendCue(cue); 173} 174 175#if ENABLE(DATACUE_VALUE) 176JSC::JSValue DataCue::value(JSC::ExecState* exec) const 177{ 178 if (exec && m_platformValue) 179 return m_platformValue->deserialize(exec); 180 181 if (m_value) 182 return m_value; 183 184 return JSC::jsNull(); 185} 186 187void DataCue::setValue(JSC::ExecState*, JSC::JSValue value) 188{ 189 // FIXME: this should use a SerializedScriptValue. 190 if (m_value) 191 JSC::gcUnprotect(m_value); 192 m_value = value; 193 if (m_value) 194 JSC::gcProtect(m_value); 195 196 m_platformValue = nullptr; 197 m_data = nullptr; 198} 199#endif 200 201} // namespace WebCore 202 203#endif 204