2 Copyright (C) 2000-2003 SKYRIX Software AG
4 This file is part of OGo
6 OGo is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 OGo is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with OGo; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
23 #include "NGJavaScriptObject.h"
24 #include "NGJavaScriptContext.h"
25 #include "NGJavaScriptObjectMappingContext.h"
28 #define ARCHIVE_AS_NSARRAY 1
30 @interface NGJavaScriptArray(Private)
31 - (NSArray *)convertToNSArray;
34 @implementation NGJavaScriptArray
37 static BOOL isInitialized = NO;
40 #if NeXT_RUNTIME || APPLE_RUNTIME || GNUSTEP_BASE_LIBRARY
41 NSLog(@"WARNING(%s): adding NSMutableArray behaviour to "
42 @"NGJavaScriptArray is not supported with the current"
43 @"runtime!", __PRETTY_FUNCTION__);
44 /* TODO: port to MacOSX/GNUstep */
46 class_add_behavior(self, [NSMutableArray class]);
51 - (void *)createJSObjectForJSClass:(void *)_class inJSContext:(void *)jsctx {
52 /* this is called by initWithClassHandle ... */
53 return JS_NewArrayObject(jsctx, 0 /* length */, NULL /* vector */);
54 //return JS_NewObject(jsctx, _class, NULL, NULL);
57 + (void *)jsObjectClass {
58 return &js_ArrayClass;
61 /* convert to array */
63 - (NSArray *)convertToNSArray {
68 if (!JS_GetArrayLength(self->jscx, self->handle, &count))
72 return [NSArray array];
74 objs = calloc(count, sizeof(id));
75 for (i = 0; i < count; i++) {
80 null = [[NSClassFromString(@"EONull") alloc] init];
82 if (!JS_GetElement(self->jscx, self->handle, i, &val))
85 objs[i] = [self->ctx objectForJSValue:&val];
87 array = [[NSArray alloc] initWithObjects:objs count:count];
89 return [array autorelease];
92 - (NSArray *)copyWithZone:(NSZone *)_zone {
93 return [[self convertToNSArray] copyWithZone:_zone];
95 - (NSMutableArray *)mutableCopyWithZone:(NSZone *)_zone {
96 return [[self convertToNSArray] mutableCopyWithZone:_zone];
101 #if ARCHIVE_AS_NSARRAY
103 - (id)replacementObjectForCoder:(NSCoder*)anEncoder {
106 array = [[[self convertToNSArray] mutableCopy] autorelease];
107 NSLog(@"%s: replace %@ with %@", __PRETTY_FUNCTION__, self, array);
111 - (Class)classForCoder {
112 return [NSMutableArray class];
117 - (void)decodeJavaScriptPropertiesWithCoder:(NSCoder *)_coder {
120 [_coder decodeValueOfObjCType:@encode(unsigned) at:&count];
121 for (i = 0; i < count; i++) {
122 id obj = [_coder decodeObject];
123 [self addObject:obj];
126 - (void)encodeJavaScriptPropertiesWithCoder:(NSCoder *)_coder {
129 count = [self count];
130 [_coder encodeValueOfObjCType:@encode(unsigned) at:&count];
132 for (i = 0; i < count; i++)
133 [_coder encodeObject:[self objectAtIndex:i]];
138 - (NSString *)description {
139 return [[self convertToNSArray] description];
142 @end /* NGJavaScriptArray */
144 @implementation NGJavaScriptArray(NSArrayCompatibility)
149 if (JS_GetArrayLength(self->jscx, self->handle, &v))
155 - (id)objectAtIndex:(unsigned)_idx {
158 if (JS_GetElement(self->jscx, self->handle, _idx, &obj))
159 return [self->ctx objectForJSValue:&obj];
165 - (NSEnumerator *)objectEnumerator {
166 return [[self convertToNSArray] objectEnumerator];
172 if (JS_GetArrayLength(self->jscx, self->handle, &v)) {
175 if (JS_GetElement(self->jscx, self->handle, v, &obj))
176 return [self->ctx objectForJSValue:&obj];
182 - (BOOL)containsObject:(id)_obj {
183 // to be improved ...
184 return [[self convertToNSArray] containsObject:_obj];
187 /* Deriving New Array */
189 - (NSArray *)arrayByAddingObject:(id)anObject {
190 return [[self convertToNSArray] arrayByAddingObject:anObject];
192 - (NSArray *)arrayByAddingObjectsFromArray:(NSArray *)anotherArray {
193 return [[self convertToNSArray] arrayByAddingObjectsFromArray:anotherArray];
196 - (NSArray *)sortedArrayUsingFunction:
197 (int(*)(id element1, id element2, void *userData))comparator
198 context:(void*)context
200 return [[self convertToNSArray]
201 sortedArrayUsingFunction:comparator
204 - (NSArray *)sortedArrayUsingSelector:(SEL)comparator {
205 return [[self convertToNSArray] sortedArrayUsingSelector:comparator];
208 - (NSArray *)subarrayWithRange:(NSRange)_range {
209 // to be improved ...
210 return [[self convertToNSArray] subarrayWithRange:_range];
213 @end /* NGJavaScriptArray(NSArrayCompatibility) */
215 @implementation NGJavaScriptArray(NSMutableArrayCompatibility)
217 - (void)setObject:(id)_obj atIndex:(unsigned)_idx {
220 if ([self->ctx jsValue:&obj forObject:_obj]) {
221 if (JS_SetElement(self->jscx, self->handle, _idx, &obj))
226 NSAssert2(NO, @"set element failed (%@ at idx %d) !", self, _idx);
230 _removeObjectsFrom(NGJavaScriptArray *self,
231 unsigned int _idx, unsigned int _count)
236 /* cannot use DeleteElement ! this doesn't adjust indizes !! */
237 NSAssert(JS_DeleteElement(self->jscx, self->handle, _idx),
238 @"delete-element failed in JS");
243 if (!JS_GetArrayLength(self->jscx, self->handle, &itemsCount))
245 if ((_idx + _count) > itemsCount)
249 for (i = (_idx + _count); i < itemsCount; i++, _idx++) {
252 if (!JS_GetElement(self->jscx, self->handle, i, &val))
255 if (!JS_SetElement(self->jscx, self->handle, _idx, &val))
260 if (JS_SetArrayLength(self->jscx, self->handle, itemsCount - _count)) {
266 NSCAssert3(NO, @"element remove failed (%@ at idx %d,%d) !",
270 - (void)removeObjectsInRange:(NSRange)aRange {
271 _removeObjectsFrom(self, aRange.location, aRange.length);
273 - (void)removeAllObjects {
274 _removeObjectsFrom(self, 0, [self count]);
276 - (void)removeLastObject {
278 itemsCount = [self count];
279 if (itemsCount > 0) _removeObjectsFrom(self, (itemsCount - 1), 1);
281 - (void)removeObjectAtIndex:(unsigned)_idx {
282 _removeObjectsFrom(self, _idx, 1);
285 - (void)insertObject:(id)_object atIndex:(unsigned)_idx {
290 NSLog(@"%s: before: %@", __PRETTY_FUNCTION__,
291 [[[self convertToNSArray]
292 valueForKey:@"description"]
293 componentsJoinedByString:@","]);
296 if (!JS_GetArrayLength(self->jscx, self->handle, &itemsCount))
299 if (_idx > itemsCount)
300 /* range exception ... */
304 for (i = itemsCount; i > _idx; i--) {
307 if (!JS_GetElement(self->jscx, self->handle, (i - 1), &val))
310 if (!JS_SetElement(self->jscx, self->handle, i, &val))
314 /* get JS value of new object */
315 if (![self->ctx jsValue:&obj forObject:_object])
319 if (JS_SetElement(self->jscx, self->handle, _idx, &obj)) {
322 NSLog(@"%s: after: %@", __PRETTY_FUNCTION__,
323 [[[self convertToNSArray]
324 valueForKey:@"description"]
325 componentsJoinedByString:@","]);
331 NSAssert2(NO, @"element insert failed (%@ at idx %d) !", self, _idx);
333 - (void)addObject:(id)_object {
334 [self insertObject:_object atIndex:[self count]];
337 @end /* NGJavaScriptArray(NSMutableArrayCompatibility) */