EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024  Index 2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: RE: data access structures, strings
From: "Jeff Hill" <[email protected]>
To: "'Andrew Johnson'" <[email protected]>, "'Kay-Uwe Kasemir'" <[email protected]>
Cc: <[email protected]>
Date: Tue, 27 Sep 2005 10:40:30 -0600

For what its worth, here is the preexisting StringSegment interface which is
similar to Andrew's string interface in many ways, but is stream based. So
here is an opportunity to decide which you like better StringEditor or
StringSegment. 

If we decide that wide characters can only be UTF8 then putChar and getChar
below could be changed to include a length argument.

The StringSegment interface assumes that, when performing string to numeric
conversions, all formatting information comes from a PropertyCatalog. For
example, the precision property would be used.

The StringSegment interface assumes that it's more efficient to do in-place
string conversion instead of copying out to a contiguous scratchpad in order
to do numeric to string conversion with the C standard library. Therefore,
numeric to string conversion is deferred to the string accessor object (or
its vassal).

The StringSegment interface includes a stream interface. If two users have a
StringSegment interface to the same string they would of course have
independent string accessor objects conforming to StringSegment, but
maintaining independent string stream (iterator) state.


enum stringDiff { sdBelow, sdEqual, sdAbove };

struct StringSegment : 
    public streamPosition, 
    public streamRead,
    public streamWrite 
{
    virtual unsigned getChar () const  = 0;
    virtual void putChar ( unsigned outChar ) = 0;
    virtual stringDiff compare ( const StringSegment & ) const  = 0;
};

struct streamPosition : vdtor {
    // returns the number of elements in the stream
    virtual size_t length () const = 0;
    // get current position
    virtual size_t position () const = 0;
    // set the current stream position
    // (returns false if request cant be satisfied)
    virtual void movePosition ( size_t newPosition ) = 0;
    // returns the number of immediately viewable 
    // elements after the current position.
    virtual size_t viewable () = 0;
    // remove all elements from current position to the 
    // end of the stream
    virtual void prune () = 0;
    // flush cached output entries 
    virtual void flush () = 0;
};

epicsShareExtern struct PropertyCatalog & voidCatalog;

struct streamWrite : vdtor {
    virtual void write ( 
        const double &, const PropertyCatalog & = voidCatalog ) = 0;
    virtual void write ( 
        const int &, const PropertyCatalog & = voidCatalog ) = 0;
    virtual void write ( 
        const long &, const PropertyCatalog & = voidCatalog ) = 0;
    virtual void write ( 
        const unsigned &, const PropertyCatalog & = voidCatalog ) = 0;
    virtual void write ( 
        const unsigned long &, const PropertyCatalog & = voidCatalog ) = 0;
    virtual void write ( 
        const epicsTime &, const PropertyCatalog & = voidCatalog ) = 0;
    virtual void write ( 
        const struct StringSegment &, const PropertyCatalog & = voidCatalog
) = 0;
};

struct streamRead : vdtor {
    virtual void read ( 
        double &, const PropertyCatalog & = voidCatalog ) const = 0;
    virtual void read ( 
        int &, const PropertyCatalog & = voidCatalog ) const = 0;
    virtual void read ( 
        long &, const PropertyCatalog & = voidCatalog ) const = 0;
    virtual void read ( 
        unsigned &, const PropertyCatalog & = voidCatalog ) const = 0;
    virtual void read ( 
        unsigned long &, const PropertyCatalog & = voidCatalog ) const = 0;
    virtual void read ( 
        epicsTime &, const PropertyCatalog & = voidCatalog ) const = 0;
    virtual void read ( 
        struct StringSegment &, const PropertyCatalog & = voidCatalog )
const = 0;
};


// First base classes with virtual functions should have a 
// virtual destructor, but should this destructor be inline. 
// That question depends on the state of C++ compiler technology. 
// To allow that issue to be maintained in only one place,
// and to avoid needing to fiddle with that issue in 100 places 
// I am deriving interface classes that do not derive from other 
// interface classes from vdtor.
struct vdtor {
    virtual ~vdtor () = 0;
};

