| // Copyright 2009 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| package os | |
| import ( | |
| "io" | |
| "syscall" | |
| ) | |
| func (file *File) readdir(n int) ([]FileInfo, error) { | |
| // If this file has no dirinfo, create one. | |
| if file.dirinfo == nil { | |
| file.dirinfo = new(dirInfo) | |
| } | |
| d := file.dirinfo | |
| size := n | |
| if size <= 0 { | |
| size = 100 | |
| n = -1 | |
| } | |
| fi := make([]FileInfo, 0, size) // Empty with room to grow. | |
| for n != 0 { | |
| // Refill the buffer if necessary. | |
| if d.bufp >= d.nbuf { | |
| nb, err := file.Read(d.buf[:]) | |
| // Update the buffer state before checking for errors. | |
| d.bufp, d.nbuf = 0, nb | |
| if err != nil { | |
| if err == io.EOF { | |
| break | |
| } | |
| return fi, &PathError{"readdir", file.name, err} | |
| } | |
| if nb < syscall.STATFIXLEN { | |
| return fi, &PathError{"readdir", file.name, syscall.ErrShortStat} | |
| } | |
| } | |
| // Get a record from the buffer. | |
| b := d.buf[d.bufp:] | |
| m := int(uint16(b[0])|uint16(b[1])<<8) + 2 | |
| if m < syscall.STATFIXLEN { | |
| return fi, &PathError{"readdir", file.name, syscall.ErrShortStat} | |
| } | |
| dir, err := syscall.UnmarshalDir(b[:m]) | |
| if err != nil { | |
| return fi, &PathError{"readdir", file.name, err} | |
| } | |
| fi = append(fi, fileInfoFromStat(dir)) | |
| d.bufp += m | |
| n-- | |
| } | |
| if n >= 0 && len(fi) == 0 { | |
| return fi, io.EOF | |
| } | |
| return fi, nil | |
| } | |
| func (file *File) readdirnames(n int) (names []string, err error) { | |
| fi, err := file.Readdir(n) | |
| names = make([]string, len(fi)) | |
| for i := range fi { | |
| names[i] = fi[i].Name() | |
| } | |
| return | |
| } |