github.com/linuxboot/fiano@v1.2.0/pkg/cbfs/payload.go (about) 1 // Copyright 2018-2021 the LinuxBoot Authors. All rights reserved 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package cbfs 6 7 import ( 8 "fmt" 9 "io" 10 "log" 11 ) 12 13 func init() { 14 if err := RegisterFileReader(&SegReader{Type: TypeSELF, Name: "Payload", New: NewPayloadRecord}); err != nil { 15 log.Fatal(err) 16 } 17 } 18 19 func NewPayloadRecord(f *File) (ReadWriter, error) { 20 p := &PayloadRecord{File: *f} 21 return p, nil 22 } 23 24 func (p *PayloadRecord) Read(in io.ReadSeeker) error { 25 for { 26 var h PayloadHeader 27 if err := Read(in, &h); err != nil { 28 Debug("PayloadHeader read: %v", err) 29 return err 30 } 31 Debug("Got PayloadHeader %s", h.String()) 32 p.Segs = append(p.Segs, h) 33 if h.Type == SegEntry { 34 break 35 } 36 } 37 // Seek to offset (after the header); the remainder is the actual payload. 38 offset, err := in.Seek(0, io.SeekCurrent) 39 if err != nil { 40 return fmt.Errorf("Finding location in stream: %v", err) 41 } 42 bodySize := int64(p.Size) - offset 43 Debug("Payload size: %v, body size: %v, offset: %v", p.Size, bodySize, offset) 44 if bodySize < 0 { 45 // This should not happen. Tolerate a potential error. 46 return nil 47 } 48 // This _may_ happen. E.g. with the test payload here. Silently ignore. 49 if bodySize == 0 { 50 Debug("Payload empty, nothing to read") 51 return nil 52 } 53 p.FData = make([]byte, bodySize) 54 n, err := in.Read(p.FData) 55 if err != nil { 56 return err 57 } 58 Debug("Payload read %d bytes", n) 59 return nil 60 } 61 62 func (h *PayloadRecord) String() string { 63 s := recString(h.File.Name, h.RecordStart, h.Type.String(), h.Size, "none") 64 for i, seg := range h.Segs { 65 s += "\n" 66 s += recString(fmt.Sprintf(" Seg #%d", i), seg.Offset, seg.Type.String(), seg.Size, seg.Compression.String()) 67 } 68 return s 69 } 70 71 func (r *PayloadHeader) String() string { 72 return fmt.Sprintf("Type %#x Compression %#x Offset %#x LoadAddress %#x Size %#x MemSize %#x", 73 r.Type, 74 r.Compression, 75 r.Offset, 76 r.LoadAddress, 77 r.Size, 78 r.MemSize) 79 } 80 81 func (r *PayloadRecord) Write(w io.Writer) error { 82 if err := Write(w, r.Segs); err != nil { 83 return err 84 } 85 return Write(w, r.FData) 86 } 87 88 func (r *PayloadRecord) GetFile() *File { 89 return &r.File 90 }