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
00017
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
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
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