qint64 VirtualSerialDevice::writeData(const char *data, qint64 maxSize) { QMutexLocker locker(&lock); qint64 bytesWritten; bool needToWait = tryFlushPendingBuffers(locker, EmitBytesWrittenAsync); if (!needToWait) { needToWait = tryWrite(data, maxSize, bytesWritten); if (needToWait && bytesWritten > 0) { // Wrote some of the buffer, adjust pointers to point to the remainder that needs queueing data += bytesWritten; maxSize -= bytesWritten; } } if (needToWait) { pendingWrites.append(QByteArray(data, maxSize)); d->writeUnblockedNotifier->setEnabled(true); // Now wait for the writeUnblocked signal or for a call to waitForBytesWritten return bytesWritten + maxSize; } else { //emitBytesWrittenIfNeeded(locker, bytesWritten); // Can't emit bytesWritten directly from writeData - means clients end up recursing emit AsyncCall_emitBytesWrittenIfNeeded(bytesWritten); return bytesWritten; } }
/* Returns true if EAGAIN encountered. Emits (or queues) bytesWritten for any buffers written. * If stopAfterWritingOneBuffer is true, return immediately if a single buffer is written, rather than * attempting to drain the whole queue. * Doesn't modify notifier. */ bool VirtualSerialDevice::tryFlushPendingBuffers(QMutexLocker& locker, FlushPendingOptions flags) { while (pendingWrites.count() > 0) { // Try writing everything we've got, until we hit EAGAIN const QByteArray& data = pendingWrites[0]; qint64 bytesWritten; bool needToWait = tryWrite(data.constData(), data.size(), bytesWritten); if (needToWait) { if (bytesWritten > 0) { // We wrote some of the data, update the pending queue QByteArray remainder = data.mid(bytesWritten); pendingWrites.removeFirst(); pendingWrites.insert(0, remainder); } return needToWait; } else { pendingWrites.removeFirst(); if (flags & EmitBytesWrittenAsync) { emit AsyncCall_emitBytesWrittenIfNeeded(bytesWritten); } else { emitBytesWrittenIfNeeded(locker, bytesWritten); } if (flags & StopAfterWritingOneBuffer) return false; // Otherwise go round loop again } } return false; // no EAGAIN encountered }
QByteArray readBody(int size) { if(server) { QByteArray out = requestBodyBuf.take(size); if(out.isEmpty()) return out; pendingInCredits += out.size(); if(!pausing && !paused) { ZhttpResponsePacket p; p.type = ZhttpResponsePacket::Credit; p.credits = pendingInCredits; pendingInCredits = 0; writePacket(p); } return out; } else { QByteArray out = responseBodyBuf.take(size); if(out.isEmpty()) return out; pendingInCredits += out.size(); if(state == ClientReceiving) tryWrite(); // this should not emit signals in current state return out; } }
void Connection::sendMsg(SendPacket* p) { if (m_status != CONN_STATUS_CONNECTED) { LOGERROR() << "sendmsg status not connected" <<"id"<<m_id <<LOGEND(); return; } short opCode = p->getOPCode(); std::string body = p->getData(); unsigned int pack = (13 << 24) + (body.size() & 0xFFFFFF); char header[MSG_HEADER_SIZE] = {0}; memmove(header, (char*)&opCode, sizeof(opCode)); memmove(header+sizeof(opCode), (char*)&pack, sizeof(pack)); std::stringstream ss; ss << std::string(header, 6) << body; m_outData.push_back(ss.str()); LOGNET() << "try send msg " << opCode << " pack size " << body.size() << LOGEND(); tryWrite(); }
void Connection::handleWrite(const boost::system::error_code& error, size_t len) { if(!error) { m_writeStatus = SW_STATUS_WRITEDONE; assert(m_outData.size() > 0); // ok write some chars //std::string& buf = m_outData.front(); // first buffer all flushed if (len == m_tempBuf.length()) { LOGNET() << "<<< write full " << len << " " <<"id"<<m_id << LOGEND(); m_outData.pop_front(); tryWrite(); } else { //LOGNET() << "<<< write partial " << len << " should " << buf.length() << " " LOGNET() << "<<< write partial " << len << " should " << m_tempBuf.length() << " " <<"id"<<m_id << LOGEND(); assert(len < m_tempBuf.length()); //buf = buf.substr(len); m_tempBuf = m_tempBuf.substr(len); tryWrite(); } } else { if (m_status == CONN_STATUS_CONNECTED) { m_status = CONN_STATUS_DISCONNECT; } else { // triggered by other event } if (m_errHandler) { m_errHandler(error, this, "handlewrite"); } } }
void CBAWMeshWriter::exportAsBlob<asset::ICPUBuffer>(asset::ICPUBuffer* _obj, uint32_t _headerIdx, io::IWriteFile* _file, SContext& _ctx) { const asset::E_WRITER_FLAGS flags = _ctx.writerOverride->getAssetWritingFlags(_ctx.inner, _obj, 3u); const uint8_t* encrPwd = nullptr; _ctx.writerOverride->getEncryptionKey(encrPwd, _ctx.inner, _obj, 3u); const float comprLvl = _ctx.writerOverride->getAssetCompressionLevel(_ctx.inner, _obj, 3u); tryWrite(_obj->getPointer(), _file, _ctx, _obj->getSize(), _headerIdx, flags, encrPwd, comprLvl); }
void RemotePluginClient::sendMIDIData(unsigned char *data, int *frameoffsets, int events) { writeOpcode(&m_shmControl->ringBuffer, RemotePluginSendMIDIData); writeInt(&m_shmControl->ringBuffer, events); tryWrite(&m_shmControl->ringBuffer, data, events * 3); if (!frameoffsets) { // This should not happen with a good client, but we'd better // cope as well as possible with the lazy ol' degenerates frameoffsets = (int *)alloca(events * sizeof(int)); memset(frameoffsets, 0, events * sizeof(int)); } // std::cerr << "RemotePluginClient::sendMIDIData(" << events << ")" << std::endl; tryWrite(&m_shmControl->ringBuffer, frameoffsets, events * sizeof(int)); commitWrite(&m_shmControl->ringBuffer); }
//! //! Writes array \a a to the stream. void ByteStream::write(const QByteArray &a) { if(!isOpen()) return; bool doWrite = bytesToWrite() == 0 ? true: false; appendWrite(a); if(doWrite) tryWrite(); }
void CBAWMeshWriter::exportAsBlob<scene::CFinalBoneHierarchy>(scene::CFinalBoneHierarchy* _obj, uint32_t _headerIdx, io::IWriteFile* _file, SContext& _ctx) { uint8_t stackData[1u<<14]; // 16kB asset::FinalBoneHierarchyBlobV1* data = asset::FinalBoneHierarchyBlobV1::createAndTryOnStack(_obj,stackData,sizeof(stackData)); tryWrite(data, _file, _ctx, asset::FinalBoneHierarchyBlobV1::calcBlobSizeForObj(_obj), _headerIdx, asset::EWF_NONE); if ((uint8_t*)data != stackData) _IRR_ALIGNED_FREE(data); }
void BConsole::sn_write() { d->w->deleteLater(); d->w = 0; if(bytesToWrite() > 0) tryWrite(); if(bytesToWrite() == 0 && d->closing) { d->closing = false; d->closed = true; delayedCloseFinished(); } }
void CBAWMeshWriter::exportAsBlob<asset::ICPUSkinnedMesh>(asset::ICPUSkinnedMesh* _obj, uint32_t _headerIdx, io::IWriteFile* _file, SContext& _ctx) { uint8_t stackData[1u << 14]; asset::SkinnedMeshBlobV1* data = asset::SkinnedMeshBlobV1::createAndTryOnStack(_obj,stackData,sizeof(stackData)); const asset::E_WRITER_FLAGS flags = _ctx.writerOverride->getAssetWritingFlags(_ctx.inner, _obj, 0u); const uint8_t* encrPwd = nullptr; _ctx.writerOverride->getEncryptionKey(encrPwd, _ctx.inner, _obj, 0u); const float comprLvl = _ctx.writerOverride->getAssetCompressionLevel(_ctx.inner, _obj, 0u); tryWrite(data, _file, _ctx, asset::SkinnedMeshBlobV1::calcBlobSizeForObj(_obj), _headerIdx, flags, encrPwd, comprLvl); if ((uint8_t*)data != stackData) _IRR_ALIGNED_FREE(data); }
void CBAWMeshWriter::exportAsBlob<asset::ICPUTexture>(asset::ICPUTexture* _obj, uint32_t _headerIdx, io::IWriteFile* _file, SContext& _ctx) { asset::ICPUTexture* tex = _obj; const WriteProperties* props = reinterpret_cast<const WriteProperties*>(_ctx.inner.params.userData); const io::path fileDir = props->relPath.size() ? props->relPath : io::IFileSystem::getFileDir(m_fileSystem->getAbsolutePath(_file->getFileName())); // get relative-file's directory io::path path = m_fileSystem->getRelativeFilename(tex->getCacheKey().c_str(), fileDir); // get texture-file path relative to the file's directory const uint32_t len = strlen(path.c_str()) + 1; const asset::E_WRITER_FLAGS flags = _ctx.writerOverride->getAssetWritingFlags(_ctx.inner, _obj, 2u); const uint8_t* encrPwd = nullptr; _ctx.writerOverride->getEncryptionKey(encrPwd, _ctx.inner, _obj, 2u); const float comprLvl = _ctx.writerOverride->getAssetCompressionLevel(_ctx.inner, _obj, 2u); tryWrite(&path[0], _file, _ctx, len, _headerIdx, flags, encrPwd, comprLvl); }
QByteArray readResponseBody(int size) { if(size != -1) size = qMin(size, in.size()); else size = in.size(); if(size == 0) return QByteArray(); QByteArray out = in.mid(0, size); in = in.mid(size); pendingInCredits += size; if(state == Receiving) tryWrite(); // this should not emit signals in current state return out; }
void handle(const ZhttpResponsePacket &packet) { if(state == ClientRequestStartWait) { if(packet.from.isEmpty()) { state = Stopped; errored = true; errorCondition = ErrorGeneric; cleanup(); log_warning("zhttp client: error id=%s initial ack for streamed input request did not contain from field", packet.id.data()); emit q->error(); return; } toAddress = packet.from; state = ClientRequesting; startKeepAlive(); } else if(state == ClientRequestFinishWait) { toAddress = packet.from; state = ClientReceiving; if(!doReq) startKeepAlive(); } if(packet.type == ZhttpResponsePacket::Error) { errored = true; errorCondition = convertError(packet.condition); log_debug("zhttp client: error id=%s cond=%s", packet.id.data(), packet.condition.data()); state = Stopped; cleanup(); emit q->error(); return; } else if(packet.type == ZhttpResponsePacket::Cancel) { log_debug("zhttp client: received cancel id=%s", packet.id.data()); errored = true; errorCondition = ErrorGeneric; state = Stopped; cleanup(); emit q->error(); return; } // if non-req mode, check sequencing if(!doReq && packet.seq != inSeq) { log_warning("zhttp client: error id=%s received message out of sequence, canceling", packet.id.data()); // if this was not an error packet, send cancel if(packet.type != ZhttpResponsePacket::Error && packet.type != ZhttpResponsePacket::Cancel) { ZhttpRequestPacket p; p.type = ZhttpRequestPacket::Cancel; writePacket(p); } state = Stopped; errored = true; errorCondition = ErrorGeneric; cleanup(); emit q->error(); return; } ++inSeq; refreshTimeout(); if(doReq && (packet.type != ZhttpResponsePacket::Data || packet.more)) { log_warning("zhttp/zws client req: received invalid req response"); state = Stopped; errored = true; errorCondition = ErrorGeneric; cleanup(); emit q->error(); return; } if(packet.type == ZhttpResponsePacket::Data) { if(!haveResponseValues) { haveResponseValues = true; responseCode = packet.code; responseReason = packet.reason; responseHeaders = packet.headers; } if(doReq) { if(responseBodyBuf.size() + packet.body.size() > REQ_BUF_MAX) log_warning("zhttp client req: id=%s server response too large", packet.id.data()); } else { if(responseBodyBuf.size() + packet.body.size() > IDEAL_CREDITS) log_warning("zhttp client: id=%s server is sending too fast", packet.id.data()); } responseBodyBuf += packet.body; if(!doReq && packet.credits > 0) { outCredits += packet.credits; if(outCredits > 0) { // try to write anything that was waiting on credits QPointer<QObject> self = this; tryWrite(); if(!self) return; } } if(packet.more) { if(!packet.body.isEmpty()) emit q->readyRead(); } else { // always emit readyRead here even if body is empty, for EOF state = Stopped; cleanup(); emit q->readyRead(); } } else if(packet.type == ZhttpResponsePacket::Credit) { if(packet.credits > 0) { outCredits += packet.credits; if(outCredits > 0) tryWrite(); } } else if(packet.type == ZhttpResponsePacket::KeepAlive) { // nothing to do } else { log_debug("zhttp client: unsupported packet type id=%s type=%d", packet.id.data(), (int)packet.type); } }
void handle(const ZhttpRequestPacket &packet) { if(paused) return; if(packet.type == ZhttpRequestPacket::Error) { errored = true; errorCondition = convertError(packet.condition); log_debug("zhttp server: error id=%s cond=%s", packet.id.data(), packet.condition.data()); state = Stopped; cleanup(); emit q->error(); return; } else if(packet.type == ZhttpRequestPacket::Cancel) { log_debug("zhttp server: received cancel id=%s", packet.id.data()); errored = true; errorCondition = ErrorGeneric; state = Stopped; cleanup(); emit q->error(); return; } if(packet.seq != inSeq) { log_warning("zhttp server: error id=%s received message out of sequence, canceling", packet.id.data()); // if this was not an error packet, send cancel if(packet.type != ZhttpRequestPacket::Error && packet.type != ZhttpRequestPacket::Cancel) { ZhttpResponsePacket p; p.type = ZhttpResponsePacket::Cancel; writePacket(p); } state = Stopped; errored = true; errorCondition = ErrorGeneric; cleanup(); emit q->error(); return; } ++inSeq; refreshTimeout(); if(packet.type == ZhttpRequestPacket::Data) { requestBodyBuf += packet.body; bool done = haveRequestBody; if(!packet.more) { haveRequestBody = true; state = ServerResponseWait; } if(packet.credits > 0) outCredits += packet.credits; if(!packet.body.isEmpty() || (!done && haveRequestBody)) emit q->readyRead(); } else if(packet.type == ZhttpRequestPacket::Credit) { if(packet.credits > 0) { outCredits += packet.credits; tryWrite(); } } else if(packet.type == ZhttpRequestPacket::KeepAlive) { // nothing to do } else if(packet.type == ZhttpRequestPacket::HandoffProceed) { if(pausing) { pausing = false; paused = true; emit q->paused(); } } else { log_debug("zhttp server: unsupported packet type id=%s type=%d", packet.id.data(), (int)packet.type); } }
void handle(const ZhttpResponsePacket &packet) { if(packet.type == ZhttpResponsePacket::Error) { errorCondition = convertError(packet.condition); log_debug("zws client: error id=%s cond=%s", packet.id.data(), packet.condition.data()); responseCode = packet.code; responseReason = packet.reason; responseHeaders = packet.headers; responseBody = packet.body; state = Idle; cleanup(); emit q->error(); return; } else if(packet.type == ZhttpResponsePacket::Cancel) { log_debug("zws client: received cancel id=%s", packet.id.data()); errorCondition = ErrorGeneric; state = Idle; cleanup(); emit q->error(); return; } if(!packet.from.isEmpty()) toAddress = packet.from; if(packet.seq != inSeq) { log_warning("zws client: error id=%s received message out of sequence, canceling", packet.id.data()); tryRespondCancel(packet); state = Idle; errorCondition = ErrorGeneric; cleanup(); emit q->error(); return; } if(!toAddress.isEmpty() && !keepAliveTimer->isActive()) startKeepAlive(); ++inSeq; refreshTimeout(); if(state == Connecting) { if(packet.type != ZhttpResponsePacket::Data && packet.type != ZhttpResponsePacket::Credit && packet.type != ZhttpResponsePacket::KeepAlive) { state = Idle; errorCondition = ErrorGeneric; cleanup(); log_warning("zws client: error id=%s initial response wrong type", packet.id.data()); emit q->error(); return; } if(packet.from.isEmpty()) { state = Idle; errorCondition = ErrorGeneric; cleanup(); log_warning("zws client: error id=%s initial ack did not contain from field", packet.id.data()); emit q->error(); return; } } if(packet.type == ZhttpResponsePacket::Data || packet.type == ZhttpResponsePacket::Ping || packet.type == ZhttpResponsePacket::Pong) { if(state == Connecting) { // this is assured earlier assert(packet.type == ZhttpResponsePacket::Data); responseCode = packet.code; responseReason = packet.reason; responseHeaders = packet.headers; if(packet.credits > 0) outCredits += packet.credits; state = Connected; update(); emit q->connected(); } else { if(inSize + packet.body.size() > IDEAL_CREDITS) log_warning("zws client: id=%s server is sending too fast", packet.id.data()); if(packet.type == ZhttpResponsePacket::Data) { handleIncomingDataPacket(packet.contentType, packet.body, packet.more); } else if(packet.type == ZhttpResponsePacket::Ping) { inFrames += Frame(Frame::Ping, packet.body, false); inSize += packet.body.size(); } else if(packet.type == ZhttpResponsePacket::Pong) { inFrames += Frame(Frame::Pong, packet.body, false); inSize += packet.body.size(); } if(packet.credits > 0) { outCredits += packet.credits; if(outCredits > 0) { // try to write anything that was waiting on credits QPointer<QObject> self = this; tryWrite(); if(!self) return; } } emit q->readyRead(); } } else if(packet.type == ZhttpResponsePacket::Close) { handlePeerClose(packet.code); } else if(packet.type == ZhttpResponsePacket::Credit) { if(packet.credits > 0) { outCredits += packet.credits; if(outCredits > 0) tryWrite(); } } else if(packet.type == ZhttpResponsePacket::KeepAlive) { // nothing to do } else { log_debug("zws client: unsupported packet type id=%s type=%d", packet.id.data(), (int)packet.type); } }
void handleRequest(ZhttpRequest *_req, const QByteArray &jsonpCallback, const QByteArray &lastPart, const QByteArray &body) { connect(_req, SIGNAL(bytesWritten(int)), SLOT(req_bytesWritten(int))); connect(_req, SIGNAL(error()), SLOT(req_error())); if(lastPart == "xhr" || lastPart == "jsonp") { if(req) { QVariantList out; out += 2010; out += QString("Another connection still open"); requests.insert(_req, new RequestItem(_req, jsonpCallback, RequestItem::Background, true)); respondOk(_req, out, "c", jsonpCallback); return; } if(peerClosed) { QVariantList out; out += 3000; out += QString("Client already closed connection"); requests.insert(_req, new RequestItem(_req, jsonpCallback, RequestItem::Background, true)); respondOk(_req, out, "c", jsonpCallback); return; } req = _req; requests.insert(req, new RequestItem(req, jsonpCallback, RequestItem::Receive)); keepAliveTimer->start(KEEPALIVE_TIMEOUT * 1000); tryWrite(); } else if(lastPart == "xhr_send" || lastPart == "jsonp_send") { // only allow one outstanding send request at a time if(findFirstSendRequest()) { requests.insert(_req, new RequestItem(_req, jsonpCallback, RequestItem::Background, true)); respondError(_req, 400, "Bad Request", "Already sending"); return; } QByteArray param; if(_req->requestMethod() == "POST") { if(lastPart == "xhr_send") { // assume json param = body; } else // jsonp_send { // assume form encoded foreach(const QByteArray &kv, body.split('&')) { int at = kv.indexOf('='); if(at == -1) continue; if(QUrl::fromPercentEncoding(kv.mid(0, at)) == "d") { param = QUrl::fromPercentEncoding(kv.mid(at + 1)).toUtf8(); break; } } } } else // GET { QUrlQuery query(_req->requestUri()); param = query.queryItemValue("d").toUtf8(); } QJsonParseError error; QJsonDocument doc = QJsonDocument::fromJson(param, &error); if(error.error != QJsonParseError::NoError || !doc.isArray()) { requests.insert(_req, new RequestItem(_req, jsonpCallback, RequestItem::Background, true)); respondError(_req, 400, "Bad Request", "Payload expected"); return; } QVariantList messages = doc.array().toVariantList(); QList<Frame> frames; int bytes = 0; foreach(const QVariant &vmessage, messages) { if(vmessage.type() != QVariant::String) { requests.insert(_req, new RequestItem(_req, jsonpCallback, RequestItem::Background, true)); respondError(_req, 400, "Bad Request", "Payload expected"); return; } QByteArray data = vmessage.toString().toUtf8(); if(data.size() > BUFFER_SIZE) { requests.insert(_req, new RequestItem(_req, jsonpCallback, RequestItem::Background, true)); respondError(_req, 400, "Bad Request", "Message too large"); return; } frames += Frame(Frame::Text, data, false); bytes += data.size(); } if(frames.isEmpty()) { requests.insert(_req, new RequestItem(_req, jsonpCallback, RequestItem::Background, true)); respondOk(_req, QString("ok"), jsonpCallback); return; } RequestItem *ri = new RequestItem(_req, jsonpCallback, RequestItem::Send); requests.insert(_req, ri); ri->sendFrames = frames; ri->sendBytes = bytes; tryRead(); }
void handle(const ZurlResponsePacket &packet) { if(state == RequestStartWait) { if(packet.replyAddress.isEmpty()) { state = Private::Stopped; errorCondition = ErrorGeneric; cleanup(); log_warning("initial ack for streamed input request did not contain reply-address"); emit q->error(); return; } replyAddress = packet.replyAddress; state = Requesting; } else if(state == RequestFinishWait) { replyAddress = packet.replyAddress; state = Receiving; } if(packet.isError) { // zurl conditions: // remote-connection-failed // connection-timeout // tls-error // bad-request // policy-violation // max-size-exceeded // cancel QByteArray cond = packet.condition; if(cond == "policy-violation") errorCondition = ErrorPolicy; else if(cond == "remote-connection-failed") errorCondition = ErrorConnect; else if(cond == "tls-error") errorCondition = ErrorTls; else if(cond == "length-required") errorCondition = ErrorLengthRequired; else if(cond == "connection-timeout") errorCondition = ErrorTimeout; else // bad-request, max-size-exceeded, cancel errorCondition = ErrorGeneric; state = Private::Stopped; cleanup(); emit q->error(); return; } if(packet.seq != inSeq) { log_warning("received message out of sequence, canceling"); // if this was not an error packet, send cancel if(packet.condition.isEmpty()) { ZurlRequestPacket p; p.id = rid.second; p.seq = outSeq++; p.cancel = true; manager->write(p, replyAddress); } state = Private::Stopped; errorCondition = ErrorGeneric; cleanup(); emit q->error(); return; } ++inSeq; refreshTimeout(); bool doReadyRead = false; if(!packet.body.isNull()) { if(!haveResponseValues) { haveResponseValues = true; responseCode = packet.code; responseStatus = packet.reason; responseHeaders = packet.headers; } if(in.size() + packet.body.size() > IDEAL_CREDITS) log_warning("zurl is sending too fast"); in += packet.body; if(packet.more) { if(!packet.body.isEmpty()) doReadyRead = true; } else { // always emit readyRead here even if body is empty, for EOF state = Private::Stopped; cleanup(); emit q->readyRead(); return; } } if(packet.credits > 0) outCredits += packet.credits; // the only reason we should need to write as a result of a read // is if we were given credits or we have credits to give if(packet.credits > 0 || pendingInCredits > 0) { QPointer<QObject> self = this; tryWrite(); if(!self) return; } if(doReadyRead) emit q->readyRead(); }
void RemotePluginClient::setDebugLevel(RemotePluginDebugLevel level) { writeOpcode(m_controlRequestFd, RemotePluginSetDebugLevel); tryWrite(m_controlRequestFd, &level, sizeof(RemotePluginDebugLevel)); }
RemotePluginServer::RemotePluginServer(std::string fileIdentifiers) : m_bufferSize(-1), m_numInputs(-1), m_numOutputs(-1), m_controlRequestFd(-1), m_controlResponseFd(-1), m_shmFd(-1), m_shmControlFd(-1), m_controlRequestFileName(0), m_controlResponseFileName(0), m_shmFileName(0), m_shmControlFileName(0), m_shm(0), m_shmSize(0), m_shmControl(0), m_inputs(0), m_outputs(0) { char tmpFileBase[60]; sprintf(tmpFileBase, "/tmp/rplugin_crq_%s", fileIdentifiers.substr(0, 6).c_str()); m_controlRequestFileName = strdup(tmpFileBase); if ((m_controlRequestFd = open(m_controlRequestFileName, O_RDONLY)) < 0) { cleanup(); throw((std::string)"Failed to open FIFO"); } sprintf(tmpFileBase, "/tmp/rplugin_crs_%s", fileIdentifiers.substr(6, 6).c_str()); m_controlResponseFileName = strdup(tmpFileBase); if ((m_controlResponseFd = open(m_controlResponseFileName, O_WRONLY)) < 0) { cleanup(); throw((std::string)"Failed to open FIFO"); } bool b = false; sprintf(tmpFileBase, "/dssi-vst-rplugin_shc_%s", fileIdentifiers.substr(12, 6).c_str()); m_shmControlFileName = strdup(tmpFileBase); m_shmControlFd = shm_open(m_shmControlFileName, O_RDWR, 0); if (m_shmControlFd < 0) { tryWrite(m_controlResponseFd, &b, sizeof(bool)); cleanup(); throw((std::string)"Failed to open or create shared memory file"); } m_shmControl = static_cast<ShmControl *>(mmap(0, sizeof(ShmControl), PROT_READ | PROT_WRITE, MAP_SHARED, m_shmControlFd, 0)); if (!m_shmControl) { tryWrite(m_controlResponseFd, &b, sizeof(bool)); cleanup(); throw((std::string)"Failed to mmap shared memory file"); } sprintf(tmpFileBase, "/dssi-vst-rplugin_shm_%s", fileIdentifiers.substr(18, 6).c_str()); m_shmFileName = strdup(tmpFileBase); if ((m_shmFd = shm_open(m_shmFileName, O_RDWR, 0)) < 0) { tryWrite(m_controlResponseFd, &b, sizeof(bool)); cleanup(); throw((std::string)"Failed to open shared memory file"); } b = true; tryWrite(m_controlResponseFd, &b, sizeof(bool)); }
void handle(const ZhttpRequestPacket &packet) { if(packet.type == ZhttpRequestPacket::Error) { errorCondition = convertError(packet.condition); log_debug("zws server: error id=%s cond=%s", packet.id.data(), packet.condition.data()); state = Idle; cleanup(); emit q->error(); return; } else if(packet.type == ZhttpRequestPacket::Cancel) { log_debug("zws server: received cancel id=%s", packet.id.data()); errorCondition = ErrorGeneric; state = Idle; cleanup(); emit q->error(); return; } if(packet.seq != inSeq) { log_warning("zws server: error id=%s received message out of sequence, canceling", packet.id.data()); tryRespondCancel(packet); state = Idle; errorCondition = ErrorGeneric; cleanup(); emit q->error(); return; } ++inSeq; refreshTimeout(); if(packet.type == ZhttpRequestPacket::Data || packet.type == ZhttpRequestPacket::Ping || packet.type == ZhttpRequestPacket::Pong) { if(inSize + packet.body.size() > IDEAL_CREDITS) log_warning("zws client: id=%s server is sending too fast", packet.id.data()); if(packet.type == ZhttpRequestPacket::Data) { handleIncomingDataPacket(packet.contentType, packet.body, packet.more); } else if(packet.type == ZhttpRequestPacket::Ping) { inFrames += Frame(Frame::Ping, packet.body, false); inSize += packet.body.size(); } else if(packet.type == ZhttpRequestPacket::Pong) { inFrames += Frame(Frame::Pong, packet.body, false); inSize += packet.body.size(); } if(packet.credits > 0) { outCredits += packet.credits; if(outCredits > 0) { // try to write anything that was waiting on credits QPointer<QObject> self = this; tryWrite(); if(!self) return; } } emit q->readyRead(); } else if(packet.type == ZhttpRequestPacket::Close) { handlePeerClose(packet.code); } else if(packet.type == ZhttpRequestPacket::Credit) { if(packet.credits > 0) { outCredits += packet.credits; tryWrite(); } } else if(packet.type == ZhttpRequestPacket::KeepAlive) { // nothing to do } else { log_debug("zws server: unsupported packet type id=%s type=%d", packet.id.data(), (int)packet.type); } }
void CBAWMeshWriter::exportAsBlob<asset::IMeshDataFormatDesc<asset::ICPUBuffer> >(asset::IMeshDataFormatDesc<asset::ICPUBuffer>* _obj, uint32_t _headerIdx, io::IWriteFile* _file, SContext& _ctx) { asset::MeshDataFormatDescBlobV1 data(_obj); tryWrite(&data, _file, _ctx, sizeof(data), _headerIdx, asset::EWF_NONE); }
void RemotePluginServer::dispatchControlEvents() { RemotePluginOpcode opcode = RemotePluginNoOpcode; static float *parameterBuffer = 0; tryRead(m_controlRequestFd, &opcode, sizeof(RemotePluginOpcode)); switch (opcode) { case RemotePluginGetVersion: writeFloat(m_controlResponseFd, getVersion()); break; case RemotePluginGetName: writeString(m_controlResponseFd, getName()); break; case RemotePluginGetMaker: writeString(m_controlResponseFd, getMaker()); break; case RemotePluginTerminate: terminate(); break; case RemotePluginGetInputCount: m_numInputs = getInputCount(); writeInt(m_controlResponseFd, m_numInputs); break; case RemotePluginGetOutputCount: m_numOutputs = getOutputCount(); writeInt(m_controlResponseFd, m_numOutputs); break; case RemotePluginGetParameterCount: writeInt(m_controlResponseFd, getParameterCount()); break; case RemotePluginGetParameterName: writeString(m_controlResponseFd, getParameterName(readInt(m_controlRequestFd))); break; case RemotePluginGetParameter: writeFloat(m_controlResponseFd, getParameter(readInt(m_controlRequestFd))); break; case RemotePluginGetParameterDefault: writeFloat(m_controlResponseFd, getParameterDefault(readInt(m_controlRequestFd))); break; case RemotePluginGetParameters: { if (!parameterBuffer) { parameterBuffer = new float[getParameterCount()]; } int p0 = readInt(m_controlRequestFd); int pn = readInt(m_controlRequestFd); getParameters(p0, pn, parameterBuffer); tryWrite(m_controlResponseFd, parameterBuffer, (pn - p0 + 1) * sizeof(float)); break; } case RemotePluginHasMIDIInput: { bool m = hasMIDIInput(); tryWrite(m_controlResponseFd, &m, sizeof(bool)); break; } case RemotePluginGetProgramCount: writeInt(m_controlResponseFd, getProgramCount()); break; case RemotePluginGetProgramName: writeString(m_controlResponseFd, getProgramName(readInt(m_controlRequestFd))); break; case RemotePluginIsReady: { if (!m_shm) sizeShm(); bool b(isReady()); std::cerr << "isReady: returning " << b << std::endl; tryWrite(m_controlResponseFd, &b, sizeof(bool)); } case RemotePluginSetDebugLevel: { RemotePluginDebugLevel newLevel = m_debugLevel; tryRead(m_controlRequestFd, &newLevel, sizeof(RemotePluginDebugLevel)); setDebugLevel(newLevel); m_debugLevel = newLevel; break; } case RemotePluginWarn: { bool b = warn(readString(m_controlRequestFd)); tryWrite(m_controlResponseFd, &b, sizeof(bool)); break; } case RemotePluginShowGUI: { showGUI(readString(m_controlRequestFd)); break; } case RemotePluginHideGUI: { hideGUI(); break; } //Deryabin Andrew: vst chunks support case RemotePluginGetVSTChunk: { std::vector<char> chunk = getVSTChunk(); writeRaw(m_controlResponseFd, chunk); break; } case RemotePluginSetVSTChunk: { std::vector<char> chunk = readRaw(m_controlRequestFd); setVSTChunk(chunk); break; } //Deryabin Andrew: vst chunks support: end code case RemotePluginNoOpcode: break; case RemotePluginReset: reset(); break; default: std::cerr << "WARNING: RemotePluginServer::dispatchControlEvents: unexpected opcode " << opcode << std::endl; } }