function CString_Class() {
  this.getmid = function (str, lstr, rstr, start, mode) {
    // '1 不区分大小写
    // '2 先查右再左
    // '4 后往前查
    mode = mode || 0;
    start = (mode & 4 && !start) ? mstr.length : start || 0;
    if (start < 0) start = start + mstr.length;
    if (mode & 1) {
      var mlstr = lstr.toLowerCase();
      var mrstr = rstr.toLowerCase();
      var mstr = str.toLowerCase();
    } else {
      var mstr = str;
      var mlstr = lstr;
      var mrstr = rstr;
    }
    if (mode & 2) {
      var r = mode & 4 ? mstr.lastIndexOf(mrstr, start) : mstr.indexOf(mrstr, start);
      if (r == -1) return;
      var l = mstr.lastIndexOf(mlstr, r - 1);
      if (l == -1) return;
      l += mlstr.length
    } else {
      var l = mode & 4 ? mstr.lastIndexOf(mlstr, start) : mstr.indexOf(mlstr, start);
      if (l == -1) return;
      l += mlstr.length
      var r = mstr.indexOf(mrstr, l);
      if (r == -1) return;
    }
    return str.slice(l, r)
  }
  //下面函数主要扩展VBS
  this.slice = function (str, start, end) {
    return str.slice(start, end)
  }
  this.substr = function (str, start, length) {
    return str.substr(start < 0 ? start + str.length : start, length)
  }
  this.Conversion = function (number, from, to) {
    if (from) number = parseInt(number, from)
    if (to) number = number.toString(to)
    return number
  }
  this.Trim = function (str, mode, s, g) {
    s = s || "\\s+";
    if (mode & 1)       //LTrim
      Reg = "^" + s
    else if (mode & 2)  //RTrim
      Reg = s + "$"
    else
      Reg = "^" + s + "|" + s + "$"
    return str.replace(new RegExp(Reg, g || mode & 4 ? 'gm' : 'g'), '');  //4 多行
  }
  this.Replace = function (str, Reg, text) {
    return str.replace(Reg, text);
  }
  this.Search = function (str, text) {
    return str.search(text);
  }
  this.Split = function (str, text) {
    return str.split(text, limit);
  }
  this.Match = function (str, Reg) {
    return str.match(Reg);
  }
  this.RegExp = function (str, g) {
    return g ? new RegExp(str, g) : eval(str);
  }
  this.Eval = function (str) {
    return eval(str);
  }
  this.Math = function () {
    return Math;
  }
  this.Array = function (vbArr) {
    if (vbArr === undefined) return new Array()
    var arr = new VBArray(vbArr)
    return arr.toArray();
  }
  this.ArrayR = function (Arr, Index) {
    return Arr[Index];
  }
  this.fromUnicode = function (str) {
    return eval("'" + str + "'");
  }
  this.toUnicode = function (str) {
    return escape(str).replace(/%/g, "\\")
  }
  // encodeURI()不编码82个字符            !#$&'()*+,/:;=?@-._~0-9a-zA-Z
  // encodeURIComponent()不编码71个字符   !'()*-._~0-9a-zA-Z   //  ,/?:@&=+$#"
  // escape()不编码69个字符               */@+-._0-9a-zA-Z
  this.urlencode = function (str, format) {
    if (str.constructor == Object) {
      var data = new Array()
      for (var i in str) {
        data.push(i + "=" + this.urlencode(str[i], format))
      }
      return data.join("&")
    }
    if (format & 4) return str
    if (format & 0x10) {  //gbk
      return str.replace(format & 1 ? /[^\!\'\(\)\*\-\.\_\~0-9a-zA-Z]+/g : format & 2 ? /[^\*\/\@\+\-\.\_0-9a-zA-Z]+/g : /[^\!\#\$\&\'\(\)\*\+\,\/\:\;\=\?\@\-\.\_\~0-9a-zA-Z]+/g, function ($0) {
        var data = Api.Malloc()
        data.FromString = Api.StrConv($0, 0x80)
        data = new VBArray(data.toArray).toArray()
        for (var i in data) {
          data[i] = data[i].toString(16)
          if (data[i].length == 1) data[i] = "0" + data[i]
        }
        return "%" + data.join("%").toUpperCase()
      })
    }
    return format & 1 ? encodeURIComponent(str) : format & 2 ? escape(str) : encodeURI(str);
  }
  this.urldecode = function (str, format) {
    if (format & 0x10) {  //gbk
      return str.replace(/(\%\w{1,2})+/g, function ($0) {
        var arr = $0.split("%")
        arr.shift()
        for (var i in arr) {
          arr[i] = parseInt(arr[i], 16)
        }
        var data = Api.Malloc()
        data.Add = Api.ArrayFormat(arr)
        return Api.StrConv(data.toString, 0x40)
      })
    }
    return format & 1 ? decodeURIComponent(str) : format & 2 ? unescape(str) : decodeURI(str);; //  -_.!~*'() //  ,/?:@&=+$#"
  }
  this.JsonParse = function (ObjText, format) {
    if (typeof ObjText == "string")
      ObjText = eval("(" + ObjText + ")")
    if (format) {
      return function callblack(a) {
        for (var i in a) {
          a[i] = callblack(a[i]);
        }
        return a.constructor == Array ? Api.ArrayFormat(a) : a
      }(ObjText)
    }
    return ObjText
  }
  this.format = function (FileName, charset, mode, toCharset) {
    var ADO = new ActiveXObject('Adodb.Stream')
    ADO.Mode = 3
    if (charset) ADO.Charset = charset
    if (mode & 1) { //读取文件
      ADO.Type = mode & 4 ? 2 : 1
      ADO.Open()
      ADO.LoadFromFile(FileName)
      ADO.Type = mode & 2 ? 1 : 2
    } else {
      if (typeof FileName == "string") {
        ADO.Type = 2; // 1=adTypeBinary 2=adTypeText 
        ADO.Open();
        ADO.WriteText("0")
        var i = ADO.Size
        ADO.WriteText(FileName)
        ADO.Position = 0
        if (toCharset) ADO.Charset = toCharset
        if (mode & 2) ADO.Type = 1
        ADO.Position = i
      } else {
        ADO.Type = 1; // 1=adTypeBinary 2=adTypeText 
        ADO.Open();
        ADO.Write(FileName);
        ADO.Position = 0
        ADO.Type = mode & 2 ? 1 : 2
      }
    }
    var Text = mode & 2 ? ADO.Read() : ADO.ReadText()
    ADO.Close()
    return Text
  }
  this.HtmlFormat = function (HTML) {
    HTML = HTML.replace(/<(?:br\s*[\/]?|\/(?:p|tr|li))\s*>/gi, "\n")
    HTML = HTML.replace(/<(style|script|iframe)[^>]*?>[\s\S]*?<\/\1\s*>/gi, '')
    HTML = HTML.replace(/<[^>]+?>/g, '')
    var arrEntities = { 'lt': '<', 'gt': '>', 'nbsp': ' ', 'amp': '&', 'quot': '"' };
    HTML = HTML.replace(/&(lt|gt|nbsp|amp|quot);/ig, function ($0, $1) { return arrEntities[$1]; });
    return HTML.replace(/&#(\d+);/g, function ($0, $1) { return String.fromCharCode($1); })
  };
  function dataFormat(Format) {
    var xml_dom = new ActiveXObject("MSXML2.DOMDocument");
    var tmpNode = xml_dom.createElement("tmpNode");
    tmpNode.dataType = Format || "bin.base64";
    return tmpNode
  }
  this.Base64Encode = function (fileSpec, charset, mode) {
    var tmpNode = dataFormat()
    tmpNode.nodeTypedValue = this.format(fileSpec, charset, mode | 2); // -1=adReadAll 
    return tmpNode.text.replace(/\n/g, "");
  }
  this.Base64Decode = function (Base64Str) {
    var tmpNode = dataFormat()
    tmpNode.text = Base64Str;
    return tmpNode.nodeTypedValue;
  }
  // Type MD5_CTX
  // dwNUMa      As Long 0
  // dwNUMb      As Long 4
  // Buffer(15)  As Byte 8
  // cIN(63)     As Byte 24
  // cDig(15)    As Byte 88
  // End Type
  this.MD5 = function (data, mode) {
    var stcContext = Api.Malloc(104)
    var Buffer = Api.Malloc()
    Api.ECall("advapi32", "MD5Init", stcContext.GetPtr(0))
    if (mode) { //文件
      data = this.format(data, null, 1 + 2)
    }
    if (typeof data == "string") {
      Buffer.FromString = Api.StrConv(data, 0x80)
    } else {
      Buffer.FromBytes = data
    }
    var i = Buffer.Size
    if (i >= 0) {
      Api.ECall("advapi32", "MD5Update", stcContext.GetPtr(0), Buffer.GetPtr(0), i + 1)
    } else {
      Api.ECall("advapi32", "MD5Update", stcContext.GetPtr(0), 0, 0)
    }
    Api.ECall("advapi32", "MD5Final", stcContext.GetPtr(0))
    if (stcContext.Read(0, 4)) {
      var Result = ""
      for (i = 0; i <= 15; i++) {
        data = stcContext.Read(88 + i, 1).toString(16)
        Result += data.length == 1 ? "0" + data : data
      }
      return Result.toUpperCase()
    }
  }
}