From: bdemsky Date: Thu, 8 Nov 2007 10:58:16 +0000 (+0000) Subject: initial port of proxy server... X-Git-Tag: preEdgeChange~381 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=ff16b3d5c34ae691dbb4d835c267a0544ef84ce7;p=IRC.git initial port of proxy server... --- diff --git a/Robust/src/Benchmarks/Jhttpp2/BR/Jhttpp2ClientInputStream.java b/Robust/src/Benchmarks/Jhttpp2/BR/Jhttpp2ClientInputStream.java new file mode 100755 index 00000000..ed259f9c --- /dev/null +++ b/Robust/src/Benchmarks/Jhttpp2/BR/Jhttpp2ClientInputStream.java @@ -0,0 +1,134 @@ +/* Written and copyright 2001-2003 Benjamin Kohl. + * Distributed under the GNU General Public License; see the README file. + * This code comes with NO WARRANTY. + */ + +import java.io.IOException; +import java.io.InputStream; +import java.io.BufferedInputStream; +import java.net.InetAddress; +import java.net.UnknownHostException; + + +/** + File: Jhttpp2BufferedFilterStream.java + @author Benjamin Kohl +*/ +public class Jhttpp2ClientInputStream { + private boolean filter; + /** + * This is set to true with requests with bodies, like "POST" + */ + + public boolean ssl; + flag foo; + + private void init() { + ssl = false; + } + + public Jhttpp2ClientInputStream() { + init(); + } + + + public Request read(String str, Jhttpp2HTTPSession connection, tag ct, tag tc) { + //can check for ssl first + String s=readstr(str, connection); + if (s!=null) { + return new Request(s){}{ct, tc}; + } else + return null; + } + + public Request readfirst(String str, Jhttpp2HTTPSession connection, tag ct, tag tc) { + String s=readstr(str, connection); + if (s!=null) { + return new Request(s){first}{ct, tc}; + } else + return null; + } + + public String readstr(String str, Jhttpp2HTTPSession connection) { + String rq=""; + int content_len=0; + boolean tempssl=false; + + if (ssl) + return str; + + String buf = getLine(str); // reads the first line + str = updateBuffer(str, buf); + if (buf==null) + return null; + rq += buf; + if (buf.startsWith("CONNECT")) + tempssl=true; + boolean cnt=true; + while(cnt) { + buf = getLine(str); // reads the first line + str = updateBuffer(str, buf); + if (buf==null) + return null; + rq += buf; + + if (buf.length()<=2) { + cnt=false; + } else { + if (buf.toUpperCase().startsWith("CONTENT-LENGTH")) { + String clen=buf.substring(16); + if (clen.indexOf("\r")!=-1) + clen=clen.substring(0,clen.indexOf("\r")); + else + if(clen.indexOf("\n")!=-1) clen=clen.substring(0,clen.indexOf("\n")); + content_len=Integer.parseInt(clen); + } + } + } + if (!tempssl) { + buf=getAdditional(str, content_len); + str = updateBuffer(str, buf); + if (buf==null) + return null; + rq+=buf; + } + ssl=tempssl; + return rq; + } + + + /** + * reads a line + * @exception IOException + */ + public static String getLine(String str) { + int l=str.indexOf('\n'); + if (l!=-1) + return str.substring(0, l+1); + else + return null; + } + + public static String getAdditional(String str, int content_len) { + if (content_len>str.length()) + return null; + else + return str.substring(0, content_len); + + } + + public static String updateBuffer(String buf, String str) { + if (str!=null) { + return buf.substring(str.length(), buf.length()); + } else + return buf; + } + + /** + * @return boolean whether the actual connection was established with the CONNECT method. + * @since 0.2.21 + */ + public boolean isTunnel() { + return ssl; + } +} diff --git a/Robust/src/Benchmarks/Jhttpp2/BR/Jhttpp2HTTPSession.java b/Robust/src/Benchmarks/Jhttpp2/BR/Jhttpp2HTTPSession.java new file mode 100644 index 00000000..f902e809 --- /dev/null +++ b/Robust/src/Benchmarks/Jhttpp2/BR/Jhttpp2HTTPSession.java @@ -0,0 +1,31 @@ +/* Written and copyright 2001-2003 Benjamin Kohl. + * Distributed under the GNU General Public License; see the README file. + * This code comes with NO WARRANTY. + */ + +import java.net.Socket; +import java.net.InetAddress; +import java.net.UnknownHostException; + +import java.io.BufferedOutputStream; +import java.io.BufferedInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.io.File; +import java.io.FileInputStream; + + +/** + One HTTP connection + @file Jhttpp2HTTPSession.java + @author Benjamin Kohl +*/ +public class Jhttpp2HTTPSession { + String request; + flag more; + flag first; + + public Jhttpp2HTTPSession() { + } +} + diff --git a/Robust/src/Benchmarks/Jhttpp2/BR/Jhttpp2Server.java b/Robust/src/Benchmarks/Jhttpp2/BR/Jhttpp2Server.java new file mode 100755 index 00000000..c6fa5c09 --- /dev/null +++ b/Robust/src/Benchmarks/Jhttpp2/BR/Jhttpp2Server.java @@ -0,0 +1,310 @@ +/* Written and copyright 2001-2003 Benjamin Kohl. + * Distributed under the GNU General Public License; see the README file. + * This code comes with NO WARRANTY. + * More Information and documentation: HTTP://jhttp2.sourceforge.net/ + */ + +import java.net.ServerSocket; +import java.net.Socket; +import java.net.UnknownHostException; +import java.net.InetAddress; +import java.net.BindException; + +import java.io.*; + +import java.util.Vector; +import java.util.Date; + +public class Jhttpp2Server +{ + private static final String CRLF; + private final String VERSION; + private final String V_SPECIAL; + private final String HTTP_VERSION; + private final String MAIN_LOGFILE; + + private final String DATA_FILE; + private final String SERVER_PROPERTIES_FILE; + + private String http_useragent; + private ServerSocket listen; + private BufferedWriter logfile; + private BufferedWriter access_logfile; + private long bytesread; + private long byteswritten; + private int numconnections; + + private boolean enable_cookies_by_default; + private WildcardDictionary dic; + private Vector urlactions; + + public final int DEFAULT_SERVER_PORT; + public final String WEB_CONFIG_FILE; + + public int port; + public InetAddress proxy; + public int proxy_port; + + public long config_auth; + public long config_session_id; + public String config_user; + public String config_password; + + public static boolean error; + public static String error_msg; + + public boolean use_proxy; + public boolean block_urls; + public boolean filter_http; + public boolean debug; + public boolean log_access; + public String log_access_filename; + public boolean webconfig; + public boolean www_server; + + + public initvars() { + CRLF="\r\n"; + VERSION = "0.4.62"; + V_SPECIAL = " 2003-05-20"; + HTTP_VERSION = "HTTP/1.1"; + MAIN_LOGFILE = "server.log"; + DATA_FILE = "server.data"; + SERVER_PROPERTIES_FILE = "server.properties"; + http_useragent = "Mozilla/4.0 (compatible; MSIE 4.0; WindowsNT 5.0)"; + enable_cookies_by_default=true; + dic = new WildcardDictionary(); + urlactions = new Vector(); + DEFAULT_SERVER_PORT = 8088; + WEB_CONFIG_FILE = "admin/jp2-config"; + port = DEFAULT_SERVER_PORT; + proxy_port = 0; + config_auth = 0; + config_session_id = 0; + config_user = "root"; + config_password = "geheim"; + use_proxy=false; + block_urls=false; + filter_http=false; + debug=false; + log_access = true; + log_access_filename="paccess.log"; + webconfig = true; + www_server = true; +} + + void init() + { + if(log_access) { + access_logfile=new BufferedWriter(new FileWriter(log_access_filename,true)); + } + + logfile=new BufferedWriter(new FileWriter(MAIN_LOGFILE,true)); + writeLog("server startup..."); + + listen = new ServerSocket(port); + + if (error) { + writeLog(error_msg); + return; + } + } + public Jhttpp2Server() { + initvars(); + init(); + } + public Jhttpp2Server(boolean b) + { + initvars(); + System.printString("jHTTPp2 HTTP Proxy Server Release " + getServerVersion() + "\r\n" + +"Copyright (c) 2001-2003 Benjamin Kohl \r\n" + +"This software comes with ABSOLUTELY NO WARRANTY OF ANY KIND.\r\n" + +"http://jhttp2.sourceforge.net/\n"); + init(); + } + /** calls init(), sets up the serverport and starts for each connection + * new Jhttpp2Connection + */ + public void setErrorMsg(String a) + { + error=true; + error_msg=a; + } + /** + * Tests what method is used with the reqest + * @return -1 if the server doesn't support the method + */ + public static int getHttpMethod(String d) + { + if (startsWith(d,"GET") || startsWith(d,"HEAD")) return 0; + if (startsWith(d,"POST") || startsWith(d,"PUT")) return 1; + if (startsWith(d,"CONNECT")) return 2; + if (startsWith(d,"OPTIONS")) return 3; + + return -1;/* No match... + + Following methods are not implemented: + || startsWith(d,"TRACE") */ + } + public static boolean startsWith(String a,String what) + { + int l=what.length(); + int l2=a.length(); + if (l2>l) + return a.substring(0,l).equals(what); + else + return false; + } + /** + *@return the Server response-header field + */ + public String getServerIdentification() + { + return "jHTTPp2/" + getServerVersion(); + } + public String getServerVersion() + { + return VERSION + V_SPECIAL; + } + /** + * saves all settings with a ObjectOutputStream into a file + * @since 0.2.10 + */ + /** restores all Jhttpp2 options from "settings.dat" + * @since 0.2.10 + */ + /** + * @return the HTTP version used by jHTTPp2 + */ + public String getHttpVersion() + { + return HTTP_VERSION; + } + /** the User-Agent header field + * @since 0.2.17 + * @return User-Agent String + */ + public String getUserAgent() + { + return http_useragent; + } + public void setUserAgent(String ua) + { + http_useragent=ua; + } + /** + * writes into the server log file and adds a new line + * @since 0.2.21 + */ + public void writeLog(String s) + { + writeLog(s,true); + } + /** writes to the server log file + * @since 0.2.21 + */ + public void writeLog(String s,boolean b) + { + s=new Date().toString() + " " + s; + logfile.write(s,0,s.length()); + if (b) logfile.newLine(); + logfile.flush(); + if (debug)System.printString(s); + } + + public void closeLog() + { + writeLog("Server shutdown."); + logfile.flush(); + logfile.close(); + access_logfile.close(); + } + + public void addBytesRead(long read) + { + bytesread+=read; + } + /** + * Functions for the jHTTPp2 statistics: + * How many connections + * Bytes read/written + * @since 0.3.0 + */ + public void addBytesWritten(int written) + { + byteswritten+=written; + } + public int getServerConnections() + { + return numconnections; + } + public long getBytesRead() + { + return bytesread; + } + public long getBytesWritten() + { + return byteswritten; + } + public void increaseNumConnections() + { + numconnections++; + } + public void decreaseNumConnections() + { + numconnections--; + } + public void AuthenticateUser(String u,String p) { + if (config_user.equals(u) && config_password.equals(p)) { + config_auth = 1; + } else config_auth = 0; + } + public String getGMTString() + { + return new Date().toString(); + } + public Jhttpp2URLMatch findMatch(String url) + { + return (Jhttpp2URLMatch)dic.get(url); + } + public WildcardDictionary getWildcardDictionary() + { + return dic; + } + public Vector getURLActions() + { + return urlactions; + } + public boolean enableCookiesByDefault() + { + return this.enable_cookies_by_default; + } + public void enableCookiesByDefault(boolean a) + { + enable_cookies_by_default=a; + } + public void resetStat() + { + bytesread=0; + byteswritten=0; + } + /** + * @since 0.4.10a + */ + /** + * @since 0.4.10a + */ + /** + * @since 0.4.10a + */ + public void logAccess(String s) + { + access_logfile.write("[" + new Date().toString() + "] " + s + "\r\n"); + access_logfile.flush(); + } + public void shutdownServer() { + closeLog(); + System.exit(0); + } + +} diff --git a/Robust/src/Benchmarks/Jhttpp2/BR/Jhttpp2Task.java b/Robust/src/Benchmarks/Jhttpp2/BR/Jhttpp2Task.java new file mode 100644 index 00000000..bd20efd4 --- /dev/null +++ b/Robust/src/Benchmarks/Jhttpp2/BR/Jhttpp2Task.java @@ -0,0 +1,180 @@ +task start(StartupObject s{initialstate}) { + Jhttpp2Server js=new Jhttpp2Server(true); + taskexit(s{!initialstate}); +} + +task acceptconnection(ServerSocket ss{SocketPending}) { + tag t=new tag(connection); + Socket s=ss.accept(t); + Jhttpp2HTTPSession js=new Jhttpp2HTTPSession() {first}{t}; + Jhttpp2ClientInputStream jcis=new Jhttpp2ClientInputStream() {}{t}; +} + +task requestfirst(Jhttpp2HTTPSession session {first}{connection tc}, Jhttpp2ClientInputStream jcis {}{connection tc}, Socket socket {IOPending}{connection tc}) { + byte[] buf=new byte[10000]; + int length=socket.read(buf); + String str=new String(buf, 0, length); + System.printString("["+str+"]\n"); + if (session.request!=null) { + str=session.request.concat(str); + } + tag ct=new tag(chained); + Request r=jcis.readfirst(str, session, ct, tc); + if (r==null) { + session.request=str; + taskexit; + } else { + session.request=str.substring(r.length(), str.length()); + if (session.request.length()>0) + taskexit(session{more, !first}); + else + taskexit(session{!first}); + } +} + +task request(Jhttpp2HTTPSession session {}{connection tc}, Jhttpp2ClientInputStream jcis {}{connection tc}, Socket socket {IOPending}{connection tc}, optional Request rold{!chained}{connection tc}) { + byte[] buf=new byte[10000]; + int length=socket.read(buf); + System.printString("length="+length+"\n"); + if (session.request!=null) + System.printString(session.request+"\n"); + if (length==0) { + taskexit; + } else if (length < 0 ) { + System.printString("ERROR\n"); + taskexit; + } + String str=new String(buf, 0, length); + System.printString("["+str+"]\n"); + + if (session.request!=null) { + str=session.request.concat(str); + } + //pull off the next request + tag ct=new tag(chained); + Request r=jcis.read(str, session, ct, tc); + if (r==null) { + session.request=str; + taskexit; + } else { + System.printString("new Request\n"); + session.request=str.substring(r.length(), str.length()); + if (session.request.length()>0) + taskexit(session{more}, rold{chained}{ct}); + else + taskexit(rold{chained}{ct}); + } +} + +task requestmore(Jhttpp2HTTPSession session {more}{connection tc}, Jhttpp2ClientInputStream jcis {}{connection tc}, optional Request rold{!chained}{connection tc}) { + String str=session.request; + //pull off the next request + tag ct=new tag(chained); + Request r=jcis.read(str, session, ct, tc); + if (r==null) { + session.request=str; + taskexit; + } else { + session.request=str.substring(r.length(), str.length()); + if (session.request.length()>0) + taskexit(rold{chained}{ct}); + else + taskexit(session{!more}, rold{chained}{ct}); + } +} + +task sendfirst(Request r{first&&!processed}{connection tc}) { + r.parseRequest(); + r.connect(); + r.sendRequest(); + taskexit(r{processed}); +} + +task sendnext(optional Request rprev{received&&!done}{chained ct}, Request r{!processed}{chained ct}) { + r.parseRequest(); + r.connect(); + r.sendRequest(); + taskexit(r{processed}, rprev{done}); +} + +task recvreq(Request r{processed&&!received&&IOPending}) { + byte[] buf=new byte[10000]; + int length=r.read(buf); + if (length==0) { + //Done + taskexit(r{received}); + } + String str=new String(buf, 0, length); + if (r.response!=null) { + str=r.response.concat(str); + } + boolean cnt=true; + int lastindex=0; + int bytes=0; + while(cnt) { + int nextindex=str.indexOf('\n',lastindex)+1; + if (nextindex==-1) { + r.response=str; + taskexit; + } + if (nextindex-lastindex<=2) { + cnt=false; + } else if (str.substring(lastindex, nextindex+1).toUpperCase().startsWith("CONTENT-LENGTH")) { + String clen=str.substring(lastindex+16, nextindex+1); + if (clen.indexOf("\r")!=-1) + clen=clen.substring(0,clen.indexOf("\r")); + else + if(clen.indexOf("\n")!=-1) + clen=clen.substring(0,clen.indexOf("\n")); + bytes=Integer.parseInt(clen); + } + lastindex=nextindex; + } + if (bytes>0) { + if ((lastindex+bytes) + * Sets up the URL, method and remote hostname. + * @return an InetAddress for the hostname, null on errors with a statuscode!=SC_OK + */ + public void parseRequest() { + String a=request.substring(0,request.indexOf('\n')); + String f; + int pos; + int method_index=Jhttpp2Server.getHttpMethod(a); + + if (ssl) { + url=""; + f = a.substring(8); + } else { + method = a.substring(0,a.indexOf(" ")); //first word in the line + pos = a.indexOf(":"); // locate first : + if (pos == -1) { // occours with "GET / HTTP/1.1" + url = a.substring(a.indexOf(" ")+1,a.lastIndexOf(" ")); + if (method_index == 0) { // method_index==0 --> GET + statuscode = SC_FILE_REQUEST; + } else { + statuscode = SC_INTERNAL_SERVER_ERROR; + errordescription="This WWW proxy supports only the \"GET\" method while acting as webserver."; + } + return; + } + f = a.substring(pos+3); //removes "http://" + } + pos=f.indexOf(" "); // locate space, should be the space before "HTTP/1.1" + if (pos==-1) { // buggy request + statuscode = SC_CLIENT_ERROR; + errordescription="Your browser sent an invalid request: \""+ a + "\""; + return; + } + f = f.substring(0,pos); //removes all after space + // if the url contains a space... it's not our mistake...(url's must never contain a space character) + pos=f.indexOf("/"); // locate the first slash + if (pos!=-1) { + url=f.substring(pos); // saves path without hostname + f=f.substring(0,pos); // reduce string to the hostname + } + else url="/"; // occurs with this request: "GET http://localhost HTTP/1.1" + pos = f.indexOf(":"); // check for the portnumber + if (pos!=-1) { + String l_port =f.substring(pos+1); + if (l_port.indexOf(" ")!=-1) + l_port=l_port.substring(0,l_port.indexOf(" ")); + int i_port=80; + i_port = Integer.parseInt(l_port); + f = f.substring(0,pos); + port=i_port; + } else + port=80; + remote_host_name = f; + address = InetAddress.getByName(f); + } + + public void connect() { + connect(address, port); + } + + public String getRequest() { + return method + " "+url+" "+"HTTP/1.1"+"\r\n"; + } + + public void sendRequest() { + write(getRequest().getBytes()); + write(request.substring(request.indexOf('\n')+1,request.length()).getBytes()); + } +} diff --git a/Robust/src/Benchmarks/Jhttpp2/BR/WildcardDictionary.java b/Robust/src/Benchmarks/Jhttpp2/BR/WildcardDictionary.java new file mode 100755 index 00000000..9d8bab67 --- /dev/null +++ b/Robust/src/Benchmarks/Jhttpp2/BR/WildcardDictionary.java @@ -0,0 +1,182 @@ +// WildcardDictionary - a dictionary with wildcard lookups +// +// Copyright (C) 1996 by Jef Poskanzer . All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +// SUCH DAMAGE. +// +// Visit the ACME Labs Java page for up-to-date versions of this and other +// fine Java utilities: http://www.acme.com/java/ + +// package Acme; + +import java.util.*; + +/// A dictionary with wildcard lookups. +//

+// The keys in this dictionary are wildcard patterns. When you do a get(), +// the string you pass in is matched against all the patterns, and the +// first match is returned. +//

+// The wildcard matcher is fairly simple, it implements * meaning any +// string, ? meaning any single character, and | separating multiple +// patterns. All other characters must match literally. +//

+// Fetch the software.
+// Fetch the entire Acme package. +//

+// @see Acme.Utils#match + +public class WildcardDictionary extends Dictionary { + + private Vector keys; + private Vector elements; + + /// Constructor. + public WildcardDictionary() { + keys = new Vector(); + elements = new Vector(); + } + + /// Returns the number of elements contained within the dictionary. + public int size() { + return elements.size(); + } + + /// Returns true if the dictionary contains no elements. + public boolean isEmpty() { + return size() == 0; + } + + /// Returns an enumeration of the dictionary's keys. + public Enumeration keys() { + return keys.elements(); + } + + /// Returns an enumeration of the elements. Use the Enumeration methods + // on the returned object to fetch the elements sequentially. + public Enumeration elements() { + return elements.elements(); + } + + /// Gets the object associated with the specified key in the dictionary. + // The key is assumed to be a String, which is matched against + // the wildcard-pattern keys in the dictionary. + // @param key the string to match + // @returns the element for the key, or null if there's no match + // @see Acme.Utils#match + public synchronized Object get( Object key ) + { + String sKey = (String) key; + for ( int i = 0; i < keys.size(); ++i ) + { + String thisKey = (String) keys.elementAt( i ); + if ( match( thisKey, sKey ) ) + return elements.elementAt( i ); + } + return null; + } + + /// Puts the specified element into the Dictionary, using the specified + // key. The element may be retrieved by doing a get() with the same + // key. The key and the element cannot be null. + // @param key the specified wildcard-pattern key + // @param value the specified element + // @return the old value of the key, or null if it did not have one. + // @exception NullPointerException If the value of the specified + // element is null. + public synchronized Object put( Object key, Object element ) + { + int i = keys.indexOf( key ); + if ( i != -1 ) + { + Object oldElement = elements.elementAt( i ); + elements.setElementAt( element, i ); + return oldElement; + } + else + { + keys.addElement( key ); + elements.addElement( element ); + return null; + } + } + + /// Removes the element corresponding to the key. Does nothing if the + // key is not present. + // @param key the key that needs to be removed + // @return the value of key, or null if the key was not found. + public synchronized Object remove( Object key ) + { + int i = keys.indexOf( key ); + if ( i != -1 ) + { + Object oldElement = elements.elementAt( i ); + keys.removeElementAt( i ); + elements.removeElementAt( i ); + return oldElement; + } + else + return null; + } + + /** Checks whether a string matches a given wildcard pattern. + * Only does ? and *, and multiple patterns separated by |. + */ + public static boolean match( String pattern, String string ) { + for ( int p = 0; true; ++p ) { + boolean cnt=true; + for ( int s = 0; cnt; ++p, ++s ) { + boolean sEnd = ( s >= string.length() ); + boolean pEnd = ( p >= pattern.length() || + pattern.charAt( p ) == '|' ); + if ( sEnd && pEnd ) + return true; + if ( sEnd || pEnd ) + cnt=false; + else if ( pattern.charAt( p ) != '?' ) { + if ( pattern.charAt( p ) == '*' ) { + int i; + ++p; + for ( i = string.length(); i >= s; --i ) + if ( match( + pattern.substring( p ), + string.substring( i ) ) ) /* not quite right */ + return true; + cnt=false; + } + if ( pattern.charAt( p ) != string.charAt( s ) ) + cnt=false; + } + } + p = pattern.indexOf( '|', p ); + if ( p == -1 ) + return false; + } + } + /** + * Deletes all elements and keys. + */ + public void removeAllElements() { + elements.clear(); + keys.clear(); + } +}