com.phloc.web.http.HTTPStringHelper Maven / Gradle / Ivy
/**
* Copyright (C) 2006-2015 phloc systems
* http://www.phloc.com
* office[at]phloc[dot]com
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.phloc.web.http;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import com.phloc.commons.annotations.PresentForCodeCoverage;
import com.phloc.commons.collections.ArrayHelper;
import com.phloc.commons.exceptions.InitializationException;
import com.phloc.commons.string.StringHelper;
/**
* HTTP string utils. Based on RFC 1945 http://tools.ietf.org/html/rfc1945
*
* @author Philip Helger
*/
@Immutable
public final class HTTPStringHelper
{
/** Minimum index (inclusive) */
public static final int MIN_INDEX = 0;
/** Maximum index (inclusive) */
public static final int MAX_INDEX = 127;
/** Comment start character */
public static final char COMMENT_BEGIN = '(';
/** Comment end character */
public static final char COMMENT_END = ')';
/** Quoted text start character */
public static final char QUOTEDTEXT_BEGIN = '"';
/** Quoted text end character */
public static final char QUOTEDTEXT_END = '"';
public static final int CHAR_TAB = 9;
public static final int CHAR_LF = 10;
public static final int CHAR_CR = 13;
public static final int CHAR_SPACE = 32;
private static final int UALPHA = 0x00000001;
private static final int LALPHA = 0x00000002;
private static final int ALPHA = 0x00000004;
private static final int DIGIT = 0x00000008;
private static final int CTL = 0x00000010;
private static final int LWS = 0x00000020;
private static final int HEX = 0x00000040;
private static final int LHEX = 0x00000080;
private static final int NON_TOKEN = 0x00000100;
private static final int NON_TEXT = 0x00000200;
private static final int NON_COMMENT = 0x00000400;
private static final int NON_QUOTEDTEXT = 0x00000800;
private static final int RESERVED = 0x00001000;
private static final int EXTRA = 0x00002000;
private static final int SAFE = 0x00004000;
private static final int UNSAFE = 0x00008000;
private static final char [] MAPPINGS = new char [] {
// 0x00
CTL | NON_TEXT | UNSAFE,
CTL | NON_TEXT | UNSAFE,
CTL | NON_TEXT | UNSAFE,
CTL | NON_TEXT | UNSAFE,
CTL | NON_TEXT | UNSAFE,
CTL | NON_TEXT | UNSAFE,
CTL | NON_TEXT | UNSAFE,
CTL | NON_TEXT | UNSAFE,
CTL | NON_TEXT | UNSAFE,
CTL | NON_TOKEN | UNSAFE | LWS,
CTL | UNSAFE | LWS,
CTL | NON_TEXT | UNSAFE,
CTL | NON_TEXT | UNSAFE,
CTL | UNSAFE | LWS,
CTL | NON_TEXT | UNSAFE,
CTL | NON_TEXT | UNSAFE,
// 0x10
CTL | NON_TEXT | UNSAFE,
CTL | NON_TEXT | UNSAFE,
CTL | NON_TEXT | UNSAFE,
CTL | NON_TEXT | UNSAFE,
CTL | NON_TEXT | UNSAFE,
CTL | NON_TEXT | UNSAFE,
CTL | NON_TEXT | UNSAFE,
CTL | NON_TEXT | UNSAFE,
CTL | NON_TEXT | UNSAFE,
CTL | NON_TEXT | UNSAFE,
CTL | NON_TEXT | UNSAFE,
CTL | NON_TEXT | UNSAFE,
CTL | NON_TEXT | UNSAFE,
CTL | NON_TEXT | UNSAFE,
CTL | NON_TEXT | UNSAFE,
CTL | NON_TEXT | UNSAFE,
// 0x20
NON_TOKEN | UNSAFE | LWS,
EXTRA,
NON_TOKEN | NON_QUOTEDTEXT | UNSAFE,
UNSAFE,
SAFE,
UNSAFE,
RESERVED,
EXTRA,
NON_TOKEN | NON_COMMENT | EXTRA,
NON_TOKEN | NON_COMMENT | EXTRA,
EXTRA,
RESERVED,
NON_TOKEN | EXTRA,
SAFE,
SAFE,
NON_TOKEN | RESERVED,
// 0x30
DIGIT | HEX | LHEX,
DIGIT | HEX | LHEX,
DIGIT | HEX | LHEX,
DIGIT | HEX | LHEX,
DIGIT | HEX | LHEX,
DIGIT | HEX | LHEX,
DIGIT | HEX | LHEX,
DIGIT | HEX | LHEX,
DIGIT | HEX | LHEX,
DIGIT | HEX | LHEX,
NON_TOKEN | RESERVED,
NON_TOKEN | RESERVED,
NON_TOKEN | UNSAFE,
NON_TOKEN | RESERVED,
NON_TOKEN | UNSAFE,
NON_TOKEN | RESERVED,
// 0x40
NON_TOKEN | RESERVED,
UALPHA | ALPHA | HEX,
UALPHA | ALPHA | HEX,
UALPHA | ALPHA | HEX,
UALPHA | ALPHA | HEX,
UALPHA | ALPHA | HEX,
UALPHA | ALPHA | HEX,
UALPHA | ALPHA,
UALPHA | ALPHA,
UALPHA | ALPHA,
UALPHA | ALPHA,
UALPHA | ALPHA,
UALPHA | ALPHA,
UALPHA | ALPHA,
UALPHA | ALPHA,
UALPHA | ALPHA,
// 0x50
UALPHA | ALPHA,
UALPHA | ALPHA,
UALPHA | ALPHA,
UALPHA | ALPHA,
UALPHA | ALPHA,
UALPHA | ALPHA,
UALPHA | ALPHA,
UALPHA | ALPHA,
UALPHA | ALPHA,
UALPHA | ALPHA,
UALPHA | ALPHA,
NON_TOKEN,
NON_TOKEN,
NON_TOKEN,
0,
SAFE,
// 0x60
0,
LALPHA | ALPHA | HEX | LHEX,
LALPHA | ALPHA | HEX | LHEX,
LALPHA | ALPHA | HEX | LHEX,
LALPHA | ALPHA | HEX | LHEX,
LALPHA | ALPHA | HEX | LHEX,
LALPHA | ALPHA | HEX | LHEX,
LALPHA | ALPHA,
LALPHA | ALPHA,
LALPHA | ALPHA,
LALPHA | ALPHA,
LALPHA | ALPHA,
LALPHA | ALPHA,
LALPHA | ALPHA,
LALPHA | ALPHA,
LALPHA | ALPHA,
// 0x70
LALPHA | ALPHA,
LALPHA | ALPHA,
LALPHA | ALPHA,
LALPHA | ALPHA,
LALPHA | ALPHA,
LALPHA | ALPHA,
LALPHA | ALPHA,
LALPHA | ALPHA,
LALPHA | ALPHA,
LALPHA | ALPHA,
LALPHA | ALPHA,
NON_TOKEN,
0,
NON_TOKEN,
0,
CTL | NON_TEXT | UNSAFE };
static
{
if (MAPPINGS.length != MAX_INDEX + 1)
throw new InitializationException ("MAPPING array is invalid!");
}
@PresentForCodeCoverage
@SuppressWarnings ("unused")
private static final HTTPStringHelper s_aInstance = new HTTPStringHelper ();
private HTTPStringHelper ()
{}
public static boolean isChar (final int n)
{
return n >= MIN_INDEX && n <= MAX_INDEX;
}
public static boolean isOctet (final int n)
{
return n >= MIN_INDEX && n < 256;
}
public static boolean isUpperAlphaChar (final int n)
{
return isChar (n) && (MAPPINGS[n] & UALPHA) == UALPHA;
}
public static boolean isLowerAlphaChar (final int n)
{
return isChar (n) && (MAPPINGS[n] & LALPHA) == LALPHA;
}
public static boolean isAlphaChar (final int n)
{
return isChar (n) && (MAPPINGS[n] & ALPHA) == ALPHA;
}
public static boolean isDigitChar (final int n)
{
return isChar (n) && (MAPPINGS[n] & DIGIT) == DIGIT;
}
public static boolean isControlChar (final int n)
{
return isChar (n) && (MAPPINGS[n] & CTL) == CTL;
}
public static boolean isCRChar (final int n)
{
return n == CHAR_CR;
}
public static boolean isLFChar (final int n)
{
return n == CHAR_LF;
}
public static boolean isSpaceChar (final int n)
{
return n == CHAR_SPACE;
}
public static boolean isTabChar (final int n)
{
return n == CHAR_TAB;
}
public static boolean isLinearWhitespaceChar (final int n)
{
return isChar (n) && (MAPPINGS[n] & LWS) == LWS;
}
public static boolean isQuoteChar (final int n)
{
return n == 34;
}
public static boolean isHexChar (final int n)
{
return isChar (n) && (MAPPINGS[n] & HEX) == HEX;
}
public static boolean isHexNotEmpty (@Nullable final char [] aChars)
{
if (ArrayHelper.isEmpty (aChars))
return false;
for (final char c : aChars)
if (!isHexChar (c))
return false;
return true;
}
public static boolean isHexNotEmpty (@Nullable final String sStr)
{
if (StringHelper.hasNoText (sStr))
return false;
return isHexNotEmpty (sStr.toCharArray ());
}
public static boolean isLowerHexChar (final int n)
{
return isChar (n) && (MAPPINGS[n] & LHEX) == LHEX;
}
public static boolean isLowerHexNotEmpty (@Nullable final char [] aChars)
{
if (ArrayHelper.isEmpty (aChars))
return false;
for (final char c : aChars)
if (!isLowerHexChar (c))
return false;
return true;
}
public static boolean isLowerHexNotEmpty (@Nullable final String sStr)
{
if (StringHelper.hasNoText (sStr))
return false;
return isLowerHexNotEmpty (sStr.toCharArray ());
}
public static boolean isNonTokenChar (final int n)
{
return isChar (n) && (MAPPINGS[n] & NON_TOKEN) == NON_TOKEN;
}
public static boolean isTokenChar (final int n)
{
return isChar (n) && (MAPPINGS[n] & (CTL | NON_TOKEN)) == 0;
}
public static boolean isToken (@Nullable final char [] aChars)
{
if (ArrayHelper.isEmpty (aChars))
return false;
for (final char c : aChars)
if (!isTokenChar (c))
return false;
return true;
}
public static boolean isToken (@Nullable final String sStr)
{
if (StringHelper.hasNoText (sStr))
return false;
return isToken (sStr.toCharArray ());
}
public static boolean isTextChar (final int n)
{
if (n < MIN_INDEX)
return false;
// Any octet allowed!
if (n > MAX_INDEX)
return n < 256;
return (MAPPINGS[n] & NON_TEXT) == 0;
}
public static boolean isCommentChar (final int n)
{
if (n < MIN_INDEX)
return false;
// Any octet allowed!
if (n > MAX_INDEX)
return n < 256;
return (MAPPINGS[n] & (NON_TEXT | NON_COMMENT)) == 0;
}
public static boolean isComment (@Nullable final char [] aChars)
{
if (ArrayHelper.getSize (aChars) < 2 || aChars[0] != COMMENT_BEGIN || aChars[aChars.length - 1] != COMMENT_END)
return false;
for (int i = 1; i < aChars.length - 1; ++i)
if (!isCommentChar (aChars[i]))
return false;
return true;
}
public static boolean isComment (@Nullable final String sStr)
{
if (StringHelper.getLength (sStr) < 2)
return false;
return isComment (sStr.toCharArray ());
}
public static boolean isQuotedTextChar (final int n)
{
return isChar (n) && (MAPPINGS[n] & (NON_TEXT | NON_QUOTEDTEXT)) == 0;
}
public static boolean isQuotedText (@Nullable final char [] aChars)
{
if (ArrayHelper.getSize (aChars) < 2 ||
aChars[0] != QUOTEDTEXT_BEGIN ||
aChars[aChars.length - 1] != QUOTEDTEXT_END)
return false;
for (int i = 1; i < aChars.length - 1; ++i)
if (!isQuotedTextChar (aChars[i]))
return false;
return true;
}
public static boolean isQuotedText (@Nullable final String sStr)
{
if (StringHelper.getLength (sStr) < 2)
return false;
return isQuotedText (sStr.toCharArray ());
}
@Nullable
public static String getQuotedTextString (@Nullable final String sStr)
{
if (sStr == null)
return null;
return QUOTEDTEXT_BEGIN + sStr + QUOTEDTEXT_END;
}
public static boolean isQuotedTextContent (@Nullable final char [] aChars)
{
if (aChars == null)
return false;
for (final char c : aChars)
if (!isQuotedTextChar (c))
return false;
return true;
}
public static boolean isQuotedTextContent (@Nullable final String sStr)
{
if (sStr == null)
return false;
return isQuotedTextContent (sStr.toCharArray ());
}
public static boolean isWord (@Nullable final char [] aChars)
{
return isToken (aChars) || isQuotedText (aChars);
}
public static boolean isWord (@Nullable final String sStr)
{
if (StringHelper.hasNoText (sStr))
return false;
return isWord (sStr.toCharArray ());
}
public static boolean isReservedChar (final int n)
{
// ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+"
return isChar (n) && (MAPPINGS[n] & RESERVED) == RESERVED;
}
public static boolean isExtraChar (final int n)
{
// "!" | "*" | "'" | "(" | ")" | ","
return isChar (n) && (MAPPINGS[n] & EXTRA) == EXTRA;
}
public static boolean isSafeChar (final int n)
{
// "$" | "-" | "_" | "."
return isChar (n) && (MAPPINGS[n] & SAFE) == SAFE;
}
public static boolean isUnsafeChar (final int n)
{
// CTL | SP | <"> | "#" | "%" | "<" | ">"
return isChar (n) && (MAPPINGS[n] & UNSAFE) == UNSAFE;
}
public static boolean isNationalChar (final int n)
{
//
if (n < MIN_INDEX)
return false;
// Any octet allowed!
if (n > MAX_INDEX)
return n < 256;
return (MAPPINGS[n] & (ALPHA | DIGIT | RESERVED | EXTRA | SAFE | UNSAFE)) == 0;
}
public static boolean isUnreservedChar (final int n)
{
// ALPHA | DIGIT | safe | extra | national
if (n < MIN_INDEX)
return false;
// Any octet allowed!
if (n > MAX_INDEX)
return n < 256;
final int nMapping = MAPPINGS[n];
return (nMapping & (ALPHA | DIGIT | RESERVED | EXTRA | SAFE | UNSAFE)) == 0 ||
(nMapping & (ALPHA | DIGIT | EXTRA | SAFE)) != 0;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy