⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 b_file.c

📁 一个类似windows
💻 C
📖 第 1 页 / 共 2 页
字号:
	    result_return->u.vboolean = ictx->stream->at_eof;
	}
      /* ***************************************************************** */
      else if (method == ctx->s_read)
	{
	  size_t got;
	  char *buffer;

	  if (args->u.vinteger != 1)
	    goto argument_error;
	  if (args[1].type != JS_INTEGER || args[1].u.vinteger < 0)
	    goto argument_type_error;

	  if (ictx->stream != NULL)
	    {
	      buffer = js_vm_alloc (vm, args[1].u.vinteger + 1);

	      got = js_iostream_read (ictx->stream, buffer,
				      args[1].u.vinteger);
	      if (got < 0)
		got = 0;

	      js_vm_make_static_string (vm, result_return, buffer, got);
	      result_return->u.vstring->staticp = 0;
	    }
	}
      /* ***************************************************************** */
      else if (method == ctx->s_readln)
	{
	  /* int ch; */
	  unsigned int bufpos = 0;
	  unsigned int buflen = 0;
	  char *buffer = NULL;

	  if (args->u.vinteger != 0)
	    goto argument_error;

	  if (ictx->stream != NULL)
	    {
	      /* Flush all buffered output data. */
	      js_iostream_flush (ictx->stream);

	      while (1)
		{
		  /* Process all the data we have in the buffer. */
		  for (; ictx->stream->bufpos < ictx->stream->data_in_buf
			 && (ictx->stream->buffer[ictx->stream->bufpos]
			     != '\n');
		       ictx->stream->bufpos++)
		    {
		      if (bufpos >= buflen)
			{
			  buflen += 1024;
			  buffer = js_vm_realloc (vm, buffer, buflen);
			}
		      buffer[bufpos++]
			= ictx->stream->buffer[ictx->stream->bufpos];
		    }

		  if (ictx->stream->bufpos >= ictx->stream->data_in_buf)
		    {
		      /* int result; */

		      /* Read past the buffer. */
		      if (ictx->stream->at_eof)
			/* EOF seen. */
			break;

		      /* Read more data. */
		      js_iostream_fill_buffer (ictx->stream);
		    }
		  else
		    {
		      /* Got it.  Skip the newline character. */
		      ictx->stream->bufpos++;
		      break;
		    }
		}

	      /* Remove '\r' characters. */
	      while (bufpos > 0)
		if (buffer[bufpos - 1] == '\r')
		  bufpos--;
		else
		  break;

	      if (buffer == NULL)
		/* An empty string.  Allocate one byte. */
		buffer = js_vm_alloc (vm, 1);

	      /*
	       * Use the data we already had.  In maximum, it has only
	       * 1023 bytes overhead.
	       */
	      js_vm_make_static_string (vm, result_return, buffer, bufpos);
	      result_return->u.vstring->staticp = 0;
	    }
	}
      /* ***************************************************************** */
      else if (method == ctx->s_readByte)
	{
	  result_return->type = JS_INTEGER;
	  if (ictx->stream == NULL)
	    result_return->u.vinteger = -1;
	  else
	    {
	    retry:
	      if (ictx->stream->bufpos < ictx->stream->data_in_buf)
		result_return->u.vinteger
		  = ictx->stream->buffer[ictx->stream->bufpos++];
	      else
		{
		  if (ictx->stream->at_eof)
		    result_return->u.vinteger = -1;
		  else
		    {
		      js_iostream_fill_buffer (ictx->stream);
		      goto retry;
		    }
		}
	    }
	}
      /* ***************************************************************** */
      else if (method == ctx->s_write || method == ctx->s_writeln)
	{
	  size_t wrote;
	  int autoflush;

	  if (args->u.vinteger != 1)
	    goto argument_error;
	  if (args[1].type != JS_STRING)
	    goto argument_type_error;

	  if (ictx->stream != NULL)
	    {
	      autoflush = ictx->stream->autoflush;
	      ictx->stream->autoflush = 0;

	      wrote = js_iostream_write (ictx->stream,
					 args[1].u.vstring->data,
					 args[1].u.vstring->len);
	      if (wrote == args[1].u.vstring->len)
		{
		  /* Success. */
		  result_return->u.vboolean = 1;

		  if (method == ctx->s_writeln)
		    if (js_iostream_write (ictx->stream,
					   JS_HOST_LINE_BREAK,
					   JS_HOST_LINE_BREAK_LEN) < 0)
		      /* No, it was not a success. */
		      result_return->u.vboolean = 0;
		}

	      ictx->stream->autoflush = autoflush;
	      if (autoflush)
		js_iostream_flush (ictx->stream);
	    }
	}
      /* ***************************************************************** */
      else if (method == ctx->s_writeByte)
	{
	  unsigned char buf[1];

	  if (args->u.vinteger != 1)
	    goto argument_error;
	  if (args[1].type != JS_INTEGER)
	    goto argument_type_error;

	  buf[0] = args[1].u.vinteger;

	  if (ictx->stream != NULL)
	    result_return->u.vboolean
	      = js_iostream_write (ictx->stream, buf, 1) >= 0;
	}
      /* ***************************************************************** */
      else if (method == ctx->s_ungetByte)
	{
	  if (args->u.vinteger != 1)
	    goto argument_error;
	  if (args[1].type != JS_INTEGER)
	    goto argument_type_error;

	  if (ictx->stream != NULL)
	    result_return->u.vboolean
	      = js_iostream_unget (ictx->stream, args[1].u.vinteger);
	}
      /* ***************************************************************** */
      else if (method == ctx->s_flush)
	{
	  if (args->u.vinteger != 0)
	    goto argument_error;

	  if (ictx->stream != NULL && js_iostream_flush (ictx->stream) >= 0)
	    result_return->u.vboolean = 1;
	}
      /* ***************************************************************** */
      else if (method == ctx->s_getLength)
	{
	  if (args->u.vinteger != 0)
	    goto argument_error;

	  /* The default error code is an integer -1. */
	  result_return->type = JS_INTEGER;
	  result_return->u.vinteger = -1;

	  if (ictx->stream != NULL)
	    result_return->u.vinteger
	      = js_iostream_get_length (ictx->stream);
	}
      /* ***************************************************************** */
      else if (method == ctx->s_exists)
	{
#if 0
	  if (args->u.vinteger != 0)
	    goto argument_error;

	  if (ictx->stream)
	    {
	      /* Since we have opened the file, it must exist. */
	      result_return->u.vboolean = 1;
	    }
	  else
	    {
	      struct stat stat_st;

	      if (stat (ictx->path, &stat_st) >= 0)
		result_return->u.vboolean = 1;
	    }
#endif
	}
      /* ***************************************************************** */
      else if (method == ctx->s_error)
	{
	  if (args->u.vinteger != 0)
	    goto argument_error;

	  result_return->type = JS_INTEGER;
	  if (ictx->stream == NULL)
	    result_return->u.vinteger = -1;
	  else
	    result_return->u.vinteger = ictx->stream->error;
	}
      /* ***************************************************************** */
      else if (method == ctx->s_clearError)
	{
	  if (args->u.vinteger != 0)
	    goto argument_error;

	  if (ictx->stream != NULL)
	    {
	      ictx->stream->error = 0;
	      result_return->u.vboolean = 1;
	    }
	}
      /* ***************************************************************** */
      else
	return JS_PROPERTY_UNKNOWN;
    }
  else
    return JS_PROPERTY_UNKNOWN;

  return JS_PROPERTY_FOUND;


  /*
   * Error handling.
   */

 argument_error:
  sprintf (vm->error, "File.%s(): illegal amount of arguments",
	   js_vm_symname (vm, method));
  js_vm_error (vm);

 argument_type_error:
  sprintf (vm->error, "File.%s(): illegal argument",
	   js_vm_symname (vm, method));
  js_vm_error (vm);

 insecure_feature:
  sprintf (vm->error, "File.%s(): not allowed in secure mode",
	   js_vm_symname (vm, method));
  js_vm_error (vm);

  /* NOTREACHED */
  return 0;
}

