Libosmium  2.20.0
Fast and flexible C++ library for working with OpenStreetMap data
crc.hpp
Go to the documentation of this file.
1#ifndef OSMIUM_OSM_CRC_HPP
2#define OSMIUM_OSM_CRC_HPP
3
4/*
5
6This file is part of Osmium (https://osmcode.org/libosmium).
7
8Copyright 2013-2023 Jochen Topf <jochen@topf.org> and others (see README).
9
10Boost Software License - Version 1.0 - August 17th, 2003
11
12Permission is hereby granted, free of charge, to any person or organization
13obtaining a copy of the software and accompanying documentation covered by
14this license (the "Software") to use, reproduce, display, distribute,
15execute, and transmit the Software, and to prepare derivative works of the
16Software, and to permit third-parties to whom the Software is furnished to
17do so, all subject to the following:
18
19The copyright notices in the Software and this entire statement, including
20the above license grant, this restriction and the following disclaimer,
21must be included in all copies of the Software, in whole or in part, and
22all derivative works of the Software, unless such copies or derivative
23works are solely in the form of machine-executable object code generated by
24a source language processor.
25
26THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
27IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
28FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
29SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
30FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
31ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
32DEALINGS IN THE SOFTWARE.
33
34*/
35
36#include <osmium/osm/area.hpp>
37#include <osmium/osm/box.hpp>
41#include <osmium/osm/node.hpp>
44#include <osmium/osm/object.hpp>
46#include <osmium/osm/tag.hpp>
48#include <osmium/osm/way.hpp>
50
51#include <cstdint>
52
53namespace osmium {
54
55 inline namespace util {
56
57 inline uint16_t byte_swap_16(uint16_t value) noexcept {
58#if defined(__GNUC__) || defined(__clang__)
59 return __builtin_bswap16(value);
60#else
61 return (value >> 8) | (value << 8);
62#endif
63 }
64
65 inline uint32_t byte_swap_32(uint32_t value) noexcept {
66#if defined(__GNUC__) || defined(__clang__)
67 return __builtin_bswap32(value);
68#else
69 return (value >> 24) |
70 ((value >> 8) & 0x0000FF00) |
71 ((value << 8) & 0x00FF0000) |
72 (value << 24);
73#endif
74 }
75
76 inline uint64_t byte_swap_64(uint64_t value) noexcept {
77#if defined(__GNUC__) || defined(__clang__)
78 return __builtin_bswap64(value);
79#else
80 const uint64_t val1 = byte_swap_32(value & 0xFFFFFFFF);
81 const uint64_t val2 = byte_swap_32(value >> 32);
82 return (val1 << 32) | val2;
83#endif
84 }
85
86 } // namespace util
87
101 template <typename TCRC>
102 class CRC {
103
104 TCRC m_crc;
105
106 public:
107
108 TCRC& operator()() noexcept {
109 return m_crc;
110 }
111
112 const TCRC& operator()() const noexcept {
113 return m_crc;
114 }
115
116 void update_bool(const bool value) noexcept {
117 m_crc.process_byte(value);
118 }
119
120 void update_int8(const uint8_t value) noexcept {
121 m_crc.process_byte(value);
122 }
123
124 void update_int16(const uint16_t value) noexcept {
125#if __BYTE_ORDER == __LITTLE_ENDIAN
126 m_crc.process_bytes(&value, sizeof(uint16_t));
127#else
128 const uint16_t v = osmium::byte_swap_16(value);
129 m_crc.process_bytes(&v, sizeof(uint16_t));
130#endif
131 }
132
133 void update_int32(const uint32_t value) noexcept {
134#if __BYTE_ORDER == __LITTLE_ENDIAN
135 m_crc.process_bytes(&value, sizeof(uint32_t));
136#else
137 const uint32_t v = osmium::byte_swap_32(value);
138 m_crc.process_bytes(&v, sizeof(uint32_t));
139#endif
140 }
141
142 void update_int64(const uint64_t value) noexcept {
143#if __BYTE_ORDER == __LITTLE_ENDIAN
144 m_crc.process_bytes(&value, sizeof(uint64_t));
145#else
146 const uint64_t v = osmium::byte_swap_64(value);
147 m_crc.process_bytes(&v, sizeof(uint64_t));
148#endif
149 }
150
151 void update_string(const char* str) noexcept {
152 while (*str) {
153 m_crc.process_byte(*str++);
154 }
155 }
156
157 void update(const Timestamp& timestamp) noexcept {
158 update_int32(static_cast<uint32_t>(timestamp));
159 }
160
161 void update(const osmium::Location& location) noexcept {
162 update_int32(location.x());
163 update_int32(location.y());
164 }
165
166 void update(const osmium::Box& box) noexcept {
167 update(box.bottom_left());
168 update(box.top_right());
169 }
170
171 void update(const NodeRef& node_ref) noexcept {
172 update_int64(static_cast<uint64_t>(node_ref.ref()));
173 update(node_ref.location());
174 }
175
176 void update(const NodeRefList& node_refs) noexcept {
177 for (const NodeRef& node_ref : node_refs) {
178 update(node_ref);
179 }
180 }
181
182 void update(const TagList& tags) noexcept {
183 for (const Tag& tag : tags) {
184 update_string(tag.key());
185 update_string(tag.value());
186 }
187 }
188
189 void update(const osmium::RelationMember& member) noexcept {
190 update_int64(static_cast<uint64_t>(member.ref()));
191 update_int16(static_cast<uint16_t>(member.type()));
192 update_string(member.role());
193 }
194
195 void update(const osmium::RelationMemberList& members) noexcept {
196 for (const RelationMember& member : members) {
197 update(member);
198 }
199 }
200
201 // XXX Changeset id is not added to the CRC. This is an oversight,
202 // but we don't want to change this now to keep compatibility.
203 void update(const osmium::OSMObject& object) noexcept {
204 update_int64(static_cast<uint64_t>(object.id()));
205 update_bool(object.visible());
206 update_int32(object.version());
207 update(object.timestamp());
208 update_int32(object.uid());
209 update_string(object.user());
210 update(object.tags());
211 }
212
213 void update(const osmium::Node& node) noexcept {
214 update(static_cast<const osmium::OSMObject&>(node));
215 update(node.location());
216 }
217
218 void update(const osmium::Way& way) noexcept {
219 update(static_cast<const osmium::OSMObject&>(way));
220 update(way.nodes());
221 }
222
223 void update(const osmium::Relation& relation) noexcept {
224 update(static_cast<const osmium::OSMObject&>(relation));
225 update(relation.members());
226 }
227
228 void update(const osmium::Area& area) noexcept {
229 update(static_cast<const osmium::OSMObject&>(area));
230 for (const auto& subitem : area) {
231 if (subitem.type() == osmium::item_type::outer_ring ||
232 subitem.type() == osmium::item_type::inner_ring) {
233 update(static_cast<const osmium::NodeRefList&>(subitem));
234 }
235 }
236 }
237
238 void update(const osmium::ChangesetDiscussion& discussion) noexcept {
239 for (const auto& comment : discussion) {
240 update(comment.date());
241 update_int32(comment.uid());
242 update_string(comment.user());
243 update_string(comment.text());
244 }
245 }
246
247 void update(const osmium::Changeset& changeset) noexcept {
248 // The static_cast and use of update_int64 is necessary here
249 // for backwards compatibility. It should have used update_int32.
250 update_int64(static_cast<uint64_t>(changeset.id()));
251 update(changeset.created_at());
252 update(changeset.closed_at());
253 update(changeset.bounds());
254 update_int32(changeset.num_changes());
255 update_int32(changeset.num_comments());
256 update_int32(changeset.uid());
257 update_string(changeset.user());
258 update(changeset.tags());
259 update(changeset.discussion());
260 }
261
262 }; // class CRC
263
264} // namespace osmium
265
266#endif // OSMIUM_OSM_CRC_HPP
Definition: area.hpp:125
Definition: crc.hpp:102
void update(const osmium::Changeset &changeset) noexcept
Definition: crc.hpp:247
void update(const osmium::RelationMemberList &members) noexcept
Definition: crc.hpp:195
void update_string(const char *str) noexcept
Definition: crc.hpp:151
void update(const osmium::Box &box) noexcept
Definition: crc.hpp:166
void update(const osmium::RelationMember &member) noexcept
Definition: crc.hpp:189
void update(const osmium::OSMObject &object) noexcept
Definition: crc.hpp:203
void update(const Timestamp &timestamp) noexcept
Definition: crc.hpp:157
const TCRC & operator()() const noexcept
Definition: crc.hpp:112
void update(const osmium::Node &node) noexcept
Definition: crc.hpp:213
void update(const osmium::Way &way) noexcept
Definition: crc.hpp:218
TCRC & operator()() noexcept
Definition: crc.hpp:108
void update(const osmium::Area &area) noexcept
Definition: crc.hpp:228
void update_int8(const uint8_t value) noexcept
Definition: crc.hpp:120
void update_int64(const uint64_t value) noexcept
Definition: crc.hpp:142
void update_int16(const uint16_t value) noexcept
Definition: crc.hpp:124
void update_bool(const bool value) noexcept
Definition: crc.hpp:116
void update(const NodeRefList &node_refs) noexcept
Definition: crc.hpp:176
void update(const NodeRef &node_ref) noexcept
Definition: crc.hpp:171
void update(const osmium::ChangesetDiscussion &discussion) noexcept
Definition: crc.hpp:238
void update_int32(const uint32_t value) noexcept
Definition: crc.hpp:133
void update(const osmium::Location &location) noexcept
Definition: crc.hpp:161
void update(const osmium::Relation &relation) noexcept
Definition: crc.hpp:223
void update(const TagList &tags) noexcept
Definition: crc.hpp:182
TCRC m_crc
Definition: crc.hpp:104
Definition: changeset.hpp:130
An OSM Changeset, a group of changes made by a single user over a short period of time.
Definition: changeset.hpp:146
Definition: location.hpp:271
Definition: node_ref_list.hpp:52
Definition: node_ref.hpp:50
Definition: node.hpp:48
Definition: object.hpp:64
Definition: relation.hpp:147
Definition: relation.hpp:56
Definition: relation.hpp:161
Definition: tag.hpp:119
Definition: tag.hpp:48
Definition: timestamp.hpp:175
Definition: way.hpp:72
uint16_t byte_swap_16(uint16_t value) noexcept
Definition: crc.hpp:57
uint64_t byte_swap_64(uint64_t value) noexcept
Definition: crc.hpp:76
uint32_t byte_swap_32(uint32_t value) noexcept
Definition: crc.hpp:65
Namespace for everything in the Osmium library.
Definition: assembler.hpp:53