2016-03-01 11:56:55 -05:00
|
|
|
#ifndef OSMIUM_OSM_CRC_HPP
|
|
|
|
#define OSMIUM_OSM_CRC_HPP
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
|
|
|
This file is part of Osmium (http://osmcode.org/libosmium).
|
|
|
|
|
2017-01-20 08:05:21 -05:00
|
|
|
Copyright 2013-2017 Jochen Topf <jochen@topf.org> and others (see README).
|
2016-03-01 11:56:55 -05:00
|
|
|
|
|
|
|
Boost Software License - Version 1.0 - August 17th, 2003
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person or organization
|
|
|
|
obtaining a copy of the software and accompanying documentation covered by
|
|
|
|
this license (the "Software") to use, reproduce, display, distribute,
|
|
|
|
execute, and transmit the Software, and to prepare derivative works of the
|
|
|
|
Software, and to permit third-parties to whom the Software is furnished to
|
|
|
|
do so, all subject to the following:
|
|
|
|
|
|
|
|
The copyright notices in the Software and this entire statement, including
|
|
|
|
the above license grant, this restriction and the following disclaimer,
|
|
|
|
must be included in all copies of the Software, in whole or in part, and
|
|
|
|
all derivative works of the Software, unless such copies or derivative
|
|
|
|
works are solely in the form of machine-executable object code generated by
|
|
|
|
a source language processor.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
|
|
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
|
|
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
|
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
|
DEALINGS IN THE SOFTWARE.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <cstdint>
|
|
|
|
|
|
|
|
#include <osmium/osm/area.hpp>
|
2016-10-03 13:08:59 -04:00
|
|
|
#include <osmium/osm/box.hpp>
|
2016-03-01 11:56:55 -05:00
|
|
|
#include <osmium/osm/changeset.hpp>
|
2016-10-03 13:08:59 -04:00
|
|
|
#include <osmium/osm/item_type.hpp>
|
2016-03-01 11:56:55 -05:00
|
|
|
#include <osmium/osm/location.hpp>
|
|
|
|
#include <osmium/osm/node.hpp>
|
2016-10-03 13:08:59 -04:00
|
|
|
#include <osmium/osm/node_ref.hpp>
|
2016-03-01 11:56:55 -05:00
|
|
|
#include <osmium/osm/node_ref_list.hpp>
|
2016-10-03 13:08:59 -04:00
|
|
|
#include <osmium/osm/object.hpp>
|
2016-03-01 11:56:55 -05:00
|
|
|
#include <osmium/osm/relation.hpp>
|
2016-10-03 13:08:59 -04:00
|
|
|
#include <osmium/osm/tag.hpp>
|
|
|
|
#include <osmium/osm/timestamp.hpp>
|
2016-03-01 11:56:55 -05:00
|
|
|
#include <osmium/osm/way.hpp>
|
|
|
|
#include <osmium/util/endian.hpp>
|
|
|
|
|
|
|
|
namespace osmium {
|
|
|
|
|
|
|
|
namespace util {
|
|
|
|
|
|
|
|
inline uint16_t byte_swap_16(uint16_t value) noexcept {
|
|
|
|
# if defined(__GNUC__) || defined(__clang__)
|
|
|
|
return __builtin_bswap16(value);
|
|
|
|
# else
|
|
|
|
return (value >> 8) | (value << 8);
|
|
|
|
# endif
|
|
|
|
}
|
|
|
|
|
|
|
|
inline uint32_t byte_swap_32(uint32_t value) noexcept {
|
|
|
|
# if defined(__GNUC__) || defined(__clang__)
|
|
|
|
return __builtin_bswap32(value);
|
|
|
|
# else
|
|
|
|
return (value >> 24) |
|
|
|
|
((value >> 8) & 0x0000FF00) |
|
|
|
|
((value << 8) & 0x00FF0000) |
|
|
|
|
(value << 24);
|
|
|
|
# endif
|
|
|
|
}
|
|
|
|
|
|
|
|
inline uint64_t byte_swap_64(uint64_t value) noexcept {
|
|
|
|
# if defined(__GNUC__) || defined(__clang__)
|
|
|
|
return __builtin_bswap64(value);
|
|
|
|
# else
|
2016-10-03 13:08:59 -04:00
|
|
|
const uint64_t val1 = byte_swap_32(value & 0xFFFFFFFF);
|
|
|
|
const uint64_t val2 = byte_swap_32(value >> 32);
|
2016-03-01 11:56:55 -05:00
|
|
|
return (val1 << 32) | val2;
|
|
|
|
# endif
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace util
|
|
|
|
|
|
|
|
template <typename TCRC>
|
|
|
|
class CRC {
|
|
|
|
|
|
|
|
TCRC m_crc;
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
2016-10-03 13:08:59 -04:00
|
|
|
TCRC& operator()() noexcept {
|
2016-03-01 11:56:55 -05:00
|
|
|
return m_crc;
|
|
|
|
}
|
|
|
|
|
2016-10-03 13:08:59 -04:00
|
|
|
const TCRC& operator()() const noexcept {
|
2016-03-01 11:56:55 -05:00
|
|
|
return m_crc;
|
|
|
|
}
|
|
|
|
|
2016-11-11 09:50:02 -05:00
|
|
|
void update_bool(const bool value) noexcept {
|
2016-03-01 11:56:55 -05:00
|
|
|
m_crc.process_byte(value);
|
|
|
|
}
|
|
|
|
|
2016-11-11 09:50:02 -05:00
|
|
|
void update_int8(const uint8_t value) noexcept {
|
2016-03-01 11:56:55 -05:00
|
|
|
m_crc.process_byte(value);
|
|
|
|
}
|
|
|
|
|
2016-11-11 09:50:02 -05:00
|
|
|
void update_int16(const uint16_t value) noexcept {
|
2016-03-01 11:56:55 -05:00
|
|
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
|
|
|
m_crc.process_bytes(&value, sizeof(uint16_t));
|
|
|
|
#else
|
2016-10-03 13:08:59 -04:00
|
|
|
const uint16_t v = osmium::util::byte_swap_16(value);
|
2016-03-01 11:56:55 -05:00
|
|
|
m_crc.process_bytes(&v, sizeof(uint16_t));
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2016-11-11 09:50:02 -05:00
|
|
|
void update_int32(const uint32_t value) noexcept {
|
2016-03-01 11:56:55 -05:00
|
|
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
|
|
|
m_crc.process_bytes(&value, sizeof(uint32_t));
|
|
|
|
#else
|
2016-10-03 13:08:59 -04:00
|
|
|
const uint32_t v = osmium::util::byte_swap_32(value);
|
2016-03-01 11:56:55 -05:00
|
|
|
m_crc.process_bytes(&v, sizeof(uint32_t));
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2016-11-11 09:50:02 -05:00
|
|
|
void update_int64(const uint64_t value) noexcept {
|
2016-03-01 11:56:55 -05:00
|
|
|
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
|
|
|
m_crc.process_bytes(&value, sizeof(uint64_t));
|
|
|
|
#else
|
2016-10-03 13:08:59 -04:00
|
|
|
const uint64_t v = osmium::util::byte_swap_64(value);
|
2016-03-01 11:56:55 -05:00
|
|
|
m_crc.process_bytes(&v, sizeof(uint64_t));
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2016-11-11 09:50:02 -05:00
|
|
|
void update_string(const char* str) noexcept {
|
2016-03-01 11:56:55 -05:00
|
|
|
while (*str) {
|
|
|
|
m_crc.process_byte(*str++);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-11 09:50:02 -05:00
|
|
|
void update(const Timestamp& timestamp) noexcept {
|
2016-03-01 11:56:55 -05:00
|
|
|
update_int32(uint32_t(timestamp));
|
|
|
|
}
|
|
|
|
|
2016-11-11 09:50:02 -05:00
|
|
|
void update(const osmium::Location& location) noexcept {
|
2016-03-01 11:56:55 -05:00
|
|
|
update_int32(location.x());
|
|
|
|
update_int32(location.y());
|
|
|
|
}
|
|
|
|
|
2016-11-11 09:50:02 -05:00
|
|
|
void update(const osmium::Box& box) noexcept {
|
2016-03-01 11:56:55 -05:00
|
|
|
update(box.bottom_left());
|
|
|
|
update(box.top_right());
|
|
|
|
}
|
|
|
|
|
2016-11-11 09:50:02 -05:00
|
|
|
void update(const NodeRef& node_ref) noexcept {
|
2016-03-01 11:56:55 -05:00
|
|
|
update_int64(node_ref.ref());
|
2016-10-03 13:08:59 -04:00
|
|
|
update(node_ref.location());
|
2016-03-01 11:56:55 -05:00
|
|
|
}
|
|
|
|
|
2016-11-11 09:50:02 -05:00
|
|
|
void update(const NodeRefList& node_refs) noexcept {
|
2016-03-01 11:56:55 -05:00
|
|
|
for (const NodeRef& node_ref : node_refs) {
|
|
|
|
update(node_ref);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-11 09:50:02 -05:00
|
|
|
void update(const TagList& tags) noexcept {
|
2016-03-01 11:56:55 -05:00
|
|
|
for (const Tag& tag : tags) {
|
|
|
|
update_string(tag.key());
|
|
|
|
update_string(tag.value());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-11 09:50:02 -05:00
|
|
|
void update(const osmium::RelationMember& member) noexcept {
|
2016-03-01 11:56:55 -05:00
|
|
|
update_int64(member.ref());
|
|
|
|
update_int16(uint16_t(member.type()));
|
|
|
|
update_string(member.role());
|
|
|
|
}
|
|
|
|
|
2016-11-11 09:50:02 -05:00
|
|
|
void update(const osmium::RelationMemberList& members) noexcept {
|
2016-03-01 11:56:55 -05:00
|
|
|
for (const RelationMember& member : members) {
|
|
|
|
update(member);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-11 09:50:02 -05:00
|
|
|
void update(const osmium::OSMObject& object) noexcept {
|
2016-03-01 11:56:55 -05:00
|
|
|
update_int64(object.id());
|
|
|
|
update_bool(object.visible());
|
|
|
|
update_int32(object.version());
|
|
|
|
update(object.timestamp());
|
|
|
|
update_int32(object.uid());
|
|
|
|
update_string(object.user());
|
|
|
|
update(object.tags());
|
|
|
|
}
|
|
|
|
|
2016-11-11 09:50:02 -05:00
|
|
|
void update(const osmium::Node& node) noexcept {
|
2016-03-01 11:56:55 -05:00
|
|
|
update(static_cast<const osmium::OSMObject&>(node));
|
|
|
|
update(node.location());
|
|
|
|
}
|
|
|
|
|
2016-11-11 09:50:02 -05:00
|
|
|
void update(const osmium::Way& way) noexcept {
|
2016-03-01 11:56:55 -05:00
|
|
|
update(static_cast<const osmium::OSMObject&>(way));
|
|
|
|
update(way.nodes());
|
|
|
|
}
|
|
|
|
|
2016-11-11 09:50:02 -05:00
|
|
|
void update(const osmium::Relation& relation) noexcept {
|
2016-03-01 11:56:55 -05:00
|
|
|
update(static_cast<const osmium::OSMObject&>(relation));
|
|
|
|
update(relation.members());
|
|
|
|
}
|
|
|
|
|
2016-11-11 09:50:02 -05:00
|
|
|
void update(const osmium::Area& area) noexcept {
|
2016-03-01 11:56:55 -05:00
|
|
|
update(static_cast<const osmium::OSMObject&>(area));
|
2016-10-03 13:08:59 -04:00
|
|
|
for (const auto& subitem : area) {
|
|
|
|
if (subitem.type() == osmium::item_type::outer_ring ||
|
|
|
|
subitem.type() == osmium::item_type::inner_ring) {
|
|
|
|
update(static_cast<const osmium::NodeRefList&>(subitem));
|
2016-03-01 11:56:55 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-11 09:50:02 -05:00
|
|
|
void update(const osmium::ChangesetDiscussion& discussion) noexcept {
|
2016-03-01 11:56:55 -05:00
|
|
|
for (const auto& comment : discussion) {
|
|
|
|
update(comment.date());
|
|
|
|
update_int32(comment.uid());
|
|
|
|
update_string(comment.user());
|
|
|
|
update_string(comment.text());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-11 09:50:02 -05:00
|
|
|
void update(const osmium::Changeset& changeset) noexcept {
|
2016-03-01 11:56:55 -05:00
|
|
|
update_int64(changeset.id());
|
|
|
|
update(changeset.created_at());
|
|
|
|
update(changeset.closed_at());
|
|
|
|
update(changeset.bounds());
|
|
|
|
update_int32(changeset.num_changes());
|
|
|
|
update_int32(changeset.num_comments());
|
|
|
|
update_int32(changeset.uid());
|
|
|
|
update_string(changeset.user());
|
|
|
|
update(changeset.tags());
|
|
|
|
update(changeset.discussion());
|
|
|
|
}
|
|
|
|
|
|
|
|
}; // class CRC
|
|
|
|
|
|
|
|
} // namespace osmium
|
|
|
|
|
|
|
|
#endif // OSMIUM_OSM_CRC
|