/lib/mg_utils.js
JavaScript | 241 lines | 163 code | 26 blank | 52 comment | 54 complexity | 784032ba3458e57a7677bdc8fcdb9ac9 MD5 | raw file
- /* UTF8 encoding/decoding functions
- * Copyright (c) 2006 by Ali Farhadi.
- * released under the terms of the Gnu Public License.
- * see the GPL for details.
- *
- * Email: ali[at]farhadi[dot]ir
- * Website: http://farhadi.ir/
- */
- //an alias of String.fromCharCode
- function chr(code)
- {
- return String.fromCharCode(code);
- }
- //returns utf8 encoded charachter of a unicode value.
- //code must be a number indicating the Unicode value.
- //returned value is a string between 1 and 4 charachters.
- function code2utf(code)
- {
- if (code < 128) return chr(code);
- if (code < 2048) return chr(192+(code>>6)) + chr(128+(code&63));
- if (code < 65536) return chr(224+(code>>12)) + chr(128+((code>>6)&63)) + chr(128+(code&63));
- if (code < 2097152) return chr(240+(code>>18)) + chr(128+((code>>12)&63)) + chr(128+((code>>6)&63)) + chr(128+(code&63));
- }
- //it is a private function for internal use in utf8Encode function
- function _utf8Encode(str)
- {
- var utf8str = new Array();
- for (var i=0; i<str.length; i++) {
- utf8str[i] = code2utf(str.charCodeAt(i));
- }
- return utf8str.join('');
- }
- //Encodes a unicode string to UTF8 format.
- exports.utf8Encode = function(str)
- {
- var utf8str = new Array();
- var pos,j = 0;
- var tmpStr = '';
-
- while ((pos = str.search(/[^\x00-\x7F]/)) != -1) {
- tmpStr = str.match(/([^\x00-\x7F]+[\x00-\x7F]{0,10})+/)[0];
- utf8str[j++] = str.substr(0, pos);
- utf8str[j++] = _utf8Encode(tmpStr);
- str = str.substr(pos + tmpStr.length);
- }
-
- utf8str[j++] = str;
- return utf8str.join('');
- }
- //it is a private function for internal use in utf8Decode function
- function _utf8Decode(utf8str)
- {
- var str = new Array();
- var code,code2,code3,code4,j = 0;
- for (var i=0; i<utf8str.length; ) {
- code = utf8str.charCodeAt(i++);
- if (code > 127) code2 = utf8str.charCodeAt(i++);
- if (code > 223) code3 = utf8str.charCodeAt(i++);
- if (code > 239) code4 = utf8str.charCodeAt(i++);
-
- if (code < 128) str[j++]= chr(code);
- else if (code < 224) str[j++] = chr(((code-192)<<6) + (code2-128));
- else if (code < 240) str[j++] = chr(((code-224)<<12) + ((code2-128)<<6) + (code3-128));
- else str[j++] = chr(((code-240)<<18) + ((code2-128)<<12) + ((code3-128)<<6) + (code4-128));
- }
- return str.join('');
- }
- //Decodes a UTF8 formated string
- exports.utf8Decode = function(utf8str)
- {
- var str = new Array();
- var pos = 0;
- var tmpStr = '';
- var j=0;
- while ((pos = utf8str.search(/[^\x00-\x7F]/)) != -1) {
- tmpStr = utf8str.match(/([^\x00-\x7F]+[\x00-\x7F]{0,10})+/)[0];
- str[j++]= utf8str.substr(0, pos) + _utf8Decode(tmpStr);
- utf8str = utf8str.substr(pos + tmpStr.length);
- }
-
- str[j++] = utf8str;
- return str.join('');
- }
- exports.ksort = function(inputArr, sort_flags) {
- // http://kevin.vanzonneveld.net
- // + original by: GeekFG (http://geekfg.blogspot.com)
- // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
- // + improved by: Brett Zamir (http://brett-zamir.me)
- // % note 1: The examples are correct, this is a new way
- // % note 2: This function deviates from PHP in returning a copy of the array instead
- // % note 2: of acting by reference and returning true; this was necessary because
- // % note 2: IE does not allow deleting and re-adding of properties without caching
- // % note 2: of property position; you can set the ini of "phpjs.strictForIn" to true to
- // % note 2: get the PHP behavior, but use this only if you are in an environment
- // % note 2: such as Firefox extensions where for-in iteration order is fixed and true
- // % note 2: property deletion is supported. Note that we intend to implement the PHP
- // % note 2: behavior by default if IE ever does allow it; only gives shallow copy since
- // % note 2: is by reference in PHP anyways
- // % note 3: Since JS objects' keys are always strings, and (the
- // % note 3: default) SORT_REGULAR flag distinguishes by key type,
- // % note 3: if the content is a numeric string, we treat the
- // % note 3: "original type" as numeric.
- // - depends on: i18n_loc_get_default
- // - depends on: strnatcmp
- // * example 1: data = {d: 'lemon', a: 'orange', b: 'banana', c: 'apple'};
- // * example 1: data = ksort(data);
- // * results 1: {a: 'orange', b: 'banana', c: 'apple', d: 'lemon'}
- // * example 2: ini_set('phpjs.strictForIn', true);
- // * example 2: data = {2: 'van', 3: 'Zonneveld', 1: 'Kevin'};
- // * example 2: ksort(data);
- // * results 2: data == {1: 'Kevin', 2: 'van', 3: 'Zonneveld'}
- // * returns 2: true
- var tmp_arr={}, keys=[], sorter, i, k, that=this, strictForIn = false, populateArr = {};
- switch (sort_flags) {
- case 'SORT_STRING': // compare items as strings
- sorter = function (a, b) {
- return that.strnatcmp(a, b);
- };
- break;
- case 'SORT_LOCALE_STRING': // compare items as strings, based on the current locale (set with i18n_loc_set_default() as of PHP6)
- var loc = this.i18n_loc_get_default();
- sorter = this.php_js.i18nLocales[loc].sorting;
- break;
- case 'SORT_NUMERIC': // compare items numerically
- sorter = function (a, b) {
- return ((a+0) - (b+0));
- };
- break;
- // case 'SORT_REGULAR': // compare items normally (don't change types)
- default:
- sorter = function (a, b) {
- var aFloat = parseFloat(a),
- bFloat = parseFloat(b),
- aNumeric = aFloat+'' === a,
- bNumeric = bFloat+'' === b;
- if (aNumeric && bNumeric) {
- return aFloat > bFloat ? 1 : aFloat < bFloat ? -1 : 0;
- }
- else if (aNumeric && !bNumeric) {
- return 1;
- }
- else if (!aNumeric && bNumeric) {
- return -1;
- }
- return a > b ? 1 : a < b ? -1 : 0;
- };
- break;
- }
- // Make a list of key names
- for (k in inputArr) {
- if (inputArr.hasOwnProperty(k)) {
- keys.push(k);
- }
- }
- keys.sort(sorter);
- // BEGIN REDUNDANT
- this.php_js = this.php_js || {};
- this.php_js.ini = this.php_js.ini || {};
- // END REDUNDANT
- strictForIn = this.php_js.ini['phpjs.strictForIn'] && this.php_js.ini['phpjs.strictForIn'].local_value &&
- this.php_js.ini['phpjs.strictForIn'].local_value !== 'off';
- populateArr = strictForIn ? inputArr : populateArr;
- // Rebuild array with sorted key names
- for (i = 0; i < keys.length; i++) {
- k = keys[i];
- tmp_arr[k] = inputArr[k];
- if (strictForIn) {
- delete inputArr[k];
- }
- }
- for (i in tmp_arr) {
- if (tmp_arr.hasOwnProperty(i)) {
- populateArr[i] = tmp_arr[i];
- }
- }
- return strictForIn || populateArr;
- }
- // PHP's function for building a query string.
- function urlencode (str) {
- str = (str+'').toString();
- // Tilde should be allowed unescaped in future versions of PHP (as reflected below), but if you want to reflect current
- // PHP behavior, you would need to add ".replace(/~/g, '%7E');" to the following.
- return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/~/g,'%7E').
- replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+');
- }
- exports.http_build_query = function(formdata, numeric_prefix, arg_separator) {
- var value, key, tmp = [], that = this;
- var _http_build_query_helper = function (key, val, arg_separator) {
- var k, tmp = [];
- if (val === true) {
- val = "1";
- } else if (val === false) {
- val = "0";
- }
- if (val !== null && typeof(val) === "object") {
- for (k in val) {
- if (val[k] !== null) {
- tmp.push(_http_build_query_helper(key + "[" + k + "]", val[k], arg_separator));
- }
- }
- return tmp.join(arg_separator);
- } else if (typeof(val) !== "function") {
- return urlencode(key) + "=" + urlencode(val);
- } else {
- throw new Error('There was an error processing for http_build_query().');
- }
- };
- if (!arg_separator) {
- arg_separator = "&";
- }
- for (key in formdata) {
- value = formdata[key];
- if (numeric_prefix && !isNaN(key)) {
- key = String(numeric_prefix) + key;
- }
- tmp.push(_http_build_query_helper(key, value, arg_separator));
- }
- return tmp.join(arg_separator);
- }