text: /*
   * Copyright (C) 2013-2017 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"
  #include "MockBox.h"
  
  #if ENABLE(MEDIA_SOURCE)
  
  #include <JavaScriptCore/ArrayBuffer.h>
  #include <JavaScriptCore/DataView.h>
  #include <JavaScriptCore/HeapInlines.h>
  #include <JavaScriptCore/Int8Array.h>
  #include <JavaScriptCore/JSCJSValueInlines.h>
  #include <JavaScriptCore/TypedArrayInlines.h>
  #include <wtf/NeverDestroyed.h>
  #include <wtf/text/StringBuilder.h>
  
  namespace WebCore {
  
  MockBox::MockBox(ArrayBuffer* data)
  {
      m_type = peekType(data);
      m_length = peekLength(data);
      ASSERT(m_length >= 8);
  }
  
  String MockBox::peekType(ArrayBuffer* data)
  {
      StringBuilder builder;
      RefPtr<Int8Array> array = JSC::Int8Array::create(data, 0, 4);
      for (int i = 0; i < 4; ++i)
          builder.append(array->item(i));
      return builder.toString();
  }
  
  size_t MockBox::peekLength(ArrayBuffer* data)
  {
      RefPtr<JSC::DataView> view = JSC::DataView::create(data, 0, data->byteLength());
      return view->get<uint32_t>(4, true);
  }
  
  MockTrackBox::MockTrackBox(ArrayBuffer* data)
      : MockBox(data)
  {
      ASSERT(m_length == 17);
  
      RefPtr<JSC::DataView> view = JSC::DataView::create(data, 0, data->byteLength());
      m_trackID = view->get<int32_t>(8, true);
  
      StringBuilder builder;
      RefPtr<Int8Array> array = JSC::Int8Array::create(data, 12, 4);
      for (int i = 0; i < 4; ++i)
          builder.append(array->item(i));
      m_codec = builder.toString();
  
      m_kind = static_cast<TrackKind>(view->get<uint8_t>(16, true));
  }
  
  const String& MockTrackBox::type()
  {
      static NeverDestroyed<String> trak(MAKE_STATIC_STRING_IMPL("trak"));
      return trak;
  }
  
  MockInitializationBox::MockInitializationBox(ArrayBuffer* data)
      : MockBox(data)
  {
      ASSERT(m_length >= 13);
  
      RefPtr<JSC::DataView> view = JSC::DataView::create(data, 0, data->byteLength());
      int32_t timeValue = view->get<int32_t>(8, true);
      int32_t timeScale = view->get<int32_t>(12, true);
      m_duration = MediaTime(timeValue, timeScale);
      
      size_t offset = 16;
  
      while (offset < m_length) {
          RefPtr<ArrayBuffer> subBuffer = data->slice(offset);
          if (MockBox::peekType(subBuffer.get()) != MockTrackBox::type())
              break;
  
          MockTrackBox trackBox(subBuffer.get());
          offset += trackBox.length();
          m_tracks.append(trackBox);
      }
  }
  
  const String& MockInitializationBox::type()
  {
      static NeverDestroyed<String> init(MAKE_STATIC_STRING_IMPL("init"));
      return init;
  }
  
  MockSampleBox::MockSampleBox(ArrayBuffer* data)
      : MockBox(data)
  {
      ASSERT(m_length == 30);
  
      RefPtr<JSC::DataView> view = JSC::DataView::create(data, 0, data->byteLength());
      int32_t timeScale = view->get<int32_t>(8, true);
  
      int32_t timeValue = view->get<int32_t>(12, true);
      m_presentationTimestamp = MediaTime(timeValue, timeScale);
  
      timeValue = view->get<int32_t>(16, true);
      m_decodeTimestamp = MediaTime(timeValue, timeScale);
  
      timeValue = view->get<int32_t>(20, true);
      m_duration = MediaTime(timeValue, timeScale);
  
      m_trackID = view->get<int32_t>(24, true);
      m_flags = view->get<uint8_t>(28, true);
      m_generation = view->get<uint8_t>(29, true);
  }
  
  const String& MockSampleBox::type()
  {
      static NeverDestroyed<String> smpl(MAKE_STATIC_STRING_IMPL("smpl"));
      return smpl;
  }
  
  }
  
  #endif
  