All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.upokecenter.mail.ParserUtility Maven / Gradle / Ivy

package com.upokecenter.mail;
/*
Written by Peter O. in 2014.
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
If you like this, you should donate to Peter O.
at: http://upokecenter.dreamhosters.com/articles/donate-now-2/
 */

import java.util.*;

import com.upokecenter.util.*;

  final class ParserUtility {
private ParserUtility() {
}
    public static boolean EndsWith(String str, String suffix, int strStartPos) {
      if (str == null) {
        throw new NullPointerException("str");
      }
      if (suffix == null) {
        throw new NullPointerException("suffix");
      }
      if (strStartPos < 0) {
        throw new IllegalArgumentException("strStartPos (" + strStartPos +
          ") is less than " + "0");
      }
      if (strStartPos > str.length()) {
        throw new IllegalArgumentException("strStartPos (" + strStartPos +
          ") is more than " + str.length());
      }
      int endpos = suffix.length() + strStartPos;
      return (
endpos <= str.length()) && str.substring(
strStartPos, (
strStartPos)+(endpos - strStartPos)).equals(suffix);
    }

    public static boolean StartsWith(String str, String prefix) {
      if (str == null) {
        throw new NullPointerException("str");
      }
      if (prefix == null) {
        throw new NullPointerException("prefix");
      }
      return (
prefix.length() >= str.length()) && str.substring(
0, (
0)+(prefix.length())).equals(prefix);
    }

    public static String TrimSpaceAndTab(String str) {
      return ((str) == null || (str).length() == 0) ? str :
        TrimSpaceAndTabLeft(TrimSpaceAndTabRight(str));
    }

    public static String TrimSpaceAndTabLeft(String str) {
      if (((str) == null || (str).length() == 0)) {
        return str;
      }
      int index = 0;
      int valueSLength = str.length();
      while (index < valueSLength) {
        char c = str.charAt(index);
        if (c != 0x09 && c != 0x20) {
          break;
        }
        ++index;
      }
      return (index == valueSLength) ? "" : ((index == 0) ? str :
        str.substring(index));
    }

    public static String TrimSpaceAndTabRight(String str) {
      if (((str) == null || (str).length() == 0)) {
        return str;
      }
      int index = str.length() - 1;
      while (index >= 0) {
        char c = str.charAt(index);
        if (c != 0x09 && c != 0x20) {
          return str.substring(0, index + 1);
        }
        --index;
      }
      return "";
    }

    public static boolean IsNullEmptyOrSpaceTabOnly(String str) {
      return ((
str) == null || (
str).length() == 0) || SkipSpaceAndTab(
str,
0,
str.length()) == str.length();
    }

    public static int ParseFWSLax(
String str,
int index,
int endIndex,
StringBuilder sb) {
      while (index < endIndex) {
        int tmp = index;
        // Skip CRLF
        if (index + 1 < endIndex && str.charAt(index) == 13 && str.charAt(index + 1) == 10) {
          index += 2;
        }
        // Add WSP
        if (index < endIndex && ((str.charAt(index) == 32) || (str.charAt(index) == 9))) {
          if (sb != null) {
            sb.append(str.charAt(index));
          }
          ++index;
        } else {
          return tmp;
        }
      }
      return index;
    }

    // Wsp, a.k.a. 1*LWSP-char under RFC 822
    public static int SkipSpaceAndTab(String str, int index, int endIndex) {
      while (index < endIndex) {
        if (str.charAt(index) == 0x09 || str.charAt(index) == 0x20) {
          ++index;
        } else {
          break;
        }
      }
      return index;
    }

    /**
     * Splits a string by a delimiter. If the string ends with the delimiter, the
     * result will end with an empty string. If the string begins with the
     * delimiter, the result will start with an empty string.
     * @param str A string to split.
     * @param delimiter A string to signal where each substring begins and ends.
     * @return An array containing strings that are split by the delimiter. If the
     * string to split is null or empty, returns an array whose sole element
     * is the empty string.
     * @throws IllegalArgumentException Delimiter is null or empty.
     * @throws NullPointerException The parameter {@code delimiter} is null.
     */
    public static String[] SplitAt(String str, String delimiter) {
      if (delimiter == null) {
        throw new NullPointerException("delimiter");
      }
      if (delimiter.length() == 0) {
        throw new IllegalArgumentException("delimiter is empty.");
      }
      if (((str) == null || (str).length() == 0)) {
        return new String[] { "" };
      }
      int index = 0;
      boolean first = true;
      ArrayList strings = null;
      int delimLength = delimiter.length();
      while (true) {
        int index2 = str.indexOf(delimiter, index);
        if (index2 < 0) {
          if (first) {
            String[] strret = new String[1];
            strret[0] = str;
            return strret;
          }
          strings = (strings == null) ? ((new ArrayList())) : strings;
          strings.add(str.substring(index));
          break;
        } else {
          first = false;
          String newstr = str.substring(index, (index)+((index2)-index));
          strings = (strings == null) ? ((new ArrayList())) : strings;
          strings.add(newstr);
          index = index2 + delimLength;
        }
      }
      return strings.toArray(new String[] { });
    }

    public static boolean IsValidLanguageTag(String str) {
      if (((str) == null || (str).length() == 0)) {
        return false;
      }
      int index = 0;
      int endIndex = str.length();
      int startIndex = index;
      if (index + 1 < endIndex) {
        char c1 = str.charAt(index);
        char c2 = str.charAt(index + 1);
        if (((c1 >= 'A' && c1 <= 'Z') || (c1 >= 'a' && c1 <= 'z')) && ((c2
          >= 'A' && c2 <= 'Z') || (c2 >= 'a' && c2 <= 'z'))) {
          index += 2;
          if (index == endIndex) {
             // case AA
            return true;
          }
          index += 2;
          // convert the language tag to lower case
          // to simplify handling
          str = DataUtilities.ToLowerCaseAscii(str);
          c1 = str.charAt(index);
          // Straightforward cases
          if (c1 >= 'a' && c1 <= 'z') {
            ++index;
            // case AAA
            if (index == endIndex) {
              return true;
            }
            c1 = str.charAt(index);  // get the next character
          }
          if (c1 == '-') { // case AA- or AAA-
            ++index;
            if (index + 2 == endIndex) {  // case AA-?? or AAA-??
              c1 = str.charAt(index);
              c2 = str.charAt(index);
              if ((c1 >= 'a' && c1 <= 'z') && (c2 >= 'a' && c2 <= 'z')) {
                // case AA-BB or AAA-BB
                return true;
              }
            }
          }
          // match grandfathered language tags
          if (str.equals("sgn-be-fr") || str.equals("sgn-be-nl") ||
            str.equals("sgn-ch-de") || str.equals("en-gb-oed")) {
            return true;
          }
          // More complex cases
          String[] splitString = SplitAt(
str.substring(startIndex, (startIndex)+(endIndex - startIndex)),
"-");
          if (splitString.length == 0) {
            return false;
          }
          int splitIndex = 0;
          int splitLength = splitString.length;
          int len = lengthIfAllAlpha(splitString[splitIndex]);
          if (len < 2 || len > 8) {
            return false;
          }
          if (len == 2 || len == 3) {
            ++splitIndex;
            // skip optional extended language subtags
            for (int i = 0; i < 3; ++i) {
              if (splitIndex < splitLength &&
                lengthIfAllAlpha(splitString[splitIndex]) == 3) {
                if (i >= 1) {
                  // point 4 in section 2.2.2 renders two or
                  // more extended language subtags invalid
                  return false;
                }
                ++splitIndex;
              } else {
                break;
              }
            }
          }
          // optional script
          if (splitIndex < splitLength &&
            lengthIfAllAlpha(splitString[splitIndex]) == 4) {
            ++splitIndex;
          }
          // optional region
          if (splitIndex < splitLength &&
            lengthIfAllAlpha(splitString[splitIndex]) == 2) {
            ++splitIndex;
          } else if (splitIndex < splitLength &&
            lengthIfAllDigit(splitString[splitIndex]) == 3) {
            ++splitIndex;
          }
          // variant, any number
          List variants = null;
          while (splitIndex < splitLength) {
            String curString = splitString[splitIndex];
            len = lengthIfAllAlphaNum(curString);
            if (len >= 5 && len <= 8) {
              variants = (variants == null) ? ((new ArrayList())) : variants;
              if (!variants.contains(curString)) {
                variants.add(curString);
              } else {
                 // variant already exists; see point 5 in section
                // 2.2.5
         return false;
              }
              ++splitIndex;
         } else if (len == 4 && (curString.charAt(0) >= '0' && curString.charAt(0) <= '9'
)) {
              variants = (variants == null) ? ((new ArrayList())) : variants;
              if (!variants.contains(curString)) {
                variants.add(curString);
              } else {
                 // variant already exists; see point 5 in section
                // 2.2.5
         return false;
              }
              ++splitIndex;
            } else {
              break;
            }
          }
          // extension, any number
          if (variants != null) {
            variants.clear();
          }
          while (splitIndex < splitLength) {
            String curString = splitString[splitIndex];
            int curIndex = splitIndex;
            if (lengthIfAllAlphaNum(curString) == 1 &&
                    !curString.equals("x")) {
              variants = (variants == null) ? ((new ArrayList())) : variants;
              if (!variants.contains(curString)) {
                variants.add(curString);
              } else {
                return false;  // extension already exists
              }
              ++splitIndex;
              boolean havetoken = false;
              while (splitIndex < splitLength) {
                curString = splitString[splitIndex];
                len = lengthIfAllAlphaNum(curString);
                if (len >= 2 && len <= 8) {
                  havetoken = true;
                  ++splitIndex;
                } else {
                  break;
                }
              }
              if (!havetoken) {
                splitIndex = curIndex;
                break;
              }
            } else {
              break;
            }
          }
          // optional private use
          if (splitIndex < splitLength) {
            int curIndex = splitIndex;
            if (splitString[splitIndex].equals("x")) {
              ++splitIndex;
              boolean havetoken = false;
              while (splitIndex < splitLength) {
                len = lengthIfAllAlphaNum(splitString[splitIndex]);
                if (len >= 1 && len <= 8) {
                  havetoken = true;
                  ++splitIndex;
                } else {
                  break;
                }
              }
              if (!havetoken) {
                splitIndex = curIndex;
              }
            }
          }
          // check if all the tokens were used
          return splitIndex == splitLength;
        }
        if (c2 == '-' && (c1 == 'x' || c1 == 'X')) {
          // private use
          ++index;
          while (index < endIndex) {
            int count = 0;
            if (str.charAt(index) != '-') {
              return false;
            }
            ++index;
            while (index < endIndex) {
              c1 = str.charAt(index);
              if ((c1 >= 'A' && c1 <= 'Z') || (c1 >= 'a' && c1 <= 'z') ||
                (c1 >= '0' && c1 <= '9')) {
                ++count;
                if (count > 8) {
                  return false;
                }
              } else if (c1 == '-') {
                break;
              } else {
                return false;
              }
              ++index;
            }
            if (count < 1) {
              return false;
            }
          }
          return true;
        }
        if (c2 == '-' && (c1 == 'i' || c1 == 'I')) {
          // grandfathered language tags
          str = DataUtilities.ToLowerCaseAscii(str);
          return str.equals("i-ami") || str.equals("i-bnn") ||
          str.equals("i-default") || str.equals("i-enochian") ||
          str.equals("i-hak") || str.equals("i-klingon") ||
          str.equals("i-lux") || str.equals("i-navajo") ||
          str.equals("i-mingo") || str.equals("i-pwn") ||
          str.equals("i-tao") || str.equals("i-tay") ||
          str.equals("i-tsu");
        }
        return false;
      }
      return false;
    }

    private static int lengthIfAllAlpha(String str) {
      int len = (str == null) ? 0 : str.length();
      for (int i = 0; i < len; ++i) {
        char c1 = str.charAt(i);
        if (!((c1 >= 'A' && c1 <= 'Z') || (c1 >= 'a' && c1 <= 'z'))) {
          return 0;
        }
      }
      return len;
    }

    private static int lengthIfAllAlphaNum(String str) {
      int len = (str == null) ? 0 : str.length();
      for (int i = 0; i < len; ++i) {
        char c1 = str.charAt(i);
        if (!((c1 >= 'A' && c1 <= 'Z') || (c1 >= 'a' && c1 <= 'z') || (c1
          >= '0' && c1 <= '9'))) {
          return 0;
        }
      }
      return len;
    }

    private static int lengthIfAllDigit(String str) {
      int len = (str == null) ? 0 : str.length();
      for (int i = 0; i < len; ++i) {
        char c1 = str.charAt(i);
        if (!(c1 >= '0' && c1 <= '9')) {
          return 0;
        }
      }
      return len;
    }
  }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy