Skip to content

Commit 60ad32d

Browse files
authored
Stream wrapper + tests (aws#43)
* Stream wrapper + tests
1 parent b15b93f commit 60ad32d

File tree

5 files changed

+384
-1
lines changed

5 files changed

+384
-1
lines changed

include/aws/crt/Types.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ namespace Aws
4545
namespace Io
4646
{
4747
using SocketOptions = aws_socket_options;
48-
}
48+
using IStream = std::basic_istream<char, std::char_traits<char>>;
49+
} // namespace Io
4950

5051
namespace Mqtt
5152
{

include/aws/crt/io/Stream.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#pragma once
2+
/*
3+
* Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License").
6+
* You may not use this file except in compliance with the License.
7+
* A copy of the License is located at
8+
*
9+
* http://aws.amazon.com/apache2.0
10+
*
11+
* or in the "license" file accompanying this file. This file is distributed
12+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13+
* express or implied. See the License for the specific language governing
14+
* permissions and limitations under the License.
15+
*/
16+
17+
#include <aws/crt/Exports.h>
18+
#include <aws/crt/Types.h>
19+
20+
struct aws_input_stream;
21+
22+
namespace Aws
23+
{
24+
namespace Crt
25+
{
26+
namespace Io
27+
{
28+
/*
29+
* Factory to create a aws-c-io input stream subclass from a C++ stream
30+
*/
31+
AWS_CRT_CPP_API aws_input_stream *AwsInputStreamNewCpp(
32+
const std::shared_ptr<Aws::Crt::Io::IStream> &stream,
33+
Aws::Crt::Allocator *allocator = DefaultAllocator()) noexcept;
34+
} // namespace Io
35+
} // namespace Crt
36+
} // namespace Aws

source/io/Stream.cpp

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
/*
2+
* Copyright 2010-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://aws.amazon.com/apache2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*/
15+
16+
#include <aws/crt/io/Stream.h>
17+
18+
#include <aws/io/stream.h>
19+
20+
static std::ios_base::seekdir s_stream_seek_basis_to_seekdir(enum aws_stream_seek_basis basis)
21+
{
22+
switch (basis)
23+
{
24+
case AWS_SSB_BEGIN:
25+
return std::ios_base::beg;
26+
27+
case AWS_SSB_END:
28+
return std::ios_base::end;
29+
}
30+
31+
return std::ios_base::beg;
32+
}
33+
34+
struct aws_input_stream_cpp_impl
35+
{
36+
std::shared_ptr<Aws::Crt::Io::IStream> stream;
37+
};
38+
39+
static int s_aws_input_stream_cpp_seek(
40+
struct aws_input_stream *stream,
41+
aws_off_t offset,
42+
enum aws_stream_seek_basis basis)
43+
{
44+
aws_input_stream_cpp_impl *impl = static_cast<aws_input_stream_cpp_impl *>(stream->impl);
45+
impl->stream->seekg(Aws::Crt::Io::IStream::off_type(offset), s_stream_seek_basis_to_seekdir(basis));
46+
47+
return AWS_OP_SUCCESS;
48+
}
49+
50+
static int s_aws_input_stream_cpp_read(struct aws_input_stream *stream, struct aws_byte_buf *dest, size_t *amount_read)
51+
{
52+
aws_input_stream_cpp_impl *impl = static_cast<aws_input_stream_cpp_impl *>(stream->impl);
53+
54+
impl->stream->read(reinterpret_cast<char *>(dest->buffer + dest->len), dest->capacity - dest->len);
55+
*amount_read = static_cast<size_t>(impl->stream->gcount());
56+
57+
dest->len += *amount_read;
58+
59+
return AWS_OP_SUCCESS;
60+
}
61+
62+
static int s_aws_input_stream_cpp_get_status(struct aws_input_stream *stream, struct aws_stream_status *status)
63+
{
64+
aws_input_stream_cpp_impl *impl = static_cast<aws_input_stream_cpp_impl *>(stream->impl);
65+
66+
status->is_end_of_stream = impl->stream->eof();
67+
status->is_valid = impl->stream->good();
68+
69+
return AWS_OP_SUCCESS;
70+
}
71+
72+
static int s_aws_input_stream_cpp_get_length(struct aws_input_stream *stream, int64_t *length)
73+
{
74+
aws_input_stream_cpp_impl *impl = static_cast<aws_input_stream_cpp_impl *>(stream->impl);
75+
76+
auto currentPosition = impl->stream->tellg();
77+
78+
impl->stream->seekg(0, std::ios_base::end);
79+
80+
if (impl->stream->good())
81+
{
82+
*length = static_cast<int64_t>(impl->stream->tellg());
83+
}
84+
else
85+
{
86+
*length = 0;
87+
}
88+
89+
impl->stream->seekg(currentPosition);
90+
91+
return AWS_OP_SUCCESS;
92+
}
93+
94+
static void s_aws_input_stream_cpp_clean_up(struct aws_input_stream *stream)
95+
{
96+
aws_input_stream_cpp_impl *impl = static_cast<aws_input_stream_cpp_impl *>(stream->impl);
97+
98+
impl->stream = nullptr;
99+
}
100+
101+
static struct aws_input_stream_vtable s_aws_input_stream_cpp_vtable = {s_aws_input_stream_cpp_seek,
102+
s_aws_input_stream_cpp_read,
103+
s_aws_input_stream_cpp_get_status,
104+
s_aws_input_stream_cpp_get_length,
105+
s_aws_input_stream_cpp_clean_up};
106+
107+
namespace Aws
108+
{
109+
namespace Crt
110+
{
111+
namespace Io
112+
{
113+
struct aws_input_stream *AwsInputStreamNewCpp(
114+
const std::shared_ptr<Aws::Crt::Io::IStream> &stream,
115+
Aws::Crt::Allocator *allocator) noexcept
116+
{
117+
struct aws_input_stream *input_stream = NULL;
118+
struct aws_input_stream_cpp_impl *impl = NULL;
119+
120+
aws_mem_acquire_many(
121+
allocator,
122+
2,
123+
&input_stream,
124+
sizeof(struct aws_input_stream),
125+
&impl,
126+
sizeof(struct aws_input_stream_cpp_impl));
127+
128+
if (!input_stream)
129+
{
130+
return NULL;
131+
}
132+
133+
AWS_ZERO_STRUCT(*input_stream);
134+
AWS_ZERO_STRUCT(*impl);
135+
136+
input_stream->allocator = allocator;
137+
input_stream->vtable = &s_aws_input_stream_cpp_vtable;
138+
input_stream->impl = impl;
139+
140+
impl->stream = stream;
141+
142+
return input_stream;
143+
}
144+
} // namespace Io
145+
} // namespace Crt
146+
} // namespace Aws

tests/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ add_test_case(DefaultResolution)
2929
add_test_case(OptionalCopySafety)
3030
add_test_case(OptionalMoveSafety)
3131
add_test_case(OptionalCopyAndMoveSemantics)
32+
add_test_case(StreamTestCreateDestroyWrapperFirst)
33+
add_test_case(StreamTestCreateDestroyWrapperLast)
34+
add_test_case(StreamTestLength)
35+
add_test_case(StreamTestRead)
36+
add_test_case(StreamTestSeekBegin)
37+
add_test_case(StreamTestSeekEnd)
3238
add_test_case(TestProviderStaticGet)
3339
add_test_case(TestProviderEnvironmentGet)
3440
add_test_case(TestProviderProfileGet)

0 commit comments

Comments
 (0)