<commit_before>/**
 * @file examples/megasync.cpp
 * @brief sample daemon, which synchronizes local and remote folders
 *
 * (c) 2013 by Mega Limited, Wellsford, New Zealand
 *
 * This file is part of the MEGA SDK - Client Access Engine.
 *
 * Applications using the MEGA API must present a valid application key
 * and comply with the the rules set forth in the Terms of Service.
 *
 * The MEGA SDK is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * @copyright Simplified (2-clause) BSD License.
 *
 * You should have received a copy of the license along with this
 * program.
 */

#include "mega.h"

#ifdef _WIN32
#include <conio.h>
#endif

using namespace mega;

class SyncApp : public MegaApp
{
    string local_folder;
    string remote_folder;
    handle cwd;
    bool initial_fetch;

    void debug_log(const char*);
    void login_result(error e);

	void fetchnodes_result (error e);

    void request_error(error e);
	void syncupdate_state(Sync*, syncstate_t);

	void syncupdate_stuck(string*);
	void syncupdate_local_folder_addition(Sync*, const char*);
	void syncupdate_local_folder_deletion(Sync*, const char*);
	void syncupdate_local_file_addition(Sync*, const char*);
	void syncupdate_local_file_deletion(Sync*, const char*);
	void syncupdate_local_file_change(Sync*, const char*);
	void syncupdate_local_move(Sync*, const char*, const char*);
	void syncupdate_get(Sync*, const char*);
	void syncupdate_put(Sync*, const char*);
	void syncupdate_remote_file_addition(Node*);
	void syncupdate_remote_file_deletion(Node*);
	void syncupdate_remote_folder_addition(Node*);
	void syncupdate_remote_folder_deletion(Node*);
	void syncupdate_remote_copy(Sync*, const char*);
	void syncupdate_remote_move(string*, string*);
	void syncupdate_treestate(LocalNode*);

    Node* nodebypath(const char* ptr, string* user, string* namepart);
public:
    bool debug;
    SyncApp (string local_folder_, string remote_folder_);
};

// globals
MegaClient* client;
//bool mega::debug = false;

// returns node pointer determined by path relative to cwd
// Path naming conventions:
// path is relative to cwd
// /path is relative to ROOT
// //in is in INBOX
// //bin is in RUBBISH
// X: is user X's INBOX
// X:SHARE is share SHARE from user X
// : and / filename components, as well as the \, must be escaped by \.
// (correct UTF-8 encoding is assumed)
// returns NULL if path malformed or not found
Node* SyncApp::nodebypath(const char* ptr, string* user = NULL, string* namepart = NULL)
{
	vector<string> c;
	string s;
	int l = 0;
	const char* bptr = ptr;
	int remote = 0;
	Node* n;
	Node* nn;

	// split path by / or :
	do {
		if (!l)
		{
			if (*ptr >= 0)
			{
				if (*ptr == '\\')
				{
					if (ptr > bptr) s.append(bptr,ptr-bptr);
					bptr = ++ptr;

					if (*bptr == 0)
					{
						c.push_back(s);
						break;
					}

					ptr++;
					continue;
				}

				if (*ptr == '/' || *ptr == ':' || !*ptr)
				{
					if (*ptr == ':')
					{
						if (c.size()) return NULL;
						remote = 1;
					}

					if (ptr > bptr) s.append(bptr,ptr-bptr);

					bptr = ptr+1;

					c.push_back(s);

					s.erase();
				}
			}
			else if ((*ptr & 0xf0) == 0xe0) l = 1;
			else if ((*ptr & 0xf8) == 0xf0) l = 2;
			else if ((*ptr & 0xfc) == 0xf8) l = 3;
			else if ((*ptr & 0xfe) == 0xfc) l = 4;
		}
		else l--;
	} while (*ptr++);

	if (l) return NULL;

	if (remote)
	{
		// target: user inbox - record username/email and return NULL
		if (c.size() == 2 && !c[1].size())
		{
			if (user) *user = c[0];
			return NULL;
		}

		User* u;

		if ((u = client->finduser(c[0].c_str())))
		{
			// locate matching share from this user
			handle_set::iterator sit;

			for (sit = u->sharing.begin(); sit != u->sharing.end(); sit++)
			{
				if ((n = client->nodebyhandle(*sit)))
				{
					if (!strcmp(c[1].c_str(),n->displayname()))
					{
						l = 2;
						break;
					}
				}

				if (l) break;
			}
		}

		if (!l) return NULL;
	}
	else
	{
		// path starting with /
		if (c.size() > 1 && !c[0].size())
		{
			// path starting with //
			if (c.size() > 2 && !c[1].size())
			{
				if (c[2] == "in") n = client->nodebyhandle(client->rootnodes[1]);
				else if (c[2] == "bin") n = client->nodebyhandle(client->rootnodes[2]);
				else if (c[2] == "mail") n = client->nodebyhandle(client->rootnodes[3]);
				else return NULL;

				l = 3;
			}
			else
			{
				n = client->nodebyhandle(client->rootnodes[0]);

				l = 1;
			}
		}
		else n = client->nodebyhandle(cwd);
	}

	// parse relative path
	while (n && l < (int)c.size())
	{
		if (c[l] != ".")
		{
			if (c[l] == "..")
			{
				if (n->parent) n = n->parent;
			}
			else
			{
				// locate child node (explicit ambiguity resolution: not implemented)
				if (c[l].size())
				{
					nn = client->childnodebyname(n,c[l].c_str());

					if (!nn)
					{
						// mv command target? return name part of not found
						if (namepart && l == (int)c.size()-1)
						{
							*namepart = c[l];
							return n;
						}

						return NULL;
					}

					n = nn;
				}
			}
		}

		l++;
	}

	return n;
}

SyncApp:: SyncApp (string local_folder_, string remote_folder_):
    local_folder (local_folder_), remote_folder (remote_folder_), cwd (UNDEF), initial_fetch (true)
{
}

// callback for displaying debug logs
void SyncApp::debug_log(const char* message)
{
    if (debug)
        cout << "DEBUG: " << message << endl;
}

// this callback function is called when we have login result (success or error)
// TODO: check for errors
void SyncApp::login_result(error e)
{
    if (e != API_OK) {
        cout << "FATAL: Failed to get login result, exiting" << endl;
        exit (1);
    }
    // get the list of nodes
    client->fetchnodes();
}

void SyncApp::fetchnodes_result (error e)
{
    if (e != API_OK) {
        cout << "FATAL: Failed to fetch remote nodes, exiting" << endl;
        exit (1);
    }

    cout << "fetchnodes_result" << endl;

    if (initial_fetch) {
        initial_fetch = false;
        if (ISUNDEF(cwd)) cwd = client->rootnodes[0];

        Node* n = nodebypath(remote_folder.c_str());
        if (client->checkaccess(n, FULL))
        {
            string localname;

            client->fsaccess->path2local(&local_folder, &localname);

            if (!n) {
                cout << remote_folder << ": Not found." << endl;
                exit (1);
            } else if (n->type == FILENODE) {
                cout << remote_folder << ": Remote sync root must be folder." << endl;
                exit (1);
            } else {
				error e = client->addsync(&localname,"Debris",NULL,n,0);
                if (e) {
                    cout << "Sync could not be added! " << endl;
                    exit (1);
                }

                cout << "Sync started !" << endl;
            }
        } else {
            cout << remote_folder << ": Syncing requires full access to path." << endl;
            exit (1);
        }
    }
}

// this callback function is called when request-level error occurred
void SyncApp::request_error(error e)
{
    cout << "FATAL: Request failed, exiting" << endl;
    exit (1);
}

void SyncApp::syncupdate_state(Sync*, syncstate_t state)
{
    if (state == SYNC_CANCELED || state == SYNC_FAILED) {
        cout << "FATAL: Sync failed !" << endl;
        exit (1);
    } else if (state == SYNC_ACTIVE) {
		cout << "Sync is now active" << endl;
    }
}

void SyncApp::syncupdate_stuck(string* reason)
{
	if (reason) cout << "Sync halted: " << *reason << " temporarily in use" << endl;
	else cout << "Sync resumed" << endl;
}

// sync update callbacks are for informational purposes only and must not change or delete the sync itself
void SyncApp::syncupdate_local_folder_addition(Sync* sync, const char* path)
{
    if (debug)
	cout << "Sync - local folder addition detected: " << path << endl;
}

void SyncApp::syncupdate_local_folder_deletion(Sync* sync, const char* path)
{
    if (debug)
	cout << "Sync - local folder deletion detected: " << path << endl;
}

void SyncApp::syncupdate_local_file_addition(Sync* sync, const char* path)
{
    if (debug)
	cout << "Sync - local file addition detected: " << path << endl;
}

void SyncApp::syncupdate_local_file_deletion(Sync* sync, const char* path)
{
    if (debug)
	cout << "Sync - local file deletion detected: " << path << endl;
}

void SyncApp::syncupdate_local_file_change(Sync* sync, const char* path)
{
    if (debug)
	cout << "Sync - local file change detected: " << path << endl;
}

void SyncApp::syncupdate_local_move(Sync*, const char* from, const char* to)
{
    if (debug)
	cout << "Sync - local rename/move " << from << " -> " << to << endl;
}

void SyncApp::syncupdate_remote_move(string* from, string* to)
{
    if (debug)
	cout << "Sync - remote rename/move " << *from << " -> " << *to << endl;
}

void SyncApp::syncupdate_remote_folder_addition(Node* n)
{
    if (debug)
	cout << "Sync - remote folder addition detected " << n->displayname() << endl;
}

void SyncApp::syncupdate_remote_file_addition(Node* n)
{
    if (debug)
	cout << "Sync - remote file addition detected " << n->displayname() << endl;
}

void SyncApp::syncupdate_remote_folder_deletion(Node* n)
{
    if (debug)
	cout << "Sync - remote folder deletion detected " << n->displayname() << endl;
}

void SyncApp::syncupdate_remote_file_deletion(Node* n)
{
    if (debug)
	cout << "Sync - remote file deletion detected " << n->displayname() << endl;
}

void SyncApp::syncupdate_get(Sync*, const char* path)
{
    if (debug)
	cout << "Sync - requesting file " << path << endl;
}

void SyncApp::syncupdate_put(Sync*, const char* path)
{
    if (debug)
	cout << "Sync - sending file " << path << endl;
}

void SyncApp::syncupdate_remote_copy(Sync*, const char* name)
{
    if (debug)
	cout << "Sync - creating remote file " << name << " by copying existing remote file" << endl;
}

static const char* treestatename(treestate_t ts)
{
	switch (ts)
	{
		case TREESTATE_NONE:
			return "None/Undefined";
		case TREESTATE_SYNCED:
			return "Synced";
		case TREESTATE_PENDING:
			return "Pending";
		case TREESTATE_SYNCING:
			return "Syncing";
	}

	return "UNKNOWN";
}

void SyncApp::syncupdate_treestate(LocalNode* l)
{
    if (debug)
	cout << "Sync - state change of node " << l->name << " to " << treestatename(l->ts) << endl;
}

