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

📄 b_array.c

📁 一个类似windows
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * The builtin Array object.
 * Copyright (c) 1998 New Generation Software (NGS) Oy
 *
 * Author: Markku Rossi <mtr@ngs.fi>
 */

/*
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
 * MA 02111-1307, USA
 */

/*
 * $Source: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/b_array.c,v $
 * $Id: b_array.c 21681 2006-04-21 15:00:24Z peterw $
 */

/*
 * Mehtods:
 *
 *   concat (array) => array
 *   join ([glue]) => string
 *   pop () => last_element
 *   push (any...) => last_element_added
 *   reverse ()
 *   shift () => first_element
 *   slice (start, end) => array
 *   splice (index, how_many[, any...]) => array
 *   sort ([sort_function])
 *   toString () => string
 *   unshift (any...) => length_of_the_array
 *
 * Properties:
 *
 *   length
 */

#include "jsint.h"
#include "mrgsort.h"

/*
 * Types and definitions.
 */

/* Class context. */
struct array_ctx_st
{
  JSSymbol s_concat;
  JSSymbol s_join;
  JSSymbol s_pop;
  JSSymbol s_push;
  JSSymbol s_reverse;
  JSSymbol s_shift;
  JSSymbol s_slice;
  JSSymbol s_splice;
  JSSymbol s_sort;
  JSSymbol s_unshift;

  JSSymbol s_length;
};

typedef struct array_ctx_st ArrayCtx;

/* Context for array sorts with JavaScript functions. */
struct array_sort_ctx_st
{
  JSVirtualMachine *vm;
  JSNode *func;
  JSNode argv[3];
};

typedef struct array_sort_ctx_st ArraySortCtx;

/*
 * Prototypes for static functions.
 */

static void new_proc (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
		      JSNode *args, JSNode *result_return);


/*
 * Static functions.
 */

static int
sort_default_cmp_func (const void *aptr, const void *bptr, void *context)
{
  JSVirtualMachine *vm = context;
  const JSNode *a = aptr;
  const JSNode *b = bptr;
  JSNode astr, bstr;

  if (a->type == JS_UNDEFINED)
    return 1;
  if (b->type == JS_UNDEFINED)
    return -1;

  js_vm_to_string (vm, a, &astr);
  js_vm_to_string (vm, b, &bstr);

  return js_compare_strings (&astr, &bstr);
}


static int
sort_js_cmp_func (const void *aptr, const void *bptr, void *context)
{
  ArraySortCtx *ctx = context;
  const JSNode *a = aptr;
  const JSNode *b = bptr;

  /*
   * Finalize the argument array.  The argumnet count has already been set.
   * when the context were initialized.
   */
  JS_COPY (&ctx->argv[1], a);
  JS_COPY (&ctx->argv[2], b);

  /* Call the function. */
  if (!js_vm_apply (ctx->vm, NULL, ctx->func, 3, ctx->argv))
    /* Raise an error. */
    js_vm_error (ctx->vm);

  /* Fetch the return value. */
  if (ctx->vm->exec_result.type != JS_INTEGER)
    {
      sprintf (ctx->vm->error,
	       "Array.sort(): comparison function didn't return integer");
      js_vm_error (ctx->vm);
    }

  return ctx->vm->exec_result.u.vinteger;
}


/* Global method proc. */
static void
global_method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
	       void *instance_context, JSNode *result_return,
	       JSNode *args)
{
  /* This does exactly the same as the new_proc. */
  new_proc (vm, builtin_info, args, result_return);
}


