Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
C
capnproto
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
capnproto
Commits
ffc74bbc
Commit
ffc74bbc
authored
8 years ago
by
Kenton Varda
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add Windows HANDLE equivalents of AutoCloseFd and streams.
parent
c02dce53
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
137 additions
and
1 deletion
+137
-1
io.c++
c++/src/kj/io.c++
+53
-1
io.h
c++/src/kj/io.h
+84
-0
No files found.
c++/src/kj/io.c++
View file @
ffc74bbc
...
...
@@ -25,7 +25,14 @@
#include <algorithm>
#include <errno.h>
#if !_WIN32
#if _WIN32
#ifndef NOMINMAX
#define NOMINMAX 1
#endif
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include "windows-sanity.h"
#else
#include <sys/uio.h>
#endif
...
...
@@ -371,4 +378,49 @@ void FdOutputStream::write(ArrayPtr<const ArrayPtr<const byte>> pieces) {
#endif
}
// =======================================================================================
#if _WIN32
AutoCloseHandle
::~
AutoCloseHandle
()
noexcept
(
false
)
{
if
(
handle
!=
(
void
*
)
-
1
)
{
KJ_WIN32
(
CloseHandle
(
handle
));
}
}
HandleInputStream
::~
HandleInputStream
()
noexcept
(
false
)
{}
size_t
HandleInputStream
::
tryRead
(
void
*
buffer
,
size_t
minBytes
,
size_t
maxBytes
)
{
byte
*
pos
=
reinterpret_cast
<
byte
*>
(
buffer
);
byte
*
min
=
pos
+
minBytes
;
byte
*
max
=
pos
+
maxBytes
;
while
(
pos
<
min
)
{
DWORD
n
;
KJ_WIN32
(
ReadFile
(
handle
,
pos
,
kj
::
min
(
max
-
pos
,
DWORD
(
kj
::
maxValue
)),
&
n
,
nullptr
));
if
(
n
==
0
)
{
break
;
}
pos
+=
n
;
}
return
pos
-
reinterpret_cast
<
byte
*>
(
buffer
);
}
HandleOutputStream
::~
HandleOutputStream
()
noexcept
(
false
)
{}
void
HandleOutputStream
::
write
(
const
void
*
buffer
,
size_t
size
)
{
const
char
*
pos
=
reinterpret_cast
<
const
char
*>
(
buffer
);
while
(
size
>
0
)
{
DWORD
n
;
KJ_WIN32
(
WriteFile
(
handle
,
pos
,
kj
::
min
(
size
,
DWORD
(
kj
::
maxValue
)),
&
n
,
nullptr
));
KJ_ASSERT
(
n
>
0
,
"write() returned zero."
);
pos
+=
n
;
size
-=
n
;
}
}
#endif // _WIN32
}
// namespace kj
This diff is collapsed.
Click to expand it.
c++/src/kj/io.h
View file @
ffc74bbc
...
...
@@ -326,6 +326,90 @@ private:
AutoCloseFd
autoclose
;
};
// =======================================================================================
// Win32 Handle I/O
#ifdef _WIN32
class
AutoCloseHandle
{
// A wrapper around a Win32 HANDLE which automatically closes the handle when destroyed.
// The wrapper supports move construction for transferring ownership of the handle. If
// CloseHandle() returns an error, the destructor throws an exception, UNLESS the destructor is
// being called during unwind from another exception, in which case the close error is ignored.
//
// If your code is not exception-safe, you should not use AutoCloseHandle. In this case you will
// have to call close() yourself and handle errors appropriately.
public
:
inline
AutoCloseHandle
()
:
handle
((
void
*
)
-
1
)
{}
inline
AutoCloseHandle
(
decltype
(
nullptr
))
:
handle
((
void
*
)
-
1
)
{}
inline
explicit
AutoCloseHandle
(
void
*
handle
)
:
handle
(
handle
)
{}
inline
AutoCloseHandle
(
AutoCloseHandle
&&
other
)
noexcept
:
handle
(
other
.
handle
)
{
other
.
handle
=
(
void
*
)
-
1
;
}
KJ_DISALLOW_COPY
(
AutoCloseHandle
);
~
AutoCloseHandle
()
noexcept
(
false
);
inline
AutoCloseHandle
&
operator
=
(
AutoCloseHandle
&&
other
)
{
AutoCloseHandle
old
(
kj
::
mv
(
*
this
));
handle
=
other
.
handle
;
other
.
handle
=
(
void
*
)
-
1
;
return
*
this
;
}
inline
AutoCloseHandle
&
operator
=
(
decltype
(
nullptr
))
{
AutoCloseHandle
old
(
kj
::
mv
(
*
this
));
return
*
this
;
}
inline
operator
void
*
()
const
{
return
handle
;
}
inline
void
*
get
()
const
{
return
handle
;
}
operator
bool
()
const
=
delete
;
// Deleting this operator prevents accidental use in boolean contexts, which
// the void* conversion operator above would otherwise allow.
inline
bool
operator
==
(
decltype
(
nullptr
))
{
return
handle
!=
(
void
*
)
-
1
;
}
inline
bool
operator
!=
(
decltype
(
nullptr
))
{
return
handle
==
(
void
*
)
-
1
;
}
private
:
void
*
handle
;
// -1 (aka INVALID_HANDLE_VALUE) if not valid.
};
class
HandleInputStream
:
public
InputStream
{
// An InputStream wrapping a Win32 HANDLE.
public
:
explicit
HandleInputStream
(
void
*
handle
)
:
handle
(
handle
)
{}
explicit
HandleInputStream
(
AutoCloseHandle
handle
)
:
handle
(
handle
),
autoclose
(
mv
(
handle
))
{}
KJ_DISALLOW_COPY
(
HandleInputStream
);
~
HandleInputStream
()
noexcept
(
false
);
size_t
tryRead
(
void
*
buffer
,
size_t
minBytes
,
size_t
maxBytes
)
override
;
private
:
void
*
handle
;
AutoCloseHandle
autoclose
;
};
class
HandleOutputStream
:
public
OutputStream
{
// An OutputStream wrapping a Win32 HANDLE.
public
:
explicit
HandleOutputStream
(
void
*
handle
)
:
handle
(
handle
)
{}
explicit
HandleOutputStream
(
AutoCloseHandle
handle
)
:
handle
(
handle
),
autoclose
(
mv
(
handle
))
{}
KJ_DISALLOW_COPY
(
HandleOutputStream
);
~
HandleOutputStream
()
noexcept
(
false
);
void
write
(
const
void
*
buffer
,
size_t
size
)
override
;
private
:
void
*
handle
;
AutoCloseHandle
autoclose
;
};
#endif // _WIN32
}
// namespace kj
#endif // KJ_IO_H_
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment