File: replace.hpp

package info (click to toggle)
higan 094-5
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 9,780 kB
  • ctags: 15,643
  • sloc: cpp: 103,963; ansic: 659; makefile: 531; sh: 25
file content (55 lines) | stat: -rwxr-xr-x 1,824 bytes parent folder | download | duplicates (5)
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
#ifdef NALL_STRING_INTERNAL_HPP

namespace nall {

template<unsigned Limit, bool Insensitive, bool Quoted>
string& string::ureplace(rstring key, rstring token) {
  if(key.size() == 0) return *this;
  enum : unsigned { limit = Limit ? Limit : ~0u };

  const char* p = data();
  unsigned counter = 0;

  while(*p) {
    if(quoteskip<Quoted>(p)) continue;
    for(unsigned n = 0;; n++) {
      if(key[n] == 0) { counter++; p += n; break; }
      if(!chrequal<Insensitive>(key[n], p[n])) { p++; break; }
    }
  }
  if(counter == 0) return *this;
  if(Limit) counter = min(counter, Limit);

  char* t = data();
  char* base = nullptr;
  signed displacement = token.size() - key.size();
  signed displacementSize = displacement * counter;

  if(token.size() > key.size()) {
    t = base = strduplicate(data());
    reserve((unsigned)(p - data()) + displacementSize);
  }
  char* o = data();

  while(*t && counter) {
    if(quotecopy<Quoted>(o, t)) continue;
    for(unsigned n = 0;; n++) {
      if(key[n] == 0) { counter--; memcpy(o, token, token.size()); t += key.size(); o += token.size(); break; }
      if(!chrequal<Insensitive>(key[n], t[n])) { *o++ = *t++; break; }
    }
  }
  do *o++ = *t; while(*t++);
  if(base) free(base);

  resize(_size + displacementSize);
  return *this;
}

template<unsigned Limit> string& string::replace(rstring key, rstring token) { return ureplace<Limit, false, false>(key, token); }
template<unsigned Limit> string& string::ireplace(rstring key, rstring token) { return ureplace<Limit, true, false>(key, token); }
template<unsigned Limit> string& string::qreplace(rstring key, rstring token) { return ureplace<Limit, false, true>(key, token); }
template<unsigned Limit> string& string::iqreplace(rstring key, rstring token) { return ureplace<Limit, true, true>(key, token); }

};

#endif