Diff
Modified: trunk/Source/WebCore/ChangeLog (108220 => 108221)
--- trunk/Source/WebCore/ChangeLog 2012-02-20 08:45:21 UTC (rev 108220)
+++ trunk/Source/WebCore/ChangeLog 2012-02-20 08:59:42 UTC (rev 108221)
@@ -1,3 +1,51 @@
+2012-02-20 Kenichi Ishibashi <[email protected]>
+
+ [WebSocket] Add deflater/inflater classes
+ https://bugs.webkit.org/show_bug.cgi?id=78449
+
+ Add WebSocketDeflater/WebSocketInflater classes which wrap zlib
+ functions. These classes are not used yet, but will be used for
+ supporting WebSocket deflate-frame extension.
+
+ This patch is second try. The previous patch broke Chromium Win
+ build. I added dependency of zlib to WebCore.gyp. I think it's
+ OK because Chromium already depends on zlib.
+
+ Reviewed by Kent Tamura.
+
+ No new tests except for chromium port. Behavior is unchanged.
+
+ * GNUmakefile.list.am: Added WebSocketDeflater.(cpp|h).
+ * WebCore.gyp/WebCore.gyp: Added zlib dependency.
+ * WebCore.gypi: Added WebSocketDeflater.(cpp|h).
+ * WebCore.vcproj/WebCore.vcproj: Ditto.
+ * WebCore.xcodeproj/project.pbxproj: Ditto.
+ * websockets/WebSocketDeflater.cpp: Added.
+ (WebCore):
+ (WebCore::WebSocketDeflater::create):
+ (WebCore::WebSocketDeflater::WebSocketDeflater):
+ (WebCore::WebSocketDeflater::initialize):
+ (WebCore::WebSocketDeflater::~WebSocketDeflater):
+ (WebCore::setStreamParameter):
+ (WebCore::WebSocketDeflater::addBytes):
+ (WebCore::WebSocketDeflater::finish):
+ (WebCore::WebSocketDeflater::reset):
+ (WebCore::WebSocketInflater::create):
+ (WebCore::WebSocketInflater::WebSocketInflater):
+ (WebCore::WebSocketInflater::initialize):
+ (WebCore::WebSocketInflater::~WebSocketInflater):
+ (WebCore::WebSocketInflater::addBytes):
+ (WebCore::WebSocketInflater::finish):
+ (WebCore::WebSocketInflater::reset):
+ * websockets/WebSocketDeflater.h: Added.
+ (WebCore):
+ (WebSocketDeflater):
+ (WebCore::WebSocketDeflater::data):
+ (WebCore::WebSocketDeflater::size):
+ (WebSocketInflater):
+ (WebCore::WebSocketInflater::data):
+ (WebCore::WebSocketInflater::size):
+
2012-02-20 [email protected] <[email protected]>
Web Inspector: consume undo/redo shortcuts.
Modified: trunk/Source/WebCore/GNUmakefile.list.am (108220 => 108221)
--- trunk/Source/WebCore/GNUmakefile.list.am 2012-02-20 08:45:21 UTC (rev 108220)
+++ trunk/Source/WebCore/GNUmakefile.list.am 2012-02-20 08:59:42 UTC (rev 108221)
@@ -4332,6 +4332,8 @@
Source/WebCore/websockets/WebSocketChannel.h \
Source/WebCore/websockets/WebSocket.cpp \
Source/WebCore/websockets/WebSocket.h \
+ Source/WebCore/websockets/WebSocketDeflater.cpp \
+ Source/WebCore/websockets/WebSocketDeflater.h \
Source/WebCore/websockets/WebSocketExtensionDispatcher.cpp \
Source/WebCore/websockets/WebSocketExtensionDispatcher.h \
Source/WebCore/websockets/WebSocketExtensionProcessor.h \
Modified: trunk/Source/WebCore/WebCore.gyp/WebCore.gyp (108220 => 108221)
--- trunk/Source/WebCore/WebCore.gyp/WebCore.gyp 2012-02-20 08:45:21 UTC (rev 108220)
+++ trunk/Source/WebCore/WebCore.gyp/WebCore.gyp 2012-02-20 08:59:42 UTC (rev 108221)
@@ -1172,6 +1172,7 @@
'<(chromium_src_dir)/third_party/ots/ots.gyp:ots',
'<(chromium_src_dir)/third_party/sqlite/sqlite.gyp:sqlite',
'<(chromium_src_dir)/third_party/angle/src/build_angle.gyp:translator_glsl',
+ '<(chromium_src_dir)/third_party/zlib/zlib.gyp:zlib',
'<(chromium_src_dir)/v8/tools/gyp/v8.gyp:v8',
'<(libjpeg_gyp_path):libjpeg',
],
Modified: trunk/Source/WebCore/WebCore.gypi (108220 => 108221)
--- trunk/Source/WebCore/WebCore.gypi 2012-02-20 08:45:21 UTC (rev 108220)
+++ trunk/Source/WebCore/WebCore.gypi 2012-02-20 08:59:42 UTC (rev 108221)
@@ -4811,6 +4811,8 @@
'websockets/WebSocketChannel.cpp',
'websockets/WebSocketChannel.h',
'websockets/WebSocketChannelClient.h',
+ 'websockets/WebSocketDeflater.cpp',
+ 'websockets/WebSocketDeflater.h',
'websockets/WebSocketExtensionDispatcher.cpp',
'websockets/WebSocketExtensionDispatcher.h',
'websockets/WebSocketExtensionProcessor.h',
Modified: trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj (108220 => 108221)
--- trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj 2012-02-20 08:45:21 UTC (rev 108220)
+++ trunk/Source/WebCore/WebCore.vcproj/WebCore.vcproj 2012-02-20 08:59:42 UTC (rev 108221)
@@ -73438,6 +73438,14 @@
>
</File>
<File
+ RelativePath="..\websockets\WebSocketDeflater.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\websockets\WebSocketDeflater.h"
+ >
+ </File>
+ <File
RelativePath="..\websockets\WebSocketExtensionDispatcher.cpp"
>
</File>
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (108220 => 108221)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2012-02-20 08:45:21 UTC (rev 108220)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2012-02-20 08:59:42 UTC (rev 108221)
@@ -1386,6 +1386,8 @@
4AD0173C127E82860015035F /* JSHTMLOutputElement.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4AD0173A127E82860015035F /* JSHTMLOutputElement.cpp */; };
4AD0173D127E82860015035F /* JSHTMLOutputElement.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AD0173B127E82860015035F /* JSHTMLOutputElement.h */; };
4ADE25FA14E3BB4C004C2213 /* WebSocketExtensionProcessor.h in Headers */ = {isa = PBXBuildFile; fileRef = 4ADE25F914E3BB4C004C2213 /* WebSocketExtensionProcessor.h */; };
+ 4AE02ABD14E8A9D200BC3BA7 /* WebSocketDeflater.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4AE02ABB14E8A9D200BC3BA7 /* WebSocketDeflater.cpp */; };
+ 4AE02ABE14E8A9D200BC3BA7 /* WebSocketDeflater.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AE02ABC14E8A9D200BC3BA7 /* WebSocketDeflater.h */; };
4AF1AD3E13FD23A400AA9590 /* EventDispatchMediator.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4AF1AD3C13FD23A400AA9590 /* EventDispatchMediator.cpp */; };
4AF1AD3F13FD23A400AA9590 /* EventDispatchMediator.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AF1AD3D13FD23A400AA9590 /* EventDispatchMediator.h */; settings = {ATTRIBUTES = (Private, ); }; };
4B2708C70AF19EE40065127F /* Pasteboard.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B2708C50AF19EE40065127F /* Pasteboard.h */; };
@@ -8250,6 +8252,8 @@
4AD0173A127E82860015035F /* JSHTMLOutputElement.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSHTMLOutputElement.cpp; sourceTree = "<group>"; };
4AD0173B127E82860015035F /* JSHTMLOutputElement.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSHTMLOutputElement.h; sourceTree = "<group>"; };
4ADE25F914E3BB4C004C2213 /* WebSocketExtensionProcessor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebSocketExtensionProcessor.h; sourceTree = "<group>"; };
+ 4AE02ABB14E8A9D200BC3BA7 /* WebSocketDeflater.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebSocketDeflater.cpp; sourceTree = "<group>"; };
+ 4AE02ABC14E8A9D200BC3BA7 /* WebSocketDeflater.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebSocketDeflater.h; sourceTree = "<group>"; };
4AF1AD3C13FD23A400AA9590 /* EventDispatchMediator.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EventDispatchMediator.cpp; sourceTree = "<group>"; };
4AF1AD3D13FD23A400AA9590 /* EventDispatchMediator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventDispatchMediator.h; sourceTree = "<group>"; };
4B2708C50AF19EE40065127F /* Pasteboard.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Pasteboard.h; sourceTree = "<group>"; };
@@ -14838,6 +14842,8 @@
510D4A47103177A20049EA54 /* WebSocketChannel.cpp */,
510D4A48103177A20049EA54 /* WebSocketChannel.h */,
510D4A49103177A20049EA54 /* WebSocketChannelClient.h */,
+ 4AE02ABB14E8A9D200BC3BA7 /* WebSocketDeflater.cpp */,
+ 4AE02ABC14E8A9D200BC3BA7 /* WebSocketDeflater.h */,
4A957F0314E241100049DBFB /* WebSocketExtensionDispatcher.cpp */,
4A957F0414E241100049DBFB /* WebSocketExtensionDispatcher.h */,
4ADE25F914E3BB4C004C2213 /* WebSocketExtensionProcessor.h */,
@@ -24203,6 +24209,7 @@
518A34C21026C831001B6896 /* WebSocket.h in Headers */,
510D4A4F103177A20049EA54 /* WebSocketChannel.h in Headers */,
510D4A50103177A20049EA54 /* WebSocketChannelClient.h in Headers */,
+ 4AE02ABE14E8A9D200BC3BA7 /* WebSocketDeflater.h in Headers */,
4A957F0714E241300049DBFB /* WebSocketExtensionDispatcher.h in Headers */,
4ADE25FA14E3BB4C004C2213 /* WebSocketExtensionProcessor.h in Headers */,
51ABAE451043AB4A008C5260 /* WebSocketHandshake.h in Headers */,
@@ -27159,6 +27166,7 @@
518A34C11026C831001B6896 /* WebSocket.cpp in Sources */,
510D4A4E103177A20049EA54 /* WebSocketChannel.cpp in Sources */,
4A957F0614E2412A0049DBFB /* WebSocketExtensionDispatcher.cpp in Sources */,
+ 4AE02ABD14E8A9D200BC3BA7 /* WebSocketDeflater.cpp in Sources */,
51ABAE441043AB4A008C5260 /* WebSocketHandshake.cpp in Sources */,
7637C541112E7B74003D6CDC /* WebSocketHandshakeRequest.cpp in Sources */,
767F99BE11A1194A0080C51D /* WebSocketHandshakeResponse.cpp in Sources */,
Added: trunk/Source/WebCore/websockets/WebSocketDeflater.cpp (0 => 108221)
--- trunk/Source/WebCore/websockets/WebSocketDeflater.cpp (rev 0)
+++ trunk/Source/WebCore/websockets/WebSocketDeflater.cpp 2012-02-20 08:59:42 UTC (rev 108221)
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2012 Google 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * 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
+ * OWNER 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"
+
+#if ENABLE(WEB_SOCKETS)
+
+#include "WebSocketDeflater.h"
+
+#include "Logging.h"
+#include <wtf/FastMalloc.h>
+#include <wtf/HashMap.h>
+#include <wtf/StdLibExtras.h>
+#include <wtf/StringExtras.h>
+#include <wtf/text/StringHash.h>
+#include <wtf/text/WTFString.h>
+
+namespace WebCore {
+
+static const int defaultMemLevel = 1;
+static const size_t bufferIncrementUnit = 4096;
+
+PassOwnPtr<WebSocketDeflater> WebSocketDeflater::create(int windowBits, ContextTakeOverMode contextTakeOverMode)
+{
+ return adoptPtr(new WebSocketDeflater(windowBits, contextTakeOverMode));
+}
+
+WebSocketDeflater::WebSocketDeflater(int windowBits, ContextTakeOverMode contextTakeOverMode)
+ : m_windowBits(windowBits)
+ , m_contextTakeOverMode(contextTakeOverMode)
+{
+ ASSERT(m_windowBits >= 8);
+ ASSERT(m_windowBits <= 15);
+ memset(&m_stream, 0, sizeof(z_stream));
+}
+
+bool WebSocketDeflater::initialize()
+{
+ return deflateInit2(&m_stream, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -m_windowBits, defaultMemLevel, Z_DEFAULT_STRATEGY) == Z_OK;
+}
+
+WebSocketDeflater::~WebSocketDeflater()
+{
+ int result = deflateEnd(&m_stream);
+ if (result != Z_OK)
+ LOG(Network, "deflateEnd() failed: %d", result);
+}
+
+static void setStreamParameter(z_stream& stream, const char* inputData, size_t inputLength, char* outputData, size_t outputLength)
+{
+ stream.next_in = reinterpret_cast<Bytef*>(const_cast<char*>(inputData));
+ stream.avail_in = inputLength;
+ stream.next_out = reinterpret_cast<Bytef*>(outputData);
+ stream.avail_out = outputLength;
+}
+
+bool WebSocketDeflater::addBytes(const char* data, size_t length)
+{
+ if (!length)
+ return false;
+
+ size_t maxLength = deflateBound(&m_stream, length);
+ size_t writePosition = m_buffer.size();
+ m_buffer.grow(writePosition + maxLength);
+ setStreamParameter(m_stream, data, length, m_buffer.data() + writePosition, maxLength);
+ int result = deflate(&m_stream, Z_NO_FLUSH);
+ if (result != Z_OK || m_stream.avail_in > 0)
+ return false;
+
+ m_buffer.shrink(writePosition + maxLength - m_stream.avail_out);
+ return true;
+}
+
+bool WebSocketDeflater::finish()
+{
+ while (true) {
+ size_t writePosition = m_buffer.size();
+ m_buffer.grow(writePosition + bufferIncrementUnit);
+ size_t availableCapacity = m_buffer.size() - writePosition;
+ setStreamParameter(m_stream, 0, 0, m_buffer.data() + writePosition, availableCapacity);
+ int result = deflate(&m_stream, Z_SYNC_FLUSH);
+ m_buffer.shrink(writePosition + availableCapacity - m_stream.avail_out);
+ if (result == Z_OK)
+ break;
+ if (result != Z_BUF_ERROR)
+ return false;
+ }
+ // Remove 4 octets from the tail as the specification requires.
+ if (m_buffer.size() <= 4)
+ return false;
+ m_buffer.resize(m_buffer.size() - 4);
+ return true;
+}
+
+void WebSocketDeflater::reset()
+{
+ m_buffer.clear();
+ if (m_contextTakeOverMode == DoNotTakeOverContext)
+ deflateReset(&m_stream);
+}
+
+PassOwnPtr<WebSocketInflater> WebSocketInflater::create(int windowBits)
+{
+ return adoptPtr(new WebSocketInflater(windowBits));
+}
+
+WebSocketInflater::WebSocketInflater(int windowBits)
+ : m_windowBits(windowBits)
+{
+ memset(&m_stream, 0, sizeof(z_stream));
+}
+
+bool WebSocketInflater::initialize()
+{
+ return inflateInit2(&m_stream, -m_windowBits) == Z_OK;
+}
+
+WebSocketInflater::~WebSocketInflater()
+{
+ int result = inflateEnd(&m_stream);
+ if (result != Z_OK)
+ LOG(Network, "inflateEnd() failed: %d", result);
+}
+
+bool WebSocketInflater::addBytes(const char* data, size_t length)
+{
+ if (!length)
+ return false;
+
+ size_t consumedSoFar = 0;
+ while (consumedSoFar < length) {
+ size_t writePosition = m_buffer.size();
+ m_buffer.grow(writePosition + bufferIncrementUnit);
+ size_t availableCapacity = m_buffer.size() - writePosition;
+ size_t remainingLength = length - consumedSoFar;
+ setStreamParameter(m_stream, data + consumedSoFar, remainingLength, m_buffer.data() + writePosition, availableCapacity);
+ int result = inflate(&m_stream, Z_NO_FLUSH);
+ consumedSoFar += remainingLength - m_stream.avail_in;
+ m_buffer.shrink(writePosition + availableCapacity - m_stream.avail_out);
+ if (result == Z_BUF_ERROR)
+ continue;
+ if (result != Z_OK)
+ return false;
+ }
+ ASSERT(consumedSoFar == length);
+ return true;
+}
+
+bool WebSocketInflater::finish()
+{
+ static const char* strippedFields = "\0\0\xff\xff";
+ static const size_t strippedLength = 4;
+
+ // Appends 4 octests of 0x00 0x00 0xff 0xff
+ size_t consumedSoFar = 0;
+ while (consumedSoFar < strippedLength) {
+ size_t writePosition = m_buffer.size();
+ m_buffer.grow(writePosition + bufferIncrementUnit);
+ size_t availableCapacity = m_buffer.size() - writePosition;
+ size_t remainingLength = strippedLength - consumedSoFar;
+ setStreamParameter(m_stream, strippedFields + consumedSoFar, remainingLength, m_buffer.data() + writePosition, availableCapacity);
+ int result = inflate(&m_stream, Z_FINISH);
+ consumedSoFar += remainingLength - m_stream.avail_in;
+ m_buffer.shrink(writePosition + availableCapacity - m_stream.avail_out);
+ if (result == Z_BUF_ERROR)
+ continue;
+ if (result != Z_OK && result != Z_STREAM_END)
+ return false;
+ }
+ ASSERT(consumedSoFar == strippedLength);
+
+ return true;
+}
+
+void WebSocketInflater::reset()
+{
+ m_buffer.clear();
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(WEB_SOCKETS)
Added: trunk/Source/WebCore/websockets/WebSocketDeflater.h (0 => 108221)
--- trunk/Source/WebCore/websockets/WebSocketDeflater.h (rev 0)
+++ trunk/Source/WebCore/websockets/WebSocketDeflater.h 2012-02-20 08:59:42 UTC (rev 108221)
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2012 Google 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * 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.
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * 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
+ * OWNER 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 WebSocketDeflater_h
+#define WebSocketDeflater_h
+
+#if ENABLE(WEB_SOCKETS)
+
+#include <wtf/Noncopyable.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+#include <wtf/Vector.h>
+#include <zlib.h>
+
+namespace WebCore {
+
+class WebSocketDeflater {
+public:
+ enum ContextTakeOverMode {
+ DoNotTakeOverContext,
+ TakeOverContext
+ };
+ static PassOwnPtr<WebSocketDeflater> create(int windowBits, ContextTakeOverMode = TakeOverContext);
+
+ ~WebSocketDeflater();
+
+ bool initialize();
+ bool addBytes(const char*, size_t);
+ bool finish();
+ const char* data() { return m_buffer.data(); }
+ size_t size() const { return m_buffer.size(); }
+ void reset();
+
+private:
+ WebSocketDeflater(int windowBits, ContextTakeOverMode);
+
+ int m_windowBits;
+ ContextTakeOverMode m_contextTakeOverMode;
+ Vector<char> m_buffer;
+ z_stream m_stream;
+};
+
+class WebSocketInflater {
+public:
+ static PassOwnPtr<WebSocketInflater> create(int windowBits = 15);
+
+ ~WebSocketInflater();
+
+ bool initialize();
+ bool addBytes(const char*, size_t);
+ bool finish();
+ const char* data() { return m_buffer.data(); }
+ size_t size() const { return m_buffer.size(); }
+ void reset();
+
+private:
+ explicit WebSocketInflater(int windowBits);
+
+ int m_windowBits;
+ Vector<char> m_buffer;
+ z_stream m_stream;
+};
+
+}
+
+#endif // ENABLE(WEB_SOCKETS)
+
+#endif // WebSocketDeflater_h
Modified: trunk/Source/WebKit/chromium/ChangeLog (108220 => 108221)
--- trunk/Source/WebKit/chromium/ChangeLog 2012-02-20 08:45:21 UTC (rev 108220)
+++ trunk/Source/WebKit/chromium/ChangeLog 2012-02-20 08:59:42 UTC (rev 108221)
@@ -1,3 +1,19 @@
+2012-02-20 Kenichi Ishibashi <[email protected]>
+
+ [WebSocket] Add deflater/inflater classes
+ https://bugs.webkit.org/show_bug.cgi?id=78449
+
+ Add tests which ensure WebSocketDeflater/WebSocketInflater can
+ compress/decompress data correctly.
+
+ Reviewed by Kent Tamura.
+
+ * WebKit.gypi: Added zlib dependency.
+ * WebKitUnitTests.gyp: Ditto.
+ * tests/WebSocketDeflaterTest.cpp: Added.
+ (WebCore):
+ (WebCore::TEST):
+
2012-02-17 Yury Semikhatsky <[email protected]>
[Chromium] Web Inspector: terminated workers are not removed from dedicated worker list
Modified: trunk/Source/WebKit/chromium/WebKit.gypi (108220 => 108221)
--- trunk/Source/WebKit/chromium/WebKit.gypi 2012-02-20 08:45:21 UTC (rev 108220)
+++ trunk/Source/WebKit/chromium/WebKit.gypi 2012-02-20 08:59:42 UTC (rev 108221)
@@ -118,6 +118,7 @@
'tests/WebLayerTest.cpp',
'tests/WebPageNewSerializerTest.cpp',
'tests/WebPageSerializerTest.cpp',
+ 'tests/WebSocketDeflaterTest.cpp',
'tests/WebSocketExtensionDispatcherTest.cpp',
'tests/WebURLRequestTest.cpp',
'tests/WebURLResponseTest.cpp',
Modified: trunk/Source/WebKit/chromium/WebKitUnitTests.gyp (108220 => 108221)
--- trunk/Source/WebKit/chromium/WebKitUnitTests.gyp 2012-02-20 08:45:21 UTC (rev 108220)
+++ trunk/Source/WebKit/chromium/WebKitUnitTests.gyp 2012-02-20 08:59:42 UTC (rev 108221)
@@ -61,6 +61,7 @@
'<(chromium_src_dir)/base/base.gyp:base',
'<(chromium_src_dir)/base/base.gyp:base_i18n',
'<(chromium_src_dir)/base/base.gyp:test_support_base',
+ '<(chromium_src_dir)/third_party/zlib/zlib.gyp:zlib',
'<(chromium_src_dir)/webkit/support/webkit_support.gyp:webkit_support',
'<(chromium_src_dir)/webkit/support/webkit_support.gyp:webkit_user_agent',
],
Added: trunk/Source/WebKit/chromium/tests/WebSocketDeflaterTest.cpp (0 => 108221)
--- trunk/Source/WebKit/chromium/tests/WebSocketDeflaterTest.cpp (rev 0)
+++ trunk/Source/WebKit/chromium/tests/WebSocketDeflaterTest.cpp 2012-02-20 08:59:42 UTC (rev 108221)
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2012 Google 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 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 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.
+ */
+
+#include "config.h"
+
+#include "WebSocketDeflater.h"
+
+#include <gtest/gtest.h>
+#include <wtf/Vector.h>
+
+using namespace WebCore;
+
+namespace {
+
+TEST(WebSocketDeflaterTest, TestCompressHello)
+{
+ // Test the first example on section 4.3 of the specification.
+ OwnPtr<WebSocketDeflater> deflater = WebSocketDeflater::create(15);
+ ASSERT_TRUE(deflater->initialize());
+ OwnPtr<WebSocketInflater> inflater = WebSocketInflater::create();
+ ASSERT_TRUE(inflater->initialize());
+ const char* inputData = "Hello";
+ const size_t inputLength = strlen(inputData);
+
+ ASSERT_TRUE(deflater->addBytes(inputData, inputLength));
+ ASSERT_TRUE(deflater->finish());
+ const char expectedFirst[] = {0xf2, 0x48, 0xcd, 0xc9, 0xc9, 0x07, 0x00};
+ EXPECT_EQ(sizeof(expectedFirst), deflater->size());
+ EXPECT_EQ(0, memcmp(expectedFirst, deflater->data(), deflater->size()));
+ ASSERT_TRUE(inflater->addBytes(deflater->data(), deflater->size()));
+ ASSERT_TRUE(inflater->finish());
+ EXPECT_EQ(inputLength, inflater->size());
+ EXPECT_EQ(0, memcmp(inputData, inflater->data(), inflater->size()));
+
+ deflater->reset();
+ inflater->reset();
+
+ ASSERT_TRUE(deflater->addBytes(inputData, inputLength));
+ ASSERT_TRUE(deflater->finish());
+ const char expectedSecond[] = {0xf2, 0x00, 0x11, 0x00, 0x00};
+ EXPECT_EQ(sizeof(expectedSecond), deflater->size());
+ EXPECT_EQ(0, memcmp(expectedSecond, deflater->data(), deflater->size()));
+ ASSERT_TRUE(inflater->addBytes(deflater->data(), deflater->size()));
+ ASSERT_TRUE(inflater->finish());
+ EXPECT_EQ(inputLength, inflater->size());
+ EXPECT_EQ(0, memcmp(inputData, inflater->data(), inflater->size()));
+}
+
+TEST(WebSocketDeflaterTest, TestMultipleAddBytesCalls)
+{
+ OwnPtr<WebSocketDeflater> deflater = WebSocketDeflater::create(15);
+ ASSERT_TRUE(deflater->initialize());
+ OwnPtr<WebSocketInflater> inflater = WebSocketInflater::create();
+ ASSERT_TRUE(inflater->initialize());
+ Vector<char> inputData(32);
+ inputData.fill('a');
+
+ for (size_t i = 0; i < inputData.size(); ++i)
+ ASSERT_TRUE(deflater->addBytes(inputData.data() + i, 1));
+ ASSERT_TRUE(deflater->finish());
+ for (size_t i = 0; i < deflater->size(); ++i)
+ ASSERT_TRUE(inflater->addBytes(deflater->data() + i, 1));
+ ASSERT_TRUE(inflater->finish());
+ EXPECT_EQ(inputData.size(), inflater->size());
+ EXPECT_EQ(0, memcmp(inputData.data(), inflater->data(), inflater->size()));
+}
+
+TEST(WebSocketDeflaterTest, TestNoContextTakeOver)
+{
+ OwnPtr<WebSocketDeflater> deflater = WebSocketDeflater::create(15, WebSocketDeflater::DoNotTakeOverContext);
+ ASSERT_TRUE(deflater->initialize());
+ OwnPtr<WebSocketInflater> inflater = WebSocketInflater::create();
+ ASSERT_TRUE(inflater->initialize());
+ const char expected[] = {0xf2, 0x48, 0xcd, 0xc9, 0xc9, 0x07, 0x00};
+ const char* inputData = "Hello";
+ const size_t inputLength = strlen(inputData);
+
+ // If we don't take over context, the second result should be the identical
+ // with the first one.
+ for (size_t i = 0; i < 2; ++i) {
+ ASSERT_TRUE(deflater->addBytes(inputData, inputLength));
+ ASSERT_TRUE(deflater->finish());
+ EXPECT_EQ(sizeof(expected), deflater->size());
+ EXPECT_EQ(0, memcmp(expected, deflater->data(), deflater->size()));
+ ASSERT_TRUE(inflater->addBytes(deflater->data(), deflater->size()));
+ ASSERT_TRUE(inflater->finish());
+ EXPECT_EQ(inputLength, inflater->size());
+ EXPECT_EQ(0, memcmp(inputData, inflater->data(), inflater->size()));
+ deflater->reset();
+ inflater->reset();
+ }
+}
+
+TEST(WebSocketDeflaterTest, TestWindowBits)
+{
+ Vector<char> inputData(1024 + 64 * 2);
+ inputData.fill('a');
+ // Modify the head and tail of the inputData so that back-reference
+ // can be used if the window size is sufficiently-large.
+ for (size_t j = 0; j < 64; ++j) {
+ inputData[j] = 'b';
+ inputData[inputData.size() - j - 1] = 'b';
+ }
+
+ OwnPtr<WebSocketDeflater> deflater = WebSocketDeflater::create(8);
+ ASSERT_TRUE(deflater->initialize());
+ ASSERT_TRUE(deflater->addBytes(inputData.data(), inputData.size()));
+ ASSERT_TRUE(deflater->finish());
+
+ OwnPtr<WebSocketInflater> inflater = WebSocketInflater::create(8);
+ ASSERT_TRUE(inflater->initialize());
+ ASSERT_TRUE(inflater->addBytes(deflater->data(), deflater->size()));
+ ASSERT_TRUE(inflater->finish());
+ EXPECT_EQ(inputData.size(), inflater->size());
+ EXPECT_EQ(0, memcmp(inputData.data(), inflater->data(), inflater->size()));
+}
+
+TEST(WebSocketDeflaterTest, TestLargeData)
+{
+ OwnPtr<WebSocketDeflater> deflater = WebSocketDeflater::create(15);
+ ASSERT_TRUE(deflater->initialize());
+ OwnPtr<WebSocketInflater> inflater = WebSocketInflater::create();
+ ASSERT_TRUE(inflater->initialize());
+ Vector<char> inputData(16 * 1024 * 1024);
+ inputData.fill('a');
+
+ ASSERT_TRUE(deflater->addBytes(inputData.data(), inputData.size()));
+ ASSERT_TRUE(deflater->finish());
+ ASSERT_TRUE(inflater->addBytes(deflater->data(), deflater->size()));
+ ASSERT_TRUE(inflater->finish());
+ EXPECT_EQ(inputData.size(), inflater->size());
+ EXPECT_EQ(0, memcmp(inputData.data(), inflater->data(), inflater->size()));
+}
+
+}