updated QR encoding type

This commit is contained in:
Florian Sundermann 2013-12-11 15:22:46 +01:00
parent bac8bce775
commit f08ed42d89
8 changed files with 57 additions and 64 deletions

View File

@ -6,11 +6,6 @@ import (
"github.com/boombuler/barcode" "github.com/boombuler/barcode"
) )
type alphaNumericEncoding struct {
}
var AlphaNumeric Encoding = alphaNumericEncoding{}
var alphaNumericTable map[byte]int = map[byte]int{ var alphaNumericTable map[byte]int = map[byte]int{
'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, '0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9,
'A': 10, 'B': 11, 'C': 12, 'D': 13, 'E': 14, 'F': 15, 'G': 16, 'H': 17, 'I': 18, 'J': 19, 'A': 10, 'B': 11, 'C': 12, 'D': 13, 'E': 14, 'F': 15, 'G': 16, 'H': 17, 'I': 18, 'J': 19,
@ -19,11 +14,7 @@ var alphaNumericTable map[byte]int = map[byte]int{
'+': 40, '-': 41, '.': 42, '/': 43, ':': 44, '+': 40, '-': 41, '.': 42, '/': 43, ':': 44,
} }
func (ane alphaNumericEncoding) String() string { func encodeAlphaNumeric(content string, ecl ErrorCorrectionLevel) (*barcode.BitList, *versionInfo, error) {
return "AlphaNumeric"
}
func (ane alphaNumericEncoding) encode(content string, ecl ErrorCorrectionLevel) (*barcode.BitList, *versionInfo, error) {
contentLenIsOdd := len(content)%2 == 1 contentLenIsOdd := len(content)%2 == 1
contentBitCount := (len(content) / 2) * 11 contentBitCount := (len(content) / 2) * 11
@ -43,14 +34,14 @@ func (ane alphaNumericEncoding) encode(content string, ecl ErrorCorrectionLevel)
c1, ok1 := alphaNumericTable[content[idx*2]] c1, ok1 := alphaNumericTable[content[idx*2]]
c2, ok2 := alphaNumericTable[content[(idx*2)+1]] c2, ok2 := alphaNumericTable[content[(idx*2)+1]]
if !ok1 || !ok2 { if !ok1 || !ok2 {
return nil, nil, fmt.Errorf("\"%s\" can not be encoded as %s", content, ane) return nil, nil, fmt.Errorf("\"%s\" can not be encoded as %s", content, AlphaNumeric)
} }
res.AddBits(c1*45+c2, 11) res.AddBits(c1*45+c2, 11)
} }
if contentLenIsOdd { if contentLenIsOdd {
c1, ok := alphaNumericTable[content[len(content)-1]] c1, ok := alphaNumericTable[content[len(content)-1]]
if !ok { if !ok {
return nil, nil, fmt.Errorf("\"%s\" can not be encoded as %s", content, ane) return nil, nil, fmt.Errorf("\"%s\" can not be encoded as %s", content, AlphaNumeric)
} }
res.AddBits(c1, 6) res.AddBits(c1, 6)
} }

View File

@ -16,25 +16,27 @@ func makeString(length int) string {
} }
func Test_AlphaNumericEncoding(t *testing.T) { func Test_AlphaNumericEncoding(t *testing.T) {
x, vi, err := AlphaNumeric.encode("HELLO WORLD", M) encode := AlphaNumeric.getEncoder()
x, vi, err := encode("HELLO WORLD", M)
if x == nil || vi == nil || vi.Version != 1 || bytes.Compare(x.GetBytes(), []byte{32, 91, 11, 120, 209, 114, 220, 77, 67, 64, 236, 17, 236, 17, 236, 17}) != 0 { if x == nil || vi == nil || vi.Version != 1 || bytes.Compare(x.GetBytes(), []byte{32, 91, 11, 120, 209, 114, 220, 77, 67, 64, 236, 17, 236, 17, 236, 17}) != 0 {
t.Errorf("\"HELLO WORLD\" failed to encode: %s", err) t.Errorf("\"HELLO WORLD\" failed to encode: %s", err)
} }
x, vi, err = AlphaNumeric.encode(makeString(4296), L) x, vi, err = encode(makeString(4296), L)
if x == nil || vi == nil || err != nil { if x == nil || vi == nil || err != nil {
t.Fail() t.Fail()
} }
x, vi, err = AlphaNumeric.encode(makeString(4297), L) x, vi, err = encode(makeString(4297), L)
if x != nil || vi != nil || err == nil { if x != nil || vi != nil || err == nil {
t.Fail() t.Fail()
} }
x, vi, err = AlphaNumeric.encode("ABc", L) x, vi, err = encode("ABc", L)
if x != nil || vi != nil || err == nil { if x != nil || vi != nil || err == nil {
t.Fail() t.Fail()
} }
x, vi, err = AlphaNumeric.encode("hello world", M) x, vi, err = encode("hello world", M)
if x != nil || vi != nil || err == nil { if x != nil || vi != nil || err == nil {
t.Error("\"hello world\" should not be encodable in alphanumeric mode") t.Error("\"hello world\" should not be encodable in alphanumeric mode")

View File

@ -5,22 +5,12 @@ import (
"github.com/boombuler/barcode" "github.com/boombuler/barcode"
) )
type autoEncoding struct { func encodeAuto(content string, ecl ErrorCorrectionLevel) (*barcode.BitList, *versionInfo, error) {
} bits, vi, _ := Numeric.getEncoder()(content, ecl)
// choose the best matching encoding
var Auto Encoding = autoEncoding{}
func (ne autoEncoding) String() string {
return "Auto"
}
func (ne autoEncoding) encode(content string, ecl ErrorCorrectionLevel) (*barcode.BitList, *versionInfo, error) {
bits, vi, _ := Numeric.encode(content, ecl)
if bits != nil && vi != nil { if bits != nil && vi != nil {
return bits, vi, nil return bits, vi, nil
} }
bits, vi, _ = AlphaNumeric.encode(content, ecl) bits, vi, _ = AlphaNumeric.getEncoder()(content, ecl)
if bits != nil && vi != nil { if bits != nil && vi != nil {
return bits, vi, nil return bits, vi, nil
} }

View File

@ -6,16 +6,16 @@ import (
) )
func Test_AutomaticEncoding(t *testing.T) { func Test_AutomaticEncoding(t *testing.T) {
tests := map[string]Encoding{ tests := map[string]encodeFn{
"0123456789": Numeric, "0123456789": Numeric.getEncoder(),
"ALPHA NUMERIC": AlphaNumeric, "ALPHA NUMERIC": AlphaNumeric.getEncoder(),
"no matching encoing": nil, "no matching encoing": nil,
} }
for str, enc := range tests { for str, enc := range tests {
testValue, _, _ := Auto.encode(str, M) testValue, _, _ := Auto.getEncoder()(str, M)
if enc != nil { if enc != nil {
correctValue, _, _ := enc.encode(str, M) correctValue, _, _ := enc(str, M)
if testValue == nil || bytes.Compare(correctValue.GetBytes(), testValue.GetBytes()) != 0 { if testValue == nil || bytes.Compare(correctValue.GetBytes(), testValue.GetBytes()) != 0 {
t.Errorf("wrong encoding used for '%s'", str) t.Errorf("wrong encoding used for '%s'", str)
} }

View File

@ -6,13 +6,42 @@ import (
"image" "image"
) )
type Encoding interface { type encodeFn func(content string, eccLevel ErrorCorrectionLevel) (*barcode.BitList, *versionInfo, error)
fmt.Stringer
encode(content string, eccLevel ErrorCorrectionLevel) (*barcode.BitList, *versionInfo, error) type Encoding byte
const (
Auto Encoding = iota
Numeric
AlphaNumeric
)
func (e Encoding) getEncoder() encodeFn {
switch e {
case Auto:
return encodeAuto
case Numeric:
return encodeNumeric
case AlphaNumeric:
return encodeAlphaNumeric
}
return nil
}
func (e Encoding) String() string {
switch e {
case Auto:
return "Auto"
case Numeric:
return "Numeric"
case AlphaNumeric:
return "AlphaNumeric"
}
return ""
} }
func Encode(content string, eccLevel ErrorCorrectionLevel, mode Encoding) (barcode.Barcode, error) { func Encode(content string, eccLevel ErrorCorrectionLevel, mode Encoding) (barcode.Barcode, error) {
bits, vi, err := mode.encode(content, eccLevel) bits, vi, err := mode.getEncoder()(content, eccLevel)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -1,11 +0,0 @@
package qr
import "testing"
import "image/png"
import "github.com/boombuler/barcode"
import "os"
func Test_EncodeQR(t *testing.T) {
}

View File

@ -7,16 +7,7 @@ import (
"strconv" "strconv"
) )
type numericEncoding struct { func encodeNumeric(content string, ecl ErrorCorrectionLevel) (*barcode.BitList, *versionInfo, error) {
}
var Numeric Encoding = numericEncoding{}
func (ne numericEncoding) String() string {
return "Numeric"
}
func (ne numericEncoding) encode(content string, ecl ErrorCorrectionLevel) (*barcode.BitList, *versionInfo, error) {
contentBitCount := (len(content) / 3) * 10 contentBitCount := (len(content) / 3) * 10
switch len(content) % 3 { switch len(content) % 3 {
case 1: case 1:
@ -44,7 +35,7 @@ func (ne numericEncoding) encode(content string, ecl ErrorCorrectionLevel) (*bar
i, err := strconv.Atoi(curStr) i, err := strconv.Atoi(curStr)
if err != nil || i < 0 { if err != nil || i < 0 {
return nil, nil, fmt.Errorf("\"%s\" can not be encoded as %s", content, ne) return nil, nil, fmt.Errorf("\"%s\" can not be encoded as %s", content, Numeric)
} }
var bitCnt byte var bitCnt byte
switch len(curStr) % 3 { switch len(curStr) % 3 {

View File

@ -6,15 +6,16 @@ import (
) )
func Test_NumericEncoding(t *testing.T) { func Test_NumericEncoding(t *testing.T) {
x, vi, err := Numeric.encode("01234567", H) encode := Numeric.getEncoder()
x, vi, err := encode("01234567", H)
if x == nil || vi == nil || vi.Version != 1 || bytes.Compare(x.GetBytes(), []byte{16, 32, 12, 86, 97, 128, 236, 17, 236}) != 0 { if x == nil || vi == nil || vi.Version != 1 || bytes.Compare(x.GetBytes(), []byte{16, 32, 12, 86, 97, 128, 236, 17, 236}) != 0 {
t.Error("\"01234567\" failed to encode") t.Error("\"01234567\" failed to encode")
} }
x, vi, err = Numeric.encode("0123456789012345", H) x, vi, err = encode("0123456789012345", H)
if x == nil || vi == nil || vi.Version != 1 || bytes.Compare(x.GetBytes(), []byte{16, 64, 12, 86, 106, 110, 20, 234, 80}) != 0 { if x == nil || vi == nil || vi.Version != 1 || bytes.Compare(x.GetBytes(), []byte{16, 64, 12, 86, 106, 110, 20, 234, 80}) != 0 {
t.Error("\"0123456789012345\" failed to encode") t.Error("\"0123456789012345\" failed to encode")
} }
x, vi, err = Numeric.encode("foo", H) x, vi, err = encode("foo", H)
if err == nil { if err == nil {
t.Error("Numeric encoding should not be able to encode \"foo\"") t.Error("Numeric encoding should not be able to encode \"foo\"")
} }