Add Freescale Nexus decoder implementation
[babeltrace.git] / converter / nexus / Application.cpp
diff --git a/converter/nexus/Application.cpp b/converter/nexus/Application.cpp
new file mode 100644 (file)
index 0000000..ced3fc0
--- /dev/null
@@ -0,0 +1,228 @@
+/*
+ * Copyright (C) 2013 Freescale Semiconductor, Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "Application.h"
+#include "NxMessageDecoder.h"
+#include "NxMessage.h"
+#include "FManDebugLogVisitor.h"
+#include "FullAddressVisitor.h"
+#include "SizedAddress.h"
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+
+using std::cout;
+using std::endl;
+using std::hex;
+using std::dec;
+using std::setfill;
+using std::setw;
+using std::ifstream;
+
+Application::Application() :
+       verbose_(false), summary_(false), data_counter_(0), msg_counter_(0)
+{
+}
+
+Application::~Application()
+{
+       vector<NxMessageVisitor*>::iterator it;
+       for (it = visitors_.begin(); it != visitors_.end(); it++) {
+               delete *it;
+       }
+       visitors_.clear();
+}
+
+// Enable the Full Address Log for the Application
+void Application::enableFullAddrLog()
+{
+       NxMessageVisitor* v = new FullAddressVisitor();
+       visitors_.push_back(v);
+}
+
+// Enable the FMan Detail Log for the Application
+void Application::enableFmanLog()
+{
+       NxMessageVisitor* v = new FManDebugLogVisitor();
+       visitors_.push_back(v);
+}
+
+// Main application entry
+bool Application::process(const string & fn)
+{
+       bool ret;
+
+       // test if file is available
+       ifstream infile(fn.c_str());
+       if (!infile) {
+               cout << "Input Filename: \"" << fn << "\" cannot be opened! ";
+               return false;
+       } else {
+               infile.close();
+       }
+
+       if (verbose_) {
+               cout << "Input Filename: \"" << fn << "\" - ";
+       }
+
+       // determine format for file
+       if (isBinFile_(fn)) {
+               if (verbose_) {
+                       cout << "Binary" << endl;
+               }
+               ret = processBinFile_(fn);
+       } else {
+               if (verbose_) {
+                       cout << "Text" << endl;
+               }
+               ret = processTextFile_(fn);
+       }
+
+       if (ret && summary_) {
+               summarize();
+       }
+
+       return ret;
+}
+
+// Determine if the name file contains Binary formatted data
+bool Application::isBinFile_(const string &fn) const
+{
+       char data[12]; // if text then expecting 0x12345678\n
+
+       // open the file as binary and read the first 12 bytes
+       ifstream infile(fn.c_str(), std::ios::in | std::ios::binary);
+       infile.read(data, 12);
+       infile.close();
+       bool text_file = ((data[0] == '0') && (data[1] == 'x')
+               && ((data[10] == '\n') || (data[10] == ' ')));
+       return !text_file;
+}
+
+// Open the named text file and process the Nexus data
+bool Application::processTextFile_(const string &fn)
+{
+       bool ret;
+       uint32_t data;
+
+       // open the file and feed the data to the decoder
+       ifstream infile(fn.c_str());
+       while (!infile.eof()) {
+               infile >> hex >> data;
+               ret = process_(data);
+               if (!ret) { // error, so quit
+                       break;
+               }
+       }
+       infile.close();
+
+       return ret;
+}
+
+// Open the named text file and process the Nexus data
+bool Application::processBinFile_(const string &fn)
+{
+       bool ret;
+       uint8_t byte[sizeof(uint32_t)];
+       uint32_t data;
+
+       // open the file and feed the data to the decoder
+       ifstream infile(fn.c_str(), std::ios::in | std::ios::binary);
+       while (!infile.eof()) {
+               infile.read((char*) &byte, sizeof(uint32_t));
+               // Nexus binary files are Big Endian data
+               data = byte[0] << 24;
+               data |= byte[1] << 16;
+               data |= byte[2] << 8;
+               data |= byte[3];
+               ret = process_(data);
+               if (!ret) { // error, so quit
+                       break;
+               }
+       }
+       infile.close();
+
+       return ret;
+}
+
+// Process the Nexus data
+bool Application::process_(const uint32_t data)
+{
+       bool ret = true;
+
+       NxMessage *msg = (NxMessage*) 0;
+       data_counter_++;
+
+       if (verbose_) {
+               cout << dec << data_counter_ << ": MDO/MSEO: 0x" << hex
+                       << setfill('0') << setw(8) << data << endl;
+       }
+
+       ret = decoder_.accept(data, msg);
+       if (ret) {
+               if (msg != 0) {
+                       ++msg_counter_;
+                       // we have a message to output
+                       cout << "Message # " << dec << msg_counter_ << endl;
+                       cout << msg->asString() << endl;
+
+                       // count the messages
+                       if (summary_) {
+                               msg_count_[msg->tcodeString()]++;
+                       }
+
+                       // Send all the visitors
+                       vector<NxMessageVisitor*>::iterator it;
+                       for (it = visitors_.begin(); it != visitors_.end();
+                               it++) {
+                               msg->accept(**it);
+                               // report on visit
+                               cout << (*it)->asString() << endl;
+                       }
+
+                       // nothing else to do for now so delete the message
+                       delete msg;
+                       msg = (NxMessage*) 0;
+               }
+       } else {
+               // error somewhere - quit
+               if (verbose_) {
+                       cout << "NxMessageDecoder Failed. Quitting." << endl;
+               }
+       }
+
+       return ret;
+}
+
+// output a summary report on number of messages by type
+void Application::summarize()
+{
+       cout << endl << "***********************" << endl;
+       cout << "Message Counts by TCODE" << endl;
+
+       map<string, uint32_t>::const_iterator iter;
+       for (iter = msg_count_.begin(); iter != msg_count_.end(); ++iter) {
+               cout << iter->first << "\t" << dec << setw(10) << setfill(' ')
+                       << iter->second << endl;
+       }
+
+}
This page took 0.025526 seconds and 4 git commands to generate.