The Go Programming Language

Source file doc/progs/cat_rot13.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	package main
     6	
     7	import (
     8		"./file"
     9		"flag"
    10		"fmt"
    11		"os"
    12	)
    13	
    14	var rot13Flag = flag.Bool("rot13", false, "rot13 the input")
    15	
    16	func rot13(b byte) byte {
    17		if 'a' <= b && b <= 'z' {
    18			b = 'a' + ((b-'a')+13)%26
    19		}
    20		if 'A' <= b && b <= 'Z' {
    21			b = 'A' + ((b-'A')+13)%26
    22		}
    23		return b
    24	}
    25	
    26	type reader interface {
    27		Read(b []byte) (ret int, err os.Error)
    28		String() string
    29	}
    30	
    31	type rotate13 struct {
    32		source reader
    33	}
    34	
    35	func newRotate13(source reader) *rotate13 {
    36		return &rotate13{source}
    37	}
    38	
    39	func (r13 *rotate13) Read(b []byte) (ret int, err os.Error) {
    40		r, e := r13.source.Read(b)
    41		for i := 0; i < r; i++ {
    42			b[i] = rot13(b[i])
    43		}
    44		return r, e
    45	}
    46	
    47	func (r13 *rotate13) String() string {
    48		return r13.source.String()
    49	}
    50	// end of rotate13 implementation
    51	
    52	func cat(r reader) {
    53		const NBUF = 512
    54		var buf [NBUF]byte
    55	
    56		if *rot13Flag {
    57			r = newRotate13(r)
    58		}
    59		for {
    60			switch nr, er := r.Read(buf[:]); {
    61			case nr < 0:
    62				fmt.Fprintf(os.Stderr, "cat: error reading from %s: %s\n", r.String(), er.String())
    63				os.Exit(1)
    64			case nr == 0: // EOF
    65				return
    66			case nr > 0:
    67				nw, ew := file.Stdout.Write(buf[0:nr])
    68				if nw != nr {
    69					fmt.Fprintf(os.Stderr, "cat: error writing from %s: %s\n", r.String(), ew.String())
    70					os.Exit(1)
    71				}
    72			}
    73		}
    74	}
    75	
    76	func main() {
    77		flag.Parse() // Scans the arg list and sets up flags
    78		if flag.NArg() == 0 {
    79			cat(file.Stdin)
    80		}
    81		for i := 0; i < flag.NArg(); i++ {
    82			f, err := file.Open(flag.Arg(i))
    83			if f == nil {
    84				fmt.Fprintf(os.Stderr, "cat: can't open %s: error %s\n", flag.Arg(i), err)
    85				os.Exit(1)
    86			}
    87			cat(f)
    88			f.Close()
    89		}
    90	}

release.r60.3. Except as noted, this content is licensed under a Creative Commons Attribution 3.0 License.