Skip to content

Commit 79e8de2

Browse files
committed
can return json of bbf now
1 parent 3d0739b commit 79e8de2

File tree

5 files changed

+137
-45
lines changed

5 files changed

+137
-45
lines changed

serve/bbf.c

Lines changed: 72 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,6 @@ void* uri_bbf_detect_objects_parse(const void* context, void* parsed, const char
150150
default:
151151
break;
152152
case s_bbf_name_interval:
153-
numeric_parser_execute(&parser->numeric_parser, buf, len);
154-
break;
155153
case s_bbf_name_min_neighbors:
156154
numeric_parser_execute(&parser->numeric_parser, buf, len);
157155
break;
@@ -191,32 +189,89 @@ void* uri_bbf_detect_objects_init(void)
191189
return context;
192190
}
193191

194-
ebb_buf uri_bbf_detect_objects_intro(const void* context, const void* parsed)
192+
int uri_bbf_detect_objects_intro(const void* context, const void* parsed, ebb_buf* buf)
195193
{
196-
ebb_buf buf;
197-
const static char bbf_intro[] =
194+
const static char bbf_desc[] =
198195
"HTTP/1.1 200 OK\r\nCache-Control: no-cache\r\nAccept: \r\nContent-Type: text/html\r\nContent-Length: 189\r\n\r\n"
199196
"<html><body><form enctype='multipart/form-data' method='post'><input name='size' value='24x24'><input name='model' value='face'><input type='file' name='source'><input type='submit'></form>\n";
200-
buf.data = (void*)bbf_intro;
201-
buf.len = sizeof(bbf_intro);
202-
return buf;
197+
/*
198+
const static char bbf_desc[] =
199+
"HTTP/1.1 200 OK\r\nCache-Control: no-cache\r\nAccept: \r\nContent-Type: application/json\r\nContent-Length: 1\r\n\r\n"
200+
"{\"model\":\"\",\"size\":\"\",\"interval\":\"\",\"min_neighbors\":\"\",\"accurate\":\"\",\"source\":\"\"}\n";
201+
*/
202+
buf->data = (void*)bbf_desc;
203+
buf->len = sizeof(bbf_desc);
204+
return 0;
203205
}
204206

205-
ebb_buf uri_bbf_detect_objects(const void* context, const void* parsed)
207+
int uri_bbf_detect_objects(const void* context, const void* parsed, ebb_buf* buf)
206208
{
207209
bbf_param_parser_t* parser = (bbf_param_parser_t*)parsed;
208210
if (parser->state != s_bbf_start)
209211
uri_bbf_param_parser_terminate(parser);
210212
ccv_dense_matrix_t* image = 0;
213+
if (parser->source.data == 0)
214+
{
215+
free(parser);
216+
return -1;
217+
}
211218
ccv_read(parser->source.data, &image, CCV_IO_ANY_STREAM | CCV_IO_GRAY, parser->source.written);
219+
free(parser->source.data);
220+
if (image == 0)
221+
{
222+
free(parser);
223+
return -1;
224+
}
212225
ccv_array_t* seq = ccv_bbf_detect_objects(image, &parser->cascade, 1, parser->params);
213-
ccv_array_free(seq);
214226
ccv_matrix_free(image);
215-
ebb_buf buf;
216-
const static char bbf_intro[] =
217-
"HTTP/1.1 201 Created\r\nCache-Control: no-cache\r\nContent-Type: text/plain\r\nContent-Length: 3\r\n\r\n"
218-
"OK\n";
219-
buf.data = (void*)bbf_intro;
220-
buf.len = sizeof(bbf_intro);
221-
return buf;
227+
if (seq == 0)
228+
{
229+
free(parser);
230+
return -1;
231+
}
232+
int i = 0;
233+
if (seq->rnum > 0)
234+
{
235+
buf->len = seq->rnum * 21 + 2;
236+
char* data = (char*)malloc(buf->len);
237+
data[0] = '[';
238+
buf->written = 1;
239+
for (i = 0; i < seq->rnum; i++)
240+
{
241+
char cell[64];
242+
ccv_comp_t* comp = (ccv_comp_t*)ccv_array_get(seq, i);
243+
snprintf(cell, 64, "[%d,%d,%d,%d,%f]", comp->rect.x, comp->rect.y, comp->rect.width, comp->rect.height, comp->confidence);
244+
size_t len = strnlen(cell, 64);
245+
while (buf->written + len + 1 >= buf->len)
246+
{
247+
buf->len = (buf->len * 3 + 1) / 2;
248+
data = (char*)realloc(data, buf->len);
249+
}
250+
memcpy(data + buf->written, cell, len);
251+
buf->written += len + 1;
252+
data[buf->written - 1] = (i == seq->rnum - 1) ? ']' : ',';
253+
}
254+
char http_header[192];
255+
snprintf(http_header, 192, "HTTP/1.1 201 Created\r\nCache-Control: no-cache\r\nContent-Type: application/json; charset=utf-8\r\nContent-Length: %zd\r\n\r\n", buf->written);
256+
size_t len = strnlen(http_header, 192);
257+
if (buf->written + len + 1 >= buf->len)
258+
{
259+
buf->len = buf->written + len + 1;
260+
data = (char*)realloc(data, buf->len);
261+
}
262+
memmove(data + len, data, buf->written);
263+
memcpy(data, http_header, len);
264+
buf->written += len + 1;
265+
data[buf->written - 1] = '\n';
266+
buf->data = data;
267+
buf->len = buf->written;
268+
buf->on_release = uri_ebb_buf_free;
269+
} else {
270+
buf->data = (void*)ebb_http_empty_array;
271+
buf->len = sizeof(ebb_http_empty_array);
272+
buf->on_release = 0;
273+
}
274+
ccv_array_free(seq);
275+
free(parser);
276+
return 0;
222277
}

