| 157 | } |
| 158 | |
| 159 | void SawyerStreamReader::decodeRunLengthMulti(MemoryStream& buffer, std::span<const std::byte> data) |
| 160 | { |
| 161 | for (size_t i = 0; i < data.size(); i++) |
| 162 | { |
| 163 | if (data[i] == std::byte{ 0xFF }) |
| 164 | { |
| 165 | i++; |
| 166 | if (i >= data.size()) |
| 167 | { |
| 168 | throw Exception::RuntimeError(exceptionInvalidRLE); |
| 169 | } |
| 170 | buffer.writeValue(data[i]); |
| 171 | } |
| 172 | else |
| 173 | { |
| 174 | auto offset = static_cast<int32_t>(data[i] >> 3) - 32; |
| 175 | assert(offset < 0); |
| 176 | if (static_cast<size_t>(-offset) > buffer.getLength()) |
| 177 | { |
| 178 | throw Exception::RuntimeError(exceptionInvalidRLE); |
| 179 | } |
| 180 | auto copySrc = buffer.data() + buffer.getLength() + offset; |
| 181 | auto copyLen = (static_cast<size_t>(data[i]) & 7) + 1; |
| 182 | |
| 183 | // Copy it to temp buffer first as we can't copy buffer to itself due to potential |
| 184 | // realloc in between reserve and push |
| 185 | std::byte copyBuffer[32]; |
| 186 | assert(copyLen <= sizeof(copyBuffer)); |
| 187 | std::memcpy(copyBuffer, copySrc, copyLen); |
| 188 | buffer.write(copyBuffer, copyLen); |
| 189 | } |
| 190 | } |
| 191 | } |
| 192 | |
| 193 | void SawyerStreamReader::decodeRotate(MemoryStream& buffer, std::span<const std::byte> data) |
| 194 | { |
nothing calls this directly
no test coverage detected