@@ -91,44 +91,65 @@ struct simple_db::impl
91
91
{
92
92
try
93
93
{
94
- std::vector<concurrency::streams::istream> streams;
95
94
auto c = make_compressor (algorithm::GZIP);
96
- std::vector<uint8_t > pre;
97
- pre.resize (w->size ());
98
- size_t used;
95
+
96
+ const int rawdata_size = w->size ();
97
+ const uint8_t * rawdata_ptr =
98
+ reinterpret_cast <const uint8_t *>(w->data ());
99
+ int rawdata_cursor = 0 ;
100
+
101
+ std::vector<uint8_t > compression_buffer;
102
+ int compressed_size = 0 ;
99
103
bool done = false ;
100
- auto got = c->compress (reinterpret_cast <const uint8_t *>(w->data ()),
101
- w->size (), pre.data (), pre.size (),
102
- web::http::compression::operation_hint::is_last,
103
- used, done);
104
- streams.emplace_back (
105
- concurrency::streams::rawptr_stream<uint8_t >::open_istream (
106
- pre.data (), got));
107
104
108
- for (auto & stream : streams)
105
+ compression_buffer.resize (rawdata_size);
106
+ while (!done)
109
107
{
110
- http_request request;
111
- request.set_request_uri (uri_with_db);
112
- request.set_method (methods::POST);
113
- request.headers ().add (" Authorization" , " Token " + token);
114
- request.headers ().add (header_names::content_encoding,
115
- algorithm::GZIP);
116
-
117
- request.set_body (stream);
118
- auto response = client.request (request);
119
- try
108
+ size_t used = 0 ;
109
+ if (compressed_size >= rawdata_size * 16 )
120
110
{
121
- response.wait ();
122
- if (!(response.get ().status_code () == status_codes::OK ||
123
- response.get ().status_code () == status_codes::NoContent))
124
- {
125
- throw std::runtime_error (response.get ().extract_string ().get ());
126
- }
111
+ throw std::runtime_error (
112
+ " gzip data is 16 times larger than raw data. abort "
113
+ " compression" );
127
114
}
128
- catch ( const std::exception& e )
115
+ if (compressed_size == compression_buffer. size () )
129
116
{
130
- throw std::runtime_error (e. what () );
117
+ compression_buffer. resize (compressed_size * 2 );
131
118
}
119
+ const int got = c->compress (
120
+ rawdata_ptr + rawdata_cursor, // rawdata ptr
121
+ rawdata_size - rawdata_cursor, // remaining rawdata size
122
+ compression_buffer.data () +
123
+ compressed_size, // buffer ptr to append
124
+ compression_buffer.size () -
125
+ compressed_size, // buffer available size
126
+ web::http::compression::operation_hint::is_last, used, done);
127
+ compressed_size += got;
128
+ rawdata_cursor += used;
129
+ }
130
+
131
+ http_request request;
132
+ request.set_request_uri (uri_with_db);
133
+ request.set_method (methods::POST);
134
+ request.headers ().add (" Authorization" , " Token " + token);
135
+ request.headers ().add (header_names::content_encoding, algorithm::GZIP);
136
+
137
+ request.set_body (
138
+ concurrency::streams::rawptr_stream<uint8_t >::open_istream (
139
+ compression_buffer.data (), compressed_size));
140
+ auto response = client.request (request);
141
+ try
142
+ {
143
+ response.wait ();
144
+ if (!(response.get ().status_code () == status_codes::OK ||
145
+ response.get ().status_code () == status_codes::NoContent))
146
+ {
147
+ throw std::runtime_error (response.get ().extract_string ().get ());
148
+ }
149
+ }
150
+ catch (const std::exception& e)
151
+ {
152
+ throw std::runtime_error (e.what ());
132
153
}
133
154
}
134
155
catch (const std::exception& e)
0 commit comments