summaryrefslogtreecommitdiffstats
path: root/chrome/browser/debugger/debugger_io_socket.cc
blob: 30c5ac1de9f4dcf64daa76b13b05a9db802a42e0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/debugger/debugger_io_socket.h"

#include "base/string_util.h"
#include "base/thread.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/debugger/debugger_shell.h"
#include "v8/include/v8.h"

////////////////////////////////////////////////

DebuggerInputOutputSocket::DebuggerInputOutputSocket(int port)
    : server_(0), connection_(0), port_(port) {
  ui_loop_ = MessageLoop::current();
  io_loop_ = g_browser_process->io_thread()->message_loop();
}

void DebuggerInputOutputSocket::Start(DebuggerHost* debugger) {
  DebuggerInputOutput::Start(debugger);
  io_loop_->PostTask(FROM_HERE, NewRunnableMethod(
      this, &DebuggerInputOutputSocket::StartListening));
}

void DebuggerInputOutputSocket::StartListening() {
  DCHECK(MessageLoop::current() == io_loop_);
  server_ = TelnetServer::Listen("127.0.0.1", port_, this);
}

DebuggerInputOutputSocket::~DebuggerInputOutputSocket() {
  // Stop() must be called prior to this being called
  DCHECK(connection_.get() == NULL);
  DCHECK(server_.get() == NULL);
}

void DebuggerInputOutputSocket::Stop() {
  io_loop_->PostTask(FROM_HERE, NewRunnableMethod(
      this, &DebuggerInputOutputSocket::StopListening));
}

void DebuggerInputOutputSocket::StopListening() {
  connection_ = NULL;
  server_ = NULL;
}

void DebuggerInputOutputSocket::DidAccept(ListenSocket *server,
                                 ListenSocket *connection) {
  DCHECK(MessageLoop::current() == io_loop_);
  if (connection_ == NULL) {
    connection_ = connection;
    connection_->AddRef();
    ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(
        debugger_, &DebuggerHost::DidConnect));
  } else {
    delete connection;
  }
}

void DebuggerInputOutputSocket::Output(const std::wstring& out) {
  OutputLater(out, false);
}

void DebuggerInputOutputSocket::OutputLine(const std::wstring& out) {
  OutputLater(out, true);
}

void DebuggerInputOutputSocket::OutputPrompt(const std::wstring& prompt) {
  Output(prompt);
}

void DebuggerInputOutputSocket::Output(const std::string& out) {
  OutputLater(out, false);
}

void DebuggerInputOutputSocket::OutputLine(const std::string& out) {
  OutputLater(out, true);
}

void DebuggerInputOutputSocket::OutputPrompt(const std::string& prompt) {
  Output(prompt);
}

void DebuggerInputOutputSocket::OutputLater(const std::wstring& out, bool lf) {
  std::string utf8 = WideToUTF8(out);
  OutputLater(utf8, lf);
}

void DebuggerInputOutputSocket::OutputLater(const std::string& out, bool lf) {
  io_loop_->PostTask(FROM_HERE, NewRunnableMethod(
      this, &DebuggerInputOutputSocket::OutputToSocket, out, lf));
}

void DebuggerInputOutputSocket::OutputToSocket(const std::string& out, bool lf) {
  DCHECK(MessageLoop::current() == io_loop_);
  if (connection_) {
    if (out.length()) {
      connection_->Send(out, lf);
    }
  } else {
    logging::LogMessage("CONSOLE", 0).stream() << "V8 debugger: " << out;
  }
}

void DebuggerInputOutputSocket::DidRead(ListenSocket *connection,
                                     const std::string& data) {
  DCHECK(MessageLoop::current() == io_loop_);
  if (connection == connection_) {
    const std::wstring wstr = UTF8ToWide(data);
    ui_loop_->PostTask(FROM_HERE, NewRunnableMethod(
        debugger_, &DebuggerHost::ProcessCommand, wstr));
  } else {
    // TODO(erikkay): assert?
  }
}

void DebuggerInputOutputSocket::DidClose(ListenSocket *sock) {
  DCHECK(MessageLoop::current() == io_loop_);
  if (connection_ == sock) {
    connection_ = NULL;
    sock->Release();
  } else {
    // TODO(erikkay): assert?
  }
}