@@ -501,6 +501,165 @@ public static decimal ParseDecimal(this StringSegment value, bool allowThousands
501501
502502 return result ;
503503 }
504+ private static readonly byte [ ] lo16 = {
505+ 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 ,
506+ 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 ,
507+ 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 ,
508+ 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 ,
509+ 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 0 , 1 ,
510+ 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 255 , 255 ,
511+ 255 , 255 , 255 , 255 , 255 , 10 , 11 , 12 , 13 , 14 ,
512+ 15 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 ,
513+ 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 ,
514+ 255 , 255 , 255 , 255 , 255 , 255 , 255 , 10 , 11 , 12 ,
515+ 13 , 14 , 15
516+ } ;
517+
518+ private static readonly byte [ ] hi16 = {
519+ 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 ,
520+ 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 ,
521+ 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 ,
522+ 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 ,
523+ 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 0 , 16 ,
524+ 32 , 48 , 64 , 80 , 96 , 112 , 128 , 144 , 255 , 255 ,
525+ 255 , 255 , 255 , 255 , 255 , 160 , 176 , 192 , 208 , 224 ,
526+ 240 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 ,
527+ 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 , 255 ,
528+ 255 , 255 , 255 , 255 , 255 , 255 , 255 , 160 , 176 , 192 ,
529+ 208 , 224 , 240
530+ } ;
531+
532+ public static Guid ParseGuid ( this StringSegment value )
533+ {
534+ //Guid can be in one of 3 forms:
535+ //1. General `{dddddddd-dddd-dddd-dddd-dddddddddddd}` or `(dddddddd-dddd-dddd-dddd-dddddddddddd)` 8-4-4-4-12 chars
536+ //2. Hex `{0xdddddddd,0xdddd,0xdddd,{0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd,0xdd}}` 8-4-4-8x2 chars
537+ //3. No style `dddddddddddddddddddddddddddddddd` 32 chars
538+
539+ int i = value . Offset ;
540+ int end = value . Offset + value . Length ;
541+ while ( Char . IsWhiteSpace ( value . Buffer [ i ] ) && i < end ) i ++ ;
542+
543+ if ( i == end )
544+ throw new FormatException ( BadFormat ) ;
545+
546+ Guid result ;
547+
548+ int guidLen ;
549+ result = ParseGeneralStyleGuid ( new StringSegment ( value . Buffer , i , end - i ) , out guidLen ) ;
550+ i += guidLen ;
551+
552+ while ( i < end && Char . IsWhiteSpace ( value . Buffer [ i ] ) ) i ++ ;
553+
554+ if ( i < end )
555+ throw new FormatException ( BadFormat ) ;
556+
557+ return result ;
558+ }
559+
560+ private static Guid ParseGeneralStyleGuid ( StringSegment value , out int len )
561+ {
562+ var buf = value . Buffer ;
563+ var n = value . Offset ;
564+
565+ int dash = 0 ;
566+ len = 32 ;
567+ bool hasParentesis = false ;
568+
569+ if ( value . Length < len )
570+ throw new FormatException ( BadFormat ) ;
571+
572+ var cs = value . GetChar ( 0 ) ;
573+ if ( cs == '{' || cs == '(' )
574+ {
575+ n ++ ;
576+ len += 2 ;
577+ hasParentesis = true ;
578+ }
504579
580+ if ( buf [ 8 + n ] == '-' )
581+ {
582+ if ( buf [ 13 + n ] != '-'
583+ || buf [ 18 + n ] != '-'
584+ || buf [ 23 + n ] != '-' )
585+ throw new FormatException ( BadFormat ) ;
586+ len += 4 ;
587+ dash = 1 ;
588+ }
589+
590+ if ( value . Length < len )
591+ throw new FormatException ( BadFormat ) ;
592+
593+ if ( hasParentesis )
594+ {
595+ var ce = buf [ value . Offset + len - 1 ] ;
596+
597+ if ( ( cs != '{' || ce != '}' ) && ( cs != '(' || ce != ')' ) )
598+ throw new FormatException ( BadFormat ) ;
599+ }
600+
601+ int a ;
602+ short b , c ;
603+ byte d , e , f , g , h , i , j , k ;
604+
605+ byte a1 = ParseHexByte ( buf [ n ] , buf [ n + 1 ] ) ;
606+ n += 2 ;
607+ byte a2 = ParseHexByte ( buf [ n ] , buf [ n + 1 ] ) ;
608+ n += 2 ;
609+ byte a3 = ParseHexByte ( buf [ n ] , buf [ n + 1 ] ) ;
610+ n += 2 ;
611+ byte a4 = ParseHexByte ( buf [ n ] , buf [ n + 1 ] ) ;
612+ a = ( a1 << 24 ) + ( a2 << 16 ) + ( a3 << 8 ) + a4 ;
613+ n += 2 + dash ;
614+
615+ byte b1 = ParseHexByte ( buf [ n ] , buf [ n + 1 ] ) ;
616+ n += 2 ;
617+ byte b2 = ParseHexByte ( buf [ n ] , buf [ n + 1 ] ) ;
618+ b = ( short ) ( ( b1 << 8 ) + b2 ) ;
619+ n += 2 + dash ;
620+
621+ byte c1 = ParseHexByte ( buf [ n ] , buf [ n + 1 ] ) ;
622+ n += 2 ;
623+ byte c2 = ParseHexByte ( buf [ n ] , buf [ n + 1 ] ) ;
624+ c = ( short ) ( ( c1 << 8 ) + c2 ) ;
625+ n += 2 + dash ;
626+
627+ d = ParseHexByte ( buf [ n ] , buf [ n + 1 ] ) ;
628+ n += 2 ;
629+ e = ParseHexByte ( buf [ n ] , buf [ n + 1 ] ) ;
630+ n += 2 + dash ;
631+
632+ f = ParseHexByte ( buf [ n ] , buf [ n + 1 ] ) ;
633+ n += 2 ;
634+ g = ParseHexByte ( buf [ n ] , buf [ n + 1 ] ) ;
635+ n += 2 ;
636+ h = ParseHexByte ( buf [ n ] , buf [ n + 1 ] ) ;
637+ n += 2 ;
638+ i = ParseHexByte ( buf [ n ] , buf [ n + 1 ] ) ;
639+ n += 2 ;
640+ j = ParseHexByte ( buf [ n ] , buf [ n + 1 ] ) ;
641+ n += 2 ;
642+ k = ParseHexByte ( buf [ n ] , buf [ n + 1 ] ) ;
643+
644+ return new Guid ( a , b , c , d , e , f , g , h , i , j , k ) ;
645+ }
646+
647+ private static byte ParseHexByte ( char c1 , char c2 )
648+ {
649+ try
650+ {
651+ byte lo = lo16 [ c2 ] ;
652+ byte hi = hi16 [ c1 ] ;
653+
654+ if ( lo == 255 || hi == 255 )
655+ throw new FormatException ( BadFormat ) ;
656+
657+ return ( byte ) ( hi + lo ) ;
658+ }
659+ catch ( IndexOutOfRangeException )
660+ {
661+ throw new FormatException ( BadFormat ) ;
662+ }
663+ }
505664 }
506665}
0 commit comments