Documentation
¶
Overview ¶
Package par2 parses the metadata packets of PAR2 2.0 files.
Ether never repairs with PAR2: a recovery block is a linear combination of every slice of the set, so rebuilding one missing article would mean reading the whole file, which defeats streaming. What it does use is the cheap part of a PAR2 set, the index file: File Description packets give every file's real name, exact length, MD5 of the whole file and MD5 of its first 16 KiB, and Input File Slice Checksum packets give the MD5 and CRC32 of each slice. That lets the stream engine name obfuscated posts from the first article of each file and check that what it serves is the content the poster hashed.
The parser is defensive: packets are located by scanning for the magic, every packet's MD5 is verified, corrupt, truncated and unknown packets are skipped and repeated packets (PAR2 files repeat critical packets) are de-duplicated.
Index ¶
Constants ¶
const ( TypeMain = "PAR 2.0\x00Main\x00\x00\x00\x00" TypeFileDesc = "PAR 2.0\x00FileDesc" TypeIFSC = "PAR 2.0\x00IFSC\x00\x00\x00\x00" TypeCreator = "PAR 2.0\x00Creator\x00" TypeUniName = "PAR 2.0\x00UniFileN" )
Packet types.
const Hash16kSize = 16 * 1024
Hash16kSize is how many leading bytes the "first 16k" MD5 covers.
const HeaderSize = 64
HeaderSize is the size of a packet header.
const Magic = "PAR2\x00PKT"
Magic starts every PAR2 packet.
Variables ¶
var ErrNoFiles = errors.New("par2: no valid file description packets")
ErrNoFiles is returned by Parse when the data holds no valid File Description packet.
Functions ¶
Types ¶
type File ¶
type File struct {
SetID ID
ID ID
// Name is the file name as stored (the Unicode name when the set has
// one). It may contain a relative path; use path.Base for display.
Name string
Length int64
MD5 [16]byte // MD5 of the whole file
MD5_16k [16]byte // MD5 of the first min(16 KiB, Length) bytes
// SliceSize is the recovery set's slice size, 0 if the Main packet was
// not seen. Slices are the IFSC checksums, nil if absent.
SliceSize int64
Slices []Slice
}
File is one file of a recovery set.
func (*File) Verify ¶
Verify checks a file's leading bytes (prefix) and, when known (> 0), its size against the recorded checksums: the length, the first-16k MD5, every slice prefix fully covers (CRC32 and MD5) and, when prefix is the whole file, its MD5. It returns how many checks ran (0 when prefix is too short to check anything) and a *MismatchError on the first failure.
type MismatchError ¶
type MismatchError struct {
Name string
What string // "length", "first 16 KiB MD5", "slice N MD5", "slice N CRC32", "file MD5"
Detail string
}
MismatchError says which PAR2 checksum the content failed.
func (*MismatchError) Error ¶
func (e *MismatchError) Error() string
type Set ¶
type Set struct {
// Files in order of first appearance.
Files []*File
// Creator is the first Creator packet's text, for diagnostics.
Creator string
// Packets counts valid, distinct packets; Skipped counts packet
// headers that were corrupt, truncated or of an unusable type.
Packets int
Skipped int
}
Set is everything usable found in one or more PAR2 files. Files from several recovery sets may be present.
func Parse ¶
Parse scans data (one or more concatenated PAR2 files, possibly with junk or gaps from missing articles) for packets. It returns ErrNoFiles if no valid File Description packet is found.
func (*Set) Identify ¶
Identify finds the file whose content starts with prefix and, if size > 0, is size bytes long. The first-16k MD5 decides when prefix covers it (and must then be unique among the files of that length); otherwise, or when no hash matches, a unique exact length does. byHash reports which rule matched. A file found by length alone whose 16k hash did not match is still returned, so the caller can name it and report the mismatch.
func (*Set) Named ¶
Named returns the files whose base name is name: exact matches, or, if there are none, case-insensitive ones.
func (*Set) SortedNames ¶
SortedNames lists the base names of the set's files, sorted (for logs).