]> AND Private Git Repository - blast.git/blob - ReferenceBlock.cpp
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
8b50bfa4d0d6d466402614e53154304dab18893b
[blast.git] / ReferenceBlock.cpp
1 #include "ReferenceBlock.h"
2
3 #include "ReferenceInterface.h"
4 #include "BlockParameter.h"
5 #include "BlockParameterUser.h"
6 #include "BlockParameterGeneric.h"
7 #include "BlockParameterPort.h"
8 #include "BlockParameterWishbone.h"
9
10 ReferenceBlock::ReferenceBlock(const QString _xmlFile) : AbstractBlock() {
11   xmlFile = _xmlFile;
12 }
13
14 void ReferenceBlock::addCategory(int id) {
15  categories.append(id);
16 }
17
18 void ReferenceBlock::setBriefDescription(const QString& str) {
19   if(str != NULL)
20     descriptionBrief = str;
21 }
22
23 void ReferenceBlock::setDetailedDescription(const QString& str) {
24   if(str != NULL)
25     descriptionDetail = str;
26 }
27
28 void ReferenceBlock::addImplementation(BlockImplementation *impl) {
29   implementations.append(impl);
30 }
31
32 void ReferenceBlock::setHashMd5() {
33   QFile file(xmlFile);
34   if (file.open(QIODevice::ReadOnly)) {
35     QByteArray fileData = file.readAll();
36     QByteArray hashData = QCryptographicHash::hash(fileData, QCryptographicHash::Md5);
37     hashMd5 = QString(hashData.toHex());
38     cout << qPrintable(xmlFile) << " has md5 hash : " << qPrintable(hashMd5) << endl;
39   }
40   else {
41     hashMd5 = "";
42   }
43 }
44
45 void ReferenceBlock::load(QDomElement &elt) throw(Exception) {
46
47
48   cout << "Block : get informations" << endl;  
49   QDomElement eltInfo  = elt.firstChildElement("informations");
50   try {
51     loadInformations(eltInfo);
52   }
53   catch(int err) {
54     throw(err);
55   }
56
57   cout << "Block : get params" << endl;  
58   QDomElement eltParams  = eltInfo.nextSiblingElement("parameters");
59   try {
60     loadParameters(eltParams);
61   }
62   catch(int err) {
63     throw(err);
64   }
65
66   cout << "Block : get interfaces" << endl;  
67   QDomElement eltInter  = eltParams.nextSiblingElement("interfaces");
68   try {
69     loadInterfaces(eltInter);
70   }
71   catch(int err) {
72     throw(err);
73   }  
74 }
75
76 void ReferenceBlock::loadInformations(QDomElement &elt) throw(Exception) {
77
78   bool ok;
79   if ((elt.isNull()) || (elt.tagName() != "informations")) throw (Exception(BLOCKFILE_CORRUPTED));
80   // getting name
81   cout << "Block info : get name" << endl;
82   QDomNode nodeName = elt.firstChild();  
83   QDomNode nodeNameTxt = nodeName.firstChild();
84   if (nodeNameTxt.isNull()) {
85     name = "no_name";
86   }
87   else {
88     QDomText txtName = nodeNameTxt.toText();
89     name = txtName.data().trimmed();
90     cout<< "block name : " << qPrintable(name) << endl;
91   }
92
93   // getting categories
94   cout << "Block info : get categories" << endl;  
95   QDomElement eltCat = nodeName.nextSiblingElement("category");
96
97   QString idsStr = eltCat.attribute("ids","none");
98   if (idsStr == "none") throw (Exception(BLOCKFILE_CORRUPTED));
99   QStringList listCat = idsStr.split(",");
100   foreach(QString str, listCat)
101   {
102     int idCat = str.toInt(&ok);
103     categories.append(idCat);
104   }
105
106   // getting description
107   cout << "Block info : get description" << endl;  
108   QDomElement eltDesc = eltCat.nextSiblingElement("description");
109   // getting brief  
110   QDomElement eltBrief = eltDesc.firstChildElement("brief");
111   QDomNode nodeBriefTxt = eltBrief.firstChild();
112   if (nodeBriefTxt.isNull()) {
113     descriptionBrief = "no brief description";
114   }
115   else {
116     QDomText txtBrief = nodeBriefTxt.toText();
117     descriptionBrief = txtBrief.data().trimmed();
118     cout << "block brief desc : " << qPrintable(descriptionBrief) << endl;
119   }
120   // getting detailed  
121   QDomElement eltDetail = eltBrief.nextSiblingElement("detailed");
122   QDomNode nodeDetailTxt = eltDetail.firstChild();
123   if (nodeDetailTxt.isNull()) {
124     descriptionDetail = "no detailed description";
125   }
126   else {
127     QDomText txtDetail = nodeDetailTxt.toText();
128     descriptionDetail = txtDetail.data().trimmed();
129     cout << "block detail desc : " << qPrintable(descriptionDetail) << endl;
130   }
131 }
132
133 void ReferenceBlock::loadParameters(QDomElement &elt) throw(Exception) {
134
135   if ((elt.isNull()) || (elt.tagName() != "parameters")) throw (Exception(BLOCKFILE_CORRUPTED));
136
137   QDomNodeList listNodeParam = elt.elementsByTagName("parameter");
138   for(int i=0; i<listNodeParam.size(); i++) {
139     QDomNode node = listNodeParam.at(i);    
140     QDomElement elt = node.toElement();    
141     QString nameStr = elt.attribute("name","none");    
142     QString contextStr = elt.attribute("context","none");
143     QString typeStr = elt.attribute("type","none");
144     QString valueStr = elt.attribute("value","none");
145     BlockParameter *param = NULL;
146
147     if(valueStr == "none"){
148         if (contextStr == "generic") throw (Exception(BLOCKFILE_CORRUPTED)); // set is required for generics
149         valueStr = "";
150     }
151     if (contextStr == "user") {
152       param = new BlockParameterUser(this,nameStr,valueStr);
153     }
154     else if (contextStr == "generic") {
155       param = new BlockParameterGeneric(this,nameStr,typeStr,valueStr);
156     }
157     else if (contextStr == "wb") {
158       QString widthStr = elt.attribute("width","none");
159       QString wbStr = elt.attribute("wishbone","none");
160       int access = 0;
161       int duration = 0;
162       QString wbValue = "";
163       QStringList listWb = wbStr.split(",");
164
165       if (listWb.at(0) == "r") {
166         access = BlockParameter::Read;
167       }
168       else if (wbStr == "w") {
169         access = BlockParameter::Write;
170         bool ok;
171         wbValue = listWb.at(1).toInt(&ok);
172         if(!ok){
173             if(listWb.at(1) == "true" || listWb.at(1) == "false"){
174                 wbValue = listWb.at(1);
175             } else {
176                 wbValue = "data";
177             }
178         }
179         if(listWb.at(2) == "trigger") {
180             duration = BlockParameter::Trigger;
181         }
182         else if(listWb.at(2) == "perm") {
183             duration = BlockParameter::Permanent;
184         }
185       }
186       param = new BlockParameterWishbone(this,nameStr,typeStr,widthStr,valueStr,access,wbValue,duration);
187     }
188     else if (contextStr == "port") {
189       QString ifaceStr = elt.attribute("iface","none");
190       param = new BlockParameterPort(this,nameStr,valueStr,ifaceStr);
191
192     }
193     else {
194       throw (Exception(BLOCKFILE_CORRUPTED));
195     }
196     params.append(param);
197   }
198 }
199
200 void ReferenceBlock::loadInterfaces(QDomElement &elt) throw(Exception) {
201
202   QString nameStr;
203   QString typeStr;
204   QString widthStr;
205   QString purposeStr;
206   int purpose;
207   QString levelStr;
208   int level;
209   QString multStr;
210   int mult;
211   AbstractInterface* inter;
212
213   if ((elt.isNull()) || (elt.tagName() != "interfaces")) throw (Exception(BLOCKFILE_CORRUPTED));
214
215   QDomElement eltInputs = elt.firstChildElement("inputs");
216   QDomNodeList listNodeInputs = eltInputs.elementsByTagName("input");
217   for(int i=0;i<listNodeInputs.size();i++) {
218     QDomNode node = listNodeInputs.at(i);
219     QDomElement eltInput = node.toElement();
220     nameStr = eltInput.attribute("name","none");
221     typeStr = eltInput.attribute("type","none");
222     widthStr = eltInput.attribute("width","none");
223     purposeStr = eltInput.attribute("purpose","none");
224     cout << "block : " << this->getName().toStdString() << endl;
225     cout << "purpose for " << nameStr.toStdString() << " : " << purposeStr.toStdString() << endl;
226     purpose = ReferenceInterface::translatePurpose(purposeStr);
227     cout << "translated purpose : " << purpose << endl;
228     levelStr = eltInput.attribute("level","none");
229     level = ReferenceInterface::translateLevel(levelStr);
230     multStr = eltInput.attribute("multiplicity","none");
231     mult = ReferenceInterface::translateMultiplicity(multStr);
232
233     inter = new ReferenceInterface(this,nameStr,typeStr,widthStr,AbstractInterface::Input, purpose, level, mult);
234     inputs.append(inter);
235   }
236
237   QDomElement eltOutputs = eltInputs.nextSiblingElement("outputs");
238   QDomNodeList listNodeOutputs = eltOutputs.elementsByTagName("output");
239   for(int i=0;i<listNodeOutputs.size();i++) {
240     QDomNode node = listNodeOutputs.at(i);
241     QDomElement eltOutput = node.toElement();
242     nameStr = eltOutput.attribute("name","none");
243     typeStr = eltOutput.attribute("type","none");
244     widthStr = eltOutput.attribute("width","none");
245     purposeStr = eltOutput.attribute("type","none");
246     purpose = ReferenceInterface::translatePurpose(purposeStr);
247     levelStr = eltOutput.attribute("level","none");
248     level = ReferenceInterface::translateLevel(levelStr);
249     multStr = eltOutput.attribute("multiplicity","none");
250     mult = ReferenceInterface::translateMultiplicity(multStr);
251
252     inter = new ReferenceInterface(this,nameStr,typeStr,widthStr,AbstractInterface::Output, purpose, level, mult);
253     outputs.append(inter);
254   }
255
256   QDomElement eltBidirs = eltInputs.nextSiblingElement("bidirs");
257   QDomNodeList listNodeBidirs = eltBidirs.elementsByTagName("bidir");
258   for(int i=0;i<listNodeBidirs.size();i++) {
259     QDomNode node = listNodeBidirs.at(i);
260     QDomElement eltBidir = node.toElement();
261     nameStr = eltBidir.attribute("name","none");
262     typeStr = eltBidir.attribute("type","none");
263     widthStr = eltBidir.attribute("width","none");
264     purposeStr = eltBidir.attribute("type","none");
265     purpose = ReferenceInterface::translatePurpose(purposeStr);
266     levelStr = eltBidir.attribute("level","none");
267     level = ReferenceInterface::translateLevel(levelStr);
268     multStr = eltBidir.attribute("multiplicity","none");
269     mult = ReferenceInterface::translateMultiplicity(multStr);
270
271     inter = new ReferenceInterface(this,nameStr,typeStr,widthStr,AbstractInterface::InOut, purpose, level, mult);
272     bidirs.append(inter);
273   }
274 }
275
276 void ReferenceBlock::parametersValidation(QList<AbstractBlock *> *checkedBlocks, QList<AbstractBlock *> *blocksToConfigure)
277 {
278     return;
279 }
280
281 /* operator<<() :
282    only used to save all ReferenceBlock in a library in binary format, so that reference blocks
283    are read very fast at application startup.
284
285  */
286 QDataStream& operator<<(QDataStream &out, const ReferenceBlock &b) {
287
288   out.setVersion(QDataStream::Qt_5_0);
289
290   QByteArray blockData;
291   QDataStream toWrite(&blockData, QIODevice::WriteOnly);
292
293   toWrite << b.name;
294   toWrite << b.xmlFile;
295   toWrite << b.descriptionBrief;
296   toWrite << b.descriptionDetail;
297   toWrite << b.categories;
298   toWrite << b.hashMd5;
299   toWrite << b.params.size();
300   BlockParameter* p;
301   for(int i=0;i<b.params.size();i++) {
302     p = b.params.at(i);
303     toWrite << p->getContext();
304     toWrite << p->getName();
305     toWrite << p->getTypeString();
306     toWrite << p->getValue().toString();
307     if (p->isPortParameter()) {
308       toWrite << ((BlockParameterPort*)p)->getIfaceName();
309     }
310     else if (p->isWishboneParameter()) {
311       BlockParameterWishbone* pwb = (BlockParameterWishbone*)p;
312       toWrite << pwb->getWidth();
313       toWrite << pwb->getWBAccess();
314       toWrite << pwb->getWBValue();
315       toWrite << pwb->getWBDuration();
316     }
317
318   }
319
320   toWrite << b.inputs.size();
321   for(int i=0; i<b.inputs.size(); i++){
322     ReferenceInterface *iface = (ReferenceInterface *)(b.inputs.at(i));
323     toWrite << iface->getName();
324     toWrite << iface->getWidth();
325     toWrite << iface->getPurpose();
326     toWrite << iface->getDirection();
327     toWrite << iface->getLevel();
328     toWrite << iface->getMultiplicity();
329   }
330   toWrite << b.outputs.size();
331   for(int i=0; i<b.outputs.size(); i++){
332     ReferenceInterface *iface = (ReferenceInterface *)(b.outputs.at(i));
333     toWrite << iface->getName();
334     toWrite << iface->getWidth();
335     toWrite << iface->getPurpose();
336     toWrite << iface->getDirection();
337     toWrite << iface->getLevel();
338     toWrite << iface->getMultiplicity();
339   }
340   toWrite << b.bidirs.size();
341   for(int i=0; i<b.bidirs.size(); i++){
342     ReferenceInterface *iface = (ReferenceInterface *)(b.bidirs.at(i));
343     toWrite << iface->getName();
344     toWrite << iface->getWidth();
345     toWrite << iface->getPurpose();
346     toWrite << iface->getDirection();
347     toWrite << iface->getLevel();
348     toWrite << iface->getMultiplicity();
349   }
350
351   out << blockData;
352
353   return out;
354 }
355
356 QDataStream& operator>>(QDataStream &in, ReferenceBlock &b) {
357
358   quint32 blockSize;
359   ReferenceInterface* iface;
360   BlockParameter* p;
361   int val;
362   QString txt="";
363
364   in.setVersion(QDataStream::Qt_5_0);
365
366   in >> blockSize;
367
368   in >> b.name;
369   in >> b.xmlFile;
370   in >> b.descriptionBrief;
371   in >> b.descriptionDetail;
372   in >> b.categories;
373   in >> b.hashMd5;
374   b.params.clear();
375   int nb;
376   in >> nb;
377   cout << qPrintable(b.name) << " has " << nb << " parameters" << endl;
378   for(int i=0;i<nb;i++) {
379     QString contextStr = "";
380     QString nameStr= "";
381     QString typeStr = "";
382     QString valueStr = "";
383     in >> contextStr;
384     in >> nameStr;
385     in >> typeStr;
386     in >> valueStr;
387
388     if (contextStr == "user") {
389       p = new BlockParameterUser(&b,nameStr,valueStr);
390     }
391     else if (contextStr == "generic") {
392       p = new BlockParameterGeneric(&b,nameStr,typeStr,valueStr);
393     }
394     else if (contextStr == "port") {
395       QString ifaceStr = "";
396       in >> ifaceStr;
397       p = new BlockParameterPort(&b,nameStr,valueStr,ifaceStr);
398     }
399     else if (contextStr == "wb") {
400       QString widthStr = "";
401       int wbAccess;
402       QString wbValue;
403       int wbDuration;
404       in >> widthStr;
405       in >> wbAccess;
406       in >> wbValue;
407       in >> wbDuration;
408       p = new BlockParameterWishbone(&b,nameStr,typeStr,widthStr,valueStr,wbAccess,wbValue,wbDuration);
409     }
410     b.params.append(p);
411   }
412
413   b.inputs.clear();
414   in >> nb;
415   for(int i=0;i<nb;i++) {
416     iface = new ReferenceInterface(&b);
417     in >> txt;
418     iface->setName(txt);
419     in >> txt;
420     iface->setWidth(txt);
421     in >> val;
422     iface->setPurpose(val);
423     in >> val;
424     iface->setDirection(val);
425     in >> val;
426     iface->setLevel(val);
427     in >> val;
428     iface->setMultiplicity(val);
429     b.inputs.append(iface);
430   }
431
432   b.outputs.clear();
433   in >> nb;
434   for(int i=0;i<nb;i++) {
435     iface = new ReferenceInterface(&b);
436     in >> txt;
437     iface->setName(txt);
438     in >> txt;
439     iface->setWidth(txt);
440     in >> val;
441     iface->setPurpose(val);
442     in >> val;
443     iface->setDirection(val);
444     in >> val;
445     iface->setLevel(val);
446     in >> val;
447     iface->setMultiplicity(val);
448     b.outputs.append(iface);
449   }
450
451   b.bidirs.clear();
452   in >> nb;
453   for(int i=0;i<nb;i++) {
454     iface = new ReferenceInterface(&b);
455     in >> txt;
456     iface->setName(txt);
457     in >> txt;
458     iface->setWidth(txt);
459     in >> val;
460     iface->setPurpose(val);
461     in >> val;
462     iface->setDirection(val);
463     in >> val;
464     iface->setLevel(val);
465     in >> val;
466     iface->setMultiplicity(val);
467     b.bidirs.append(iface);
468   }
469
470   return in;
471 }