io.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. // Copyright 2019 Google LLC
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // https://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #include "dap/io.h"
  15. #include <atomic>
  16. #include <condition_variable>
  17. #include <cstdarg>
  18. #include <cstdio>
  19. #include <cstring> // strlen
  20. #include <deque>
  21. #include <mutex>
  22. #include <string>
  23. namespace {
  24. class Pipe : public dap::ReaderWriter {
  25. public:
  26. // dap::ReaderWriter compliance
  27. bool isOpen() override {
  28. std::unique_lock<std::mutex> lock(mutex);
  29. return !closed;
  30. }
  31. void close() override {
  32. std::unique_lock<std::mutex> lock(mutex);
  33. closed = true;
  34. cv.notify_all();
  35. }
  36. size_t read(void* buffer, size_t bytes) override {
  37. std::unique_lock<std::mutex> lock(mutex);
  38. auto out = reinterpret_cast<uint8_t*>(buffer);
  39. size_t n = 0;
  40. while (true) {
  41. cv.wait(lock, [&] { return closed || data.size() > 0; });
  42. if (closed) {
  43. return n;
  44. }
  45. for (; n < bytes && data.size() > 0; n++) {
  46. out[n] = data.front();
  47. data.pop_front();
  48. }
  49. if (n == bytes) {
  50. return n;
  51. }
  52. }
  53. }
  54. bool write(const void* buffer, size_t bytes) override {
  55. std::unique_lock<std::mutex> lock(mutex);
  56. if (closed) {
  57. return false;
  58. }
  59. if (bytes == 0) {
  60. return true;
  61. }
  62. auto notify = data.size() == 0;
  63. auto src = reinterpret_cast<const uint8_t*>(buffer);
  64. for (size_t i = 0; i < bytes; i++) {
  65. data.emplace_back(src[i]);
  66. }
  67. if (notify) {
  68. cv.notify_all();
  69. }
  70. return true;
  71. }
  72. private:
  73. std::mutex mutex;
  74. std::condition_variable cv;
  75. std::deque<uint8_t> data;
  76. bool closed = false;
  77. };
  78. class RW : public dap::ReaderWriter {
  79. public:
  80. RW(const std::shared_ptr<Reader>& r, const std::shared_ptr<Writer>& w)
  81. : r(r), w(w) {}
  82. // dap::ReaderWriter compliance
  83. bool isOpen() override { return r->isOpen() && w->isOpen(); }
  84. void close() override {
  85. r->close();
  86. w->close();
  87. }
  88. size_t read(void* buffer, size_t n) override { return r->read(buffer, n); }
  89. bool write(const void* buffer, size_t n) override {
  90. return w->write(buffer, n);
  91. }
  92. private:
  93. const std::shared_ptr<dap::Reader> r;
  94. const std::shared_ptr<dap::Writer> w;
  95. };
  96. class File : public dap::ReaderWriter {
  97. public:
  98. File(FILE* f, bool closable) : f(f), closable(closable) {}
  99. ~File() { close(); }
  100. // dap::ReaderWriter compliance
  101. bool isOpen() override { return !closed; }
  102. void close() override {
  103. if (closable) {
  104. if (!closed.exchange(true)) {
  105. fclose(f);
  106. }
  107. }
  108. }
  109. size_t read(void* buffer, size_t n) override {
  110. std::unique_lock<std::mutex> lock(readMutex);
  111. auto out = reinterpret_cast<char*>(buffer);
  112. for (size_t i = 0; i < n; i++) {
  113. int c = fgetc(f);
  114. if (c == EOF) {
  115. return i;
  116. }
  117. out[i] = char(c);
  118. }
  119. return n;
  120. }
  121. bool write(const void* buffer, size_t n) override {
  122. std::unique_lock<std::mutex> lock(writeMutex);
  123. if (fwrite(buffer, 1, n, f) == n) {
  124. fflush(f);
  125. return true;
  126. }
  127. return false;
  128. }
  129. private:
  130. FILE* const f;
  131. const bool closable;
  132. std::mutex readMutex;
  133. std::mutex writeMutex;
  134. std::atomic<bool> closed = {false};
  135. };
  136. class ReaderSpy : public dap::Reader {
  137. public:
  138. ReaderSpy(const std::shared_ptr<dap::Reader>& r,
  139. const std::shared_ptr<dap::Writer>& s,
  140. const std::string& prefix)
  141. : r(r), s(s), prefix(prefix) {}
  142. // dap::Reader compliance
  143. bool isOpen() override { return r->isOpen(); }
  144. void close() override { r->close(); }
  145. size_t read(void* buffer, size_t n) override {
  146. auto c = r->read(buffer, n);
  147. if (c > 0) {
  148. auto chars = reinterpret_cast<const char*>(buffer);
  149. std::string buf = prefix;
  150. buf.append(chars, chars + c);
  151. s->write(buf.data(), buf.size());
  152. }
  153. return c;
  154. }
  155. private:
  156. const std::shared_ptr<dap::Reader> r;
  157. const std::shared_ptr<dap::Writer> s;
  158. const std::string prefix;
  159. };
  160. class WriterSpy : public dap::Writer {
  161. public:
  162. WriterSpy(const std::shared_ptr<dap::Writer>& w,
  163. const std::shared_ptr<dap::Writer>& s,
  164. const std::string& prefix)
  165. : w(w), s(s), prefix(prefix) {}
  166. // dap::Writer compliance
  167. bool isOpen() override { return w->isOpen(); }
  168. void close() override { w->close(); }
  169. bool write(const void* buffer, size_t n) override {
  170. if (!w->write(buffer, n)) {
  171. return false;
  172. }
  173. auto chars = reinterpret_cast<const char*>(buffer);
  174. std::string buf = prefix;
  175. buf.append(chars, chars + n);
  176. s->write(buf.data(), buf.size());
  177. return true;
  178. }
  179. private:
  180. const std::shared_ptr<dap::Writer> w;
  181. const std::shared_ptr<dap::Writer> s;
  182. const std::string prefix;
  183. };
  184. } // anonymous namespace
  185. namespace dap {
  186. std::shared_ptr<ReaderWriter> ReaderWriter::create(
  187. const std::shared_ptr<Reader>& r,
  188. const std::shared_ptr<Writer>& w) {
  189. return std::make_shared<RW>(r, w);
  190. }
  191. std::shared_ptr<ReaderWriter> pipe() {
  192. return std::make_shared<Pipe>();
  193. }
  194. std::shared_ptr<ReaderWriter> file(FILE* f, bool closable /* = true */) {
  195. return std::make_shared<File>(f, closable);
  196. }
  197. std::shared_ptr<ReaderWriter> file(const char* path) {
  198. if (auto f = fopen(path, "wb")) {
  199. return std::make_shared<File>(f, true);
  200. }
  201. return nullptr;
  202. }
  203. // spy() returns a Reader that copies all reads from the Reader r to the Writer
  204. // s, using the given optional prefix.
  205. std::shared_ptr<Reader> spy(const std::shared_ptr<Reader>& r,
  206. const std::shared_ptr<Writer>& s,
  207. const char* prefix /* = "\n<-" */) {
  208. return std::make_shared<ReaderSpy>(r, s, prefix);
  209. }
  210. // spy() returns a Writer that copies all writes to the Writer w to the Writer
  211. // s, using the given optional prefix.
  212. std::shared_ptr<Writer> spy(const std::shared_ptr<Writer>& w,
  213. const std::shared_ptr<Writer>& s,
  214. const char* prefix /* = "\n->" */) {
  215. return std::make_shared<WriterSpy>(w, s, prefix);
  216. }
  217. bool writef(const std::shared_ptr<Writer>& w, const char* msg, ...) {
  218. char buf[2048];
  219. va_list vararg;
  220. va_start(vararg, msg);
  221. vsnprintf(buf, sizeof(buf), msg, vararg);
  222. va_end(vararg);
  223. return w->write(buf, strlen(buf));
  224. }
  225. } // namespace dap