// snf_xci.hpp
// Copyright (C) 2006 - 2009 ARM Research Labs, LLC
// See www.armresearch.com for the copyright terms.
//
// SNF XML Command Interface
// See snf_xci.hpp for details / notes.

#include "snf_xci.hpp"

//// snf_xci Interpreter Object ////////////////////////////////////////////////

snf_xci::snf_xci() :                                                            // Construcing a blank snf_xci.
  Reader("snf"),                                                                // The Reader looks for "snf"
  ReadWasGood(false) {                                                          // There has been no good read yet.
    SNFWasParsed.setup(ReadWasGood);                                            // Link our configurator to that flag.
    SetupReader();                                                              // Configure our reader.
    reset();                                                                    // and initialize our data.
}

snf_xci::snf_xci(const char* bfr, int len) :                                    // Constructing with a full buffer.
  Reader("snf"),                                                                // Start with our blank construction.
  ReadWasGood(false) {
    SNFWasParsed.setup(ReadWasGood);
    SetupReader();
    reset();
    ConfigurationData Data(bfr, len);                                           // Then build ConfigurationData from
    Reader.interpret(Data);                                                     // the buffer and interpret it.
}

snf_xci::snf_xci(string& input) :                                               // Constructing with a string.
  Reader("snf"),                                                                // Start with our blank construction.
  ReadWasGood(false) {
    SNFWasParsed.setup(ReadWasGood);
    SetupReader();
    reset();
    ConfigurationData Data(input.c_str(), input.length());                      // Then build ConfigurationData from
    Reader.interpret(Data);                                                     // the string and interpret it.
}

void snf_xci::SetupReader() {                                                   // Configure the reader to recognize
    Reader                                                                      // the snf_xci protocol.
        .setInitOnInterpret()
        .atEndCall(SNFWasParsed)                                                // Set flag to true when successful.
        .Element("<!-- SNFWasParsed -->", ReadWasGood, false).End()             // Trick using impossible element name.
        .Element("xci")
            .Element("scanner")
                .Element("scan")
                    .Attribute("file", scanner_scan_file,"")
                    .Attribute("xhdr", scanner_scan_xhdr, false)
                    .Attribute("log", scanner_scan_log, false)
                    .Attribute("ip", scanner_scan_ip, "")
                .End("scan")
                .Element("result")
                    .Attribute("code", scanner_result_code,0)
                    .Element("xhdr", scanner_result_xhdr, "")
                    .End("xhdr")
                    .Element("log", scanner_result_log, "")
                    .End("log")
                .End("result")
            .End("scanner")
            .Element("gbudb")
                .Element("set")
                    .Attribute("ip", gbudb_set_ip, "")
                    .Attribute("type", gbudb_set_type, "")
                    .Attribute("b", gbudb_set_bad_count, -1)
                    .Attribute("g", gbudb_set_good_count, -1)
                .End("set")
                .Element("good")
                    .Attribute("ip", gbudb_good_ip, "")
                .End("good")
                .Element("bad")
                    .Attribute("ip", gbudb_bad_ip, "")
                .End("bad")
                .Element("test")
                    .Attribute("ip", gbudb_test_ip, "")
                .End("test")
                .Element("drop")
                    .Attribute("ip", gbudb_drop_ip, "")
                .End("drop")
                .Element("result")
                    .Attribute("ip", gbudb_result_ip, "")
                    .Attribute("type", gbudb_result_type, "")
                    .Attribute("p", gbudb_result_probability, 0.0)
                    .Attribute("c", gbudb_result_confidence, 0.0)
                    .Attribute("b", gbudb_result_bad_count, -1)
                    .Attribute("g", gbudb_result_good_count, -1)
                    .Attribute("range", gbudb_result_range, "")
                    .Attribute("code", gbudb_result_code, 0)
                .End("result")
            .End("gbudb")
            .Element("report")
                .Element("request")
                    .Element("status")
                        .Attribute("class", report_request_status_class, "")
                    .End("status")
                .End("request")
                .Element("response", report_response, "")
                .End("response")
            .End("report")
            .Element("server")
                .Element("command", xci_server_command_content, "")
                    .Attribute("command", xci_server_command, "")
                .End("command")
                .Element("response")
                    .Attribute("message", xci_server_response, "")
                    .Attribute("code", xci_server_response_code, -1)
                .End("response")
            .End("server")
            .Element("error")
                .Attribute("message", xci_error_message, "")
            .End("error")
        .End("xci")
    .End("snf");
}

void snf_xci::reset() {                                                         // Reset the reader for new data.
    ReadWasGood = false;                                                        // There has been no read yet.
    Reader.initialize();                                                        // Initialize to the defaults.
};

bool snf_xci::read(const char* bfr, int len) {                                  // To read from a buffer we
    ConfigurationData Data(bfr, len);                                           // construct ConfigurationData from
    Reader.interpret(Data);                                                     // the buffer and interpret it.
    return good();                                                              // Return true if it looked good.
}

bool snf_xci::read(string& input) {                                             // To read from a string we
    return read(input.c_str(), input.length());                                 // get the strings buffer and hand off
}                                                                               // to our buffer read()

bool snf_xci::good() {                                                          // True if the Reader finished the
    return (true == ReadWasGood);                                               // snf element successfully.
}

bool snf_xci::bad() {                                                           // False if the Reader finished the
    return (false == ReadWasGood);                                              // snf element successfully.
}

