mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-27 17:25:29 +03:00
Greatly simplify circular buffer logic, fixing several bugs
This commit is contained in:
parent
01febe75c4
commit
d5a15faab7
@ -28,7 +28,8 @@ namespace skyline {
|
|||||||
* @param copyOffset The offset into the buffer after which to use memcpy rather than copyFunction, -1 will use it for the entire buffer
|
* @param copyOffset The offset into the buffer after which to use memcpy rather than copyFunction, -1 will use it for the entire buffer
|
||||||
* @return The amount of data written into the input buffer in units of Type
|
* @return The amount of data written into the input buffer in units of Type
|
||||||
*/
|
*/
|
||||||
size_t Read(span <Type> buffer, void copyFunction(Type *, Type *) = {}, ssize_t copyOffset = -1) {
|
template<typename CopyFunc>
|
||||||
|
size_t Read(span <Type> buffer, CopyFunc copyFunction) {
|
||||||
std::scoped_lock guard{mtx};
|
std::scoped_lock guard{mtx};
|
||||||
|
|
||||||
if (empty)
|
if (empty)
|
||||||
@ -48,40 +49,19 @@ namespace skyline {
|
|||||||
size = sizeBegin + sizeEnd;
|
size = sizeBegin + sizeEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (copyFunction && (copyOffset != 0 && copyOffset < sizeEnd)) {
|
{
|
||||||
auto sourceEnd{start + ((copyOffset != -1) ? copyOffset : sizeEnd)};
|
auto sourceEnd{start + sizeEnd};
|
||||||
|
|
||||||
for (auto source{start}, destination{pointer}; source < sourceEnd; source++, destination++)
|
for (; start < sourceEnd; start++, pointer++)
|
||||||
copyFunction(source, destination);
|
copyFunction(start, pointer);
|
||||||
|
|
||||||
if (copyOffset != -1) {
|
|
||||||
std::memcpy(pointer + copyOffset, start + copyOffset, static_cast<size_t>(sizeEnd - copyOffset) * sizeof(Type));
|
|
||||||
copyOffset -= sizeEnd;
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
if (copyOffset)
|
|
||||||
copyOffset -= static_cast<size_t>(sizeEnd) * sizeof(Type);
|
|
||||||
std::memcpy(pointer, start, static_cast<size_t>(sizeEnd) * sizeof(Type));
|
|
||||||
}
|
|
||||||
|
|
||||||
pointer += sizeEnd;
|
|
||||||
|
|
||||||
if (sizeBegin) {
|
if (sizeBegin) {
|
||||||
if (copyFunction && copyOffset) {
|
start = array.begin();
|
||||||
auto sourceEnd{array.begin() + ((copyOffset != -1) ? copyOffset : sizeBegin)};
|
auto sourceEnd{array.begin() + sizeBegin};
|
||||||
|
|
||||||
for (auto source{array.begin()}, destination{pointer}; source < sourceEnd; source++, destination++)
|
for (; start < sourceEnd; start++, pointer++)
|
||||||
copyFunction(source, destination);
|
copyFunction(start, pointer);
|
||||||
|
|
||||||
if (copyOffset != -1)
|
|
||||||
std::memcpy(array.begin() + copyOffset, pointer + copyOffset, static_cast<size_t>(sizeBegin - copyOffset) * sizeof(Type));
|
|
||||||
} else {
|
|
||||||
std::memcpy(pointer, array.begin(), static_cast<size_t>(sizeBegin) * sizeof(Type));
|
|
||||||
}
|
|
||||||
|
|
||||||
start = array.begin() + sizeBegin;
|
|
||||||
} else {
|
|
||||||
start += sizeEnd;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (start == end)
|
if (start == end)
|
||||||
@ -97,48 +77,24 @@ namespace skyline {
|
|||||||
std::scoped_lock guard{mtx};
|
std::scoped_lock guard{mtx};
|
||||||
|
|
||||||
Type *pointer{buffer.data()};
|
Type *pointer{buffer.data()};
|
||||||
ssize_t size{static_cast<ssize_t>(buffer.size())};
|
ssize_t remainingSize{static_cast<ssize_t>(buffer.size())};
|
||||||
while (size) {
|
while (remainingSize) {
|
||||||
if (start <= end && end != array.end()) {
|
ssize_t writeSize{std::min([&]() {
|
||||||
auto sizeEnd{std::min(array.end() - end, size)};
|
if (start <= end)
|
||||||
std::memcpy(end, pointer, static_cast<size_t>(sizeEnd) * sizeof(Type));
|
return array.end() - end;
|
||||||
|
|
||||||
pointer += sizeEnd;
|
|
||||||
size -= sizeEnd;
|
|
||||||
|
|
||||||
end += sizeEnd;
|
|
||||||
} else {
|
|
||||||
auto sizePreStart{(end == array.end()) ? std::min(start - array.begin(), size) : std::min(start - end, size)};
|
|
||||||
auto sizePostStart{std::min(array.end() - start, size - sizePreStart)};
|
|
||||||
|
|
||||||
if (sizePreStart)
|
|
||||||
std::memcpy((end == array.end()) ? array.begin() : end, pointer, static_cast<size_t>(sizePreStart) * sizeof(Type));
|
|
||||||
|
|
||||||
if (end == array.end())
|
|
||||||
end = array.begin() + sizePreStart;
|
|
||||||
else
|
else
|
||||||
end += sizePreStart;
|
return start - end - 1;
|
||||||
|
}(), remainingSize)};
|
||||||
|
|
||||||
pointer += sizePreStart;
|
if (writeSize) {
|
||||||
size -= sizePreStart;
|
std::memcpy(end, pointer, static_cast<size_t>(writeSize) * sizeof(Type));
|
||||||
|
remainingSize -= writeSize;
|
||||||
if (sizePostStart)
|
end += writeSize;
|
||||||
std::memcpy(end, pointer, static_cast<size_t>(sizePostStart) * sizeof(Type));
|
pointer += writeSize;
|
||||||
|
|
||||||
if (start == array.end())
|
|
||||||
start = array.begin() + sizePostStart;
|
|
||||||
else
|
|
||||||
start += sizePostStart;
|
|
||||||
|
|
||||||
if (end == array.end())
|
|
||||||
end = array.begin() + sizePostStart;
|
|
||||||
else
|
|
||||||
end += sizePostStart;
|
|
||||||
|
|
||||||
pointer += sizePostStart;
|
|
||||||
size -= sizePostStart;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (end == array.end())
|
||||||
|
end = array.begin();
|
||||||
empty = false;
|
empty = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user