77using PolylineAlgorithm ;
88using PolylineAlgorithm . Diagnostics ;
99using PolylineAlgorithm . Internal ;
10+ using PolylineAlgorithm . Internal . Diagnostics ;
1011using PolylineAlgorithm . Internal . Logging ;
1112using System ;
1213using System . Runtime . CompilerServices ;
1314using System . Threading ;
1415
15- namespace PolylineAlgorithm . Abstraction
16- {
16+ namespace PolylineAlgorithm . Abstraction {
1717 /// <summary>
1818 /// Decodes encoded polyline strings into sequences of geographic coordinates.
1919 /// Implements the <see cref="IPolylineDecoder{TPolyline, TCoordinate}"/> interface.
2020 /// </summary>
2121 /// <remarks>
2222 /// This abstract class provides a base implementation for decoding polylines, allowing subclasses to define how to handle specific polyline formats.
2323 /// </remarks>
24- public abstract class AbstractPolylineDecoder < TPolyline , TCoordinate > : IPolylineDecoder < TPolyline , TCoordinate >
25- {
24+ public abstract class AbstractPolylineDecoder < TPolyline , TCoordinate > : IPolylineDecoder < TPolyline , TCoordinate > {
2625 private readonly ILogger < AbstractPolylineDecoder < TPolyline , TCoordinate > > _logger ;
2726
2827 /// <summary>
@@ -40,10 +39,15 @@ protected AbstractPolylineDecoder()
4039 /// <exception cref="ArgumentNullException">
4140 /// Thrown when <paramref name="encodingOptions"/> is <see langword="null" />
4241 /// </exception>
43- protected AbstractPolylineDecoder ( PolylineEncodingOptions encodingOptions )
44- {
45- Options = encodingOptions ?? throw new ArgumentNullException ( nameof ( encodingOptions ) ) ;
46- _logger = Options . LoggerFactory . CreateLogger < AbstractPolylineDecoder < TPolyline , TCoordinate > > ( ) ;
42+ protected AbstractPolylineDecoder ( PolylineEncodingOptions options ) {
43+ if ( options is null ) {
44+ ExceptionGuard . ThrowArgumentNull ( nameof ( options ) ) ;
45+ }
46+
47+ Options = options ;
48+ _logger = Options
49+ . LoggerFactory
50+ . CreateLogger < AbstractPolylineDecoder < TPolyline , TCoordinate > > ( ) ;
4751 }
4852
4953 /// <summary>
@@ -81,99 +85,83 @@ public IEnumerable<TCoordinate> Decode(TPolyline polyline)
8185 /// <exception cref="ArgumentNullException"/>
8286 /// <exception cref="ArgumentException"/>
8387 /// <exception cref="InvalidPolylineException"/>
84- public IEnumerable < TCoordinate > Decode ( TPolyline polyline , CancellationToken cancellationToken )
85- {
88+ public IEnumerable < TCoordinate > Decode ( TPolyline polyline , CancellationToken cancellationToken ) {
8689 const string OperationName = nameof ( Decode ) ;
8790
8891 _logger ? . LogOperationStartedDebug ( OperationName ) ;
8992
9093 ValidateNullPolyline ( polyline , _logger ) ;
9194
92- ReadOnlyMemory < char > polylineSequence = GetReadOnlyMemory ( in polyline ) ;
95+ ReadOnlyMemory < char > sequence = GetReadOnlyMemory ( in polyline ) ;
9396
94- ValidateEmptySequence ( polylineSequence , _logger ) ;
95- ValidateFormat ( polylineSequence , _logger ) ;
97+ ValidateSequence ( sequence , _logger ) ;
98+ ValidateFormat ( sequence , _logger ) ;
9699
97- int currentPosition = 0 ;
100+ int position = 0 ;
98101 int encodedLatitude = 0 ;
99102 int encodedLongitude = 0 ;
100103
101- try
102- {
103- while ( currentPosition < polylineSequence . Length )
104- {
104+ try {
105+ while ( position < sequence . Length ) {
105106 cancellationToken . ThrowIfCancellationRequested ( ) ;
106107
107- if ( ! PolylineEncoding . TryReadValue ( ref encodedLatitude , polylineSequence , ref currentPosition )
108- || ! PolylineEncoding . TryReadValue ( ref encodedLongitude , polylineSequence , ref currentPosition ) )
109- {
108+ if ( ! PolylineEncoding . TryReadValue ( ref encodedLatitude , sequence , ref position )
109+ || ! PolylineEncoding . TryReadValue ( ref encodedLongitude , sequence , ref position ) ) {
110110 _logger ? . LogOperationFailedDebug ( OperationName ) ;
111- _logger ? . LogInvalidPolylineWarning ( currentPosition ) ;
111+ _logger ? . LogInvalidPolylineWarning ( position ) ;
112112
113- OnInvalidPolyline ( currentPosition , polylineSequence ) ;
114- InvalidPolylineException . Throw ( currentPosition ) ;
113+ OnInvalidPolyline ( position , sequence ) ;
114+ ExceptionGuard . ThrowInvalidPolylineFormat ( position ) ;
115115 }
116116
117117 double decodedLatitude = PolylineEncoding . Denormalize ( encodedLatitude , Options . Precision ) ;
118118 double decodedLongitude = PolylineEncoding . Denormalize ( encodedLongitude , Options . Precision ) ;
119119
120- _logger ? . LogDecodedCoordinateDebug ( decodedLatitude , decodedLongitude , currentPosition ) ;
120+ _logger ? . LogDecodedCoordinateDebug ( decodedLatitude , decodedLongitude , position ) ;
121121
122122 yield return CreateCoordinate ( decodedLatitude , decodedLongitude ) ;
123123 }
124- }
125- finally
126- {
124+ } finally {
127125 _logger ? . LogOperationFinishedDebug ( OperationName ) ;
128126 }
129127 }
130128
131129 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
132- private static void ValidateNullPolyline ( TPolyline polyline , ILogger logger )
133- {
134- if ( polyline is null )
135- {
130+ private static void ValidateNullPolyline ( TPolyline polyline , ILogger ? logger ) {
131+ if ( polyline is null ) {
136132 logger ? . LogNullArgumentWarning ( nameof ( polyline ) ) ;
137- throw new ArgumentNullException ( nameof ( polyline ) , "Polyline argument cannot be null." ) ;
133+ ExceptionGuard . ThrowArgumentNull ( nameof ( polyline ) ) ;
138134 }
139135 }
140136
141137 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
142- private static void ValidateEmptySequence ( ReadOnlyMemory < char > polylineSequence , ILogger logger )
143- {
144- if ( polylineSequence . Length < Defaults . Polyline . Block . Length . Min )
145- {
138+ private static void ValidateSequence ( ReadOnlyMemory < char > polylineSequence , ILogger ? logger ) {
139+ if ( polylineSequence . Length < Defaults . Polyline . Block . Length . Min ) {
146140 logger ? . LogOperationFailedDebug ( nameof ( Decode ) ) ;
147- logger ? . LogPolylineCannotBeShorterThanWarning ( nameof ( polylineSequence ) , polylineSequence . Length , Defaults . Polyline . Block . Length . Min ) ;
141+ logger ? . LogPolylineCannotBeShorterThanWarning ( polylineSequence . Length , Defaults . Polyline . Block . Length . Min ) ;
148142
149- throw new ArgumentException (
150- $ "Polyline must be at least { Defaults . Polyline . Block . Length . Min } characters long, but was { polylineSequence . Length } .",
151- nameof ( polylineSequence ) ) ;
143+ ExceptionGuard . ThrowInvalidPolylineLength ( polylineSequence . Length , Defaults . Polyline . Block . Length . Min ) ;
152144 }
153145 }
154146
155147 /// <summary>
156148 /// Validates the polyline format for allowed characters.
157149 /// </summary>
158150 [ MethodImpl ( MethodImplOptions . AggressiveInlining ) ]
159- protected virtual void ValidateFormat ( ReadOnlyMemory < char > polylineSequence , ILogger logger )
160- {
161- try
162- {
163- PolylineEncoding . Validation . ValidateFormat ( polylineSequence . Span ) ;
164- }
165- catch ( ArgumentException ex )
166- {
167- logger ? . LogWarning ( ex . Message ) ;
151+ protected virtual void ValidateFormat ( ReadOnlyMemory < char > sequence , ILogger ? logger ) {
152+ try {
153+ PolylineEncoding . Validation . ValidateFormat ( sequence . Span ) ;
154+ } catch ( ArgumentException ex ) {
155+ logger ? . LogInvalidPolylineFormatWarning ( ex ) ;
156+
168157 throw ;
169158 }
170159 }
171160
172161 /// <summary>
173162 /// Hook for subclasses to handle invalid polyline cases.
174163 /// </summary>
175- protected virtual void OnInvalidPolyline ( int position , ReadOnlyMemory < char > polylineSequence )
176- {
164+ protected virtual void OnInvalidPolyline ( int position , ReadOnlyMemory < char > polylineSequence ) {
177165 // Subclasses can override for custom error handling/logging.
178166 }
179167
0 commit comments