org.codehaus.httpcache4j.util.DirectivesParser Maven / Gradle / Ivy
The newest version!
/*
* Copyright (c) 2010. The Codehaus. All Rights Reserved.
*
* 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 org.codehaus.httpcache4j.util;
import org.codehaus.httpcache4j.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
*
* Modified version of the HTTP Components BasicHeaderValueParser.
* Original authors: http://hc.apache.org/httpcomponents-core/index.html
*
* @author Erlend Hamnaberg
* @version $Revision: $
*/
public final class DirectivesParser {
public static final int CR = 13; //
public static final int LF = 10; //
public static final int SP = 32; //
public static final int HT = 9; //
public static boolean isWhitespace(char ch) {
return ch == SP || ch == HT || ch == CR || ch == LF;
}
private final static char PARAM_DELIMITER = ';';
private final static char ELEM_DELIMITER = ',';
private final static char[] ALL_DELIMITERS = new char[]{
PARAM_DELIMITER,
ELEM_DELIMITER
};
public static Directives parse(String value) {
if (value.length() > 0) {
StringBuilder builder = new StringBuilder(value);
ParserCursor cursor = new ParserCursor(0, value.length());
DirectivesParser parser = new DirectivesParser();
return new Directives(parser.parseDirectives(builder, cursor));
}
return new Directives();
}
private List parseDirectives(final StringBuilder buffer, final ParserCursor cursor) {
List elements = new ArrayList<>();
while (!cursor.atEnd()) {
Directive element = parseDirective(buffer, cursor);
if (!(element.getName().length() == 0 && element.getValue() == null)) {
elements.add(element);
}
}
return elements;
}
private Directive parseDirective(final StringBuilder buffer, final ParserCursor cursor) {
Parameter parameter = parseParameter(buffer, cursor, ALL_DELIMITERS);
List params = Collections.emptyList();
if (!cursor.atEnd()) {
char ch = buffer.charAt(cursor.getPos() - 1);
if (ch != ELEM_DELIMITER) {
params = parseParameters(buffer, cursor);
}
}
if (parameter instanceof QuotedParameter) {
return createDirective(parameter.getName(), ((QuotedParameter) parameter).getQuotedValue(), params);
}
return createDirective(parameter.getName(), parameter.getValue(), params);
}
/**
* Creates a header element.
* Called from {@link #parseDirective}.
*
* @return a header element representing the argument
*/
private Directive createDirective(
final String name,
final String value,
final List params) {
if (isQuoted(value)) {
return new QuotedDirective(name, value, params);
}
if (HeaderConstants.LINK_HEADER.equals(name)) {
return new LinkDirective(value, params);
}
return new Directive(name, value, params);
}
private List parseParameters(final StringBuilder buffer, final ParserCursor cursor) {
if (buffer == null) {
throw new IllegalArgumentException("Char array buffer may not be null");
}
if (cursor == null) {
throw new IllegalArgumentException("Parser cursor may not be null");
}
int pos = cursor.getPos();
int indexTo = cursor.getUpperBound();
while (pos < indexTo) {
char ch = buffer.charAt(pos);
if (isWhitespace(ch)) {
pos++;
}
else {
break;
}
}
cursor.updatePos(pos);
if (cursor.atEnd()) {
return Collections.emptyList();
}
List params = new ArrayList<>();
while (!cursor.atEnd()) {
params.add(parseParameter(buffer, cursor, ALL_DELIMITERS));
char ch = buffer.charAt(cursor.getPos() - 1);
if (ch == ELEM_DELIMITER) {
break;
}
}
return params;
}
private static boolean isOneOf(final char ch, final char[] chars) {
if (chars != null) {
for (char chr : chars) {
if (ch == chr) {
return true;
}
}
}
return false;
}
private Parameter parseParameter(final StringBuilder buffer,
final ParserCursor cursor,
final char[] delimiters) {
if (buffer == null) {
throw new IllegalArgumentException("Char array buffer may not be null");
}
if (cursor == null) {
throw new IllegalArgumentException("Parser cursor may not be null");
}
boolean terminated = false;
int pos = cursor.getPos();
int indexFrom = cursor.getPos();
int indexTo = cursor.getUpperBound();
// Find name
String name;
while (pos < indexTo) {
char ch = buffer.charAt(pos);
if (ch == '=') {
break;
}
if (isOneOf(ch, delimiters)) {
terminated = true;
break;
}
pos++;
}
if (pos == indexTo) {
terminated = true;
name = buffer.substring(indexFrom, indexTo).trim();
}
else {
name = buffer.substring(indexFrom, pos).trim();
pos++;
}
if (terminated) {
cursor.updatePos(pos);
int i = name.indexOf('<');
int j = name.indexOf('>');
if (i != -1 && j != -1) { //this is a Link header
return createParameter(HeaderConstants.LINK_HEADER, name.substring(i + 1, j));
}
return createParameter(name, null);
}
// Find value
String value;
int i1 = pos;
boolean qouted = false;
boolean escaped = false;
while (pos < indexTo) {
char ch = buffer.charAt(pos);
if (ch == '"' && !escaped) {
qouted = !qouted;
}
if (!qouted && !escaped && isOneOf(ch, delimiters)) {
terminated = true;
break;
}
if (escaped) {
escaped = false;
}
else {
escaped = qouted && ch == '\\';
}
pos++;
}
int i2 = pos;
// Trim leading white spaces
while (i1 < i2 && (isWhitespace(buffer.charAt(i1)))) {
i1++;
}
// Trim trailing white spaces
while ((i2 > i1) && (isWhitespace(buffer.charAt(i2 - 1)))) {
i2--;
}
value = buffer.substring(i1, i2);
if (terminated) {
pos++;
}
cursor.updatePos(pos);
return createParameter(name, value);
}
/**
* Creates a Parameter
*
* @param name the name
* @param value the value, or null
* @return a name-value pair representing the arguments
*/
static Parameter createParameter(final String name, final String value) {
if (value != null && isQuoted(value)) {
return new QuotedParameter(name, value);
}
return new Parameter(name, value);
}
static boolean isQuoted(String value) {
return value.startsWith("\"") && value.endsWith("\"");
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy