entry.go 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. package storage
  2. import "unicode/utf8"
  3. // Entries is for sorting by Position
  4. type Entries []Entry
  5. func (e Entries) Len() int { return len(e) }
  6. func (e Entries) Swap(i, j int) { e[i], e[j] = e[j], e[i] }
  7. func (e Entries) Less(i, j int) bool { return e[i].Position < e[j].Position }
  8. // Type of Entry
  9. type Type int
  10. const (
  11. // FileType represents a file payload from the tar stream.
  12. //
  13. // This will be used to map to relative paths on disk. Only Size > 0 will get
  14. // read into a resulting output stream (due to hardlinks).
  15. FileType Type = 1 + iota
  16. // SegmentType represents a raw bytes segment from the archive stream. These raw
  17. // byte segments consist of the raw headers and various padding.
  18. //
  19. // Its payload is to be marshalled base64 encoded.
  20. SegmentType
  21. )
  22. // Entry is the structure for packing and unpacking the information read from
  23. // the Tar archive.
  24. //
  25. // FileType Payload checksum is using `hash/crc64` for basic file integrity,
  26. // _not_ for cryptography.
  27. // From http://www.backplane.com/matt/crc64.html, CRC32 has almost 40,000
  28. // collisions in a sample of 18.2 million, CRC64 had none.
  29. type Entry struct {
  30. Type Type `json:"type"`
  31. Name string `json:"name,omitempty"`
  32. NameRaw []byte `json:"name_raw,omitempty"`
  33. Size int64 `json:"size,omitempty"`
  34. Payload []byte `json:"payload"` // SegmentType stores payload here; FileType stores crc64 checksum here;
  35. Position int `json:"position"`
  36. }
  37. // SetName will check name for valid UTF-8 string, and set the appropriate
  38. // field. See https://github.com/vbatts/tar-split/issues/17
  39. func (e *Entry) SetName(name string) {
  40. if utf8.ValidString(name) {
  41. e.Name = name
  42. } else {
  43. e.NameRaw = []byte(name)
  44. }
  45. }
  46. // SetNameBytes will check name for valid UTF-8 string, and set the appropriate
  47. // field
  48. func (e *Entry) SetNameBytes(name []byte) {
  49. if utf8.Valid(name) {
  50. e.Name = string(name)
  51. } else {
  52. e.NameRaw = name
  53. }
  54. }
  55. // GetName returns the string for the entry's name, regardless of the field stored in
  56. func (e *Entry) GetName() string {
  57. if len(e.NameRaw) > 0 {
  58. return string(e.NameRaw)
  59. }
  60. return e.Name
  61. }
  62. // GetNameBytes returns the bytes for the entry's name, regardless of the field stored in
  63. func (e *Entry) GetNameBytes() []byte {
  64. if len(e.NameRaw) > 0 {
  65. return e.NameRaw
  66. }
  67. return []byte(e.Name)
  68. }