Tiberian Technologies Scripts Reference Revision: 9000
Loading...
Searching...
No Matches
datasafe.h
1/* Renegade Scripts.dll
2 Copyright 2013 Tiberian Technologies
3
4 This file is part of the Renegade scripts.dll
5 The Renegade scripts.dll is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free
7 Software Foundation; either version 2, or (at your option) any later
8 version. See the file COPYING for more details.
9 In addition, an exemption is given to allow Run Time Dynamic Linking of this code with any closed source module that does not contain code covered by this licence.
10 Only the source code to the module(s) containing the licenced code has to be released.
11*/
12#ifndef TT_INCLUDE_DATASAFE_H
13#define TT_INCLUDE_DATASAFE_H
14#include "SysTimeClass.h"
15#if (PARAM_EDITING_ON) || (DDBEDIT) || (W3DVIEWER)
16#define safe_int int
17#define safe_unsigned_int unsigned int
18#define safe_long long
19#define safe_unsigned_long unsigned long
20#define safe_float float
21#define safe_double double
22#else //PARAM_EDITING_ON
23#define safe_int SafeDataClass<int>
24#define safe_unsigned_int SafeDataClass<unsigned int>
25#define safe_long SafeDataClass<int>
26#define safe_unsigned_long SafeDataClass<unsigned int>
27#define safe_float SafeDataClass<float>
28#define safe_double SafeDataClass<double>
29#define MAX_ENTRIES_PER_LIST 16
30#define MAX_DATASAFE_LISTS 8192
31#define MAX_DATASAFE_TYPES 128
32#define MAX_OBJECT_COPIES 8
33#define DATASAFE_TIME_CHECK_CALLS 100000
34#define TICKS_PER_SECOND 1000
35#define SECURITY_CHECK_TIME (TICKS_PER_SECOND * 15)
36#define SENTINEL_ONE 0x29874362
37#define SENTINEL_TWO 0x0bad0bad
38template <typename T, int size> class RefArray
39{
40protected:
41 char _dummy[size * sizeof(T)];
42public:
43 operator T* ()
44 {
45 return (T*) this;
46 };
47 operator const T* () const
48 {
49 return (T*) this;
50 };
51 T* operator & ()
52 {
53 return (T*) this;
54 };
55 const T* operator & () const
56 {
57 return (T*) this;
58 };
59};
60class DataSafeHandleClass
61{
62public:
63 DataSafeHandleClass(int val = 0)
64 {
65 Handle.Whole.WholeHandle = val;
66 }
67 bool Is_Valid(void) const
68 {
69 return Handle.Whole.WholeHandle != -1;
70 }
71 inline int operator =(const int &val)
72 {
73 Handle.Whole.WholeHandle = val;
74 return val;
75 }
76 inline operator int(void)
77 {
78 return Handle.Whole.WholeHandle;
79 }
80 inline operator int(void) const
81 {
82 return Handle.Whole.WholeHandle;
83 }
84 inline int &operator() (void)
85 {
86 return Handle.Whole.WholeHandle;
87 }
88 union tHandle
89 {
90 struct
91 {
92 int WholeHandle;
93 } Whole;
94 struct
95 {
96 unsigned char ID;
97 unsigned char Type;
98 unsigned short List;
99 } Part;
100 } Handle;
101};
102
103#pragma pack(push)
104#pragma pack(4)
105class DataSafeEntryClass
106{
107public:
108 DataSafeHandleClass Handle;
109 DataSafeEntryClass *Next;
110 DataSafeEntryClass *Prev;
111 unsigned long Size;
112 bool IsSlop;
113};
114
115template<class T>
116class DataSafeEntryDataClass : public DataSafeEntryClass
117{
118public:
119 T Data;
120};
121
122#pragma pack(pop)
123class DataSafeEntryListClass
124{
125public:
126 DataSafeEntryListClass(void)
127 {
128 SafeList = NULL;
129 EntryCount = 0;
130 EntryType = -1;
131 SlopCount = 0;
132 memset(HandleIDUsage, 0, sizeof(HandleIDUsage));
133 };
134 DataSafeEntryClass *SafeList;
135 int EntryCount;
136 int EntryType;
137 int SlopCount;
138 char HandleIDUsage[MAX_ENTRIES_PER_LIST];
139};
140
141class DataSafeEntryTypeClass
142{
143public:
144 DataSafeEntryTypeClass(void)
145 {
146 TypeCode = 0;
147 ID = -1;
148 Size = 0;
149 };
150 unsigned long TypeCode;
151 int ID;
152 int Size;
153};
154
155class GenericDataSafeClass
156{
157public:
158 GenericDataSafeClass(void);
159 SCRIPTS_API static DataSafeEntryClass *Get_Entry(DataSafeHandleClass handle);
160 SCRIPTS_API static int Get_Entry_Type(DataSafeHandleClass handle);
161 SCRIPTS_API static void Reset_Timers(void);
162 SCRIPTS_API static void Dump_Safe_Stats(char *dump_buffer, int buffer_size);
163 SCRIPTS_API static void Print_Safe_Stats_To_Debug_Output(void);
164 SCRIPTS_API static void Reset(void);
165 static void Set_Preferred_Thread(unsigned int thread_id) {PreferredThread = thread_id;};
166protected:
167 SCRIPTS_API void Shutdown(void);
168 SCRIPTS_API static DataSafeEntryClass *Get_Entry_By_Index(int list, int index);
169 SCRIPTS_API static void Shuffle(bool forced = false);
170 SCRIPTS_API static void Swap_Entries(DataSafeEntryClass *first, DataSafeEntryClass *second, int type);
171 SCRIPTS_API static void Encrypt(void *data, int size, unsigned long key = SimpleKey, bool do_checksum = true);
172 SCRIPTS_API static void Decrypt(void *data, int size, unsigned long key = SimpleKey, bool do_checksum = true);
173 SCRIPTS_API static void Mem_Copy_Encrypt(void *dest, void *src, int size, bool do_checksum);
174 SCRIPTS_API static void Mem_Copy_Decrypt(void *dest, void *src, int size, bool do_checksum);
175 static __forceinline void Security_Check(void);
176 static __forceinline void Security_Fault(void);
177 SCRIPTS_API static void Say_Security_Fault(void);
178 SCRIPTS_API static int Get_Random_List_For_Insertion(int type);
179 SCRIPTS_API static void Random_Insertion(DataSafeEntryClass *entry, int list, int type, bool is_slop = false);
180 SCRIPTS_API static int Create_Safe_List(int type);
181 SCRIPTS_API static int Get_Handle_ID(int list);
182 SCRIPTS_API static void Remove_From_List(int list, DataSafeEntryClass *entry_ptr);
183 SCRIPTS_API static void Free_Handle_ID(int list, int id);
184 static inline int Get_Type_Size(int type);
185 SCRIPTS_API static REF_DECL(unsigned int, PreferredThread);
186 SCRIPTS_API static REF_DECL(unsigned long, SimpleKey);
187 SCRIPTS_API static REF_DECL(unsigned long, HandleKey);
188 SCRIPTS_API static REF_DECL(int, NumLists);
189 SCRIPTS_API static REF_DECL(TT_NOOP(RefArray<DataSafeEntryListClass *, MAX_DATASAFE_LISTS>), Safe);
190 SCRIPTS_API static REF_DECL(unsigned long, Checksum);
191 SCRIPTS_API static REF_DECL(unsigned long, ShuffleDelay);
192 SCRIPTS_API static REF_DECL(unsigned long, SecurityCheckDelay);
193 SCRIPTS_API static REF_DECL(TT_NOOP(RefArray<DataSafeEntryTypeClass, MAX_DATASAFE_TYPES>), TypeList);
194 SCRIPTS_API static REF_DECL(int, TypeListCount);
195 SCRIPTS_API static REF_DECL(DataSafeHandleClass, SentinelOne);
196 SCRIPTS_API static REF_DECL(DataSafeHandleClass, SentinelTwo);
197 SCRIPTS_API static REF_DECL(int, CRCErrors);
198};
199
200template<class T>
201class DataSafeClass : public GenericDataSafeClass
202{
203public:
204 DataSafeClass(T *bogus_ptr = NULL, int slopcount = 3);
205 ~DataSafeClass(void);
206 static bool Get(DataSafeHandleClass handle, T* &item);
207 static inline bool In_Return_List(T *ptr)
208 {
209 if (ptr)
210 {
211 void *temp = (void*)ptr;
212 if (temp >= &(ReturnList[0][0]) && temp < &(ReturnList[MAX_OBJECT_COPIES][0])) {
213 if (((unsigned long) temp - (unsigned long)(&(ReturnList[0][0]))) % sizeof(T) == 0)
214 {
215 return true;
216 }
217 }
218 }
219 return false;
220 };
221 static bool Set(DataSafeHandleClass handle, T *data);
222 static DataSafeHandleClass Add_Entry(T &value, bool is_slop = false);
223 static void Delete_Entry(DataSafeHandleClass handle);
224private:
225 static int Get_Type_ID(unsigned long type_code, int size);
226 static unsigned long Get_Type_Code(void);
227 SCRIPTS_API static REF_DECL(int, Type);
228 SCRIPTS_API static REF_DECL(int, MinSlop);
229 SCRIPTS_API static REF_DECL(TT_NOOP(RefArray<RefArray<char, sizeof(T)>, MAX_OBJECT_COPIES>), ReturnList);
230 SCRIPTS_API static REF_DECL(int, ReturnIndex);
231};
232
233extern char ErrorVal[1024];
234template<class T>
235class SafeDataClass
236{
237public:
238 SafeDataClass(void);
239 SafeDataClass(T data);
240 ~SafeDataClass(void);
241 SafeDataClass(SafeDataClass &)
242 {
243 TT_ASSERT(false);
244 };
245 inline T* Get_Ptr(void) const;
246 inline bool Commit(T* data_ptr) const;
247 inline T &operator() (void) const;
248 inline T &operator = (T const &data);
249 inline T &operator = (SafeDataClass<T> &safedata);
250 inline operator T() const;
251 inline bool operator == (T const &data);
252 inline bool operator == (SafeDataClass<T> &safedata);
253 inline bool operator != (T const &data);
254 inline bool operator != (SafeDataClass<T> &safedata);
255 inline bool operator > (T const &data);
256 inline bool operator > (SafeDataClass<T> &safedata);
257 inline bool operator >= (T const &data);
258 inline bool operator >= (SafeDataClass<T> &safedata);
259 inline bool operator < (T const &data);
260 inline bool operator < (SafeDataClass<T> &safedata);
261 inline bool operator <= (T const &data);
262 inline bool operator <= (SafeDataClass<T> &safedata);
263 inline T &operator + (T const &data);
264 inline T &operator + (SafeDataClass<T> &safedata);
265 inline T &operator += (T const &data);
266 inline T &operator += (SafeDataClass<T> &safedata);
267 inline T &operator - (T const &data);
268 inline T &operator - (SafeDataClass<T> &safedata);
269 inline T &operator -= (T const &data);
270 inline T &operator -= (SafeDataClass<T> &safedata);
271 inline T &operator * (T const &data);
272 inline T &operator * (SafeDataClass<T> &safedata);
273 inline T &operator *= (T const &data);
274 inline T &operator *= (SafeDataClass<T> &safedata);
275 inline T &operator / (T const &data);
276 inline T &operator / (SafeDataClass<T> &safedata);
277 inline T &operator /= (T const &data);
278 inline T &operator /= (SafeDataClass<T> &safedata);
279 inline T &operator ++ (void);
280 inline T &operator -- (void);
281 inline T &operator ++ (int);
282 inline T &operator -- (int);
283 DataSafeHandleClass Get_Handle(void)
284 {
285 return(Handle);
286 }
287 T Get(void);
288 void Set(T);
289private:
290 DataSafeHandleClass Handle;
291};
292
293inline int GenericDataSafeClass::Get_Type_Size(int type)
294{
295 return TypeList[type].Size;
296}
297
298__forceinline void GenericDataSafeClass::Security_Fault(void)
299{
300 CRCErrors++;
301 Say_Security_Fault();
302}
303
304__forceinline void GenericDataSafeClass::Security_Check(void)
305{
306 static bool _checking = false;
307 static unsigned long _calls = 0;
308 _calls++;
309 if (_calls < DATASAFE_TIME_CHECK_CALLS)
310 {
311 return;
312 }
313 _calls = 0;
314 if (HandleKey - SimpleKey == HandleKey)
315 {
316 Security_Fault();
317 }
318 if (SimpleKey - HandleKey == SimpleKey)
319 {
320 Security_Fault();
321 }
322 unsigned long time = TIMEGETTIME();
323 if (time < SecurityCheckDelay || (time | SecurityCheckDelay) == 0 || (time - SecurityCheckDelay) > SECURITY_CHECK_TIME)
324 {
325 if (!_checking)
326 {
327 _checking = true;
328 SecurityCheckDelay = time;
329 unsigned long checkey = ~SimpleKey;
330 for (int i=0 ; i<NumLists ; i++)
331 {
332 if (Safe[i] != NULL && Safe[i]->EntryCount > 0)
333 {
334 DataSafeEntryClass *entry_ptr = Safe[i]->SafeList;
335 unsigned long *data = NULL;
336 int data_size = entry_ptr->Size;
337 data_size = data_size >> 2;
338 if (entry_ptr)
339 {
340 for (int j=0 ; j<Safe[i]->EntryCount ; j++)
341 {
342 checkey ^= entry_ptr->Handle;
343 data = (unsigned long *) (((char*)entry_ptr) + sizeof(*entry_ptr));
344 for (int z=0 ; z<data_size ; z++)
345 {
346 checkey ^= *data++;
347 }
348 entry_ptr = entry_ptr->Next;
349 }
350 }
351 }
352 }
353 if (checkey != Checksum)
354 {
355 Security_Fault();
356 }
357 if (NumLists)
358 {
359 int *val = NULL;
360 if ((int)SentinelOne != 0)
361 {
362 bool got = DataSafeClass<int>::Get(SentinelOne, val);
363 if (!got || val == NULL || *val != SENTINEL_ONE)
364 {
365 Security_Fault();
366 }
367 }
368 val = NULL;
369 if ((int)SentinelTwo != 0)
370 {
371 bool got = DataSafeClass<int>::Get(SentinelTwo, val);
372 if (!got || val == NULL || *val != SENTINEL_TWO)
373 {
374 Security_Fault();
375 }
376 }
377 }
378 _checking = false;
379 }
380 }
381}
382
383template <class T>
384DataSafeClass<T>::DataSafeClass(T*, int slopcount)
385{
386 memset(ReturnList, 0, MAX_OBJECT_COPIES * sizeof(T));
387 ReturnIndex = 0;
388 int data_size = sizeof(T);
389 int type_code = Get_Type_Code();
390 int id = Get_Type_ID(type_code, data_size);
391 Type = id;
392 MinSlop = slopcount;
393 for (int i=0 ; i<slopcount ; i++)
394 {
395#pragma warning(suppress: 6255) // _alloca indicates failure by raising a stack overflow exception
396#pragma warning(suppress: 6263) // warning c6263: Using alloca in a loop
397 void *stackmem = _alloca(sizeof(T));
398 T *slop_ptr = new (stackmem) T;
399 Add_Entry(*slop_ptr, true);
400 }
401}
402
403template <class T>
404DataSafeClass<T>::~DataSafeClass(void)
405{
406 for (int i=0 ; i<NumLists ; i++)
407 {
408 if (Safe[i] != NULL && Safe[i]->EntryType == Type && Safe[i]->EntryCount > 0)
409 {
410 while (Safe[i]->EntryCount > 0)
411 {
412 int entries = Safe[i]->EntryCount;
413 DataSafeHandleClass handle = Safe[i]->SafeList->Handle ^ SimpleKey;
414 handle = handle ^ HandleKey;
415 Delete_Entry(handle);
416 if (entries != Safe[i]->EntryCount+1)
417 {
418 break;
419 }
420 }
421 }
422 }
423 Shutdown();
424}
425
426template <class T>
427unsigned long DataSafeClass<T>::Get_Type_Code(void)
428{
429 static int dummy;
430 return (unsigned long)&dummy;
431}
432
433template <class T>
434int DataSafeClass<T>::Get_Type_ID(unsigned long type_code, int size)
435{
436 int id = 0;
437 for (int i=0 ; i<TypeListCount ; i++)
438 {
439 if (TypeList[i].TypeCode == type_code)
440 {
441 return(TypeList[i].ID);
442 }
443 }
444 if (TypeListCount < MAX_DATASAFE_TYPES)
445 {
446 TypeList[TypeListCount].TypeCode = type_code;
447 TypeList[TypeListCount].ID = TypeListCount;
448 TypeList[TypeListCount].Size = size;
449 id = TypeListCount++;
450 }
451 return id;
452}
453
454template <class T>
455DataSafeHandleClass DataSafeClass<T>::Add_Entry(T &value, bool is_slop)
456{
457 Security_Check();
458 DataSafeEntryClass *entry_ptr = (DataSafeEntryClass*) (new char [sizeof(DataSafeEntryDataClass<T>)]);
459 if (entry_ptr)
460 {
461 entry_ptr->Next = NULL;
462 entry_ptr->Prev = NULL;
463 entry_ptr->Size = sizeof(value);
464 entry_ptr->IsSlop = is_slop;
465 DataSafeEntryDataClass<T>* data_ptr = (DataSafeEntryDataClass<T>*) entry_ptr;
466 Mem_Copy_Encrypt(& data_ptr->Data, &value, sizeof(value), true);
467 int list = Get_Random_List_For_Insertion(Type);
468 if (list != -1 && Safe[list] != NULL)
469 {
470 int index = Get_Handle_ID(list);
471 DataSafeHandleClass handle;
472 handle.Handle.Part.List = (unsigned short)list;
473 handle.Handle.Part.ID = (unsigned char)index;
474 handle.Handle.Part.Type = (unsigned char)Type;
475 DataSafeHandleClass encrypted_handle = handle ^ SimpleKey;
476 Checksum = Checksum ^ encrypted_handle;
477 entry_ptr->Handle = encrypted_handle;
478 Random_Insertion(entry_ptr, list, Type, is_slop);
479 if (Safe[list]->EntryCount == 1 && !is_slop)
480 {
481 for (int i=0 ; i<MinSlop ; i++)
482 {
483 entry_ptr = (DataSafeEntryClass*) (new char [sizeof(DataSafeEntryDataClass<T>)]);
484 if (entry_ptr)
485 {
486 entry_ptr->Next = NULL;
487 entry_ptr->Prev = NULL;
488 entry_ptr->Size = sizeof(T);
489 entry_ptr->IsSlop = true;
490 Encrypt(&((DataSafeEntryDataClass<T>*)entry_ptr)->Data, sizeof(T), SimpleKey, true);
491 DataSafeHandleClass slop_handle;
492 slop_handle.Handle.Part.ID = (unsigned char)Get_Handle_ID(list);
493 slop_handle.Handle.Part.List = (unsigned short)list;
494 slop_handle.Handle.Part.Type = (unsigned char)Type;
495 DataSafeHandleClass encrypted_slop_handle = slop_handle ^ SimpleKey;
496 Checksum = Checksum ^ encrypted_slop_handle;
497 entry_ptr->Handle = encrypted_slop_handle;
498 Random_Insertion(entry_ptr, list, Type, true);
499 }
500 }
501 }
502 if (Safe[list]->SlopCount != 0 && Safe[list]->EntryCount > Safe[list]->SlopCount * 2 && !is_slop)
503 {
504 entry_ptr = Safe[list]->SafeList;
505 DataSafeHandleClass removal_list[MAX_ENTRIES_PER_LIST];
506 int removal_count = 0;
507 if (entry_ptr)
508 {
509 for (int j=0 ; j<Safe[list]->EntryCount ; j++)
510 {
511 if (entry_ptr->IsSlop)
512 {
513 DataSafeHandleClass decode_handle = entry_ptr->Handle ^ SimpleKey;
514 decode_handle = decode_handle ^ HandleKey;
515 removal_list[removal_count++] = decode_handle;
516 }
517 entry_ptr = entry_ptr->Next;
518 }
519 }
520 for (int j=0 ; j<removal_count ; j++)
521 {
522 Delete_Entry(removal_list[j]);
523 }
524 }
525 handle.Handle.Whole.WholeHandle ^= HandleKey;
526 return handle;
527 }
528 }
529 return (DataSafeHandleClass)-1;
530}
531
532template <class T>
533void DataSafeClass<T>::Delete_Entry(DataSafeHandleClass handle)
534{
535 int list;
536 int id;
537 Security_Check();
538 DataSafeHandleClass new_handle = handle ^ HandleKey;
539 list = new_handle.Handle.Part.List;
540 id = new_handle.Handle.Part.ID;
541 DataSafeEntryClass *entry_ptr = Get_Entry(handle);
542 if (entry_ptr != NULL)
543 {
544 DataSafeHandleClass match_handle = new_handle ^ SimpleKey;
545 Checksum ^= match_handle;
546 DataSafeEntryDataClass<T> *whole_entry_ptr = (DataSafeEntryDataClass<T>*) entry_ptr;
547 Decrypt(&whole_entry_ptr->Data, Get_Type_Size(Safe[list]->EntryType), SimpleKey);
548 if (!whole_entry_ptr->IsSlop)
549 {
550 whole_entry_ptr->Data.T::~T();
551 }
552 Remove_From_List(list, entry_ptr);
553 Free_Handle_ID(list, id);
554 delete [] (void*) entry_ptr;
555 return;
556 }
557}
558
559template <class T>
560bool DataSafeClass<T>::Get(DataSafeHandleClass handle, T* &item)
561{
562 DataSafeEntryClass *entry_ptr = Get_Entry(handle);
563 if (entry_ptr == NULL)
564 {
565 return(false);
566 }
567 DataSafeEntryDataClass<T> *data_entry_ptr = (DataSafeEntryDataClass<T>*) entry_ptr;
568 Mem_Copy_Decrypt(&(ReturnList[ReturnIndex][0]), &data_entry_ptr->Data, sizeof(T), false);
569 item = (T*)(&(ReturnList[ReturnIndex][0]));
570 ReturnIndex++;
571 if (ReturnIndex >= MAX_OBJECT_COPIES)
572 {
573 ReturnIndex = 0;
574 }
575 Shuffle();
576 Security_Check();
577 return(true);
578}
579
580template <class T>
581bool DataSafeClass<T>::Set(DataSafeHandleClass handle, T *data)
582{
583 DataSafeEntryClass *entry_ptr = Get_Entry(handle);
584 if (entry_ptr == NULL)
585 {
586 return(false);
587 }
588 DataSafeEntryDataClass<T> *data_entry_ptr = (DataSafeEntryDataClass<T>*) entry_ptr;
589 Decrypt(&data_entry_ptr->Data, sizeof(T), SimpleKey, true);
590 Mem_Copy_Encrypt(&data_entry_ptr->Data, data, sizeof(T), true);
591 Shuffle();
592 Security_Check();
593 return true;
594}
595
596template <class T>
597inline SafeDataClass<T>::SafeDataClass(T data)
598{
599 Handle = DataSafeClass<T>::Add_Entry(data);
600}
601
602template <class T>
603SafeDataClass<T>::SafeDataClass(void)
604{
605#pragma warning(suppress: 6255) // _alloca indicates failure by raising a stack overflow exception
606 void *stackmem = _alloca(sizeof(T));
607#pragma warning(suppress: 28193) // warning C28193: The variable holds a value that must be examined
608 T *data = new (stackmem) T;
609#pragma warning(suppress: 6011) //warning C6011: dereferencing NULL pointer 'data'
610 Handle = DataSafeClass<T>::Add_Entry(*data);
611}
612
613template <class T>
614inline SafeDataClass<T>::~SafeDataClass(void)
615{
616 if (Handle.Is_Valid())
617 {
618 DataSafeClass<T>::Delete_Entry(Handle);
619 }
620}
621
622template <class T>
623inline T &SafeDataClass<T>::operator = (T const &data)
624{
625 if (Handle.Is_Valid())
626 {
627 DataSafeClass<T>::Set(Handle, (T*) &data);
628 }
629 return (T&)data;
630}
631
632template <class T>
633inline T &SafeDataClass<T>::operator = (SafeDataClass<T> &safedata)
634{
635 T *other_value = NULL;
636 if (Handle.Is_Valid())
637 {
638 other_value = safedata.Get_Ptr();
639 if (other_value)
640 {
641 DataSafeClass<T>::Set(Handle, (T*) other_value);
642 }
643 else
644 {
645 return (T&)*other_value;
646 }
647 }
648#pragma warning(suppress: 6011) //warning C6011: dereferencing NULL pointer 'other_value'
649 return (T&)*other_value;
650}
651
652template <class T>
653inline bool SafeDataClass<T>::operator == (T const &data)
654{
655 T *data_ptr = NULL;
656 if (Handle.Is_Valid())
657 {
658 DataSafeClass<T>::Get(Handle, data_ptr);
659 if (data_ptr)
660 {
661 return(*data_ptr == data);
662 }
663 }
664 return false;
665}
666
667template <class T>
668inline bool SafeDataClass<T>::operator == (SafeDataClass<T> &safedata)
669{
670 T *data_ptr = NULL;
671 T *other_value = NULL;
672 if (Handle.Is_Valid())
673 {
674 DataSafeClass<T>::Get(Handle, data_ptr);
675 if (data_ptr)
676 {
677 other_value = safedata.Get_Ptr();
678 if (other_value)
679 {
680 return *data_ptr == *other_value;
681 }
682 }
683 }
684 return false;
685}
686
687template <class T>
688inline bool SafeDataClass<T>::operator != (T const &data)
689{
690 T *data_ptr = NULL;
691 if (Handle.Is_Valid())
692 {
693 DataSafeClass<T>::Get(Handle, data_ptr);
694 if (data_ptr)
695 {
696 return *data_ptr != data;
697 }
698 }
699 return true;
700}
701
702template <class T>
703inline bool SafeDataClass<T>::operator != (SafeDataClass<T> &safedata)
704{
705 T *data_ptr = NULL;
706 T *other_value = NULL;
707 if (Handle.Is_Valid())
708 {
709 DataSafeClass<T>::Get(Handle, data_ptr);
710 if (data_ptr)
711 {
712 other_value = safedata.Get_Ptr();
713 if (other_value)
714 {
715 return(*data_ptr != *other_value);
716 }
717 }
718 }
719 return false;
720}
721
722template <class T>
723inline bool SafeDataClass<T>::operator > (T const &data)
724{
725 T *data_ptr = NULL;
726 if (Handle.Is_Valid())
727 {
728 DataSafeClass<T>::Get(Handle, data_ptr);
729 if (data_ptr)
730 {
731 return *data_ptr > data;
732 }
733 }
734 return false;
735}
736
737template <class T>
738inline bool SafeDataClass<T>::operator > (SafeDataClass<T> &safedata)
739{
740 T *data_ptr = NULL;
741 T *other_value = NULL;
742 if (Handle.Is_Valid())
743 {
744 DataSafeClass<T>::Get(Handle, data_ptr);
745 if (data_ptr)
746 {
747 other_value = safedata.Get_Ptr();
748 if (other_value)
749 {
750 return *data_ptr > *other_value;
751 }
752 }
753 }
754 return false;
755}
756
757template <class T>
758inline bool SafeDataClass<T>::operator >= (T const &data)
759{
760 T *data_ptr = NULL;
761 if (Handle.Is_Valid())
762 {
763 DataSafeClass<T>::Get(Handle, data_ptr);
764 if (data_ptr)
765 {
766 return(*data_ptr >= data);
767 }
768 }
769 return false;
770}
771
772template <class T>
773inline bool SafeDataClass<T>::operator >= (SafeDataClass<T> &safedata)
774{
775 T *data_ptr = NULL;
776 T *other_value = NULL;
777 if (Handle.Is_Valid())
778 {
779 DataSafeClass<T>::Get(Handle, data_ptr);
780 if (data_ptr)
781 {
782 other_value = safedata.Get_Ptr();
783 if (other_value)
784 {
785 return(*data_ptr >= *other_value);
786 }
787 }
788 }
789 return(false);
790}
791template <class T>
792inline bool SafeDataClass<T>::operator < (T const &data)
793{
794 T *data_ptr = NULL;
795 if (Handle.Is_Valid())
796 {
797 DataSafeClass<T>::Get(Handle, data_ptr);
798 if (data_ptr)
799 {
800 return *data_ptr < data;
801 }
802 }
803 return false;
804}
805template <class T>
806inline bool SafeDataClass<T>::operator < (SafeDataClass<T> &safedata)
807{
808 T *data_ptr = NULL;
809 T *other_value = NULL;
810 if (Handle.Is_Valid())
811 {
812 DataSafeClass<T>::Get(Handle, data_ptr);
813 if (data_ptr)
814 {
815 other_value = safedata.Get_Ptr();
816 if (other_value)
817 {
818 return *data_ptr < *other_value;
819 }
820 }
821 }
822 return false;
823}
824template <class T>
825inline bool SafeDataClass<T>::operator <= (T const &data)
826{
827 T *data_ptr = NULL;
828 if (Handle.Is_Valid())
829 {
830 DataSafeClass<T>::Get(Handle, data_ptr);
831 if (data_ptr)
832 {
833 return *data_ptr <= data;
834 }
835 }
836 return false;
837}
838template <class T>
839inline bool SafeDataClass<T>::operator <= (SafeDataClass<T> &safedata)
840{
841 T *data_ptr = NULL;
842 T *other_value = NULL;
843 if (Handle.Is_Valid())
844 {
845 DataSafeClass<T>::Get(Handle, data_ptr);
846 if (data_ptr)
847 {
848 other_value = safedata.Get_Ptr();
849 if (other_value)
850 {
851 return *data_ptr <= *other_value;
852 }
853 }
854 }
855 return false;
856}
857template <class T>
858inline T &SafeDataClass<T>::operator + (T const &value)
859{
860 T *data_ptr = NULL;
861 if (Handle.Is_Valid())
862 {
863 DataSafeClass<T>::Get(Handle, data_ptr);
864 if (data_ptr)
865 {
866 *data_ptr = *data_ptr + value;
867 return (T&)*data_ptr;
868 }
869 }
870 return (T&)ErrorVal[0];
871}
872template <class T>
873inline T &SafeDataClass<T>::operator + (SafeDataClass<T> &safevalue)
874{
875 T *data_ptr = NULL;
876 T *other_value = NULL;
877 if (Handle.Is_Valid())
878 {
879 DataSafeClass<T>::Get(Handle, data_ptr);
880 if (data_ptr)
881 {
882 other_value = safevalue.Get_Ptr();
883 if (other_value)
884 {
885 *data_ptr = *data_ptr + *other_value;
886 return (T&)*data_ptr;
887 }
888 else
889 {
890 return (T&)*data_ptr;
891 }
892 }
893 }
894 return (T&)ErrorVal[0];
895}
896template <class T>
897inline T &SafeDataClass<T>::operator += (T const &value)
898{
899 T *data_ptr = NULL;
900 if (Handle.Is_Valid())
901 {
902 DataSafeClass<T>::Get(Handle, data_ptr);
903 if (data_ptr)
904 {
905 *data_ptr = *data_ptr + value;
906 DataSafeClass<T>::Set(Handle, data_ptr);
907 return (T&)*data_ptr;
908 }
909 }
910 return (T&)ErrorVal[0];
911}
912template <class T>
913inline T &SafeDataClass<T>::operator += (SafeDataClass<T> &safevalue)
914{
915 T *data_ptr = NULL;
916 T *other_value = NULL;
917 if (Handle.Is_Valid())
918 {
919 DataSafeClass<T>::Get(Handle, data_ptr);
920 if (data_ptr)
921 {
922 other_value = safevalue.Get_Ptr();
923 if (other_value)
924 {
925 *data_ptr = *data_ptr + *other_value;
926 DataSafeClass<T>::Set(Handle, data_ptr);
927 return (T&)*data_ptr;
928 }
929 else
930 {
931 return (T&)*data_ptr;
932 }
933 }
934 }
935 return (T&)ErrorVal[0];
936}
937template <class T>
938inline T &SafeDataClass<T>::operator - (T const &value)
939{
940 T *data_ptr = NULL;
941 if (Handle.Is_Valid())
942 {
943 DataSafeClass<T>::Get(Handle, data_ptr);
944 if (data_ptr)
945 {
946 *data_ptr = *data_ptr - value;
947 return (T&)*data_ptr;
948 }
949 }
950 return (T&)ErrorVal[0];
951}
952template <class T>
953inline T &SafeDataClass<T>::operator - (SafeDataClass<T> &safevalue)
954{
955 T *data_ptr = NULL;
956 T *other_value = NULL;
957 if (Handle.Is_Valid())
958 {
959 DataSafeClass<T>::Get(Handle, data_ptr);
960 if (data_ptr)
961 {
962 other_value = safevalue.Get_Ptr();
963 if (other_value)
964 {
965 *data_ptr = *data_ptr - *other_value;
966 return (T&)*data_ptr;
967 }
968 else
969 {
970 return (T&)*data_ptr;
971 }
972 }
973 }
974 return (T&)ErrorVal[0];
975}
976template <class T>
977inline T &SafeDataClass<T>::operator -= (T const &value)
978{
979 T *data_ptr = NULL;
980 if (Handle.Is_Valid())
981 {
982 DataSafeClass<T>::Get(Handle, data_ptr);
983 if (data_ptr)
984 {
985 *data_ptr = *data_ptr - value;
986 DataSafeClass<T>::Set(Handle, data_ptr);
987 return (T&)*data_ptr;
988 }
989 }
990 return (T&)ErrorVal[0];
991}
992template <class T>
993inline T &SafeDataClass<T>::operator -= (SafeDataClass<T> &safevalue)
994{
995 T *data_ptr = NULL;
996 T *other_value = NULL;
997 if (Handle.Is_Valid())
998 {
999 DataSafeClass<T>::Get(Handle, data_ptr);
1000 if (data_ptr)
1001 {
1002 other_value = safevalue.Get_Ptr();
1003 if (other_value)
1004 {
1005 *data_ptr = *data_ptr - *other_value;
1006 DataSafeClass<T>::Set(Handle, data_ptr);
1007 return (T&)*data_ptr;
1008 }
1009 else
1010 {
1011 return (T&)*data_ptr;
1012 }
1013 }
1014 }
1015 return (T&)ErrorVal[0];
1016}
1017template <class T>
1018inline T &SafeDataClass<T>::operator * (T const &value)
1019{
1020 T *data_ptr = NULL;
1021 if (Handle.Is_Valid())
1022 {
1023 DataSafeClass<T>::Get(Handle, data_ptr);
1024 if (data_ptr)
1025 {
1026 *data_ptr = *data_ptr * value;
1027 return (T&)*data_ptr;
1028 }
1029 }
1030 return (T&)ErrorVal[0];
1031}
1032template <class T>
1033inline T &SafeDataClass<T>::operator * (SafeDataClass<T> &safevalue)
1034{
1035 T *data_ptr = NULL;
1036 T *other_value = NULL;
1037 if (Handle.Is_Valid())
1038 {
1039 DataSafeClass<T>::Get(Handle, data_ptr);
1040 if (data_ptr)
1041 {
1042 other_value = safevalue.Get_Ptr();
1043 if (other_value)
1044 {
1045 *data_ptr = *data_ptr * *other_value;
1046 return (T&)*data_ptr;
1047 }
1048 else
1049 {
1050 return (T&)*data_ptr;
1051 }
1052 }
1053 }
1054 return (T&)ErrorVal[0];
1055}
1056template <class T>
1057inline T &SafeDataClass<T>::operator *= (T const &value)
1058{
1059 T *data_ptr = NULL;
1060 if (Handle.Is_Valid())
1061 {
1062 DataSafeClass<T>::Get(Handle, data_ptr);
1063 if (data_ptr)
1064 {
1065 *data_ptr = *data_ptr * value;
1066 DataSafeClass<T>::Set(Handle, data_ptr);
1067 return (T&)*data_ptr;
1068 }
1069 }
1070 return (T&)ErrorVal[0];
1071}
1072template <class T>
1073inline T &SafeDataClass<T>::operator *= (SafeDataClass<T> &safevalue)
1074{
1075 T *data_ptr = NULL;
1076 T *other_value = NULL;
1077 if (Handle.Is_Valid())
1078 {
1079 DataSafeClass<T>::Get(Handle, data_ptr);
1080 if (data_ptr)
1081 {
1082 other_value = safevalue.Get_Ptr();
1083 if (other_value)
1084 {
1085 *data_ptr = *data_ptr * *other_value;
1086 DataSafeClass<T>::Set(Handle, data_ptr);
1087 return (T&)*data_ptr;
1088 }
1089 else
1090 {
1091 return (T&)*data_ptr;
1092 }
1093 }
1094 }
1095 return (T&)ErrorVal[0];
1096}
1097template <class T>
1098inline T &SafeDataClass<T>::operator / (T const &value)
1099{
1100 T *data_ptr = NULL;
1101 if (Handle.Is_Valid())
1102 {
1103 DataSafeClass<T>::Get(Handle, data_ptr);
1104 if (data_ptr)
1105 {
1106 *data_ptr = *data_ptr / value;
1107 return (T&)*data_ptr;
1108 }
1109 }
1110 return (T&)ErrorVal[0];
1111}
1112template <class T>
1113inline T &SafeDataClass<T>::operator / (SafeDataClass<T> &safevalue)
1114{
1115 T *data_ptr = NULL;
1116 T *other_value = NULL;
1117 if (Handle.Is_Valid())
1118 {
1119 DataSafeClass<T>::Get(Handle, data_ptr);
1120 if (data_ptr)
1121 {
1122 other_value = safevalue.Get_Ptr();
1123 if (other_value)
1124 {
1125 *data_ptr = *data_ptr / *other_value;
1126 return (T&)*data_ptr;
1127 }
1128 else
1129 {
1130 return (T&)*data_ptr;
1131 }
1132 }
1133 }
1134 return (T&)ErrorVal[0];
1135}
1136template <class T>
1137inline T &SafeDataClass<T>::operator /= (T const &value)
1138{
1139 T *data_ptr = NULL;
1140 if (Handle.Is_Valid())
1141 {
1142 DataSafeClass<T>::Get(Handle, data_ptr);
1143 if (data_ptr)
1144 {
1145 *data_ptr = *data_ptr / value;
1146 DataSafeClass<T>::Set(Handle, data_ptr);
1147 return (T&)*data_ptr;
1148 }
1149 }
1150 return (T&)ErrorVal[0];
1151}
1152template <class T>
1153inline T &SafeDataClass<T>::operator /= (SafeDataClass<T> &safevalue)
1154{
1155 T *data_ptr = NULL;
1156 T *other_value = NULL;
1157 if (Handle.Is_Valid())
1158 {
1159 DataSafeClass<T>::Get(Handle, data_ptr);
1160 if (data_ptr)
1161 {
1162 other_value = safevalue.Get_Ptr();
1163 if (other_value)
1164 {
1165 *data_ptr = *data_ptr / *other_value;
1166 DataSafeClass<T>::Set(Handle, data_ptr);
1167 return (T&)*data_ptr;
1168 }
1169 else
1170 {
1171 return (T&)*data_ptr;
1172 }
1173 }
1174 }
1175 return (T&)ErrorVal[0];
1176}
1177template <class T>
1178inline T &SafeDataClass<T>::operator ++ (void)
1179{
1180 T *data_ptr = NULL;
1181 if (Handle.Is_Valid())
1182 {
1183 DataSafeClass<T>::Get(Handle, data_ptr);
1184 if (data_ptr)
1185 {
1186 (*data_ptr)++;
1187 DataSafeClass<T>::Set(Handle, data_ptr);
1188 return (T&)*data_ptr;
1189 }
1190 }
1191 return (T&)ErrorVal[0];
1192}
1193template <class T>
1194inline T &SafeDataClass<T>::operator -- (void)
1195{
1196 T *data_ptr = NULL;
1197 if (Handle.Is_Valid())
1198 {
1199 DataSafeClass<T>::Get(Handle, data_ptr);
1200 if (data_ptr)
1201 {
1202 (*data_ptr)--;
1203 DataSafeClass<T>::Set(Handle, data_ptr);
1204 return (T&)*data_ptr;
1205 }
1206 }
1207 return (T&)ErrorVal[0];
1208}
1209template <class T>
1210inline T &SafeDataClass<T>::operator ++ (int)
1211{
1212 return this->operator ++ ();
1213}
1214template <class T>
1215inline T &SafeDataClass<T>::operator -- (int)
1216{
1217 return this->operator -- ();
1218}
1219template <class T>
1220inline T &SafeDataClass<T>::operator () (void) const
1221{
1222 T *data_ptr = NULL;
1223 if (Handle.Is_Valid())
1224 {
1225 DataSafeClass<T>::Get(Handle, data_ptr);
1226 if (data_ptr)
1227 {
1228 return *data_ptr;
1229 }
1230 }
1231 static T oh_dear;
1232 return oh_dear;
1233}
1234template<class T>
1235inline SafeDataClass<T>::operator T() const
1236{
1237 return (*this)();
1238}
1239template <class T>
1240inline T *SafeDataClass<T>::Get_Ptr(void) const
1241{
1242 T *data_ptr = NULL;
1243 if (Handle.Is_Valid())
1244 {
1245 DataSafeClass<T>::Get(Handle, data_ptr);
1246 if (data_ptr)
1247 {
1248 return data_ptr;
1249 }
1250 }
1251 return NULL;
1252}
1253template <class T>
1254inline bool SafeDataClass<T>::Commit(T *data_ptr) const
1255{
1256 if (Handle.Is_Valid())
1257 {
1258 if (DataSafeClass<T>::In_Return_List(data_ptr))
1259 {
1260 return DataSafeClass<T>::Set(Handle, data_ptr);
1261 }
1262 }
1263 return false;
1264}
1265#endif //PARAM_EDITING_ON
1266#endif