TEST(Buffer, UTF8) { buffer * buf, * utf8; unsigned char* copy; size_t len; buf = buffer_new(1); buffer_append_string(buf, "诶"); EXPECT_EQ(buf->size, 5); EXPECT_EQ(buf->used, 3); len = buf->used; copy = (unsigned char*) malloc(len + 1); memcpy( copy, buf->data, len); copy[len] = '\0'; buffer_destroy(buf); buf = buffer_new(len); buffer_append_data(buf, copy, len); utf8 = buffer_to_buffer_utf8(buf); buffer_destroy(buf); EXPECT_EQ(utf8->used, len * 2); buf = buffer_utf8_to_buffer(utf8); EXPECT_EQ(buf->used, len); EXPECT_TRUE(strcmp((char*)buf->data, (char*)copy) == 0); EXPECT_EQ(buf->size, 4); EXPECT_EQ(buf->used, 3); buffer_destroy(buf); buffer_destroy(utf8); free(copy); }
void std2_new_unrefer_request(int fork_id, int mod, int clas, void* ptr) { fork_state* fs = get_fork(fork_id); buffer_append_32(&fs->out_buffer, 'u'); buffer_append_32(&fs->out_buffer, 0); buffer_append_32(&fs->out_buffer, mod); buffer_append_32(&fs->out_buffer, clas); buffer_append_data(&fs->out_buffer, &ptr, sizeof(void*)); yield_callbacks(fork_id); }
int file_read_dump(buffer_t **buffer, const char *filename) { int fd = -1; buffer_t *new_buf = NULL; uint8_t data[READ_BUFFER_SIZE]; ssize_t current_read; if (!filename) return RC_BAD_PARAM; if ((fd = open(filename, O_RDONLY)) == -1) { g_warning("Cannot open %s for reading, returned %d:%s\n", filename, errno, strerror(errno)); return RC_FAIL; } CHECK_FCT(buffer_new_from_data(&new_buf, NULL, 0, 0)); do { current_read = read(fd, data, READ_BUFFER_SIZE); if (current_read == -1) { g_warning("Failed to read data from file, returned %d:%s\n", errno, strerror(errno)); return RC_FAIL; } CHECK_FCT(buffer_append_data(new_buf, data, current_read)); } while(current_read == READ_BUFFER_SIZE); *buffer = new_buf; buffer_dump(new_buf, stdout); close(fd); return RC_OK; }
void std2_process_request() { fork_state* fs = get_fork(current_fork_id); if (read_buffer_append(fs->to_client_fd[0], &fs->in_buffer, 20)) { fprintf(stderr, "std2: child got disconnection\n"); exit(1); } int marker = buffer_read_32(&fs->in_buffer); int req_id = buffer_read_32(&fs->in_buffer); if (marker == 'c') { int m = buffer_read_32(&fs->in_buffer); int f = buffer_read_32(&fs->in_buffer); int params_size = buffer_read_32(&fs->in_buffer); read_buffer_append(fs->to_client_fd[0], &fs->in_buffer, params_size); fprintf(stderr, "call id=%d, %d, %d, %d\n", req_id, m, f, params_size); // Construct parameters. void* start_ptr = buffer_cursor(&fs->in_buffer); void* end_ptr = (char*)buffer_cursor(&fs->in_buffer) + params_size; void* p = start_ptr; void* args[16]; int param_count = std2_get_param_count(m, f); int i; for (i = 0; i < param_count; i++) { struct std2_param t = std2_get_param_type(m, f, i); switch (t.type) { case STD2_INT32: args[i] = p; p = (char*)p + 4; break; case STD2_C_STRING: { int size = *(int*)p; p = (char*)p + 4; args[i] = p; p = (char*)p + size; } break; case STD2_INSTANCE: args[i] = *(void**)p; p = (char*)p + sizeof(void*); break; default: fprintf(stderr, "std2: (c) unknown type %d\n", t.type); abort(); } assert(p <= end_ptr); } fs->in_buffer.pos += (char*)p - (char*)start_ptr; // Do the call. struct std2_param ret_type = std2_get_return_type(m, f); buffer_append_32(&fs->out_buffer, req_id); // size will be filled afterwards int size_pos = fs->out_buffer.size; buffer_append_32(&fs->out_buffer, 0); // size will be filled afterwards int ret; switch (ret_type.type) { case STD2_VOID: ret = std2_call(0, m, f, 0, args); break; case STD2_INT32: { std2_int32 v; ret = std2_call(0, m, f, &v, args); if (!ret) buffer_append_32(&fs->out_buffer, v); } break; case STD2_C_STRING: { const char* v; ret = std2_call(0, m, f, &v, args); if (!ret) { int l = strlen(v) + 1; int n = (l + 3) & ~3; buffer_append_32(&fs->out_buffer, n); buffer_append_data(&fs->out_buffer, v, l); buffer_append_alignment(&fs->out_buffer, 4); } } break; case STD2_INSTANCE: { void* v; ret = std2_call(0, m, f, &v, args); if (!ret) buffer_append_data(&fs->out_buffer, &v, sizeof(void*)); } break; default: fprintf(stderr, "std2: (a) unknown type %d\n", ret_type.type); abort(); } if (ret) { fprintf(stderr, "delayed return\n"); fs->out_buffer.size -= 8; // req_id and size return; } *(int*)((char*)fs->out_buffer.data + size_pos) = fs->out_buffer.size - size_pos - 4; while (buffer_avail(&fs->out_buffer)) write_buffer(fs->to_host_fd[1], &fs->out_buffer); fprintf(stderr, "response written\n"); buffer_compact(&fs->in_buffer); buffer_compact(&fs->out_buffer); } else if (marker == 'u') { assert(!"todo unrefer"); } else { fprintf(stderr, "std2: protocol error, bad marker %d\n", marker); abort(); } }