Merge branch 'Fix-bad-loops-in-Util' into 'ibm-trunk'

Removed incorrect loop counter in Util.

See merge request !67
diff --git a/yoko-core/src/main/java/org/apache/yoko/orb/OCI/IIOP/Util.java b/yoko-core/src/main/java/org/apache/yoko/orb/OCI/IIOP/Util.java
index 4057148..3eb6804 100644
--- a/yoko-core/src/main/java/org/apache/yoko/orb/OCI/IIOP/Util.java
+++ b/yoko-core/src/main/java/org/apache/yoko/orb/OCI/IIOP/Util.java
@@ -19,28 +19,40 @@
 
 import org.apache.yoko.orb.CORBA.InputStream;
 import org.apache.yoko.orb.CORBA.OutputStream;
+import org.apache.yoko.orb.OCI.Buffer;
+import org.apache.yoko.orb.OCI.ProfileInfo;
+import org.apache.yoko.orb.OCI.ProfileInfoHolder;
+import org.apache.yoko.orb.OCI.ProfileInfoSeqHolder;
 import org.omg.CORBA.Any;
+import org.omg.CSIIOP.CompoundSecMech;
 import org.omg.CSIIOP.CompoundSecMechList;
 import org.omg.CSIIOP.CompoundSecMechListHelper;
+import org.omg.CSIIOP.TAG_CSI_SEC_MECH_LIST;
 import org.omg.CSIIOP.TAG_TLS_SEC_TRANS;
 import org.omg.CSIIOP.TLS_SEC_TRANS;
 import org.omg.CSIIOP.TLS_SEC_TRANSHelper;
 import org.omg.CSIIOP.TransportAddress;
