Home | History | Annotate | Download | only in message
      1 /*
      2  * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicHeaderElementIterator.java $
      3  * $Revision: 592088 $
      4  * $Date: 2007-11-05 09:03:39 -0800 (Mon, 05 Nov 2007) $
      5  *
      6  * ====================================================================
      7  * Licensed to the Apache Software Foundation (ASF) under one
      8  * or more contributor license agreements.  See the NOTICE file
      9  * distributed with this work for additional information
     10  * regarding copyright ownership.  The ASF licenses this file
     11  * to you under the Apache License, Version 2.0 (the
     12  * "License"); you may not use this file except in compliance
     13  * with the License.  You may obtain a copy of the License at
     14  *
     15  *   http://www.apache.org/licenses/LICENSE-2.0
     16  *
     17  * Unless required by applicable law or agreed to in writing,
     18  * software distributed under the License is distributed on an
     19  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
     20  * KIND, either express or implied.  See the License for the
     21  * specific language governing permissions and limitations
     22  * under the License.
     23  * ====================================================================
     24  *
     25  * This software consists of voluntary contributions made by many
     26  * individuals on behalf of the Apache Software Foundation.  For more
     27  * information on the Apache Software Foundation, please see
     28  * <http://www.apache.org/>.
     29  *
     30  */
     31 
     32 package org.apache.http.message;
     33 
     34 import java.util.NoSuchElementException;
     35 
     36 import org.apache.http.FormattedHeader;
     37 import org.apache.http.Header;
     38 import org.apache.http.HeaderElement;
     39 import org.apache.http.HeaderElementIterator;
     40 import org.apache.http.HeaderIterator;
     41 import org.apache.http.util.CharArrayBuffer;
     42 
     43 /**
     44  * Basic implementation of a {@link HeaderElementIterator}.
     45  *
     46  * @version $Revision: 592088 $
     47  *
     48  * @author Andrea Selva <selva.andre at gmail.com>
     49  * @author Oleg Kalnichevski <oleg at ural.ru>
     50  */
     51 public class BasicHeaderElementIterator implements HeaderElementIterator {
     52 
     53     private final HeaderIterator headerIt;
     54     private final HeaderValueParser parser;
     55 
     56     private HeaderElement currentElement = null;
     57     private CharArrayBuffer buffer = null;
     58     private ParserCursor cursor = null;
     59 
     60     /**
     61      * Creates a new instance of BasicHeaderElementIterator
     62      */
     63     public BasicHeaderElementIterator(
     64             final HeaderIterator headerIterator,
     65             final HeaderValueParser parser) {
     66         if (headerIterator == null) {
     67             throw new IllegalArgumentException("Header iterator may not be null");
     68         }
     69         if (parser == null) {
     70             throw new IllegalArgumentException("Parser may not be null");
     71         }
     72         this.headerIt = headerIterator;
     73         this.parser = parser;
     74     }
     75 
     76 
     77     public BasicHeaderElementIterator(final HeaderIterator headerIterator) {
     78         this(headerIterator, BasicHeaderValueParser.DEFAULT);
     79     }
     80 
     81 
     82     private void bufferHeaderValue() {
     83         this.cursor = null;
     84         this.buffer = null;
     85         while (this.headerIt.hasNext()) {
     86             Header h = this.headerIt.nextHeader();
     87             if (h instanceof FormattedHeader) {
     88                 this.buffer = ((FormattedHeader) h).getBuffer();
     89                 this.cursor = new ParserCursor(0, this.buffer.length());
     90                 this.cursor.updatePos(((FormattedHeader) h).getValuePos());
     91                 break;
     92             } else {
     93                 String value = h.getValue();
     94                 if (value != null) {
     95                     this.buffer = new CharArrayBuffer(value.length());
     96                     this.buffer.append(value);
     97                     this.cursor = new ParserCursor(0, this.buffer.length());
     98                     break;
     99                 }
    100             }
    101         }
    102     }
    103 
    104     private void parseNextElement() {
    105         // loop while there are headers left to parse
    106         while (this.headerIt.hasNext() || this.cursor != null) {
    107             if (this.cursor == null || this.cursor.atEnd()) {
    108                 // get next header value
    109                 bufferHeaderValue();
    110             }
    111             // Anything buffered?
    112             if (this.cursor != null) {
    113                 // loop while there is data in the buffer
    114                 while (!this.cursor.atEnd()) {
    115                     HeaderElement e = this.parser.parseHeaderElement(this.buffer, this.cursor);
    116                     if (!(e.getName().length() == 0 && e.getValue() == null)) {
    117                         // Found something
    118                         this.currentElement = e;
    119                         return;
    120                     }
    121                 }
    122                 // if at the end of the buffer
    123                 if (this.cursor.atEnd()) {
    124                     // discard it
    125                     this.cursor = null;
    126                     this.buffer = null;
    127                 }
    128             }
    129         }
    130     }
    131 
    132     public boolean hasNext() {
    133         if (this.currentElement == null) {
    134             parseNextElement();
    135         }
    136         return this.currentElement != null;
    137     }
    138 
    139     public HeaderElement nextElement() throws NoSuchElementException {
    140         if (this.currentElement == null) {
    141             parseNextElement();
    142         }
    143 
    144         if (this.currentElement == null) {
    145             throw new NoSuchElementException("No more header elements available");
    146         }
    147 
    148         HeaderElement element = this.currentElement;
    149         this.currentElement = null;
    150         return element;
    151     }
    152 
    153     public final Object next() throws NoSuchElementException {
    154         return nextElement();
    155     }
    156 
    157     public void remove() throws UnsupportedOperationException {
    158         throw new UnsupportedOperationException("Remove not supported");
    159     }
    160 
    161 }