PageRenderTime 56ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/mg_utils.js

https://github.com/gengo/mygengo_node
JavaScript | 241 lines | 163 code | 26 blank | 52 comment | 54 complexity | 784032ba3458e57a7677bdc8fcdb9ac9 MD5 | raw file
  1. /* UTF8 encoding/decoding functions
  2. * Copyright (c) 2006 by Ali Farhadi.
  3. * released under the terms of the Gnu Public License.
  4. * see the GPL for details.
  5. *
  6. * Email: ali[at]farhadi[dot]ir
  7. * Website: http://farhadi.ir/
  8. */
  9. //an alias of String.fromCharCode
  10. function chr(code)
  11. {
  12. return String.fromCharCode(code);
  13. }
  14. //returns utf8 encoded charachter of a unicode value.
  15. //code must be a number indicating the Unicode value.
  16. //returned value is a string between 1 and 4 charachters.
  17. function code2utf(code)
  18. {
  19. if (code < 128) return chr(code);
  20. if (code < 2048) return chr(192+(code>>6)) + chr(128+(code&63));
  21. if (code < 65536) return chr(224+(code>>12)) + chr(128+((code>>6)&63)) + chr(128+(code&63));
  22. if (code < 2097152) return chr(240+(code>>18)) + chr(128+((code>>12)&63)) + chr(128+((code>>6)&63)) + chr(128+(code&63));
  23. }
  24. //it is a private function for internal use in utf8Encode function
  25. function _utf8Encode(str)
  26. {
  27. var utf8str = new Array();
  28. for (var i=0; i<str.length; i++) {
  29. utf8str[i] = code2utf(str.charCodeAt(i));
  30. }
  31. return utf8str.join('');
  32. }
  33. //Encodes a unicode string to UTF8 format.
  34. exports.utf8Encode = function(str)
  35. {
  36. var utf8str = new Array();
  37. var pos,j = 0;
  38. var tmpStr = '';
  39. while ((pos = str.search(/[^\x00-\x7F]/)) != -1) {
  40. tmpStr = str.match(/([^\x00-\x7F]+[\x00-\x7F]{0,10})+/)[0];
  41. utf8str[j++] = str.substr(0, pos);
  42. utf8str[j++] = _utf8Encode(tmpStr);
  43. str = str.substr(pos + tmpStr.length);
  44. }
  45. utf8str[j++] = str;
  46. return utf8str.join('');
  47. }
  48. //it is a private function for internal use in utf8Decode function
  49. function _utf8Decode(utf8str)
  50. {
  51. var str = new Array();
  52. var code,code2,code3,code4,j = 0;
  53. for (var i=0; i<utf8str.length; ) {
  54. code = utf8str.charCodeAt(i++);
  55. if (code > 127) code2 = utf8str.charCodeAt(i++);
  56. if (code > 223) code3 = utf8str.charCodeAt(i++);
  57. if (code > 239) code4 = utf8str.charCodeAt(i++);
  58. if (code < 128) str[j++]= chr(code);
  59. else if (code < 224) str[j++] = chr(((code-192)<<6) + (code2-128));
  60. else if (code < 240) str[j++] = chr(((code-224)<<12) + ((code2-128)<<6) + (code3-128));
  61. else str[j++] = chr(((code-240)<<18) + ((code2-128)<<12) + ((code3-128)<<6) + (code4-128));
  62. }
  63. return str.join('');
  64. }
  65. //Decodes a UTF8 formated string
  66. exports.utf8Decode = function(utf8str)
  67. {
  68. var str = new Array();
  69. var pos = 0;
  70. var tmpStr = '';
  71. var j=0;
  72. while ((pos = utf8str.search(/[^\x00-\x7F]/)) != -1) {
  73. tmpStr = utf8str.match(/([^\x00-\x7F]+[\x00-\x7F]{0,10})+/)[0];
  74. str[j++]= utf8str.substr(0, pos) + _utf8Decode(tmpStr);
  75. utf8str = utf8str.substr(pos + tmpStr.length);
  76. }
  77. str[j++] = utf8str;
  78. return str.join('');
  79. }
  80. exports.ksort = function(inputArr, sort_flags) {
  81. // http://kevin.vanzonneveld.net
  82. // + original by: GeekFG (http://geekfg.blogspot.com)
  83. // + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  84. // + improved by: Brett Zamir (http://brett-zamir.me)
  85. // % note 1: The examples are correct, this is a new way
  86. // % note 2: This function deviates from PHP in returning a copy of the array instead
  87. // % note 2: of acting by reference and returning true; this was necessary because
  88. // % note 2: IE does not allow deleting and re-adding of properties without caching
  89. // % note 2: of property position; you can set the ini of "phpjs.strictForIn" to true to
  90. // % note 2: get the PHP behavior, but use this only if you are in an environment
  91. // % note 2: such as Firefox extensions where for-in iteration order is fixed and true
  92. // % note 2: property deletion is supported. Note that we intend to implement the PHP
  93. // % note 2: behavior by default if IE ever does allow it; only gives shallow copy since
  94. // % note 2: is by reference in PHP anyways
  95. // % note 3: Since JS objects' keys are always strings, and (the
  96. // % note 3: default) SORT_REGULAR flag distinguishes by key type,
  97. // % note 3: if the content is a numeric string, we treat the
  98. // % note 3: "original type" as numeric.
  99. // - depends on: i18n_loc_get_default
  100. // - depends on: strnatcmp
  101. // * example 1: data = {d: 'lemon', a: 'orange', b: 'banana', c: 'apple'};
  102. // * example 1: data = ksort(data);
  103. // * results 1: {a: 'orange', b: 'banana', c: 'apple', d: 'lemon'}
  104. // * example 2: ini_set('phpjs.strictForIn', true);
  105. // * example 2: data = {2: 'van', 3: 'Zonneveld', 1: 'Kevin'};
  106. // * example 2: ksort(data);
  107. // * results 2: data == {1: 'Kevin', 2: 'van', 3: 'Zonneveld'}
  108. // * returns 2: true
  109. var tmp_arr={}, keys=[], sorter, i, k, that=this, strictForIn = false, populateArr = {};
  110. switch (sort_flags) {
  111. case 'SORT_STRING': // compare items as strings
  112. sorter = function (a, b) {
  113. return that.strnatcmp(a, b);
  114. };
  115. break;
  116. case 'SORT_LOCALE_STRING': // compare items as strings, based on the current locale (set with i18n_loc_set_default() as of PHP6)
  117. var loc = this.i18n_loc_get_default();
  118. sorter = this.php_js.i18nLocales[loc].sorting;
  119. break;
  120. case 'SORT_NUMERIC': // compare items numerically
  121. sorter = function (a, b) {
  122. return ((a+0) - (b+0));
  123. };
  124. break;
  125. // case 'SORT_REGULAR': // compare items normally (don't change types)
  126. default:
  127. sorter = function (a, b) {
  128. var aFloat = parseFloat(a),
  129. bFloat = parseFloat(b),
  130. aNumeric = aFloat+'' === a,
  131. bNumeric = bFloat+'' === b;
  132. if (aNumeric && bNumeric) {
  133. return aFloat > bFloat ? 1 : aFloat < bFloat ? -1 : 0;
  134. }
  135. else if (aNumeric && !bNumeric) {
  136. return 1;
  137. }
  138. else if (!aNumeric && bNumeric) {
  139. return -1;
  140. }
  141. return a > b ? 1 : a < b ? -1 : 0;
  142. };
  143. break;
  144. }
  145. // Make a list of key names
  146. for (k in inputArr) {
  147. if (inputArr.hasOwnProperty(k)) {
  148. keys.push(k);
  149. }
  150. }
  151. keys.sort(sorter);
  152. // BEGIN REDUNDANT
  153. this.php_js = this.php_js || {};
  154. this.php_js.ini = this.php_js.ini || {};
  155. // END REDUNDANT
  156. strictForIn = this.php_js.ini['phpjs.strictForIn'] && this.php_js.ini['phpjs.strictForIn'].local_value &&
  157. this.php_js.ini['phpjs.strictForIn'].local_value !== 'off';
  158. populateArr = strictForIn ? inputArr : populateArr;
  159. // Rebuild array with sorted key names
  160. for (i = 0; i < keys.length; i++) {
  161. k = keys[i];
  162. tmp_arr[k] = inputArr[k];
  163. if (strictForIn) {
  164. delete inputArr[k];
  165. }
  166. }
  167. for (i in tmp_arr) {
  168. if (tmp_arr.hasOwnProperty(i)) {
  169. populateArr[i] = tmp_arr[i];
  170. }
  171. }
  172. return strictForIn || populateArr;
  173. }
  174. // PHP's function for building a query string.
  175. function urlencode (str) {
  176. str = (str+'').toString();
  177. // Tilde should be allowed unescaped in future versions of PHP (as reflected below), but if you want to reflect current
  178. // PHP behavior, you would need to add ".replace(/~/g, '%7E');" to the following.
  179. return encodeURIComponent(str).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/~/g,'%7E').
  180. replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+');
  181. }
  182. exports.http_build_query = function(formdata, numeric_prefix, arg_separator) {
  183. var value, key, tmp = [], that = this;
  184. var _http_build_query_helper = function (key, val, arg_separator) {
  185. var k, tmp = [];
  186. if (val === true) {
  187. val = "1";
  188. } else if (val === false) {
  189. val = "0";
  190. }
  191. if (val !== null && typeof(val) === "object") {
  192. for (k in val) {
  193. if (val[k] !== null) {
  194. tmp.push(_http_build_query_helper(key + "[" + k + "]", val[k], arg_separator));
  195. }
  196. }
  197. return tmp.join(arg_separator);
  198. } else if (typeof(val) !== "function") {
  199. return urlencode(key) + "=" + urlencode(val);
  200. } else {
  201. throw new Error('There was an error processing for http_build_query().');
  202. }
  203. };
  204. if (!arg_separator) {
  205. arg_separator = "&";
  206. }
  207. for (key in formdata) {
  208. value = formdata[key];
  209. if (numeric_prefix && !isNaN(key)) {
  210. key = String(numeric_prefix) + key;
  211. }
  212. tmp.push(_http_build_query_helper(key, value, arg_separator));
  213. }
  214. return tmp.join(arg_separator);
  215. }