[yunq] Add codegen for clients and servers (untested).
This commit is contained in:
parent
963cc0b4fa
commit
71e3521b87
|
@ -30,6 +30,7 @@ static const uint64_t FAILED_PRECONDITION = 0x8;
|
|||
static const uint64_t INTERNAL = 0x100;
|
||||
static const uint64_t UNIMPLEMENTED = 0x101;
|
||||
static const uint64_t EXHAUSTED = 0x102;
|
||||
static const uint64_t INVALID_RESPONSE = 0x103;
|
||||
|
||||
// Kernel specific error codes (relating to capabilities).
|
||||
static const uint64_t CAP_NOT_FOUND = 0x1000;
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
// Generated file - DO NOT MODIFY
|
||||
#include "{{file}}.client.h"
|
||||
|
||||
#include <glacier/buffer/byte_buffer.h>
|
||||
#include <glacier/buffer/cap_buffer.h>
|
||||
|
||||
{% for interface in interfaces %}
|
||||
{% for method in interface.methods %}
|
||||
|
||||
glcr::ErrorCode {{method.name}}(const {{method.request}}& request, {{method.response}}& response) {
|
||||
uint64_t buffer_size = 0x1000;
|
||||
// FIXME: Maybe raise this limit.
|
||||
uint64_t cap_size = 100;
|
||||
glcr::ByteBuffer buffer(buffer_size);
|
||||
glcr::CapBuffer caps(cap_size);
|
||||
|
||||
const uint32_t kSentinel = 0xBEEFDEAD;
|
||||
buffer.WriteAt<uint32_t>(0, kSentinel);
|
||||
buffer.WriteAt<uint64_t>(8, {method_number});
|
||||
|
||||
uint64_t length = request.SerializeToBytes(buffer, /*offset=*/16, caps);
|
||||
buffer.WriteAt<uint32_t>(4, 16 + length);
|
||||
|
||||
z_cap_t reply_port_cap;
|
||||
// FIXME: We need to be able to send capabilities via endpoint call.
|
||||
RET_ERR(ZEndpointSend(endpoint_, 16 + length, buffer.RawPtr()));
|
||||
|
||||
// FIXME: Add a way to zero out the first buffer.
|
||||
glcr::ByteBuffer recv_buffer(buffer_size);
|
||||
glcr::CapBuffer recv_caps(cap_size);
|
||||
RET_ERR(ZReplyPortRecv(reply_port_cap, &buffer_size, recv_buffer.RawPtr(), &cap_size, recv_caps.RawPtr()));
|
||||
|
||||
if (recv_buffer.At<uint32_t>(0) != kSentinel) {
|
||||
return glcr::INVALID_RESPONSE;
|
||||
}
|
||||
|
||||
// Check Response Code.
|
||||
RET_ERR(recv_buffer.At<uint64_t>(8));
|
||||
|
||||
response.ParseFromBytes(recv_buffer, 16, recv_caps);
|
||||
|
||||
return glcr::OK;
|
||||
}
|
||||
|
||||
{% endfor %}
|
||||
{% endfor %}
|
|
@ -0,0 +1,22 @@
|
|||
// Generated file - DO NOT MODIFY
|
||||
#pragma once
|
||||
|
||||
#include <ztypes.h>
|
||||
|
||||
#include "{{file}}.h"
|
||||
|
||||
{% for interface in interfaces -%}
|
||||
class {{interface.name}}Client {
|
||||
public:
|
||||
{{interface.name}}Client(z_cap_t {{interface.name}}_cap) : endpoint_({{interface.name}}_cap) {}
|
||||
{{interface.name}}Client(const {{interface.name}}Client&) = delete;
|
||||
{{interface.name}}Client({{interface.name}}Client&&) = delete;
|
||||
{% for method in interface.methods %}
|
||||
[[nodiscard]] glcr::ErrorCode {{method.name}}(const {{method.request}}& request, {{method.response}}& response);
|
||||
{% endfor %}
|
||||
private:
|
||||
z_cap_t endpoint_;
|
||||
};
|
||||
|
||||
{%- endfor %}
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
// Generated file - DO NOT MODIFY
|
||||
#include "example.yunq.client.h"
|
||||
|
||||
#include <glacier/buffer/byte_buffer.h>
|
||||
#include <glacier/buffer/cap_buffer.h>
|
||||
|
||||
|
||||
|
||||
|
||||
glcr::ErrorCode open(const OpenFileRequest& request, File& response) {
|
||||
uint64_t buffer_size = 0x1000;
|
||||
// FIXME: Maybe raise this limit.
|
||||
uint64_t cap_size = 100;
|
||||
glcr::ByteBuffer buffer(buffer_size);
|
||||
glcr::CapBuffer caps(cap_size);
|
||||
|
||||
const uint32_t kSentinel = 0xBEEFDEAD;
|
||||
buffer.WriteAt<uint32_t>(0, kSentinel);
|
||||
buffer.WriteAt<uint64_t>(8, {method_number});
|
||||
|
||||
uint64_t length = request.SerializeToBytes(buffer, /*offset=*/16, caps);
|
||||
buffer.WriteAt<uint32_t>(4, 16 + length);
|
||||
|
||||
z_cap_t reply_port_cap;
|
||||
// FIXME: We need to be able to send capabilities via endpoint call.
|
||||
RET_ERR(ZEndpointSend(endpoint_, 16 + length, buffer.RawPtr()));
|
||||
|
||||
// FIXME: Add a way to zero out the first buffer.
|
||||
glcr::ByteBuffer recv_buffer(buffer_size);
|
||||
glcr::CapBuffer recv_caps(cap_size);
|
||||
RET_ERR(ZReplyPortRecv(reply_port_cap, &buffer_size, recv_buffer.RawPtr(), &cap_size, recv_caps.RawPtr()));
|
||||
|
||||
if (recv_buffer.At<uint32_t>(0) != kSentinel) {
|
||||
return glcr::INVALID_RESPONSE;
|
||||
}
|
||||
|
||||
// Check Response Code.
|
||||
RET_ERR(recv_buffer.At<uint64_t>(8));
|
||||
|
||||
response.ParseFromBytes(recv_buffer, 16, recv_caps);
|
||||
|
||||
return glcr::OK;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
// Generated file - DO NOT MODIFY
|
||||
#pragma once
|
||||
|
||||
#include <ztypes.h>
|
||||
|
||||
#include "example.yunq.h"
|
||||
|
||||
class VFSClient {
|
||||
public:
|
||||
VFSClient(z_cap_t VFS_cap) : endpoint_(VFS_cap) {}
|
||||
VFSClient(const VFSClient&) = delete;
|
||||
VFSClient(VFSClient&&) = delete;
|
||||
|
||||
[[nodiscard]] glcr::ErrorCode open(const OpenFileRequest& request, File& response);
|
||||
|
||||
private:
|
||||
z_cap_t endpoint_;
|
||||
};
|
|
@ -1,3 +1,4 @@
|
|||
// Generated file -- DO NOT MODIFY.
|
||||
#include "example.yunq.h"
|
||||
|
||||
namespace {
|
||||
|
@ -26,86 +27,148 @@ void WriteHeader(glcr::ByteBuffer& bytes, uint64_t offset, uint32_t core_size, u
|
|||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
|
||||
|
||||
void OpenFileRequest::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset) {
|
||||
CheckHeader(bytes);
|
||||
|
||||
|
||||
|
||||
auto {field.name}_pointer = bytes.At<ExtPointer>(offset + header_size + (8 * {loop.index}));
|
||||
// Parse path.
|
||||
auto path_pointer = bytes.At<ExtPointer>(offset + header_size + (8 * 0));
|
||||
|
||||
set_path(bytes.StringAt(offset + path_pointer.offset, path_pointer.length));
|
||||
|
||||
|
||||
|
||||
set_options(bytes.At<uint64_t>(offset + header_size + (8 * 2)));
|
||||
|
||||
|
||||
// Parse options.
|
||||
set_options(bytes.At<uint64_t>(offset + header_size + (8 * 1)));
|
||||
}
|
||||
|
||||
void {message.name}::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset, const glcr::CapBuffer& caps) {
|
||||
void OpenFileRequest::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset, const glcr::CapBuffer& caps) {
|
||||
CheckHeader(bytes);
|
||||
|
||||
|
||||
|
||||
auto {field.name}_pointer = bytes.At<ExtPointer>(offset + header_size + (8 * {loop.index}));
|
||||
// Parse path.
|
||||
auto path_pointer = bytes.At<ExtPointer>(offset + header_size + (8 * 0));
|
||||
|
||||
set_path(bytes.StringAt(offset + path_pointer.offset, path_pointer.length));
|
||||
|
||||
|
||||
|
||||
set_options(bytes.At<uint64_t>(offset + header_size + (8 * 2)));
|
||||
|
||||
|
||||
// Parse options.
|
||||
set_options(bytes.At<uint64_t>(offset + header_size + (8 * 1)));
|
||||
}
|
||||
|
||||
uint64_t OpenFileRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) {
|
||||
uint32_t next_extension = header_size + 8 * 2;
|
||||
const uint32_t core_size = next_extension;
|
||||
// Write path.
|
||||
ExtPointer path_ptr{
|
||||
.offset = next_extension,
|
||||
// FIXME: Check downcast of str length.
|
||||
.length = (uint32_t)path().length(),
|
||||
};
|
||||
|
||||
bytes.WriteStringAt(offset + next_extension, path());
|
||||
next_extension += path_ptr.length;
|
||||
|
||||
bytes.WriteAt<ExtPointer>(offset + header_size + (8 * 0), path_ptr);
|
||||
// Write options.
|
||||
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 1), options());
|
||||
|
||||
// The next extension pointer is the length of the message.
|
||||
WriteHeader(bytes, offset, core_size, next_extension);
|
||||
|
||||
return next_extension;
|
||||
}
|
||||
|
||||
uint64_t OpenFileRequest::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) {
|
||||
uint32_t next_extension = header_size + 8 * 2;
|
||||
const uint32_t core_size = next_extension;
|
||||
uint64_t next_cap = 0;
|
||||
// Write path.
|
||||
ExtPointer path_ptr{
|
||||
.offset = next_extension,
|
||||
// FIXME: Check downcast of str length.
|
||||
.length = (uint32_t)path().length(),
|
||||
};
|
||||
|
||||
bytes.WriteStringAt(offset + next_extension, path());
|
||||
next_extension += path_ptr.length;
|
||||
|
||||
bytes.WriteAt<ExtPointer>(offset + header_size + (8 * 0), path_ptr);
|
||||
// Write options.
|
||||
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 1), options());
|
||||
|
||||
// The next extension pointer is the length of the message.
|
||||
WriteHeader(bytes, offset, core_size, next_extension);
|
||||
|
||||
return next_extension;
|
||||
}
|
||||
void File::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset) {
|
||||
CheckHeader(bytes);
|
||||
|
||||
|
||||
|
||||
auto {field.name}_pointer = bytes.At<ExtPointer>(offset + header_size + (8 * {loop.index}));
|
||||
// Parse path.
|
||||
auto path_pointer = bytes.At<ExtPointer>(offset + header_size + (8 * 0));
|
||||
|
||||
set_path(bytes.StringAt(offset + path_pointer.offset, path_pointer.length));
|
||||
|
||||
|
||||
|
||||
set_attrs(bytes.At<uint64_t>(offset + header_size + (8 * 2)));
|
||||
|
||||
|
||||
|
||||
// Parse attrs.
|
||||
set_attrs(bytes.At<uint64_t>(offset + header_size + (8 * 1)));
|
||||
// Parse mem_cap.
|
||||
// FIXME: Implement in-buffer capabilities for inprocess serialization.
|
||||
set_mem_cap(0);
|
||||
|
||||
|
||||
}
|
||||
|
||||
void {message.name}::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset, const glcr::CapBuffer& caps) {
|
||||
void File::ParseFromBytes(const glcr::ByteBuffer& bytes, uint64_t offset, const glcr::CapBuffer& caps) {
|
||||
CheckHeader(bytes);
|
||||
|
||||
|
||||
|
||||
auto {field.name}_pointer = bytes.At<ExtPointer>(offset + header_size + (8 * {loop.index}));
|
||||
// Parse path.
|
||||
auto path_pointer = bytes.At<ExtPointer>(offset + header_size + (8 * 0));
|
||||
|
||||
set_path(bytes.StringAt(offset + path_pointer.offset, path_pointer.length));
|
||||
|
||||
|
||||
|
||||
set_attrs(bytes.At<uint64_t>(offset + header_size + (8 * 2)));
|
||||
|
||||
|
||||
|
||||
uint64_t mem_cap_ptr = bytes.At<uint64_t>(offset + header_size + (8 * {offset}));
|
||||
// Parse attrs.
|
||||
set_attrs(bytes.At<uint64_t>(offset + header_size + (8 * 1)));
|
||||
// Parse mem_cap.
|
||||
uint64_t mem_cap_ptr = bytes.At<uint64_t>(offset + header_size + (8 * 2));
|
||||
|
||||
set_mem_cap(caps.At(mem_cap_ptr));
|
||||
|
||||
|
||||
}
|
||||
|
||||
uint64_t File::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset) {
|
||||
uint32_t next_extension = header_size + 8 * 3;
|
||||
const uint32_t core_size = next_extension;
|
||||
// Write path.
|
||||
ExtPointer path_ptr{
|
||||
.offset = next_extension,
|
||||
// FIXME: Check downcast of str length.
|
||||
.length = (uint32_t)path().length(),
|
||||
};
|
||||
|
||||
bytes.WriteStringAt(offset + next_extension, path());
|
||||
next_extension += path_ptr.length;
|
||||
|
||||
bytes.WriteAt<ExtPointer>(offset + header_size + (8 * 0), path_ptr);
|
||||
// Write attrs.
|
||||
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 1), attrs());
|
||||
// Write mem_cap.
|
||||
// FIXME: Implement inbuffer capabilities.
|
||||
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 2), 0);
|
||||
|
||||
// The next extension pointer is the length of the message.
|
||||
WriteHeader(bytes, offset, core_size, next_extension);
|
||||
|
||||
return next_extension;
|
||||
}
|
||||
|
||||
uint64_t File::SerializeToBytes(glcr::ByteBuffer& bytes, uint64_t offset, glcr::CapBuffer& caps) {
|
||||
uint32_t next_extension = header_size + 8 * 3;
|
||||
const uint32_t core_size = next_extension;
|
||||
uint64_t next_cap = 0;
|
||||
// Write path.
|
||||
ExtPointer path_ptr{
|
||||
.offset = next_extension,
|
||||
// FIXME: Check downcast of str length.
|
||||
.length = (uint32_t)path().length(),
|
||||
};
|
||||
|
||||
bytes.WriteStringAt(offset + next_extension, path());
|
||||
next_extension += path_ptr.length;
|
||||
|
||||
bytes.WriteAt<ExtPointer>(offset + header_size + (8 * 0), path_ptr);
|
||||
// Write attrs.
|
||||
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 1), attrs());
|
||||
// Write mem_cap.
|
||||
caps.WriteAt(next_cap, mem_cap());
|
||||
bytes.WriteAt<uint64_t>(offset + header_size + (8 * 2), next_cap++);
|
||||
|
||||
// The next extension pointer is the length of the message.
|
||||
WriteHeader(bytes, offset, core_size, next_extension);
|
||||
|
||||
return next_extension;
|
||||
}
|
|
@ -5,9 +5,6 @@
|
|||
#include <glacier/buffer/cap_buffer.h>
|
||||
#include <glacier/string/string.h>
|
||||
#include <ztypes.h>
|
||||
|
||||
|
||||
|
||||
class OpenFileRequest {
|
||||
public:
|
||||
OpenFileRequest() {}
|
||||
|
@ -19,24 +16,16 @@ class OpenFileRequest {
|
|||
void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset, const glcr::CapBuffer&);
|
||||
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset);
|
||||
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&);
|
||||
|
||||
|
||||
glcr::String path() { return path_; }
|
||||
void set_path(const glcr::String& value) { path_ = value; }
|
||||
|
||||
uint64_t options() { return options_; }
|
||||
void set_options(const uint64_t& value) { options_ = value; }
|
||||
|
||||
|
||||
private:
|
||||
|
||||
glcr::String path_;
|
||||
|
||||
uint64_t options_;
|
||||
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
class File {
|
||||
public:
|
||||
File() {}
|
||||
|
@ -48,25 +37,16 @@ class File {
|
|||
void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset, const glcr::CapBuffer&);
|
||||
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset);
|
||||
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&);
|
||||
|
||||
|
||||
glcr::String path() { return path_; }
|
||||
void set_path(const glcr::String& value) { path_ = value; }
|
||||
|
||||
uint64_t attrs() { return attrs_; }
|
||||
void set_attrs(const uint64_t& value) { attrs_ = value; }
|
||||
|
||||
z_cap_t mem_cap() { return mem_cap_; }
|
||||
void set_mem_cap(const z_cap_t& value) { mem_cap_ = value; }
|
||||
|
||||
|
||||
private:
|
||||
|
||||
glcr::String path_;
|
||||
|
||||
uint64_t attrs_;
|
||||
|
||||
z_cap_t mem_cap_;
|
||||
|
||||
|
||||
}
|
||||
};
|
|
@ -0,0 +1,45 @@
|
|||
// Generated file - DO NOT MODIFY
|
||||
#include "example.yunq.client.h"
|
||||
|
||||
#include <glacier/buffer/byte_buffer.h>
|
||||
#include <glacier/buffer/cap_buffer.h>
|
||||
|
||||
|
||||
|
||||
|
||||
glcr::ErrorCode open(const OpenFileRequest& request, File& response) {
|
||||
uint64_t buffer_size = 0x1000;
|
||||
// FIXME: Maybe raise this limit.
|
||||
uint64_t cap_size = 100;
|
||||
glcr::ByteBuffer buffer(buffer_size);
|
||||
glcr::CapBuffer caps(cap_size);
|
||||
|
||||
const uint32_t kSentinel = 0xBEEFDEAD;
|
||||
buffer.WriteAt<uint32_t>(0, kSentinel);
|
||||
buffer.WriteAt<uint64_t>(8, {method_number});
|
||||
|
||||
uint64_t length = request.SerializeToBytes(buffer, /*offset=*/16, caps);
|
||||
buffer.WriteAt<uint32_t>(4, 16 + length);
|
||||
|
||||
z_cap_t reply_port_cap;
|
||||
// FIXME: We need to be able to send capabilities via endpoint call.
|
||||
RET_ERR(ZEndpointSend(endpoint_, 16 + length, buffer.RawPtr()));
|
||||
|
||||
// FIXME: Add a way to zero out the first buffer.
|
||||
glcr::ByteBuffer recv_buffer(buffer_size);
|
||||
glcr::CapBuffer recv_caps(cap_size);
|
||||
RET_ERR(ZReplyPortRecv(reply_port_cap, &buffer_size, recv_buffer.RawPtr(), &cap_size, recv_caps.RawPtr()));
|
||||
|
||||
if (recv_buffer.At<uint32_t>(0) != kSentinel) {
|
||||
return glcr::INVALID_RESPONSE;
|
||||
}
|
||||
|
||||
// Check Response Code.
|
||||
RET_ERR(recv_buffer.At<uint64_t>(8));
|
||||
|
||||
response.ParseFromBytes(recv_buffer, 16, recv_caps);
|
||||
|
||||
return glcr::OK;
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
// Generated File -- DO NOT MODIFY.
|
||||
#pragma once
|
||||
|
||||
#include <mammoth/thread.h>
|
||||
#include <ztypes.h>
|
||||
|
||||
#include "example.yunq.h"
|
||||
|
||||
|
||||
|
||||
class VFSServerBase {
|
||||
public:
|
||||
VFSServerBase(z_cap_t VFS_cap) : {}
|
||||
VFSServerBase(const VFSServerBase&) = delete;
|
||||
VFSServerBase(VFSServerBase&&) = delete;
|
||||
|
||||
[[nodiscard]] Thread RunServer();
|
||||
|
||||
|
||||
[[nodiscard]] virtual glcr::ErrorCode Handleopen(const OpenFileRequest&, File&) = 0;
|
||||
|
||||
|
||||
private:
|
||||
z_cap_t endpoint_;
|
||||
|
||||
friend void VFSServerBaseThreadBootstrap(void*);
|
||||
void ServerThread();
|
||||
|
||||
[[nodiscard]] glcr::ErrorCode HandleRequest(const glcr::ByteBuffer& request, glcr::ByteBuffer& response,
|
||||
glcr::CapBuffer& resp_caps);
|
||||
};
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
// Generated file -- DO NOT MODIFY.
|
||||
#include "{{file}}.server.h"
|
||||
|
||||
#include <mammoth/debug.h>
|
||||
#include <zcall.h>
|
||||
|
||||
namespace {
|
||||
|
||||
const uint32_t kSentinel = 0xBEEFDEAD;
|
||||
const uint32_t kHeaderSize = 0x10;
|
||||
|
||||
void WriteError(glcr::ByteBuffer& buffer, glcr::ErrorCode err) {
|
||||
buffer.WriteAt<uint32_t>(0, kSentinel);
|
||||
buffer.WriteAt<uint32_t>(4, kHeaderSize);
|
||||
buffer.WriteAt<uint64_t>(8, err);
|
||||
}
|
||||
|
||||
void WriteHeader(glcr::ByteBuffer& buffer, uint64_t message_length) {
|
||||
buffer.WriteAt<uint32_t>(0, kSentinel);
|
||||
buffer.WriteAt<uint32_t>(4, kHeaderSize + message_length);
|
||||
buffer.WriteAt<uint64_t>(8, glcr::OK);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
{% for interface in interfaces %}
|
||||
void {{interface.name}}ServerBaseThreadBootstrap(void* server_base) {
|
||||
({{interface.name}}ServerBase*)(server_base)->ServerThread();
|
||||
}
|
||||
|
||||
Thread {{interface.name}}::RunServer() {
|
||||
return Thread({{interface.name}}ServerBaseThreadBootstrap, this);
|
||||
}
|
||||
|
||||
void {{interface.name}}::ServerThread() {
|
||||
glcr::ByteBuffer recv_buffer(0x1000);
|
||||
glcr::ByteBuffer resp_buffer(0x1000);
|
||||
uint64_t resp_cap_size = 0x10;
|
||||
glcr::CapBuffer resp_cap(resp_cap_size);
|
||||
z_cap_t reply_port_cap;
|
||||
|
||||
while (true) {
|
||||
uint64_t recv_buf_size = 0x1000;
|
||||
glcr::ErrorCode recv_err = ZEndpointRecv(endpoint_, &recv_buf_size, recv_buffer.RawPtr(), &reply_port_cap);
|
||||
if (recv_err != glcr::OK) {
|
||||
dbgln("Error in receive: %x", recv_err);
|
||||
continue;
|
||||
}
|
||||
|
||||
uint64_t resp_length = 0;
|
||||
|
||||
glcr::ErrorCode err = HandlRequest(recv_buffer, resp_buffer, resp_length, resp_cap);
|
||||
if (err != glcr::OK) {
|
||||
WriteError(resp_buffer, err);
|
||||
ZReplyPortSend(reply_port_cap, kHeaderSize, resp_buffer.RawPtr(), 0, nullptr);
|
||||
} else {
|
||||
WriteHeader(resp_buffer, resp_length);
|
||||
ZReplyPortSend(reply_port_cap, resp_length, resp_buffer.RawPtr(), resp_cap.UsedSlots(), resp_cap.RawPtr());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
glcr::ErrorCode {{interface.name}}::HandleRequest(const glcr::ByteBuffer& request, glcr::ByteBuffer& response, uint64_t& resp_length
|
||||
glcr::CapBuffer& resp_caps) {
|
||||
if (recv_buffer.At<uint32_t>(0) != kSentinel) {
|
||||
return glcr::INVALID_INPUT;
|
||||
}
|
||||
|
||||
uint64_t method_select = recv_buffer.At<uint64_t>(8);
|
||||
|
||||
switch(method_select) {
|
||||
{%- for method in interface.methods %}
|
||||
case {{loop.index0}}: {
|
||||
{{method.request}} request;
|
||||
{{method.response}} response;
|
||||
|
||||
request.ParseFromBytes(recv_buffer, kHeaderSize);
|
||||
|
||||
RET_ERR(Handle{{method.name}}(request, response));
|
||||
|
||||
resp_length = response.SerializeToBytes(resp_buffer, kHeaderSize, resp_cap);
|
||||
break;
|
||||
}
|
||||
{%- endfor %}
|
||||
default: {
|
||||
return glcr::UNIMPLEMENTED;
|
||||
}
|
||||
}
|
||||
return glcr::OK;
|
||||
}
|
||||
{% endfor %}
|
|
@ -0,0 +1,33 @@
|
|||
// Generated File -- DO NOT MODIFY.
|
||||
#pragma once
|
||||
|
||||
#include <mammoth/thread.h>
|
||||
#include <ztypes.h>
|
||||
|
||||
#include "{{file}}.h"
|
||||
|
||||
{% for interface in interfaces %}
|
||||
|
||||
class {{interface.name}}ServerBase {
|
||||
public:
|
||||
{{interface.name}}ServerBase(z_cap_t {{interface.name}}_cap) : {}
|
||||
{{interface.name}}ServerBase(const {{interface.name}}ServerBase&) = delete;
|
||||
{{interface.name}}ServerBase({{interface.name}}ServerBase&&) = delete;
|
||||
|
||||
[[nodiscard]] Thread RunServer();
|
||||
|
||||
{% for method in interface.methods %}
|
||||
[[nodiscard]] virtual glcr::ErrorCode Handle{{method.name}}(const {{method.request}}&, {{method.response}}&) = 0;
|
||||
{% endfor %}
|
||||
|
||||
private:
|
||||
z_cap_t endpoint_;
|
||||
|
||||
friend void {{interface.name}}ServerBaseThreadBootstrap(void*);
|
||||
void ServerThread();
|
||||
|
||||
[[nodiscard]] glcr::ErrorCode HandleRequest(const glcr::ByteBuffer& request, glcr::ByteBuffer& response,
|
||||
glcr::CapBuffer& resp_caps);
|
||||
};
|
||||
|
||||
{% endfor %}
|
19
yunq/yunq.py
19
yunq/yunq.py
|
@ -38,6 +38,25 @@ def main():
|
|||
message_impl = message_impl_tmpl.render(file=filename, messages=messages)
|
||||
f.write(message_impl)
|
||||
|
||||
client_header_tmpl = jinja_env.get_template("client.h.jinja")
|
||||
with open(filename + '.client.h', mode='w') as f:
|
||||
client_header = client_header_tmpl.render(file=filename, interfaces=interfaces)
|
||||
f.write(client_header)
|
||||
|
||||
client_impl_tmpl = jinja_env.get_template("client.cpp.jinja")
|
||||
with open(filename + '.client.cpp', mode='w') as f:
|
||||
client_impl = client_impl_tmpl.render(file=filename, interfaces=interfaces)
|
||||
f.write(client_impl)
|
||||
|
||||
server_header_tmpl = jinja_env.get_template("server.h.jinja")
|
||||
with open(filename + '.server.h', mode='w') as f:
|
||||
server_header = server_header_tmpl.render(file=filename, interfaces=interfaces)
|
||||
f.write(server_header)
|
||||
|
||||
server_impl_tmpl = jinja_env.get_template("server.cpp.jinja")
|
||||
with open(filename + '.server.cpp', mode='w') as f:
|
||||
server_impl = client_impl_tmpl.render(file=filename, interfaces=interfaces)
|
||||
f.write(server_impl)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
Loading…
Reference in New Issue