| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449 |
- /*
- ** Command & Conquer Renegade(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /***********************************************************************************************
- *** Confidential - Westwood Studios ***
- ***********************************************************************************************
- * *
- * Project Name : Commando *
- * *
- * $Archive:: /Commando/Code/Commando/datasafe.h $*
- * *
- * $Author:: Steve_t $*
- * *
- * $Modtime:: 1/31/02 12:13p $*
- * *
- * $Revision:: 20 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #ifndef _DATASAFE_H
- #define _DATASAFE_H
- /*
- ** Adapted from original code by Jeff Brown
- **
- ** //=============================================================================
- ** // DataSafe.h
- ** // Public header file for the datasafe
- ** // Author: Jeff Brown
- ** // Date: Apr 16, 1999
- ** //=============================================================================
- **
- **
- **
- **
- ** Class Overview. ST - 7/11/2001 8:19PM
- **
- ** DataSafeHandleClass.
- ** Used to manage handles to items stored in the data safe.
- **
- ** DataSafeEntryClass and DataSafeEntryDataClass<T>.
- ** Represent a single item as stored in the data safe. DataSafeEntryClass has the header
- ** information used to retrieve the item from the safe and the derived DataSafeEntryDataClass
- ** also includes the actual type specific data payload.
- **
- ** DataSafeEntryListClass
- ** This is a manager class for a linked list of DataSafeEntryDataClass<T>'s. Only the same
- ** type of DataSafeEntryDataClass<T> classes can currently be linked together and exist in
- ** the same list.
- **
- ** DataSafeEntryTypeClass
- ** Every object put into the data safe is allocated a type ID so that like types (with the
- ** same ID) can be identified for linking and swapping purposes. DataSafeEntryTypeClass is
- ** a covenient holder for type information.
- **
- ** GenericDataSafeClass and DataSafeClass<T>
- ** The safe itself consists of one static GenericDataSafeClass and many DataSafeClass<T>'s -
- ** one DataSafeClass<T> for every type of data we want to store in the data safe.
- ** Also included is an array of DataSafeEntryListClass's that act as pointers to the data safe
- ** entries.
- **
- **
- ** SafeDataClass
- ** This is a convenience class used to automate insertion and removal of items and provide
- ** a set of operators for common types. Using this class, adding existing data to the data safe
- ** can be as simple as just changing how it's declared. e.g.
- **
- ** int SomeData;
- **
- ** becomes
- **
- ** SafeDataClass<int> SomeData;
- **
- ** There are also some macros provided to make declaration easier so you could also just say
- **
- ** safe_int SomeData;
- **
- ** Currently, only a subset of operators are defined but more can easily be added as needed.
- ** Some changes to code will be required where operators are not available. For example
- **
- ** SomeData += 10;
- **
- ** would be a problem because the += operator is not defined. However the 'int' operator, the
- ** = operator and the conversion operator () are defined so you could change the code to read
- **
- ** SomeData = (int)SomeData + 10;
- **
- ** or
- **
- ** SomeData = SomeData() + 10;
- **
- ** You can pretty much throw anything into the data safe using this class to automate isertion
- ** and retrieval. Some examples.
- **
- ** safe_float HideyFloat;
- ** safe_double CantFindMe[256];
- ** SafeDataClass<SomeNamedClass> ASafeClass;
- ** SafeDataClass<SomeOtherType> ASafeType;
- **
- ** For types without existing macros, you will have to declare a new DataSafeClass<T> once for
- ** each type in DataSafe.cpp using the DECLARE_DATA_SAFE macro. So in the above example, you
- ** would have to add the following lines in DataSafe.cpp to allow storage of the new types
- **
- ** DECLARE_DATA_SAFE(SomeNamedClass);
- ** DECLARE_DATA_SAFE(SomeOtherType);
- **
- **
- **
- **
- ** Known external dependencies.
- ** DynamicVectorClass
- ** TICKS_PER_SECOND = 1000
- ** FreeRandom - Renegade random number generator.
- ** WWDEBUG_SAY - Equivalent to DebugString in C&C. Just a formatted debug output.
- **
- */
- /*
- ** Includes.
- */
- #ifndef _ALWAYS_H
- #include "always.h"
- #include <assert.h>
- #include <malloc.h>
- #include <memory.h>
- #include <windows.h>
- #endif //_ALWAYS_H
- #ifndef _TIMEMGR_H
- #include "timemgr.h"
- #endif //_TIMEMGR_H
- #ifndef _WWDEBUG_H
- #include "wwdebug.h"
- #endif //_WWDEBUG_H
- //#ifndef MMSYS_H
- //#include "mmsys.h"
- //#endif //MMSYS_H
- #include "systimer.h"
- /*
- ** Use Renegade assert.
- */
- #ifdef WWASSERT
- #define ds_assert WWASSERT
- #else //WWASSERT
- #define ds_assert assert
- #endif //WWASSERT
- /*
- ** TEMP. Profile builds don't have asserts.
- */
- #ifndef DEBUG
- #undef ds_assert
- #define ds_assert(x)
- #pragma warning(disable : 4189)
- #endif //DEBUG
- #ifndef WWDEBUG
- #pragma warning(disable : 4101)
- #endif
- /*
- ** Enable this define to make the datasafe thread safe (there is a performance penalty).
- */
- //#define THREAD_SAFE_DATA_SAFE
- /*
- ** Number of linked lists we can create for data safe items. Only like sized items can be stored in the same list.
- */
- #define MAX_DATASAFE_LISTS 8192
- /*
- ** The maximum number of different data types that can be stored in the data safe. This should normally fit into a byte for
- ** handle encoding reasons.
- */
- #define MAX_DATASAFE_TYPES 128
- /*
- ** Max number of entries in a single list before we have to create a second list for items of the same size. The smaller this
- ** value, the quicker we will be able to retrieve data from the safe. The larger we make it, the more secure the data safe will
- ** be.
- */
- #define MAX_ENTRIES_PER_LIST 16
- /*
- ** How often the data safe entries get shuffled around and re-keyed. This is the delay between each shuffle.
- */
- #define SHUFFLE_TIME (TICKS_PER_SECOND * 7)
- /*
- ** The delay between each integrity check on the data safe. This is a slow operation.
- */
- #define SECURITY_CHECK_TIME (TICKS_PER_SECOND * 15)
- /*
- ** The number of copies of objects of any one type that can exist in an unencrypted state. These copies are only used as return
- ** values and changes to the copies can never be propagated back into the safe.
- */
- #define MAX_OBJECT_COPIES 8
- /*
- ** Sentinel values. Used to see if someone just zeroes the whole safe or tampered with the get function.
- */
- #define SENTINEL_ONE 0x29874362
- #define SENTINEL_TWO 0x0bad0bad
- #define DATASAFE_TIME_CHECK_CALLS 100000
- /*
- ** Defines to allow convenient use of built-in types inside the data safe.
- **
- */
- #ifdef PARAM_EDITING_ON
- #define safe_int int
- #define safe_unsigned_int unsigned int
- #define safe_long long
- #define safe_unsigned_long unsigned long
- #define safe_float float
- #define safe_double double
- #else //PARAM_EDITING_ON
- #define safe_int SafeDataClass<int>
- #define safe_unsigned_int SafeDataClass<unsigned int>
- #define safe_long SafeDataClass<int>
- #define safe_unsigned_long SafeDataClass<unsigned int>
- #define safe_float SafeDataClass<float>
- #define safe_double SafeDataClass<double>
- #endif //PARAM_EDITING_ON
- /*
- ** Make sure we pulled in the right timer defines.
- */
- #if TICKS_PER_SECOND != 1000
- #error Code assumes TICKS_PER_SECOND == 1000
- #endif
- /*
- ** We want to inline functions within inline functions to make the code harder to hack by having multiple copies of it.
- */
- #pragma inline_recursion(on)
- #pragma inline_depth(4)
- #pragma warning(disable : 4714)
- /*
- ** Data safe handle.
- **
- ** This consists of a linked list number, an entry identifier and a type.
- **
- ** The whole shooting match can just be treated like an int.
- **
- */
- class DataSafeHandleClass
- {
- public:
- /*
- ** Consturctor.
- */
- DataSafeHandleClass(int val = 0) {
- Handle.Whole.WholeHandle = val;
- };
- /*
- ** Validity check.
- */
- bool Is_Valid(void) const {
- return(Handle.Whole.WholeHandle != -1);
- };
- /*
- ** Convenience functions and operators to handle setting or getting a handle using an int.
- */
- inline int operator = (const int &val) {
- Handle.Whole.WholeHandle = val;
- return(val);
- };
- inline operator int (void) {
- return(Handle.Whole.WholeHandle);
- }
- inline operator int (void) const {
- return(Handle.Whole.WholeHandle);
- }
- inline int &operator () (void) {
- return(Handle.Whole.WholeHandle);
- }
- /*
- ** Handle data.
- */
- union tHandle {
- struct {
- /*
- ** All the handle components conveniently together in an int.
- */
- int WholeHandle;
- } Whole;
- struct {
- /*
- ** ID is basically the index of the item in the linked list. It's a little more complex
- ** than that since an ID can be re-used after the original user is removed from the
- ** list but the whole list is searched for a matching ID when retrieving anyway.
- */
- unsigned char ID;
- /*
- ** The type of object this handle represents.
- */
- unsigned char Type;
- /*
- ** The list number where we can find this object.
- */
- unsigned short List;
- } Part;
- } Handle;
- };
- /*
- ** Known packing is required here otherwise the default alignment is the same as the largest member
- ** of the structure. When combined with an expansion of DataSafeEntryDataClass<T> for doubles, the
- ** packing alignment becomes 8 (the size of a double) thus the offset of Data is not always as expected.
- ** i.e. you can no longer use sizeof(DataSafeEntryClass) to get the offset of the Data member of
- ** the derived class. This also prevents bloating (due to the bool member) when using large expansions
- ** for 'T'
- */
- #pragma pack(push)
- #pragma pack(4)
- /*
- **
- ** This class represents an internal data safe entry minus the actual data. In practice, this class will never be used
- ** except to refer to a DataSafeEntryDataClass<T> which actually contains the type specific data.
- **
- */
- class DataSafeEntryClass
- {
- public:
- /*
- ** Identifying handle.
- */
- DataSafeHandleClass Handle;
- /*
- ** Linked list next and prev.
- **
- ** Note: These can point to a DataSafeEntryDataClass expanded for any type.
- */
- DataSafeEntryClass *Next;
- DataSafeEntryClass *Prev;
- /*
- ** Size of data.
- */
- unsigned long Size;
- /*
- ** Is this a slop (fake, to allow swapping with only 1 real entry) entry?
- */
- bool IsSlop;
- };
- /*
- ** This is a complete internal data safe entry including the header and the encrypted data.
- **
- */
- template<class T>
- class DataSafeEntryDataClass : public DataSafeEntryClass
- {
- public:
- T Data;
- };
- #pragma pack(pop)
- /*
- ** This class represents a single data safe entry list. There can be mutiple lists in a data safe but all entries in a single
- ** list must be of the same type.
- */
- class DataSafeEntryListClass
- {
- public:
- /*
- ** Constructor.
- */
- DataSafeEntryListClass(void) {
- SafeList = NULL;
- EntryCount = 0;
- EntryType = -1;
- SlopCount = 0;
- memset(HandleIDUsage, 0, sizeof(HandleIDUsage));
- };
- /*
- ** Pointer to the head of the list.
- */
- DataSafeEntryClass *SafeList;
- /*
- ** Number of entries in the list.
- */
- int EntryCount;
- /*
- ** Type of entry in this list.
- */
- int EntryType;
- /*
- ** Number of slop entries in this list.
- */
- int SlopCount;
- /*
- ** Handle IDs used in this list.
- */
- char HandleIDUsage[MAX_ENTRIES_PER_LIST];
- };
- /*
- **
- ** This class describes a type of entry in the data safe. It's important to keep track of the types of objects we add since
- ** only similar types can be swapped in memory. This class is just a convenient container to help us match type codes with
- ** unique IDs.
- **
- **
- */
- class DataSafeEntryTypeClass
- {
- public:
- DataSafeEntryTypeClass(void) {
- TypeCode = 0;
- ID = -1;
- Size = 0;
- };
- /*
- ** A unique number used to match and assign type IDs. This can come from anywhere as long as it's different for every type.
- */
- unsigned long TypeCode;
- /*
- ** This is the user friendly ID that is stored along with entries in the data safe and returned in the handle that's
- ** given out when something is added to the safe.
- ** It's also the index into the type list.
- */
- int ID;
- /*
- ** The size of this type of object. Must be a multiple of 4 bytes for the data safe. (This is redundant now that we
- ** have a type/size lookup table).
- */
- int Size;
- };
- /*
- ** GenericDataSafeClass
- **
- ** This class represents a single data safe. It can only function as the base class to one or more instances of
- ** DataSafeClass<T>.
- **
- **
- ** This class functions as a base class for all the templated 'DataSafeClass'es so that they can all share a single set of
- ** static data. Normally, static data in a templated class is duplicated for each expansion of the class.
- **
- ** Even though there may be many instances and expansions of the derived DataSafeClass<T> there is only ever one global
- ** data safe and that is represented by this class.
- **
- */
- class GenericDataSafeClass
- {
- public:
- /*
- ** Constructor.
- */
- GenericDataSafeClass(void);
- /*
- ** Query functions.
- */
- static DataSafeEntryClass * Get_Entry(DataSafeHandleClass handle);
- static int Get_Entry_Type(DataSafeHandleClass handle);
- /*
- ** System timer reset.
- */
- static void Reset_Timers(void);
- /*
- ** Thread safety. This is normally handled automatically but if you need to manually lock the safe for a period of time
- ** to do a read/hold/write then this is the way to do it.
- */
- #ifdef THREAD_SAFE_DATA_SAFE
- static void Lock(void);
- static void Unlock(void);
- #endif //THREAD_SAFE_DATA_SAFE
- /*
- ** Stats, debug helpers.
- */
- static void Dump_Safe_Stats(char *dump_buffer, int buffer_size);
- static void Print_Safe_Stats_To_Debug_Output(void);
- static void Reset(void);
- #ifdef THREAD_SAFE_DATA_SAFE
- static void Set_Preferred_Thread(unsigned int){};
- #else //THREAD_SAFE_DATA_SAFE
- static void Set_Preferred_Thread(unsigned int thread_id) {PreferredThread = thread_id;};
- #endif //THREAD_SAFE_DATA_SAFE
- protected:
- /*
- ** Cleanup.
- */
- void Shutdown(void);
- /*
- ** Query functions.
- */
- static DataSafeEntryClass * Get_Entry_By_Index(int list, int index);
- /*
- ** Security
- */
- static void Shuffle(bool forced = false);
- static void Swap_Entries(DataSafeEntryClass *first, DataSafeEntryClass *second, int type);
- static void Encrypt(void *data, int size, unsigned long key = SimpleKey, bool do_checksum = true);
- static void Decrypt(void *data, int size, unsigned long key = SimpleKey, bool do_checksum = true);
- static void Mem_Copy_Encrypt(void *dest, void *src, int size, bool do_checksum);
- static void Mem_Copy_Decrypt(void *dest, void *src, int size, bool do_checksum);
- static __forceinline void Security_Check(void);
- static __forceinline void Security_Fault(void);
- static void Say_Security_Fault(void);
- /*
- ** Insertion support.
- */
- static int Get_Random_List_For_Insertion(int type);
- static void Random_Insertion(DataSafeEntryClass *entry, int list, int type, bool is_slop = false);
- static int Create_Safe_List(int type);
- static int Get_Handle_ID(int list);
- /*
- ** Deletion support. Just used to make sure we are doing type safe deletion.
- */
- static void Remove_From_List(int list, DataSafeEntryClass *entry_ptr);
- static void Free_Handle_ID(int list, int id);
- /*
- ** Type identification.
- */
- static inline int Get_Type_Size(int type);
- #ifdef THREAD_SAFE_DATA_SAFE
- /*
- ** Thread safety.
- */
- class ThreadLockClass
- {
- public:
- /*
- ** Constructor. Grabs the mutex.
- */
- inline ThreadLockClass(void) {
- int deadlock = WaitForSingleObject(GenericDataSafeClass::SafeMutex, 10 * 1000);
- if (deadlock == WAIT_TIMEOUT) {
- WWDEBUG_SAY(("Data Safe: Timeout waiting for data safe mutex\n"));
- ds_assert(deadlock != WAIT_TIMEOUT);
- }
- };
- /*
- ** Destructor, releases the mutex.
- */
- inline ~ThreadLockClass(void) {
- ReleaseMutex(GenericDataSafeClass::SafeMutex);
- };
- };
- #else //THREAD_SAFE_DATA_SAFE
- /*
- ** If thread safety is not required, this class compiles out to nothing when used in release mode.
- */
- class ThreadLockClass
- {
- public:
- #ifdef WWDEBUG
- __forceinline ThreadLockClass(void) {
- if (GenericDataSafeClass::PreferredThread != GetCurrentThreadId()) {
- WWDEBUG_SAY(("DATASAFE.H - PreferredThread = %08X, GetCurrentThreadId() == %08X\n", GenericDataSafeClass::PreferredThread, GetCurrentThreadId()));
- }
- ds_assert(GenericDataSafeClass::PreferredThread == GetCurrentThreadId());
- };
- #endif //WWDEBUG
- };
- static unsigned int PreferredThread;
- #endif //THREAD_SAFE_DATA_SAFE
- friend ThreadLockClass;
- /*
- ** Static data. We only need one each of these, regardless of how many DataSafeClass 'types' there are.
- **
- **
- **
- */
- /*
- ** Simple key value used for xoring.
- */
- static unsigned long SimpleKey;
- /*
- ** Key used for encrypting handles.
- */
- static unsigned long HandleKey;
- /*
- ** Number of valid entries in the Safe list.
- */
- static int NumLists;
- /*
- ** Array of pointers to data lists. We can't use a dynamic vector class here because the handles we give out include
- ** an index into this array. Dynamic vector class moves entries around to remove gaps in the array which would leave
- ** the handles pointing to the wrong element.
- */
- static DataSafeEntryListClass *Safe[MAX_DATASAFE_LISTS];
- /*
- ** Integrity check.
- */
- static unsigned long Checksum;
- /*
- ** Shuffle delay.
- */
- static unsigned long ShuffleDelay;
- /*
- ** Security check delay.
- */
- static unsigned long SecurityCheckDelay;
- /*
- ** List of types that are stored in the data safe.
- */
- static DataSafeEntryTypeClass TypeList[MAX_DATASAFE_TYPES];
- static int TypeListCount;
- /*
- ** Mutex to ensure thread safety.
- */
- #ifdef THREAD_SAFE_DATA_SAFE
- static HANDLE SafeMutex;
- #endif //THREAD_SAFE_DATA_SAFE
- /*
- ** Sentinels. Can't use 'SafeDataClass' as it's constructor adds data to the safe - i.e. us.
- */
- static DataSafeHandleClass SentinelOne;
- static DataSafeHandleClass SentinelTwo;
- /*
- ** Number of CRC errors so we can report it in the game results.
- */
- static int CRCErrors;
- /*
- ** Statistics - debug only.
- */
- #ifdef WWDEBUG
- static unsigned long LastDump;
- static int NumSwaps;
- static int NumFetches;
- static int SlopCount;
- static int NumSecurityChecks;
- static int NumShuffles;
- #endif //WWDEBUG
- };
- /*
- ** DataSafeClass<T>
- **
- ** This templated class is used to provide type specific functionality in the data safe. There must be at least one instance
- ** of this class for each type of data we want to store in the safe. This, along with 'GenericDataSafeClass' represents
- ** a single global data safe.
- **
- */
- template<class T>
- class DataSafeClass : public GenericDataSafeClass
- {
- public:
- DataSafeClass(T *bogus_ptr = NULL, int slopcount = 3);
- ~DataSafeClass(void);
- /*
- ** Query functions.
- */
- static bool Get(DataSafeHandleClass handle, T* &item);
- static inline bool In_Return_List(T *ptr) {
- if (ptr) {
- void *temp = (void*)ptr;
- if (temp >= &ReturnList[0][0] && temp < &ReturnList[MAX_OBJECT_COPIES][0]) {
- if (((unsigned long) temp - (unsigned long)(&ReturnList[0][0])) % sizeof(T) == 0) {
- return(true);
- }
- }
- }
- return(false);
- };
- /*
- ** Set functions.
- */
- static bool Set(DataSafeHandleClass handle, T *data);
- /*
- ** Add functions.
- */
- static DataSafeHandleClass Add_Entry(T &value, bool is_slop = false);
- /*
- ** Removal functions.
- */
- static void Delete_Entry(DataSafeHandleClass handle);
- private:
- /*
- ** Type identification.
- */
- static int Get_Type_ID(unsigned long type_code, int size);
- static unsigned long Get_Type_Code(void);
- /*
- ** Type of this DataSafe.
- */
- static int Type;
- /*
- ** Min slop entries for this type of safe.
- */
- static int MinSlop;
- /*
- ** Copies of items in the data safe. Only used to return copies of items in the safe.
- **
- ** The number of elements in this list is the number of times you can call the 'Get' function before you start to
- ** invalidate the data you got 'n' calls ago. For this reason, you should always make a copy of data retrieved from
- ** the safe if you plan to use it more than once.
- */
- static char ReturnList[MAX_OBJECT_COPIES][sizeof(T)];
- static int ReturnIndex;
- };
- /*
- **
- ** Macros to help in declaring data safe types.
- **
- **
- **
- */
- #define DECLARE_DATA_SAFE(type) \
- DataSafeClass<type> DataSafe##type; \
- int DataSafeClass<type>::Type; \
- char DataSafeClass<type>::ReturnList[MAX_OBJECT_COPIES][sizeof(type)]; \
- int DataSafeClass<type>::ReturnIndex; \
- int DataSafeClass<type>::MinSlop;
- /*
- **
- ** SafeDataClass.
- **
- ** This class is for convenience when using the data safe. Just expand this class for the type you want to add to the data safe
- ** and it will keep track of the handle and automate the adding in, and removal of, data in the safe.
- **
- */
- extern char ErrorVal[1024];
- template<class T>
- class SafeDataClass
- {
- public:
- /*
- ** Constructor, destructor.
- */
- SafeDataClass(void);
- SafeDataClass(T data);
- ~SafeDataClass(void);
- /*
- ** Copy constructor. This is a bad thing to call.
- */
- SafeDataClass(SafeDataClass &) {
- ds_assert(false);
- };
- /*
- ** Helper functions for data safe class storage.
- */
- inline T* Get_Ptr(void) const;
- inline bool Commit(T* data_ptr) const;
- /*
- ** Operators.
- */
- inline T &operator () (void) const;
- inline T &operator = (T const &data);
- inline T &operator = (SafeDataClass<T> &safedata);
- inline operator int(void) const;
- inline operator unsigned int(void) const;
- inline operator long(void) const;
- inline operator unsigned long(void) const;
- inline operator float(void) const;
- inline operator double(void) const;
- inline bool operator == (T const &data);
- inline bool operator == (SafeDataClass<T> &safedata);
- inline bool operator != (T const &data);
- inline bool operator != (SafeDataClass<T> &safedata);
- inline bool operator > (T const &data);
- inline bool operator > (SafeDataClass<T> &safedata);
- inline bool operator >= (T const &data);
- inline bool operator >= (SafeDataClass<T> &safedata);
- inline bool operator < (T const &data);
- inline bool operator < (SafeDataClass<T> &safedata);
- inline bool operator <= (T const &data);
- inline bool operator <= (SafeDataClass<T> &safedata);
- inline T &operator + (T const &data);
- inline T &operator + (SafeDataClass<T> &safedata);
- inline T &operator += (T const &data);
- inline T &operator += (SafeDataClass<T> &safedata);
- inline T &operator - (T const &data);
- inline T &operator - (SafeDataClass<T> &safedata);
- inline T &operator -= (T const &data);
- inline T &operator -= (SafeDataClass<T> &safedata);
- inline T &operator * (T const &data);
- inline T &operator * (SafeDataClass<T> &safedata);
- inline T &operator *= (T const &data);
- inline T &operator *= (SafeDataClass<T> &safedata);
- inline T &operator / (T const &data);
- inline T &operator / (SafeDataClass<T> &safedata);
- inline T &operator /= (T const &data);
- inline T &operator /= (SafeDataClass<T> &safedata);
- inline T &operator ++ (void);
- inline T &operator -- (void);
- inline T &operator ++ (int);
- inline T &operator -- (int);
- /*
- ** Query and set functions.
- */
- DataSafeHandleClass Get_Handle(void) {return(Handle);};
- T Get(void);
- void Set(T);
- private:
- /*
- ** This is the handle that represents this classes data in the datasafe.
- */
- DataSafeHandleClass Handle;
- #ifdef WWDEBUG
- T DebugData;
- #endif //WWDEBUG
- };
- /***********************************************************************************************
- **
- **
- **
- ** File separation.
- **
- **
- */
- /*
- ** Simple functions, suitable for inline expansion.
- **
- **
- **
- **
- */
- /*
- **
- **
- ** GenericDataSafeClass functions.
- **
- **
- */
- /***********************************************************************************************
- * GenericDataSafeClass::Get_Type_Size -- Get the size of this type *
- * *
- * *
- * *
- * INPUT: Type ID of object *
- * *
- * OUTPUT: Size of object *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 6/27/2001 12:47PM ST : Created *
- *=============================================================================================*/
- inline int GenericDataSafeClass::Get_Type_Size(int type)
- {
- ds_assert(type >= 0);
- ds_assert(type < MAX_DATASAFE_TYPES);
- ds_assert(type < TypeListCount);
- return(TypeList[type].Size);
- }
- /***********************************************************************************************
- * GenericDataSafeClass::Security_Fault -- Security fault handler *
- * *
- * __forceinline used to make sure there are multiple copies of this code. It's bloaty *
- * but it makes it harder to hack out (but only a little bit) *
- * *
- * *
- * INPUT: Nothing *
- * *
- * OUTPUT: Nothing *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/9/2001 2:20PM ST : Created *
- *=============================================================================================*/
- __forceinline void GenericDataSafeClass::Security_Fault(void)
- {
- WWDEBUG_SAY(("Data Safe:Security fault\n"));
- CRCErrors++;
- Say_Security_Fault();
- ds_assert(false);
- }
- /***********************************************************************************************
- * GenericDataSafeClass::Security_Check -- Look for security problems. *
- * *
- * __forceinline used to make sure there are multiple copies of this code. It's bloaty *
- * but it makes it harder to hack out (but only a little bit) *
- * *
- * *
- * INPUT: Nothing *
- * *
- * OUTPUT: Nothing *
- * *
- * WARNINGS: *
- * *
- * HISTORY: *
- * 7/9/2001 1:08PM ST : Created *
- *=============================================================================================*/
- __forceinline void GenericDataSafeClass::Security_Check(void)
- {
- ThreadLockClass locker;
- /*
- ** Flag to prevent recursion.
- */
- static bool _checking = false;
- /*
- ** Only check the time every n calls.
- */
- static unsigned long _calls = 0;
- _calls++;
- if (_calls < DATASAFE_TIME_CHECK_CALLS) {
- return;
- }
- _calls = 0;
- /*
- ** See if SimpleKey has been zeroed out.
- */
- if (HandleKey - SimpleKey == HandleKey) {
- WWDEBUG_SAY(("Data Safe: Simple Key compromised!\n"));
- Security_Fault();
- }
- /*
- ** See if HandleKey has been zeroed out.
- */
- if (SimpleKey - HandleKey == SimpleKey) {
- WWDEBUG_SAY(("Data Safe: Handle Key compromised!\n"));
- Security_Fault();
- }
- /*
- ** Use the checksum to verify the whole data safe.
- ** Yes, the whole safe. A teeny bit slow maybe.
- **
- ** Since we are going through the whole safe here, we might as well make a note of where slop
- ** needs to be added or removed and count how many total slop entries we have.
- */
- unsigned long time = TIMEGETTIME();
- if (time < SecurityCheckDelay || (time | SecurityCheckDelay) == 0 || (time - SecurityCheckDelay) > SECURITY_CHECK_TIME) {
- #ifdef WWDEBUG
- SlopCount = 0;
- NumSecurityChecks++;
- #endif //WWDEBUG
- /*
- ** If toooo much time has gone by then do it anyway.
- */
- if (!_checking) { // || (time - SecurityCheckDelay) > SECURITY_CHECK_TIME * 5) {
- _checking = true;
- //WWDEBUG_SAY(("Data Safe: Performing security check\n"));
- SecurityCheckDelay = time;
- unsigned long checkey = ~SimpleKey;
- /*
- ** Loop through every list.
- */
- for (int i=0 ; i<NumLists ; i++) {
- ds_assert(Safe[i] != NULL);
- if (Safe[i] != NULL && Safe[i]->EntryCount > 0) {
- /*
- ** Dereference stuff - make sure the list makes sense.
- */
- DataSafeEntryClass *entry_ptr = Safe[i]->SafeList;
- unsigned long *data = NULL;
- ds_assert(entry_ptr != NULL);
- int data_size = entry_ptr->Size;
- ds_assert((data_size & 3) == 0);
- data_size = data_size >> 2;
- if (entry_ptr) {
- /*
- ** Go through each entry in the list.
- */
- for (int j=0 ; j<Safe[i]->EntryCount ; j++) {
- #ifdef WWDEBUG
- /*
- ** Count slop entries for debug purposes.
- */
- if (entry_ptr->IsSlop) {
- SlopCount++;
- }
- #endif //WWDEBUG
- /*
- ** Add in the handle.
- */
- checkey ^= entry_ptr->Handle;
- /*
- ** Add in the data.
- */
- data = (unsigned long *) (((char*)entry_ptr) + sizeof(*entry_ptr));
- for (int z=0 ; z<data_size ; z++) {
- checkey ^= *data++;
- }
- /*
- ** Next entry.
- */
- entry_ptr = entry_ptr->Next;
- }
- }
- }
- }
- if (checkey != Checksum) {
- WWDEBUG_SAY(("Data Safe: Incorrect checksum!\n"));
- Security_Fault();
- }
- /*
- ** Check the values of the sentinels.
- */
- if (NumLists) {
- int *val = NULL;
- if ((int)SentinelOne != 0) {
- bool got = DataSafeClass<int>::Get(SentinelOne, val);
- if (!got || val == NULL || *val != SENTINEL_ONE) {
- WWDEBUG_SAY(("Data Safe: Incorrect sentinel value!\n"));
- Security_Fault();
- }
- }
- val = NULL;
- if ((int)SentinelTwo != 0) {
- bool got = DataSafeClass<int>::Get(SentinelTwo, val);
- if (!got || val == NULL || *val != SENTINEL_TWO) {
- WWDEBUG_SAY(("Data Safe: Incorrect sentinel value!\n"));
- Security_Fault();
- }
- }
- }
- #ifdef WWDEBUG
- Print_Safe_Stats_To_Debug_Output();
- #endif //WWDEBUG
- _checking = false;
- }
- }
- }
- /*
- **
- **
- ** DataSafeClass functions.
- **
- **
- */
- /***********************************************************************************************
- * DataSafeClass::DataSafeClass -- Class constructor *
- * *
- * *
- * *
- * INPUT: Bogus pointer. Pointer that isn't referenced. It's only used for type info *
- * Number of 'slop' entries to create *
- * *
- * OUTPUT: Nothing *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 6/25/2001 1:51PM ST : Created *
- *=============================================================================================*/
- template <class T>
- DataSafeClass<T>::DataSafeClass(T*, int slopcount)
- {
- ThreadLockClass locker;
- /*
- ** Clear out the return list.
- */
- memset(ReturnList, 0, sizeof(ReturnList));
- ReturnIndex = 0;
- /*
- ** Get the type info for 'T'. Different types get stored in different places in the safe. Only similar types can be in the
- ** same safe list.
- */
- int data_size = sizeof(T);
- int type_code = Get_Type_Code();
- /*
- ** Get_Type_ID will return the Type ID for this type code (instruction pointer). It will create a new type if this one
- ** doesn't already exist.
- */
- int id = Get_Type_ID(type_code, data_size);
- Type = id;
- MinSlop = slopcount;
- /*
- ** Add some slop entries here. These are just bogues entries than can be swapped in memory with real entries. The less
- ** commonly added data types should be give more slop entries.
- */
- for (int i=0 ; i<slopcount ; i++) {
- /*
- ** We need to make sure the constructor gets called for this object type before it's added to the safe. But we must
- ** also make sure that the destructor *isn't* called when we go out of scope here - it will be called explicitly
- ** when the datasafe is destructed. By using _alloca, and doing an in-place new, the memory that the object sits in
- ** will be freed when it goes out of scope but the destructor for 'T' won't be called.
- */
- void *stackmem = _alloca(sizeof(T));
- T *slop_ptr = new (stackmem) T;
- Add_Entry(*slop_ptr, true);
- }
- }
- /***********************************************************************************************
- * DataSafeClass::~DataSafeClass -- Class destructor. Removes remaining slop entries. *
- * *
- * *
- * *
- * INPUT: Nothing *
- * *
- * OUTPUT: Nothing *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/5/2001 11:38AM ST : Created *
- *=============================================================================================*/
- template <class T>
- DataSafeClass<T>::~DataSafeClass(void)
- {
- ThreadLockClass locker;
- /*
- ** Remove all slop enries of our type from all lists. Note that this will delete non-slop entries too if any remain at this
- ** time.
- */
- for (int i=0 ; i<NumLists ; i++) {
- ds_assert(Safe[i] != NULL);
- if (Safe[i] != NULL && Safe[i]->EntryType == Type && Safe[i]->EntryCount > 0) {
- while (Safe[i]->EntryCount > 0) {
- /*
- ** Delete the first entry in the list.
- */
- int entries = Safe[i]->EntryCount;
- DataSafeHandleClass handle = Safe[i]->SafeList->Handle ^ SimpleKey;
- handle = handle ^ HandleKey;
- Delete_Entry(handle);
- /*
- ** Safety check. If something goes wrong and we didn't delete the entry then we will never get out of this loop
- ** so check for that case.
- */
- ds_assert(entries == Safe[i]->EntryCount+1);
- if (entries != Safe[i]->EntryCount+1) {
- break;
- }
- }
- }
- }
- Shutdown();
- }
- /***********************************************************************************************
- * DataSafeClass::Get_Type_Code -- Get a unique code per type without using RTTI *
- * *
- * *
- * *
- * INPUT: Nothing *
- * *
- * OUTPUT: Type code *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/2/2001 11:17AM ST : Created *
- *=============================================================================================*/
- template <class T>
- unsigned long DataSafeClass<T>::Get_Type_Code(void)
- {
- /*
- ** Make sure this function gets expanded multiple times for different types by referencing the type.
- */
- volatile int data_size = sizeof(T);
- data_size = data_size;
- /*
- ** Since we aren't using RTTI I need some other way of distinguishing types in the safe. Because it's templatised, this
- ** code will get expanded once for each type it's used with. I will use the location in memory of the function to
- ** uniquely identify each type. What a cunning plan.
- */
- static unsigned long instruction_pointer;
- instruction_pointer = 0;
- __asm {
- here:
- lea eax,here
- mov [instruction_pointer],eax
- };
- ds_assert(instruction_pointer != 0);
- return(instruction_pointer);
- }
- /***********************************************************************************************
- * DataSafeClass::Get_Type_ID -- Get the id for the given type and size *
- * *
- * *
- * *
- * INPUT: Type identifier code *
- * Size of type *
- * *
- * OUTPUT: Type ID *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 6/27/2001 12:44PM ST : Created *
- *=============================================================================================*/
- template <class T>
- int DataSafeClass<T>::Get_Type_ID(unsigned long type_code, int size)
- {
- int id = 0;
- /*
- ** See if we already have an ID for this type code.
- */
- for (int i=0 ; i<TypeListCount ; i++) {
- if (TypeList[i].TypeCode == type_code) {
- ds_assert(TypeList[i].Size == size);
- return(TypeList[i].ID);
- }
- }
- /*
- ** Create a new type entry.
- */
- ds_assert(TypeListCount < MAX_DATASAFE_TYPES);
- if (TypeListCount < MAX_DATASAFE_TYPES) {
- ds_assert(TypeList[TypeListCount].TypeCode == 0);
- ds_assert(TypeList[TypeListCount].Size == 0);
- TypeList[TypeListCount].TypeCode = type_code;
- TypeList[TypeListCount].ID = TypeListCount;
- TypeList[TypeListCount].Size = size;
- id = TypeListCount++;
- }
- return(id);
- }
- /***********************************************************************************************
- * DataSafeClass::Add_Entry -- Create a new data safe entry and init it to the value provided *
- * *
- * *
- * *
- * INPUT: Value *
- * *
- * OUTPUT: Handle *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 6/19/2001 8:34PM ST : Created *
- *=============================================================================================*/
- template <class T>
- DataSafeHandleClass DataSafeClass<T>::Add_Entry(T &value, bool is_slop)
- {
- ThreadLockClass locker;
- Security_Check();
- /*
- ** Allocate memory for the new entry.
- */
- DataSafeEntryClass *entry_ptr = (DataSafeEntryClass*) new char [sizeof(DataSafeEntryDataClass<T>)];
- ds_assert(entry_ptr);
- if (entry_ptr) {
- /*
- ** Init the data safe entry to reasonable values.
- */
- entry_ptr->Next = NULL;
- entry_ptr->Prev = NULL;
- entry_ptr->Size = sizeof(value);
- entry_ptr->IsSlop = is_slop;
- /*
- ** Copy the data to the safe entry.
- */
- DataSafeEntryDataClass<T>* data_ptr = (DataSafeEntryDataClass<T>*) entry_ptr;
- Mem_Copy_Encrypt(& data_ptr->Data, &value, sizeof(value), true);
- /*
- ** Find out which list we will be adding the entry to.
- */
- int list = Get_Random_List_For_Insertion(Type);
- ds_assert(list >= 0 && list < MAX_DATASAFE_LISTS);
- ds_assert(Safe[list] != NULL);
- if (list != -1 && Safe[list] != NULL) {
- /*
- ** Now we know the list, we can get the next index id for that list and build a handle for the entry.
- */
- int index = Get_Handle_ID(list);
- ds_assert(index >= 0 && index < MAX_ENTRIES_PER_LIST);
- DataSafeHandleClass handle;
- handle.Handle.Part.List = list;
- handle.Handle.Part.ID = index;
- handle.Handle.Part.Type = Type;
- /*
- ** We have a handle. Better encrypt it.
- */
- DataSafeHandleClass encrypted_handle = handle ^ SimpleKey;
- Checksum = Checksum ^ encrypted_handle;
- /*
- ** Store it in the entry so we can do a search and match to get this entry out again.
- */
- entry_ptr->Handle = encrypted_handle;
- /*
- ** Insert the entry into the chosen list.
- */
- Random_Insertion(entry_ptr, list, Type, is_slop);
- /*
- ** Maybe add slop here if there is only one entry in the list.
- ** It will get removed later as more entries are added.
- */
- if (Safe[list]->EntryCount == 1 && !is_slop) {
- for (int i=0 ; i<MinSlop ; i++) {
- entry_ptr = (DataSafeEntryClass*) new char [sizeof(DataSafeEntryDataClass<T>)];
- ds_assert(entry_ptr);
- if (entry_ptr) {
- entry_ptr->Next = NULL;
- entry_ptr->Prev = NULL;
- entry_ptr->Size = sizeof(T);
- entry_ptr->IsSlop = true;
- /*
- ** Encrypt the garbage data in the uninitialized memory we just allocated for the
- ** object. It has to be encrypted to keep the CRC right.
- */
- Encrypt(&((DataSafeEntryDataClass<T>*)entry_ptr)->Data, sizeof(T), SimpleKey, true);
- /*
- ** Get a handle ID. Not really needed since we won't be returning a handle but it
- ** keeps the ID usage list neat. Fill in the rest of the handle to make it valid.
- */
- DataSafeHandleClass slop_handle;
- slop_handle.Handle.Part.ID = Get_Handle_ID(list);
- slop_handle.Handle.Part.List = list;
- slop_handle.Handle.Part.Type = Type;
- DataSafeHandleClass encrypted_slop_handle = slop_handle ^ SimpleKey;
- Checksum = Checksum ^ encrypted_slop_handle;
- entry_ptr->Handle = encrypted_slop_handle;
- /*
- ** Insert the slop entry.
- */
- Random_Insertion(entry_ptr, list, Type, true);
- }
- }
- ds_assert(Safe[list]->SlopCount == MinSlop);
- ds_assert(Safe[list]->EntryCount == MinSlop + 1);
- }
- /*
- ** Maybe remove some slop if the list is filling up.
- */
- if (Safe[list]->SlopCount != 0 && Safe[list]->EntryCount > Safe[list]->SlopCount * 2 && !is_slop) {
- /*
- ** Lots of entries here. Remove all slop by building a list of slop entries then
- ** removing them one by one.
- */
- entry_ptr = Safe[list]->SafeList;
- ds_assert(entry_ptr != NULL);
- DataSafeHandleClass removal_list[MAX_ENTRIES_PER_LIST];
- int removal_count = 0;
- if (entry_ptr) {
- /*
- ** Go through each entry in the list.
- */
- for (int j=0 ; j<Safe[list]->EntryCount ; j++) {
- /*
- ** If this is a slop entry then mark it for removal.
- */
- if (entry_ptr->IsSlop) {
- DataSafeHandleClass decode_handle = entry_ptr->Handle ^ SimpleKey;
- decode_handle = decode_handle ^ HandleKey;
- removal_list[removal_count++] = decode_handle;
- }
- /*
- ** Next entry.
- */
- entry_ptr = entry_ptr->Next;
- }
- }
- /*
- ** Remove all marked entries. Delete_Entry will fix up the lists slop count.
- */
- for (int j=0 ; j<removal_count ; j++) {
- Delete_Entry(removal_list[j]);
- }
- ds_assert(Safe[list]->SlopCount == 0);
- }
- /*
- ** Return the handle, encrypted using the handle key.
- */
- handle.Handle.Whole.WholeHandle ^= HandleKey;
- return(handle);
- }
- }
- /*
- ** Allocation error.
- */
- return((DataSafeHandleClass)-1);
- }
- /***********************************************************************************************
- * DataSafeClass::Delete_Entry -- Delete an entry from the data safe *
- * *
- * *
- * *
- * INPUT: Handle to entry *
- * *
- * OUTPUT: Nothing *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 6/25/2001 1:32PM ST : Created *
- *=============================================================================================*/
- template <class T>
- void DataSafeClass<T>::Delete_Entry(DataSafeHandleClass handle)
- {
- /*
- ** Locals.
- */
- ThreadLockClass locker;
- int list;
- int id;
- /*
- ** Asserts.
- */
- ds_assert(handle.Is_Valid());
- /*
- ** Check safe integrity.
- */
- Security_Check();
- /*
- ** The handles we give out are encrypted so we need to decrypt temporarily to extract the list number.
- */
- DataSafeHandleClass new_handle = handle ^ HandleKey;
- list = new_handle.Handle.Part.List;
- id = new_handle.Handle.Part.ID;
- /*
- ** Check that list number.
- */
- ds_assert(list >= 0);
- ds_assert(list < NumLists);
- ds_assert(Safe[list] != NULL);
- /*
- ** Get a pointer to the actual entry in the safe list.
- */
- DataSafeEntryClass *entry_ptr = Get_Entry(handle);
- ds_assert(entry_ptr != NULL);
- if (entry_ptr != NULL) {
- /*
- ** Apply the current data key to the handle to fix up the checksum.
- */
- DataSafeHandleClass match_handle = new_handle ^ SimpleKey;
- Checksum ^= match_handle;
- /*
- ** We found the entry for this handle. We need to fix up the list pointers and delete the memory.
- ** Since we originally memcpy'ed this object into place we will have to call the destructor explicitly. The explicit
- ** destructor call will have no effect if the object doesn't have a destructor defined.
- **
- ** We need to decrypt the object in place before calling the desturctor otherwise it will have a hard time acting on
- ** it's own data. This has the bonus of fixing up the checksum too.
- */
- DataSafeEntryDataClass<T> *whole_entry_ptr = (DataSafeEntryDataClass<T>*) entry_ptr;
- Decrypt(&whole_entry_ptr->Data, Get_Type_Size(Safe[list]->EntryType), SimpleKey);
- if (!whole_entry_ptr->IsSlop) {
- whole_entry_ptr->Data.T::~T();
- }
- Remove_From_List(list, entry_ptr);
- Free_Handle_ID(list, id);
- delete [] (void*) entry_ptr;
- return;
- }
- /*
- ** No match found.
- */
- WWDEBUG_SAY(("Datasafe: No item found for handle %08x\n", (int)handle));
- }
- /***********************************************************************************************
- * DataSafeClass::Get -- Get a copy of an item in the data safe. *
- * *
- * *
- * *
- * INPUT: Handle to data safe entry *
- * (out) Pointer to copy of object *
- * *
- * OUTPUT: True if object retrieved OK *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/2/2001 11:07AM ST : Created *
- *=============================================================================================*/
- template <class T>
- bool DataSafeClass<T>::Get(DataSafeHandleClass handle, T* &item)
- {
- ThreadLockClass locker;
- /*
- ** Get a pointer to the entry.
- */
- DataSafeEntryClass *entry_ptr = Get_Entry(handle);
- if (entry_ptr == NULL) {
- return(false);
- }
- DataSafeEntryDataClass<T> *data_entry_ptr = (DataSafeEntryDataClass<T>*) entry_ptr;
- /*
- ** Copy the object from the data safe and decrypt it in one pass. Don't adjust the checksum as the object is staying
- ** the same in the safe.
- */
- Mem_Copy_Decrypt(&ReturnList[ReturnIndex][0], &data_entry_ptr->Data, sizeof(T), false);
- /*
- ** Return the object.
- */
- item = (T*)(&ReturnList[ReturnIndex][0]);
- /*
- ** Fix up the return list index.
- */
- ReturnIndex++;
- if (ReturnIndex >= MAX_OBJECT_COPIES) {
- ReturnIndex = 0;
- }
- /*
- ** Move stuff around.
- */
- Shuffle();
- /*
- ** Check safe integrity.
- */
- Security_Check();
- return(true);
- }
- /***********************************************************************************************
- * DataSafeClass::Set -- Set the value of an entry in the data safe *
- * *
- * *
- * *
- * INPUT: Handle to data in the safe *
- * New value to set *
- * *
- * OUTPUT: True if handle was valid *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:11PM ST : Created *
- *=============================================================================================*/
- template <class T>
- bool DataSafeClass<T>::Set(DataSafeHandleClass handle, T *data)
- {
- ThreadLockClass locker;
- /*
- ** Get a pointer to the entry.
- */
- DataSafeEntryClass *entry_ptr = Get_Entry(handle);
- if (entry_ptr == NULL) {
- return(false);
- }
- DataSafeEntryDataClass<T> *data_entry_ptr = (DataSafeEntryDataClass<T>*) entry_ptr;
- /*
- ** Decrypt the old entry just to fix up the checksum.
- */
- Decrypt(&data_entry_ptr->Data, sizeof(T), SimpleKey, true);
- /*
- ** Copy the object into the data safe and encrypt it in one pass.
- */
- Mem_Copy_Encrypt(&data_entry_ptr->Data, data, sizeof(T), true);
- /*
- ** Move stuff around.
- */
- Shuffle();
- /*
- ** Check safe integrity.
- */
- Security_Check();
- return(true);
- }
- /*
- **
- **
- ** SafeDataClass functions.
- **
- **
- */
- /***********************************************************************************************
- * SafeDataClass::SafeDataClass -- Class constructor. Adds the data to the data safe *
- * *
- * *
- * *
- * INPUT: Initial value to store in the safe *
- * *
- * OUTPUT: Nothing *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 11:50AM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline SafeDataClass<T>::SafeDataClass(T data)
- {
- Handle = DataSafeClass<T>::Add_Entry(data);
- #ifdef WWDEBUG
- DebugData = data;
- #endif //WWDEBUG
- }
- /***********************************************************************************************
- * SafeDataClass::SafeDataClass -- Class constructor. Adds the fetches a safe handle *
- * *
- * *
- * *
- * INPUT: Nothing *
- * *
- * OUTPUT: Nothing *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 11:50AM ST : Created *
- *=============================================================================================*/
- //warning C4700: local variable 'data' used without having been initialized
- //#pragma warning(push, 0)
- //#pragma warning(disable : 4700)
- template <class T>
- SafeDataClass<T>::SafeDataClass(void)
- {
- /*
- ** The data here isn't initialised since no default value was provided. I have to provide *some* sort of
- ** init though as the bloody compiler won't let me turn off the 'local variable 'data' used without having been initialized'
- ** message. Grrrr.
- **
- ** Allocating the memory on the stack then doing an in place new seems to mollify the compiler so we don't get the warning
- ** and it does much the same thing as just declaring 'T data'. It also has the benefit that the destructor won't be called
- ** for the slop object when we exit this function but the memory will be freed.
- */
- void *stackmem = _alloca(sizeof(T));
- T *data = new (stackmem) T;
- /*
- ** Add the entry to the data safe and note the handle.
- */
- Handle = DataSafeClass<T>::Add_Entry(*data);
- #ifdef WWDEBUG
- DebugData = *data;
- #endif //WWDEBUG
- }
- //#pragma warning(pop)
- /***********************************************************************************************
- * SafeDataClass::~SafeDataClass -- Class desturctor. Removes the data from the data safe *
- * *
- * *
- * *
- * INPUT: Nothing *
- * *
- * OUTPUT: Nothing *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 11:51AM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline SafeDataClass<T>::~SafeDataClass(void)
- {
- if (Handle.Is_Valid()) {
- DataSafeClass<T>::Delete_Entry(Handle);
- }
- }
- /***********************************************************************************************
- * SafeDataClass::operator = - assignment operator. *
- * *
- * *
- * *
- * INPUT: Data to assign *
- * *
- * OUTPUT: Data assigned *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline T &SafeDataClass<T>::operator = (T const &data)
- {
- /*
- ** If we have a valid handle, then set the data into the data safe.
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Set(Handle, (T*) &data);
- ds_assert(ok);
- #ifdef WWDEBUG
- DebugData = data;
- #endif //WWDEBUG
- }
- return((T&)data);
- }
- /***********************************************************************************************
- * SafeDataClass::operator = - assignment operator for assigning from other SafeDataClass's *
- * *
- * *
- * *
- * INPUT: Data to assign *
- * *
- * OUTPUT: Data assigned *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline T &SafeDataClass<T>::operator = (SafeDataClass<T> &safedata)
- {
- /*
- ** Locals.
- */
- T *other_value = NULL;
- /*
- ** Asserts.
- */
- ds_assert(Handle.Is_Valid());
- ds_assert(safedata.Get_Handle().Is_Valid());
- ds_assert(GenericDataSafeClass::Get_Entry_Type(Handle) == GenericDataSafeClass::Get_Entry_Type(safedata.Get_Handle()));
- /*
- ** If we have a valid handle, then get the data for this handle from the data safe.
- */
- if (Handle.Is_Valid()) {
- /*
- ** Get the value for the other safe data class
- ** and set it into the safe entry with our handle.
- */
- other_value = safedata.Get_Ptr();
- ds_assert(other_value != NULL);
- if (other_value) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Set(Handle, (T*) other_value);
- ds_assert(ok);
- #ifdef WWDEBUG
- DebugData = *other_value;
- #endif //WWDEBUG
- } else {
- /*
- ** Bad error case, have to return something so use the value we already have.
- */
- return((T&)*other_value);
- }
- }
- return((T&)*other_value);
- }
- /***********************************************************************************************
- * SafeDataClass::operator == - Equality check operator. *
- * *
- * *
- * *
- * INPUT: Data to compare against *
- * *
- * OUTPUT: true if equal *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline bool SafeDataClass<T>::operator == (T const &data)
- {
- T *data_ptr = NULL;
- /*
- ** If we have a valid handle, then check the value against the supplied data.
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- ds_assert(data_ptr);
- if (data_ptr) {
- return(*data_ptr == data);
- }
- }
- return(false);
- }
- /***********************************************************************************************
- * SafeDataClass::operator == - Equality check operator. *
- * *
- * *
- * *
- * INPUT: Safe Data to compare against *
- * *
- * OUTPUT: true if equal *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline bool SafeDataClass<T>::operator == (SafeDataClass<T> &safedata)
- {
- /*
- ** Locals.
- */
- T *data_ptr = NULL;
- T *other_value = NULL;
- /*
- ** Asserts.
- */
- ds_assert(Handle.Is_Valid());
- ds_assert(safedata.Get_Handle().Is_Valid());
- ds_assert(GenericDataSafeClass::Get_Entry_Type(Handle) == GenericDataSafeClass::Get_Entry_Type(safedata.Get_Handle()));
- /*
- ** If we have a valid handle, then check the value against the supplied data.
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- ds_assert(data_ptr);
- if (data_ptr) {
- /*
- ** Looks like we have the value for this safe data class. Get the value for the other one.
- */
- other_value = safedata.Get_Ptr();
- ds_assert(other_value != NULL);
- if (other_value) {
- /*
- ** Check them against each other,
- */
- return(*data_ptr == *other_value);
- }
- }
- }
- return(false);
- }
- /***********************************************************************************************
- * SafeDataClass::operator != - Inequality check operator. *
- * *
- * *
- * *
- * INPUT: Data to compare against *
- * *
- * OUTPUT: true if not equal *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline bool SafeDataClass<T>::operator != (T const &data)
- {
- T *data_ptr = NULL;
- /*
- ** If we have a valid handle, then check the value against the supplied data.
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- ds_assert(data_ptr);
- if (data_ptr) {
- return(*data_ptr != data);
- }
- }
- return(true);
- }
- /***********************************************************************************************
- * SafeDataClass::operator != - Inequality check operator. *
- * *
- * *
- * *
- * INPUT: Data to compare against *
- * *
- * OUTPUT: true if not equal *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline bool SafeDataClass<T>::operator != (SafeDataClass<T> &safedata)
- {
- /*
- ** Locals.
- */
- T *data_ptr = NULL;
- T *other_value = NULL;
- /*
- ** Asserts.
- */
- ds_assert(Handle.Is_Valid());
- ds_assert(safedata.Get_Handle().Is_Valid());
- ds_assert(GenericDataSafeClass::Get_Entry_Type(Handle) == GenericDataSafeClass::Get_Entry_Type(safedata.Get_Handle()));
- /*
- ** If we have a valid handle, then check the value against the supplied data.
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- ds_assert(data_ptr);
- if (data_ptr) {
- /*
- ** Looks like we have the value for this safe data class. Get the value for the other one.
- */
- other_value = safedata.Get_Ptr();
- ds_assert(other_value != NULL);
- if (other_value) {
- /*
- ** Check them against each other,
- */
- return(*data_ptr != *other_value);
- }
- }
- }
- return(false);
- }
- /***********************************************************************************************
- * SafeDataClass::operator > - > operator. *
- * *
- * *
- * *
- * INPUT: Data to compare against *
- * *
- * OUTPUT: true if greater than *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline bool SafeDataClass<T>::operator > (T const &data)
- {
- T *data_ptr = NULL;
- /*
- ** If we have a valid handle, then check the value against the supplied data.
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- ds_assert(data_ptr);
- if (data_ptr) {
- return(*data_ptr > data);
- }
- }
- return(false);
- }
- /***********************************************************************************************
- * SafeDataClass::operator > - > operator. *
- * *
- * *
- * *
- * INPUT: Safe Data to compare against *
- * *
- * OUTPUT: true if greater than *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline bool SafeDataClass<T>::operator > (SafeDataClass<T> &safedata)
- {
- /*
- ** Locals.
- */
- T *data_ptr = NULL;
- T *other_value = NULL;
- /*
- ** Asserts.
- */
- ds_assert(Handle.Is_Valid());
- ds_assert(safedata.Get_Handle().Is_Valid());
- ds_assert(GenericDataSafeClass::Get_Entry_Type(Handle) == GenericDataSafeClass::Get_Entry_Type(safedata.Get_Handle()));
- /*
- ** If we have a valid handle, then check the value against the supplied data.
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- ds_assert(data_ptr);
- if (data_ptr) {
- /*
- ** Looks like we have the value for this safe data class. Get the value for the other one.
- */
- other_value = safedata.Get_Ptr();
- ds_assert(other_value != NULL);
- if (other_value) {
- /*
- ** Check them against each other,
- */
- return(*data_ptr > *other_value);
- }
- }
- }
- return(false);
- }
- /***********************************************************************************************
- * SafeDataClass::operator >= - >= operator. *
- * *
- * *
- * *
- * INPUT: Data to compare against *
- * *
- * OUTPUT: true if greater than or equal *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline bool SafeDataClass<T>::operator >= (T const &data)
- {
- T *data_ptr = NULL;
- /*
- ** If we have a valid handle, then check the value against the supplied data.
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- ds_assert(data_ptr);
- if (data_ptr) {
- return(*data_ptr >= data);
- }
- }
- return(false);
- }
- /***********************************************************************************************
- * SafeDataClass::operator >= - >= operator. *
- * *
- * *
- * *
- * INPUT: Safe Data to compare against *
- * *
- * OUTPUT: true if greater than or equal *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline bool SafeDataClass<T>::operator >= (SafeDataClass<T> &safedata)
- {
- /*
- ** Locals.
- */
- T *data_ptr = NULL;
- T *other_value = NULL;
- /*
- ** Asserts.
- */
- ds_assert(Handle.Is_Valid());
- ds_assert(safedata.Get_Handle().Is_Valid());
- ds_assert(GenericDataSafeClass::Get_Entry_Type(Handle) == GenericDataSafeClass::Get_Entry_Type(safedata.Get_Handle()));
- /*
- ** If we have a valid handle, then check the value against the supplied data.
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- ds_assert(data_ptr);
- if (data_ptr) {
- /*
- ** Looks like we have the value for this safe data class. Get the value for the other one.
- */
- other_value = safedata.Get_Ptr();
- ds_assert(other_value != NULL);
- if (other_value) {
- /*
- ** Check them against each other,
- */
- return(*data_ptr >= *other_value);
- }
- }
- }
- return(false);
- }
- /***********************************************************************************************
- * SafeDataClass::operator < - < operator. *
- * *
- * *
- * *
- * INPUT: Data to compare against *
- * *
- * OUTPUT: true if less than *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline bool SafeDataClass<T>::operator < (T const &data)
- {
- T *data_ptr = NULL;
- /*
- ** If we have a valid handle, then check the value against the supplied data.
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- ds_assert(data_ptr);
- if (data_ptr) {
- return(*data_ptr < data);
- }
- }
- return(false);
- }
- /***********************************************************************************************
- * SafeDataClass::operator < - < operator. *
- * *
- * *
- * *
- * INPUT: Safe Data to compare against *
- * *
- * OUTPUT: true if less than *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline bool SafeDataClass<T>::operator < (SafeDataClass<T> &safedata)
- {
- /*
- ** Locals.
- */
- T *data_ptr = NULL;
- T *other_value = NULL;
- /*
- ** Asserts.
- */
- ds_assert(Handle.Is_Valid());
- ds_assert(safedata.Get_Handle().Is_Valid());
- ds_assert(GenericDataSafeClass::Get_Entry_Type(Handle) == GenericDataSafeClass::Get_Entry_Type(safedata.Get_Handle()));
- /*
- ** If we have a valid handle, then check the value against the supplied data.
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- ds_assert(data_ptr);
- if (data_ptr) {
- /*
- ** Looks like we have the value for this safe data class. Get the value for the other one.
- */
- other_value = safedata.Get_Ptr();
- ds_assert(other_value != NULL);
- if (other_value) {
- /*
- ** Check them against each other,
- */
- return(*data_ptr < *other_value);
- }
- }
- }
- return(false);
- }
- /***********************************************************************************************
- * SafeDataClass::operator <= - <= operator. *
- * *
- * *
- * *
- * INPUT: Data to compare against *
- * *
- * OUTPUT: true if less than or equal *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline bool SafeDataClass<T>::operator <= (T const &data)
- {
- T *data_ptr = NULL;
- /*
- ** If we have a valid handle, then check the value against the supplied data.
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- ds_assert(data_ptr);
- if (data_ptr) {
- return(*data_ptr <= data);
- }
- }
- return(false);
- }
- /***********************************************************************************************
- * SafeDataClass::operator <= - <= operator. *
- * *
- * *
- * *
- * INPUT: Safe Data to compare against *
- * *
- * OUTPUT: true if less than or equal *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline bool SafeDataClass<T>::operator <= (SafeDataClass<T> &safedata)
- {
- /*
- ** Locals.
- */
- T *data_ptr = NULL;
- T *other_value = NULL;
- /*
- ** Asserts.
- */
- ds_assert(Handle.Is_Valid());
- ds_assert(safedata.Get_Handle().Is_Valid());
- ds_assert(GenericDataSafeClass::Get_Entry_Type(Handle) == GenericDataSafeClass::Get_Entry_Type(safedata.Get_Handle()));
- /*
- ** If we have a valid handle, then check the value against the supplied data.
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- ds_assert(data_ptr);
- if (data_ptr) {
- /*
- ** Looks like we have the value for this safe data class. Get the value for the other one.
- */
- other_value = safedata.Get_Ptr();
- ds_assert(other_value != NULL);
- if (other_value) {
- /*
- ** Check them against each other,
- */
- return(*data_ptr <= *other_value);
- }
- }
- }
- return(false);
- }
- /***********************************************************************************************
- * SafeDataClass::operator + - + operator. *
- * *
- * *
- * *
- * INPUT: Data to add *
- * *
- * OUTPUT: Result *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline T &SafeDataClass<T>::operator + (T const &value)
- {
- /*
- ** Locals.
- */
- T *data_ptr = NULL;
- /*
- ** Asserts.
- */
- ds_assert(Handle.Is_Valid());
- /*
- ** If we have a valid handle, then get the current value and apply the change
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- ds_assert(data_ptr);
- if (data_ptr) {
- *data_ptr = *data_ptr + value;
- return((T&)*data_ptr);
- }
- }
- /*
- ** Error case, have to return something.
- */
- return((T&)ErrorVal[0]);
- }
- /***********************************************************************************************
- * SafeDataClass::operator + - + operator *
- * *
- * *
- * *
- * INPUT: Data to add *
- * *
- * OUTPUT: Result *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline T &SafeDataClass<T>::operator + (SafeDataClass<T> &safevalue)
- {
- /*
- ** Locals.
- */
- T *data_ptr = NULL;
- T *other_value = NULL;
- /*
- ** Asserts.
- */
- ds_assert(Handle.Is_Valid());
- ds_assert(safevalue.Get_Handle().Is_Valid());
- ds_assert(GenericDataSafeClass::Get_Entry_Type(Handle) == GenericDataSafeClass::Get_Entry_Type(safevalue.Get_Handle()));
- /*
- ** If we have a valid handle, then get the data for this handle from the data safe.
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- ds_assert(data_ptr);
- if (data_ptr) {
- /*
- ** Looks like we have the value for this safe data class. Get the value for the other one.
- ** and do the math.
- */
- other_value = safevalue.Get_Ptr();
- ds_assert(other_value != NULL);
- if (other_value) {
- *data_ptr = *data_ptr + *other_value;
- return((T&)*data_ptr);
- } else {
- /*
- ** Bad error case, have to return something so use the value we already have.
- */
- return((T&)*data_ptr);
- }
- }
- }
- /*
- ** Error case, have to return something.
- */
- return((T&)ErrorVal[0]);
- }
- /***********************************************************************************************
- * SafeDataClass::operator += - += operator. *
- * *
- * *
- * *
- * INPUT: Data to add *
- * *
- * OUTPUT: Result *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline T &SafeDataClass<T>::operator += (T const &value)
- {
- /*
- ** Locals.
- */
- T *data_ptr = NULL;
- /*
- ** Asserts.
- */
- ds_assert(Handle.Is_Valid());
- /*
- ** If we have a valid handle, then get the current value and apply the change
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- ds_assert(data_ptr);
- if (data_ptr) {
- *data_ptr = *data_ptr + value;
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Set(Handle, data_ptr);
- ds_assert(ok);
- #ifdef WWDEBUG
- DebugData = *data_ptr;
- #endif //WWDEBUG
- return((T&)*data_ptr);
- }
- }
- /*
- ** Error case, have to return something.
- */
- return((T&)ErrorVal[0]);
- }
- /***********************************************************************************************
- * SafeDataClass::operator += - += operator *
- * *
- * *
- * *
- * INPUT: Data to add *
- * *
- * OUTPUT: Result *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline T &SafeDataClass<T>::operator += (SafeDataClass<T> &safevalue)
- {
- /*
- ** Locals.
- */
- T *data_ptr = NULL;
- T *other_value = NULL;
- /*
- ** Asserts.
- */
- ds_assert(Handle.Is_Valid());
- ds_assert(safevalue.Get_Handle().Is_Valid());
- ds_assert(GenericDataSafeClass::Get_Entry_Type(Handle) == GenericDataSafeClass::Get_Entry_Type(safevalue.Get_Handle()));
- /*
- ** If we have a valid handle, then get the data for this handle from the data safe.
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- ds_assert(data_ptr);
- if (data_ptr) {
- /*
- ** Looks like we have the value for this safe data class. Get the value for the other one.
- ** and do the math.
- */
- other_value = safevalue.Get_Ptr();
- ds_assert(other_value != NULL);
- if (other_value) {
- *data_ptr = *data_ptr + *other_value;
- #ifdef WWDEBUG
- ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Set(Handle, data_ptr);
- ds_assert(ok);
- #ifdef WWDEBUG
- DebugData = *data_ptr;
- #endif //WWDEBUG
- return((T&)*data_ptr);
- } else {
- /*
- ** Bad error case, have to return something so use the value we already have.
- */
- return((T&)*data_ptr);
- }
- }
- }
- /*
- ** Error case, have to return something.
- */
- return((T&)ErrorVal[0]);
- }
- /***********************************************************************************************
- * SafeDataClass::operator - - - operator. *
- * *
- * *
- * *
- * INPUT: Data to subtract *
- * *
- * OUTPUT: Result *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline T &SafeDataClass<T>::operator - (T const &value)
- {
- /*
- ** Locals.
- */
- T *data_ptr = NULL;
- /*
- ** Asserts.
- */
- ds_assert(Handle.Is_Valid());
- /*
- ** If we have a valid handle, then get the current value and apply the change
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- ds_assert(data_ptr);
- if (data_ptr) {
- *data_ptr = *data_ptr - value;
- return((T&)*data_ptr);
- }
- }
- /*
- ** Error case, have to return something.
- */
- return((T&)ErrorVal[0]);
- }
- /***********************************************************************************************
- * SafeDataClass::operator - - - operator *
- * *
- * *
- * *
- * INPUT: Data to subtract *
- * *
- * OUTPUT: Result *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline T &SafeDataClass<T>::operator - (SafeDataClass<T> &safevalue)
- {
- /*
- ** Locals.
- */
- T *data_ptr = NULL;
- T *other_value = NULL;
- /*
- ** Asserts.
- */
- ds_assert(Handle.Is_Valid());
- ds_assert(safevalue.Get_Handle().Is_Valid());
- ds_assert(GenericDataSafeClass::Get_Entry_Type(Handle) == GenericDataSafeClass::Get_Entry_Type(safevalue.Get_Handle()));
- /*
- ** If we have a valid handle, then get the data for this handle from the data safe.
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- ds_assert(data_ptr);
- if (data_ptr) {
- /*
- ** Looks like we have the value for this safe data class. Get the value for the other one.
- ** and do the math.
- */
- other_value = safevalue.Get_Ptr();
- ds_assert(other_value != NULL);
- if (other_value) {
- *data_ptr = *data_ptr - *other_value;
- return((T&)*data_ptr);
- } else {
- /*
- ** Bad error case, have to return something so use the value we already have.
- */
- return((T&)*data_ptr);
- }
- }
- }
- /*
- ** Error case, have to return something.
- */
- return((T&)ErrorVal[0]);
- }
- /***********************************************************************************************
- * SafeDataClass::operator -= - -= operator. *
- * *
- * *
- * *
- * INPUT: Data to subtract *
- * *
- * OUTPUT: Result *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline T &SafeDataClass<T>::operator -= (T const &value)
- {
- /*
- ** Locals.
- */
- T *data_ptr = NULL;
- /*
- ** Asserts.
- */
- ds_assert(Handle.Is_Valid());
- /*
- ** If we have a valid handle, then get the current value and apply the change
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- ds_assert(data_ptr);
- if (data_ptr) {
- *data_ptr = *data_ptr - value;
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Set(Handle, data_ptr);
- ds_assert(ok);
- #ifdef WWDEBUG
- DebugData = *data_ptr;
- #endif //WWDEBUG
- return((T&)*data_ptr);
- }
- }
- /*
- ** Error case, have to return something.
- */
- return((T&)ErrorVal[0]);
- }
- /***********************************************************************************************
- * SafeDataClass::operator -= - -= operator *
- * *
- * *
- * *
- * INPUT: Data to subtract *
- * *
- * OUTPUT: Result *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline T &SafeDataClass<T>::operator -= (SafeDataClass<T> &safevalue)
- {
- /*
- ** Locals.
- */
- T *data_ptr = NULL;
- T *other_value = NULL;
- /*
- ** Asserts.
- */
- ds_assert(Handle.Is_Valid());
- ds_assert(safevalue.Get_Handle().Is_Valid());
- ds_assert(GenericDataSafeClass::Get_Entry_Type(Handle) == GenericDataSafeClass::Get_Entry_Type(safevalue.Get_Handle()));
- /*
- ** If we have a valid handle, then get the data for this handle from the data safe.
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- ds_assert(data_ptr);
- if (data_ptr) {
- /*
- ** Looks like we have the value for this safe data class. Get the value for the other one.
- ** and do the math.
- */
- other_value = safevalue.Get_Ptr();
- ds_assert(other_value != NULL);
- if (other_value) {
- *data_ptr = *data_ptr - *other_value;
- #ifdef WWDEBUG
- ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Set(Handle, data_ptr);
- ds_assert(ok);
- #ifdef WWDEBUG
- DebugData = *data_ptr;
- #endif //WWDEBUG
- return((T&)*data_ptr);
- } else {
- /*
- ** Bad error case, have to return something so use the value we already have.
- */
- return((T&)*data_ptr);
- }
- }
- }
- /*
- ** Error case, have to return something.
- */
- return((T&)ErrorVal[0]);
- }
- /***********************************************************************************************
- * SafeDataClass::operator * - * operator. *
- * *
- * *
- * *
- * INPUT: Data to multiply by *
- * *
- * OUTPUT: Result *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline T &SafeDataClass<T>::operator * (T const &value)
- {
- /*
- ** Locals.
- */
- T *data_ptr = NULL;
- /*
- ** Asserts.
- */
- ds_assert(Handle.Is_Valid());
- /*
- ** If we have a valid handle, then get the current value and apply the change
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- ds_assert(data_ptr);
- if (data_ptr) {
- *data_ptr = *data_ptr * value;
- return((T&)*data_ptr);
- }
- }
- /*
- ** Error case, have to return something.
- */
- return((T&)ErrorVal[0]);
- }
- /***********************************************************************************************
- * SafeDataClass::operator * - * operator *
- * *
- * *
- * *
- * INPUT: Data to multiply by *
- * *
- * OUTPUT: Result *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline T &SafeDataClass<T>::operator * (SafeDataClass<T> &safevalue)
- {
- /*
- ** Locals.
- */
- T *data_ptr = NULL;
- T *other_value = NULL;
- /*
- ** Asserts.
- */
- ds_assert(Handle.Is_Valid());
- ds_assert(safevalue.Get_Handle().Is_Valid());
- ds_assert(GenericDataSafeClass::Get_Entry_Type(Handle) == GenericDataSafeClass::Get_Entry_Type(safevalue.Get_Handle()));
- /*
- ** If we have a valid handle, then get the data for this handle from the data safe.
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- ds_assert(data_ptr);
- if (data_ptr) {
- /*
- ** Looks like we have the value for this safe data class. Get the value for the other one.
- ** and do the math.
- */
- other_value = safevalue.Get_Ptr();
- ds_assert(other_value != NULL);
- if (other_value) {
- *data_ptr = *data_ptr * *other_value;
- return((T&)*data_ptr);
- } else {
- /*
- ** Bad error case, have to return something so use the value we already have.
- */
- return((T&)*data_ptr);
- }
- }
- }
- /*
- ** Error case, have to return something.
- */
- return((T&)ErrorVal[0]);
- }
- /***********************************************************************************************
- * SafeDataClass::operator *= - *= operator. *
- * *
- * *
- * *
- * INPUT: Data to multiply by *
- * *
- * OUTPUT: Result *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline T &SafeDataClass<T>::operator *= (T const &value)
- {
- /*
- ** Locals.
- */
- T *data_ptr = NULL;
- /*
- ** Asserts.
- */
- ds_assert(Handle.Is_Valid());
- /*
- ** If we have a valid handle, then get the current value and apply the change
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- ds_assert(data_ptr);
- if (data_ptr) {
- *data_ptr = *data_ptr * value;
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Set(Handle, data_ptr);
- ds_assert(ok);
- #ifdef WWDEBUG
- DebugData = *data_ptr;
- #endif //WWDEBUG
- return((T&)*data_ptr);
- }
- }
- /*
- ** Error case, have to return something.
- */
- return((T&)ErrorVal[0]);
- }
- /***********************************************************************************************
- * SafeDataClass::operator *= - *= operator *
- * *
- * *
- * *
- * INPUT: Data to multiply by *
- * *
- * OUTPUT: Result *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline T &SafeDataClass<T>::operator *= (SafeDataClass<T> &safevalue)
- {
- /*
- ** Locals.
- */
- T *data_ptr = NULL;
- T *other_value = NULL;
- /*
- ** Asserts.
- */
- ds_assert(Handle.Is_Valid());
- ds_assert(safevalue.Get_Handle().Is_Valid());
- ds_assert(GenericDataSafeClass::Get_Entry_Type(Handle) == GenericDataSafeClass::Get_Entry_Type(safevalue.Get_Handle()));
- /*
- ** If we have a valid handle, then get the data for this handle from the data safe.
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- ds_assert(data_ptr);
- if (data_ptr) {
- /*
- ** Looks like we have the value for this safe data class. Get the value for the other one.
- ** and do the math.
- */
- other_value = safevalue.Get_Ptr();
- ds_assert(other_value != NULL);
- if (other_value) {
- *data_ptr = *data_ptr * *other_value;
- #ifdef WWDEBUG
- ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Set(Handle, data_ptr);
- ds_assert(ok);
- #ifdef WWDEBUG
- DebugData = *data_ptr;
- #endif //WWDEBUG
- return((T&)*data_ptr);
- } else {
- /*
- ** Bad error case, have to return something so use the value we already have.
- */
- return((T&)*data_ptr);
- }
- }
- }
- /*
- ** Error case, have to return something.
- */
- return((T&)ErrorVal[0]);
- }
- /***********************************************************************************************
- * SafeDataClass::operator / - / operator. *
- * *
- * *
- * *
- * INPUT: Data to divide by *
- * *
- * OUTPUT: Result *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline T &SafeDataClass<T>::operator / (T const &value)
- {
- /*
- ** Locals.
- */
- T *data_ptr = NULL;
- /*
- ** Asserts.
- */
- ds_assert(Handle.Is_Valid());
- ds_assert(value != 0);
- /*
- ** If we have a valid handle, then get the current value and apply the change
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- ds_assert(data_ptr);
- if (data_ptr) {
- *data_ptr = *data_ptr / value;
- return((T&)*data_ptr);
- }
- }
- /*
- ** Error case, have to return something.
- */
- return((T&)ErrorVal[0]);
- }
- /***********************************************************************************************
- * SafeDataClass::operator / - / operator *
- * *
- * *
- * *
- * INPUT: Data to divide by *
- * *
- * OUTPUT: Result *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline T &SafeDataClass<T>::operator / (SafeDataClass<T> &safevalue)
- {
- /*
- ** Locals.
- */
- T *data_ptr = NULL;
- T *other_value = NULL;
- /*
- ** Asserts.
- */
- ds_assert(Handle.Is_Valid());
- ds_assert(safevalue.Get_Handle().Is_Valid());
- ds_assert(GenericDataSafeClass::Get_Entry_Type(Handle) == GenericDataSafeClass::Get_Entry_Type(safevalue.Get_Handle()));
- /*
- ** If we have a valid handle, then get the data for this handle from the data safe.
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- ds_assert(data_ptr);
- if (data_ptr) {
- /*
- ** Looks like we have the value for this safe data class. Get the value for the other one.
- ** and do the math.
- */
- other_value = safevalue.Get_Ptr();
- ds_assert(other_value != NULL);
- if (other_value) {
- ds_assert(*other_value != 0);
- *data_ptr = *data_ptr / *other_value;
- return((T&)*data_ptr);
- } else {
- /*
- ** Bad error case, have to return something so use the value we already have.
- */
- return((T&)*data_ptr);
- }
- }
- }
- /*
- ** Error case, have to return something.
- */
- return((T&)ErrorVal[0]);
- }
- /***********************************************************************************************
- * SafeDataClass::operator /= - /= operator. *
- * *
- * *
- * *
- * INPUT: Data to divide by *
- * *
- * OUTPUT: Result *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline T &SafeDataClass<T>::operator /= (T const &value)
- {
- /*
- ** Locals.
- */
- T *data_ptr = NULL;
- /*
- ** Asserts.
- */
- ds_assert(Handle.Is_Valid());
- ds_assert(value != 0);
- /*
- ** If we have a valid handle, then get the current value and apply the change
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- ds_assert(data_ptr);
- if (data_ptr) {
- *data_ptr = *data_ptr / value;
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Set(Handle, data_ptr);
- ds_assert(ok);
- #ifdef WWDEBUG
- DebugData = *data_ptr;
- #endif //WWDEBUG
- return((T&)*data_ptr);
- }
- }
- /*
- ** Error case, have to return something.
- */
- return((T&)ErrorVal[0]);
- }
- /***********************************************************************************************
- * SafeDataClass::operator /= - /= operator *
- * *
- * *
- * *
- * INPUT: Data to divide by *
- * *
- * OUTPUT: Result *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline T &SafeDataClass<T>::operator /= (SafeDataClass<T> &safevalue)
- {
- /*
- ** Locals.
- */
- T *data_ptr = NULL;
- T *other_value = NULL;
- /*
- ** Asserts.
- */
- ds_assert(Handle.Is_Valid());
- ds_assert(safevalue.Get_Handle().Is_Valid());
- ds_assert(GenericDataSafeClass::Get_Entry_Type(Handle) == GenericDataSafeClass::Get_Entry_Type(safevalue.Get_Handle()));
- /*
- ** If we have a valid handle, then get the data for this handle from the data safe.
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- ds_assert(data_ptr);
- if (data_ptr) {
- /*
- ** Looks like we have the value for this safe data class. Get the value for the other one.
- ** and do the math.
- */
- other_value = safevalue.Get_Ptr();
- ds_assert(other_value != NULL);
- if (other_value) {
- ds_assert(*other_value != 0);
- *data_ptr = *data_ptr / *other_value;
- #ifdef WWDEBUG
- ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Set(Handle, data_ptr);
- ds_assert(ok);
- #ifdef WWDEBUG
- DebugData = *data_ptr;
- #endif //WWDEBUG
- return((T&)*data_ptr);
- } else {
- /*
- ** Bad error case, have to return something so use the value we already have.
- */
- return((T&)*data_ptr);
- }
- }
- }
- /*
- ** Error case, have to return something.
- */
- return((T&)ErrorVal[0]);
- }
- /***********************************************************************************************
- * SafeDataClass::operator ++ - prefix increment operator. *
- * *
- * *
- * *
- * INPUT: Nothing *
- * *
- * OUTPUT: Result *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline T &SafeDataClass<T>::operator ++ (void)
- {
- /*
- ** Locals.
- */
- T *data_ptr = NULL;
- /*
- ** Asserts.
- */
- ds_assert(Handle.Is_Valid());
- /*
- ** If we have a valid handle, then get the current value and apply the change
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- ds_assert(data_ptr);
- if (data_ptr) {
- (*data_ptr)++;
- #ifdef WWDEBUG
- ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Set(Handle, data_ptr);
- ds_assert(ok);
- #ifdef WWDEBUG
- DebugData = *data_ptr;
- #endif //WWDEBUG
- return((T&)*data_ptr);
- }
- }
- /*
- ** Error case, have to return something.
- */
- return((T&)ErrorVal[0]);
- }
- /***********************************************************************************************
- * SafeDataClass::operator -- - prefix decrement operator. *
- * *
- * *
- * *
- * INPUT: Nothing *
- * *
- * OUTPUT: Result *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline T &SafeDataClass<T>::operator -- (void)
- {
- /*
- ** Locals.
- */
- T *data_ptr = NULL;
- /*
- ** Asserts.
- */
- ds_assert(Handle.Is_Valid());
- /*
- ** If we have a valid handle, then get the current value and apply the change
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- ds_assert(data_ptr);
- if (data_ptr) {
- (*data_ptr)--;
- #ifdef WWDEBUG
- ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Set(Handle, data_ptr);
- ds_assert(ok);
- #ifdef WWDEBUG
- DebugData = *data_ptr;
- #endif //WWDEBUG
- return((T&)*data_ptr);
- }
- }
- /*
- ** Error case, have to return something.
- */
- return((T&)ErrorVal[0]);
- }
- /***********************************************************************************************
- * SafeDataClass::operator ++ - postfix ++ operator *
- * *
- * *
- * *
- * INPUT: int (not used, denotes postfix operator) *
- * *
- * OUTPUT: Nothing *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/23/2001 3:54PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline T &SafeDataClass<T>::operator ++ (int)
- {
- /*
- ** Just call the prefix version of the operator.
- */
- return(this->operator ++ ());
- }
- /***********************************************************************************************
- * SafeDataClass::operator -- - postfix -- operator *
- * *
- * *
- * *
- * INPUT: int (not used, denotes postfix operator) *
- * *
- * OUTPUT: Nothing *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/23/2001 3:54PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline T &SafeDataClass<T>::operator -- (int)
- {
- /*
- ** Just call the prefix version of the operator.
- */
- return(this->operator -- ());
- }
- /***********************************************************************************************
- * SafeDataClass::operator () - Conversion operator used for data retrieval *
- * *
- * *
- * *
- * INPUT: nothing *
- * *
- * OUTPUT: Copy of data in safe *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline T &SafeDataClass<T>::operator () (void) const
- {
- T *data_ptr = NULL;
- /*
- ** If the handle we have is valid then use it to get a pointer to a temporary copy of the data safe contents for this
- ** handle.
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- if (data_ptr) {
- return(*data_ptr);
- }
- }
- /*
- ** Error case. Need to return some valid value.
- */
- static T oh_dear;
- return(oh_dear);
- }
- /***********************************************************************************************
- * SafeDataClass::operator int -- Return the data for this class as an int *
- * *
- * *
- * *
- * INPUT: Nothing *
- * *
- * OUTPUT: Data cast to int *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/6/2001 11:47AM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline SafeDataClass<T>::operator int (void) const
- {
- ds_assert(sizeof(T) == sizeof(int));
- T *data_ptr = NULL;
- #ifdef WWDEBUG
- /*
- ** Check that T is safe to return as an int
- */
- T x = 0;
- int y = (T)x;
- ds_assert(x == y);
- #endif //WWDEBUG
- /*
- ** If the handle we have is valid then use it to get a pointer to a temporary copy of the data safe contents for this
- ** handle.
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- if (data_ptr) {
- return(*((int*)data_ptr));
- }
- }
- /*
- ** Error case. Need to return some valid value.
- */
- static int oh_dear;
- return(oh_dear);
- }
- /***********************************************************************************************
- * SafeDataClass::operator unsigned int -- Return the data for this class as an unsigned int *
- * *
- * *
- * *
- * INPUT: Nothing *
- * *
- * OUTPUT: Data cast to unsigned int *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/6/2001 11:47AM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline SafeDataClass<T>::operator unsigned int (void) const
- {
- ds_assert(sizeof(T) == sizeof(unsigned int));
- T *data_ptr = NULL;
- #ifdef WWDEBUG
- /*
- ** Check that T is safe to return as an unsigned int
- */
- T x = 0;
- unsigned int y = (T)x;
- ds_assert(x == y);
- #endif //WWDEBUG
- /*
- ** If the handle we have is valid then use it to get a pointer to a temporary copy of the data safe contents for this
- ** handle.
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- if (data_ptr) {
- return(*((unsigned int*)data_ptr));
- }
- }
- /*
- ** Error case. Need to return some valid value.
- */
- static unsigned int oh_dear;
- return(oh_dear);
- }
- /***********************************************************************************************
- * SafeDataClass::operator long -- Return the data for this class as a long *
- * *
- * *
- * *
- * INPUT: Nothing *
- * *
- * OUTPUT: Data cast to long *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/6/2001 11:47AM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline SafeDataClass<T>::operator long (void) const
- {
- ds_assert(sizeof(T) == sizeof(long));
- T *data_ptr = NULL;
- #ifdef WWDEBUG
- /*
- ** Check that T is safe to return as a long
- */
- T x = 0;
- long y = (T)x;
- ds_assert(x == y);
- #endif //WWDEBUG
- /*
- ** If the handle we have is valid then use it to get a pointer to a temporary copy of the data safe contents for this
- ** handle.
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- if (data_ptr) {
- return(*((long*)data_ptr));
- }
- }
- /*
- ** Error case. Need to return some valid value.
- */
- static long oh_dear;
- return(oh_dear);
- }
- /***********************************************************************************************
- * SafeDataClass::operator int -- Return the data for this class as an unsigned long *
- * *
- * *
- * *
- * INPUT: Nothing *
- * *
- * OUTPUT: Data cast to unsigned long *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/6/2001 11:47AM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline SafeDataClass<T>::operator unsigned long (void) const
- {
- ds_assert(sizeof(T) == sizeof(unsigned long));
- T *data_ptr = NULL;
- #ifdef WWDEBUG
- /*
- ** Check that T is safe to return as an unsigned long
- */
- T x = 0;
- unsigned long y = (T)x;
- ds_assert(x == y);
- #endif //WWDEBUG
- /*
- ** If the handle we have is valid then use it to get a pointer to a temporary copy of the data safe contents for this
- ** handle.
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- if (data_ptr) {
- return(*((unsigned long*)data_ptr));
- }
- }
- /*
- ** Error case. Need to return some valid value.
- */
- static unsigned long oh_dear;
- return(oh_dear);
- }
- /***********************************************************************************************
- * SafeDataClass::operator int -- Return the data for this class as a float *
- * *
- * *
- * *
- * INPUT: Nothing *
- * *
- * OUTPUT: Data cast to float *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/6/2001 11:47AM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline SafeDataClass<T>::operator float (void) const
- {
- ds_assert(sizeof(T) == sizeof(float));
- T *data_ptr = NULL;
- #ifdef WWDEBUG
- /*
- ** Check that T is safe to return as a float
- */
- T x = 0;
- float y = (T)x;
- ds_assert(x == y);
- #endif //WWDEBUG
- /*
- ** If the handle we have is valid then use it to get a pointer to a temporary copy of the data safe contents for this
- ** handle.
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- if (data_ptr) {
- return(*((float*)data_ptr));
- }
- }
- /*
- ** Error case. Need to return some valid value.
- */
- static float oh_dear;
- return(oh_dear);
- }
- /***********************************************************************************************
- * SafeDataClass::operator int -- Return the data for this class as a double *
- * *
- * *
- * *
- * INPUT: Nothing *
- * *
- * OUTPUT: Data cast to double *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/6/2001 11:47AM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline SafeDataClass<T>::operator double (void) const
- {
- ds_assert(sizeof(T) == sizeof(double));
- T *data_ptr = NULL;
- #ifdef WWDEBUG
- /*
- ** Check that T is safe to return as a double
- */
- T x = 0;
- double y = (T)x;
- ds_assert(x == y);
- #endif //WWDEBUG
- /*
- ** If the handle we have is valid then use it to get a pointer to a temporary copy of the data safe contents for this
- ** handle.
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- if (data_ptr) {
- return(*((double*)data_ptr));
- }
- }
- /*
- ** Error case. Need to return some valid value.
- */
- static double oh_dear;
- return(oh_dear);
- }
- /***********************************************************************************************
- * SafeDataClass::Get_Ptr - Get a pointer to a decrypted version of a class in the data safe *
- * *
- * *
- * *
- * INPUT: nothing *
- * *
- * OUTPUT: Ptr to copy of data in safe *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/3/2001 12:05PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline T *SafeDataClass<T>::Get_Ptr(void) const
- {
- T *data_ptr = NULL;
- /*
- ** If the handle we have is valid then use it to get a pointer to a temporary copy of the data safe contents for this
- ** handle.
- */
- if (Handle.Is_Valid()) {
- #ifdef WWDEBUG
- bool ok =
- #endif //WWDEBUG
- DataSafeClass<T>::Get(Handle, data_ptr);
- ds_assert(ok);
- if (data_ptr) {
- return(data_ptr);
- }
- }
- /*
- ** Error case.
- */
- ds_assert(false);
- return(NULL);
- }
- /***********************************************************************************************
- * SafeDataClass::Commit -- Write decrypted data safe data back into the safe *
- * *
- * *
- * *
- * INPUT: Ptr to data (must be from prior return list) *
- * *
- * OUTPUT: True if commited back into the safe *
- * *
- * WARNINGS: None *
- * *
- * HISTORY: *
- * 7/13/2001 2:28PM ST : Created *
- *=============================================================================================*/
- template <class T>
- inline bool SafeDataClass<T>::Commit(T *data_ptr) const
- {
- ds_assert(Handle.Is_Valid());
- ds_assert(DataSafeClass<T>::In_Return_List(data_ptr));
- /*
- ** If the handle is valid, and the data pointer is one of our temporary return buffers
- ** then copy the data back into the safe.
- */
- if (Handle.Is_Valid()) {
- /*
- ** Verify it's one of our temp data pointers.
- */
- if (DataSafeClass<T>::In_Return_List(data_ptr)) {
- #ifdef WWDEBUG
- DebugData = *data_ptr;
- #endif //WWDEBUG
- return(DataSafeClass<T>::Set(Handle, data_ptr));
- }
- }
- return(false);
- }
- #pragma warning(default : 4189)
- #pragma warning(default : 4101)
- #endif //_DATASAFE_H
|