]> Cypherpunks repositories - gostls13.git/commitdiff
Add Upper, Lower, Trim methods to strings package.
authorSteve Newman <devnull@localhost>
Fri, 5 Jun 2009 20:09:03 +0000 (13:09 -0700)
committerSteve Newman <devnull@localhost>
Fri, 5 Jun 2009 20:09:03 +0000 (13:09 -0700)
APPROVED=rsc
DELTA=110  (110 added, 0 deleted, 0 changed)
OCL=29766
CL=29951

src/lib/strings/strings.go
src/lib/strings/strings_test.go

index fabd9329f29eb6a2ae447c1ee05d98bfa9680b4d..2e3dc0215e49f33b18cdf9b4187396bbcf4330f3 100644 (file)
@@ -118,3 +118,61 @@ func HasPrefix(s, prefix string) bool {
 func HasSuffix(s, suffix string) bool {
        return len(s) >= len(suffix) && s[len(s)-len(suffix):len(s)] == suffix
 }
+
+// Upper returns a copy of the string s, with all low ASCII lowercase letters
+// converted to uppercase.
+// TODO: full Unicode support
+func UpperASCII(s string) string {
+       // Note, we can work byte-by-byte because UTF-8 multibyte characters
+       // don't use any low ASCII byte values.
+       b := make([]byte, len(s));
+       for i := 0; i < len(s); i++ {
+               c := s[i];
+               if 'a' <= c && c <= 'z' {
+                       c -= 'a' - 'A';
+               }
+               b[i] = c;
+       }
+       return string(b);
+}
+
+// Upper returns a copy of the string s, with all low ASCII lowercase letters
+// converted to lowercase.
+// TODO: full Unicode support
+func LowerASCII(s string) string {
+       // Note, we can work byte-by-byte because UTF-8 multibyte characters
+       // don't use any low ASCII byte values.
+       b := make([]byte, len(s));
+       for i := 0; i < len(s); i++ {
+               c := s[i];
+               if 'A' <= c && c <= 'Z' {
+                       c += 'a' - 'A';
+               }
+               b[i] = c;
+       }
+       return string(b);
+}
+
+func isWhitespaceASCII(c byte) bool {
+       switch int(c) {
+       case ' ', '\t', '\r', '\n':
+               return true;
+       }
+       return false;
+}
+
+// Trim returns a slice of the string s, with all leading and trailing whitespace
+// removed.  "Whitespace" for now defined as space, tab, CR, or LF.
+// TODO: full Unicode whitespace support (need a unicode.IsWhitespace method)
+func TrimSpaceASCII(s string) string {
+       // Note, we can work byte-by-byte because UTF-8 multibyte characters
+       // don't use any low ASCII byte values.
+       start, end := 0, len(s);
+       for start < end && isWhitespaceASCII(s[start]) {
+               start++;
+       }
+       for start < end && isWhitespaceASCII(s[end-1]) {
+               end--;
+       }
+       return s[start:end];
+}
index 2cbf70b93bbbf54908453be127f128378842a450..05e66203212110fc6b4be10ff39afcd921db9bfd 100644 (file)
@@ -79,3 +79,55 @@ func TestSplit(t *testing.T) {
        }
 }
 
+// Test case for any function which accepts and returns a single string.
+type StringTest struct {
+       in, out string;
+}
+
+// Execute f on each test case.  funcName should be the name of f; it's used
+// in failure reports.
+func runStringTests(t *testing.T, f func(string) string, funcName string, testCases []StringTest) {
+       for i, tc := range testCases {
+               actual := f(tc.in);
+               if (actual != tc.out) {
+                       t.Errorf("%s(%q) = %q; want %q", funcName, tc.in, actual, tc.out);
+               }
+       }
+}
+
+var upperASCIITests = []StringTest {
+       StringTest{"", ""},
+       StringTest{"abc", "ABC"},
+       StringTest{"AbC123", "ABC123"},
+       StringTest{"azAZ09_", "AZAZ09_"}
+}
+
+var lowerASCIITests = []StringTest {
+       StringTest{"", ""},
+       StringTest{"abc", "abc"},
+       StringTest{"AbC123", "abc123"},
+       StringTest{"azAZ09_", "azaz09_"}
+}
+
+var trimSpaceASCIITests = []StringTest {
+       StringTest{"", ""},
+       StringTest{"abc", "abc"},
+       StringTest{" ", ""},
+       StringTest{" \t\r\n \t\t\r\r\n\n ", ""},
+       StringTest{" \t\r\n x\t\t\r\r\n\n ", "x"},
+       StringTest{" \t\r\n x\t\t\r\r\ny\n ", "x\t\t\r\r\ny"},
+       StringTest{"1 \t\r\n2", "1 \t\r\n2"},
+}
+
+func TestUpperASCII(t *testing.T) {
+       runStringTests(t, UpperASCII, "UpperASCII", upperASCIITests);
+}
+
+func TestLowerASCII(t *testing.T) {
+       runStringTests(t, LowerASCII, "LowerASCII", lowerASCIITests);
+}
+
+func TestTrimSpaceASCII(t *testing.T) {
+       runStringTests(t, TrimSpaceASCII, "TrimSpaceASCII", trimSpaceASCIITests);
+}
+