Lingua-RU-Money-XS

 view release on metacpan or  search on metacpan

XS.xs  view on Meta::CPAN

	sv_catpvn(value_pv, kopeck[ending], strlen(kopeck[ending]));
	return value_pv;
}

STATIC SV *
ruble2words(pTHX_ U16 value, U8 decade, bool words) {
	U8 ending = ending4value(value);
	SV *value_pv = sv_2mortal(newSVpvs(""));
	if (!value) {
		if (!decade)
			sv_catpvn(value_pv, ruble[decade][ending], strlen(ruble[decade][ending]));
		return value_pv;
	}
	if (words) {
		sv_catpvn(value_pv, hundreds[value / 100], strlen(hundreds[value / 100]));
		char **units = (char **) (decade == THOUSAND ? funits : munits);
		if (value % 100 < 20) {
			sv_catpvn(value_pv, units[value % 100], strlen(units[value % 100]));
		} else {
			sv_catpvn(value_pv, tens[value % 100 / 10], strlen(tens[value % 100 / 10]));
			sv_catpvn(value_pv, units[value % 10], strlen(units[value % 10]));
		}
	} else {
		char value_str[5];
		sprintf(value_str, "%d ", value);
		sv_catpvn(value_pv, value_str, strlen(value_str));
	}
	sv_catpvn(value_pv, ruble[decade][ending], strlen(ruble[decade][ending]));
	return value_pv;
}

STATIC SV *
money2words(pTHX_ double amount, bool ruble_cvt, bool kopeck_cvt) {
	if (unlikely(amount < MONEY_MIN))
		croak("Negative amount can't be processed");
	if (unlikely(amount >= MONEY_MAX))
		croak("Given amount can't be processed due to the type overflow");
	if (unlikely(amount >= pow(1e3, TRILLION)))
		warn("Kopeck value is calculated inaccurate due to the lack for "
			"significant digits after the radix point");
	U8 kopeck_v = amount < pow(1e3, TRILLION) ? double2kopeck(amount) : 0;
	AV *stack = (AV *) sv_2mortal((SV *) newAV());
	av_push(stack, kopeck2words(aTHX_ kopeck_v, kopeck_cvt));
	U64 ruble_v = (U64) amount;
	U8 decade;
	for (decade = UNIT; ruble_v > 0; ruble_v /= 1000, decade++)
		av_push(stack, ruble2words(aTHX_ ruble_v % 1000, decade, ruble_cvt));
	/* Build the result string */
	SV *words = sv_2mortal(newSVpvs(""));
	while (av_len(stack) + 1)
		sv_catsv(words, av_pop(stack));
	SvUTF8_on(words);
	return words;
}

MODULE = Lingua::RU::Money::XS		PACKAGE = Lingua::RU::Money::XS

void
rur2words(SV *amount)
	PROTOTYPE: $
	PPCODE:
		ST(0) = money2words(aTHX_ SvNV(amount), true, false);
		XSRETURN(1);

void
all2words(SV *amount)
	PROTOTYPE: $
	PPCODE:
		ST(0) = money2words(aTHX_ SvNV(amount), true, true);
		XSRETURN(1);



( run in 1.925 second using v1.01-cache-2.11-cpan-71847e10f99 )