Diff
Modified: trunk/Source/WebCore/ChangeLog (137953 => 137954)
--- trunk/Source/WebCore/ChangeLog 2012-12-17 23:54:18 UTC (rev 137953)
+++ trunk/Source/WebCore/ChangeLog 2012-12-17 23:59:47 UTC (rev 137954)
@@ -1,3 +1,51 @@
+2012-12-17 Michael Pruett <[email protected]>
+
+ IndexedDB: Don't use strings to represent serialized values
+ https://bugs.webkit.org/show_bug.cgi?id=104354
+
+ Reviewed by Kentaro Hara.
+
+ Use Vector<uint8_t> rather than String to represent serialized values
+ in IndexedDB. This change is necessary to implement IndexedDB for JSC.
+
+ Tests: storage/indexeddb/*
+
+ * Modules/indexeddb/IDBBackingStore.cpp:
+ (WebCore::IDBBackingStore::getRecord):
+ (WebCore::IDBBackingStore::putRecord):
+ (WebCore::ObjectStoreKeyCursorImpl::value):
+ (WebCore::ObjectStoreKeyCursorImpl::ObjectStoreKeyCursorImpl):
+ (WebCore::ObjectStoreCursorImpl::value):
+ (ObjectStoreCursorImpl):
+ (WebCore::ObjectStoreCursorImpl::loadCurrentRow):
+ (WebCore::IndexKeyCursorImpl::value):
+ (WebCore::IndexCursorImpl::value):
+ (WebCore::IndexCursorImpl::IndexCursorImpl):
+ (IndexCursorImpl):
+ (WebCore::IndexCursorImpl::loadCurrentRow):
+ * Modules/indexeddb/IDBBackingStore.h:
+ (IDBBackingStore):
+ (Cursor):
+ * Modules/indexeddb/IDBCursorBackendImpl.cpp:
+ (WebCore::IDBCursorBackendImpl::CursorPrefetchIterationOperation::perform):
+ * Modules/indexeddb/IDBCursorBackendImpl.h:
+ (WebCore::IDBCursorBackendImpl::value):
+ * Modules/indexeddb/IDBIndexBackendImpl.cpp:
+ (WebCore::IDBIndexBackendImpl::IndexReferencedValueRetrievalOperation::perform):
+ * Modules/indexeddb/IDBObjectStoreBackendImpl.cpp:
+ (WebCore::IDBObjectStoreBackendImpl::ObjectStoreRetrievalOperation::perform):
+ (WebCore::IDBObjectStoreBackendImpl::ObjectStoreStorageOperation::perform):
+ * bindings/js/SerializedScriptValue.cpp:
+ (WebCore::SerializedScriptValue::SerializedScriptValue):
+ (WebCore):
+ * bindings/js/SerializedScriptValue.h:
+ * bindings/v8/SerializedScriptValue.cpp:
+ (WebCore::SerializedScriptValue::createFromWireBytes):
+ (WebCore):
+ (WebCore::SerializedScriptValue::toWireBytes):
+ * bindings/v8/SerializedScriptValue.h:
+ (SerializedScriptValue):
+
2012-12-17 Jaehun Lim <[email protected]>
Change SET_VAR, SET_BORDERVALUE_COLOR macro to require semicolon(;) at the end of the line
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBBackingStore.cpp (137953 => 137954)
--- trunk/Source/WebCore/Modules/indexeddb/IDBBackingStore.cpp 2012-12-17 23:54:18 UTC (rev 137953)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBBackingStore.cpp 2012-12-17 23:59:47 UTC (rev 137954)
@@ -766,7 +766,7 @@
return true;
}
-bool IDBBackingStore::getRecord(IDBBackingStore::Transaction* transaction, int64_t databaseId, int64_t objectStoreId, const IDBKey& key, String& record)
+bool IDBBackingStore::getRecord(IDBBackingStore::Transaction* transaction, int64_t databaseId, int64_t objectStoreId, const IDBKey& key, Vector<uint8_t>& record)
{
IDB_TRACE("IDBBackingStore::getRecord");
LevelDBTransaction* levelDBTransaction = IDBBackingStore::Transaction::levelDBTransactionFrom(transaction);
@@ -774,10 +774,11 @@
const Vector<char> leveldbKey = ObjectStoreDataKey::encode(databaseId, objectStoreId, key);
Vector<char> data;
+ record.clear();
+
bool found = false;
bool ok = levelDBTransaction->safeGet(leveldbKey, data, found);
if (!ok) {
- record = String();
InternalError(IDBLevelDBBackingStoreReadErrorGetRecord);
return false;
}
@@ -786,11 +787,10 @@
const char* p = decodeVarInt(data.begin(), data.end(), version);
if (!p) {
InternalError(IDBLevelDBBackingStoreReadErrorGetRecord);
- record = String();
return false;
}
- record = decodeString(p, data.end());
+ record.appendRange(p, static_cast<const char*>(data.end()));
return true;
}
@@ -820,7 +820,7 @@
return true;
}
-bool IDBBackingStore::putRecord(IDBBackingStore::Transaction* transaction, int64_t databaseId, int64_t objectStoreId, const IDBKey& key, const String& value, RecordIdentifier* recordIdentifier)
+bool IDBBackingStore::putRecord(IDBBackingStore::Transaction* transaction, int64_t databaseId, int64_t objectStoreId, const IDBKey& key, const Vector<uint8_t>& value, RecordIdentifier* recordIdentifier)
{
IDB_TRACE("IDBBackingStore::putRecord");
ASSERT(key.isValid());
@@ -834,7 +834,7 @@
Vector<char> v;
v.append(encodeVarInt(version));
- v.append(encodeString(value));
+ v.appendVector(value);
levelDBTransaction->put(objectStoredataKey, v);
@@ -1389,7 +1389,7 @@
}
// IDBBackingStore::Cursor
- virtual String value() const { ASSERT_NOT_REACHED(); return String(); }
+ virtual const Vector<uint8_t>& value() const { ASSERT_NOT_REACHED(); return *new Vector<uint8_t>(); }
virtual bool loadCurrentRow();
private:
@@ -1402,7 +1402,6 @@
: IDBBackingStore::Cursor(other)
{
}
-
};
bool ObjectStoreKeyCursorImpl::loadCurrentRow()
@@ -1445,7 +1444,7 @@
}
// IDBBackingStore::Cursor
- virtual String value() const { return m_currentValue; }
+ virtual const Vector<uint8_t>& value() const { return m_currentValue; }
virtual bool loadCurrentRow();
private:
@@ -1460,7 +1459,7 @@
{
}
- String m_currentValue;
+ Vector<uint8_t> m_currentValue;
};
bool ObjectStoreCursorImpl::loadCurrentRow()
@@ -1487,7 +1486,8 @@
// FIXME: This re-encodes what was just decoded; try and optimize.
m_recordIdentifier.reset(encodeIDBKey(*m_currentKey), version);
- m_currentValue = decodeString(valuePosition, m_iterator->value().end());
+ m_currentValue.clear();
+ m_currentValue.appendRange(valuePosition, static_cast<const char*>(m_iterator->value().end()));
return true;
}
@@ -1505,7 +1505,7 @@
}
// IDBBackingStore::Cursor
- virtual String value() const { ASSERT_NOT_REACHED(); return String(); }
+ virtual const Vector<uint8_t>& value() const { ASSERT_NOT_REACHED(); return *new Vector<uint8_t>(); }
virtual PassRefPtr<IDBKey> primaryKey() const { return m_primaryKey; }
virtual const IDBBackingStore::RecordIdentifier& recordIdentifier() const { ASSERT_NOT_REACHED(); return m_recordIdentifier; }
virtual bool loadCurrentRow();
@@ -1584,7 +1584,7 @@
}
// IDBBackingStore::Cursor
- virtual String value() const { return m_value; }
+ virtual const Vector<uint8_t>& value() const { return m_currentValue; }
virtual PassRefPtr<IDBKey> primaryKey() const { return m_primaryKey; }
virtual const IDBBackingStore::RecordIdentifier& recordIdentifier() const { ASSERT_NOT_REACHED(); return m_recordIdentifier; }
bool loadCurrentRow();
@@ -1598,13 +1598,13 @@
IndexCursorImpl(const IndexCursorImpl* other)
: IDBBackingStore::Cursor(other)
, m_primaryKey(other->m_primaryKey)
- , m_value(other->m_value)
+ , m_currentValue(other->m_currentValue)
, m_primaryLevelDBKey(other->m_primaryLevelDBKey)
{
}
RefPtr<IDBKey> m_primaryKey;
- String m_value;
+ Vector<uint8_t> m_currentValue;
Vector<char> m_primaryLevelDBKey;
};
@@ -1653,7 +1653,8 @@
return false;
}
- m_value = decodeString(t, result.end());
+ m_currentValue.clear();
+ m_currentValue.appendRange(t, static_cast<const char*>(result.end()));
return true;
}
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBBackingStore.h (137953 => 137954)
--- trunk/Source/WebCore/Modules/indexeddb/IDBBackingStore.h 2012-12-17 23:54:18 UTC (rev 137953)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBBackingStore.h 2012-12-17 23:59:47 UTC (rev 137954)
@@ -77,8 +77,8 @@
int64_t m_version;
};
- virtual bool getRecord(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, const IDBKey&, String& record) WARN_UNUSED_RETURN;
- virtual bool putRecord(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, const IDBKey&, const String& value, RecordIdentifier*) WARN_UNUSED_RETURN;
+ virtual bool getRecord(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, const IDBKey&, Vector<uint8_t>& record) WARN_UNUSED_RETURN;
+ virtual bool putRecord(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, const IDBKey&, const Vector<uint8_t>& value, RecordIdentifier*) WARN_UNUSED_RETURN;
virtual void clearObjectStore(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId);
virtual void deleteRecord(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, const RecordIdentifier&);
virtual bool getKeyGeneratorCurrentNumber(IDBBackingStore::Transaction*, int64_t databaseId, int64_t objectStoreId, int64_t& currentNumber) WARN_UNUSED_RETURN;
@@ -115,7 +115,7 @@
virtual PassRefPtr<Cursor> clone() = 0;
virtual PassRefPtr<IDBKey> primaryKey() const { return m_currentKey; }
- virtual String value() const = 0;
+ virtual const Vector<uint8_t>& value() const = 0;
virtual const RecordIdentifier& recordIdentifier() const { return m_recordIdentifier; }
virtual ~Cursor() { }
virtual bool loadCurrentRow() = 0;
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBCursorBackendImpl.cpp (137953 => 137954)
--- trunk/Source/WebCore/Modules/indexeddb/IDBCursorBackendImpl.cpp 2012-12-17 23:54:18 UTC (rev 137953)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBCursorBackendImpl.cpp 2012-12-17 23:59:47 UTC (rev 137954)
@@ -209,14 +209,14 @@
foundPrimaryKeys.append(m_cursor->m_cursor->primaryKey());
if (m_cursor->m_cursorType != IDBCursorBackendInterface::IndexKeyCursor)
- foundValues.append(SerializedScriptValue::createFromWire(m_cursor->m_cursor->value()));
+ foundValues.append(SerializedScriptValue::createFromWireBytes(m_cursor->m_cursor->value()));
else
foundValues.append(SerializedScriptValue::create());
sizeEstimate += m_cursor->m_cursor->key()->sizeEstimate();
sizeEstimate += m_cursor->m_cursor->primaryKey()->sizeEstimate();
if (m_cursor->m_cursorType != IDBCursorBackendInterface::IndexKeyCursor)
- sizeEstimate += m_cursor->m_cursor->value().length() * sizeof(UChar);
+ sizeEstimate += m_cursor->m_cursor->value().size();
if (sizeEstimate > maxSizeEstimate)
break;
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBCursorBackendImpl.h (137953 => 137954)
--- trunk/Source/WebCore/Modules/indexeddb/IDBCursorBackendImpl.h 2012-12-17 23:54:18 UTC (rev 137953)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBCursorBackendImpl.h 2012-12-17 23:59:47 UTC (rev 137954)
@@ -67,7 +67,7 @@
PassRefPtr<IDBKey> key() const { return m_cursor->key(); }
PassRefPtr<IDBKey> primaryKey() const { return m_cursor->primaryKey(); }
- PassRefPtr<SerializedScriptValue> value() const { return (m_cursorType == IndexKeyCursor) ? 0 : SerializedScriptValue::createFromWire(m_cursor->value()); }
+ PassRefPtr<SerializedScriptValue> value() const { return (m_cursorType == IndexKeyCursor) ? 0 : SerializedScriptValue::createFromWireBytes(m_cursor->value()); }
void close();
private:
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBIndexBackendImpl.cpp (137953 => 137954)
--- trunk/Source/WebCore/Modules/indexeddb/IDBIndexBackendImpl.cpp 2012-12-17 23:54:18 UTC (rev 137953)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBIndexBackendImpl.cpp 2012-12-17 23:59:47 UTC (rev 137954)
@@ -237,22 +237,22 @@
return;
}
- String value;
+ Vector<uint8_t> value;
ok = m_index->backingStore()->getRecord(transaction->backingStoreTransaction(), m_index->databaseId(), m_index->m_objectStoreBackend->id(), *primaryKey, value);
if (!ok) {
m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error in getRecord."));
return;
}
- if (value.isNull()) {
+ if (value.isEmpty()) {
m_callbacks->onSuccess();
return;
}
if (m_index->m_objectStoreBackend->autoIncrement() && !m_index->m_objectStoreBackend->keyPath().isNull()) {
- m_callbacks->onSuccess(SerializedScriptValue::createFromWire(value), primaryKey, m_index->m_objectStoreBackend->keyPath());
+ m_callbacks->onSuccess(SerializedScriptValue::createFromWireBytes(value), primaryKey, m_index->m_objectStoreBackend->keyPath());
return;
}
- m_callbacks->onSuccess(SerializedScriptValue::createFromWire(value));
+ m_callbacks->onSuccess(SerializedScriptValue::createFromWireBytes(value));
}
Modified: trunk/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp (137953 => 137954)
--- trunk/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp 2012-12-17 23:54:18 UTC (rev 137953)
+++ trunk/Source/WebCore/Modules/indexeddb/IDBObjectStoreBackendImpl.cpp 2012-12-17 23:59:47 UTC (rev 137954)
@@ -308,22 +308,22 @@
key = backingStoreCursor->key();
}
- String wireData;
+ Vector<uint8_t> wireData;
bool ok = m_objectStore->backingStore()->getRecord(transaction->backingStoreTransaction(), m_objectStore->databaseId(), m_objectStore->id(), *key, wireData);
if (!ok) {
m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error in getRecord."));
return;
}
- if (wireData.isNull()) {
+ if (wireData.isEmpty()) {
m_callbacks->onSuccess();
return;
}
if (m_objectStore->autoIncrement() && !m_objectStore->keyPath().isNull()) {
- m_callbacks->onSuccess(SerializedScriptValue::createFromWire(wireData), key, m_objectStore->keyPath());
+ m_callbacks->onSuccess(SerializedScriptValue::createFromWireBytes(wireData), key, m_objectStore->keyPath());
return;
}
- m_callbacks->onSuccess(SerializedScriptValue::createFromWire(wireData));
+ m_callbacks->onSuccess(SerializedScriptValue::createFromWireBytes(wireData));
}
void IDBObjectStoreBackendImpl::put(PassRefPtr<SerializedScriptValue> value, PassRefPtr<IDBKey> key, PutMode putMode, PassRefPtr<IDBCallbacks> prpCallbacks, IDBTransactionBackendInterface* transactionPtr, const Vector<int64_t>& indexIds, const Vector<IndexKeys>& indexKeys)
@@ -560,7 +560,7 @@
// Before this point, don't do any mutation. After this point, rollback the transaction in case of error.
- backingStoreSuccess = m_objectStore->backingStore()->putRecord(transaction->backingStoreTransaction(), m_objectStore->databaseId(), m_objectStore->id(), *m_key, m_value->toWireString(), &recordIdentifier);
+ backingStoreSuccess = m_objectStore->backingStore()->putRecord(transaction->backingStoreTransaction(), m_objectStore->databaseId(), m_objectStore->id(), *m_key, m_value->toWireBytes(), &recordIdentifier);
if (!backingStoreSuccess) {
m_callbacks->onError(IDBDatabaseError::create(IDBDatabaseException::UnknownError, "Internal error: backing store error performing put/add."));
return;
Modified: trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp (137953 => 137954)
--- trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp 2012-12-17 23:54:18 UTC (rev 137953)
+++ trunk/Source/WebCore/bindings/js/SerializedScriptValue.cpp 2012-12-17 23:59:47 UTC (rev 137954)
@@ -1003,18 +1003,6 @@
class CloneDeserializer : CloneBase {
public:
- static String toWireString(const Vector<unsigned char>& value)
- {
- const uint8_t* start = value.begin();
- const uint8_t* end = value.end();
- const uint32_t length = value.size() / sizeof(UChar);
- String str;
- if (!CloneDeserializer::readString(start, end, str, length))
- return String();
-
- return String(str.impl());
- }
-
static String deserializeString(const Vector<uint8_t>& buffer)
{
const uint8_t* ptr = buffer.begin();
@@ -1750,6 +1738,11 @@
{
}
+SerializedScriptValue::SerializedScriptValue(const Vector<uint8_t>& buffer)
+ : m_data(buffer)
+{
+}
+
SerializedScriptValue::SerializedScriptValue(Vector<uint8_t>& buffer)
{
m_data.swap(buffer);
@@ -1853,19 +1846,6 @@
}
#endif
-String SerializedScriptValue::toWireString() const
-{
- return CloneDeserializer::toWireString(m_data);
-}
-
-PassRefPtr<SerializedScriptValue> SerializedScriptValue::createFromWire(const String& value)
-{
- Vector<uint8_t> buffer;
- if (!writeLittleEndian(buffer, value.impl()->characters(), value.length()))
- return 0;
- return adoptRef(new SerializedScriptValue(buffer));
-}
-
PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(JSContextRef originContext, JSValueRef apiValue,
MessagePortArray* messagePorts, ArrayBufferArray* arrayBuffers,
JSValueRef* exception)
Modified: trunk/Source/WebCore/bindings/js/SerializedScriptValue.h (137953 => 137954)
--- trunk/Source/WebCore/bindings/js/SerializedScriptValue.h 2012-12-17 23:54:18 UTC (rev 137953)
+++ trunk/Source/WebCore/bindings/js/SerializedScriptValue.h 2012-12-17 23:59:47 UTC (rev 137954)
@@ -104,8 +104,11 @@
JSC::JSValue deserialize(JSC::ExecState*, JSC::JSGlobalObject*);
#endif
- static PassRefPtr<SerializedScriptValue> createFromWire(const String& data);
- String toWireString() const;
+ static PassRefPtr<SerializedScriptValue> createFromWireBytes(const Vector<uint8_t>& data)
+ {
+ return adoptRef(new SerializedScriptValue(data));
+ }
+ const Vector<uint8_t>& toWireBytes() const { return m_data; }
~SerializedScriptValue();
@@ -115,6 +118,7 @@
static bool serializationDidCompleteSuccessfully(SerializationReturnCode);
static PassOwnPtr<ArrayBufferContentsArray> transferArrayBuffers(ArrayBufferArray&, SerializationReturnCode&);
+ SerializedScriptValue(const Vector<unsigned char>&);
SerializedScriptValue(Vector<unsigned char>&);
SerializedScriptValue(Vector<unsigned char>&, Vector<String>& blobURLs);
SerializedScriptValue(Vector<unsigned char>&, Vector<String>& blobURLs, PassOwnPtr<ArrayBufferContentsArray>);
Modified: trunk/Source/WebCore/bindings/v8/SerializedScriptValue.cpp (137953 => 137954)
--- trunk/Source/WebCore/bindings/v8/SerializedScriptValue.cpp 2012-12-17 23:54:18 UTC (rev 137953)
+++ trunk/Source/WebCore/bindings/v8/SerializedScriptValue.cpp 2012-12-17 23:59:47 UTC (rev 137954)
@@ -64,6 +64,7 @@
#include <wtf/ArrayBuffer.h>
#include <wtf/ArrayBufferView.h>
#include <wtf/Assertions.h>
+#include <wtf/ByteOrder.h>
#include <wtf/Float32Array.h>
#include <wtf/Float64Array.h>
#include <wtf/Int16Array.h>
@@ -2249,6 +2250,20 @@
return adoptRef(new SerializedScriptValue(data));
}
+PassRefPtr<SerializedScriptValue> SerializedScriptValue::createFromWireBytes(const Vector<uint8_t>& data)
+{
+ // Decode wire data from big endian to host byte order.
+ ASSERT(!(data.size() % sizeof(UChar)));
+ size_t length = data.size() / sizeof(UChar);
+ Vector<UChar> buffer(length);
+ const UChar* src = "" UChar*>(data.data());
+ UChar* dst = buffer.data();
+ for (size_t i = 0; i < length; i++)
+ dst[i] = ntohs(src[i]);
+
+ return createFromWire(String::adopt(buffer));
+}
+
PassRefPtr<SerializedScriptValue> SerializedScriptValue::create(const String& data, v8::Isolate* isolate)
{
Writer writer(isolate);
@@ -2297,6 +2312,20 @@
return adoptRef(new SerializedScriptValue(wireData));
}
+Vector<uint8_t> SerializedScriptValue::toWireBytes() const
+{
+ // Convert serialized string to big endian wire data.
+ size_t length = m_data.length();
+ Vector<uint8_t> result(length * sizeof(UChar));
+
+ const UChar* src = ""
+ UChar* dst = reinterpret_cast<UChar*>(result.data());
+ for (size_t i = 0; i < length; i++)
+ dst[i] = htons(src[i]);
+
+ return result;
+}
+
PassRefPtr<SerializedScriptValue> SerializedScriptValue::release()
{
RefPtr<SerializedScriptValue> result = adoptRef(new SerializedScriptValue(m_data));
Modified: trunk/Source/WebCore/bindings/v8/SerializedScriptValue.h (137953 => 137954)
--- trunk/Source/WebCore/bindings/v8/SerializedScriptValue.h 2012-12-17 23:54:18 UTC (rev 137953)
+++ trunk/Source/WebCore/bindings/v8/SerializedScriptValue.h 2012-12-17 23:59:47 UTC (rev 137954)
@@ -57,6 +57,7 @@
bool& didThrow, v8::Isolate* = 0);
static PassRefPtr<SerializedScriptValue> create(v8::Handle<v8::Value>, v8::Isolate* = 0);
static PassRefPtr<SerializedScriptValue> createFromWire(const String& data);
+ static PassRefPtr<SerializedScriptValue> createFromWireBytes(const Vector<uint8_t>& data);
static PassRefPtr<SerializedScriptValue> create(const String& data, v8::Isolate* = 0);
static PassRefPtr<SerializedScriptValue> create();
@@ -70,6 +71,7 @@
PassRefPtr<SerializedScriptValue> release();
String toWireString() const { return m_data; }
+ Vector<uint8_t> toWireBytes() const;
// Deserializes the value (in the current context). Returns a null value in
// case of failure.