Skip to content

Commit 1f5b4a9

Browse files
committed
Refactoring: Move code out of ewkb:writer_t class
Move some code out of the ewkb:writer_t class that works well as standalone functions. This also changes the srid parameters to use the more (for wkb) correct type uint32_t. We also change some of the code to use the convention that pointers are used for out parameters.
1 parent ab8fa1d commit 1f5b4a9

File tree

1 file changed

+68
-44
lines changed

1 file changed

+68
-44
lines changed

src/wkb.hpp

Lines changed: 68 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,44 @@ enum wkb_byte_order_type_t : uint8_t
4343
#endif
4444
};
4545

46+
template <typename T>
47+
static void str_push(std::string *str, T data)
48+
{
49+
assert(str);
50+
str->append(reinterpret_cast<char const *const>(&data), sizeof(T));
51+
}
52+
53+
/**
54+
* Add a EWKB header to the string.
55+
*
56+
* \pre \code str != nullptr \endcode
57+
*/
58+
inline std::size_t write_header(std::string *str, geometry_type type,
59+
uint32_t srid)
60+
{
61+
assert(str);
62+
63+
str_push(str, Endian);
64+
str_push(str, type | wkb_srid);
65+
str_push(str, srid);
66+
67+
return str->size();
68+
}
69+
70+
/**
71+
* Add a EWKB header to the string and add a dummy placeholder length of 0.
72+
* This can later be replaced by the real length.
73+
*
74+
* \pre \code str != nullptr \endcode
75+
*/
76+
inline std::size_t write_header_with_length(std::string *str,
77+
geometry_type type, uint32_t srid)
78+
{
79+
auto const offset = write_header(str, type, srid);
80+
str_push(str, static_cast<uint32_t>(0));
81+
return offset;
82+
}
83+
4684
/**
4785
* Writer for EWKB data suitable for postgres.
4886
*
@@ -52,40 +90,22 @@ class writer_t
5290
{
5391

5492
std::string m_data;
55-
int m_srid;
56-
57-
size_t m_geometry_size_offset = 0;
58-
size_t m_multigeometry_size_offset = 0;
59-
size_t m_ring_size_offset = 0;
60-
61-
size_t header(std::string &str, geometry_type type, bool add_length) const
62-
{
63-
str_push(str, Endian);
64-
str_push(str, type | wkb_srid);
65-
str_push(str, m_srid);
66-
67-
std::size_t const offset = str.size();
68-
if (add_length) {
69-
str_push(str, static_cast<uint32_t>(0));
70-
}
71-
return offset;
72-
}
93+
uint32_t m_srid;
7394

74-
void set_size(size_t const offset, size_t const size)
75-
{
76-
uint32_t s = static_cast<uint32_t>(size);
77-
std::copy_n(reinterpret_cast<char *>(&s), sizeof(uint32_t),
78-
&m_data[offset]);
79-
}
95+
std::size_t m_geometry_size_offset = 0;
96+
std::size_t m_multigeometry_size_offset = 0;
97+
std::size_t m_ring_size_offset = 0;
8098

81-
template <typename T>
82-
inline static void str_push(std::string &str, T data)
99+
void set_size(std::size_t offset, std::size_t size)
83100
{
84-
str.append(reinterpret_cast<char const *>(&data), sizeof(T));
101+
assert(m_data.size() >= offset + sizeof(uint32_t));
102+
auto const s = static_cast<uint32_t>(size);
103+
std::memcpy(&m_data[offset], reinterpret_cast<char const *>(&s),
104+
sizeof(uint32_t));
85105
}
86106

87107
public:
88-
explicit writer_t(int srid) : m_srid(srid) {}
108+
explicit writer_t(uint32_t srid) : m_srid(srid) {}
89109

90110
void add_sub_geometry(std::string const &part)
91111
{
@@ -96,18 +116,18 @@ class writer_t
96116
void add_location(osmium::geom::Coordinates const &xy)
97117
{
98118
assert(!m_data.empty());
99-
str_push(m_data, xy.x);
100-
str_push(m_data, xy.y);
119+
str_push(&m_data, xy.x);
120+
str_push(&m_data, xy.y);
101121
}
102122

103123
/* Point */
104124

105125
std::string make_point(osmium::geom::Coordinates const &xy) const
106126
{
107127
std::string data;
108-
header(data, wkb_point, false);
109-
str_push(data, xy.x);
110-
str_push(data, xy.y);
128+
write_header(&data, wkb_point, m_srid);
129+
str_push(&data, xy.x);
130+
str_push(&data, xy.y);
111131

112132
return data;
113133
}
@@ -117,10 +137,11 @@ class writer_t
117137
void linestring_start()
118138
{
119139
assert(m_data.empty());
120-
m_geometry_size_offset = header(m_data, wkb_line, true);
140+
m_geometry_size_offset =
141+
write_header_with_length(&m_data, wkb_line, m_srid);
121142
}
122143

123-
std::string linestring_finish(size_t num_points)
144+
std::string linestring_finish(std::size_t num_points)
124145
{
125146
set_size(m_geometry_size_offset, num_points);
126147
std::string data;
@@ -136,10 +157,11 @@ class writer_t
136157
void multilinestring_start()
137158
{
138159
assert(m_data.empty());
139-
m_multigeometry_size_offset = header(m_data, wkb_multi_line, true);
160+
m_multigeometry_size_offset =
161+
write_header_with_length(&m_data, wkb_multi_line, m_srid);
140162
}
141163

142-
std::string multilinestring_finish(size_t num_lines)
164+
std::string multilinestring_finish(std::size_t num_lines)
143165
{
144166
set_size(m_multigeometry_size_offset, num_lines);
145167
std::string data;
@@ -155,21 +177,22 @@ class writer_t
155177
void polygon_start()
156178
{
157179
assert(m_data.empty());
158-
m_geometry_size_offset = header(m_data, wkb_polygon, true);
180+
m_geometry_size_offset =
181+
write_header_with_length(&m_data, wkb_polygon, m_srid);
159182
}
160183

161184
void polygon_ring_start()
162185
{
163186
m_ring_size_offset = m_data.size();
164-
str_push(m_data, static_cast<uint32_t>(0));
187+
str_push(&m_data, static_cast<uint32_t>(0));
165188
}
166189

167-
void polygon_ring_finish(size_t num_points)
190+
void polygon_ring_finish(std::size_t num_points)
168191
{
169192
set_size(m_ring_size_offset, num_points);
170193
}
171194

172-
std::string polygon_finish(size_t num_rings)
195+
std::string polygon_finish(std::size_t num_rings)
173196
{
174197
set_size(m_geometry_size_offset, num_rings);
175198
std::string data;
@@ -185,10 +208,11 @@ class writer_t
185208
void multipolygon_start()
186209
{
187210
assert(m_data.empty());
188-
m_multigeometry_size_offset = header(m_data, wkb_multi_polygon, true);
211+
m_multigeometry_size_offset =
212+
write_header_with_length(&m_data, wkb_multi_polygon, m_srid);
189213
}
190214

191-
std::string multipolygon_finish(size_t num_polygons)
215+
std::string multipolygon_finish(std::size_t num_polygons)
192216
{
193217
set_size(m_multigeometry_size_offset, num_polygons);
194218
std::string data;
@@ -198,7 +222,7 @@ class writer_t
198222

199223
return data;
200224
}
201-
};
225+
}; // class writer_t
202226

203227
/**
204228
* Class that allows to iterate over the elements of a ewkb geometry.

0 commit comments

Comments
 (0)