| // Copyright 2016 The Fuchsia 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 "src/lib/fsl/socket/strings.h" |
| |
| #include <lib/syslog/cpp/macros.h> |
| |
| #include <utility> |
| |
| #include "src/lib/fsl/socket/blocking_drain.h" |
| |
| namespace fsl { |
| |
| bool BlockingCopyToString(zx::socket source, std::string* result) { |
| FX_CHECK(result); |
| result->clear(); |
| return BlockingDrainFrom(std::move(source), [result](const void* buffer, uint32_t num_bytes) { |
| result->append(static_cast<const char*>(buffer), num_bytes); |
| return num_bytes; |
| }); |
| } |
| |
| bool BlockingCopyFromString(std::string_view source, const zx::socket& destination) { |
| const char* ptr = source.data(); |
| size_t to_write = source.size(); |
| for (;;) { |
| size_t written; |
| zx_status_t result = destination.write(0, ptr, to_write, &written); |
| if (result == ZX_OK) { |
| if (written == to_write) |
| return true; |
| to_write -= written; |
| ptr += written; |
| } else if (result == ZX_ERR_SHOULD_WAIT) { |
| result = destination.wait_one(ZX_SOCKET_WRITABLE | ZX_SOCKET_PEER_CLOSED, |
| zx::time::infinite(), nullptr); |
| if (result != ZX_OK) { |
| // If the socket was closed, then treat as EOF. |
| return result == ZX_ERR_PEER_CLOSED; |
| } |
| } else { |
| // If the socket was closed, then treat as EOF. |
| return result == ZX_ERR_PEER_CLOSED; |
| } |
| } |
| } |
| |
| zx::socket WriteStringToSocket(std::string_view source) { |
| // TODO(qsr): Check that source.size() <= socket max capacity when the |
| // information is retrievable. Until then use the know socket capacity. |
| FX_DCHECK(source.size() < 256 * 1024); |
| zx::socket socket1, socket2; |
| zx::socket::create(0u, &socket1, &socket2); |
| BlockingCopyFromString(source, std::move(socket1)); |
| return socket2; |
| } |
| |
| } // namespace fsl |