3 * Copyright (C) 2013-2023 Filipe Coelho <falktx@falktx.com>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * For a full copy of the GNU General Public License see the doc/GPL.txt file.
18 #ifndef CARLA_PIPE_UTILS_HPP_INCLUDED
19 #define CARLA_PIPE_UTILS_HPP_INCLUDED
21 #include "CarlaJuceUtils.hpp"
22 #include "CarlaMutex.hpp"
25 # include "lv2/atom.h"
27 # include "lv2/atom/atom.h"
30 // -----------------------------------------------------------------------
31 // CarlaPipeCommon class
39 CarlaPipeCommon() noexcept
;
44 virtual ~CarlaPipeCommon() /*noexcept*/;
47 * A message has been received (in the context of idlePipe()).
48 * If extra data is required, use any of the readNextLineAs* functions.
49 * Returning true means the message has been handled and should not propagate to subclasses.
51 virtual bool msgReceived(const char* msg
) noexcept
= 0;
54 * An error has occurred during the current requested operation.
55 * Reimplementing this method allows to catch these errors as strings.
56 * By default the error is simply printed to stderr.
58 virtual void fail(const char* error
) noexcept
65 * Check if the pipe is running.
67 bool isPipeRunning() const noexcept
;
70 * Check the pipe for new messages and send them to msgReceived().
72 void idlePipe(bool onlyOnce
= false) noexcept
;
74 // -------------------------------------------------------------------
78 * Lock the pipe write mutex.
80 void lockPipe() const noexcept
;
83 * Try locking the pipe write mutex.
84 * Returns true if successful.
86 bool tryLockPipe() const noexcept
;
89 * Unlock the pipe write mutex.
91 void unlockPipe() const noexcept
;
94 * Get the pipe write lock.
96 CarlaMutex
& getPipeLock() const noexcept
;
98 // -------------------------------------------------------------------
99 // read lines, must only be called in the context of msgReceived()
102 * Read the next line as a boolean.
104 bool readNextLineAsBool(bool& value
) const noexcept
;
107 * Read the next line as a byte.
109 bool readNextLineAsByte(uint8_t& value
) const noexcept
;
112 * Read the next line as an integer.
114 bool readNextLineAsInt(int32_t& value
) const noexcept
;
117 * Read the next line as an unsigned integer.
119 bool readNextLineAsUInt(uint32_t& value
) const noexcept
;
122 * Read the next line as a long integer.
124 bool readNextLineAsLong(int64_t& value
) const noexcept
;
127 * Read the next line as a long unsigned integer.
129 bool readNextLineAsULong(uint64_t& value
) const noexcept
;
132 * Read the next line as a floating point number (single precision).
134 bool readNextLineAsFloat(float& value
) const noexcept
;
137 * Read the next line as a floating point number (double precision).
139 bool readNextLineAsDouble(double& value
) const noexcept
;
142 * Read the next line as a string.
143 * @note: @a value must be freed if valid and allocateString is true.
145 bool readNextLineAsString(const char*& value
, bool allocateString
, uint32_t size
= 0) const noexcept
;
148 * Read the next line as a string, returning an allocated copy that needs to be freed.
150 char* readNextLineAsString() const noexcept
;
152 // -------------------------------------------------------------------
153 // write messages, must be locked before calling
156 * Write a valid message with unknown size.
157 * A valid message has only one '\n' character and it's at the end.
159 bool writeMessage(const char* msg
) const noexcept
;
162 * Write a valid message with known size.
163 * A valid message has only one '\n' character and it's at the end.
165 bool writeMessage(const char* msg
, std::size_t size
) const noexcept
;
168 * Write and fix a message.
170 bool writeAndFixMessage(const char* msg
) const noexcept
;
173 * Write an empty message, which means a single '\n'.
175 bool writeEmptyMessage() const noexcept
;
178 * Sync all messages currently in cache.
179 * This call will forcely write any messages in cache to any relevant IO.
181 bool syncMessages() const noexcept
;
183 // -------------------------------------------------------------------
184 // write prepared messages, no lock or flush needed (done internally)
187 * Write an "error" message.
189 bool writeErrorMessage(const char* error
) const noexcept
;
192 * Write a "control" message used for parameter/control changes.
194 bool writeControlMessage(uint32_t index
, float value
, bool withWriteLock
= true) const noexcept
;
197 * Write a "configure" message used for state changes.
199 bool writeConfigureMessage(const char* key
, const char* value
) const noexcept
;
202 * Write a "program" message (using index).
204 bool writeProgramMessage(uint32_t index
) const noexcept
;
207 * Write a "program" message (using channel, bank and program).
209 bool writeProgramMessage(uint8_t channel
, uint32_t bank
, uint32_t program
) const noexcept
;
212 * Write a "midiprogram" message (using bank and program).
214 bool writeMidiProgramMessage(uint32_t bank
, uint32_t program
) const noexcept
;
217 * Write a "reloadprograms" message.
219 bool writeReloadProgramsMessage(int32_t index
) const noexcept
;
222 * Write a MIDI "note" message.
224 bool writeMidiNoteMessage(bool onOff
, uint8_t channel
, uint8_t note
, uint8_t velocity
) const noexcept
;
227 * Write an lv2 "atom" message.
229 bool writeLv2AtomMessage(uint32_t index
, const LV2_Atom
* atom
) const noexcept
;
232 * Write an lv2 "parameter" message.
234 bool writeLv2ParameterMessage(const char* uri
, float value
, bool withWriteLock
= true) const noexcept
;
237 * Write an lv2 "urid" message.
239 bool writeLv2UridMessage(uint32_t urid
, const char* uri
) const noexcept
;
241 // -------------------------------------------------------------------
245 PrivateData
* const pData
;
247 // -------------------------------------------------------------------
250 const char* _readline(bool allocReturn
, uint16_t size
, bool& readSucess
) const noexcept
;
253 const char* _readlineblock(bool allocReturn
, uint16_t size
= 0, uint32_t timeOutMilliseconds
= 50) const noexcept
;
256 bool _writeMsgBuffer(const char* msg
, std::size_t size
) const noexcept
;
258 CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeCommon
)
261 // -----------------------------------------------------------------------
262 // CarlaPipeServer class
264 class CarlaPipeServer
: public CarlaPipeCommon
270 CarlaPipeServer() noexcept
;
275 ~CarlaPipeServer() /*noexcept*/ override
;
278 * Get the process ID of this pipe's matching client.
279 * Will return 0 if client is not running.
280 * @note: Unsupported on Windows
282 uintptr_t getPID() const noexcept
;
285 * Start the pipe server using @a filename with 2 arguments.
288 bool startPipeServer(const char* const filename
, const char* const arg1
, const char* const arg2
, const int size
= -1) noexcept
;
291 * Stop the pipe server.
292 * This will send a quit message to the client, wait for it to close for @a timeOutMilliseconds, and close the pipes.
294 void stopPipeServer(const uint32_t timeOutMilliseconds
) noexcept
;
297 * Close the pipes without waiting for the child process to terminate.
299 void closePipeServer() noexcept
;
301 // -------------------------------------------------------------------
302 // write prepared messages, no lock or flush needed (done internally)
305 * Write a single "show" message.
307 void writeShowMessage() const noexcept
;
310 * Write a single "focus" message.
312 void writeFocusMessage() const noexcept
;
315 * Write a single "hide" message.
317 void writeHideMessage() const noexcept
;
319 CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeServer
)
322 // -----------------------------------------------------------------------
323 // CarlaPipeClient class
325 class CarlaPipeClient
: public CarlaPipeCommon
331 CarlaPipeClient() noexcept
;
336 ~CarlaPipeClient() /*noexcept*/ override
;
339 * Initialize the pipes used by a server.
340 * @a argv must match the arguments set the by server.
342 bool initPipeClient(const char* argv
[]) noexcept
;
347 void closePipeClient() noexcept
;
349 // -------------------------------------------------------------------
350 // write prepared messages, no lock or flush needed (done internally)
353 * Write a single "exiting" message and wait for server to respond.
355 void writeExitingMessageAndWait() noexcept
;
357 CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeClient
)
360 // -----------------------------------------------------------------------
362 #endif // CARLA_PIPE_UTILS_HPP_INCLUDED