common: prevent buffer overflow
[supercollider.git] / server / scsynth / SC_UnitDef.cpp
blob1c17881279b0a75d271c33e1d8d74bc1b638cc30
1 /*
2 SuperCollider real time audio synthesis system
3 Copyright (c) 2002 James McCartney. All rights reserved.
4 http://www.audiosynth.com
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "SC_UnitDef.h"
23 #include "SC_World.h"
24 #include "SC_Unit.h"
25 #include "SC_InterfaceTable.h"
26 #include "SC_Prototypes.h"
27 #include "SC_Str4.h"
28 #include <stdlib.h>
30 bool UnitDef_Create(const char *inName, size_t inAllocSize, UnitCtorFunc inCtor, UnitDtorFunc inDtor, uint32 inFlags)
32 if (strlen(inName) >= kSCNameByteLen) return false;
34 UnitDef *unitDef = (UnitDef*)malloc(sizeof(UnitDef));
35 if (!unitDef) return false;
37 str4cpy(unitDef->mUnitDefName, inName);
38 unitDef->mHash = Hash(unitDef->mUnitDefName);
40 unitDef->mAllocSize = inAllocSize;
41 unitDef->mUnitCtorFunc = inCtor;
42 unitDef->mUnitDtorFunc = inDtor;
44 unitDef->mCmds = 0;
45 unitDef->mFlags = inFlags;
47 if (!AddUnitDef(unitDef)) {
48 free(unitDef);
49 return false;
51 return true;
55 #include "SC_Lib_Cintf.h"
57 bool UnitDef_AddCmd(const char *inUnitDefName, const char *inCmdName, UnitCmdFunc inFunc)
59 if (strlen(inUnitDefName) >= kSCNameByteLen) return false;
60 int32 unitDefName[kSCNameLen];
61 memset(unitDefName, 0, kSCNameByteLen);
62 strcpy((char*)unitDefName, inUnitDefName);
64 if (strlen(inCmdName) >= kSCNameByteLen) return false;
66 UnitDef* unitDef = GetUnitDef(unitDefName);
67 if (!unitDef) return false;
69 if (!unitDef->mCmds) {
70 unitDef->mCmds = new HashTable<UnitCmd, Malloc>(&gMalloc, 4, true);
73 UnitCmd *cmd = new UnitCmd();
74 memset(cmd->mCmdName, 0, kSCNameByteLen);
75 strcpy((char*)cmd->mCmdName, inCmdName);
77 cmd->mFunc = inFunc;
78 cmd->mHash = Hash(cmd->mCmdName);
79 unitDef->mCmds->Add(cmd);
81 return true;
84 bool PlugIn_DefineCmd(const char *inCmdName, PlugInCmdFunc inFunc, void *inUserData)
87 if (strlen(inCmdName) >= kSCNameByteLen) return false;
89 PlugInCmd *cmd = new PlugInCmd();
90 memset(cmd->mCmdName, 0, kSCNameByteLen);
91 strcpy((char*)cmd->mCmdName, inCmdName);
93 cmd->mFunc = inFunc;
94 cmd->mHash = Hash(cmd->mCmdName);
95 cmd->mUserData = inUserData;
96 AddPlugInCmd(cmd);
98 return true;
101 #include "sc_msg_iter.h"
102 #include "SC_Graph.h"
104 int Unit_DoCmd(World *inWorld, int inSize, char *inData)
106 sc_msg_iter msg(inSize, inData);
107 int nodeID = msg.geti();
108 Graph* graph = World_GetGraph(inWorld, nodeID);
109 if (!graph) return kSCErr_NodeNotFound;
111 uint32 unitID = msg.geti();
112 if (unitID >= graph->mNumUnits) return kSCErr_IndexOutOfRange;
114 Unit *unit = graph->mUnits[unitID];
116 UnitDef* unitDef = unit->mUnitDef;
118 int32 *cmdName = msg.gets4();
119 if (!cmdName) return kSCErr_Failed;
121 if (!unitDef->mCmds) return kSCErr_Failed;
122 UnitCmd *cmd = unitDef->mCmds->Get(cmdName);
123 if (!cmd) return kSCErr_Failed;
125 (cmd->mFunc)(unit, &msg);
127 return kSCErr_None;
130 int PlugIn_DoCmd(World *inWorld, int inSize, char *inData, ReplyAddress *inReply)
132 sc_msg_iter msg(inSize, inData);
134 int32 *cmdName = msg.gets4();
135 if (!cmdName) return kSCErr_Failed;
137 PlugInCmd *cmd = GetPlugInCmd(cmdName);
138 if (!cmd) return kSCErr_Failed;
140 (cmd->mFunc)(inWorld, cmd->mUserData, &msg, (void*)inReply);
142 return kSCErr_None;