diff --git a/src/PolylineAlgorithm/Abstraction/AbstractPolylineDecoder.cs b/src/PolylineAlgorithm/Abstraction/AbstractPolylineDecoder.cs index 12c4a447..c8cc1e54 100644 --- a/src/PolylineAlgorithm/Abstraction/AbstractPolylineDecoder.cs +++ b/src/PolylineAlgorithm/Abstraction/AbstractPolylineDecoder.cs @@ -12,12 +12,14 @@ namespace PolylineAlgorithm.Abstraction { /// - /// Decodes encoded polyline strings into sequences of geographic coordinates. - /// Implements the interface. + /// Provides a base implementation for decoding encoded polyline strings into sequences of geographic coordinates. /// /// - /// This abstract class provides a base implementation for decoding polylines, allowing subclasses to define how to handle specific polyline formats. + /// Derive from this class to implement a decoder for a specific polyline type. Override + /// and to provide type-specific behavior. /// + /// The type that represents the encoded polyline input. + /// The type that represents a decoded geographic coordinate. public abstract class AbstractPolylineDecoder : IPolylineDecoder { private readonly ILogger> _logger; @@ -34,7 +36,7 @@ protected AbstractPolylineDecoder() /// The to use for encoding operations. /// /// - /// Thrown when is + /// Thrown when is . /// protected AbstractPolylineDecoder(PolylineEncodingOptions options) { if (options is null) { @@ -74,14 +76,30 @@ public IEnumerable Decode(TPolyline polyline) => Decode(polyline, CancellationToken.None); /// - /// Decodes an encoded polyline with cancellation support. + /// Decodes an encoded into a sequence of instances, + /// with support for cancellation. /// - /// The encoded polyline. - /// Cancellation token. - /// Decoded coordinates. - /// - /// - /// + /// + /// The instance containing the encoded polyline string to decode. + /// + /// + /// A that can be used to cancel the decoding operation. + /// + /// + /// An of representing the decoded latitude and longitude pairs. + /// + /// + /// Thrown when is . + /// + /// + /// Thrown when is empty. + /// + /// + /// Thrown when the polyline format is invalid or malformed at a specific position. + /// + /// + /// Thrown when is canceled during decoding. + /// public IEnumerable Decode(TPolyline polyline, CancellationToken cancellationToken) { const string OperationName = nameof(Decode); @@ -124,11 +142,9 @@ public IEnumerable Decode(TPolyline polyline, CancellationToken can /// /// Validates that the provided polyline is not . - /// Throws an if the polyline is . - /// Optionally logs a warning if a logger is provided. /// /// The polyline instance to validate. - /// Optional logger for diagnostic messages. + /// An optional used to log a warning when validation fails. /// /// Thrown when is . /// @@ -141,12 +157,10 @@ private static void ValidateNullPolyline(TPolyline polyline, ILogger? logger) { } /// - /// Validates that the polyline sequence meets the minimum required length. - /// Throws an if the sequence is too short. - /// Optionally logs diagnostic messages if a logger is provided. + /// Validates that the polyline character sequence meets the minimum required length. /// /// The polyline character sequence to validate. - /// Optional logger for diagnostic messages. + /// An optional used to log diagnostic messages when validation fails. /// /// Thrown when is shorter than the minimum allowed length. /// @@ -161,8 +175,17 @@ private static void ValidateSequence(ReadOnlyMemory polylineSequence, ILog } /// - /// Validates the polyline format for allowed characters. + /// Validates the format of the polyline character sequence, ensuring all characters are within the allowed range. /// + /// + /// The read-only memory region of characters representing the polyline to validate. + /// + /// + /// An optional used to log a warning when format validation fails. + /// + /// + /// Thrown when the polyline contains characters outside the valid encoding range or has an invalid block structure. + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected virtual void ValidateFormat(ReadOnlyMemory sequence, ILogger? logger) { try { @@ -174,9 +197,30 @@ protected virtual void ValidateFormat(ReadOnlyMemory sequence, ILogger? lo } } + /// + /// Extracts the underlying read-only memory region of characters from the specified polyline instance. + /// + /// + /// The instance from which to extract the character sequence. + /// + /// + /// A of representing the encoded polyline characters. + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected abstract ReadOnlyMemory GetReadOnlyMemory(in TPolyline polyline); + /// + /// Creates a instance from the specified latitude and longitude values. + /// + /// + /// The latitude component of the coordinate, in degrees. + /// + /// + /// The longitude component of the coordinate, in degrees. + /// + /// + /// A instance representing the specified geographic coordinate. + /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected abstract TCoordinate CreateCoordinate(double latitude, double longitude); } diff --git a/src/PolylineAlgorithm/Abstraction/AbstractPolylineEncoder.cs b/src/PolylineAlgorithm/Abstraction/AbstractPolylineEncoder.cs index 816684f3..3f68736a 100644 --- a/src/PolylineAlgorithm/Abstraction/AbstractPolylineEncoder.cs +++ b/src/PolylineAlgorithm/Abstraction/AbstractPolylineEncoder.cs @@ -16,12 +16,14 @@ namespace PolylineAlgorithm.Abstraction; using System.Runtime.CompilerServices; /// -/// Provides functionality to encode a collection of geographic coordinates into an encoded polyline string. -/// Implements the interface. +/// Provides a base implementation for encoding sequences of geographic coordinates into encoded polyline strings. /// /// -/// This abstract class serves as a base for specific polyline encoders, allowing customization of the encoding process. +/// Derive from this class to implement an encoder for a specific coordinate and polyline type. Override +/// , , and to provide type-specific behavior. /// +/// The type that represents a geographic coordinate to encode. +/// The type that represents the encoded polyline output. public abstract class AbstractPolylineEncoder : IPolylineEncoder { private readonly ILogger> _logger; /// @@ -68,8 +70,9 @@ protected AbstractPolylineEncoder(PolylineEncodingOptions options) { /// /// Thrown when is an empty enumeration. /// - /// - /// + /// + /// Thrown when the internal encoding buffer cannot accommodate the encoded value. + /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "MA0051:Method is too long", Justification = "Method contains local methods. Actual method only 55 lines.")] public TPolyline Encode(ReadOnlySpan coordinates) { const string OperationName = nameof(Encode); diff --git a/src/PolylineAlgorithm/Extensions/PolylineDecoderExtensions.cs b/src/PolylineAlgorithm/Extensions/PolylineDecoderExtensions.cs index 2557e7a7..b29c0ecd 100644 --- a/src/PolylineAlgorithm/Extensions/PolylineDecoderExtensions.cs +++ b/src/PolylineAlgorithm/Extensions/PolylineDecoderExtensions.cs @@ -28,7 +28,7 @@ public static class PolylineDecoderExtensions { /// An containing the decoded latitude and longitude pairs. /// /// - /// Thrown when is . + /// Thrown when or is . /// public static IEnumerable Decode(this IPolylineDecoder decoder, string polyline) { if (decoder is null) { @@ -51,7 +51,7 @@ public static IEnumerable Decode(this IPolylineDecoder containing the decoded latitude and longitude pairs. /// /// - /// Thrown when is . + /// Thrown when or is . /// public static IEnumerable Decode(this IPolylineDecoder decoder, char[] polyline) { if (decoder is null) { diff --git a/src/PolylineAlgorithm/Extensions/PolylineEncoderExtensions.cs b/src/PolylineAlgorithm/Extensions/PolylineEncoderExtensions.cs index 113d3d09..e9b66923 100644 --- a/src/PolylineAlgorithm/Extensions/PolylineEncoderExtensions.cs +++ b/src/PolylineAlgorithm/Extensions/PolylineEncoderExtensions.cs @@ -1,4 +1,7 @@ - +// +// Copyright © Pete Sramek. All rights reserved. +// Licensed under the MIT License. See LICENSE file in the project root for full license information. +// namespace PolylineAlgorithm.Extensions; @@ -15,19 +18,21 @@ namespace PolylineAlgorithm.Extensions; /// public static class PolylineEncoderExtensions { /// - /// Encodes a collection of instances into an encoded polyline. + /// Encodes a of instances into an encoded polyline. /// + /// The type that represents a geographic coordinate to encode. + /// The type that represents the encoded polyline output. /// /// The instance used to perform the encoding operation. /// /// - /// The sequence of objects to encode. + /// The list of objects to encode. /// /// - /// A representing the encoded polyline string for the provided coordinates. + /// A instance representing the encoded polyline for the provided coordinates. /// /// - /// Thrown when is . + /// Thrown when or is . /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1002:Do not expose generic lists", Justification = "We need a list as we do need to marshal it as span.")] [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "MA0016:Prefer using collection abstraction instead of implementation", Justification = "We need a list as we do need to marshal it as span.")] @@ -49,19 +54,21 @@ public static TPolyline Encode(this IPolylineEncoder - /// Encodes an array of instances into an encoded polyline. + /// Encodes an array of instances into an encoded polyline. /// + /// The type that represents a geographic coordinate to encode. + /// The type that represents the encoded polyline output. /// /// The instance used to perform the encoding operation. /// /// - /// The array of objects to encode. + /// The array of objects to encode. /// /// - /// A representing the encoded polyline string for the provided coordinates. + /// A instance representing the encoded polyline for the provided coordinates. /// /// - /// Thrown when is . + /// Thrown when or is . /// public static TPolyline Encode(this IPolylineEncoder encoder, TCoordinate[] coordinates) { if (encoder is null) { diff --git a/src/PolylineAlgorithm/Internal/CoordinateDelta.cs b/src/PolylineAlgorithm/Internal/CoordinateDelta.cs index 830d90ef..cfb0e896 100644 --- a/src/PolylineAlgorithm/Internal/CoordinateDelta.cs +++ b/src/PolylineAlgorithm/Internal/CoordinateDelta.cs @@ -10,8 +10,10 @@ namespace PolylineAlgorithm.Internal; /// /// Represents the difference (delta) in latitude and longitude between consecutive geographic coordinates. -/// This struct is used to compute and store the change in coordinate values as integer deltas. /// +/// +/// This struct computes and stores the change in coordinate values as integer deltas between successive coordinates. +/// [DebuggerDisplay("{ToString(),nq}")] [StructLayout(LayoutKind.Auto)] internal struct CoordinateDelta { @@ -39,7 +41,6 @@ public CoordinateDelta() { /// /// The next latitude value. /// The next longitude value. - public void Next(int latitude, int longitude) { Latitude = Delta(_current.Latitude, latitude); Longitude = Delta(_current.Longitude, longitude); @@ -57,7 +58,6 @@ public void Next(int latitude, int longitude) { /// The previous coordinate value. /// The next coordinate value. /// The computed delta between and . - private static int Delta(int initial, int next) => next - initial; /// diff --git a/src/PolylineAlgorithm/Internal/Defaults.cs b/src/PolylineAlgorithm/Internal/Defaults.cs index 28f32b2a..38da0263 100644 --- a/src/PolylineAlgorithm/Internal/Defaults.cs +++ b/src/PolylineAlgorithm/Internal/Defaults.cs @@ -9,8 +9,10 @@ namespace PolylineAlgorithm.Internal; /// /// Provides default values and constants used throughout the Polyline Algorithm. -/// Organizes defaults for algorithm parameters, polyline encoding, and geographic coordinates into nested static classes. /// +/// +/// Organizes defaults for algorithm parameters, polyline encoding, and geographic coordinates into nested static classes. +/// [ExcludeFromCodeCoverage] internal static class Defaults { /// @@ -18,7 +20,7 @@ internal static class Defaults { /// internal static class Logging { /// - /// Log level multiplier used to distinguish event identification for each log level + /// Log level multiplier used to distinguish event identification for each log level. /// internal const int LogLevelMultiplier = 100; } @@ -48,6 +50,9 @@ internal static class Algorithm { internal const byte UnitSeparator = 31; } + /// + /// Contains default values and constants for geographic coordinate validation. + /// internal static class Coordinate { /// /// Provides constants representing latitude values, including the default, minimum, and maximum valid values. @@ -95,7 +100,7 @@ internal static class Polyline { /// internal static class Block { /// - /// Contains constants related to the length of encoded vakues in polyline encoding. + /// Contains constants related to the length of encoded values in polyline encoding. /// internal static class Length { /// diff --git a/src/PolylineAlgorithm/PolylineEncoding.cs b/src/PolylineAlgorithm/PolylineEncoding.cs index 045445da..4b8d5312 100644 --- a/src/PolylineAlgorithm/PolylineEncoding.cs +++ b/src/PolylineAlgorithm/PolylineEncoding.cs @@ -27,7 +27,7 @@ public static class PolylineEncoding { /// /// /// This method converts a floating-point coordinate value into a normalized integer by multiplying it by 10 raised - /// to the power of the specified precision, then rounding the result using the specified strategy. + /// to the power of the specified precision, then truncating the result to an integer. /// /// /// For example, with the default precision of 5: @@ -211,7 +211,7 @@ public static bool TryReadValue(ref int delta, ReadOnlyMemory buffer, ref /// more characters follow. The position is advanced as characters are written. /// /// - /// Before writing, the method validates that sufficient space is available in the buffer by calling . + /// Before writing, the method validates that sufficient space is available in the buffer by calling . /// If the buffer does not have enough remaining capacity, the method returns without modifying the buffer or position. /// /// diff --git a/src/PolylineAlgorithm/PolylineEncodingOptionsBuilder.cs b/src/PolylineAlgorithm/PolylineEncodingOptionsBuilder.cs index 24fa7572..b39f00e1 100644 --- a/src/PolylineAlgorithm/PolylineEncodingOptionsBuilder.cs +++ b/src/PolylineAlgorithm/PolylineEncodingOptionsBuilder.cs @@ -50,7 +50,7 @@ public PolylineEncodingOptions Build() { /// The maximum buffer size to use for stack allocation. Must be greater than or equal to 1. /// /// - /// Returns the current instance for method chaining. + /// The current instance for method chaining. /// /// /// Thrown if is less than 1. @@ -71,13 +71,13 @@ public PolylineEncodingOptionsBuilder WithStackAllocLimit(int stackAllocLimit) { } /// - /// Sets the precision for encoding values. + /// Sets the coordinate encoding precision. /// /// - /// The number of decimal places to use for encoding values. Default is 5. + /// The number of decimal places to use for encoding coordinate values. Default is 5. /// /// - /// The current builder instance. + /// The current instance for method chaining. /// public PolylineEncodingOptionsBuilder WithPrecision(uint precision) { _precision = precision; @@ -92,7 +92,7 @@ public PolylineEncodingOptionsBuilder WithPrecision(uint precision) { /// The instance to use for logging. If , a will be used instead. /// /// - /// Returns the current instance for method chaining. + /// The current instance for method chaining. /// public PolylineEncodingOptionsBuilder WithLoggerFactory(ILoggerFactory loggerFactory) { _loggerFactory = loggerFactory ?? NullLoggerFactory.Instance;