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
}