You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2007/11/05 18:03:40 UTC
svn commit: r592088 - in
/jakarta/httpcomponents/httpcore/trunk/module-main/src:
main/java/org/apache/http/message/ test/java/org/apache/http/message/
Author: olegk
Date: Mon Nov 5 09:03:39 2007
New Revision: 592088
URL: http://svn.apache.org/viewvc?rev=592088&view=rev
Log:
* BasicHeaderElementIterator now takes any arbitrary HeaderValueParser as an optional parameter
* Implemented lazy parsing of header elements
Modified:
jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicHeaderElementIterator.java
jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/ParserCursor.java
jakarta/httpcomponents/httpcore/trunk/module-main/src/test/java/org/apache/http/message/TestBasicHeaderElementIterator.java
Modified: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicHeaderElementIterator.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicHeaderElementIterator.java?rev=592088&r1=592087&r2=592088&view=diff
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicHeaderElementIterator.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/BasicHeaderElementIterator.java Mon Nov 5 09:03:39 2007
@@ -32,9 +32,13 @@
package org.apache.http.message;
import java.util.NoSuchElementException;
+
+import org.apache.http.FormattedHeader;
+import org.apache.http.Header;
import org.apache.http.HeaderElement;
import org.apache.http.HeaderElementIterator;
import org.apache.http.HeaderIterator;
+import org.apache.http.util.CharArrayBuffer;
/**
* Basic implementation of a {@link HeaderElementIterator}.
@@ -42,64 +46,108 @@
* @version $Revision$
*
* @author Andrea Selva <selva.andre at gmail.com>
+ * @author Oleg Kalnichevski <oleg at ural.ru>
*/
public class BasicHeaderElementIterator implements HeaderElementIterator {
private final HeaderIterator headerIt;
-
- private int currentElementIdx = -1;
-
- private HeaderElement[] currentElements = null;
+ private final HeaderValueParser parser;
private HeaderElement currentElement = null;
+ private CharArrayBuffer buffer = null;
+ private ParserCursor cursor = null;
/**
* Creates a new instance of BasicHeaderElementIterator
*/
- public BasicHeaderElementIterator(final HeaderIterator headerIterator) {
+ public BasicHeaderElementIterator(
+ final HeaderIterator headerIterator,
+ final HeaderValueParser parser) {
if (headerIterator == null) {
throw new IllegalArgumentException("Header iterator may not be null");
}
+ if (parser == null) {
+ throw new IllegalArgumentException("Parser may not be null");
+ }
this.headerIt = headerIterator;
-
- if (this.headerIt.hasNext()) {
- this.currentElementIdx = 0;
- this.currentElements = this.headerIt.nextHeader().getElements();
- this.currentElement = findNext();
- }
+ this.parser = parser;
}
+
+ public BasicHeaderElementIterator(final HeaderIterator headerIterator) {
+ this(headerIterator, BasicHeaderValueParser.DEFAULT);
+ }
- protected HeaderElement findNext() {
- HeaderElement tmpHeader;
-
- if (this.currentElementIdx == this.currentElements.length) {
- if (!this.headerIt.hasNext()) {
- return null;
+
+ private void bufferHeaderValue() {
+ this.cursor = null;
+ this.buffer = null;
+ while (this.headerIt.hasNext()) {
+ Header h = this.headerIt.nextHeader();
+ if (h instanceof FormattedHeader) {
+ this.buffer = ((FormattedHeader) h).getBuffer();
+ this.cursor = new ParserCursor(0, this.buffer.length());
+ this.cursor.updatePos(((FormattedHeader) h).getValuePos());
+ break;
+ } else {
+ String value = h.getValue();
+ if (value != null) {
+ this.buffer = new CharArrayBuffer(value.length());
+ this.buffer.append(value);
+ this.cursor = new ParserCursor(0, this.buffer.length());
+ break;
+ }
}
- this.currentElements = this.headerIt.nextHeader().getElements();
- this.currentElementIdx = 0;
}
+ }
- tmpHeader = this.currentElements[this.currentElementIdx++];
- return tmpHeader;
-
+ private void parseNextElement() {
+ // loop while there are headers left to parse
+ while (this.headerIt.hasNext() || this.cursor != null) {
+ if (this.cursor == null || this.cursor.atEnd()) {
+ // get next header value
+ bufferHeaderValue();
+ }
+ // Anything buffered?
+ if (this.cursor != null) {
+ // loop while there is data in the buffer
+ while (!this.cursor.atEnd()) {
+ HeaderElement e = this.parser.parseHeaderElement(this.buffer, this.cursor);
+ if (!(e.getName().length() == 0 && e.getValue() == null)) {
+ // Found something
+ this.currentElement = e;
+ return;
+ }
+ }
+ // if at the end of the buffer
+ if (this.cursor.atEnd()) {
+ // discard it
+ this.cursor = null;
+ this.buffer = null;
+ }
+ }
+ }
}
public boolean hasNext() {
- return (this.currentElement != null);
+ if (this.currentElement == null) {
+ parseNextElement();
+ }
+ return this.currentElement != null;
}
public HeaderElement nextElement() throws NoSuchElementException {
-
- final HeaderElement current = this.currentElement;
- if (current == null) {
- throw new NoSuchElementException("Iteration already finished.");
+ if (this.currentElement == null) {
+ parseNextElement();
}
- this.currentElement = findNext();
+ if (this.currentElement == null) {
+ throw new NoSuchElementException("No more header elements available");
+ }
- return current;
+ HeaderElement element = this.currentElement;
+ this.currentElement = null;
+ return element;
}
public final Object next() throws NoSuchElementException {
Modified: jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/ParserCursor.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/ParserCursor.java?rev=592088&r1=592087&r2=592088&view=diff
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/ParserCursor.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-main/src/main/java/org/apache/http/message/ParserCursor.java Mon Nov 5 09:03:39 2007
@@ -58,7 +58,7 @@
}
this.lowerBound = lowerBound;
this.upperBound = upperBound;
- this.pos = 0;
+ this.pos = lowerBound;
}
public int getLowerBound() {
Modified: jakarta/httpcomponents/httpcore/trunk/module-main/src/test/java/org/apache/http/message/TestBasicHeaderElementIterator.java
URL: http://svn.apache.org/viewvc/jakarta/httpcomponents/httpcore/trunk/module-main/src/test/java/org/apache/http/message/TestBasicHeaderElementIterator.java?rev=592088&r1=592087&r2=592088&view=diff
==============================================================================
--- jakarta/httpcomponents/httpcore/trunk/module-main/src/test/java/org/apache/http/message/TestBasicHeaderElementIterator.java (original)
+++ jakarta/httpcomponents/httpcore/trunk/module-main/src/test/java/org/apache/http/message/TestBasicHeaderElementIterator.java Mon Nov 5 09:03:39 2007
@@ -1,5 +1,7 @@
package org.apache.http.message;
+import java.util.NoSuchElementException;
+
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
@@ -43,14 +45,34 @@
};
HeaderElementIterator hei =
- new BasicHeaderElementIterator(new BasicHeaderIterator(headers, "Name"));
+ new BasicHeaderElementIterator(
+ new BasicHeaderIterator(headers, "Name"));
+ assertTrue(hei.hasNext());
HeaderElement elem = (HeaderElement) hei.next();
assertEquals("The two header values must be equal",
"value0", elem.getName());
+
+ assertTrue(hei.hasNext());
elem = (HeaderElement)hei.next();
assertEquals("The two header values must be equal",
"value1", elem.getName());
+
+ assertFalse(hei.hasNext());
+ try {
+ hei.next();
+ fail("NoSuchElementException should have been thrown");
+ } catch (NoSuchElementException ex) {
+ // expected
+ }
+
+ assertFalse(hei.hasNext());
+ try {
+ hei.next();
+ fail("NoSuchElementException should have been thrown");
+ } catch (NoSuchElementException ex) {
+ // expected
+ }
}
public void testMultiHeaderSameLine() {
@@ -79,6 +101,34 @@
"cookie2", elem.getName());
assertEquals("The two header values must be equal",
"2", elem.getValue());
+ }
+
+ public void testFringeCases() {
+ Header[] headers = new Header[]{
+ new BasicHeader("Name", null),
+ new BasicHeader("Name", " "),
+ new BasicHeader("Name", ",,,")
+ };
+
+ HeaderElementIterator hei =
+ new BasicHeaderElementIterator(
+ new BasicHeaderIterator(headers, "Name"));
+
+ assertFalse(hei.hasNext());
+ try {
+ hei.next();
+ fail("NoSuchElementException should have been thrown");
+ } catch (NoSuchElementException ex) {
+ // expected
+ }
+
+ assertFalse(hei.hasNext());
+ try {
+ hei.next();
+ fail("NoSuchElementException should have been thrown");
+ } catch (NoSuchElementException ex) {
+ // expected
+ }
}
}