//# 0 errors, 130 messages
//#
/*
    //#IRCStringConverter.java:1:1: class: com.dmdirc.parser.irc.IRCStringConverter
    //#IRCStringConverter.java:1:1: method: com.dmdirc.parser.irc.IRCStringConverter.com.dmdirc.parser.irc.IRCStringConverter__static_init
 * Copyright (c) 2006-2009 Chris Smith, Shane Mc Cormack, Gregory Holmes
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package com.dmdirc.parser.irc;

/**
 * IRC String Converter.
 *
 * @author Shane Mc Cormack
 */
public class IRCStringConverter {
	/** Characters to use when converting tolowercase. */
	private final char[] lowercase;
	/** Characters to use when converting touppercase. */
	private final char[] uppercase;
	/** limit */
	private final byte limit;

	/**
	 * Create a new IRCStringConverter with rfc1459 encoding.
	 */
	public IRCStringConverter() {
		this((byte)4);
    //#IRCStringConverter.java:42: method: void com.dmdirc.parser.irc.IRCStringConverter.com.dmdirc.parser.irc.IRCStringConverter()
    //#input(void com.dmdirc.parser.irc.IRCStringConverter()): this
    //#output(void com.dmdirc.parser.irc.IRCStringConverter()): new char[](IRCStringConverter#1) num objects
    //#output(void com.dmdirc.parser.irc.IRCStringConverter()): new char[](IRCStringConverter#1).length
    //#output(void com.dmdirc.parser.irc.IRCStringConverter()): new char[](IRCStringConverter#1)[0..65_535]
    //#output(void com.dmdirc.parser.irc.IRCStringConverter()): new char[](IRCStringConverter#2) num objects
    //#output(void com.dmdirc.parser.irc.IRCStringConverter()): new char[](IRCStringConverter#2).length
    //#output(void com.dmdirc.parser.irc.IRCStringConverter()): new char[](IRCStringConverter#2)[0..65_567]
    //#output(void com.dmdirc.parser.irc.IRCStringConverter()): this.limit
    //#output(void com.dmdirc.parser.irc.IRCStringConverter()): this.lowercase
    //#output(void com.dmdirc.parser.irc.IRCStringConverter()): this.uppercase
    //#new obj(void com.dmdirc.parser.irc.IRCStringConverter()): new char[](IRCStringConverter#1)
    //#new obj(void com.dmdirc.parser.irc.IRCStringConverter()): new char[](IRCStringConverter#2)
    //#post(void com.dmdirc.parser.irc.IRCStringConverter()): this.limit == 4
    //#post(void com.dmdirc.parser.irc.IRCStringConverter()): this.lowercase == &new char[](IRCStringConverter#1)
    //#post(void com.dmdirc.parser.irc.IRCStringConverter()): this.uppercase == &new char[](IRCStringConverter#2)
    //#post(void com.dmdirc.parser.irc.IRCStringConverter()): new char[](IRCStringConverter#1) num objects == 1
    //#post(void com.dmdirc.parser.irc.IRCStringConverter()): new char[](IRCStringConverter#2) num objects == 1
    //#post(void com.dmdirc.parser.irc.IRCStringConverter()): new char[](IRCStringConverter#1).length == 127
    //#post(void com.dmdirc.parser.irc.IRCStringConverter()): new char[](IRCStringConverter#2).length == 127
    //#post(void com.dmdirc.parser.irc.IRCStringConverter()): possibly_updated(new char[](IRCStringConverter#1)[0..65_535])
    //#post(void com.dmdirc.parser.irc.IRCStringConverter()): possibly_updated(new char[](IRCStringConverter#2)[0..65_567])
	}
    //#IRCStringConverter.java:43: end of method: void com.dmdirc.parser.irc.IRCStringConverter.com.dmdirc.parser.irc.IRCStringConverter()
	
