mobile/android/thirdparty/ch/boye/httpclientandroidlib/message/BasicHeaderValueParser.java

Wed, 31 Dec 2014 07:22:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 07:22:50 +0100
branch
TOR_BUG_3246
changeset 4
fc2d59ddac77
permissions
-rw-r--r--

Correct previous dual key logic pending first delivery installment.

     1 /*
     2  * ====================================================================
     3  * Licensed to the Apache Software Foundation (ASF) under one
     4  * or more contributor license agreements.  See the NOTICE file
     5  * distributed with this work for additional information
     6  * regarding copyright ownership.  The ASF licenses this file
     7  * to you under the Apache License, Version 2.0 (the
     8  * "License"); you may not use this file except in compliance
     9  * with the License.  You may obtain a copy of the License at
    10  *
    11  *   http://www.apache.org/licenses/LICENSE-2.0
    12  *
    13  * Unless required by applicable law or agreed to in writing,
    14  * software distributed under the License is distributed on an
    15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    16  * KIND, either express or implied.  See the License for the
    17  * specific language governing permissions and limitations
    18  * under the License.
    19  * ====================================================================
    20  *
    21  * This software consists of voluntary contributions made by many
    22  * individuals on behalf of the Apache Software Foundation.  For more
    23  * information on the Apache Software Foundation, please see
    24  * <http://www.apache.org/>.
    25  *
    26  */
    28 package ch.boye.httpclientandroidlib.message;
    30 import java.util.List;
    31 import java.util.ArrayList;
    33 import ch.boye.httpclientandroidlib.HeaderElement;
    34 import ch.boye.httpclientandroidlib.NameValuePair;
    35 import ch.boye.httpclientandroidlib.ParseException;
    36 import ch.boye.httpclientandroidlib.protocol.HTTP;
    37 import ch.boye.httpclientandroidlib.util.CharArrayBuffer;
    39 /**
    40  * Basic implementation for parsing header values into elements.
    41  * Instances of this class are stateless and thread-safe.
    42  * Derived classes are expected to maintain these properties.
    43  *
    44  * @since 4.0
    45  */
    46 public class BasicHeaderValueParser implements HeaderValueParser {
    48     /**
    49      * A default instance of this class, for use as default or fallback.
    50      * Note that {@link BasicHeaderValueParser} is not a singleton, there
    51      * can be many instances of the class itself and of derived classes.
    52      * The instance here provides non-customized, default behavior.
    53      */
    54     public final static
    55         BasicHeaderValueParser DEFAULT = new BasicHeaderValueParser();
    57     private final static char PARAM_DELIMITER                = ';';
    58     private final static char ELEM_DELIMITER                 = ',';
    59     private final static char[] ALL_DELIMITERS               = new char[] {
    60                                                                 PARAM_DELIMITER,
    61                                                                 ELEM_DELIMITER
    62                                                                 };
    64     // public default constructor
    67     /**
    68      * Parses elements with the given parser.
    69      *
    70      * @param value     the header value to parse
    71      * @param parser    the parser to use, or <code>null</code> for default
    72      *
    73      * @return  array holding the header elements, never <code>null</code>
    74      */
    75     public final static
    76         HeaderElement[] parseElements(final String value,
    77                                       HeaderValueParser parser)
    78         throws ParseException {
    80         if (value == null) {
    81             throw new IllegalArgumentException
    82                 ("Value to parse may not be null");
    83         }
    85         if (parser == null)
    86             parser = BasicHeaderValueParser.DEFAULT;
    88         CharArrayBuffer buffer = new CharArrayBuffer(value.length());
    89         buffer.append(value);
    90         ParserCursor cursor = new ParserCursor(0, value.length());
    91         return parser.parseElements(buffer, cursor);
    92     }
    95     // non-javadoc, see interface HeaderValueParser
    96     public HeaderElement[] parseElements(final CharArrayBuffer buffer,
    97                                          final ParserCursor cursor) {
    99         if (buffer == null) {
   100             throw new IllegalArgumentException("Char array buffer may not be null");
   101         }
   102         if (cursor == null) {
   103             throw new IllegalArgumentException("Parser cursor may not be null");
   104         }
   106         List elements = new ArrayList();
   107         while (!cursor.atEnd()) {
   108             HeaderElement element = parseHeaderElement(buffer, cursor);
   109             if (!(element.getName().length() == 0 && element.getValue() == null)) {
   110                 elements.add(element);
   111             }
   112         }
   113         return (HeaderElement[])
   114             elements.toArray(new HeaderElement[elements.size()]);
   115     }
   118     /**
   119      * Parses an element with the given parser.
   120      *
   121      * @param value     the header element to parse
   122      * @param parser    the parser to use, or <code>null</code> for default
   123      *
   124      * @return  the parsed header element
   125      */
   126     public final static
   127         HeaderElement parseHeaderElement(final String value,
   128                                          HeaderValueParser parser)
   129         throws ParseException {
   131         if (value == null) {
   132             throw new IllegalArgumentException
   133                 ("Value to parse may not be null");
   134         }
   136         if (parser == null)
   137             parser = BasicHeaderValueParser.DEFAULT;
   139         CharArrayBuffer buffer = new CharArrayBuffer(value.length());
   140         buffer.append(value);
   141         ParserCursor cursor = new ParserCursor(0, value.length());
   142         return parser.parseHeaderElement(buffer, cursor);
   143     }
   146     // non-javadoc, see interface HeaderValueParser
   147     public HeaderElement parseHeaderElement(final CharArrayBuffer buffer,
   148                                             final ParserCursor cursor) {
   150         if (buffer == null) {
   151             throw new IllegalArgumentException("Char array buffer may not be null");
   152         }
   153         if (cursor == null) {
   154             throw new IllegalArgumentException("Parser cursor may not be null");
   155         }
   157         NameValuePair nvp = parseNameValuePair(buffer, cursor);
   158         NameValuePair[] params = null;
   159         if (!cursor.atEnd()) {
   160             char ch = buffer.charAt(cursor.getPos() - 1);
   161             if (ch != ELEM_DELIMITER) {
   162                 params = parseParameters(buffer, cursor);
   163             }
   164         }
   165         return createHeaderElement(nvp.getName(), nvp.getValue(), params);
   166     }
   169     /**
   170      * Creates a header element.
   171      * Called from {@link #parseHeaderElement}.
   172      *
   173      * @return  a header element representing the argument
   174      */
   175     protected HeaderElement createHeaderElement(
   176             final String name,
   177             final String value,
   178             final NameValuePair[] params) {
   179         return new BasicHeaderElement(name, value, params);
   180     }
   183     /**
   184      * Parses parameters with the given parser.
   185      *
   186      * @param value     the parameter list to parse
   187      * @param parser    the parser to use, or <code>null</code> for default
   188      *
   189      * @return  array holding the parameters, never <code>null</code>
   190      */
   191     public final static
   192         NameValuePair[] parseParameters(final String value,
   193                                         HeaderValueParser parser)
   194         throws ParseException {
   196         if (value == null) {
   197             throw new IllegalArgumentException
   198                 ("Value to parse may not be null");
   199         }
   201         if (parser == null)
   202             parser = BasicHeaderValueParser.DEFAULT;
   204         CharArrayBuffer buffer = new CharArrayBuffer(value.length());
   205         buffer.append(value);
   206         ParserCursor cursor = new ParserCursor(0, value.length());
   207         return parser.parseParameters(buffer, cursor);
   208     }
   212     // non-javadoc, see interface HeaderValueParser
   213     public NameValuePair[] parseParameters(final CharArrayBuffer buffer,
   214                                            final ParserCursor cursor) {
   216         if (buffer == null) {
   217             throw new IllegalArgumentException("Char array buffer may not be null");
   218         }
   219         if (cursor == null) {
   220             throw new IllegalArgumentException("Parser cursor may not be null");
   221         }
   223         int pos = cursor.getPos();
   224         int indexTo = cursor.getUpperBound();
   226         while (pos < indexTo) {
   227             char ch = buffer.charAt(pos);
   228             if (HTTP.isWhitespace(ch)) {
   229                 pos++;
   230             } else {
   231                 break;
   232             }
   233         }
   234         cursor.updatePos(pos);
   235         if (cursor.atEnd()) {
   236             return new NameValuePair[] {};
   237         }
   239         List params = new ArrayList();
   240         while (!cursor.atEnd()) {
   241             NameValuePair param = parseNameValuePair(buffer, cursor);
   242             params.add(param);
   243             char ch = buffer.charAt(cursor.getPos() - 1);
   244             if (ch == ELEM_DELIMITER) {
   245                 break;
   246             }
   247         }
   249         return (NameValuePair[])
   250             params.toArray(new NameValuePair[params.size()]);
   251     }
   253     /**
   254      * Parses a name-value-pair with the given parser.
   255      *
   256      * @param value     the NVP to parse
   257      * @param parser    the parser to use, or <code>null</code> for default
   258      *
   259      * @return  the parsed name-value pair
   260      */
   261     public final static
   262        NameValuePair parseNameValuePair(final String value,
   263                                         HeaderValueParser parser)
   264         throws ParseException {
   266         if (value == null) {
   267             throw new IllegalArgumentException
   268                 ("Value to parse may not be null");
   269         }
   271         if (parser == null)
   272             parser = BasicHeaderValueParser.DEFAULT;
   274         CharArrayBuffer buffer = new CharArrayBuffer(value.length());
   275         buffer.append(value);
   276         ParserCursor cursor = new ParserCursor(0, value.length());
   277         return parser.parseNameValuePair(buffer, cursor);
   278     }
   281     // non-javadoc, see interface HeaderValueParser
   282     public NameValuePair parseNameValuePair(final CharArrayBuffer buffer,
   283                                             final ParserCursor cursor) {
   284         return parseNameValuePair(buffer, cursor, ALL_DELIMITERS);
   285     }
   287     private static boolean isOneOf(final char ch, final char[] chs) {
   288         if (chs != null) {
   289             for (int i = 0; i < chs.length; i++) {
   290                 if (ch == chs[i]) {
   291                     return true;
   292                 }
   293             }
   294         }
   295         return false;
   296     }
   298     public NameValuePair parseNameValuePair(final CharArrayBuffer buffer,
   299                                             final ParserCursor cursor,
   300                                             final char[] delimiters) {
   302         if (buffer == null) {
   303             throw new IllegalArgumentException("Char array buffer may not be null");
   304         }
   305         if (cursor == null) {
   306             throw new IllegalArgumentException("Parser cursor may not be null");
   307         }
   309         boolean terminated = false;
   311         int pos = cursor.getPos();
   312         int indexFrom = cursor.getPos();
   313         int indexTo = cursor.getUpperBound();
   315         // Find name
   316         String name = null;
   317         while (pos < indexTo) {
   318             char ch = buffer.charAt(pos);
   319             if (ch == '=') {
   320                 break;
   321             }
   322             if (isOneOf(ch, delimiters)) {
   323                 terminated = true;
   324                 break;
   325             }
   326             pos++;
   327         }
   329         if (pos == indexTo) {
   330             terminated = true;
   331             name = buffer.substringTrimmed(indexFrom, indexTo);
   332         } else {
   333             name = buffer.substringTrimmed(indexFrom, pos);
   334             pos++;
   335         }
   337         if (terminated) {
   338             cursor.updatePos(pos);
   339             return createNameValuePair(name, null);
   340         }
   342         // Find value
   343         String value = null;
   344         int i1 = pos;
   346         boolean qouted = false;
   347         boolean escaped = false;
   348         while (pos < indexTo) {
   349             char ch = buffer.charAt(pos);
   350             if (ch == '"' && !escaped) {
   351                 qouted = !qouted;
   352             }
   353             if (!qouted && !escaped && isOneOf(ch, delimiters)) {
   354                 terminated = true;
   355                 break;
   356             }
   357             if (escaped) {
   358                 escaped = false;
   359             } else {
   360                 escaped = qouted && ch == '\\';
   361             }
   362             pos++;
   363         }
   365         int i2 = pos;
   366         // Trim leading white spaces
   367         while (i1 < i2 && (HTTP.isWhitespace(buffer.charAt(i1)))) {
   368             i1++;
   369         }
   370         // Trim trailing white spaces
   371         while ((i2 > i1) && (HTTP.isWhitespace(buffer.charAt(i2 - 1)))) {
   372             i2--;
   373         }
   374         // Strip away quotes if necessary
   375         if (((i2 - i1) >= 2)
   376             && (buffer.charAt(i1) == '"')
   377             && (buffer.charAt(i2 - 1) == '"')) {
   378             i1++;
   379             i2--;
   380         }
   381         value = buffer.substring(i1, i2);
   382         if (terminated) {
   383             pos++;
   384         }
   385         cursor.updatePos(pos);
   386         return createNameValuePair(name, value);
   387     }
   389     /**
   390      * Creates a name-value pair.
   391      * Called from {@link #parseNameValuePair}.
   392      *
   393      * @param name      the name
   394      * @param value     the value, or <code>null</code>
   395      *
   396      * @return  a name-value pair representing the arguments
   397      */
   398     protected NameValuePair createNameValuePair(final String name, final String value) {
   399         return new BasicNameValuePair(name, value);
   400     }
   402 }

mercurial