github.com/qiniu/x@v1.11.9/bytes/replace.go (about) 1 /* 2 Copyright 2020 Qiniu Limited (qiniu.com) 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package bytes 18 19 import ( 20 "bytes" 21 ) 22 23 // --------------------------------------------------- 24 25 // ReplaceAt does a replace operation at position `off` in place. 26 func ReplaceAt(b []byte, off, nsrc int, dest []byte) []byte { 27 ndelta := len(dest) - nsrc 28 if ndelta < 0 { 29 left := b[off+nsrc:] 30 off += copy(b[off:], dest) 31 off += copy(b[off:], left) 32 return b[:off] 33 } 34 35 if ndelta > 0 { 36 b = append(b, dest[:ndelta]...) 37 copy(b[off+len(dest):], b[off+nsrc:]) 38 copy(b[off:], dest) 39 } else { 40 copy(b[off:], dest) 41 } 42 return b 43 } 44 45 // ReplaceOne does a replace operation from `from` position in place. 46 // It returns an offset for next replace operation. 47 // If the returned offset is -1, it means no replace operation occurred. 48 func ReplaceOne(b []byte, from int, src, dest []byte) ([]byte, int) { 49 pos := bytes.Index(b[from:], src) 50 if pos < 0 { 51 return b, -1 52 } 53 54 from += pos 55 return ReplaceAt(b, from, len(src), dest), from + len(dest) 56 } 57 58 // Unlike bytes.Replace, this Replace does replace operations in place. 59 func Replace(b []byte, src, dest []byte, n int) []byte { 60 from := 0 61 for n != 0 { 62 b, from = ReplaceOne(b, from, src, dest) 63 if from < 0 { 64 break 65 } 66 n-- 67 } 68 return b 69 } 70 71 // ---------------------------------------------------