/* Method proc. */
static int
method (JSVirtualMachine *vm, JSBuiltinInfo *builtin_info,
	void *instance_context, JSSymbol method, JSNode *result_return,
	JSNode *args)
{
  ArrayCtx *ctx = builtin_info->obj_context;
  JSNode *n = instance_context;
  int i;

  /* XXX 15.7.4.3 toSource(). */

  /* Handle static methods here. */
  if (instance_context == NULL)
    {
      if (method == vm->syms.s_toString)
	js_vm_make_static_string (vm, result_return, "Array", 5);
      /* ************************************************************ */
      else
	return JS_PROPERTY_UNKNOWN;

      return JS_PROPERTY_FOUND;
    }

  /* Handle the instance methods. */

  /* Set the default result type. */
  result_return->type = JS_UNDEFINED;

  if (method == ctx->s_concat)
    {
      int nlen;
      int pos;

      /* Count the new len; */

      nlen = n->u.varray->length;
      for (i = 0; i < args->u.vinteger; i++)
	{
	  if (args[i + 1].type != JS_ARRAY)
	    goto argument_error;

	  nlen += args[i + 1].u.varray->length;
	}

      js_vm_make_array (vm, result_return, nlen);

      /* Insert the items. */
      memcpy (result_return->u.varray->data, n->u.varray->data,
	      n->u.varray->length * sizeof (JSNode));
      pos = n->u.varray->length;

      for (i = 0; i < args->u.vinteger; i++)
	{
	  memcpy (&result_return->u.varray->data[pos],
		  args[i + 1].u.varray->data,
		  args[i + 1].u.varray->length * sizeof (JSNode));
	  pos += args[i + 1].u.varray->length;
	}
    }
  /* ********************************************************************** */
  else if (method == ctx->s_join || method == vm->syms.s_toString)
    {
      char *glue = NULL;

      if (method == vm->syms.s_toString)
	{
	  if (args->u.vinteger != 0)
	    goto argument_error;
	}
      else
	{
	  if (args->u.vinteger == 0)
	    ;
	  else if (args->u.vinteger == 1)
	    {
	      JSNode glue_result;

	      js_vm_to_string (vm, &args[1], &glue_result);
	      glue = js_string_to_c_string (vm, &glue_result);
	    }
	  else
	    goto argument_error;
	}

      /* Ok, ready to run. */
      if (n->u.varray->length == 0)
	js_vm_make_static_string (vm, result_return, "", 0);
      else
	{
	  int len;
	  int glue_len = glue ? strlen (glue) : 1;

	  /* Estimate the result length. */
	  len = (n->u.varray->length * 5
		 + (n->u.varray->length - 1) * glue_len);

	  js_vm_make_string (vm, result_return, NULL, len);
	  result_return->u.vstring->len = 0;

	  /* Do the join. */
	  for (i = 0; i < n->u.varray->length; i++)
	    {
	      JSNode sitem;
	      int delta;

	      js_vm_to_string (vm, &n->u.varray->data[i], &sitem);
	      delta = sitem.u.vstring->len;

	      if (i + 1 < n->u.varray->length)
		delta += glue_len;

	      result_return->u.vstring->data
		= js_vm_realloc (vm, result_return->u.vstring->data,
				 result_return->u.vstring->len + delta);

	      memcpy (result_return->u.vstring->data
		      + result_return->u.vstring->len,
		      sitem.u.vstring->data,
		      sitem.u.vstring->len);
	      result_return->u.vstring->len += sitem.u.vstring->len;

	      if (i + 1 < n->u.varray->length)
		{
		  if (glue)
		    {
		      memcpy (result_return->u.vstring->data
			      + result_return->u.vstring->len,
			      glue, glue_len);
		      result_return->u.vstring->len += glue_len;
		    }
		  else
		    result_return->u.vstring->data
		      [result_return->u.vstring->len++] = ',';
		}
	    }
	}

      if (glue)
	js_free (glue);
    }
  /* ********************************************************************** */
  else if (method == ctx->s_pop)
    {
      if (args->u.vinteger != 0)
	goto argument_error;

      if (n->u.varray->length == 0)
	result_return->type = JS_UNDEFINED;
      else
	{
	  JS_COPY (result_return, &n->u.varray->data[n->u.varray->length - 1]);
	  n->u.varray->length--;
	}
    }
  /* ********************************************************************** */
  else if (method == ctx->s_push)
    {
      int old_len;

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

      old_len = n->u.varray->length;
      js_vm_expand_array (vm, n, n->u.varray->length + args->u.vinteger);

      for (i = 0; i < args->u.vinteger; i++)

⌨️ 快捷键说明

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