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