diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/nu/ProgressTracker.h | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/nu/ProgressTracker.h')
-rw-r--r-- | Src/nu/ProgressTracker.h | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/Src/nu/ProgressTracker.h b/Src/nu/ProgressTracker.h new file mode 100644 index 00000000..c0f1153a --- /dev/null +++ b/Src/nu/ProgressTracker.h @@ -0,0 +1,125 @@ +#include <map> +#include "AutoLock.h" +#include <bfc/platform/types.h> + +class ProgressTracker +{ +public: + static const uint64_t null_position; + ProgressTracker() + { + current_position=0; + current_chunk=0; + chunks[0]=0; + chunks[null_position]=null_position; + }; + + void Write(uint64_t bytes_written) + { + Nullsoft::Utility::AutoLock list_lock(list_guard); + ChunkList::iterator next, itr = chunks.find(current_chunk); + current_position += bytes_written; + if (itr->second < current_position) + itr->second = current_position; + + for (;;) + { + next = itr; + ++next; + if (next != chunks.end() && (next->first <= itr->second)) + { + itr->second = next->second; + chunks.erase(next); + } + else + break; + } + } + + bool Valid(uint64_t requested_position, uint64_t requested_end) + { + Nullsoft::Utility::AutoLock list_lock(list_guard); + for (ChunkList::iterator itr=chunks.begin();itr!=chunks.end();itr++) + { + if (requested_position >= itr->first) + { + if (requested_position < itr->second) + { + if (requested_end <= itr->second) + { + return true; + } + else + { + return false; + } + } + } + } + return false; + } + + bool Seek(uint64_t requested_position, uint64_t requested_end, uint64_t *new_start, uint64_t *new_end) + { + Nullsoft::Utility::AutoLock list_lock(list_guard); + uint64_t last_good_start=0; + ChunkList::iterator itr; + for (itr=chunks.begin();itr!=chunks.end();itr++) + { + if (requested_position >= itr->first) + { + current_chunk = itr->first; + if (requested_position <= itr->second) + { + ChunkList::iterator next = itr; + ++next; + *new_end = next->first; + + *new_start = current_position = itr->second; + + if (requested_end <= itr->second) + { + return true; + } + else + { + return false; + } + } + else + { + last_good_start = itr->second; + } + } + } + if (last_good_start > requested_position) + *new_start = current_position = last_good_start; + else + { + + *new_start = current_chunk = current_position = requested_position; + chunks[current_chunk] = current_chunk; + } + *new_end = null_position; + return false; + } + +#if 0 + void Dump() + { + ChunkList::iterator itr; + for (itr=chunks.begin();itr!=chunks.end();itr++) + { + printf("%I64u - %I64u\n", itr->first, itr->second); + } + + } + #endif + + typedef std::map<uint64_t, uint64_t> ChunkList; + ChunkList chunks; + uint64_t current_chunk; + uint64_t current_position; + Nullsoft::Utility::LockGuard list_guard; +}; +const uint64_t ProgressTracker::null_position = (uint64_t)-1;
\ No newline at end of file |