Annotation of parser3/src/classes/math.C, revision 1.19

1.1       parser      1: /** @file
                      2:        Parser: @b math parser class.
                      3: 
1.12      paf         4:        Copyright (c) 2001, 2002 ArtLebedev Group (http://www.artlebedev.com)
1.13      paf         5:        Author: Alexandr Petrosian <paf@design.ru> (http://paf.design.ru)
1.1       parser      6: 
1.19    ! paf         7:        $Id: math.C,v 1.18 2002/04/18 10:51:00 paf Exp $
1.1       parser      8: */
                      9: 
                     10: #include "pa_common.h"
                     11: #include "pa_vint.h"
1.2       parser     12: #include "pa_vmath.h"
1.1       parser     13: #include "pa_request.h"
1.19    ! paf        14: #include "pa_md5.h"
1.1       parser     15: 
1.5       parser     16: #ifdef WIN32
1.19    ! paf        17: // for threadID
1.5       parser     18: #      include <windows.h>
                     19: #endif
                     20: 
1.1       parser     21: // defines
                     22: 
1.3       parser     23: #define PI 3.1415926535
1.1       parser     24: 
                     25: // class
                     26: 
                     27: class MMath : public Methoded {
                     28: public:
                     29:        MMath(Pool& pool);
1.5       parser     30:        void configure_admin(Request& r);
                     31: 
1.1       parser     32: public: // Methoded
1.15      paf        33:        bool used_directly() { return false; }
1.1       parser     34: };
                     35: 
                     36: // methods
1.5       parser     37: static unsigned int randomizer=0;
1.1       parser     38: static void _random(Request& r, const String& method_name, MethodParams *params) {
                     39:        Pool& pool=r.pool();
                     40: 
1.3       parser     41:        Value& range=params->as_junction(0, "range must be expression");
1.17      paf        42:     double top=r.process_to_value(range).as_double();
1.14      paf        43:     if(top<=1)
1.16      paf        44:                throw Exception("parser.runtime",
1.1       parser     45:                        &method_name,
1.14      paf        46:                        "top must be above 1 (%g)", top);
1.1       parser     47:        
1.18      paf        48:        int result=(int)( ((double)((randomizer=rand())% RAND_MAX)) / RAND_MAX * uint(top) );
                     49:        r.write_no_lang(*new(pool) VInt(pool, result));
1.1       parser     50: }
                     51: 
                     52: 
                     53: typedef double (*math1_func_ptr)(double);
1.3       parser     54: static double frac(double param) { return param-trunc(param); }
                     55: static double degrees(double param) { return param /PI *180; }
                     56: static double radians(double param) { return param /180 *PI; }
1.1       parser     57: 
                     58: static void math1(Request& r, 
                     59:                                  const String& method_name, MethodParams *params,
                     60:                                  math1_func_ptr func) {
                     61:        Pool& pool=r.pool();
1.3       parser     62:        Value& param=params->as_junction(0, "parameter must be expression");
1.1       parser     63: 
1.18      paf        64:        double result=(*func)(r.process_to_value(param).as_double());
                     65:        r.write_no_lang(*new(pool) VDouble(pool, result));
1.1       parser     66: }
                     67: 
                     68: #define MATH1(name) \
                     69:        static void _##name(Request& r, const String& method_name, MethodParams *params) {\
                     70:                math1(r, method_name, params, &name);\
                     71:        }
                     72: #define MATH1P(name_parser, name_c) \
                     73:        static void _##name_parser(Request& r, const String& method_name, MethodParams *params) {\
                     74:                math1(r, method_name, params, &name_c);\
                     75:        }
                     76: MATH1(round);  MATH1(floor);   MATH1P(ceiling, ceil);
1.3       parser     77: MATH1(trunc);  MATH1(frac);
1.1       parser     78: MATH1P(abs, fabs);     MATH1(sign);
                     79: MATH1(exp);    MATH1(log);     
                     80: MATH1(sin);    MATH1(asin);    
                     81: MATH1(cos);    MATH1(acos);    
                     82: MATH1(tan);    MATH1(atan);
