| 347 | ) |
| 348 | |
| 349 | func findSignature(r io.ReaderAt, search []byte) ([]int64, error) { |
| 350 | chunk := make([]byte, chunkSize+len(search)) |
| 351 | offsets := make([]int64, 0, 2) |
| 352 | |
| 353 | for offset := int64(0); offset < searchLimit; offset += chunkSize { |
| 354 | n, err := r.ReadAt(chunk, offset) |
| 355 | |
| 356 | for i := 0; ; { |
| 357 | idx := bytes.Index(chunk[i:n], search) |
| 358 | if idx == -1 { |
| 359 | break |
| 360 | } |
| 361 | |
| 362 | offsets = append(offsets, offset+int64(i+idx)) |
| 363 | if offsets[0] == 0 { |
| 364 | // If signature is at the beginning, return immediately, it's a regular archive |
| 365 | return offsets, nil |
| 366 | } |
| 367 | |
| 368 | i += idx + 1 |
| 369 | } |
| 370 | |
| 371 | if err != nil { |
| 372 | if errors.Is(err, io.EOF) { |
| 373 | break |
| 374 | } |
| 375 | |
| 376 | return nil, fmt.Errorf("sevenzip: error reading chunk: %w", err) |
| 377 | } |
| 378 | } |
| 379 | |
| 380 | return offsets, nil |
| 381 | } |
| 382 | |
| 383 | //nolint:cyclop,funlen,gocognit,gocyclo,maintidx |
| 384 | func (z *Reader) init(r io.ReaderAt, size int64) (err error) { |