serve/makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ all: libccv.a $(TARGETS)
1010
clean:
1111
${MAKE} clean -C ../lib ; rm -f *.o $(TARGETS) -f
1212

13-
$(TARGETS): serve.o uri.o parsers.o bbf.o async.o ebb.o ebb_request_parser.o libccv.a
14-
$(CC) -o $@ serve.o uri.o parsers.o bbf.o async.o ebb.o ebb_request_parser.o $(LDFLAGS)
13+
$(TARGETS): serve.o uri.o parsers.o bbf.o dpm.o async.o ebb.o ebb_request_parser.o libccv.a
14+
$(CC) -o $@ serve.o uri.o parsers.o bbf.o dpm.o async.o ebb.o ebb_request_parser.o $(LDFLAGS)
1515

1616
libccv.a:
1717
${MAKE} -C ../lib

serve/serve.c

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#include "uri.h"
66
#include "async.h"
77

8-
static const char ebb_http_404[] = "HTTP/1.1 404 Not Found\r\nCache-Control: no-cache\r\nContent-Type: text/plain\r\nContent-Length: 4\r\n\r\n404\n";
8+
static const char ebb_http_404[] = "HTTP/1.1 404 Not Found\r\nCache-Control: no-cache\r\nContent-Type: application/json; charset=utf-8\r\nContent-Length: 6\r\n\r\nfalse\n";
99

