OSDN Git Service

libgo: Update to current Go library.
[pf3gnuchains/gcc-fork.git] / libgo / go / net / parse.go
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 )
14
15 type file struct {
16         file  *os.File
17         data  []byte
18         atEOF bool
19 }
20
21 func (f *file) close() { f.file.Close() }
22
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
36                 }
37         }
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
43         }
44         return
45 }
46
47 func (f *file) readLine() (s string, ok bool) {
48         if s, ok = f.getLineFromData(); ok {
49                 return
50         }
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]
56                 }
57                 if err == os.EOF {
58                         f.atEOF = true
59                 }
60         }
61         s, ok = f.getLineFromData()
62         return
63 }
64
65 func open(name string) (*file, os.Error) {
66         fd, err := os.Open(name)
67         if err != nil {
68                 return nil, err
69         }
70         return &file{fd, make([]byte, 1024)[0:0], false}, nil
71 }
72
73 func byteIndex(s string, c byte) int {
74         for i := 0; i < len(s); i++ {
75                 if s[i] == c {
76                         return i
77                 }
78         }
79         return -1
80 }
81
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++
88                 }
89         }
90         return n
91 }
92
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])
102                                 n++
103                         }
104                         last = i + 1
105                 }
106         }
107         if last < len(s) {
108                 a[n] = string(s[last:])
109                 n++
110         }
111         return a[0:n]
112 }
113
114 func getFields(s string) []string { return splitAtBytes(s, " \r\t\n") }
115
116 // Bigger than we need, not too big to worry about overflow
117 const big = 0xFFFFFF
118
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
127                 }
128         }
129         if i == i0 {
130                 return 0, i, false
131         }
132         return n, i, true
133 }
134
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
151                 }
152                 if n >= big {
153                         return 0, i, false
154                 }
155         }
156         if i == i0 {
157                 return 0, i, false
158         }
159         return n, i, true
160 }
161
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
170         }
171         ui := uint(i)
172         for ui > 0 || n == len(buf) {
173                 n--
174                 buf[n] = byte('0' + ui%10)
175                 ui /= 10
176         }
177         if neg {
178                 n--
179                 buf[n] = '-'
180         }
181         return string(buf[n:])
182 }
183
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 {
189                         n++
190                 }
191         }
192         return n
193 }
194
195 // Index of rightmost occurrence of b in s.
196 func last(s string, b byte) int {
197         i := len(s)
198         for i--; i >= 0; i-- {
199                 if s[i] == b {
200                         break
201                 }
202         }
203         return i
204 }