/* Property proc. */
static int
property (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
	  void *instance_context, JSSymbol property, int set, JSNode *node)
{
  FileCtx *ctx = builtin_info->obj_context;
  FileInstanceCtx *ictx = instance_context;

  if (ictx)
    {
      /* Instance properties. */
      if (property == ctx->s_autoFlush)
	{
	  if (ictx->stream == NULL)
	    goto not_open;

	  if (set)
	    {
	      if (node->type != JS_BOOLEAN)
		goto argument_type_error;

	      ictx->stream->autoflush = node->u.vboolean;
	    }
	  else
	    {
	      node->type = JS_BOOLEAN;
	      node->u.vboolean = ictx->stream->autoflush;
	    }
	}
      /* ***************************************************************** */
      else if (property == ctx->s_bufferSize)
	{
	  if (ictx->stream == NULL)
	    goto not_open;

	  if (set)
	    {
	      unsigned char *buf;
	      unsigned int len;

	      if (node->type != JS_INTEGER)
		goto argument_type_error;

	      js_iostream_flush (ictx->stream);

	      len = node->u.vinteger;
	      buf = js_realloc (vm, ictx->stream->buffer, len);

	      ictx->stream->buflen = len;
	      ictx->stream->buffer = buf;
	    }
	  else
	    {
	      node->type = JS_INTEGER;
	      node->u.vinteger = ictx->stream->buflen;
	    }
	}
      /* ***************************************************************** */
      else
	{
	  if (!set)
	    node->type = JS_UNDEFINED;

	  return JS_PROPERTY_UNKNOWN;
	}
    }
  else
    {
      if (!set)
	node->type = JS_UNDEFINED;

      return JS_PROPERTY_UNKNOWN;
    }

  return JS_PROPERTY_FOUND;


  /* Error handling. */

 argument_type_error:
  sprintf (vm->error, "File.%s: illegal value",
	   js_vm_symname (vm, property));
  js_vm_error (vm);

 not_open:
  sprintf (vm->error, "File.%s: the stream is not opened",
	   js_vm_symname (vm, property));
  js_vm_error (vm);

  /* NOTREACHED */
  return 0;
}


