| 267 | } |
| 268 | |
| 269 | Status BaseSequenceScanner::SkipToSync(const uint8_t* sync, int sync_size) { |
| 270 | // offset into current buffer of end of sync (once found, -1 until then) |
| 271 | int offset = -1; |
| 272 | uint8_t* buffer; |
| 273 | int64_t buffer_len; |
| 274 | Status status; |
| 275 | |
| 276 | // Read buffers until we find a sync or reach the end of the scan range. If we read all |
| 277 | // the buffers remaining in the scan range and none of them contain a sync (including a |
| 278 | // sync that starts at the end of this scan range and continues into the next one), then |
| 279 | // there are no more syncs in this scan range and we're finished. |
| 280 | while (!stream_->eosr()) { |
| 281 | // Check if there's a sync fully contained in the current buffer |
| 282 | RETURN_IF_ERROR(stream_->GetBuffer(true, &buffer, &buffer_len)); |
| 283 | offset = FindSyncBlock(buffer, buffer_len, sync, sync_size); |
| 284 | DCHECK_LE(offset, buffer_len); |
| 285 | if (offset != -1) break; |
| 286 | |
| 287 | // No sync found in the current buffer, so check if there's a sync spanning the |
| 288 | // current buffer and the next. First we skip so there are sync_size - 1 bytes left, |
| 289 | // then we read these bytes plus the first sync_size - 1 bytes of the next buffer. |
| 290 | // This guarantees that we find any syncs that start in the current buffer and end in |
| 291 | // the next buffer. |
| 292 | int64_t to_skip = max<int64_t>(0, buffer_len - (sync_size - 1)); |
| 293 | RETURN_IF_FALSE(stream_->SkipBytes(to_skip, &parse_status_)); |
| 294 | // Peek so we don't advance stream_ into the next buffer. If we don't find a sync here |
| 295 | // then we'll need to check all of the next buffer, including the first sync_size -1 |
| 296 | // bytes. |
| 297 | RETURN_IF_FALSE(stream_->GetBytes( |
| 298 | (sync_size - 1) * 2, &buffer, &buffer_len, &parse_status_, true)); |
| 299 | offset = FindSyncBlock(buffer, buffer_len, sync, sync_size); |
| 300 | DCHECK_LE(offset, buffer_len); |
| 301 | if (offset != -1) break; |
| 302 | |
| 303 | // No sync starting in this buffer, so advance stream_ to the beginning of the next |
| 304 | // buffer. |
| 305 | RETURN_IF_ERROR(stream_->GetBuffer(false, &buffer, &buffer_len)); |
| 306 | } |
| 307 | |
| 308 | if (offset == -1) { |
| 309 | // No more syncs in this scan range |
| 310 | DCHECK(stream_->eosr()); |
| 311 | eos_ = true; |
| 312 | return Status::OK(); |
| 313 | } |
| 314 | DCHECK_GE(offset, sync_size); |
| 315 | |
| 316 | // Make sure sync starts in our scan range |
| 317 | if (offset - sync_size >= stream_->bytes_left()) { |
| 318 | eos_ = true; |
| 319 | return Status::OK(); |
| 320 | } |
| 321 | |
| 322 | RETURN_IF_FALSE(stream_->SkipBytes(offset, &parse_status_)); |
| 323 | VLOG_FILE << "Found sync for: " << stream_->filename() |
| 324 | << " at " << stream_->file_offset() - sync_size; |
| 325 | if (stream_->eof()) eos_ = true; |
| 326 | block_start_ = stream_->file_offset(); |
nothing calls this directly
no test coverage detected