OLD | NEW |
| (Empty) |
1 // Copyright 2014 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 "mojo/common/data_pipe_utils.h" | |
6 | |
7 #include <stdio.h> | |
8 | |
9 #include "base/files/file_path.h" | |
10 #include "base/files/file_util.h" | |
11 #include "base/files/scoped_file.h" | |
12 #include "base/message_loop/message_loop.h" | |
13 #include "base/task_runner_util.h" | |
14 | |
15 namespace mojo { | |
16 namespace common { | |
17 namespace { | |
18 | |
19 bool BlockingCopyHelper(ScopedDataPipeConsumerHandle source, | |
20 const base::Callback<size_t(const void*, uint32_t)>& write_bytes) { | |
21 for (;;) { | |
22 const void* buffer; | |
23 uint32_t num_bytes; | |
24 MojoResult result = BeginReadDataRaw( | |
25 source.get(), &buffer, &num_bytes, MOJO_READ_DATA_FLAG_NONE); | |
26 if (result == MOJO_RESULT_OK) { | |
27 size_t bytes_written = write_bytes.Run(buffer, num_bytes); | |
28 result = EndReadDataRaw(source.get(), num_bytes); | |
29 if (bytes_written < num_bytes || result != MOJO_RESULT_OK) | |
30 return false; | |
31 } else if (result == MOJO_RESULT_SHOULD_WAIT) { | |
32 result = Wait(source.get(), | |
33 MOJO_HANDLE_SIGNAL_READABLE, | |
34 MOJO_DEADLINE_INDEFINITE, | |
35 nullptr); | |
36 if (result != MOJO_RESULT_OK) { | |
37 // If the producer handle was closed, then treat as EOF. | |
38 return result == MOJO_RESULT_FAILED_PRECONDITION; | |
39 } | |
40 } else if (result == MOJO_RESULT_FAILED_PRECONDITION) { | |
41 // If the producer handle was closed, then treat as EOF. | |
42 return true; | |
43 } else { | |
44 // Some other error occurred. | |
45 break; | |
46 } | |
47 } | |
48 | |
49 return false; | |
50 } | |
51 | |
52 size_t CopyToStringHelper( | |
53 std::string* result, const void* buffer, uint32_t num_bytes) { | |
54 result->append(static_cast<const char*>(buffer), num_bytes); | |
55 return num_bytes; | |
56 } | |
57 | |
58 size_t CopyToFileHelper(FILE* fp, const void* buffer, uint32_t num_bytes) { | |
59 return fwrite(buffer, 1, num_bytes, fp); | |
60 } | |
61 | |
62 } // namespace | |
63 | |
64 | |
65 // TODO(hansmuller): Add a max_size parameter. | |
66 bool BlockingCopyToString(ScopedDataPipeConsumerHandle source, | |
67 std::string* result) { | |
68 CHECK(result); | |
69 result->clear(); | |
70 return BlockingCopyHelper( | |
71 source.Pass(), base::Bind(&CopyToStringHelper, result)); | |
72 } | |
73 | |
74 bool MOJO_COMMON_EXPORT BlockingCopyFromString( | |
75 const std::string& source, | |
76 const ScopedDataPipeProducerHandle& destination) { | |
77 auto it = source.begin(); | |
78 for (;;) { | |
79 void* buffer = nullptr; | |
80 uint32_t buffer_num_bytes = 0; | |
81 MojoResult result = | |
82 BeginWriteDataRaw(destination.get(), &buffer, &buffer_num_bytes, | |
83 MOJO_WRITE_DATA_FLAG_NONE); | |
84 if (result == MOJO_RESULT_OK) { | |
85 char* char_buffer = static_cast<char*>(buffer); | |
86 uint32_t byte_index = 0; | |
87 while (it != source.end() && byte_index < buffer_num_bytes) { | |
88 char_buffer[byte_index++] = *it++; | |
89 } | |
90 EndWriteDataRaw(destination.get(), byte_index); | |
91 } else if (result == MOJO_RESULT_SHOULD_WAIT) { | |
92 result = Wait(destination.get(), MOJO_HANDLE_SIGNAL_WRITABLE, | |
93 MOJO_DEADLINE_INDEFINITE, nullptr); | |
94 if (result != MOJO_RESULT_OK) { | |
95 // If the consumer handle was closed, then treat as EOF. | |
96 return result == MOJO_RESULT_FAILED_PRECONDITION; | |
97 } | |
98 } else { | |
99 // If the consumer handle was closed, then treat as EOF. | |
100 return result == MOJO_RESULT_FAILED_PRECONDITION; | |
101 } | |
102 } | |
103 } | |
104 | |
105 bool BlockingCopyToFile(ScopedDataPipeConsumerHandle source, | |
106 const base::FilePath& destination) { | |
107 base::ScopedFILE fp(base::OpenFile(destination, "wb")); | |
108 if (!fp) | |
109 return false; | |
110 return BlockingCopyHelper( | |
111 source.Pass(), base::Bind(&CopyToFileHelper, fp.get())); | |
112 } | |
113 | |
114 void CopyToFile(ScopedDataPipeConsumerHandle source, | |
115 const base::FilePath& destination, | |
116 base::TaskRunner* task_runner, | |
117 const base::Callback<void(bool)>& callback) { | |
118 base::PostTaskAndReplyWithResult( | |
119 task_runner, | |
120 FROM_HERE, | |
121 base::Bind(&BlockingCopyToFile, base::Passed(&source), destination), | |
122 callback); | |
123 } | |
124 | |
125 } // namespace common | |
126 } // namespace mojo | |
OLD | NEW |