[Freeswitch-svn] [commit] r5701 - freeswitch/trunk/src/mod/languages/mod_spidermonkey_socket

Freeswitch SVN mikej at freeswitch.org
Tue Sep 11 19:29:50 EDT 2007


Author: mikej
Date: Tue Sep 11 19:29:50 2007
New Revision: 5701

Added:
   freeswitch/trunk/src/mod/languages/mod_spidermonkey_socket/
   freeswitch/trunk/src/mod/languages/mod_spidermonkey_socket/Makefile
   freeswitch/trunk/src/mod/languages/mod_spidermonkey_socket/mod_spidermonkey_socket.c
   freeswitch/trunk/src/mod/languages/mod_spidermonkey_socket/mod_spidermonkey_socket.vcproj

Log:
MODLANG-21:  Add socket module for spidermonkey from Jonas Gauffin

methods: connect, close, send, readBytes, read.

Note! It's completely untested.

usage:
var socket = new Socket();
socket.connect("hostname", 1234");
var line = socket.read();
socket.send("this is something\n");

The read method takes a delimiter and do not return until the
delimiter have been received (or the connection have been dropped).
The default delimiter is "\n".
The readBytes method reads the number of specified bytes.

only a TCP socket implementation. 





Added: freeswitch/trunk/src/mod/languages/mod_spidermonkey_socket/Makefile
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/languages/mod_spidermonkey_socket/Makefile	Tue Sep 11 19:29:50 2007
@@ -0,0 +1,4 @@
+switch_srcdir=../../../..
+
+include ../mod_spidermonkey/sm.mak
+

Added: freeswitch/trunk/src/mod/languages/mod_spidermonkey_socket/mod_spidermonkey_socket.c
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/languages/mod_spidermonkey_socket/mod_spidermonkey_socket.c	Tue Sep 11 19:29:50 2007
@@ -0,0 +1,354 @@
+/* 
+ * Spidermonkey Socket Module
+ * Copyright (C) 2007, Jonas Gauffin <jonas.gauffin at gmail.com>
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Initial Developer of the Original Code is
+ * Jonas Gauffin
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * 
+ * Jonas Gauffin <jonas.gauffin at gmail.com>
+ *
+ *
+ * mod_spidermonkey_socket.c -- Socket Javascript Module
+ *
+ */
+#include "mod_spidermonkey.h"
+
+static const char modname[] = "Socket";
+
+struct js_socket_obj {
+	switch_socket_t *socket;
+	switch_memory_pool_t *pool;
+	char* read_buffer;
+	switch_size_t buffer_size;
+	int state;
+};
+typedef struct js_socket_obj js_socket_obj_t;
+
+/* Socket Object */
+/*********************************************************************************/
+static JSBool socket_construct(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
+{
+	if (argc > 0) {
+		js_socket_obj_t* js_socket_obj = 0;
+		switch_memory_pool_t *pool;
+		switch_socket_t *socket;
+
+		switch_core_new_memory_pool(&pool);
+		if (!switch_socket_create(&socket, AF_INET, SOCK_STREAM, SWITCH_PROTO_TCP, pool))
+		{
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Failed to create socket.\n");
+			return JS_FALSE;
+		}
+
+		// allocate information needed by JS to be able to write to the log.
+		// (needed since multitple js sessions can write to the same log)
+		js_socket_obj = switch_core_alloc(pool, sizeof(js_socket_obj_t));
+		js_socket_obj->pool = pool;
+		js_socket_obj->socket = socket;
+		JS_SetPrivate(cx, obj, js_socket_obj);
+		return JS_TRUE;
+	}
+
+	return JS_FALSE;
+}
+
+static void socket_destroy(JSContext * cx, JSObject * obj)
+{
+	js_socket_obj_t *socket = JS_GetPrivate(cx, obj);
+	if (socket == NULL)
+		return;
+
+	if (socket->socket != 0)
+	{
+		switch_socket_shutdown(socket->socket, SWITCH_SHUTDOWN_READWRITE);
+		switch_socket_close(socket->socket);
+		switch_core_destroy_memory_pool(&socket->pool);
+	}
+}
+
+static JSBool socket_connect(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
+{
+	js_socket_obj_t *socket = JS_GetPrivate(cx, obj);
+	if (socket == NULL)
+	{
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to find js object.\n");
+		return JS_FALSE;
+	}
+
+	if (argc == 2)
+	{
+		char *host = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
+		int32 port;
+		switch_sockaddr_t *addr;
+		switch_status_t ret;
+
+		JS_ValueToInt32(cx, argv[1], &port);
+
+		ret = switch_sockaddr_info_get(&addr, host, AF_INET, (switch_port_t)port, 0, socket->pool);
+		if (ret != SWITCH_STATUS_SUCCESS)
+		{
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "switch_sockaddr_info_get failed: %d.\n", ret);
+			return JS_FALSE;
+		}
+
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Connecting to: %s:%d.\n", host, port);
+		ret = switch_socket_connect(socket->socket, addr);
+		if (ret != SWITCH_STATUS_SUCCESS)
+		{
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "switch_socket_connect failed: %d.\n", ret);
+			*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
+		}
+		else
+			*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
+
+	}
+
+	return JS_TRUE;
+}
+
+static JSBool socket_send(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
+{
+	js_socket_obj_t *socket = JS_GetPrivate(cx, obj);
+	if (socket == NULL)
+	{
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to find js object.\n");
+		return JS_FALSE;
+	}
+
+	if (argc == 1)
+	{
+		char *buffer = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
+		switch_size_t len = strlen(buffer);
+		switch_status_t ret = switch_socket_send(socket->socket, buffer, &len);
+		if (ret != SWITCH_STATUS_SUCCESS)
+		{
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "switch_socket_send failed: %d.\n", ret);
+			*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
+		}
+		else
+			*rval = BOOLEAN_TO_JSVAL(JS_TRUE);
+	}
+
+	return JS_TRUE;
+}
+
+static JSBool socket_read_bytes(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
+{
+	js_socket_obj_t *socket = JS_GetPrivate(cx, obj);
+	if (socket == NULL)
+	{
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to find js object.\n");
+		return JS_FALSE;
+	}
+
+	if (argc == 1)
+	{
+		int32 bytes_to_read;
+		switch_status_t ret;
+		switch_size_t len;
+
+		JS_ValueToInt32(cx, argv[0], &bytes_to_read);
+		len = (switch_size_t)bytes_to_read;
+
+		if (socket->buffer_size < len)
+		{
+			socket->read_buffer = switch_core_alloc(socket->pool, len+1);
+			socket->buffer_size = bytes_to_read + 1;
+		}
+
+		ret = switch_socket_recv(socket->socket, socket->read_buffer, &len);
+		if (ret != SWITCH_STATUS_SUCCESS)
+		{
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "switch_socket_send failed: %d.\n", ret);
+			*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
+		}
+		else
+		{
+			socket->read_buffer[len] = 0;
+			*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, socket->read_buffer));
+		}
+	}
+
+	return JS_TRUE;
+}
+
+static JSBool socket_read(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
+{
+	js_socket_obj_t *socket = JS_GetPrivate(cx, obj);
+	if (socket == NULL)
+	{
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to find js object.\n");
+		return JS_FALSE;
+	}
+
+	if (argc >= 0)
+	{
+		char* delimiter = "\n";
+		switch_status_t ret;
+		switch_size_t len = 1;
+		switch_size_t total_length = 0;
+		BOOL can_run = TRUE;
+		char tempbuf[2];
+
+		if (argc == 1)
+			delimiter = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
+
+
+		if (socket->read_buffer == 0)
+			socket->read_buffer = switch_core_alloc(socket->pool, socket->buffer_size);
+
+		while (can_run == TRUE)
+		{
+			ret = switch_socket_recv(socket->socket, tempbuf, &len);
+			if (ret != SWITCH_STATUS_SUCCESS)
+				break;
+
+			tempbuf[1] = 0;
+			if (tempbuf[0] == delimiter[0])
+				break;
+			else if (tempbuf[0] == '\r' && delimiter[0] == '\n')
+				continue;
+			else
+			{
+				// Buffer is full, let's increase it.
+				if (total_length == socket->buffer_size - 1)
+				{
+					switch_size_t new_size = socket->buffer_size + 4196;
+					char* new_buffer = switch_core_alloc(socket->pool, socket->buffer_size);
+					memcpy(new_buffer, socket->read_buffer, total_length);
+					socket->buffer_size = new_size;
+					socket->read_buffer = new_buffer;
+				}
+				socket->read_buffer[total_length] = tempbuf[0];
+				++total_length;
+			}
+		}
+		if (ret != SWITCH_STATUS_SUCCESS)
+		{
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "socket receive failed: %d.\n", ret);
+			*rval = BOOLEAN_TO_JSVAL(JS_FALSE);
+		}
+		else
+		{
+			socket->read_buffer[total_length] = 0;
+			*rval = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, socket->read_buffer));
+		}
+	}
+
+	return JS_TRUE;
+}
+
+static JSBool socket_close(JSContext * cx, JSObject * obj, uintN argc, jsval * argv, jsval * rval)
+{
+	js_socket_obj_t *socket = JS_GetPrivate(cx, obj);
+	if (socket == NULL)
+	{
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to find js object.\n");
+		return JS_FALSE;
+	}
+
+	switch_socket_shutdown(socket->socket, SWITCH_SHUTDOWN_READWRITE);
+	switch_socket_close(socket->socket);
+	socket->socket = NULL;
+	return JS_TRUE;
+}
+
+static JSFunctionSpec socket_methods[] = {
+	{"connect", socket_connect, 1},
+	{"close", socket_close, 1},
+	{"send", socket_send, 1},
+	{"readBytes", socket_read_bytes, 1},
+	{"read", socket_read, 1},
+	{0}
+};
+
+#define SOCKET_ADDRESS 1
+#define SOCKET_PORT 2
+
+static JSPropertySpec socket_props[] = {
+	{"address", SOCKET_ADDRESS, JSPROP_READONLY | JSPROP_PERMANENT},
+	{"port", SOCKET_PORT, JSPROP_READONLY | JSPROP_PERMANENT},
+	{0}
+};
+
+
+static JSBool socket_getProperty(JSContext * cx, JSObject * obj, jsval id, jsval * vp)
+{
+	JSBool res = JS_TRUE;
+//	js_socket_obj_t *socket = JS_GetPrivate(cx, obj);
+	char *name;
+	int param = 0;
+
+	name = JS_GetStringBytes(JS_ValueToString(cx, id));
+	/* numbers are our props anything else is a method */
+	if (name[0] >= 48 && name[0] <= 57) {
+		param = atoi(name);
+	} else {
+		return JS_TRUE;
+	}
+
+	switch (param) {
+	case SOCKET_ADDRESS:
+		*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, "unknown"));
+		break;
+	case SOCKET_PORT:
+		*vp = INT_TO_JSVAL(1234);
+		break;
+	}
+
+	return res;
+}
+
+JSClass socket_class = {
+	modname, JSCLASS_HAS_PRIVATE,
+	JS_PropertyStub, JS_PropertyStub, socket_getProperty, JS_PropertyStub,
+	JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, socket_destroy, NULL, NULL, NULL,
+	socket_construct
+};
+
+
+switch_status_t socket_load(JSContext * cx, JSObject * obj)
+{
+	JS_InitClass(cx, obj, NULL, &socket_class, socket_construct, 3, socket_props, socket_methods, socket_props, socket_methods);
+	return SWITCH_STATUS_SUCCESS;
+}
+
+
+const sm_module_interface_t socket_module_interface = {
+	/*.name = */ modname,
+	/*.spidermonkey_load */ socket_load,
+	/*.next */ NULL
+};
+
+SWITCH_MOD_DECLARE(switch_status_t) spidermonkey_init(const sm_module_interface_t ** module_interface)
+{
+	*module_interface = &socket_module_interface;
+	return SWITCH_STATUS_SUCCESS;
+}
+
+/* For Emacs:
+ * Local Variables:
+ * mode:c
+ * indent-tabs-mode:t
+ * tab-width:4
+ * c-basic-offset:4
+ * End:
+ * For VIM:
+ * vim:set softtabstop=4 shiftwidth=4 tabstop=4 expandtab:
+ */

Added: freeswitch/trunk/src/mod/languages/mod_spidermonkey_socket/mod_spidermonkey_socket.vcproj
==============================================================================
--- (empty file)
+++ freeswitch/trunk/src/mod/languages/mod_spidermonkey_socket/mod_spidermonkey_socket.vcproj	Tue Sep 11 19:29:50 2007
@@ -0,0 +1,205 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="mod_spidermonkey_socket"
+	ProjectGUID="{028C7278-05D7-4E18-82FE-BE231B844F41}"
+	RootNamespace="mod_spidermonkey_socket"
+	Keyword="Win32Proj"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="2"
+			InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+			CharacterSet="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="&quot;$(InputDir)..\..\..\include&quot;;&quot;$(InputDir)..\..\..\..\libs\include&quot;;&quot;$(InputDir)..\..\..\..\libs\js\src&quot;;&quot;$(InputDir)..\..\..\..\libs\js\nsprpub\pr\include&quot;;&quot;$(InputDir)..\mod_spidermonkey&quot;"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;MOD_EXPORTS;XP_WIN;DEBUG;_X86_=1;JSFILE;EXPORT_JS_API;HAVE_CURL;CURL_STATICLIB;JS_THREADSAFE"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="3"
+				UsePrecompiledHeader="0"
+				WarningLevel="4"
+				WarnAsError="true"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkLibraryDependencies="true"
+				AdditionalOptions="&quot;..\..\..\..\libs\win32\js\debug\js32.lib&quot; &quot;..\..\..\..\libs\win32\apr\debug\libapr-1.lib&quot; &quot;..\..\..\..\w32\library\debug\freeswitchcore.lib&quot; &quot;..\..\..\..\libs\win32\debug\libetpan.lib&quot; &quot;..\mod_spidermonkey\debug\mod_spidermonkey.lib&quot;"
+				OutputFile="$(SolutionDir)$(OutDir)/mod/$(InputName).dll"
+				LinkIncremental="1"
+				AdditionalLibraryDirectories="&quot;..\..\..\..\libs\nspr-4.6.1.winnt5.$(OutDir)\nspr-4.6.1\lib&quot;"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				ImportLibrary="$(OutDir)/mod_spidermonkey_socket.lib"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="2"
+			CharacterSet="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;MOD_SPIDERMONKEY_SOCKET_EXPORTS"
+				RuntimeLibrary="2"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				LinkIncremental="1"
+				GenerateDebugInformation="true"
+				SubSystem="2"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath=".\mod_spidermonkey_socket.c"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>



More information about the Freeswitch-svn mailing list