-import org.omg.IOP.Codec;
+import org.omg.IIOP.ProfileBody_1_0;
+import org.omg.IIOP.ProfileBody_1_0Helper;
+import org.omg.IOP.*;
 import org.omg.IOP.CodecPackage.FormatMismatch;
 import org.omg.IOP.CodecPackage.TypeMismatch;
 
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
 final public class Util {
-    static public org.omg.IOP.IOR createIOR(String host, int port, String id,
-            org.apache.yoko.orb.OCI.ProfileInfo profileInfo) {
-        org.omg.IOP.IOR ior = new org.omg.IOP.IOR();
+    static public IOR createIOR(String host, int port, String id, ProfileInfo profileInfo) {
+        IOR ior = new IOR();
         ior.type_id = id;
         ior.profiles = new org.omg.IOP.TaggedProfile[1];
         ior.profiles[0] = new org.omg.IOP.TaggedProfile();
-        ior.profiles[0].tag = org.omg.IOP.TAG_INTERNET_IOP.value;
+        ior.profiles[0].tag = TAG_INTERNET_IOP.value;
 
         if (profileInfo.major == 1 && profileInfo.minor == 0) {
-            org.omg.IIOP.ProfileBody_1_0 body = new org.omg.IIOP.ProfileBody_1_0();
+            ProfileBody_1_0 body = new ProfileBody_1_0();
             body.iiop_version = new org.omg.IIOP.Version((byte) 1, (byte) 0);
             body.host = host;
             if (port >= 0x8000)
@@ -48,10 +60,10 @@
             else
                 body.port = (short) port;
             body.object_key = profileInfo.key;
-            org.apache.yoko.orb.OCI.Buffer buf = new org.apache.yoko.orb.OCI.Buffer();
+            Buffer buf = new Buffer();
             OutputStream out = new OutputStream(buf);
             out._OB_writeEndian();
-            org.omg.IIOP.ProfileBody_1_0Helper.write(out, body);
+            ProfileBody_1_0Helper.write(out, body);
             ior.profiles[0].profile_data = new byte[buf.length()];
             System.arraycopy(buf.data(), 0, ior.profiles[0].profile_data, 0,
                     buf.length());
@@ -66,7 +78,7 @@
                 body.port = (short) port;
             body.object_key = profileInfo.key;
             body.components = profileInfo.components;
-            org.apache.yoko.orb.OCI.Buffer buf = new org.apache.yoko.orb.OCI.Buffer();
+            Buffer buf = new Buffer();
             OutputStream out = new OutputStream(buf);
             out._OB_writeEndian();
             org.omg.IIOP.ProfileBody_1_1Helper.write(out, body);
@@ -78,39 +90,37 @@
         return ior;
     }
 
-    static public org.omg.IOP.IOR createIOR(org.omg.IOP.IOR ior, String id,
-            byte[] key) {
+    static public IOR createIOR(IOR ior, String id, byte[] key) {
         //
         // Extract the IIOP profile information from the provided IOR
         //
         int profile;
         for (profile = 0; profile < ior.profiles.length; profile++)
-            if (ior.profiles[profile].tag == org.omg.IOP.TAG_INTERNET_IOP.value)
+            if (ior.profiles[profile].tag == TAG_INTERNET_IOP.value)
                 break;
 
         // TODO: Internal error?
         org.apache.yoko.orb.OB.Assert._OB_assert(profile < ior.profiles.length);
 
-        org.apache.yoko.orb.OCI.Buffer buf = new org.apache.yoko.orb.OCI.Buffer(
+        Buffer buf = new Buffer(
                 ior.profiles[profile].profile_data,
                 ior.profiles[profile].profile_data.length);
         InputStream in = new InputStream(buf, 0, false, null, null);
         in._OB_readEndian();
-        org.omg.IIOP.ProfileBody_1_0 body = org.omg.IIOP.ProfileBody_1_0Helper
+        ProfileBody_1_0 body = ProfileBody_1_0Helper
                 .read(in);
 
-        org.apache.yoko.orb.OCI.ProfileInfo profileInfo = new org.apache.yoko.orb.OCI.ProfileInfo();
+        ProfileInfo profileInfo = new ProfileInfo();
         profileInfo.key = key;
         profileInfo.major = body.iiop_version.major;
         profileInfo.minor = body.iiop_version.minor;
-        profileInfo.components = new org.omg.IOP.TaggedComponent[0];
+        profileInfo.components = new TaggedComponent[0];
         return createIOR(body.host, body.port, id, profileInfo);
     }
 
-    static public boolean extractProfileInfo(org.omg.IOP.IOR ior,
-            org.apache.yoko.orb.OCI.ProfileInfoHolder profileInfo) {
-        org.apache.yoko.orb.OCI.ProfileInfoSeqHolder profileInfoSeq = new org.apache.yoko.orb.OCI.ProfileInfoSeqHolder();
-        profileInfoSeq.value = new org.apache.yoko.orb.OCI.ProfileInfo[0];
+    static public boolean extractProfileInfo(IOR ior, ProfileInfoHolder profileInfo) {
+        ProfileInfoSeqHolder profileInfoSeq = new ProfileInfoSeqHolder();
+        profileInfoSeq.value = new ProfileInfo[0];
         extractAllProfileInfos(ior, profileInfoSeq, false, null, 0, false, null);
         if (profileInfoSeq.value.length > 0) {
             profileInfo.value = profileInfoSeq.value[0];
@@ -120,8 +130,7 @@
         return false;
     }
 
-    static public boolean hostMatch(String host1, String host2,
-            boolean loopbackMatches) {
+    static public boolean hostMatch(String host1, String host2, boolean matchLoopback) {
         //
         // Direct host name comparison
         //
@@ -132,11 +141,9 @@
             // addresses to be really sure if the hosts differ
             //
             try {
-                java.net.InetAddress addr1 = java.net.InetAddress
-                        .getByName(host1);
+                InetAddress addr1 = InetAddress.getByName(host1);
 
-                java.net.InetAddress addr2 = java.net.InetAddress
-                        .getByName(host2);
+                InetAddress addr2 = InetAddress.getByName(host2);
 
                 if (!addr1.equals(addr2)) {
                     //
@@ -144,9 +151,8 @@
                     // the key if the profile body contains the
                     // loopback address?
                     //
-                    if (loopbackMatches) {
-                        java.net.InetAddress loopback = java.net.InetAddress
-                                .getByName("127.0.0.1");
+                    if (matchLoopback) {
+                        InetAddress loopback = InetAddress.getByName("127.0.0.1");
 
                         if (!addr2.equals(loopback))
                             return false;
@@ -164,111 +170,44 @@
         return true;
     }
 
-    static public void extractAllProfileInfos(org.omg.IOP.IOR ior,
-            org.apache.yoko.orb.OCI.ProfileInfoSeqHolder profileInfoSeq,
-            boolean performMatch, String host, int port, boolean loopbackMatches, Codec codec) {
-        short portNo;
-        if (port >= 0x8000) {
-            portNo = (short) (port - 0xffff - 1);
-        }
-        else {
-            portNo = (short) port;
-        }
+    static public void extractAllProfileInfos(IOR ior, ProfileInfoSeqHolder profileInfoSeq,
+            boolean performMatch, String host, int port, boolean matchLoopback, Codec codec) {
+        short portNo = (short) port;
 
-        java.util.Vector vec = new java.util.Vector();
+        List<ProfileInfo> list = new ArrayList<>();
+
         for (int i = 0; i < ior.profiles.length; i++) {
-            if (ior.profiles[i].tag == org.omg.IOP.TAG_INTERNET_IOP.value) {
-                //
-                // Get the IIOP profile body
-                //
-                byte[] data = ior.profiles[i].profile_data;
-                org.apache.yoko.orb.OCI.Buffer buf = new org.apache.yoko.orb.OCI.Buffer(
-                        data, data.length);
-                InputStream in = new InputStream(buf, 0, false, null, null);
-                in._OB_readEndian();
-                org.omg.IIOP.ProfileBody_1_0 body = org.omg.IIOP.ProfileBody_1_0Helper
-                        .read(in);
+            if (ior.profiles[i].tag != TAG_INTERNET_IOP.value) continue;
+            //
+            // Get the IIOP profile body
+            //
+            byte[] data = ior.profiles[i].profile_data;
+            Buffer buf = new Buffer(data, data.length);
+            InputStream in = new InputStream(buf, 0, false, null, null);
+            in._OB_readEndian();
+            ProfileBody_1_0 body = ProfileBody_1_0Helper.read(in);
 
-                //
-                // Read components if the IIOP version is > 1.0
-                //
-                org.omg.IOP.TaggedComponent[] components;
-                if (body.iiop_version.major > 1 || body.iiop_version.minor > 0) {
-                    int len = in.read_ulong();
-                    components = new org.omg.IOP.TaggedComponent[len];
-                    for (int j = 0; j < len; j++) {
-                        components[j] = org.omg.IOP.TaggedComponentHelper.read(in);
-                    }
-                } else {
-                    components = new org.omg.IOP.TaggedComponent[0];
+            //
+            // Read components if the IIOP version is > 1.0
+            //
+            TaggedComponent[] components;
+            if (body.iiop_version.major > 1 || body.iiop_version.minor > 0) {
+                int len = in.read_ulong();
+                components = new TaggedComponent[len];
+                for (int j = 0; j < len; j++) {
+                    components[j] = TaggedComponentHelper.read(in);
                 }
+            } else {
+                components = new TaggedComponent[0];
+            }
 
-                if (performMatch) {
-                    //
-                    // Check primary host/port
-                    //
-                    boolean match = false;
-                    if (portNo == body.port
-                            && hostMatch(host, body.host, loopbackMatches)) {
-                        match = true;
-                    }
-
-                    //
-                    // Check alternate host/port
-                    //
-                    if (!match) {
-                        for (int j = 0; j < components.length && !match; j++) {
-                            if (components[j].tag == org.omg.IOP.TAG_ALTERNATE_IIOP_ADDRESS.value) {
-                                byte[] d = components[j].component_data;
-                                org.apache.yoko.orb.OCI.Buffer b = new org.apache.yoko.orb.OCI.Buffer(
-                                        d, d.length);
-                                InputStream s = new InputStream(b, 0, false,
-                                        null, null);
-                                s._OB_readEndian();
-                                String altHost = s.read_string();
-                                short altPort = s.read_ushort();
-                                if (portNo == altPort
-                                        && hostMatch(host, altHost,
-                                                loopbackMatches)) {
-                                    match = true;
-                                }
-                            } else if (components[j].tag == org.omg.CSIIOP.TAG_CSI_SEC_MECH_LIST.value) {
-                                Any any;
-                                try {
-                                    any = codec.decode_value(components[j].component_data, CompoundSecMechListHelper.type());
-                                    CompoundSecMechList csml = CompoundSecMechListHelper.extract(any);
-
-                                    for (int k = 0; i < csml.mechanism_list.length && !match; i++) {
-                                        org.omg.IOP.TaggedComponent tc = csml.mechanism_list[k].transport_mech;
-                                        if (tc.tag == TAG_TLS_SEC_TRANS.value) {
-                                            Any tstAny = codec.decode_value(tc.component_data, TLS_SEC_TRANSHelper.type());
-                                            TLS_SEC_TRANS tst = TLS_SEC_TRANSHelper.extract(tstAny);
-                                            TransportAddress[] transportAddresses = tst.addresses;
-                                            for (TransportAddress addr: transportAddresses) {
-                                                if (portNo == addr.port && hostMatch(host, addr.host_name, loopbackMatches)) {
-                                                    match = true;
-                                                    break;
-                                                }
-                                            }
-
-                                        }
-                                    }
-
-                                } catch (FormatMismatch e) {
-                                } catch (TypeMismatch e) {
-                                }
-                            }
-                        }
-                    }
-
-                    if (!match)
-                        continue;
-                }
-
-                //
-                // OK, found a match
-                //
-                org.apache.yoko.orb.OCI.ProfileInfo profileInfo = new org.apache.yoko.orb.OCI.ProfileInfo();
+            // add this profile to the list unless
+            // A) the caller requested matching
+            // B) the profile doesn't match the supplied host and port
+            if (!!!performMatch
+                    || hostAndPortMatch(host, portNo, body.host, body.port, matchLoopback)
+                    || taggedComponentsMatch(components, host, portNo, codec, matchLoopback)) {
+                ProfileInfo profileInfo = new ProfileInfo();
                 profileInfo.key = body.object_key;
                 profileInfo.minor = body.iiop_version.minor;
                 profileInfo.major = body.iiop_version.major;
@@ -276,46 +215,84 @@
                 profileInfo.index = i;
                 profileInfo.components = components;
 
-                vec.addElement(profileInfo);
+                list.add(profileInfo);
             }
         }
 
-        if (vec.size() > 0) {
-            int len = profileInfoSeq.value.length;
-            if (len == 0) {
-                profileInfoSeq.value = new org.apache.yoko.orb.OCI.ProfileInfo[vec
-                        .size()];
-                vec.copyInto(profileInfoSeq.value);
-            } else {
-                org.apache.yoko.orb.OCI.ProfileInfo[] arr = new org.apache.yoko.orb.OCI.ProfileInfo[len
-                        + vec.size()];
-                System.arraycopy(profileInfoSeq.value, 0, arr, 0, len);
-                for (int i = 0; i < vec.size(); i++) {
-                    arr[len + i] = (org.apache.yoko.orb.OCI.ProfileInfo) vec.elementAt(i);
-                }
-                profileInfoSeq.value = arr;
-            }
+        if (!!!list.isEmpty()) {
+            List<ProfileInfo> bigList = new ArrayList<>(Arrays.asList(profileInfoSeq.value));
+            bigList.addAll(list);
+            profileInfoSeq.value = bigList.toArray(profileInfoSeq.value);
         }
     }
 
-    static public boolean equivalent(org.omg.IOP.IOR ior1, org.omg.IOP.IOR ior2) {
+    private static boolean hostAndPortMatch(String host, short portNo, String bodyHost, short bodyPort, boolean matchLoopback) {
+        return portNo == bodyPort && hostMatch(host, bodyHost, matchLoopback);
+    }
+
+    private static boolean taggedComponentsMatch(TaggedComponent[] components, String host, short port, Codec codec, boolean matchLoopback) {
+        for (final TaggedComponent component : components) {
+            if (component.tag == TAG_ALTERNATE_IIOP_ADDRESS.value) {
+                byte[] d = component.component_data;
+                Buffer b = new Buffer(d, d.length);
+                InputStream s = new InputStream(b, 0, false, null, null);
+                s._OB_readEndian();
+                String altHost = s.read_string();
+                short altPort = s.read_ushort();
+                if (hostAndPortMatch(host, port, altHost, altPort, matchLoopback)) {
+                    return true;
+                }
+            } else if (component.tag == TAG_CSI_SEC_MECH_LIST.value) {
+                Any any;
+                try {
+                    any = codec.decode_value(component.component_data, CompoundSecMechListHelper.type());
+                    CompoundSecMechList csml = CompoundSecMechListHelper.extract(any);
+
+                    for (CompoundSecMech csm : csml.mechanism_list) {
+                        TaggedComponent tc = csm.transport_mech;
+                        if (tc.tag == TAG_TLS_SEC_TRANS.value) {
+                            Any tstAny = codec.decode_value(tc.component_data, TLS_SEC_TRANSHelper.type());
+                            TLS_SEC_TRANS tst = TLS_SEC_TRANSHelper.extract(tstAny);
+                            TransportAddress[] transportAddresses = tst.addresses;
+                            if (transportAddressesMatch(transportAddresses, host, port, matchLoopback))
+                                return true;
+                        }
+                    }
+                } catch (FormatMismatch | TypeMismatch ignored) {
+                }
+            }
+        }
+        return false;
+    }
+
+    private static boolean transportAddressesMatch(TransportAddress[] addrs, String host, short port, boolean loopbackMatches) {
+        for (TransportAddress addr: addrs) {
+            final short addrPort = addr.port;
+            if (hostAndPortMatch(host, port, addr.host_name, addrPort, loopbackMatches)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    static public boolean equivalent(IOR ior1, IOR ior2) {
         int p1, p2, b1, b2;
         int cnt1 = 0, cnt2 = 0;
-        org.omg.IIOP.ProfileBody_1_0[] bodies1;
-        org.omg.IIOP.ProfileBody_1_0[] bodies2;
+        ProfileBody_1_0[] bodies1;
+        ProfileBody_1_0[] bodies2;
 
         //
         // Calculate number of IIOP profiles in ior1
         //
         for (p1 = 0; p1 < ior1.profiles.length; p1++)
-            if (ior1.profiles[p1].tag == org.omg.IOP.TAG_INTERNET_IOP.value)
+            if (ior1.profiles[p1].tag == TAG_INTERNET_IOP.value)
                 cnt1++;
 
         //
         // Calculate number of IIOP profiles in ior2
         //
         for (p2 = 0; p2 < ior2.profiles.length; p2++)
-            if (ior2.profiles[p2].tag == org.omg.IOP.TAG_INTERNET_IOP.value)
+            if (ior2.profiles[p2].tag == TAG_INTERNET_IOP.value)
                 cnt2++;
 
         //
@@ -328,15 +305,15 @@
         //
         // Create an array with all IIOP profile bodies of ior1
         //
-        bodies1 = new org.omg.IIOP.ProfileBody_1_0[cnt1];
+        bodies1 = new ProfileBody_1_0[cnt1];
         for (p1 = 0, b1 = 0; p1 < ior1.profiles.length; p1++)
-            if (ior1.profiles[p1].tag == org.omg.IOP.TAG_INTERNET_IOP.value) {
+            if (ior1.profiles[p1].tag == TAG_INTERNET_IOP.value) {
                 byte[] data = ior1.profiles[p1].profile_data;
-                org.apache.yoko.orb.OCI.Buffer buf = new org.apache.yoko.orb.OCI.Buffer(
+                Buffer buf = new Buffer(
                         data, data.length);
                 InputStream in = new InputStream(buf, 0, false, null, null);
                 in._OB_readEndian();
-                bodies1[b1++] = org.omg.IIOP.ProfileBody_1_0Helper.read(in);
+                bodies1[b1++] = ProfileBody_1_0Helper.read(in);
             }
 
         if (b1 != cnt1)
@@ -345,15 +322,15 @@
         //
         // Create an array with all IIOP profile bodies of ior2
         //
-        bodies2 = new org.omg.IIOP.ProfileBody_1_0[cnt2];
+        bodies2 = new ProfileBody_1_0[cnt2];
         for (p2 = 0, b2 = 0; p2 < ior2.profiles.length; p2++)
-            if (ior2.profiles[p2].tag == org.omg.IOP.TAG_INTERNET_IOP.value) {
+            if (ior2.profiles[p2].tag == TAG_INTERNET_IOP.value) {
                 byte[] data = ior2.profiles[p2].profile_data;
-                org.apache.yoko.orb.OCI.Buffer buf = new org.apache.yoko.orb.OCI.Buffer(
+                Buffer buf = new Buffer(
                         data, data.length);
                 InputStream in = new InputStream(buf, 0, false, null, null);
                 in._OB_readEndian();
-                bodies2[b2++] = org.omg.IIOP.ProfileBody_1_0Helper.read(in);
+                bodies2[b2++] = ProfileBody_1_0Helper.read(in);
             }
 
         if (b2 != cnt2)
@@ -395,8 +372,8 @@
         return true;
     }
 
-    static boolean compareBodies(org.omg.IIOP.ProfileBody_1_0 body1,
-            org.omg.IIOP.ProfileBody_1_0 body2) {
+    static boolean compareBodies(ProfileBody_1_0 body1,
+            ProfileBody_1_0 body2) {
         //
         // Compare versions
         //
@@ -430,10 +407,10 @@
             // addresses to be really sure if the hosts differ
             //
             try {
-                java.net.InetAddress addr1 = java.net.InetAddress
+                InetAddress addr1 = InetAddress
                         .getByName(body1.host);
 
-                java.net.InetAddress addr2 = java.net.InetAddress
+                InetAddress addr2 = InetAddress
                         .getByName(body2.host);
 
                 if (!addr1.equals(addr2))
@@ -455,33 +432,30 @@
     //
     // Calculate a hash for an IOR containing IIOP profiles
     //
-    static public int hash(org.omg.IOP.IOR ior, int maximum) {
+    static public int hash(IOR ior, int maximum) {
         int hash = 0;
 
-        for (int i = 0; i < ior.profiles.length; i++) {
-            if (ior.profiles[i].tag == org.omg.IOP.TAG_INTERNET_IOP.value) {
-                //
-                // Get the first IIOP profile body
-                //
-                byte[] data = ior.profiles[i].profile_data;
-                org.apache.yoko.orb.OCI.Buffer buf = new org.apache.yoko.orb.OCI.Buffer(
-                        data, data.length);
-                InputStream in = new InputStream(buf, 0, false, null, null);
-                in._OB_readEndian();
-                org.omg.IIOP.ProfileBody_1_0 body = org.omg.IIOP.ProfileBody_1_0Helper
-                        .read(in);
+        for (TaggedProfile profile : ior.profiles) {
+            if (profile.tag == TAG_INTERNET_IOP.value) continue;
+            //
+            // Get the first IIOP profile body
+            //
+            byte[] data = profile.profile_data;
+            Buffer buf = new Buffer(data, data.length);
+            InputStream in = new InputStream(buf, 0, false, null, null);
+            in._OB_readEndian();
+            ProfileBody_1_0 body = ProfileBody_1_0Helper.read(in);
 
-                //
-                // Add port to hash
-                //
-                hash ^= body.port;
+            //
+            // Add port to hash
+            //
+            hash ^= body.port;
 
-                //
-                // Add object key to hash
-                //
-                for (int j = 0; j + 1 < body.object_key.length; j += 2)
-                    hash ^= body.object_key[j + 1] * 256 + body.object_key[j];
-            }
+            //
+            // Add object key to hash
+            //
+            for (int j = 0; j + 1 < body.object_key.length; j += 2)
+                hash ^= body.object_key[j + 1] * 256 + body.object_key[j];
         }
 
         return hash % (maximum + 1);