Fix "PR c++/92804 ICE trying to use concept as a nested-name-specifier"
[official-gcc.git] / libgo / go / syscall / dirent.go
blob57264493163b7b15da86a8495591ac5b58d2671d
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // +build aix darwin dragonfly freebsd hurd js,wasm linux netbsd openbsd solaris
7 package syscall
9 import "unsafe"
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
16 if isBigEndian {
17 return readIntBE(b[off:], size), true
19 return readIntLE(b[off:], size), true
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")
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")
60 // ParseDirent parses up to max directory entries in buf,
61 // appending the names to names. It returns the number of
62 // bytes consumed from buf, the number of entries added
63 // to names, and the new names slice.
64 func ParseDirent(buf []byte, max int, names []string) (consumed int, count int, newnames []string) {
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
72 rec := buf[:reclen]
73 buf = buf[reclen:]
74 ino, ok := direntIno(rec)
75 if !ok {
76 break
78 if ino == 0 { // File absent in directory.
79 continue
81 const namoff = uint64(unsafe.Offsetof(Dirent{}.Name))
82 namlen, ok := direntNamlen(rec)
83 if !ok || namoff+namlen > uint64(len(rec)) {
84 break
86 name := rec[namoff : namoff+namlen]
87 for i, c := range name {
88 if c == 0 {
89 name = name[:i]
90 break
93 // Check for useless names before allocating a string.
94 if string(name) == "." || string(name) == ".." {
95 continue
97 max--
98 count++
99 names = append(names, string(name))
101 return origlen - len(buf), count, names