@@ -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
87107public:
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