Merge from mainline (167278:168000).
[official-gcc/graphite-test-results.git] / libgo / go / net / parse.go
blob605f3110b7baf3c77f8151ebc004958cbf2a0430
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 // Simple file i/o and string manipulation, to avoid
6 // depending on strconv and bufio and strings.
8 package net
10 import (
11 "io"
12 "os"
15 type file struct {
16 file *os.File
17 data []byte
18 atEOF bool
21 func (f *file) close() { f.file.Close() }
23 func (f *file) getLineFromData() (s string, ok bool) {
24 data := f.data
25 i := 0
26 for i = 0; i < len(data); i++ {
27 if data[i] == '\n' {
28 s = string(data[0:i])
29 ok = true
30 // move data
31 i++
32 n := len(data) - i
33 copy(data[0:], data[i:])
34 f.data = data[0:n]
35 return
38 if f.atEOF && len(f.data) > 0 {
39 // EOF, return all we have
40 s = string(data)
41 f.data = f.data[0:0]
42 ok = true
44 return
47 func (f *file) readLine() (s string, ok bool) {
48 if s, ok = f.getLineFromData(); ok {
49 return
51 if len(f.data) < cap(f.data) {
52 ln := len(f.data)
53 n, err := io.ReadFull(f.file, f.data[ln:cap(f.data)])
54 if n >= 0 {
55 f.data = f.data[0 : ln+n]
57 if err == os.EOF {
58 f.atEOF = true
61 s, ok = f.getLineFromData()
62 return
65 func open(name string) (*file, os.Error) {
66 fd, err := os.Open(name, os.O_RDONLY, 0)
67 if err != nil {
68 return nil, err
70 return &file{fd, make([]byte, 1024)[0:0], false}, nil
73 func byteIndex(s string, c byte) int {
74 for i := 0; i < len(s); i++ {
75 if s[i] == c {
76 return i
79 return -1
82 // Count occurrences in s of any bytes in t.
83 func countAnyByte(s string, t string) int {
84 n := 0
85 for i := 0; i < len(s); i++ {
86 if byteIndex(t, s[i]) >= 0 {
87 n++
90 return n
93 // Split s at any bytes in t.
94 func splitAtBytes(s string, t string) []string {
95 a := make([]string, 1+countAnyByte(s, t))
96 n := 0
97 last := 0
98 for i := 0; i < len(s); i++ {
99 if byteIndex(t, s[i]) >= 0 {
100 if last < i {
101 a[n] = string(s[last:i])
104 last = i + 1
107 if last < len(s) {
108 a[n] = string(s[last:])
111 return a[0:n]
114 func getFields(s string) []string { return splitAtBytes(s, " \r\t\n") }
116 // Bigger than we need, not too big to worry about overflow
117 const big = 0xFFFFFF
119 // Decimal to integer starting at &s[i0].
120 // Returns number, new offset, success.
121 func dtoi(s string, i0 int) (n int, i int, ok bool) {
122 n = 0
123 for i = i0; i < len(s) && '0' <= s[i] && s[i] <= '9'; i++ {
124 n = n*10 + int(s[i]-'0')
125 if n >= big {
126 return 0, i, false
129 if i == i0 {
130 return 0, i, false
132 return n, i, true
135 // Hexadecimal to integer starting at &s[i0].
136 // Returns number, new offset, success.
137 func xtoi(s string, i0 int) (n int, i int, ok bool) {
138 n = 0
139 for i = i0; i < len(s); i++ {
140 if '0' <= s[i] && s[i] <= '9' {
141 n *= 16
142 n += int(s[i] - '0')
143 } else if 'a' <= s[i] && s[i] <= 'f' {
144 n *= 16
145 n += int(s[i]-'a') + 10
146 } else if 'A' <= s[i] && s[i] <= 'F' {
147 n *= 16
148 n += int(s[i]-'A') + 10
149 } else {
150 break
152 if n >= big {
153 return 0, i, false
156 if i == i0 {
157 return 0, i, false
159 return n, i, true
162 // Integer to decimal.
163 func itoa(i int) string {
164 var buf [30]byte
165 n := len(buf)
166 neg := false
167 if i < 0 {
168 i = -i
169 neg = true
171 ui := uint(i)
172 for ui > 0 || n == len(buf) {
174 buf[n] = byte('0' + ui%10)
175 ui /= 10
177 if neg {
179 buf[n] = '-'
181 return string(buf[n:])
184 // Number of occurrences of b in s.
185 func count(s string, b byte) int {
186 n := 0
187 for i := 0; i < len(s); i++ {
188 if s[i] == b {
192 return n
195 // Returns the prefix of s up to but not including the character c
196 func prefixBefore(s string, c byte) string {
197 for i, v := range s {
198 if v == int(c) {
199 return s[0:i]
202 return s
205 // Index of rightmost occurrence of b in s.
206 func last(s string, b byte) int {
207 i := len(s)
208 for i--; i >= 0; i-- {
209 if s[i] == b {
210 break
213 return i