diff options
author | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
---|---|---|
committer | upstream source tree <ports@midipix.org> | 2015-03-15 20:14:05 -0400 |
commit | 554fd8c5195424bdbcabf5de30fdc183aba391bd (patch) | |
tree | 976dc5ab7fddf506dadce60ae936f43f58787092 /libjava/classpath/gnu/java/net/protocol/http/Headers.java | |
download | cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.bz2 cbb-gcc-4.6.4-554fd8c5195424bdbcabf5de30fdc183aba391bd.tar.xz |
obtained gcc-4.6.4.tar.bz2 from upstream website;upstream
verified gcc-4.6.4.tar.bz2.sig;
imported gcc-4.6.4 source tree from verified upstream tarball.
downloading a git-generated archive based on the 'upstream' tag
should provide you with a source tree that is binary identical
to the one extracted from the above tarball.
if you have obtained the source via the command 'git clone',
however, do note that line-endings of files in your working
directory might differ from line-endings of the respective
files in the upstream repository.
Diffstat (limited to 'libjava/classpath/gnu/java/net/protocol/http/Headers.java')
-rw-r--r-- | libjava/classpath/gnu/java/net/protocol/http/Headers.java | 424 |
1 files changed, 424 insertions, 0 deletions
diff --git a/libjava/classpath/gnu/java/net/protocol/http/Headers.java b/libjava/classpath/gnu/java/net/protocol/http/Headers.java new file mode 100644 index 000000000..faf5eb195 --- /dev/null +++ b/libjava/classpath/gnu/java/net/protocol/http/Headers.java @@ -0,0 +1,424 @@ +/* Headers.java -- + Copyright (C) 2004, 2006 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +02110-1301 USA. + +Linking this library statically or dynamically with other modules is +making a combined work based on this library. Thus, the terms and +conditions of the GNU General Public License cover the whole +combination. + +As a special exception, the copyright holders of this library give you +permission to link this library with independent modules to produce an +executable, regardless of the license terms of these independent +modules, and to copy and distribute the resulting executable under +terms of your choice, provided that you also meet, for each linked +independent module, the terms and conditions of the license of that +module. An independent module is a module which is not derived from +or based on this library. If you modify this library, you may extend +this exception to your version of the library, but you are not +obligated to do so. If you do not wish to do so, delete this +exception statement from your version. */ + + +package gnu.java.net.protocol.http; + +import gnu.java.lang.CPStringBuilder; + +import gnu.java.net.LineInputStream; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.Iterable; +import java.text.DateFormat; +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * A collection of HTTP header names and associated values. The + * values are {@link ArrayList ArrayLists} of Strings. Retrieval of + * values is case insensitive. An iteration over the collection + * returns the header names in the order they were received. + * + * @author Chris Burdess (dog@gnu.org) + * @author David Daney (ddaney@avtrex.com) + */ +class Headers implements Iterable<Headers.HeaderElement> +{ + /** + * A list of HeaderElements + */ + private final ArrayList<HeaderElement> headers + = new ArrayList<HeaderElement>(); + + /** + * The HTTP dateformat used to parse date header fields. + */ + private static final DateFormat dateFormat = new HTTPDateFormat(); + + /** + * Class for a Header element consisting of + * a name and value String. + */ + static class HeaderElement + { + String name; + String value; + + HeaderElement(String name, String value) + { + this.name = name; + this.value = value; + } + } + + /** + * Default constructor. + */ + public Headers() + { + // nothing to do + } + + /** + * Return an Iterator over this collection of headers. + * Iterator.getNext() returns objects of type {@link HeaderElement}. + * + * @return the Iterator. + */ + public Iterator<HeaderElement> iterator() + { + return headers.iterator(); + } + + /** + * Returns the value of the specified header as a string. If + * multiple values are present, the last one is returned. + * + * @param header the header name (case insensitive search) + * @return The header value or <code>null</code> if not found. + */ + public String getValue(String header) + { + for (int i = headers.size() - 1; i >= 0; i--) + { + HeaderElement e = headers.get(i); + if (e.name.equalsIgnoreCase(header)) + { + return e.value; + } + } + return null; + } + + /** + * Returns the value of the specified header as an integer. If + * multiple values are present, the last one is returned. + * + * @param header the header name (case insensitive search) + * @return The header value or <code>-1</code> if not present or + * not an integer value. + */ + public int getIntValue(String header) + { + String val = getValue(header); + if (val == null) + { + return -1; + } + try + { + return Integer.parseInt(val); + } + catch (NumberFormatException e) + { + // fall through + } + return -1; + } + + /** + * Returns the value of the specified header as a long. If + * multiple values are present, the last one is returned. + * + * @param header the header name (case insensitive search) + * @return The header value or <code>-1</code> if not present or + * not a long value. + */ + public long getLongValue(String header) + { + String val = getValue(header); + if (val == null) + { + return -1; + } + try + { + return Long.parseLong(val); + } + catch (NumberFormatException e) + { + // fall through + } + return -1; + } + + /** + * Returns the value of the specified header as a date. If + * multiple values are present, the last one is returned. + * + * @param header the header name (case insensitive search) + * @return The header value or <code>null</code> if not present or + * not a date value. + */ + public Date getDateValue(String header) + { + String val = getValue(header); + if (val == null) + { + return null; + } + try + { + return dateFormat.parse(val); + } + catch (ParseException e) + { + return null; + } + } + + /** + * Add a header to this set of headers. If there is an existing + * header with the same name it's value is replaced with the new value. + * If multiple headers of the same name exist only the last one's value + * is replaced. + * + * @param name the header name + * @param value the header value + * + * @see #addValue(String, String) + */ + public void put(String name, String value) + { + for (int i = headers.size() - 1; i >= 0; i--) + { + HeaderElement e = headers.get(i); + if (e.name.equalsIgnoreCase(name)) + { + e.value = value; + return; + } + } + + // nothing was replaced so add it as new HeaderElement + addValue(name, value); + } + + /** + * Add all headers from a set of headers to this set. Any existing header + * with the same (case insensitive) name as one of the new headers will + * be overridden. + * + * @param o the headers to be added + */ + public void putAll(Headers o) + { + for (Iterator<HeaderElement> it = o.iterator(); it.hasNext(); ) + { + HeaderElement e = it.next(); + remove(e.name); + addValue(e.name, e.value); + } + } + + /** + * Remove a header from this set of headers. If there is more than + * one instance of a header of the given name, they are all removed. + * + * @param name the header name + */ + public void remove(String name) + { + for (Iterator<HeaderElement> it = headers.iterator(); it.hasNext(); ) + { + HeaderElement e = it.next(); + if (e.name.equalsIgnoreCase(name)) + it.remove(); + } + } + + /** + * Parse the specified InputStream, adding headers to this collection. + * + * @param in the InputStream. + * @throws IOException if I/O error occured. + */ + public void parse(InputStream in) + throws IOException + { + LineInputStream lin = (in instanceof LineInputStream) ? + (LineInputStream) in : new LineInputStream(in); + + String name = null; + CPStringBuilder value = new CPStringBuilder(); + while (true) + { + String line = lin.readLine(); + if (line == null) + { + if (name != null) + { + addValue(name, value.toString()); + } + break; + } + int len = line.length(); + if (len < 2) + { + if (name != null) + { + addValue(name, value.toString()); + } + break; + } + char c1 = line.charAt(0); + if (c1 == ' ' || c1 == '\t') + { + // Continuation + int last = len - 1; + if (line.charAt(last) != '\r') + ++last; + value.append(line.substring(0, last)); + } + else + { + if (name != null) + { + addValue(name, value.toString()); + } + + int di = line.indexOf(':'); + name = line.substring(0, di); + value.setLength(0); + do + { + di++; + } + while (di < len && line.charAt(di) == ' '); + int last = len - 1; + if (line.charAt(last) != '\r') + ++last; + value.append(line.substring(di, last)); + } + } + } + + + /** + * Add a header to this set of headers. If there is an existing + * header with the same name, it is not effected. + * + * @param name the header name + * @param value the header value + * + * @see #put(String, String) + */ + public void addValue(String name, String value) + { + headers.add(headers.size(), new HeaderElement(name, value)); + } + + /** + * Get a new Map containing all the headers. The keys of the Map + * are Strings (the header names). The headers will be included + * case-sensitive in the map so that querying must be done with the + * correct case of the needed header name. The values of the Map are + * unmodifiable Lists containing Strings (the header values). + * + * <p> + * The returned map is modifiable. Changing it will not effect this + * collection of Headers in any way.</p> + * + * @return a Map containing all the headers. + */ + public Map<String,List<String>> getAsMap() + { + LinkedHashMap<String,List<String>> m = new LinkedHashMap<String,List<String>>(); + for (Iterator<HeaderElement> it = headers.iterator(); it.hasNext(); ) + { + HeaderElement e = it.next(); + ArrayList<String> l = (ArrayList<String>)m.get(e.name); + if (l == null) + { + l = new ArrayList<String>(1); + l.add(e.value); + m.put(e.name, l); + } + else + l.add(0, e.value); + } + for (Iterator<Map.Entry<String,List<String>>> it = m.entrySet().iterator(); it.hasNext(); ) + { + Map.Entry<String,List<String>> me = it.next(); + List<String> l = me.getValue(); + me.setValue(Collections.unmodifiableList(l)); + } + return m; + } + + /** + * Get the name of the Nth header. + * + * @param i the header index. + * + * @return The header name, or <code>null</code> if index outside of range. + * + * @see #getHeaderValue(int) + */ + public String getHeaderName(int i) + { + if (i >= headers.size() || i < 0) + return null; + + return headers.get(i).name; + } + + /** + * Get the value of the Nth header. + * + * @param i the header index. + * + * @return the header value, or <code>null</code> if index outside of range. + * + * @see #getHeaderName(int) + */ + public String getHeaderValue(int i) + { + if (i >= headers.size() || i < 0) + return null; + + return headers.get(i).value; + } +} |