diff options
author | Russ Cox <rsc@golang.org> | 2008-09-12 16:12:20 -0700 |
---|---|---|
committer | Russ Cox <rsc@golang.org> | 2008-09-12 16:12:20 -0700 |
commit | 638ba499b0112cbcdb2fa975f80c3ed9fa109d38 (patch) | |
tree | 70ecb7c35636e31843be3b5619b7ad372cb4f671 /src/lib/strings.go | |
parent | daf0485787cc8e926a57a75cbc46ca6ef80c6268 (diff) | |
download | golang-638ba499b0112cbcdb2fa975f80c3ed9fa109d38.tar.gz |
rudimentary string utilities.
R=r
DELTA=314 (306 added, 8 deleted, 0 changed)
OCL=15074
CL=15263
Diffstat (limited to 'src/lib/strings.go')
-rw-r--r-- | src/lib/strings.go | 198 |
1 files changed, 198 insertions, 0 deletions
diff --git a/src/lib/strings.go b/src/lib/strings.go new file mode 100644 index 000000000..54aac30c9 --- /dev/null +++ b/src/lib/strings.go @@ -0,0 +1,198 @@ +// 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. + +package strings + +// Count UTF-8 sequences in s. +// Assumes s is well-formed. +export func utflen(s string) int { + n := 0; + for i := 0; i < len(s); i++ { + if s[i]&0xC0 != 0x80 { + n++ + } + } + return n +} + +// Split string into array of UTF-8 sequences (still strings) +export func explode(s string) *[]string { + a := new([]string, utflen(s)); + j := 0; + for i := 0; i < len(a); i++ { + ej := j; + ej++; + for ej < len(s) && (s[ej]&0xC0) == 0x80 { + ej++ + } + a[i] = s[j:ej]; + j = ej + } + return a +} + +// Count non-overlapping instances of sep in s. +export func count(s, sep string) int { + if sep == "" { + return utflen(s)+1 + } + c := sep[0]; + n := 0; + for i := 0; i+len(sep) <= len(s); i++ { + if s[i] == c && (len(sep) == 1 || s[i:i+len(sep)] == sep) { + n++; + i += len(sep)-1 + } + } + return n +} + +// Return index of first instance of sep in s. +export func index(s, sep string) int { + if sep == "" { + return 0 + } + c := sep[0]; + for i := 0; i+len(sep) <= len(s); i++ { + if s[i] == c && (len(sep) == 1 || s[i:i+len(sep)] == sep) { + return i + } + } + return -1 +} + +// Split string into list of strings at separators +export func split(s, sep string) *[]string { + if sep == "" { + return explode(s) + } + c := sep[0]; + start := 0; + n := count(s, sep)+1; + a := new([]string, n); + na := 0; + for i := 0; i+len(sep) <= len(s); i++ { + if s[i] == c && (len(sep) == 1 || s[i:i+len(sep)] == sep) { + a[na] = s[start:i]; + na++; + start = i+len(sep); + i += len(sep)-1 + } + } + a[na] = s[start:len(s)]; + return a +} + +// Join list of strings with separators between them. +export func join(a *[]string, sep string) string { + if len(a) == 0 { + return 0 + } + if len(a) == 1 { + return a[0] + } + n := len(sep) * (len(a)-1); + for i := 0; i < len(a); i++ { + n += len(a[i]) + } + + b := new([]byte, n); + bp := 0; + for i := 0; i < len(a); i++ { + s := a[i]; + for j := 0; j < len(s); j++ { + b[bp] = s[j]; + bp++ + } + if i + 1 < len(a) { + s = sep; + for j := 0; j < len(s); j++ { + b[bp] = s[j]; + bp++ + } + } + } + return string(b) +} + +// Convert decimal string to integer. +// TODO: Doesn't check for overflow. +export func atoi(s string) (i int, ok bool) { + // empty string bad + if len(s) == 0 { + return 0, false + } + + // pick off leading sign + neg := false; + if s[0] == '+' { + s = s[1:len(s)] + } else if s[0] == '-' { + neg = true; + s = s[1:len(s)] + } + + // empty string bad + if len(s) == 0 { + return 0, false + } + + // pick off zero + if s == "0" { + return 0, true + } + + // otherwise, leading zero bad + if s[0] == '0' { + return 0, false + } + + // parse number + n := 0; + for i := 0; i < len(s); i++ { + if s[i] < '0' || s[i] > '9' { + return 0, false + } + n = n*10 + int(s[i] - '0') + } + if neg { + n = -n + } + return n, true +} + +export func itoa(i int) string { + if i == 0 { + return "0" + } + + neg := false; // negative + bigneg := false; // largest negative number + if i < 0 { + neg = true; + i = -i; + if i < 0 { + bigneg = true; // is largest negative int + i-- // now positive + } + } + + // Assemble decimal in reverse order. + var b [32]byte; + bp := len(b); + for ; i > 0; i /= 10 { + bp--; + b[bp] = byte(i%10) + '0' + } + if neg { // add sign + bp--; + b[bp] = '-' + } + if bigneg { // account for i-- above + b[len(b)-1]++ + } + + // BUG return string(b[bp:len(b)]) + return string((&b)[bp:len(b)]) +} |