File indexing completed on 2024-05-12 05:25:58

0001 /*
0002  * Copyright (C) 2014 Aaron Seigo <aseigo@kde.org>
0003  * Copyright (C) 2016 Christian Mollekopf <mollekopf@kolabsys.com>
0004  *
0005  * This library is free software; you can redistribute it and/or
0006  * modify it under the terms of the GNU Lesser General Public
0007  * License as published by the Free Software Foundation; either
0008  * version 2.1 of the License, or (at your option) version 3, or any
0009  * later version accepted by the membership of KDE e.V. (or its
0010  * successor approved by the membership of KDE e.V.), which shall
0011  * act as a proxy defined in Section 6 of version 3 of the license.
0012  *
0013  * This library is distributed in the hope that it will be useful,
0014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0016  * Lesser General Public License for more details.
0017  *
0018  * You should have received a copy of the GNU Lesser General Public
0019  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
0020  */
0021 
0022 #include "commands.h"
0023 
0024 #include <QLocalSocket>
0025 #include <log.h>
0026 
0027 namespace Sink {
0028 
0029 namespace Commands {
0030 
0031 QByteArray name(int commandId)
0032 {
0033     switch (commandId) {
0034         case UnknownCommand:
0035             return "Unknown";
0036         case CommandCompletionCommand:
0037             return "Completion";
0038         case HandshakeCommand:
0039             return "Handshake";
0040         case RevisionUpdateCommand:
0041             return "RevisionUpdate";
0042         case SynchronizeCommand:
0043             return "Synchronize";
0044         case DeleteEntityCommand:
0045             return "DeleteEntity";
0046         case ModifyEntityCommand:
0047             return "ModifyEntity";
0048         case CreateEntityCommand:
0049             return "CreateEntity";
0050         case SearchSourceCommand:
0051             return "SearchSource";
0052         case ShutdownCommand:
0053             return "Shutdown";
0054         case NotificationCommand:
0055             return "Notification";
0056         case PingCommand:
0057             return "Ping";
0058         case RevisionReplayedCommand:
0059             return "RevisionReplayed";
0060         case InspectionCommand:
0061             return "Inspection";
0062         case RemoveFromDiskCommand:
0063             return "RemoveFromDisk";
0064         case FlushCommand:
0065             return "Flush";
0066         case SecretCommand:
0067             return "Secret";
0068         case UpgradeCommand:
0069             return "Upgrade";
0070         case AbortSynchronizationCommand:
0071             return "AbortSynchronization";
0072         case CustomCommand:
0073             return "Custom";
0074     };
0075     return QByteArray("Invalid commandId");
0076 }
0077 
0078 int headerSize()
0079 {
0080     return sizeof(int) + (sizeof(uint) * 2);
0081 }
0082 
0083 void write(QLocalSocket *device, int messageId, int commandId)
0084 {
0085     write(device, messageId, commandId, nullptr, 0);
0086 }
0087 
0088 static void write(QLocalSocket *device, const char *buffer, uint size)
0089 {
0090     const auto bytesWritten = device->write(buffer, size);
0091     if (bytesWritten < 0) {
0092         SinkWarningCtx(Sink::Log::Context{"commands"}) << "Error while writing " << device->errorString();
0093     } else if (bytesWritten != size) {
0094         SinkErrorCtx(Sink::Log::Context{"commands"}) << "Wrote incorrect number of bytes " << bytesWritten << " Expected " << size << " Buffer " << QByteArray{buffer, static_cast<int>(size)};
0095         Q_ASSERT(false);
0096     }
0097 }
0098 
0099 void write(QLocalSocket *device, int messageId, int commandId, const char *buffer, uint size)
0100 {
0101     if (size > 0 && !buffer) {
0102         size = 0;
0103     }
0104 
0105     write(device, (const char *)&messageId, sizeof(int));
0106     write(device, (const char *)&commandId, sizeof(int));
0107     write(device, (const char *)&size, sizeof(uint));
0108     if (buffer) {
0109         write(device, buffer, size);
0110     }
0111     //The default implementation will happily buffer 200k bytes before sending it out which doesn't make the sytem exactly responsive.
0112     //1k is arbitrary, but fits a bunch of messages at least.
0113     if (device->bytesToWrite() > 1000) {
0114         device->flush();
0115     }
0116 }
0117 
0118 void write(QLocalSocket *device, int messageId, int commandId, flatbuffers::FlatBufferBuilder &fbb)
0119 {
0120     write(device, messageId, commandId, (const char *)fbb.GetBufferPointer(), fbb.GetSize());
0121 }
0122 
0123 } // namespace Commands
0124 
0125 } // namespace Sink