/* * Copyright (C) 2010, 2014-2015 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. AND ITS 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 APPLE INC. OR ITS 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 NetworkCacheCoders_h #define NetworkCacheCoders_h #if ENABLE(NETWORK_CACHE) #include "NetworkCacheDecoder.h" #include "NetworkCacheEncoder.h" #include #include #include #include #include #include #include namespace WebKit { namespace NetworkCache { template struct Coder> { static void encode(Encoder& encoder, const std::pair& pair) { encoder << pair.first << pair.second; } static bool decode(Decoder& decoder, std::pair& pair) { T first; if (!decoder.decode(first)) return false; U second; if (!decoder.decode(second)) return false; pair.first = first; pair.second = second; return true; } }; template struct Coder> { static void encode(Encoder& encoder, const std::chrono::duration& duration) { static_assert(std::is_integral::value && std::is_signed::value && sizeof(Rep) <= sizeof(int64_t), "Serialization of this Rep type is not supported yet. Only signed integer type which can be fit in an int64_t is currently supported."); encoder << static_cast(duration.count()); } static bool decode(Decoder& decoder, std::chrono::duration& result) { int64_t count; if (!decoder.decode(count)) return false; result = std::chrono::duration(static_cast(count)); return true; } }; template struct Coder> { static void encode(Encoder& encoder, const WTF::KeyValuePair& pair) { encoder << pair.key << pair.value; } static bool decode(Decoder& decoder, WTF::KeyValuePair& pair) { KeyType key; if (!decoder.decode(key)) return false; ValueType value; if (!decoder.decode(value)) return false; pair.key = key; pair.value = value; return true; } }; template struct VectorCoder; template struct VectorCoder { static void encode(Encoder& encoder, const Vector& vector) { encoder << static_cast(vector.size()); for (size_t i = 0; i < vector.size(); ++i) encoder << vector[i]; } static bool decode(Decoder& decoder, Vector& vector) { uint64_t size; if (!decoder.decode(size)) return false; Vector tmp; for (size_t i = 0; i < size; ++i) { T element; if (!decoder.decode(element)) return false; tmp.append(WTFMove(element)); } tmp.shrinkToFit(); vector.swap(tmp); return true; } }; template struct VectorCoder { static void encode(Encoder& encoder, const Vector& vector) { encoder << static_cast(vector.size()); encoder.encodeFixedLengthData(reinterpret_cast(vector.data()), vector.size() * sizeof(T), alignof(T)); } static bool decode(Decoder& decoder, Vector& vector) { uint64_t size; if (!decoder.decode(size)) return false; // Since we know the total size of the elements, we can allocate the vector in // one fell swoop. Before allocating we must however make sure that the decoder buffer // is big enough. if (!decoder.bufferIsLargeEnoughToContain(size)) return false; Vector temp; temp.resize(size); decoder.decodeFixedLengthData(reinterpret_cast(temp.data()), size * sizeof(T)); vector.swap(temp); return true; } }; template struct Coder> : VectorCoder::value, T, inlineCapacity> { }; template struct Coder> { typedef HashMap HashMapType; static void encode(Encoder& encoder, const HashMapType& hashMap) { encoder << static_cast(hashMap.size()); for (typename HashMapType::const_iterator it = hashMap.begin(), end = hashMap.end(); it != end; ++it) encoder << *it; } static bool decode(Decoder& decoder, HashMapType& hashMap) { uint64_t hashMapSize; if (!decoder.decode(hashMapSize)) return false; HashMapType tempHashMap; for (uint64_t i = 0; i < hashMapSize; ++i) { KeyArg key; MappedArg value; if (!decoder.decode(key)) return false; if (!decoder.decode(value)) return false; if (!tempHashMap.add(key, value).isNewEntry) { // The hash map already has the specified key, bail. return false; } } hashMap.swap(tempHashMap); return true; } }; template struct Coder> { typedef HashSet HashSetType; static void encode(Encoder& encoder, const HashSetType& hashSet) { encoder << static_cast(hashSet.size()); for (typename HashSetType::const_iterator it = hashSet.begin(), end = hashSet.end(); it != end; ++it) encoder << *it; } static bool decode(Decoder& decoder, HashSetType& hashSet) { uint64_t hashSetSize; if (!decoder.decode(hashSetSize)) return false; HashSetType tempHashSet; for (uint64_t i = 0; i < hashSetSize; ++i) { KeyArg key; if (!decoder.decode(key)) return false; if (!tempHashSet.add(key).isNewEntry) { // The hash map already has the specified key, bail. return false; } } hashSet.swap(tempHashSet); return true; } }; template<> struct Coder { static void encode(Encoder&, const AtomicString&); static bool decode(Decoder&, AtomicString&); }; template<> struct Coder { static void encode(Encoder&, const CString&); static bool decode(Decoder&, CString&); }; template<> struct Coder { static void encode(Encoder&, const String&); static bool decode(Decoder&, String&); }; template<> struct Coder { static void encode(Encoder&, const WebCore::CertificateInfo&); static bool decode(Decoder&, WebCore::CertificateInfo&); }; template<> struct Coder { static void encode(Encoder&, const SHA1::Digest&); static bool decode(Decoder&, SHA1::Digest&); }; } } #endif #endif