Пример #1
0
static ERL_NIF_TERM do_date_get_field(ErlNifEnv* env, UCalendar* cal,
    const ERL_NIF_TERM field_atom, UErrorCode& status)
{
    char value[ATOM_LEN];
    int parsed_value, amount;
    UCalendarDateFields field;

    if (!enif_get_atom(env, field_atom, (char*) value, ATOM_LEN,
            ERL_NIF_LATIN1)) {
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return 0;
    }

    parsed_value = parseCalendarDateField(value);
    if (parsed_value == -1) {
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return 0;
    }

    field = (UCalendarDateFields) parsed_value;

    amount = (int) ucal_get(cal, field, &status);
    if (U_FAILURE(status))
        return 0;

    if (field == UCAL_MONTH)
        amount++; /* month from 0 */

    return enif_make_int(env, amount);
}
Пример #2
0
inline static ERL_NIF_TERM do_offset(ErlNifEnv* env, 
    UCalendar* cal,
    date_fun_ptr fun,
    const ERL_NIF_TERM in) 
{
    UCalendarDateFields field;
    UErrorCode status = U_ZERO_ERROR;

    ERL_NIF_TERM head, tail;
    ERL_NIF_TERM* tuple;
    unsigned int count, i;
    int32_t len, offset; 

    char    value[ATOM_LEN];
    int     parsed_value;
    
    
    i = 0;
    if (!enif_get_list_length(env, in, &count)) 
        return enif_make_badarg(env);

    tail = in;

    while (enif_get_list_cell(env, tail, &head, &tail)) {

        if (enif_get_tuple(env, head, &len, (const ERL_NIF_TERM**) &tuple)
            && (len == 2)) { 

            /* Set an attribute start */

            if (!(enif_get_atom(env, tuple[0], (char*) value, 
                        ATOM_LEN, ERL_NIF_LATIN1) 
               && enif_get_int(env, tuple[1], &offset))) 
                goto bad_elem;
                
            parsed_value = parseCalendarDateField(value);
            if ((parsed_value == -1)) 
                goto bad_elem;

            field = (UCalendarDateFields) parsed_value;
 
            fun(cal, field, offset, &status);

            if (U_FAILURE(status))
                goto bad_elem;
            
            /* Set an attribute end */

        } else 
            goto bad_elem;
    }


    return calendar_to_double(env, (const UCalendar*) cal);

    bad_elem:
        return list_element_error(env, in, i);
}
Пример #3
0
ERL_NIF_TERM date_clear(ErlNifEnv* env, int argc, 
    const ERL_NIF_TERM argv[])
{
    UErrorCode status = U_ZERO_ERROR;
    UCalendar* cal;
    cloner* ptr;
    double date;

    UCalendarDateFields field;
    ERL_NIF_TERM head, tail;
    unsigned int count, i = 0;

    char    value[ATOM_LEN];
    int     parsed_value;

    if(!((argc == 3)
      && enif_get_resource(env, argv[0], calendar_type, (void**) &ptr)  
      && enif_get_double(env, argv[1], &date)
      && enif_get_list_length(env, argv[2], &count))) {
        return enif_make_badarg(env);
    }

    cal = (UCalendar*) cloner_get(ptr);
    CHECK_RES(env, cal);

    ucal_setMillis(cal, (UDate) date, &status);
    CHECK(env, status);

    tail = argv[2];
    while (enif_get_list_cell(env, tail, &head, &tail)) {

            /* Set an attribute start */

            if (!enif_get_atom(env, head, (char*) value, 
                    ATOM_LEN, ERL_NIF_LATIN1)) 
                goto bad_elem;
                
            parsed_value = parseCalendarDateField(value);
            if ((parsed_value == -1)) 
                goto bad_elem;

            field = (UCalendarDateFields) parsed_value;
 
            ucal_clearField(cal, field);

            if (U_FAILURE(status))
                goto bad_elem;
            
            /* Set an attribute end */

    }

    return calendar_to_double(env, (const UCalendar*) cal);

    bad_elem:
        return list_element_error(env, argv[2], i);
}
Пример #4
0
ERL_NIF_TERM date_diff_field(ErlNifEnv* env, int argc, 
    const ERL_NIF_TERM argv[])
{
    UErrorCode status = U_ZERO_ERROR;
    UCalendar* cal;
    cloner* ptr;
    double startMs, targetMs;

    char    value[ATOM_LEN];
    int     parsed_value, amount;
    UCalendarDateFields field;


    if(!((argc == 4)
      && enif_get_resource(env, argv[0], calendar_type, (void**) &ptr)  
      && enif_get_double(env, argv[1], &startMs)
      && enif_get_double(env, argv[2], &targetMs)
      && enif_get_atom(env, argv[3], (char*) value, ATOM_LEN, 
            ERL_NIF_LATIN1))) {
        return enif_make_badarg(env);
    }

    cal = (UCalendar*) cloner_get(ptr);
    CHECK_RES(env, cal);

    ucal_setMillis(cal, (UDate) startMs, &status);
    CHECK(env, status);



    parsed_value = parseCalendarDateField(value);
    if (parsed_value == -1) {
        status = U_ILLEGAL_ARGUMENT_ERROR;
        CHECK(env, status);
    }

    field = (UCalendarDateFields) parsed_value;

    amount = (int) dateFieldDifference(cal, 
        targetMs, 
        field, 
        status);
    CHECK(env, status);

    return enif_make_int(env, amount);
}
Пример #5
0
ERL_NIF_TERM date_diff_fields(ErlNifEnv* env, int argc, 
    const ERL_NIF_TERM argv[])
{
    UErrorCode status = U_ZERO_ERROR;
    UCalendar* cal;
    cloner* ptr;
    double startMs, targetMs;

    ERL_NIF_TERM head, tail, out;
    unsigned int count;

    char    value[ATOM_LEN];
    int     parsed_value;
    UCalendarDateFields field;

    struct {
        int enable;
        ERL_NIF_TERM atom;
        int32_t amount;
    } fields[UCAL_FIELD_COUNT];


    if(!((argc == 4)
      && enif_get_resource(env, argv[0], calendar_type, (void**) &ptr)  
      && enif_get_double(env, argv[1], &startMs)
      && enif_get_double(env, argv[2], &targetMs)
      && enif_get_list_length(env, argv[3], &count))) {
        return enif_make_badarg(env);
    }

    cal = (UCalendar*) cloner_get(ptr);
    CHECK_RES(env, cal);

    ucal_setMillis(cal, (UDate) startMs, &status);
    CHECK(env, status);

    for (int i = 0; i < UCAL_FIELD_COUNT; i++)
        fields[i].enable = 0;

    tail = argv[3];
    while (enif_get_list_cell(env, tail, &head, &tail)) {

        /* Set an attribute start */

        if (!enif_get_atom(env, head, (char*) value, ATOM_LEN, 
            ERL_NIF_LATIN1)) {
            status = U_ILLEGAL_ARGUMENT_ERROR;
            CHECK(env, status);
        }

        parsed_value = parseCalendarDateField(value);
        if (parsed_value == -1) {
            status = U_ILLEGAL_ARGUMENT_ERROR;
            CHECK(env, status);
        }

        field = (UCalendarDateFields) parsed_value;
        fields[field].enable = 1;
        fields[field].atom = head;

        /* Set an attribute end */

    }

    for (int i = 0; i < UCAL_FIELD_COUNT; i++) {
        if (fields[i].enable)
        {
            field = (UCalendarDateFields) i;
            fields[i].amount = (int) dateFieldDifference(cal, 
                targetMs, 
                field, 
                status);

            CHECK(env, status);
        }
    }

    out = enif_make_list(env, 0);
    for (int i = UCAL_FIELD_COUNT; i; ) {
        i--;
        if (fields[i].enable)
            out = enif_make_list_cell(env, 
                    enif_make_tuple2(env, fields[i].atom,
                        enif_make_int(env, fields[i].amount)
                    ),
                    out);

    }

    return out;
}
Пример #6
0
ERL_NIF_TERM date_diff_fields(ErlNifEnv* env, int argc, 
    const ERL_NIF_TERM argv[])
{
    UErrorCode status = U_ZERO_ERROR;
    UCalendar* cal;
    cloner* ptr;
    double startMs, targetMs;

    ERL_NIF_TERM head, tail, out;
    unsigned int count;

    char    value[ATOM_LEN];
    int     parsed_value, pos;
    UCalendarDateFields field;

    struct {
        int enable;
        ERL_NIF_TERM atom;
        int32_t amount;
    /* 
    //} fields[POS_MAX];
       Allocate more memory, but we will use only POS_MAX elems.
    */
    } fields[UCAL_FIELD_COUNT];


    if(!((argc == 4)
      && enif_get_resource(env, argv[0], calendar_type, (void**) &ptr)  
      && enif_get_double(env, argv[1], &startMs)
      && enif_get_double(env, argv[2], &targetMs)
      && enif_get_list_length(env, argv[3], &count))) {
        return enif_make_badarg(env);
    }

    cal = (UCalendar*) cloner_get(ptr);
    CHECK_RES(env, cal);

    ucal_setMillis(cal, (UDate) startMs, &status);
    CHECK(env, status);

    for (int i = 0; i < UCAL_FIELD_COUNT; i++)
        fields[i].enable = 0;

    tail = argv[3];
    while (enif_get_list_cell(env, tail, &head, &tail)) {

        /* Set an attribute start */

        if (!enif_get_atom(env, head, (char*) value, ATOM_LEN, 
            ERL_NIF_LATIN1)) {
            return enif_make_badarg(env);
        }

        parsed_value = parseCalendarDateField(value);
        if (parsed_value == -1) {
            return enif_make_badarg(env);
        }

        field = (UCalendarDateFields) parsed_value;
        /* Define the position in the sorted array */
        pos = field_to_pos[field];

        /* Unsupported type */
        if (pos == -1)
            return enif_make_badarg(env);
            
        fields[pos].enable = 1;
        fields[pos].atom = head;

        /* Set an attribute end */

    }

    for (int i = 0; i < POS_MAX; i++) {
        if (fields[i].enable)
        {
            /* Retrive the 'real' type */
            field = (UCalendarDateFields) pos_to_field[i];
            fields[i].amount = (int) dateFieldDifference(cal, 
                (UDate) targetMs, 
                field, 
                status);

            CHECK(env, status);
        }
    }

    out = enif_make_list(env, 0);
    for (int i = POS_MAX; i; ) {
        i--;
        if (fields[i].enable)
            out = enif_make_list_cell(env, 
                    enif_make_tuple2(env, fields[i].atom,
                        enif_make_int(env, fields[i].amount)
                    ),
                    out);

    }

    return out;
}