881f073844b3f50aeaddaaa1be0a5cea8cf6148d
2 ** NetXMS - Network Management System
3 ** NetXMS Scripting Language Interpreter
4 ** Copyright (C) 2005-2010 Victor Kirhenshtein
6 ** This program is free software; you can redistribute it and/or modify
7 ** it under the terms of the GNU General Public License as published by
8 ** the Free Software Foundation; either version 2 of the License, or
9 ** (at your option) any later version.
11 ** This program is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 ** GNU General Public License for more details.
16 ** You should have received a copy of the GNU General Public License
17 ** along with this program; if not, write to the Free Software
18 ** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 // Assign value to correct number field
31 #define ASSIGN_NUMERIC_VALUE(x) \
36 m_value.nInt32 = (x); \
38 case NXSL_DT_UINT32: \
39 m_value.uInt32 = (x); \
42 m_value.nInt64 = (x); \
44 case NXSL_DT_UINT64: \
45 m_value.uInt64 = (x); \
48 m_value.dReal = (x); \
57 // Retrieve correct number field
60 #define RETRIEVE_NUMERIC_VALUE(x, dt) \
65 x = (dt)m_value.nInt32; \
67 case NXSL_DT_UINT32: \
68 x = (dt)m_value.uInt32; \
71 x = (dt)m_value.nInt64; \
73 case NXSL_DT_UINT64: \
74 x = (dt)m_value.uInt64; \
77 x = (dt)m_value.dReal; \
90 NXSL_Value
::NXSL_Value()
92 m_nDataType
= NXSL_DT_NULL
;
94 m_bStringIsValid
= FALSE
;
97 NXSL_Value
::NXSL_Value(const NXSL_Value
*pValue
)
101 m_nDataType
= pValue
->m_nDataType
;
102 if (m_nDataType
== NXSL_DT_OBJECT
)
104 m_value
.pObject
= new NXSL_Object(pValue
->m_value
.pObject
);
106 else if (m_nDataType
== NXSL_DT_ARRAY
)
108 m_value
.pArray
= pValue
->m_value
.pArray
;
109 m_value
.pArray
->incRefCount();
113 memcpy(&m_value
, &pValue
->m_value
, sizeof(m_value
));
115 m_bStringIsValid
= pValue
->m_bStringIsValid
;
116 if (m_bStringIsValid
)
118 m_dwStrLen
= pValue
->m_dwStrLen
;
119 m_pszValStr
= (char *)nx_memdup(pValue
->m_pszValStr
, m_dwStrLen
+ 1);
128 m_nDataType
= NXSL_DT_NULL
;
133 NXSL_Value
::NXSL_Value(NXSL_Object
*pObject
)
135 m_nDataType
= NXSL_DT_OBJECT
;
136 m_value
.pObject
= pObject
;
138 m_bStringIsValid
= FALSE
;
141 NXSL_Value
::NXSL_Value(NXSL_Array
*pArray
)
143 m_nDataType
= NXSL_DT_ARRAY
;
144 m_value
.pArray
= pArray
;
145 pArray
->incRefCount();
147 m_bStringIsValid
= FALSE
;
150 NXSL_Value
::NXSL_Value(LONG nValue
)
152 m_nDataType
= NXSL_DT_INT32
;
154 m_bStringIsValid
= FALSE
;
155 m_value
.nInt32
= nValue
;
158 NXSL_Value
::NXSL_Value(DWORD uValue
)
160 m_nDataType
= NXSL_DT_UINT32
;
162 m_bStringIsValid
= FALSE
;
163 m_value
.uInt32
= uValue
;
166 NXSL_Value
::NXSL_Value(INT64 nValue
)
168 m_nDataType
= NXSL_DT_INT64
;
170 m_bStringIsValid
= FALSE
;
171 m_value
.nInt64
= nValue
;
174 NXSL_Value
::NXSL_Value(QWORD uValue
)
176 m_nDataType
= NXSL_DT_UINT64
;
178 m_bStringIsValid
= FALSE
;
179 m_value
.uInt64
= uValue
;
182 NXSL_Value
::NXSL_Value(double dValue
)
184 m_nDataType
= NXSL_DT_REAL
;
186 m_bStringIsValid
= FALSE
;
187 m_value
.dReal
= dValue
;
190 NXSL_Value
::NXSL_Value(const TCHAR
*pszValue
)
192 m_nDataType
= NXSL_DT_STRING
;
193 if (pszValue
!= NULL
)
195 m_dwStrLen
= (DWORD
)_tcslen(pszValue
);
196 m_pszValStr
= _tcsdup(pszValue
);
201 m_pszValStr
= _tcsdup(_T(""));
203 m_bStringIsValid
= TRUE
;
207 NXSL_Value
::NXSL_Value(const TCHAR
*pszValue
, DWORD dwLen
)
209 m_nDataType
= NXSL_DT_STRING
;
211 m_pszValStr
= (TCHAR
*)malloc((dwLen
+ 1) * sizeof(TCHAR
));
212 if (pszValue
!= NULL
)
214 memcpy(m_pszValStr
, pszValue
, dwLen
* sizeof(TCHAR
));
215 m_pszValStr
[dwLen
] = 0;
219 memset(m_pszValStr
, 0, (dwLen
+ 1) * sizeof(TCHAR
));
221 m_bStringIsValid
= TRUE
;
230 NXSL_Value
::~NXSL_Value()
232 safe_free(m_pszValStr
);
233 if (m_nDataType
== NXSL_DT_OBJECT
)
235 delete m_value
.pObject
;
237 else if (m_nDataType
== NXSL_DT_ARRAY
)
239 m_value
.pArray
->decRefCount();
240 if (m_value
.pArray
->isUnused())
241 delete m_value
.pArray
;
250 void NXSL_Value
::set(LONG nValue
)
252 m_nDataType
= NXSL_DT_INT32
;
253 safe_free(m_pszValStr
);
255 m_bStringIsValid
= FALSE
;
256 m_value
.nInt32
= nValue
;
261 // Update numeric value after string change
264 void NXSL_Value
::updateNumber()
270 nVal
= strtoll(m_pszValStr
, &eptr
, 0);
271 if ((*eptr
== 0) && ((DWORD
)(eptr
- m_pszValStr
) == m_dwStrLen
))
273 if (nVal
> 0x7FFFFFFF)
275 m_nDataType
= NXSL_DT_INT64
;
276 m_value
.nInt64
= nVal
;
280 m_nDataType
= NXSL_DT_INT32
;
281 m_value
.nInt32
= (LONG
)nVal
;
286 dVal
= strtod(m_pszValStr
, &eptr
);
287 if ((*eptr
== 0) && ((DWORD
)(eptr
- m_pszValStr
) == m_dwStrLen
))
289 m_nDataType
= NXSL_DT_REAL
;
290 m_value
.dReal
= dVal
;
297 // Update string value
300 void NXSL_Value
::updateString()
304 safe_free(m_pszValStr
);
308 sprintf(szBuffer
, "%d", m_value
.nInt32
);
311 sprintf(szBuffer
, "%u", m_value
.uInt32
);
314 sprintf(szBuffer
, INT64_FMT
, m_value
.nInt64
);
317 sprintf(szBuffer
, UINT64_FMT
, m_value
.uInt64
);
320 sprintf(szBuffer
, "%f", m_value
.dReal
);
326 m_dwStrLen
= (DWORD
)strlen(szBuffer
);
327 m_pszValStr
= strdup(szBuffer
);
328 m_bStringIsValid
= TRUE
;
333 // Convert to another data type
336 bool NXSL_Value
::convert(int nDataType
)
345 if (m_nDataType
== nDataType
)
348 if ((nDataType
== NXSL_DT_STRING
) && isString())
354 RETRIEVE_NUMERIC_VALUE(nInt32
, LONG
);
355 m_nDataType
= nDataType
;
356 m_value
.nInt32
= nInt32
;
359 RETRIEVE_NUMERIC_VALUE(uInt32
, DWORD
);
360 m_nDataType
= nDataType
;
361 m_value
.uInt32
= uInt32
;
364 RETRIEVE_NUMERIC_VALUE(nInt64
, INT64
);
365 m_nDataType
= nDataType
;
366 m_value
.nInt64
= nInt64
;
369 RETRIEVE_NUMERIC_VALUE(uInt64
, QWORD
);
370 m_nDataType
= nDataType
;
371 m_value
.uInt64
= uInt64
;
374 if (m_nDataType
== NXSL_DT_UINT64
)
380 dReal
= getValueAsReal();
381 m_nDataType
= nDataType
;
382 m_value
.dReal
= dReal
;
386 if (m_nDataType
== NXSL_DT_NULL
)
388 m_nDataType
= NXSL_DT_STRING
;
390 // String value will be invalidated on exit, and next
391 // call to updateString() will create empty string value
405 // Get value as ASCIIZ string
408 const TCHAR
*NXSL_Value
::getValueAsCString()
410 if (isNull() || isObject() || isArray())
413 if (!m_bStringIsValid
)
420 // Get value as string
423 const TCHAR
*NXSL_Value
::getValueAsString(DWORD
*pdwLen
)
425 if (isNull() || isObject() || isArray())
431 if (!m_bStringIsValid
)
433 *pdwLen
= m_dwStrLen
;
439 // Get value as 32 bit integer
442 LONG NXSL_Value
::getValueAsInt32()
446 RETRIEVE_NUMERIC_VALUE(nVal
, LONG
);
452 // Get value as unsigned 32 bit integer
455 DWORD NXSL_Value
::getValueAsUInt32()
459 RETRIEVE_NUMERIC_VALUE(uVal
, DWORD
);
465 // Get value as 64 bit integer
468 INT64 NXSL_Value
::getValueAsInt64()
472 RETRIEVE_NUMERIC_VALUE(nVal
, INT64
);
478 // Get value as unsigned 64 bit integer
481 QWORD NXSL_Value
::getValueAsUInt64()
485 RETRIEVE_NUMERIC_VALUE(uVal
, QWORD
);
491 // Get value as real number
494 double NXSL_Value
::getValueAsReal()
501 dVal
= (double)m_value
.nInt32
;
504 dVal
= (double)m_value
.uInt32
;
507 dVal
= (double)m_value
.nInt64
;
510 dVal
= (double)((INT64
)m_value
.uInt64
);
513 dVal
= m_value
.dReal
;
524 // Concatenate string value
527 void NXSL_Value
::concatenate(const TCHAR
*pszString
, DWORD dwLen
)
529 if (!m_bStringIsValid
)
531 m_pszValStr
= (char *)realloc(m_pszValStr
, m_dwStrLen
+ dwLen
+ 1);
532 memcpy(&m_pszValStr
[m_dwStrLen
], pszString
, dwLen
);
534 m_pszValStr
[m_dwStrLen
] = 0;
543 void NXSL_Value
::increment()
576 void NXSL_Value
::decrement()
609 void NXSL_Value
::negate()
616 m_value
.nInt32
= -m_value
.nInt32
;
619 m_value
.nInt32
= -((LONG
)m_value
.uInt32
);
620 m_nDataType
= NXSL_DT_INT32
;
623 m_value
.nInt64
= -m_value
.nInt64
;
626 m_value
.nInt64
= -((INT64
)m_value
.uInt64
);
627 m_nDataType
= NXSL_DT_INT64
;
630 m_value
.dReal
= -m_value
.dReal
;
644 void NXSL_Value
::bitNot()
651 m_value
.nInt32
= ~m_value
.nInt32
;
654 m_value
.nInt32
= ~m_value
.uInt32
;
657 m_value
.nInt64
= ~m_value
.nInt64
;
660 m_value
.nInt64
= ~m_value
.uInt64
;
671 // Check if value is zero
674 bool NXSL_Value
::isZero()
681 bVal
= (m_value
.nInt32
== 0);
684 bVal
= (m_value
.uInt32
== 0);
687 bVal
= (m_value
.nInt64
== 0);
690 bVal
= (m_value
.uInt64
== 0);
693 bVal
= (m_value
.dReal
== 0);
703 // Check if value is not a zero
706 bool NXSL_Value
::isNonZero()
713 bVal
= (m_value
.nInt32
!= 0);
716 bVal
= (m_value
.uInt32
!= 0);
719 bVal
= (m_value
.nInt64
!= 0);
722 bVal
= (m_value
.uInt64
!= 0);
725 bVal
= (m_value
.dReal
!= 0);
736 // All these functions assumes that both values have same type
739 BOOL NXSL_Value
::EQ(NXSL_Value
*pVal
)
746 bVal
= (m_value
.nInt32
== pVal
->m_value
.nInt32
);
749 bVal
= (m_value
.uInt32
== pVal
->m_value
.uInt32
);
752 bVal
= (m_value
.nInt64
== pVal
->m_value
.nInt64
);
755 bVal
= (m_value
.uInt64
== pVal
->m_value
.uInt64
);
758 bVal
= (m_value
.dReal
== pVal
->m_value
.dReal
);
766 BOOL NXSL_Value
::LT(NXSL_Value
*pVal
)
773 bVal
= (m_value
.nInt32
< pVal
->m_value
.nInt32
);
776 bVal
= (m_value
.uInt32
< pVal
->m_value
.uInt32
);
779 bVal
= (m_value
.nInt64
< pVal
->m_value
.nInt64
);
782 bVal
= (m_value
.uInt64
< pVal
->m_value
.uInt64
);
785 bVal
= (m_value
.dReal
< pVal
->m_value
.dReal
);
793 BOOL NXSL_Value
::LE(NXSL_Value
*pVal
)
800 bVal
= (m_value
.nInt32
<= pVal
->m_value
.nInt32
);
803 bVal
= (m_value
.uInt32
<= pVal
->m_value
.uInt32
);
806 bVal
= (m_value
.nInt64
<= pVal
->m_value
.nInt64
);
809 bVal
= (m_value
.uInt64
<= pVal
->m_value
.uInt64
);
812 bVal
= (m_value
.dReal
<= pVal
->m_value
.dReal
);
820 BOOL NXSL_Value
::GT(NXSL_Value
*pVal
)
827 bVal
= (m_value
.nInt32
> pVal
->m_value
.nInt32
);
830 bVal
= (m_value
.uInt32
> pVal
->m_value
.uInt32
);
833 bVal
= (m_value
.nInt64
> pVal
->m_value
.nInt64
);
836 bVal
= (m_value
.uInt64
> pVal
->m_value
.uInt64
);
839 bVal
= (m_value
.dReal
> pVal
->m_value
.dReal
);
847 BOOL NXSL_Value
::GE(NXSL_Value
*pVal
)
854 bVal
= (m_value
.nInt32
>= pVal
->m_value
.nInt32
);
857 bVal
= (m_value
.uInt32
>= pVal
->m_value
.uInt32
);
860 bVal
= (m_value
.nInt64
>= pVal
->m_value
.nInt64
);
863 bVal
= (m_value
.uInt64
>= pVal
->m_value
.uInt64
);
866 bVal
= (m_value
.dReal
>= pVal
->m_value
.dReal
);
876 // Arithmetic and bit operations
877 // All these functions assumes that both values have same type
880 void NXSL_Value
::add(NXSL_Value
*pVal
)
885 m_value
.nInt32
+= pVal
->m_value
.nInt32
;
888 m_value
.uInt32
+= pVal
->m_value
.uInt32
;
891 m_value
.nInt64
+= pVal
->m_value
.nInt64
;
894 m_value
.uInt64
+= pVal
->m_value
.uInt64
;
897 m_value
.dReal
+= pVal
->m_value
.dReal
;
905 void NXSL_Value
::sub(NXSL_Value
*pVal
)
910 m_value
.nInt32
-= pVal
->m_value
.nInt32
;
913 m_value
.uInt32
-= pVal
->m_value
.uInt32
;
916 m_value
.nInt64
-= pVal
->m_value
.nInt64
;
919 m_value
.uInt64
-= pVal
->m_value
.uInt64
;
922 m_value
.dReal
-= pVal
->m_value
.dReal
;
930 void NXSL_Value
::mul(NXSL_Value
*pVal
)
935 m_value
.nInt32
*= pVal
->m_value
.nInt32
;
938 m_value
.uInt32
*= pVal
->m_value
.uInt32
;
941 m_value
.nInt64
*= pVal
->m_value
.nInt64
;
944 m_value
.uInt64
*= pVal
->m_value
.uInt64
;
947 m_value
.dReal
*= pVal
->m_value
.dReal
;
955 void NXSL_Value
::div(NXSL_Value
*pVal
)
960 m_value
.nInt32
/= pVal
->m_value
.nInt32
;
963 m_value
.uInt32
/= pVal
->m_value
.uInt32
;
966 m_value
.nInt64
/= pVal
->m_value
.nInt64
;
969 m_value
.uInt64
/= pVal
->m_value
.uInt64
;
972 m_value
.dReal
/= pVal
->m_value
.dReal
;
980 void NXSL_Value
::rem(NXSL_Value
*pVal
)
985 m_value
.nInt32
%= pVal
->m_value
.nInt32
;
988 m_value
.uInt32
%= pVal
->m_value
.uInt32
;
991 m_value
.nInt64
%= pVal
->m_value
.nInt64
;
994 m_value
.uInt64
%= pVal
->m_value
.uInt64
;
1002 void NXSL_Value
::bitAnd(NXSL_Value
*pVal
)
1007 m_value
.nInt32
&= pVal
->m_value
.nInt32
;
1009 case NXSL_DT_UINT32
:
1010 m_value
.uInt32
&= pVal
->m_value
.uInt32
;
1013 m_value
.nInt64
&= pVal
->m_value
.nInt64
;
1015 case NXSL_DT_UINT64
:
1016 m_value
.uInt64
&= pVal
->m_value
.uInt64
;
1024 void NXSL_Value
::bitOr(NXSL_Value
*pVal
)
1029 m_value
.nInt32
|= pVal
->m_value
.nInt32
;
1031 case NXSL_DT_UINT32
:
1032 m_value
.uInt32
|= pVal
->m_value
.uInt32
;
1035 m_value
.nInt64
|= pVal
->m_value
.nInt64
;
1037 case NXSL_DT_UINT64
:
1038 m_value
.uInt64
|= pVal
->m_value
.uInt64
;
1046 void NXSL_Value
::bitXor(NXSL_Value
*pVal
)
1051 m_value
.nInt32
^= pVal
->m_value
.nInt32
;
1053 case NXSL_DT_UINT32
:
1054 m_value
.uInt32
^= pVal
->m_value
.uInt32
;
1057 m_value
.nInt64
^= pVal
->m_value
.nInt64
;
1059 case NXSL_DT_UINT64
:
1060 m_value
.uInt64
^= pVal
->m_value
.uInt64
;
1070 // Bit shift operations
1073 void NXSL_Value
::lshift(int nBits
)
1078 m_value
.nInt32
<<= nBits
;
1080 case NXSL_DT_UINT32
:
1081 m_value
.uInt32
<<= nBits
;
1084 m_value
.nInt64
<<= nBits
;
1086 case NXSL_DT_UINT64
:
1087 m_value
.uInt64
<<= nBits
;
1095 void NXSL_Value
::rshift(int nBits
)
1100 m_value
.nInt32
>>= nBits
;
1102 case NXSL_DT_UINT32
:
1103 m_value
.uInt32
>>= nBits
;
1106 m_value
.nInt64
>>= nBits
;
1108 case NXSL_DT_UINT64
:
1109 m_value
.uInt64
>>= nBits
;