⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 string.cc

📁 ac3的解码程序
💻 CC
📖 第 1 页 / 共 2 页
字号:
/* Copyright (C) 1988 Free Software Foundation    written by Doug Lea (dl@rocky.oswego.edu)This file is part of the GNU C++ Library.  This library is freesoftware; you can redistribute it and/or modify it under the terms ofthe GNU Library General Public License as published by the FreeSoftware Foundation; either version 2 of the License, or (at youroption) any later version.  This library is distributed in the hopethat it will be useful, but WITHOUT ANY WARRANTY; without even theimplied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULARPURPOSE.  See the GNU Library General Public License for more details.You should have received a copy of the GNU Library General PublicLicense along with this library; if not, write to the Free SoftwareFoundation, 675 Mass Ave, Cambridge, MA 02139, USA.*//*   String class implementation */#ifdef __GNUG__#pragma implementation#endif#include <String.h>#include <unistd.h>#include <ctype.h>#include <limits.h>#include <new.h>#include <builtin.h>void String::error(const char* msg) const{  (*lib_error_handler)("String", msg);}String::operator const char*() const{   return (const char*)chars();}//  globalsStrRep  _nilStrRep = { 0, 1, { 0 } }; // nil strings point hereString _nilString;               // nil SubStrings point here/* the following inline fcts are specially designed to work in support of String classes, and are not meant as generic replacements for libc "str" functions. inline copy fcts -  I like left-to-right from->to arguments. all versions assume that `to' argument is non-null These are worth doing inline, rather than through calls because, via procedural integration, adjacent copy calls can be smushed together by the optimizer.*/// copy n bytesinline static void ncopy(const char* from, char* to, int n){  if (from != to) while (--n >= 0) *to++ = *from++;}// copy n bytes, null-terminateinline static void ncopy0(const char* from, char* to, int n){  if (from != to)   {    while (--n >= 0) *to++ = *from++;    *to = 0;  }  else    to[n] = 0;}// copy until nullinline static void scopy(const char* from, char* to){  if (from != 0) while((*to++ = *from++) != 0);}// copy right-to-leftinline static void revcopy(const char* from, char* to, short n){  if (from != 0) while (--n >= 0) *to-- = *from--;}inline static int slen(const char* t) // inline  strlen{  if (t == 0)    return 0;  else  {    const char* a = t;    while (*a++ != 0);    return a - 1 - t;  }}// minimum & maximum representable rep size#define MAXStrRep_SIZE   ((1 << (sizeof(short) * CHAR_BIT - 1)) - 1)#define MINStrRep_SIZE   16#ifndef MALLOC_MIN_OVERHEAD#define MALLOC_MIN_OVERHEAD  4#endif// The basic allocation primitive:// Always round request to something close to a power of two.// This ensures a bit of padding, which often means that// concatenations don't have to realloc. Plus it tends to// be faster when lots of Strings are created and discarded,// since just about any version of malloc (op new()) will// be faster when it can reuse identically-sized chunksinline static StrRep* Snew(int newsiz){  unsigned int siz = sizeof(StrRep) + newsiz + MALLOC_MIN_OVERHEAD;  unsigned int allocsiz = MINStrRep_SIZE;  while (allocsiz < siz) allocsiz <<= 1;  allocsiz -= MALLOC_MIN_OVERHEAD;  if (allocsiz >= MAXStrRep_SIZE)    (*lib_error_handler)("String", "Requested length out of range");      StrRep* rep = (StrRep *) new char[allocsiz];  rep->sz = allocsiz - sizeof(StrRep);  return rep;}// Do-something-while-allocating routines.// We live with two ways to signify empty Sreps: either the// null pointer (0) or a pointer to the nilStrRep.// We always signify unknown source lengths (usually when fed a char*)// via len == -1, in which case it is computed.// allocate, copying src if nonullStrRep* Salloc(StrRep* old, const char* src, int srclen, int newlen){  if (old == &_nilStrRep) old = 0;  if (srclen < 0) srclen = slen(src);  if (newlen < srclen) newlen = srclen;  StrRep* rep;  if (old == 0 || newlen > old->sz)    rep = Snew(newlen);  else    rep = old;  rep->len = newlen;  ncopy0(src, rep->s, srclen);  if (old != rep && old != 0) delete old;  return rep;}// reallocate: Given the initial allocation scheme, it will// generally be faster in the long run to get new space & copy// than to call reallocstatic StrRep*Sresize(StrRep* old, int newlen){  if (old == &_nilStrRep) old = 0;  StrRep* rep;  if (old == 0)    rep = Snew(newlen);  else if (newlen > old->sz)  {    rep = Snew(newlen);    ncopy0(old->s, rep->s, old->len);    delete old;  }  else    rep = old;  rep->len = newlen;  return rep;}voidString::alloc (int newsize){  unsigned short old_len = rep->len;  rep = Sresize(rep, newsize);  rep->len = old_len;}// like allocate, but we know that src is a StrRepStrRep* Scopy(StrRep* old, const StrRep* s){  if (old == &_nilStrRep) old = 0;  if (s == &_nilStrRep) s = 0;  if (old == s)     return (old == 0)? &_nilStrRep : old;  else if (s == 0)  {    old->s[0] = 0;    old->len = 0;    return old;  }  else   {    StrRep* rep;    int newlen = s->len;    if (old == 0 || newlen > old->sz)    {      if (old != 0) delete old;      rep = Snew(newlen);    }    else      rep = old;    rep->len = newlen;    ncopy0(s->s, rep->s, newlen);    return rep;  }}// allocate & concatenateStrRep* Scat(StrRep* old, const char* s, int srclen, const char* t, int tlen){  if (old == &_nilStrRep) old = 0;  if (srclen < 0) srclen = slen(s);  if (tlen < 0) tlen = slen(t);  int newlen = srclen + tlen;  StrRep* rep;  if (old == 0 || newlen > old->sz ||       (t >= old->s && t < &(old->s[old->len]))) // beware of aliasing    rep = Snew(newlen);  else    rep = old;  rep->len = newlen;  ncopy(s, rep->s, srclen);  ncopy0(t, &(rep->s[srclen]), tlen);  if (old != rep && old != 0) delete old;  return rep;}// double-concatenateStrRep* Scat(StrRep* old, const char* s, int srclen, const char* t, int tlen,             const char* u, int ulen){  if (old == &_nilStrRep) old = 0;  if (srclen < 0) srclen = slen(s);  if (tlen < 0) tlen = slen(t);  if (ulen < 0) ulen = slen(u);  int newlen = srclen + tlen + ulen;  StrRep* rep;  if (old == 0 || newlen > old->sz ||       (t >= old->s && t < &(old->s[old->len])) ||      (u >= old->s && u < &(old->s[old->len])))    rep = Snew(newlen);  else    rep = old;  rep->len = newlen;  ncopy(s, rep->s, srclen);  ncopy(t, &(rep->s[srclen]), tlen);  ncopy0(u, &(rep->s[srclen+tlen]), ulen);  if (old != rep && old != 0) delete old;  return rep;}// like cat, but we know that new stuff goes in the front of existing repStrRep* Sprepend(StrRep* old, const char* t, int tlen){  char* s;  int srclen;  if (old == &_nilStrRep || old == 0)  {    s = 0; old = 0; srclen = 0;  }  else  {    s = old->s; srclen = old->len;  }  if (tlen < 0) tlen = slen(t);  int newlen = srclen + tlen;  StrRep* rep;  if (old == 0 || newlen > old->sz ||       (t >= old->s && t < &(old->s[old->len])))    rep = Snew(newlen);  else    rep = old;  rep->len = newlen;  revcopy(&(s[srclen]), &(rep->s[newlen]), srclen+1);  ncopy(t, rep->s, tlen);  if (old != rep && old != 0) delete old;  return rep;}// string compare: first argument is known to be non-nullinline static int scmp(const char* a, const char* b){  if (b == 0)    return *a != 0;  else  {    signed char diff = 0;    while ((diff = *a - *b++) == 0 && *a++ != 0);    return diff;  }}inline static int ncmp(const char* a, int al, const char* b, int bl){  int n = (al <= bl)? al : bl;  signed char diff;  while (n-- > 0) if ((diff = *a++ - *b++) != 0) return diff;  return al - bl;}int fcompare(const String& x, const String& y){  const char* a = x.chars();  const char* b = y.chars();  int al = x.length();  int bl = y.length();  int n = (al <= bl)? al : bl;  signed char diff = 0;  while (n-- > 0)  {    char ac = *a++;    char bc = *b++;    if ((diff = ac - bc) != 0)    {      if (ac >= 'a' && ac <= 'z')        ac = ac - 'a' + 'A';      if (bc >= 'a' && bc <= 'z')        bc = bc - 'a' + 'A';      if ((diff = ac - bc) != 0)        return diff;    }  }  return al - bl;}// these are not inline, but pull in the above inlines, so are // pretty fastint compare(const String& x, const char* b){  return scmp(x.chars(), b);}int compare(const String& x, const String& y){  return scmp(x.chars(), y.chars());}int compare(const String& x, const SubString& y){  return ncmp(x.chars(), x.length(), y.chars(), y.length());}int compare(const SubString& x, const String& y){  return ncmp(x.chars(), x.length(), y.chars(), y.length());}int compare(const SubString& x, const SubString& y){  return ncmp(x.chars(), x.length(), y.chars(), y.length());}int compare(const SubString& x, const char* b){  if (b == 0)    return x.length();  else  {    const char* a = x.chars();    int n = x.length();    signed char diff;    while (n-- > 0) if ((diff = *a++ - *b++) != 0) return diff;    return (*b == 0) ? 0 : -1;  }}/* index fcts*/int String::search(int start, int sl, char c) const{  const char* s = chars();  if (sl > 0)  {    if (start >= 0)    {      const char* a = &(s[start]);      const char* lasta = &(s[sl]);      while (a < lasta) if (*a++ == c) return --a - s;    }    else    {      const char* a = &(s[sl + start + 1]);      while (--a >= s) if (*a == c) return a - s;    }  }  return -1;}int String::search(int start, int sl, const char* t, int tl) const{  const char* s = chars();  if (tl < 0) tl = slen(t);  if (sl > 0 && tl > 0)  {    if (start >= 0)    {      const char* lasts = &(s[sl - tl]);      const char* lastt = &(t[tl]);      const char* p = &(s[start]);      while (p <= lasts)      {        const char* x = p++;        const char* y = t;        while (*x++ == *y++) if (y >= lastt) return --p - s;      }    }    else    {      const char* firsts = &(s[tl - 1]);      const char* lastt =  &(t[tl - 1]);      const char* p = &(s[sl + start + 1]);       while (--p >= firsts)      {        const char* x = p;        const char* y = lastt;        while (*x-- == *y--) if (y < t) return ++x - s;      }    }  }  return -1;}int String::match(int start, int sl, int exact, const char* t, int tl) const{  if (tl < 0) tl = slen(t);  if (start < 0)  {    start = sl + start - tl + 1;    if (start < 0 || (exact && start != 0))      return -1;  }  else if (exact && sl - start != tl)    return -1;  if (sl == 0 || tl == 0 || sl - start < tl || start >= sl)    return -1;  int n = tl;  const char* s = &(rep->s[start]);  while (--n >= 0) if (*s++ != *t++) return -1;  return tl;}void SubString::assign(const StrRep* ysrc, const char* ys, int ylen){  if (&S == &_nilString) return;  if (ylen < 0) ylen = slen(ys);  StrRep* targ = S.rep;  int sl = targ->len - len + ylen;  if (ysrc == targ || sl >= targ->sz)  {    StrRep* oldtarg = targ;    targ = Sresize(0, sl);    ncopy(oldtarg->s, targ->s, pos);    ncopy(ys, &(targ->s[pos]), ylen);    scopy(&(oldtarg->s[pos + len]), &(targ->s[pos + ylen]));    delete oldtarg;  }  else if (len == ylen)    ncopy(ys, &(targ->s[pos]), len);  else if (ylen < len)  {    ncopy(ys, &(targ->s[pos]), ylen);    scopy(&(targ->s[pos + len]), &(targ->s[pos + ylen]));  }  else  {    revcopy(&(targ->s[targ->len]), &(targ->s[sl]), targ->len-pos-len +1);    ncopy(ys, &(targ->s[pos]), ylen);  }  targ->len = sl;  S.rep = targ;}/* * substitution */int String::_gsub(const char* pat, int pl, const char* r, int rl){  int nmatches = 0;  if (pl < 0) pl = slen(pat);  if (rl < 0) rl = slen(r);  int sl = length();  if (sl <= 0 || pl <= 0 || sl < pl)    return nmatches;    const char* s = chars();  // prepare to make new rep  StrRep* nrep = 0;  int nsz = 0;  char* x = 0;  int si = 0;  int xi = 0;  int remaining = sl;  while (remaining >= pl)  {    int pos = search(si, sl, pat, pl);    if (pos < 0)      break;    else    {      ++nmatches;      int mustfit = xi + remaining + rl - pl;      if (mustfit >= nsz)      {        if (nrep != 0) nrep->len = xi;        nrep = Sresize(nrep, mustfit);        nsz = nrep->sz;        x = nrep->s;      }      pos -= si;      ncopy(&(s[si]), &(x[xi]), pos);      ncopy(r, &(x[xi + pos]), rl);      si += pos + pl;      remaining -= pos + pl;      xi += pos + rl;    }  }  if (nrep == 0)  {    if (nmatches == 0)      return nmatches;    else      nrep = Sresize(nrep, xi+remaining);  }  ncopy0(&(s[si]), &(x[xi]), remaining);  nrep->len = xi + remaining;  if (nrep->len <= rep->sz)   // fit back in if possible  {    rep->len = nrep->len;    ncopy0(nrep->s, rep->s, rep->len);    delete(nrep);  }  else  {    delete(rep);    rep = nrep;  }  return nmatches;}int String::_gsub(const Regex& pat, const char* r, int rl){  int nmatches = 0;  int sl = length();  if (sl <= 0)    return nmatches;  if (rl < 0) rl = slen(r);  const char* s = chars();  StrRep* nrep = 0;  int nsz = 0;  char* x = 0;  int si = 0;  int xi = 0;  int remaining = sl;  int  pos, pl = 0;				  // how long is a regular expression?  while (remaining > 0)  {    pos = pat.search(s, sl, pl, si); // unlike string search, the pos returned here is absolute    if (pos < 0 || pl <= 0)      break;    else    {      ++nmatches;      int mustfit = xi + remaining + rl - pl;      if (mustfit >= nsz)      {        if (nrep != 0) nrep->len = xi;        nrep = Sresize(nrep, mustfit);        x = nrep->s;        nsz = nrep->sz;      }      pos -= si;      ncopy(&(s[si]), &(x[xi]), pos);      ncopy(r, &(x[xi + pos]), rl);      si += pos + pl;      remaining -= pos + pl;      xi += pos + rl;    }  }  if (nrep == 0)  {    if (nmatches == 0)      return nmatches;    else      nrep = Sresize(nrep, xi+remaining);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -