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: [Fwd: RE: Standard String]
From: Marty Kraimer <[email protected]>
To: [email protected]
Date: Mon, 18 Jul 2005 06:47:10 -0500


-------- Original Message --------
Subject: RE: Standard String
Date: Fri, 15 Jul 2005 12:10:51 -0600
From: Jeff Hill <[email protected]>
To: 'Marty Kraimer' <[email protected]>, 'Andrew Johnson' <[email protected]>



Hi,

Thanks for getting the ball rolling. I will discuss first my interface :-),
and benefit from your perspective. There are comments on your interface at
the end.

I have attached below what is in DA for strings. It would be unfortunate to
discard this design without any discussion given the considerable effort
that went into carefully designing it. This is more than a philosophical
discussion. DA There are capabilities in these interfaces not present in
EpicsString which DA needs in order to implement its support libraries.

I have 4 interfaces: StringSegment, StreamPosition, StreamRead, and
StreamWrite.

Here is a summary:
StringSegment - it has putChar, getChar, compare
StreamPosition - manipulation of a stream (moving around pruning etc)
StreamRead - it has read VF for all fundamental types allowing DA properties
to impact precision etc
StreamWrite - it has write VF for all fundamental types allowing DA
properties to impact precision etc

In the StringSegment interface I am willing to change putChar and getChar to
write / read blocks of characters should we also decide to require UTF-8 as
the only way to do wide characters.
I am flexible about whether these interfaces should or should not be bound
together into a StringSegment by inheritance. There are of course trade offs
associated with either choice.

struct StringSegment : public StreamPosition, public StreamRead, public StreamWrite {
   virtual int getChar () const = 0; // returns 0 when end of string is
reached
   virtual void putChar ( int ) = 0;
   virtual StringDiff compare ( const StringSegment & ) const = 0;
};

struct StreamPosition {
public:
   // 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
   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;
};

struct StreamWrite {
public:
   typedef PropertyCatalog < PropertyViewer > catalog_t;
virtual void write ( const double &, const catalog_t & = catalog_t::voidCatalog ) = 0; virtual void write ( const int &, const catalog_t & = catalog_t::voidCatalog ) = 0; virtual void write ( const long &, const catalog_t & = catalog_t::voidCatalog ) = 0; virtual void write ( const unsigned &, const catalog_t & = catalog_t::voidCatalog ) = 0; virtual void write ( const unsigned long &, const catalog_t & = catalog_t::voidCatalog )
= 0;
virtual void write ( const epicsTime &, const catalog_t & = catalog_t::voidCatalog ) = 0; virtual void write ( const struct StringSegment &, const catalog_t & =
catalog_t::voidCatalog ) = 0;
};


struct StreamRead {
public:
   typedef PropertyCatalog < PropertyViewer > catalog_t;
virtual void read ( double &, const catalog_t & = catalog_t::voidCatalog ) const = 0; virtual void read ( int &, const catalog_t & = catalog_t::voidCatalog ) const = 0; virtual void read ( long &, const catalog_t & = catalog_t::voidCatalog ) const = 0; virtual void read ( unsigned &, const catalog_t & = catalog_t::voidCatalog ) const = 0; virtual void read ( unsigned long &, const catalog_t & = catalog_t::voidCatalog ) const
= 0;
virtual void read ( epicsTime &, const catalog_t & = catalog_t::voidCatalog ) const = 0; virtual void read ( struct StringSegment &, const catalog_t & = catalog_t::voidCatalog )
const = 0;
};

Comments on EpicsString
-----------------------

1) My general comment is that really great designs often get compromised
because they have too much in them. When you add too much then the best
parts of the design are unable to be used in the widest variety of
situations. For example (4) and (6) below.

2) I'm not terribly fond of interfaces that hand off handles to internal
data. I'm not enamored, for example, with "std::string::c_str()" and
"EpicsString::expose". Meyers has a chapter on this. I will add only that
such functions are even worse in multi-threaded systems because there is no
way for the compiler to enforce locking requirements.

3) Is EpicsString::createBuffer assigning a buffer to be used by the string?
It's confusing who manages the storage lifetime. Does ~EpicsString destroy
it with delete (making the class unusable should the buffer not be created
with new), or does the assigner destroy it? See also (3). From my
perspective, the implementation should decide how the string get allocated.

4) The "EpicsBufferCreator *bufferCreator()" seems to require that
EpicsBufferCreator storage management is used. IMHO the core string
interface should not enforce a storage management solution. For example, in
CA I would like for the string to live in protocol buffers. I already have a
storage management solution based on a free lists template that I am quite
happy with. Furthermore, I might have a string constant implementation that
just references the string constant directly throwing an exception should
some author allow a non const ref to it.

