summaryrefslogtreecommitdiff
path: root/response.c
blob: 11cd504e945b7bd1c428b8c322be67f4763b84e6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include "response.h"
#include "socket-common.h"
#include <string.h>
#include <stdlib.h>

//RESPONSE related functions from the server

extern guint signalMyCb; //signal id
extern GAsyncQueue* stdinQueue; //our queue
SignalObject* signalObject; //the signal object which registered the signal id

//write output to client
static gssize writeOutput(GPollableOutputStream* stream, gchar* data, gssize size);

//callback for client output, this is where the queue messages are sent to the client
gboolean cbClientOutput(gpointer data, gpointer additional)
{
	GPollableOutputStream* outStream = (GPollableOutputStream*)data;
	GAsyncQueue* queue = (GAsyncQueue*)additional;
	if(g_async_queue_length(queue) <= 0) {
		return FALSE;
	}

	gpointer elem;
	g_print_debug("Try pop\n");
	//try to pop an element from the queue
	elem=g_async_queue_try_pop(queue);
	g_print_debug("after pop\n");
	if(elem) {
		char* buf = (char*)elem;
		g_print_debug("Extracted %s\n", buf);
		gssize size = strlen(buf);
		gssize written = 0;

		written=g_pollable_output_stream_write_nonblocking(outStream, buf, size+1, NULL, NULL);
		if(written==-1) {
			g_printerr("Could not write to client\n");
		}

		//free the alloc'ed memory
		free(buf);
	}

	return FALSE;
}

//the client input callback
gboolean cbClientInput(gpointer data, gpointer additional)
{

	char buffer[1024];
	gssize size=0;
	memset(buffer,0,1024);

	GPollableInputStream* inStream = (GPollableInputStream*)data;
	GPollableOutputStream* outStream = (GPollableOutputStream*)additional;

	size=g_pollable_input_stream_read_nonblocking(inStream, buffer, 1024, NULL, NULL);
	if(size <=0 || size == G_IO_ERROR_WOULD_BLOCK) {
		g_print_debug("Got: %d\n", size);
		return FALSE;
	}

	//emit a signal which calls the responseCb function
	SignalObjectClass myStruct;
	myStruct.instance = NULL;
	myStruct.cb = writeOutput;
	myStruct.data = buffer;
	myStruct.size = size;
	myStruct.inStream = inStream;
	myStruct.outStream = outStream;
	g_signal_emit(signalObject, signalMyCb, 0, &myStruct, NULL);

	return TRUE;
}

//write output to client
static gssize writeOutput(GPollableOutputStream* stream, gchar* data, gssize size)
{
	gssize what=0;
	what=g_pollable_output_stream_write_nonblocking(stream, data, size, NULL, NULL);
	if(what < 0 || what == G_IO_ERROR_WOULD_BLOCK) {
		return -1;
	}
	return what;
}

//initialize the signals
void initSignals(guint *signal)
{
	*signal = g_signal_new("runEchoService", SIGNAL_OBJECT_TYPE, G_SIGNAL_RUN_FIRST, 0, NULL, NULL,
	                       g_cclosure_marshal_VOID__POINTER , G_TYPE_NONE, 1, G_TYPE_POINTER);

	signalObject = g_object_new(SIGNAL_OBJECT_TYPE, NULL);
	g_signal_connect (signalObject, "runEchoService", G_CALLBACK (responseCb), NULL);
}

//send to client 3 times
void responseCb(gpointer instance, GObject *arg1, gpointer user_data)
{
        static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
        g_static_mutex_lock (&mutex);
        SignalObjectClass *data = (SignalObjectClass*)arg1;
        GPollableOutputStream* stream = (GPollableOutputStream*)data->outStream;
        gchar* str = data->data;
        gssize len = data->size;
        gssize written = 0;

        gchar* upper = g_ascii_strup(str, len);

	gchar *out_string = g_strdup_printf("%s\n%s\n%s\n",upper,upper,upper);
	gssize out_len = strlen (out_string);

        //send response back to client
        written = data->cb(stream, out_string, out_len);
        if(written == -1) {
                g_print_debug("Could not send message to client\n");
        }

        g_free(upper);
	g_free(out_string);

        g_static_mutex_unlock (&mutex);
}