//
int main (int argc, char *argv[])
{
    static byte pwkey[SymmCipher::KEYLENGTH];
    bool is_active = true;
    SyncApp *app;

    if (argc < 3) {
        cout << "Usage: " << argv[0] << " [local folder] [remote folder]" << endl;
        return 1;
    }

    app = new SyncApp (argv[1], argv[2]);

    if (!getenv ("MEGA_EMAIL") || !getenv ("MEGA_PWD")) {
        cout << "Please set both MEGA_EMAIL and MEGA_PWD env variables!" << endl;
        return 1;
    }

    // if MEGA_DEBUG env variable is set
    if (getenv ("MEGA_DEBUG")) {
        if (!strcmp (getenv ("MEGA_DEBUG"), "1")) {
            app->debug = true;
        } else if (!strcmp (getenv ("MEGA_DEBUG"), "2")) {
            app->debug = true;
            mega::debug = true;
        }
    }

    // create MegaClient, providing our custom MegaApp and Waiter classes
    client = new MegaClient(app, new WAIT_CLASS, new HTTPIO_CLASS, new FSACCESS_CLASS,
//#ifdef DBACCESS_CLASS
//	new DBACCESS_CLASS,
//#else
	NULL,
//#endif
    "megasync", "megaclisync");

    // get values from env
    client->pw_key (getenv ("MEGA_PWD"), pwkey);
    client->login (getenv ("MEGA_EMAIL"), pwkey);

    while (is_active) {
	    // pass the CPU to the engine (nonblocking)
		client->exec();
		client->wait();
    }

    return 0;
}
<commit_msg>remove mega::debug variable<commit_after>/**
 * @file examples/megasync.cpp
 * @brief sample daemon, which synchronizes local and remote folders
 *
 * (c) 2013 by Mega Limited, Wellsford, New Zealand
 *
 * This file is part of the MEGA SDK - Client Access Engine.
 *
 * Applications using the MEGA API must present a valid application key
 * and comply with the the rules set forth in the Terms of Service.
 *
 * The MEGA SDK is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * @copyright Simplified (2-clause) BSD License.
 *
 * You should have received a copy of the license along with this
 * program.
 */

#include "mega.h"

#ifdef _WIN32
#include <conio.h>
#endif

using namespace mega;

class SyncApp : public MegaApp
{
    string local_folder;
    string remote_folder;
    handle cwd;
    bool initial_fetch;

    void debug_log(const char*);
    void login_result(error e);

	void fetchnodes_result (error e);

    void request_error(error e);
	void syncupdate_state(Sync*, syncstate_t);

	void syncupdate_stuck(string*);
	void syncupdate_local_folder_addition(Sync*, const char*);
	void syncupdate_local_folder_deletion(Sync*, const char*);
	void syncupdate_local_file_addition(Sync*, const char*);
	void syncupdate_local_file_deletion(Sync*, const char*);
	void syncupdate_local_file_change(Sync*, const char*);
	void syncupdate_local_move(Sync*, const char*, const char*);
	void syncupdate_get(Sync*, const char*);
	void syncupdate_put(Sync*, const char*);
	void syncupdate_remote_file_addition(Node*);
	void syncupdate_remote_file_deletion(Node*);
	void syncupdate_remote_folder_addition(Node*);
	void syncupdate_remote_folder_deletion(Node*);
	void syncupdate_remote_copy(Sync*, const char*);
	void syncupdate_remote_move(string*, string*);
	void syncupdate_treestate(LocalNode*);

    Node* nodebypath(const char* ptr, string* user, string* namepart);
public:
    bool debug;
    SyncApp (string local_folder_, string remote_folder_);
};

// globals
MegaClient* client;

// returns node pointer determined by path relative to cwd
// Path naming conventions:
// path is relative to cwd
// /path is relative to ROOT
// //in is in INBOX
// //bin is in RUBBISH
// X: is user X's INBOX
// X:SHARE is share SHARE from user X
// : and / filename components, as well as the \, must be escaped by \.
// (correct UTF-8 encoding is assumed)
// returns NULL if path malformed or not found
Node* SyncApp::nodebypath(const char* ptr, string* user = NULL, string* namepart = NULL)
{
	vector<string> c;
	string s;
	int l = 0;
	const char* bptr = ptr;
	int remote = 0;
	Node* n;
	Node* nn;

	// split path by / or :
	do {
		if (!l)
		{
			if (*ptr >= 0)
			{
				if (*ptr == '\\')
				{
					if (ptr > bptr) s.append(bptr,ptr-bptr);
					bptr = ++ptr;

					if (*bptr == 0)
					{
						c.push_back(s);
						break;
					}

					ptr++;
					continue;
				}

				if (*ptr == '/' || *ptr == ':' || !*ptr)
				{
					if (*ptr == ':')
					{
						if (c.size()) return NULL;
						remote = 1;
					}

					if (ptr > bptr) s.append(bptr,ptr-bptr);

					bptr = ptr+1;

					c.push_back(s);

					s.erase();
				}
			}
			else if ((*ptr & 0xf0) == 0xe0) l = 1;
			else if ((*ptr & 0xf8) == 0xf0) l = 2;
			else if ((*ptr & 0xfc) == 0xf8) l = 3;
			else if ((*ptr & 0xfe) == 0xfc) l = 4;
		}
		else l--;
	} while (*ptr++);

	if (l) return NULL;

	if (remote)
	{
		// target: user inbox - record username/email and return NULL
		if (c.size() == 2 && !c[1].size())
		{
			if (user) *user = c[0];
			return NULL;
		}

		User* u;

		if ((u = client->finduser(c[0].c_str())))
		{
			// locate matching share from this user
			handle_set::iterator sit;

			for (sit = u->sharing.begin(); sit != u->sharing.end(); sit++)
			{
				if ((n = client->nodebyhandle(*sit)))
				{
					if (!strcmp(c[1].c_str(),n->displayname()))
					{
						l = 2;
						break;
					}
				}

				if (l) break;
			}
		}

		if (!l) return NULL;
	}
	else
	{
		// path starting with /
		if (c.size() > 1 && !c[0].size())
		{
			// path starting with //
			if (c.size() > 2 && !c[1].size())
			{
				if (c[2] == "in") n = client->nodebyhandle(client->rootnodes[1]);
				else if (c[2] == "bin") n = client->nodebyhandle(client->rootnodes[2]);
				else if (c[2] == "mail") n = client->nodebyhandle(client->rootnodes[3]);
				else return NULL;

				l = 3;
			}
			else
			{
				n = client->nodebyhandle(client->rootnodes[0]);

				l = 1;
			}
		}
		else n = client->nodebyhandle(cwd);
	}

	// parse relative path
	while (n && l < (int)c.size())
	{
		if (c[l] != ".")
		{
			if (c[l] == "..")
			{
				if (n->parent) n = n->parent;
			}
			else
			{
				// locate child node (explicit ambiguity resolution: not implemented)
				if (c[l].size())
				{
					nn = client->childnodebyname(n,c[l].c_str());

					if (!nn)
					{
						// mv command target? return name part of not found
						if (namepart && l == (int)c.size()-1)
						{
							*namepart = c[l];
							return n;
						}

						return NULL;
					}

					n = nn;
				}
			}
		}

		l++;
	}

	return n;
}

SyncApp:: SyncApp (string local_folder_, string remote_folder_):
    local_folder (local_folder_), remote_folder (remote_folder_), cwd (UNDEF), initial_fetch (true)
{
}

// callback for displaying debug logs
void SyncApp::debug_log(const char* message)
{
    if (debug)
        cout << "DEBUG: " << message << endl;
}

// this callback function is called when we have login result (success or error)
// TODO: check for errors
void SyncApp::login_result(error e)
{
    if (e != API_OK) {
        cout << "FATAL: Failed to get login result, exiting" << endl;
        exit (1);
    }
    // get the list of nodes
    client->fetchnodes();
}

void SyncApp::fetchnodes_result (error e)
{
    if (e != API_OK) {
        cout << "FATAL: Failed to fetch remote nodes, exiting" << endl;
        exit (1);
    }

    cout << "fetchnodes_result" << endl;

    if (initial_fetch) {
        initial_fetch = false;
        if (ISUNDEF(cwd)) cwd = client->rootnodes[0];

        Node* n = nodebypath(remote_folder.c_str());
        if (client->checkaccess(n, FULL))
        {
            string localname;

            client->fsaccess->path2local(&local_folder, &localname);

            if (!n) {
                cout << remote_folder << ": Not found." << endl;
                exit (1);
            } else if (n->type == FILENODE) {
                cout << remote_folder << ": Remote sync root must be folder." << endl;
                exit (1);
            } else {
				error e = client->addsync(&localname,"Debris",NULL,n,0);
                if (e) {
                    cout << "Sync could not be added! " << endl;
                    exit (1);
                }

                cout << "Sync started !" << endl;
            }
        } else {
            cout << remote_folder << ": Syncing requires full access to path." << endl;
            exit (1);
        }
    }
}

// this callback function is called when request-level error occurred
void SyncApp::request_error(error e)
{
    cout << "FATAL: Request failed, exiting" << endl;
    exit (1);
}

void SyncApp::syncupdate_state(Sync*, syncstate_t state)
{
    if (state == SYNC_CANCELED || state == SYNC_FAILED) {
        cout << "FATAL: Sync failed !" << endl;
        exit (1);
    } else if (state == SYNC_ACTIVE) {
		cout << "Sync is now active" << endl;
    }
}

void SyncApp::syncupdate_stuck(string* reason)
{
	if (reason) cout << "Sync halted: " << *reason << " temporarily in use" << endl;
	else cout << "Sync resumed" << endl;
}

// sync update callbacks are for informational purposes only and must not change or delete the sync itself
void SyncApp::syncupdate_local_folder_addition(Sync* sync, const char* path)
{
    if (debug)
	cout << "Sync - local folder addition detected: " << path << endl;
}

void SyncApp::syncupdate_local_folder_deletion(Sync* sync, const char* path)
{
    if (debug)
	cout << "Sync - local folder deletion detected: " << path << endl;
}

void SyncApp::syncupdate_local_file_addition(Sync* sync, const char* path)
{
    if (debug)
	cout << "Sync - local file addition detected: " << path << endl;
}

void SyncApp::syncupdate_local_file_deletion(Sync* sync, const char* path)
{
    if (debug)
	cout << "Sync - local file deletion detected: " << path << endl;
}

void SyncApp::syncupdate_local_file_change(Sync* sync, const char* path)
{
    if (debug)
	cout << "Sync - local file change detected: " << path << endl;
}

void SyncApp::syncupdate_local_move(Sync*, const char* from, const char* to)
{
    if (debug)
	cout << "Sync - local rename/move " << from << " -> " << to << endl;
}

void SyncApp::syncupdate_remote_move(string* from, string* to)
{
    if (debug)
	cout << "Sync - remote rename/move " << *from << " -> " << *to << endl;
}

void SyncApp::syncupdate_remote_folder_addition(Node* n)
{
    if (debug)
	cout << "Sync - remote folder addition detected " << n->displayname() << endl;
}

void SyncApp::syncupdate_remote_file_addition(Node* n)
{
    if (debug)
	cout << "Sync - remote file addition detected " << n->displayname() << endl;
}

void SyncApp::syncupdate_remote_folder_deletion(Node* n)
{
    if (debug)
	cout << "Sync - remote folder deletion detected " << n->displayname() << endl;
}

void SyncApp::syncupdate_remote_file_deletion(Node* n)
{
    if (debug)
	cout << "Sync - remote file deletion detected " << n->displayname() << endl;
}

void SyncApp::syncupdate_get(Sync*, const char* path)
{
    if (debug)
	cout << "Sync - requesting file " << path << endl;
}

void SyncApp::syncupdate_put(Sync*, const char* path)
{
    if (debug)
	cout << "Sync - sending file " << path << endl;
}

void SyncApp::syncupdate_remote_copy(Sync*, const char* name)
{
    if (debug)
	cout << "Sync - creating remote file " << name << " by copying existing remote file" << endl;
}

static const char* treestatename(treestate_t ts)
{
	switch (ts)
	{
		case TREESTATE_NONE:
			return "None/Undefined";
		case TREESTATE_SYNCED:
			return "Synced";
		case TREESTATE_PENDING:
			return "Pending";
		case TREESTATE_SYNCING:
			return "Syncing";
	}

	return "UNKNOWN";
}

void SyncApp::syncupdate_treestate(LocalNode* l)
{
    if (debug)
	cout << "Sync - state change of node " << l->name << " to " << treestatename(l->ts) << endl;
}

//
int main (int argc, char *argv[])
{
    static byte pwkey[SymmCipher::KEYLENGTH];
    bool is_active = true;
    SyncApp *app;

    if (argc < 3) {
        cout << "Usage: " << argv[0] << " [local folder] [remote folder]" << endl;
        return 1;
    }

    app = new SyncApp (argv[1], argv[2]);

    if (!getenv ("MEGA_EMAIL") || !getenv ("MEGA_PWD")) {
        cout << "Please set both MEGA_EMAIL and MEGA_PWD env variables!" << endl;
        return 1;
    }

    // if MEGA_DEBUG env variable is set
    if (getenv ("MEGA_DEBUG")) {
        if (!strcmp (getenv ("MEGA_DEBUG"), "1")) {
            app->debug = true;
        } else if (!strcmp (getenv ("MEGA_DEBUG"), "2")) {
            app->debug = true;
        }
    }

    // create MegaClient, providing our custom MegaApp and Waiter classes
    client = new MegaClient(app, new WAIT_CLASS, new HTTPIO_CLASS, new FSACCESS_CLASS,
//#ifdef DBACCESS_CLASS
//	new DBACCESS_CLASS,
//#else
	NULL,
//#endif
    "megasync", "megaclisync");

    // get values from env
    client->pw_key (getenv ("MEGA_PWD"), pwkey);
    client->login (getenv ("MEGA_EMAIL"), pwkey);

    while (is_active) {
	    // pass the CPU to the engine (nonblocking)
		client->exec();
		client->wait();
    }

    return 0;
}
<|endoftext|>


<commit_before>/*****************************************************************************
 * Licensed to Qualys, Inc. (QUALYS) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * QUALYS licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ****************************************************************************/

/**
 * @file
 * @brief Predicate --- DAG
 *
 * Defines the base hierarchy for DAG nodes.
 *
 * @author Christopher Alfeld <calfeld@qualys.com>
 */

#ifndef __PREDICATE__DAG__
#define __PREDICATE__DAG__

#include <boost/foreach.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>

#include <iostream>
#include <list>
#include <string>

#include <ironbeepp/field.hpp>
#include <ironbeepp/transaction.hpp>

namespace IronBee {
namespace Predicate {

typedef IronBee::ConstField Value;
typedef IronBee::ConstTransaction Context;

class Node;
class Call;
class Literal;
class Null;
class String;

// Defined in reporter.hpp
class NodeReporter;
// Defined in merge_graph.hpp
class MergeGraph;
// Defined in call_factory.hpp
class CallFactory;

/// @cond Impl
namespace Impl {

/**
 * Used to make certain classes unsubclassable.
 *
 * See C++ FAQ.
 **/
class Final
{
    // Classes to be final.
    friend class Null;
    friend class String;
private:
    //! Private constructor.
    Final() {}
};

} // Impl
/// @endcond

/**
 * Shared pointer to Node.
 **/
typedef boost::shared_ptr<Node> node_p;

/**
 * Weak pointer to Node.
 **/
typedef boost::weak_ptr<Node> weak_node_p;

/**
 * Shared const pointer to Node.
 **/
typedef boost::shared_ptr<const Node> node_cp;

/**
 * Shared pointer to Call.
 **/
typedef boost::shared_ptr<Call> call_p;

/**
 * Shared const pointer to Call.
 **/
typedef boost::shared_ptr<const Call> call_cp;

/**
 * Shared pointer to Literal.
 **/
typedef boost::shared_ptr<Literal> literal_p;

/**
 * Shared const pointer to Literal.
 **/
typedef boost::shared_ptr<const Literal> literal_cp;

//! List of nodes.  See children().
typedef std::list<node_p> node_list_t;

//! Weak list of nodes.  See parents().
typedef std::list<weak_node_p> weak_node_list_t;

/**
 * A node in the predicate DAG.
 *
 * Nodes make up the predicate DAG.  They also appear in the expressions trees
 * that are merged together to construct the DAG. This class is the top of
 * the class hierarchy for nodes.  It can not be directly instantiated or
 * subclassed.  For literal values, instantiate Null or String.  For
 * call values, create and instantiate a subclass of Call.
 *
 * @sa Call
 * @sa Literal
 */
class Node :
    public boost::enable_shared_from_this<Node>
{
    friend class Call;
    friend class Literal;

private:
    //! Private Constructor.
    Node();

public:

    //! Destructor.
    virtual ~Node();

    /**
     * S-Expression.
     *
     * An S-expression representation of the expression tree rooted at this
     * node.  See parse.hpp for detailed grammar.
     *
     * This method returns a string reference, but this reference is not
     * stable if this node or any children are changed.  It should be copied
     * if needed beyond such operations.
     *
     * S-Expressions are calculated dynamically and cached, so calling this
     * method is cheap.
     *
     * @return S-Expression of expression tree rooted at node.
     **/
    virtual const std::string& to_s() const = 0;

    /**
     * Add a child.
     *
     * Adds to end of children() and adds @c this to end of parents() of
     * child.  Subclasses can add additional behavior.
     *
     * O(1)
     *
     * @param[in] child Child to add.
     * @throw IronBee::einval if ! @a child.
     **/
    virtual void add_child(const node_p& child);

    /**
     * Remove a child.
     *
     * Removes from children() and removes @c this from parents() of child.
     * Subclasses can add additional behavior.
     *
     * O(n) where n is size of children() of @c this or parents() of child.
     *
     * @param[in] child Child to remove.
     * @throw IronBee::enoent if no such child.
     * @throw IronBee::einval if not a parent of child.
     * @throw IronBee::einval if ! @a child.
     **/
    virtual void remove_child(const node_p& child);

    /**
     * Replace a child.
     *
     * Replaces a child with another node.  This can be used to change
     * a child without moving it to the end of the children as remove_child(),
     * add_child() would.
     *
     * O(n) where n is size of children() of @c this or parents() of child.
     *
     * @param[in] child Child to replace.
     * @param[in] with  Child to replace with.
     * @throw IronBee::enoent if no such child.
     * @throw IronBee::einval if not a parent of child.
     * @throw IronBee::einval if ! @a child or ! @a with.
     **/
    virtual void replace_child(const node_p& child, const node_p& with);

    //! Children accessor -- const.
    const node_list_t& children() const
    {
        return m_children;
    }
    //! Parents accessor -- const.
    const weak_node_list_t& parents() const
    {
        return m_parents;
    }

    //! True iff has value.
    bool has_value() const
    {
        return m_has_value;
    }

    //! True iff node is a literal, in which case eval(Context()) is valid.
    bool is_literal() const;

    //! Return value, calculating if needed.
    Value eval(Context context);

    //! Return value, throwing if none.
    Value value() const;

    //! Reset to valueless.
    void reset();

    /**
     * Perform pre-transformation validations.
     *
     * This method may be overridden by a child.  Default behavior is to do
     * nothing.
     *
     * @note Exceptions will not be immediately caught so should only be used
     *       if it is appropriate to abort the entire predicate system, e.g.,
     *       on an insanity error.
     *
     * @param[in] reporter Reporter to use for errors or warnings.
     **/
    virtual void pre_transform(NodeReporter reporter) const;

    /**
     * Perform transformations.
     *
     * This method may be overridden by a child.  Default behavior is to
     * do nothing and return false.
     *
     * This method is called for every Node during the transformation phase.
     * If any such call returns true, the whole process is repeated.
     *
     * Transformations should not be done directly, but rather through
     * @a merge_graph(), i.e., do not use add_child(), remove_child(), or
     * replace_child(); instead use MergeGraph::add(), MergeGraph::remove(),
     * or MergeGraph::replace().  Note that your method can fetch a
     * @ref node_p for itself via shared_from_this().
     *
     * Note: Reporting errors will allow the current transformation loop to
     * continue for other nodes, but will then end the transformation phase.
     *
     * @param[in] reporter     Reporter to use for errors or warnings.
     * @param[in] merge_graph  MergeGraph used to change the DAG.
     * @param[in] call_factory CallFactory to create new nodes with.
     * @return true iff any changes were made.
     **/
    virtual bool transform(
        NodeReporter       reporter,
        MergeGraph&        merge_graph,
        const CallFactory& call_factory
    );

    /**
     * Perform post-transformation validations.
     *
     * See pre_transform() for additional discussion.
     * @param[in] reporter Reporter to use for errors or warnings.
     **/
    virtual void post_transform(NodeReporter reporter) const;

protected:
    /**
     * Calculate value.
     *
     * Subclass classes should implement this to calculate and return the
     * value.
     *
     * @param [in] context Contex of calculation.
     * @return Value of node.
     */
    virtual Value calculate(Context context) = 0;

private:
    /**
     * Remove this from parents of @a child.
     *
     * @param[in] child Child to unlink from.
     * @throw IronBee::einval if not in @a child's parent list.
     **/
    void unlink_from_child(const node_p& child) const;

    bool             m_has_value;
    Value            m_value;
    weak_node_list_t m_parents;
    node_list_t      m_children;
};

//! Ostream output operator.
std::ostream& operator<<(std::ostream& out, const Node& node);

/**
 * Node representing a function Call.
 *
 * All Call nodes must have a name.  Calls with the same name are considered
 * to implement the same function.
 *
 * This class is unique in the class hierarchy as being subclassable.  Users
 * should create subclasses for specific functions.  Subclasses must implement
 * name() and calculate().  Subclasses may also define add_child(),
 * remove_child(), and replace_child() but must call the parents methods
* within.
 **/
class Call :
    public Node
{
public:
    //! Constructor.
    Call();

    //! See Node::add_child().
    virtual void add_child(const node_p& child);

    //! See Node::remove_child().
    virtual void remove_child(const node_p& child);

    //! See Node::replace_child().
    virtual void replace_child(const node_p& child, const node_p& with);

    //! S-expression: (@c name children...)
    virtual const std::string& to_s() const;

    /**
     * Name accessor.
     */
    virtual std::string name() const = 0;

private:
    //! Mark m_s as in need of recalculation.
    void reset_s() const;

    //! Recalculate m_s.
    void recalculate_s() const;

    // Because name() is pure, Call::Call() can not calculate m_s.  I.e., we
    // need to fully construct the class before setting m_s.  So we have
    // to_s() calculate it on the fly the first time.  The following two
    // members maintain that cache.

    //! Have we calculate m_s at all?
    mutable bool m_calculated_s;

    //! String form.
    mutable std::string m_s;
};

/**
 * Literal node: no children and value independent of Context.
 *
 * This class may not be subclassed.
 **/
class Literal :
    public Node
{
    friend class String;
    friend class Null;

private:
    //! Private constructor to limit subclassing.
    Literal() {}
public:
    //! @throw IronBee::einval always.
    virtual void add_child(const node_p&);
    //! @throw IronBee::einval always.
    virtual void remove_child(const node_p&);
    //! @throw IronBee::einval always.
    virtual void replace_child(const node_p& child, const node_p& with);
};

/**
 * String literal: Literal node representing a string.
 *
 * This class may not be subclassed.
 **/
class String :
    public Literal,
    public virtual Impl::Final
{
public:
    /**
     * Constructor.
     *
     * @param[in] s Value of node.
     **/
    explicit
    String(const std::string& value);

    //! Value as string.
    std::string value_as_s() const
    {
        return m_value_as_s;
    }

    //! S-expression: 'value'
    virtual const std::string& to_s() const
    {
        return m_s;
    }

    /**
     * Escape a string.
     *
     * Adds backslashes before all single quotes and backslashes.
     *
     * @param[in] s String to escape.
     * @return Escaped string.
     **/
    static std::string escape(const std::string& s);

protected:
    //! See Node::calculate()
    virtual Value calculate(Context context);

private:
    //! Value as a C++ string.
    const std::string         m_value_as_s;
    //! S-expression.
    const std::string         m_s;
    //! Memory pool to create field value from.  Alias of m_value_as_s.
    boost::shared_ptr<
        IronBee::ScopedMemoryPool
    > m_pool;
    //! Value returned by calculate().
    IronBee::ConstField       m_value_as_field;
};

/**
 * Null literal: Literal node representing the null value.
 *
 * This class may not be subclassed.
 **/
class Null :
    public Literal,
    public virtual Impl::Final
{
public:
    //! S-expression: null
    virtual const std::string& to_s() const;

protected:
    //! See Node::calculate()
    virtual Value calculate(Context context);
};

} // Predicate
} // IronBee

