Repository: trafficserver
Updated Branches:
  refs/heads/master f5c2b2c94 -> d3e4614bf


Fix issues releasing MLocHandles in headers


Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/d3e4614b
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/d3e4614b
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/d3e4614b

Branch: refs/heads/master
Commit: d3e4614bf3e945c07c367cc488dc13ee832ce131
Parents: f5c2b2c
Author: Brian Geffon <[email protected]>
Authored: Tue Feb 18 14:48:36 2014 -0800
Committer: Brian Geffon <[email protected]>
Committed: Tue Feb 18 14:48:36 2014 -0800

----------------------------------------------------------------------
 lib/atscppapi/src/Headers.cc                  | 171 +++++++++++----------
 lib/atscppapi/src/include/atscppapi/Headers.h | 157 +++++++++----------
 2 files changed, 159 insertions(+), 169 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/d3e4614b/lib/atscppapi/src/Headers.cc
----------------------------------------------------------------------
diff --git a/lib/atscppapi/src/Headers.cc b/lib/atscppapi/src/Headers.cc
index 8eb0ce5..871fecc 100644
--- a/lib/atscppapi/src/Headers.cc
+++ b/lib/atscppapi/src/Headers.cc
@@ -20,6 +20,7 @@
  * @file Headers.cc
  */
 #include "atscppapi/Headers.h"
+#include "atscppapi/shared_ptr.h"
 #include "InitializableValue.h"
 #include "logging_internal.h"
 #include <string>
