• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

TsBuffer.h

Go to the documentation of this file.
00001 # if ! defined TS_BUFFER_HEADER
00002 # define TS_BUFFER_HEADER
00003 
00004 /** @file
00005     Definitions for a buffer type, to carry a reference to a chunk of memory.
00006 
00007     @internal This is a copy of TsBuffer.h in lib/tsconfig. That should
00008     eventually be replaced with this promoted file.
00009 
00010     @section license License
00011 
00012     Licensed to the Apache Software Foundation (ASF) under one
00013     or more contributor license agreements.  See the NOTICE file
00014     distributed with this work for additional information
00015     regarding copyright ownership.  The ASF licenses this file
00016     to you under the Apache License, Version 2.0 (the
00017     "License"); you may not use this file except in compliance
00018     with the License.  You may obtain a copy of the License at
00019 
00020     http://www.apache.org/licenses/LICENSE-2.0
00021 
00022     Unless required by applicable law or agreed to in writing, software
00023     distributed under the License is distributed on an "AS IS" BASIS,
00024     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00025     See the License for the specific language governing permissions and
00026     limitations under the License.
00027  */
00028 
00029 # if defined _MSC_VER
00030 # include <stddef.h>
00031 # else
00032 # include <unistd.h>
00033 # endif
00034 
00035 // For memcmp()
00036 # include <memory.h>
00037 
00038 /// Apache Traffic Server commons.
00039 namespace ts {
00040   struct ConstBuffer;
00041   /** A chunk of writable memory.
00042       A convenience class because we pass this kind of pair frequently.
00043 
00044       @note The default construct leaves the object
00045       uninitialized. This is for performance reasons. To construct an
00046       empty @c Buffer use @c Buffer(0).
00047    */
00048   struct Buffer {
00049     typedef Buffer self; ///< Self reference type.
00050     typedef bool (self::*pseudo_bool)() const;
00051 
00052     char * _ptr; ///< Pointer to base of memory chunk.
00053     size_t _size; ///< Size of memory chunk.
00054 
00055     /// Default constructor (empty buffer).
00056     Buffer();
00057 
00058     /** Construct from pointer and size.
00059         @note Due to ambiguity issues do not call this with
00060         two arguments if the first argument is 0.
00061      */
00062     Buffer(
00063       char* ptr, ///< Pointer to buffer.
00064       size_t n  ///< Size of buffer.
00065     );
00066     /** Construct from two pointers.
00067         @note This presumes a half open range, (start, end]
00068     */
00069     Buffer(
00070      char* start, ///< First valid character.
00071      char* end ///< First invalid character.
00072     );
00073 
00074     /** Equality.
00075         @return @c true if @a that refers to the same memory as @a this,
00076         @c false otherwise.
00077      */
00078     bool operator == (self const& that) const;
00079     /** Inequality.
00080         @return @c true if @a that does not refer to the same memory as @a this,
00081         @c false otherwise.
00082      */
00083     bool operator != (self const& that) const;
00084     /** Equality for a constant buffer.
00085         @return @c true if @a that refers to the same memory as @a this.
00086         @c false otherwise.
00087      */
00088     bool operator == (ConstBuffer const& that) const;
00089     /** Inequality.
00090         @return @c true if @a that does not refer to the same memory as @a this,
00091         @c false otherwise.
00092      */
00093     bool operator != (ConstBuffer const& that) const;
00094 
00095     /// @return The first character in the buffer.
00096     char operator* () const;
00097     /** Discard the first character in the buffer.
00098         @return @a this object.
00099     */
00100     self& operator++();
00101 
00102     /// Check for empty buffer.
00103     /// @return @c true if the buffer has a zero pointer @b or size.
00104     bool operator ! () const;
00105     /// Check for non-empty buffer.
00106     /// @return @c true if the buffer has a non-zero pointer @b and size.
00107     operator pseudo_bool() const;
00108 
00109     /// @name Accessors.
00110     //@{
00111     /// Get the data in the buffer.
00112     char* data() const;
00113     /// Get the size of the buffer.
00114     size_t size() const;
00115     //@}
00116 
00117     /// Set the chunk.
00118     /// Any previous values are discarded.
00119     /// @return @c this object.
00120     self& set(
00121       char* ptr, ///< Buffer address.
00122       size_t n = 0 ///< Buffer size.
00123     );
00124     /// Reset to empty.
00125     self& reset();
00126   };
00127 
00128   /** A chunk of read only memory.
00129       A convenience class because we pass this kind of pair frequently.
00130    */
00131   struct ConstBuffer {
00132     typedef ConstBuffer self; ///< Self reference type.
00133     typedef bool (self::*pseudo_bool)() const;
00134 
00135     char const * _ptr; ///< Pointer to base of memory chunk.
00136     size_t _size; ///< Size of memory chunk.
00137 
00138     /// Default constructor (empty buffer).
00139     ConstBuffer();
00140 
00141     /** Construct from pointer and size.
00142      */
00143     ConstBuffer(
00144       char const * ptr, ///< Pointer to buffer.
00145       size_t n ///< Size of buffer.
00146     );
00147     /** Construct from two pointers.
00148         @note This presumes a half open range (start, end]
00149         @note Due to ambiguity issues do not invoke this with
00150         @a start == 0.
00151     */
00152     ConstBuffer(
00153       char const* start, ///< First valid character.
00154       char const* end ///< First invalid character.
00155     );
00156     /// Construct from writable buffer.
00157     ConstBuffer(
00158       Buffer const& buffer ///< Buffer to copy.
00159     );
00160 
00161     /** Equality.
00162         @return @c true if @a that refers to the same memory as @a this,
00163         @c false otherwise.
00164      */
00165     bool operator == (self const& that) const;
00166     /** Equality.
00167         @return @c true if @a that refers to the same memory as @a this,
00168         @c false otherwise.
00169      */
00170     bool operator == (Buffer const& that) const;
00171     /** Inequality.
00172         @return @c true if @a that does not refer to the same memory as @a this,
00173         @c false otherwise.
00174      */
00175     bool operator != (self const& that) const;
00176     /** Inequality.
00177         @return @c true if @a that does not refer to the same memory as @a this,
00178         @c false otherwise.
00179      */
00180     bool operator != (Buffer const& that) const;
00181     /// Assign from non-const Buffer.
00182     self& operator = (
00183         Buffer const& that ///< Source buffer.
00184     );
00185 
00186     /// @return The first character in the buffer.
00187     char operator* () const;
00188     /** Discard the first character in the buffer.
00189         @return @a this object.
00190     */
00191     self& operator++();
00192     /** Discard the first @a n characters.
00193         @return @a this object.
00194     */
00195     self& operator += (size_t n);
00196 
00197     /// Check for empty buffer.
00198     /// @return @c true if the buffer has a zero pointer @b or size.
00199     bool operator ! () const;
00200     /// Check for non-empty buffer.
00201     /// @return @c true if the buffer has a non-zero pointer @b and size.
00202     operator pseudo_bool() const;
00203 
00204     /// @name Accessors.
00205     //@{
00206     /// Get the data in the buffer.
00207     char const * data() const;
00208     /// Get the size of the buffer.
00209     size_t size() const;
00210     /// Access a character (no bounds check).
00211     char operator[] (int n) const;
00212     //@}
00213     /// @return @c true if @a p points at a character in @a this.
00214     bool contains(char const* p) const;
00215 
00216     /// Set the chunk.
00217     /// Any previous values are discarded.
00218     /// @return @c this object.
00219     self& set(
00220       char const * ptr, ///< Buffer address.
00221       size_t n = 0 ///< Buffer size.
00222     );
00223     /** Set from 2 pointers.
00224         @note This presumes a half open range (start, end]
00225     */
00226     self& set(
00227            char const* start, ///< First valid character.
00228            char const* end ///< First invalid character.
00229            );
00230     /// Reset to empty.
00231     self& reset();
00232 
00233     /** Find a character.
00234         @return A pointer to the first occurrence of @a c in @a this
00235         or @c NULL if @a c is not found.
00236     */
00237     char const* find(char c) const;
00238 
00239     /** Split the buffer on the character at @a p.
00240 
00241         The buffer is split in to two parts and the character at @a p
00242         is discarded. @a this retains all data @b after @a p. The
00243         initial part of the buffer is returned. Neither buffer will
00244         contain the character at @a p.
00245 
00246         This is convenient when tokenizing and @a p points at the token
00247         separator.
00248 
00249         @note If @a *p is in the buffer then @a this is not changed
00250         and an empty buffer is returned. This means the caller can
00251         simply pass the result of @c find and check for an empty
00252         buffer returned to detect no more separators.
00253 
00254         @return A buffer containing data up to but not including @a p.
00255     */
00256     self splitOn(char const* p);
00257 
00258     /** Split the buffer on the character @a c.
00259 
00260         The buffer is split in to two parts and the occurrence of @a c
00261         is discarded. @a this retains all data @b after @a c. The
00262         initial part of the buffer is returned. Neither buffer will
00263         contain the first occurrence of @a c.
00264 
00265         This is convenient when tokenizing and @a c is the token
00266         separator.
00267 
00268         @note If @a c is not found then @a this is not changed and an
00269         empty buffer is returned.
00270 
00271         @return A buffer containing data up to but not including @a p.
00272     */
00273     self splitOn(char c);
00274     /** Get a trailing segment of the buffer.
00275     
00276         @return A buffer that contains all data after @a p.
00277     */
00278     self after(char const* p) const;
00279     /** Get a trailing segment of the buffer.
00280 
00281         @return A buffer that contains all data after the first
00282         occurrence of @a c.
00283     */
00284     self after(char c) const;
00285     /** Remove trailing segment.
00286 
00287         Data at @a p and beyond is removed from the buffer.
00288         If @a p is not in the buffer, no change is made.
00289 
00290         @return @a this.
00291     */
00292     self& clip(char const* p);
00293   };
00294 
00295   // ----------------------------------------------------------
00296   // Inline implementations.
00297 
00298   inline Buffer::Buffer() : _ptr(NULL), _size(0) { }
00299   inline Buffer::Buffer(char* ptr, size_t n) : _ptr(ptr), _size(n) { }
00300   inline Buffer& Buffer::set(char* ptr, size_t n) { _ptr = ptr; _size = n; return *this; }
00301   inline Buffer::Buffer(char* start, char* end) : _ptr(start), _size(end - start) { }
00302   inline Buffer& Buffer::reset() { _ptr = 0; _size = 0 ; return *this; }
00303   inline bool Buffer::operator != (self const& that) const { return ! (*this == that); }
00304   inline bool Buffer::operator != (ConstBuffer const& that) const { return ! (*this == that); }
00305   inline bool Buffer::operator == (self const& that) const {
00306     return _size == that._size &&  _ptr == that._ptr;
00307   }
00308   inline bool Buffer::operator == (ConstBuffer const& that) const {
00309     return _size == that._size &&  _ptr == that._ptr;
00310   }
00311   inline bool Buffer::operator ! () const { return !(_ptr && _size); }
00312   inline Buffer::operator pseudo_bool() const { return _ptr && _size ? &self::operator! : 0; }
00313   inline char Buffer::operator * () const { return *_ptr; }
00314   inline Buffer& Buffer::operator++ () {
00315     ++_ptr;
00316     --_size;
00317     return *this;
00318   }
00319   inline char * Buffer::data() const { return _ptr; }
00320   inline size_t Buffer::size() const { return _size; }
00321 
00322   inline ConstBuffer::ConstBuffer() : _ptr(NULL), _size(0) { }
00323   inline ConstBuffer::ConstBuffer(char const* ptr, size_t n) : _ptr(ptr), _size(n) { }
00324   inline ConstBuffer::ConstBuffer(char const* start, char const* end) : _ptr(start), _size(end - start) { }
00325   inline ConstBuffer::ConstBuffer(Buffer const& that) : _ptr(that._ptr), _size(that._size) { }
00326   inline ConstBuffer& ConstBuffer::set(char const* ptr, size_t n) { _ptr = ptr; _size = n; return *this; }
00327 
00328   inline ConstBuffer& ConstBuffer::set(char const* start, char const* end) {
00329     _ptr = start;
00330     _size = end - start;
00331     return *this;
00332   }
00333 
00334   inline ConstBuffer& ConstBuffer::reset() { _ptr = 0; _size = 0 ; return *this; }
00335   inline bool ConstBuffer::operator != (self const& that) const { return ! (*this == that); }
00336   inline bool ConstBuffer::operator != (Buffer const& that) const { return ! (*this == that); }
00337   inline bool ConstBuffer::operator == (self const& that) const {
00338       return _size == that._size && 0 == memcmp(_ptr, that._ptr, _size);
00339   }
00340   inline ConstBuffer& ConstBuffer::operator = (Buffer const& that) { _ptr = that._ptr ; _size = that._size; return *this; }
00341   inline bool ConstBuffer::operator == (Buffer const& that) const {
00342       return _size == that._size && 0 == memcmp(_ptr, that._ptr, _size);
00343   }
00344   inline bool ConstBuffer::operator ! () const { return !(_ptr && _size); }
00345   inline ConstBuffer::operator pseudo_bool() const { return _ptr && _size ? &self::operator! : 0; }
00346   inline char ConstBuffer::operator * () const { return *_ptr; }
00347   inline ConstBuffer& ConstBuffer::operator++ () {
00348     ++_ptr;
00349     --_size;
00350     return *this;
00351   }
00352   inline ConstBuffer& ConstBuffer::operator += (size_t n) {
00353     _ptr += n;
00354     _size -= n;
00355     return *this;
00356   }
00357   inline char const * ConstBuffer::data() const { return _ptr; }
00358   inline char ConstBuffer::operator[] (int n) const { return _ptr[n]; }
00359   inline size_t ConstBuffer::size() const { return _size; }
00360   inline bool ConstBuffer::contains(char const* p) const {
00361     return _ptr <= p && p < _ptr + _size;
00362   }
00363 
00364   inline ConstBuffer ConstBuffer::splitOn(char const* p) {
00365     self zret; // default to empty return.
00366     if (this->contains(p)) {
00367       size_t n = p - _ptr;
00368       zret.set(_ptr, n);
00369       _ptr = p + 1;
00370       _size -= n + 1;
00371     }
00372     return zret;
00373   }
00374     
00375   inline char const* ConstBuffer::find(char c) const {
00376     return static_cast<char const*>(memchr(_ptr, c, _size));
00377   }
00378 
00379   inline ConstBuffer ConstBuffer::splitOn(char c) {
00380     return this->splitOn(this->find(c));
00381   }
00382 
00383   inline ConstBuffer ConstBuffer::after(char const* p) const {
00384     return this->contains(p) ? self(p + 1, (_size-(p-_ptr))-1) : self();
00385   }
00386   inline ConstBuffer ConstBuffer::after(char c) const {
00387     return this->after(this->find(c));
00388   }
00389   inline ConstBuffer& ConstBuffer::clip(char const* p) {
00390     if (this->contains(p)) {
00391       _size = p - _ptr;
00392     }
00393     return *this;
00394   }
00395 
00396 } // end namespace
00397 
00398 typedef ts::Buffer TsBuffer;
00399 typedef ts::ConstBuffer TsConstBuffer;
00400 
00401 # endif // TS_BUFFER_HEADER

Generated by  doxygen 1.7.1