1 // =================================
  2 // Copyright (c) 2021 Seppo Laakko
  3 // Distributed under the MIT license
  4 // =================================
  5 
  6 #include <cmajor/build/FiberConnection.hpp>
  7 #include <cmajor/build/BuildServer.hpp>
  8 #include <soulng/util/Fiber.hpp>
  9 #include <sngjson/json/JsonParser.hpp>
 10 #include <sngjson/json/JsonLexer.hpp>
 11 
 12 namespace cmajor { namespace build {
 13 
 14 FiberClient::FiberClient() : name("fiber client")
 15 {
 16 }
 17 
 18 const std::string& FiberClient::Name() const
 19 {
 20     return name;
 21 }
 22 
 23 void FiberClient::Exit()
 24 {
 25 }
 26 
 27 FiberServer::FiberServer() : name("fiber server")
 28 {
 29 }
 30 
 31 const std::string& FiberServer::Name() const
 32 {
 33     return name;
 34 }
 35 
 36 void FiberServer::Exit()
 37 {
 38 }
 39 
 40 FiberConnection::FiberConnection(Log* log) : Connection(log)serverFiber(nullptr)clientFiber(nullptr)currentFiber(nullptr)client()server()
 41 {
 42 }
 43 
 44 FiberConnection::~FiberConnection()
 45 {
 46     if (clientFiber)
 47     {
 48         SwitchToFiber(clientFiber);
 49     }
 50 }
 51 
 52 void FiberConnection::SetFibers(void* serverFibervoid* clientFiber)
 53 {
 54     this->serverFiber = serverFiber;
 55     this->clientFiber = clientFiber;
 56     currentFiber = serverFiber;
 57 }
 58 
 59 void FiberConnection::Switch()
 60 {
 61     if (currentFiber == clientFiber)
 62     {
 63         currentFiber = serverFiber;
 64         SwitchToFiber(serverFiber);
 65     }
 66     else
 67     {
 68         currentFiber = clientFiber;
 69         SwitchToFiber(clientFiber);
 70     }
 71 }
 72 
 73 const std::string& FiberConnection::GetActor() const
 74 {
 75     if (currentFiber == clientFiber)
 76     {
 77         return client.Name();
 78     }
 79     else
 80     {
 81         return server.Name();
 82     }
 83 }
 84 
 85 Host* FiberConnection::GetHost() const
 86 {
 87     if (currentFiber == clientFiber)
 88     {
 89         return const_cast<FiberClient*>(&client);
 90     }
 91     else
 92     {
 93         return const_cast<FiberServer*>(&server);
 94     }
 95 }
 96 
 97 void FiberConnection::DoSend(JsonObject* messageObject)
 98 {
 99     if (messageObject)
100     {
101         messageStr = messageObject->ToString();
102     }
103     else
104     {
105         messageStr = "{ }";
106     }
107     Switch();
108 }
109 
110 std::std::unique_ptr<JsonObject>FiberConnection::DoReceive()
111 {
112     Switch();
113     JsonLexer lexer(ToUtf32(messageStr)""0);
114     std::unique_ptr<JsonValue> jsonValue = JsonParser::Parse(lexer);
115     if (jsonValue->Type() == JsonValueType::object)
116     {
117         std::unique_ptr<JsonObject> messageObject(static_cast<JsonObject*>(jsonValue.release()));
118         return messageObject;
119     }
120     else
121     {
122         throw std::runtime_error("FiberConnection: JSON object expected");
123     }
124 }
125 
126 void FiberConnection::DoClose()
127 {
128 }
129 
130 std::std::unique_ptr<FiberConnection>CreateFiberConnection(Log*log)
131 {
132     return std::unique_ptr<FiberConnection>(new FiberConnection(log));
133 }
134 
135 } } // namespace cmajor::buil