extensions/sdktools/vdecoder.cpp
author David Anderson <dvander@alliedmods.net>
Sat Jun 16 15:40:22 2007 +0000 (2007-06-16)
changeset 953 801e27ece340
parent 950 ac855ba24c7d
child 954 3dd58fa4ccdc
permissions -rw-r--r--
added by-address calling
dvander@950
     1
#include "smsdk_ext.h"
dvander@950
     2
#include "extension.h"
dvander@950
     3
#include "vdecoder.h"
dvander@950
     4
dvander@950
     5
using namespace SourceMod;
dvander@950
     6
using namespace SourcePawn;
dvander@950
     7
dvander@950
     8
/**
dvander@950
     9
 * For object pointers, the data looks like this instead:
dvander@950
    10
 * 4 bytes: POINTER TO NEXT FOUR BYTES
dvander@950
    11
 * + bytes: Object internal data
dvander@950
    12
 *
dvander@950
    13
 * We use the virtual stack as extra fake stack space and create a temp object.
dvander@950
    14
 * If these objects had destructors, we'd need to fake destroy toom of course.
dvander@950
    15
 * Of course, BinTools only reads the first four bytes and passes the pointer.
dvander@950
    16
 */
dvander@950
    17
dvander@950
    18
size_t ValveParamToBinParam(ValveType type, 
dvander@950
    19
						  PassType pass,
dvander@950
    20
						  unsigned int flags,
dvander@950
    21
						  PassInfo *info)
dvander@950
    22
{
dvander@950
    23
	switch (type)
dvander@950
    24
	{
dvander@950
    25
	case Valve_Vector:
dvander@950
    26
		{
dvander@950
    27
			size_t mySize = sizeof(Vector *);
dvander@950
    28
			if (pass == PassType_Basic)
dvander@950
    29
			{
dvander@950
    30
				if (info->flags & PASSFLAG_BYREF)
dvander@950
    31
				{
dvander@950
    32
					return 0;
dvander@950
    33
				}
dvander@950
    34
				info->type = PassType_Basic;
dvander@950
    35
				info->flags = flags;
dvander@950
    36
				info->size = sizeof(Vector *);
dvander@950
    37
				mySize += sizeof(Vector);
dvander@950
    38
			} else if (pass == PassType_Object) {
dvander@950
    39
				info->type = PassType_Object;
dvander@950
    40
				info->flags = flags | PASSFLAG_OASSIGNOP | PASSFLAG_OCTOR;
dvander@950
    41
				info->size = sizeof(Vector);
dvander@950
    42
			} else {
dvander@950
    43
				return 0;
dvander@950
    44
			}
dvander@950
    45
			return mySize;
dvander@950
    46
		}
dvander@950
    47
	case Valve_QAngle:
dvander@950
    48
		{
dvander@950
    49
			size_t mySize = sizeof(QAngle *);
dvander@950
    50
			if (pass == PassType_Basic)
dvander@950
    51
			{
dvander@950
    52
				if (info->flags & PASSFLAG_BYREF)
dvander@950
    53
				{
dvander@950
    54
					return 0;
dvander@950
    55
				}
dvander@950
    56
				info->type = PassType_Basic;
dvander@950
    57
				info->flags = flags;
dvander@950
    58
				info->size = sizeof(QAngle *);
dvander@950
    59
				mySize += sizeof(QAngle);
dvander@950
    60
			} else if (pass == PassType_Object) {
dvander@950
    61
				info->type = PassType_Object;
dvander@950
    62
				info->flags = flags | PASSFLAG_OASSIGNOP | PASSFLAG_OCTOR;
dvander@950
    63
				info->size = sizeof(QAngle);
dvander@950
    64
			} else {
dvander@950
    65
				return 0;
dvander@950
    66
			}
dvander@950
    67
			return mySize;
dvander@950
    68
		}
dvander@950
    69
	case Valve_CBaseEntity:
dvander@950
    70
	case Valve_CBasePlayer:
dvander@950
    71
	case Valve_POD:
dvander@950
    72
	case Valve_Edict:
dvander@950
    73
	case Valve_String:
dvander@950
    74
		{
dvander@950
    75
			if (pass != PassType_Basic
dvander@950
    76
				|| (info->flags & PASSFLAG_BYREF))
dvander@950
    77
			{
dvander@950
    78
				return 0;
dvander@950
    79
			}
dvander@950
    80
			info->type = PassType_Basic;
dvander@950
    81
			info->flags = flags;
dvander@950
    82
			info->size = sizeof(void *);
dvander@950
    83
			return sizeof(void *);
dvander@950
    84
		}
dvander@950
    85
	case Valve_Float:
dvander@950
    86
		{
dvander@950
    87
			info->type = PassType_Float;
dvander@950
    88
			info->flags = flags;
dvander@950
    89
			info->size = sizeof(float);
dvander@950
    90
			return sizeof(float);
dvander@950
    91
		}
dvander@950
    92
	}
dvander@950
    93
dvander@950
    94
	return 0;
dvander@950
    95
}
dvander@950
    96
dvander@950
    97
DataStatus EncodeValveParam(IPluginContext *pContext,
dvander@950
    98
							cell_t param, 
dvander@950
    99
							ValveType type, 
dvander@950
   100
							PassType pass, 
dvander@950
   101
							const void *buffer)
dvander@950
   102
{
dvander@950
   103
	switch (type)
dvander@950
   104
	{
dvander@950
   105
	case Valve_Vector:
dvander@950
   106
		{
dvander@950
   107
			Vector *v = NULL;
dvander@950
   108
dvander@950
   109
			if (pass == PassType_Basic)
dvander@950
   110
			{
dvander@950
   111
				v = *(Vector **)((unsigned char *)buffer + sizeof(Vector *));
dvander@950
   112
			} else if (pass == PassType_Object) {
dvander@950
   113
				v = (Vector *)buffer;
dvander@950
   114
			}
dvander@950
   115
dvander@950
   116
			cell_t *addr;
dvander@950
   117
			pContext->LocalToPhysAddr(param, &addr);
dvander@950
   118
dvander@950
   119
			addr[0] = v->x;
dvander@950
   120
			addr[1] = v->y;
dvander@950
   121
			addr[2] = v->z;
dvander@950
   122
dvander@950
   123
			return Data_Okay;
dvander@950
   124
		}
dvander@950
   125
	case Valve_QAngle:
dvander@950
   126
		{
dvander@950
   127
			QAngle *q = NULL;
dvander@950
   128
dvander@950
   129
			if (pass == PassType_Basic)
dvander@950
   130
			{
dvander@950
   131
				q = *(QAngle **)((unsigned char *)buffer + sizeof(QAngle *));
dvander@950
   132
			} else if (pass == PassType_Object) {
dvander@950
   133
				q = (QAngle *)buffer;
dvander@950
   134
			}
dvander@950
   135
dvander@950
   136
			cell_t *addr;
dvander@950
   137
			pContext->LocalToPhysAddr(param, &addr);
dvander@950
   138
dvander@950
   139
			addr[0] = q->x;
dvander@950
   140
			addr[1] = q->y;
dvander@950
   141
			addr[2] = q->z;
dvander@950
   142
dvander@950
   143
			return Data_Okay;
dvander@950
   144
		}
dvander@950
   145
	case Valve_CBaseEntity:
dvander@950
   146
	case Valve_CBasePlayer:
dvander@950
   147
		{
dvander@950
   148
			cell_t *addr;
dvander@950
   149
			pContext->LocalToPhysAddr(param, &addr);
dvander@950
   150
dvander@950
   151
			CBaseEntity *pEntity = *(CBaseEntity **)buffer;
dvander@950
   152
			if (pEntity)
dvander@950
   153
			{
dvander@950
   154
				edict_t *pEdict = gameents->BaseEntityToEdict(pEntity);
dvander@950
   155
				*addr = engine->IndexOfEdict(pEdict);
dvander@950
   156
			} else {
dvander@950
   157
				*addr = -1;
dvander@950
   158
			}
dvander@950
   159
dvander@950
   160
			return Data_Okay;
dvander@950
   161
		}
dvander@950
   162
	case Valve_Edict:
dvander@950
   163
		{
dvander@950
   164
			cell_t *addr;
dvander@950
   165
			pContext->LocalToPhysAddr(param, &addr);
dvander@950
   166
dvander@950
   167
			edict_t *pEdict = *(edict_t **)buffer;
dvander@950
   168
			if (pEdict)
dvander@950
   169
			{
dvander@950
   170
				*addr = engine->IndexOfEdict(pEdict);
dvander@950
   171
			} else {
dvander@950
   172
				*addr = -1;
dvander@950
   173
			}
dvander@950
   174
dvander@950
   175
			return Data_Okay;
dvander@950
   176
		}
dvander@950
   177
	case Valve_POD:
dvander@950
   178
	case Valve_Float:
dvander@950
   179
		{
dvander@950
   180
			cell_t *addr;
dvander@950
   181
			pContext->LocalToPhysAddr(param, &addr);
dvander@950
   182
dvander@950
   183
			*addr = *(cell_t *)buffer;
dvander@950
   184
dvander@950
   185
			return Data_Okay;
dvander@950
   186
		}
dvander@950
   187
	}
dvander@950
   188
dvander@950
   189
	return Data_Fail;
dvander@950
   190
}
dvander@950
   191
dvander@950
   192
DataStatus DecodeValveParam(IPluginContext *pContext,
dvander@950
   193
					  cell_t param,
dvander@950
   194
					  ValveType vtype,
dvander@950
   195
					  unsigned int vflags,
dvander@950
   196
					  PassType type,
dvander@950
   197
					  void *buffer)
dvander@950
   198
{
dvander@950
   199
	switch (vtype)
dvander@950
   200
	{
dvander@950
   201
	case Valve_Vector:
dvander@950
   202
		{
dvander@950
   203
			cell_t *addr;
dvander@950
   204
			int err;
dvander@950
   205
			err = pContext->LocalToPhysAddr(param, &addr);
dvander@950
   206
dvander@950
   207
			unsigned char *mem = (unsigned char *)buffer;
dvander@950
   208
			if (type == PassType_Basic)
dvander@950
   209
			{
dvander@950
   210
				/* Store the object in the next N bytes, and store
dvander@950
   211
				 * a pointer to that object right beforehand.
dvander@950
   212
				 */
dvander@950
   213
				Vector **realPtr = (Vector **)buffer;
dvander@950
   214
dvander@950
   215
				if (addr == pContext->GetNullRef(SP_NULL_VECTOR))
dvander@950
   216
				{
dvander@950
   217
					if (vflags & VDECODE_FLAG_ALLOWNULL)
dvander@950
   218
					{
dvander@950
   219
						*realPtr = NULL;
dvander@950
   220
						return Data_Okay;
dvander@950
   221
					} else {
dvander@950
   222
						pContext->ThrowNativeError("NULL not allowed");
dvander@950
   223
						return Data_Fail;
dvander@950
   224
					}
dvander@950
   225
				} else {
dvander@950
   226
					mem += sizeof(Vector *);
dvander@950
   227
					*realPtr = (Vector *)mem;
dvander@950
   228
				}
dvander@950
   229
			}
dvander@950
   230
dvander@950
   231
			if (err != SP_ERROR_NONE)
dvander@950
   232
			{
dvander@950
   233
				pContext->ThrowNativeErrorEx(err, "Could not read plugin data");
dvander@950
   234
				return Data_Fail;
dvander@950
   235
			}
dvander@950
   236
dvander@950
   237
			/* Use placement new to initialize the object cleanly
dvander@950
   238
			 * This has no destructor so we don't need to do 
dvander@950
   239
			 * DestroyValveParam() or something :]
dvander@950
   240
			 */
dvander@950
   241
			Vector *v = new (mem) Vector(
dvander@950
   242
				sp_ctof(addr[0]),
dvander@950
   243
				sp_ctof(addr[1]),
dvander@950
   244
				sp_ctof(addr[2]));
dvander@950
   245
dvander@950
   246
			return Data_Okay;
dvander@950
   247
		}
dvander@950
   248
	case Valve_QAngle:
dvander@950
   249
		{
dvander@950
   250
			cell_t *addr;
dvander@950
   251
			int err;
dvander@950
   252
			err = pContext->LocalToPhysAddr(param, &addr);
dvander@950
   253
dvander@950
   254
			unsigned char *mem = (unsigned char *)buffer;
dvander@950
   255
			if (type == PassType_Basic)
dvander@950
   256
			{
dvander@950
   257
				/* Store the object in the next N bytes, and store
dvander@953
   258
				 * a pointer to that object right beforehand.
dvander@953
   259
				 */
dvander@950
   260
				QAngle **realPtr = (QAngle **)buffer;
dvander@950
   261
dvander@950
   262
				if (addr == pContext->GetNullRef(SP_NULL_VECTOR))
dvander@950
   263
				{
dvander@950
   264
					if (!(vflags & VDECODE_FLAG_ALLOWNULL))
dvander@950
   265
					{
dvander@950
   266
						pContext->ThrowNativeError("NULL not allowed");
dvander@950
   267
						return Data_Fail;
dvander@950
   268
					} else {
dvander@950
   269
						*realPtr = NULL;
dvander@950
   270
						return Data_Okay;
dvander@950
   271
					}
dvander@950
   272
				} else {
dvander@950
   273
					mem += sizeof(QAngle *);
dvander@950
   274
					*realPtr = (QAngle *)mem;
dvander@950
   275
				}
dvander@950
   276
			}
dvander@950
   277
dvander@950
   278
			if (err != SP_ERROR_NONE)
dvander@950
   279
			{
dvander@950
   280
				pContext->ThrowNativeErrorEx(err, "Could not read plugin data");
dvander@950
   281
				return Data_Fail;
dvander@950
   282
			}
dvander@950
   283
dvander@950
   284
			/* Use placement new to initialize the object cleanly
dvander@953
   285
			 * This has no destructor so we don't need to do 
dvander@953
   286
			 * DestroyValveParam() or something :]
dvander@953
   287
			 */
dvander@950
   288
			QAngle *v = new (mem) QAngle(
dvander@950
   289
				sp_ctof(addr[0]),
dvander@950
   290
				sp_ctof(addr[1]),
dvander@950
   291
				sp_ctof(addr[2]));
dvander@950
   292
dvander@950
   293
			return Data_Okay;
dvander@950
   294
		}
dvander@950
   295
	case Valve_CBasePlayer:
dvander@950
   296
		{
dvander@950
   297
			edict_t *pEdict;
dvander@950
   298
			if (vflags & VDECODE_FLAG_BYREF)
dvander@950
   299
			{
dvander@950
   300
				cell_t *addr;
dvander@950
   301
				pContext->LocalToPhysAddr(param, &addr);
dvander@950
   302
				param = *addr;
dvander@950
   303
			}
dvander@950
   304
			if (param >= 1 && param <= playerhelpers->GetMaxClients())
dvander@950
   305
			{
dvander@950
   306
				IGamePlayer *player = playerhelpers->GetGamePlayer(param);
dvander@950
   307
				if ((vflags & VDECODE_FLAG_ALLOWNOTINGAME)
dvander@950
   308
					&& !player->IsConnected())
dvander@950
   309
				{
dvander@950
   310
					pContext->ThrowNativeError("Client %d is not connected", param);
dvander@950
   311
					return Data_Fail;
dvander@950
   312
				} else if (!player->IsInGame()) {
dvander@950
   313
					pContext->ThrowNativeError("Client %d is not in game", param);
dvander@950
   314
					return Data_Fail;
dvander@950
   315
				}
dvander@950
   316
				pEdict = player->GetEdict();
dvander@950
   317
			} else if (param == -1) {
dvander@950
   318
				if (vflags & VDECODE_FLAG_ALLOWNULL)
dvander@950
   319
				{
dvander@950
   320
					pEdict = NULL;
dvander@950
   321
				} else {
dvander@950
   322
					pContext->ThrowNativeError("NULL not allowed");
dvander@950
   323
					return Data_Fail;
dvander@950
   324
				}
dvander@950
   325
			} else if (param == 0) {
dvander@950
   326
				if (vflags & VDECODE_FLAG_ALLOWWORLD)
dvander@950
   327
				{
dvander@950
   328
					pEdict = engine->PEntityOfEntIndex(0);
dvander@950
   329
				} else {
dvander@950
   330
					pContext->ThrowNativeError("World not allowed");
dvander@950
   331
					return Data_Fail;
dvander@950
   332
				}
dvander@950
   333
			} else {
dvander@950
   334
				pContext->ThrowNativeError("Entity index %d is not a valid client", param);
dvander@950
   335
				return Data_Fail;
dvander@950
   336
			}
dvander@950
   337
			CBaseEntity *pEntity;
dvander@950
   338
			if (pEdict)
dvander@950
   339
			{
dvander@950
   340
				IServerUnknown *pUnknown = pEdict->GetUnknown();
dvander@950
   341
				if (!pUnknown)
dvander@950
   342
				{
dvander@950
   343
					pContext->ThrowNativeError("Entity %d is a not an IServerUnknown");
dvander@950
   344
					return Data_Fail;
dvander@950
   345
				}
dvander@950
   346
				pEntity = pUnknown->GetBaseEntity();
dvander@950
   347
				if (!pEntity)
dvander@950
   348
				{
dvander@950
   349
					pContext->ThrowNativeError("Entity %d is not a CBaseEntity");
dvander@950
   350
					return Data_Fail;
dvander@950
   351
				}
dvander@950
   352
			} else {
dvander@950
   353
				pEdict = NULL;
dvander@950
   354
			}
dvander@950
   355
dvander@950
   356
			CBaseEntity **ebuf = (CBaseEntity **)buffer;
dvander@950
   357
			*ebuf = pEntity;
dvander@950
   358
dvander@950
   359
			return Data_Okay;
dvander@950
   360
		}
dvander@950
   361
	case Valve_CBaseEntity:
dvander@950
   362
		{
dvander@950
   363
			edict_t *pEdict;
dvander@950
   364
			if (vflags & VDECODE_FLAG_BYREF)
dvander@950
   365
			{
dvander@950
   366
				cell_t *addr;
dvander@950
   367
				pContext->LocalToPhysAddr(param, &addr);
dvander@950
   368
				param = *addr;
dvander@950
   369
			}
dvander@950
   370
			if (param >= 1 && param <= playerhelpers->GetMaxClients())
dvander@950
   371
			{
dvander@950
   372
				IGamePlayer *player = playerhelpers->GetGamePlayer(param);
dvander@950
   373
				if ((vflags & VDECODE_FLAG_ALLOWNOTINGAME)
dvander@950
   374
					&& !player->IsConnected())
dvander@950
   375
				{
dvander@950
   376
					pContext->ThrowNativeError("Client %d is not connected", param);
dvander@950
   377
					return Data_Fail;
dvander@950
   378
				} else if (!player->IsInGame()) {
dvander@950
   379
					pContext->ThrowNativeError("Client %d is not in game", param);
dvander@950
   380
					return Data_Fail;
dvander@950
   381
				}
dvander@950
   382
				pEdict = player->GetEdict();
dvander@950
   383
			} else if (param == -1) {
dvander@950
   384
				if (vflags & VDECODE_FLAG_ALLOWNULL)
dvander@950
   385
				{
dvander@950
   386
					pEdict = NULL;
dvander@950
   387
				} else {
dvander@950
   388
					pContext->ThrowNativeError("NULL not allowed");
dvander@950
   389
					return Data_Fail;
dvander@950
   390
				}
dvander@950
   391
			} else if (param == 0) {
dvander@950
   392
				if (vflags & VDECODE_FLAG_ALLOWWORLD)
dvander@950
   393
				{
dvander@950
   394
					pEdict = engine->PEntityOfEntIndex(0);
dvander@950
   395
				} else {
dvander@950
   396
					pContext->ThrowNativeError("World not allowed");
dvander@950
   397
					return Data_Fail;
dvander@950
   398
				}
dvander@950
   399
			} else {
dvander@950
   400
				pEdict = engine->PEntityOfEntIndex(param);
dvander@950
   401
				if (!pEdict || pEdict->IsFree())
dvander@950
   402
				{
dvander@950
   403
					pContext->ThrowNativeError("Entity %d is not valid or is freed", param);
dvander@950
   404
					return Data_Fail;
dvander@950
   405
				}
dvander@950
   406
			}
dvander@950
   407
			CBaseEntity *pEntity;
dvander@950
   408
			if (pEdict)
dvander@950
   409
			{
dvander@950
   410
				IServerUnknown *pUnknown = pEdict->GetUnknown();
dvander@950
   411
				if (!pUnknown)
dvander@950
   412
				{
dvander@950
   413
					pContext->ThrowNativeError("Entity %d is a not an IServerUnknown");
dvander@950
   414
					return Data_Fail;
dvander@950
   415
				}
dvander@950
   416
				pEntity = pUnknown->GetBaseEntity();
dvander@950
   417
				if (!pEntity)
dvander@950
   418
				{
dvander@950
   419
					pContext->ThrowNativeError("Entity %d is not a CBaseEntity");
dvander@950
   420
					return Data_Fail;
dvander@950
   421
				}
dvander@950
   422
			} else {
dvander@950
   423
				pEdict = NULL;
dvander@950
   424
			}
dvander@950
   425
dvander@950
   426
			CBaseEntity **ebuf = (CBaseEntity **)buffer;
dvander@950
   427
			*ebuf = pEntity;
dvander@950
   428
dvander@950
   429
			return Data_Okay;
dvander@950
   430
		}
dvander@950
   431
	case Valve_Edict:
dvander@950
   432
		{
dvander@950
   433
			edict_t *pEdict;
dvander@950
   434
			if (vflags & VDECODE_FLAG_BYREF)
dvander@950
   435
			{
dvander@950
   436
				cell_t *addr;
dvander@950
   437
				pContext->LocalToPhysAddr(param, &addr);
dvander@950
   438
				param = *addr;
dvander@950
   439
			}
dvander@950
   440
			if (param >= 1 && param <= playerhelpers->GetMaxClients())
dvander@950
   441
			{
dvander@950
   442
				IGamePlayer *player = playerhelpers->GetGamePlayer(param);
dvander@950
   443
				if ((vflags & VDECODE_FLAG_ALLOWNOTINGAME)
dvander@950
   444
					&& !player->IsConnected())
dvander@950
   445
				{
dvander@950
   446
					pContext->ThrowNativeError("Client %d is not connected", param);
dvander@950
   447
					return Data_Fail;
dvander@950
   448
				} else if (!player->IsInGame()) {
dvander@950
   449
					pContext->ThrowNativeError("Client %d is not in game", param);
dvander@950
   450
					return Data_Fail;
dvander@950
   451
				}
dvander@950
   452
				pEdict = player->GetEdict();
dvander@950
   453
			} else if (param == -1) {
dvander@950
   454
				if (vflags & VDECODE_FLAG_ALLOWNULL)
dvander@950
   455
				{
dvander@950
   456
					pEdict = NULL;
dvander@950
   457
				} else {
dvander@950
   458
					pContext->ThrowNativeError("NULL not allowed");
dvander@950
   459
					return Data_Fail;
dvander@950
   460
				}
dvander@950
   461
			} else if (param == 0) {
dvander@950
   462
				if (vflags & VDECODE_FLAG_ALLOWWORLD)
dvander@950
   463
				{
dvander@950
   464
					pEdict = engine->PEntityOfEntIndex(0);
dvander@950
   465
				} else {
dvander@950
   466
					pContext->ThrowNativeError("World not allowed");
dvander@950
   467
					return Data_Fail;
dvander@950
   468
				}
dvander@950
   469
			} else {
dvander@950
   470
				pEdict = engine->PEntityOfEntIndex(param);
dvander@950
   471
				if (!pEdict || pEdict->IsFree())
dvander@950
   472
				{
dvander@950
   473
					pContext->ThrowNativeError("Entity %d is not valid or is freed", param);
dvander@950
   474
					return Data_Fail;
dvander@950
   475
				}
dvander@950
   476
			}
dvander@950
   477
dvander@950
   478
			edict_t **ebuf = (edict_t **)buffer;
dvander@950
   479
			*ebuf = pEdict;
dvander@950
   480
dvander@950
   481
			return Data_Okay;
dvander@950
   482
		}
dvander@950
   483
	case Valve_POD:
dvander@950
   484
	case Valve_Float:
dvander@950
   485
		{
dvander@950
   486
			if (vflags & VDECODE_FLAG_BYREF)
dvander@950
   487
			{
dvander@950
   488
				cell_t *addr;
dvander@950
   489
				pContext->LocalToPhysAddr(param, &addr);
dvander@950
   490
				param = *addr;
dvander@950
   491
			}
dvander@950
   492
			*(cell_t *)buffer = param;
dvander@950
   493
			return Data_Okay;
dvander@950
   494
		}
dvander@950
   495
	case Valve_String:
dvander@950
   496
		{
dvander@950
   497
			char *addr;
dvander@950
   498
			pContext->LocalToString(param, &addr);
dvander@950
   499
			*(char **)buffer = addr;
dvander@950
   500
			return Data_Okay;
dvander@950
   501
		}
dvander@950
   502
	}
dvander@950
   503
dvander@950
   504
	return Data_Fail;
dvander@950
   505
}