PageRenderTime 49ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/flash/video/gnash-bzr/src/gnash-build/extensions/fileio/fileio.cpp

https://github.com/o1iver/Code-Backup
C++ | 620 lines | 457 code | 93 blank | 70 comment | 30 complexity | 88a2afa6ab5dcb3b55420f2a885c7178 MD5 | raw file
  1. //
  2. // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
  3. // Foundation, Inc
  4. //
  5. // This program is free software; you can redistribute it and/or modify
  6. // it under the terms of the GNU General Public License as published by
  7. // the Free Software Foundation; either version 3 of the License, or
  8. // (at your option) any later version.
  9. //
  10. // This program is distributed in the hope that it will be useful,
  11. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. // GNU General Public License for more details.
  14. //
  15. // You should have received a copy of the GNU General Public License
  16. // along with this program; if not, write to the Free Software
  17. // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  18. #ifdef HAVE_CONFIG_H
  19. #include "gnashconfig.h"
  20. #endif
  21. #include <map>
  22. #include <iostream>
  23. #include <string>
  24. #include <cstdio>
  25. #include <boost/algorithm/string/case_conv.hpp>
  26. #include <dirent.h> // used by scandir()
  27. #include "GnashSystemIOHeaders.h" // used by unlink()
  28. #include <fcntl.h> // used by asyncmode()
  29. //#include "VM.h"
  30. #include "log.h"
  31. #include "fn_call.h"
  32. #include "as_object.h"
  33. #include "builtin_function.h" // need builtin_function
  34. #include "Globals.h"
  35. #include "fileio.h"
  36. #include "Array_as.h" // used by scandir()
  37. using namespace std;
  38. namespace gnash
  39. {
  40. static const int BUFSIZE = 1024;
  41. as_value fileio_fopen(const fn_call& fn);
  42. as_value fileio_fread(const fn_call& fn);
  43. as_value fileio_fgetc(const fn_call& fn);
  44. as_value fileio_fgets(const fn_call& fn);
  45. as_value fileio_gets(const fn_call& fn);
  46. as_value fileio_fwrite(const fn_call& fn);
  47. as_value fileio_fputc(const fn_call& fn);
  48. as_value fileio_fputs(const fn_call& fn);
  49. as_value fileio_puts(const fn_call& fn);
  50. as_value fileio_fclose(const fn_call& fn);
  51. as_value fileio_getchar(const fn_call& fn);
  52. as_value fileio_putchar(const fn_call& fn);
  53. as_value fileio_fflush(const fn_call& fn);
  54. as_value fileio_ftell(const fn_call& fn);
  55. as_value fileio_feof(const fn_call& fn);
  56. as_value fileio_fseek(const fn_call& fn);
  57. as_value fileio_unlink(const fn_call& fn);
  58. as_value fileio_asyncmode(const fn_call& fn);
  59. // <Udo> I needed a scandir() function and implemented it here for simplicity.
  60. // Maybe this should be moved to a dedicated extension and a different class?
  61. // The scandir() syntax comes from PHP, since the C syntax is not quite
  62. // applicable in ActionScript.
  63. // Same applies for unlink(). Maybe a class FileOP or sim. would be
  64. // appriopriate.
  65. as_value fileio_scandir(const fn_call& fn);
  66. LogFile& dbglogfile = LogFile::getDefaultInstance();
  67. // TODO: Document this class !!
  68. class FileIO : public Relay
  69. {
  70. public:
  71. FileIO();
  72. ~FileIO();
  73. bool fopen(const std::string &filespec, const std::string &mode);
  74. int fread(std::string &str);
  75. int fgetc();
  76. std::string &fgets(std::string &str);
  77. int fwrite(const std::string &str);
  78. bool fputc(int c);
  79. bool fputs(const std::string &str);
  80. int fclose();
  81. int fflush();
  82. void rewind();
  83. int fseek(long offset);
  84. int fseek(long offset, int whence);
  85. long ftell();
  86. bool asyncmode(bool async);
  87. bool feof();
  88. bool unlink(const std::string &filespec);
  89. private:
  90. FILE *_stream;
  91. std::string _filespec;
  92. };
  93. static void
  94. attachInterface(as_object& obj)
  95. {
  96. Global_as& gl = getGlobal(obj);
  97. obj.init_member("fopen", gl.createFunction(fileio_fopen));
  98. obj.init_member("fread", gl.createFunction(fileio_fread));
  99. obj.init_member("fgetc", gl.createFunction(fileio_fgetc));
  100. obj.init_member("fgets", gl.createFunction(fileio_fgets));
  101. obj.init_member("gets", gl.createFunction(fileio_fgets));
  102. obj.init_member("getchar", gl.createFunction(fileio_getchar));
  103. obj.init_member("fwrite", gl.createFunction(fileio_fwrite));
  104. obj.init_member("fputc", gl.createFunction(fileio_fputc));
  105. obj.init_member("fputs", gl.createFunction(fileio_fputs));
  106. obj.init_member("puts", gl.createFunction(fileio_puts));
  107. obj.init_member("putchar", gl.createFunction(fileio_putchar));
  108. obj.init_member("fflush", gl.createFunction(fileio_fflush));
  109. obj.init_member("fseek", gl.createFunction(fileio_fseek));
  110. obj.init_member("ftell", gl.createFunction(fileio_ftell));
  111. obj.init_member("asyncmode", gl.createFunction(fileio_asyncmode));
  112. obj.init_member("feof", gl.createFunction(fileio_feof));
  113. obj.init_member("fclose", gl.createFunction(fileio_fclose));
  114. obj.init_member("unlink", gl.createFunction(fileio_unlink));
  115. obj.init_member("scandir", gl.createFunction(fileio_scandir));
  116. }
  117. static as_value
  118. fileio_ctor(const fn_call& fn)
  119. {
  120. as_object* obj = ensure<ValidThis>(fn);
  121. obj->setRelay(new FileIO());
  122. if (fn.nargs > 0) {
  123. IF_VERBOSE_ASCODING_ERRORS(
  124. std::stringstream ss; fn.dump_args(ss);
  125. log_aserror("new FileIO(%s): all arguments discarded",
  126. ss.str().c_str());
  127. );
  128. }
  129. return as_value();
  130. }
  131. FileIO::FileIO()
  132. :
  133. _stream(0)
  134. {
  135. }
  136. FileIO::~FileIO()
  137. {
  138. // GNASH_REPORT_FUNCTION;
  139. fclose();
  140. }
  141. int
  142. FileIO::fflush()
  143. {
  144. // GNASH_REPORT_FUNCTION;
  145. if (_stream) {
  146. return ::fflush(_stream);
  147. }
  148. return -1;
  149. }
  150. void
  151. FileIO::rewind()
  152. {
  153. // GNASH_REPORT_FUNCTION;
  154. if (_stream) {
  155. ::fseek(_stream, 0L, SEEK_SET);
  156. }
  157. }
  158. int
  159. FileIO::fseek(long offset)
  160. {
  161. // GNASH_REPORT_FUNCTION;
  162. if (_stream) {
  163. return ::fseek(_stream, offset, SEEK_SET);
  164. }
  165. return -1;
  166. }
  167. int
  168. FileIO::fseek(long offset, int whence)
  169. {
  170. // GNASH_REPORT_FUNCTION;
  171. if (_stream) {
  172. return ::fseek(_stream, offset, whence);
  173. }
  174. return -1;
  175. }
  176. long
  177. FileIO::ftell()
  178. {
  179. // GNASH_REPORT_FUNCTION;
  180. if (_stream) {
  181. return ::ftell(_stream);
  182. }
  183. return -1;
  184. }
  185. bool
  186. FileIO::asyncmode(bool async)
  187. {
  188. // GNASH_REPORT_FUNCTION;
  189. if (_stream) {
  190. int fd = fileno(_stream);
  191. long flags = fcntl(fd, F_GETFL);
  192. int res;
  193. if (async)
  194. res = fcntl(fd, F_SETFL, flags|O_NONBLOCK);
  195. else
  196. res = fcntl(fd, F_SETFL, flags&(~O_NONBLOCK));
  197. return res>=0;
  198. }
  199. return false;
  200. }
  201. bool
  202. FileIO::feof()
  203. {
  204. // GNASH_REPORT_FUNCTION;
  205. if (_stream) {
  206. return ::feof(_stream);
  207. }
  208. return -1;
  209. }
  210. bool
  211. FileIO::fopen(const string &filespec, const string &mode)
  212. {
  213. // GNASH_REPORT_FUNCTION;
  214. _stream = ::fopen(filespec.c_str(), mode.c_str());
  215. if (_stream) {
  216. return true;
  217. } else {
  218. return false;
  219. }
  220. }
  221. int
  222. FileIO::fread(string &str)
  223. {
  224. // GNASH_REPORT_FUNCTION;
  225. int ret = -1;
  226. if (_stream) {
  227. char buf[BUFSIZE];
  228. memset(buf, 0, BUFSIZE);
  229. ret = ::fread(buf, 1, BUFSIZE, _stream);
  230. if (ret) {
  231. str = buf;
  232. }
  233. }
  234. return ret;
  235. }
  236. int
  237. FileIO::fgetc()
  238. {
  239. // GNASH_REPORT_FUNCTION;
  240. if (_stream) {
  241. return ::fgetc(_stream);
  242. }
  243. return -1;
  244. }
  245. string &
  246. FileIO::fgets(std::string &str)
  247. {
  248. // GNASH_REPORT_FUNCTION;
  249. if (_stream) {
  250. char buf[BUFSIZE];
  251. memset(buf, 0, BUFSIZE);
  252. char* res = ::fgets(buf, BUFSIZE, _stream);
  253. if (res)
  254. str = res;
  255. else
  256. str = ""; // we might want to return NULL to the VM ?
  257. return str;
  258. }
  259. return str;
  260. }
  261. int
  262. FileIO::fwrite(const string &str)
  263. {
  264. // GNASH_REPORT_FUNCTION;
  265. return ::fwrite(str.c_str(), str.size(), 1, _stream);
  266. }
  267. bool
  268. FileIO::fputc(int c)
  269. {
  270. // GNASH_REPORT_FUNCTION;
  271. if (_stream) {
  272. if (::fputc(c, _stream)) {
  273. return true;
  274. }
  275. }
  276. return false;
  277. }
  278. bool
  279. FileIO::fputs(const string &str)
  280. {
  281. // GNASH_REPORT_FUNCTION;
  282. if (_stream) {
  283. if (::fputs(str.c_str(), _stream)) {
  284. return true;
  285. }
  286. }
  287. return false;
  288. }
  289. int
  290. FileIO::fclose()
  291. {
  292. // GNASH_REPORT_FUNCTION;
  293. if (_stream) {
  294. int ret = ::fclose(_stream);
  295. _stream = 0;
  296. return ret;
  297. }
  298. return -1;
  299. }
  300. bool
  301. FileIO::unlink(const std::string &filespec)
  302. {
  303. // GNASH_REPORT_FUNCTION;
  304. return ::unlink(filespec.c_str()) >= 0;
  305. }
  306. as_value
  307. fileio_fopen(const fn_call& fn)
  308. {
  309. // GNASH_REPORT_FUNCTION;
  310. FileIO* ptr = ensure<ThisIsNative<FileIO> >(fn);
  311. assert(ptr);
  312. if (fn.nargs < 2) {
  313. IF_VERBOSE_ASCODING_ERRORS(
  314. std::stringstream ss; fn.dump_args(ss);
  315. log_aserror("FileIO.fopen(%s): need two arguments", ss.str().c_str());
  316. );
  317. return as_value(false);
  318. }
  319. string filespec = fn.arg(0).to_string();
  320. string mode = fn.arg(1).to_string();
  321. return as_value(ptr->fopen(filespec, mode));
  322. }
  323. as_value
  324. fileio_fclose(const fn_call& fn)
  325. {
  326. // GNASH_REPORT_FUNCTION;
  327. FileIO* ptr = ensure<ThisIsNative<FileIO> >(fn);
  328. assert(ptr);
  329. return as_value(ptr->fclose());
  330. }
  331. as_value
  332. fileio_fread(const fn_call& fn)
  333. {
  334. // GNASH_REPORT_FUNCTION;
  335. FileIO* ptr = ensure<ThisIsNative<FileIO> >(fn);
  336. assert(ptr);
  337. string str;
  338. int count = ptr->fread(str);
  339. if (count<0) {
  340. return as_value(false);
  341. } else {
  342. return as_value(str.c_str());
  343. }
  344. }
  345. as_value
  346. fileio_fgetc(const fn_call& fn)
  347. {
  348. // GNASH_REPORT_FUNCTION;
  349. FileIO* ptr = ensure<ThisIsNative<FileIO> >(fn);
  350. assert(ptr);
  351. int i = ptr->fgetc();
  352. if ((i==EOF) || (i<0)) {
  353. return as_value(false); // possible in async mode
  354. } else {
  355. char c[2]="x"; // set to 1 char to get the zero byte!
  356. c[0] = i;
  357. return as_value(c);
  358. }
  359. }
  360. as_value
  361. fileio_fgets(const fn_call& fn)
  362. {
  363. // GNASH_REPORT_FUNCTION;
  364. FileIO* ptr = ensure<ThisIsNative<FileIO> >(fn);
  365. assert(ptr);
  366. string str;
  367. str = ptr->fgets(str);
  368. return as_value(str.c_str());
  369. }
  370. as_value
  371. fileio_gets(const fn_call& fn)
  372. {
  373. // GNASH_REPORT_FUNCTION;
  374. FileIO* ptr = ensure<ThisIsNative<FileIO> >(fn);
  375. assert(ptr);
  376. char buf[BUFSIZE];
  377. memset(buf, 0, BUFSIZE);
  378. string str = ::gets(buf);
  379. return as_value(buf);
  380. }
  381. // Read a single character from standard in
  382. as_value
  383. fileio_getchar(const fn_call& fn)
  384. {
  385. // GNASH_REPORT_FUNCTION;
  386. FileIO* ptr = ensure<ThisIsNative<FileIO> >(fn);
  387. assert(ptr);
  388. int i = ::getchar();
  389. char *c = reinterpret_cast<char *>(&i);
  390. return as_value(c);
  391. }
  392. as_value
  393. fileio_fwrite(const fn_call& fn)
  394. {
  395. // GNASH_REPORT_FUNCTION;
  396. FileIO* ptr = ensure<ThisIsNative<FileIO> >(fn);
  397. assert(ptr);
  398. string str = fn.arg(0).to_string();
  399. return as_value(ptr->fputs(str));
  400. }
  401. as_value
  402. fileio_fputc(const fn_call& fn)
  403. {
  404. // GNASH_REPORT_FUNCTION;
  405. FileIO* ptr = ensure<ThisIsNative<FileIO> >(fn);
  406. assert(ptr);
  407. int c = (int) fn.arg(0).to_number();
  408. return as_value(ptr->fputc(c));
  409. }
  410. as_value
  411. fileio_fputs(const fn_call& fn)
  412. {
  413. // GNASH_REPORT_FUNCTION;
  414. FileIO* ptr = ensure<ThisIsNative<FileIO> >(fn);
  415. string str = fn.arg(0).to_string();
  416. return as_value(ptr->fputs(str));
  417. }
  418. // print to standard put
  419. as_value
  420. fileio_puts(const fn_call& fn)
  421. {
  422. // GNASH_REPORT_FUNCTION;
  423. string str = fn.arg(0).to_string();
  424. return as_value(::puts(str.c_str()));
  425. }
  426. as_value
  427. fileio_putchar(const fn_call& fn)
  428. {
  429. // GNASH_REPORT_FUNCTION;
  430. FileIO* ptr = ensure<ThisIsNative<FileIO> >(fn);
  431. assert(ptr);
  432. string x = fn.arg(0).to_string();
  433. return as_value(::putchar(x[0]));
  434. }
  435. as_value
  436. fileio_fflush(const fn_call& fn)
  437. {
  438. // GNASH_REPORT_FUNCTION;
  439. FileIO* ptr = ensure<ThisIsNative<FileIO> >(fn);
  440. assert(ptr);
  441. return as_value(ptr->fflush());
  442. }
  443. as_value
  444. fileio_fseek(const fn_call& fn)
  445. {
  446. // GNASH_REPORT_FUNCTION;
  447. FileIO* ptr = ensure<ThisIsNative<FileIO> >(fn);
  448. assert(ptr);
  449. long c = static_cast<long>(fn.arg(0).to_number());
  450. return as_value(ptr->fseek(c));
  451. }
  452. as_value
  453. fileio_ftell(const fn_call& fn)
  454. {
  455. // GNASH_REPORT_FUNCTION;
  456. FileIO* ptr = ensure<ThisIsNative<FileIO> >(fn);
  457. assert(ptr);
  458. int i = ptr->ftell();
  459. return as_value(i);
  460. }
  461. as_value
  462. fileio_asyncmode(const fn_call& fn)
  463. {
  464. // GNASH_REPORT_FUNCTION;
  465. FileIO* ptr = ensure<ThisIsNative<FileIO> >(fn);
  466. assert(ptr);
  467. bool b = (bool) fn.arg(0).to_bool();
  468. return as_value(ptr->asyncmode(b));
  469. }
  470. as_value
  471. fileio_feof(const fn_call& fn)
  472. {
  473. // GNASH_REPORT_FUNCTION;
  474. FileIO* ptr = ensure<ThisIsNative<FileIO> >(fn);
  475. assert(ptr);
  476. bool b = ptr->feof();
  477. return as_value(b);
  478. }
  479. as_value
  480. fileio_unlink(const fn_call& fn)
  481. {
  482. // GNASH_REPORT_FUNCTION;
  483. FileIO* ptr = ensure<ThisIsNative<FileIO> >(fn);
  484. assert(ptr);
  485. string str = fn.arg(0).to_string();
  486. return as_value(ptr->unlink(str));
  487. }
  488. as_value
  489. fileio_scandir(const fn_call& fn)
  490. {
  491. // GNASH_REPORT_FUNCTION;
  492. // TODO: Check optional second parameter and sort array if it's true
  493. // or missing.
  494. if (!fn.nargs) return as_value(false);
  495. const std::string& dir = fn.arg(0).to_string();
  496. struct dirent **namelist;
  497. const int n = ::scandir(dir.c_str(), &namelist, 0, alphasort);
  498. if (n < 0) {
  499. return as_value(false);
  500. }
  501. Global_as& gl = getGlobal(fn);
  502. string_table& st = getStringTable(fn);
  503. as_object* array = gl.createArray();
  504. for (int idx = 0; idx < n; ++idx) {
  505. array->set_member(arrayKey(st, idx), namelist[idx]->d_name);
  506. free(namelist[idx]);
  507. }
  508. free(namelist);
  509. return as_value(array);
  510. }
  511. extern "C" {
  512. void
  513. fileio_class_init(as_object& where, const ObjectURI& /* uri */)
  514. {
  515. // GNASH_REPORT_FUNCTION;
  516. Global_as& gl = getGlobal(where);
  517. as_object* proto = gl.createObject();
  518. attachInterface(*proto);
  519. as_object* cl = gl.createClass(&fileio_ctor, proto);
  520. where.init_member("FileIO", cl);
  521. }
  522. } // end of extern C
  523. } // end of gnash namespace
  524. // Local Variables:
  525. // mode: C++
  526. // indent-tabs-mode: nil
  527. // End: