github.com/ethersphere/bee/v2@v2.2.0/pkg/manifest/simple.go (about) 1 // Copyright 2020 The Swarm 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 manifest 6 7 import ( 8 "context" 9 "errors" 10 "fmt" 11 12 "github.com/ethersphere/bee/v2/pkg/file" 13 "github.com/ethersphere/bee/v2/pkg/manifest/simple" 14 "github.com/ethersphere/bee/v2/pkg/swarm" 15 ) 16 17 const ( 18 // ManifestSimpleContentType represents content type used for noting that 19 // specific file should be processed as 'simple' manifest 20 ManifestSimpleContentType = "application/bzz-manifest-simple+json" 21 ) 22 23 type simpleManifest struct { 24 manifest simple.Manifest 25 26 reference swarm.Address 27 ls file.LoadSaver 28 } 29 30 // NewSimpleManifest creates a new simple manifest. 31 func NewSimpleManifest(ls file.LoadSaver) (Interface, error) { 32 return &simpleManifest{ 33 manifest: simple.NewManifest(), 34 ls: ls, 35 }, nil 36 } 37 38 // NewSimpleManifestReference loads existing simple manifest. 39 func NewSimpleManifestReference(ref swarm.Address, l file.LoadSaver) (Interface, error) { 40 m := &simpleManifest{ 41 manifest: simple.NewManifest(), 42 reference: ref, 43 ls: l, 44 } 45 err := m.load(context.Background(), ref) 46 return m, err 47 } 48 49 func (m *simpleManifest) Type() string { 50 return ManifestSimpleContentType 51 } 52 53 func (m *simpleManifest) Add(_ context.Context, path string, entry Entry) error { 54 e := entry.Reference().String() 55 56 return m.manifest.Add(path, e, entry.Metadata()) 57 } 58 59 func (m *simpleManifest) Remove(_ context.Context, path string) error { 60 err := m.manifest.Remove(path) 61 if err != nil { 62 if errors.Is(err, simple.ErrNotFound) { 63 return ErrNotFound 64 } 65 return err 66 } 67 68 return nil 69 } 70 71 func (m *simpleManifest) Lookup(_ context.Context, path string) (Entry, error) { 72 n, err := m.manifest.Lookup(path) 73 if err != nil { 74 return nil, ErrNotFound 75 } 76 77 address, err := swarm.ParseHexAddress(n.Reference()) 78 if err != nil { 79 return nil, fmt.Errorf("parse swarm address: %w", err) 80 } 81 82 entry := NewEntry(address, n.Metadata()) 83 84 return entry, nil 85 } 86 87 func (m *simpleManifest) HasPrefix(_ context.Context, prefix string) (bool, error) { 88 return m.manifest.HasPrefix(prefix), nil 89 } 90 91 func (m *simpleManifest) Store(ctx context.Context, storeSizeFn ...StoreSizeFunc) (swarm.Address, error) { 92 data, err := m.manifest.MarshalBinary() 93 if err != nil { 94 return swarm.ZeroAddress, fmt.Errorf("manifest marshal error: %w", err) 95 } 96 97 if len(storeSizeFn) > 0 { 98 dataLen := int64(len(data)) 99 for i := range storeSizeFn { 100 err = storeSizeFn[i](dataLen) 101 if err != nil { 102 return swarm.ZeroAddress, fmt.Errorf("manifest store size func: %w", err) 103 } 104 } 105 } 106 107 ref, err := m.ls.Save(ctx, data) 108 if err != nil { 109 return swarm.ZeroAddress, fmt.Errorf("manifest save error: %w", err) 110 } 111 m.reference = swarm.NewAddress(ref) 112 return m.reference, nil 113 } 114 115 func (m *simpleManifest) IterateAddresses(ctx context.Context, fn swarm.AddressIterFunc) error { 116 if swarm.ZeroAddress.Equal(m.reference) { 117 return ErrMissingReference 118 } 119 120 // NOTE: making it behave same for all manifest implementation 121 err := fn(m.reference) 122 if err != nil { 123 return fmt.Errorf("manifest iterate addresses: %w", err) 124 } 125 126 walker := func(path string, entry simple.Entry, err error) error { 127 if err != nil { 128 return err 129 } 130 131 ref, err := swarm.ParseHexAddress(entry.Reference()) 132 if err != nil { 133 return err 134 } 135 136 return fn(ref) 137 } 138 139 err = m.manifest.WalkEntry("", walker) 140 if err != nil { 141 return fmt.Errorf("manifest iterate addresses: %w", err) 142 } 143 144 return nil 145 } 146 147 func (m *simpleManifest) load(ctx context.Context, reference swarm.Address) error { 148 buf, err := m.ls.Load(ctx, reference.Bytes()) 149 if err != nil { 150 return fmt.Errorf("manifest load error: %w", err) 151 } 152 153 err = m.manifest.UnmarshalBinary(buf) 154 if err != nil { 155 return fmt.Errorf("manifest unmarshal error: %w", err) 156 } 157 158 return nil 159 }