@@ -49,7 +49,7 @@ private enum State
4949 private string _prefix ;
5050 private string _media ;
5151 private readonly IDictionary < string , string > _params ;
52- private string [ ] _tags ;
52+ private readonly string [ ] _tags ;
5353
5454 /// <summary>
5555 /// Construct with the components provided to avoid parsing.
@@ -62,7 +62,6 @@ public ChannelUri(string prefix, string media, IDictionary<string, string> @para
6262 _prefix = prefix ;
6363 _media = media ;
6464 _params = @params ;
65-
6665 _tags = SplitTags ( _params . GetOrDefault ( Aeron . Context . TAGS_PARAM_NAME ) ) ;
6766 }
6867
@@ -185,27 +184,31 @@ public string Remove(string key)
185184 /// </summary>
186185 /// <param name="key"> to be lookup. </param>
187186 /// <returns> true if the key has a value otherwise false. </returns>
187+ /// <see cref="Aeron.Context.TAGS_PARAM_NAME"/>
188+ /// <see cref="Aeron.Context.TAG_PREFIX"/>
188189 public bool ContainsKey ( string key )
189190 {
190191 return _params . ContainsKey ( key ) ;
191192 }
192193
193194 /// <summary>
194- /// Get the channel tag.
195+ /// Get the channel tag, if it exists, that refers to an another channel .
195196 /// </summary>
196- /// <returns> channel tag. </returns>
197+ /// <returns> channel tag if it exists or null if not in this URI . </returns>
197198 public string ChannelTag ( )
198199 {
199- return ( _tags . Length > CHANNEL_TAG_INDEX ) ? _tags [ CHANNEL_TAG_INDEX ] : null ;
200+ return ( null != _tags && _tags . Length > CHANNEL_TAG_INDEX ) ? _tags [ CHANNEL_TAG_INDEX ] : null ;
200201 }
201202
202203 /// <summary>
203- /// Get the entity tag.
204+ /// Get the entity tag, if it exists, that refers to an entity such as subscription or publication .
204205 /// </summary>
205- /// <returns> entity tag. </returns>
206+ /// <returns> entity tag if it exists or null if not in this URI. </returns>
207+ /// <see cref="Aeron.Context.TAGS_PARAM_NAME"/>
208+ /// <see cref="Aeron.Context.TAG_PREFIX"/>
206209 public string EntityTag ( )
207210 {
208- return ( _tags . Length > ENTITY_TAG_INDEX ) ? _tags [ ENTITY_TAG_INDEX ] : null ;
211+ return ( null != _tags && _tags . Length > ENTITY_TAG_INDEX ) ? _tags [ ENTITY_TAG_INDEX ] : null ;
209212 }
210213
211214 /// <summary>
@@ -275,7 +278,7 @@ public static ChannelUri Parse(string cs)
275278 {
276279 int position = 0 ;
277280 string prefix ;
278- if ( StartsWith ( cs , Aeron . Context . SPY_PREFIX ) )
281+ if ( StartsWith ( cs , 0 , Aeron . Context . SPY_PREFIX ) )
279282 {
280283 prefix = SPY_QUALIFIER ;
281284 position = Aeron . Context . SPY_PREFIX . Length ;
@@ -326,33 +329,28 @@ public static ChannelUri Parse(string cs)
326329 break ;
327330
328331 case State . PARAMS_KEY :
329- switch ( c )
332+ if ( c == '=' )
330333 {
331- case '=' :
332- key = builder . ToString ( ) ;
333- builder . Length = 0 ;
334- state = State . PARAMS_VALUE ;
335- break ;
336-
337- default :
338- builder . Append ( c ) ;
339- break ;
334+ key = builder . ToString ( ) ;
335+ builder . Length = 0 ;
336+ state = State . PARAMS_VALUE ;
337+ }
338+ else
339+ {
340+ builder . Append ( c ) ;
340341 }
341-
342342 break ;
343343
344344 case State . PARAMS_VALUE :
345- switch ( c )
345+ if ( c == '|' )
346346 {
347- case '|' :
348- @params [ key ] = builder . ToString ( ) ;
349- builder . Length = 0 ;
350- state = State . PARAMS_KEY ;
351- break ;
352-
353- default :
354- builder . Append ( c ) ;
355- break ;
347+ @params [ key ] = builder . ToString ( ) ;
348+ builder . Length = 0 ;
349+ state = State . PARAMS_KEY ;
350+ }
351+ else
352+ {
353+ builder . Append ( c ) ;
356354 }
357355
358356 break ;
@@ -394,20 +392,24 @@ public static string AddSessionId(string channel, int sessionId)
394392 }
395393
396394 /// <summary>
397- /// Is the param tagged? (starts with the "tag:" prefix)
395+ /// Is the param value tagged? (starts with the "tag:" prefix)
398396 /// </summary>
399397 /// <param name="paramValue"> to check if tagged. </param>
400398 /// <returns> true if tagged or false if not. </returns>
399+ /// <see cref="Aeron.Context.TAGS_PARAM_NAME"/>
400+ /// <see cref="Aeron.Context.TAG_PREFIX"/>
401401 public static bool IsTagged ( string paramValue )
402402 {
403- return StartsWith ( paramValue , "tag:" ) ;
403+ return StartsWith ( paramValue , 0 , Aeron . Context . TAG_PREFIX ) ;
404404 }
405405
406406 /// <summary>
407- /// Get the value of the tag from a given parameter.
407+ /// Get the value of the tag from a given parameter value .
408408 /// </summary>
409409 /// <param name="paramValue"> to extract the tag value from. </param>
410410 /// <returns> the value of the tag or <seealso cref="INVALID_TAG"/> if not tagged. </returns>
411+ /// <see cref="Aeron.Context.TAGS_PARAM_NAME"/>
412+ /// <see cref="Aeron.Context.TAG_PREFIX"/>
411413 public static long GetTag ( string paramValue )
412414 {
413415 return IsTagged ( paramValue ) ? long . Parse ( paramValue . Substring ( 4 , paramValue . Length - 4 ) ) : INVALID_TAG ;
@@ -430,49 +432,56 @@ private static bool StartsWith(string input, int position, string prefix)
430432
431433 return true ;
432434 }
433-
434- private static bool StartsWith ( string input , string prefix )
435- {
436- return StartsWith ( input , 0 , prefix ) ;
437- }
438435
439- private static string [ ] SplitTags ( string tags )
436+ private static string [ ] SplitTags ( string tagsValue )
440437 {
441- string [ ] stringArray = new string [ 0 ] ;
438+ string [ ] tags = ArrayUtil . EMPTY_STRING_ARRAY ;
442439
443- if ( null != tags )
440+ if ( null != tagsValue )
444441 {
445- int currentStartIndex = 0 ;
446- int tagIndex = 0 ;
447- stringArray = new string [ 2 ] ;
448- int length = tags . Length ;
449-
450- for ( int i = 0 ; i < length ; i ++ )
442+ int tagCount = CountTags ( tagsValue ) ;
443+ if ( tagCount == 1 )
451444 {
452- if ( tags [ i ] == ',' )
453- {
454- string tag = null ;
445+ tags = new [ ] { tagsValue } ;
446+ }
447+ else
448+ {
449+ int tagStartPosition = 0 ;
450+ int tagIndex = 0 ;
451+ tags = new string [ tagCount ] ;
455452
456- if ( i - currentStartIndex > 0 )
453+ for ( int i = 0 , length = tagsValue . Length ; i < length ; i ++ )
454+ {
455+ if ( tagsValue [ i ] == ',' )
457456 {
458- tag = tags . Substring ( currentStartIndex , i - currentStartIndex ) ;
459- currentStartIndex = i + 1 ;
460- }
457+ tags [ tagIndex ++ ] = tagsValue . Substring ( tagStartPosition , i - tagStartPosition ) ;
458+ tagStartPosition = i + 1 ;
461459
462- stringArray = ArrayUtil . EnsureCapacity ( stringArray , tagIndex + 1 ) ;
463- stringArray [ tagIndex ] = tag ;
464- tagIndex ++ ;
460+ if ( tagIndex >= ( tagCount - 1 ) )
461+ {
462+ tags [ tagIndex ] = tagsValue . Substring ( tagStartPosition , length - tagStartPosition ) ;
463+ }
464+ }
465465 }
466466 }
467+ }
467468
468- if ( ( length - currentStartIndex ) > 0 )
469+ return tags ;
470+ }
471+
472+ private static int CountTags ( string tags )
473+ {
474+ int count = 1 ;
475+
476+ for ( int i = 0 , length = tags . Length ; i < length ; i ++ )
477+ {
478+ if ( tags [ i ] == ',' )
469479 {
470- stringArray = ArrayUtil . EnsureCapacity ( stringArray , tagIndex + 1 ) ;
471- stringArray [ tagIndex ] = tags . Substring ( currentStartIndex , length - currentStartIndex ) ;
480+ ++ count ;
472481 }
473482 }
474483
475- return stringArray ;
484+ return count ;
476485 }
477486 }
478487}
0 commit comments