src/pkg/net/parse.go - The Go Programming Language

Golang

Source file src/pkg/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	}