Преглед на файлове

Refactored exception handling and reporting.

Began implementing the Configuration Engine.
Began implementing the message move mechanism.

git-svn-id: https://svn.microneil.com/svn/SNF4CGP/trunk@26 59e8e3e7-56fa-483b-b4b4-fa6ab0af3dfc
master
madscientist преди 15 години
родител
ревизия
566a593b83
променени са 4 файла, в които са добавени 269 реда и са изтрити 18 реда
  1. 32
    0
      SNF4CGP/ConfigurationEngine.cpp
  2. 90
    0
      SNF4CGP/ConfigurationEngine.hpp
  3. 127
    13
      SNF4CGP/JobPool.cpp
  4. 20
    5
      SNF4CGP/JobPool.hpp

+ 32
- 0
SNF4CGP/ConfigurationEngine.cpp Целия файл

@@ -0,0 +1,32 @@
// SNF4CGP/ConfigurationEngine.cpp
// Copyright (C) 2009 ARM Research Labs, LLC
// See www.armresearch.com for more information.
#include "ConfigurationEngine.hpp"
#include "..\SNFMulti\SNFMulti.hpp"
using namespace std;
ConfigurationManager::ConfigurationManager(snf_RulebaseHandler& R) :
Rulebase(R),
Generation_(0),
Configurations(ResultConfigurationSize) {
for(size_t i = 0; i < Configurations.size(); i++) {
Configurations[i].ResultCode = i;
}
}
bool ConfigurationManager::isOutOfDate() {
return (Generation_ != Rulebase.Generation());
}
void ConfigurationManager::update() {
}
const int OutOfRangeDefaultCode = 0;
ResultConfiguration& ConfigurationManager::ConfigurationForResultCode(int Code) {
if(0 > Code || HighestResultCode < Code) Code = OutOfRangeDefaultCode;
return Configurations[Code];
}

+ 90
- 0
SNF4CGP/ConfigurationEngine.hpp Целия файл

@@ -0,0 +1,90 @@
// SNF4CGP/ConfigurationEngine.hpp
// Copyright (C) 2009 ARM Research Labs, LLC
// See www.armresearch.com for more information.
//
// This module parses the configuration and keeps track of it's generation.
// When asked it can produce the appropriate configuration for a given Job
// based on the scan result that was recieved. If it is asked and the current
// configuration is out of date then the new configuration is parsed first.
#ifndef IncludedConfigurationEngine
#define IncludedConfigurationEngine
#include <string>
#include <vector>
using namespace std;
class snf_RulebaseHandler;
class ResultConfiguration {
public:
enum ActionType {
Bypass,
Allow,
Reject,
Delete,
Hold
};
int ResultCode;
ActionType Action;
bool InjectHeaders;
bool EmitXMLLog;
bool EmitClassicLog;
string LogComment;
string RejectionReason;
string HoldPath;
ResultConfiguration() :
ResultCode(0),
Action(Bypass),
InjectHeaders(false),
EmitXMLLog(false),
EmitClassicLog(false),
LogComment(""),
RejectionReason(""),
HoldPath("") {
}
ResultConfiguration(const ResultConfiguration& R) :
ResultCode(R.ResultCode),
Action(R.Action),
InjectHeaders(R.InjectHeaders),
EmitXMLLog(R.EmitXMLLog),
EmitClassicLog(R.EmitClassicLog),
LogComment(R.LogComment),
RejectionReason(R.RejectionReason),
HoldPath(R.HoldPath) {
}
ResultConfiguration& operator=(const ResultConfiguration& R) {
ResultCode = R.ResultCode;
Action = R.Action;
InjectHeaders = R.InjectHeaders;
EmitXMLLog = R.EmitXMLLog;
EmitClassicLog = R.EmitClassicLog;
LogComment = R.LogComment;
RejectionReason = R.RejectionReason;
HoldPath = R.HoldPath;
return (*this);
}
};
const int HighestResultCode = 63;
const int ResultConfigurationSize = HighestResultCode + 1;
class ConfigurationManager {
private:
snf_RulebaseHandler& Rulebase;
int Generation_;
vector<ResultConfiguration> Configurations;
public:
ConfigurationManager(snf_RulebaseHandler& R);
bool isOutOfDate();
void update();
ResultConfiguration& ConfigurationForResultCode(int Code);
};
#endif

+ 127
- 13
SNF4CGP/JobPool.cpp Целия файл

