Joedb 10.2.1
The Journal-Only Embedded Database
Loading...
Searching...
No Matches
Client.h
Go to the documentation of this file.
1#ifndef joedb_rpc_Client_declared
2#define joedb_rpc_Client_declared
3
7#include "joedb/Thread_Safe.h"
11
12#include <vector>
13
14namespace joedb::rpc
15{
16 class Client
17 {
18 private:
19 Buffer<13> buffer;
21 const std::vector<Signature> &signatures;
22
23 int64_t session_id;
24
25 void handshake()
26 {
27 const SHA_256::Hash h = get_hash(signatures);
28
29 {
30 Lock<Channel&> lock(channel);
31 lock->write((const char *)h.data(), h.size() * sizeof h[0]);
32 lock->read(buffer.data, 9);
33 }
34
35 buffer.index = 0;
36 if (buffer.read<char>() != 'H')
37 throw Exception("failed handshake");
38 session_id = buffer.read<int64_t>();
39 }
40
41 void ping(Lock<Channel&> &lock)
42 {
43 char c = 'P';
44 lock->write(&c, 1);
45 lock->read(&c, 1);
46 }
47
48 // TODO: ping thread
49
50 public:
51 Client(Channel &channel, const std::vector<Signature> &signatures):
52 channel(channel),
53 signatures(signatures)
54 {
55 handshake();
56 }
57
58 void call(int64_t procedure_id, Memory_File &file)
59 {
60 Lock<Channel&> lock(channel);
61
62 auto &signature = signatures[procedure_id];
63
64 {
65 // Check that the prolog is matching?
66 const int64_t from = int64_t(signature.prolog.size());
67 const int64_t until = file.get_size();
68
69 buffer.index = 0;
70 buffer.write<char>('C');
71 buffer.write<int64_t>(procedure_id);
72 buffer.write<int64_t>(until);
73
74 // Could be optimized into one single write?
75 lock->write(buffer.data, buffer.index);
76 lock->write(file.get_data().data() + from, until - from);
77 lock->read(buffer.data, 9);
78 }
79
80 buffer.index = 0;
81 const char reply = buffer.read<char>();
82
83 if (reply == 'C')
84 {
85 const size_t from = file.get_data().size();
86 const int64_t until = buffer.read<int64_t>();
87 file.get_data().resize(size_t(until));
88 lock->read(file.get_data().data() + from, size_t(until) - from);
89 file.pwrite((const char *)&until, 8, 0);
90 file.pwrite((const char *)&until, 8, 8);
91 }
92 else
93 {
94 const int64_t n = buffer.read<int64_t>();
95 std::string error_message;
96 error_message.resize(n);
97 lock->read(error_message.data(), n);
98 throw Exception(error_message);
99 }
100 }
101
103 {
104 try
105 {
106 Lock<Channel&> lock(channel);
107 lock->write("Q", 1);
108 }
109 catch (...)
110 {
111 }
112 }
113 };
114}
115
116#endif
size_t index
Definition Buffer.h:20
void write(T x)
Definition Buffer.h:23
char data[size+extra_size]
Definition Buffer.h:19
void pwrite(const char *buffer, size_t size, int64_t offset) override
Write a range of bytes. Extend file size if necessary.
std::string & get_data()
Definition Memory_File.h:23
int64_t get_size() const override
Get the size of the file, or -1 if it is unknown.
Definition Memory_File.h:27
std::array< uint32_t, 8 > Hash
Definition SHA_256.h:59
Client(Channel &channel, const std::vector< Signature > &signatures)
Definition Client.h:51
void call(int64_t procedure_id, Memory_File &file)
Definition Client.h:58
SHA_256::Hash get_hash(const std::vector< Signature > &signatures)
Compute hash code for a collection of procedure signatures.
Definition get_hash.cpp:9