static void
test_value_datetime(void) {

    const char * datestring = "19980717T14:08:55";
    time_t const datetime = 900684535;

    xmlrpc_value * v;
    xmlrpc_env env;
    const char * ds;
    time_t dt;

    xmlrpc_env_init(&env);

    v = xmlrpc_datetime_new_str(&env, datestring);
    TEST_NO_FAULT(&env);
    TEST(XMLRPC_TYPE_DATETIME == xmlrpc_value_type(v));

    xmlrpc_read_datetime_str(&env, v, &ds);
    TEST_NO_FAULT(&env);
    TEST(strcmp(ds, datestring) == 0);
    strfree(ds);

    xmlrpc_read_datetime_sec(&env, v, &dt);
    TEST_NO_FAULT(&env);
    TEST(dt == datetime);

    xmlrpc_DECREF(v);

    v = xmlrpc_datetime_new_sec(&env, datetime);
    TEST_NO_FAULT(&env);
    TEST(XMLRPC_TYPE_DATETIME == xmlrpc_value_type(v));

    xmlrpc_read_datetime_str(&env, v, &ds);
    TEST_NO_FAULT(&env);
    TEST(strcmp(ds, datestring) == 0);
    strfree(ds);

    xmlrpc_read_datetime_sec(&env, v, &dt);
    TEST_NO_FAULT(&env);
    TEST(dt == datetime);

    xmlrpc_DECREF(v);

    v = xmlrpc_build_value(&env, "8", datestring);
    TEST_NO_FAULT(&env);
    TEST(v != NULL);
    TEST(XMLRPC_TYPE_DATETIME == xmlrpc_value_type(v));
    xmlrpc_decompose_value(&env, v, "8", &ds);
    xmlrpc_DECREF(v);
    TEST_NO_FAULT(&env);
    TEST(strcmp(ds, datestring) == 0);
    strfree(ds);

    xmlrpc_env_clean(&env);
}
Beispiel #2
0
static void
test_value_datetime_str_invalid1(const char * const datestring) {

    /* Ideally, xmlrpc_datetime_new_str() would fail on these, but
       the code doesn't implement that today.  However,
       xmlrpc_read_datetime_sec() does catch many cases, so we
       use that.

       Note that xmlrpc_read_datetime_sec() doesn't catch them all.
       Sometimes it just returns garbage, e.g. returns July 1 for
       June 31.
    */

    xmlrpc_value * v;
    xmlrpc_env env;
    time_t dt;

    xmlrpc_env_init(&env);

    v = xmlrpc_datetime_new_str(&env, datestring);
    TEST_NO_FAULT(&env);

    xmlrpc_read_datetime_sec(&env, v, &dt);
    TEST_FAULT(&env, XMLRPC_PARSE_ERROR);

    xmlrpc_DECREF(v);

    xmlrpc_env_clean(&env);
}
value_datetime::operator time_t() const {

    time_t retval;
    env_wrap env;

    xmlrpc_read_datetime_sec(&env.env_c, this->cValueP, &retval);
    throwIfError(env);

    return retval;
}
Beispiel #4
0
static void
test_build_decomp_datetime(void) {

    const char * datestring = "19980717T14:08:55";
    time_t const datetime = 900684535;

    xmlrpc_env env;
    xmlrpc_value * v;
    time_t dt;
    const char * ds;

    xmlrpc_env_init(&env);

    v = xmlrpc_build_value(&env, "t", datetime);
    TEST_NO_FAULT(&env);
    TEST(v != NULL);
    TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_DATETIME);

    dt = 0;
    xmlrpc_read_datetime_sec(&env, v, &dt);
    TEST(dt == datetime);

    dt = 0;
    xmlrpc_decompose_value(&env, v, "t", &dt);
    xmlrpc_DECREF(v);
    TEST_NO_FAULT(&env);
    TEST(dt == datetime);

    v = xmlrpc_int_new(&env, 9);
    TEST_NO_FAULT(&env);
    xmlrpc_decompose_value(&env, v, "t", &dt);
    TEST_FAULT(&env, XMLRPC_TYPE_ERROR);
    xmlrpc_env_clean(&env);
    xmlrpc_env_init(&env);
    xmlrpc_decompose_value(&env, v, "8", &ds);
    TEST_FAULT(&env, XMLRPC_TYPE_ERROR);
    xmlrpc_env_clean(&env);
    xmlrpc_env_init(&env);
    xmlrpc_DECREF(v);

    v = xmlrpc_build_value(&env, "8", datestring);
    TEST_NO_FAULT(&env);
    TEST(v != NULL);
    TEST(xmlrpc_value_type(v) == XMLRPC_TYPE_DATETIME);
    xmlrpc_decompose_value(&env, v, "8", &ds);
    xmlrpc_DECREF(v);
    TEST_NO_FAULT(&env);
    TEST(streq(ds, datestring));
    strfree(ds);

    xmlrpc_env_clean(&env);
}
Beispiel #5
0
static void
test_value_datetime_not_unix(const char * const datestring) {

    xmlrpc_value * v;
    xmlrpc_env env;
    time_t dt;

    xmlrpc_env_init(&env);

    v = xmlrpc_datetime_new_str(&env, datestring);
    TEST_NO_FAULT(&env);

    xmlrpc_read_datetime_sec(&env, v, &dt);
    TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR);

    xmlrpc_DECREF(v);

    xmlrpc_env_clean(&env);
}
Beispiel #6
0
static void
test_value_datetime_varytime(const char * const datestring,
                             time_t       const datetime,
                             unsigned int const usec) {

    xmlrpc_value * v;
    xmlrpc_env env;
    const char * readBackString;
    time_t readBackDt;
    unsigned int readBackUsec;
    const char * datestringSec;
#if XMLRPC_HAVE_TIMEVAL
    struct timeval const dtTimeval = makeTv(datetime, usec);
    struct timeval readBackTv;
#endif
#if XMLRPC_HAVE_TIMESPEC
    struct timespec const dtTimespec = makeTs(datetime, usec);
    struct timespec readBackTs;
#endif
    const char * const dt8601 = make8601(datetime, usec);
    const char * readBack8601;

    datestringSec = truncateFracSec(datestring);

    xmlrpc_env_init(&env);

    /* Test xmlrpc_datetime_new_str and time read functions*/
    v = xmlrpc_datetime_new_str(&env, datestring);
    TEST_NO_FAULT(&env);
    TEST(XMLRPC_TYPE_DATETIME == xmlrpc_value_type(v));

    xmlrpc_read_datetime_sec(&env, v, &readBackDt);
    TEST_NO_FAULT(&env);
    TEST(readBackDt == datetime);

    xmlrpc_read_datetime_usec(&env, v, &readBackDt, &readBackUsec);
    TEST_NO_FAULT(&env);
    TEST(readBackDt == datetime);
    TEST(readBackUsec == usec);

#if XMLRPC_HAVE_TIMEVAL
    xmlrpc_read_datetime_timeval(&env, v, &readBackTv);
    TEST_NO_FAULT(&env);
    TEST(tvIsEqual(dtTimeval, readBackTv));
#endif

#if XMLRPC_HAVE_TIMESPEC
    xmlrpc_read_datetime_timespec(&env, v, &readBackTs);
    TEST_NO_FAULT(&env);
    TEST(tsIsEqual(dtTimespec, readBackTs));
#endif

    xmlrpc_read_datetime_8601(&env, v, &readBack8601);
    TEST_NO_FAULT(&env);
    TEST(xmlrpc_streq(dt8601, readBack8601));
    strfree(readBack8601);

    xmlrpc_DECREF(v);

    /* Test xmlrpc_datetime_new_sec */
    v = xmlrpc_datetime_new_sec(&env, datetime);
    TEST_NO_FAULT(&env);
    TEST(XMLRPC_TYPE_DATETIME == xmlrpc_value_type(v));

    xmlrpc_read_datetime_str(&env, v, &readBackString);
    TEST_NO_FAULT(&env);
    TEST(streq(readBackString, datestringSec));
    strfree(readBackString);

    xmlrpc_DECREF(v);

    /* Test xmlrpc_datetime_new_usec */
    v = xmlrpc_datetime_new_usec(&env, datetime, usec);
    TEST_NO_FAULT(&env);
    TEST(XMLRPC_TYPE_DATETIME == xmlrpc_value_type(v));

    xmlrpc_read_datetime_str(&env, v, &readBackString);
    TEST_NO_FAULT(&env);
    TEST(streq(readBackString, datestring));
    strfree(readBackString);

    xmlrpc_DECREF(v);

#if XMLRPC_HAVE_TIMEVAL
    /* Test xmlrpc_datetime_new_timeval */
    v = xmlrpc_datetime_new_timeval(&env, dtTimeval);
    TEST_NO_FAULT(&env);
    TEST(XMLRPC_TYPE_DATETIME == xmlrpc_value_type(v));

    xmlrpc_read_datetime_str(&env, v, &readBackString);
    TEST_NO_FAULT(&env);
    TEST(streq(readBackString, datestring));
    strfree(readBackString);

    xmlrpc_DECREF(v);
#endif

#if XMLRPC_HAVE_TIMESPEC
    /* Test xmlrpc_datetime_new_timespec */
    v = xmlrpc_datetime_new_timespec(&env, dtTimespec);
    TEST_NO_FAULT(&env);
    TEST(XMLRPC_TYPE_DATETIME == xmlrpc_value_type(v));

    xmlrpc_read_datetime_str(&env, v, &readBackString);
    TEST_NO_FAULT(&env);
    TEST(streq(readBackString, datestring));
    strfree(readBackString);

    xmlrpc_DECREF(v);
#endif

    xmlrpc_env_clean(&env);
    strfree(datestringSec);
}
static void 
decomposeValueWithTree(xmlrpc_env *                  const envP,
                       xmlrpc_value *                const valueP,
                       bool                          const oldstyleMemMgmt,
                       const struct decompTreeNode * const decompRootP) {
/*----------------------------------------------------------------------------
   Decompose XML-RPC value *valueP, given the decomposition tree
   *decompRootP.  The decomposition tree tells what structure *valueP
   is expected to have and where to put the various components of it
   (e.g. it says "it's an array of 3 integers.  Put their values at
   locations x, y, and z")
-----------------------------------------------------------------------------*/
    switch (decompRootP->formatSpecChar) {
    case '-':
        /* There's nothing to validate or return */
        break;
    case 'i':
        xmlrpc_read_int(envP, valueP, decompRootP->store.Tinteger.valueP);
        break;

    case 'b':
        xmlrpc_read_bool(envP, valueP, decompRootP->store.Tbool.valueP);
        break;

    case 'd':
        xmlrpc_read_double(envP, valueP, decompRootP->store.Tdouble.valueP);
        break;

    case 't':
        xmlrpc_read_datetime_sec(envP, valueP,
                                 decompRootP->store.TdatetimeT.valueP);
        break;

    case '8':
        readDatetime8Str(envP, valueP, decompRootP->store.Tdatetime8.valueP,
                         oldstyleMemMgmt);
        break;

    case 's':
        if (decompRootP->store.Tstring.sizeP)
            readStringLp(envP, valueP,
                         decompRootP->store.Tstring.sizeP,
                         decompRootP->store.Tstring.valueP,
                         oldstyleMemMgmt);
        else
            readString(envP, valueP, decompRootP->store.Tstring.valueP,
                       oldstyleMemMgmt);
        break;

    case 'w':
#if HAVE_UNICODE_WCHAR
        if (decompRootP->store.Tstring.sizeP)
            readStringWLp(envP, valueP,
                          decompRootP->store.TwideString.sizeP,
                          decompRootP->store.TwideString.valueP,
                          oldstyleMemMgmt);
        else
            readStringW(envP, valueP, decompRootP->store.TwideString.valueP,
                        oldstyleMemMgmt);
#else
        XMLRPC_ASSERT(false);
#endif /* HAVE_UNICODE_WCHAR */
        break;
        
    case '6':
        readBase64(envP, valueP,
                   decompRootP->store.TbitString.sizeP,
                   decompRootP->store.TbitString.valueP,
                   oldstyleMemMgmt);
        break;

    case 'n':
        xmlrpc_read_nil(envP, valueP);
        break;

    case 'I':
        xmlrpc_read_i8(envP, valueP, decompRootP->store.Ti8.valueP);
        break;

    case 'p':
        xmlrpc_read_cptr(envP, valueP, decompRootP->store.Tcptr.valueP);
        break;

    case 'V':
        *decompRootP->store.Tvalue.valueP = valueP;
        if (!oldstyleMemMgmt)
            xmlrpc_INCREF(valueP);
        break;

    case 'A':
        if (xmlrpc_value_type(valueP) != XMLRPC_TYPE_ARRAY)
            xmlrpc_env_set_fault_formatted(
                envP, XMLRPC_TYPE_ERROR, "Value to be decomposed is of type "
                "%s, but the 'A' specifier requires type ARRAY",
                xmlrpc_type_name(xmlrpc_value_type(valueP)));
        else {
            *decompRootP->store.TarrayVal.valueP = valueP;
            if (!oldstyleMemMgmt)
                xmlrpc_INCREF(valueP);
        }
        break;

    case 'S':
        if (xmlrpc_value_type(valueP) != XMLRPC_TYPE_STRUCT)
            xmlrpc_env_set_fault_formatted(
                envP, XMLRPC_TYPE_ERROR, "Value to be decomposed is of type "
                "%s, but the 'S' specifier requires type STRUCT.",
                xmlrpc_type_name(xmlrpc_value_type(valueP)));
        else {
            *decompRootP->store.TstructVal.valueP = valueP;
            if (!oldstyleMemMgmt)
                xmlrpc_INCREF(valueP);
        }
        break;

    case '(':
        if (xmlrpc_value_type(valueP) != XMLRPC_TYPE_ARRAY)
            xmlrpc_env_set_fault_formatted(
                envP, XMLRPC_TYPE_ERROR, "Value to be decomposed is of type "
                "%s, but the '(...)' specifier requires type ARRAY",
                xmlrpc_type_name(xmlrpc_value_type(valueP)));
        else
            parsearray(envP, valueP, decompRootP->store.Tarray,
                       oldstyleMemMgmt);
        break;

    case '{':
        if (xmlrpc_value_type(valueP) != XMLRPC_TYPE_STRUCT)
            xmlrpc_env_set_fault_formatted(
                envP, XMLRPC_TYPE_ERROR, "Value to be decomposed is of type "
                "%s, but the '{...}' specifier requires type STRUCT",
                xmlrpc_type_name(xmlrpc_value_type(valueP)));
        else
            parsestruct(envP, valueP, decompRootP->store.Tstruct,
                        oldstyleMemMgmt);
        break;

    default:
        /* Every format character that is allowed in a decomposition tree
           node is handled above.
        */
        XMLRPC_ASSERT(false);
    }
}