#endif
<commit_msg>predicate/dag: Improved documentation.<commit_after>/*****************************************************************************
 * Licensed to Qualys, Inc. (QUALYS) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * QUALYS licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ****************************************************************************/

/**
 * @file
 * @brief Predicate --- DAG
 *
 * Defines the base hierarchy for DAG nodes.
 *
 * @author Christopher Alfeld <calfeld@qualys.com>
 */

#ifndef __PREDICATE__DAG__
#define __PREDICATE__DAG__

#include <boost/foreach.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>

#include <iostream>
#include <list>
#include <string>

#include <ironbeepp/field.hpp>
#include <ironbeepp/transaction.hpp>

namespace IronBee {
namespace Predicate {

/*
 * The following typedefs are the primary parameters for tying the public
 * API to IronBee.  If this code was to be used in a different system, much
 * of the implementation, especially of standard.hpp, would need to change,
 * but changing these typedefs should suffice for adapating the
 * public API.
 */

/**
 * Value of a node.
 **/
typedef IronBee::ConstField Value;

/**
 * Context a node is evaluated in.
 **/
typedef IronBee::ConstTransaction Context;

// Defined below.
class Node;
class Call;
class Literal;
class Null;
class String;

// Defined in reporter.hpp
class NodeReporter;
// Defined in merge_graph.hpp
class MergeGraph;
// Defined in call_factory.hpp
class CallFactory;

/// @cond Impl
namespace Impl {

/**
 * Used to make certain classes unsubclassable.
 *
 * See C++ FAQ.
 **/
class Final
{
    // Classes to be final.
    friend class Null;
    friend class String;
private:
    //! Private constructor.
    Final() {}
};

} // Impl
/// @endcond

/**
 * Shared pointer to Node.
 **/
typedef boost::shared_ptr<Node> node_p;

/**
 * Weak pointer to Node.
 **/
typedef boost::weak_ptr<Node> weak_node_p;

/**
 * Shared const pointer to Node.
 **/
typedef boost::shared_ptr<const Node> node_cp;

/**
 * Shared pointer to Call.
 **/
typedef boost::shared_ptr<Call> call_p;

/**
 * Shared const pointer to Call.
 **/
typedef boost::shared_ptr<const Call> call_cp;

/**
 * Shared pointer to Literal.
 **/
typedef boost::shared_ptr<Literal> literal_p;

/**
 * Shared const pointer to Literal.
 **/
typedef boost::shared_ptr<const Literal> literal_cp;

//! List of nodes.  See children().
typedef std::list<node_p> node_list_t;

//! Weak list of nodes.  See parents().
typedef std::list<weak_node_p> weak_node_list_t;

/**
 * A node in the predicate DAG.
 *
 * Nodes make up the predicate DAG.  They also appear in the expressions trees
 * that are merged together to construct the DAG. This class is the top of
 * the class hierarchy for nodes.  It can not be directly instantiated or
 * subclassed.  For literal values, instantiate Null or String.  For
 * call values, create and instantiate a subclass of Call.
 *
 * @sa Call
 * @sa Literal
 */
class Node :
    public boost::enable_shared_from_this<Node>
{
    friend class Call;
    friend class Literal;

private:
    //! Private Constructor.
    Node();

public:

    //! Destructor.
    virtual ~Node();

    /**
     * S-Expression.
     *
     * An S-expression representation of the expression tree rooted at this
     * node.  See parse.hpp for detailed grammar.
     *
     * This method returns a string reference, but this reference is not
     * stable if this node or any children are changed.  It should be copied
     * if needed beyond such operations.
     *
     * S-Expressions are calculated dynamically and cached, so calling this
     * method is cheap.
     *
     * @return S-Expression of expression tree rooted at node.
     **/
    virtual const std::string& to_s() const = 0;

    /**
     * Add a child.
     *
     * Adds to end of children() and adds @c this to end of parents() of
     * child.  Subclasses can add additional behavior.
     *
     * O(1)
     *
     * @param[in] child Child to add.
     * @throw IronBee::einval if ! @a child.
     **/
    virtual void add_child(const node_p& child);

    /**
     * Remove a child.
     *
     * Removes from children() and removes @c this from parents() of child.
     * Subclasses can add additional behavior.
     *
     * O(n) where n is size of children() of @c this or parents() of child.
     *
     * @param[in] child Child to remove.
     * @throw IronBee::enoent if no such child.
     * @throw IronBee::einval if not a parent of child.
     * @throw IronBee::einval if ! @a child.
     **/
    virtual void remove_child(const node_p& child);

    /**
     * Replace a child.
     *
     * Replaces a child with another node.  This can be used to change
     * a child without moving it to the end of the children as remove_child(),
     * add_child() would.
     *
     * O(n) where n is size of children() of @c this or parents() of child.
     *
     * @param[in] child Child to replace.
     * @param[in] with  Child to replace with.
     * @throw IronBee::enoent if no such child.
     * @throw IronBee::einval if not a parent of child.
     * @throw IronBee::einval if ! @a child or ! @a with.
     **/
    virtual void replace_child(const node_p& child, const node_p& with);

    //! Children accessor -- const.
    const node_list_t& children() const
    {
        return m_children;
    }
    //! Parents accessor -- const.
    const weak_node_list_t& parents() const
    {
        return m_parents;
    }

    //! True iff has value.
    bool has_value() const
    {
        return m_has_value;
    }

    //! True iff node is a literal, in which case eval(Context()) is valid.
    bool is_literal() const;

    //! Return value, calculating if needed.
    Value eval(Context context);

    //! Return value, throwing if none.
    Value value() const;

    //! Reset to valueless.
    void reset();

    /**
     * Perform pre-transformation validations.
     *
     * This method may be overridden by a child.  Default behavior is to do
     * nothing.
     *
     * @note Exceptions will not be immediately caught so should only be used
     *       if it is appropriate to abort the entire predicate system, e.g.,
     *       on an insanity error.
     *
     * @param[in] reporter Reporter to use for errors or warnings.
     **/
    virtual void pre_transform(NodeReporter reporter) const;

    /**
     * Perform transformations.
     *
     * This method may be overridden by a child.  Default behavior is to
     * do nothing and return false.
     *
     * This method is called for every Node during the transformation phase.
     * If any such call returns true, the whole process is repeated.
     *
     * Transformations should not be done directly, but rather through
     * @a merge_graph(), i.e., do not use add_child(), remove_child(), or
     * replace_child(); instead use MergeGraph::add(), MergeGraph::remove(),
     * or MergeGraph::replace().  Note that your method can fetch a
     * @ref node_p for itself via shared_from_this().
     *
     * Note: Reporting errors will allow the current transformation loop to
     * continue for other nodes, but will then end the transformation phase.
     *
     * @param[in] reporter     Reporter to use for errors or warnings.
     * @param[in] merge_graph  MergeGraph used to change the DAG.
     * @param[in] call_factory CallFactory to create new nodes with.
     * @return true iff any changes were made.
     **/
    virtual bool transform(
        NodeReporter       reporter,
        MergeGraph&        merge_graph,
        const CallFactory& call_factory
    );

    /**
     * Perform post-transformation validations.
     *
     * See pre_transform() for additional discussion.
     * @param[in] reporter Reporter to use for errors or warnings.
     **/
    virtual void post_transform(NodeReporter reporter) const;

protected:
    /**
     * Calculate value.
     *
     * Subclass classes should implement this to calculate and return the
     * value.
     *
     * @param [in] context Contex of calculation.
     * @return Value of node.
     */
    virtual Value calculate(Context context) = 0;

private:
    /**
     * Remove this from parents of @a child.
     *
     * @param[in] child Child to unlink from.
     * @throw IronBee::einval if not in @a child's parent list.
     **/
    void unlink_from_child(const node_p& child) const;

    //! True if a value has been set.
    bool m_has_value;
    //! What value has been set; may be singular to indicate null/false.
    Value m_value;
    //! List of parents (note weak pointers).
    weak_node_list_t m_parents;
    //! List of children.
    node_list_t m_children;
};

//! Ostream output operator.
std::ostream& operator<<(std::ostream& out, const Node& node);

/**
 * Node representing a function Call.
 *
 * All Call nodes must have a name.  Calls with the same name are considered
 * to implement the same function.
 *
 * This class is unique in the class hierarchy as being subclassable.  Users
 * should create subclasses for specific functions.  Subclasses must implement
 * name() and calculate().  Subclasses may also define add_child(),
 * remove_child(), and replace_child() but must call the parents methods
* within.
 **/
class Call :
    public Node
{
public:
    //! Constructor.
    Call();

    //! See Node::add_child().
    virtual void add_child(const node_p& child);

    //! See Node::remove_child().
    virtual void remove_child(const node_p& child);

    //! See Node::replace_child().
    virtual void replace_child(const node_p& child, const node_p& with);

    //! S-expression: (@c name children...)
    virtual const std::string& to_s() const;

    /**
     * Name accessor.
     */
    virtual std::string name() const = 0;

private:
    //! Mark m_s as in need of recalculation.
    void reset_s() const;

    //! Recalculate m_s.
    void recalculate_s() const;

    // Because name() is pure, Call::Call() can not calculate m_s.  I.e., we
    // need to fully construct the class before setting m_s.  So we have
    // to_s() calculate it on the fly the first time.  The following two
    // members maintain that cache.

    //! Have we calculate m_s at all?
    mutable bool m_calculated_s;

    //! String form.
    mutable std::string m_s;
};

/**
 * Literal node: no children and value independent of Context.
 *
 * This class may not be subclassed.
 **/
class Literal :
    public Node
{
    friend class String;
    friend class Null;

private:
    //! Private constructor to limit subclassing.
    Literal() {}
public:
    //! @throw IronBee::einval always.
    virtual void add_child(const node_p&);
    //! @throw IronBee::einval always.
    virtual void remove_child(const node_p&);
    //! @throw IronBee::einval always.
    virtual void replace_child(const node_p& child, const node_p& with);
};

/**
 * String literal: Literal node representing a string.
 *
 * This class may not be subclassed.
 **/
class String :
    public Literal,
    public virtual Impl::Final
{
public:
    /**
     * Constructor.
     *
     * @param[in] s Value of node.
     **/
    explicit
    String(const std::string& value);

    //! Value as string.
    std::string value_as_s() const
    {
        return m_value_as_s;
    }

    //! S-expression: 'value'
    virtual const std::string& to_s() const
    {
        return m_s;
    }

    /**
     * Escape a string.
     *
     * Adds backslashes before all single quotes and backslashes.
     *
     * @param[in] s String to escape.
     * @return Escaped string.
     **/
    static std::string escape(const std::string& s);

protected:
    //! See Node::calculate()
    virtual Value calculate(Context context);

private:
    //! Value as a C++ string.
    const std::string m_value_as_s;
    //! S-expression.
    const std::string m_s;
    //! Memory pool to create field value from.  Alias of m_value_as_s.
    boost::shared_ptr<IronBee::ScopedMemoryPool> m_pool;
    //! Value returned by calculate().
    IronBee::ConstField m_value_as_field;
};

/**
 * Null literal: Literal node representing the null value.
 *
 * This class may not be subclassed.
 **/
class Null :
    public Literal,
    public virtual Impl::Final
{
public:
    //! S-expression: null
    virtual const std::string& to_s() const;

protected:
    //! See Node::calculate()
    virtual Value calculate(Context context);
};

} // Predicate
} // IronBee

#endif
<|endoftext|>


<commit_before>/*
 *  FilePusher: service which monitors the file system and pushes files to
 *  a remote repository
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

/*-------------------------------------------------------------------------//
//                                                                         //
//      INCLUDES                                                           //
//                                                                         //
//-------------------------------------------------------------------------*/

#ifndef GUCEF_CORE_CGUCEFAPPLICATION_H
#include "CGUCEFApplication.h"
#define GUCEF_CORE_CGUCEFAPPLICATION_H
#endif /* GUCEF_CORE_CGUCEFAPPLICATION_H ? */

#ifndef GUCEF_CORE_LOGGING_H
#include "gucefCORE_Logging.h"
#define GUCEF_CORE_LOGGING_H
#endif /* GUCEF_CORE_LOGGING_H ? */

#ifndef GUCEF_CORE_DVCPPOSWRAP_H
#include "DVCPPOSWRAP.h"
#define GUCEF_CORE_DVCPPOSWRAP_H
#endif /* GUCEF_CORE_DVCPPOSWRAP_H ? */

#ifndef GUCEF_CORE_CROLLINGFILEACCESS_H
#include "gucefCORE_CRollingFileAccess.h"
#define GUCEF_CORE_CROLLINGFILEACCESS_H
#endif /* GUCEF_CORE_CROLLINGFILEACCESS_H ? */

#ifndef GUCEF_CORE_CONFIGSTORE_H
#include "CConfigStore.h"
#define GUCEF_CORE_CONFIGSTORE_H
#endif /* GUCEF_CORE_CONFIGSTORE_H ? */

#ifndef GUCEF_CORE_CTRACER_H
#include "CTracer.h"
#define GUCEF_CORE_CTRACER_H
#endif /* GUCEF_CORE_CTRACER_H ? */

#ifndef GUCEF_CORE_CPLATFORMNATIVECONSOLEWINDOW_H
#include "gucefCORE_CPlatformNativeConsoleWindow.h"
#define GUCEF_CORE_CPLATFORMNATIVECONSOLEWINDOW_H
#endif /* GUCEF_CORE_CPLATFORMNATIVECONSOLEWINDOW_H ? */

#ifndef GUCEF_CORE_CVALUELIST_H
#include "CValueList.h"
#define GUCEF_CORE_CVALUELIST_H
#endif /* GUCEF_CORE_CVALUELIST_H ? */

#ifndef GUCEF_CORE_CTIMER_H
#include "CTimer.h"
#define GUCEF_CORE_CTIMER_H
#endif /* GUCEF_CORE_CTIMER_H ? */

#ifndef GUCEF_COMCORE_CUDPSOCKET_H
#include "CUDPSocket.h"
#define GUCEF_COMCORE_CUDPSOCKET_H
#endif /* GUCEF_COMCORE_CUDPSOCKET_H ? */

#ifndef GUCEF_COMCORE_CTCPSERVERSOCKET_H
#include "CTCPServerSocket.h"
#define GUCEF_COMCORE_CTCPSERVERSOCKET_H
#endif /* GUCEF_COMCORE_CTCPSERVERSOCKET_H ? */

#ifndef GUCEF_COMCORE_CCOMCOREGLOBAL_H
#include "gucefCOMCORE_CComCoreGlobal.h"
#define GUCEF_COMCORE_CCOMCOREGLOBAL_H
#endif /* GUCEF_COMCORE_CCOMCOREGLOBAL_H ? */

#ifndef GUCEF_COM_CCOMGLOBAL_H
#include "gucefCOM_CComGlobal.h"
#define GUCEF_COM_CCOMGLOBAL_H
#endif /* GUCEF_COM_CCOMGLOBAL_H ? */

#ifndef GUCEF_VFS_CVFSGLOBAL_H
#include "gucefVFS_CVfsGlobal.h"
#define GUCEF_VFS_CVFSGLOBAL_H
#endif /* GUCEF_VFS_CVFSGLOBAL_H ? */

#include "FilePusher.h"

/*-------------------------------------------------------------------------//
//                                                                         //
//      NAMESPACE                                                          //
//                                                                         //
//-------------------------------------------------------------------------*/

using namespace GUCEF;

/*-------------------------------------------------------------------------//
//                                                                         //
//      UTILITIES                                                          //
//                                                                         //
//-------------------------------------------------------------------------*/

bool
LoadConfig( const CORE::CString& configPath            ,
            CORE::CValueList& keyValueList             ,
            CORE::CDataNode* loadedConfig = GUCEF_NULL )
{GUCEF_TRACE;

    #ifdef GUCEF_DEBUG_MODE
    const CORE::CString configFile = "FilePusher_d.ini";
    #else
    const CORE::CString configFile = "FilePusher.ini";
    #endif

    CORE::CString configFilePath;
    bool foundViaParam = false;
    if ( !configPath.IsNULLOrEmpty() )
    {
        GUCEF_LOG( CORE::LOGLEVEL_BELOW_NORMAL, "Checking for config file @ " + configPath );
        foundViaParam = CORE::FileExists( configPath );
        configFilePath = configPath;
    }

    if ( !foundViaParam )
    {
        configFilePath = CORE::CombinePath( "$CURWORKDIR$", configFile );
        configFilePath = CORE::RelativePath( configFilePath );

        GUCEF_LOG( CORE::LOGLEVEL_BELOW_NORMAL, "Checking for config file @ " + configFilePath );
        if ( !CORE::FileExists( configFilePath ) )
        {
            configFilePath = CORE::CombinePath( "$MODULEDIR$", configFile );
            configFilePath = CORE::RelativePath( configFilePath );

            GUCEF_LOG( CORE::LOGLEVEL_BELOW_NORMAL, "Checking for config file @ " + configFilePath );
            if ( !FileExists( configFilePath ) )
            {
                GUCEF_WARNING_LOG( CORE::LOGLEVEL_NORMAL, "Unable to locate any config file, will rely on params" );
                return false;
            }
        }
    }
    GUCEF_LOG( CORE::LOGLEVEL_NORMAL, "Located config file @ " + configFilePath );

    keyValueList.SetConfigNamespace( "Main/AppArgs" );
    keyValueList.SetUseGlobalConfig( true );
    keyValueList.SetAllowDuplicates( false );
    keyValueList.SetAllowMultipleValues( true );

    CORE::CConfigStore& configStore = CORE::CCoreGlobal::Instance()->GetConfigStore();
    configStore.SetConfigFile( configFilePath );
    return configStore.LoadConfig( loadedConfig );
}

/*-------------------------------------------------------------------------*/

void
ParseParams( const int argc                 ,
             char* argv[]                   ,
             CORE::CValueList& keyValueList )
{GUCEF_TRACE;

    GUCEF::CORE::CString argString;
    if ( argc > 0 )
    {
        argString = *argv;

        // Combine the argument strings back into a single string because we don't want to use
        // a space as the seperator
        for ( int i=1; i<argc; ++i )
        {
            argString += ' ' + CORE::CString( argv[ i ] );
        }

        // Parse the param list based on the ' symbol
        GUCEF_LOG( CORE::LOGLEVEL_NORMAL, "Application parameters: " + argString );
        keyValueList.SetMultiple( argString, '*' );
    }
}

/*-------------------------------------------------------------------------*/

void
GucefAppSignalHandler( int signal )
{GUCEF_TRACE;

    ::GUCEF::CORE::CCoreGlobal::Instance()->GetApplication().Stop();
}

/*-------------------------------------------------------------------------*/

/*
 *      Application entry point
 */
//GUCEF_OSMAIN_BEGIN
GUCEF_OSSERVICEMAIN_BEGIN( "FilePusher" )
{GUCEF_TRACE;

    GUCEF_LOG( CORE::LOGLEVEL_NORMAL, "This tool was compiled on: " __DATE__ " @ " __TIME__ );

    CORE::CCoreGlobal::Instance();
    COMCORE::CComCoreGlobal::Instance();
    COM::CComGlobal::Instance();
    VFS::CVfsGlobal::Instance();

    // Check for config param first
    CORE::CValueList keyValueList;
    ParseParams( argc, argv, keyValueList );
    CORE::CString configPathParam = keyValueList.GetValueAlways( "ConfigPath" );
    keyValueList.Clear();

    // Load settings from a config file (if any) and then override with params (if any)
    CORE::CDataNode* globalConfig = new CORE::CDataNode();
    LoadConfig( configPathParam, keyValueList, globalConfig );
    ParseParams( argc, argv, keyValueList );

    CORE::CString outputDir = CORE::RelativePath( keyValueList.GetValueAlways( "outputDir" ) );
    if ( outputDir.IsNULLOrEmpty() )
    {
        outputDir = CORE::RelativePath( "$CURWORKDIR$" );
    }
    CORE::CreateDirs( outputDir );

    CORE::CString logFilename = CORE::CombinePath( outputDir, "FilePusher_log.txt" );

    keyValueList.Set( "logfile", logFilename );

    CORE::CRollingFileAccess logFileAccess( logFilename, "w" );
    CORE::CStdLogger logger( logFileAccess );
    CORE::CCoreGlobal::Instance()->GetLogManager().AddLogger( &logger );

    CORE::CPlatformNativeConsoleLogger console;
    if ( GUCEF_APP_TYPE == GUCEF_APP_TYPE_CONSOLE )
        CORE::CCoreGlobal::Instance()->GetLogManager().AddLogger( console.GetLogger() );

    CORE::Int32 minLogLevel = CORE::LOGLEVEL_BELOW_NORMAL;
    CORE::CString valueStr = keyValueList.GetValueAlways( "MinimalLogLevel" );
    if ( !valueStr.IsNULLOrEmpty() )
    {
        minLogLevel = CORE::StringToInt32( valueStr );
        CORE::CCoreGlobal::Instance()->GetLogManager().SetMinLogLevel( minLogLevel );
    }

    CORE::CCoreGlobal::Instance()->GetLogManager().FlushBootstrapLogEntriesToLogs();
    GUCEF_LOG( CORE::LOGLEVEL_NORMAL, "Flushed to log @ " + logFilename );

    GUCEF_OSMAIN_SIGNAL_HANDLER( GucefAppSignalHandler );

    FilePusher filePusher;
    if ( !filePusher.LoadConfig( keyValueList, *globalConfig ) )
    {
        delete globalConfig;
        GUCEF_ERROR_LOG( CORE::LOGLEVEL_CRITICAL, "FilePusher: Exiting because LoadConfig failed" );
        return -1;
    }
    delete globalConfig;

    if ( !filePusher.Start() )
    {
        GUCEF_ERROR_LOG( CORE::LOGLEVEL_CRITICAL, "FilePusher: Failed to Start()" );
        return -2;
    }

    auto& app = CORE::CCoreGlobal::Instance()->GetApplication();
    app.GetPulseGenerator()->RequestPulseInterval( 10 );
    return app.main( argc, argv, true );
}
GUCEF_OSMAIN_END

/*---------------------------------------------------------------------------*/
<commit_msg>FilePusher: Limit rolling log file count to a max of 10<commit_after>/*
 *  FilePusher: service which monitors the file system and pushes files to
 *  a remote repository
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

/*-------------------------------------------------------------------------//
//                                                                         //
//      INCLUDES                                                           //
//                                                                         //
//-------------------------------------------------------------------------*/

#ifndef GUCEF_CORE_CGUCEFAPPLICATION_H
#include "CGUCEFApplication.h"
#define GUCEF_CORE_CGUCEFAPPLICATION_H
#endif /* GUCEF_CORE_CGUCEFAPPLICATION_H ? */

#ifndef GUCEF_CORE_LOGGING_H
#include "gucefCORE_Logging.h"
#define GUCEF_CORE_LOGGING_H
#endif /* GUCEF_CORE_LOGGING_H ? */

#ifndef GUCEF_CORE_DVCPPOSWRAP_H
#include "DVCPPOSWRAP.h"
#define GUCEF_CORE_DVCPPOSWRAP_H
#endif /* GUCEF_CORE_DVCPPOSWRAP_H ? */

#ifndef GUCEF_CORE_CROLLINGFILEACCESS_H
#include "gucefCORE_CRollingFileAccess.h"
#define GUCEF_CORE_CROLLINGFILEACCESS_H
#endif /* GUCEF_CORE_CROLLINGFILEACCESS_H ? */

#ifndef GUCEF_CORE_CONFIGSTORE_H
#include "CConfigStore.h"
#define GUCEF_CORE_CONFIGSTORE_H
#endif /* GUCEF_CORE_CONFIGSTORE_H ? */

#ifndef GUCEF_CORE_CTRACER_H
#include "CTracer.h"
#define GUCEF_CORE_CTRACER_H
#endif /* GUCEF_CORE_CTRACER_H ? */

#ifndef GUCEF_CORE_CPLATFORMNATIVECONSOLEWINDOW_H
#include "gucefCORE_CPlatformNativeConsoleWindow.h"
#define GUCEF_CORE_CPLATFORMNATIVECONSOLEWINDOW_H
#endif /* GUCEF_CORE_CPLATFORMNATIVECONSOLEWINDOW_H ? */

#ifndef GUCEF_CORE_CVALUELIST_H
#include "CValueList.h"
#define GUCEF_CORE_CVALUELIST_H
#endif /* GUCEF_CORE_CVALUELIST_H ? */

#ifndef GUCEF_CORE_CTIMER_H
#include "CTimer.h"
#define GUCEF_CORE_CTIMER_H
#endif /* GUCEF_CORE_CTIMER_H ? */

#ifndef GUCEF_COMCORE_CUDPSOCKET_H
#include "CUDPSocket.h"
#define GUCEF_COMCORE_CUDPSOCKET_H
#endif /* GUCEF_COMCORE_CUDPSOCKET_H ? */

#ifndef GUCEF_COMCORE_CTCPSERVERSOCKET_H
#include "CTCPServerSocket.h"
#define GUCEF_COMCORE_CTCPSERVERSOCKET_H
#endif /* GUCEF_COMCORE_CTCPSERVERSOCKET_H ? */

#ifndef GUCEF_COMCORE_CCOMCOREGLOBAL_H
#include "gucefCOMCORE_CComCoreGlobal.h"
#define GUCEF_COMCORE_CCOMCOREGLOBAL_H
#endif /* GUCEF_COMCORE_CCOMCOREGLOBAL_H ? */

#ifndef GUCEF_COM_CCOMGLOBAL_H
#include "gucefCOM_CComGlobal.h"
#define GUCEF_COM_CCOMGLOBAL_H
#endif /* GUCEF_COM_CCOMGLOBAL_H ? */

#ifndef GUCEF_VFS_CVFSGLOBAL_H
#include "gucefVFS_CVfsGlobal.h"
#define GUCEF_VFS_CVFSGLOBAL_H
#endif /* GUCEF_VFS_CVFSGLOBAL_H ? */

#include "FilePusher.h"

/*-------------------------------------------------------------------------//
//                                                                         //
//      NAMESPACE                                                          //
//                                                                         //
//-------------------------------------------------------------------------*/

using namespace GUCEF;

/*-------------------------------------------------------------------------//
//                                                                         //
//      UTILITIES                                                          //
//                                                                         //
//-------------------------------------------------------------------------*/

bool
LoadConfig( const CORE::CString& configPath            ,
            CORE::CValueList& keyValueList             ,
            CORE::CDataNode* loadedConfig = GUCEF_NULL )
{GUCEF_TRACE;

    #ifdef GUCEF_DEBUG_MODE
    const CORE::CString configFile = "FilePusher_d.ini";
    #else
    const CORE::CString configFile = "FilePusher.ini";
    #endif

    CORE::CString configFilePath;
    bool foundViaParam = false;
    if ( !configPath.IsNULLOrEmpty() )
    {
        GUCEF_LOG( CORE::LOGLEVEL_BELOW_NORMAL, "Checking for config file @ " + configPath );
        foundViaParam = CORE::FileExists( configPath );
        configFilePath = configPath;
    }

    if ( !foundViaParam )
    {
        configFilePath = CORE::CombinePath( "$CURWORKDIR$", configFile );
        configFilePath = CORE::RelativePath( configFilePath );

        GUCEF_LOG( CORE::LOGLEVEL_BELOW_NORMAL, "Checking for config file @ " + configFilePath );
        if ( !CORE::FileExists( configFilePath ) )
        {
            configFilePath = CORE::CombinePath( "$MODULEDIR$", configFile );
            configFilePath = CORE::RelativePath( configFilePath );

            GUCEF_LOG( CORE::LOGLEVEL_BELOW_NORMAL, "Checking for config file @ " + configFilePath );
            if ( !FileExists( configFilePath ) )
            {
                GUCEF_WARNING_LOG( CORE::LOGLEVEL_NORMAL, "Unable to locate any config file, will rely on params" );
                return false;
            }
        }
    }
    GUCEF_LOG( CORE::LOGLEVEL_NORMAL, "Located config file @ " + configFilePath );

    keyValueList.SetConfigNamespace( "Main/AppArgs" );
    keyValueList.SetUseGlobalConfig( true );
    keyValueList.SetAllowDuplicates( false );
    keyValueList.SetAllowMultipleValues( true );

    CORE::CConfigStore& configStore = CORE::CCoreGlobal::Instance()->GetConfigStore();
    configStore.SetConfigFile( configFilePath );
    return configStore.LoadConfig( loadedConfig );
}

/*-------------------------------------------------------------------------*/

void
ParseParams( const int argc                 ,
             char* argv[]                   ,
             CORE::CValueList& keyValueList )
{GUCEF_TRACE;

    GUCEF::CORE::CString argString;
    if ( argc > 0 )
    {
        argString = *argv;

        // Combine the argument strings back into a single string because we don't want to use
        // a space as the seperator
        for ( int i=1; i<argc; ++i )
        {
            argString += ' ' + CORE::CString( argv[ i ] );
        }

        // Parse the param list based on the ' symbol
        GUCEF_LOG( CORE::LOGLEVEL_NORMAL, "Application parameters: " + argString );
        keyValueList.SetMultiple( argString, '*' );
    }
}

/*-------------------------------------------------------------------------*/

void
GucefAppSignalHandler( int signal )
{GUCEF_TRACE;

    ::GUCEF::CORE::CCoreGlobal::Instance()->GetApplication().Stop();
}

/*-------------------------------------------------------------------------*/

/*
 *      Application entry point
 */
//GUCEF_OSMAIN_BEGIN
GUCEF_OSSERVICEMAIN_BEGIN( "FilePusher" )
{GUCEF_TRACE;

    GUCEF_LOG( CORE::LOGLEVEL_NORMAL, "This tool was compiled on: " __DATE__ " @ " __TIME__ );

    CORE::CCoreGlobal::Instance();
    COMCORE::CComCoreGlobal::Instance();
    COM::CComGlobal::Instance();
    VFS::CVfsGlobal::Instance();

    // Check for config param first
    CORE::CValueList keyValueList;
    ParseParams( argc, argv, keyValueList );
    CORE::CString configPathParam = keyValueList.GetValueAlways( "ConfigPath" );
    keyValueList.Clear();

    // Load settings from a config file (if any) and then override with params (if any)
    CORE::CDataNode* globalConfig = new CORE::CDataNode();
    LoadConfig( configPathParam, keyValueList, globalConfig );
    ParseParams( argc, argv, keyValueList );

    CORE::CString outputDir = CORE::RelativePath( keyValueList.GetValueAlways( "outputDir" ) );
    if ( outputDir.IsNULLOrEmpty() )
    {
        outputDir = CORE::RelativePath( "$CURWORKDIR$" );
    }
    CORE::CreateDirs( outputDir );

    CORE::CString logFilename = CORE::CombinePath( outputDir, "FilePusher_log.txt" );

    keyValueList.Set( "logfile", logFilename );

    CORE::CRollingFileAccess logFileAccess( logFilename, "w" );
    logFileAccess.SetMaxRolloverFilesBeforeDeletion( 10 );
    CORE::CStdLogger logger( logFileAccess );
    CORE::CCoreGlobal::Instance()->GetLogManager().AddLogger( &logger );

    CORE::CPlatformNativeConsoleLogger console;
    if ( GUCEF_APP_TYPE == GUCEF_APP_TYPE_CONSOLE )
        CORE::CCoreGlobal::Instance()->GetLogManager().AddLogger( console.GetLogger() );

    CORE::Int32 minLogLevel = CORE::LOGLEVEL_BELOW_NORMAL;
    CORE::CString valueStr = keyValueList.GetValueAlways( "MinimalLogLevel" );
    if ( !valueStr.IsNULLOrEmpty() )
    {
        minLogLevel = CORE::StringToInt32( valueStr );
        CORE::CCoreGlobal::Instance()->GetLogManager().SetMinLogLevel( minLogLevel );
    }

    CORE::CCoreGlobal::Instance()->GetLogManager().FlushBootstrapLogEntriesToLogs();
    GUCEF_LOG( CORE::LOGLEVEL_NORMAL, "Flushed to log @ " + logFilename );

    GUCEF_OSMAIN_SIGNAL_HANDLER( GucefAppSignalHandler );

    FilePusher filePusher;
    if ( !filePusher.LoadConfig( keyValueList, *globalConfig ) )
    {
        delete globalConfig;
        GUCEF_ERROR_LOG( CORE::LOGLEVEL_CRITICAL, "FilePusher: Exiting because LoadConfig failed" );
        return -1;
    }
    delete globalConfig;

    if ( !filePusher.Start() )
    {
        GUCEF_ERROR_LOG( CORE::LOGLEVEL_CRITICAL, "FilePusher: Failed to Start()" );
        return -2;
    }

    auto& app = CORE::CCoreGlobal::Instance()->GetApplication();
    app.GetPulseGenerator()->RequestPulseInterval( 10 );
    return app.main( argc, argv, true );
}
GUCEF_OSMAIN_END

/*---------------------------------------------------------------------------*/
<|endoftext|>


<commit_before>#include "../include/cIGZApp.h"
#include "../include/cIGZFrameWork.h"
#include "../include/cISC4App.h"
#include "../include/cRZCOMDllDirector.h"

static const uint32_t kExtraCheatsPluginCOMDirectorID = 0x8bbd9623;
static const uint32_t kGZIID_cISC4App = 0x26ce01c0;

class cSC4ExtraCheatsPluginCOMDirector : public cRZCOMDllDirector
{
	public:
		uint32_t GetDirectorID() const {
			return kExtraCheatsPluginCOMDirectorID;
		}

		bool PreAppInit() {
			cIGZFrameWork* const pFramework = RZGetFrameWork();
			if (pFramework) {
				cIGZApp* const pApp = pFramework->Application();
				if (pApp) {
					cISC4App* pISC4App;
					if (pApp->QueryInterface(kGZIID_cISC4App, (void**)&pISC4App)) {
						pISC4App->SetDebugFunctionalityEnabled(true);
					}
				}
			}

			return true;
		}

		bool OnStart(cIGZCOM* pCOM) {
			cIGZFrameWork* const pFramework = RZGetFrameWork();
			if (pFramework) {
				if (pFramework->GetState() < cIGZFrameWork::kStatePreAppInit) {
					pFramework->AddHook(this);
				}
				else {
					PreAppInit();
				}
			}
			return true;
		}
};

// You need to replace the director returned here for the game and this DLL
// to use the right director. This is the only place that it's necessary to
// do so.
cRZCOMDllDirector* RZGetCOMDllDirector() {
	static cSC4ExtraCheatsPluginCOMDirector sDirector;
	return &sDirector;
}<commit_msg>Update cGZExtraCheatsDllDirector to demonstrate message reception<commit_after>#include "../include/cIGZApp.h"
#include "../include/cIGZFrameWork.h"
#include "../include/cIGZMessage2.h"
#include "../include/cIGZMessageServer2.h"
#include "../include/cIGZMessageTarget2.h"
#include "../include/cISC4App.h"
#include "../include/cISC4RenderProperties.h"
#include "../include/cRZCOMDllDirector.h"
#include "../include/GZServPtrs.h"
#include <Windows.h>

static const uint32_t kExtraCheatsPluginCOMDirectorID = 0x8bbd9623;
static const uint32_t kGZIID_cISC4App = 0x26ce01c0;

class cSC4ExtraCheatsPluginCOMDirector : public cRZCOMDllDirector, public cIGZMessageTarget2
{
	public:
		/* Failing to explicitly delegate these methods results in some
		   ambiguity when resolving which virtual methods to use: those
		   from cIGZMessageTarget (which are pure abstract) or those from
		   cRZCOMDllDirector, and the compiler will complain. */
		bool QueryInterface(uint32_t riid, void** ppvObj) {
			return cRZCOMDllDirector::QueryInterface(riid, ppvObj);
		}

		uint32_t AddRef(void) {
			return cRZCOMDllDirector::AddRef();
		}

		uint32_t Release(void) {
			return cRZCOMDllDirector::Release();
		}

		uint32_t GetDirectorID() const {
			return kExtraCheatsPluginCOMDirectorID;
		}

		bool DoMessage(cIGZMessage2* pMessage) {
			if (pMessage->GetType() == 0xea8ae29a) {
				MessageBoxA(NULL, "City finished loading", NULL, NULL);
			}

			return true;
		}

		bool PreAppInit() {
			cIGZFrameWork* const pFramework = RZGetFrameWork();
			if (pFramework) {
				cIGZApp* const pApp = pFramework->Application();
				if (pApp) {
					cISC4App* pISC4App;
					if (pApp->QueryInterface(kGZIID_cISC4App, (void**)&pISC4App)) {
						pISC4App->SetDebugFunctionalityEnabled(true);
					}
				}
			}

			return true;
		}

		bool PostAppInit() {
			// The cRZSysServPtr will automatically try to receive the service
			// pointer for us.
			cIGZMessageServer2Ptr pMsgServ;
			if (pMsgServ) {
				pMsgServ->AddNotification(this, 0xea8ae29a);
			}

			return true;
		}

		bool OnStart(cIGZCOM* pCOM) {
			cIGZFrameWork* const pFramework = RZGetFrameWork();
			if (pFramework) {
				if (pFramework->GetState() < cIGZFrameWork::kStatePreAppInit) {
					pFramework->AddHook(this);
				}
				else {
					PreAppInit();
				}
			}
			return true;
		}
};

// You need to replace the director returned here for the game and this DLL
// to use the right director. This is the only place that it's necessary to
// do so.
cRZCOMDllDirector* RZGetCOMDllDirector() {
	static cSC4ExtraCheatsPluginCOMDirector sDirector;
	return &sDirector;
}<|endoftext|>


<commit_before>#include <stdlib.h>
#include <time.h>
#include "SDL.h"

int main(int argc, char *argv[])
{
	SDL_Surface* Surf_Display;

	SDL_Window *sdlWindow;
	SDL_Renderer *sdlRenderer;
	SDL_CreateWindowAndRenderer(0, 0, SDL_WINDOW_FULLSCREEN_DESKTOP, &sdlWindow, &sdlRenderer);

	SDL_SetRenderDrawColor(sdlRenderer, 0, 0, 0, 255);
	SDL_RenderClear(sdlRenderer);
	SDL_RenderPresent(sdlRenderer);

	SDL_Quit();
	return 0;
}<commit_msg>Fixed Full Screen<commit_after>#include <stdlib.h>
#include <time.h>
#include "SDL.h"

int main(int argc, char *argv[])
{
	SDL_Surface* Surf_Display;

	SDL_Window *sdlWindow;
	SDL_Renderer *sdlRenderer;
	SDL_CreateWindowAndRenderer(1280, 720, SDL_WINDOW_SHOWN, &sdlWindow, &sdlRenderer);

	SDL_SetRenderDrawColor(sdlRenderer, 0, 0, 0, 255);
	SDL_RenderClear(sdlRenderer);
	SDL_RenderPresent(sdlRenderer);

	for (;;){}

	SDL_Quit();
	return 0;
}<|endoftext|>


<commit_before>/*
 * Vulkan
 *
 * Copyright (C) 2014 LunarG, 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 <assert.h>
#include <unordered_map>
#include "vk_dispatch_table_helper.h"
#include "vk_layer.h"
#include "vk_layer_table.h"
static device_table_map tableMap;
static instance_table_map tableInstanceMap;

#define DISPATCH_MAP_DEBUG 0

// Map lookup must be thread safe
VkLayerDispatchTable *device_dispatch_table(void* object)
{
    dispatch_key key = get_dispatch_key(object);
    device_table_map::const_iterator it = tableMap.find((void *) key);
    assert(it != tableMap.end() && "Not able to find device dispatch entry");
    return it->second;
}

VkLayerInstanceDispatchTable *instance_dispatch_table(void* object)
{
    dispatch_key key = get_dispatch_key(object);
    instance_table_map::const_iterator it = tableInstanceMap.find((void *) key);
#if DISPATCH_MAP_DEBUG
    if (it != tableInstanceMap.end()) {
        fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key, it->second);
    } else {
        fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key);
    }
#endif
    assert(it != tableInstanceMap.end() && "Not able to find instance dispatch entry");
    return it->second;
}

void destroy_dispatch_table(device_table_map &map, dispatch_key key)
{
    device_table_map::const_iterator it = map.find((void *) key);
#if DISPATCH_MAP_DEBUG
    if (it != map.end()) {
        fprintf(stderr, "destroy device dispatch_table: map: %p, key: %p, table: %p\n", &map, key, it->second);
    } else {
        fprintf(stderr, "destroy device dispatch table: map: %p, key: %p, table: UNKNOWN\n", &map, key);
        assert(it != map.end());
    }
#endif
    map.erase(key);
}

void destroy_dispatch_table(instance_table_map &map, dispatch_key key)
{
    instance_table_map::const_iterator it = map.find((void *) key);
#if DISPATCH_MAP_DEBUG
    if (it != map.end()) {
        fprintf(stderr, "destroy instance dispatch_table: map: %p, key: %p, table: %p\n", &map, key, it->second);
    } else {
        fprintf(stderr, "destroy instance dispatch table: map: %p, key: %p, table: UNKNOWN\n", &map, key);
        assert(it != map.end());
    }
#endif
    map.erase(key);
}

void destroy_device_dispatch_table(dispatch_key key)
{
    destroy_dispatch_table(tableMap, key);
}

void destroy_instance_dispatch_table(dispatch_key key)
{
    destroy_dispatch_table(tableInstanceMap, key);
}

VkLayerDispatchTable *get_dispatch_table(device_table_map &map, void* object)
{
    dispatch_key key = get_dispatch_key(object);
    device_table_map::const_iterator it = map.find((void *) key);
#if DISPATCH_MAP_DEBUG
    if (it != map.end()) {
        fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key, it->second);
    } else {
        fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key);
    }
#endif
    assert(it != map.end() && "Not able to find device dispatch entry");
    return it->second;
}

VkLayerInstanceDispatchTable *get_dispatch_table(instance_table_map &map, void* object)
{
//    VkLayerInstanceDispatchTable *pDisp = *(VkLayerInstanceDispatchTable **) object;
    dispatch_key key = get_dispatch_key(object);
    instance_table_map::const_iterator it = map.find((void *) key);
#if DISPATCH_MAP_DEBUG
    if (it != map.end()) {
        fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key, it->second);
    } else {
        fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key);
    }
#endif
    assert(it != map.end() && "Not able to find instance dispatch entry");
    return it->second;
}

/* Various dispatchable objects will use the same underlying dispatch table if they
 * are created from that "parent" object. Thus use pointer to dispatch table
 * as the key to these table maps.
 *    Instance -> PhysicalDevice
 *    Device -> CmdBuffer or Queue
 * If use the object themselves as key to map then implies Create entrypoints have to be intercepted
 * and a new key inserted into map */
VkLayerInstanceDispatchTable * initInstanceTable(instance_table_map &map, const VkBaseLayerObject *instancew)
{
    VkLayerInstanceDispatchTable *pTable;
    assert(instancew);
    VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instancew->baseObject;

    std::unordered_map<void *, VkLayerInstanceDispatchTable *>::const_iterator it = map.find((void *) *ppDisp);
    if (it == map.end())
    {
        pTable =  new VkLayerInstanceDispatchTable;
        map[(void *) *ppDisp] = pTable;
#if DISPATCH_MAP_DEBUG
        fprintf(stderr, "New, Instance: map: %p, base object: %p, key: %p, table: %p\n", &map, instancew, *ppDisp, pTable);
#endif
        assert(map.size() <= 1 && "Instance dispatch table map has more than one entry");
    } else
    {
#if DISPATCH_MAP_DEBUG
        fprintf(stderr, "Instance: map: %p, base object: %p, key: %p, table: %p\n", &map, instancew, *ppDisp, it->second);
#endif
        return it->second;
    }

    layer_init_instance_dispatch_table(pTable, instancew);

    return pTable;
}

VkLayerInstanceDispatchTable * initInstanceTable(const VkBaseLayerObject *instancew)
{
    return initInstanceTable(tableInstanceMap, instancew);
}

VkLayerDispatchTable * initDeviceTable(device_table_map &map, const VkBaseLayerObject *devw)
{
    VkLayerDispatchTable *layer_device_table = NULL;
    assert(devw);
    VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) (devw->baseObject);
    VkLayerDispatchTable *base_device_table = *ppDisp;

    std::unordered_map<void *, VkLayerDispatchTable *>::const_iterator it = map.find((void *) base_device_table);
    if (it == map.end())
    {
        layer_device_table =  new VkLayerDispatchTable;
        map[(void *) base_device_table] = layer_device_table;
#if DISPATCH_MAP_DEBUG
        fprintf(stderr, "New, Device: map: %p, base object: %p, key: %p, table: %p\n", &map, devw, *ppDisp, layer_device_table);
#endif
    } else
    {
#if DISPATCH_MAP_DEBUG
        fprintf(stderr, "Device: map: %p, base object: %p, key: %p, table: %p\n", &map, devw, *ppDisp, it->second);
#endif
        return it->second;
    }

    layer_initialize_dispatch_table(layer_device_table, devw);

    return layer_device_table;
}

