001/* 002 * ==================================================================== 003 * Licensed to the Apache Software Foundation (ASF) under one 004 * or more contributor license agreements. See the NOTICE file 005 * distributed with this work for additional information 006 * regarding copyright ownership. The ASF licenses this file 007 * to you under the Apache License, Version 2.0 (the 008 * "License"); you may not use this file except in compliance 009 * with the License. You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, 014 * software distributed under the License is distributed on an 015 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 016 * KIND, either express or implied. See the License for the 017 * specific language governing permissions and limitations 018 * under the License. 019 * ==================================================================== 020 * 021 * This software consists of voluntary contributions made by many 022 * individuals on behalf of the Apache Software Foundation. For more 023 * information on the Apache Software Foundation, please see 024 * <http://www.apache.org/>. 025 * 026 */ 027 028package org.apache.http.message; 029 030import java.io.Serializable; 031 032import org.apache.http.FormattedHeader; 033import org.apache.http.HeaderElement; 034import org.apache.http.ParseException; 035import org.apache.http.util.Args; 036import org.apache.http.util.CharArrayBuffer; 037 038/** 039 * This class represents a raw HTTP header whose content is parsed 'on demand' 040 * only when the header value needs to be consumed. 041 * 042 * @since 4.0 043 */ 044public class BufferedHeader implements FormattedHeader, Cloneable, Serializable { 045 046 private static final long serialVersionUID = -2768352615787625448L; 047 048 /** 049 * Header name. 050 */ 051 private final String name; 052 053 /** 054 * The buffer containing the entire header line. 055 */ 056 private final CharArrayBuffer buffer; 057 058 /** 059 * The beginning of the header value in the buffer 060 */ 061 private final int valuePos; 062 063 064 /** 065 * Creates a new header from a buffer. 066 * The name of the header will be parsed immediately, 067 * the value only if it is accessed. 068 * 069 * @param buffer the buffer containing the header to represent 070 * 071 * @throws ParseException in case of a parse error 072 */ 073 public BufferedHeader(final CharArrayBuffer buffer) 074 throws ParseException { 075 076 super(); 077 Args.notNull(buffer, "Char array buffer"); 078 final int colon = buffer.indexOf(':'); 079 if (colon == -1) { 080 throw new ParseException 081 ("Invalid header: " + buffer.toString()); 082 } 083 final String s = buffer.substringTrimmed(0, colon); 084 if (s.length() == 0) { 085 throw new ParseException 086 ("Invalid header: " + buffer.toString()); 087 } 088 this.buffer = buffer; 089 this.name = s; 090 this.valuePos = colon + 1; 091 } 092 093 094 @Override 095 public String getName() { 096 return this.name; 097 } 098 099 @Override 100 public String getValue() { 101 return this.buffer.substringTrimmed(this.valuePos, this.buffer.length()); 102 } 103 104 @Override 105 public HeaderElement[] getElements() throws ParseException { 106 final ParserCursor cursor = new ParserCursor(0, this.buffer.length()); 107 cursor.updatePos(this.valuePos); 108 return BasicHeaderValueParser.INSTANCE.parseElements(this.buffer, cursor); 109 } 110 111 @Override 112 public int getValuePos() { 113 return this.valuePos; 114 } 115 116 @Override 117 public CharArrayBuffer getBuffer() { 118 return this.buffer; 119 } 120 121 @Override 122 public String toString() { 123 return this.buffer.toString(); 124 } 125 126 @Override 127 public Object clone() throws CloneNotSupportedException { 128 // buffer is considered immutable 129 // no need to make a copy of it 130 return super.clone(); 131 } 132 133}