package storage import "unicode/utf8" // Entries is for sorting by Position type Entries []Entry func (e Entries) Len() int { return len(e) } func (e Entries) Swap(i, j int) { e[i], e[j] = e[j], e[i] } func (e Entries) Less(i, j int) bool { return e[i].Position < e[j].Position } // Type of Entry type Type int const ( // FileType represents a file payload from the tar stream. // // This will be used to map to relative paths on disk. Only Size > 0 will get // read into a resulting output stream (due to hardlinks). FileType Type = 1 + iota // SegmentType represents a raw bytes segment from the archive stream. These raw // byte segments consist of the raw headers and various padding. // // Its payload is to be marshalled base64 encoded. SegmentType ) // Entry is the structure for packing and unpacking the information read from // the Tar archive. // // FileType Payload checksum is using `hash/crc64` for basic file integrity, // _not_ for cryptography. // From http://www.backplane.com/matt/crc64.html, CRC32 has almost 40,000 // collisions in a sample of 18.2 million, CRC64 had none. type Entry struct { Type Type `json:"type"` Name string `json:"name,omitempty"` NameRaw []byte `json:"name_raw,omitempty"` Size int64 `json:"size,omitempty"` Payload []byte `json:"payload"` // SegmentType stores payload here; FileType stores crc64 checksum here; Position int `json:"position"` } // SetName will check name for valid UTF-8 string, and set the appropriate // field. See https://github.com/vbatts/tar-split/issues/17 func (e *Entry) SetName(name string) { if utf8.ValidString(name) { e.Name = name } else { e.NameRaw = []byte(name) } } // SetNameBytes will check name for valid UTF-8 string, and set the appropriate // field func (e *Entry) SetNameBytes(name []byte) { if utf8.Valid(name) { e.Name = string(name) } else { e.NameRaw = name } } // GetName returns the string for the entry's name, regardless of the field stored in func (e *Entry) GetName() string { if len(e.NameRaw) > 0 { return string(e.NameRaw) } return e.Name } // GetNameBytes returns the bytes for the entry's name, regardless of the field stored in func (e *Entry) GetNameBytes() []byte { if len(e.NameRaw) > 0 { return e.NameRaw } return []byte(e.Name) }