www.pudn.com > Flirt.zip > array_class.c
/* Flirt, an SWF rendering library Copyright (c) 2004-2006 Dave HaydenAll rights reserved. http://www.opaque.net/flirt/ This code is distributed under the two-clause BSD license. Read the LICENSE file or visit the URL above for details */ #include #include #include #include "array_class.h" #include "object_class.h" #include "../function.h" ddActionClass* ddActionArrayClass = NULL; static ddActionValue ddActionArray_getProperty(ddActionContext* context, ddActionObject* object, const char* name) { ddActionArray* array = (ddActionArray*)object; if ( !ddActionObject_isKindOfClass(object, ddActionArrayClass) ) return ddUndefValue; if ( strcasecmp(name, "length") == 0 ) return dd_newActionValue_int(array->length); return ddActionObject_getProperty_default(context, object, name); } ddActionArray* dd_newActionArray_size(int size) { ddActionArray* array = dd_malloc(sizeof(struct _ddActionArray)); ddActionObject_init((ddActionObject*)array); array->length = size; ddActionObject_setClass((ddActionObject*)array, ddActionArrayClass); return array; } ddActionArray* dd_newActionArray() { return dd_newActionArray_size(0); } void ddActionArray_setMember(ddActionArray* array, int member, ddActionValue value) { char* name = dd_malloc(16); /* XXX - ??? */ sprintf(name, "%i", member); if ( member >= array->length ) array->length = member+1; ddActionHash_setValue(((ddActionObject*)array)->properties, name, value); } ddActionValue ddActionArray_getMember(ddActionArray* array, int member) { char* name; ddActionValue val; if ( member >= array->length ) return ddNullValue; name = dd_malloc(16); /* XXX - ??? */ sprintf(name, "%i", member); val = ddActionHash_findValue(((ddActionObject*)array)->properties, name); dd_free(name); return val; } static ddActionValue Array_concat(ddActionObject* object, ddActionContext* context, int nargs) { //ddActionArray* array = (ddActionArray*)object; return ddNullValue; } static ddActionValue Array_join(ddActionObject* object, ddActionContext* context, int nargs) { //ddActionArray* array = (ddActionArray*)object; return ddNullValue; } static ddActionValue Array_pop(ddActionObject* object, ddActionContext* context, int nargs) { ddActionArray* array = (ddActionArray*)object; int num; if ( !ddActionObject_isKindOfClass(object, ddActionArrayClass) ) return ddUndefValue; num = array->length-1; /* XXX */ //ddActionValue val = ddActionArray_getMember(array, num); char* name = dd_malloc(sizeof(char)*16); sprintf(name, "%i", num); ddActionHash_removeValue(object->properties, name); return ddNullValue; } static ddActionValue Array_push(ddActionObject* object, ddActionContext* context, int nargs) { ddActionArray* array = (ddActionArray*)object; int i; if ( !ddActionObject_isKindOfClass(object, ddActionArrayClass) ) return ddUndefValue; for ( i = 0; i < nargs; ++i ) { ddActionValue val = ddActionStack_pop(&context->stack); ddActionArray_setMember(array, array->length, val); } return ddNullValue; } static ddActionValue Array_reverse(ddActionObject* object, ddActionContext* context, int nargs) { ddActionArray* array = (ddActionArray*)object; int i; int len; ddActionValue* members; if ( !ddActionObject_isKindOfClass(object, ddActionArrayClass) ) return ddUndefValue; len = array->length; members = dd_malloc(len * sizeof(ddActionValue)); for ( i = 0; i < len; ++i ) members[i] = ddActionArray_getMember(array, i); for ( i = 0; i < len; ++i ) ddActionArray_setMember(array, len - i - 1, members[i]); dd_free(members); return ddNullValue; } static ddActionValue Array_shift(ddActionObject* object, ddActionContext* context, int nargs) { //ddActionArray* array = (ddActionArray*)object; return ddNullValue; } static ddActionValue Array_slice(ddActionObject* object, ddActionContext* context, int nargs) { //ddActionArray* array = (ddActionArray*)object; return ddNullValue; } static ddActionValue Array_sort(ddActionObject* object, ddActionContext* context, int nargs) { //ddActionArray* array = (ddActionArray*)object; return ddNullValue; } static ddActionValue Array_splice(ddActionObject* object, ddActionContext* context, int nargs) { //ddActionArray* array = (ddActionArray*)object; return ddNullValue; } #define ARRAY_TOSTRING_INCREMENT 256 static ddActionValue Array_toString(ddActionObject* object, ddActionContext* context, int nargs) { ddActionArray* array = (ddActionArray*)object; char* strval = NULL; int i; int p = 0; int bufsize = 0; if ( !ddActionObject_isKindOfClass(object, ddActionArrayClass) ) return ddUndefValue; for ( i = 0; i < array->length; ++i ) { ddActionValue val = ddActionArray_getMember(array, i); char* str = ddActionValue_getStringValue(context, val); int len = strlen(str); if ( p + len + 1 > bufsize ) { bufsize += ARRAY_TOSTRING_INCREMENT; strval = dd_realloc(strval, bufsize); } if ( i > 0 ) strval[p++] = ','; strcpy(strval+p, str); p+= len; } return dd_newActionValue_string(strval); } static ddActionValue Array_unshift(ddActionObject* object, ddActionContext* context, int nargs) { //ddActionArray* array = (ddActionArray*)object; return ddNullValue; } static ddActionValue Array_constructor(ddActionObject* object, ddActionContext* context, int nargs) { ddActionArray* array; if ( nargs == 1 ) { ddActionValue val = ddActionStack_pop(&context->stack); int size = ddActionValue_getIntValue(val); ddActionValue_release(val); array = dd_newActionArray_size(size); } else { int i; array = dd_newActionArray(); for ( i = 0; i < nargs; ++i ) { ddActionValue val = ddActionStack_pop(&context->stack); ddActionArray_setMember(array, i, val); ddActionValue_release(val); } } return dd_newActionValue_object((ddActionObject*)array); } ddActionFunction* dd_initArrayClass() { ddActionObject* classObject; ddActionFunction* ctor = dd_newActionNativeFunction(Array_constructor, FUNCTION_VARARGS); ddActionArrayClass = dd_newActionClass(); classObject = (ddActionObject*)ddActionArrayClass; ddActionArrayClass->getProperty = ddActionArray_getProperty; ddActionObject_addNativeMethod(classObject, strdup("concat"), Array_concat, 1); ddActionObject_addNativeMethod(classObject, strdup("join"), Array_join, 1); ddActionObject_addNativeMethod(classObject, strdup("pop"), Array_pop, FUNCTION_VARARGS); ddActionObject_addNativeMethod(classObject, strdup("push"), Array_push, FUNCTION_VARARGS); ddActionObject_addNativeMethod(classObject, strdup("reverse"), Array_reverse, 0); ddActionObject_addNativeMethod(classObject, strdup("shift"), Array_shift, FUNCTION_VARARGS); ddActionObject_addNativeMethod(classObject, strdup("slice"), Array_slice, 0); ddActionObject_addNativeMethod(classObject, strdup("sort"), Array_sort, 1); ddActionObject_addNativeMethod(classObject, strdup("splice"), Array_splice, FUNCTION_VARARGS); ddActionObject_addNativeMethod(classObject, strdup("toString"), Array_toString, 0); ddActionObject_addNativeMethod(classObject, strdup("unshift"), Array_unshift, FUNCTION_VARARGS); ddActionFunction_setPrototype(ctor, classObject); return ctor; }