Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

LinearExtent.h

00001 #ifndef _STR_LinearExtent_H_  // -*-c++-*-
00002 
00003 /*
00004  * Copyright (C) 1991-9 Eric M. Hopper <hopper@omnifarious.mn.org>
00005  * 
00006  *     This program is free software; you can redistribute it and/or modify it
00007  *     under the terms of the GNU Lesser General Public License as published
00008  *     by the Free Software Foundation; either version 2 of the License, or
00009  *     (at your option) any later version.
00010  * 
00011  *     This program is distributed in the hope that it will be useful, but
00012  *     WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  *     Lesser General Public License for more details.
00015  * 
00016  *     You should have received a copy of the GNU Lesser General Public
00017  *     License along with this program; if not, write to the Free Software
00018  *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00019  */
00020 
00021 #ifdef __GNUG__
00022 #  pragma interface
00023 #endif
00024 
00025 /* $Header: /home/hopper/src/cvs/C++/StrMod/StrMod/LinearExtent.h,v 1.12 2002/09/16 02:21:01 hopper Exp $ */
00026 
00027 // For a log, see ../ChangeLog
00028 //
00029 // Revision 1.4  1999/09/16 01:37:17  hopper
00030 // Added this function to help write the telnet code.
00031 //
00032 // Revision 1.3  1996/09/21 18:40:04  hopper
00033 // Changed LinearExtent::SubExtent_eq to return const LinearExtent & to
00034 // be more like x= operators.
00035 //
00036 // Revision 1.2  1996/06/29 06:24:25  hopper
00037 // Added const in places that needed it.
00038 // Added new SubExtent_eq for in-place sub-extension calculation.
00039 // Added declaration for stream output operator.
00040 //
00041 // Revision 1.1  1996/05/08 11:16:53  hopper
00042 // First functional revision
00043 //
00044 
00045 #include <iosfwd>  // For ostream
00046 #include <climits>
00047 
00048 #define _STR_LinearExtent_H_
00049 
00050 namespace strmod {
00051 namespace strmod {
00052 
00053 /** \class LinearExtent LinearExtent.h StrMod/LinearExtent.h
00054  * A simple class describing a subrange of a contiguous sequence.
00055  *
00056  * This class sees such a subrange as beginning at an offset, and proceeding
00057  * for some number of items.
00058  *
00059  * The results of using objects of this class when Offset() + Length() >
00060  * full_extent.Length() are undefined.  To be safe, you should always use
00061  * extents to refer to things who's absolute length is < UINT_MAX
00062  */
00063 class LinearExtent {
00064  public:
00065    typedef unsigned int off_t;  ///< Type for expressing the offset.
00066    typedef unsigned int length_t;  ///< Type for expressing the length.
00067    static const off_t OFFSET_MAX = UINT_MAX;
00068    static const length_t LENGTH_MAX = UINT_MAX;
00069 
00070    /**
00071     * A constant for an infinite length extent starting at offset 0.
00072     *
00073     * Not actually _infinite_, but of length UINT_MAX.
00074     */
00075    static const LinearExtent full_extent;
00076 
00077    //! A zero length extent starting at offset 0.
00078    inline LinearExtent();
00079    //! An extent starting at \c offset having length \c length.
00080    inline LinearExtent(off_t offset, length_t length);
00081    //! Not meant to be inherited from, so not virtual.
00082    inline ~LinearExtent();
00083 
00084    //! Retrieve offset.
00085    inline off_t Offset() const;
00086    //! Set offset.
00087    inline void Offset(off_t new_off);
00088    //! Retrieve length.
00089    inline length_t Length() const;
00090    //! Set length.
00091    inline void Length(length_t new_length);
00092 
00093    /** \name STL Transforms
00094     * These functions translate the extent coordinate system of offset, length
00095     * into the STL coordinate system of [begin, end).
00096     */
00097    //@{
00098    //! Offset of beginning of extent (for STL like algorithms).  Same as
00099    //! Offset().
00100    inline off_t beginOffset() const;
00101    //! Offset of end of extent (for STL like algorithms).  Same as Offset() +
00102    //! Length()  (undefined when Offset() + Length() > full_extent.Length()
00103    inline off_t endOffset() const;
00104    //@}
00105 
00106    /** Given two extents, what is extent is common to both?
00107     *
00108     * If there is no intersection, this will return an extent who's Offset() is
00109     * undefined, and who's Length() is 0.
00110     *
00111     * This operator commutes.  a.intersection(b) is guaranteed to yield the
00112     * exact same results as b.intersection(a) in all cases except where
00113     * a.Offset() + a.Length() > full_extent.Length(), or b.Offset() + b.Length()
00114     * > full_extent.Length().  The results of intersection in the latter two
00115     * cases are undefined.
00116     */
00117    inline const LinearExtent intersection(const LinearExtent &other) const;
00118 
00119    /** \name Extent as a Moveable Tape Measure
00120     * To understand what all these functions do, it's helpful to keep an image
00121     * of the full contiguous sequence in mind, whith the LinearExtent acting
00122     * as a sort of tape measure stretched along some part of the sequence.
00123     */
00124    //@{
00125    //! Lengthen an extent by lowering the offset and increasing the length by
00126    //! the same amount.
00127    void LengthenLeft(length_t by);
00128    //! Lengthen an extent merely by adding to the length.
00129    inline void LengthenRight(length_t by);
00130 
00131    //! Shorten an extent by increasing its offset and decreasing its length by
00132    //! the same amount.
00133    void ShortenLeft(length_t by);
00134    //! Shorten an extent by simply decreasing its length.
00135    inline void ShortenRight(length_t by);
00136 
00137    //! Add to the offset.
00138    inline void MoveRight(off_t by);
00139    //! Subtract from the offset.
00140    inline void MoveLeft(off_t by);
00141    //@}
00142 
00143    //! Translate a subextent into the underlying sequence's coordinate space.
00144    const LinearExtent SubExtent(const LinearExtent &extent) const;
00145    //! This function is to SubExtent() as += is to +.
00146    const LinearExtent &SubExtent_eq(const LinearExtent &extent);
00147 
00148  private:
00149    off_t m_offset;
00150    length_t m_length;
00151 };
00152 
00153 //! Print out a LinearExtent on an iostream.
00154 ::std::ostream &operator <<(::std::ostream &os, const LinearExtent &ext);
00155 
00156 //-----------------------------inline functions--------------------------------
00157 
00158 inline LinearExtent::LinearExtent() : m_offset(0), m_length(0)
00159 {
00160 }
00161 
00162 inline LinearExtent::LinearExtent(off_t offset, length_t length)
00163      : m_offset(offset), m_length(length)
00164 {
00165 }
00166 
00167 inline LinearExtent::~LinearExtent()
00168 {
00169 }
00170 
00171 inline LinearExtent::off_t LinearExtent::Offset() const
00172 {
00173    return(m_offset);
00174 }
00175 
00176 inline void LinearExtent::Offset(LinearExtent::off_t new_off)
00177 {
00178    m_offset = new_off;
00179 }
00180 
00181 inline LinearExtent::length_t LinearExtent::Length() const
00182 {
00183    return(m_length);
00184 }
00185 
00186 inline void LinearExtent::Length(LinearExtent::length_t new_length)
00187 {
00188    m_length = new_length;
00189 }
00190 
00191 inline LinearExtent::off_t LinearExtent::beginOffset() const
00192 {
00193     return(Offset());
00194 }
00195 
00196 inline LinearExtent::off_t LinearExtent::endOffset() const
00197 {
00198     return(Offset() + Length());
00199 }
00200 
00201 inline const LinearExtent
00202 LinearExtent::intersection(const LinearExtent &other) const
00203 {
00204    off_t intstart = (Offset() > other.Offset()) ? Offset() : other.Offset();
00205    off_t myend = endOffset();
00206    off_t otherend = other.endOffset();
00207    off_t intend = (myend < otherend) ? myend : otherend;
00208    return(LinearExtent(intstart,
00209                        (intend <= intstart) ? 0 : (intend - intstart)));
00210 }
00211 
00212 inline void LinearExtent::MoveRight(LinearExtent::off_t by)
00213 {
00214    if ((LENGTH_MAX - endOffset()) >= by) {
00215       m_offset += by;
00216    } else {
00217       m_offset = LENGTH_MAX - Length();
00218    }
00219 }
00220 
00221 inline void LinearExtent::MoveLeft(LinearExtent::off_t by)
00222 {
00223    if (by < m_offset) {
00224       m_offset -= by;
00225    } else {
00226       m_offset = 0;
00227    }
00228 }
00229 
00230 inline void LinearExtent::LengthenRight(length_t by)
00231 {
00232    if ((LENGTH_MAX - m_length) >= by) {
00233       m_length += by;
00234    } else {
00235       m_length = LENGTH_MAX;
00236    }
00237 }
00238 
00239 inline void LinearExtent::ShortenRight(length_t by)
00240 {
00241    if (m_length >= by) {
00242       m_length -= by;
00243    } else {
00244       m_length = 0;
00245    }
00246 }
00247 
00248 inline bool operator ==(const LinearExtent &a, const LinearExtent &b)
00249 {
00250    return (a.Offset() == b.Offset()) && (a.Length() == b.Length());
00251 }
00252 
00253 inline bool operator !=(const LinearExtent &a, const LinearExtent &b)
00254 {
00255    return !(a == b);
00256 }
00257 
00258 }  // namespace strmod
00259 }  // namespace strmod
00260 
00261 #endif

Generated on Wed Jan 29 00:32:44 2003 for libNet by doxygen1.3-rc1