void DataSink::_ReadCallback(ev::io &watcher, int revents) { if (EV_ERROR & revents) { LOG(WARNING) << "got invalid event"; return; } ByteBuffer *buf = (ByteBuffer *) watcher.data; buf->Defragment(); int len = buf->GetContinuousBytesLeft(); unsigned int numBytesReceived = recv(watcher.fd, buf->GetWriteReference(), len, MSG_NOSIGNAL); buf->BytesWritten(numBytesReceived); if (numBytesReceived < 0) { LOG(ERROR) << "failed reading socket - client probably disconnected"; return; } if (numBytesReceived <= 0) { // Stop and free watcher if client socket is closing LOG(INFO) << "client disconnected: " << _watcherMap[&watcher] << " -> " << --_numConnectedClients << " client(s) connected"; _DeleteAndCleanupWatcher(watcher); return; } while (buf->GetBytesAvailable() > 4) { // As long as there are more than 4 bytes available there could be // (at least) one more full message in the buffer int messageLength = ntohl(*((unsigned int *) buf->GetReadReference())); if (messageLength > buf->GetCapacity() - 4) { // Current buffer too small, double the capacity at a minimum // and wait until next read on socket if (messageLength > buf->GetCapacity() * 2) buf->Resize(messageLength); else buf->Resize(buf->GetCapacity() * 2); LOG(INFO) << "Buffer resized, new capacity: " << buf->GetCapacity(); break; } if (buf->GetBytesAvailable() - 4 < messageLength) // Fragmented packet, wait until next event. // Note that the same message length header will be read over again break; // There is still at least one more full message available buf->BytesRead(4); _router->Route(buf->GetReadReference(), messageLength); buf->BytesRead(messageLength); } _ioLogger->Read(numBytesReceived); }
bool SimpleCache::GetFileForIndex(int index, ByteBuffer & data) { String filePath; BuildPathForFileInCache(index, filePath); if (!File::IsFileExist(filePath)) { return false; } AppLog("Reading data from cached file at %S", filePath.GetPointer()); File cachedFile; cachedFile.Construct(filePath, L"r+"); if (IsFailed(GetLastResult())) { AppLog("Error opening destination file in cache"); return false; } FileAttributes fAttributes; File::GetAttributes(filePath, fAttributes); data.Construct(fAttributes.GetFileSize()); cachedFile.Read(data); AppLog("Read cache: %d bytes", data.GetCapacity()); if (IsFailed(GetLastResult())) { AppLog("Error reading from cached file"); return false; } return true; }