Cleanup
[carla.git] / source / utils / CarlaPipeUtils.hpp
blobce3163e9446a88b8fe3de596c61d07ba2c57ddb2
1 /*
2 * Carla Pipe utils
3 * Copyright (C) 2013-2024 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"
24 #ifdef BUILDING_CARLA
25 # include "lv2/atom.h"
26 #else
27 # include "lv2/atom/atom.h"
28 #endif
30 // -----------------------------------------------------------------------
31 // CarlaPipeCommon class
33 class CarlaPipeCommon
35 protected:
36 /*!
37 * Constructor.
39 CarlaPipeCommon() noexcept;
41 /*!
42 * Destructor.
44 virtual ~CarlaPipeCommon() /*noexcept*/;
46 /*!
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;
53 /*!
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
60 carla_stderr2(error);
63 public:
64 /*!
65 * Check if the pipe is running.
67 bool isPipeRunning() const noexcept;
69 /*!
70 * Check the pipe for new messages and send them to msgReceived().
72 void idlePipe(bool onlyOnce = false) noexcept;
74 // -------------------------------------------------------------------
75 // write lock
77 /*!
78 * Lock the pipe write mutex.
80 void lockPipe() const noexcept;
82 /*!
83 * Try locking the pipe write mutex.
84 * Returns true if successful.
86 bool tryLockPipe() const noexcept;
88 /*!
89 * Unlock the pipe write mutex.
91 void unlockPipe() const noexcept;
93 /*!
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 // -------------------------------------------------------------------
243 protected:
244 struct PrivateData;
245 PrivateData* const pData;
247 // -------------------------------------------------------------------
249 /*! @internal */
250 const char* _readline(bool allocReturn, uint16_t size, bool& readSucess) const noexcept;
252 /*! @internal */
253 const char* _readlineblock(bool allocReturn, uint16_t size = 0, uint32_t timeOutMilliseconds = 50) const noexcept;
255 /*! @internal */
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
266 public:
268 * Constructor.
270 CarlaPipeServer() noexcept;
273 * Destructor.
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.
286 * @see fail()
288 bool startPipeServer(const char* helperTool, const char* filename, const char* arg1, const char* arg2,
289 int size = -1, int timeOutMilliseconds = -1) noexcept;
292 * Start the pipe server using @a filename with 2 arguments.
293 * @see fail()
295 bool startPipeServer(const char* filename, const char* arg1, const char* arg2,
296 int size = -1, int timeOutMilliseconds = -1) noexcept;
299 * Stop the pipe server.
300 * This will send a quit message to the client, wait for it to close for @a timeOutMilliseconds, and close the pipes.
302 void stopPipeServer(uint32_t timeOutMilliseconds) noexcept;
305 * Close the pipes without waiting for the child process to terminate.
307 void closePipeServer() noexcept;
309 // -------------------------------------------------------------------
310 // write prepared messages, no lock or flush needed (done internally)
313 * Write a single "show" message.
315 void writeShowMessage() const noexcept;
318 * Write a single "focus" message.
320 void writeFocusMessage() const noexcept;
323 * Write a single "hide" message.
325 void writeHideMessage() const noexcept;
327 CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeServer)
330 // -----------------------------------------------------------------------
331 // CarlaPipeClient class
333 class CarlaPipeClient : public CarlaPipeCommon
335 public:
337 * Constructor.
339 CarlaPipeClient() noexcept;
342 * Destructor.
344 ~CarlaPipeClient() /*noexcept*/ override;
347 * Initialize the pipes used by a server.
348 * @a argv must match the arguments set the by server.
350 bool initPipeClient(const char* argv[]) noexcept;
353 * Close the pipes.
355 void closePipeClient() noexcept;
357 // -------------------------------------------------------------------
358 // write prepared messages, no lock or flush needed (done internally)
361 * Write a single "exiting" message and wait for server to respond.
363 void writeExitingMessageAndWait() noexcept;
365 CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(CarlaPipeClient)
368 // -----------------------------------------------------------------------
370 #endif // CARLA_PIPE_UTILS_HPP_INCLUDED