1010
typedef struct {
1111
ebb_request* request;
@@ -47,10 +47,6 @@ static void on_request_part_data(ebb_request* request, const char* at, size_t le
4747
request_extras->context = request_extras->dispatcher->parse(request_extras->dispatcher->context, request_extras->context, at, length, URI_MULTIPART_DATA, -1);
4848
}
4949

50-
static void on_request_part_data_complete(ebb_request* request)
51-
{
52-
}
53-
5450
static void on_request_multipart_header_field(ebb_request* request, const char* at, size_t length, int header_index)
5551
{
5652
ebb_request_extras* request_extras = (ebb_request_extras*)request->data;
@@ -80,6 +76,12 @@ static void on_request_body(ebb_request* request, const char* at, size_t length)
8076

8177
static void on_connection_response_continue(ebb_connection* connection)
8278
{
79+
ebb_connection_extras* connection_extras = (ebb_connection_extras*)(connection->data);
80+
ebb_request* request = connection_extras->request;
81+
ebb_request_extras* request_extras = (ebb_request_extras*)request->data;
82+
// call custom release function for the buffer
83+
if (request_extras->response.data && request_extras->response.on_release)
84+
request_extras->response.on_release(&request_extras->response);
8385
ebb_connection_schedule_close(connection);
8486
}
8587

@@ -97,25 +99,36 @@ static void on_request_execute(void* context)
9799
// this is called off-thread
98100
ebb_request* request = (ebb_request*)context;
99101
ebb_request_extras* request_extras = (ebb_request_extras*)request->data;
102+
const static char http_bad_request[] =
103+
"HTTP/1.1 400 Bad Request\r\nCache-Control: no-cache\r\nContent-Type: application/json; charset=utf8\r\nContent-Length: 6\r\n\r\n"
104+
"false\n";
105+
int response_code = 0;
106+
request_extras->response.on_release = 0;
100107
switch (request->method)
101108
{
102109
case EBB_POST:
103110
if (request_extras->dispatcher->post)
104111
{
105-
request_extras->response = request_extras->dispatcher->post(request_extras->dispatcher->context, request_extras->context);
112+
response_code = request_extras->dispatcher->post(request_extras->dispatcher->context, request_extras->context, &request_extras->response);
106113
break;
107114
}
108115
case EBB_GET:
109116
if (request_extras->dispatcher->get)
110117
{
111-
request_extras->response = request_extras->dispatcher->get(request_extras->dispatcher->context, request_extras->context);
118+
response_code = request_extras->dispatcher->get(request_extras->dispatcher->context, request_extras->context, &request_extras->response);
112119
break;
113120
}
114121
default:
115122
request_extras->response.data = (void*)ebb_http_404;
116123
request_extras->response.len = sizeof(ebb_http_404);
117124
break;
118125
}
126+
if (response_code != 0)
127+
{
128+
assert(request_extras->response.on_release == 0);
129+
request_extras->response.data = (void*)http_bad_request;
130+
request_extras->response.len = sizeof(http_bad_request);
131+
}
119132
main_async_f(request, on_request_response);
120133
}
121134

@@ -145,7 +158,6 @@ static ebb_request* new_request(ebb_connection* connection)
145158
request->on_part_data = on_request_part_data;
146159
request->on_multipart_header_field = on_request_multipart_header_field;
147160
request->on_multipart_header_value = on_request_multipart_header_value;
148-
request->on_part_data_complete = on_request_part_data_complete;
149161
request->on_body = on_request_body;
150162
request->on_query_string = on_request_query_string;
151163
request->on_complete = on_request_dispatch;
@@ -175,10 +187,10 @@ int main(int argc, char** argv)
175187
ebb_server_init(&server, EV_DEFAULT);
176188
server.new_connection = new_connection;
177189
ebb_server_listen_on_port(&server, 3350);
178-
printf("Listen on 3350, http://localhost:3350/\n");
179190
uri_init();
180191
main_async_init();
181192
main_async_start(EV_DEFAULT);
193+
printf("listen on 3350, http://localhost:3350/\n");
182194
ev_run(EV_DEFAULT_ 0);
183195
main_async_destroy();
184196
return 0;

serve/uri.c

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
#include "uri.h"
22
#include <string.h>
3+
#include <stdlib.h>
4+
#include <stdio.h>
5+
6+
void uri_ebb_buf_free(ebb_buf* buf)
7+
{
8+
free(buf->data);
9+
buf->data = 0;
10+
buf->len = buf->written = 0;
11+
buf->on_release = 0;
12+
}
313

414
static uri_dispatch_t uri_map[] = {
515
{
@@ -17,10 +27,10 @@ static uri_dispatch_t uri_map[] = {
1727
},
1828
{
1929
.uri = "/dpm/detect.objects",
20-
.init = 0,
21-
.parse = 0,
22-
.get = 0,
23-
.post = 0,
30+
.init = uri_dpm_detect_objects_init,
31+
.parse = uri_dpm_detect_objects_parse,
32+
.get = uri_dpm_detect_objects_intro,
33+
.post = uri_dpm_detect_objects,
2434
},
2535
{
2636
.uri = "/swt/detect.words",
@@ -54,16 +64,20 @@ void uri_init(void)
5464
int i;
5565
size_t len = sizeof(uri_map) / sizeof(uri_dispatch_t);
5666
for (i = 0; i < len; i++)
57-
uri_map[i].context = (uri_map[i].init) ? uri_map[i].init() : 0;
67+
if (uri_map[i].init)
68+
{
69+
printf("init context for %s\n", uri_map[i].uri);
70+
uri_map[i].context = uri_map[i].init();
71+
} else
72+
uri_map[i].context = 0;
5873
}
5974

60-
ebb_buf uri_root_discovery(const void* context, const void* parsed)
75+
int uri_root_discovery(const void* context, const void* parsed, ebb_buf* buf)
6176
{
62-
ebb_buf buf;
6377
const static char root_discovery[] =
64-
"HTTP/1.1 200 OK\r\nCache-Control: no-cache\r\nContent-Type: text/plain\r\nContent-Length: 23\r\n\r\n"
65-
"[\"/bbf/detect.objects\"]\n";
66-
buf.data = (void*)root_discovery;
67-
buf.len = sizeof(root_discovery);
68-
return buf;
78+
"HTTP/1.1 200 OK\r\nCache-Control: no-cache\r\nContent-Type: application/json\r\nContent-Length: 45\r\n\r\n"
79+
"[\"/bbf/detect.objects\",\"/dpm/detect.objects\"]\n";
80+
buf->data = (void*)root_discovery;
81+
buf->len = sizeof(root_discovery);
82+
return 0;
6983
}

serve/uri.h

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33

44
#include "ebb.h"
55

6+
static const char ebb_http_404[] = "HTTP/1.1 404 Not Found\r\nCache-Control: no-cache\r\nContent-Type: application/json; charset=utf-8\r\nContent-Length: 6\r\n\r\nfalse\n";
7+
static const char ebb_http_empty_object[] = "HTTP/1.1 201 Created\r\nCache-Control: no-cache\r\nContent-Type: application/json; charset=utf-8\r\nContent-Length: 3\r\n\r\n{}\n";
8+
static const char ebb_http_empty_array[] = "HTTP/1.1 201 Created\r\nCache-Control: no-cache\r\nContent-Type: application/json; charset=utf-8\r\nContent-Length: 3\r\n\r\n[]\n";
9+
10+
void uri_ebb_buf_free(ebb_buf* buf);
11+
612
typedef enum {
713
s_form_data_start,
814
s_form_data_header_field,
@@ -104,18 +110,23 @@ typedef struct {
104110
void* context;
105111
void* (*init)(void); // this runs on server start
106112
void* (*parse)(const void*, void*, const char*, size_t, uri_parse_state_t, int); // this runs on main thread
107-
ebb_buf (*get)(const void*, const void*); // this runs off thread
108-
ebb_buf (*post)(const void*, const void*); // this runs off thread
113+
int (*get)(const void*, const void*, ebb_buf*); // this runs off thread
114+
int (*post)(const void*, const void*, ebb_buf*); // this runs off thread
109115
} uri_dispatch_t;
110116

111117
uri_dispatch_t* find_uri_dispatch(const char* path);
112118
void uri_init(void);
113119

114-
ebb_buf uri_root_discovery(const void* context, const void* parsed);
120+
int uri_root_discovery(const void* context, const void* parsed, ebb_buf* buf);
115121

116122
void* uri_bbf_detect_objects_init(void);
117123
void* uri_bbf_detect_objects_parse(const void* context, void* parsed, const char* buf, size_t len, uri_parse_state_t state, int header_index);
118-
ebb_buf uri_bbf_detect_objects_intro(const void* context, const void* parsed);
119-
ebb_buf uri_bbf_detect_objects(const void* context, const void* parsed);
124+
int uri_bbf_detect_objects_intro(const void* context, const void* parsed, ebb_buf* buf);
125+
int uri_bbf_detect_objects(const void* context, const void* parsed, ebb_buf* buf);
126+
127+
void* uri_dpm_detect_objects_init(void);
128+
void* uri_dpm_detect_objects_parse(const void* context, void* parsed, const char* buf, size_t len, uri_parse_state_t state, int header_index);
129+
int uri_dpm_detect_objects_intro(const void* context, const void* parsed, ebb_buf* buf);
130+
int uri_dpm_detect_objects(const void* context, const void* parsed, ebb_buf* buf);
120131

121132
#endif

0 commit comments

Comments
 (0)