Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(325)

Side by Side Diff: printing/backend/cups_connection.cc

Issue 2105463002: Create a new print backend for the updated CUPS APIs (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix comment. Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "printing/backend/cups_connection.h"
6
7 #include <string>
8 #include <utility>
9
10 #include "base/logging.h"
11 #include "base/memory/ptr_util.h"
12 #include "base/strings/stringprintf.h"
13
14 namespace {
15
16 static const int kTimeoutMs = 3000;
17
18 class DestinationEnumerator {
19 public:
20 static int cups_callback(void* user_data, unsigned flags, cups_dest_t* dest) {
21 cups_dest_t* copied_dest;
22 cupsCopyDest(dest, 0, &copied_dest);
23 reinterpret_cast<DestinationEnumerator*>(user_data)->store_dest(
24 copied_dest);
25
26 // keep going
27 return 1;
28 }
29
30 void store_dest(cups_dest_t* dest) { dests_.emplace_back(dest); }
31
32 // Returns the collected destinations. Remove desired destinations from the
33 // vector or they will be cleaned up when this object is destroyed.
34 std::vector<std::unique_ptr<cups_dest_t, printing::DestinationDeleter>>&
Lei Zhang 2016/07/19 22:26:39 Getting a bit unwieldy to write. Might be good to
skau 2016/07/20 23:58:22 Moving the class into the printing namespace worke
35 get_dests() {
36 return dests_;
37 }
38
39 private:
40 std::vector<std::unique_ptr<cups_dest_t, printing::DestinationDeleter>>
41 dests_;
42 };
43
44 } // namespace
45
46 namespace printing {
47
48 CupsConnection::Impl::Impl(http_t* http)
49 : cups_http_(http), http_factory_(http) {}
50
51 CupsConnection::Impl::~Impl() {
52 http_factory_.InvalidateWeakPtrs();
53 }
54
55 base::WeakPtr<http_t> CupsConnection::Impl::GetHttp() {
56 return http_factory_.GetWeakPtr();
57 }
58
59 CupsConnection::CupsConnection(const GURL& print_server_url,
60 http_encryption_t encryption,
61 bool blocking)
62 : print_server_url_(print_server_url),
63 cups_encryption_(encryption),
64 blocking_(blocking),
65 impl_(nullptr),
66 cups_http_(nullptr) {}
67
68 CupsConnection::CupsConnection(CupsConnection&& connection)
69 : print_server_url_(connection.print_server_url_),
70 cups_encryption_(connection.cups_encryption_),
71 blocking_(connection.blocking_),
72 impl_(std::move(connection.impl_)),
73 cups_http_(std::move(connection.cups_http_)) {}
74
75 CupsConnection::~CupsConnection() {}
76
77 bool CupsConnection::Connect() {
78 if (cups_http_)
79 return true; // we're already connected
80
81 std::string host;
82 int port;
83
84 if (!print_server_url_.is_empty()) {
85 host = print_server_url_.host();
86 port = print_server_url_.IntPort();
87 } else {
88 host = cupsServer();
89 port = ippPort();
90 }
91
92 http_t* connection =
93 httpConnect2(host.c_str(), port, nullptr, AF_UNSPEC, cups_encryption_,
94 blocking_ ? 1 : 0, kTimeoutMs, nullptr);
95
96 if (!connection)
97 return false;
98
99 impl_ = base::MakeUnique<Impl>(connection);
100 cups_http_ = impl_->GetHttp();
101 return true;
102 }
103
104 std::vector<CupsPrinter> CupsConnection::GetDests() {
105 if (!Connect()) {
106 LOG(WARNING) << "CUPS connection failed";
107 return std::vector<CupsPrinter>();
108 }
109
110 DestinationEnumerator enumerator;
111 int success =
112 cupsEnumDests(CUPS_DEST_FLAGS_NONE, kTimeoutMs,
113 nullptr, // no cancel signal
114 0, // all the printers
115 CUPS_PRINTER_SCANNER, // except the scanners
116 &DestinationEnumerator::cups_callback, &enumerator);
117
118 if (!success) {
119 LOG(WARNING) << "Enumerating printers failed";
120 return std::vector<CupsPrinter>();
121 }
122
123 auto& dests = enumerator.get_dests();
124 std::vector<CupsPrinter> printers;
125 for (auto& dest : dests) {
126 printers.emplace_back(impl_->GetHttp(), std::move(dest), nullptr);
127 }
128
129 dests.clear(); // CupsPrinter takes ownership of all the cups_dest_t objects
Lei Zhang 2016/07/19 22:26:39 Do you feel it would be clearer if we did: auto d
skau 2016/07/20 23:58:22 That seems reasonable. I'll defer to you as to if
130
131 return printers;
132 }
133
134 std::unique_ptr<CupsPrinter> CupsConnection::GetPrinter(
135 const std::string& name) {
136 if (!Connect())
137 return nullptr;
138
139 cups_dest_t* dest = cupsGetNamedDest(cups_http_.get(), name.c_str(), nullptr);
140 if (!dest)
141 return nullptr;
142
143 cups_dinfo_t* info = cupsCopyDestInfo(cups_http_.get(), dest);
144 return base::MakeUnique<CupsPrinter>(
145 impl_->GetHttp(), std::unique_ptr<cups_dest_t, DestinationDeleter>(dest),
146 std::unique_ptr<cups_dinfo_t, DestInfoDeleter>(info));
147 }
148
149 std::string CupsConnection::server_name() const {
150 return print_server_url_.host();
151 }
152
153 int CupsConnection::last_error() const {
154 return cupsLastError();
155 }
156
157 } // namespace printing
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698