Source file src/pkg/strings/replace.go
1
2
3
4
5 package strings
6
7 import "io"
8
9
10 type Replacer struct {
11 r replacer
12 }
13
14
15 type replacer interface {
16 Replace(s string) string
17 WriteString(w io.Writer, s string) (n int, err error)
18 }
19
20
21
22
23 type byteBitmap [256 / 32]uint32
24
25 func (m *byteBitmap) set(b byte) {
26 m[b>>5] |= uint32(1 << (b & 31))
27 }
28
29
30
31 func NewReplacer(oldnew ...string) *Replacer {
32 if len(oldnew)%2 == 1 {
33 panic("strings.NewReplacer: odd argument count")
34 }
35
36 if len(oldnew) == 2 && len(oldnew[0]) > 1 {
37 return &Replacer{r: makeSingleStringReplacer(oldnew[0], oldnew[1])}
38 }
39
40 allNewBytes := true
41 for i := 0; i < len(oldnew); i += 2 {
42 if len(oldnew[i]) != 1 {
43 return &Replacer{r: makeGenericReplacer(oldnew)}
44 }
45 if len(oldnew[i+1]) != 1 {
46 allNewBytes = false
47 }
48 }
49
50 if allNewBytes {
51 bb := &byteReplacer{}
52 for i := 0; i < len(oldnew); i += 2 {
53 o, n := oldnew[i][0], oldnew[i+1][0]
54 if bb.old[o>>5]&uint32(1<<(o&31)) != 0 {
55
56 continue
57 }
58 bb.old.set(o)
59 bb.new[o] = n
60 }
61 return &Replacer{r: bb}
62 }
63
64 bs := &byteStringReplacer{}
65 for i := 0; i < len(oldnew); i += 2 {
66 o, new := oldnew[i][0], oldnew[i+1]
67 if bs.old[o>>5]&uint32(1<<(o&31)) != 0 {
68
69 continue
70 }
71 bs.old.set(o)
72 bs.new[o] = []byte(new)
73 }
74 return &Replacer{r: bs}
75 }
76
77
78 func (r *Replacer) Replace(s string) string {
79 return r.r.Replace(s)
80 }
81
82
83 func (r *Replacer) WriteString(w io.Writer, s string) (n int, err error) {
84 return r.r.WriteString(w, s)
85 }
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104 type trieNode struct {
105
106
107 value string
108
109
110
111
112
113 priority int
114
115
116
117
118
119
120
121
122
123
124
125
126 prefix string
127 next *trieNode
128
129
130
131
132
133
134
135
136 table []*trieNode
137 }
138
139 func (t *trieNode) add(key, val string, priority int, r *genericReplacer) {
140 if key == "" {
141 if t.priority == 0 {
142 t.value = val
143 t.priority = priority
144 }
145 return
146 }
147
148 if t.prefix != "" {
149
150 var n int
151 for ; n < len(t.prefix) && n < len(key); n++ {
152 if t.prefix[n] != key[n] {
153 break
154 }
155 }
156 if n == len(t.prefix) {
157 t.next.add(key[n:], val, priority, r)
158 } else if n == 0 {
159
160
161
162 var prefixNode *trieNode
163 if len(t.prefix) == 1 {
164 prefixNode = t.next
165 } else {
166 prefixNode = &trieNode{
167 prefix: t.prefix[1:],
168 next: t.next,
169 }
170 }
171 keyNode := new(trieNode)
172 t.table = make([]*trieNode, r.tableSize)
173 t.table[r.mapping[t.prefix[0]]] = prefixNode
174 t.table[r.mapping[key[0]]] = keyNode
175 t.prefix = ""
176 t.next = nil
177 keyNode.add(key[1:], val, priority, r)
178 } else {
179
180 next := &trieNode{
181 prefix: t.prefix[n:],
182 next: t.next,
183 }
184 t.prefix = t.prefix[:n]
185 t.next = next
186 next.add(key[n:], val, priority, r)
187 }
188 } else if t.table != nil {
189
190 m := r.mapping[key[0]]
191 if t.table[m] == nil {
192 t.table[m] = new(trieNode)
193 }
194 t.table[m].add(key[1:], val, priority, r)
195 } else {
196 t.prefix = key
197 t.next = new(trieNode)
198 t.next.add("", val, priority, r)
199 }
200 }
201
202 func (r *genericReplacer) lookup(s string, ignoreRoot bool) (val string, keylen int, found bool) {
203
204
205 bestPriority := 0
206 node := &r.root
207 n := 0
208 for node != nil {
209 if node.priority > bestPriority && !(ignoreRoot && node == &r.root) {
210 bestPriority = node.priority
211 val = node.value
212 keylen = n
213 found = true
214 }
215
216 if s == "" {
217 break
218 }
219 if node.table != nil {
220 index := r.mapping[s[0]]
221 if int(index) == r.tableSize {
222 break
223 }
224 node = node.table[index]
225 s = s[1:]
226 n++
227 } else if node.prefix != "" && HasPrefix(s, node.prefix) {
228 n += len(node.prefix)
229 s = s[len(node.prefix):]
230 node = node.next
231 } else {
232 break
233 }
234 }
235 return
236 }
237
238
239
240 type genericReplacer struct {
241 root trieNode
242
243
244 tableSize int
245
246 mapping [256]byte
247 }
248
249 func makeGenericReplacer(oldnew []string) *genericReplacer {
250 r := new(genericReplacer)
251
252 for i := 0; i < len(oldnew); i += 2 {
253 key := oldnew[i]
254 for j := 0; j < len(key); j++ {
255 r.mapping[key[j]] = 1
256 }
257 }
258
259 for _, b := range r.mapping {
260 r.tableSize += int(b)
261 }
262
263 var index byte
264 for i, b := range r.mapping {
265 if b == 0 {
266 r.mapping[i] = byte(r.tableSize)
267 } else {
268 r.mapping[i] = index
269 index++
270 }
271 }
272
273 r.root.table = make([]*trieNode, r.tableSize)
274
275 for i := 0; i < len(oldnew); i += 2 {
276 r.root.add(oldnew[i], oldnew[i+1], len(oldnew)-i, r)
277 }
278 return r
279 }
280
281 type appendSliceWriter []byte
282
283
284 func (w *appendSliceWriter) Write(p []byte) (int, error) {
285 *w = append(*w, p...)
286 return len(p), nil
287 }
288
289
290 func (w *appendSliceWriter) WriteString(s string) (int, error) {
291 *w = append(*w, s...)
292 return len(s), nil
293 }
294
295 type stringWriterIface interface {
296 WriteString(string) (int, error)
297 }
298
299 type stringWriter struct {
300 w io.Writer
301 }
302
303 func (w stringWriter) WriteString(s string) (int, error) {
304 return w.w.Write([]byte(s))
305 }
306
307 func getStringWriter(w io.Writer) stringWriterIface {
308 sw, ok := w.(stringWriterIface)
309 if !ok {
310 sw = stringWriter{w}
311 }
312 return sw
313 }
314
315 func (r *genericReplacer) Replace(s string) string {
316 buf := make(appendSliceWriter, 0, len(s))
317 r.WriteString(&buf, s)
318 return string(buf)
319 }
320
321 func (r *genericReplacer) WriteString(w io.Writer, s string) (n int, err error) {
322 sw := getStringWriter(w)
323 var last, wn int
324 var prevMatchEmpty bool
325 for i := 0; i <= len(s); {
326
327 val, keylen, match := r.lookup(s[i:], prevMatchEmpty)
328 prevMatchEmpty = match && keylen == 0
329 if match {
330 wn, err = sw.WriteString(s[last:i])
331 n += wn
332 if err != nil {
333 return
334 }
335 wn, err = sw.WriteString(val)
336 n += wn
337 if err != nil {
338 return
339 }
340 i += keylen
341 last = i
342 continue
343 }
344 i++
345 }
346 if last != len(s) {
347 wn, err = sw.WriteString(s[last:])
348 n += wn
349 }
350 return
351 }
352
353
354
355 type singleStringReplacer struct {
356 finder *stringFinder
357
358 value string
359 }
360
361 func makeSingleStringReplacer(pattern string, value string) *singleStringReplacer {
362 return &singleStringReplacer{finder: makeStringFinder(pattern), value: value}
363 }
364
365 func (r *singleStringReplacer) Replace(s string) string {
366 var buf []byte
367 i := 0
368 for {
369 match := r.finder.next(s[i:])
370 if match == -1 {
371 break
372 }
373 buf = append(buf, s[i:i+match]...)
374 buf = append(buf, r.value...)
375 i += match + len(r.finder.pattern)
376 }
377 if buf == nil {
378 return s
379 }
380 buf = append(buf, s[i:]...)
381 return string(buf)
382 }
383
384 func (r *singleStringReplacer) WriteString(w io.Writer, s string) (n int, err error) {
385 sw := getStringWriter(w)
386 var i, wn int
387 for {
388 match := r.finder.next(s[i:])
389 if match == -1 {
390 break
391 }
392 wn, err = sw.WriteString(s[i : i+match])
393 n += wn
394 if err != nil {
395 return
396 }
397 wn, err = sw.WriteString(r.value)
398 n += wn
399 if err != nil {
400 return
401 }
402 i += match + len(r.finder.pattern)
403 }
404 wn, err = sw.WriteString(s[i:])
405 n += wn
406 return
407 }
408
409
410
411 type byteReplacer struct {
412
413 old byteBitmap
414
415
416
417 new [256]byte
418 }
419
420 func (r *byteReplacer) Replace(s string) string {
421 var buf []byte
422 for i := 0; i < len(s); i++ {
423 b := s[i]
424 if r.old[b>>5]&uint32(1<<(b&31)) != 0 {
425 if buf == nil {
426 buf = []byte(s)
427 }
428 buf[i] = r.new[b]
429 }
430 }
431 if buf == nil {
432 return s
433 }
434 return string(buf)
435 }
436
437 func (r *byteReplacer) WriteString(w io.Writer, s string) (n int, err error) {
438
439 bufsize := 32 << 10
440 if len(s) < bufsize {
441 bufsize = len(s)
442 }
443 buf := make([]byte, bufsize)
444
445 for len(s) > 0 {
446 ncopy := copy(buf, s[:])
447 s = s[ncopy:]
448 for i, b := range buf[:ncopy] {
449 if r.old[b>>5]&uint32(1<<(b&31)) != 0 {
450 buf[i] = r.new[b]
451 }
452 }
453 wn, err := w.Write(buf[:ncopy])
454 n += wn
455 if err != nil {
456 return n, err
457 }
458 }
459 return n, nil
460 }
461
462
463
464
465 type byteStringReplacer struct {
466
467 old byteBitmap
468
469
470
471 new [256][]byte
472 }
473
474 func (r *byteStringReplacer) Replace(s string) string {
475 newSize := 0
476 anyChanges := false
477 for i := 0; i < len(s); i++ {
478 b := s[i]
479 if r.old[b>>5]&uint32(1<<(b&31)) != 0 {
480 anyChanges = true
481 newSize += len(r.new[b])
482 } else {
483 newSize++
484 }
485 }
486 if !anyChanges {
487 return s
488 }
489 buf := make([]byte, newSize)
490 bi := buf
491 for i := 0; i < len(s); i++ {
492 b := s[i]
493 if r.old[b>>5]&uint32(1<<(b&31)) != 0 {
494 n := copy(bi[:], r.new[b])
495 bi = bi[n:]
496 } else {
497 bi[0] = b
498 bi = bi[1:]
499 }
500 }
501 return string(buf)
502 }
503
504
505
506
507 func (r *byteStringReplacer) WriteString(w io.Writer, s string) (n int, err error) {
508
509 bufsize := 32 << 10
510 if len(s) < bufsize {
511 bufsize = len(s)
512 }
513 buf := make([]byte, bufsize)
514 bi := buf[:0]
515
516 for i := 0; i < len(s); i++ {
517 b := s[i]
518 var new []byte
519 if r.old[b>>5]&uint32(1<<(b&31)) != 0 {
520 new = r.new[b]
521 } else {
522 bi = append(bi, b)
523 }
524 if len(bi) == cap(bi) || (len(bi) > 0 && len(new) > 0) {
525 nw, err := w.Write(bi)
526 n += nw
527 if err != nil {
528 return n, err
529 }
530 bi = buf[:0]
531 }
532 if len(new) > 0 {
533 nw, err := w.Write(new)
534 n += nw
535 if err != nil {
536 return n, err
537 }
538 }
539 }
540 if len(bi) > 0 {
541 nw, err := w.Write(bi)
542 n += nw
543 if err != nil {
544 return n, err
545 }
546 }
547 return n, nil
548 }
View as plain text