CCFileUtils.js 37 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820
  1. /****************************************************************************
  2. Copyright (c) 2010-2012 cocos2d-x.org
  3. Copyright (c) 2008-2010 Ricardo Quesada
  4. Copyright (c) 2011 Zynga Inc.
  5. http://www.cocos2d-x.org
  6. Permission is hereby granted, free of charge, to any person obtaining a copy
  7. of this software and associated documentation files (the "Software"), to deal
  8. in the Software without restriction, including without limitation the rights
  9. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. copies of the Software, and to permit persons to whom the Software is
  11. furnished to do so, subject to the following conditions:
  12. The above copyright notice and this permission notice shall be included in
  13. all copies or substantial portions of the Software.
  14. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. THE SOFTWARE.
  21. ****************************************************************************/
  22. /**
  23. * @constant
  24. * @type Number
  25. */
  26. cc.SAX_NONE = 0;
  27. /**
  28. * @constant
  29. * @type Number
  30. */
  31. cc.SAX_KEY = 1;
  32. /**
  33. * @constant
  34. * @type Number
  35. */
  36. cc.SAX_DICT = 2;
  37. /**
  38. * @constant
  39. * @type Number
  40. */
  41. cc.SAX_INT = 3;
  42. /**
  43. * @constant
  44. * @type Number
  45. */
  46. cc.SAX_REAL = 4;
  47. /**
  48. * @constant
  49. * @type Number
  50. */
  51. cc.SAX_STRING = 5;
  52. /**
  53. * @constant
  54. * @type Number
  55. */
  56. cc.SAX_ARRAY = 6;
  57. //Compatibility with IE9
  58. var Uint8Array = Uint8Array || Array;
  59. if (/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent)) {
  60. var IEBinaryToArray_ByteStr_Script =
  61. "<!-- IEBinaryToArray_ByteStr -->\r\n" +
  62. //"<script type='text/vbscript'>\r\n" +
  63. "Function IEBinaryToArray_ByteStr(Binary)\r\n" +
  64. " IEBinaryToArray_ByteStr = CStr(Binary)\r\n" +
  65. "End Function\r\n" +
  66. "Function IEBinaryToArray_ByteStr_Last(Binary)\r\n" +
  67. " Dim lastIndex\r\n" +
  68. " lastIndex = LenB(Binary)\r\n" +
  69. " if lastIndex mod 2 Then\r\n" +
  70. " IEBinaryToArray_ByteStr_Last = Chr( AscB( MidB( Binary, lastIndex, 1 ) ) )\r\n" +
  71. " Else\r\n" +
  72. " IEBinaryToArray_ByteStr_Last = " + '""' + "\r\n" +
  73. " End If\r\n" +
  74. "End Function\r\n";// +
  75. //"</script>\r\n";
  76. // inject VBScript
  77. //document.write(IEBinaryToArray_ByteStr_Script);
  78. var myVBScript = document.createElement('script');
  79. myVBScript.type = "text/vbscript";
  80. myVBScript.textContent = IEBinaryToArray_ByteStr_Script;
  81. document.body.appendChild(myVBScript);
  82. // helper to convert from responseBody to a "responseText" like thing
  83. cc._convertResponseBodyToText = function (binary) {
  84. var byteMapping = {};
  85. for (var i = 0; i < 256; i++) {
  86. for (var j = 0; j < 256; j++) {
  87. byteMapping[ String.fromCharCode(i + j * 256) ] =
  88. String.fromCharCode(i) + String.fromCharCode(j);
  89. }
  90. }
  91. var rawBytes = IEBinaryToArray_ByteStr(binary);
  92. var lastChr = IEBinaryToArray_ByteStr_Last(binary);
  93. return rawBytes.replace(/[\s\S]/g,
  94. function (match) {
  95. return byteMapping[match];
  96. }) + lastChr;
  97. };
  98. }
  99. /**
  100. * @namespace
  101. */
  102. cc.FileUtils = cc.Class.extend({
  103. _fileDataCache:null,
  104. _textFileCache:null,
  105. _directory:null,
  106. _filenameLookupDict:null,
  107. _searchResolutionsOrderArray:null,
  108. _searchPathArray:null,
  109. _defaultResRootPath:"",
  110. ctor:function () {
  111. this._fileDataCache = {};
  112. this._textFileCache = {};
  113. this._searchPathArray = [];
  114. this._searchPathArray.push(this._defaultResRootPath);
  115. this._searchResolutionsOrderArray = [];
  116. this._searchResolutionsOrderArray.push("");
  117. },
  118. /**
  119. * <p>
  120. * Purges the file searching cache. <br/>
  121. * <br/>
  122. * @note It should be invoked after the resources were updated. <br/>
  123. * For instance, in the CocosPlayer sample, every time you run application from CocosBuilder, <br/>
  124. * All the resources will be downloaded to the writable folder, before new js app launchs, <br/>
  125. * this method should be invoked to clean the file search cache.
  126. * </p>
  127. */
  128. purgeCachedEntries:function(){
  129. this._searchPathArray.length = 0;
  130. },
  131. /**
  132. * Get Byte Array from file
  133. * @function
  134. * @param {String} fileName The resource file name which contain the path
  135. * @param {String} mode mode The read mode of the file
  136. * @param {Number} size If get the file data succeed the it will be the data size,or it will be 0
  137. * @warning If you get the file data succeed,you must delete it after used.
  138. */
  139. getByteArrayFromFile:function (fileName, mode, size) {
  140. fileName = this.fullPathForFilename(fileName);
  141. if (this._fileDataCache[fileName])
  142. return this._fileDataCache[fileName];
  143. return this._loadBinaryFileData(fileName);
  144. },
  145. _getXMLHttpRequest:function () {
  146. if (window.XMLHttpRequest) {
  147. return new window.XMLHttpRequest();
  148. } else {
  149. return new ActiveXObject("MSXML2.XMLHTTP");
  150. }
  151. },
  152. unloadBinaryFileData:function (fileUrl) {
  153. if (this._fileDataCache[fileUrl])
  154. delete this._fileDataCache[fileUrl];
  155. },
  156. preloadBinaryFileData:function (fileUrl, selector, target) {
  157. fileUrl = this.fullPathForFilename(fileUrl);
  158. var selfPointer = this;
  159. var xhr = this._getXMLHttpRequest();
  160. xhr.open("GET", fileUrl, true);
  161. if (/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent)) {
  162. // IE-specific logic here
  163. xhr.setRequestHeader("Accept-Charset", "x-user-defined");
  164. xhr.onreadystatechange = function (event) {
  165. if (xhr.readyState == 4) {
  166. if (xhr.status == 200) {
  167. var fileContents = cc._convertResponseBodyToText(xhr["responseBody"]);
  168. if (fileContents)
  169. selfPointer._fileDataCache[fileUrl] = selfPointer._stringConvertToArray(fileContents);
  170. } else {
  171. cc.doCallback(selector, target, fileUrl);
  172. }
  173. cc.doCallback(selector, target);
  174. }
  175. };
  176. } else {
  177. if (xhr.overrideMimeType)
  178. xhr.overrideMimeType("text\/plain; charset=x-user-defined");
  179. xhr.onload = function (e) {
  180. var fileContents = xhr.responseText;
  181. if (fileContents) {
  182. selfPointer._fileDataCache[fileUrl] = selfPointer._stringConvertToArray(fileContents);
  183. } else {
  184. cc.doCallback(selector, target, fileUrl);
  185. }
  186. cc.doCallback(selector, target);
  187. };
  188. }
  189. xhr.send(null);
  190. },
  191. _loadBinaryFileData:function (fileUrl) {
  192. var req = this._getXMLHttpRequest();
  193. req.open('GET', fileUrl, false);
  194. var arrayInfo = null;
  195. if (/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent)) {
  196. req.setRequestHeader("Accept-Charset", "x-user-defined");
  197. req.send(null);
  198. if (req.status != 200) {
  199. cc.log("cocos2d: Unable to load file: " + fileUrl);
  200. return null;
  201. }
  202. var fileContents = cc._convertResponseBodyToText(req["responseBody"]);
  203. if (fileContents) {
  204. arrayInfo = this._stringConvertToArray(fileContents);
  205. this._fileDataCache[fileUrl] = arrayInfo;
  206. }
  207. } else {
  208. if (req.overrideMimeType)
  209. req.overrideMimeType('text\/plain; charset=x-user-defined');
  210. req.send(null);
  211. if (req.status != 200) {
  212. cc.log("cocos2d: Unable to load file: " + fileUrl);
  213. return null;
  214. }
  215. arrayInfo = this._stringConvertToArray(req.responseText);
  216. this._fileDataCache[fileUrl] = arrayInfo;
  217. }
  218. return arrayInfo;
  219. },
  220. _stringConvertToArray:function (strData) {
  221. if (!strData)
  222. return null;
  223. var arrData = new Uint8Array(strData.length);
  224. for (var i = 0; i < strData.length; i++) {
  225. arrData[i] = strData.charCodeAt(i) & 0xff;
  226. }
  227. return arrData;
  228. },
  229. unloadTextFileData:function (fileUrl) {
  230. fileUrl = this.fullPathForFilename(fileUrl);
  231. if (this._textFileCache[fileUrl])
  232. delete this._textFileCache[fileUrl];
  233. },
  234. preloadTextFileData:function (fileUrl, selector, target) {
  235. fileUrl = this.fullPathForFilename(fileUrl);
  236. var selfPointer = this;
  237. var xhr = this._getXMLHttpRequest();
  238. xhr.open("GET", fileUrl, true);
  239. if (/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent)) {
  240. // IE-specific logic here
  241. xhr.setRequestHeader("Accept-Charset", "utf-8");
  242. xhr.onreadystatechange = function (event) {
  243. if (xhr.readyState == 4) {
  244. if (xhr.status == 200) {
  245. var fileContents = xhr.responseText;
  246. if (fileContents)
  247. selfPointer._textFileCache[fileUrl] = fileContents;
  248. } else {
  249. cc.doCallback(selector, target,fileUrl);
  250. }
  251. cc.doCallback(selector, target);
  252. }
  253. };
  254. } else {
  255. if (xhr.overrideMimeType)
  256. xhr.overrideMimeType("text\/plain; charset=utf-8");
  257. xhr.onload = function (e) {
  258. if (xhr.responseText) {
  259. selfPointer._textFileCache[fileUrl] = xhr.responseText;
  260. } else {
  261. cc.doCallback(selector, target,fileUrl);
  262. }
  263. cc.doCallback(selector, target);
  264. };
  265. }
  266. xhr.send(null);
  267. },
  268. _loadTextFileData:function (fileUrl) {
  269. var req = this._getXMLHttpRequest();
  270. req.open('GET', fileUrl, false);
  271. var fileContents = null;
  272. if (/msie/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent)) {
  273. req.setRequestHeader("Accept-Charset", "utf-8");
  274. } else {
  275. if (req.overrideMimeType)
  276. req.overrideMimeType('text\/plain; charset=utf-8');
  277. }
  278. req.send(null);
  279. if (req.status != 200)
  280. return null;
  281. fileContents = req.responseText;
  282. if (fileContents) {
  283. this._textFileCache[fileUrl] = fileContents;
  284. }
  285. return fileContents;
  286. },
  287. /**
  288. * Gets resource file data
  289. * @param {String} fileUrl The resource file name which contains the path.
  290. * @returns {String}
  291. */
  292. getTextFileData:function (fileUrl) {
  293. fileUrl = this.fullPathForFilename(fileUrl);
  294. if (this._textFileCache[fileUrl])
  295. return this._textFileCache[fileUrl];
  296. return this._loadTextFileData(fileUrl);
  297. },
  298. /**
  299. * Get resource file data from zip file
  300. * @function
  301. * @param {String} pszZipFilePath
  302. * @param {String} fileName fileName The resource file name which contain the relative path of zip file
  303. * @param {Number} size size If get the file data succeed the it will be the data size,or it will be 0
  304. * @warning If you get the file data succeed,you must delete it after used.
  305. * @deprecated
  306. */
  307. getFileDataFromZip:function (pszZipFilePath, fileName, size) {
  308. },
  309. /**
  310. * removes the HD suffix from a path
  311. * @function
  312. * @param {String} path
  313. * @deprecated
  314. */
  315. removeSuffixFromFile:function (path) {
  316. },
  317. //////////////////////////////////////////////////////////////////////////
  318. // Notification support when getByteArrayFromFile from invalid file path.
  319. //////////////////////////////////////////////////////////////////////////
  320. /**
  321. * Notification support when getByteArrayFromFile from invalid file path.
  322. * @function
  323. * @type {Boolean}
  324. */
  325. popupNotify:true,
  326. /**
  327. * Generate the absolute path of the file.
  328. * @function
  329. * @param {String} pszRelativePath
  330. * @return {String} The absolute path of the file.
  331. * @warning We only add the ResourcePath before the relative path of the file. <br/>
  332. * If you have not set the ResourcePath,the function add "/NEWPLUS/TDA_DATA/UserData/" as default.<br/>
  333. * You can set ResourcePath by function void setResourcePath(const char *resourcePath);
  334. */
  335. fullPathFromRelativePath:function (pszRelativePath) {
  336. return pszRelativePath;
  337. },
  338. /**
  339. * <p>
  340. * Returns the fullpath for a given filename. </br>
  341. * First it will try to get a new filename from the "filenameLookup" dictionary. </br>
  342. * If a new filename can't be found on the dictionary, it will use the original filename. </br>
  343. * Then it will try obtain the full path of the filename using the CCFileUtils search rules: resources directory and search paths. </br>
  344. * The file search is based on the array element order of search paths and resolution directories. </br>
  345. * </br>
  346. * For instance: </br>
  347. * </br>
  348. * We set two elements("/mnt/sdcard/", "internal_dir/") to search paths vector by setSearchPaths, </br>
  349. * and set three elements("resources-ipadhd/", "resources-ipad/", "resources-iphonehd") </br>
  350. * to resolutions vector by setSearchResolutionsOrder. The "internal_dir" is relative to "Resources/". </br>
  351. * </br>
  352. * If we have a file named 'sprite.png', the mapping in fileLookup dictionary contains `key: sprite.png -> value: sprite.pvr.gz`. </br>
  353. * Firstly, it will replace 'sprite.png' with 'sprite.pvr.gz', then searching the file sprite.pvr.gz as follows: </br>
  354. * /mnt/sdcard/resources-ipadhd/sprite.pvr.gz (if not found, search next) </br>
  355. * /mnt/sdcard/resources-ipad/sprite.pvr.gz (if not found, search next) </br>
  356. * /mnt/sdcard/resources-iphonehd/sprite.pvr.gz (if not found, search next) </br>
  357. * /mnt/sdcard/sprite.pvr.gz (if not found, search next) </br>
  358. * internal_dir/resources-ipadhd/sprite.pvr.gz (if not found, search next) </br>
  359. * internal_dir/resources-ipad/sprite.pvr.gz (if not found, search next) </br>
  360. * internal_dir/resources-iphonehd/sprite.pvr.gz (if not found, search next) </br>
  361. * internal_dir/sprite.pvr.gz (if not found, return "sprite.png") </br>
  362. * </br>
  363. * If the filename contains relative path like "gamescene/uilayer/sprite.png", </br>
  364. * and the mapping in fileLookup dictionary contains `key: gamescene/uilayer/sprite.png -> value: gamescene/uilayer/sprite.pvr.gz`. </br>
  365. * The file search order will be: </br>
  366. * /mnt/sdcard/gamescene/uilayer/resources-ipadhd/sprite.pvr.gz (if not found, search next) </br>
  367. * /mnt/sdcard/gamescene/uilayer/resources-ipad/sprite.pvr.gz (if not found, search next) </br>
  368. * /mnt/sdcard/gamescene/uilayer/resources-iphonehd/sprite.pvr.gz (if not found, search next) </br>
  369. * /mnt/sdcard/gamescene/uilayer/sprite.pvr.gz (if not found, search next) </br>
  370. * internal_dir/gamescene/uilayer/resources-ipadhd/sprite.pvr.gz (if not found, search next) </br>
  371. * internal_dir/gamescene/uilayer/resources-ipad/sprite.pvr.gz (if not found, search next) </br>
  372. * internal_dir/gamescene/uilayer/resources-iphonehd/sprite.pvr.gz (if not found, search next) </br>
  373. * internal_dir/gamescene/uilayer/sprite.pvr.gz (if not found, return "gamescene/uilayer/sprite.png") </br>
  374. * </br>
  375. * If the new file can't be found on the file system, it will return the parameter pszFileName directly. </br>
  376. * </br>
  377. * This method was added to simplify multiplatform support. Whether you are using cocos2d-js or any cross-compilation toolchain like StellaSDK or Apportable, </br>
  378. * you might need to load different resources for a given file in the different platforms.
  379. * </p>
  380. * @param {String} filename
  381. * @return {String} full path for a given filename.
  382. */
  383. fullPathForFilename:function (filename) {
  384. if (filename.indexOf("://") > 0) {
  385. return filename;
  386. }
  387. var found = false;
  388. var newFileName = this._getNewFilename(filename);
  389. var fullPath;
  390. //if (newFileName && newFileName.length > 1)
  391. // return newFileName;
  392. for (var i = 0; i < this._searchPathArray.length; i++) {
  393. var searchPath = this._searchPathArray[i];
  394. for (var j = 0; j < this._searchResolutionsOrderArray.length; j++) {
  395. var resourceDirectory = this._searchResolutionsOrderArray[j];
  396. fullPath = this._getPathForFilename(newFileName, resourceDirectory, searchPath);
  397. if (fullPath) {
  398. found = true;
  399. break;
  400. }
  401. }
  402. if (found)
  403. break;
  404. }
  405. return found ? fullPath : newFileName;
  406. },
  407. /**
  408. * <p>
  409. * Loads the filenameLookup dictionary from the contents of a filename. <br/>
  410. * <br/>
  411. * @note The plist file name should follow the format below: <br/>
  412. * <?xml version="1.0" encoding="UTF-8"?> <br/>
  413. * <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <br/>
  414. * <plist version="1.0"> <br/>
  415. * <dict> <br/>
  416. * <key>filenames</key> <br/>
  417. * <dict> <br/>
  418. * <key>sounds/click.wav</key> <br/>
  419. * <string>sounds/click.caf</string> <br/>
  420. * <key>sounds/endgame.wav</key> <br/>
  421. * <string>sounds/endgame.caf</string> <br/>
  422. * <key>sounds/gem-0.wav</key> <br/>
  423. * <string>sounds/gem-0.caf</string> <br/>
  424. * </dict> <br/>
  425. * <key>metadata</key> <br/>
  426. * <dict> <br/>
  427. * <key>version</key> <br/>
  428. * <integer>1</integer> <br/>
  429. * </dict> <br/>
  430. * </dict> <br/>
  431. * </plist> <br/>
  432. * </p>
  433. * @param {String} filename The plist file name.
  434. */
  435. loadFilenameLookup:function (filename) {
  436. var fullPath = this.fullPathForFilename(filename);
  437. if (fullPath.length > 0) {
  438. var dict = cc.SAXParser.getInstance().parse(fullPath);
  439. var metadataDict = dict["metadata"];
  440. var version = parseInt(metadataDict["version"]);
  441. if (version != 1) {
  442. cc.log("cocos2d: ERROR: Invalid filenameLookup dictionary version: " + version + ". Filename: " + filename);
  443. return;
  444. }
  445. this.setFilenameLookupDictionary(dict["filenames"]);
  446. }
  447. },
  448. /**
  449. * Sets the filenameLookup dictionary.
  450. * @param {Object} filenameLookupDict The dictionary for replacing filename.
  451. */
  452. setFilenameLookupDictionary:function (filenameLookupDict) {
  453. this._filenameLookupDict = filenameLookupDict;
  454. },
  455. /**
  456. * Gets full path from a file name and the path of the reletive file.
  457. * @param {String} filename The file name.
  458. * @param {String} relativeFile The path of the relative file.
  459. * @return {String} The full path.
  460. */
  461. fullPathFromRelativeFile:function (filename, relativeFile) {
  462. var tmpPath;
  463. if (filename) {
  464. tmpPath = relativeFile.substring(0, relativeFile.lastIndexOf("/") + 1);
  465. return tmpPath + filename;
  466. }
  467. else {
  468. tmpPath = relativeFile.substring(0, relativeFile.lastIndexOf("."));
  469. tmpPath = tmpPath + ".png";
  470. return tmpPath;
  471. }
  472. },
  473. /**
  474. * <p>
  475. * Sets the array that contains the search order of the resources.
  476. * </p>
  477. * @see getSearchResolutionsOrder(void), fullPathForFilename(const char*).
  478. * @param {Array} searchResolutionsOrder
  479. */
  480. setSearchResolutionsOrder:function (searchResolutionsOrder) {
  481. this._searchResolutionsOrderArray = searchResolutionsOrder;
  482. },
  483. /**
  484. * Gets the array that contains the search order of the resources.
  485. * @see setSearchResolutionsOrder(), fullPathForFilename(const char*).
  486. * @return {Array}
  487. */
  488. getSearchResolutionsOrder:function () {
  489. return this._searchResolutionsOrderArray;
  490. },
  491. /**
  492. * <p>
  493. * Array of search paths. <br/>
  494. * You can use this array to modify the search path of the resources. <br/>
  495. * If you want to use "themes" or search resources in the "cache", you can do it easily by adding new entries in this array. <br/>
  496. * <br/>
  497. * By default it is an array with only the "" (empty string) element. <br/>
  498. * </p>
  499. * @param {Array} searchPaths
  500. */
  501. setSearchPath:function (searchPaths) {
  502. this._searchPathArray = searchPaths;
  503. },
  504. /**
  505. * return Array of search paths.
  506. * @return {Array}
  507. */
  508. getSearchPath:function () {
  509. return this._searchPathArray;
  510. },
  511. getResourceDirectory:function () {
  512. return this._directory;
  513. },
  514. /**
  515. * Set the ResourcePath,we will find resource in this path
  516. * @function
  517. * @param {String} resourcePath The absolute resource path
  518. * @warning Don't call this function in android and iOS, it has not effect.<br/>
  519. * In android, if you want to read file other than apk, you shoud use invoke getByteArrayFromFile(), and pass the<br/>
  520. * absolute path.
  521. * @deprecated
  522. */
  523. setResourcePath:function (resourcePath) {
  524. },
  525. /**
  526. * Generate an Dictionary of object by file
  527. * @deprecated
  528. * @param fileName The file name of *.plist file
  529. * @return {object} The Dictionary of object generated from the file
  530. */
  531. dictionaryWithContentsOfFile:function (fileName) {
  532. cc.log("dictionaryWithContentsOfFile is deprecated. Use createDictionaryWithContentsOfFile instead");
  533. return this.createDictionaryWithContentsOfFile(fileName);
  534. },
  535. /**
  536. * Generate an Dictionary of object by file
  537. * @param filename The file name of *.plist file
  538. * @return {object} The Dictionary of object generated from the file
  539. */
  540. createDictionaryWithContentsOfFile: function(filename){
  541. return cc.SAXParser.getInstance().parse(filename);
  542. },
  543. /**
  544. * get string from file
  545. * @function
  546. * @param {String} fileName
  547. * @return {String}
  548. */
  549. getStringFromFile:function (fileName) {
  550. return this.getTextFileData(fileName); //cc.SAXParser.getInstance().getList(fileName);
  551. },
  552. /**
  553. * The same meaning as dictionaryWithContentsOfFile(), but it doesn't call autorelease, so the invoker should call release().
  554. * @function
  555. * @param {String} fileName
  556. * @return {object} The Dictionary of object generated from the file
  557. */
  558. dictionaryWithContentsOfFileThreadSafe:function (fileName) {
  559. return cc.SAXParser.getInstance().parse(fileName);
  560. },
  561. /**
  562. * Get the writeable path
  563. * @return {String} The path that can write/read file
  564. * @deprecated
  565. */
  566. getWritablePath:function () {
  567. return "";
  568. },
  569. /**
  570. * Set whether pop-up a message box when the image load failed
  571. * @param {Boolean} notify
  572. */
  573. setPopupNotify:function (notify) {
  574. cc.popupNotify = notify;
  575. },
  576. /**
  577. * Get whether pop-up a message box when the image load failed
  578. * @return {Boolean}
  579. */
  580. isPopupNotify:function () {
  581. return cc.popupNotify;
  582. },
  583. _resourceRootPath:"",
  584. getResourceRootPath:function () {
  585. return this._resourceRootPath;
  586. },
  587. setResourceRootPath:function (resourceRootPath) {
  588. this._resourceRootPath = resourceRootPath;
  589. },
  590. /**
  591. * Gets the new filename from the filename lookup dictionary.
  592. * @param {String} filename
  593. * @return {String|null} The new filename after searching in the filename lookup dictionary. If the original filename wasn't in the dictionary, it will return the original filename.
  594. * @private
  595. */
  596. _getNewFilename:function (filename) {
  597. var newFileName = null;
  598. var fileNameFound = this._filenameLookupDict ? this._filenameLookupDict[filename] : null;
  599. if (!fileNameFound || fileNameFound.length === 0)
  600. newFileName = filename;
  601. else {
  602. newFileName = fileNameFound;
  603. cc.log("FOUND NEW FILE NAME: " + newFileName);
  604. }
  605. return newFileName;
  606. },
  607. /**
  608. * Gets full path for filename, resolution directory and search path.
  609. * @param {String} filename
  610. * @param {String} resourceDirectory
  611. * @param {String} searchPath
  612. * @return {String} The full path of the file. It will return an empty string if the full path of the file doesn't exist.
  613. * @private
  614. */
  615. _getPathForFilename:function (filename, resourceDirectory, searchPath) {
  616. var ret;
  617. var resourceRootPath = this.getResourceRootPath(); //cc.Application.getInstance().getResourceRootPath();
  618. if (filename && (filename.length > 0) && (filename.indexOf('/') === 0 || filename.indexOf("\\") === 0)) {
  619. ret = "";
  620. } else if (resourceRootPath.length > 0) {
  621. ret = resourceRootPath;
  622. if (ret[ret.length - 1] != '\\' && ret[ret.length - 1] != '/')
  623. ret += "/";
  624. } else {
  625. ret = resourceRootPath;
  626. }
  627. var file = filename;
  628. var file_path = "";
  629. var pos = filename.lastIndexOf('/');
  630. if (pos != -1) {
  631. file_path = filename.substr(0, pos + 1);
  632. file = filename.substr(pos + 1);
  633. }
  634. var path = searchPath;
  635. if (path.length > 0 && path.lastIndexOf('/') !== path.length - 1)
  636. path += '/';
  637. if(resourceDirectory && resourceDirectory != "")
  638. path += resourceDirectory+"/";
  639. path += file_path;
  640. if (path.length > 0 && path.lastIndexOf("/") !== path.length - 1)
  641. path += '/';
  642. path += file;
  643. ret += path;
  644. return ret;
  645. },
  646. /**
  647. * Gets full path for the directory and the filename.
  648. * @param {String} directory The directory contains the file we are looking for.
  649. * @param {String} fileName The name of the file.
  650. * @return {Boolean} The full path of the file, if the file can't be found, it will return an empty string.
  651. * @private
  652. */
  653. _getFullPathForDirectoryAndFilename:function(directory, fileName){
  654. },
  655. /**
  656. * <p>
  657. * Sets the array of search paths. <br/>
  658. * <br/>
  659. * You can use this array to modify the search path of the resources. <br/>
  660. * If you want to use "themes" or search resources in the "cache", you can do it easily by adding new entries in this array. <br/>
  661. * <br/>
  662. * @note This method could access relative path and absolute path. <br/>
  663. * If the relative path was passed to the vector, CCFileUtils will add the default resource directory before the relative path. <br/>
  664. * For instance: <br/>
  665. * On Android, the default resource root path is "assets/". <br/>
  666. * If "/mnt/sdcard/" and "resources-large" were set to the search paths vector, <br/>
  667. * "resources-large" will be converted to "assets/resources-large" since it was a relative path.
  668. * </p>
  669. * @see fullPathForFilename(const char*)
  670. * @param {Array} searchPaths The array contains search paths.
  671. */
  672. setSearchPaths:function (searchPaths) {
  673. var existDefaultRootPath = false;
  674. var locPathArray = this._searchPathArray;
  675. locPathArray.length = 0;
  676. for (var i = 0; i < searchPaths.length; i++) {
  677. var iter = searchPaths[i];
  678. var strPrefix;
  679. var path;
  680. if (!this.isAbsolutePath(iter)) { // Not an absolute path
  681. strPrefix = this._defaultResRootPath;
  682. }
  683. path = strPrefix + iter;
  684. if (path.length > 0 && path[path.length - 1] != '/') {
  685. path += "/";
  686. }
  687. if (!existDefaultRootPath && path == this._defaultResRootPath) {
  688. existDefaultRootPath = true;
  689. }
  690. locPathArray.push(path);
  691. }
  692. if (!existDefaultRootPath) {
  693. //cc.log("Default root path doesn't exist, adding it.");
  694. locPathArray.push(this._defaultResRootPath);
  695. }
  696. },
  697. /**
  698. * Add search path.
  699. * @param {String} path
  700. */
  701. addSearchPath:function (path) {
  702. var strPrefix;
  703. if (!this.isAbsolutePath(path)) { // Not an absolute path
  704. strPrefix = this._defaultResRootPath;
  705. }
  706. path = strPrefix + path;
  707. if (path.length > 0 && path[path.length - 1] != '/') {
  708. path += "/";
  709. }
  710. this._searchPathArray.push(path);
  711. },
  712. /**
  713. * Gets the array of search paths.
  714. * @see fullPathForFilename(const char*).
  715. * @return {Array} The array of search paths.
  716. */
  717. getSearchPaths:function(){
  718. },
  719. /**
  720. * Checks whether the path is an absolute path.
  721. * @param {String} strPath The path that needs to be checked.
  722. * @returns {boolean} true if it's an absolute path, otherwise it will return false.
  723. */
  724. isAbsolutePath:function (strPath) {
  725. return (strPath[0] == '/');
  726. }
  727. });
  728. cc.s_SharedFileUtils = null;
  729. /**
  730. * Gets the instance of CCFileUtils.
  731. * @returns {cc.FileUtils}
  732. */
  733. cc.FileUtils.getInstance = function () {
  734. if (cc.s_SharedFileUtils == null) {
  735. cc.s_SharedFileUtils = new cc.FileUtils();
  736. }
  737. return cc.s_SharedFileUtils;
  738. };