file.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. /**
  2. * @constructor
  3. * @param {Sk.builtin.str} name
  4. * @param {Sk.builtin.str} mode
  5. * @param {Object} buffering
  6. */
  7. Sk.builtin.file = function (name, mode, buffering) {
  8. var i;
  9. var elem;
  10. if (!(this instanceof Sk.builtin.file)) {
  11. return new Sk.builtin.file(name, mode, buffering);
  12. }
  13. this.mode = mode;
  14. this.name = Sk.ffi.remapToJs(name);
  15. this.closed = false;
  16. if (this.name === "/dev/stdout") {
  17. this.data$ = Sk.builtin.none.none$;
  18. this.fileno = 1;
  19. } else if (this.name === "/dev/stdin") {
  20. this.fileno = 0;
  21. } else if (this.name === "/dev/stderr") {
  22. this.fileno = 2;
  23. } else {
  24. if (Sk.inBrowser) { // todo: Maybe provide a replaceable function for non-import files
  25. this.fileno = 10;
  26. this.data$ = Sk.inBrowser(this.name);
  27. this.lineList = this.data$.split("\n");
  28. } else {
  29. this.fileno = 11;
  30. this.data$ = Sk.read(name.v);
  31. this.lineList = this.data$.split("\n");
  32. this.lineList = this.lineList.slice(0, -1);
  33. }
  34. for (i in this.lineList) {
  35. this.lineList[i] = this.lineList[i] + "\n";
  36. }
  37. this.currentLine = 0;
  38. }
  39. this.pos$ = 0;
  40. this.__class__ = Sk.builtin.file;
  41. return this;
  42. };
  43. Sk.abstr.setUpInheritance("file", Sk.builtin.file, Sk.builtin.object);
  44. Sk.builtin.file.prototype["$r"] = function () {
  45. return new Sk.builtin.str("<" +
  46. (this.closed ? "closed" : "open") +
  47. "file '" +
  48. this.name +
  49. "', mode '" +
  50. Sk.ffi.remapToJs(this.mode) +
  51. "'>");
  52. };
  53. Sk.builtin.file.prototype["__enter__"] = new Sk.builtin.func(function __enter__(self) {
  54. return self;
  55. });
  56. Sk.builtin.file.prototype["__exit__"] = new Sk.builtin.func(function __exit__(self) {
  57. return Sk.misceval.callsim(Sk.builtin.file.prototype["close"], self);
  58. });
  59. Sk.builtin.file.prototype.tp$iter = function () {
  60. var allLines = this.lineList;
  61. var ret =
  62. {
  63. tp$iter : function () {
  64. return ret;
  65. },
  66. $obj : this,
  67. $index : 0,
  68. $lines : allLines,
  69. tp$iternext: function () {
  70. if (ret.$index >= ret.$lines.length) {
  71. return undefined;
  72. }
  73. return new Sk.builtin.str(ret.$lines[ret.$index++]);
  74. }
  75. };
  76. return ret;
  77. };
  78. Sk.builtin.file.prototype["close"] = new Sk.builtin.func(function close(self) {
  79. self.closed = true;
  80. return Sk.builtin.none.none$;
  81. });
  82. Sk.builtin.file.prototype["flush"] = new Sk.builtin.func(function flush(self) {
  83. });
  84. Sk.builtin.file.prototype["fileno"] = new Sk.builtin.func(function fileno(self) {
  85. return this.fileno;
  86. }); // > 0, not 1/2/3
  87. Sk.builtin.file.prototype["isatty"] = new Sk.builtin.func(function isatty(self) {
  88. return false;
  89. });
  90. Sk.builtin.file.prototype["read"] = new Sk.builtin.func(function read(self, size) {
  91. var ret;
  92. var len;
  93. if (self.closed) {
  94. throw new Sk.builtin.ValueError("I/O operation on closed file");
  95. }
  96. len = self.data$.length;
  97. if (size === undefined) {
  98. size = len;
  99. }
  100. ret = new Sk.builtin.str(self.data$.substr(self.pos$, size));
  101. self.pos$ += size;
  102. if (self.pos$ >= len) {
  103. self.pos$ = len;
  104. }
  105. return ret;
  106. });
  107. Sk.builtin.file.$readline = function (self, size, prompt) {
  108. if (self.fileno === 0) {
  109. var x, resolution, susp;
  110. var lprompt = Sk.ffi.remapToJs(prompt);
  111. lprompt = lprompt ? lprompt : "";
  112. x = Sk.inputfun(lprompt);
  113. if (x instanceof Promise) {
  114. susp = new Sk.misceval.Suspension();
  115. susp.resume = function() {
  116. return new Sk.builtin.str(resolution);
  117. };
  118. susp.data = {
  119. type: "Sk.promise",
  120. promise: x.then(function(value) {
  121. resolution = value;
  122. return value;
  123. }, function(err) {
  124. resolution = "";
  125. return err;
  126. })
  127. };
  128. return susp;
  129. } else {
  130. return new Sk.builtin.str(x);
  131. }
  132. } else {
  133. var line = "";
  134. if (self.currentLine < self.lineList.length) {
  135. line = self.lineList[self.currentLine];
  136. self.currentLine++;
  137. }
  138. return new Sk.builtin.str(line);
  139. }
  140. };
  141. Sk.builtin.file.prototype["readline"] = new Sk.builtin.func(function readline(self, size) {
  142. return Sk.builtin.file.$readline(self, size, undefined);
  143. });
  144. Sk.builtin.file.prototype["readlines"] = new Sk.builtin.func(function readlines(self, sizehint) {
  145. if (self.fileno === 0) {
  146. return new Sk.builtin.NotImplementedError("readlines ins't implemented because the web doesn't support Ctrl+D");
  147. }
  148. var i;
  149. var arr = [];
  150. for (i = self.currentLine; i < self.lineList.length; i++) {
  151. arr.push(new Sk.builtin.str(self.lineList[i]));
  152. }
  153. return new Sk.builtin.list(arr);
  154. });
  155. Sk.builtin.file.prototype["seek"] = new Sk.builtin.func(function seek(self, offset, whence) {
  156. if (whence === undefined) {
  157. whence = 1;
  158. }
  159. if (whence == 1) {
  160. self.pos$ = offset;
  161. } else {
  162. self.pos$ = self.data$ + offset;
  163. }
  164. });
  165. Sk.builtin.file.prototype["tell"] = new Sk.builtin.func(function tell(self) {
  166. return self.pos$;
  167. });
  168. Sk.builtin.file.prototype["truncate"] = new Sk.builtin.func(function truncate(self, size) {
  169. goog.asserts.fail();
  170. });
  171. Sk.builtin.file.prototype["write"] = new Sk.builtin.func(function write(self, str) {
  172. //var mode = Sk.ffi.remapToJs(self.mode);
  173. if (self.fileno === 1) {
  174. Sk.output(Sk.ffi.remapToJs(str));
  175. } else {
  176. goog.asserts.fail();
  177. }
  178. return Sk.builtin.none.none$;
  179. /*if (mode === "w" || mode === "wb" || mode === "a" || mode === "ab") {
  180. } else {
  181. goog.asserts.fail();
  182. }*/
  183. });
  184. goog.exportSymbol("Sk.builtin.file", Sk.builtin.file);