Commit c5f104b3 authored by sergeyu's avatar sergeyu Committed by Commit bot

replace NULL->nullptr in src/remoting.

Review URL: https://codereview.chromium.org/810133003

Cr-Commit-Position: refs/heads/master@{#310816}
parent a261cb0d
......@@ -93,7 +93,7 @@ void AudioDecodeScheduler::Core::ProcessDecodedPacket(
scoped_ptr<AudioPacket> packet,
const base::Closure& done) {
DCHECK(main_task_runner_->BelongsToCurrentThread());
// Only process |packet| if it is non-NULL.
// Only process |packet| if it is non-null.
if (packet.get() && audio_player_.get())
audio_player_->ProcessAudioPacket(packet.Pass());
done.Run();
......
......@@ -46,7 +46,7 @@ static void LoadNative(JNIEnv* env, jclass clazz, jobject context) {
// runtime API keys have been specified by the environment. Unfortunately, we
// neither launch Chromium nor have a command line, so we need to prevent
// them from DCHECKing out when they go looking.
base::CommandLine::Init(0, NULL);
base::CommandLine::Init(0, nullptr);
// Create the singleton now so that the Chromoting threads will be set up.
remoting::ChromotingJniRuntime::GetInstance();
......@@ -245,7 +245,7 @@ void ChromotingJniRuntime::DisconnectFromHost() {
DCHECK(ui_task_runner_->BelongsToCurrentThread());
if (session_.get()) {
session_->Disconnect();
session_ = NULL;
session_ = nullptr;
}
}
......
......@@ -23,7 +23,7 @@ JniFrameConsumer::JniFrameConsumer(
scoped_refptr<ChromotingJniInstance> jni_instance)
: jni_runtime_(jni_runtime),
jni_instance_(jni_instance),
frame_producer_(NULL) {
frame_producer_(nullptr) {
}
JniFrameConsumer::~JniFrameConsumer() {
......
......@@ -168,7 +168,7 @@ base::LazyInstance<base::WeakPtr<ChromotingInstance> >::Leaky
g_logging_instance = LAZY_INSTANCE_INITIALIZER;
base::LazyInstance<base::Lock>::Leaky
g_logging_lock = LAZY_INSTANCE_INITIALIZER;
logging::LogMessageHandlerFunction g_logging_old_handler = NULL;
logging::LogMessageHandlerFunction g_logging_old_handler = nullptr;
} // namespace
......@@ -299,9 +299,9 @@ void ChromotingInstance::HandleMessage(const pp::Var& message) {
scoped_ptr<base::Value> json(
base::JSONReader::Read(message.AsString(),
base::JSON_ALLOW_TRAILING_COMMAS));
base::DictionaryValue* message_dict = NULL;
base::DictionaryValue* message_dict = nullptr;
std::string method;
base::DictionaryValue* data = NULL;
base::DictionaryValue* data = nullptr;
if (!json.get() ||
!json->GetAsDictionary(&message_dict) ||
!message_dict->GetString("method", &method) ||
......@@ -950,7 +950,7 @@ void ChromotingInstance::Disconnect() {
VLOG(0) << "Disconnecting from host.";
// Disconnect the input pipeline and teardown the connection.
mouse_input_filter_.set_input_stub(NULL);
mouse_input_filter_.set_input_stub(nullptr);
client_.reset();
video_renderer_.reset();
}
......@@ -1046,7 +1046,7 @@ void ChromotingInstance::UnregisterLoggingInstance() {
// Unregister this instance for logging.
g_has_logging_instance = false;
g_logging_instance.Get().reset();
g_logging_task_runner.Get() = NULL;
g_logging_task_runner.Get() = nullptr;
VLOG(1) << "Unregistering global log handler";
}
......
......@@ -29,7 +29,7 @@ void DelegatingSignalStrategy::OnIncomingMessage(const std::string& message) {
ObserverListBase<Listener>::Iterator it(listeners_);
Listener* listener;
while ((listener = it.GetNext()) != NULL) {
while ((listener = it.GetNext()) != nullptr) {
if (listener->OnSignalStrategyIncomingStanza(stanza.get()))
break;
}
......
......@@ -43,18 +43,18 @@ int32_t PPP_InitializeModule(PP_Module module_id,
void PPP_ShutdownModule() {
delete pp::Module::Get();
pp::InternalSetModuleSingleton(NULL);
pp::InternalSetModuleSingleton(nullptr);
}
const void* PPP_GetInterface(const char* interface_name) {
if (!pp::Module::Get())
return NULL;
return nullptr;
return pp::Module::Get()->GetPluginInterface(interface_name);
}
const void* PPP_GetBrowserInterface(const char* interface_name) {
if (!pp::Module::Get())
return NULL;
return nullptr;
return pp::Module::Get()->GetBrowserInterface(interface_name);
}
......
......@@ -60,7 +60,7 @@ protocol::MouseEvent MakeMouseEvent(const pp::MouseInputEvent& pp_mouse_event,
} // namespace
PepperInputHandler::PepperInputHandler()
: input_stub_(NULL),
: input_stub_(nullptr),
has_focus_(false),
send_mouse_input_when_unfocused_(false),
send_mouse_move_deltas_(false),
......
......@@ -413,7 +413,7 @@ rtc::AsyncPacketSocket* PepperPacketSocketFactory::CreateUdpSocket(
uint16 max_port) {
scoped_ptr<UdpPacketSocket> result(new UdpPacketSocket(pp_instance_));
if (!result->Init(local_address, min_port, max_port))
return NULL;
return nullptr;
return result.release();
}
......@@ -424,7 +424,7 @@ rtc::AsyncPacketSocket* PepperPacketSocketFactory::CreateServerTcpSocket(
int opts) {
// We don't use TCP sockets for remoting connections.
NOTREACHED();
return NULL;
return nullptr;
}
rtc::AsyncPacketSocket* PepperPacketSocketFactory::CreateClientTcpSocket(
......@@ -435,7 +435,7 @@ rtc::AsyncPacketSocket* PepperPacketSocketFactory::CreateClientTcpSocket(
int opts) {
// We don't use TCP sockets for remoting connections.
NOTREACHED();
return NULL;
return nullptr;
}
rtc::AsyncResolverInterface*
......
......@@ -56,7 +56,7 @@ const char* GetValueSessionState(ConnectionToHost::State state) {
return kValueSessionStateClosed;
default:
NOTREACHED();
return NULL;
return nullptr;
}
}
......@@ -86,7 +86,7 @@ const char* GetValueError(ErrorCode error) {
return "unknown-error";
default:
NOTREACHED();
return NULL;
return nullptr;
}
}
......
......@@ -20,7 +20,7 @@ class AudioCapturer {
virtual ~AudioCapturer() {}
// Returns true if audio capturing is supported on this platform. If this
// returns true, then Create() must not return NULL.
// returns true, then Create() must not return nullptr.
static bool IsSupported();
static scoped_ptr<AudioCapturer> Create();
......
......@@ -76,7 +76,7 @@ void AudioCapturerLinux::OnDataRead(
}
bool AudioCapturer::IsSupported() {
return g_pulseaudio_pipe_sink_reader.Get().get() != NULL;
return g_pulseaudio_pipe_sink_reader.Get().get() != nullptr;
}
scoped_ptr<AudioCapturer> AudioCapturer::Create() {
......
......@@ -51,7 +51,7 @@ bool AudioCapturerWin::Start(const PacketCapturedCallback& callback) {
DCHECK(!audio_capture_client_.get());
DCHECK(!audio_client_.get());
DCHECK(!mm_device_.get());
DCHECK(static_cast<PWAVEFORMATEX>(wave_format_ex_) == NULL);
DCHECK(static_cast<PWAVEFORMATEX>(wave_format_ex_) == nullptr);
DCHECK(thread_checker_.CalledOnValidThread());
callback_ = callback;
......@@ -80,7 +80,7 @@ bool AudioCapturerWin::Start(const PacketCapturedCallback& callback) {
// Get an audio client.
hr = mm_device_->Activate(__uuidof(IAudioClient),
CLSCTX_ALL,
NULL,
nullptr,
audio_client_.ReceiveVoid());
if (FAILED(hr)) {
LOG(ERROR) << "Failed to get an IAudioClient. Error " << hr;
......@@ -88,7 +88,7 @@ bool AudioCapturerWin::Start(const PacketCapturedCallback& callback) {
}
REFERENCE_TIME device_period;
hr = audio_client_->GetDevicePeriod(&device_period, NULL);
hr = audio_client_->GetDevicePeriod(&device_period, nullptr);
if (FAILED(hr)) {
LOG(ERROR) << "IAudioClient::GetDevicePeriod failed. Error " << hr;
return false;
......@@ -169,7 +169,7 @@ bool AudioCapturerWin::Start(const PacketCapturedCallback& callback) {
k100nsPerMillisecond,
0,
wave_format_ex_,
NULL);
nullptr);
if (FAILED(hr)) {
LOG(ERROR) << "Failed to initialize IAudioClient. Error " << hr;
return false;
......@@ -208,14 +208,14 @@ void AudioCapturerWin::Stop() {
mm_device_.Release();
audio_client_.Release();
audio_capture_client_.Release();
wave_format_ex_.Reset(NULL);
wave_format_ex_.Reset(nullptr);
thread_checker_.DetachFromThread();
}
bool AudioCapturerWin::IsStarted() {
DCHECK(thread_checker_.CalledOnValidThread());
return capture_timer_.get() != NULL;
return capture_timer_.get() != nullptr;
}
void AudioCapturerWin::DoCapture() {
......@@ -238,7 +238,8 @@ void AudioCapturerWin::DoCapture() {
BYTE* data;
UINT32 frames;
DWORD flags;
hr = audio_capture_client_->GetBuffer(&data, &frames, &flags, NULL, NULL);
hr = audio_capture_client_->GetBuffer(&data, &frames, &flags, nullptr,
nullptr);
if (FAILED(hr))
break;
......
......@@ -46,7 +46,7 @@ void AudioScheduler::Stop() {
DCHECK(audio_stub_);
// Clear |audio_stub_| to prevent audio packets being delivered to the client.
audio_stub_ = NULL;
audio_stub_ = nullptr;
audio_task_runner_->PostTask(
FROM_HERE,
......@@ -89,7 +89,7 @@ void AudioScheduler::EncodeAudioPacket(scoped_ptr<AudioPacket> packet) {
scoped_ptr<AudioPacket> encoded_packet =
audio_encoder_->Encode(packet.Pass());
// The audio encoder returns a NULL audio packet if there's no audio to send.
// The audio encoder returns a null audio packet if there's no audio to send.
if (encoded_packet.get()) {
network_task_runner_->PostTask(
FROM_HERE, base::Bind(&AudioScheduler::SendAudioPacket,
......
......@@ -96,7 +96,7 @@ class CastCreateSessionDescriptionObserver
session);
}
void OnSuccess(webrtc::SessionDescriptionInterface* desc) override {
if (cast_extension_session_ == NULL) {
if (cast_extension_session_ == nullptr) {
LOG(ERROR)
<< "No CastExtensionSession. Creating session description succeeded.";
return;
......@@ -104,7 +104,7 @@ class CastCreateSessionDescriptionObserver
cast_extension_session_->OnCreateSessionDescription(desc);
}
void OnFailure(const std::string& error) override {
if (cast_extension_session_ == NULL) {
if (cast_extension_session_ == nullptr) {
LOG(ERROR)
<< "No CastExtensionSession. Creating session description failed.";
return;
......@@ -162,7 +162,7 @@ CastExtensionSession::~CastExtensionSession() {
// Explicitly clear |create_session_desc_observer_|'s pointer to |this|,
// since the CastExtensionSession is destructing. Otherwise,
// |create_session_desc_observer_| would be left with a dangling pointer.
create_session_desc_observer_->SetCastExtensionSession(NULL);
create_session_desc_observer_->SetCastExtensionSession(nullptr);
CleanupPeerConnection();
}
......@@ -239,7 +239,7 @@ void CastExtensionSession::OnCreateVideoCapturer(
if (received_offer_) {
has_grabbed_capturer_ = true;
if (SetupVideoStream(capturer->Pass())) {
peer_connection_->CreateAnswer(create_session_desc_observer_, NULL);
peer_connection_->CreateAnswer(create_session_desc_observer_, nullptr);
} else {
has_grabbed_capturer_ = false;
// Ignore the received offer, since we failed to setup a video stream.
......@@ -313,8 +313,8 @@ CastExtensionSession::CastExtensionSession(
stats_observer_(CastStatsObserver::Create()),
received_offer_(false),
has_grabbed_capturer_(false),
signaling_thread_wrapper_(NULL),
worker_thread_wrapper_(NULL),
signaling_thread_wrapper_(nullptr),
worker_thread_wrapper_(nullptr),
worker_thread_(kWorkerThreadName) {
DCHECK(caller_task_runner_->BelongsToCurrentThread());
DCHECK(url_request_context_getter_.get());
......@@ -331,7 +331,7 @@ CastExtensionSession::CastExtensionSession(
bool CastExtensionSession::ParseAndSetRemoteDescription(
base::DictionaryValue* message) {
DCHECK(peer_connection_.get() != NULL);
DCHECK(peer_connection_.get() != nullptr);
base::DictionaryValue* message_data;
if (!message->GetDictionary(kTopLevelData, &message_data)) {
......@@ -369,7 +369,7 @@ bool CastExtensionSession::ParseAndSetRemoteDescription(
bool CastExtensionSession::ParseAndAddICECandidate(
base::DictionaryValue* message) {
DCHECK(peer_connection_.get() != NULL);
DCHECK(peer_connection_.get() != nullptr);
base::DictionaryValue* message_data;
if (!message->GetDictionary(kTopLevelData, &message_data)) {
......@@ -409,7 +409,7 @@ bool CastExtensionSession::SendMessageToClient(const std::string& subject,
const std::string& data) {
DCHECK(caller_task_runner_->BelongsToCurrentThread());
if (client_stub_ == NULL) {
if (client_stub_ == nullptr) {
LOG(ERROR) << "No Client Stub. Cannot send message to client.";
return false;
}
......@@ -437,7 +437,7 @@ void CastExtensionSession::EnsureTaskAndSetSend(rtc::Thread** ptr,
jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true);
*ptr = jingle_glue::JingleThreadWrapper::current();
if (event != NULL) {
if (event != nullptr) {
event->Signal();
}
}
......@@ -446,7 +446,7 @@ bool CastExtensionSession::WrapTasksAndSave() {
DCHECK(caller_task_runner_->BelongsToCurrentThread());
EnsureTaskAndSetSend(&signaling_thread_wrapper_);
if (signaling_thread_wrapper_ == NULL)
if (signaling_thread_wrapper_ == nullptr)
return false;
base::WaitableEvent wrap_worker_thread_event(true, false);
......@@ -458,18 +458,19 @@ bool CastExtensionSession::WrapTasksAndSave() {
&wrap_worker_thread_event));
wrap_worker_thread_event.Wait();
return (worker_thread_wrapper_ != NULL);
return (worker_thread_wrapper_ != nullptr);
}
bool CastExtensionSession::InitializePeerConnection() {
DCHECK(caller_task_runner_->BelongsToCurrentThread());
DCHECK(!peer_conn_factory_);
DCHECK(!peer_connection_);
DCHECK(worker_thread_wrapper_ != NULL);
DCHECK(signaling_thread_wrapper_ != NULL);
DCHECK(worker_thread_wrapper_ != nullptr);
DCHECK(signaling_thread_wrapper_ != nullptr);
peer_conn_factory_ = webrtc::CreatePeerConnectionFactory(
worker_thread_wrapper_, signaling_thread_wrapper_, NULL, NULL, NULL);
worker_thread_wrapper_, signaling_thread_wrapper_, nullptr, nullptr,
nullptr);
if (!peer_conn_factory_.get()) {
CleanupPeerConnection();
......@@ -499,7 +500,7 @@ bool CastExtensionSession::InitializePeerConnection() {
network_settings_, url_request_context_getter_);
peer_connection_ = peer_conn_factory_->CreatePeerConnection(
rtc_config, &constraints, port_allocator_factory, NULL, this);
rtc_config, &constraints, port_allocator_factory, nullptr, this);
if (!peer_connection_.get()) {
CleanupPeerConnection();
......@@ -572,14 +573,14 @@ void CastExtensionSession::PollPeerConnectionStats() {
void CastExtensionSession::CleanupPeerConnection() {
peer_connection_->Close();
peer_connection_ = NULL;
stream_ = NULL;
peer_conn_factory_ = NULL;
peer_connection_ = nullptr;
stream_ = nullptr;
peer_conn_factory_ = nullptr;
worker_thread_.Stop();
}
bool CastExtensionSession::connection_active() const {
return peer_connection_.get() != NULL;
return peer_connection_.get() != nullptr;
}
// webrtc::PeerConnectionObserver implementation -------------------------------
......
......@@ -155,9 +155,9 @@ class CastExtensionSession : public HostExtensionSession,
// Creates the jingle wrapper for the current thread, sets send to allowed,
// and saves a pointer to the relevant thread pointer in ptr. If |event|
// is not NULL, signals the event on completion.
// is not nullptr, signals the event on completion.
void EnsureTaskAndSetSend(rtc::Thread** ptr,
base::WaitableEvent* event = NULL);
base::WaitableEvent* event = nullptr);
// Wraps each task runner in JingleThreadWrapper using EnsureTaskAndSetSend(),
// returning true if successful. Wrapping the task runners allows them to be
......
......@@ -28,7 +28,7 @@ CastVideoCapturerAdapter::~CastVideoCapturerAdapter() {
webrtc::SharedMemory* CastVideoCapturerAdapter::CreateSharedMemory(
size_t size) {
return NULL;
return nullptr;
}
void CastVideoCapturerAdapter::OnCaptureCompleted(webrtc::DesktopFrame* frame) {
......@@ -163,7 +163,7 @@ void CastVideoCapturerAdapter::Stop() {
capture_timer_.reset();
SetCaptureFormat(NULL);
SetCaptureFormat(nullptr);
SetCaptureState(cricket::CS_STOPPED);
VLOG(1) << "CastVideoCapturerAdapter stopped.";
......
......@@ -18,7 +18,7 @@
namespace remoting {
AuraDesktopCapturer::AuraDesktopCapturer()
: callback_(NULL), desktop_window_(NULL), weak_factory_(this) {
: callback_(nullptr), desktop_window_(nullptr), weak_factory_(this) {
}
AuraDesktopCapturer::~AuraDesktopCapturer() {
......
......@@ -64,7 +64,7 @@ void AuraDesktopCapturerTest::SetUp() {
}
TEST_F(AuraDesktopCapturerTest, ConvertSkBitmapToDesktopFrame) {
webrtc::DesktopFrame* captured_frame = NULL;
webrtc::DesktopFrame* captured_frame = nullptr;
EXPECT_CALL(*this, OnCaptureCompleted(_)).Times(1).WillOnce(
SaveArg<0>(&captured_frame));
......@@ -72,7 +72,7 @@ TEST_F(AuraDesktopCapturerTest, ConvertSkBitmapToDesktopFrame) {
SimulateFrameCapture();
ASSERT_TRUE(captured_frame != NULL);
ASSERT_TRUE(captured_frame != nullptr);
uint8_t* captured_data = captured_frame->data();
EXPECT_EQ(
0,
......
......@@ -29,10 +29,10 @@ SkiaBitmapDesktopFrame::SkiaBitmapDesktopFrame(webrtc::DesktopSize size,
int stride,
uint8_t* data,
scoped_ptr<SkBitmap> bitmap)
: DesktopFrame(size, stride, data, NULL), bitmap_(bitmap.Pass()) {
: DesktopFrame(size, stride, data, nullptr), bitmap_(bitmap.Pass()) {
}
SkiaBitmapDesktopFrame::~SkiaBitmapDesktopFrame() {
}
} // namespace remoting
\ No newline at end of file
} // namespace remoting
......@@ -24,7 +24,7 @@ class ChromotingHostContext {
// Create threads and URLRequestContextGetter for use by a host.
// During shutdown the caller should tear-down the ChromotingHostContext and
// then continue to run until |ui_task_runner| is no longer referenced.
// NULL is returned if any threads fail to start.
// nullptr is returned if any threads fail to start.
static scoped_ptr<ChromotingHostContext> Create(
scoped_refptr<AutoThreadTaskRunner> ui_task_runner);
......
......@@ -196,7 +196,7 @@ class ChromotingHostTest : public testing::Test {
connection.Pass(),
desktop_environment_factory_.get(),
base::TimeDelta(),
NULL,
nullptr,
std::vector<HostExtension*>()));
connection_ptr->set_host_stub(client.get());
......@@ -227,7 +227,7 @@ class ChromotingHostTest : public testing::Test {
void TearDown() override {
// Make sure that the host has been properly deleted.
DCHECK(host_.get() == NULL);
DCHECK(host_.get() == nullptr);
}
// Change the session route for |client1_|.
......@@ -322,7 +322,7 @@ class ChromotingHostTest : public testing::Test {
void StopAndReleaseTaskRunner() {
host_.reset();
task_runner_ = NULL;
task_runner_ = nullptr;
desktop_environment_factory_.reset();
}
......
......@@ -136,7 +136,7 @@ void ClientSession::NotifyClientResolution(
void ClientSession::ControlVideo(const protocol::VideoControl& video_control) {
DCHECK(CalledOnValidThread());
// Note that |video_scheduler_| may be NULL, depending upon whether extensions
// Note that |video_scheduler_| may be null, depending upon whether extensions
// choose to wrap or "steal" the video capturer or encoder.
if (video_control.has_enable()) {
VLOG(1) << "Received VideoControl (enable="
......@@ -366,11 +366,11 @@ void ClientSession::OnConnectionClosed(
// longer valid once ConnectionToClient calls OnConnectionClosed().
if (audio_scheduler_.get()) {
audio_scheduler_->Stop();
audio_scheduler_ = NULL;
audio_scheduler_ = nullptr;
}
if (video_scheduler_.get()) {
video_scheduler_->Stop();
video_scheduler_ = NULL;
video_scheduler_ = nullptr;
}
client_clipboard_factory_.InvalidateWeakPtrs();
......@@ -436,7 +436,7 @@ void ClientSession::ResetVideoPipeline() {
if (video_scheduler_.get()) {
video_scheduler_->Stop();
video_scheduler_ = NULL;
video_scheduler_ = nullptr;
}
// Create VideoEncoder and DesktopCapturer to match the session's video
......
......@@ -219,8 +219,8 @@ class ClientSession
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
// Schedulers for audio and video capture.
// |video_scheduler_| may be NULL if the video channel is not required - see
// ResetVideoPipeline().
// |video_scheduler_| may be nullptr if the video channel is not required -
// see ResetVideoPipeline().
scoped_refptr<AudioScheduler> audio_scheduler_;
scoped_refptr<VideoScheduler> video_scheduler_;
......
......@@ -224,7 +224,7 @@ void ClientSessionTest::SetUp() {
void ClientSessionTest::TearDown() {
// Clear out |task_runner_| reference so the loop can quit, and run it until
// it does.
task_runner_ = NULL;
task_runner_ = nullptr;
run_loop_.Run();
}
......@@ -236,9 +236,9 @@ void ClientSessionTest::CreateClientSession() {
EXPECT_CALL(*session, SetEventHandler(_));
// Mock protocol::ConnectionToClient APIs called directly by ClientSession.
// HostStub is not touched by ClientSession, so we can safely pass NULL.
// HostStub is not touched by ClientSession, so we can safely pass nullptr.
scoped_ptr<MockConnectionToClient> connection(
new MockConnectionToClient(session, NULL));
new MockConnectionToClient(session, nullptr));
EXPECT_CALL(*connection, session()).WillRepeatedly(Return(session));
EXPECT_CALL(*connection, client_stub())
.WillRepeatedly(Return(&client_stub_));
......@@ -257,7 +257,7 @@ void ClientSessionTest::CreateClientSession() {
connection.Pass(),
desktop_environment_factory_.get(),
base::TimeDelta(),
NULL,
nullptr,
extensions_));
}
......
......@@ -51,7 +51,7 @@ ClipboardMac::ClipboardMac() : current_change_count_(0) {
ClipboardMac::~ClipboardMac() {
// In it2me the destructor is not called in the same thread that the timer is
// created. Thus the timer must have already been destroyed by now.
DCHECK(clipboard_polling_timer_.get() == NULL);
DCHECK(clipboard_polling_timer_.get() == nullptr);
}
void ClipboardMac::Start(scoped_ptr<protocol::ClipboardStub> client_clipboard) {
......
......@@ -88,7 +88,7 @@ class ScopedClipboard {
HANDLE GetData(UINT format) {
if (!opened_) {
NOTREACHED();
return NULL;
return nullptr;
}
return ::GetClipboardData(format);
}
......@@ -134,8 +134,8 @@ class ClipboardWin : public Clipboard {
};
<