1231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block/* 2231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * Copyright (C) 2009 Google Inc. All rights reserved. 3231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * 4231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * Redistribution and use in source and binary forms, with or without 5231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * modification, are permitted provided that the following conditions are 6231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * met: 7231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * 8231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * * Redistributions of source code must retain the above copyright 9231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * notice, this list of conditions and the following disclaimer. 10231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * * Redistributions in binary form must reproduce the above 11231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * copyright notice, this list of conditions and the following disclaimer 12231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * in the documentation and/or other materials provided with the 13231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * distribution. 14231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * * Neither the name of Google Inc. nor the names of its 15231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * contributors may be used to endorse or promote products derived from 16231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * this software without specific prior written permission. 17231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * 18231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block */ 30231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 31231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "config.h" 32231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "SocketStreamHandleBase.h" 33231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 34643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "SocketStreamHandle.h" 35231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include "SocketStreamHandleClient.h" 36231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 37231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blocknamespace WebCore { 38231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 39231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockconst unsigned int bufferSize = 100 * 1024 * 1024; 40231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 41231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockSocketStreamHandleBase::SocketStreamHandleBase(const KURL& url, SocketStreamHandleClient* client) 42231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block : m_url(url) 43231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block , m_client(client) 44231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block , m_state(Connecting) 45231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 46231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 47231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 48231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockSocketStreamHandleBase::SocketStreamState SocketStreamHandleBase::state() const 49231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 50231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return m_state; 51231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 52231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 53231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockbool SocketStreamHandleBase::send(const char* data, int length) 54231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 55231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (m_state == Connecting) 56231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return false; 57231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!m_buffer.isEmpty()) { 58231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (m_buffer.size() + length > bufferSize) { 59231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // FIXME: report error to indicate that buffer has no more space. 60231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return false; 61231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 62231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_buffer.append(data, length); 63231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return true; 64231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 65231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block int bytesWritten = 0; 66231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (m_state == Open) 67231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block bytesWritten = platformSend(data, length); 68643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (bytesWritten < 0) 69231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return false; 70231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (m_buffer.size() + length - bytesWritten > bufferSize) { 71231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // FIXME: report error to indicate that buffer has no more space. 72231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return false; 73231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 74231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (bytesWritten < length) 75231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_buffer.append(data + bytesWritten, length - bytesWritten); 76231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return true; 77231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 78231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 79231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid SocketStreamHandleBase::close() 80231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 81643ca7872b450ea4efacab6188849e5aac2ba161Steve Block RefPtr<SocketStreamHandle> protect(static_cast<SocketStreamHandle*>(this)); // platformClose calls the client, which may make the handle get deallocated immediately. 82643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 83231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block platformClose(); 84231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_state = Closed; 85231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 86231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 87231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid SocketStreamHandleBase::setClient(SocketStreamHandleClient* client) 88231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 89231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(!client || (!m_client && m_state == Connecting)); 90231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_client = client; 91231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 92231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 93231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockbool SocketStreamHandleBase::sendPendingData() 94231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 95231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (m_state != Open) 96231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return false; 97231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (m_buffer.isEmpty()) 98231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return false; 99231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block int bytesWritten = platformSend(m_buffer.data(), m_buffer.size()); 100231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (bytesWritten <= 0) 101231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return false; 102231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block Vector<char> remainingData; 103231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block ASSERT(m_buffer.size() - bytesWritten <= bufferSize); 104231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block remainingData.append(m_buffer.data() + bytesWritten, m_buffer.size() - bytesWritten); 105231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block m_buffer.swap(remainingData); 106231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return true; 107231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 108231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 109231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} // namespace WebCore 110