11using Microsoft . CodeAnalysis ;
22using Microsoft . CodeAnalysis . Text ;
33using System . Net ;
4+ using System . Net . Sockets ;
45using System . Text ;
56
67namespace OpenShock . CodeGen ;
@@ -11,6 +12,39 @@ internal class CloudflareProxiesGenerator : IIncrementalGenerator
1112 private const string IpV4Name = "cloudflare-ips-v4.txt" ;
1213 private const string IpV6Name = "cloudflare-ips-v6.txt" ;
1314
15+ private static bool TryParseAndWriteIpNetworkArrayEntry ( StringBuilder builder , string ipNetwork , AddressFamily addressFamily )
16+ {
17+ if ( string . IsNullOrEmpty ( ipNetwork ) ) return false ;
18+
19+ int slash = ipNetwork . IndexOf ( '/' ) ;
20+ if ( slash < 1 || slash == ipNetwork . Length - 1 ) return false ;
21+
22+ // split into address/CIDR without extra array allocations
23+ string addressPart = ipNetwork . Substring ( 0 , slash ) ;
24+ string cidrPart = ipNetwork . Substring ( slash + 1 ) ;
25+
26+ if ( ! ushort . TryParse ( cidrPart , out var cidr ) || ! IPAddress . TryParse ( addressPart , out var ipAddress ) ) return false ;
27+
28+ if ( ipAddress . AddressFamily != addressFamily ) return false ;
29+
30+ var bytes = ipAddress . GetAddressBytes ( ) ;
31+
32+ builder . Append ( "new IPNetwork(new IPAddress(new byte[]{" ) ;
33+
34+ for ( int i = 0 , last = bytes . Length - 1 ; i <= last ; i ++ )
35+ {
36+ builder . Append ( bytes [ i ] ) ;
37+ if ( i < last )
38+ builder . Append ( ',' ) ;
39+ }
40+
41+ builder . Append ( "})," ) ;
42+ builder . Append ( cidr ) ;
43+ builder . AppendLine ( ")," ) ;
44+
45+ return true ;
46+ }
47+
1448 public void Initialize ( IncrementalGeneratorInitializationContext context )
1549 {
1650 var additionalFiles = context . AdditionalTextsProvider
@@ -31,46 +65,34 @@ public void Initialize(IncrementalGeneratorInitializationContext context)
3165
3266 foreach ( var line in ipv4Lines )
3367 {
34- if ( ! IPAddress . TryParse ( line , out _ ) )
68+ if ( ! TryParseAndWriteIpNetworkArrayEntry ( sourceBuilder , line , AddressFamily . InterNetwork ) )
3569 {
3670 ctx . ReportDiagnostic ( Diagnostic . Create (
3771 new DiagnosticDescriptor (
3872 "CF001" ,
39- "Invalid IP Address" ,
40- $ "The entry '{ line } ' in { IpV4Name } is not a valid IP Address.",
73+ "Invalid IPv4 Address" ,
74+ $ "The entry '{ line } ' in { IpV4Name } is not a valid IPv4 Address.",
4175 "CloudflareProxiesGenerator" ,
4276 DiagnosticSeverity . Error ,
4377 true ) ,
4478 Location . None ) ) ;
45-
46- continue ; // Skip invalid entry
4779 }
48-
49- sourceBuilder . Append ( " IPNetwork.Parse(\" " ) ;
50- sourceBuilder . Append ( line ) ;
51- sourceBuilder . AppendLine ( "\" )," ) ;
5280 }
5381 sourceBuilder . AppendLine ( "\n // IPv6" ) ;
5482 foreach ( var line in ipv6Lines )
5583 {
56- if ( ! IPAddress . TryParse ( line , out _ ) )
84+ if ( ! TryParseAndWriteIpNetworkArrayEntry ( sourceBuilder , line , AddressFamily . InterNetworkV6 ) )
5785 {
5886 ctx . ReportDiagnostic ( Diagnostic . Create (
5987 new DiagnosticDescriptor (
60- "CF001 " ,
61- "Invalid IP Address" ,
62- $ "The entry '{ line } ' in { IpV6Name } is not a valid IP Address.",
88+ "CF002 " ,
89+ "Invalid IPv6 Address" ,
90+ $ "The entry '{ line } ' in { IpV6Name } is not a valid IPv6 Address.",
6391 "CloudflareProxiesGenerator" ,
6492 DiagnosticSeverity . Error ,
6593 true ) ,
6694 Location . None ) ) ;
67-
68- continue ; // Skip invalid entry
6995 }
70-
71- sourceBuilder . Append ( " IPNetwork.Parse(\" " ) ;
72- sourceBuilder . Append ( line ) ;
73- sourceBuilder . AppendLine ( "\" )," ) ;
7496 }
7597
7698 sourceBuilder . AppendLine ( " ];\n }" ) ;
0 commit comments