blob: 8b10519d41bfd68487df51f6b874cde2642e39cc [file] [log] [blame]
// 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 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.ReadFull(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
}