| 45 | } |
| 46 | |
| 47 | bool Ge0Parser::ParseAfterPrefix(std::string const & url, size_t from, Result & result) |
| 48 | { |
| 49 | size_t constexpr kEncodedZoomAndCoordinatesLength = 10; |
| 50 | if (url.size() < from + kEncodedZoomAndCoordinatesLength) |
| 51 | return false; |
| 52 | |
| 53 | size_t constexpr kMaxNameLength = 256; |
| 54 | |
| 55 | size_t const posZoom = from; |
| 56 | size_t const posLatLon = posZoom + 1; |
| 57 | size_t const posName = from + kEncodedZoomAndCoordinatesLength + 1; |
| 58 | size_t const lengthLatLon = posName - posLatLon - 1; |
| 59 | |
| 60 | uint8_t const zoomI = DecodeBase64Char(url[posZoom]); |
| 61 | if (zoomI >= 64) |
| 62 | return false; |
| 63 | result.m_zoomLevel = DecodeZoom(zoomI); |
| 64 | |
| 65 | if (!DecodeLatLon(url.substr(posLatLon, lengthLatLon), result.m_lat, result.m_lon)) |
| 66 | return false; |
| 67 | |
| 68 | ASSERT(mercator::ValidLat(result.m_lat), (result.m_lat)); |
| 69 | ASSERT(mercator::ValidLon(result.m_lon), (result.m_lon)); |
| 70 | |
| 71 | if (url.size() >= posName) |
| 72 | { |
| 73 | CHECK_GREATER(posName, 0, ()); |
| 74 | if (url[posName - 1] != '/') |
| 75 | return false; |
| 76 | result.m_name = DecodeName(url.substr(posName, std::min(url.size() - posName, kMaxNameLength))); |
| 77 | } |
| 78 | |
| 79 | return true; |
| 80 | } |
| 81 | |
| 82 | uint8_t Ge0Parser::DecodeBase64Char(char const c) |
| 83 | { |
no test coverage detected