package com.limegroup.gnutella.altlocs; import java.io.IOException; import java.util.StringTokenizer; import org.limewire.collection.BitNumbers; import org.limewire.collection.Function; import com.limegroup.gnutella.URN; import com.limegroup.gnutella.http.HTTPUtils; /** * Provides utility methods relating to {@link AlternateLocation} objects. */ public class AltLocUtils { private AltLocUtils() {} /** * Parses an http string of alternate locations, passing each parsed * location to the given function. * If either sha1 or locations are null, nothing is done. * @param sha1 The expected sha1 of each location. If mismatched, an AssertionError is thrown. * @param locations The comma-separated string of alternate locations. * @param allowTLS Whether or not a tls=# index is allowed. * @param function The closure-like function that each location is passed to. */ public static void parseAlternateLocations(URN sha1, String locations, boolean allowTLS, AlternateLocationFactory alternateLocationFactory, Function<AlternateLocation, Void> function) { parseAlternateLocations(sha1, locations, allowTLS, alternateLocationFactory, function, false); } public static void parseAlternateLocations(URN sha1, String locations, boolean allowTLS, AlternateLocationFactory alternateLocationFactory, Function<AlternateLocation, Void> function, boolean allowMe) { if(locations == null) return; if(sha1 == null) return; BitNumbers tlsIdx = null; StringTokenizer st = new StringTokenizer(locations, ","); int idx = 0; while(st.hasMoreTokens()) { String token = st.nextToken().trim(); if(allowTLS && tlsIdx == null && token.startsWith(DirectAltLoc.TLS_IDX)) { tlsIdx = BitNumbers.EMPTY_BN; try { String value = HTTPUtils.parseValue(token); if(value != null) { try { tlsIdx = new BitNumbers(value); } catch(IllegalArgumentException ignored) {} } } catch(IOException invalid) {} continue; } // if we didn't set a BitNumbers above, stop us from ever doing it again. if(tlsIdx == null) { tlsIdx = BitNumbers.EMPTY_BN; } try { AlternateLocation al = alternateLocationFactory.create(token, sha1, tlsIdx.isSet(idx)); idx++; assert al.getSHA1Urn().equals(sha1) : "sha1 mismatch!"; if (al.isMe() && !allowMe) continue; function.apply(al); } catch(IOException e) { tlsIdx = BitNumbers.EMPTY_BN; // prevent us from reading future alt-locs as tls-capable } } } }