]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
buffer: implement bufferptr::iterator
authorSage Weil <sage@redhat.com>
Tue, 13 Sep 2016 18:03:01 +0000 (14:03 -0400)
committerSage Weil <sage@redhat.com>
Sun, 16 Oct 2016 14:32:50 +0000 (10:32 -0400)
Signed-off-by: Sage Weil <sage@redhat.com>
src/include/buffer.h

index 019708754b5269e26159d3c12ba911c99799331f..57f29944d652930246c696b1a10604e12e916866 100644 (file)
@@ -169,6 +169,73 @@ namespace buffer CEPH_BUFFER_API {
     void release();
 
   public:
+    class iterator {
+      const ptr *bp;     ///< parent ptr
+      const char *start; ///< starting pointer into bp->c_str()
+      const char *pos;   ///< pointer into bp->c_str()
+      const char *end_ptr;   ///< pointer to bp->end_c_str()
+      bool deep;         ///< if true, no not allow shallow ptr copies
+
+      iterator(const ptr *p, size_t offset, bool d)
+       : bp(p),
+         start(p->c_str() + offset),
+         pos(start),
+         end_ptr(p->end_c_str()),
+         deep(d) {}
+
+      friend class ptr;
+
+    public:
+      const char *c_str_add(size_t n) {
+       const char *r = pos;
+       pos += n;
+       if (pos > end_ptr)
+         throw end_of_buffer();
+       return r;
+      }
+
+      ptr get_ptr(size_t len) {
+       if (deep) {
+         return buffer::copy(c_str_add(len), len);
+       } else {
+         size_t off = pos - bp->c_str();
+         pos += len;
+         if (pos > end_ptr)
+           throw end_of_buffer();
+         return ptr(*bp, off, len);
+       }
+      }
+      ptr get_preceding_ptr(size_t len) {
+       if (deep) {
+         return buffer::copy(c_str() - len, len);
+       } else {
+         size_t off = pos - bp->c_str();
+         return ptr(*bp, off - len, len);
+       }
+      }
+
+      void advance(size_t len) {
+       pos += len;
+       if (pos > end_ptr)
+         throw end_of_buffer();
+      }
+
+      const char *c_str() {
+       return pos;
+      }
+      const char *end_c_str() {
+       return end_ptr;
+      }
+
+      size_t get_offset() {
+       return pos - start;
+      }
+
+      bool end() const {
+       return pos == end_ptr;
+      }
+    };
+
     ptr() : _raw(0), _off(0), _len(0) {}
     // cppcheck-suppress noExplicitConstructor
     ptr(raw *r);
@@ -190,6 +257,13 @@ namespace buffer CEPH_BUFFER_API {
     void swap(ptr& other);
     ptr& make_shareable();
 
+    iterator begin(size_t offset=0) const {
+      return iterator(this, offset, false);
+    }
+    iterator begin_deep(size_t offset=0) const {
+      return iterator(this, offset, true);
+    }
+
     // misc
     bool at_buffer_head() const { return _off == 0; }
     bool at_buffer_tail() const;