	/**
	 * Create a new IRCStringConverter.
	 * @param limit Number of post-alphabetical characters to convert
	 *              0 = ascii encoding
	 *              3 = strict-rfc1459 encoding
	 *              4 = rfc1459 encoding
	 */
	public IRCStringConverter(final byte limit) {
    //#IRCStringConverter.java:52: method: void com.dmdirc.parser.irc.IRCStringConverter.com.dmdirc.parser.irc.IRCStringConverter(byte)
    //#input(void com.dmdirc.parser.irc.IRCStringConverter(byte)): limit
    //#input(void com.dmdirc.parser.irc.IRCStringConverter(byte)): this
    //#output(void com.dmdirc.parser.irc.IRCStringConverter(byte)): new char[](IRCStringConverter#1) num objects
    //#output(void com.dmdirc.parser.irc.IRCStringConverter(byte)): this.lowercase.length
    //#output(void com.dmdirc.parser.irc.IRCStringConverter(byte)): this.lowercase[0..65_535]
    //#output(void com.dmdirc.parser.irc.IRCStringConverter(byte)): new char[](IRCStringConverter#2) num objects
    //#output(void com.dmdirc.parser.irc.IRCStringConverter(byte)): this.uppercase.length
    //#output(void com.dmdirc.parser.irc.IRCStringConverter(byte)): this.uppercase[0..65_567]
    //#output(void com.dmdirc.parser.irc.IRCStringConverter(byte)): this.limit
    //#output(void com.dmdirc.parser.irc.IRCStringConverter(byte)): this.lowercase
    //#output(void com.dmdirc.parser.irc.IRCStringConverter(byte)): this.uppercase
    //#new obj(void com.dmdirc.parser.irc.IRCStringConverter(byte)): new char[](IRCStringConverter#1)
    //#new obj(void com.dmdirc.parser.irc.IRCStringConverter(byte)): new char[](IRCStringConverter#2)
    //#post(void com.dmdirc.parser.irc.IRCStringConverter(byte)): this.limit == One-of{4, limit}
    //#post(void com.dmdirc.parser.irc.IRCStringConverter(byte)): this.limit in {0..4}
    //#post(void com.dmdirc.parser.irc.IRCStringConverter(byte)): this.lowercase == &new char[](IRCStringConverter#1)
    //#post(void com.dmdirc.parser.irc.IRCStringConverter(byte)): this.uppercase == &new char[](IRCStringConverter#2)
    //#post(void com.dmdirc.parser.irc.IRCStringConverter(byte)): new char[](IRCStringConverter#1) num objects == 1
    //#post(void com.dmdirc.parser.irc.IRCStringConverter(byte)): new char[](IRCStringConverter#2) num objects == 1
    //#post(void com.dmdirc.parser.irc.IRCStringConverter(byte)): this.lowercase.length == 127
    //#post(void com.dmdirc.parser.irc.IRCStringConverter(byte)): this.uppercase.length == 127
    //#post(void com.dmdirc.parser.irc.IRCStringConverter(byte)): this.lowercase[0..65_535] == One-of{VN37:[...] + 32, this.lowercase[0..65_535]}
    //#post(void com.dmdirc.parser.irc.IRCStringConverter(byte)): this.uppercase[0..65_567] == One-of{VN42:[...] - 32, this.uppercase[0..65_567]}
    //#test_vector(void com.dmdirc.parser.irc.IRCStringConverter(byte)): limit: {5..255}, {0..4}, {-128..-1}
		// If limit is out side the boundries, use rfc1459
		if (limit > 4 || limit < 0 ) { this.limit = (byte)4; }
		else { this.limit = limit; }
		
		lowercase = new char[127];
		uppercase = new char[127];
		// Normal Chars
		for (char i = 0; i < lowercase.length; ++i) {
			lowercase[i] = i;
			uppercase[i] = i;
		}

		// Replace the uppercase chars with lowercase
		for (char i = 65; i <= (90 + this.limit); ++i) {
			lowercase[i] = (char)(i + 32);
			uppercase[i + 32] = i;
		}
	}
    //#IRCStringConverter.java:70: end of method: void com.dmdirc.parser.irc.IRCStringConverter.com.dmdirc.parser.irc.IRCStringConverter(byte)

	/**
	 * Get last used chararray limit.
	 *
	 * @return last used chararray limit
	 */
	protected int getLimit() { return limit; }
    //#IRCStringConverter.java:77: method: int com.dmdirc.parser.irc.IRCStringConverter.getLimit()
    //#input(int getLimit()): this
    //#input(int getLimit()): this.limit
    //#output(int getLimit()): return_value
    //#post(int getLimit()): return_value == this.limit
    //#post(int getLimit()): return_value in {-128..255}
    //#IRCStringConverter.java:77: end of method: int com.dmdirc.parser.irc.IRCStringConverter.getLimit()
	
	/**
	 * Get the lowercase version of a String for this Server.
	 *
	 * @param input String to convert lowercase
	 * @return input String converterd to lowercase
	 */
	public String toLowerCase(final String input) {
		final char[] result = input.toCharArray();
    //#IRCStringConverter.java:86: method: String com.dmdirc.parser.irc.IRCStringConverter.toLowerCase(String)
    //#input(String toLowerCase(String)): input
    //#input(String toLowerCase(String)): this
    //#input(String toLowerCase(String)): this.lowercase
    //#input(String toLowerCase(String)): this.lowercase.length
    //#input(String toLowerCase(String)): this.lowercase[0..65_535]
    //#output(String toLowerCase(String)): new String(toLowerCase#1) num objects
    //#output(String toLowerCase(String)): return_value
    //#new obj(String toLowerCase(String)): new String(toLowerCase#1)
    //#pre[1] (String toLowerCase(String)): input != null
    //#pre[3] (String toLowerCase(String)): (soft) this.lowercase != null
    //#pre[5] (String toLowerCase(String)): (soft) init'ed(this.lowercase[0..65_535])
    //#presumption(String toLowerCase(String)): result.length@86 >= 1
    //#presumption(String toLowerCase(String)): java.lang.String:length(...)@87 <= result.length@86
    //#post(String toLowerCase(String)): return_value == &new String(toLowerCase#1)
    //#post(String toLowerCase(String)): new String(toLowerCase#1) num objects == 1
		for (int i = 0; i < input.length(); ++i) {
			if (result[i] >= 0 && result[i] < lowercase.length) {
    //#IRCStringConverter.java:88: Warning: test always goes same way
    //#    Test predetermined because init'ed(result[i])
    //#    severity: LOW
    //#    class: com.dmdirc.parser.irc.IRCStringConverter
    //#    method: String toLowerCase(String)
    //#    from bb: bb_3
    //#    live edge: bb_3-->bb_4
    //#    tested vn: result[i]
    //#    tested vn values: {0..65_535}
				result[i] = lowercase[result[i]];
			} else {
				result[i] = result[i];
			}
		}
		return new String(result);
    //#IRCStringConverter.java:94: end of method: String com.dmdirc.parser.irc.IRCStringConverter.toLowerCase(String)
	}

	/**
	 * Get the uppercase version of a String for this Server.
	 *
	 * @param input String to convert uppercase
	 * @return input String converterd to uppercase
	 */
	public String toUpperCase(final String input) {
		final char[] result = input.toCharArray();
    //#IRCStringConverter.java:104: method: String com.dmdirc.parser.irc.IRCStringConverter.toUpperCase(String)
    //#input(String toUpperCase(String)): input
    //#input(String toUpperCase(String)): this
    //#input(String toUpperCase(String)): this.uppercase
    //#input(String toUpperCase(String)): this.uppercase.length
    //#input(String toUpperCase(String)): this.uppercase[0..65_535]
    //#output(String toUpperCase(String)): new String(toUpperCase#1) num objects
    //#output(String toUpperCase(String)): return_value
    //#new obj(String toUpperCase(String)): new String(toUpperCase#1)
    //#pre[1] (String toUpperCase(String)): input != null
    //#pre[3] (String toUpperCase(String)): (soft) this.uppercase != null
    //#pre[5] (String toUpperCase(String)): (soft) init'ed(this.uppercase[0..65_535])
    //#presumption(String toUpperCase(String)): result.length@104 >= 1
    //#presumption(String toUpperCase(String)): java.lang.String:length(...)@105 <= result.length@104
    //#post(String toUpperCase(String)): return_value == &new String(toUpperCase#1)
    //#post(String toUpperCase(String)): new String(toUpperCase#1) num objects == 1
		for (int i = 0; i < input.length(); ++i) {
			if (result[i] >= 0 && result[i] < uppercase.length) {
    //#IRCStringConverter.java:106: Warning: test always goes same way
    //#    Test predetermined because init'ed(result[i])
    //#    severity: LOW
    //#    class: com.dmdirc.parser.irc.IRCStringConverter
    //#    method: String toUpperCase(String)
    //#    from bb: bb_3
    //#    live edge: bb_3-->bb_4
    //#    tested vn: result[i]
    //#    tested vn values: {0..65_535}
				result[i] = uppercase[result[i]];
			} else {
				result[i] = result[i];
			}
		}
		return new String(result);
    //#IRCStringConverter.java:112: end of method: String com.dmdirc.parser.irc.IRCStringConverter.toUpperCase(String)
	}

