func TestSmallRewind(test *testing.T) { t := NewTapeFromReadByter(bufio.NewReader(strings.NewReader("hello, world!"))) test_read := func(expected_char byte) { out_char, err := t.ReadElement() if err != nil { test.Errorf("Unexpected end of characters; expecting '%c'", expected_char) } else if out_char != expected_char { test.Errorf("Unexpected character '%c'; expecting '%c'", out_char, expected_char) } } test_str_read := func(expected_str string) { rdr := strings.Reader(expected_str) for { expected_byte, err := rdr.ReadByte() if err != nil { return } test_read(expected_byte) } } test_str_read("hel") t.Rewind(1) test_str_read("llo") test_str_read(", world") test_str_read("!") t.Rewind(6) test_str_read("world!") }
// contents returns all the entries inside a directory. func (fs *FS) contents(e *entry) (entries []entry, err error) { if !e.dir { return nil, errors.New("not a directory") } fs.rd = strings.Reader(fs.s[e.offset:]) err = fs.dec.Decode(&entries) return }
// Decode converts a file system as encoded by Encode // into an FS. func Decode(s string) (*FS, error) { fs := new(FS) r := strings.NewReader(s[len(s)-4:]) if err := binary.Read(r, binary.LittleEndian, &fs.root); err != nil { return nil, err } fs.s = s[0 : len(s)-4] fs.dec = gob.NewDecoder(&fs.rd) // read dummy entry at start to prime the gob types. fs.rd = strings.Reader(fs.s) if err := fs.dec.Decode(new([]entry)); err != nil { return nil, err } return fs, nil }
// Open opens the named path within fs. // Paths are slash-separated, with an optional // slash prefix. func (fs *FS) Open(path string) (*File, error) { p := strings.FieldsFunc(path, isSlash) e := &entry{dir: true, offset: int(fs.root)} fs.mu.Lock() defer fs.mu.Unlock() for _, name := range p { var err error e, err = fs.walk(e, name) if err != nil { return nil, err } } if e.dir { return &File{fs, "", e}, nil } return &File{ fs, strings.Reader(fs.s[e.offset : e.offset+e.len]), e, }, nil }