core/smn_datapacks.cpp
author David Anderson <dvander@alliedmods.net>
Sun Nov 16 16:06:18 2008 -0800 (2008-11-16)
changeset 2411 8dfaa3d730b5
parent 2289 44045ead61cd
permissions -rw-r--r--
Removed pointless "systems" folder from core.
     1 /**
     2  * vim: set ts=4 :
     3  * =============================================================================
     4  * SourceMod
     5  * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
     6  * =============================================================================
     7  *
     8  * This program is free software; you can redistribute it and/or modify it under
     9  * the terms of the GNU General Public License, version 3.0, as published by the
    10  * Free Software Foundation.
    11  * 
    12  * This program is distributed in the hope that it will be useful, but WITHOUT
    13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    14  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
    15  * details.
    16  *
    17  * You should have received a copy of the GNU General Public License along with
    18  * this program.  If not, see <http://www.gnu.org/licenses/>.
    19  *
    20  * As a special exception, AlliedModders LLC gives you permission to link the
    21  * code of this program (as well as its derivative works) to "Half-Life 2," the
    22  * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
    23  * by the Valve Corporation.  You must obey the GNU General Public License in
    24  * all respects for all other code used.  Additionally, AlliedModders LLC grants
    25  * this exception to all derivative works.  AlliedModders LLC defines further
    26  * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
    27  * or <http://www.sourcemod.net/license.php>.
    28  *
    29  * Version: $Id$
    30  */
    31 
    32 #include "sm_globals.h"
    33 #include "HandleSys.h"
    34 #include "CDataPack.h"
    35 
    36 HandleType_t g_DataPackType;
    37 
    38 class DataPackNatives : 
    39 	public SMGlobalClass,
    40 	public IHandleTypeDispatch
    41 {
    42 public:
    43 	void OnSourceModAllInitialized()
    44 	{
    45 		HandleAccess hacc;
    46 		TypeAccess tacc;
    47 
    48 		g_HandleSys.InitAccessDefaults(&tacc, &hacc);
    49 		tacc.access[HTypeAccess_Create] = true;
    50 		tacc.access[HTypeAccess_Inherit] = true;
    51 		tacc.ident = g_pCoreIdent;
    52 		hacc.access[HandleAccess_Read] = HANDLE_RESTRICT_OWNER;
    53 
    54 		g_DataPackType = g_HandleSys.CreateType("DataPack", this, 0, &tacc, &hacc, g_pCoreIdent, NULL);
    55 	}
    56 	void OnSourceModShutdown()
    57 	{
    58 		g_HandleSys.RemoveType(g_DataPackType, g_pCoreIdent);
    59 		g_DataPackType = 0;
    60 	}
    61 	void OnHandleDestroy(HandleType_t type, void *object)
    62 	{
    63 		g_SourceMod.FreeDataPack(reinterpret_cast<IDataPack *>(object));
    64 	}
    65 };
    66 
    67 static cell_t smn_CreateDataPack(IPluginContext *pContext, const cell_t *params)
    68 {
    69 	IDataPack *pDataPack = g_SourceMod.CreateDataPack();
    70 
    71 	if (!pDataPack)
    72 	{
    73 		return 0;
    74 	}
    75 
    76 	return g_HandleSys.CreateHandle(g_DataPackType, pDataPack, pContext->GetIdentity(), g_pCoreIdent, NULL);
    77 }
    78 
    79 static cell_t smn_WritePackCell(IPluginContext *pContext, const cell_t *params)
    80 {
    81 	Handle_t hndl = static_cast<Handle_t>(params[1]);
    82 	HandleError herr;
    83 	HandleSecurity sec;
    84 	IDataPack *pDataPack;
    85 
    86 	sec.pOwner = pContext->GetIdentity();
    87 	sec.pIdentity = g_pCoreIdent;
    88 
    89 	if ((herr=g_HandleSys.ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
    90 		!= HandleError_None)
    91 	{
    92 		return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
    93 	}
    94 
    95 	pDataPack->PackCell(params[2]);
    96 
    97 	return 1;
    98 }
    99 
   100 static cell_t smn_WritePackFloat(IPluginContext *pContext, const cell_t *params)
   101 {
   102 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   103 	HandleError herr;
   104 	HandleSecurity sec;
   105 	IDataPack *pDataPack;
   106 
   107 	sec.pOwner = pContext->GetIdentity();
   108 	sec.pIdentity = g_pCoreIdent;
   109 
   110 	if ((herr=g_HandleSys.ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
   111 		!= HandleError_None)
   112 	{
   113 		return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
   114 	}
   115 
   116 	pDataPack->PackFloat(sp_ctof(params[2]));
   117 
   118 	return 1;
   119 }
   120 
   121 static cell_t smn_WritePackString(IPluginContext *pContext, const cell_t *params)
   122 {
   123 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   124 	HandleError herr;
   125 	HandleSecurity sec;
   126 	IDataPack *pDataPack;
   127 	int err;
   128 
   129 	sec.pOwner = pContext->GetIdentity();
   130 	sec.pIdentity = g_pCoreIdent;
   131 
   132 	if ((herr=g_HandleSys.ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
   133 		!= HandleError_None)
   134 	{
   135 		return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
   136 	}
   137 
   138 	char *str;
   139 	if ((err=pContext->LocalToString(params[2], &str)) != SP_ERROR_NONE)
   140 	{
   141 		pContext->ThrowNativeErrorEx(err, NULL);
   142 		return 0;
   143 	}
   144 
   145 	pDataPack->PackString(str);
   146 
   147 	return 1;
   148 }
   149 
   150 static cell_t smn_ReadPackCell(IPluginContext *pContext, const cell_t *params)
   151 {
   152 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   153 	HandleError herr;
   154 	HandleSecurity sec;
   155 	IDataPack *pDataPack;
   156 
   157 	sec.pOwner = pContext->GetIdentity();
   158 	sec.pIdentity = g_pCoreIdent;
   159 
   160 	if ((herr=g_HandleSys.ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
   161 		!= HandleError_None)
   162 	{
   163 		return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
   164 	}
   165 
   166 	if (!pDataPack->IsReadable(sizeof(size_t) + sizeof(cell_t)))
   167 	{
   168 		return pContext->ThrowNativeError("DataPack operation is out of bounds.");
   169 	}
   170 
   171 	return pDataPack->ReadCell();
   172 }
   173 
   174 static cell_t smn_ReadPackFloat(IPluginContext *pContext, const cell_t *params)
   175 {
   176 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   177 	HandleError herr;
   178 	HandleSecurity sec;
   179 	IDataPack *pDataPack;
   180 
   181 	sec.pOwner = pContext->GetIdentity();
   182 	sec.pIdentity = g_pCoreIdent;
   183 
   184 	if ((herr=g_HandleSys.ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
   185 		!= HandleError_None)
   186 	{
   187 		return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
   188 	}
   189 
   190 	if (!pDataPack->IsReadable(sizeof(size_t) + sizeof(float)))
   191 	{
   192 		return pContext->ThrowNativeError("DataPack operation is out of bounds.");
   193 	}
   194 
   195 	return sp_ftoc(pDataPack->ReadFloat());
   196 }
   197 
   198 static cell_t smn_ReadPackString(IPluginContext *pContext, const cell_t *params)
   199 {
   200 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   201 	HandleError herr;
   202 	HandleSecurity sec;
   203 	IDataPack *pDataPack;
   204 
   205 	sec.pOwner = pContext->GetIdentity();
   206 	sec.pIdentity = g_pCoreIdent;
   207 
   208 	if ((herr=g_HandleSys.ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
   209 		!= HandleError_None)
   210 	{
   211 		return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
   212 	}
   213 
   214 	const char *str;
   215 	if (!(str=pDataPack->ReadString(NULL)))
   216 	{
   217 		return pContext->ThrowNativeError("DataPack operation is out of bounds.");
   218 	}
   219 
   220 	pContext->StringToLocal(params[2], params[3], str);
   221 
   222 	return 1;
   223 }
   224 
   225 static cell_t smn_ResetPack(IPluginContext *pContext, const cell_t *params)
   226 {
   227 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   228 	HandleError herr;
   229 	HandleSecurity sec;
   230 	IDataPack *pDataPack;
   231 
   232 	sec.pOwner = pContext->GetIdentity();
   233 	sec.pIdentity = g_pCoreIdent;
   234 
   235 	if ((herr=g_HandleSys.ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
   236 		!= HandleError_None)
   237 	{
   238 		return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
   239 	}
   240 
   241 	pDataPack->Reset();
   242 	if (params[2])
   243 	{
   244 		pDataPack->ResetSize();
   245 	}
   246 
   247 	return 1;
   248 }
   249 
   250 static cell_t smn_GetPackPosition(IPluginContext *pContext, const cell_t *params)
   251 {
   252 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   253 	HandleError herr;
   254 	HandleSecurity sec;
   255 	IDataPack *pDataPack;
   256 
   257 	sec.pOwner = pContext->GetIdentity();
   258 	sec.pIdentity = g_pCoreIdent;
   259 
   260 	if ((herr=g_HandleSys.ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
   261 		!= HandleError_None)
   262 	{
   263 		return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
   264 	}
   265 
   266 	return static_cast<cell_t>(pDataPack->GetPosition());
   267 }
   268 
   269 static cell_t smn_SetPackPosition(IPluginContext *pContext, const cell_t *params)
   270 {
   271 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   272 	HandleError herr;
   273 	HandleSecurity sec;
   274 	IDataPack *pDataPack;
   275 
   276 	sec.pOwner = pContext->GetIdentity();
   277 	sec.pIdentity = g_pCoreIdent;
   278 
   279 	if ((herr=g_HandleSys.ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
   280 		!= HandleError_None)
   281 	{
   282 		return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
   283 	}
   284 
   285 	if (!pDataPack->SetPosition(params[2]))
   286 	{
   287 		return pContext->ThrowNativeError("Invalid DataPack position, %d is out of bounds", params[2]);
   288 	}
   289 
   290 	return 1;
   291 }
   292 
   293 static cell_t smn_IsPackReadable(IPluginContext *pContext, const cell_t *params)
   294 {
   295 	Handle_t hndl = static_cast<Handle_t>(params[1]);
   296 	HandleError herr;
   297 	HandleSecurity sec;
   298 	IDataPack *pDataPack;
   299 
   300 	sec.pOwner = pContext->GetIdentity();
   301 	sec.pIdentity = g_pCoreIdent;
   302 
   303 	if ((herr=g_HandleSys.ReadHandle(hndl, g_DataPackType, &sec, (void **)&pDataPack))
   304 		!= HandleError_None)
   305 	{
   306 		return pContext->ThrowNativeError("Invalid data pack handle %x (error %d)", hndl, herr);
   307 	}
   308 
   309 	return pDataPack->IsReadable(params[2]) ? 1 : 0;
   310 }
   311 
   312 static DataPackNatives s_DataPackNatives;
   313 
   314 REGISTER_NATIVES(datapacknatives)
   315 {
   316 	{"CreateDataPack",			smn_CreateDataPack},
   317 	{"WritePackCell",			smn_WritePackCell},
   318 	{"WritePackFloat",			smn_WritePackFloat},
   319 	{"WritePackString",			smn_WritePackString},
   320 	{"ReadPackCell",			smn_ReadPackCell},
   321 	{"ReadPackFloat",			smn_ReadPackFloat},
   322 	{"ReadPackString",			smn_ReadPackString},
   323 	{"ResetPack",				smn_ResetPack},
   324 	{"GetPackPosition",			smn_GetPackPosition},
   325 	{"SetPackPosition",			smn_SetPackPosition},
   326 	{"IsPackReadable",			smn_IsPackReadable},
   327 	{NULL,						NULL}
   328 };