#include "odbcomponentparser.h" #include <QTextStream> #include <QStringList> #include <QtMath> class PcbCamOdbComponentParserPrivate { Q_DECLARE_PUBLIC(PcbCamOdbComponentParser) public: PcbCamOdbComponentParserPrivate(PcbCamOdbComponentParser *qptr) : q_ptr(qptr){ } ~PcbCamOdbComponentParserPrivate() { } QList<PcbCamOdbFeatureInfo> featureList; QStringList errorList; QByteArray featData; QHash<int, QString> symbolsHash; QHash<int, QString> attrNameHash; QHash<int, QString> attrTextHash; protected: PcbCamOdbComponentParser * const q_ptr; }; PcbCamOdbComponentParser::PcbCamOdbComponentParser(const QByteArray &iData) : d_ptr(new PcbCamOdbComponentParserPrivate(this)) { Q_D(PcbCamOdbComponentParser); d->featData = iData; } PcbCamOdbComponentParser::~PcbCamOdbComponentParser() { } void PcbCamOdbComponentParser::parse() { Q_D(PcbCamOdbComponentParser); d->attrNameHash.clear(); d->attrTextHash.clear(); d->featureList.clear(); d->errorList.clear(); QTextStream stream(&d->featData); QString line; while (stream.readLineInto(&line)) { if (line.startsWith("#") || line.length() == 0) { // comment continue; } if (line.startsWith("@")) { // symbol names parseAttrName(line); } else if (line.startsWith("&")) { // attr text strings parseAttrText(line); } else if (line.startsWith("CMP")) { // component parseComponent(line); } } } QList<PcbCamOdbFeatureInfo> PcbCamOdbComponentParser::features() { Q_D(const PcbCamOdbComponentParser); return d->featureList; } QStringList PcbCamOdbComponentParser::errors() { Q_D(const PcbCamOdbComponentParser); return d->errorList; } void PcbCamOdbComponentParser::parseAttrName(const QString &iLine) { Q_D(PcbCamOdbComponentParser); QStringList tmp = iLine.split(" ", Qt::SkipEmptyParts); if (tmp.length() == 2) { d->attrNameHash.insert(tmp[0].mid(1).toInt(), tmp[1]); } } void PcbCamOdbComponentParser::parseAttrText(const QString &iLine) { Q_D(PcbCamOdbComponentParser); QStringList tmp = iLine.split(" ", Qt::SkipEmptyParts); if (tmp.length() == 2) { d->attrTextHash.insert(tmp[0].mid(1).toInt(), tmp[1]); } } void PcbCamOdbComponentParser::parseComponent(const QString &iLine) { Q_D(PcbCamOdbComponentParser); QStringList param; QVariantMap attrmap; parseAttributes(iLine, ¶m, &attrmap); // CMP <pkg_ref> <x> <y> <rot> <mirror> <comp_name> <part_name> ; <attributes> PcbCamOdbFeatureInfo feat; feat.type = PcbCam::ComponentFeature; feat.ps = QPointF(param.value(2).toDouble(), param.value(3).toDouble()); feat.symbol = param.value(1); feat.widthFactor = param.value(4).toDouble(); // 为了节省内层空间,角度<rot>放在widthFactor里 feat.cw = (param.value(5) == "Y"); // 为了节省内层空间,是否镜像<mirror>放在cw里 feat.text = param.value(6); // comp_name feat.font = param.value(7); // part_name feat.attributes = attrmap; d->featureList.append(feat); } void PcbCamOdbComponentParser::parseAttributes(const QString &iLine, QStringList *oParams, QVariantMap *oAttrMap) const { Q_D(const PcbCamOdbComponentParser); //拆分属性 //CMP 9 3.7385827 5.1106299 180.0 N J7002 998-6533 ;0=2,1=0.166142 int loc = iLine.lastIndexOf(";"); QString record = iLine.left(loc).trimmed(); QString attr; if (loc != -1) { attr = iLine.right(iLine.length() - loc - 1).trimmed(); } //拆分文字的单引号 //CMP 9 3.7385827 5.1106299 180.0 N 'J7002 1' 998-6533 1;0 if (record.indexOf("'") != -1) { int loc = record.indexOf("'"); int loc2 = record.indexOf("'", loc + 1); QString left = record.left(loc); QString middle = record.mid(loc + 1, loc2 - loc - 1); QString right = record.right(record.length() - loc2 - 1); *oParams = left.split(" ", Qt::SkipEmptyParts); *oParams << middle; *oParams += right.split(" ", Qt::SkipEmptyParts); } else { *oParams = record.split(" ", Qt::SkipEmptyParts); } if (!attr.isEmpty()) { QStringList terms = attr.split(','); for (int i = 0; i < terms.size(); ++i) { QStringList v = terms[i].split('='); QString key = d->attrNameHash.value(v[0].toInt()); if (v.size() == 1) { oAttrMap->insert(key, QVariant(true)); } else { oAttrMap->insert(key, d->attrTextHash.value(v[1].toInt())); } } } }