-
Notifications
You must be signed in to change notification settings - Fork 0
/
cycle_string.go
144 lines (117 loc) · 4.21 KB
/
cycle_string.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package cycle_string
import (
"encoding/json"
"strings"
)
// CycleString 循环字符串
type CycleString struct {
// 原始的字符串,就是对这个字符串进行周期重复
baseString string
// 原始字符串的字符表示形式,用于一些中文场景的处理
baseStringRuneSlice []rune
}
var _ json.Marshaler = &CycleString{}
var _ json.Unmarshaler = &CycleString{}
// NewCycleString 创建一个循环字符串
func NewCycleString(baseString string) *CycleString {
return &CycleString{
baseString: baseString,
baseStringRuneSlice: []rune(baseString),
}
}
// ------------------------------------------------- --------------------------------------------------------------------
// RealRuneLength 返回真实的字符长度
func (x *CycleString) RealRuneLength() int {
return len(x.baseStringRuneSlice)
}
// RealByteLength 返回真实的字节长度
func (x *CycleString) RealByteLength() int {
return len(x.baseString)
}
// ------------------------------------------------- --------------------------------------------------------------------
// At 返回给定位置的字节,同ByteAt
func (x *CycleString) At(index int) byte {
return x.ByteAt(index)
}
// ByteAt 获取给定下标的字节,会按照字节长度获取
func (x *CycleString) ByteAt(index int) byte {
if index < 0 {
panic("Out of Index")
}
targetIndex := index % len(x.baseString)
return x.baseString[targetIndex]
}
// RuneAt 获取给定下标的字符,会按照字符长度计算下标
func (x *CycleString) RuneAt(index int) rune {
if index < 0 {
panic("Out of Index")
}
targetIndex := index % len(x.baseStringRuneSlice)
return x.baseStringRuneSlice[targetIndex]
}
// CharAt 返回给定位置的字符,同RuneAt
func (x *CycleString) CharAt(index int) rune {
return x.RuneAt(index)
}
// ------------------------------------------------- --------------------------------------------------------------------
// SubString 获取当前字符串的子字符串
func (x *CycleString) SubString(from, to int) string {
if to <= from || from < 0 || to <= 0 {
return ""
}
// TODO 更高效的实现
result := strings.Builder{}
for from < to {
result.WriteByte(x.ByteAt(from))
from++
}
return result.String()
}
// SubStringRune 字符形式的子串
func (x *CycleString) SubStringRune(from, to int) string {
if to <= from || from < 0 || to <= 0 {
return ""
}
// TODO 更高效的实现
result := strings.Builder{}
for from < to {
result.WriteRune(x.CharAt(from))
from++
}
return result.String()
}
// ------------------------------------------------- --------------------------------------------------------------------
// RuneIterator 返回一个当前对象的字符迭代器,当然这个迭代器是没有尽头的
func (x *CycleString) RuneIterator() *CycleStringRuneIterator {
return NewCycleStringRuneIterator(x)
}
// ByteIterator 返回一个当前对象的字节迭代器,当然这个迭代器是没有尽头的
func (x *CycleString) ByteIterator() *CycleStringByteIterator {
return NewCycleStringByteIterator(x)
}
// ------------------------------------------------- --------------------------------------------------------------------
// 转为string的时候只返回原始的字符串
func (x *CycleString) String() string {
return x.baseString
}
// ------------------------------------------------- --------------------------------------------------------------------
// CycleStringBaseStringJsonFieldName JSON序列化后存储真实字符串的字段名称,用于让序列化后的JSON能够具有一定的辨识和阅读性
const CycleStringBaseStringJsonFieldName = "CycleStringBaseString"
// MarshalJSON JSON序列化
func (x *CycleString) MarshalJSON() ([]byte, error) {
m := make(map[string]string)
m[CycleStringBaseStringJsonFieldName] = x.baseString
return json.Marshal(m)
}
// UnmarshalJSON JSON反序列化
func (x *CycleString) UnmarshalJSON(bytes []byte) error {
m := make(map[string]string)
err := json.Unmarshal(bytes, &m)
if err != nil {
return err
}
x.baseString = m[CycleStringBaseStringJsonFieldName]
x.baseStringRuneSlice = []rune(x.baseString)
return nil
}
// ------------------------------------------------- --------------------------------------------------------------------