Audio-AMaMP

 view release on metacpan or  search on metacpan

amamp_binding/amamp_binding.c  view on Meta::CPAN

			}
		}

		/* Free the line we've been working on. */
		if (lineText != NULL)
			free(lineText);
		line++;
	}

	/* See if we have a message to return. */
	if (completeMessage == 1)
	{
		/* Before returning the message, we need to remove it from the buffer. */
		int newBufferLen = 1 + strlen(core->messageBuffer) - strlen(message);
		char *newBuffer = malloc(newBufferLen < 1 ? 1 : newBufferLen);
		memcpy(newBuffer, core->messageBuffer + strlen(message), newBufferLen);
		*(newBuffer + newBufferLen - 1) = 0;	/* To ensure we're null terminated. */
		free(core->messageBuffer);
		core->messageBuffer = newBuffer;

		/* Return it. */
		return message;
	}
	else
	{
		free(message);
		return NULL;
	}
}


/* amampFreeCore takes a core structure and frees all memory associated with it. Note that you
 * need to free any messages seperately.                                                       */
void amampFreeCore(AMAMP_CORE *core)
{
	if (core != NULL)
	{
		/* Free stuff. Here we need to go look at platform stuff. */
#if AMAMP_BINDING_WIN32 == 1
		/* Win32. Close handles, Free structure. */
		struct _amamp_binding_win32core *handle = core->handle;
		CloseHandle(handle->coreReadPipe);
		CloseHandle(handle->coreWritePipe);
		free(handle);
#else
		/* POSIX. pclose to clean up the file handle. */
		struct _amamp_binding_posixcore *handle = core->handle;
		close(handle->coreReadPipe);
		close(handle->coreWritePipe);
		free(handle);
#endif

		/* Free buffer and the core structure itself. */
		if (core->messageBuffer != NULL)
			free(core->messageBuffer);
		free(core);
	}
}


/* Checks if the core is still alive. Returns zero if it is not and a non-zero value
   otherwise. */
int amampIsCoreAlive(AMAMP_CORE *core)
{
	/* If we know it's dead, return 0 right away. */
	if (core == NULL || core->coreAlive == 0)
		return 0;

	/* Otherwise, do something to check it. Go native. */
#if AMAMP_BINDING_WIN32 == 1
	/* Win32. We can simply do a peek pipe operation. */
	if (1) {
		/* Get us some working variables. */
		struct _amamp_binding_win32core *handle = core->handle;
		int bytesRead = 0;
		int bytesAvailable = 0;
		int bytesRemaining = 0;
		int retVal;
		char test[1];

		/* Check return value of peek operation. */
		retVal = PeekNamedPipe(handle->coreReadPipe, &test[0], 1, &bytesRead, &bytesAvailable, &bytesRemaining);
		if (retVal == 0)
			core->coreAlive = 0;
	}
#else
	/* POSIX. We're just going to try doing a read. Of course, if we get anything we
	   will have to put it into the message queue. Hopefully one day I'll find a far
	   eaiser way of doing this bit. */
	if (1)
	{
		/* First declare some variables. */
		struct _amamp_binding_posixcore *handle = core->handle;
		char *tmpBuffer;
		int bytesRead;
		int curLen;
		int newLen;
		char *newBuffer;

		/* Turn off blocking. This check should never block. */
		int flags = fcntl(handle->coreReadPipe, F_GETFL, 0);	/* get current file status flags */
		flags |= O_NONBLOCK;					/* set non-blocking flag */
		fcntl(handle->coreReadPipe, F_SETFL, flags);      /* set up non-blocking read */

		/* Grab data from the pipe. Assume there will never be more than 32K in there. */
		tmpBuffer = malloc(32768);
		if (tmpBuffer == NULL)
			return core->coreAlive;
		bytesRead = read(handle->coreReadPipe, tmpBuffer, 32768);
		if (bytesRead > 0)
		{
			_amampStrip0x13(tmpBuffer);
			curLen = strlen(core->messageBuffer);
			newLen = curLen + bytesRead + 1;
			newBuffer = realloc(core->messageBuffer, newLen);
			if (newBuffer == NULL)
			{
				free(tmpBuffer);
				return core->coreAlive;
			}
			memcpy(newBuffer + curLen, tmpBuffer, bytesRead);



( run in 4.566 seconds using v1.01-cache-2.11-cpan-df04353d9ac )