home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / yeah09.zip / yea.h < prev    next >
C/C++ Source or Header  |  1996-05-25  |  17KB  |  618 lines

  1. #ifndef YEA_H
  2. #define YEA_H
  3.  
  4. //------------------------------------------------------------
  5. //
  6. // Name:     yea.h
  7. // Version:  0.9
  8. // Author:   Björn Fahller.
  9. //
  10. // Copyright (C) Björn Fahller, 1996.
  11. //
  12. // Purpose:  All necessary declarations for YEAH, both the base
  13. //           functionality (class EA and TEA<T>) and the provided
  14. //           implementations of StringEA, SequenceEA and
  15. //           TSequenceEA<T>
  16. //
  17. // History:
  18. //          Ver.  Date         What
  19. //          0.9   1996-05-26   First official release.
  20. //
  21. //------------------------------------------------------------
  22.  
  23.  
  24. class fstreambase;
  25. struct _EAOP2;
  26.  
  27. #include <IString.hpp>
  28. #include <IMap.h>
  29. #include <IKSSet.h>
  30. #include <ISeq.h>
  31. #include <IPtr.h>
  32.  
  33. #include <IExcept.hpp>
  34. #include <strstrea.h>
  35.  
  36. IEXCLASSDECLARE(EAError, IException);
  37. IEXCLASSDECLARE(EAReadError, EAError);
  38. IEXCLASSDECLARE(EAWriteError, EAError);
  39. IEXCLASSDECLARE(EATypeMismatchError, EAError);
  40. IEXCLASSDECLARE(EATSeqeuceEAInstError,EATypeMismatchError);
  41.  
  42. class EA
  43. {
  44. public:
  45.   typedef unsigned short Identifier;
  46.   struct CreatorIdPair;
  47.   typedef IMap<CreatorIdPair, Identifier> CreatorMap;
  48.   typedef EA* (*Creator)(istrstream&, CreatorMap*);
  49.   struct CreatorIdPair {
  50.     Creator c;
  51.     Identifier id;
  52.     IMngPointer<CreatorMap> pSubMap;
  53.  
  54.     CreatorIdPair(const Creator& cc, Identifier i) : c(cc), id(i) {};
  55.     IBoolean operator==(const CreatorIdPair& i) const { return id == i.id; };
  56.     IBoolean operator<(const CreatorIdPair& i) const { return id < i.id; };
  57.   };
  58.   static CreatorMap defaultCreatorMap;
  59.  
  60.   typedef enum { optional = 0, mandatory = 0x80 } Flagset;
  61.   struct Name {
  62.     IString name;
  63.     Flagset flags;
  64.     Name(const IString& n, Flagset f) : name(n), flags(f) {};
  65.     IBoolean operator==(const Name& n) const { return name == n.name; };
  66.     IBoolean operator<(const Name& n) const { return name < n.name; };
  67.   };
  68.   typedef IKeySortedSet<Name, IString> NameSet;
  69.  
  70.   typedef enum {
  71.     ReadError,
  72.     WriteError,
  73.     NoSuchEAError,
  74.     TypeMismatchError
  75.   } Error;
  76.  
  77.   typedef void (*ErrorHandler)(Error, unsigned long);
  78.   static ErrorHandler errorHandler;
  79.  
  80.   static NameSet namesIn(const IString& file);
  81.   static NameSet namesIn(fstreambase& file);
  82.  
  83.   virtual ~EA(void);
  84.  
  85.   Identifier attributeId(void) const { return id; };
  86.   Flagset getFlags(void) const { return (Flagset)flags;};
  87.   void setFlags(Flagset f) { flags = (char)f; };
  88.  
  89.   static EA* newFrom(const IString& file,
  90.                      const IString& name,
  91.                      const CreatorMap& = defaultCreatorMap);
  92.   static EA* newFrom(fstreambase& file,
  93.                      const IString& name,
  94.                      const CreatorMap& = defaultCreatorMap);
  95.  
  96.   static void remove(const IString& file, const IString& name);
  97.   static void remove(fstreambase& file, const IString& name);
  98.  
  99.   void getFrom(const IString& file, const IString& name);
  100.   void getFrom(fstreambase& file, const IString& name);
  101.  
  102.   void storeTo(const IString& file, const IString& name);
  103.   void storeTo(fstreambase& file, const IString& name);
  104.  
  105.   virtual EA* clone(void) const = 0;
  106.   virtual void setCreatorMap(const CreatorMap*) {};
  107. protected:
  108.   EA(Identifier anId);
  109.   EA(const EA&);
  110.   const EA& operator=(const EA&);
  111.  
  112.   static istrstream& read(EA* pea, istrstream& is)
  113.     { return pea->readFrom(is);};
  114.   static ostrstream& write(EA* pea, ostrstream& os)
  115.     { return pea->writeTo(os);};
  116.  
  117.   virtual istrstream& readFrom(istrstream&) = 0;
  118.   virtual ostrstream& writeTo(ostrstream&) = 0;
  119. private:
  120.   void setupFEA(const IString&);
  121.   void feaproc(void);
  122.  
  123.   Identifier id;
  124.   _EAOP2* peaop2;
  125.   char flags;
  126.  
  127.   friend EA* createFrom(_EAOP2*, const EA::CreatorMap&);
  128. };
  129.  
  130. template <class T, EA::Identifier eaid>
  131. class TEA : public EA
  132. {
  133. public:
  134.   enum { id = eaid };
  135.  
  136.   static T* cast(EA*);
  137.   static const T* cast(const EA*);
  138.   virtual ~TEA(void) {};
  139.  
  140.   static void allowDynamic(EA::CreatorMap* pCM = &EA::defaultCreatorMap,
  141.                            const EA::Creator& creator =  createFrom);
  142.   static void disallowDynamic(EA::CreatorMap* pCM = &EA::defaultCreatorMap);
  143. protected:
  144.   TEA(void) : EA(eaid) {};
  145.   TEA(const TEA<T, eaid>&t) : EA(t) {};
  146.   const TEA<T, eaid>& operator=(const TEA<T, eaid>& t)
  147.     { EA::operator=(t); return *this;};
  148. private:
  149.   static EA* createFrom(istrstream&, EA::CreatorMap*);
  150.  
  151.   static NameSet namesIn(const IString& file);
  152.   static NameSet namesIn(fstreambase& file);
  153.   static EA* newFrom(const IString& file,
  154.                      const IString& name,
  155.                      const CreatorMap& = defaultCreatorMap);
  156.   static EA* newFrom(fstreambase& file,
  157.                      const IString& name,
  158.                      const CreatorMap& = defaultCreatorMap);
  159.   static void remove(const IString& file, const IString& name);
  160.   static void remove(fstreambase& file, const IString& name);
  161.   static istrstream& read(EA*,istrstream&);
  162.   static ostrstream& write(EA*,ostrstream&);
  163.   class Creator {};
  164.   class CreatorMap {};
  165.   class CreatorIdPair {};
  166.   class Name {};
  167.   class Error {};
  168.   class ErrorHandler {};
  169.   class Flagset {};
  170.   class Identifier {};
  171.   class NameSet {};
  172. };
  173.  
  174.  
  175. class StringEA : public TEA<StringEA, 0xfffd>,
  176.                  public IString
  177. {
  178. public:
  179.   StringEA(void) : IString() {};
  180.   StringEA(const void* pBuffer, unsigned lenBuffer, char padCharacter = ' ')
  181.     : IString(pBuffer, lenBuffer, padCharacter) {};
  182.   StringEA(const IString& s) : IString(s) {  };
  183.   StringEA(int i) : IString(i) { };
  184.   StringEA(unsigned u) : IString(u) {  };
  185.   StringEA(double d) : IString(d) {  };
  186.   StringEA(char c) : IString(c) {  };
  187.   StringEA(unsigned char uc) : IString(uc) {  };
  188.   StringEA(signed char sc) : IString(sc) {  };
  189.   StringEA(const char* p) : IString(p) {  };
  190.   StringEA(const unsigned char* p) : IString(p) {  };
  191.   StringEA(const signed char* p) : IString(p) {  };
  192.   StringEA(const void* pBuffer1, unsigned lenBuffer1,
  193.            const void* pBuffer2, unsigned lenBuffer2,
  194.            char padCharacter = ' ') : IString(pBuffer1, lenBuffer1,
  195.                                               pBuffer2, lenBuffer2,
  196.                                               padCharacter) {};
  197.   StringEA(const void* pBuffer1, unsigned lenBuffer1,
  198.            const void* pBuffer2, unsigned lenBuffer2,
  199.            const void* pBuffer3, unsigned lenBuffer3,
  200.            char padCharacter = ' ') : IString(pBuffer1, lenBuffer1,
  201.                                               pBuffer2, lenBuffer2,
  202.                                               pBuffer3, lenBuffer3,
  203.                                               padCharacter) {};
  204.  
  205.   StringEA(const StringEA& s) : TEA<StringEA, StringEA::id>(s), IString(s) {};
  206.   virtual ~StringEA(void) {};
  207.  
  208.   const StringEA& operator=(const StringEA& s)
  209.   {
  210.     TEA<StringEA, StringEA::id>::operator=(s);
  211.     IString::operator=(s);
  212.     return *this;
  213.   };
  214.   const StringEA& operator=(const IString& s)
  215.   {
  216.     IString::operator=(s);
  217.     return *this;
  218.   };
  219.  
  220.   StringEA(const IString& filename, const IString& eaname)
  221.     { getFrom(filename, eaname);};
  222.   StringEA(fstreambase& file, const IString& eaname)
  223.     { getFrom(file, eaname); };
  224.  
  225.   virtual StringEA* clone(void) const;
  226.  
  227. protected:
  228.   virtual istrstream& readFrom(istrstream&);
  229.   virtual ostrstream& writeTo(ostrstream&);
  230. private:
  231. };
  232.  
  233. class MTSequenceEA : public TEA< MTSequenceEA, 0xffdf>,
  234.                      public ISequence<EA*>
  235. {
  236. public:
  237.   typedef EA* (*ErrorFunction)(EA::Identifier);
  238.   static ErrorFunction errorFunction;
  239.  
  240.   MTSequenceEA(const EA::CreatorMap* = &EA::defaultCreatorMap);
  241.   MTSequenceEA(const MTSequenceEA& mvea);
  242.   MTSequenceEA(const ISequence<EA*>&,
  243.                const EA::CreatorMap* = &EA::defaultCreatorMap);
  244.   MTSequenceEA(const IString& filename,
  245.                const IString& eaname,
  246.                const EA::CreatorMap* = &EA::defaultCreatorMap);
  247.   MTSequenceEA(fstreambase& file,
  248.                const IString& eaname,
  249.                const EA::CreatorMap* = &EA::defaultCreatorMap);
  250.  
  251.   const MTSequenceEA& operator=(const MTSequenceEA& mvea);
  252.   const MTSequenceEA& operator=(const ISequence<EA*>& isea);
  253.   virtual ~MTSequenceEA(void);
  254.  
  255.   unsigned short getCodePage(void) const { return cp; };
  256.   void setCodePage(unsigned short p) { cp = p;};
  257.  
  258.   const EA::CreatorMap* pCreatorMap;
  259.  
  260.   virtual MTSequenceEA* clone(void) const;
  261.   virtual void setCreatorMap(const EA::CreatorMap* pCM)
  262.     { pCreatorMap = pCM; };
  263. protected:
  264.   virtual istrstream& readFrom(istrstream&);
  265.   virtual ostrstream& writeTo(ostrstream&);
  266. private:
  267.   unsigned short cp;
  268. };
  269.  
  270. class SequenceEA : public TEA<SequenceEA, 0xffde>
  271. {
  272. public:
  273.   static EA* (*errorFunction)(EA::Identifier);
  274.  
  275.   virtual ~SequenceEA(void);
  276.  
  277.   unsigned short getCodePage(void) const { return cp; };
  278.   void setCodePage(unsigned short p) { cp = p;};
  279.  
  280.   EA::Identifier contentId(void) const
  281.     { return contentType; };
  282.   virtual void setCreatorMap(const EA::CreatorMap* pCM)
  283.     { pCreatorMap = pCM; };
  284.   virtual SequenceEA* clone(void) const { return 0; };
  285. protected:
  286.   SequenceEA(EA::Identifier id,
  287.              EA::CreatorMap* pCM = &EA::defaultCreatorMap);
  288.   SequenceEA(const SequenceEA& mvea);
  289.  
  290.   const SequenceEA& operator=(const SequenceEA& mvea);
  291.  
  292.   virtual ostrstream& writeTo(ostrstream& os) { return os;};
  293.   virtual istrstream& readFrom(istrstream& is) { return is;};
  294.  
  295.   const EA::CreatorMap* pCreatorMap;
  296.  
  297. private:
  298.   static void disallowDynamic(EA::CreatorMap* pCM = &EA::defaultCreatorMap);
  299.  
  300.   static EA* createFrom(istrstream&, EA::CreatorMap*);
  301.  
  302.   unsigned short cp;
  303.   EA::Identifier contentType;
  304.  
  305.   SequenceEA(void) {};
  306.   friend EA* TEA<SequenceEA, id>::createFrom(istrstream&, EA::CreatorMap*);
  307. protected:
  308.   static void allowDynamic(EA::CreatorMap* pCM,
  309.                            const EA::Creator& creator = createFrom)
  310.     { TEA<SequenceEA, SequenceEA::id>::allowDynamic(pCM, creator);};
  311. };
  312.  
  313. template <class ET>
  314. class TSequenceEA : public SequenceEA,
  315.                     public ISequence<ET*>
  316. {
  317. public:
  318.   enum { elementId = ET::id };
  319.  
  320.   static TSequenceEA<ET>* cast(EA*);
  321.   static const TSequenceEA<ET>* cast(const EA*);
  322.  
  323.   TSequenceEA(EA::CreatorMap* pCM = &EA::defaultCreatorMap)
  324.     : SequenceEA(ET::id, pCM) {};
  325.   TSequenceEA(const TSequenceEA<ET>& t);
  326.   TSequenceEA(const ISequence<ET*>& t,
  327.               EA::CreatorMap* pCM = &EA::defaultCreatorMap)
  328.     : SequenceEA(ET::id, pCM), ISequence<ET*>(t) {};
  329.   TSequenceEA(const IString& filename,
  330.               const IString& eaname,
  331.               EA::CreatorMap* pCM = &EA::defaultCreatorMap)
  332.     : SequenceEA(ET::id,pCM) { getFrom(filename, eaname); };
  333.   TSequenceEA(fstreambase& file,
  334.               const IString& eaname,
  335.               EA::CreatorMap* pCM = &EA::defaultCreatorMap)
  336.     : SequenceEA(ET::id, pCM) { getFrom(file, eaname);};
  337.   const TSequenceEA<ET>& operator=(const TSequenceEA<ET>& t);
  338.   const TSequenceEA<ET>& operator=(const ISequence<ET*>& t);
  339.  
  340.   virtual ~TSequenceEA(void);
  341.  
  342.   static void allowDynamic(EA::CreatorMap* pCM = &EA::defaultCreatorMap,
  343.                            const EA::Creator& creator = createFrom);
  344.   static void disallowDynamic(EA::CreatorMap* pCM = &EA::defaultCreatorMap);
  345.  
  346.  
  347.   virtual TSequenceEA<ET>* clone(void) const;
  348. protected:
  349.   virtual ostrstream& writeTo(ostrstream& os);
  350.   virtual istrstream& readFrom(istrstream& is);
  351. private:
  352.   static EA* createFrom(istrstream&, EA::CreatorMap*);
  353. };
  354.  
  355. template <class ET>
  356. void TSequenceEA<ET>::allowDynamic(EA::CreatorMap* pCM,
  357.                                    const EA::Creator& creator)
  358. {
  359.   EA::CreatorMap::Cursor cursor(*pCM);
  360.   if (!pCM->locateElementWithKey(SequenceEA::id, cursor))
  361.   {
  362.     SequenceEA::allowDynamic(pCM);
  363.     pCM->locateElementWithKey(SequenceEA::id,cursor);
  364.   }
  365.   EA::CreatorIdPair& cidp = pCM->elementAt(cursor);
  366.   if (cidp.pSubMap == 0)
  367.   {
  368.     cidp.pSubMap = IMngPointer<EA::CreatorMap>(new EA::CreatorMap,
  369.                                                IExplicitInit());
  370.   }
  371.   ET::allowDynamic(cidp.pSubMap, creator);
  372. }
  373.  
  374. template <class ET>
  375. void TSequenceEA<ET>::disallowDynamic(EA::CreatorMap* pCM)
  376. {
  377.   EA::CreatorIdPair& cidp = pCM->elementWithKey(SequenceEA::id);
  378.   ET::disallowDynamic(cidp.pSubMap);
  379.   if (cidp.pSubMap->numberOfElements() == 0)
  380.   {
  381.     pCM->removeElementWithKey(SequenceEA::id);
  382.   }
  383. }
  384.  
  385.  
  386. inline
  387. const EA::Identifier& key(const EA::CreatorIdPair& p)
  388. {
  389.   return p.id;
  390. }
  391.  
  392. inline
  393. const IString& key(const EA::Name& n)
  394. {
  395.   return n.name;
  396. }
  397.  
  398. template <class T, EA::Identifier eaid>
  399. void TEA<T, eaid>::allowDynamic(EA::CreatorMap* pCM,
  400.                                 const EA::Creator& creator)
  401. {
  402.   pCM->add(EA::CreatorIdPair(creator, eaid));
  403. }
  404.  
  405. template <class T, EA::Identifier eaid>
  406. void TEA<T, eaid>::disallowDynamic(EA::CreatorMap* pCM)
  407. {
  408.   pCM->removeElementWithKey(eaid);
  409. }
  410.  
  411.  
  412. template <class T, EA::Identifier eaid>
  413. EA* TEA<T, eaid>::createFrom(istrstream& is, EA::CreatorMap*)
  414. {
  415.   EA* pt = new T;
  416.   return pt;
  417. }
  418.  
  419.  
  420. template <class T, EA::Identifier eaid>
  421. const T* TEA<T, eaid>::cast(const EA* pea)
  422. {
  423.   if (!pea)
  424.   {
  425.     return 0;
  426.   }
  427.   if (pea->attributeId() == eaid)
  428.   {
  429.     return (const T*)(pea);
  430.   }
  431.   return 0;
  432. }
  433.  
  434. template <class T, EA::Identifier eaid>
  435. T* TEA<T, eaid>::cast(EA* pea)
  436. {
  437.   if (!pea)
  438.   {
  439.     return 0;
  440.   }
  441.   if (pea->attributeId() == eaid)
  442.   {
  443.     return (T*)(pea);
  444.   }
  445.   return 0;
  446. }
  447.  
  448.  
  449. template <class ET>
  450. EA* TSequenceEA<ET>::createFrom(istrstream& is, EA::CreatorMap*)
  451. {
  452.   TSequenceEA<ET>* pct = new TSequenceEA<ET>;
  453.   return pct;
  454. }
  455.  
  456. template <class ET>
  457. TSequenceEA<ET>::TSequenceEA(const TSequenceEA<ET>& t)
  458.   : SequenceEA(t)
  459. {
  460.   Cursor c(t);
  461.   forCursor (c)
  462.   {
  463.     addAsLast(c.element()->clone());
  464.   }
  465. }
  466.  
  467. template <class ET>
  468. TSequenceEA<ET>::TSequenceEA(const ISequence<ET*>& t,
  469.                              EA::CreatorMap* pCM)
  470.   : SequenceEA(ET::id, pCM)
  471. {
  472.   Cursor c(t);
  473.   forCursor (c)
  474.   {
  475.     addAsLast(c.element()->clone());
  476.   }
  477. }
  478.  
  479. template <class ET>
  480. const TSequenceEA<ET>& TSequenceEA<ET>::operator=(const TSequenceEA<ET>& t)
  481. {
  482.   if (&t != this)
  483.   {
  484.     while (numberOfElements())
  485.     {
  486.       EA* p = firstElement();
  487.       removeFirst();
  488.       delete p;
  489.     }
  490.     SequenceEA::operator=(t);
  491.     Cursor c(t);
  492.     forCursor (c)
  493.     {
  494.       addAsLast(c.element()->clone());
  495.     }
  496.   }
  497.   return *this;
  498. };
  499.  
  500. template <class ET>
  501. const TSequenceEA<ET>& TSequenceEA<ET>::operator=(const ISequence<ET*>& t)
  502. {
  503.   if (&t != (const ISequence<ET*>*)this)
  504.   {
  505.     while (numberOfElements())
  506.     {
  507.       EA* p = firstElement();
  508.       removeFirst();
  509.       delete p;
  510.     }
  511.     Cursor c(t);
  512.     forCursor (c)
  513.     {
  514.       addAsLast(c.element()->clone());
  515.     }
  516.   }
  517.   return *this;
  518. };
  519.  
  520.  
  521. template <class ET>
  522. TSequenceEA<ET>::~TSequenceEA(void)
  523. {
  524.   while (numberOfElements() > 0)
  525.   {
  526.     EA* pea = firstElement();
  527.     removeFirst();
  528.     delete pea;
  529.   }
  530. }
  531.  
  532. template <class ET>
  533. TSequenceEA<ET>* TSequenceEA<ET>::cast(EA* pea)
  534. {
  535.   SequenceEA* psea = SequenceEA::cast(pea);
  536.   if (psea == 0)
  537.   {
  538.     return 0;
  539.   }
  540.   if (psea->contentId() == ET::id)
  541.   {
  542.     return (TSequenceEA<ET>*)(psea);
  543.   }
  544.   return 0;
  545. }
  546.  
  547. template <class ET>
  548. const TSequenceEA<ET>* TSequenceEA<ET>::cast(const EA* pea)
  549. {
  550.   const SequenceEA* psea = SequenceEA::cast(pea);
  551.   if (psea == 0)
  552.   {
  553.     return 0;
  554.   }
  555.   if (psea->contentId() == ET::id)
  556.   {
  557.     return (const TSequenceEA<ET>*)(psea);
  558.   }
  559.   return 0;
  560. }
  561.  
  562. template <class ET>
  563. istrstream& TSequenceEA<ET>::readFrom(istrstream& is)
  564. {
  565.   unsigned short cp;
  566.   is.read((char*)(&cp), sizeof(cp));
  567.   setCodePage(cp);
  568.   unsigned short entries;
  569.   is.read((char*)(&entries), sizeof(entries));
  570.   EA::Identifier identifier;
  571.   is.read((char*)(&identifier), sizeof(identifier));
  572.   if (identifier != ET::id)
  573.   {
  574.     EA::errorHandler(TypeMismatchError, identifier);
  575.     return is;
  576.   }
  577.   for (unsigned count=0; count < entries; ++count)
  578.   {
  579.     ET* pt = new ET;
  580.     pt->setCreatorMap(pCreatorMap);
  581.     EA::read(pt, is);
  582.     add(pt);
  583.   }
  584.  
  585.   return is;
  586. }
  587.  
  588. template <class ET>
  589. ostrstream& TSequenceEA<ET>::writeTo(ostrstream& os)
  590. {
  591.   unsigned short cp = getCodePage();
  592.   os.write((char*)(&cp), sizeof(cp));
  593.   unsigned short entries = (unsigned short)numberOfElements();
  594.   os.write((char*)(&entries), sizeof(entries));
  595.   EA::Identifier identifier = ET::id;
  596.   os.write((char*)(&identifier), sizeof(identifier));
  597.   Cursor c(*this);
  598.   forCursor(c)
  599.   {
  600.     ET* pet = c.element();
  601.     EA::write(pet, os);
  602.   }
  603.  
  604.   return os;
  605. }
  606.  
  607. template <class ET>
  608. TSequenceEA<ET>* TSequenceEA<ET>::clone(void) const
  609. {
  610.   return new TSequenceEA<ET>(*this);
  611. }
  612.  
  613. #pragma define(IKeySortedSet<EA::Name, IString>)
  614.  
  615.  
  616. #endif // YEA_H
  617.  
  618.