gstring.cc

来自「swf文件查看工具,能够看flash文件的格式」· CC 代码 · 共 719 行

CC
719
字号
//========================================================================//// GString.cc//// Simple variable-length string type.//// Copyright 1996-2003 Glyph & Cog, LLC////========================================================================#include <aconf.h>#ifdef USE_GCC_PRAGMAS#pragma implementation#endif#include <stdlib.h>#include <stddef.h>#include <string.h>#include <ctype.h>#include <math.h>#include "gmem.h"#include "GString.h"//------------------------------------------------------------------------union GStringFormatArg {  int i;  Guint ui;  long l;  Gulong ul;  double f;  char c;  char *s;  GString *gs;};enum GStringFormatType {  fmtIntDecimal,  fmtIntHex,  fmtIntOctal,  fmtIntBinary,  fmtUIntDecimal,  fmtUIntHex,  fmtUIntOctal,  fmtUIntBinary,  fmtLongDecimal,  fmtLongHex,  fmtLongOctal,  fmtLongBinary,  fmtULongDecimal,  fmtULongHex,  fmtULongOctal,  fmtULongBinary,  fmtDouble,  fmtDoubleTrim,  fmtChar,  fmtString,  fmtGString,  fmtSpace};static char *formatStrings[] = {  "d", "x", "o", "b", "ud", "ux", "uo", "ub",  "ld", "lx", "lo", "lb", "uld", "ulx", "ulo", "ulb",  "f", "g",  "c",  "s",  "t",  "w",  NULL};//------------------------------------------------------------------------static inline int size(int len) {  int delta;  for (delta = 8; delta < len && delta < 0x100000; delta <<= 1) ;  // this is ((len + 1) + (delta - 1)) & ~(delta - 1)  return (len + delta) & ~(delta - 1);}inline void GString::resize(int length1) {  char *s1;  if (!s) {    s = new char[size(length1)];  } else if (size(length1) != size(length)) {    s1 = new char[size(length1)];    if (length1 < length) {      memcpy(s1, s, length1);      s1[length1] = '\0';    } else {      memcpy(s1, s, length + 1);    }    delete[] s;    s = s1;  }}GString::GString() {  s = NULL;  resize(length = 0);  s[0] = '\0';}GString::GString(const char *sA) {  int n = strlen(sA);  s = NULL;  resize(length = n);  memcpy(s, sA, n + 1);}GString::GString(const char *sA, int lengthA) {  s = NULL;  resize(length = lengthA);  memcpy(s, sA, length * sizeof(char));  s[length] = '\0';}GString::GString(GString *str, int idx, int lengthA) {  s = NULL;  resize(length = lengthA);  memcpy(s, str->getCString() + idx, length);  s[length] = '\0';}GString::GString(GString *str) {  s = NULL;  resize(length = str->getLength());  memcpy(s, str->getCString(), length + 1);}GString::GString(GString *str1, GString *str2) {  int n1 = str1->getLength();  int n2 = str2->getLength();  s = NULL;  resize(length = n1 + n2);  memcpy(s, str1->getCString(), n1);  memcpy(s + n1, str2->getCString(), n2 + 1);}GString *GString::fromInt(int x) {  char buf[24]; // enough space for 64-bit ints plus a little extra  char *p;  int len;  formatInt(x, buf, sizeof(buf), gFalse, 0, 10, &p, &len);  return new GString(p, len);}GString *GString::format(char *fmt, ...) {  va_list argList;  GString *s;  s = new GString();  va_start(argList, fmt);  s->appendfv(fmt, argList);  va_end(argList);  return s;}GString *GString::formatv(char *fmt, va_list argList) {  GString *s;  s = new GString();  s->appendfv(fmt, argList);  return s;}GString::~GString() {  delete[] s;}GString *GString::clear() {  s[length = 0] = '\0';  resize(0);  return this;}GString *GString::append(char c) {  resize(length + 1);  s[length++] = c;  s[length] = '\0';  return this;}GString *GString::append(GString *str) {  int n = str->getLength();  resize(length + n);  memcpy(s + length, str->getCString(), n + 1);  length += n;  return this;}GString *GString::append(const char *str) {  int n = strlen(str);  resize(length + n);  memcpy(s + length, str, n + 1);  length += n;  return this;}GString *GString::append(const char *str, int lengthA) {  resize(length + lengthA);  memcpy(s + length, str, lengthA);  length += lengthA;  s[length] = '\0';  return this;}GString *GString::appendf(char *fmt, ...) {  va_list argList;  va_start(argList, fmt);  appendfv(fmt, argList);  va_end(argList);  return this;}GString *GString::appendfv(char *fmt, va_list argList) {  GStringFormatArg *args;  int argsLen, argsSize;  GStringFormatArg arg;  int idx, width, prec;  GBool reverseAlign, zeroFill;  GStringFormatType ft;  char buf[65];  int len, i;  char *p0, *p1, *str;  argsLen = 0;  argsSize = 8;  args = (GStringFormatArg *)gmallocn(argsSize, sizeof(GStringFormatArg));  p0 = fmt;  while (*p0) {    if (*p0 == '{') {      ++p0;      if (*p0 == '{') {	++p0;	append('{');      } else {	// parse the format string	if (!(*p0 >= '0' && *p0 <= '9')) {	  break;	}	idx = *p0 - '0';	for (++p0; *p0 >= '0' && *p0 <= '9'; ++p0) {	  idx = 10 * idx + (*p0 - '0');	}	if (*p0 != ':') {	  break;	}	++p0;	if (*p0 == '-') {	  reverseAlign = gTrue;	  ++p0;	} else {	  reverseAlign = gFalse;	}	width = 0;	zeroFill = *p0 == '0';	for (; *p0 >= '0' && *p0 <= '9'; ++p0) {	  width = 10 * width + (*p0 - '0');	}	if (*p0 == '.') {	  ++p0;	  prec = 0;	  for (; *p0 >= '0' && *p0 <= '9'; ++p0) {	    prec = 10 * prec + (*p0 - '0');	  }	} else {	  prec = 0;	}	for (ft = (GStringFormatType)0;	     formatStrings[ft];	     ft = (GStringFormatType)(ft + 1)) {	  if (!strncmp(p0, formatStrings[ft], strlen(formatStrings[ft]))) {	    break;	  }	}	if (!formatStrings[ft]) {	  break;	}	p0 += strlen(formatStrings[ft]);	if (*p0 != '}') {	  break;	}	++p0;	// fetch the argument	if (idx > argsLen) {	  break;	}	if (idx == argsLen) {	  if (argsLen == argsSize) {	    argsSize *= 2;	    args = (GStringFormatArg *)greallocn(args, argsSize,						 sizeof(GStringFormatArg));	  }	  switch (ft) {	  case fmtIntDecimal:	  case fmtIntHex:	  case fmtIntOctal:	  case fmtIntBinary:	  case fmtSpace:	    args[argsLen].i = va_arg(argList, int);	    break;	  case fmtUIntDecimal:	  case fmtUIntHex:	  case fmtUIntOctal:	  case fmtUIntBinary:	    args[argsLen].ui = va_arg(argList, Guint);	    break;	  case fmtLongDecimal:	  case fmtLongHex:	  case fmtLongOctal:	  case fmtLongBinary:	    args[argsLen].l = va_arg(argList, long);	    break;	  case fmtULongDecimal:	  case fmtULongHex:	  case fmtULongOctal:	  case fmtULongBinary:	    args[argsLen].ul = va_arg(argList, Gulong);	    break;	  case fmtDouble:	  case fmtDoubleTrim:	    args[argsLen].f = va_arg(argList, double);	    break;	  case fmtChar:	    args[argsLen].c = (char)va_arg(argList, int);	    break;	  case fmtString:	    args[argsLen].s = va_arg(argList, char *);	    break;	  case fmtGString:	    args[argsLen].gs = va_arg(argList, GString *);	    break;	  }	  ++argsLen;	}	// format the argument	arg = args[idx];	switch (ft) {	case fmtIntDecimal:	  formatInt(arg.i, buf, sizeof(buf), zeroFill, width, 10, &str, &len);	  break;	case fmtIntHex:	  formatInt(arg.i, buf, sizeof(buf), zeroFill, width, 16, &str, &len);	  break;	case fmtIntOctal:	  formatInt(arg.i, buf, sizeof(buf), zeroFill, width, 8, &str, &len);	  break;	case fmtIntBinary:	  formatInt(arg.i, buf, sizeof(buf), zeroFill, width, 2, &str, &len);	  break;	case fmtUIntDecimal:	  formatUInt(arg.ui, buf, sizeof(buf), zeroFill, width, 10,		     &str, &len);	  break;	case fmtUIntHex:	  formatUInt(arg.ui, buf, sizeof(buf), zeroFill, width, 16,		     &str, &len);	  break;	case fmtUIntOctal:	  formatUInt(arg.ui, buf, sizeof(buf), zeroFill, width, 8, &str, &len);	  break;	case fmtUIntBinary:	  formatUInt(arg.ui, buf, sizeof(buf), zeroFill, width, 2, &str, &len);	  break;	case fmtLongDecimal:	  formatInt(arg.l, buf, sizeof(buf), zeroFill, width, 10, &str, &len);	  break;	case fmtLongHex:	  formatInt(arg.l, buf, sizeof(buf), zeroFill, width, 16, &str, &len);	  break;	case fmtLongOctal:	  formatInt(arg.l, buf, sizeof(buf), zeroFill, width, 8, &str, &len);	  break;	case fmtLongBinary:	  formatInt(arg.l, buf, sizeof(buf), zeroFill, width, 2, &str, &len);	  break;	case fmtULongDecimal:	  formatUInt(arg.ul, buf, sizeof(buf), zeroFill, width, 10,		     &str, &len);	  break;	case fmtULongHex:	  formatUInt(arg.ul, buf, sizeof(buf), zeroFill, width, 16,		     &str, &len);	  break;	case fmtULongOctal:	  formatUInt(arg.ul, buf, sizeof(buf), zeroFill, width, 8, &str, &len);	  break;	case fmtULongBinary:	  formatUInt(arg.ul, buf, sizeof(buf), zeroFill, width, 2, &str, &len);	  break;	case fmtDouble:	  formatDouble(arg.f, buf, sizeof(buf), prec, gFalse, &str, &len);	  break;	case fmtDoubleTrim:	  formatDouble(arg.f, buf, sizeof(buf), prec, gTrue, &str, &len);	  break;	case fmtChar:	  buf[0] = arg.c;	  str = buf;	  len = 1;	  reverseAlign = !reverseAlign;	  break;	case fmtString:	  str = arg.s;	  len = strlen(str);	  reverseAlign = !reverseAlign;	  break;	case fmtGString:	  str = arg.gs->getCString();	  len = arg.gs->getLength();	  reverseAlign = !reverseAlign;	  break;	case fmtSpace:	  str = buf;	  len = 0;	  width = arg.i;	  break;	}	// append the formatted arg, handling width and alignment	if (!reverseAlign && len < width) {	  for (i = len; i < width; ++i) {	    append(' ');	  }	}	append(str, len);	if (reverseAlign && len < width) {	  for (i = len; i < width; ++i) {	    append(' ');	  }	}      }    } else if (*p0 == '}') {      ++p0;      if (*p0 == '}') {	++p0;      }      append('}');          } else {      for (p1 = p0 + 1; *p1 && *p1 != '{' && *p1 != '}'; ++p1) ;      append(p0, p1 - p0);      p0 = p1;    }  }  gfree(args);  return this;}void GString::formatInt(long x, char *buf, int bufSize,			GBool zeroFill, int width, int base,			char **p, int *len) {  static char vals[17] = "0123456789abcdef";  GBool neg;  int start, i, j;  i = bufSize;  if ((neg = x < 0)) {    x = -x;  }  start = neg ? 1 : 0;  if (x == 0) {    buf[--i] = '0';  } else {    while (i > start && x) {      buf[--i] = vals[x % base];      x /= base;    }  }  if (zeroFill) {    for (j = bufSize - i; i > start && j < width - start; ++j) {      buf[--i] = '0';    }  }  if (neg) {    buf[--i] = '-';  }  *p = buf + i;  *len = bufSize - i;}void GString::formatUInt(Gulong x, char *buf, int bufSize,			 GBool zeroFill, int width, int base,			 char **p, int *len) {  static char vals[17] = "0123456789abcdef";  int i, j;  i = bufSize;  if (x == 0) {    buf[--i] = '0';  } else {    while (i > 0 && x) {      buf[--i] = vals[x % base];      x /= base;    }  }  if (zeroFill) {    for (j = bufSize - i; i > 0 && j < width; ++j) {      buf[--i] = '0';    }  }  *p = buf + i;  *len = bufSize - i;}void GString::formatDouble(double x, char *buf, int bufSize, int prec,			   GBool trim, char **p, int *len) {  GBool neg, started;  double x2;  int d, i, j;  if ((neg = x < 0)) {    x = -x;  }  x = floor(x * pow(10, prec) + 0.5);  i = bufSize;  started = !trim;  for (j = 0; j < prec && i > 1; ++j) {    x2 = floor(0.1 * (x + 0.5));    d = (int)floor(x - 10 * x2 + 0.5);    if (started || d != 0) {      buf[--i] = '0' + d;      started = gTrue;    }    x = x2;  }  if (i > 1 && started) {    buf[--i] = '.';  }  if (i > 1) {    do {      x2 = floor(0.1 * (x + 0.5));      d = (int)floor(x - 10 * x2 + 0.5);      buf[--i] = '0' + d;      x = x2;    } while (i > 1 && x);  }  if (neg) {    buf[--i] = '-';  }  *p = buf + i;  *len = bufSize - i;}GString *GString::insert(int i, char c) {  int j;  resize(length + 1);  for (j = length + 1; j > i; --j)    s[j] = s[j-1];  s[i] = c;  ++length;  return this;}GString *GString::insert(int i, GString *str) {  int n = str->getLength();  int j;  resize(length + n);  for (j = length; j >= i; --j)    s[j+n] = s[j];  memcpy(s+i, str->getCString(), n);  length += n;  return this;}GString *GString::insert(int i, const char *str) {  int n = strlen(str);  int j;  resize(length + n);  for (j = length; j >= i; --j)    s[j+n] = s[j];  memcpy(s+i, str, n);  length += n;  return this;}GString *GString::insert(int i, const char *str, int lengthA) {  int j;  resize(length + lengthA);  for (j = length; j >= i; --j)    s[j+lengthA] = s[j];  memcpy(s+i, str, lengthA);  length += lengthA;  return this;}GString *GString::del(int i, int n) {  int j;  if (n > 0) {    if (i + n > length) {      n = length - i;    }    for (j = i; j <= length - n; ++j) {      s[j] = s[j + n];    }    resize(length -= n);  }  return this;}GString *GString::upperCase() {  int i;  for (i = 0; i < length; ++i) {    if (islower(s[i]))      s[i] = toupper(s[i]);  }  return this;}GString *GString::lowerCase() {  int i;  for (i = 0; i < length; ++i) {    if (isupper(s[i]))      s[i] = tolower(s[i]);  }  return this;}int GString::cmp(GString *str) {  int n1, n2, i, x;  char *p1, *p2;  n1 = length;  n2 = str->length;  for (i = 0, p1 = s, p2 = str->s; i < n1 && i < n2; ++i, ++p1, ++p2) {    x = *p1 - *p2;    if (x != 0) {      return x;    }  }  return n1 - n2;}int GString::cmpN(GString *str, int n) {  int n1, n2, i, x;  char *p1, *p2;  n1 = length;  n2 = str->length;  for (i = 0, p1 = s, p2 = str->s;       i < n1 && i < n2 && i < n;       ++i, ++p1, ++p2) {    x = *p1 - *p2;    if (x != 0) {      return x;    }  }  if (i == n) {    return 0;  }  return n1 - n2;}int GString::cmp(const char *sA) {  int n1, i, x;  const char *p1, *p2;  n1 = length;  for (i = 0, p1 = s, p2 = sA; i < n1 && *p2; ++i, ++p1, ++p2) {    x = *p1 - *p2;    if (x != 0) {      return x;    }  }  if (i < n1) {    return 1;  }  if (*p2) {    return -1;  }  return 0;}int GString::cmpN(const char *sA, int n) {  int n1, i, x;  const char *p1, *p2;  n1 = length;  for (i = 0, p1 = s, p2 = sA; i < n1 && *p2 && i < n; ++i, ++p1, ++p2) {    x = *p1 - *p2;    if (x != 0) {      return x;    }  }  if (i == n) {    return 0;  }  if (i < n1) {    return 1;  }  if (*p2) {    return -1;  }  return 0;}

⌨️ 快捷键说明

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