summaryrefslogtreecommitdiff
path: root/src/pkg/net/parse.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/net/parse.go')
-rw-r--r--src/pkg/net/parse.go160
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
+}
+