Updated Branches:
  refs/heads/master b984db31f -> 83d43ab13

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/83d43ab1/lib/atscppapi/src/include/atscppapi/Headers.h
----------------------------------------------------------------------
diff --git a/lib/atscppapi/src/include/atscppapi/Headers.h 
b/lib/atscppapi/src/include/atscppapi/Headers.h
index af02707..c83c5c8 100644
--- a/lib/atscppapi/src/include/atscppapi/Headers.h
+++ b/lib/atscppapi/src/include/atscppapi/Headers.h
@@ -24,218 +24,580 @@
 #ifndef ATSCPPAPI_HEADERS_H_
 #define ATSCPPAPI_HEADERS_H_
 
-#include <map>
-#include <list>
-#include <atscppapi/CaseInsensitiveStringComparator.h>
 #include <atscppapi/noncopyable.h>
+#include <string>
 
 namespace atscppapi {
 
 struct HeadersState;
+struct HeaderFieldIteratorState;
+struct HeaderFieldState;
+struct HeaderFieldValueIteratorState;
 class Request;
 class ClientRequest;
 class Response;
 
 /**
- * @brief Encapsulates the headers portion of a request or response.
+ * @brief A HeaderFieldName is a lightweight wrapper around a string that 
allows for case insensitive comparisons.
+ * Because header field names must be case insensitive this allows easy case 
insentive comparisons of names.
+ *
  */
-class Headers: noncopyable {
+class HeaderFieldName {
+ private:
+   std::string name_;
+ public:
+   typedef std::string::size_type size_type;
+
+   /**
+    * Constructor: build a new HeaderField name with the given string
+    */
+   HeaderFieldName(const std::string &name);
+
+   /**
+    * std::string conversion
+    * @return a string which is this HeaderFieldName
+    */
+   operator std::string();
+
+   /**
+     * const char * conversion
+     * @return a const char * which is this HeaderFieldName
+     */
+   operator const char*();
+
+   /**
+    * @return the length of this HeaderFieldName
+    */
+   size_type length();
+
+   /**
+    * @return a string which is this HeaderFieldName
+    */
+   std::string str();
+
+   /**
+    * @return a const char * which points to the name of this HeaderFIeldName
+    */
+   const char *c_str();
+
+   /**
+    * Case insensitive comparison of this HeaderFieldName
+    * @return true if the two strings are equal.
+    */
+   bool operator==(const char *field_name);
+
+   /**
+     * Case insensitive comparison of this HeaderFieldName
+     * @return true if the two strings are equal.
+     */
+   bool operator==(const std::string &field_name);
+
+   /**
+     * Case insensitive comparison of this HeaderFieldName
+     * @return true if the two strings are not equal.
+     */
+   bool operator!=(const char *field_name);
+
+   /**
+     * Case insensitive comparison of this HeaderFieldName
+     * @return true if the two strings are not equal.
+     */
+   bool operator!=(const std::string &field_name);
+};
+
+class HeaderField;
+
+/**
+ * @brief A header field value iterator iterates through all header fields.
+ */
+class header_field_value_iterator : public 
std::iterator<std::forward_iterator_tag, int>
+{
+  private:
+    HeaderFieldValueIteratorState *state_;
+  public:
+    /**
+      * Constructor for header_field_value_iterator, this shouldn't need to be 
used directly.
+      * @param bufp the TSMBuffer associated with the headers
+      * @param mloc the TSMLoc associated with the headers.
+      * @param field_loc the TSMLoc assocated with the field.
+      * @param index the index of the value in the HeaderField
+      * @warning This shouldn't need to be used directly!
+      */
+    header_field_value_iterator(void *bufp, void *hdr_loc, void *field_loc, 
int index);
+
+    /**
+      * Copy Constructor for header_field_value_iterator, this shouldn't need 
to be used directly.
+      * @param header_field_value_iterator an existing iterator to copy
+      * @warning This shouldn't need to be used directly!
+      */
+    header_field_value_iterator(const header_field_value_iterator& it);
+    ~header_field_value_iterator();
+
+    /**
+     * Dereference this iterator into a string (get the value pointed to by 
this iterator)
+     * @return a string which is the value pointed to by this iterator
+     */
+    std::string operator*();
+
+    /**
+     * Advance the iterator to the next header field value
+     * @return a reference to a the next iterator
+     */
+    header_field_value_iterator& operator++();
+
+    /**
+     * Advance the current iterator to the next header field
+     * @return a new iterator which points to the next element
+     */
+    header_field_value_iterator operator++(int);
+
+    /**
+     * Compare two iterators returning true if they are equal
+     * @return true if two iterators are equal
+     */
+    bool operator==(const header_field_value_iterator& rhs) const;
+
+    /**
+     * Compare two iterators returning true if they are NOT equal
+     * @return true if two iterators are not equal.
+     */
+    bool operator!=(const header_field_value_iterator& rhs) const;
+
+    friend class HeaderField;
+};
+class header_field_iterator;
+
+/**
+ * @brief A HeaderField is a class that contains the header field name and all 
of the values.
+ * @note You may have several HeaderFields with the same name for a given set 
of Headers.
+ */
+class HeaderField {
+private:
+  HeaderFieldState *state_;
 public:
-  
-  enum Type { TYPE_REQUEST, TYPE_RESPONSE };
+  typedef unsigned int size_type;
+  typedef header_field_value_iterator iterator;
 
-  Headers(Type type = TYPE_REQUEST);
+  /**
+   * Constructor for HeaderField, this shouldn't be used directly unless 
you're trying to mix the C++ and C apis.
+   * @param bufp the TSMBuffer associated with the header field
+   * @param mloc the TSMLoc associated with the headers
+   * @param field_loc the TSMLoc associated with the header field
+   * @warning This should only be used if you're mixing the C++ and C apis, it 
will be constructed automatically if using only the C++ api.
+   */
+  HeaderField(void *bufp, void *hdr_loc, void *field_loc);
+  ~HeaderField();
 
-  Type getType() const;
+  /**
+    * Get the size of the HeaderField, this is the number of values associated 
with the header field.
+    * @return the number of values in this HeaderField.
+    */
+  size_type size() const;
 
-  typedef std::map<std::string, std::list<std::string>, 
CaseInsensitiveStringComparator> NameValuesMap;
+  /**
+    * Returns an iterator to the start of the values
+    * @return an iterator point to the start of this header field's values
+    */
+  iterator begin();
 
-  typedef NameValuesMap::size_type size_type;
-  typedef NameValuesMap::const_iterator const_iterator;
-  typedef NameValuesMap::const_reverse_iterator const_reverse_iterator;
+  /**
+    * Returns an iterator to the end of this header field's values.
+    * @return an iterator that points beyond the last element of the header 
field's values.
+    */
+  iterator end();
 
   /**
-   * @return Iterator to first header.
+   * Get the name of this HeaderField
+   * @return a HeaderFieldName object.
+   * @see HeaderFieldName which is a thin wrapper around a string to allow for 
case insensitive comparisons.
    */
-  const_iterator begin() const;
+  HeaderFieldName name() const;
 
   /**
-   * @return Iterator to end of headers.
-   */
-  const_iterator end() const;
+    * Join all the values of this HeaderField into a single string seperated 
by the join string.
+    * @param an optional join string (defaults to ",")
+    * @return a string which is all of the joined values of this HeaderField
+    */
+  std::string values(const char *join = ",");
 
   /**
-   * @return Iterator to last header.
-   */
-  const_reverse_iterator rbegin() const;
+    * Join all the values of this HeaderField into a single string seperated 
by the join string.
+    * @param a join string
+    * @return a string which is all of the joined values of this HeaderField
+    */
+  std::string values(const std::string &join);
 
   /**
-   * @return Iterator to "reverse end"
-   */
-  const_reverse_iterator rend() const;
+    * Join all the values of this HeaderField into a single string seperated 
by the join string.
+    * @param a optional join character
+    * @return a string which is all of the joined values of this HeaderField
+    */
+  std::string values(const char join);
 
   /**
-   * @param key Name of header
-   * @return Iterator to header if exists, else end()
-   */
-  const_iterator find(const std::string &key) const;
+    * Check if this HeaderField is empty (no values).
+    * @return a boolean value representing whether or not the header field has 
values.
+    */
+  bool empty();
 
   /**
-   * @param key Name of header
-   * @return 1 if header exists, 0 if not. 
+   * Remove all values from this HeaderField
+   * @return true if the clear succeeeds.
    */
-  size_type count(const std::string &key) const;
+  bool clear();
 
   /**
-   * Erases header with given name.
-   *
-   * @param key Name of header
-   * @return 1 if header was erased, 0 if not. 
+   * Remove a single value from this HeaderField which is pointed to by the 
given iterator
+   * @param an iterator which points to a single HeaderField value.
+   * @return true if the header value was successfully erased.
    */
-  size_type erase(const std::string &key);
+  bool erase(iterator it);
 
   /**
-   * Sets the given header and values. If a header of same name existed, that 
is
-   * deleted. Else header is appended.
-   * 
-   * @param pair Contains the name and list of values.
-   *
-   * @return Iterator to header set. 
+   * Append a value or a seperated list of values to this HeaderField
+   * @param a string containing the value(s).
+   * @return true if the values was appended.
    */
-  const_iterator set(const std::pair<std::string, std::list<std::string> > 
&pair);
+  bool append(const std::string &value);
 
   /**
-   * Sets the given header and values. If a header of same name existed, that 
is
-   * deleted. Else header is appended.
-   *
-   * @param key Name of header
-   * @param val List of values
-   * 
-   * @return Iterator to header set. 
+   * Append a value or a seperated list of values to this HeaderField
+   * @param a string containing the value.
+   * @param the length of the value that is being appended.
+   * @return true if the values was appended.
    */
-  const_iterator set(const std::string &key, const std::list<std::string> 
&val);
+  bool append(const char *value, int length = -1);
 
   /**
-   * Sets the given header and values. If a header of same name existed, that 
is
-   * deleted. Else header is appended.
-   *
-   * @param key Name of header
-   * @param val Value
-   * 
-   * @return Iterator to header set. 
+   * Change the name of this HeaderField to the given key.
+   * @param string - the new name of the header field
+   * @return true if the header field name was successfully changed.
    */
-  const_iterator set(const std::string &key, const std::string &val);
+  bool setName(const std::string &str);
 
   /**
-   * Appends a new header. If a header of the same name exists, value(s) is 
tacked
-   * on that the end of current value(s). 
-   * 
-   * @param pair Contains the name and list of values.
-   *
-   * @return Iterator to header appended. 
+   * Compares the name of the header field only (not the values).
+   * @note This is a case insensitive comparison.
+   * @return true if the name is equal (case insensitive comparison).
    */
-  const_iterator append(const std::pair<std::string, std::list<std::string> > 
&pair);
+  bool operator==(const char *field_name) const;
 
-  /**
-   * Appends a new header. If a header of the same name exists, value(s) is 
tacked
-   * on that the end of current value(s). 
-   * 
-   * @param key Name of header
-   * @param val List of values
-   * 
-   * @return Iterator to header appended. 
+  /** Compares the name of the header field only (not the values).
+   * @note This is a case insensitive comparison.
+   * @return true if the name is equal (case insensitive comparison).
    */
-  const_iterator append(const std::string &key, const std::list<std::string> 
&val);
+  bool operator==(const std::string &field_name) const;
 
-  /**
-   * Appends a new header. If a header of the same name exists, value(s) is 
tacked
-   * on that the end of current value(s). 
-   * 
-   * @param key Name of header
-   * @param val Value
-   * 
-   * @return Iterator to header appended. 
+  /** Compares the name of the header field only (not the values).
+   * @note This is a case insensitive comparison.
+   * @return true if the name is NOT equal (case insensitive comparison).
    */
-  const_iterator append(const std::string &key, const std::string &val);
+  bool operator!=(const char *field_name) const;
 
-  /**
-   * Joins provided list of values with delimiter (defaulting to ',').
-   *
-   * @return Composite string
+  /** Compares the name of the header field only (not the values).
+   * @note This is a case insensitive comparison.
+   * @return true if the name is NOT equal (case insensitive comparison).
    */
-  static std::string getJoinedValues(const std::list<std::string> &values, 
char delimiter = ',');
+  bool operator!=(const std::string &field_name) const ;
 
   /**
-   * Joins values of provided header with delimiter (defaulting to ',').
-   *
-   * @return Composite string if header exists, else empty strings.
+   * Set the VALUES of the header field to the given value string
+   * @param string - the values to set on the current header field
+   * @return true if the value is sucessfully changed.
    */
-  std::string getJoinedValues(const std::string &key, char value_delimiter = 
',');
+  bool operator=(const std::string &field_value);
 
   /**
-   * @return True if there are no headers.
+   * Set the VALUES of the header field to the given value string
+   * @param the values to set on the current header field
+   * @return true if the value is sucessfully changed.
    */
-  bool empty() const;
+  bool operator=(const char *field_value);
 
   /**
-   * @return Largest possible size of underlying map.
+    * Get the index value from this HeaderField
+    * @param the index to retrieve a copy of
+    * @return a copy of the string which is the index^th value in this 
HeaderField
+    * @note as currently written this returns an immutable string, it will NOT 
allow you to
+    * change the value.
+    */
+  std::string operator[](const int index);
+
+  /**
+    * Get a string representing all the header field's values
+    * @return a string representation of all the header fields
+    */
+  friend std::ostream& operator<<(std::ostream& os, HeaderField& obj);
+
+  /**
+    * Get a string representing all the header field's values.
+    * @return a string representation of all the header fields
+    */
+  std::string str();
+  friend class Headers;
+  friend class header_field_iterator;
+};
+
+/**
+ * @brief A header field iterator is an iterator that dereferences to a 
HeaderField.
+ */
+class header_field_iterator : public std::iterator<std::forward_iterator_tag, 
int>
+{
+  private:
+    HeaderFieldIteratorState *state_;
+  public:
+    header_field_iterator();
+    ~header_field_iterator();
+
+   /**
+     * Constructor for header_field_iterator, this shouldn't need to be used 
directly.
+     * @param bufp the TSMBuffer associated with the headers
+     * @param mloc the TSMLoc associated with the headers.
+     * @param field_loc the TSMLoc assocated with the field.
+     * @warning This shouldn't need to be used directly!
+     */
+    header_field_iterator(void *bufp, void *hdr_loc, void *field_loc);
+
+    /**
+      * Constructor for header_field_iterator, this shouldn't need to be used 
directly.
+      * @param HeaderField the header field to use for constructing the 
iterator.
+      * @warning This shouldn't need to be used directly!
+      */
+    header_field_iterator(HeaderField &hf);
+
+    /**
+      * Copy Constructor for header_field_iterator, this shouldn't need to be 
used directly.
+      * @param header_field_iterator: for constructing the iterator.
+      * @warning This shouldn't need to be used directly!
+     */
+    header_field_iterator(const header_field_iterator& it);
+
+    /**
+     * Advance the iterator to the next header field
+     * @return a reference to a the next iterator
+     */
+    header_field_iterator& operator++();
+
+    /**
+     * Advance the current iterator to the next header field
+     * @return a new iterator which points to the next element
+     */
+    header_field_iterator operator++(int);
+
+    /**
+     * Comparison operator, compare two iterators
+     * @return true if the two iterators point to the same HeaderField
+     */
+    bool operator==(const header_field_iterator& rhs) const;
+
+    /**
+     * Inequality Operator, compare two iterators
+     * @return false if the two iterators are the same.
+     */
+    bool operator!=(const header_field_iterator& rhs) const;
+
+    /**
+     * Dereference an iterator
+     * @return a HeaderField pointed to by this iterator
+     */
+    HeaderField operator*();
+
+    /**
+     * Dereference an iterator
+     * @return a HeaderField pointed to by this iterator
+     */
+    HeaderField operator()();
+
+    friend class Headers;
+};
+
+/**
+ * @brief Encapsulates the headers portion of a request or response.
+ */
+class Headers: noncopyable {
+public:
+  /**
+   * Constructor for Headers, this shouldn't be used directly unless you're 
trying to mix the C++ and C apis.
+   * @warning This should only be used if you're mixing the C++ and C apis, it 
will be constructed automatically if using only the C++ api.
    */
-  size_type max_size() const;
+  Headers();
 
   /**
-   * @return Number of headers currently stored.
+   * Constructor for Headers, this shouldn't be used directly unless you're 
trying to mix the C++ and C apis.
+   * @param bufp the TSMBuffer associated with the headers
+   * @param mloc the TSMLoc associated with the headers.
+   * @warning This should only be used if you're mixing the C++ and C apis, it 
will be constructed automatically if using only the C++ api.
    */
+  Headers(void *bufp, void *mloc);
+
+  /**
+    * Context Values are a way to share data between plugins, the key is 
always a string
+    * and the value can be a shared_ptr to any type that extends ContextValue.
+    * @param bufp the TSMBuffer associated with the headers
+    * @param mloc the TSMLoc associated with the headers.
+    * @warning This should only be used if you're mixing the C++ and C apis.
+    */
+  void reset(void *bufp, void *mloc);
+
+  /**
+    * Check if the header class has been initialized. If you're only using the 
C++ api then this
+    * should always return true.
+    * @return a boolean value representing whether or not the Headers have 
been initialized..
+    */
+  bool isInitialized() const;
+
+  typedef unsigned int size_type;
+  typedef header_field_iterator iterator;
+
+  /**
+    * Check if the headers are empty
+    * @return a boolean value representing whether or not the Headers are empty
+    */
+  bool empty();
+
+  /**
+    * Get the size of the headers (the number of HeaderFields).
+    * @return the number of HeaderFields
+    */
   size_type size() const;
 
-  typedef std::map<std::string, std::list<std::string> > RequestCookieMap;
+  /**
+    * Get the size of the headers (the number of HeaderFields).
+    * @return the number of HeaderFields
+    */
+  size_type lengthBytes() const;
 
   /**
-   * @return Cookies in the "Cookie" headers of a request object.
-   */
-  const RequestCookieMap &getRequestCookies() const;
-
-  struct ResponseCookie {
-    std::string name_;
-    std::string value_;
-    std::string comment_;
-    std::string domain_;
-    int max_age_;
-    std::string path_;
-    bool secure_;
-    int version_;
-    ResponseCookie() : max_age_(0), secure_(false), version_(0) { };
-  };
-
-  /**
-   * @return Cookies in the "Set-Cookie" headers of a response object.
-   */
-  const std::list<ResponseCookie> &getResponseCookies() const;
+    * Returns an iterator to the start of the HeaderFields.
+    * @return an iterator point to the start of the header fields.
+    */
+  iterator begin();
+
+  /**
+    * Returns an iterator to the end of the HeaderFields (beyond the last 
element).
+    * @return an iterator that points beyond the last element in the header 
fields.
+    */
+  iterator end();
+
+  /**
+    * Clears all headers.
+    * @return true if the headers were succesfully cleared.
+    */
+  bool clear();
+
+  /**
+    * Erase a single header field pointed to by an iterator
+    * @param an iterator pointing to a header field.
+    * @return true if the header field pointed to by the iterator was erased.
+    */
+  bool erase(iterator it);
+
+  /**
+    * Erase all headers whose name matches key (this is a case insensitive 
match).
+    * @param the name of the header fields to erase
+    * @return the number of elements erased that matched the key
+    */
+  size_type erase(const std::string &key);
 
-  /** Adds a request cookie */
-  bool addCookie(const std::string &name, const std::string &value);
+  /**
+    * Erase all headers whose name matches key (this is a case insensitive 
match).
+    * @param the name of the header fields to erase
+    * @param the length of the key (optional).
+    * @return the number of elements erased that matched the key
+    */
+  size_type erase(const char *key, int length = -1);
+
+  /**
+    * Count all headers whose name matches key (this is a case insensitive 
match).
+    * @param the name of the header fields to erase
+    * @param the length of the key (optional).
+    * @return the number of elements erased that matched the key
+    */
+  size_type count(const char *key, int length = -1);
 
-  /** Adds a response cookie */
-  bool addCookie(const ResponseCookie &response_cookie);
-  
-  /** Sets, i.e., clears current value and adds new value, of a request cookie 
*/
-  bool setCookie(const std::string &name, const std::string &value);
+  /**
+    * Count all headers whose name matches key (this is a case insensitive 
match).
+    * @param the name of the header fields to count
+    * @return the number of elements whose name is key.
+    */
+  size_type count(const std::string &key);
+
+  /**
+    * Join all headers whos name is key with the optionally specified join 
string
+    * @param the name of the headers to join into a single string
+    * @param an optional join string (defaults to ",")
+    * @return a string which is all of the joined values of headers matching 
key.
+    */
+  std::string values(const std::string &key, const char *join = ",");
 
-  /** Sets, i.e., clears current value and adds new value, of a response 
cookie */
-  bool setCookie(const ResponseCookie &response_cookie);
+  /**
+    * Join all headers whos name is key with the optionally specified join 
string
+    * @param the name of the headers to join into a single string
+    * @param the string to join the fields with
+    * @return a string which is all of the joined values of headers matching 
key.
+    */
+  std::string values(const std::string &key, const std::string &join);
+
+  /**
+    * Join all headers whos name is key with the optionally specified join 
character
+    * @param the name of the headers to join into a single string
+    * @param the join character.
+    * @return a string which is all of the joined values of headers matching 
key.
+    */
+  std::string values(const std::string &key, const char join);
+
+  /**
+    * Returns an iterator to the first HeaderField with the name key.
+    * @param key the name of first header field ot find.
+    * @return an iterator that points to the first matching header field with 
name key.
+    */
+  iterator find(const std::string &key);
+
+  /**
+    * Returns an iterator to the first HeaderField with the name key.
+    * @param key the name of first header field ot find.
+    * @param the length of the key specified (optional).
+    * @return an iterator that points to the first matching header field with 
name key.
+    */
+  iterator find(const char *key, int length = -1);
+
+  /**
+    * Append a HeaderField.
+    * @param key the name of the header field to append
+    * @param value the value of the header field to append
+    * @return an iterator to the appended header field or the end() iterator 
if append fails.
+    */
+  iterator append(const std::string &key, const std::string &value);
+
+  /**
+    * Erase all headers with name specified by key and then re-create the 
header with the specified values.
+    * @param key the name of the header field to erased and re-created.
+    * @param value the value of the header field to set.
+    * @return an iterator to the new header field or the end() iterator if 
append fails.
+    */
+  iterator eraseAndSet(const std::string &key, const std::string &value);
+
+  /**
+    * Set the header field values to the value given, the header field will be 
created
+    * if it does not already exist.
+    * @param key the name of the header field whose value to set.
+    * @return an iterator to the new header field or the end() iterator if 
append fails.
+    * @warning This will create a header field with the given name, thus it 
should not be
+    * used to check for the existance of a header, use count() or find() 
instead.
+    */
+  HeaderField operator[](const std::string &key);
+
+  /**
+    * Get a string representing all the header fields.
+    * @return a string representation of all the header fields
+    */
+  std::string str();
 
-  /** Deletes a cookie */
-  bool deleteCookie(const std::string &name);
+  friend std::ostream& operator<<(std::ostream &os, Headers &obj);
 
   ~Headers();
 private:
   HeadersState *state_;
-  bool checkAndInitHeaders() const;
-  void init(void *hdr_buf, void *hdr_loc);
-  void initDetached();
-  void setType(Type type);
-  void updateRequestCookieHeaderFromMap();
-  const_iterator doBasicAppend(const std::pair<std::string, 
std::list<std::string> > &pair);
-  size_type doBasicErase(const std::string &key);
   friend class Request;
   friend class ClientRequest;
   friend class Response;

Reply via email to