// restPath returns the path to the given resource. func restPath(url *url.URL, h restic.Handle) string { u := *url var dir string switch h.Type { case restic.ConfigFile: dir = "" h.Name = "config" case restic.DataFile: dir = backend.Paths.Data case restic.SnapshotFile: dir = backend.Paths.Snapshots case restic.IndexFile: dir = backend.Paths.Index case restic.LockFile: dir = backend.Paths.Locks case restic.KeyFile: dir = backend.Paths.Keys default: dir = string(h.Type) } u.Path = path.Join(url.Path, dir, h.Name) return u.String() }
// Stat returns information about a file in the backend. func (be *MemoryBackend) Stat(h restic.Handle) (restic.FileInfo, error) { be.m.Lock() defer be.m.Unlock() if err := h.Valid(); err != nil { return restic.FileInfo{}, err } if h.Type == restic.ConfigFile { h.Name = "" } debug.Log("stat %v", h) e, ok := be.data[entry{h.Type, h.Name}] if !ok { return restic.FileInfo{}, errors.New("no such data") } return restic.FileInfo{Size: int64(len(e))}, nil }
// Load reads data from the backend. func (be *MemoryBackend) Load(h restic.Handle, p []byte, off int64) (int, error) { if err := h.Valid(); err != nil { return 0, err } be.m.Lock() defer be.m.Unlock() if h.Type == restic.ConfigFile { h.Name = "" } debug.Log("get %v offset %v len %v", h, off, len(p)) if _, ok := be.data[entry{h.Type, h.Name}]; !ok { return 0, errors.New("no such data") } buf := be.data[entry{h.Type, h.Name}] switch { case off > int64(len(buf)): return 0, errors.New("offset beyond end of file") case off < -int64(len(buf)): off = 0 case off < 0: off = int64(len(buf)) + off } buf = buf[off:] n := copy(p, buf) if len(p) > len(buf) { return n, io.ErrUnexpectedEOF } return n, nil }
// Save adds new Data to the backend. func (be *MemoryBackend) Save(h restic.Handle, p []byte) error { if err := h.Valid(); err != nil { return err } be.m.Lock() defer be.m.Unlock() if h.Type == restic.ConfigFile { h.Name = "" } if _, ok := be.data[entry{h.Type, h.Name}]; ok { return errors.New("file already exists") } debug.Log("save %v bytes at %v", len(p), h) buf := make([]byte, len(p)) copy(buf, p) be.data[entry{h.Type, h.Name}] = buf return nil }