You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

135 lines
2.3 KiB

6 years ago
10 years ago
10 years ago
10 years ago
  1. package needle
  2. import (
  3. "strconv"
  4. )
  5. const (
  6. //stored unit types
  7. Empty byte = iota
  8. Minute
  9. Hour
  10. Day
  11. Week
  12. Month
  13. Year
  14. )
  15. type TTL struct {
  16. Count byte
  17. Unit byte
  18. }
  19. var EMPTY_TTL = &TTL{}
  20. // translate a readable ttl to internal ttl
  21. // Supports format example:
  22. // 3m: 3 minutes
  23. // 4h: 4 hours
  24. // 5d: 5 days
  25. // 6w: 6 weeks
  26. // 7M: 7 months
  27. // 8y: 8 years
  28. func ReadTTL(ttlString string) (*TTL, error) {
  29. if ttlString == "" {
  30. return EMPTY_TTL, nil
  31. }
  32. ttlBytes := []byte(ttlString)
  33. unitByte := ttlBytes[len(ttlBytes)-1]
  34. countBytes := ttlBytes[0 : len(ttlBytes)-1]
  35. if '0' <= unitByte && unitByte <= '9' {
  36. countBytes = ttlBytes
  37. unitByte = 'm'
  38. }
  39. count, err := strconv.Atoi(string(countBytes))
  40. unit := toStoredByte(unitByte)
  41. return &TTL{Count: byte(count), Unit: unit}, err
  42. }
  43. // read stored bytes to a ttl
  44. func LoadTTLFromBytes(input []byte) (t *TTL) {
  45. return &TTL{Count: input[0], Unit: input[1]}
  46. }
  47. // read stored bytes to a ttl
  48. func LoadTTLFromUint32(ttl uint32) (t *TTL) {
  49. input := make([]byte, 2)
  50. input[1] = byte(ttl)
  51. input[0] = byte(ttl >> 8)
  52. return LoadTTLFromBytes(input)
  53. }
  54. // save stored bytes to an output with 2 bytes
  55. func (t *TTL) ToBytes(output []byte) {
  56. output[0] = t.Count
  57. output[1] = t.Unit
  58. }
  59. func (t *TTL) ToUint32() (output uint32) {
  60. output = uint32(t.Count) << 8
  61. output += uint32(t.Unit)
  62. return output
  63. }
  64. func (t *TTL) String() string {
  65. if t == nil || t.Count == 0 {
  66. return ""
  67. }
  68. if t.Unit == Empty {
  69. return ""
  70. }
  71. countString := strconv.Itoa(int(t.Count))
  72. switch t.Unit {
  73. case Minute:
  74. return countString + "m"
  75. case Hour:
  76. return countString + "h"
  77. case Day:
  78. return countString + "d"
  79. case Week:
  80. return countString + "w"
  81. case Month:
  82. return countString + "M"
  83. case Year:
  84. return countString + "y"
  85. }
  86. return ""
  87. }
  88. func toStoredByte(readableUnitByte byte) byte {
  89. switch readableUnitByte {
  90. case 'm':
  91. return Minute
  92. case 'h':
  93. return Hour
  94. case 'd':
  95. return Day
  96. case 'w':
  97. return Week
  98. case 'M':
  99. return Month
  100. case 'y':
  101. return Year
  102. }
  103. return 0
  104. }
  105. func (t TTL) Minutes() uint32 {
  106. switch t.Unit {
  107. case Empty:
  108. return 0
  109. case Minute:
  110. return uint32(t.Count)
  111. case Hour:
  112. return uint32(t.Count) * 60
  113. case Day:
  114. return uint32(t.Count) * 60 * 24
  115. case Week:
  116. return uint32(t.Count) * 60 * 24 * 7
  117. case Month:
  118. return uint32(t.Count) * 60 * 24 * 31
  119. case Year:
  120. return uint32(t.Count) * 60 * 24 * 365
  121. }
  122. return 0
  123. }