	/**
	 * Check if 2 strings are equal to each other ignoring case.
	 *
	 * @param first First string to check
	 * @param second Second string to check
	 * @return True if both strings are equal after being lowercased
	 */
	public boolean equalsIgnoreCase(final String first, final String second) {
		if (first == null && second == null) { return true; }
    //#IRCStringConverter.java:123: method: bool com.dmdirc.parser.irc.IRCStringConverter.equalsIgnoreCase(String, String)
    //#input(bool equalsIgnoreCase(String, String)): first
    //#input(bool equalsIgnoreCase(String, String)): second
    //#input(bool equalsIgnoreCase(String, String)): this
    //#input(bool equalsIgnoreCase(String, String)): this.lowercase
    //#input(bool equalsIgnoreCase(String, String)): this.lowercase.length
    //#input(bool equalsIgnoreCase(String, String)): this.lowercase[0..65_535]
    //#output(bool equalsIgnoreCase(String, String)): return_value
    //#pre[11] (bool equalsIgnoreCase(String, String)): (soft) this.lowercase != null
    //#pre[12] (bool equalsIgnoreCase(String, String)): (soft) this.lowercase.length >= 1
    //#pre[13] (bool equalsIgnoreCase(String, String)): (soft) init'ed(this.lowercase[0..65_535])
    //#presumption(bool equalsIgnoreCase(String, String)): firstChar[i]@127 < this.lowercase.length
    //#presumption(bool equalsIgnoreCase(String, String)): firstChar[i]@127 < this.lowercase.length
    //#presumption(bool equalsIgnoreCase(String, String)): java.lang.String:length(...)@129 <= firstChar.length@127
    //#presumption(bool equalsIgnoreCase(String, String)): secondChar.length@128 >= 1
    //#presumption(bool equalsIgnoreCase(String, String)): java.lang.String:length(...)@129 <= secondChar.length@128
    //#presumption(bool equalsIgnoreCase(String, String)): secondChar[i]@128 < this.lowercase.length
    //#presumption(bool equalsIgnoreCase(String, String)): secondChar[i]@128 < this.lowercase.length
    //#post(bool equalsIgnoreCase(String, String)): init'ed(return_value)
    //#test_vector(bool equalsIgnoreCase(String, String)): first: Inverse{null}, Addr_Set{null}
    //#test_vector(bool equalsIgnoreCase(String, String)): second: Inverse{null}, Addr_Set{null}
    //#test_vector(bool equalsIgnoreCase(String, String)): firstChar[i]@127 - this.lowercase.length: {0..65_534}, {-65_535..-1}
    //#test_vector(bool equalsIgnoreCase(String, String)): secondChar[i]@128 - this.lowercase.length: {0..65_534}, {-Inf..-1}
		if (first == null || second == null) { return false; }
		boolean result = (first.length() == second.length());
		if (result) {
			final char[] firstChar = first.toCharArray();
			final char[] secondChar = second.toCharArray();
			for (int i = 0; i < first.length(); ++i) {
				if (firstChar[i] < lowercase.length && secondChar[i] < lowercase.length) {
					result = (lowercase[firstChar[i]] == lowercase[secondChar[i]]);
				} else {
					result = firstChar[i] == secondChar[i];
				}
				if (!result) { break; }
			}
		}

		return result;
    //#IRCStringConverter.java:139: end of method: bool com.dmdirc.parser.irc.IRCStringConverter.equalsIgnoreCase(String, String)
	}

}
    //#output(com.dmdirc.parser.irc.IRCStringConverter__static_init): __Descendant_Table[com/dmdirc/parser/irc/IRCStringConverter]
    //#output(com.dmdirc.parser.irc.IRCStringConverter__static_init): __Dispatch_Table.equalsIgnoreCase(Ljava/lang/String;Ljava/lang/String;)Z
    //#output(com.dmdirc.parser.irc.IRCStringConverter__static_init): __Dispatch_Table.getLimit()I
    //#output(com.dmdirc.parser.irc.IRCStringConverter__static_init): __Dispatch_Table.toLowerCase(Ljava/lang/String;)Ljava/lang/String;
    //#output(com.dmdirc.parser.irc.IRCStringConverter__static_init): __Dispatch_Table.toUpperCase(Ljava/lang/String;)Ljava/lang/String;
    //#post(com.dmdirc.parser.irc.IRCStringConverter__static_init): __Descendant_Table[com/dmdirc/parser/irc/IRCStringConverter] == &__Dispatch_Table
    //#post(com.dmdirc.parser.irc.IRCStringConverter__static_init): __Dispatch_Table.equalsIgnoreCase(Ljava/lang/String;Ljava/lang/String;)Z == &equalsIgnoreCase
    //#post(com.dmdirc.parser.irc.IRCStringConverter__static_init): __Dispatch_Table.getLimit()I == &getLimit
    //#post(com.dmdirc.parser.irc.IRCStringConverter__static_init): __Dispatch_Table.toLowerCase(Ljava/lang/String;)Ljava/lang/String; == &toLowerCase
    //#post(com.dmdirc.parser.irc.IRCStringConverter__static_init): __Dispatch_Table.toUpperCase(Ljava/lang/String;)Ljava/lang/String; == &toUpperCase
    //#IRCStringConverter.java:: end of method: com.dmdirc.parser.irc.IRCStringConverter.com.dmdirc.parser.irc.IRCStringConverter__static_init
    //#IRCStringConverter.java:: end of class: com.dmdirc.parser.irc.IRCStringConverter
