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