+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.apache.tomcat.util.collections;
-
-import org.apache.tomcat.util.buf.MessageBytes;
-
-// Originally MimeHeaders
-
-/**
- * An efficient representation for certain type of map. The keys
- * can have a single or multi values, but most of the time there are
- * single values.
- *
- * The data is of "MessageBytes" type, meaning bytes[] that can be
- * converted to Strings ( if needed, and encoding is lazy-binded ).
- *
- * This is a base class for MimeHeaders, Parameters and Cookies.
- *
- * Data structures: each field is a single-valued key/value.
- * The fields are allocated when needed, and are recycled.
- * The current implementation does linear search, in future we'll
- * also use the hashkey.
- *
- * @author dac@eng.sun.com
- * @author James Todd [gonzo@eng.sun.com]
- * @author Costin Manolache
- */
-public class MultiMap {
-
- protected Field[] fields;
- // fields in use
- protected int count;
-
- /**
- *
- */
- public MultiMap(int initial_size) {
- fields=new Field[initial_size];
- }
-
- /**
- * Clears all header fields.
- */
- public void recycle() {
- for (int i = 0; i < count; i++) {
- fields[i].recycle();
- }
- count = 0;
- }
-
- // -------------------- Idx access to headers ----------
- // This allows external iterators.
-
- /**
- * Returns the current number of header fields.
- */
- public int size() {
- return count;
- }
-
- /**
- * Returns the Nth header name
- * This may be used to iterate through all header fields.
- *
- * An exception is thrown if the index is not valid ( <0 or >size )
- */
- public MessageBytes getName(int n) {
- // n >= 0 && n < count ? headers[n].getName() : null
- return fields[n].name;
- }
-
- /**
- * Returns the Nth header value
- * This may be used to iterate through all header fields.
- */
- public MessageBytes getValue(int n) {
- return fields[n].value;
- }
-
- /** Find the index of a field with the given name.
- */
- public int find( String name, int starting ) {
- // We can use a hash - but it's not clear how much
- // benefit you can get - there is an overhead
- // and the number of headers is small (4-5 ?)
- // Another problem is that we'll pay the overhead
- // of constructing the hashtable
-
- // A custom search tree may be better
- for (int i = starting; i < count; i++) {
- if (fields[i].name.equals(name)) {
- return i;
- }
- }
- return -1;
- }
-
- /** Find the index of a field with the given name.
- */
- public int findIgnoreCase( String name, int starting ) {
- // We can use a hash - but it's not clear how much
- // benefit you can get - there is an overhead
- // and the number of headers is small (4-5 ?)
- // Another problem is that we'll pay the overhead
- // of constructing the hashtable
-
- // A custom search tree may be better
- for (int i = starting; i < count; i++) {
- if (fields[i].name.equalsIgnoreCase(name)) {
- return i;
- }
- }
- return -1;
- }
-
- /**
- * Removes the field at the specified position.
- *
- * MultiMap will preserve the order of field add unless remove()
- * is called. This is not thread-safe, and will invalidate all
- * iterators.
- *
- * This is not a frequent operation for Headers and Parameters -
- * there are better ways ( like adding a "isValid" field )
- */
- public void remove( int i ) {
- // reset and swap with last header
- Field mh = fields[i];
- // reset the field
- mh.recycle();
-
- fields[i] = fields[count - 1];
- fields[count - 1] = mh;
- count--;
- }
-
- /** Create a new, uninitialized entry.
- */
- public int addField() {
- int len = fields.length;
- int pos=count;
- if (count >= len) {
- // expand header list array
- Field tmp[] = new Field[pos * 2];
- System.arraycopy(fields, 0, tmp, 0, len);
- fields = tmp;
- }
- if (fields[pos] == null) {
- fields[pos] = new Field();
- }
- count++;
- return pos;
- }
-
- public MessageBytes get( String name) {
- for (int i = 0; i < count; i++) {
- if (fields[i].name.equals(name)) {
- return fields[i].value;
- }
- }
- return null;
- }
-
- public int findFirst( String name ) {
- for (int i = 0; i < count; i++) {
- if (fields[i].name.equals(name)) {
- return i;
- }
- }
- return -1;
- }
-
- public int findNext( int startPos ) {
- int next= fields[startPos].nextPos;
- if( next != MultiMap.NEED_NEXT ) {
- return next;
- }
-
- // next==NEED_NEXT, we never searched for this header
- MessageBytes name=fields[startPos].name;
- for (int i = startPos; i < count; i++) {
- if (fields[i].name.equals(name)) {
- // cache the search result
- fields[startPos].nextPos=i;
- return i;
- }
- }
- fields[startPos].nextPos= MultiMap.LAST;
- return -1;
- }
-
- // workaround for JDK1.1.8/solaris
- static final int NEED_NEXT=-2;
- static final int LAST=-1;
-
- // -------------------- Internal representation --------------------
- final class Field {
- MessageBytes name;
- MessageBytes value;
-
- // Extra info for speed
-
- // multiple fields with same name - a linked list will
- // speed up multiple name enumerations and search.
- int nextPos;
-
- // hashkey
- int hash;
- Field nextSameHash;
-
- Field() {
- nextPos=MultiMap.NEED_NEXT;
- }
-
- void recycle() {
- name.recycle();
- value.recycle();
- nextPos=MultiMap.NEED_NEXT;
- }
- }
-}
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.apache.tomcat.util.collections;
-
-import java.util.Enumeration;
-
-/** Enumerate the distinct header names.
- Each nextElement() is O(n) ( a comparison is
- done with all previous elements ).
-
- This is less frequent than add() -
- we want to keep add O(1).
-*/
-public final class MultiMapNamesEnumeration implements Enumeration<String> {
- int pos;
- int size;
- String next;
- MultiMap headers;
-
- // toString and unique options are not implemented -
- // we always to toString and unique.
-
- /** Create a new multi-map enumeration.
- * @param headers the collection to enumerate
- * @param toString convert each name to string
- * @param unique return only unique names
- */
- MultiMapNamesEnumeration(MultiMap headers, boolean toString,
- boolean unique) {
- this.headers=headers;
- pos=0;
- size = headers.size();
- findNext();
- }
-
- private void findNext() {
- next=null;
- for( ; pos< size; pos++ ) {
- next=headers.getName( pos ).toString();
- for( int j=0; j<pos ; j++ ) {
- if( headers.getName( j ).equalsIgnoreCase( next )) {
- // duplicate.
- next=null;
- break;
- }
- }
- if( next!=null ) {
- // it's not a duplicate
- break;
- }
- }
- // next time findNext is called it will try the
- // next element
- pos++;
- }
-
- public boolean hasMoreElements() {
- return next!=null;
- }
-
- public String nextElement() {
- String current=next;
- findNext();
- return current;
- }
-}
+++ /dev/null
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You 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.apache.tomcat.util.collections;
-
-import java.util.Enumeration;
-
-import org.apache.tomcat.util.buf.MessageBytes;
-
-/** Enumerate the values for a (possibly ) multiple
- * value element.
- */
-class MultiMapValuesEnumeration implements Enumeration<String> {
- int pos;
- int size;
- MessageBytes next;
- MultiMap headers;
- String name;
-
- MultiMapValuesEnumeration(MultiMap headers, String name,
- boolean toString) {
- this.name=name;
- this.headers=headers;
- pos=0;
- size = headers.size();
- findNext();
- }
-
- private void findNext() {
- next=null;
- for( ; pos< size; pos++ ) {
- MessageBytes n1=headers.getName( pos );
- if( n1.equalsIgnoreCase( name )) {
- next=headers.getValue( pos );
- break;
- }
- }
- pos++;
- }
-
- public boolean hasMoreElements() {
- return next!=null;
- }
-
- public String nextElement() {
- MessageBytes current=next;
- findNext();
- return current.toString();
- }
-}