Read directory entries

andybalholm
Apr 6, 2023, 12:52 AM
DF5RFSLHH4Y6GBM7MUTRTHXK5WC7FWV6RSEKDYGTKPSAKE2PQBXQC

Dependencies

  • [2] 7VEHGTEY Switch from reading text format to reading binary format.
  • [3] AYLFNM5C Add the ability to output the contents of a file.
  • [*] EKAB33DH Start using some parser combinators

Change contents

  • edit in output.go at line 4
    [3.59]
    [3.59]
    "errors"
  • edit in output.go at line 140
    [3.3030]
    type DirEntry struct {
    IsDirectory bool
    Name string
    Encoding string
    Inode *Block
    }
    func dirEntry(data []byte) ([]byte, DirEntry, error) {
    var d DirEntry
    var err error
    data, d.IsDirectory, err = mapValue(uint16LE, func(n uint16) bool {
    return n&0x200 != 0
    })(data)
    if err != err {
    return data, d, err
    }
    _, _, err = tuple(
    assign(&d.Name, toString(lengthData(uint64LE))),
    assign(&d.Encoding, mapValue(option(toString(lengthData(uint64LE))), func(p *string) string {
    if p == nil {
    return ""
    }
    return *p
    })),
    )(data)
    if err != nil {
    d.Name = string(data)
    }
    return nil, d, nil
    }
    func ReadDir(dirInode *Block) ([]DirEntry, error) {
    var entries []DirEntry
    for _, e := range dirInode.Edges {
    if e.Flag&EdgeFlagsDeleted != 0 {
    continue
    }
    if e.Flag&EdgeFlagsFolder == 0 {
    return nil, errors.New("ReadDir: found an edge that doesn't have Folder flag set")
    }
    b := e.To
    _, entry, err := dirEntry(b.Content)
    if err != nil {
    return nil, fmt.Errorf("not a valid directory entry: %q", b.Content)
    }
    for _, inodeEdge := range b.Edges {
    if inodeEdge.Flag&EdgeFlagsDeleted != 0 {
    continue
    }
    if inodeEdge.Flag&EdgeFlagsFolder == 0 {
    return nil, fmt.Errorf("directory entry for %s has an edge without Folder flag", entry.Name)
    }
    entry.Inode = inodeEdge.To
    break
    }
    if entry.Inode == nil {
    return nil, fmt.Errorf("directory entry for %s has no inode", entry.Name)
    }
    entries = append(entries, entry)
    }
    return entries, nil
    }
  • edit in combinators.go at line 277
    [2.6661]
    [2.6661]
    func uint16LE(input []byte) ([]byte, uint16, error) {
    if len(input) < 2 {
    return input, 0, fmt.Errorf("need 2 bytes to parse a 16-bit integer; only got %d", len(input))
    }
    return input[2:], binary.LittleEndian.Uint16(input), nil
    }