github.com/brownsys/tracing-framework-go@v0.0.0-20161210174012-0542a62412fe/go/darwin_amd64/src/net/parse.go (about) 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. 4 5 // Simple file i/o and string manipulation, to avoid 6 // depending on strconv and bufio and strings. 7 8 package net 9 10 import ( 11 "io" 12 "os" 13 "time" 14 _ "unsafe" // For go:linkname 15 ) 16 17 type file struct { 18 file *os.File 19 data []byte 20 atEOF bool 21 } 22 23 func (f *file) close() { f.file.Close() } 24 25 func (f *file) getLineFromData() (s string, ok bool) { 26 data := f.data 27 i := 0 28 for i = 0; i < len(data); i++ { 29 if data[i] == '\n' { 30 s = string(data[0:i]) 31 ok = true 32 // move data 33 i++ 34 n := len(data) - i 35 copy(data[0:], data[i:]) 36 f.data = data[0:n] 37 return 38 } 39 } 40 if f.atEOF && len(f.data) > 0 { 41 // EOF, return all we have 42 s = string(data) 43 f.data = f.data[0:0] 44 ok = true 45 } 46 return 47 } 48 49 func (f *file) readLine() (s string, ok bool) { 50 if s, ok = f.getLineFromData(); ok { 51 return 52 } 53 if len(f.data) < cap(f.data) { 54 ln := len(f.data) 55 n, err := io.ReadFull(f.file, f.data[ln:cap(f.data)]) 56 if n >= 0 { 57 f.data = f.data[0 : ln+n] 58 } 59 if err == io.EOF || err == io.ErrUnexpectedEOF { 60 f.atEOF = true 61 } 62 } 63 s, ok = f.getLineFromData() 64 return 65 } 66 67 func open(name string) (*file, error) { 68 fd, err := os.Open(name) 69 if err != nil { 70 return nil, err 71 } 72 return &file{fd, make([]byte, 0, os.Getpagesize()), false}, nil 73 } 74 75 func stat(name string) (mtime time.Time, size int64, err error) { 76 st, err := os.Stat(name) 77 if err != nil { 78 return time.Time{}, 0, err 79 } 80 return st.ModTime(), st.Size(), nil 81 } 82 83 // byteIndex is strings.IndexByte. It returns the index of the 84 // first instance of c in s, or -1 if c is not present in s. 85 // strings.IndexByte is implemented in runtime/asm_$GOARCH.s 86 //go:linkname byteIndex strings.IndexByte 87 func byteIndex(s string, c byte) int 88 89 // Count occurrences in s of any bytes in t. 90 func countAnyByte(s string, t string) int { 91 n := 0 92 for i := 0; i < len(s); i++ { 93 if byteIndex(t, s[i]) >= 0 { 94 n++ 95 } 96 } 97 return n 98 } 99 100 // Split s at any bytes in t. 101 func splitAtBytes(s string, t string) []string { 102 a := make([]string, 1+countAnyByte(s, t)) 103 n := 0 104 last := 0 105 for i := 0; i < len(s); i++ { 106 if byteIndex(t, s[i]) >= 0 { 107 if last < i { 108 a[n] = s[last:i] 109 n++ 110 } 111 last = i + 1 112 } 113 } 114 if last < len(s) { 115 a[n] = s[last:] 116 n++ 117 } 118 return a[0:n] 119 } 120 121 func getFields(s string) []string { return splitAtBytes(s, " \r\t\n") } 122 123 // Bigger than we need, not too big to worry about overflow 124 const big = 0xFFFFFF 125 126 // Decimal to integer starting at &s[i0]. 127 // Returns number, new offset, success. 128 func dtoi(s string, i0 int) (n int, i int, ok bool) { 129 n = 0 130 neg := false 131 if len(s) > 0 && s[0] == '-' { 132 neg = true 133 s = s[1:] 134 } 135 for i = i0; i < len(s) && '0' <= s[i] && s[i] <= '9'; i++ { 136 n = n*10 + int(s[i]-'0') 137 if n >= big { 138 if neg { 139 return -big, i + 1, false 140 } 141 return big, i, false 142 } 143 } 144 if i == i0 { 145 return 0, i, false 146 } 147 if neg { 148 n = -n 149 i++ 150 } 151 return n, i, true 152 } 153 154 // Hexadecimal to integer starting at &s[i0]. 155 // Returns number, new offset, success. 156 func xtoi(s string, i0 int) (n int, i int, ok bool) { 157 n = 0 158 for i = i0; i < len(s); i++ { 159 if '0' <= s[i] && s[i] <= '9' { 160 n *= 16 161 n += int(s[i] - '0') 162 } else if 'a' <= s[i] && s[i] <= 'f' { 163 n *= 16 164 n += int(s[i]-'a') + 10 165 } else if 'A' <= s[i] && s[i] <= 'F' { 166 n *= 16 167 n += int(s[i]-'A') + 10 168 } else { 169 break 170 } 171 if n >= big { 172 return 0, i, false 173 } 174 } 175 if i == i0 { 176 return 0, i, false 177 } 178 return n, i, true 179 } 180 181 // xtoi2 converts the next two hex digits of s into a byte. 182 // If s is longer than 2 bytes then the third byte must be e. 183 // If the first two bytes of s are not hex digits or the third byte 184 // does not match e, false is returned. 185 func xtoi2(s string, e byte) (byte, bool) { 186 if len(s) > 2 && s[2] != e { 187 return 0, false 188 } 189 n, ei, ok := xtoi(s[:2], 0) 190 return byte(n), ok && ei == 2 191 } 192 193 // Convert integer to decimal string. 194 func itoa(val int) string { 195 if val < 0 { 196 return "-" + uitoa(uint(-val)) 197 } 198 return uitoa(uint(val)) 199 } 200 201 // Convert unsigned integer to decimal string. 202 func uitoa(val uint) string { 203 if val == 0 { // avoid string allocation 204 return "0" 205 } 206 var buf [20]byte // big enough for 64bit value base 10 207 i := len(buf) - 1 208 for val >= 10 { 209 q := val / 10 210 buf[i] = byte('0' + val - q*10) 211 i-- 212 val = q 213 } 214 // val < 10 215 buf[i] = byte('0' + val) 216 return string(buf[i:]) 217 } 218 219 // Convert i to a hexadecimal string. Leading zeros are not printed. 220 func appendHex(dst []byte, i uint32) []byte { 221 if i == 0 { 222 return append(dst, '0') 223 } 224 for j := 7; j >= 0; j-- { 225 v := i >> uint(j*4) 226 if v > 0 { 227 dst = append(dst, hexDigit[v&0xf]) 228 } 229 } 230 return dst 231 } 232 233 // Number of occurrences of b in s. 234 func count(s string, b byte) int { 235 n := 0 236 for i := 0; i < len(s); i++ { 237 if s[i] == b { 238 n++ 239 } 240 } 241 return n 242 } 243 244 // Index of rightmost occurrence of b in s. 245 func last(s string, b byte) int { 246 i := len(s) 247 for i--; i >= 0; i-- { 248 if s[i] == b { 249 break 250 } 251 } 252 return i 253 } 254 255 // lowerASCIIBytes makes x ASCII lowercase in-place. 256 func lowerASCIIBytes(x []byte) { 257 for i, b := range x { 258 if 'A' <= b && b <= 'Z' { 259 x[i] += 'a' - 'A' 260 } 261 } 262 } 263 264 // lowerASCII returns the ASCII lowercase version of b. 265 func lowerASCII(b byte) byte { 266 if 'A' <= b && b <= 'Z' { 267 return b + ('a' - 'A') 268 } 269 return b 270 } 271 272 // trimSpace returns x without any leading or trailing ASCII whitespace. 273 func trimSpace(x []byte) []byte { 274 for len(x) > 0 && isSpace(x[0]) { 275 x = x[1:] 276 } 277 for len(x) > 0 && isSpace(x[len(x)-1]) { 278 x = x[:len(x)-1] 279 } 280 return x 281 } 282 283 // isSpace reports whether b is an ASCII space character. 284 func isSpace(b byte) bool { 285 return b == ' ' || b == '\t' || b == '\n' || b == '\r' 286 } 287 288 // removeComment returns line, removing any '#' byte and any following 289 // bytes. 290 func removeComment(line []byte) []byte { 291 if i := bytesIndexByte(line, '#'); i != -1 { 292 return line[:i] 293 } 294 return line 295 } 296 297 // foreachLine runs fn on each line of x. 298 // Each line (except for possibly the last) ends in '\n'. 299 // It returns the first non-nil error returned by fn. 300 func foreachLine(x []byte, fn func(line []byte) error) error { 301 for len(x) > 0 { 302 nl := bytesIndexByte(x, '\n') 303 if nl == -1 { 304 return fn(x) 305 } 306 line := x[:nl+1] 307 x = x[nl+1:] 308 if err := fn(line); err != nil { 309 return err 310 } 311 } 312 return nil 313 } 314 315 // foreachField runs fn on each non-empty run of non-space bytes in x. 316 // It returns the first non-nil error returned by fn. 317 func foreachField(x []byte, fn func(field []byte) error) error { 318 x = trimSpace(x) 319 for len(x) > 0 { 320 sp := bytesIndexByte(x, ' ') 321 if sp == -1 { 322 return fn(x) 323 } 324 if field := trimSpace(x[:sp]); len(field) > 0 { 325 if err := fn(field); err != nil { 326 return err 327 } 328 } 329 x = trimSpace(x[sp+1:]) 330 } 331 return nil 332 } 333 334 // bytesIndexByte is bytes.IndexByte. It returns the index of the 335 // first instance of c in s, or -1 if c is not present in s. 336 // bytes.IndexByte is implemented in runtime/asm_$GOARCH.s 337 //go:linkname bytesIndexByte bytes.IndexByte 338 func bytesIndexByte(s []byte, c byte) int 339 340 // stringsHasSuffix is strings.HasSuffix. It reports whether s ends in 341 // suffix. 342 func stringsHasSuffix(s, suffix string) bool { 343 return len(s) >= len(suffix) && s[len(s)-len(suffix):] == suffix 344 } 345 346 // stringsHasSuffixFold reports whether s ends in suffix, 347 // ASCII-case-insensitively. 348 func stringsHasSuffixFold(s, suffix string) bool { 349 if len(suffix) > len(s) { 350 return false 351 } 352 for i := 0; i < len(suffix); i++ { 353 if lowerASCII(suffix[i]) != lowerASCII(s[len(s)-len(suffix)+i]) { 354 return false 355 } 356 } 357 return true 358 } 359 360 // stringsHasPrefix is strings.HasPrefix. It reports whether s begins with prefix. 361 func stringsHasPrefix(s, prefix string) bool { 362 return len(s) >= len(prefix) && s[:len(prefix)] == prefix 363 } 364 365 func readFull(r io.Reader) (all []byte, err error) { 366 buf := make([]byte, 1024) 367 for { 368 n, err := r.Read(buf) 369 all = append(all, buf[:n]...) 370 if err == io.EOF { 371 return all, nil 372 } 373 if err != nil { 374 return nil, err 375 } 376 } 377 } 378 379 // goDebugString returns the value of the named GODEBUG key. 380 // GODEBUG is of the form "key=val,key2=val2" 381 func goDebugString(key string) string { 382 s := os.Getenv("GODEBUG") 383 for i := 0; i < len(s)-len(key)-1; i++ { 384 if i > 0 && s[i-1] != ',' { 385 continue 386 } 387 afterKey := s[i+len(key):] 388 if afterKey[0] != '=' || s[i:i+len(key)] != key { 389 continue 390 } 391 val := afterKey[1:] 392 for i, b := range val { 393 if b == ',' { 394 return val[:i] 395 } 396 } 397 return val 398 } 399 return "" 400 }