diff options
Diffstat (limited to 'src/pkg/net/parse.go')
-rw-r--r-- | src/pkg/net/parse.go | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/src/pkg/net/parse.go b/src/pkg/net/parse.go new file mode 100644 index 000000000..de47cb812 --- /dev/null +++ b/src/pkg/net/parse.go @@ -0,0 +1,160 @@ +// 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. + +// Simple file i/o and string manipulation, to avoid +// depending on strconv and bufio. + +package net + +import ( + "io"; + "os"; +) + +type Error struct { + os.ErrorString +} + +type file struct { + file *os.File; + data []byte; +} + +func (f *file) close() { + f.file.Close() +} + +func (f *file) getLineFromData() (s string, ok bool) { + data := f.data; + for i := 0; i < len(data); i++ { + if data[i] == '\n' { + s = string(data[0:i]); + ok = true; + // move data + i++; + n := len(data) - i; + for j := 0; j < n; j++ { + data[j] = data[i+j]; + } + f.data = data[0:n]; + return + } + } + return +} + +func (f *file) readLine() (s string, ok bool) { + if s, ok = f.getLineFromData(); ok { + return + } + if len(f.data) < cap(f.data) { + ln := len(f.data); + n, err := io.FullRead(f.file, f.data[ln:cap(f.data)]); + if n >= 0 { + f.data = f.data[0:ln+n]; + } + } + s, ok = f.getLineFromData(); + return +} + +func open(name string) (*file, os.Error) { + fd, err := os.Open(name, os.O_RDONLY, 0); + if err != nil { + return nil, err; + } + return &file{fd, make([]byte, 1024)[0:0]}, nil; +} + +func byteIndex(s string, c byte) int { + for i := 0; i < len(s); i++ { + if s[i] == c { + return i + } + } + return -1 +} + +// Count occurrences in s of any bytes in t. +func countAnyByte(s string, t string) int { + n := 0; + for i := 0; i < len(s); i++ { + if byteIndex(t, s[i]) >= 0 { + n++; + } + } + return n +} + +// Split s at any bytes in t. +func splitAtBytes(s string, t string) []string { + a := make([]string, 1+countAnyByte(s, t)); + n := 0; + last := 0; + for i := 0; i < len(s); i++ { + if byteIndex(t, s[i]) >= 0 { + if last < i { + a[n] = string(s[last:i]); + n++; + } + last = i+1; + } + } + if last < len(s) { + a[n] = string(s[last:len(s)]); + n++; + } + return a[0:n]; +} + +func getFields(s string) []string { + return splitAtBytes(s, " \r\t\n"); +} + +// Bigger than we need, not too big to worry about overflow +const big = 0xFFFFFF + +// Decimal to integer starting at &s[i0]. +// Returns number, new offset, success. +func dtoi(s string, i0 int) (n int, i int, ok bool) { + n = 0; + for i = i0; i < len(s) && '0' <= s[i] && s[i] <= '9'; i++ { + n = n*10 + int(s[i] - '0'); + if n >= big { + return 0, i, false + } + } + if i == i0 { + return 0, i, false + } + return n, i, true +} + +// Hexadecimal to integer starting at &s[i0]. +// Returns number, new offset, success. +func xtoi(s string, i0 int) (n int, i int, ok bool) { + n = 0; + for i = i0; i < len(s); i++ { + if '0' <= s[i] && s[i] <= '9' { + n *= 16; + n += int(s[i] - '0') + } else if 'a' <= s[i] && s[i] <= 'f' { + n *= 16; + n += int(s[i] - 'a') + 10 + } else if 'A' <= s[i] && s[i] <= 'F' { + n *= 16; + n += int(s[i] -'A') + 10 + } else { + break + } + if n >= big { + return 0, i, false + } + } + if i == i0 { + return 0, i, false + } + return n, i, true +} + |