Browse Source

Fix for Go weekly.2012-01-15.

Dmitry Chestnykh 14 years ago
parent
commit
90a7bd4b43
8 changed files with 32 additions and 37 deletions
  1. 5 5
      audio.go
  2. 4 4
      captcha.go
  3. 4 4
      example/main.go
  4. 2 3
      image.go
  5. 2 5
      image_test.go
  6. 3 3
      random.go
  7. 3 4
      server.go
  8. 9 9
      store.go

+ 5 - 5
audio.go

@@ -7,10 +7,10 @@ package captcha
 import (
 	"bytes"
 	"encoding/binary"
-	"math"
-	"os"
-	"rand"
 	"io"
+
+	"math"
+	"math/rand"
 )
 
 const sampleRate = 8000 // Hz
@@ -24,7 +24,7 @@ func init() {
 }
 
 type Audio struct {
-	body *bytes.Buffer
+	body        *bytes.Buffer
 	digitSounds [][]byte
 }
 
@@ -79,7 +79,7 @@ func NewAudio(digits []byte, lang string) *Audio {
 
 // WriteTo writes captcha audio in WAVE format into the given io.Writer, and
 // returns the number of bytes written and an error if any.
-func (a *Audio) WriteTo(w io.Writer) (n int64, err os.Error) {
+func (a *Audio) WriteTo(w io.Writer) (n int64, err error) {
 	// Calculate padded length of PCM chunk data.
 	bodyLen := uint32(a.body.Len())
 	paddedBodyLen := bodyLen

+ 4 - 4
captcha.go

@@ -47,8 +47,8 @@ package captcha
 
 import (
 	"bytes"
+	"errors"
 	"io"
-	"os"
 )
 
 const (
@@ -62,7 +62,7 @@ const (
 )
 
 var (
-	ErrNotFound = os.NewError("captcha: id not found")
+	ErrNotFound = errors.New("captcha: id not found")
 	// globalStore is a shared storage for captchas, generated by New function.
 	globalStore = NewMemoryStore(CollectNum, Expiration)
 )
@@ -104,7 +104,7 @@ func Reload(id string) bool {
 
 // WriteImage writes PNG-encoded image representation of the captcha with the
 // given id. The image will have the given width and height.
-func WriteImage(w io.Writer, id string, width, height int) os.Error {
+func WriteImage(w io.Writer, id string, width, height int) error {
 	d := globalStore.Get(id, false)
 	if d == nil {
 		return ErrNotFound
@@ -116,7 +116,7 @@ func WriteImage(w io.Writer, id string, width, height int) os.Error {
 // WriteAudio writes WAV-encoded audio representation of the captcha with the
 // given id and the given language. If there are no sounds for the given
 // language, English is used.
-func WriteAudio(w io.Writer, id string, lang string) os.Error {
+func WriteAudio(w io.Writer, id string, lang string) error {
 	d := globalStore.Get(id, false)
 	if d == nil {
 		return ErrNotFound

+ 4 - 4
example/main.go

@@ -8,10 +8,10 @@ package main
 import (
 	"fmt"
 	"github.com/dchest/captcha"
-	"http"
 	"io"
 	"log"
-	"template"
+	"net/http"
+	"text/template"
 )
 
 var formTemplate = template.Must(template.New("example").Parse(formTemplateSrc))
@@ -22,12 +22,12 @@ func showFormHandler(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 	d := struct {
-		CaptchaId  string
+		CaptchaId string
 	}{
 		captcha.New(),
 	}
 	if err := formTemplate.Execute(w, &d); err != nil {
-		http.Error(w, err.String(), http.StatusInternalServerError)
+		http.Error(w, err.Error(), http.StatusInternalServerError)
 	}
 }
 

+ 2 - 3
image.go

@@ -10,8 +10,7 @@ import (
 	"image/png"
 	"io"
 	"math"
-	"os"
-	"rand"
+	"math/rand"
 )
 
 const (
@@ -86,7 +85,7 @@ func NewImage(digits []byte, width, height int) *Image {
 // doesn't report this.
 
 // WriteTo writes captcha image in PNG format into the given writer.
-func (m *Image) WriteTo(w io.Writer) (int64, os.Error) {
+func (m *Image) WriteTo(w io.Writer) (int64, error) {
 	return 0, png.Encode(w, m.Paletted)
 }
 

+ 2 - 5
image_test.go

@@ -4,16 +4,13 @@
 
 package captcha
 
-import (
-	"os"
-	"testing"
-)
+import "testing"
 
 type byteCounter struct {
 	n int64
 }
 
-func (bc *byteCounter) Write(b []byte) (int, os.Error) {
+func (bc *byteCounter) Write(b []byte) (int, error) {
 	bc.n += int64(len(b))
 	return len(b), nil
 }

+ 3 - 3
random.go

@@ -7,7 +7,7 @@ package captcha
 import (
 	crand "crypto/rand"
 	"io"
-	"rand"
+	"math/rand"
 	"time"
 )
 
@@ -18,7 +18,7 @@ const idLen = 20
 var idChars = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
 
 func init() {
-	rand.Seed(time.Nanoseconds())
+	rand.Seed(time.Now().UnixNano())
 }
 
 // RandomDigits returns a byte slice of the given length containing
@@ -32,7 +32,7 @@ func RandomDigits(length int) []byte {
 func randomBytes(length int) (b []byte) {
 	b = make([]byte, length)
 	if _, err := io.ReadFull(crand.Reader, b); err != nil {
-		panic("captcha: error reading random source: " + err.String())
+		panic("captcha: error reading random source: " + err.Error())
 	}
 	return
 }

+ 3 - 4
server.go

@@ -5,8 +5,7 @@
 package captcha
 
 import (
-	"http"
-	"os"
+	"net/http"
 	"path"
 	"strconv"
 	"strings"
@@ -39,11 +38,11 @@ type captchaHandler struct {
 // By default, the Server serves audio in English language. To serve audio
 // captcha in one of the other supported languages, append "lang" value, for
 // example, "?lang=ru".
-func Server(imgWidth, imgHeight int) http.Handler { 
+func Server(imgWidth, imgHeight int) http.Handler {
 	return &captchaHandler{imgWidth, imgHeight}
 }
 
-func (h *captchaHandler) serve(w http.ResponseWriter, id, ext string, lang string, download bool) os.Error {
+func (h *captchaHandler) serve(w http.ResponseWriter, id, ext string, lang string, download bool) error {
 	if download {
 		w.Header().Set("Content-Type", "application/octet-stream")
 	}

+ 9 - 9
store.go

@@ -30,7 +30,7 @@ type Store interface {
 // memoryStore for indexing generated captchas by timestamp to enable garbage
 // collection of expired captchas.
 type idByTimeValue struct {
-	timestamp int64
+	timestamp time.Time
 	id        string
 }
 
@@ -44,13 +44,13 @@ type memoryStore struct {
 	// Number of saved items that triggers collection.
 	collectNum int
 	// Expiration time of captchas.
-	expiration int64
+	expiration time.Duration
 }
 
 // NewMemoryStore returns a new standard memory store for captchas with the
-// given collection threshold and expiration time in seconds. The returned
+// given collection threshold and expiration time (duration). The returned
 // store must be registered with SetCustomStore to replace the default one.
-func NewMemoryStore(collectNum int, expiration int64) Store {
+func NewMemoryStore(collectNum int, expiration time.Duration) Store {
 	s := new(memoryStore)
 	s.digitsById = make(map[string][]byte)
 	s.idByTime = list.New()
@@ -62,7 +62,7 @@ func NewMemoryStore(collectNum int, expiration int64) Store {
 func (s *memoryStore) Set(id string, digits []byte) {
 	s.mu.Lock()
 	s.digitsById[id] = digits
-	s.idByTime.PushBack(idByTimeValue{time.Seconds(), id})
+	s.idByTime.PushBack(idByTimeValue{time.Now(), id})
 	s.numStored++
 	if s.numStored <= s.collectNum {
 		s.mu.Unlock()
@@ -86,7 +86,7 @@ func (s *memoryStore) Get(id string, clear bool) (digits []byte) {
 		return
 	}
 	if clear {
-		s.digitsById[id] = nil, false
+		delete(s.digitsById, id)
 		// XXX(dchest) Index (s.idByTime) will be cleaned when
 		// collecting expired captchas.  Can't clean it here, because
 		// we don't store reference to expValue in the map.
@@ -96,7 +96,7 @@ func (s *memoryStore) Get(id string, clear bool) (digits []byte) {
 }
 
 func (s *memoryStore) collect() {
-	now := time.Seconds()
+	now := time.Now()
 	s.mu.Lock()
 	defer s.mu.Unlock()
 	s.numStored = 0
@@ -105,8 +105,8 @@ func (s *memoryStore) collect() {
 		if !ok {
 			return
 		}
-		if ev.timestamp+s.expiration < now {
-			s.digitsById[ev.id] = nil, false
+		if ev.timestamp.Add(s.expiration).Before(now) {
+			delete(s.digitsById, ev.id)
 			next := e.Next()
 			s.idByTime.Remove(e)
 			e = next