--- /dev/null
+/*
+ * 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;
+ }
+
+}