inline vdtor::~vdtor () {}

> -----Original Message-----
> From: Andrew Johnson [mailto:[email protected]]
> Sent: Monday, September 26, 2005 5:08 PM
> To: Kay-Uwe Kasemir
> Cc: Jeff Hill; [email protected]
> Subject: Re: data access structures, strings
> 
> Kay-Uwe Kasemir wrote:
> >
> > When do you think the stringSegment will be usable?
> 
> I'm hoping Jeff will replace his stringSegment in dataAccess with the
> string API that I've been working on.  These are the current base
> classes; there will non-member non-friend functions for doing numeric
> conversions, and other convenience functions like operator==:
> 
>   class StringReader {
>   public:
>       // String length
>       virtual size_t size() const = 0;
> 
>       // Comparison functions
>       virtual bool equals(const StringReader & rhs) const = 0;
>       virtual bool contains(const StringReader & rhs, size_t pos) const =
> 0;
>       virtual bool contains(const char *str, size_t len, size_t pos = 0)
> const = 0;
> 
>       // Individual character access
>       virtual char operator[] (size_t pos) const = 0;
> 
>       // Copy out to buffer, no terminator
>       virtual size_t extract(char *buf, size_t cap, size_t pos = 0)
> const = 0;
>   };
> 
>   class StringEditor :
>       public StringReader {
>   public:
>       // Length adjustment
>       virtual void resize(size_t len, char fill = '\0') = 0;
> 
>       // Buffer storage management
>       virtual size_t capacity() const = 0;
>       virtual void reserve(size_t cap) = 0;
> 
>       // Assignment
>       virtual void assign(const StringReader & src, size_t pos = 0) = 0;
>       virtual void assign(const char *str, size_t len) = 0;
> 
>       // Append
>       virtual void append(char chr) = 0;
>       virtual void append(const StringReader & src, size_t pos = 0) = 0;
>       virtual void append(const char *str, size_t len) = 0;
> 
>       // Overloaded operators
>       StringEditor& operator = (const StringReader &rhs);
>       StringEditor& operator = (const char *rhs);
>       StringEditor& operator += (char chr);
>       StringEditor& operator += (const StringReader &rhs);
>       StringEditor& operator += (const char *rhs);
>   };
> 
> I have three tested concrete implementations which use contiguous buffers:
> 
> ConstString : Concrete implementation of StringReader for wrapping
> "string literals" and other const char* buffers.
> 
> FixedString<int> : Template implementation of StringEditor, using a
> fixed size buffer which is a class data member (no new/delete).  The
> size is set at compile time by the template parameter, so this is a safe
> version of a regular char[] buffer.
> 
> VariableString : Implementation of StringEditor, using new[] and
> delete[] to provide a contiguous buffer which increases in size as
> needed by multiples of 2.
> 
> All the above implementations maintain a hidden \0 terminator byte after
> the end of the string data, and also provide a c_str() function (not
> part of the base class interface) for compatibility with C functions. If
> you created the string, you get to look inside the box; if you're given
> a StringReader or even a StringEditor you don't, and you'll have to copy
> it to pass it to printf().
> 
> I am also working on another implementation using multiple fixed size
> buffer segments that are allocated from and returned to a freelist. This
> is the implementation I'm hoping we'll use in the IOC database for
> string fields as it solves the memory fragmentation problem.
> 
> 
> Comments and questions on the above are welcome.
> 
> - Andrew
> --
> English probably arose from Normans trying to pick up Saxon girls.



References:
Re: data access structures, strings Andrew Johnson

Navigate by Date:
Prev: Re: data access structures, strings Kay-Uwe Kasemir
Next: RE: data access structures, strings Jeff Hill
Index: 2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: Re: data access structures, strings Andrew Johnson
Next: RE: data access structures, strings Jeff Hill
Index: 2002  2003  2004  <20052006  2007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 02 Feb 2012 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·