--- parser3/src/classes/math.C 2009/01/25 03:10:11 1.56 +++ parser3/src/classes/math.C 2012/05/28 10:33:18 1.61 @@ -1,15 +1,13 @@ /** @file Parser: @b math parser class. - Copyright(c) 2001-2005 ArtLebedev Group(http://www.artlebedev.com) + Copyright (c) 2001-2012 Art. Lebedev Studio (http://www.artlebedev.com) Author: Alexandr Petrosian (http://paf.design.ru) portions from gen_uuid.c, Copyright (C) 1996, 1997, 1998, 1999 Theodore Ts'o. */ -static const char * const IDENT_MATH_C="$Date: 2009/01/25 03:10:11 $"; - #include "pa_vmethod_frame.h" #include "pa_common.h" #include "pa_vint.h" @@ -32,6 +30,8 @@ static const char * const IDENT_MATH_C=" extern char *crypt(const char* , const char* ); #endif +volatile const char * IDENT_MATH_C="$Id: math.C,v 1.61 2012/05/28 10:33:18 moko Exp $"; + // defines #define MAX_SALT 8 @@ -357,6 +357,51 @@ static void _crc32(Request& r, MethodPar r.write_no_lang(*new VInt(pa_crc32(string, strlen(string)))); } +static void toBase(unsigned int value, unsigned int base, char*& ptr){ + static const char* hex="0123456789ABCDEF"; + int rest = value % base; + if(value >= base) + toBase( (value-rest)/base, base, ptr); + *ptr++=(char)hex[rest]; +} + +static void _convert(Request& r, MethodParams& params) { + const char *str=params.as_string(0, PARAMETER_MUST_BE_STRING).cstr(); + + int base_from=params.as_int(1, "base from must be integer", r); + if(base_from < 2 || base_from > 16) + throw Exception(PARSER_RUNTIME, 0, "base from must be an integer from 2 to 16"); + + int base_to=params.as_int(2, "base to must be integer", r); + if(base_to < 2 || base_to > 16) + throw Exception(PARSER_RUNTIME, 0, "base to must be an integer from 2 to 16"); + + while(isspace(*str)) + str++; + + if(!*str) + return; + + bool negative=false; + if(str[0]=='-') { + negative=true; + str++; + } else if(str[0]=='+') { + str++; + } + + unsigned int value=pa_atoui(str, base_from); + + char result_cstr[sizeof(unsigned int)*8+1/*minus for negative number*/+1/*terminator*/]; + char* ptr=result_cstr; + if(negative) + *ptr++='-'; + + toBase(value, base_to, ptr); + *ptr=0; + r.write_pass_lang(*new String(pa_strdup(result_cstr))); +} + // constructor MMath::MMath(): Methoded("math") { @@ -399,4 +444,7 @@ MMath::MMath(): Methoded("math") { // ^math:uid64[] ADD0(uid64); + + // ^math:convert[number](base-from;base-to) + add_native_method("convert", Method::CT_STATIC, _convert, 3, 3); }