encode.go 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. package code128
  2. import (
  3. "fmt"
  4. "github.com/boombuler/barcode"
  5. "github.com/boombuler/barcode/utils"
  6. "strings"
  7. "unicode/utf8"
  8. )
  9. func strToRunes(str string) []rune {
  10. result := make([]rune, utf8.RuneCountInString(str))
  11. i := 0
  12. for _, r := range str {
  13. result[i] = r
  14. i++
  15. }
  16. return result
  17. }
  18. func shouldUseCTable(nextRunes []rune, curEncoding byte) bool {
  19. requiredDigits := 4
  20. if curEncoding == startCSymbol {
  21. requiredDigits = 2
  22. }
  23. if len(nextRunes) < requiredDigits {
  24. return false
  25. }
  26. for i := 0; i < requiredDigits; i++ {
  27. if nextRunes[i] < '0' || nextRunes[i] > '9' {
  28. return false
  29. }
  30. }
  31. return true
  32. }
  33. func getCodeIndexList(content []rune) *utils.BitList {
  34. result := new(utils.BitList)
  35. curEncoding := byte(0)
  36. for i := 0; i < len(content); i++ {
  37. if shouldUseCTable(content[i:], curEncoding) {
  38. if curEncoding != startCSymbol {
  39. result.AddByte(startCSymbol)
  40. curEncoding = startCSymbol
  41. }
  42. idx := (content[i] - '0') * 10
  43. i++
  44. idx = idx + (content[i] - '0')
  45. result.AddByte(byte(idx))
  46. } else {
  47. if curEncoding != startBSymbol {
  48. result.AddByte(startBSymbol)
  49. curEncoding = startBSymbol
  50. }
  51. idx := strings.IndexRune(bTable, content[i])
  52. if idx < 0 {
  53. return nil
  54. }
  55. result.AddByte(byte(idx))
  56. }
  57. }
  58. fmt.Println(result.GetBytes())
  59. return result
  60. }
  61. func Encode(content string) (barcode.Barcode, error) {
  62. contentRunes := strToRunes(content)
  63. if len(contentRunes) < 0 || len(contentRunes) > 80 {
  64. return nil, fmt.Errorf("content length should be between 1 and 80 runes but got %d", len(contentRunes))
  65. }
  66. idxList := getCodeIndexList(contentRunes)
  67. if idxList == nil {
  68. return nil, fmt.Errorf("\"%s\" could not be encoded", content)
  69. }
  70. result := new(utils.BitList)
  71. sum := 0
  72. for i, idx := range idxList.GetBytes() {
  73. if i == 0 {
  74. sum = int(idx)
  75. } else {
  76. sum += i * int(idx)
  77. }
  78. result.AddBit(encodingTable[idx]...)
  79. }
  80. result.AddBit(encodingTable[sum%103]...)
  81. result.AddBit(encodingTable[stopSymbol]...)
  82. return utils.New1DCode("Code 128", content, result), nil
  83. }