#ifndef CommandInterface #define CommandInterface /* * The interface to sending commands is trivial from this edge. First, one must * initialize() the library with some layout.xml that conforms to layout.xsd. * One should then parse the command string and if the return handle is NOT 0, * then call execute with it. The use must then call either waitFor() or * ignore or you will have one serious memory leak. */ namespace commandInterface { /* * Initialize the system by parsing the specified (layoutFileName) XML file * and determining what the remote configuration looks like. If the layout * is successfully parsed, then all the other functions will work. * * Notes: * 1) This function can be called many times and only the last successful * layout is used. However, it can be used to switch between commanding * several different testbeds. * 2) The state of whether this library is initialized is fully dependent * on the last call to initialize(). No history is retained which means * if the library is successfully initialized and used and then * reinitialized but fails, then this library will report failures * with the reason that the library has not properly initialized. */ bool initialize (const char *layoutFileName, const char *classpath, const char *hostname = 0, const bool dump = false); /* * These functions are to be used in conjunction with one another to obtain * command processing equivalent to using the command line. First, it must * be noted that all of these functions will fail if the library has not * been properly initialized. The user can then subsequently call 'append' * with a series of command line parameters that would make up a complete * instruction. Once all of the commands are ready the user would then call * 'execute'. This will empty the current list of commands and send them all * to the testbed in use. The user can then call 'collect' at any time to * retrieve the data returned by the testbed from the commands issued. * If the user requested data to be retained and then it is never collected, * then 'flush' can be used to empty the retention buffer so that excessive * memory is not used. * * Note: All of these methods should be considered thread safe in that * they are internally atomic. * * Also: Use a call to free to release the handle_t when done with it. * A call to malloc was used to allocate the space originally. * Hence, handle_t should be usable in both C and C++. * * append() * This function takes a set of command line arguments and generates a sret * of instructions to execute. It then appends a successful translation to * the list of things to do. * * INPUTS: * command : the command line arguments in a set of strings. Each string * should reflect what the command line parser would return * given a single long string. The set must be NULL terminated. * handle : if non-null, it will return a set of handles that allows the * user to 'collect' the results at a later time. Otherwise the * results are simply discarded. * Note, although the pointer should point to a * 'handle_t *handles', it should not be preallocated in size. * This call will allocate the space it needs but it does NOT * deallocate whatever is already there. * OUTPUTS: * If the 'command' parses successfully and is appended to the queue of * things to do, then the function will return true. Otherwise it will * return false. * * collect() * This function allows the user to collect data from a command at some * time after the command was issued. The user must have a valid handle * to retained data that has not yet been erased. * * INPUTS: * handle : a reference to the command sent that will allow the user * to collect data returned from a previous command. * erase : once read, remove the data from the queue which invalidates * the handle for all subsequent calls. * wait : if true, waits until the results are returned from the * testbed and returns immediately when false. The user must * test 'arrived' when wait is false. * OUTPUTS: * Returns true if the handle was valid plus all outputs are non-null * and false otherwise. * * arrived : if the results are were there and waiting, then true. * Otherwise, it will be false. It should always be true when * 'wait' is true as well. * success : if the status of the resultant from the testbed is success * then this will be set to true. Otherwise it be set to false. * result : if the results have arrived, then result will be set to the * new value. Otherwise it will remain unchanged. * * execute() * Sends all of the instructions that have been built up using append to * the testbed for execution. It then empties all of the instructions out * of the queue. * * INPUTS: * waitForResponse : if true, then the call will not return until all * the instructions have completed. If false, the call * returns immediately after sending the commands. * OUTPUTS: * Returns true if all instructions were transmitted and received. * Otherwise, it returns false. * * flush() * Clears the queue of all retained messages. This is helper function and * should be considered fairly dangerous as all handles still in use will * become instantly invalid. Use with great care in multi-threaded code. */ typedef char* handle_t; bool append (const char **command, handle_t **handle = 0); bool collect (const handle_t handle, const bool erase, const bool wait, bool *arrived, bool *success, char **resultant); bool execute (const bool waitForResponse = false); void flush (void); /* * Start some method for monitoring the remote system. If a GUI is not used, * then the information will be dumped to stdout. This will more than likely * overwhelm just about anyone, but what else can one do? * * Note: The monitor can attach to any testbed not just the one used for * for initialization. */ void monitor (const char *xmlfile, const bool useGUI = true); } #endif //CommandInterface