| 29 | } |
| 30 | |
| 31 | void UncompressedFile::read(char * s, std::streamsize n) { |
| 32 | /* mutex lock */ |
| 33 | std::unique_lock<std::mutex> lock(m_mutex); |
| 34 | |
| 35 | /* wait until there is sufficient data */ |
| 36 | tellpChanged.wait(lock, [&] { |
| 37 | return |
| 38 | m_abort || |
| 39 | (n + m_tellg <= m_tellp) || |
| 40 | (n + m_tellg > m_fileSize); |
| 41 | }); |
| 42 | |
| 43 | /* handle read behind eof */ |
| 44 | if (n + m_tellg > m_fileSize) { |
| 45 | n = m_fileSize - m_tellg; |
| 46 | m_rdstate = std::ios_base::eofbit | std::ios_base::failbit; |
| 47 | } else |
| 48 | m_rdstate = std::ios_base::goodbit; |
| 49 | |
| 50 | /* read data */ |
| 51 | m_gcount = 0; |
| 52 | while (n > 0) { |
| 53 | /* find starting log container */ |
| 54 | std::shared_ptr<LogContainer> logContainer = logContainerContaining(m_tellg); |
| 55 | if (!logContainer) |
| 56 | break; |
| 57 | |
| 58 | /* offset to read */ |
| 59 | std::streamoff offset = m_tellg - logContainer->filePosition; |
| 60 | |
| 61 | /* copy data */ |
| 62 | std::streamsize gcount = std::min(n, static_cast<std::streamsize>(logContainer->uncompressedFileSize - offset)); |
| 63 | std::copy(logContainer->uncompressedFile.cbegin() + offset, logContainer->uncompressedFile.cbegin() + offset + gcount, s); |
| 64 | |
| 65 | /* remember get count */ |
| 66 | m_gcount += gcount; |
| 67 | |
| 68 | /* new get position */ |
| 69 | m_tellg += gcount; |
| 70 | |
| 71 | /* advance */ |
| 72 | s += gcount; |
| 73 | |
| 74 | /* calculate remaining data to copy */ |
| 75 | n -= gcount; |
| 76 | } |
| 77 | |
| 78 | /* notify */ |
| 79 | tellgChanged.notify_all(); |
| 80 | } |
| 81 | |
| 82 | std::streampos UncompressedFile::tellg() { |
| 83 | /* mutex lock */ |