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: