void SendFailureCmd::InitSendFailureCmd(const char *inCmdName, const char* inErrString)
{
	mCmdName = (char*)World_Alloc(mWorld, strlen(inCmdName)+1);
	strcpy(mCmdName, inCmdName);

	mErrString = (char*)World_Alloc(mWorld, strlen(inErrString)+1);
	strcpy(mErrString, inErrString);
}
int BufReadChannelCmd::Init(char *inData, int inSize)
{
	sc_msg_iter msg(inSize, inData);
	mBufIndex = msg.geti();

	const char *filename = msg.gets();
	if (!filename) return kSCErr_WrongArgType;

	if(mWorld->mRestrictedPath){
		mFilename = allocAndRestrictPath(mWorld, filename, mWorld->mRestrictedPath);
	}else{
		mFilename = (char*)World_Alloc(mWorld, strlen(filename)+1);
		strcpy(mFilename, filename);
	}

	mFileOffset = msg.geti();
	mNumFrames = msg.geti(-1);
	mBufOffset = msg.geti();
	mLeaveFileOpen = msg.geti();

	InitChannels(msg);

	GET_COMPLETION_MSG(msg);

	return kSCErr_None;
}
int SendReplyCmd::Init(char *inData, int inSize)
{
	mMsgSize = inSize;
	mMsgData = (char*)World_Alloc(mWorld, mMsgSize);
	memcpy(mMsgData, inData, inSize);
	return kSCErr_None;
}
int BufWriteCmd::Init(char *inData, int inSize)
{
#ifdef NO_LIBSNDFILE
	SendFailure(&mReplyAddress, "/b_write", "scsynth compiled without libsndfile\n");
 	scprintf("scsynth compiled without libsndfile\n");
	return false;
#else
	sc_msg_iter msg(inSize, inData);
	mBufIndex = msg.geti();

	const char *filename = msg.gets();
	if (!filename) return kSCErr_WrongArgType;

	if(mWorld->mRestrictedPath){
		mFilename = allocAndRestrictPath(mWorld, filename, mWorld->mRestrictedPath);
	}else{
		mFilename = (char*)World_Alloc(mWorld, strlen(filename)+1);
		strcpy(mFilename, filename);
	}

	const char *headerFormatString = msg.gets("aiff");
	const char *sampleFormatString = msg.gets("int16");

	mNumFrames = msg.geti(-1);
	mBufOffset = msg.geti();
	mLeaveFileOpen = msg.geti();

	GET_COMPLETION_MSG(msg);

	memset(&mFileInfo, 0, sizeof(mFileInfo));
	return sndfileFormatInfoFromStrings(&mFileInfo, headerFormatString, sampleFormatString);
#endif
}
int RecvSynthDefCmd::Init(char *inData, int inSize)
{
	sc_msg_iter msg(inSize, inData);

	int size = msg.getbsize();
	if (!size) throw kSCErr_WrongArgType;

	mBuffer = (char*)World_Alloc(mWorld, size);
	msg.getb(mBuffer, size);

	GET_COMPLETION_MSG(msg);

	mDefs = 0;
	return kSCErr_None;
}
Ejemplo n.º 6
0
SCErr SendReplyCmd_d_removed(World * inWorld,int inSize,char* inData, ReplyAddress *inReply)
{
	void* space = World_Alloc(inWorld, sizeof(SendReplyCmd)); 
	SendReplyCmd *cmd = new (space) SendReplyCmd(inWorld, inReply); 
	if (!cmd) return kSCErr_Failed; 
	int err = cmd->Init(inData, inSize); 
	if (err) { 
		cmd->~SendReplyCmd(); 
		World_Free(inWorld, space); 
		return err; 
	} 
	if (inWorld->mRealTime) cmd->CallNextStage(); 
	else cmd->CallEveryStage();
	return kSCErr_None;
}
int BufGenCmd::Init(char *inData, int inSize)
{
	mSize = inSize;
	mData = (char*)World_Alloc(mWorld, mSize);
	memcpy(mData, inData, mSize);

	sc_msg_iter msg(mSize, mData);
	mBufIndex = msg.geti();

	int32 *genName = msg.gets4();
	if (!genName) return kSCErr_WrongArgType;

	mBufGen = GetBufGen(genName);
	if (!mBufGen) return kSCErr_BufGenNotFound;

	mMsg = msg;

	return kSCErr_None;
}
int LoadSynthDefDirCmd::Init(char *inData, int inSize)
{
	sc_msg_iter msg(inSize, inData);

	const char *filename = msg.gets();
	if (!filename) return kSCErr_WrongArgType;

	if(mWorld->mRestrictedPath){
		mFilename = allocAndRestrictPath(mWorld, filename, mWorld->mRestrictedPath);
	}else{
		mFilename = (char*)World_Alloc(mWorld, strlen(filename)+1);
		strcpy(mFilename, filename);
	}

	GET_COMPLETION_MSG(msg);

	mDefs = 0;
	return kSCErr_None;
}
AsyncPlugInCmd::AsyncPlugInCmd(World *inWorld, ReplyAddress *inReplyAddress,
			const char* cmdName,
			void *cmdData,
			AsyncStageFn stage2, // stage2 is non real time
			AsyncStageFn stage3, // stage3 is real time - completion msg performed if stage3 returns true
			AsyncStageFn stage4, // stage4 is non real time - sends done if stage4 returns true
			AsyncFreeFn cleanup, // cleanup is called in real time
			int completionMsgSize,
			void* completionMsgData)
	: SC_SequencedCommand(inWorld, inReplyAddress),
	mCmdName(cmdName), mCmdData(cmdData),
	mStage2(stage2), mStage3(stage3), mStage4(stage4),
	mCleanup(cleanup)
{
	if (completionMsgSize && completionMsgData) {
		mMsgSize = completionMsgSize;
		mMsgData = (char*)World_Alloc(mWorld, mMsgSize);
		memcpy(mMsgData, completionMsgData, mMsgSize);
	}
}
char* allocAndRestrictPath(World *mWorld, const char* inPath, const char* restrictBase){
	char strbuf[PATH_MAX];
	int offset = 0;
	int remain = PATH_MAX;

	// Ensure begins with the base
	if(strncmp(inPath, restrictBase, strlen(restrictBase)) != 0){
		strcpy(strbuf, restrictBase);
		offset = strlen(restrictBase);
		remain -= offset;
		if(inPath[0]!='/' && strbuf[strlen(strbuf)-1]!='/'){
			strbuf[offset] = '/';
			++offset;
			--remain;
		}
	}

	// Now copy string, but discard any ".." (which could be benign, but easy to abuse)
	SC_StringParser sp(inPath, '/');
	size_t tokenlen;
	while (!sp.AtEnd()) {
		const char *token = const_cast<char *>(sp.NextToken());
		tokenlen = strlen(token);
		// now add the new token, then a slash, as long as token is neither dodgy nor overflows
		if(strcmp(token, "..")!=0 && remain > tokenlen){
			strcpy(strbuf+offset, token);
			offset += tokenlen;
			remain -= tokenlen;
			if(!sp.AtEnd()) {
				strbuf[offset] = '/';
				++offset;
				--remain;
			}
		}
	}

	// Now we can make a long-term home for the string and return it
	char* saferPath = (char*)World_Alloc(mWorld, strlen(strbuf)+1);
	strcpy(saferPath, strbuf);
	return saferPath;
}
int PerformAsynchronousCommand(
			World *inWorld,
			void* replyAddr,
			const char* cmdName,
			void *cmdData,
			AsyncStageFn stage2, // stage2 is non real time
			AsyncStageFn stage3, // stage3 is real time - completion msg performed if stage3 returns true
			AsyncStageFn stage4, // stage4 is non real time - sends done if stage4 returns true
			AsyncFreeFn cleanup,
			int completionMsgSize,
			void* completionMsgData
)
{
	void* space = World_Alloc(inWorld, sizeof(AsyncPlugInCmd));
	AsyncPlugInCmd *cmd = new (space) AsyncPlugInCmd(inWorld, (ReplyAddress*)replyAddr,
								cmdName, cmdData, stage2, stage3, stage4, cleanup,
								completionMsgSize, completionMsgData);
	if (!cmd) return kSCErr_Failed;
	if (inWorld->mRealTime) cmd->CallNextStage();
	else cmd->CallEveryStage();
	return kSCErr_None;
}
Ejemplo n.º 12
0
// Send a reply from a node to a client program.
//
// This function puts the reply on a FIFO which is harvested by another thread that
// actually does the sending.
//
// NOTE: Only to be called from the realtime thread.
void Node_SendReply(Node* inNode, int replyID, const char* cmdName, int numArgs,  const float* values)
{
	World *world = inNode->mWorld;
	if (!world->mRealTime) return;

	const int cmdNameSize = strlen(cmdName);
	void* mem = World_Alloc(world, cmdNameSize + numArgs*sizeof(float));
	if (mem == 0)
		return;

	NodeReplyMsg msg;
	msg.mWorld = world;
	msg.mNodeID = inNode->mID;
	msg.mID = replyID;
	msg.mValues = (float*)((char*)mem + cmdNameSize);
	memcpy(msg.mValues, values, numArgs*sizeof(float));
	msg.mNumArgs = numArgs;
	msg.mCmdName = (char*)mem;
	memcpy(msg.mCmdName, cmdName, cmdNameSize);
	msg.mCmdNameSize = cmdNameSize;
	msg.mRTMemory = mem;
	world->hw->mNodeMsgs.Write(msg);
}
Ejemplo n.º 13
0
// create a new node
int Node_New(World *inWorld, NodeDef *def, int32 inID, Node** outNode)
{
	if (inID < 0) {
		if (inID == -1) { // -1 means generate an id for the event
			HiddenWorld* hw = inWorld->hw;
			inID = hw->mHiddenID = (hw->mHiddenID - 8) | 0x80000000;
		} else {
			return kSCErr_ReservedNodeID;
		}
	}

	if (World_GetNode(inWorld, inID)) {
		return kSCErr_DuplicateNodeID;
	}

	Node* node = (Node*)World_Alloc(inWorld, def->mAllocSize);

	node->mWorld = inWorld;
	node->mDef = def;
	node->mParent = 0;
	node->mPrev = 0;
	node->mNext = 0;
	node->mIsGroup = false;

	node->mID = inID;
	node->mHash = Hash(inID);
	if (!World_AddNode(inWorld, node)) {
		World_Free(inWorld, node);
		return kSCErr_TooManyNodes;
	}

	inWorld->hw->mRecentID = inID;

	*outNode = node;

	return kSCErr_None;
}