881f073844b3f50aeaddaaa1be0a5cea8cf6148d
[public/netxms.git] / src / libnxsl / value.cpp
1 /*
2 ** NetXMS - Network Management System
3 ** NetXMS Scripting Language Interpreter
4 ** Copyright (C) 2005-2010 Victor Kirhenshtein
5 **
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.
10 **
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.
15 **
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.
19 **
20 ** File: value.cpp
21 **
22 **/
23
24 #include "libnxsl.h"
25
26
27 //
28 // Assign value to correct number field
29 //
30
31 #define ASSIGN_NUMERIC_VALUE(x) \
32 { \
33 switch(m_nDataType) \
34 { \
35 case NXSL_DT_INT32: \
36 m_value.nInt32 = (x); \
37 break; \
38 case NXSL_DT_UINT32: \
39 m_value.uInt32 = (x); \
40 break; \
41 case NXSL_DT_INT64: \
42 m_value.nInt64 = (x); \
43 break; \
44 case NXSL_DT_UINT64: \
45 m_value.uInt64 = (x); \
46 break; \
47 case NXSL_DT_REAL: \
48 m_value.dReal = (x); \
49 break; \
50 default: \
51 break; \
52 } \
53 }
54
55
56 //
57 // Retrieve correct number field
58 //
59
60 #define RETRIEVE_NUMERIC_VALUE(x, dt) \
61 { \
62 switch(m_nDataType) \
63 { \
64 case NXSL_DT_INT32: \
65 x = (dt)m_value.nInt32; \
66 break; \
67 case NXSL_DT_UINT32: \
68 x = (dt)m_value.uInt32; \
69 break; \
70 case NXSL_DT_INT64: \
71 x = (dt)m_value.nInt64; \
72 break; \
73 case NXSL_DT_UINT64: \
74 x = (dt)m_value.uInt64; \
75 break; \
76 case NXSL_DT_REAL: \
77 x = (dt)m_value.dReal; \
78 break; \
79 default: \
80 x = 0; \
81 break; \
82 } \
83 }
84
85
86 //
87 // Constructors
88 //
89
90 NXSL_Value::NXSL_Value()
91 {
92 m_nDataType = NXSL_DT_NULL;
93 m_pszValStr = NULL;
94 m_bStringIsValid = FALSE;
95 }
96
97 NXSL_Value::NXSL_Value(const NXSL_Value *pValue)
98 {
99 if (pValue != NULL)
100 {
101 m_nDataType = pValue->m_nDataType;
102 if (m_nDataType == NXSL_DT_OBJECT)
103 {
104 m_value.pObject = new NXSL_Object(pValue->m_value.pObject);
105 }
106 else if (m_nDataType == NXSL_DT_ARRAY)
107 {
108 m_value.pArray = pValue->m_value.pArray;
109 m_value.pArray->incRefCount();
110 }
111 else
112 {
113 memcpy(&m_value, &pValue->m_value, sizeof(m_value));
114 }
115 m_bStringIsValid = pValue->m_bStringIsValid;
116 if (m_bStringIsValid)
117 {
118 m_dwStrLen = pValue->m_dwStrLen;
119 m_pszValStr = (char *)nx_memdup(pValue->m_pszValStr, m_dwStrLen + 1);
120 }
121 else
122 {
123 m_pszValStr = NULL;
124 }
125 }
126 else
127 {
128 m_nDataType = NXSL_DT_NULL;
129 m_pszValStr = NULL;
130 }
131 }
132
133 NXSL_Value::NXSL_Value(NXSL_Object *pObject)
134 {
135 m_nDataType = NXSL_DT_OBJECT;
136 m_value.pObject = pObject;
137 m_pszValStr = NULL;
138 m_bStringIsValid = FALSE;
139 }
140
141 NXSL_Value::NXSL_Value(NXSL_Array *pArray)
142 {
143 m_nDataType = NXSL_DT_ARRAY;
144 m_value.pArray = pArray;
145 pArray->incRefCount();
146 m_pszValStr = NULL;
147 m_bStringIsValid = FALSE;
148 }
149
150 NXSL_Value::NXSL_Value(LONG nValue)
151 {
152 m_nDataType = NXSL_DT_INT32;
153 m_pszValStr = NULL;
154 m_bStringIsValid = FALSE;
155 m_value.nInt32 = nValue;
156 }
157
158 NXSL_Value::NXSL_Value(DWORD uValue)
159 {
160 m_nDataType = NXSL_DT_UINT32;
161 m_pszValStr = NULL;
162 m_bStringIsValid = FALSE;
163 m_value.uInt32 = uValue;
164 }
165
166 NXSL_Value::NXSL_Value(INT64 nValue)
167 {
168 m_nDataType = NXSL_DT_INT64;
169 m_pszValStr = NULL;
170 m_bStringIsValid = FALSE;
171 m_value.nInt64 = nValue;
172 }
173
174 NXSL_Value::NXSL_Value(QWORD uValue)
175 {
176 m_nDataType = NXSL_DT_UINT64;
177 m_pszValStr = NULL;
178 m_bStringIsValid = FALSE;
179 m_value.uInt64 = uValue;
180 }
181
182 NXSL_Value::NXSL_Value(double dValue)
183 {
184 m_nDataType = NXSL_DT_REAL;
185 m_pszValStr = NULL;
186 m_bStringIsValid = FALSE;
187 m_value.dReal = dValue;
188 }
189
190 NXSL_Value::NXSL_Value(const TCHAR *pszValue)
191 {
192 m_nDataType = NXSL_DT_STRING;
193 if (pszValue != NULL)
194 {
195 m_dwStrLen = (DWORD)_tcslen(pszValue);
196 m_pszValStr = _tcsdup(pszValue);
197 }
198 else
199 {
200 m_dwStrLen = 0;
201 m_pszValStr = _tcsdup(_T(""));
202 }
203 m_bStringIsValid = TRUE;
204 updateNumber();
205 }
206
207 NXSL_Value::NXSL_Value(const TCHAR *pszValue, DWORD dwLen)
208 {
209 m_nDataType = NXSL_DT_STRING;
210 m_dwStrLen = dwLen;
211 m_pszValStr = (TCHAR *)malloc((dwLen + 1) * sizeof(TCHAR));
212 if (pszValue != NULL)
213 {
214 memcpy(m_pszValStr, pszValue, dwLen * sizeof(TCHAR));
215 m_pszValStr[dwLen] = 0;
216 }
217 else
218 {
219 memset(m_pszValStr, 0, (dwLen + 1) * sizeof(TCHAR));
220 }
221 m_bStringIsValid = TRUE;
222 updateNumber();
223 }
224
225
226 //
227 // Destructor
228 //
229
230 NXSL_Value::~NXSL_Value()
231 {
232 safe_free(m_pszValStr);
233 if (m_nDataType == NXSL_DT_OBJECT)
234 {
235 delete m_value.pObject;
236 }
237 else if (m_nDataType == NXSL_DT_ARRAY)
238 {
239 m_value.pArray->decRefCount();
240 if (m_value.pArray->isUnused())
241 delete m_value.pArray;
242 }
243 }
244
245
246 //
247 // Set value
248 //
249
250 void NXSL_Value::set(LONG nValue)
251 {
252 m_nDataType = NXSL_DT_INT32;
253 safe_free(m_pszValStr);
254 m_pszValStr = NULL;
255 m_bStringIsValid = FALSE;
256 m_value.nInt32 = nValue;
257 }
258
259
260 //
261 // Update numeric value after string change
262 //
263
264 void NXSL_Value::updateNumber()
265 {
266 char *eptr;
267 INT64 nVal;
268 double dVal;
269
270 nVal = strtoll(m_pszValStr, &eptr, 0);
271 if ((*eptr == 0) && ((DWORD)(eptr - m_pszValStr) == m_dwStrLen))
272 {
273 if (nVal > 0x7FFFFFFF)
274 {
275 m_nDataType = NXSL_DT_INT64;
276 m_value.nInt64 = nVal;
277 }
278 else
279 {
280 m_nDataType = NXSL_DT_INT32;
281 m_value.nInt32 = (LONG)nVal;
282 }
283 }
284 else
285 {
286 dVal = strtod(m_pszValStr, &eptr);
287 if ((*eptr == 0) && ((DWORD)(eptr - m_pszValStr) == m_dwStrLen))
288 {
289 m_nDataType = NXSL_DT_REAL;
290 m_value.dReal = dVal;
291 }
292 }
293 }
294
295
296 //
297 // Update string value
298 //
299
300 void NXSL_Value::updateString()
301 {
302 char szBuffer[64];
303
304 safe_free(m_pszValStr);
305 switch(m_nDataType)
306 {
307 case NXSL_DT_INT32:
308 sprintf(szBuffer, "%d", m_value.nInt32);
309 break;
310 case NXSL_DT_UINT32:
311 sprintf(szBuffer, "%u", m_value.uInt32);
312 break;
313 case NXSL_DT_INT64:
314 sprintf(szBuffer, INT64_FMT, m_value.nInt64);
315 break;
316 case NXSL_DT_UINT64:
317 sprintf(szBuffer, UINT64_FMT, m_value.uInt64);
318 break;
319 case NXSL_DT_REAL:
320 sprintf(szBuffer, "%f", m_value.dReal);
321 break;
322 default:
323 szBuffer[0] = 0;
324 break;
325 }
326 m_dwStrLen = (DWORD)strlen(szBuffer);
327 m_pszValStr = strdup(szBuffer);
328 m_bStringIsValid = TRUE;
329 }
330
331
332 //
333 // Convert to another data type
334 //
335
336 bool NXSL_Value::convert(int nDataType)
337 {
338 LONG nInt32;
339 DWORD uInt32;
340 INT64 nInt64;
341 QWORD uInt64;
342 double dReal;
343 bool bRet = true;
344
345 if (m_nDataType == nDataType)
346 return true;
347
348 if ((nDataType == NXSL_DT_STRING) && isString())
349 return true;
350
351 switch(nDataType)
352 {
353 case NXSL_DT_INT32:
354 RETRIEVE_NUMERIC_VALUE(nInt32, LONG);
355 m_nDataType = nDataType;
356 m_value.nInt32 = nInt32;
357 break;
358 case NXSL_DT_UINT32:
359 RETRIEVE_NUMERIC_VALUE(uInt32, DWORD);
360 m_nDataType = nDataType;
361 m_value.uInt32 = uInt32;
362 break;
363 case NXSL_DT_INT64:
364 RETRIEVE_NUMERIC_VALUE(nInt64, INT64);
365 m_nDataType = nDataType;
366 m_value.nInt64 = nInt64;
367 break;
368 case NXSL_DT_UINT64:
369 RETRIEVE_NUMERIC_VALUE(uInt64, QWORD);
370 m_nDataType = nDataType;
371 m_value.uInt64 = uInt64;
372 break;
373 case NXSL_DT_REAL:
374 if (m_nDataType == NXSL_DT_UINT64)
375 {
376 bRet = false;
377 }
378 else
379 {
380 dReal = getValueAsReal();
381 m_nDataType = nDataType;
382 m_value.dReal = dReal;
383 }
384 break;
385 case NXSL_DT_STRING:
386 if (m_nDataType == NXSL_DT_NULL)
387 {
388 m_nDataType = NXSL_DT_STRING;
389 bRet = true;
390 // String value will be invalidated on exit, and next
391 // call to updateString() will create empty string value
392 }
393 break;
394 default:
395 bRet = false;
396 break;
397 }
398 if (bRet)
399 invalidateString();
400 return bRet;
401 }
402
403
404 //
405 // Get value as ASCIIZ string
406 //
407
408 const TCHAR *NXSL_Value::getValueAsCString()
409 {
410 if (isNull() || isObject() || isArray())
411 return NULL;
412
413 if (!m_bStringIsValid)
414 updateString();
415 return m_pszValStr;
416 }
417
418
419 //
420 // Get value as string
421 //
422
423 const TCHAR *NXSL_Value::getValueAsString(DWORD *pdwLen)
424 {
425 if (isNull() || isObject() || isArray())
426 {
427 *pdwLen = 0;
428 return NULL;
429 }
430
431 if (!m_bStringIsValid)
432 updateString();
433 *pdwLen = m_dwStrLen;
434 return m_pszValStr;
435 }
436
437
438 //
439 // Get value as 32 bit integer
440 //
441
442 LONG NXSL_Value::getValueAsInt32()
443 {
444 LONG nVal;
445
446 RETRIEVE_NUMERIC_VALUE(nVal, LONG);
447 return nVal;
448 }
449
450
451 //
452 // Get value as unsigned 32 bit integer
453 //
454
455 DWORD NXSL_Value::getValueAsUInt32()
456 {
457 DWORD uVal;
458
459 RETRIEVE_NUMERIC_VALUE(uVal, DWORD);
460 return uVal;
461 }
462
463
464 //
465 // Get value as 64 bit integer
466 //
467
468 INT64 NXSL_Value::getValueAsInt64()
469 {
470 INT64 nVal;
471
472 RETRIEVE_NUMERIC_VALUE(nVal, INT64);
473 return nVal;
474 }
475
476
477 //
478 // Get value as unsigned 64 bit integer
479 //
480
481 QWORD NXSL_Value::getValueAsUInt64()
482 {
483 QWORD uVal;
484
485 RETRIEVE_NUMERIC_VALUE(uVal, QWORD);
486 return uVal;
487 }
488
489
490 //
491 // Get value as real number
492 //
493
494 double NXSL_Value::getValueAsReal()
495 {
496 double dVal;
497
498 switch(m_nDataType)
499 {
500 case NXSL_DT_INT32:
501 dVal = (double)m_value.nInt32;
502 break;
503 case NXSL_DT_UINT32:
504 dVal = (double)m_value.uInt32;
505 break;
506 case NXSL_DT_INT64:
507 dVal = (double)m_value.nInt64;
508 break;
509 case NXSL_DT_UINT64:
510 dVal = (double)((INT64)m_value.uInt64);
511 break;
512 case NXSL_DT_REAL:
513 dVal = m_value.dReal;
514 break;
515 default:
516 dVal = 0;
517 break;
518 }
519 return dVal;
520 }
521
522
523 //
524 // Concatenate string value
525 //
526
527 void NXSL_Value::concatenate(const TCHAR *pszString, DWORD dwLen)
528 {
529 if (!m_bStringIsValid)
530 updateString();
531 m_pszValStr = (char *)realloc(m_pszValStr, m_dwStrLen + dwLen + 1);
532 memcpy(&m_pszValStr[m_dwStrLen], pszString, dwLen);
533 m_dwStrLen += dwLen;
534 m_pszValStr[m_dwStrLen] = 0;
535 updateNumber();
536 }
537
538
539 //
540 // Increment value
541 //
542
543 void NXSL_Value::increment()
544 {
545 if (isNumeric())
546 {
547 switch(m_nDataType)
548 {
549 case NXSL_DT_INT32:
550 m_value.nInt32++;
551 break;
552 case NXSL_DT_UINT32:
553 m_value.uInt32++;
554 break;
555 case NXSL_DT_INT64:
556 m_value.nInt64++;
557 break;
558 case NXSL_DT_UINT64:
559 m_value.uInt64++;
560 break;
561 case NXSL_DT_REAL:
562 m_value.dReal++;
563 break;
564 default:
565 break;
566 }
567 invalidateString();
568 }
569 }
570
571
572 //
573 // Decrement value
574 //
575
576 void NXSL_Value::decrement()
577 {
578 if (isNumeric())
579 {
580 switch(m_nDataType)
581 {
582 case NXSL_DT_INT32:
583 m_value.nInt32++;
584 break;
585 case NXSL_DT_UINT32:
586 m_value.uInt32++;
587 break;
588 case NXSL_DT_INT64:
589 m_value.nInt64++;
590 break;
591 case NXSL_DT_UINT64:
592 m_value.uInt64++;
593 break;
594 case NXSL_DT_REAL:
595 m_value.dReal++;
596 break;
597 default:
598 break;
599 }
600 invalidateString();
601 }
602 }
603
604
605 //
606 // Negate value
607 //
608
609 void NXSL_Value::negate()
610 {
611 if (isNumeric())
612 {
613 switch(m_nDataType)
614 {
615 case NXSL_DT_INT32:
616 m_value.nInt32 = -m_value.nInt32;
617 break;
618 case NXSL_DT_UINT32:
619 m_value.nInt32 = -((LONG)m_value.uInt32);
620 m_nDataType = NXSL_DT_INT32;
621 break;
622 case NXSL_DT_INT64:
623 m_value.nInt64 = -m_value.nInt64;
624 break;
625 case NXSL_DT_UINT64:
626 m_value.nInt64 = -((INT64)m_value.uInt64);
627 m_nDataType = NXSL_DT_INT64;
628 break;
629 case NXSL_DT_REAL:
630 m_value.dReal = -m_value.dReal;
631 break;
632 default:
633 break;
634 }
635 invalidateString();
636 }
637 }
638
639
640 //
641 // Bitwise NOT
642 //
643
644 void NXSL_Value::bitNot()
645 {
646 if (isNumeric())
647 {
648 switch(m_nDataType)
649 {
650 case NXSL_DT_INT32:
651 m_value.nInt32 = ~m_value.nInt32;
652 break;
653 case NXSL_DT_UINT32:
654 m_value.nInt32 = ~m_value.uInt32;
655 break;
656 case NXSL_DT_INT64:
657 m_value.nInt64 = ~m_value.nInt64;
658 break;
659 case NXSL_DT_UINT64:
660 m_value.nInt64 = ~m_value.uInt64;
661 break;
662 default:
663 break;
664 }
665 invalidateString();
666 }
667 }
668
669
670 //
671 // Check if value is zero
672 //
673
674 bool NXSL_Value::isZero()
675 {
676 bool bVal = false;
677
678 switch(m_nDataType)
679 {
680 case NXSL_DT_INT32:
681 bVal = (m_value.nInt32 == 0);
682 break;
683 case NXSL_DT_UINT32:
684 bVal = (m_value.uInt32 == 0);
685 break;
686 case NXSL_DT_INT64:
687 bVal = (m_value.nInt64 == 0);
688 break;
689 case NXSL_DT_UINT64:
690 bVal = (m_value.uInt64 == 0);
691 break;
692 case NXSL_DT_REAL:
693 bVal = (m_value.dReal == 0);
694 break;
695 default:
696 break;
697 }
698 return bVal;
699 }
700
701
702 //
703 // Check if value is not a zero
704 //
705
706 bool NXSL_Value::isNonZero()
707 {
708 bool bVal = false;
709
710 switch(m_nDataType)
711 {
712 case NXSL_DT_INT32:
713 bVal = (m_value.nInt32 != 0);
714 break;
715 case NXSL_DT_UINT32:
716 bVal = (m_value.uInt32 != 0);
717 break;
718 case NXSL_DT_INT64:
719 bVal = (m_value.nInt64 != 0);
720 break;
721 case NXSL_DT_UINT64:
722 bVal = (m_value.uInt64 != 0);
723 break;
724 case NXSL_DT_REAL:
725 bVal = (m_value.dReal != 0);
726 break;
727 default:
728 break;
729 }
730 return bVal;
731 }
732
733
734 //
735 // Compare value
736 // All these functions assumes that both values have same type
737 //
738
739 BOOL NXSL_Value::EQ(NXSL_Value *pVal)
740 {
741 BOOL bVal = FALSE;
742
743 switch(m_nDataType)
744 {
745 case NXSL_DT_INT32:
746 bVal = (m_value.nInt32 == pVal->m_value.nInt32);
747 break;
748 case NXSL_DT_UINT32:
749 bVal = (m_value.uInt32 == pVal->m_value.uInt32);
750 break;
751 case NXSL_DT_INT64:
752 bVal = (m_value.nInt64 == pVal->m_value.nInt64);
753 break;
754 case NXSL_DT_UINT64:
755 bVal = (m_value.uInt64 == pVal->m_value.uInt64);
756 break;
757 case NXSL_DT_REAL:
758 bVal = (m_value.dReal == pVal->m_value.dReal);
759 break;
760 default:
761 break;
762 }
763 return bVal;
764 }
765
766 BOOL NXSL_Value::LT(NXSL_Value *pVal)
767 {
768 BOOL bVal = FALSE;
769
770 switch(m_nDataType)
771 {
772 case NXSL_DT_INT32:
773 bVal = (m_value.nInt32 < pVal->m_value.nInt32);
774 break;
775 case NXSL_DT_UINT32:
776 bVal = (m_value.uInt32 < pVal->m_value.uInt32);
777 break;
778 case NXSL_DT_INT64:
779 bVal = (m_value.nInt64 < pVal->m_value.nInt64);
780 break;
781 case NXSL_DT_UINT64:
782 bVal = (m_value.uInt64 < pVal->m_value.uInt64);
783 break;
784 case NXSL_DT_REAL:
785 bVal = (m_value.dReal < pVal->m_value.dReal);
786 break;
787 default:
788 break;
789 }
790 return bVal;
791 }
792
793 BOOL NXSL_Value::LE(NXSL_Value *pVal)
794 {
795 BOOL bVal = FALSE;
796
797 switch(m_nDataType)
798 {
799 case NXSL_DT_INT32:
800 bVal = (m_value.nInt32 <= pVal->m_value.nInt32);
801 break;
802 case NXSL_DT_UINT32:
803 bVal = (m_value.uInt32 <= pVal->m_value.uInt32);
804 break;
805 case NXSL_DT_INT64:
806 bVal = (m_value.nInt64 <= pVal->m_value.nInt64);
807 break;
808 case NXSL_DT_UINT64:
809 bVal = (m_value.uInt64 <= pVal->m_value.uInt64);
810 break;
811 case NXSL_DT_REAL:
812 bVal = (m_value.dReal <= pVal->m_value.dReal);
813 break;
814 default:
815 break;
816 }
817 return bVal;
818 }
819
820 BOOL NXSL_Value::GT(NXSL_Value *pVal)
821 {
822 BOOL bVal = FALSE;
823
824 switch(m_nDataType)
825 {
826 case NXSL_DT_INT32:
827 bVal = (m_value.nInt32 > pVal->m_value.nInt32);
828 break;
829 case NXSL_DT_UINT32:
830 bVal = (m_value.uInt32 > pVal->m_value.uInt32);
831 break;
832 case NXSL_DT_INT64:
833 bVal = (m_value.nInt64 > pVal->m_value.nInt64);
834 break;
835 case NXSL_DT_UINT64:
836 bVal = (m_value.uInt64 > pVal->m_value.uInt64);
837 break;
838 case NXSL_DT_REAL:
839 bVal = (m_value.dReal > pVal->m_value.dReal);
840 break;
841 default:
842 break;
843 }
844 return bVal;
845 }
846
847 BOOL NXSL_Value::GE(NXSL_Value *pVal)
848 {
849 BOOL bVal = FALSE;
850
851 switch(m_nDataType)
852 {
853 case NXSL_DT_INT32:
854 bVal = (m_value.nInt32 >= pVal->m_value.nInt32);
855 break;
856 case NXSL_DT_UINT32:
857 bVal = (m_value.uInt32 >= pVal->m_value.uInt32);
858 break;
859 case NXSL_DT_INT64:
860 bVal = (m_value.nInt64 >= pVal->m_value.nInt64);
861 break;
862 case NXSL_DT_UINT64:
863 bVal = (m_value.uInt64 >= pVal->m_value.uInt64);
864 break;
865 case NXSL_DT_REAL:
866 bVal = (m_value.dReal >= pVal->m_value.dReal);
867 break;
868 default:
869 break;
870 }
871 return bVal;
872 }
873
874
875 //
876 // Arithmetic and bit operations
877 // All these functions assumes that both values have same type
878 //
879
880 void NXSL_Value::add(NXSL_Value *pVal)
881 {
882 switch(m_nDataType)
883 {
884 case NXSL_DT_INT32:
885 m_value.nInt32 += pVal->m_value.nInt32;
886 break;
887 case NXSL_DT_UINT32:
888 m_value.uInt32 += pVal->m_value.uInt32;
889 break;
890 case NXSL_DT_INT64:
891 m_value.nInt64 += pVal->m_value.nInt64;
892 break;
893 case NXSL_DT_UINT64:
894 m_value.uInt64 += pVal->m_value.uInt64;
895 break;
896 case NXSL_DT_REAL:
897 m_value.dReal += pVal->m_value.dReal;
898 break;
899 default:
900 break;
901 }
902 invalidateString();
903 }
904
905 void NXSL_Value::sub(NXSL_Value *pVal)
906 {
907 switch(m_nDataType)
908 {
909 case NXSL_DT_INT32:
910 m_value.nInt32 -= pVal->m_value.nInt32;
911 break;
912 case NXSL_DT_UINT32:
913 m_value.uInt32 -= pVal->m_value.uInt32;
914 break;
915 case NXSL_DT_INT64:
916 m_value.nInt64 -= pVal->m_value.nInt64;
917 break;
918 case NXSL_DT_UINT64:
919 m_value.uInt64 -= pVal->m_value.uInt64;
920 break;
921 case NXSL_DT_REAL:
922 m_value.dReal -= pVal->m_value.dReal;
923 break;
924 default:
925 break;
926 }
927 invalidateString();
928 }
929
930 void NXSL_Value::mul(NXSL_Value *pVal)
931 {
932 switch(m_nDataType)
933 {
934 case NXSL_DT_INT32:
935 m_value.nInt32 *= pVal->m_value.nInt32;
936 break;
937 case NXSL_DT_UINT32:
938 m_value.uInt32 *= pVal->m_value.uInt32;
939 break;
940 case NXSL_DT_INT64:
941 m_value.nInt64 *= pVal->m_value.nInt64;
942 break;
943 case NXSL_DT_UINT64:
944 m_value.uInt64 *= pVal->m_value.uInt64;
945 break;
946 case NXSL_DT_REAL:
947 m_value.dReal *= pVal->m_value.dReal;
948 break;
949 default:
950 break;
951 }
952 invalidateString();
953 }
954
955 void NXSL_Value::div(NXSL_Value *pVal)
956 {
957 switch(m_nDataType)
958 {
959 case NXSL_DT_INT32:
960 m_value.nInt32 /= pVal->m_value.nInt32;
961 break;
962 case NXSL_DT_UINT32:
963 m_value.uInt32 /= pVal->m_value.uInt32;
964 break;
965 case NXSL_DT_INT64:
966 m_value.nInt64 /= pVal->m_value.nInt64;
967 break;
968 case NXSL_DT_UINT64:
969 m_value.uInt64 /= pVal->m_value.uInt64;
970 break;
971 case NXSL_DT_REAL:
972 m_value.dReal /= pVal->m_value.dReal;
973 break;
974 default:
975 break;
976 }
977 invalidateString();
978 }
979
980 void NXSL_Value::rem(NXSL_Value *pVal)
981 {
982 switch(m_nDataType)
983 {
984 case NXSL_DT_INT32:
985 m_value.nInt32 %= pVal->m_value.nInt32;
986 break;
987 case NXSL_DT_UINT32:
988 m_value.uInt32 %= pVal->m_value.uInt32;
989 break;
990 case NXSL_DT_INT64:
991 m_value.nInt64 %= pVal->m_value.nInt64;
992 break;
993 case NXSL_DT_UINT64:
994 m_value.uInt64 %= pVal->m_value.uInt64;
995 break;
996 default:
997 break;
998 }
999 invalidateString();
1000 }
1001
1002 void NXSL_Value::bitAnd(NXSL_Value *pVal)
1003 {
1004 switch(m_nDataType)
1005 {
1006 case NXSL_DT_INT32:
1007 m_value.nInt32 &= pVal->m_value.nInt32;
1008 break;
1009 case NXSL_DT_UINT32:
1010 m_value.uInt32 &= pVal->m_value.uInt32;
1011 break;
1012 case NXSL_DT_INT64:
1013 m_value.nInt64 &= pVal->m_value.nInt64;
1014 break;
1015 case NXSL_DT_UINT64:
1016 m_value.uInt64 &= pVal->m_value.uInt64;
1017 break;
1018 default:
1019 break;
1020 }
1021 invalidateString();
1022 }
1023
1024 void NXSL_Value::bitOr(NXSL_Value *pVal)
1025 {
1026 switch(m_nDataType)
1027 {
1028 case NXSL_DT_INT32:
1029 m_value.nInt32 |= pVal->m_value.nInt32;
1030 break;
1031 case NXSL_DT_UINT32:
1032 m_value.uInt32 |= pVal->m_value.uInt32;
1033 break;
1034 case NXSL_DT_INT64:
1035 m_value.nInt64 |= pVal->m_value.nInt64;
1036 break;
1037 case NXSL_DT_UINT64:
1038 m_value.uInt64 |= pVal->m_value.uInt64;
1039 break;
1040 default:
1041 break;
1042 }
1043 invalidateString();
1044 }
1045
1046 void NXSL_Value::bitXor(NXSL_Value *pVal)
1047 {
1048 switch(m_nDataType)
1049 {
1050 case NXSL_DT_INT32:
1051 m_value.nInt32 ^= pVal->m_value.nInt32;
1052 break;
1053 case NXSL_DT_UINT32:
1054 m_value.uInt32 ^= pVal->m_value.uInt32;
1055 break;
1056 case NXSL_DT_INT64:
1057 m_value.nInt64 ^= pVal->m_value.nInt64;
1058 break;
1059 case NXSL_DT_UINT64:
1060 m_value.uInt64 ^= pVal->m_value.uInt64;
1061 break;
1062 default:
1063 break;
1064 }
1065 invalidateString();
1066 }
1067
1068
1069 //
1070 // Bit shift operations
1071 //
1072
1073 void NXSL_Value::lshift(int nBits)
1074 {
1075 switch(m_nDataType)
1076 {
1077 case NXSL_DT_INT32:
1078 m_value.nInt32 <<= nBits;
1079 break;
1080 case NXSL_DT_UINT32:
1081 m_value.uInt32 <<= nBits;
1082 break;
1083 case NXSL_DT_INT64:
1084 m_value.nInt64 <<= nBits;
1085 break;
1086 case NXSL_DT_UINT64:
1087 m_value.uInt64 <<= nBits;
1088 break;
1089 default:
1090 break;
1091 }
1092 invalidateString();
1093 }
1094
1095 void NXSL_Value::rshift(int nBits)
1096 {
1097 switch(m_nDataType)
1098 {
1099 case NXSL_DT_INT32:
1100 m_value.nInt32 >>= nBits;
1101 break;
1102 case NXSL_DT_UINT32:
1103 m_value.uInt32 >>= nBits;
1104 break;
1105 case NXSL_DT_INT64:
1106 m_value.nInt64 >>= nBits;
1107 break;
1108 case NXSL_DT_UINT64:
1109 m_value.uInt64 >>= nBits;
1110 break;
1111 default:
1112 break;
1113 }
1114 invalidateString();
1115 }