VkLayerDispatchTable * initDeviceTable(const VkBaseLayerObject *devw)
{
    return initDeviceTable(tableMap, devw);
}
<commit_msg>layers: No assert on init instance table map.size != 1<commit_after>/*
 * Vulkan
 *
 * Copyright (C) 2014 LunarG, 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 <assert.h>
#include <unordered_map>
#include "vk_dispatch_table_helper.h"
#include "vk_layer.h"
#include "vk_layer_table.h"
static device_table_map tableMap;
static instance_table_map tableInstanceMap;

#define DISPATCH_MAP_DEBUG 0

// Map lookup must be thread safe
VkLayerDispatchTable *device_dispatch_table(void* object)
{
    dispatch_key key = get_dispatch_key(object);
    device_table_map::const_iterator it = tableMap.find((void *) key);
    assert(it != tableMap.end() && "Not able to find device dispatch entry");
    return it->second;
}

VkLayerInstanceDispatchTable *instance_dispatch_table(void* object)
{
    dispatch_key key = get_dispatch_key(object);
    instance_table_map::const_iterator it = tableInstanceMap.find((void *) key);
#if DISPATCH_MAP_DEBUG
    if (it != tableInstanceMap.end()) {
        fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key, it->second);
    } else {
        fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key);
    }
#endif
    assert(it != tableInstanceMap.end() && "Not able to find instance dispatch entry");
    return it->second;
}

void destroy_dispatch_table(device_table_map &map, dispatch_key key)
{
    device_table_map::const_iterator it = map.find((void *) key);
#if DISPATCH_MAP_DEBUG
    if (it != map.end()) {
        fprintf(stderr, "destroy device dispatch_table: map: %p, key: %p, table: %p\n", &map, key, it->second);
    } else {
        fprintf(stderr, "destroy device dispatch table: map: %p, key: %p, table: UNKNOWN\n", &map, key);
        assert(it != map.end());
    }
#endif
    map.erase(key);
}

void destroy_dispatch_table(instance_table_map &map, dispatch_key key)
{
    instance_table_map::const_iterator it = map.find((void *) key);
#if DISPATCH_MAP_DEBUG
    if (it != map.end()) {
        fprintf(stderr, "destroy instance dispatch_table: map: %p, key: %p, table: %p\n", &map, key, it->second);
    } else {
        fprintf(stderr, "destroy instance dispatch table: map: %p, key: %p, table: UNKNOWN\n", &map, key);
        assert(it != map.end());
    }
#endif
    map.erase(key);
}

void destroy_device_dispatch_table(dispatch_key key)
{
    destroy_dispatch_table(tableMap, key);
}

void destroy_instance_dispatch_table(dispatch_key key)
{
    destroy_dispatch_table(tableInstanceMap, key);
}

VkLayerDispatchTable *get_dispatch_table(device_table_map &map, void* object)
{
    dispatch_key key = get_dispatch_key(object);
    device_table_map::const_iterator it = map.find((void *) key);
#if DISPATCH_MAP_DEBUG
    if (it != map.end()) {
        fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key, it->second);
    } else {
        fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key);
    }
#endif
    assert(it != map.end() && "Not able to find device dispatch entry");
    return it->second;
}

VkLayerInstanceDispatchTable *get_dispatch_table(instance_table_map &map, void* object)
{
//    VkLayerInstanceDispatchTable *pDisp = *(VkLayerInstanceDispatchTable **) object;
    dispatch_key key = get_dispatch_key(object);
    instance_table_map::const_iterator it = map.find((void *) key);
#if DISPATCH_MAP_DEBUG
    if (it != map.end()) {
        fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: %p\n", &tableInstanceMap, object, key, it->second);
    } else {
        fprintf(stderr, "instance_dispatch_table: map: %p, object: %p, key: %p, table: UNKNOWN\n", &tableInstanceMap, object, key);
    }
#endif
    assert(it != map.end() && "Not able to find instance dispatch entry");
    return it->second;
}

/* Various dispatchable objects will use the same underlying dispatch table if they
 * are created from that "parent" object. Thus use pointer to dispatch table
 * as the key to these table maps.
 *    Instance -> PhysicalDevice
 *    Device -> CmdBuffer or Queue
 * If use the object themselves as key to map then implies Create entrypoints have to be intercepted
 * and a new key inserted into map */
VkLayerInstanceDispatchTable * initInstanceTable(instance_table_map &map, const VkBaseLayerObject *instancew)
{
    VkLayerInstanceDispatchTable *pTable;
    assert(instancew);
    VkLayerInstanceDispatchTable **ppDisp = (VkLayerInstanceDispatchTable **) instancew->baseObject;

    std::unordered_map<void *, VkLayerInstanceDispatchTable *>::const_iterator it = map.find((void *) *ppDisp);
    if (it == map.end())
    {
        pTable =  new VkLayerInstanceDispatchTable;
        map[(void *) *ppDisp] = pTable;
#if DISPATCH_MAP_DEBUG
        fprintf(stderr, "New, Instance: map: %p, base object: %p, key: %p, table: %p\n", &map, instancew, *ppDisp, pTable);
#endif
    } else
    {
#if DISPATCH_MAP_DEBUG
        fprintf(stderr, "Instance: map: %p, base object: %p, key: %p, table: %p\n", &map, instancew, *ppDisp, it->second);
#endif
        return it->second;
    }

    layer_init_instance_dispatch_table(pTable, instancew);

    return pTable;
}

VkLayerInstanceDispatchTable * initInstanceTable(const VkBaseLayerObject *instancew)
{
    return initInstanceTable(tableInstanceMap, instancew);
}

VkLayerDispatchTable * initDeviceTable(device_table_map &map, const VkBaseLayerObject *devw)
{
    VkLayerDispatchTable *layer_device_table = NULL;
    assert(devw);
    VkLayerDispatchTable **ppDisp = (VkLayerDispatchTable **) (devw->baseObject);
    VkLayerDispatchTable *base_device_table = *ppDisp;

    std::unordered_map<void *, VkLayerDispatchTable *>::const_iterator it = map.find((void *) base_device_table);
    if (it == map.end())
    {
        layer_device_table =  new VkLayerDispatchTable;
        map[(void *) base_device_table] = layer_device_table;
#if DISPATCH_MAP_DEBUG
        fprintf(stderr, "New, Device: map: %p, base object: %p, key: %p, table: %p\n", &map, devw, *ppDisp, layer_device_table);
#endif
    } else
    {
#if DISPATCH_MAP_DEBUG
        fprintf(stderr, "Device: map: %p, base object: %p, key: %p, table: %p\n", &map, devw, *ppDisp, it->second);
#endif
        return it->second;
    }

    layer_initialize_dispatch_table(layer_device_table, devw);

    return layer_device_table;
}

VkLayerDispatchTable * initDeviceTable(const VkBaseLayerObject *devw)
{
    return initDeviceTable(tableMap, devw);
}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/hwpf/fapi2/include/fapi2_vpd_access.H $            */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
/// @file fapi2_vpd_access.H
/// @brief Common file that defines the vpd access functions that
/// platform code must implement.
///
//

#ifndef _FAPI2_VPDACCESS_H_
#define _FAPI2_VPDACCESS_H_

#include <return_code.H>
#include <target_types.H>
#include <vpd_access_defs.H>
#include <plat_vpd_access.H>

namespace fapi2
{

/// constants for VPD Info
constexpr uint64_t VPD_INFO_INVALID  = 0xffffffffffffffff;

/// @brief  Specialized class representing required VPDInfo to be used
///         in collecting VPD for the MCA target type.
/// @tparam T fapi2::TARGET_TYPE_MCA
template<>
class VPDInfo<TARGET_TYPE_MCA>
{
    public:
        // @brief VPDInfo constructor
        VPDInfo( const fapi2::MemVpdData& i_vpd_type)
            : iv_vpd_type(i_vpd_type),
              iv_size(VPD_INFO_INVALID),
              iv_freq_mhz(VPD_INFO_INVALID),
              iv_rank_count_dimm_0(VPD_INFO_INVALID),
              iv_rank_count_dimm_1(VPD_INFO_INVALID)
        {};
        // type of vpd field to return
        fapi2::MemVpdData_t iv_vpd_type;

        // size of the vpd data
        size_t   iv_size;
        uint64_t iv_freq_mhz;
        uint64_t iv_rank_count_dimm_0;
        uint64_t iv_rank_count_dimm_1;

};

/// @brief Return a blob of memory VPD data associated with the input target
/// @param[in] i_target     a valid fapi2 target
/// @param[in] io_vpd_info  fapi2::VPDInfo class that specifies which piece of data to return
/// @param[out] o_blob      the blob of raw data from the vpd
/// @return FAPI2_RC_SUCCESS if there's no problem
/// @note passing nullptr for o_blob will return the size of the keyword
///
/// Example:
/// fapi2::VPDInfo<fapi2::TARGET_TYPE_MCA> vpdInfo(MR_keyword);
/// vpdInfo.iv_freq = 2667;
///
/// uint8_t * blob = NULL;
///
/// FAPI_TRY(getVPD( mcs, vpdInfo, blob ));
/// blob = static_cast<uint8_t *>(malloc(vpdInfo.iv_size));
/// FAPI_TRY(getVPD( mcs, vpdInfo, blob ));
/// blob now contains the VPD data for the MCA.
///
template<TargetType T>
ReturnCode getVPD(const Target<T>& i_target,
                  VPDInfo<T>& io_vpd_info,
                  uint8_t* o_blob);

};
#endif
<commit_msg>Packaging of memory vpd on Nimbus, MCA->MCS<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/hwpf/fapi2/include/fapi2_vpd_access.H $            */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
/// @file fapi2_vpd_access.H
/// @brief Common file that defines the vpd access functions that
/// platform code must implement.
///
//

#ifndef _FAPI2_VPDACCESS_H_
#define _FAPI2_VPDACCESS_H_

#include <return_code.H>
#include <target_types.H>
#include <vpd_access_defs.H>
#include <plat_vpd_access.H>

namespace fapi2
{

/// constants for VPD Info
constexpr uint64_t VPD_INFO_INVALID  = 0xffffffffffffffff;

/// @brief  Specialized class representing required VPDInfo to be used
///         in collecting VPD for the MCS target type.
/// @tparam T fapi2::TARGET_TYPE_MCS
template<>
class VPDInfo<TARGET_TYPE_MCS>
{
    public:
        // @brief VPDInfo constructor
        VPDInfo( const fapi2::MemVpdData& i_vpd_type)
            : iv_vpd_type(i_vpd_type),
              iv_size(VPD_INFO_INVALID),
              iv_freq_mhz(VPD_INFO_INVALID),
              iv_rank_count_dimm_0(VPD_INFO_INVALID),
              iv_rank_count_dimm_1(VPD_INFO_INVALID)
        {};
        // type of vpd field to return
        fapi2::MemVpdData_t iv_vpd_type;

        // size of the vpd data
        size_t   iv_size;
        uint64_t iv_freq_mhz;
        uint64_t iv_rank_count_dimm_0;
        uint64_t iv_rank_count_dimm_1;

};

/// @brief Return a blob of memory VPD data associated with the input target
/// @param[in] i_target     a valid fapi2 target
/// @param[in] io_vpd_info  fapi2::VPDInfo class that specifies which piece of data to return
/// @param[out] o_blob      the blob of raw data from the vpd
/// @return FAPI2_RC_SUCCESS if there's no problem
/// @note passing nullptr for o_blob will return the size of the keyword
///
/// Example:
/// fapi2::VPDInfo<fapi2::TARGET_TYPE_MCS> vpdInfo(MR_keyword);
/// vpdInfo.iv_freq = 2667;
///
/// uint8_t * blob = NULL;
///
/// FAPI_TRY(getVPD( mcs, vpdInfo, blob ));
/// blob = static_cast<uint8_t *>(malloc(vpdInfo.iv_size));
/// FAPI_TRY(getVPD( mcs, vpdInfo, blob ));
/// blob now contains the VPD data for the MCS.
///
template<TargetType T>
ReturnCode getVPD(const Target<T>& i_target,
                  VPDInfo<T>& io_vpd_info,
                  uint8_t* o_blob);

};
#endif
<|endoftext|>