diff options
19 files changed, 4 insertions, 37 deletions
diff --git a/Slimber/MainController.cpp b/Slimber/MainController.cpp index c2bbb40..523040c 100644 --- a/Slimber/MainController.cpp +++ b/Slimber/MainController.cpp @@ -16,19 +16,19 @@ #include <Swiften/LinkLocal/LinkLocalServiceBrowser.h> #include <Swiften/LinkLocal/DNSSD/PlatformDNSSDQuerierFactory.h> #include "Slimber/Server.h" #include "Slimber/FileVCardCollection.h" #include "Slimber/MenuletController.h" #include "Slimber/Menulet.h" using namespace Swift; -MainController::MainController(Menulet* menulet, EventLoop* eventLoop) : menulet(menulet) { +MainController::MainController(Menulet* menulet, EventLoop* eventLoop) { dnsSDQuerier = PlatformDNSSDQuerierFactory(eventLoop).createQuerier(); assert(dnsSDQuerier); linkLocalServiceBrowser = new LinkLocalServiceBrowser(dnsSDQuerier); linkLocalServiceBrowser->onServiceAdded.connect( boost::bind(&MainController::handleServicesChanged, this)); linkLocalServiceBrowser->onServiceRemoved.connect( boost::bind(&MainController::handleServicesChanged, this)); linkLocalServiceBrowser->onServiceChanged.connect( diff --git a/Slimber/MainController.h b/Slimber/MainController.h index 4b341d9..a91f10c 100644 --- a/Slimber/MainController.h +++ b/Slimber/MainController.h @@ -31,16 +31,15 @@ class MainController { void handleSelfConnected(bool b); void handleServicesChanged(); void handleServerStopped(boost::optional<Swift::ServerError> error); void handleRestartRequested(); void start(); void stop(); private: - Menulet* menulet; boost::shared_ptr<Swift::DNSSDQuerier> dnsSDQuerier; Swift::LinkLocalServiceBrowser* linkLocalServiceBrowser; Swift::VCardCollection* vCardCollection; Swift::Server* server; MenuletController* menuletController; }; diff --git a/Swiften/Avatars/VCardUpdateAvatarManager.cpp b/Swiften/Avatars/VCardUpdateAvatarManager.cpp index 0c3ad23..3c086d5 100644 --- a/Swiften/Avatars/VCardUpdateAvatarManager.cpp +++ b/Swiften/Avatars/VCardUpdateAvatarManager.cpp @@ -14,19 +14,19 @@ #include <Swiften/StringCodecs/SHA1.h> #include <Swiften/StringCodecs/Hexify.h> #include <Swiften/Avatars/AvatarStorage.h> #include <Swiften/MUC/MUCRegistry.h> #include <Swiften/VCards/VCardManager.h> #include <Swiften/Base/Log.h> namespace Swift { -VCardUpdateAvatarManager::VCardUpdateAvatarManager(VCardManager* vcardManager, StanzaChannel* stanzaChannel, AvatarStorage* avatarStorage, MUCRegistry* mucRegistry) : vcardManager_(vcardManager), stanzaChannel_(stanzaChannel), avatarStorage_(avatarStorage), mucRegistry_(mucRegistry) { +VCardUpdateAvatarManager::VCardUpdateAvatarManager(VCardManager* vcardManager, StanzaChannel* stanzaChannel, AvatarStorage* avatarStorage, MUCRegistry* mucRegistry) : vcardManager_(vcardManager), avatarStorage_(avatarStorage), mucRegistry_(mucRegistry) { stanzaChannel->onPresenceReceived.connect(boost::bind(&VCardUpdateAvatarManager::handlePresenceReceived, this, _1)); stanzaChannel->onAvailableChanged.connect(boost::bind(&VCardUpdateAvatarManager::handleStanzaChannelAvailableChanged, this, _1)); vcardManager_->onVCardChanged.connect(boost::bind(&VCardUpdateAvatarManager::handleVCardChanged, this, _1, _2)); } void VCardUpdateAvatarManager::handlePresenceReceived(boost::shared_ptr<Presence> presence) { boost::shared_ptr<VCardUpdate> update = presence->getPayload<VCardUpdate>(); if (!update || presence->getPayload<ErrorPayload>()) { return; diff --git a/Swiften/Avatars/VCardUpdateAvatarManager.h b/Swiften/Avatars/VCardUpdateAvatarManager.h index de68672..28630ea 100644 --- a/Swiften/Avatars/VCardUpdateAvatarManager.h +++ b/Swiften/Avatars/VCardUpdateAvatarManager.h @@ -30,15 +30,14 @@ namespace Swift { private: void handlePresenceReceived(boost::shared_ptr<Presence>); void handleStanzaChannelAvailableChanged(bool); void handleVCardChanged(const JID& from, VCard::ref); void setAvatarHash(const JID& from, const std::string& hash); JID getAvatarJID(const JID& o) const; private: VCardManager* vcardManager_; - StanzaChannel* stanzaChannel_; AvatarStorage* avatarStorage_; MUCRegistry* mucRegistry_; std::map<JID, std::string> avatarHashes_; }; } diff --git a/Swiften/Examples/SendFile/ReceiveFile.cpp b/Swiften/Examples/SendFile/ReceiveFile.cpp index f80f03a..39b3cc3 100644 --- a/Swiften/Examples/SendFile/ReceiveFile.cpp +++ b/Swiften/Examples/SendFile/ReceiveFile.cpp @@ -112,21 +112,18 @@ class FileReceiver { private: JID jid; std::string password; Client* client; ClientXMLTracer* tracer; JingleSessionManager* jingleSessionManager; IncomingFileTransferManager* incomingFileTransferManager; std::vector<IncomingFileTransfer::ref> incomingFileTransfers; - DefaultLocalJingleTransportCandidateGeneratorFactory *localFactory; - DefaultRemoteJingleTransportCandidateSelectorFactory *remoteFactory; - SOCKS5BytestreamRegistry* bytestreamRegistry; }; int main(int argc, char* argv[]) { if (argc != 3) { std::cerr << "Usage: " << argv[0] << " <jid> <password>" << std::endl; return -1; } diff --git a/Swiften/Examples/SendFile/SendFile.cpp b/Swiften/Examples/SendFile/SendFile.cpp index df3cea4..a926170 100644 --- a/Swiften/Examples/SendFile/SendFile.cpp +++ b/Swiften/Examples/SendFile/SendFile.cpp @@ -119,20 +119,18 @@ class FileSender { } void exit(int code) { exitCode = code; eventLoop.stop(); } private: BoostConnectionServer::ref connectionServer; - SOCKS5BytestreamServer* socksBytestreamServer; - SOCKS5BytestreamRegistry* registry; OutgoingFileTransfer::ref outgoingFileTransfer; JID jid; std::string password; JID recipient; boost::filesystem::path file; Client* client; ClientXMLTracer* tracer; }; diff --git a/Swiften/FileTransfer/FileTransferManagerImpl.cpp b/Swiften/FileTransfer/FileTransferManagerImpl.cpp index 83320b2..853738c 100644 --- a/Swiften/FileTransfer/FileTransferManagerImpl.cpp +++ b/Swiften/FileTransfer/FileTransferManagerImpl.cpp @@ -25,19 +25,19 @@ #include <Swiften/Presence/PresenceOracle.h> #include <Swiften/Elements/Presence.h> #include <Swiften/Network/ConnectionFactory.h> #include <Swiften/Network/ConnectionServerFactory.h> #include <Swiften/Network/HostAddress.h> #include <Swiften/Network/NATTraverser.h> namespace Swift { -FileTransferManagerImpl::FileTransferManagerImpl(const JID& ownFullJID, JingleSessionManager* jingleSessionManager, IQRouter* router, EntityCapsProvider* capsProvider, PresenceOracle* presOracle, ConnectionFactory* connectionFactory, ConnectionServerFactory* connectionServerFactory, TimerFactory* timerFactory, NATTraverser* natTraverser) : ownJID(ownFullJID), jingleSM(jingleSessionManager), iqRouter(router), capsProvider(capsProvider), presenceOracle(presOracle), timerFactory(timerFactory), connectionFactory(connectionFactory), connectionServerFactory(connectionServerFactory), natTraverser(natTraverser), bytestreamServer(NULL), s5bProxyFinder(NULL) { +FileTransferManagerImpl::FileTransferManagerImpl(const JID& ownFullJID, JingleSessionManager* jingleSessionManager, IQRouter* router, EntityCapsProvider* capsProvider, PresenceOracle* presOracle, ConnectionFactory* connectionFactory, ConnectionServerFactory* connectionServerFactory, TimerFactory* timerFactory, NATTraverser* natTraverser) : ownJID(ownFullJID), jingleSM(jingleSessionManager), iqRouter(router), capsProvider(capsProvider), presenceOracle(presOracle), connectionServerFactory(connectionServerFactory), bytestreamServer(NULL), s5bProxyFinder(NULL) { assert(!ownFullJID.isBare()); connectivityManager = new ConnectivityManager(natTraverser); bytestreamRegistry = new SOCKS5BytestreamRegistry(); bytestreamProxy = new SOCKS5BytestreamProxy(connectionFactory, timerFactory); localCandidateGeneratorFactory = new DefaultLocalJingleTransportCandidateGeneratorFactory(connectivityManager, bytestreamRegistry, bytestreamProxy, ownFullJID); remoteCandidateSelectorFactory = new DefaultRemoteJingleTransportCandidateSelectorFactory(connectionFactory, timerFactory); outgoingFTManager = new OutgoingFileTransferManager(jingleSM, iqRouter, capsProvider, remoteCandidateSelectorFactory, localCandidateGeneratorFactory, bytestreamRegistry, bytestreamProxy); diff --git a/Swiften/FileTransfer/FileTransferManagerImpl.h b/Swiften/FileTransfer/FileTransferManagerImpl.h index 248b437..ecc692d 100644 --- a/Swiften/FileTransfer/FileTransferManagerImpl.h +++ b/Swiften/FileTransfer/FileTransferManagerImpl.h @@ -61,21 +61,18 @@ namespace Swift { OutgoingFileTransferManager* outgoingFTManager; IncomingFileTransferManager* incomingFTManager; RemoteJingleTransportCandidateSelectorFactory* remoteCandidateSelectorFactory; LocalJingleTransportCandidateGeneratorFactory* localCandidateGeneratorFactory; JingleSessionManager* jingleSM; IQRouter* iqRouter; EntityCapsProvider* capsProvider; PresenceOracle* presenceOracle; - TimerFactory* timerFactory; - ConnectionFactory* connectionFactory; ConnectionServerFactory* connectionServerFactory; - NATTraverser* natTraverser; SOCKS5BytestreamRegistry* bytestreamRegistry; SOCKS5BytestreamServer* bytestreamServer; SOCKS5BytestreamProxy* bytestreamProxy; ConnectivityManager* connectivityManager; SOCKS5BytestreamProxyFinder* s5bProxyFinder; }; } diff --git a/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp b/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp index 35f6bea..808ff58 100644 --- a/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp +++ b/Swiften/FileTransfer/IncomingJingleFileTransfer.cpp @@ -35,19 +35,18 @@ IncomingJingleFileTransfer::IncomingJingleFileTransfer( RemoteJingleTransportCandidateSelectorFactory* candidateSelectorFactory, LocalJingleTransportCandidateGeneratorFactory* candidateGeneratorFactory, IQRouter* router, SOCKS5BytestreamRegistry* registry, SOCKS5BytestreamProxy* proxy, TimerFactory* timerFactory) : ourJID(ourJID), session(session), router(router), - timerFactory(timerFactory), initialContent(content), state(Initial), receivedBytes(0), s5bRegistry(registry), s5bProxy(proxy), remoteTransportCandidateSelectFinished(false), localTransportCandidateSelectFinished(false), serverSession(0) { diff --git a/Swiften/FileTransfer/IncomingJingleFileTransfer.h b/Swiften/FileTransfer/IncomingJingleFileTransfer.h index 4ae0bfb..746d837 100644 --- a/Swiften/FileTransfer/IncomingJingleFileTransfer.h +++ b/Swiften/FileTransfer/IncomingJingleFileTransfer.h @@ -95,19 +95,18 @@ namespace Swift { void useOurCandidateChoiceForTransfer(JingleS5BTransportPayload::Candidate candidate); void useTheirCandidateChoiceForTransfer(JingleS5BTransportPayload::Candidate candidate); void decideOnUsedTransport(); void fillCandidateMap(CandidateMap& map, JingleS5BTransportPayload::ref s5bPayload); private: JID ourJID; JingleSession::ref session; IQRouter* router; - TimerFactory* timerFactory; JingleContentPayload::ref initialContent; State state; JingleFileTransferDescription::ref description; WriteBytestream::ref stream; boost::uintmax_t receivedBytes; IncrementalBytestreamHashCalculator* hashCalculator; Timer::ref waitOnHashTimer; IDGenerator idGenerator; diff --git a/Swiften/FileTransfer/OutgoingJingleFileTransfer.cpp b/Swiften/FileTransfer/OutgoingJingleFileTransfer.cpp index 5e2a1c3..e22260e 100644 --- a/Swiften/FileTransfer/OutgoingJingleFileTransfer.cpp +++ b/Swiften/FileTransfer/OutgoingJingleFileTransfer.cpp @@ -39,19 +39,19 @@ OutgoingJingleFileTransfer::OutgoingJingleFileTransfer(JingleSession::ref sessio LocalJingleTransportCandidateGeneratorFactory* localFactory, IQRouter* router, IDGenerator *idGenerator, const JID& fromJID, const JID& toJID, boost::shared_ptr<ReadBytestream> readStream, const StreamInitiationFileInfo &fileInfo, SOCKS5BytestreamRegistry* bytestreamRegistry, SOCKS5BytestreamProxy* bytestreamProxy) : - session(session), remoteFactory(remoteFactory), localFactory(localFactory), router(router), idGenerator(idGenerator), fromJID(fromJID), toJID(toJID), readStream(readStream), fileInfo(fileInfo), s5bRegistry(bytestreamRegistry), s5bProxy(bytestreamProxy), serverSession(NULL), contentID(JingleContentID(idGenerator->generateID(), JingleContentPayload::InitiatorCreator)), canceled(false) { + session(session), router(router), idGenerator(idGenerator), fromJID(fromJID), toJID(toJID), readStream(readStream), fileInfo(fileInfo), s5bRegistry(bytestreamRegistry), s5bProxy(bytestreamProxy), serverSession(NULL), contentID(JingleContentID(idGenerator->generateID(), JingleContentPayload::InitiatorCreator)), canceled(false) { session->onSessionAcceptReceived.connect(boost::bind(&OutgoingJingleFileTransfer::handleSessionAcceptReceived, this, _1, _2, _3)); session->onSessionTerminateReceived.connect(boost::bind(&OutgoingJingleFileTransfer::handleSessionTerminateReceived, this, _1)); session->onTransportInfoReceived.connect(boost::bind(&OutgoingJingleFileTransfer::handleTransportInfoReceived, this, _1, _2)); session->onTransportAcceptReceived.connect(boost::bind(&OutgoingJingleFileTransfer::handleTransportAcceptReceived, this, _1, _2)); fileSizeInBytes = fileInfo.getSize(); filename = fileInfo.getName(); localCandidateGenerator = localFactory->createCandidateGenerator(); localCandidateGenerator->onLocalTransportCandidatesGenerated.connect(boost::bind(&OutgoingJingleFileTransfer::handleLocalTransportCandidatesGenerated, this, _1)); diff --git a/Swiften/FileTransfer/OutgoingJingleFileTransfer.h b/Swiften/FileTransfer/OutgoingJingleFileTransfer.h index ff7bfc7..0260016 100644 --- a/Swiften/FileTransfer/OutgoingJingleFileTransfer.h +++ b/Swiften/FileTransfer/OutgoingJingleFileTransfer.h @@ -79,21 +79,19 @@ private: void decideOnCandidates(); void fillCandidateMap(CandidateMap& map, JingleS5BTransportPayload::ref s5bPayload); private: void sendSessionInfoHash(); private: JingleSession::ref session; RemoteJingleTransportCandidateSelector* remoteCandidateSelector; - RemoteJingleTransportCandidateSelectorFactory* remoteFactory; LocalJingleTransportCandidateGenerator* localCandidateGenerator; - LocalJingleTransportCandidateGeneratorFactory* localFactory; IQRouter* router; IDGenerator* idGenerator; JID fromJID; JID toJID; boost::shared_ptr<ReadBytestream> readStream; StreamInitiationFileInfo fileInfo; IncrementalBytestreamHashCalculator *hashCalculator; diff --git a/Swiften/FileTransfer/SOCKS5BytestreamClientSession.h b/Swiften/FileTransfer/SOCKS5BytestreamClientSession.h index ea45955..e522ff8 100644 --- a/Swiften/FileTransfer/SOCKS5BytestreamClientSession.h +++ b/Swiften/FileTransfer/SOCKS5BytestreamClientSession.h @@ -73,19 +73,18 @@ private: void finish(bool error); void sendData(); private: boost::shared_ptr<Connection> connection; HostAddressPort addressPort; std::string destination; // hexify(SHA1(sessionID + requester + target)) State state; - int destinationPort; ByteArray unprocessedData; ByteArray authenticateAddress; int chunkSize; boost::shared_ptr<WriteBytestream> writeBytestream; boost::shared_ptr<ReadBytestream> readBytestream; Timer::ref weFailedTimeout; diff --git a/Swiften/Network/BOSHConnectionPool.cpp b/Swiften/Network/BOSHConnectionPool.cpp index 0adeb45..293bc1a 100644 --- a/Swiften/Network/BOSHConnectionPool.cpp +++ b/Swiften/Network/BOSHConnectionPool.cpp @@ -15,19 +15,18 @@ #include <Swiften/Network/TLSConnectionFactory.h> #include <Swiften/Network/HTTPConnectProxiedConnectionFactory.h> #include <Swiften/Network/CachingNameOnlyDomainNameResolver.h> namespace Swift { BOSHConnectionPool::BOSHConnectionPool(const URL& boshURL, DomainNameResolver* realResolver, ConnectionFactory* connectionFactoryParameter, XMLParserFactory* parserFactory, TLSContextFactory* tlsFactory, TimerFactory* timerFactory, EventLoop* eventLoop, const std::string& to, unsigned long long initialRID, const URL& boshHTTPConnectProxyURL, const SafeString& boshHTTPConnectProxyAuthID, const SafeString& boshHTTPConnectProxyAuthPassword) : boshURL(boshURL), connectionFactory(connectionFactoryParameter), xmlParserFactory(parserFactory), - tlsFactory(tlsFactory), timerFactory(timerFactory), rid(initialRID), pendingTerminate(false), to(to), requestLimit(2), restartCount(0), pendingRestart(false) { if (!boshHTTPConnectProxyURL.empty()) { diff --git a/Swiften/Network/BOSHConnectionPool.h b/Swiften/Network/BOSHConnectionPool.h index 8bc0a7c..00c1e65 100644 --- a/Swiften/Network/BOSHConnectionPool.h +++ b/Swiften/Network/BOSHConnectionPool.h @@ -47,19 +47,18 @@ namespace Swift { BOSHConnection::ref createConnection(); void destroyConnection(BOSHConnection::ref connection); void tryToSendQueuedData(); BOSHConnection::ref getSuitableConnection(); private: URL boshURL; ConnectionFactory* connectionFactory; XMLParserFactory* xmlParserFactory; - TLSContextFactory* tlsFactory; TimerFactory* timerFactory; std::vector<BOSHConnection::ref> connections; std::string sid; unsigned long long rid; std::vector<SafeByteArray> dataQueue; bool pendingTerminate; std::string to; size_t requestLimit; int restartCount; diff --git a/Swiften/Session/BOSHSessionStream.cpp b/Swiften/Session/BOSHSessionStream.cpp index 6f15b84..479e415 100644 --- a/Swiften/Session/BOSHSessionStream.cpp +++ b/Swiften/Session/BOSHSessionStream.cpp @@ -35,23 +35,18 @@ BOSHSessionStream::BOSHSessionStream( TimerFactory* timerFactory, XMLParserFactory* xmlParserFactory, EventLoop* eventLoop, DomainNameResolver* resolver, const std::string& to, const URL& boshHTTPConnectProxyURL, const SafeString& boshHTTPConnectProxyAuthID, const SafeString& boshHTTPConnectProxyAuthPassword) : available(false), - payloadParserFactories(payloadParserFactories), - payloadSerializers(payloadSerializers), - tlsContextFactory(tlsContextFactory), - timerFactory(timerFactory), - xmlParserFactory(xmlParserFactory), eventLoop(eventLoop), firstHeader(true) { boost::mt19937 random; boost::uniform_int<unsigned long long> dist(0, (1LL<<53) - 1); random.seed(time(NULL)); unsigned long long initialRID = boost::variate_generator<boost::mt19937&, boost::uniform_int<unsigned long long> >(random, dist)(); connectionPool = new BOSHConnectionPool(boshURL, resolver, connectionFactory, xmlParserFactory, tlsContextFactory, timerFactory, eventLoop, to, initialRID, boshHTTPConnectProxyURL, boshHTTPConnectProxyAuthID, boshHTTPConnectProxyAuthPassword); diff --git a/Swiften/Session/BOSHSessionStream.h b/Swiften/Session/BOSHSessionStream.h index 99851b5..290a4c5 100644 --- a/Swiften/Session/BOSHSessionStream.h +++ b/Swiften/Session/BOSHSessionStream.h @@ -81,21 +81,16 @@ namespace Swift { void handlePoolSessionTerminated(BOSHError::ref condition); private: void fakeStreamHeaderReceipt(); void fakeStreamFooterReceipt(BOSHError::ref error); private: BOSHConnectionPool* connectionPool; bool available; - PayloadParserFactoryCollection* payloadParserFactories; - PayloadSerializerCollection* payloadSerializers; - TLSContextFactory* tlsContextFactory; - TimerFactory* timerFactory; - XMLParserFactory* xmlParserFactory; XMPPLayer* xmppLayer; ProtocolHeader streamHeader; EventLoop* eventLoop; bool firstHeader; }; } diff --git a/Swiften/Session/BasicSessionStream.cpp b/Swiften/Session/BasicSessionStream.cpp index cbe85ab..cd6d0e6 100644 --- a/Swiften/Session/BasicSessionStream.cpp +++ b/Swiften/Session/BasicSessionStream.cpp @@ -24,23 +24,20 @@ BasicSessionStream::BasicSessionStream( StreamType streamType, boost::shared_ptr<Connection> connection, PayloadParserFactoryCollection* payloadParserFactories, PayloadSerializerCollection* payloadSerializers, TLSContextFactory* tlsContextFactory, TimerFactory* timerFactory, XMLParserFactory* xmlParserFactory) : available(false), connection(connection), - payloadParserFactories(payloadParserFactories), - payloadSerializers(payloadSerializers), tlsContextFactory(tlsContextFactory), timerFactory(timerFactory), - streamType(streamType), compressionLayer(NULL), tlsLayer(NULL), whitespacePingLayer(NULL) { xmppLayer = new XMPPLayer(payloadParserFactories, payloadSerializers, xmlParserFactory, streamType); xmppLayer->onStreamStart.connect(boost::bind(&BasicSessionStream::handleStreamStartReceived, this, _1)); xmppLayer->onElement.connect(boost::bind(&BasicSessionStream::handleElementReceived, this, _1)); xmppLayer->onError.connect(boost::bind(&BasicSessionStream::handleXMPPError, this)); xmppLayer->onDataRead.connect(boost::bind(&BasicSessionStream::handleDataRead, this, _1)); xmppLayer->onWriteData.connect(boost::bind(&BasicSessionStream::handleDataWritten, this, _1)); diff --git a/Swiften/Session/BasicSessionStream.h b/Swiften/Session/BasicSessionStream.h index 084a191..389ecbe 100644 --- a/Swiften/Session/BasicSessionStream.h +++ b/Swiften/Session/BasicSessionStream.h @@ -71,23 +71,20 @@ namespace Swift { void handleTLSError(boost::shared_ptr<TLSError>); void handleStreamStartReceived(const ProtocolHeader&); void handleElementReceived(boost::shared_ptr<Element>); void handleDataRead(const SafeByteArray& data); void handleDataWritten(const SafeByteArray& data); private: bool available; boost::shared_ptr<Connection> connection; - PayloadParserFactoryCollection* payloadParserFactories; - PayloadSerializerCollection* payloadSerializers; TLSContextFactory* tlsContextFactory; TimerFactory* timerFactory; - StreamType streamType; XMPPLayer* xmppLayer; ConnectionLayer* connectionLayer; CompressionLayer* compressionLayer; TLSLayer* tlsLayer; WhitespacePingLayer* whitespacePingLayer; StreamStack* streamStack; }; } |
Swift