Functions

gs_call.cpp File Reference

#include <oct.h>
#include <stdio.h>
#include <stdlib.h>
#include "grpc.h"
#include "gs_oct.h"
Include dependency graph for gs_call.cpp:

Go to the source code of this file.

Functions

 DEFUN_DLD (gs_call, args, nargout,"Octave client for GridSolve")

Function Documentation

DEFUN_DLD ( gs_call  ,
args  ,
nargout  ,
"Octave client for GridSolve"   
)

Definition at line 22 of file gs_call.cpp.

                                                                  {
    octave_value_list retvals;      //return value
    octave_value_list bad_retval;   //bad return value
    gs_problem_t* pd;               //GridSolve problem description
    grpc_arg_stack* argstack;       //GridRPC argument stack
    gs_argument_t* argp;            //GridRPC argument pointer
    grpc_function_handle_t *handle; //GridRPC function handle
    grpc_error_t status;            //GridRPC status/error code
    char *info[1];


    //meaningless return value for error condition
    //or those calls that do not make grpc function call
    for (int i = 0; i < nargout; i++) {
        bad_retval(i) = Matrix(0, 0);
    }

    //initialize the GridSolve environment
    status = grpc_initialize(NULL);
    if (status != GRPC_NO_ERROR && status != GRPC_ALREADY_INITIALIZED) {
        fprintf(stderr, "%s\n", grpc_error_string(status));
        return bad_retval;
    }

    //number of input arguments
    int nargin = args.length();

    //invalid first argument
    if (nargin >= 1 && !args(0).is_string()) {
        fprintf(stderr, "Invalid first parameter: should be a string. Aborted.\n");
        grpc_finalize();
        return bad_retval;
    }

    //do a grpc call to a remote service
    if (nargin >= 1) {
        int strlen = args(0).string_value().length();

        //get the problem name
        char *pname = new char[strlen + 1];
        for (int i = 0; i < strlen; i++)
            pname[i] = (args(0).string_value())[i];
        pname[strlen] = '\0';

        //initialize the GridRPC function handle
        handle = (grpc_function_handle_t *) malloc(sizeof(grpc_function_handle_t));
        if (handle == NULL) {
            perror("malloc");
            delete pname;
            grpc_finalize();
            return bad_retval;
        }

        status = grpc_function_handle_default(handle, pname);
        if (status != GRPC_NO_ERROR) {
            fprintf(stderr, "%s\n", grpc_error_string(status));
            delete pname;
            grpc_function_handle_destruct(handle);
            if (handle != NULL) free(handle);
            grpc_finalize();
            return bad_retval;
        }

        //get the GridSolve problem description
        pd = handle->problem_desc;

        if (pd == NULL) {
            fprintf(stderr, "Empty GridSolve problem description. Aborted.\n");
            delete pname;
            grpc_function_handle_destruct(handle);
            if (handle != NULL) free(handle);
            grpc_finalize();
            return bad_retval;
        }

        //convert object types before make the call
        if (convert_octave_arguments(pd, args) < 0) {
            fprintf(stderr, "Failure to convert input arguments. Aborted.\n");
            delete pname;
            grpc_function_handle_destruct(handle);
            if (handle != NULL) free(handle);
            grpc_finalize();
            return bad_retval;
        }

        int arg_stack_size = 0;
        //compute the argument stack size
        for (argp = pd->arglist; argp != NULL; argp = argp->next) {
            if (argp->inout != GS_WORKSPACE) arg_stack_size++;
        }

        //create a new argument stack for the grpc call
        if ((argstack = grpc_arg_stack_new(arg_stack_size)) == NULL) {
            fprintf(stderr, "Failed to create argument stack. Aborted.\n");
            delete pname;
            grpc_function_handle_destruct(handle);
            if (handle != NULL) free(handle);
            grpc_arg_stack_destruct(argstack);
            if (argstack != NULL) free(argstack);
            grpc_finalize();
            return bad_retval;
        }

        //push the converted arguments onto the stack
        for (argp = pd->arglist; argp != NULL; argp = argp->next) {
            if (argp->inout != GS_WORKSPACE) {
                if (grpc_arg_stack_push_arg(argstack, argp->data) < 0) {
                    fprintf(stderr, "Error in pushing argument stack. Aborted.\n");
                    delete pname;
                    grpc_function_handle_destruct(handle);
                    if (handle != NULL) free(handle);
                    grpc_arg_stack_destruct(argstack);
                    if (argstack != NULL) free(argstack);
                    grpc_finalize();
                    return bad_retval;
                }
            }
        }

        grpc_set_default_major("C");
        grpc_set_client_major("C");

        //calling the remote service
        status = grpc_call_arg_stack(handle, argstack);
        if (status == GRPC_NO_ERROR) {
            //printf("Blocking GridRPC call succeeded.\n");
        } else {
            fprintf(stderr, "%s\n", grpc_error_string(status));
            delete pname;
            grpc_function_handle_destruct(handle);
            if (handle != NULL) free(handle);
            grpc_arg_stack_destruct(argstack);
            if (argstack != NULL) free(argstack);
            grpc_finalize();
            return bad_retval;
        }

        //printf("Blocking GridRPC call finishes...\n");

        //create the return value object
        retvals = octave_value_list();

        //convert object back
        if (convert_output_objects(pd, retvals) < 0) {
            fprintf(stderr, "Failed to convert output arguments. Aborted.\n");
            delete pname;
            grpc_function_handle_destruct(handle);
            if (handle != NULL) free(handle);
            grpc_arg_stack_destruct(argstack);
            if (argstack != NULL) free(argstack);
            grpc_finalize();
            return bad_retval;
        }

        //finalize and clean up
        grpc_function_handle_destruct(handle);
        if (handle != NULL) free(handle);
        delete pname;
        grpc_arg_stack_destruct(argstack);
        grpc_finalize();

        return retvals;
    }
}

Here is the call graph for this function: