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.

141 lines
2.4 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. if input[0] == 0 && input[1] == 0 {
  46. return EMPTY_TTL
  47. }
  48. return &TTL{Count: input[0], Unit: input[1]}
  49. }
  50. // read stored bytes to a ttl
  51. func LoadTTLFromUint32(ttl uint32) (t *TTL) {
  52. input := make([]byte, 2)
  53. input[1] = byte(ttl)
  54. input[0] = byte(ttl >> 8)
  55. return LoadTTLFromBytes(input)
  56. }
  57. // save stored bytes to an output with 2 bytes
  58. func (t *TTL) ToBytes(output []byte) {
  59. output[0] = t.Count
  60. output[1] = t.Unit
  61. }
  62. func (t *TTL) ToUint32() (output uint32) {
  63. if t == nil || t.Count == 0 {
  64. return 0
  65. }
  66. output = uint32(t.Count) << 8
  67. output += uint32(t.Unit)
  68. return output
  69. }
  70. func (t *TTL) String() string {
  71. if t == nil || t.Count == 0 {
  72. return ""
  73. }
  74. if t.Unit == Empty {
  75. return ""
  76. }
  77. countString := strconv.Itoa(int(t.Count))
  78. switch t.Unit {
  79. case Minute:
  80. return countString + "m"
  81. case Hour:
  82. return countString + "h"
  83. case Day:
  84. return countString + "d"
  85. case Week:
  86. return countString + "w"
  87. case Month:
  88. return countString + "M"
  89. case Year:
  90. return countString + "y"
  91. }
  92. return ""
  93. }
  94. func toStoredByte(readableUnitByte byte) byte {
  95. switch readableUnitByte {
  96. case 'm':
  97. return Minute
  98. case 'h':
  99. return Hour
  100. case 'd':
  101. return Day
  102. case 'w':
  103. return Week
  104. case 'M':
  105. return Month
  106. case 'y':
  107. return Year
  108. }
  109. return 0
  110. }
  111. func (t TTL) Minutes() uint32 {
  112. switch t.Unit {
  113. case Empty:
  114. return 0
  115. case Minute:
  116. return uint32(t.Count)
  117. case Hour:
  118. return uint32(t.Count) * 60
  119. case Day:
  120. return uint32(t.Count) * 60 * 24
  121. case Week:
  122. return uint32(t.Count) * 60 * 24 * 7
  123. case Month:
  124. return uint32(t.Count) * 60 * 24 * 31
  125. case Year:
  126. return uint32(t.Count) * 60 * 24 * 365
  127. }
  128. return 0
  129. }