vendor/golang.org/x/sys/unix/dirent.go
changeset 251 1c52a0eeb952
parent 242 2a9ec03fe5a1
child 256 6d9efbef00a9
equal deleted inserted replaced
250:c040f992052f 251:1c52a0eeb952
     1 // Copyright 2009 The Go Authors. All rights reserved.
     1 // Copyright 2009 The Go Authors. All rights reserved.
     2 // Use of this source code is governed by a BSD-style
     2 // Use of this source code is governed by a BSD-style
     3 // license that can be found in the LICENSE file.
     3 // license that can be found in the LICENSE file.
     4 
     4 
     5 // +build aix darwin dragonfly freebsd linux nacl netbsd openbsd solaris
     5 // +build aix darwin dragonfly freebsd linux netbsd openbsd solaris
     6 
     6 
     7 package unix
     7 package unix
     8 
     8 
     9 import "syscall"
     9 import "unsafe"
       
    10 
       
    11 // readInt returns the size-bytes unsigned integer in native byte order at offset off.
       
    12 func readInt(b []byte, off, size uintptr) (u uint64, ok bool) {
       
    13 	if len(b) < int(off+size) {
       
    14 		return 0, false
       
    15 	}
       
    16 	if isBigEndian {
       
    17 		return readIntBE(b[off:], size), true
       
    18 	}
       
    19 	return readIntLE(b[off:], size), true
       
    20 }
       
    21 
       
    22 func readIntBE(b []byte, size uintptr) uint64 {
       
    23 	switch size {
       
    24 	case 1:
       
    25 		return uint64(b[0])
       
    26 	case 2:
       
    27 		_ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
       
    28 		return uint64(b[1]) | uint64(b[0])<<8
       
    29 	case 4:
       
    30 		_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
       
    31 		return uint64(b[3]) | uint64(b[2])<<8 | uint64(b[1])<<16 | uint64(b[0])<<24
       
    32 	case 8:
       
    33 		_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
       
    34 		return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 |
       
    35 			uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56
       
    36 	default:
       
    37 		panic("syscall: readInt with unsupported size")
       
    38 	}
       
    39 }
       
    40 
       
    41 func readIntLE(b []byte, size uintptr) uint64 {
       
    42 	switch size {
       
    43 	case 1:
       
    44 		return uint64(b[0])
       
    45 	case 2:
       
    46 		_ = b[1] // bounds check hint to compiler; see golang.org/issue/14808
       
    47 		return uint64(b[0]) | uint64(b[1])<<8
       
    48 	case 4:
       
    49 		_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808
       
    50 		return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24
       
    51 	case 8:
       
    52 		_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808
       
    53 		return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 |
       
    54 			uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
       
    55 	default:
       
    56 		panic("syscall: readInt with unsupported size")
       
    57 	}
       
    58 }
    10 
    59 
    11 // ParseDirent parses up to max directory entries in buf,
    60 // ParseDirent parses up to max directory entries in buf,
    12 // appending the names to names. It returns the number of
    61 // appending the names to names. It returns the number of
    13 // bytes consumed from buf, the number of entries added
    62 // bytes consumed from buf, the number of entries added
    14 // to names, and the new names slice.
    63 // to names, and the new names slice.
    15 func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) {
    64 func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) {
    16 	return syscall.ParseDirent(buf, max, names)
    65 	origlen := len(buf)
       
    66 	count = 0
       
    67 	for max != 0 && len(buf) > 0 {
       
    68 		reclen, ok := direntReclen(buf)
       
    69 		if !ok || reclen > uint64(len(buf)) {
       
    70 			return origlen, count, names
       
    71 		}
       
    72 		rec := buf[:reclen]
       
    73 		buf = buf[reclen:]
       
    74 		ino, ok := direntIno(rec)
       
    75 		if !ok {
       
    76 			break
       
    77 		}
       
    78 		if ino == 0 { // File absent in directory.
       
    79 			continue
       
    80 		}
       
    81 		const namoff = uint64(unsafe.Offsetof(Dirent{}.Name))
       
    82 		namlen, ok := direntNamlen(rec)
       
    83 		if !ok || namoff+namlen > uint64(len(rec)) {
       
    84 			break
       
    85 		}
       
    86 		name := rec[namoff : namoff+namlen]
       
    87 		for i, c := range name {
       
    88 			if c == 0 {
       
    89 				name = name[:i]
       
    90 				break
       
    91 			}
       
    92 		}
       
    93 		// Check for useless names before allocating a string.
       
    94 		if string(name) == "." || string(name) == ".." {
       
    95 			continue
       
    96 		}
       
    97 		max--
       
    98 		count++
       
    99 		names = append(names, string(name))
       
   100 	}
       
   101 	return origlen - len(buf), count, names
    17 }
   102 }