@@ -13,6 +13,7 @@
#include "../CodeDweller/faults.hpp"
#include <iostream>
#include <string>
#include <vector>
using namespace std;
@@ -109,8 +110,9 @@ void Job::doINTF() {
void Job::doFAIL() {
ostringstream O;
O << "SNF4CGP Does not understand: " << formatAsCGPString(CurrentCommand.Data);
emitComment(O.str());
O << "* SNF4CGP[" << CurrentCommand.Number << "] Does not understand: "
<< formatAsCGPString(CurrentCommand.Data) << endl;
OutputBuffer.append(O.str());
emitFAILURE();
}
@@ -118,6 +120,7 @@ void Job::doFILE() {
doRead();
doScan();
doAction();
closeReader();
}
RuntimeCheck CheckMessageReaderIsValid("Job::Reader() Check(0 != Reader_)");
@@ -180,13 +183,20 @@ string Job::ScanName() {
return ScanNameFormatter.str();
}
void Job::setConfigurationFromScanResult(ScopeScanner& myScanner) {
ScanResultConfiguration = Scanners.ConfigurationForResultCode(ScanResultCode);
if(ScanResultConfiguration.InjectHeaders) HeadersToInject = myScanner.Engine().getXHDRs();
if(ScanResultConfiguration.EmitXMLLog) XMLLogData = myScanner.Engine().getXMLLog();
if(ScanResultConfiguration.EmitClassicLog) ClassicLogData = myScanner.Engine().getClassicLog();
}
void Job::doScan() {
ScopeScanner myScanner(Scanners);
ScanResultCode =
myScanner.Engine().scanMessage(
&ReadBuffer[0], Reader().gcount(), ScanName(), JobTimer.getElapsedTime()
);
HeadersToInject = myScanner.Engine().getXHDRs();
setConfigurationFromScanResult(myScanner);
}
void Job::doAction() {
@@ -206,21 +216,115 @@ void Job::doReject() {
void Job::doDelete() {
}
void Job::moveMessageToHoldPath(ifstream& Reader) {
void Job::emitMessageMovedTo(string& Destination) {
ostringstream O;
O << "* SNF4CGP[" << CurrentCommand.Number << "] Moved message to " << Destination << endl;
OutputBuffer.append(O.str());
}
void Job::identifyLocalLineEnd() { // Identify the line endings in use:
if(0 < LocalLineEnd.length()) return; // Do this only once for any system.
for(int i = 0; i < Reader().gcount(); i++) { // Look for the first line end.
if('\r' == ReadBuffer[i] && '\n' == ReadBuffer[i+1]) { // It may be \r\n.
LocalLineEnd = "\r\n"; return;
} else
if('\n' == ReadBuffer[i] && '\n' == ReadBuffer[i+1]) { // It may be \n. (find block end \n\n)
LocalLineEnd = "\n"; return;
}
}
}
RuntimeCheck CheckLineEndsIdentified("Job::findHeaderInsertPoint() Check(0 < LocalLineEnd.length())");
size_t Job::findHeaderInsertPoint() { // How to find the insert point:
identifyLocalLineEnd();
CheckLineEndsIdentified(0 < LocalLineEnd.length());
string BlockTerminus = LocalLineEnd + LocalLineEnd;
size_t InsertCursor = 0;
//// Search for the end of the CGP control block.
for(;InsertCursor < (Reader().gcount() - BlockTerminus.length()); InsertCursor++) {
if(0 == BlockTerminus.compare(reinterpret_cast<char*>(&ReadBuffer[InsertCursor]))) break;
}
//// Search for the end of the message headers.
InsertCursor += BlockTerminus.length();
for(;InsertCursor < (Reader().gcount() - BlockTerminus.length()); InsertCursor++) {
if(0 == BlockTerminus.compare(reinterpret_cast<char*>(&ReadBuffer[InsertCursor]))) break;
}
//// The correct insert point is between the two LocalLineEnd in the BlockTerminus
InsertCursor += LocalLineEnd.length();
return InsertCursor;
}
void Job::writeUpToInjectionPoint(size_t InjectionPoint) {
}
void Job::writeHeaders() {
}
void Job:: writeTheRestOfTheFirstBuffer() {
}
void Job::injectHeadersInMessageMove() {
//// writeUpToTheInjectionPoint()
//// writeTheHeaders()
//// writeTheRestOfTheFirstBuffer()
}
void Job::copyRestOfLongMessage() {
//// while(MoreToDo) {
//// readBufferFull()
//// writeBufferFull()
//// }
}
void Job::moveMessageToHoldPath(string& Destination) {
openWriter(Destination);
if(ScanResultConfiguration.InjectHeaders) injectHeadersInMessageMove();
copyRestOfLongMessage();
closeWriter();
}
const string PathSeparators = "\\/";
string FileNamePart(string Path) { // How to get the file name part of a path:
string::size_type Found = Path.find_last_of(PathSeparators);
if(string::npos != Found) Path = Path.substr(Found+1); // Return all after the last separator
return Path; // or Path if no separators are found.
}
string Job::calculateDestinationFileName() { // How to get the message move destination:
string Source = CurrentCommand.Data;
string Destination = ScanResultConfiguration.HoldPath;
Destination.append(FileNamePart(Source));
return Destination;
}
void Job::doHold() {
string Destination = calculateDestinationFileName();
moveMessageToHoldPath(Destination);
emitMessageMovedTo(Destination);
}
const int NoScanYet = -1;
Job::Job(ScannerPool& S, OutputProcessor& O) : // Construct with important links.
Scanners(S),
Output(O),
ScanResultCode(0),
ScanResultCode(NoScanYet),
Reader_(0),
Writer_(0) { // Minimize heap thrashing.
OutputBuffer.reserve(StringReserveSize);
HeadersToInject.reserve(StringReserveSize);
ReadBuffer.reserve(ReadBufferSize);
OutputBuffer.reserve(StringReserveSize);
HeadersToInject.reserve(StringReserveSize);
XMLLogData.reserve(StringReserveSize);
ClassicLogData.reserve(StringReserveSize);
ReadBuffer.reserve(ReadBufferSize);
}
Job::~Job() { // Cleanup when destructing.
@@ -230,10 +334,11 @@ Job::~Job() {
void Job::clear() { // Cleanup for the next command.
CurrentCommand.clear();
ScanResultCode = 0;
ScanResultCode = NoScanYet;
OutputBuffer.clear();
HeadersToInject.clear();
MessageMoveFilePath.clear();
XMLLogData.clear();
ClassicLogData.clear();
ReadBuffer.clear();
closeReader();
closeWriter();
@@ -258,15 +363,24 @@ void Job::executeCommand() {
}
void Job::emitException(const string& What) {
ostringstream O;
O << "* SNF4CGP[" << CurrentCommand.Number << "] Exception: " << What << endl;
OutputBuffer.append(O.str());
}
void Job::emitUnknownException() {
ostringstream O;
O << "* SNF4CGP[" << CurrentCommand.Number << "] Unknown Exception!" << endl;
OutputBuffer.append(O.str());
}
void Job::doIt() { // Get the job done.
try { executeCommand(); }
catch(exception& e) { emitException(e.what()); }
catch(...) { emitUnknownException(); }
try { // emitFAILURE() on all exceptions.
try { executeCommand(); } // executeCommand() and report exceptions.
catch(exception& e) { emitException(e.what()); throw; }
catch(...) { emitUnknownException(); throw; }
}
catch(...) { emitFAILURE(); }
finalize();
}

+ 20
- 5
SNF4CGP/JobPool.hpp Целия файл

@@ -27,6 +27,7 @@
#include "../CodeDweller/threading.hpp"
#include "Command.hpp"
#include "ConfigurationEngine.hpp"
#include <fstream>
#include <string>
@@ -35,6 +36,7 @@
using namespace std;
class ScannerPool;
class ScopeScanner;
class OutputProcessor;
class Job { // SNF4CGP Job instance.
@@ -49,10 +51,13 @@ class Job {
//// SNF Scan and move data and tools
int ScanResultCode;
string HeadersToInject;
string MessageMoveFilePath;
vector<unsigned char> ReadBuffer; // Preserves a file read buffer.
ResultConfiguration ScanResultConfiguration;
string HeadersToInject; // Reuse Header Injection Buffer
string XMLLogData; // Reuse XML Log Data Buffer
string ClassicLogData; // Reuse Classic Log Data Buffer
void setConfigurationFromScanResult(ScopeScanner& myScanner);
vector<unsigned char> ReadBuffer; // Reuse file read buffer.
ifstream* Reader_; // Open ifstream for current message.
ifstream& Reader(); // Safe access to Reader_.
void openReader(string Path);
@@ -63,7 +68,17 @@ class Job {
void openWriter(string Path);
void closeWriter();
void moveMessageToHoldPath(ifstream& Reader);
string calculateDestinationFileName();
void emitMessageMovedTo(string& Destination);
string LocalLineEnd;
void Job::identifyLocalLineEnd();
size_t findHeaderInsertPoint();
void writeUpToInjectionPoint(size_t InjectionPoint);
void writeHeaders();
void writeTheRestOfTheFirstBuffer();
void injectHeadersInMessageMove();
void copyRestOfLongMessage();
void moveMessageToHoldPath(string& Destination);
//// Utility methods
@@ -84,7 +99,7 @@ class Job {
void executeCommand();
void emitException(const string& What);
void Job::emitUnknownException();
void emitUnknownException();
//// These methods embody how we get jobs done.

Loading…
Отказ
Запис