/* New proc. */
static void
new_proc (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info, JSNode *args,
	  JSNode *result_return)
{
  FileInstanceCtx *instance;

  if (args->u.vinteger != 1)
    {
      sprintf (vm->error, "new File(): illegal amount of arguments");
      js_vm_error (vm);
    }
  if (args[1].type != JS_STRING)
    {
      sprintf (vm->error, "new File(): illegal argument");
      js_vm_error (vm);
    }

  instance = js_calloc (vm, 1, sizeof (*instance));
  instance->path = js_string_to_c_string (vm, &args[1]);
  instance->vm = vm;

  js_vm_builtin_create (vm, result_return, builtin_info, instance);
}

/* Delete proc. */
static void
delete_proc (JSBuiltinInfo *builtin_info, void *instance_context)
{
  FileInstanceCtx *ictx = instance_context;

  if (ictx)
    {
      if (ictx->stream)
	{
	  if (!ictx->dont_close)
	    {
	      js_iostream_close (ictx->stream);
	      JS_VM_FREE_FD (ictx->vm);
	    }

	  ictx->stream = NULL;
	}

      js_free (ictx->path);
      js_free (ictx);
    }
}

/*
 * Global functions.
 */

void
js_builtin_File (JSVirtualMachine *vm)
{
  JSNode *n;
  JSBuiltinInfo *info;
  FileCtx *ctx;

  ctx = js_calloc (vm, 1, sizeof (*ctx));

  ctx->s_byteToString	= js_vm_intern (vm, "byteToString");
  ctx->s_chmod		= js_vm_intern (vm, "chmod");
  ctx->s_lstat		= js_vm_intern (vm, "lstat");
  ctx->s_remove		= js_vm_intern (vm, "remove");
  ctx->s_rename		= js_vm_intern (vm, "rename");
  ctx->s_stat		= js_vm_intern (vm, "stat");
  ctx->s_stringToByte	= js_vm_intern (vm, "stringToByte");

  ctx->s_open		= js_vm_intern (vm, "open");
  ctx->s_close		= js_vm_intern (vm, "close");
  ctx->s_setPosition	= js_vm_intern (vm, "setPosition");
  ctx->s_getPosition	= js_vm_intern (vm, "getPosition");
  ctx->s_eof		= js_vm_intern (vm, "eof");
  ctx->s_read		= js_vm_intern (vm, "read");
  ctx->s_readln		= js_vm_intern (vm, "readln");
  ctx->s_readByte	= js_vm_intern (vm, "readByte");
  ctx->s_write		= js_vm_intern (vm, "write");
  ctx->s_writeln	= js_vm_intern (vm, "writeln");
  ctx->s_writeByte	= js_vm_intern (vm, "writeByte");
  ctx->s_ungetByte	= js_vm_intern (vm, "ungetByte");
  ctx->s_flush		= js_vm_intern (vm, "flush");
  ctx->s_getLength	= js_vm_intern (vm, "getLength");
  ctx->s_exists		= js_vm_intern (vm, "exists");
  ctx->s_error		= js_vm_intern (vm, "error");
  ctx->s_clearError	= js_vm_intern (vm, "clearError");

  ctx->s_autoFlush	= js_vm_intern (vm, "autoFlush");
  ctx->s_bufferSize	= js_vm_intern (vm, "bufferSize");


  /* Object information. */

  info = js_vm_builtin_info_create (vm);

  info->method_proc 		= method;
  info->property_proc 		= property;
  info->new_proc 		= new_proc;
  info->delete_proc 		= delete_proc;
  info->obj_context 		= ctx;
  info->obj_context_delete	= js_free;

  /* Define it. */
  n = &vm->globals[js_vm_intern (vm, "File")];
  js_vm_builtin_create (vm, n, info, NULL);
}


void
js_builtin_File_new (JSVirtualMachine *vm, JSNode *result_return,
		     char *path, JSIOStream *stream, int dont_close)
{
  JSNode *n;
  FileInstanceCtx *ictx;

  /* Lookup our context. */
  n = &vm->globals[js_vm_intern (vm, "File")];

  /* Create a file instance. */
  ictx = js_calloc (vm, 1, sizeof (*ictx));
  ictx->path = js_strdup (vm, path);
  ictx->stream = stream;
  ictx->dont_close = dont_close;
  ictx->vm = vm;

  /* Create the builtin. */
  js_vm_builtin_create (vm, result_return, n->u.vbuiltin->info, ictx);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -