ERL_NIF_TERM date_get6(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { UErrorCode status = U_ZERO_ERROR; UCalendar* cal; cloner* ptr; int32_t year, month, day, hour, minute, second; if(!((argc == 7) && enif_get_resource(env, argv[0], calendar_type, (void**) &ptr) && enif_get_int(env, argv[1], &year) && enif_get_int(env, argv[2], &month) && enif_get_int(env, argv[3], &day) && enif_get_int(env, argv[4], &hour) && enif_get_int(env, argv[5], &minute) && enif_get_int(env, argv[6], &second))) { return enif_make_badarg(env); } month--; cal = (UCalendar*) cloner_get(ptr); CHECK_RES(env, cal); ucal_setDateTime(cal, year, month, day, hour, minute, second, &status); CHECK(env, status); return calendar_to_double(env, (const UCalendar*) cal); }
ERL_NIF_TERM date_get_field(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { UErrorCode status = U_ZERO_ERROR; UCalendar* cal; cloner* ptr; double date; ERL_NIF_TERM res; if(!((argc == 3) && enif_get_resource(env, argv[0], calendar_type, (void**) &ptr) && enif_get_double(env, argv[1], &date))) { return enif_make_badarg(env); } cal = (UCalendar*) cloner_get(ptr); CHECK_RES(env, cal); ucal_setMillis(cal, (UDate) date, &status); CHECK(env, status); res = do_date_get_field(env, cal, argv[2], status); CHECK(env, status); return res; }
ERL_NIF_TERM split(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary in; cloner* ptr; UBreakIterator* iter; int len = -1, last, pos, is_valid; UErrorCode status = U_ZERO_ERROR; ERL_NIF_TERM head, tail; UChar* bin; UChar* text; if (argc != 2) return enif_make_badarg(env); /* Last argument must be a binary */ if (!(enif_inspect_binary(env, argv[1], &in) && enif_get_resource(env, argv[0], iterator_type, (void**) &ptr))) { return enif_make_badarg(env); } iter = (UBreakIterator*) cloner_get(ptr); CHECK_RES(env, iter); if (iter == NULL) { return enif_make_badarg(env); } text = (UChar*) in.data; ubrk_setText(iter, text, TO_ULEN(in.size), &status); CHECK(env, status); tail = enif_make_list(env, 0); pos = (int) ubrk_last(iter); while (pos) { last = pos; is_valid = is_valid_elem(ptr, iter); /* get the next elem. */ pos = (int) ubrk_previous(iter); if (pos == UBRK_DONE) pos = 0; if (is_valid) /* Is the old element valid? */ { len = FROM_ULEN(last - pos); bin = (UChar*) enif_make_new_binary(env, len, &head); memcpy(bin, (const char*) (text + pos), len); tail = enif_make_list_cell(env, head, tail); } }; return tail; }
ERL_NIF_TERM trans(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary in; cloner* ptr; const Transliterator* t; UnicodeString input; if (argc != 2) return enif_make_badarg(env); /* Second argument must be a binary */ if(!(enif_inspect_binary(env, argv[1], &in) && enif_get_resource(env, argv[0], trans_type, (void**) &ptr))) { return enif_make_badarg(env); } t = (Transliterator*) cloner_get(ptr); CHECK_RES(env, t); input = copy_binary_to_string(in); t->transliterate(input); return string_to_term(env, input); }
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); }
ERL_NIF_TERM to_title(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary in, out; int32_t ulen; char locale[LOCALE_LEN]; const char* locptr; cloner* ptr; UBreakIterator* iter; UErrorCode status = U_ZERO_ERROR; if (argc != 2) return enif_make_badarg(env); /* Second argument must be a binary */ if(!enif_inspect_binary(env, argv[1], &in)) { return enif_make_badarg(env); } if (enif_get_atom(env, argv[0], locale, LOCALE_LEN, ERL_NIF_LATIN1)) { /* First element is an atom. */ locptr = (const char*) locale; iter = NULL; } else if (enif_get_resource(env, argv[0], iterator_type, (void**) &ptr)) { /* First element is an iterator. */ iter = (UBreakIterator*) cloner_get(ptr); CHECK_RES(env, iter); /* Iterator contains a locale name. Extract it. */ locptr = ubrk_getLocaleByType((const UBreakIterator*) iter, ULOC_ACTUAL_LOCALE, /* locale type */ &status); CHECK(env, status); } else { return enif_make_badarg(env); } ulen = TO_ULEN(in.size); do_to_title(in, out, ulen, iter, locptr, status); if (status == U_BUFFER_OVERFLOW_ERROR) { do_to_title(in, out, ulen, iter, locptr, status); } CHECK(env, status); return enif_make_binary(env, &out); }
ERL_NIF_TERM split_index(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary in; cloner* ptr; UBreakIterator* iter; int pos; UErrorCode status = U_ZERO_ERROR; ERL_NIF_TERM head, tail; if (argc != 2) return enif_make_badarg(env); /* Last argument must be a binary */ if (!(enif_inspect_binary(env, argv[1], &in) && enif_get_resource(env, argv[0], iterator_type, (void**) &ptr))) { return enif_make_badarg(env); } iter = (UBreakIterator*) cloner_get(ptr); CHECK_RES(env, iter); if (iter == NULL) { return enif_make_badarg(env); } ubrk_setText(iter, (UChar*) in.data, TO_ULEN(in.size), &status); CHECK(env, status); tail = enif_make_list(env, 0); pos = (int) ubrk_last(iter); while ((pos != UBRK_DONE) && (pos != 0)) { if (is_valid_elem(ptr, iter)) { head = enif_make_int(env, pos); tail = enif_make_list_cell(env, head, tail); } /* get the next elem. */ pos = (int) ubrk_previous(iter); }; return tail; }
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); }
ERL_NIF_TERM date_get_fields(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { UErrorCode status = U_ZERO_ERROR; UCalendar* cal; cloner* ptr; double date; ERL_NIF_TERM res; ERL_NIF_TERM head, tail, out; unsigned int count; 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]; out = enif_make_list(env, 0); while (enif_get_list_cell(env, tail, &head, &tail)) { /* Set an attribute start */ res = do_date_get_field(env, cal, head, status); CHECK(env, status); out = enif_make_list_cell(env, enif_make_tuple2(env, head, res), out); /* Set an attribute end */ } return out; }
ERL_NIF_TERM len(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { ErlNifBinary in; cloner* ptr; UBreakIterator* iter; int count = 0, pos; UErrorCode status = U_ZERO_ERROR; if (argc != 2) return enif_make_badarg(env); /* Last argument must be a binary */ if (!(enif_inspect_binary(env, argv[1], &in) && enif_get_resource(env, argv[0], iterator_type, (void**) &ptr))) { return enif_make_badarg(env); } iter = (UBreakIterator*) cloner_get(ptr); CHECK_RES(env, iter); if (iter == NULL) { return enif_make_badarg(env); } /* Do count */ ubrk_setText(iter, (UChar *) in.data, TO_ULEN(in.size), &status); CHECK(env, status); pos = ubrk_first(iter); if (pos != UBRK_DONE) while (1) { pos = ubrk_next(iter); if (pos == UBRK_DONE) break; if (is_valid_elem(ptr, iter)) count++; } return enif_make_int(env, count); }
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; }
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; }