1.3       parser     83: MATH1(degrees);        MATH1(radians);
1.1       parser     84: MATH1(sqrt);
                     85: 
                     86: 
                     87: typedef double (*math2_func_ptr)(double, double);
                     88: static void math2(Request& r, 
                     89:                                  const String& method_name, MethodParams *params,
                     90:                                  math2_func_ptr func) {
                     91:        Pool& pool=r.pool();
1.3       parser     92:        Value& a=params->as_junction(0, "parameter must be expression");
                     93:        Value& b=params->as_junction(1, "parameter must be expression");
1.1       parser     94: 
1.18      paf        95:        double result=(*func)(
1.17      paf        96:                r.process_to_value(a).as_double(),
1.18      paf        97:                r.process_to_value(b).as_double());
                     98:        r.write_no_lang(*new(pool) VDouble(pool, result));
1.1       parser     99: }
                    100: 
                    101: #define MATH2(name) \
                    102:        static void _##name(Request& r, const String& method_name, MethodParams *params) {\
                    103:                math2(r, method_name, params, &name);\
                    104:        }
                    105: MATH2(pow);
                    106: 
1.19    ! paf       107: static void _crypt(Request& r, const String& method_name, MethodParams *params) {
        !           108:        Pool& pool=r.pool();
        !           109:        const char *password=params->as_string(0, "password must be string").cstr();
        !           110:        const char *salt=params->as_string(1, "salt must be string").cstr();
        !           111: 
        !           112:     /* FreeBSD style MD5 string 
        !           113:      */
        !           114:     if (strncmp(salt, PA_MD5PW_ID, PA_MD5PW_IDLEN) == 0) {
        !           115:                const size_t sample_size=120;
        !           116:                char *sample_buf=(char *)pool.malloc(sample_size);
        !           117:                pa_MD5Encode((const unsigned char *)password,
        !           118:                                 (const unsigned char *)salt, sample_buf, sample_size);
        !           119:                r.write_pass_lang(*new(pool) String(pool, sample_buf));
        !           120:     } else
        !           121:                throw Exception("parser.runtime",
        !           122:                        &method_name,
        !           123:                        "salt must start with '" PA_MD5PW_ID "'");
        !           124: }
        !           125: 
1.1       parser    126: // constructor
                    127: 
1.18      paf       128: MMath::MMath(Pool& apool) : Methoded(apool, "math") {
1.1       parser    129:        // ^FUNC(expr)  
                    130: #define ADD1(name) \
                    131:        add_native_method(#name, Method::CT_STATIC, _##name, 1, 1)
                    132: 
                    133:        ADD1(round);    ADD1(floor);    ADD1(ceiling);
1.3       parser    134:        ADD1(trunc);    ADD1(frac);
1.1       parser    135:        ADD1(abs);      ADD1(sign);
                    136:        ADD1(exp);      ADD1(log);      
                    137:        ADD1(sin);      ADD1(asin);     
                    138:        ADD1(cos);      ADD1(acos);     
                    139:        ADD1(tan);      ADD1(atan);
1.3       parser    140:        ADD1(degrees);  ADD1(radians);
1.1       parser    141:        ADD1(sqrt);
1.3       parser    142:        ADD1(random);
1.1       parser    143: 
                    144: #define ADD2(name) \
                    145:        add_native_method(#name, Method::CT_STATIC, _##name, 2, 2)
                    146: 
                    147:        // ^pow(x;y)
                    148:        ADD2(pow);
                    149: 
1.19    ! paf       150:        // ^crypt[password;salt]
        !           151:        ADD2(crypt);
1.5       parser    152: }
                    153: 
                    154: // in MSVC each thread has it's own pseudo-random sequence
                    155: // in win32 apache each thread can handle multiple requests
                    156: // so to get proper randoms we remember random generated in one thread
                    157: void MMath::configure_admin(Request&) {
                    158:        // setting seed
                    159:        srand(
1.14      paf       160:                randomizer
1.5       parser    161: #ifdef WIN32
1.14      paf       162:                ^ GetCurrentThreadId()
1.5       parser    163: #else
1.14      paf       164:                ^ getpid()
1.5       parser    165: #endif
1.14      paf       166:                ^ (unsigned int)time(NULL)
1.5       parser    167:        );
                    168:        if(!randomizer)
                    169:                randomizer=rand();
1.1       parser    170: }
                    171: 
1.2       parser    172: // global variables
                    173: 
                    174: Methoded *math_base_class;
                    175: Hash *math_consts;
                    176: 
1.1       parser    177: // creator
                    178: 
                    179: Methoded *MMath_create(Pool& pool) {
1.2       parser    180:        math_consts=new(pool) Hash(pool);
                    181:        math_consts->put(
                    182:                *new(pool) String(pool, "PI"), 
1.3       parser    183:                new(pool) VDouble(pool, PI));
1.2       parser    184: 
                    185:        return math_base_class=new(pool) MMath(pool);
1.1       parser    186: }

E-mail: