コード例 #1
0
ファイル: streambuf.c プロジェクト: gnalbandian/squeezeplay
static int stream_readL(lua_State *L) {
	struct stream *stream;
	u8_t buf[1024];
	u8_t *buf_ptr, *body_ptr;
	size_t header_len;
	ssize_t n;

	/*
	 * 1: Stream (self)
	 * 2: Playback (self)
	 */

	stream = lua_touserdata(L, 1);


	/* shortcut, just read to streambuf */
	if (stream->num_crlf == 4) {
		n = streambuf_feed_fd(stream->fd, L);
		if (n == 0) {
			/* closed */
			lua_pushboolean(L, FALSE);
			return 1;
		}

		if (n == -ENOSPC) {
			lua_pushinteger(L, 0);
			return 1;
		}

		if (n < 0) {
			CLOSESOCKET(stream->fd);

			lua_pushnil(L);
			lua_pushstring(L, strerror(n));
			return 2;

		}

		lua_pushinteger(L, n);
		return 1;
	}

	/* read buffer, but we must not overflow the stream fifo */
	n = streambuf_get_freebytes();
	if (n > (ssize_t)sizeof(buf)) {
		n = sizeof(buf);
	}

	n = recv(stream->fd, buf, sizeof(buf), 0);

	/* socket closed */
	if (n == 0) {
		lua_pushboolean(L, FALSE);
		return 1;
	}

	/* socket error */
	if (n < 0) {
		// XXXX do we need to handle timeout here?
		CLOSESOCKET(stream->fd);

		lua_pushnil(L);
		lua_pushstring(L, strerror(SOCKETERROR));
		return 2;
	}

	buf_ptr = buf;


	/* read http header */
	if (stream->num_crlf < 4) {
		stream->body = realloc(stream->body, stream->body_len + n);
		body_ptr = stream->body + stream->body_len;
		stream->body_len += n;

		while (n) {
			*body_ptr++ = *buf_ptr;

			if (*buf_ptr == '\n' || *buf_ptr == '\r') {
				stream->num_crlf++;
			}
			else {
				stream->num_crlf = 0;
			}

			buf_ptr++;
			n--;

			if (stream->num_crlf == 4) {
				header_len = body_ptr - stream->body;

				//LOG_DEBUG(log_audio_decode, "headers %d %*s\n", header_len, header_len, stream->body);

				/* Send headers to SqueezeCenter */
				lua_getfield(L, 2, "_streamHttpHeaders");
				lua_pushvalue(L, 2);
				lua_pushlstring(L, (char *)stream->body, header_len);
				lua_call(L, 2, 0);

				/* do not free the header here - leave it to disconnect -
				 * so that it can be used by the proxy code
				 */

				/* Send headers to proxy clients */
				proxy_chunk(stream->body, header_len, L);

				break;
			}
		}
	}

	/* we need to loop when playing sound effects, so we need to remember where the stream starts */
	streambuf_lptr = streambuf_fifo.wptr;

	/* feed remaining buffer */
	streambuf_feedL(buf_ptr, n, L);

	lua_pushboolean(L, TRUE);
	return 1;
}