5) With regards to epicsString::get and epicsString::put my perception is
that the StreamPosition approach is cleaner compared to passing the extra
offset argument every time?

6) epicsString::hash might be a nice idea, but given that there are multiple
ways to hash a string, and given that we can hash a string using the
interfaces already present, then perhaps epicsString::hash is a pollution of
the core interface. I worry that eventually we will have two different
implementations of hash tables using epicsString. Will there be member
functions hash and hashImproved?
7) This epicsString::isEqual taking an epicsBuffer as an argument is IMHO
not architecturally clean given that A) a string isn't being compared to a
string and B) the storage management and the string are getting mixed up
together.

8) IMHO it is best to remain consistent with the convention of the C/C++
standard library and use size_t for the size of things.

virtual epicsBoolean operator==(const EpicsString &lhs, const
EpicsString &rhs);
virtual epicsBoolean operator!=(const EpicsString &lhs, const
EpicsString &rhs);

Yes, this isn't going to fly with C++ because virtual is only for member
functions.

class epicsStringFactory {
public:
    static EpicsString * create();
    static EpicsString * create(const char *literal);
    static EpicsString * create(const char *bufferType, epicsInt32
capacity);
    static void destroy(EpicsString &);
};

I would return a reference.
I assume that you have a factory creating your particular implementation in
mind. That's fine - there can be different types of factories for different
types of strings, but perhaps the name epicsStringFactory should be
xxxStringFactory.


Jeff

-----Original Message-----
From: Marty Kraimer [mailto:[email protected]]
Sent: Friday, July 15, 2005 7:53 AM
To: Jeff Hill; Andrew Johnson
Subject: Standard String

Hi,

This is an attempt to see if we can have a standard string implemention.

Jeff said that he wanted it to be an interface class.

I have taken epicsString and attempted to redefine it as an interface.
In the following:

1) For now lets not discuss naming convention. That is Epics may not be
the name we use.
2) Lets postone discussion of primitive types.
3) I dont know if what I did for == and != is legal C++

Here is initial proposal

class EpicsString {
public:
    virtual EpicsString& operator=(const EpicsString &rhs) = 0;
    virtual void createBuffer(const char *bufferType,
                              epicsInt32 capacity = 0) = 0;
    virtual void createBuffer(EpicsBufferCreator *creator,
                              epicsInt32 capacity = 0) = 0;
    virtual EpicsBufferCreator *bufferCreator() const = 0;
    virtual void destroyBuffer();
    virtual epicsInt32 get(epicsInt32 offset, epicsInt32 len,
                   epicsOctet *pto) const = 0;
    virtual epicsInt32 put(epicsInt32 offset, epicsInt32 len,
                   const epicsOctet *pfrom) = 0;
    virtual epicsInt32 hash(epicsInt16 nBitsHashIndex) const = 0;

    // These routines are as described for EpicsBuffer
    virtual void reserve(epicsInt32 capacity) = 0;
    virtual epicsInt32 capacity() const = 0;
    virtual void resize(epicsInt32 newsize) = 0;
    virtual epicsInt32 size() const = 0;
    virtual epicsInt32 maxSize() const = 0;
    virtual bool mutable() const = 0;
    virtual bool isEqual(const EpicsBuffer &cmp) const;
    virtual bool isEqual(epicsInt32 offset, epicsInt32 len,
                 const epicsOctet *pdata) const = 0;
    virtual bool expose(epicsInt32 offset, epicsInt32 &len,
                epicsOctet *&pdata) = 0;
    virtual bool expose(epicsInt32 offset, epicsInt32 &len,
                const epicsOctet *&pdata) const = 0;
};

virtual epicsBoolean operator==(const EpicsString &lhs, const
EpicsString &rhs);
virtual epicsBoolean operator!=(const EpicsString &lhs, const
EpicsString &rhs);


class epicsStringFactory {
public:
    static EpicsString * create();
    static EpicsString * create(const char *literal);
    static EpicsString * create(const char *bufferType, epicsInt32
capacity);
    static void destroy(EpicsString &);
};





Replies:
Re: [Fwd: RE: Standard String] Kay-Uwe Kasemir

Navigate by Date:
Prev: [Fwd: Standard String] Marty Kraimer
Next: [Fwd: Re: Standard String] Marty Kraimer
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: [Fwd: Standard String] Marty Kraimer
Next: Re: [Fwd: RE: Standard String] Kay-Uwe Kasemir
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 ·