• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

lduchosal / ipnetwork / 960

15 May 2026 07:18AM UTC coverage: 0.0% (-94.1%) from 94.053%
960

Pull #411

appveyor

web-flow
Merge ef6b054ce into 4cec191ae
Pull Request #411: Bump MSTest.TestFramework from 4.2.2 to 4.2.3

0 of 2438 relevant lines covered (0.0%)

0.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/System.Net.IPNetwork/IPNetwork2SupernetArray.cs
1
// <copyright file="IPNetwork2SupernetArray.cs" company="IPNetwork">
2
// Copyright (c) IPNetwork. All rights reserved.
3
// </copyright>
4

5
namespace System.Net;
6

7
using System.Collections.Generic;
8
using System.Diagnostics.CodeAnalysis;
9

10
/// <summary>
11
/// SupernetArray.
12
/// </summary>
13
public sealed partial class IPNetwork2
14
{
15
    /// <summary>
16
    /// Supernet a list of subnet
17
    /// 192.168.0.0/24 + 192.168.1.0/24 = 192.168.0.0/23
18
    /// 192.168.0.0/24 + 192.168.1.0/24 + 192.168.2.0/24 + 192.168.3.0/24 = 192.168.0.0/22.
19
    /// </summary>
20
    /// <param name="ipnetworks">A list of IPNetwork to merge into common supernets.</param>
21
    /// <returns>The result of IPNetwork if merges succeed, the first ipnetwork otherwise.</returns>
22
    public static IPNetwork2[] Supernet(IPNetwork2[] ipnetworks)
23
    {
×
24
        if (!InternalSupernet(false, ipnetworks, out IPNetwork2[]? supernet))
×
25
        {
×
26
            throw new ArgumentException("Failed to supernet IP networks.", nameof(ipnetworks));
×
27
        }
28

29
        return supernet;
×
30
    }
×
31

32
    /// <summary>
33
    /// Supernet a list of subnet
34
    /// 192.168.0.0/24 + 192.168.1.0/24 = 192.168.0.0/23
35
    /// 192.168.0.0/24 + 192.168.1.0/24 + 192.168.2.0/24 + 192.168.3.0/24 = 192.168.0.0/22.
36
    /// </summary>
37
    /// <param name="ipnetworks">A list of IPNetwork to merge into common supernets.</param>
38
    /// <param name="supernet">The result of IPNetwork merges.</param>
39
    /// <returns>true if ipnetworks was supernetted successfully; otherwise, false.</returns>
40
    public static bool TrySupernet(IPNetwork2[] ipnetworks, [NotNullWhen(true)] out IPNetwork2[]? supernet)
41
    {
×
42
        bool supernetted = InternalSupernet(true, ipnetworks, out supernet);
×
43
        return supernetted;
×
44
    }
×
45

46
    /// <summary>
47
    /// Attempts to merge an array of adjacent IP networks with equal CIDR values into the smallest possible set of supernets.
48
    /// </summary>
49
    /// <param name="trySupernet">If true, suppresses exceptions on failure; otherwise, throws.</param>
50
    /// <param name="ipnetworks">The array of IP networks to attempt to merge.</param>
51
    /// <param name="supernet">The resulting array of merged supernets if successful; otherwise, the original input.</param>
52
    /// <returns><c>true</c> if supernetting was successful; otherwise, <c>false</c>.</returns>
53
    internal static bool InternalSupernet(bool trySupernet, IPNetwork2[] ipnetworks, [NotNullWhen(true)] out IPNetwork2[]? supernet)
54
    {
×
55
        // ReSharper disable once ConditionIsAlwaysTrueOrFalseAccordingToNullableAPIContract
56
        if (ipnetworks == null)
×
57
        {
×
58
            if (!trySupernet)
×
59
            {
×
60
                throw new ArgumentNullException(nameof(ipnetworks));
×
61
            }
62

63
            supernet = null;
×
64
            return false;
×
65
        }
66

67
        if (ipnetworks.Length <= 0)
×
68
        {
×
69
            supernet = [];
×
70
            return true;
×
71
        }
72

73
        var supernetted = new List<IPNetwork2>();
×
74
        List<IPNetwork2> ipns = Array2List(ipnetworks);
×
75
        Stack<IPNetwork2> current = List2Stack(ipns);
×
76
        int previousCount = 0;
×
77
        int currentCount = current.Count;
×
78

79
        while (previousCount != currentCount)
×
80
        {
×
81
            supernetted.Clear();
×
82
            while (current.Count > 1)
×
83
            {
×
84
                IPNetwork2 ipn1 = current.Pop();
×
85
                IPNetwork2 ipn2 = current.Peek();
×
86

87
                if (ipn1.TrySupernet(ipn2, out IPNetwork2? outNetwork))
×
88
                {
×
89
                    current.Pop();
×
90
                    current.Push(outNetwork);
×
91
                }
×
92
                else
93
                {
×
94
                    supernetted.Add(ipn1);
×
95
                }
×
96
            }
×
97

98
            if (current.Count == 1)
×
99
            {
×
100
                supernetted.Add(current.Pop());
×
101
            }
×
102

103
            previousCount = currentCount;
×
104
            currentCount = supernetted.Count;
×
105
            current = List2Stack(supernetted);
×
106
        }
×
107

108
        supernet = supernetted.ToArray();
×
109
        return true;
×
110
    }
×
111

112
    private static Stack<IPNetwork2> List2Stack(List<IPNetwork2> list)
113
    {
×
114
        var stack = new Stack<IPNetwork2>();
×
115
        list.ForEach(delegate(IPNetwork2 ipn)
×
116
        {
×
117
            stack.Push(ipn);
×
118
        });
×
119
        return stack;
×
120
    }
×
121

122
    private static List<IPNetwork2> Array2List(IPNetwork2[] array)
123
    {
×
124
        var ipns = new List<IPNetwork2>();
×
125
        ipns.AddRange(array);
×
126
        RemoveNull(ipns);
×
127
        ipns.Sort(delegate(IPNetwork2 ipn1, IPNetwork2 ipn2)
×
128
        {
×
129
            int networkCompare = ipn1.InternalNetwork.CompareTo(ipn2.InternalNetwork);
×
130
            if (networkCompare == 0)
×
131
            {
×
132
                int cidrCompare = ipn1.cidr.CompareTo(ipn2.cidr);
×
133
                return cidrCompare;
×
134
            }
×
135

×
136
            return networkCompare;
×
137
        });
×
138
        ipns.Reverse();
×
139

140
        return ipns;
×
141
    }
×
142

143
    private static void RemoveNull(List<IPNetwork2> ipns)
144
    {
×
145
        ipns.RemoveAll(delegate(IPNetwork2 ipn)
×
146
        {
×
147
            if (ipn == null)
×
148
            {
×
149
                return true;
×
150
            }
×
151

×
152
            return false;
×
153
        });
×
154
    }
×
155
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc