From 8024cc61a5d70e6135e4fc0c312fd864f521da79 Mon Sep 17 00:00:00 2001 From: Vladimir Byko-Ianko Date: Mon, 16 Oct 2017 19:12:08 +0300 Subject: [PATCH] Trasnit data structures validation. --- generator/transit_generator.cpp | 15 ++++++++- routing_common/transit_types.cpp | 54 ++++++++++++++++++++++++++++++++ routing_common/transit_types.hpp | 12 ++++++- 3 files changed, 79 insertions(+), 2 deletions(-) diff --git a/generator/transit_generator.cpp b/generator/transit_generator.cpp index 4d439959d5..cdd97820be 100644 --- a/generator/transit_generator.cpp +++ b/generator/transit_generator.cpp @@ -125,13 +125,24 @@ void DeserializeGatesFromJson(my::Json const & root, string const & mwmDir, stri } } +template +bool IsValid(vector const & items) +{ + for (auto const & i : items) + { + if (!i.IsValid()) + return false; + } + return true; +} + /// \brief Reads from |root| (json) and serializes an array to |serializer|. template void SerializeObject(my::Json const & root, string const & key, Serializer & serializer) { vector items; DeserializeFromJson(root, key, items); - + CHECK(IsValid(items), ("key:", key, "items:", items)); serializer(items); } } // namespace @@ -200,6 +211,7 @@ void BuildTransit(string const & mwmPath, string const & transitDir) // the mwm is used to filled |gates|. vector gates; DeserializeGatesFromJson(root, my::GetDirectory(mwmPath), countryId, gates); + CHECK(IsValid(gates), (gates)); FilesContainerW cont(mwmPath, FileWriter::OP_WRITE_EXISTING); FileWriter w = cont.GetWriter(TRANSIT_FILE_TAG); @@ -232,6 +244,7 @@ void BuildTransit(string const & mwmPath, string const & transitDir) header.m_endOffset = base::checked_cast(w.Pos() - startOffset); // Rewriting header info. + CHECK(header.IsValid(), (header)); auto const endOffset = w.Pos(); w.Seek(startOffset); header.Visit(serializer); diff --git a/routing_common/transit_types.cpp b/routing_common/transit_types.cpp index 4c316a81ec..ea8424b022 100644 --- a/routing_common/transit_types.cpp +++ b/routing_common/transit_types.cpp @@ -54,6 +54,13 @@ bool TransitHeader::IsEqualForTesting(TransitHeader const & header) const && m_endOffset == header.m_endOffset; } +bool TransitHeader::IsValid() const +{ + return m_gatesOffset <= m_edgesOffset && m_edgesOffset <= m_transfersOffset && + m_transfersOffset <= m_linesOffset && m_linesOffset <= m_shapesOffset && + m_shapesOffset <= m_networksOffset && m_networksOffset <= m_endOffset; +} + // TitleAnchor ------------------------------------------------------------------------------------ TitleAnchor::TitleAnchor(uint8_t minZoom, Anchor anchor) : m_minZoom(minZoom), m_anchor(anchor) {} @@ -67,6 +74,11 @@ bool TitleAnchor::IsEqualForTesting(TitleAnchor const & titleAnchor) const return *this == titleAnchor; } +bool TitleAnchor::IsValid() const +{ + return m_anchor != kInvalidAnchor; +} + // Stop ------------------------------------------------------------------------------------------- Stop::Stop(StopId id, FeatureId featureId, TransferId transferId, std::vector const & lineIds, m2::PointD const & point, @@ -89,6 +101,11 @@ bool Stop::IsEqualForTesting(Stop const & stop) const m_titleAnchors == stop.m_titleAnchors; } +bool Stop::IsValid() const +{ + return m_id != kInvalidStopId && !m_lineIds.empty(); +} + // SingleMwmSegment ------------------------------------------------------------------------------- SingleMwmSegment::SingleMwmSegment(FeatureId featureId, uint32_t segmentIdx, bool forward) : m_featureId(featureId), m_segmentIdx(segmentIdx), m_forward(forward) @@ -100,6 +117,11 @@ bool SingleMwmSegment::IsEqualForTesting(SingleMwmSegment const & s) const return m_featureId == s.m_featureId && m_segmentIdx == s.m_segmentIdx && m_forward == s.m_forward; } +bool SingleMwmSegment::IsValid() const +{ + return true; +} + // Gate ------------------------------------------------------------------------------------------- Gate::Gate(FeatureId featureId, bool entrance, bool exit, double weight, std::vector const & stopIds, m2::PointD const & point) @@ -121,6 +143,11 @@ bool Gate::IsEqualForTesting(Gate const & gate) const my::AlmostEqualAbs(m_point, gate.m_point, kPointsEqualEpsilon); } +bool Gate::IsValid() const +{ + return m_weight != kInvalidWeight && !m_stopIds.empty(); +} + // Edge ------------------------------------------------------------------------------------------- Edge::Edge(StopId stop1Id, StopId stop2Id, double weight, LineId lineId, bool transfer, std::vector const & shapeIds) @@ -141,6 +168,12 @@ bool Edge::IsEqualForTesting(Edge const & edge) const m_shapeIds == edge.m_shapeIds; } +bool Edge::IsValid() const +{ + // @TODO(bykoianko) |m_weight| should be valid for Edge validity. + return m_stop1Id != kInvalidStopId && m_stop2Id != kInvalidStopId && m_lineId != kInvalidLineId; +} + // Transfer --------------------------------------------------------------------------------------- Transfer::Transfer(StopId id, m2::PointD const & point, std::vector const & stopIds, std::vector const & titleAnchors) @@ -155,6 +188,11 @@ bool Transfer::IsEqualForTesting(Transfer const & transfer) const m_stopIds == transfer.m_stopIds && m_titleAnchors == transfer.m_titleAnchors; } +bool Transfer::IsValid() const +{ + return m_id != kInvalidStopId && !m_stopIds.empty(); +} + // Line ------------------------------------------------------------------------------------------- Line::Line(LineId id, std::string const & number, std::string const & title, std::string const & type, NetworkId networkId, std::vector const & stopIds) @@ -173,6 +211,11 @@ bool Line::IsEqualForTesting(Line const & line) const m_type == line.m_type && m_networkId == line.m_networkId && m_stopIds == line.m_stopIds; } +bool Line::IsValid() const +{ + return m_id != kInvalidLineId && m_networkId != kInvalidNetworkId && !m_stopIds.empty(); +} + // Shape ------------------------------------------------------------------------------------------ Shape::Shape(ShapeId id, StopId stop1_id, StopId stop2_id, std::vector const & polyline) : m_id(id), m_stop1_id(stop1_id), m_stop2_id(stop2_id), m_polyline(polyline) @@ -195,6 +238,12 @@ bool Shape::IsEqualForTesting(Shape const & shape) const return true; } +bool Shape::IsValid() const +{ + return m_id != kInvalidShapeId && m_stop1_id != kInvalidStopId && m_stop2_id != kInvalidStopId && + !m_polyline.empty(); +} + // Network ---------------------------------------------------------------------------------------- Network::Network(NetworkId id, std::string const & title) : m_id(id), m_title(title) @@ -205,5 +254,10 @@ bool Network::IsEqualForTesting(Network const & shape) const { return m_id == shape.m_id && m_title == shape.m_title; } + +bool Network::IsValid() const +{ + return m_id != kInvalidNetworkId; +} } // namespace transit } // namespace routing diff --git a/routing_common/transit_types.hpp b/routing_common/transit_types.hpp index f8d5011a5f..28bac43918 100644 --- a/routing_common/transit_types.hpp +++ b/routing_common/transit_types.hpp @@ -51,6 +51,7 @@ struct TransitHeader uint32_t networksOffset, uint32_t endOffset); void Reset(); bool IsEqualForTesting(TransitHeader const & header) const; + bool IsValid() const; private: DECLARE_TRANSIT_TYPE_FRIENDS @@ -83,6 +84,7 @@ public: bool operator==(TitleAnchor const & titleAnchor) const; bool IsEqualForTesting(TitleAnchor const & titleAnchor) const; + bool IsValid() const; uint8_t GetMinZoom() const { return m_minZoom; } Anchor const & GetAnchor() const { return m_anchor; } @@ -103,6 +105,7 @@ public: Stop(StopId id, FeatureId featureId, TransferId transferId, std::vector const & lineIds, m2::PointD const & point, std::vector const & titleAnchors); bool IsEqualForTesting(Stop const & stop) const; + bool IsValid() const; StopId GetId() const { return m_id; } FeatureId GetFeatureId() const { return m_featureId; } @@ -132,6 +135,7 @@ public: SingleMwmSegment() = default; SingleMwmSegment(FeatureId featureId, uint32_t segmentIdx, bool forward); bool IsEqualForTesting(SingleMwmSegment const & s) const; + bool IsValid() const; FeatureId GetFeatureId() const { return m_featureId; } uint32_t GetSegmentIdx() const { return m_segmentIdx; } @@ -155,6 +159,7 @@ public: Gate(FeatureId featureId, bool entrance, bool exit, double weight, std::vector const & stopIds, m2::PointD const & point); bool IsEqualForTesting(Gate const & gate) const; + bool IsValid() const; void SetBestPedestrianSegment(SingleMwmSegment const & s) { m_bestPedestrianSegment = s; }; FeatureId GetFeatureId() const { return m_featureId; } @@ -191,6 +196,7 @@ public: Edge(StopId stop1Id, StopId stop2Id, double weight, LineId lineId, bool transfer, std::vector const & shapeIds); bool IsEqualForTesting(Edge const & edge) const; + bool IsValid() const; StopId GetStop1Id() const { return m_stop1Id; } StopId GetStop2Id() const { return m_stop2Id; } @@ -221,6 +227,7 @@ public: Transfer(StopId id, m2::PointD const & point, std::vector const & stopIds, std::vector const & titleAnchors); bool IsEqualForTesting(Transfer const & transfer) const; + bool IsValid() const; StopId GetId() const { return m_id; } m2::PointD const & GetPoint() const { return m_point; } @@ -246,6 +253,7 @@ public: Line(LineId id, std::string const & number, std::string const & title, std::string const & type, NetworkId networkId, std::vector const & stopIds); bool IsEqualForTesting(Line const & line) const; + bool IsValid() const; LineId GetId() const { return m_id; } std::string const & GetNumber() const { return m_number; } @@ -275,6 +283,7 @@ public: Shape() = default; Shape(ShapeId id, StopId stop1_id, StopId stop2_id, std::vector const & polyline); bool IsEqualForTesting(Shape const & shape) const; + bool IsValid() const; ShapeId GetId() const { return m_id; } StopId GetStop1Id() const { return m_stop1_id; } @@ -298,6 +307,7 @@ public: Network() = default; Network(NetworkId id, std::string const & title); bool IsEqualForTesting(Network const & shape) const; + bool IsValid() const; NetworkId GetId() const { return m_id; } std::string const & GetTitle() const { return m_title; } @@ -306,7 +316,7 @@ private: DECLARE_TRANSIT_TYPE_FRIENDS DECLARE_VISITOR_AND_DEBUG_PRINT(Network, visitor(m_id, "id"), visitor(m_title, "title")) - NetworkId m_id; + NetworkId m_id = kInvalidNetworkId; std::string m_title; };