github.com/apptainer/singularity@v3.1.1+incompatible/pkg/image/reader.go (about) 1 // Copyright (c) 2019, Sylabs Inc. All rights reserved. 2 // This software is licensed under a 3-clause BSD license. Please consult the 3 // LICENSE.md file distributed with the sources of this project regarding your 4 // rights to use or distribute this software. 5 6 package image 7 8 import ( 9 "fmt" 10 "io" 11 "os" 12 ) 13 14 type readerError string 15 16 func (e readerError) Error() string { return string(e) } 17 18 const ( 19 // ErrNoSection corresponds to an image section not found 20 ErrNoSection = readerError("no section found") 21 // ErrNoPartition corresponds to an image partition not found 22 ErrNoPartition = readerError("no partition found") 23 ) 24 25 func checkImage(image *Image) error { 26 if image == nil { 27 return fmt.Errorf("image is nil") 28 } 29 if image.File == nil { 30 return fmt.Errorf("image is not open for read") 31 } 32 return nil 33 } 34 35 func getSectionReader(file *os.File, section Section) io.Reader { 36 return io.NewSectionReader(file, int64(section.Offset), int64(section.Size)) 37 } 38 39 func commonSectionReader(partition bool, image *Image, name string, index int) (io.Reader, error) { 40 var err error 41 42 idx := -1 43 if err = checkImage(image); err != nil { 44 return nil, err 45 } 46 47 sectionName := "sections" 48 sections := image.Sections 49 err = ErrNoSection 50 51 if partition { 52 sectionName = "partitions" 53 sections = image.Partitions 54 err = ErrNoPartition 55 } 56 57 if index >= 0 { 58 l := len(sections) 59 if index > l-1 { 60 return nil, fmt.Errorf("index too large, image contains %d %s", l, sectionName) 61 } 62 idx = index 63 } 64 if name == "" && idx < 0 { 65 return nil, fmt.Errorf("no name or positive index provided") 66 } 67 for i, p := range sections { 68 if p.Name == name || i == idx { 69 return getSectionReader(image.File, p), nil 70 } 71 } 72 return nil, err 73 } 74 75 // NewPartitionReader searches and returns a reader for an image 76 // partition identified by name or by index, if index is less than 0 77 // only partition with provided name will be returned if a matching 78 // entry is found 79 func NewPartitionReader(image *Image, name string, index int) (io.Reader, error) { 80 return commonSectionReader(true, image, name, index) 81 } 82 83 // NewSectionReader searches and returns a reader for an image 84 // section identified by name or by index, if index is less than 0 85 // only section with provided name will be returned if a matching 86 // entry is found 87 func NewSectionReader(image *Image, name string, index int) (io.Reader, error) { 88 return commonSectionReader(false, image, name, index) 89 }