File: fake_datagram_socket.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (151 lines) | stat: -rw-r--r-- 5,243 bytes parent folder | download | duplicates (7)
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef REMOTING_PROTOCOL_FAKE_DATAGRAM_SOCKET_H_
#define REMOTING_PROTOCOL_FAKE_DATAGRAM_SOCKET_H_

#include <map>
#include <memory>
#include <string>
#include <vector>

#include "base/memory/weak_ptr.h"
#include "net/base/completion_repeating_callback.h"
#include "remoting/protocol/datagram_channel_factory.h"
#include "remoting/protocol/p2p_datagram_socket.h"

namespace base {
class SingleThreadTaskRunner;
}

namespace remoting::protocol {

// FakeDatagramSocket implement P2PStreamSocket interface. All data written to
// FakeDatagramSocket is stored in a buffer returned by written_packets().
// Read() reads data from another buffer that can be set with
// AppendInputPacket(). Pending reads are supported, so if there is a pending
// read AppendInputPacket() calls the read callback.
//
// Two fake sockets can be connected to each other using the
// PairWith() method, e.g.: a->PairWith(b). After this all data
// written to |a| can be read from |b| and vice versa. Two connected
// sockets |a| and |b| must be created and used on the same thread.
class FakeDatagramSocket : public P2PDatagramSocket {
 public:
  FakeDatagramSocket();

  FakeDatagramSocket(const FakeDatagramSocket&) = delete;
  FakeDatagramSocket& operator=(const FakeDatagramSocket&) = delete;

  ~FakeDatagramSocket() override;

  const std::vector<std::string>& written_packets() const {
    return written_packets_;
  }

  // Enables asynchronous Write().
  void set_async_send(bool async_send) { async_send_ = async_send; }

  // Set error codes for the next Write() call. Once returned the
  // value is automatically reset to net::OK .
  void set_next_send_error(int error) { next_send_error_ = error; }

  void AppendInputPacket(const std::string& data);

  // Current position in the input in number of packets, i.e. number of finished
  // Recv() calls.
  int input_pos() const { return input_pos_; }

  // Pairs the socket with |peer_socket|. Deleting either of the paired sockets
  // unpairs them.
  void PairWith(FakeDatagramSocket* peer_socket);

  base::WeakPtr<FakeDatagramSocket> GetWeakPtr();

  // P2PDatagramSocket implementation.
  int Recv(const scoped_refptr<net::IOBuffer>& buf,
           int buf_len,
           const net::CompletionRepeatingCallback& callback) override;
  int Send(const scoped_refptr<net::IOBuffer>& buf,
           int buf_len,
           const net::CompletionRepeatingCallback& callback) override;

 private:
  int CopyReadData(const scoped_refptr<net::IOBuffer>& buf, int buf_len);

  void DoAsyncSend(const scoped_refptr<net::IOBuffer>& buf,
                   int buf_len,
                   const net::CompletionRepeatingCallback& callback);
  int DoSend(const scoped_refptr<net::IOBuffer>& buf, int buf_len);

  bool async_send_ = false;
  bool send_pending_ = false;
  int next_send_error_ = 0;

  base::WeakPtr<FakeDatagramSocket> peer_socket_;

  scoped_refptr<net::IOBuffer> read_buffer_;
  int read_buffer_size_;
  net::CompletionRepeatingCallback read_callback_;

  std::vector<std::string> written_packets_;
  std::vector<std::string> input_packets_;
  int input_pos_;

  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
  base::WeakPtrFactory<FakeDatagramSocket> weak_factory_{this};
};

class FakeDatagramChannelFactory : public DatagramChannelFactory {
 public:
  FakeDatagramChannelFactory();

  FakeDatagramChannelFactory(const FakeDatagramChannelFactory&) = delete;
  FakeDatagramChannelFactory& operator=(const FakeDatagramChannelFactory&) =
      delete;

  ~FakeDatagramChannelFactory() override;

  void set_asynchronous_create(bool asynchronous_create) {
    asynchronous_create_ = asynchronous_create;
  }

  void set_fail_create(bool fail_create) { fail_create_ = fail_create; }

  // Pair with |peer_factory|. Once paired the factory will be automatically
  // pairing created sockets with the sockets with the same name from the peer
  // factory.
  void PairWith(FakeDatagramChannelFactory* peer_factory);

  // Can be used to retrieve FakeDatagramSocket created by this factory, e.g. to
  // feed data into it. The caller doesn't get ownership of the result. Returns
  // nullptr if the socket doesn't exist.
  FakeDatagramSocket* GetFakeChannel(const std::string& name);

  // DatagramChannelFactory interface.
  void CreateChannel(const std::string& name,
                     ChannelCreatedCallback callback) override;
  void CancelChannelCreation(const std::string& name) override;

 private:
  typedef std::map<std::string, base::WeakPtr<FakeDatagramSocket>> ChannelsMap;

  void NotifyChannelCreated(std::unique_ptr<FakeDatagramSocket> owned_socket,
                            const std::string& name,
                            ChannelCreatedCallback callback);

  base::WeakPtr<FakeDatagramChannelFactory> peer_factory_;

  scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
  bool asynchronous_create_;
  ChannelsMap channels_;

  bool fail_create_;

  base::WeakPtrFactory<FakeDatagramChannelFactory> weak_factory_{this};
};

}  // namespace remoting::protocol

#endif  // REMOTING_PROTOCOL_FAKE_DATAGRAM_SOCKET_H_