/* * Copyright (C) 2013 University of Washington. 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 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 EncodedValue_h #define EncodedValue_h #if ENABLE(WEB_REPLAY) #include "InspectorValues.h" #include #include namespace JSC { class NondeterministicInputBase; template struct EncodingTraits; class EncodedValue final { public: explicit EncodedValue(RefPtr&& value) : m_value(value) { } EncodedValue() : m_value(nullptr) { } static EncodedValue createObject() { return EncodedValue(Inspector::InspectorObject::create()); } static EncodedValue createArray() { return EncodedValue(Inspector::InspectorArray::create()); } static EncodedValue createString(const String& value) { return EncodedValue(Inspector::InspectorValue::create(value)); } static EncodedValue createString(const char* value) { return EncodedValue(Inspector::InspectorValue::create(value)); } template void put(const String&, const typename EncodingTraits::DecodedType&); template void append(const typename EncodingTraits::DecodedType&); template bool get(const String&, typename EncodingTraits::DecodedType&); template bool get(const String&, std::unique_ptr::DecodedType>&); template T convertTo(); JS_EXPORT_PRIVATE RefPtr asObject(); JS_EXPORT_PRIVATE RefPtr asArray(); private: RefPtr m_value; }; template<> JS_EXPORT_PRIVATE bool EncodedValue::convertTo(); template<> JS_EXPORT_PRIVATE double EncodedValue::convertTo(); template<> JS_EXPORT_PRIVATE float EncodedValue::convertTo(); template<> JS_EXPORT_PRIVATE int32_t EncodedValue::convertTo(); template<> JS_EXPORT_PRIVATE int64_t EncodedValue::convertTo(); template<> JS_EXPORT_PRIVATE uint32_t EncodedValue::convertTo(); template<> JS_EXPORT_PRIVATE uint64_t EncodedValue::convertTo(); template<> JS_EXPORT_PRIVATE String EncodedValue::convertTo(); template struct EncodingTraits { typedef T DecodedType; static EncodedValue encodeValue(const DecodedType&); static bool decodeValue(EncodedValue&, DecodedType&); static bool decodeValue(EncodedValue&, std::unique_ptr&); }; template struct EncodingTraits> { typedef Vector::DecodedType, inlineCapacity, OverflowHandler> DecodedType; static EncodedValue encodeValue(const DecodedType& vectorOfValues) { EncodedValue encodedVector = EncodedValue::createArray(); for (const typename EncodingTraits::DecodedType& value : vectorOfValues) encodedVector.append(value); return encodedVector; } static bool decodeValue(EncodedValue& encodedVector, DecodedType& decodedValue) { RefPtr inspectorArray = encodedVector.asArray(); decodedValue = Vector::DecodedType, inlineCapacity, OverflowHandler>(inspectorArray->length()); for (size_t i = 0; i < inspectorArray->length(); ++i) { EncodedValue encodedElement(inspectorArray->get(i)); if (!EncodingTraits::decodeValue(encodedElement, decodedValue.at(i))) return false; } return true; } }; template<> struct EncodingTraits { typedef EncodedValue DecodedType; // We should never attempt to decode or encode an encoded value, // so encodeValue and decodeValue are intentionally omitted here. }; // Specialize byte vectors to use base64 encoding. template<> struct EncodingTraits> { typedef Vector DecodedType; static EncodedValue encodeValue(const DecodedType&); static bool decodeValue(EncodedValue&, DecodedType&); }; template struct ScalarEncodingTraits { typedef T DecodedType; static JS_EXPORT_PRIVATE EncodedValue encodeValue(const DecodedType& decodedValue); static bool decodeValue(EncodedValue& encodedValue, DecodedType& decodedValue) { decodedValue = encodedValue.convertTo(); return true; } }; template<> struct EncodingTraits : public ScalarEncodingTraits { }; template<> struct EncodingTraits : public ScalarEncodingTraits { }; template<> struct EncodingTraits : public ScalarEncodingTraits { }; template<> struct EncodingTraits : public ScalarEncodingTraits { }; template<> struct EncodingTraits : public ScalarEncodingTraits { }; template<> struct EncodingTraits : public ScalarEncodingTraits { }; template<> struct EncodingTraits : public ScalarEncodingTraits { }; template<> struct EncodingTraits : public ScalarEncodingTraits { static EncodedValue encodeValue(const String& value) { return EncodedValue::createString(value); } }; // Base cases for loading and storing values. template<> JS_EXPORT_PRIVATE void EncodedValue::put(const String& key, const typename EncodingTraits::DecodedType&); template<> JS_EXPORT_PRIVATE void EncodedValue::append(const typename EncodingTraits::DecodedType&); template<> JS_EXPORT_PRIVATE bool EncodedValue::get(const String& key, typename EncodingTraits::DecodedType&); // Load and store types with an accompanying EncodingTraits implementation. template void EncodedValue::put(const String& key, const typename EncodingTraits::DecodedType& value) { EncodedValue encodedValue = EncodingTraits::encodeValue(value); put(key, encodedValue); } template void EncodedValue::append(const typename EncodingTraits::DecodedType& value) { EncodedValue encodedValue = EncodingTraits::encodeValue(value); append(encodedValue); } template bool EncodedValue::get(const String& key, typename EncodingTraits::DecodedType& decodedValue) { EncodedValue encodedValue; if (!get(key, encodedValue)) return false; return EncodingTraits::decodeValue(encodedValue, decodedValue); } template bool EncodedValue::get(const String& key, std::unique_ptr::DecodedType>& decodedValue) { EncodedValue encodedValue; if (!get(key, encodedValue)) return false; return EncodingTraits::decodeValue(encodedValue, decodedValue); } } // namespace JSC using JSC::EncodedValue; using JSC::EncodingTraits; #endif // ENABLE(WEB_REPLAY) #endif // EncodedValue_h