[Yunq] Add support for empty requests and responses.
This commit is contained in:
parent
6d108f6965
commit
cc4b5bd811
|
@ -8,7 +8,13 @@
|
|||
{% for interface in interfaces %}
|
||||
{% for method in interface.methods %}
|
||||
|
||||
{% if method.request == None %}
|
||||
glcr::ErrorCode {{interface.name}}Client::{{method.name}}({{method.response}}& response) {
|
||||
{% elif method.response == None %}
|
||||
glcr::ErrorCode {{interface.name}}Client::{{method.name}}(const {{method.request}}& request) {
|
||||
{% else %}
|
||||
glcr::ErrorCode {{interface.name}}Client::{{method.name}}(const {{method.request}}& request, {{method.response}}& response) {
|
||||
{% endif %}
|
||||
uint64_t buffer_size = kBufferSize;
|
||||
uint64_t cap_size = kCapBufferSize;
|
||||
|
||||
|
@ -17,7 +23,12 @@ glcr::ErrorCode {{interface.name}}Client::{{method.name}}(const {{method.request
|
|||
buffer_.WriteAt<uint64_t>(8, {{loop.index0}});
|
||||
|
||||
cap_buffer_.Reset();
|
||||
{% if method.request == None %}
|
||||
uint64_t length = 0;
|
||||
{% else %}
|
||||
uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_);
|
||||
{% endif %}
|
||||
|
||||
buffer_.WriteAt<uint32_t>(4, 16 + length);
|
||||
|
||||
z_cap_t reply_port_cap;
|
||||
|
@ -33,7 +44,9 @@ glcr::ErrorCode {{interface.name}}Client::{{method.name}}(const {{method.request
|
|||
// Check Response Code.
|
||||
RET_ERR(buffer_.At<uint64_t>(8));
|
||||
|
||||
{% if method.response != None %}
|
||||
response.ParseFromBytes(buffer_, 16, cap_buffer_);
|
||||
{% endif %}
|
||||
|
||||
return glcr::OK;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,13 @@ class {{interface.name}}Client {
|
|||
z_cap_t Capability() { return endpoint_; }
|
||||
|
||||
{% for method in interface.methods %}
|
||||
{% if method.request == None %}
|
||||
[[nodiscard]] glcr::ErrorCode {{method.name}}({{method.response}}& response);
|
||||
{% elif method.response == None %}
|
||||
[[nodiscard]] glcr::ErrorCode {{method.name}}(const {{method.request}}& request);
|
||||
{% else %}
|
||||
[[nodiscard]] glcr::ErrorCode {{method.name}}(const {{method.request}}& request, {{method.response}}& response);
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
private:
|
||||
z_cap_t endpoint_;
|
||||
|
|
|
@ -8,7 +8,9 @@
|
|||
|
||||
|
||||
|
||||
|
||||
glcr::ErrorCode VFSClient::open(const OpenFileRequest& request, File& response) {
|
||||
|
||||
uint64_t buffer_size = kBufferSize;
|
||||
uint64_t cap_size = kCapBufferSize;
|
||||
|
||||
|
@ -17,7 +19,10 @@ glcr::ErrorCode VFSClient::open(const OpenFileRequest& request, File& response)
|
|||
buffer_.WriteAt<uint64_t>(8, 0);
|
||||
|
||||
cap_buffer_.Reset();
|
||||
|
||||
uint64_t length = request.SerializeToBytes(buffer_, /*offset=*/16, cap_buffer_);
|
||||
|
||||
|
||||
buffer_.WriteAt<uint32_t>(4, 16 + length);
|
||||
|
||||
z_cap_t reply_port_cap;
|
||||
|
@ -33,8 +38,10 @@ glcr::ErrorCode VFSClient::open(const OpenFileRequest& request, File& response)
|
|||
// Check Response Code.
|
||||
RET_ERR(buffer_.At<uint64_t>(8));
|
||||
|
||||
|
||||
response.ParseFromBytes(buffer_, 16, cap_buffer_);
|
||||
|
||||
|
||||
return glcr::OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,9 @@ class VFSClient {
|
|||
z_cap_t Capability() { return endpoint_; }
|
||||
|
||||
|
||||
|
||||
[[nodiscard]] glcr::ErrorCode open(const OpenFileRequest& request, File& response);
|
||||
|
||||
|
||||
private:
|
||||
z_cap_t endpoint_;
|
||||
|
|
|
@ -44,9 +44,9 @@ void OpenFileRequest::ParseFromBytesInternal(const glcr::ByteBuffer& bytes, uint
|
|||
// Parse options.
|
||||
auto options_pointer = bytes.At<ExtPointer>(offset + header_size + (8 * 1));
|
||||
|
||||
options_.Resize(options_pointer.length);
|
||||
options_.Resize(options_pointer.length / sizeof(uint64_t));
|
||||
for (uint64_t i = offset + options_pointer.offset;
|
||||
i < offset + options_pointer.offset + (sizeof(uint64_t) * options_pointer.length);
|
||||
i < offset + options_pointer.offset + options_pointer.length;
|
||||
i += sizeof(uint64_t)) {
|
||||
options_.PushBack(bytes.At<uint64_t>(i));
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ class OpenFileRequest {
|
|||
void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset, const glcr::CapBuffer&);
|
||||
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset) const;
|
||||
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const;
|
||||
glcr::String path() const { return path_; }
|
||||
const glcr::String& path() const { return path_; }
|
||||
void set_path(const glcr::String& value) { path_ = value; }
|
||||
const glcr::Vector<uint64_t>& options() const { return options_; }
|
||||
void add_options(const uint64_t& value) { options_.PushBack(value); }
|
||||
|
@ -40,11 +40,11 @@ class File {
|
|||
void ParseFromBytes(const glcr::ByteBuffer&, uint64_t offset, const glcr::CapBuffer&);
|
||||
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset) const;
|
||||
uint64_t SerializeToBytes(glcr::ByteBuffer&, uint64_t offset, glcr::CapBuffer&) const;
|
||||
glcr::String path() const { return path_; }
|
||||
const glcr::String& path() const { return path_; }
|
||||
void set_path(const glcr::String& value) { path_ = value; }
|
||||
uint64_t attrs() const { return attrs_; }
|
||||
const uint64_t& attrs() const { return attrs_; }
|
||||
void set_attrs(const uint64_t& value) { attrs_ = value; }
|
||||
z_cap_t mem_cap() const { return mem_cap_; }
|
||||
const z_cap_t& mem_cap() const { return mem_cap_; }
|
||||
void set_mem_cap(const z_cap_t& value) { mem_cap_ = value; }
|
||||
|
||||
private:
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// Generated file -- DO NOT MODIFY.
|
||||
#include "example.yunq.server.h"
|
||||
|
||||
#include <mammoth/debug.h>
|
||||
#include <mammoth/util/debug.h>
|
||||
#include <zcall.h>
|
||||
|
||||
namespace {
|
||||
|
@ -87,12 +87,19 @@ glcr::ErrorCode VFSServerBase::HandleRequest(const glcr::ByteBuffer& request,
|
|||
|
||||
switch(method_select) {
|
||||
case 0: {
|
||||
|
||||
|
||||
OpenFileRequest yunq_request;
|
||||
File yunq_response;
|
||||
|
||||
yunq_request.ParseFromBytes(request, kHeaderSize, req_caps);
|
||||
|
||||
|
||||
|
||||
File yunq_response;
|
||||
|
||||
|
||||
|
||||
RET_ERR(Handleopen(yunq_request, yunq_response));
|
||||
|
||||
|
||||
resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps);
|
||||
break;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#pragma once
|
||||
|
||||
#include <glacier/status/error_or.h>
|
||||
#include <mammoth/thread.h>
|
||||
#include <mammoth/proc/thread.h>
|
||||
#include <ztypes.h>
|
||||
|
||||
#include "example.yunq.h"
|
||||
|
@ -21,9 +21,11 @@ class VFSServerBase {
|
|||
[[nodiscard]] Thread RunServer();
|
||||
|
||||
|
||||
|
||||
[[nodiscard]] virtual glcr::ErrorCode Handleopen(const OpenFileRequest&, File&) = 0;
|
||||
|
||||
|
||||
|
||||
private:
|
||||
z_cap_t endpoint_;
|
||||
|
||||
|
|
|
@ -211,13 +211,20 @@ class Parser():
|
|||
|
||||
self.consume_check(LexemeType.LEFT_PAREN)
|
||||
|
||||
request = self.consume_identifier()
|
||||
request = None
|
||||
# FIXME: Fix error handling here (and for response). We want to show
|
||||
# "expected rparen or identifier" if type is wrong rather than just
|
||||
# "expected rparen".
|
||||
if self.peektype() == LexemeType.NAME:
|
||||
request = self.consume_identifier()
|
||||
|
||||
self.consume_check(LexemeType.RIGHT_PAREN)
|
||||
self.consume_check(LexemeType.ARROW)
|
||||
self.consume_check(LexemeType.LEFT_PAREN)
|
||||
|
||||
response = self.consume_identifier()
|
||||
response = None
|
||||
if self.peektype() == LexemeType.NAME:
|
||||
response = self.consume_identifier()
|
||||
|
||||
self.consume_check(LexemeType.RIGHT_PAREN)
|
||||
self.consume_check(LexemeType.SEMICOLON)
|
||||
|
@ -269,14 +276,18 @@ def type_check(decls: list[Decl]):
|
|||
for decl in decls:
|
||||
if type(decl) is Interface:
|
||||
for method in decl.methods:
|
||||
if method.request not in name_dict.keys():
|
||||
sys.exit("Request type '%s' for '%s.%s' does not exist" % (method.request, decl.name, method.name))
|
||||
if type(name_dict[method.request]) is not Message:
|
||||
sys.exit("Request type '%s' for '%s.%s' should be a message" % (method.request, decl.name, method.name))
|
||||
if method.response not in name_dict.keys():
|
||||
sys.exit("Response type '%s' for '%s.%s' does not exist" % (method.response, decl.name, method.name))
|
||||
if type(name_dict[method.response]) is not Message:
|
||||
sys.exit("Response type '%s' for '%s.%s' should be a message" % (method.response, decl.name, method.name))
|
||||
if method.request is None and method.response is None:
|
||||
sys.exit("Method '%s.%s' cannot have empty request and response" % (decl.name, method.name))
|
||||
if method.request is not None:
|
||||
if method.request not in name_dict.keys():
|
||||
sys.exit("Request type '%s' for '%s.%s' does not exist" % (method.request, decl.name, method.name))
|
||||
if type(name_dict[method.request]) is not Message:
|
||||
sys.exit("Request type '%s' for '%s.%s' should be a message" % (method.request, decl.name, method.name))
|
||||
if method.response is not None:
|
||||
if method.response not in name_dict.keys():
|
||||
sys.exit("Response type '%s' for '%s.%s' does not exist" % (method.response, decl.name, method.name))
|
||||
if type(name_dict[method.response]) is not Message:
|
||||
sys.exit("Response type '%s' for '%s.%s' should be a message" % (method.response, decl.name, method.name))
|
||||
|
||||
def print_ast(decls: list[Decl]):
|
||||
for decl in decls:
|
||||
|
|
|
@ -88,14 +88,29 @@ glcr::ErrorCode {{interface.name}}ServerBase::HandleRequest(const glcr::ByteBuff
|
|||
switch(method_select) {
|
||||
{%- for method in interface.methods %}
|
||||
case {{loop.index0}}: {
|
||||
|
||||
{% if method.request != None %}
|
||||
{{method.request}} yunq_request;
|
||||
{{method.response}} yunq_response;
|
||||
|
||||
yunq_request.ParseFromBytes(request, kHeaderSize, req_caps);
|
||||
{% endif %}
|
||||
|
||||
{% if method.response != None %}
|
||||
{{method.response}} yunq_response;
|
||||
{% endif %}
|
||||
|
||||
{% if method.request == None %}
|
||||
RET_ERR(Handle{{method.name}}(yunq_response));
|
||||
{% elif method.response == None %}
|
||||
RET_ERR(Handle{{method.name}}(yunq_request));
|
||||
{% else %}
|
||||
RET_ERR(Handle{{method.name}}(yunq_request, yunq_response));
|
||||
{% endif %}
|
||||
|
||||
{% if method.response != None %}
|
||||
resp_length = yunq_response.SerializeToBytes(response, kHeaderSize, resp_caps);
|
||||
{% else %}
|
||||
resp_length = 0;
|
||||
{% endif %}
|
||||
break;
|
||||
}
|
||||
{%- endfor %}
|
||||
|
|
|
@ -21,7 +21,13 @@ class {{interface.name}}ServerBase {
|
|||
[[nodiscard]] Thread RunServer();
|
||||
|
||||
{% for method in interface.methods %}
|
||||
{% if method.request == None %}
|
||||
[[nodiscard]] virtual glcr::ErrorCode Handle{{method.name}}({{method.response}}&) = 0;
|
||||
{% elif method.response == None %}
|
||||
[[nodiscard]] virtual glcr::ErrorCode Handle{{method.name}}(const {{method.request}}&) = 0;
|
||||
{% else %}
|
||||
[[nodiscard]] virtual glcr::ErrorCode Handle{{method.name}}(const {{method.request}}&, {{method.response}}&) = 0;
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
private:
|
||||
|
|
Loading…
Reference in New Issue