1/* 2 * Copyright (C) 2013 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#ifndef KeyedCoding_h 27#define KeyedCoding_h 28 29#include <functional> 30#include <wtf/Forward.h> 31#include <wtf/Vector.h> 32 33namespace WebCore { 34 35class SharedBuffer; 36 37class KeyedDecoder { 38protected: 39 virtual ~KeyedDecoder() { } 40 41public: 42 virtual bool decodeBytes(const String& key, const uint8_t*&, size_t&) = 0; 43 virtual bool decodeBool(const String& key, bool&) = 0; 44 virtual bool decodeUInt32(const String& key, uint32_t&) = 0; 45 virtual bool decodeInt32(const String& key, int32_t&) = 0; 46 virtual bool decodeInt64(const String& key, int64_t&) = 0; 47 virtual bool decodeFloat(const String& key, float&) = 0; 48 virtual bool decodeDouble(const String& key, double&) = 0; 49 virtual bool decodeString(const String& key, String&) = 0; 50 51 template<typename T> 52 bool decodeBytes(const String& key, Vector<T>& vector) 53 { 54 static_assert(sizeof(T) == 1, ""); 55 56 size_t size; 57 const uint8_t* bytes; 58 if (!decodeBytes(key, bytes, size)) 59 return false; 60 61 vector.resize(size); 62 std::copy(bytes, bytes + size, vector.data()); 63 return true; 64 } 65 66 template<typename T, typename F> 67 bool decodeEnum(const String& key, T& value, F&& isValidEnumFunction) 68 { 69 static_assert(std::is_enum<T>::value, "T must be an enum type"); 70 71 int64_t intValue; 72 if (!decodeInt64(key, intValue)) 73 return false; 74 75 if (!isValidEnumFunction(static_cast<T>(intValue))) 76 return false; 77 78 value = static_cast<T>(intValue); 79 return true; 80 } 81 82 template<typename T, typename F> 83 bool decodeObject(const String& key, T& object, F&& function) 84 { 85 if (!beginObject(key)) 86 return false; 87 bool result = function(*this, object); 88 endObject(); 89 return result; 90 } 91 92 template<typename T, typename F> 93 bool decodeConditionalObject(const String& key, T& object, F&& function) 94 { 95 // FIXME: beginObject can return false for two reasons: either the 96 // key doesn't exist or the key refers to something that isn't an object. 97 // Because of this, decodeConditionalObject won't distinguish between a 98 // missing object or a value that isn't an object. 99 if (!beginObject(key)) 100 return true; 101 102 bool result = function(*this, object); 103 endObject(); 104 return result; 105 } 106 107 template<typename T, typename F> 108 bool decodeObjects(const String& key, Vector<T>& objects, F&& function) 109 { 110 if (!beginArray(key)) 111 return false; 112 113 bool result = true; 114 while (beginArrayElement()) { 115 T element; 116 if (!function(*this, element)) { 117 result = false; 118 break; 119 } 120 objects.append(WTF::move(element)); 121 endArrayElement(); 122 } 123 124 endArray(); 125 return result; 126 } 127 128private: 129 virtual bool beginObject(const String& key) = 0; 130 virtual void endObject() = 0; 131 132 virtual bool beginArray(const String& key) = 0; 133 virtual bool beginArrayElement() = 0; 134 virtual void endArrayElement() = 0; 135 virtual void endArray() = 0; 136}; 137 138class KeyedEncoder { 139protected: 140 virtual ~KeyedEncoder() { } 141 142public: 143 virtual void encodeBytes(const String& key, const uint8_t*, size_t) = 0; 144 virtual void encodeBool(const String& key, bool) = 0; 145 virtual void encodeUInt32(const String& key, uint32_t) = 0; 146 virtual void encodeInt32(const String& key, int32_t) = 0; 147 virtual void encodeInt64(const String& key, int64_t) = 0; 148 virtual void encodeFloat(const String& key, float) = 0; 149 virtual void encodeDouble(const String& key, double) = 0; 150 virtual void encodeString(const String& key, const String&) = 0; 151 152 virtual PassRefPtr<SharedBuffer> finishEncoding() = 0; 153 154 template<typename T> 155 void encodeEnum(const String& key, T value) 156 { 157 static_assert(std::is_enum<T>::value, "T must be an enum type"); 158 159 encodeInt64(key, static_cast<int64_t>(value)); 160 } 161 162 template<typename T, typename F> 163 void encodeObject(const String& key, const T& object, F&& function) 164 { 165 beginObject(key); 166 function(*this, object); 167 endObject(); 168 } 169 170 template<typename T, typename F> 171 void encodeConditionalObject(const String& key, const T* object, F&& function) 172 { 173 if (!object) 174 return; 175 176 encodeObject(key, *object, std::forward<F>(function)); 177 } 178 179 template<typename T, typename F> 180 void encodeObjects(const String& key, T begin, T end, F&& function) 181 { 182 beginArray(key); 183 for (T it = begin; it != end; ++it) { 184 beginArrayElement(); 185 function(*this, *it); 186 endArrayElement(); 187 } 188 endArray(); 189 } 190 191private: 192 virtual void beginObject(const String& key) = 0; 193 virtual void endObject() = 0; 194 195 virtual void beginArray(const String& key) = 0; 196 virtual void beginArrayElement() = 0; 197 virtual void endArrayElement() = 0; 198 virtual void endArray() = 0; 199}; 200 201} // namespace WebCore 202 203#endif // KeyedCoding_h 204