mobile/android/thirdparty/ch/boye/httpclientandroidlib/message/BasicHeaderValueFormatter.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 ch.boye.httpclientandroidlib.HeaderElement;
    31 import ch.boye.httpclientandroidlib.NameValuePair;
    32 import ch.boye.httpclientandroidlib.util.CharArrayBuffer;
    34 /**
    35  * Basic implementation for formatting header value elements.
    36  * Instances of this class are stateless and thread-safe.
    37  * Derived classes are expected to maintain these properties.
    38  *
    39  * @since 4.0
    40  */
    41 public class BasicHeaderValueFormatter implements HeaderValueFormatter {
    43     /**
    44      * A default instance of this class, for use as default or fallback.
    45      * Note that {@link BasicHeaderValueFormatter} is not a singleton, there
    46      * can be many instances of the class itself and of derived classes.
    47      * The instance here provides non-customized, default behavior.
    48      */
    49     public final static
    50         BasicHeaderValueFormatter DEFAULT = new BasicHeaderValueFormatter();
    53     /**
    54      * Special characters that can be used as separators in HTTP parameters.
    55      * These special characters MUST be in a quoted string to be used within
    56      * a parameter value .
    57      */
    58     public final static String SEPARATORS = " ;,:@()<>\\\"/[]?={}\t";
    61     /**
    62      * Unsafe special characters that must be escaped using the backslash
    63      * character
    64      */
    65     public final static String UNSAFE_CHARS = "\"\\";
    69     // public default constructor
    73     /**
    74      * Formats an array of header elements.
    75      *
    76      * @param elems     the header elements to format
    77      * @param quote     <code>true</code> to always format with quoted values,
    78      *                  <code>false</code> to use quotes only when necessary
    79      * @param formatter         the formatter to use, or <code>null</code>
    80      *                          for the {@link #DEFAULT default}
    81      *
    82      * @return  the formatted header elements
    83      */
    84     public final static
    85         String formatElements(final HeaderElement[] elems,
    86                               final boolean quote,
    87                               HeaderValueFormatter formatter) {
    88         if (formatter == null)
    89             formatter = BasicHeaderValueFormatter.DEFAULT;
    90         return formatter.formatElements(null, elems, quote).toString();
    91     }
    94     // non-javadoc, see interface HeaderValueFormatter
    95     public CharArrayBuffer formatElements(CharArrayBuffer buffer,
    96                                           final HeaderElement[] elems,
    97                                           final boolean quote) {
    98         if (elems == null) {
    99             throw new IllegalArgumentException
   100                 ("Header element array must not be null.");
   101         }
   103         int len = estimateElementsLen(elems);
   104         if (buffer == null) {
   105             buffer = new CharArrayBuffer(len);
   106         } else {
   107             buffer.ensureCapacity(len);
   108         }
   110         for (int i=0; i<elems.length; i++) {
   111             if (i > 0) {
   112                 buffer.append(", ");
   113             }
   114             formatHeaderElement(buffer, elems[i], quote);
   115         }
   117         return buffer;
   118     }
   121     /**
   122      * Estimates the length of formatted header elements.
   123      *
   124      * @param elems     the header elements to format, or <code>null</code>
   125      *
   126      * @return  a length estimate, in number of characters
   127      */
   128     protected int estimateElementsLen(final HeaderElement[] elems) {
   129         if ((elems == null) || (elems.length < 1))
   130             return 0;
   132         int result = (elems.length-1) * 2; // elements separated by ", "
   133         for (int i=0; i<elems.length; i++) {
   134             result += estimateHeaderElementLen(elems[i]);
   135         }
   137         return result;
   138     }
   142     /**
   143      * Formats a header element.
   144      *
   145      * @param elem      the header element to format
   146      * @param quote     <code>true</code> to always format with quoted values,
   147      *                  <code>false</code> to use quotes only when necessary
   148      * @param formatter         the formatter to use, or <code>null</code>
   149      *                          for the {@link #DEFAULT default}
   150      *
   151      * @return  the formatted header element
   152      */
   153     public final static
   154         String formatHeaderElement(final HeaderElement elem,
   155                                    boolean quote,
   156                                    HeaderValueFormatter formatter) {
   157         if (formatter == null)
   158             formatter = BasicHeaderValueFormatter.DEFAULT;
   159         return formatter.formatHeaderElement(null, elem, quote).toString();
   160     }
   163     // non-javadoc, see interface HeaderValueFormatter
   164     public CharArrayBuffer formatHeaderElement(CharArrayBuffer buffer,
   165                                                final HeaderElement elem,
   166                                                final boolean quote) {
   167         if (elem == null) {
   168             throw new IllegalArgumentException
   169                 ("Header element must not be null.");
   170         }
   172         int len = estimateHeaderElementLen(elem);
   173         if (buffer == null) {
   174             buffer = new CharArrayBuffer(len);
   175         } else {
   176             buffer.ensureCapacity(len);
   177         }
   179         buffer.append(elem.getName());
   180         final String value = elem.getValue();
   181         if (value != null) {
   182             buffer.append('=');
   183             doFormatValue(buffer, value, quote);
   184         }
   186         final int parcnt = elem.getParameterCount();
   187         if (parcnt > 0) {
   188             for (int i=0; i<parcnt; i++) {
   189                 buffer.append("; ");
   190                 formatNameValuePair(buffer, elem.getParameter(i), quote);
   191             }
   192         }
   194         return buffer;
   195     }
   198     /**
   199      * Estimates the length of a formatted header element.
   200      *
   201      * @param elem      the header element to format, or <code>null</code>
   202      *
   203      * @return  a length estimate, in number of characters
   204      */
   205     protected int estimateHeaderElementLen(final HeaderElement elem) {
   206         if (elem == null)
   207             return 0;
   209         int result = elem.getName().length(); // name
   210         final String value = elem.getValue();
   211         if (value != null) {
   212             // assume quotes, but no escaped characters
   213             result += 3 + value.length(); // ="value"
   214         }
   216         final int parcnt = elem.getParameterCount();
   217         if (parcnt > 0) {
   218             for (int i=0; i<parcnt; i++) {
   219                 result += 2 +                   // ; <param>
   220                     estimateNameValuePairLen(elem.getParameter(i));
   221             }
   222         }
   224         return result;
   225     }
   230     /**
   231      * Formats a set of parameters.
   232      *
   233      * @param nvps      the parameters to format
   234      * @param quote     <code>true</code> to always format with quoted values,
   235      *                  <code>false</code> to use quotes only when necessary
   236      * @param formatter         the formatter to use, or <code>null</code>
   237      *                          for the {@link #DEFAULT default}
   238      *
   239      * @return  the formatted parameters
   240      */
   241     public final static
   242         String formatParameters(final NameValuePair[] nvps,
   243                                 final boolean quote,
   244                                 HeaderValueFormatter formatter) {
   245         if (formatter == null)
   246             formatter = BasicHeaderValueFormatter.DEFAULT;
   247         return formatter.formatParameters(null, nvps, quote).toString();
   248     }
   251     // non-javadoc, see interface HeaderValueFormatter
   252     public CharArrayBuffer formatParameters(CharArrayBuffer buffer,
   253                                             NameValuePair[] nvps,
   254                                             boolean quote) {
   255         if (nvps == null) {
   256             throw new IllegalArgumentException
   257                 ("Parameters must not be null.");
   258         }
   260         int len = estimateParametersLen(nvps);
   261         if (buffer == null) {
   262             buffer = new CharArrayBuffer(len);
   263         } else {
   264             buffer.ensureCapacity(len);
   265         }
   267         for (int i = 0; i < nvps.length; i++) {
   268             if (i > 0) {
   269                 buffer.append("; ");
   270             }
   271             formatNameValuePair(buffer, nvps[i], quote);
   272         }
   274         return buffer;
   275     }
   278     /**
   279      * Estimates the length of formatted parameters.
   280      *
   281      * @param nvps      the parameters to format, or <code>null</code>
   282      *
   283      * @return  a length estimate, in number of characters
   284      */
   285     protected int estimateParametersLen(final NameValuePair[] nvps) {
   286         if ((nvps == null) || (nvps.length < 1))
   287             return 0;
   289         int result = (nvps.length-1) * 2; // "; " between the parameters
   290         for (int i=0; i<nvps.length; i++) {
   291             result += estimateNameValuePairLen(nvps[i]);
   292         }
   294         return result;
   295     }
   298     /**
   299      * Formats a name-value pair.
   300      *
   301      * @param nvp       the name-value pair to format
   302      * @param quote     <code>true</code> to always format with a quoted value,
   303      *                  <code>false</code> to use quotes only when necessary
   304      * @param formatter         the formatter to use, or <code>null</code>
   305      *                          for the {@link #DEFAULT default}
   306      *
   307      * @return  the formatted name-value pair
   308      */
   309     public final static
   310         String formatNameValuePair(final NameValuePair nvp,
   311                                    final boolean quote,
   312                                    HeaderValueFormatter formatter) {
   313         if (formatter == null)
   314             formatter = BasicHeaderValueFormatter.DEFAULT;
   315         return formatter.formatNameValuePair(null, nvp, quote).toString();
   316     }
   319     // non-javadoc, see interface HeaderValueFormatter
   320     public CharArrayBuffer formatNameValuePair(CharArrayBuffer buffer,
   321                                                final NameValuePair nvp,
   322                                                final boolean quote) {
   323         if (nvp == null) {
   324             throw new IllegalArgumentException
   325                 ("NameValuePair must not be null.");
   326         }
   328         int len = estimateNameValuePairLen(nvp);
   329         if (buffer == null) {
   330             buffer = new CharArrayBuffer(len);
   331         } else {
   332             buffer.ensureCapacity(len);
   333         }
   335         buffer.append(nvp.getName());
   336         final String value = nvp.getValue();
   337         if (value != null) {
   338             buffer.append('=');
   339             doFormatValue(buffer, value, quote);
   340         }
   342         return buffer;
   343     }
   346     /**
   347      * Estimates the length of a formatted name-value pair.
   348      *
   349      * @param nvp       the name-value pair to format, or <code>null</code>
   350      *
   351      * @return  a length estimate, in number of characters
   352      */
   353     protected int estimateNameValuePairLen(final NameValuePair nvp) {
   354         if (nvp == null)
   355             return 0;
   357         int result = nvp.getName().length(); // name
   358         final String value = nvp.getValue();
   359         if (value != null) {
   360             // assume quotes, but no escaped characters
   361             result += 3 + value.length(); // ="value"
   362         }
   363         return result;
   364     }
   367     /**
   368      * Actually formats the value of a name-value pair.
   369      * This does not include a leading = character.
   370      * Called from {@link #formatNameValuePair formatNameValuePair}.
   371      *
   372      * @param buffer    the buffer to append to, never <code>null</code>
   373      * @param value     the value to append, never <code>null</code>
   374      * @param quote     <code>true</code> to always format with quotes,
   375      *                  <code>false</code> to use quotes only when necessary
   376      */
   377     protected void doFormatValue(final CharArrayBuffer buffer,
   378                                  final String value,
   379                                  boolean quote) {
   381         if (!quote) {
   382             for (int i = 0; (i < value.length()) && !quote; i++) {
   383                 quote = isSeparator(value.charAt(i));
   384             }
   385         }
   387         if (quote) {
   388             buffer.append('"');
   389         }
   390         for (int i = 0; i < value.length(); i++) {
   391             char ch = value.charAt(i);
   392             if (isUnsafe(ch)) {
   393                 buffer.append('\\');
   394             }
   395             buffer.append(ch);
   396         }
   397         if (quote) {
   398             buffer.append('"');
   399         }
   400     }
   403     /**
   404      * Checks whether a character is a {@link #SEPARATORS separator}.
   405      *
   406      * @param ch        the character to check
   407      *
   408      * @return  <code>true</code> if the character is a separator,
   409      *          <code>false</code> otherwise
   410      */
   411     protected boolean isSeparator(char ch) {
   412         return SEPARATORS.indexOf(ch) >= 0;
   413     }
   416     /**
   417      * Checks whether a character is {@link #UNSAFE_CHARS unsafe}.
   418      *
   419      * @param ch        the character to check
   420      *
   421      * @return  <code>true</code> if the character is unsafe,
   422      *          <code>false</code> otherwise
   423      */
   424     protected boolean isUnsafe(char ch) {
   425         return UNSAFE_CHARS.indexOf(ch) >= 0;
   426     }
   429 } // class BasicHeaderValueFormatter

mercurial