Make your own free website on Tripod.com
Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

element.h

Go to the documentation of this file.
00001 #ifndef FILE_ELEMENT_H
00002 #define FILE_ELEMENT_H
00003 
00004 #include <string>
00005 #include <map>
00006 #include <vector>
00007 #include <memory>
00008 #include <iostream>
00009 #include "func.h"
00010 
00011 class Element
00012 {
00013 public:
00014         Element(const char* name);
00015         /**
00016          * Assign position to this element
00017          * Return next pos
00018          */
00019         virtual int AssignPos(int currPos)=0;
00020         int GetLength() const { return len; }
00021         virtual void Output(ostream& out,Element* sel)=0;
00022 protected:
00023         std::string name;
00024         int position;
00025         int len;
00026 };
00027 
00028 Element::Element(const char* _name):name(_name),position(-1),len(-1)
00029 {
00030 }
00031 
00032 class Elements
00033 {
00034 public:
00035         void Add(Element* e);
00036         ~Elements();
00037 private:
00038         friend class ComplexElement;
00039         typedef std::vector<Element*> TV;
00040         TV v;
00041 };
00042 
00043 Elements::~Elements()
00044 {
00045         for(TV::iterator i=v.begin(); i != v.end(); ++i)
00046                 delete (*i);
00047 }
00048 
00049 void Elements::Add(Element* e)
00050 {
00051         v.push_back(e);
00052 }
00053 
00054 class ComplexElement: public Element
00055 {
00056 public:
00057         ComplexElement(const char* name,enum ComplexType type,
00058                         Elements* elements);
00059         ~ComplexElement();
00060         static ComplexElement* Find(const char* name);
00061         int AssignPos(int currPos);
00062         void Process(ostream& out);
00063         void Output(ostream& out,Element* sel);
00064 private:
00065         enum ComplexType type;
00066         std::auto_ptr<Elements> elements;
00067         static std::map<std::string,ComplexElement*> all;
00068 };
00069 
00070 std::map<std::string,ComplexElement*> ComplexElement::all;
00071 
00072 ComplexElement::ComplexElement(const char* _name,enum ComplexType _type,
00073                         Elements* _elements):
00074 Element(_name),type(_type),elements(_elements)
00075 {
00076         all[name] = this;
00077 }
00078 
00079 ComplexElement::~ComplexElement()
00080 {
00081         all.erase(name);
00082 }
00083 
00084 ComplexElement* ComplexElement::Find(const char* name)
00085 {
00086         if (all.find(name) == all.end())
00087                 return NULL;
00088         return all[name];
00089 }
00090 
00091 int ComplexElement::AssignPos(int currPos)
00092 {
00093         position = currPos;
00094         
00095         Elements::TV::iterator i = elements->v.begin();
00096         Elements::TV::iterator end = elements->v.end();
00097         int pos = currPos;
00098         int maxPos = currPos;
00099         for(; i!= end;++i)
00100         {
00101                 pos = (*i)->AssignPos(pos);
00102                 if (type==Union)
00103                 {
00104                         // union, calc maximun for result and then reset
00105                         maxPos = maxPos > pos ? maxPos : pos;
00106                         pos = currPos;
00107                 }
00108                 else
00109                 {
00110                         maxPos = pos;
00111                 }
00112         }
00113         
00114         len = maxPos - position;
00115         
00116         return maxPos;
00117 }
00118 
00119 void ComplexElement::Output(ostream& out,Element* sel)
00120 {
00121         Elements::TV::iterator i = elements->v.begin();
00122         Elements::TV::iterator end = elements->v.end();
00123         out << "Complex " << name << " pos:" << position << " len:" << len << " {" << endl;
00124         for(; i!= end;++i)
00125         {
00126                 (*i)->Output(out,NULL);
00127         }
00128         out << "};" << endl;
00129 }
00130 
00131 void ComplexElement::Process(ostream& out)
00132 {
00133         AssignPos(0);
00134         Output(out,NULL);
00135 }
00136 
00137 class DefinedElement: public Element
00138 {
00139 public:
00140         DefinedElement(const char* name,ComplexElement* type,int n);
00141         int AssignPos(int currPos);
00142         void Output(ostream& out,Element* sel);
00143 private:
00144         ComplexElement* type;
00145         int n;
00146 };
00147 
00148 DefinedElement::DefinedElement(const char* name,ComplexElement* _type,int _n):
00149         Element(name),type(_type),n(_n)
00150 {
00151         
00152 }
00153 
00154 int DefinedElement::AssignPos(int currPos)
00155 {
00156         position = currPos;
00157         len = type->GetLength();
00158         return currPos + len;
00159 }
00160 
00161 void DefinedElement::Output(ostream& out,Element* sel)
00162 {
00163         out << "Defined " << name << " pos:" << position << " len:" << len << " {" << endl;
00164         type->Output(out,NULL);
00165         out << "};" << name << "{" << endl;
00166 }
00167 
00168 class SimpleElement: public Element
00169 {
00170 public:
00171         SimpleElement(const char* name,bool isSigned,int size,int n);
00172         int AssignPos(int currPos);
00173         void Output(ostream& out,Element* sel);
00174 private:
00175         bool isSigned;
00176         int size,n;
00177 };
00178 
00179 SimpleElement::SimpleElement(const char* name,bool _isSigned,int _size,int _n):
00180   Element(name),isSigned(_isSigned),size(_size),n(_n)
00181 {
00182 }
00183 
00184 int SimpleElement::AssignPos(int currPos)
00185 {
00186         position = currPos;
00187         len = size*(n==0?1:n);
00188         return currPos + len;
00189 }
00190 
00191 void SimpleElement::Output(ostream& out,Element* sel)
00192 {
00193         out << "Simple " << name << " pos:" << position << " len:" << len << ";" << endl;
00194 }
00195 
00196 // just skip some bytes for paddind
00197 class PaddingElement: public Element
00198 {
00199 public:
00200         PaddingElement(const char* name,int size);
00201         int AssignPos(int currPos);
00202         void Output(ostream& out,Element* sel);
00203 private:
00204         int size;
00205 };
00206 
00207 PaddingElement::PaddingElement(const char* name,int _size):
00208         Element(name),size(_size)
00209 {
00210         
00211 }
00212 
00213 int PaddingElement::AssignPos(int currPos)
00214 {
00215         position = currPos;
00216         len = size;
00217         return currPos + len;
00218 }
00219 
00220 void PaddingElement::Output(ostream& out,Element* sel)
00221 {
00222         out << "Padding " << name << " pos:" << position << " len:" << len << ";" << endl;
00223 }
00224 
00225 #endif // FILE_ELEMENT_H
00226 

Generated on Mon Jan 13 22:20:34 2003 for perdr by doxygen1.2.15