@@ -147,45 +148,46 @@ bool header_field_value_iterator::operator!=(const 
header_field_value_iterator&
 /**
  * @private
  */
-struct HeaderFieldState: noncopyable {
+struct MLocContainer {
   TSMBuffer hdr_buf_;
   TSMLoc hdr_loc_;
   TSMLoc field_loc_;
-  HeaderFieldState() : hdr_buf_(NULL), hdr_loc_(NULL), field_loc_(NULL) { }
-  void reset(TSMBuffer bufp, TSMLoc hdr_loc, TSMLoc field_loc) {
-    hdr_buf_ = bufp;
-    hdr_loc_ = hdr_loc;
-    field_loc_ = field_loc;
+  MLocContainer(TSMBuffer bufp, TSMLoc hdr_loc, TSMLoc field_loc) :
+    hdr_buf_(bufp), hdr_loc_(hdr_loc), field_loc_(field_loc) { }
+  ~MLocContainer() {
+    if (field_loc_ != TS_NULL_MLOC) {
+      TSHandleMLocRelease(hdr_buf_, hdr_loc_, field_loc_);
+    }
   }
 };
 
-HeaderField::HeaderField(void *bufp, void *hdr_loc, void *field_loc)
-{
-  state_ = new HeaderFieldState();
-  state_->hdr_buf_ = static_cast<TSMBuffer>(bufp);
-  state_->hdr_loc_ = static_cast<TSMLoc>(hdr_loc);
-  state_->field_loc_ = static_cast<TSMLoc>(field_loc);
-}
+/**
+ * @private
+ */
+struct HeaderFieldIteratorState {
+  shared_ptr<MLocContainer> mloc_container_;
+  HeaderFieldIteratorState(TSMBuffer bufp, TSMLoc hdr_loc, TSMLoc field_loc)
+    : mloc_container_(new MLocContainer(bufp, hdr_loc, field_loc)) { }
+};
 
 HeaderField::~HeaderField() {
-  delete state_;
 }
 
 HeaderField::size_type HeaderField::size() const {
-  return TSMimeHdrFieldValuesCount(state_->hdr_buf_, state_->hdr_loc_, 
state_->field_loc_);
+  return TSMimeHdrFieldValuesCount(iter_.state_->mloc_container_->hdr_buf_, 
iter_.state_->mloc_container_->hdr_loc_, 
iter_.state_->mloc_container_->field_loc_);
 }
 
 header_field_value_iterator HeaderField::begin() {
-  return header_field_value_iterator(state_->hdr_buf_, state_->hdr_loc_, 
state_->field_loc_, 0);
+  return header_field_value_iterator(iter_.state_->mloc_container_->hdr_buf_, 
iter_.state_->mloc_container_->hdr_loc_, 
iter_.state_->mloc_container_->field_loc_, 0);
 }
 
 header_field_value_iterator HeaderField::end() {
-  return header_field_value_iterator(state_->hdr_buf_, state_->hdr_loc_, 
state_->field_loc_, size());
+  return header_field_value_iterator(iter_.state_->mloc_container_->hdr_buf_, 
iter_.state_->mloc_container_->hdr_loc_, 
iter_.state_->mloc_container_->field_loc_, size());
 }
 
 HeaderFieldName HeaderField::name() const {
   int length = 0;
-  const char *str = TSMimeHdrFieldNameGet(state_->hdr_buf_, state_->hdr_loc_, 
state_->field_loc_, &length);
+  const char *str = 
TSMimeHdrFieldNameGet(iter_.state_->mloc_container_->hdr_buf_, 
iter_.state_->mloc_container_->hdr_loc_, 
iter_.state_->mloc_container_->field_loc_, &length);
   if (str && length) {
     return std::string(str, length);
   }
@@ -211,12 +213,29 @@ std::string HeaderField::values(const char join) {
   return values(std::string().append(1,join));
 }
 
+std::string Headers::value(const std::string key, size_type index /* = 0 */) {
+  header_field_iterator iter = find(key);
+  if (iter == end()) {
+    return string();
+  }
+  if (index == 0) { // skip for loop
+    return *((*iter).begin());
+  }
+  for (; iter != end(); iter.nextDup()) {
+    if (index < (*iter).size()) {
+      return (*iter)[index];
+    }
+    index -= (*iter).size();
+  }
+  return string();
+}
+
 bool HeaderField::empty() {
   return (begin() == end());
 }
 
 bool HeaderField::clear() {
-  return (TSMimeHdrFieldValuesClear(state_->hdr_buf_, state_->hdr_loc_, 
state_->field_loc_) == TS_SUCCESS);
+  return (TSMimeHdrFieldValuesClear(iter_.state_->mloc_container_->hdr_buf_, 
iter_.state_->mloc_container_->hdr_loc_, 
iter_.state_->mloc_container_->field_loc_) == TS_SUCCESS);
 }
 
 bool HeaderField::erase(header_field_value_iterator it) {
@@ -228,11 +247,11 @@ bool HeaderField::append(const std::string &value) {
 }
 
 bool HeaderField::append(const char *value, int length) {
-  return (TSMimeHdrFieldValueStringInsert(state_->hdr_buf_, state_->hdr_loc_, 
state_->field_loc_, -1, value, -1) == TS_SUCCESS);
+  return 
(TSMimeHdrFieldValueStringInsert(iter_.state_->mloc_container_->hdr_buf_, 
iter_.state_->mloc_container_->hdr_loc_, 
iter_.state_->mloc_container_->field_loc_, -1, value, -1) == TS_SUCCESS);
 }
 
 bool HeaderField::setName(const std::string &str) {
-  return (TSMimeHdrFieldNameSet(state_->hdr_buf_, state_->hdr_loc_, 
state_->field_loc_, str.c_str(), str.length()) == TS_SUCCESS);
+  return (TSMimeHdrFieldNameSet(iter_.state_->mloc_container_->hdr_buf_, 
iter_.state_->mloc_container_->hdr_loc_, 
iter_.state_->mloc_container_->field_loc_, str.c_str(), str.length()) == 
TS_SUCCESS);
 }
 
 bool HeaderField::operator==(const char *field_name) const {
@@ -266,7 +285,7 @@ bool HeaderField::operator=(const char *field_value) {
 }
 
 std::string HeaderField::operator[](const int index) {
-  return *header_field_value_iterator(state_->hdr_buf_, state_->hdr_loc_, 
state_->field_loc_, index);
+  return *header_field_value_iterator(iter_.state_->mloc_container_->hdr_buf_, 
iter_.state_->mloc_container_->hdr_loc_, 
iter_.state_->mloc_container_->field_loc_, index);
 }
 
 std::string HeaderField::str() {
@@ -286,50 +305,40 @@ std::ostream& operator<<(std::ostream& os, HeaderField& 
obj) {
   return os;
 }
 
-/**
- * @private
- */
-struct HeaderFieldIteratorState: noncopyable {
-  TSMBuffer hdr_buf_;
-  TSMLoc hdr_loc_;
-  TSMLoc field_loc_;
-  HeaderFieldIteratorState() : hdr_buf_(NULL), hdr_loc_(NULL), 
field_loc_(NULL) { }
-  void reset(TSMBuffer bufp, TSMLoc hdr_loc, TSMLoc field_loc) {
-    hdr_buf_ = bufp;
-    hdr_loc_ = hdr_loc;
-    field_loc_ = field_loc;
-  }
-};
+header_field_iterator::header_field_iterator(void *hdr_buf, void *hdr_loc, 
void *field_loc) :
+  state_(new HeaderFieldIteratorState(static_cast<TSMBuffer>(hdr_buf), 
static_cast<TSMLoc>(hdr_loc),
+                                      static_cast<TSMLoc>(field_loc))) { }
 
-header_field_iterator::header_field_iterator() {
-  state_ = new HeaderFieldIteratorState();
-}
+header_field_iterator::header_field_iterator(const header_field_iterator& it) :
+  state_(new HeaderFieldIteratorState(*it.state_)) { } 
 
-header_field_iterator::header_field_iterator(void *bufp, void *hdr_loc, void 
*field_loc) {
-  state_ = new HeaderFieldIteratorState();
-  state_->reset(static_cast<TSMBuffer>(bufp), static_cast<TSMLoc>(hdr_loc), 
static_cast<TSMLoc>(field_loc));
-}
-
-header_field_iterator::header_field_iterator(HeaderField &hf) {
-  state_ = new HeaderFieldIteratorState();
-  state_->reset(hf.state_->hdr_buf_, hf.state_->hdr_loc_, 
hf.state_->field_loc_);
-}
-
-header_field_iterator::header_field_iterator(const header_field_iterator& it) {
-  state_ = new HeaderFieldIteratorState();
-  state_->reset(it.state_->hdr_buf_, it.state_->hdr_loc_, 
it.state_->field_loc_);
+header_field_iterator &header_field_iterator::operator=(const 
header_field_iterator &rhs) {
+  if (this != &rhs) {
+    delete state_;
+    state_ = new HeaderFieldIteratorState(*rhs.state_);
+  }
+  return *this;
 }
 
 header_field_iterator::~header_field_iterator() {
   delete state_;
 }
 
-header_field_iterator& header_field_iterator::operator++() {
-  if (state_->field_loc_ == TS_NULL_MLOC) {
-    return *this;
+// utility function to use to advance iterators using different functions
+HeaderFieldIteratorState *advanceIterator(HeaderFieldIteratorState *state,
+                                          TSMLoc (*getNextField)(TSMBuffer, 
TSMLoc, TSMLoc)) {
+  if (state->mloc_container_->field_loc_ != TS_NULL_MLOC) {
+    TSMBuffer hdr_buf = state->mloc_container_->hdr_buf_;
+    TSMLoc hdr_loc = state->mloc_container_->hdr_loc_;
+    TSMLoc next_field_loc = getNextField(hdr_buf, hdr_loc, 
state->mloc_container_->field_loc_);
+    delete state;
+    state = new HeaderFieldIteratorState(hdr_buf, hdr_loc, next_field_loc);
   }
+  return state;
+}
 
-  state_->field_loc_ = TSMimeHdrFieldNext(state_->hdr_buf_, state_->hdr_loc_, 
state_->field_loc_);
+header_field_iterator& header_field_iterator::operator++() {
+  state_ = advanceIterator(state_, TSMimeHdrFieldNext);  
   return *this;
 }
 
@@ -339,9 +348,14 @@ header_field_iterator 
header_field_iterator::operator++(int) {
   return tmp;
 }
 
+header_field_iterator& header_field_iterator::nextDup() {
+  state_ = advanceIterator(state_, TSMimeHdrFieldNextDup);  
+  return *this;
+}
+
 bool header_field_iterator::operator==(const header_field_iterator& rhs) const 
{
-  return (state_->hdr_buf_ == rhs.state_->hdr_buf_) && (state_->hdr_loc_ == 
rhs.state_->hdr_loc_) &&
-      (state_->field_loc_ == rhs.state_->field_loc_);
+  return (state_->mloc_container_->hdr_buf_ == 
rhs.state_->mloc_container_->hdr_buf_) && (state_->mloc_container_->hdr_loc_ == 
rhs.state_->mloc_container_->hdr_loc_) &&
+      (state_->mloc_container_->field_loc_ == 
rhs.state_->mloc_container_->field_loc_);
 }
 
 bool header_field_iterator::operator!=(const header_field_iterator& rhs) const 
{
@@ -349,11 +363,7 @@ bool header_field_iterator::operator!=(const 
header_field_iterator& rhs) const {
 }
 
 HeaderField header_field_iterator::operator*() {
-  return HeaderField(state_->hdr_buf_, state_->hdr_loc_, state_->field_loc_);
-}
-
-HeaderField header_field_iterator::operator()() {
-  return operator*();
+  return HeaderField(*this);
 }
 
 /**
@@ -415,7 +425,7 @@ bool Headers::clear() {
 }
 
 bool Headers::erase(header_field_iterator it) {
-  return (TSMimeHdrFieldDestroy(it.state_->hdr_buf_, it.state_->hdr_loc_, 
it.state_->field_loc_) == TS_SUCCESS);
+  return (TSMimeHdrFieldDestroy(it.state_->mloc_container_->hdr_buf_, 
it.state_->mloc_container_->hdr_loc_, it.state_->mloc_container_->field_loc_) 
== TS_SUCCESS);
 }
 
 Headers::size_type Headers::erase(const std::string &key) {
@@ -423,20 +433,15 @@ Headers::size_type Headers::erase(const std::string &key) 
{
 }
 
 Headers::size_type Headers::erase(const char *key, int length) {
-  header_field_iterator it;
-  header_field_iterator prev_iter;
-  size_type count = 0;
-  while((it = find(key, length)) != end() &&
-      it != prev_iter) {
-
-    if(erase(it) != true)
-      return count;
-
-    // If find continues to return the same element because erase fails then 
we will stop.
-    prev_iter = it;
-    count++;
+  header_field_iterator iter = find(key, length);
+  size_type erased_count = 0;
+  while (iter != end()) {
+    header_field_iterator iter_to_delete = iter;
+    iter.nextDup();
+    erase(iter_to_delete);
+    ++erased_count;
   }
-  return count;
+  return erased_count;
 }
 
 Headers::size_type Headers::count(const char *key, int length) {
@@ -458,12 +463,10 @@ std::string Headers::values(const std::string &key, const 
char *join) {
   Headers::size_type num_header_fields = count(key);
   ret.reserve(128 * num_header_fields);
 
-  for (header_field_iterator it = begin(); it != end(); ++it) {
-    if (*it == key) {
-      ret.append((*it).values(join));
-      if (--num_header_fields > 0) {
-        ret.append(join);
-      }
+  for (header_field_iterator it = find(key); it != end(); it.nextDup()) {
+    ret.append((*it).values(join));
+    if (--num_header_fields > 0) {
+      ret.append(join);
     }
   }
 
@@ -502,7 +505,7 @@ Headers::iterator Headers::append(const std::string &key, 
const std::string &val
     return end();
 }
 
-Headers::iterator Headers::eraseAndSet(const std::string &key, const 
std::string &value) {
+Headers::iterator Headers::set(const std::string &key, const std::string 
&value) {
   erase(key);
   return append(key, value);
 }

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/d3e4614b/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 2a41907..19d46f8 100644
--- a/lib/atscppapi/src/include/atscppapi/Headers.h
+++ b/lib/atscppapi/src/include/atscppapi/Headers.h
@@ -31,7 +31,6 @@ namespace atscppapi {
 
 struct HeadersState;
 struct HeaderFieldIteratorState;
-struct HeaderFieldState;
 struct HeaderFieldValueIteratorState;
 class Request;
 class ClientRequest;
@@ -165,7 +164,66 @@ class header_field_value_iterator : public 
std::iterator<std::forward_iterator_t
 
     friend class HeaderField;
 };
-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_;
+    header_field_iterator(void *hdr_buf, void *hdr_loc, void *field_loc);
+  public:
+    ~header_field_iterator();
+
+    /**
+      * 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);
+
+    header_field_iterator &operator=(const header_field_iterator &rhs);
+
+    /**
+     * 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);
+
+    /**
+     * Advance the iterator to the next header field with the same name
+     * @return a reference to a the next iterator
+     */
+    header_field_iterator& nextDup();
+
+    /**
+     * 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*();
+
+    friend class HeaderField;
+    friend class Headers;
+};
 
 /**
  * @brief A HeaderField is a class that contains the header field name and all 
of the values.
@@ -173,19 +231,13 @@ class header_field_iterator;
  */
 class HeaderField {
 private:
-  HeaderFieldState *state_;
+  header_field_iterator iter_;
+  HeaderField(header_field_iterator iter) : iter_(iter) { }
+  
 public:
   typedef unsigned int size_type;
   typedef header_field_value_iterator iterator;
 
-  /**
-   * 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();
 
   /**
@@ -339,79 +391,6 @@ public:
 };
 
 /**
- * @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 {
@@ -547,6 +526,14 @@ public:
   std::string values(const std::string &key, const char join);
 
   /**
+    * Returns the value at given position of header with given name
+    * @param name of header
+    * @param position of value 
+    * @return value
+    */
+  std::string value(const std::string key, size_type index = 0);
+
+  /**
     * 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.
@@ -575,7 +562,7 @@ public:
     * @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);
+  iterator set(const std::string &key, const std::string &value);
 
   /**
     * Set the header field values to the value given, the header field will be 
created

Reply via email to