Imported Upstream version 4.7.2
[platform/upstream/gcc48.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 == io.EOF {
58                         f.atEOF = true
59                 }
60         }
61         s, ok = f.getLineFromData()
62         return
63 }
64
65 func open(name string) (*file, error) {
66         fd, err := os.Open(name)
67         if err != nil {
68                 return nil, err
69         }
70         return &file{fd, make([]byte, os.Getpagesize())[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 // xtoi2 converts the next two hex digits of s into a byte.
163 // If s is longer than 2 bytes then the third byte must be e.
164 // If the first two bytes of s are not hex digits or the third byte
165 // does not match e, false is returned.
166 func xtoi2(s string, e byte) (byte, bool) {
167         if len(s) > 2 && s[2] != e {
168                 return 0, false
169         }
170         n, ei, ok := xtoi(s[:2], 0)
171         return byte(n), ok && ei == 2
172 }
173
174 // Integer to decimal.
175 func itoa(i int) string {
176         var buf [30]byte
177         n := len(buf)
178         neg := false
179         if i < 0 {
180                 i = -i
181                 neg = true
182         }
183         ui := uint(i)
184         for ui > 0 || n == len(buf) {
185                 n--
186                 buf[n] = byte('0' + ui%10)
187                 ui /= 10
188         }
189         if neg {
190                 n--
191                 buf[n] = '-'
192         }
193         return string(buf[n:])
194 }
195
196 // Convert i to decimal string.
197 func itod(i uint) string {
198         if i == 0 {
199                 return "0"
200         }
201
202         // Assemble decimal in reverse order.
203         var b [32]byte
204         bp := len(b)
205         for ; i > 0; i /= 10 {
206                 bp--
207                 b[bp] = byte(i%10) + '0'
208         }
209
210         return string(b[bp:])
211 }
212
213 // Convert i to hexadecimal string.
214 func itox(i uint, min int) string {
215         // Assemble hexadecimal in reverse order.
216         var b [32]byte
217         bp := len(b)
218         for ; i > 0 || min > 0; i /= 16 {
219                 bp--
220                 b[bp] = "0123456789abcdef"[byte(i%16)]
221                 min--
222         }
223
224         return string(b[bp:])
225 }
226
227 // Number of occurrences of b in s.
228 func count(s string, b byte) int {
229         n := 0
230         for i := 0; i < len(s); i++ {
231                 if s[i] == b {
232                         n++
233                 }
234         }
235         return n
236 }
237
238 // Index of rightmost occurrence of b in s.
239 func last(s string, b byte) int {
240         i := len(s)
241         for i--; i >= 0; i-- {
242                 if s[i] == b {
243                         break
244                 }
245         }
246         return i
247 }