• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/test/test_utils.h"
6 
7 #include <fcntl.h>
8 #include <io.h>
9 #include <string.h>
10 #include <windows.h>
11 
12 #include "base/base_paths.h"
13 #include "base/path_service.h"
14 #include "base/strings/string_util.h"
15 
16 namespace mojo {
17 namespace test {
18 
BlockingWrite(const embedder::PlatformHandle & handle,const void * buffer,size_t bytes_to_write,size_t * bytes_written)19 bool BlockingWrite(const embedder::PlatformHandle& handle,
20                    const void* buffer,
21                    size_t bytes_to_write,
22                    size_t* bytes_written) {
23   OVERLAPPED overlapped = { 0 };
24   DWORD bytes_written_dword = 0;
25 
26   if (!WriteFile(handle.handle, buffer, static_cast<DWORD>(bytes_to_write),
27                  &bytes_written_dword, &overlapped)) {
28     if (GetLastError() != ERROR_IO_PENDING ||
29         !GetOverlappedResult(handle.handle, &overlapped, &bytes_written_dword,
30                              TRUE)) {
31       return false;
32     }
33   }
34 
35   *bytes_written = bytes_written_dword;
36   return true;
37 }
38 
BlockingRead(const embedder::PlatformHandle & handle,void * buffer,size_t buffer_size,size_t * bytes_read)39 bool BlockingRead(const embedder::PlatformHandle& handle,
40                   void* buffer,
41                   size_t buffer_size,
42                   size_t* bytes_read) {
43   OVERLAPPED overlapped = { 0 };
44   DWORD bytes_read_dword = 0;
45 
46   if (!ReadFile(handle.handle, buffer, static_cast<DWORD>(buffer_size),
47                 &bytes_read_dword, &overlapped)) {
48     if (GetLastError() != ERROR_IO_PENDING ||
49         !GetOverlappedResult(handle.handle, &overlapped, &bytes_read_dword,
50                              TRUE)) {
51       return false;
52     }
53   }
54 
55   *bytes_read = bytes_read_dword;
56   return true;
57 }
58 
NonBlockingRead(const embedder::PlatformHandle & handle,void * buffer,size_t buffer_size,size_t * bytes_read)59 bool NonBlockingRead(const embedder::PlatformHandle& handle,
60                      void* buffer,
61                      size_t buffer_size,
62                      size_t* bytes_read) {
63   OVERLAPPED overlapped = { 0 };
64   DWORD bytes_read_dword = 0;
65 
66   if (!ReadFile(handle.handle, buffer, static_cast<DWORD>(buffer_size),
67                 &bytes_read_dword, &overlapped)) {
68     if (GetLastError() != ERROR_IO_PENDING)
69       return false;
70 
71     CancelIo(handle.handle);
72 
73     if (!GetOverlappedResult(handle.handle, &overlapped, &bytes_read_dword,
74                              TRUE)) {
75       *bytes_read = 0;
76       return true;
77     }
78   }
79 
80   *bytes_read = bytes_read_dword;
81   return true;
82 }
83 
PlatformHandleFromFILE(base::ScopedFILE fp)84 embedder::ScopedPlatformHandle PlatformHandleFromFILE(base::ScopedFILE fp) {
85   CHECK(fp);
86 
87   HANDLE rv = INVALID_HANDLE_VALUE;
88   PCHECK(DuplicateHandle(
89       GetCurrentProcess(),
90       reinterpret_cast<HANDLE>(_get_osfhandle(_fileno(fp.get()))),
91       GetCurrentProcess(),
92       &rv,
93       0,
94       TRUE,
95       DUPLICATE_SAME_ACCESS)) << "DuplicateHandle";
96   return embedder::ScopedPlatformHandle(embedder::PlatformHandle(rv));
97 }
98 
FILEFromPlatformHandle(embedder::ScopedPlatformHandle h,const char * mode)99 base::ScopedFILE FILEFromPlatformHandle(embedder::ScopedPlatformHandle h,
100                                         const char* mode) {
101   CHECK(h.is_valid());
102   // Microsoft's documentation for |_open_osfhandle()| only discusses these
103   // flags (and |_O_WTEXT|). Hmmm.
104   int flags = 0;
105   if (strchr(mode, 'a'))
106     flags |= _O_APPEND;
107   if (strchr(mode, 'r'))
108     flags |= _O_RDONLY;
109   if (strchr(mode, 't'))
110     flags |= _O_TEXT;
111   base::ScopedFILE rv(
112       _fdopen(_open_osfhandle(reinterpret_cast<intptr_t>(h.release().handle),
113                               flags),
114               mode));
115   PCHECK(rv) << "_fdopen";
116   return rv.Pass();
117 }
118 
GetFilePathForJSResource(const std::string & path)119 base::FilePath GetFilePathForJSResource(const std::string& path) {
120   std::string binding_path = "gen/" + path + ".js";
121   base::ReplaceChars(binding_path, "//", "\\", &binding_path);
122   base::FilePath exe_dir;
123   PathService::Get(base::DIR_EXE, &exe_dir);
124   return exe_dir.AppendASCII(binding_path);
125 }
126 
127 }  // namespace test
128 }  // namespace mojo
129