From b066487b3e566ed86a85e6dc11f99e8cd141ae80 Mon Sep 17 00:00:00 2001 From: Florian Sundermann Date: Thu, 26 Jan 2017 08:20:38 +0100 Subject: [PATCH] moved checksum function to its own interface its not needed that all barcodes have an integer checksum so it should not be needed in every implementation. --- aztec/azteccode.go | 4 ---- barcode.go | 6 ++++++ codabar/encoder.go | 2 +- code128/encode.go | 7 ++++--- code39/encoder.go | 4 ++-- datamatrix/datamatrixcode.go | 4 ---- ean/encoder.go | 6 +++--- qr/qrcode.go | 4 ---- scaledbarcode.go | 33 ++++++++++++++++++++++++++------- twooffive/encoder.go | 2 +- utils/base1dcode.go | 19 ++++++++++++++----- 11 files changed, 57 insertions(+), 34 deletions(-) diff --git a/aztec/azteccode.go b/aztec/azteccode.go index 5a15975..fb50420 100644 --- a/aztec/azteccode.go +++ b/aztec/azteccode.go @@ -42,10 +42,6 @@ func (c *aztecCode) At(x, y int) color.Color { return color.White } -func (c *aztecCode) CheckSum() int { - return 0 -} - func (c *aztecCode) set(x, y int) { c.SetBit(x*c.size+y, true) } diff --git a/barcode.go b/barcode.go index 7e147f2..3479c7b 100644 --- a/barcode.go +++ b/barcode.go @@ -17,5 +17,11 @@ type Barcode interface { Metadata() Metadata // the data that was encoded in this barcode Content() string +} + +// Additional interface that some barcodes might implement to provide +// the value of its checksum. +type BarcodeIntCS interface { + Barcode CheckSum() int } diff --git a/codabar/encoder.go b/codabar/encoder.go index 69cf1a9..dce0ac4 100644 --- a/codabar/encoder.go +++ b/codabar/encoder.go @@ -45,5 +45,5 @@ func Encode(content string) (barcode.Barcode, error) { } resBits.AddBit(encodingTable[r]...) } - return utils.New1DCode("Codabar", content, resBits, 0), nil + return utils.New1DCode("Codabar", content, resBits), nil } diff --git a/code128/encode.go b/code128/encode.go index 757347e..e1dbae1 100644 --- a/code128/encode.go +++ b/code128/encode.go @@ -103,7 +103,7 @@ func getCodeIndexList(content []rune) *utils.BitList { } // Encode creates a Code 128 barcode for the given content -func Encode(content string) (barcode.Barcode, error) { +func Encode(content string) (barcode.BarcodeIntCS, error) { contentRunes := strToRunes(content) if len(contentRunes) <= 0 || len(contentRunes) > 80 { return nil, fmt.Errorf("content length should be between 1 and 80 runes but got %d", len(contentRunes)) @@ -124,7 +124,8 @@ func Encode(content string) (barcode.Barcode, error) { } result.AddBit(encodingTable[idx]...) } - result.AddBit(encodingTable[sum%103]...) + sum = sum % 103 + result.AddBit(encodingTable[sum]...) result.AddBit(encodingTable[stopSymbol]...) - return utils.New1DCode("Code 128", content, result, sum%103), nil + return utils.New1DCodeIntCheckSum("Code 128", content, result, sum), nil } diff --git a/code39/encoder.go b/code39/encoder.go index 669450f..5919133 100644 --- a/code39/encoder.go +++ b/code39/encoder.go @@ -113,7 +113,7 @@ func prepare(content string) (string, error) { // Encode returns a code39 barcode for the given content // if includeChecksum is set to true, a checksum character is calculated and added to the content -func Encode(content string, includeChecksum bool, fullASCIIMode bool) (barcode.Barcode, error) { +func Encode(content string, includeChecksum bool, fullASCIIMode bool) (barcode.BarcodeIntCS, error) { if fullASCIIMode { var err error content, err = prepare(content) @@ -148,5 +148,5 @@ func Encode(content string, includeChecksum bool, fullASCIIMode bool) (barcode.B if err != nil { checkSum = 0 } - return utils.New1DCode("Code 39", content, result, int(checkSum)), nil + return utils.New1DCodeIntCheckSum("Code 39", content, result, int(checkSum)), nil } diff --git a/datamatrix/datamatrixcode.go b/datamatrix/datamatrixcode.go index 0e60269..ece74b8 100644 --- a/datamatrix/datamatrixcode.go +++ b/datamatrix/datamatrixcode.go @@ -40,10 +40,6 @@ func (c *datamatrixCode) At(x, y int) color.Color { return color.White } -func (c *datamatrixCode) CheckSum() int { - return 0 -} - func (c *datamatrixCode) get(x, y int) bool { return c.GetBit(x*c.Rows + y) } diff --git a/ean/encoder.go b/ean/encoder.go index d89294f..212c9e1 100644 --- a/ean/encoder.go +++ b/ean/encoder.go @@ -158,7 +158,7 @@ func encodeEAN13(code string) *utils.BitList { } // Encode returns a EAN 8 or EAN 13 barcode for the given code -func Encode(code string) (barcode.Barcode, error) { +func Encode(code string) (barcode.BarcodeIntCS, error) { var checkSum int if len(code) == 7 || len(code) == 12 { code += string(calcCheckNum(code)) @@ -175,12 +175,12 @@ func Encode(code string) (barcode.Barcode, error) { if len(code) == 8 { result := encodeEAN8(code) if result != nil { - return utils.New1DCode("EAN 8", code, result, checkSum), nil + return utils.New1DCodeIntCheckSum("EAN 8", code, result, checkSum), nil } } else if len(code) == 13 { result := encodeEAN13(code) if result != nil { - return utils.New1DCode("EAN 13", code, result, checkSum), nil + return utils.New1DCodeIntCheckSum("EAN 13", code, result, checkSum), nil } } return nil, errors.New("invalid ean code data") diff --git a/qr/qrcode.go b/qr/qrcode.go index ab123ce..b7ac26d 100644 --- a/qr/qrcode.go +++ b/qr/qrcode.go @@ -46,10 +46,6 @@ func (qr *qrcode) Set(x, y int, val bool) { qr.data.SetBit(x*qr.dimension+y, val) } -func (qr *qrcode) CheckSum() int { - return 0 -} - func (qr *qrcode) calcPenalty() uint { return qr.calcPenaltyRule1() + qr.calcPenaltyRule2() + qr.calcPenaltyRule3() + qr.calcPenaltyRule4() } diff --git a/scaledbarcode.go b/scaledbarcode.go index c59c9fe..7e29f3b 100644 --- a/scaledbarcode.go +++ b/scaledbarcode.go @@ -16,6 +16,10 @@ type scaledBarcode struct { rect image.Rectangle } +type intCSscaledBC struct { + scaledBarcode +} + func (bc *scaledBarcode) Content() string { return bc.wrapped.Content() } @@ -36,8 +40,11 @@ func (bc *scaledBarcode) At(x, y int) color.Color { return bc.wrapperFunc(x, y) } -func (bc *scaledBarcode) CheckSum() int { - return bc.wrapped.CheckSum() +func (bc *intCSscaledBC) CheckSum() int { + if cs, ok := bc.wrapped.(BarcodeIntCS); ok { + return cs.CheckSum() + } + return 0 } // Scale returns a resized barcode with the given width and height. @@ -52,6 +59,19 @@ func Scale(bc Barcode, width, height int) (Barcode, error) { return nil, errors.New("unsupported barcode format") } +func newScaledBC(wrapped Barcode, wrapperFunc wrapFunc, rect image.Rectangle) Barcode { + result := &scaledBarcode{ + wrapped: wrapped, + wrapperFunc: wrapperFunc, + rect: rect, + } + + if _, ok := wrapped.(BarcodeIntCS); ok { + return &intCSscaledBC{*result} + } + return result +} + func scale2DCode(bc Barcode, width, height int) (Barcode, error) { orgBounds := bc.Bounds() orgWidth := orgBounds.Max.X - orgBounds.Min.X @@ -77,11 +97,11 @@ func scale2DCode(bc Barcode, width, height int) (Barcode, error) { return bc.At(x, y) } - return &scaledBarcode{ + return newScaledBC( bc, wrap, image.Rect(0, 0, width, height), - }, nil + ), nil } func scale1DCode(bc Barcode, width, height int) (Barcode, error) { @@ -106,10 +126,9 @@ func scale1DCode(bc Barcode, width, height int) (Barcode, error) { return bc.At(x, 0) } - return &scaledBarcode{ + return newScaledBC( bc, wrap, image.Rect(0, 0, width, height), - }, nil - + ), nil } diff --git a/twooffive/encoder.go b/twooffive/encoder.go index de3ae97..ea16299 100644 --- a/twooffive/encoder.go +++ b/twooffive/encoder.go @@ -134,5 +134,5 @@ func Encode(content string, interleaved bool) (barcode.Barcode, error) { if interleaved { kindTxt = " (interleaved)" } - return utils.New1DCode("2 of 5"+kindTxt, content, resBits, -1), nil + return utils.New1DCode("2 of 5"+kindTxt, content, resBits), nil } diff --git a/utils/base1dcode.go b/utils/base1dcode.go index 22a2e30..75e5004 100644 --- a/utils/base1dcode.go +++ b/utils/base1dcode.go @@ -10,8 +10,12 @@ import ( type base1DCode struct { *BitList - kind string - content string + kind string + content string +} + +type base1DCodeIntCS struct { + base1DCode checksum int } @@ -38,11 +42,16 @@ func (c *base1DCode) At(x, y int) color.Color { return color.White } -func (c *base1DCode) CheckSum() int { +func (c *base1DCodeIntCS) CheckSum() int { return c.checksum } // New1DCode creates a new 1D barcode where the bars are represented by the bits in the bars BitList -func New1DCode(codeKind, content string, bars *BitList, checksum int) barcode.Barcode { - return &base1DCode{bars, codeKind, content, checksum} +func New1DCodeIntCheckSum(codeKind, content string, bars *BitList, checksum int) barcode.BarcodeIntCS { + return &base1DCodeIntCS{base1DCode{bars, codeKind, content}, checksum} +} + +// New1DCode creates a new 1D barcode where the bars are represented by the bits in the bars BitList +func New1DCode(codeKind, content string, bars *BitList) barcode.Barcode { + return &base1DCode{bars, codeKind, content} }