Example C interface

When querying the FEWS database with a small C program like the one below, the result is a string - in simple cases, just the value or values you wanted, in other cases the contents of an XML file, conforming to the FEWS published interface (PI).

The program below is a translation of most of the Java example. It simply prints the answer, but in an actual program you will need to parse the XML content to extract the relevant information:

/*
 * Sample program, using the wrappers
 */

#include <stdio.h>

/*
 * Wrapper code is included
 */
#include "pi_wrapper.c"

/* 
 * Main program
 */

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

    char *result;
    char *stateTimes;
    char *firstTime;
    char *textContents;
    char *zipContents;
    FILE *outf;
    char *startTime;
    char *systemTime;
    char *endTime;
    char *timeZero;
    char *date;
    char *taskId;
    char *taskRunId;
    int   success;

    char *parameters[] = {"QIN", "RQIN"};
    char *locations[]  = {"DETO3", "GPRO3", "FOSO3"};
    int nParameters = 2;
    int nLocations = 3;

    /* Get the library started */
    Init( argv[0] );
    InitPiService( "localhost", 8100 );

    printf( "Current system time: %s\n", getSystemTime( "aa" ) );
    printf( "State times: %s\n", getAvailableStateTimes( "TestConfig", "RSNWELEV_DETO3I" ) );
    printf( "Cold states: %s\n", getColdStateIds( "TestConfig", "RSNWELEV_DETO3I" ) );

    result = getAvailableStateTimes( "TestConfig", "RSNWELEV_DETO3I" );
    stateTimes = strdup( result ) ; /* Save the result - we need it in the next step */

    /* This test is excluded: there is no binary state file in the sample configuration */
#if 0
    /* Extract the first time */

    firstTime = getElement( stateTimes, 0 );
    zipContents = getModuleStateBinary( "TestConfig", "SNOW17_LSMO3U", NULL, -1, &size );

    outf = fopen( "statefile.bin", "wb" );
    fwrite( zipContents, size, outf );
    fclose( outf );

    free( zipContents );
#endif

    /* Note: name of file, extension of file */
    textContents = getClientConfigFile( "MyClientConfigFile", "txt" );
    outf = fopen( "client.txt", "w" );
    fprintf( outf, "%s", textContents );
    fclose( outf );

    printf( "Locations:\n---begin---\n" );
    printf( "%s", getLocations( "aa" ) );
    printf( "---end---\n" );

    printf( "Ensemble members: %s\n", getEnsembleMemberIndices( "aa", "ESP" ) );

    printf( "Log message: %s\n", getLogMessages( "aa", "NWSNWMC00:0000026" ) );

    /* Use pre-formatted strings for these test programs */
    startTime = "2009-04-01T00:00:00+00:00";
    endTime   = "2009-04-11T00:00:00+00:00";

    systemTime = getSystemTime( "aa" );

#define TRUE  1
#define FALSE 0

    printf( "Timeseries:\n---begin---\n" );
    printf( "%s", getTimeSeries( "TestConfig", "Reservoir", NULL,
                      startTime, systemTime, endTime,
                      parameters, nParameters, locations, nLocations,
                      NULL, -1, FALSE ) );
    printf( "---end---\n" );

    /*
     * Running a task ...
     */
    printf( "Running Santiam_Forecast ...\n" );

    taskId = createTask( "aa" );
    date   = getSystemTime( "aa" );

    taskRunId = runTask( "aa", taskId, "Santiam_Forecast", date, date, date, NULL, NULL,
                    "Test user", "PiWebservice taskrun" );

    success = waitForTask( "aa", taskRunId, 120000); /* Wait for 120 seconds = 120000 ms */

    printf( "%s\n", (success? "OK!" : "Problem!") );

    TearDown();
}

Some notes

The program in the attachment uses several external libraries to take care of the actual connection. These libraries are: the Tcl library (version 8.4 or 8.5 should do) and the TclSOAP extension. More on this below.

As for the C interface itself:

To link the program using the gcc compiler, use:

gcc -o example example.c -I. -ltcl84

Code

The C code for the wrapper functions and a Tcl example are available via the attachments.

More on the Tcl libraries

The Tcl library and the TclSOAP extension can be downloaded from ActiveState (http://www.activestate.com).
The TclSOAP extension uses the TclDOM 2.6 extension and Tcllib. All of these are available as open source.