Пример #1
0
void
xs_stream_encrypt(xsMachine *the)
{
	crypt_stream_t *stream = xsGetHostData(xsThis);
	int ac = xsToInteger(xsArgc);
	size_t len;
	void *indata, *outdata;

	if (xsTypeOf(xsArg(0)) == xsStringType)
		len = c_strlen(xsToString(xsArg(0)));
	else
		len = xsGetArrayBufferLength(xsArg(0));
	if (ac > 2 && xsTypeOf(xsArg(2)) != xsUndefinedType) {
		size_t n = xsToInteger(xsArg(2));
		if (n < len)
			len = n;
	}
	if (ac > 1 && xsTest(xsArg(1))) {
		if (xsGetArrayBufferLength(xsArg(1)) < (xsIntegerValue)len)
			crypt_throw_error(the, "too small buffer");
		xsResult = xsArg(1);
	}
	else
		xsResult = xsArrayBuffer(NULL, len);
	if (xsTypeOf(xsArg(0)) == xsStringType)
		indata = xsToString(xsArg(0));
	else
		indata = xsToArrayBuffer(xsArg(0));
	outdata = xsToArrayBuffer(xsResult);
	(*stream->process)(stream->ctx, indata, outdata, len);
}
Пример #2
0
void
xs_stream_encrypt(xsMachine *the)
{
	crypt_stream_t *stream = xsGetHostData(xsThis);
	int ac = xsToInteger(xsArgc);
	size_t len;
	void *indata, *outdata;

	if (xsTypeOf(xsArg(0)) == xsStringType)
		len = strlen(xsToString(xsArg(0)));
	else
		len = xsGetArrayBufferLength(xsArg(0));
	if (ac > 2 && xsTypeOf(xsArg(2)) != xsUndefinedType) {
		size_t n = xsToInteger(xsArg(2));
		if (n < len)
			len = n;
	}
	xsResult = ac > 1 && xsTest(xsArg(1)) ? xsArg(1) : xsArrayBuffer(NULL, len);
	if (xsTypeOf(xsArg(0)) == xsStringType)
		indata = xsToString(xsArg(0));
	else
		indata = xsToArrayBuffer(xsArg(0));
	outdata = xsToArrayBuffer(xsResult);
	(*stream->process)(stream->ctx, indata, outdata, len);
}
Пример #3
0
void xs_gpio_init(xsMachine* the)
{
    FskErr err;
    FskGPIO gpio;
    SInt32 pin = 0;
	GPIOdirection dir;
    char *pinName = NULL;

    xsVars(1);

    if ((gpio = xsGetHostData(xsThis)))
        xsThrowDiagnosticIfFskErr(kFskErrOperationFailed, "Digital pin %d already initialized.", (int)gpio->pinNum);

    dir = stringToDirection(the, xsToString(xsGet(xsThis, xsID("_direction"))), gpio);

    xsVar(0) = xsGet(xsThis, xsID("_pin"));
    if (xsStringType == xsTypeOf(xsVar(0)))
        pinName = xsToString(xsVar(0));
    else
        pin = xsToInteger(xsVar(0));

    err = FskGPIONew(&gpio, pin, pinName, dir);
    xsThrowDiagnosticIfFskErr(err, "Digital pin %d initialization failed with error %s.", pin, FskInstrumentationGetErrorString(err));

    xsSetHostData(xsThis, gpio);
}
Пример #4
0
void KPR_message_setRequestCertificate(xsMachine* the)
{
	KprMessage self = xsGetHostData(xsThis);
	FskSocketCertificateRecord* certs = NULL;
	FskSocketCertificateRecord certsRecord = {
		NULL, 0,
		NULL,
		NULL,
		NULL, 0,
	};
	if (xsIsInstanceOf(xsArg(0), xsObjectPrototype)) {
		certs = &certsRecord;
		if (xsHas(xsArg(0), xsID("certificates"))) {
			certs->certificates = (void*)xsToString(xsGet(xsArg(0), xsID("certificates")));
			certs->certificatesSize = FskStrLen(certs->certificates);
		}
		if (xsHas(xsArg(0), xsID("policies"))) {
			certs->policies = xsToString(xsGet(xsArg(0), xsID("policies")));
		}
		if (xsHas(xsArg(0), xsID("key"))) {
			certs->key = (void*)xsToString(xsGet(xsArg(0), xsID("key")));
			certs->keySize = FskStrLen(certs->key);
		}
	}
	else { // compatibility
		certs = &certsRecord;
		if (xsTest(xsArg(0))) {
			certs->certificates = xsGetHostData(xsArg(0));
			certs->certificatesSize = xsToInteger(xsGet(xsArg(0), xsID_length));
		}
		if (xsTest(xsArg(1)))
			certs->policies = xsToString(xsArg(1));
	}
	xsThrowIfFskErr(KprMessageSetRequestCertificate(self, certs));
}
Пример #5
0
void KPR_debug_file(xsMachine *the)
{
	KprDebug self = xsGetHostData(xsThis);
	KprDebugMachine machine = NULL;
	int command = mxNoCommand;
	char* path = NULL;
	char* value = NULL;
	xsIntegerValue line = -1;
	xsIntegerValue c = xsToInteger(xsArgc);
	xsVars(4);
	if ((c >= 2) && (xsTypeOf(xsArg(0)) == xsStringType) && (xsTypeOf(xsArg(1)) == xsIntegerType)) {
		char* address = xsToString(xsArg(0));
		command = xsToInteger(xsArg(1));
		machine = KprDebugFindMachine(self, address);
	}
	if ((c >= 4) && (xsTypeOf(xsArg(2)) == xsStringType) && (xsTypeOf(xsArg(3)) == xsIntegerType)) {
		path = FskStrDoCopy(xsToString(xsArg(2)));
		line = xsToInteger(xsArg(3));
	}
	if ((c >= 5) && (xsTypeOf(xsArg(4)) == xsStringType)) {
		value = FskStrDoCopy(xsToString(xsArg(4)));
	}
	if (machine && ((command == mxFramesView) || (command == mxFilesView) || (command == mxLogView) || (command == mxBreakpointsView))) {
		xsEnterSandbox();
		KprDebugMachineDispatchCommand(machine, command, path, value, line);
		xsLeaveSandbox();
	}
	else
		xsThrowIfFskErr(kFskErrInvalidParameter);
	FskMemPtrDispose(value);
	FskMemPtrDispose(path);
}
Пример #6
0
void xsToolWriteString(xsMachine* the)
{
	char* aPath;
	FILE* aFile;
	char *aBuffer;
	size_t aSize;

	aPath = xsToString(xsArg(0));
#if mxWindows
	{
		char* aSlash;
		aSlash = aPath;
		while (*aSlash) {
			if (*aSlash == '/')
				*aSlash = '\\';
			aSlash++;
		}
	}
#endif
	aFile = fopen(aPath, "wb");
	if (aFile) {
		aBuffer = xsToString(xsArg(1));
		aSize = strlen(aBuffer);
		fwrite(aBuffer, 1, aSize, aFile);
		fclose(aFile);
	}
}
Пример #7
0
void KPR_message_setResponseHeader(xsMachine* the)
{
	KprMessage self = kprGetHostData(xsThis, this, message);
	xsStringValue name = xsToString(xsArg(0));
	xsStringValue value = xsToString(xsArg(1));
	(void)KprMessageSetResponseHeader(self, name, value);
}
Пример #8
0
void Library_cacheQuery(xsMachine* the)
{
    KprLibraryServer self = gLibraryServer;
    UInt32 index;
    KprLibraryQuery query;
    FskMutexAcquire(self->queryMutex);
    index = self->queryIndex % kQueryCount;
    query = self->queries[index];
    if (query) {
        KprLibraryQueryDispose(query);
        self->queries[index] = NULL;
    }
    KprLibraryQueryNew(&query);
    FskInstrumentedItemSetOwner(query, self);
    xsEnterSandbox();
    query->index = self->queryIndex;
    query->info = FskStrDoCopy(xsToString(xsGet(xsArg(0), xsID("info"))));
    query->kind = xsToInteger(xsGet(xsArg(0), xsID("kind")));
    query->mime = FskStrDoCopy(xsToString(xsGet(xsArg(0), xsID("mime"))));
    query->url = FskStrDoCopy(xsToString(xsGet(xsArg(0), xsID("url"))));
    xsResult = xsGet(xsArg(0), xsID("authorization"));
    if (xsTest(xsResult))
        query->authorization = FskStrDoCopy(xsToString(xsResult));
    xsLeaveSandbox();
    self->queries[index] = query;
    xsResult = xsInteger(self->queryIndex);
    self->queryIndex++;
    FskMutexRelease(self->queryMutex);
}
Пример #9
0
void KPR_mqttclient_publish(xsMachine* the)
{
	KPR_MQTTClientRecord *self = xsGetHostData(xsThis);
	FskErr err = kFskErrNone;
	char *topic;
	void *payload = NULL;
	UInt32 payloadLength = 0;
	UInt8 qos;
	Boolean retain;
	UInt16 token;

	if (xsToInteger(xsArgc) != 4) xsThrowIfFskErr(kFskErrParameterError);

	topic = xsToString(xsArg(0));

	if (xsTest(xsArg(1))) {
		if (isArrayBuffer(xsArg(1))) {
			payload = xsToArrayBuffer(xsArg(1));
			payloadLength = xsGetArrayBufferLength(xsArg(1));
		} else {
			payload = xsToString(xsArg(1));
			payloadLength = FskStrLen(payload);
		}
	}

	qos = xsToInteger(xsArg(2));
	retain = xsToBoolean(xsArg(3));

	bailIfError(KprMQTTClientPublish(self->client, topic, payload, payloadLength, qos, retain, &token));
	xsResult = xsInteger(token);

bail:
	xsThrowIfFskErr(err);
}
Пример #10
0
void
xs_env_set(xsMachine *the)
{
	mc_env_t *env;
	char *val, *name;
	int pos;
	int argc = xsToInteger(xsArgc);

	if (argc < 1)
		return;
	env = xsGetHostData(xsThis);
	if (1 == argc || xsTypeOf(xsArg(1)) == xsUndefinedType) {
		int result;

		name = xsToString(xsArg(0));
		result = mc_env_unset(env, name);
		xsSetBoolean(xsResult, result == 0);
	}
	else {
		if ((val = mc_strdup(xsToString(xsArg(1)))) == NULL)
			return;
		pos = argc > 2 && xsTypeOf(xsArg(2)) != xsUndefinedType ? xsToInteger(xsArg(2)) : -1;
		name = xsToString(xsArg(0));
		mc_env_set(env, name, val, pos);
		mc_free(val);
	}
}
Пример #11
0
void
xs_dbg_login(xsMachine *the)
{
	char *host = xsToString(xsArg(0));
	char *name = NULL;
	if (xsToInteger(xsArgc) > 1 && xsTest(xsArg(1)))
		name = xsToString(xsArg(1));
	xsSetBoolean(xsResult, xsStartDebug(the, host, name));
}
Пример #12
0
void KPR_mergeURI(xsMachine *the)
{
	xsStringValue base = xsToString(xsArg(0));
	xsStringValue url = xsToString(xsArg(1));
	xsStringValue target;
	xsThrowIfFskErr(KprURLMerge(base, url, &target));
	xsResult = xsString(target);
	FskMemPtrDispose(target);
}
Пример #13
0
void xsToolResolvePath(xsMachine* the)
{
#if mxWindows
	char* srcPath;
	char* aSlash;
	char aPath[1024];
	DWORD attributes;
	int aResult = 0;

	srcPath = xsToString(xsArg(0));
	aSlash = srcPath;
	while (*aSlash) {
		if (*aSlash == '/')
			*aSlash = '\\';
		aSlash++;
	}	
	if (_fullpath(aPath, srcPath, 1024) != NULL) {
		attributes = GetFileAttributes(aPath);
		if (attributes != 0xFFFFFFFF) {
			if (xsToInteger(xsArgc) == 1)
				aResult = 1;
			else if (xsToBoolean(xsArg(1)))
				aResult = (attributes & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0; 
			else
				aResult = (attributes & FILE_ATTRIBUTE_DIRECTORY) ? 0 : 1; 
		}
	}
#else
	char* srcPath;
	char aPath[PATH_MAX];
	struct stat a_stat;
	int aResult = 0;
	
	srcPath = xsToString(xsArg(0));
	if (realpath(srcPath, aPath) != NULL) {
		if (stat(aPath, &a_stat) == 0) {
			if (xsToInteger(xsArgc) == 1)
				aResult = 1;
			else if (xsToBoolean(xsArg(1)))
				aResult = S_ISDIR(a_stat.st_mode) ? 1 : 0;
			else
				aResult = S_ISREG(a_stat.st_mode) ? 1 : 0;
		}
	}
#endif
	if (aResult) {
		if (xsToBoolean(xsArg(1))) {
			aResult = strlen(aPath) - 1;
			if (aPath[aResult] == mxSeparator)
				aPath[aResult] = 0;
		}
		xsResult = xsString(aPath);
	}
}
Пример #14
0
void xsToolOpenFile(xsMachine* the)
{
	FILE* aFile;
	int argc = xsToInteger(xsArgc);
	char *path = xsToString(xsArg(0));
	if (argc > 1)
		aFile = fopen(path, xsToString(xsArg(1)));
	else
		aFile = fopen(path, "w");
	xsElseError(aFile);
	xsSetHostData(xsThis, aFile);
}
Пример #15
0
void kpr2jsCompareName(xsMachine* the)
{
    char *aName1 = NULL;
    char *aName2 = NULL;

    aName1 = xsToString(xsArg(0));
    aName2 = xsToString(xsArg(1));
#if mxWindows
    xsResult = xsInteger(_stricmp(aName1, aName2));
#else
    xsResult = xsInteger(strcasecmp(aName1, aName2));
#endif
}
Пример #16
0
void KPR_host_setBreakpoint(xsMachine* the)
{
#ifdef mxDebug
	KprHost self = xsGetHostData(xsThis);
	KprApplication application = (KprApplication)self->first;
	xsStringValue file = xsToString(xsArg(0));
	xsStringValue line = xsToString(xsArg(1));
	xsBeginHost(application->the);
	{
		(void)xsCall2(xsGet(xsGet(xsGlobal, xsID("xs")), xsID("debug")), xsID("setBreakpoint"), xsString(file), xsString(line));
	}
	xsEndHost(application->the);
#endif
}
Пример #17
0
void kpr2jsCompareFile(xsMachine* the)
{
    char *aPath1 = NULL;
    char *aPath2 = NULL;

    aPath1 = xsToString(xsArg(0));
    aPath2 = xsToString(xsArg(1));
#if mxWindows
    xsResult = xsInteger(_stricmp(aPath1, aPath2) == 0);
#elif mxMacOSX
    xsResult = xsInteger(strcasecmp(aPath1, aPath2) == 0);
#else
    xsResult = xsInteger(strcmp(aPath1, aPath2) == 0);
#endif
}
Пример #18
0
void kpr2jsSplitPath(xsMachine* the)
{
    char *aPath;
    char *aSeparator = NULL;
    char *aDot = NULL;
    int aLength;
    char aDirectory[1024];
    char aName[1024];
    char anExtension[1024];

    aPath = xsToString(xsArg(0));
    aSeparator = strrchr(aPath, mxSeparator);
    if (aSeparator == NULL)
        aSeparator = aPath;
    else
        aSeparator++;
    aDot = strrchr(aSeparator, '.');
    if (aDot == NULL)
        aDot = aSeparator + strlen(aSeparator);
    aLength = aSeparator - aPath;
    strncpy(aDirectory, aPath, aLength);
    aDirectory[aLength - 1] = 0;
    aLength = aDot - aSeparator;
    strncpy(aName, aSeparator, aLength);
    aName[aLength] = 0;
    strcpy(anExtension, aDot);
    xsResult = xsNewInstanceOf(xsArrayPrototype);
    xsSet(xsResult, 0, xsString(aDirectory));
    xsSet(xsResult, 1, xsString(aName));
    xsSet(xsResult, 2, xsString(anExtension));
}
Пример #19
0
void kpr2jsWriteFile(xsMachine* the)
{
    FILE* aFile = xsGetHostData(xsThis);
    int c = fprintf(aFile, "%s", xsToString(xsArg(0)));
    c += xsToInteger(xsGet(xsThis, xsID("charCount")));
    xsSet(xsThis, xsID("charCount"), xsInteger(c));
}
Пример #20
0
void KPR_Message_cancelReferrer(xsMachine* the)
{
	char* url = FskStrDoCopy(xsToString(xsArg(0)));
	xsThrowIfNULL(url);
	KprMessageCancelReferrer(url);
	FskMemPtrDispose(url);
}
Пример #21
0
void kpr2jsReport(xsMachine* the)
{
    char *aString = NULL;

    aString = xsToString(xsArg(0));
    fprintf(stderr, "%s\n", aString);
}
Пример #22
0
void xsToolReadString(xsMachine* the)
{
	char* aPath;
	FILE* aFile;
	size_t aSize;
	char *aBuffer;

	aPath = xsToString(xsArg(0));
#if mxWindows
	{
		char* aSlash;
		aSlash = aPath;
		while (*aSlash) {
			if (*aSlash == '/')
				*aSlash = '\\';
			aSlash++;
		}
	}
#endif
	aFile = fopen(aPath, "rb");
	if (aFile) {
		fseek(aFile, 0, SEEK_END);
		aSize = ftell(aFile);
		fseek(aFile, 0, SEEK_SET);
		aBuffer = malloc(aSize + 1);
		if (aBuffer) {
			aSize = fread(aBuffer, 1, aSize, aFile);
			aBuffer[aSize] = 0;
			xsResult = xsString(aBuffer);
			free(aBuffer);
		}
		fclose(aFile);
	}
}
Пример #23
0
void KPR_Message_URI(xsMachine* the)
{
	char* url = NULL;
	xsThrowIfFskErr(KprMessageURL(xsGetContext(the), xsToString(xsArg(0)), &url));
	xsResult = xsString(url);
	FskMemPtrDispose(url);
}
Пример #24
0
void
xs_system_init_rng(xsMachine *the)
{
	size_t sz;
	void *data;

	switch (xsTypeOf(xsArg(0))) {
	case xsIntegerType:
	case xsNumberType: {
		unsigned long n = xsToNumber(xsArg(0));
		data = &n;
		sz = sizeof(long);
		break;
	}
	case xsStringType: {
		char *s = xsToString(xsArg(0));
		data = s;
		sz = strlen(s);
		break;
	}
	default:
		if (xsIsInstanceOf(xsArg(0), xsArrayBufferPrototype)) {
			data = xsToArrayBuffer(xsArg(0));
			sz = xsGetArrayBufferLength(xsArg(0));
		}
		else {
			data = NULL;
			sz = 0;
		}
		break;
	}
	mc_rng_init(data, sz);
}
Пример #25
0
void KPR_message_getResponseHeader(xsMachine* the)
{
	KprMessage self = kprGetHostData(xsThis, this, message);
	xsStringValue result = KprMessageGetResponseHeader(self, xsToString(xsArg(0)));
	if (result)
		xsResult = xsString(result);
}
Пример #26
0
void KPR_canvasRadialGradient_setStyle(xsMachine *the)
{
	FskCanvas2dContext ctx = xsGetHostData(xsArg(0));
	xsNumberValue x0 = xsToNumber(xsGet(xsThis, xsID("x0")));
	xsNumberValue y0 = xsToNumber(xsGet(xsThis, xsID("y0")));
	xsNumberValue r0 = xsToNumber(xsGet(xsThis, xsID("r0")));
	xsNumberValue x1 = xsToNumber(xsGet(xsThis, xsID("x1")));
	xsNumberValue y1 = xsToNumber(xsGet(xsThis, xsID("y1")));
	xsNumberValue r1 = xsToNumber(xsGet(xsThis, xsID("r1")));
	UInt32 c, i;
	FskCanvas2dGradientStop stops[kCanvas2DMaxGradientStops];
	xsVars(2);
	xsVar(0) = xsGet(xsThis, xsID("stops"));
	c = xsToInteger(xsGet(xsVar(0), xsID("length")));
	if (c > kCanvas2DMaxGradientStops) c = kCanvas2DMaxGradientStops;
	for (i = 0; i < c; i++) {
		xsVar(1) = xsGetAt(xsVar(0), xsInteger(i));
		stops[i].offset = xsToNumber(xsGet(xsVar(1), xsID("offset")));
		xsVar(1) = xsGet(xsVar(1), xsID("color"));
		if (!KprParseColor(the, xsToString(xsVar(1)), &(stops[i].color)))
			return;
	}
	if (xsTest(xsArg(1)))
		FskCanvas2dSetStrokeStyleRadialGradient(ctx, x0, y0, r0, x1, y1, r1, c, stops);
	else
		FskCanvas2dSetFillStyleRadialGradient(ctx, x0, y0, r0, x1, y1, r1, c, stops);
}
Пример #27
0
void KPR_canvasPattern_setStyle(xsMachine *the)
{
	FskCanvas2dContext ctx = xsGetHostData(xsArg(0));
	UInt32 repetition = kFskCanvas2dPatternRepeat;
	FskConstBitmap bitmap = NULL;
	Boolean owned = false;
	xsVars(1);
	xsVar(0) = xsGet(xsThis, xsID("repetition"));
	if (xsTest(xsVar(0))) {
		xsStringValue it = xsToString(xsVar(0));
		if (!FskStrCompare(it, "no-repeat")) repetition = kFskCanvas2dPatternRepeatNone;
		else if (!FskStrCompare(it, "repeat-x")) repetition = kFskCanvas2dPatternRepeatX;
		else if (!FskStrCompare(it, "repeat-y")) repetition = kFskCanvas2dPatternRepeatY;
		else if (!FskStrCompare(it, "repeat")) repetition = kFskCanvas2dPatternRepeat;
		else xsError(kFskErrInvalidParameter);
	}
	xsVar(0) = xsGet(xsThis, xsID("image"));
	if (xsIsInstanceOf(xsVar(0), xsGet(xsGet(xsGlobal, xsID_KPR), xsID_texture))) {
		KprTexture texture = xsGetHostData(xsVar(0));
		bitmap = KprTextureGetBitmap(texture, NULL, &owned);
	}
	else {
		KprContent content = xsGetHostData(xsVar(0));
		bitmap = (*content->dispatch->getBitmap)(content, NULL, &owned);
	}
	if (!bitmap)
		xsError(kFskErrInvalidParameter);
	if (xsTest(xsArg(1)))
		FskCanvas2dSetStrokeStylePattern(ctx, repetition, bitmap);
	else
		FskCanvas2dSetFillStylePattern(ctx, repetition, bitmap);
	if (!owned)
		FskBitmapDispose((FskBitmap)bitmap);
}
Пример #28
0
void KPR_canvasRenderingContext2D_clip(xsMachine *the)
{
	FskCanvas2dContext	ctx			= xsGetHostData(xsThis);
	FskCanvas2dPath		path		=  NULL;
	SInt32				fillRule	= kFskCanvas2dFillRuleNonZero;
	int					numArgs		= xsToInteger(xsArgc);

	if (numArgs > 0) {																		/* ctx.clip(), when numArgs==0 */
		if (xsIsInstanceOf(xsArg(0), xsGet(xsGet(xsGlobal, xsID_KPR), xsID("path2D")))) {	/* ctx.clip(path) */
			path = xsGetHostData(xsArg(0));
			if (numArgs > 1)	fillRule = GetFillRule(xsToString(xsArg(1)));				/* ctx.clip(path, fillRule) */
		} else {				fillRule = GetFillRule(xsToString(xsArg(0)));				/* ctx.clip(fillRule) */
		}
	}
	FskCanvas2dPathClip(ctx, path, fillRule);
}
Пример #29
0
void KPR_mqttclient_unsubscribe(xsMachine* the)
{
	KPR_MQTTClientRecord *self = xsGetHostData(xsThis);
	FskErr err = kFskErrNone;
	xsIntegerValue c = xsToInteger(xsArgc);
	char **topics = NULL;
	int i, count;
	UInt16 token;

	if (c == 0) xsThrowIfFskErr(kFskErrParameterError);

	count = c;

	bailIfError(FskMemPtrNew(sizeof(char*) * count, &topics));

	for (i = 0; i < count; i++) {
		topics[i] = xsToString(xsArg(i));
	}

	bailIfError(KprMQTTClientUnsubscribeTopics(self->client, topics, count, &token));
	xsResult = xsInteger(token);

bail:
	FskMemPtrDispose(topics);
	xsThrowIfFskErr(err);
}
Пример #30
0
void KPR_system_saveFile(xsMachine* the)
{
	FskErr err;
	xsIntegerValue argc = xsToInteger(xsArgc);
	xsStringValue name = NULL;
	xsStringValue prompt = NULL;
	xsStringValue initialPath = NULL;
	xsStringValue path = NULL;
	xsStringValue url = NULL;
	if ((argc > 0) && xsTest(xsArg(0))) {
		if (xsFindResult(xsArg(0), xsID_name))
			name = xsToStringCopy(xsResult);
		if (xsFindResult(xsArg(0), xsID_prompt))
			prompt = xsToStringCopy(xsResult);
		if (xsFindResult(xsArg(0), xsID_url))
			KprURLToPath(xsToString(xsResult), &initialPath);
	}
	err = FskFileChooseSave(name, prompt, initialPath, &path);
	if ((kFskErrNone == err) && (NULL != path)) {
		KprPathToURL(path, &url);
		(void)xsCallFunction1(xsArg(1), xsNull, xsString(url));
	}
	FskMemPtrDispose(url);
	FskMemPtrDispose(path);
	FskMemPtrDispose(initialPath);
	FskMemPtrDispose(prompt);
	FskMemPtrDispose(name);
}