Initial commit of mod_v8
This commit is contained in:
parent
cc8a8c5198
commit
b762332669
|
@ -169,6 +169,9 @@ Release/
|
|||
/src/mod/say/mod_say_nl/Makefile
|
||||
/src/mod/say/mod_say_th/Makefile
|
||||
/src/mod/say/mod_say_zh/Makefile
|
||||
/src/mod/languages/mod_v8/Makefile
|
||||
/src/mod/languages/mod_v8/Makefile.in
|
||||
/src/mod/languages/mod_v8/mod_v8.log
|
||||
|
||||
BuildLog.htm
|
||||
|
||||
|
|
|
@ -87,6 +87,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "autoload_configs", "autoloa
|
|||
conf\vanilla\autoload_configs\spidermonkey.conf.xml = conf\vanilla\autoload_configs\spidermonkey.conf.xml
|
||||
conf\vanilla\autoload_configs\switch.conf.xml = conf\vanilla\autoload_configs\switch.conf.xml
|
||||
conf\vanilla\autoload_configs\syslog.conf.xml = conf\vanilla\autoload_configs\syslog.conf.xml
|
||||
conf\vanilla\autoload_configs\v8.conf.xml = conf\vanilla\autoload_configs\v8.conf.xml
|
||||
conf\vanilla\autoload_configs\voicemail.conf.xml = conf\vanilla\autoload_configs\voicemail.conf.xml
|
||||
conf\vanilla\autoload_configs\wanpipe.conf.xml = conf\vanilla\autoload_configs\wanpipe.conf.xml
|
||||
conf\vanilla\autoload_configs\woomera.conf.xml = conf\vanilla\autoload_configs\woomera.conf.xml
|
||||
|
@ -195,6 +196,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libteletone", "libs\libtele
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_spidermonkey", "src\mod\languages\mod_spidermonkey\mod_spidermonkey.2012.vcxproj", "{1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_v8", "src\mod\languages\mod_v8\mod_v8.2012.vcxproj", "{9B9D2551-D6BD-4F20-8BE5-DE30E154A064}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_v8_skel", "src\mod\languages\mod_v8\mod_v8_skel.2012.vcxproj", "{8B754330-A434-4791-97E5-1EE67060BAC0}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_cepstral", "src\mod\asr_tts\mod_cepstral\mod_cepstral.2012.vcxproj", "{692F6330-4D87-4C82-81DF-40DB5892636E}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_ilbc", "src\mod\codecs\mod_ilbc\mod_ilbc.2012.vcxproj", "{D3EC0AFF-76FC-4210-A825-9A17410660A3}"
|
||||
|
@ -577,6 +582,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libcbt", "libs\win32\libcbt
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "make_cielab_luts", "libs\spandsp\src\msvc\make_cielab_luts.2012.vcxproj", "{85F0CF8C-C7AB-48F6-BA19-CC94CF87F981}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Download V8", "libs\win32\Download V8.2012.vcxproj", "{13077E43-E5DF-4EF6-9EB1-2A0B22E8DFAF}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libv8", "libs\win32\v8\libv8.2012.vcxproj", "{AB03E82B-48B1-4374-B32A-A1AF83DDC6C2}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Download OPUS", "libs\win32\Download OPUS.2012.vcxproj", "{092124C9-09ED-43C7-BD6D-4AE5D6B3C547}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "opus", "opus", "{ED2CA8B5-8E91-4296-A120-02BB0B674652}"
|
||||
|
@ -839,6 +848,38 @@ Global
|
|||
{1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}.Release|x64.Build.0 = Release|x64
|
||||
{1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}.Release|x64 Setup.ActiveCfg = Release|x64
|
||||
{1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}.Release|x86 Setup.ActiveCfg = Release|Win32
|
||||
{9B9D2551-D6BD-4F20-8BE5-DE30E154A064}.All|Win32.ActiveCfg = Release|x64
|
||||
{9B9D2551-D6BD-4F20-8BE5-DE30E154A064}.All|x64.ActiveCfg = Release|x64
|
||||
{9B9D2551-D6BD-4F20-8BE5-DE30E154A064}.All|x64.Build.0 = Release|x64
|
||||
{9B9D2551-D6BD-4F20-8BE5-DE30E154A064}.All|x64 Setup.ActiveCfg = Release|x64
|
||||
{9B9D2551-D6BD-4F20-8BE5-DE30E154A064}.All|x64 Setup.Build.0 = Release|x64
|
||||
{9B9D2551-D6BD-4F20-8BE5-DE30E154A064}.All|x86 Setup.ActiveCfg = Release|x64
|
||||
{9B9D2551-D6BD-4F20-8BE5-DE30E154A064}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{9B9D2551-D6BD-4F20-8BE5-DE30E154A064}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{9B9D2551-D6BD-4F20-8BE5-DE30E154A064}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{9B9D2551-D6BD-4F20-8BE5-DE30E154A064}.Debug|x64.Build.0 = Debug|x64
|
||||
{9B9D2551-D6BD-4F20-8BE5-DE30E154A064}.Debug|x64 Setup.ActiveCfg = Debug|x64
|
||||
{9B9D2551-D6BD-4F20-8BE5-DE30E154A064}.Debug|x86 Setup.ActiveCfg = Debug|Win32
|
||||
{9B9D2551-D6BD-4F20-8BE5-DE30E154A064}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{9B9D2551-D6BD-4F20-8BE5-DE30E154A064}.Release|Win32.Build.0 = Release|Win32
|
||||
{9B9D2551-D6BD-4F20-8BE5-DE30E154A064}.Release|x64.ActiveCfg = Release|x64
|
||||
{9B9D2551-D6BD-4F20-8BE5-DE30E154A064}.Release|x64.Build.0 = Release|x64
|
||||
{9B9D2551-D6BD-4F20-8BE5-DE30E154A064}.Release|x64 Setup.ActiveCfg = Release|x64
|
||||
{9B9D2551-D6BD-4F20-8BE5-DE30E154A064}.Release|x86 Setup.ActiveCfg = Release|Win32
|
||||
{8B754330-A434-4791-97E5-1EE67060BAC0}.All|Win32.ActiveCfg = Release|x64
|
||||
{8B754330-A434-4791-97E5-1EE67060BAC0}.All|x64.ActiveCfg = Release|x64
|
||||
{8B754330-A434-4791-97E5-1EE67060BAC0}.All|x64.Build.0 = Release|x64
|
||||
{8B754330-A434-4791-97E5-1EE67060BAC0}.All|x64 Setup.ActiveCfg = Release|x64
|
||||
{8B754330-A434-4791-97E5-1EE67060BAC0}.All|x64 Setup.Build.0 = Release|x64
|
||||
{8B754330-A434-4791-97E5-1EE67060BAC0}.All|x86 Setup.ActiveCfg = Release|x64
|
||||
{8B754330-A434-4791-97E5-1EE67060BAC0}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{8B754330-A434-4791-97E5-1EE67060BAC0}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{8B754330-A434-4791-97E5-1EE67060BAC0}.Debug|x64 Setup.ActiveCfg = Debug|x64
|
||||
{8B754330-A434-4791-97E5-1EE67060BAC0}.Debug|x86 Setup.ActiveCfg = Debug|Win32
|
||||
{8B754330-A434-4791-97E5-1EE67060BAC0}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{8B754330-A434-4791-97E5-1EE67060BAC0}.Release|x64.ActiveCfg = Release|x64
|
||||
{8B754330-A434-4791-97E5-1EE67060BAC0}.Release|x64 Setup.ActiveCfg = Release|x64
|
||||
{8B754330-A434-4791-97E5-1EE67060BAC0}.Release|x86 Setup.ActiveCfg = Release|Win32
|
||||
{692F6330-4D87-4C82-81DF-40DB5892636E}.All|Win32.ActiveCfg = Release|x64
|
||||
{692F6330-4D87-4C82-81DF-40DB5892636E}.All|x64.ActiveCfg = Release|x64
|
||||
{692F6330-4D87-4C82-81DF-40DB5892636E}.All|x64.Build.0 = Release|x64
|
||||
|
@ -3838,6 +3879,41 @@ Global
|
|||
{85F0CF8C-C7AB-48F6-BA19-CC94CF87F981}.Release|x64.Build.0 = All|Win32
|
||||
{85F0CF8C-C7AB-48F6-BA19-CC94CF87F981}.Release|x64 Setup.ActiveCfg = All|Win32
|
||||
{85F0CF8C-C7AB-48F6-BA19-CC94CF87F981}.Release|x86 Setup.ActiveCfg = All|Win32
|
||||
{13077E43-E5DF-4EF6-9EB1-2A0B22E8DFAF}.All|Win32.ActiveCfg = Release|Win32
|
||||
{13077E43-E5DF-4EF6-9EB1-2A0B22E8DFAF}.All|Win32.Build.0 = Release|Win32
|
||||
{13077E43-E5DF-4EF6-9EB1-2A0B22E8DFAF}.All|x64.ActiveCfg = Release|Win32
|
||||
{13077E43-E5DF-4EF6-9EB1-2A0B22E8DFAF}.All|x64 Setup.ActiveCfg = Release|Win32
|
||||
{13077E43-E5DF-4EF6-9EB1-2A0B22E8DFAF}.All|x86 Setup.ActiveCfg = Release|Win32
|
||||
{13077E43-E5DF-4EF6-9EB1-2A0B22E8DFAF}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{13077E43-E5DF-4EF6-9EB1-2A0B22E8DFAF}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{13077E43-E5DF-4EF6-9EB1-2A0B22E8DFAF}.Debug|x64.ActiveCfg = Debug|Win32
|
||||
{13077E43-E5DF-4EF6-9EB1-2A0B22E8DFAF}.Debug|x64.Build.0 = Debug|Win32
|
||||
{13077E43-E5DF-4EF6-9EB1-2A0B22E8DFAF}.Debug|x64 Setup.ActiveCfg = Debug|Win32
|
||||
{13077E43-E5DF-4EF6-9EB1-2A0B22E8DFAF}.Debug|x86 Setup.ActiveCfg = Debug|Win32
|
||||
{13077E43-E5DF-4EF6-9EB1-2A0B22E8DFAF}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{13077E43-E5DF-4EF6-9EB1-2A0B22E8DFAF}.Release|Win32.Build.0 = Release|Win32
|
||||
{13077E43-E5DF-4EF6-9EB1-2A0B22E8DFAF}.Release|x64.ActiveCfg = Release|Win32
|
||||
{13077E43-E5DF-4EF6-9EB1-2A0B22E8DFAF}.Release|x64.Build.0 = Release|Win32
|
||||
{13077E43-E5DF-4EF6-9EB1-2A0B22E8DFAF}.Release|x64 Setup.ActiveCfg = Release|Win32
|
||||
{13077E43-E5DF-4EF6-9EB1-2A0B22E8DFAF}.Release|x86 Setup.ActiveCfg = Release|Win32
|
||||
{AB03E82B-48B1-4374-B32A-A1AF83DDC6C2}.All|Win32.ActiveCfg = Debug|x64
|
||||
{AB03E82B-48B1-4374-B32A-A1AF83DDC6C2}.All|x64.ActiveCfg = Debug|x64
|
||||
{AB03E82B-48B1-4374-B32A-A1AF83DDC6C2}.All|x64.Build.0 = Debug|x64
|
||||
{AB03E82B-48B1-4374-B32A-A1AF83DDC6C2}.All|x64 Setup.ActiveCfg = Debug|x64
|
||||
{AB03E82B-48B1-4374-B32A-A1AF83DDC6C2}.All|x64 Setup.Build.0 = Debug|x64
|
||||
{AB03E82B-48B1-4374-B32A-A1AF83DDC6C2}.All|x86 Setup.ActiveCfg = Debug|x64
|
||||
{AB03E82B-48B1-4374-B32A-A1AF83DDC6C2}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{AB03E82B-48B1-4374-B32A-A1AF83DDC6C2}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{AB03E82B-48B1-4374-B32A-A1AF83DDC6C2}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{AB03E82B-48B1-4374-B32A-A1AF83DDC6C2}.Debug|x64.Build.0 = Debug|x64
|
||||
{AB03E82B-48B1-4374-B32A-A1AF83DDC6C2}.Debug|x64 Setup.ActiveCfg = Debug|x64
|
||||
{AB03E82B-48B1-4374-B32A-A1AF83DDC6C2}.Debug|x86 Setup.ActiveCfg = Debug|Win32
|
||||
{AB03E82B-48B1-4374-B32A-A1AF83DDC6C2}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{AB03E82B-48B1-4374-B32A-A1AF83DDC6C2}.Release|Win32.Build.0 = Release|Win32
|
||||
{AB03E82B-48B1-4374-B32A-A1AF83DDC6C2}.Release|x64.ActiveCfg = Release|x64
|
||||
{AB03E82B-48B1-4374-B32A-A1AF83DDC6C2}.Release|x64.Build.0 = Release|x64
|
||||
{AB03E82B-48B1-4374-B32A-A1AF83DDC6C2}.Release|x64 Setup.ActiveCfg = Release|x64
|
||||
{AB03E82B-48B1-4374-B32A-A1AF83DDC6C2}.Release|x86 Setup.ActiveCfg = Release|Win32
|
||||
{092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.All|Win32.ActiveCfg = Release|Win32
|
||||
{092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.All|Win32.Build.0 = Release|Win32
|
||||
{092124C9-09ED-43C7-BD6D-4AE5D6B3C547}.All|x64.ActiveCfg = Release|Win32
|
||||
|
@ -4098,10 +4174,13 @@ Global
|
|||
{2386B892-35F5-46CF-A0F0-10394D2FBF9B} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
|
||||
{77BC1DD2-C9A1-44D7-BFFA-1320370CACB9} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
|
||||
{85F0CF8C-C7AB-48F6-BA19-CC94CF87F981} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
|
||||
{AB03E82B-48B1-4374-B32A-A1AF83DDC6C2} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
|
||||
{ED2CA8B5-8E91-4296-A120-02BB0B674652} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
|
||||
{EDDB8AB9-C53E-44C0-A620-0E86C2CBD5D5} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
|
||||
{EC3E5C7F-EE09-47E2-80FE-546363D14A98} = {B8F5B47B-8568-46EB-B320-64C17D2A98BC}
|
||||
{1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F} = {0C808854-54D1-4230-BFF5-77B5FD905000}
|
||||
{9B9D2551-D6BD-4F20-8BE5-DE30E154A064} = {0C808854-54D1-4230-BFF5-77B5FD905000}
|
||||
{8B754330-A434-4791-97E5-1EE67060BAC0} = {0C808854-54D1-4230-BFF5-77B5FD905000}
|
||||
{ACFFF684-4D19-4D48-AF12-88EA1D778BDF} = {0C808854-54D1-4230-BFF5-77B5FD905000}
|
||||
{8F992C49-6C51-412F-B2A3-34EAB708EB65} = {0C808854-54D1-4230-BFF5-77B5FD905000}
|
||||
{0A6B5EA5-6E9B-4A51-931F-ED25AA87B4DF} = {0C808854-54D1-4230-BFF5-77B5FD905000}
|
||||
|
@ -4139,6 +4218,7 @@ Global
|
|||
{B808178B-82F0-4CF4-A2B1-921939FA24D0} = {C120A020-773F-4EA3-923F-B67AF28B750D}
|
||||
{D578E676-7EC8-4548-BD8B-845C635F14AD} = {C120A020-773F-4EA3-923F-B67AF28B750D}
|
||||
{652AD5F7-8488-489F-AAD0-7FBE064703B6} = {C120A020-773F-4EA3-923F-B67AF28B750D}
|
||||
{13077E43-E5DF-4EF6-9EB1-2A0B22E8DFAF} = {C120A020-773F-4EA3-923F-B67AF28B750D}
|
||||
{092124C9-09ED-43C7-BD6D-4AE5D6B3C547} = {C120A020-773F-4EA3-923F-B67AF28B750D}
|
||||
{988CACF7-3FCB-4992-BE69-77872AE67DC8} = {6CD61A1D-797C-470A-BE08-8C31B68BB336}
|
||||
{5BC072DB-3826-48EA-AF34-FE32AA01E83B} = {6CD61A1D-797C-470A-BE08-8C31B68BB336}
|
||||
|
|
|
@ -119,6 +119,7 @@ languages/mod_lua
|
|||
#languages/mod_perl
|
||||
#languages/mod_python
|
||||
#languages/mod_spidermonkey
|
||||
languages/mod_v8
|
||||
#languages/mod_yaml
|
||||
loggers/mod_console
|
||||
loggers/mod_logfile
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
<configuration name="v8.conf" description="Google V8 JavaScript Plug-Ins">
|
||||
<modules>
|
||||
<!-- <load module="mod_v8_skel"/> -->
|
||||
</modules>
|
||||
</configuration>
|
|
@ -79,7 +79,8 @@
|
|||
<!-- Timers -->
|
||||
|
||||
<!-- Languages -->
|
||||
<load module="mod_spidermonkey"/>
|
||||
<!-- <load module="mod_spidermonkey"/> -->
|
||||
<load module="mod_v8"/>
|
||||
<!-- <load module="mod_perl"/> -->
|
||||
<!-- <load module="mod_python"/> -->
|
||||
<!-- <load module="mod_java"/> -->
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
<configuration name="v8.conf" description="Google V8 JavaScript Plug-Ins">
|
||||
<modules>
|
||||
<!-- <load module="mod_v8_skel"/> -->
|
||||
</modules>
|
||||
</configuration>
|
|
@ -110,6 +110,7 @@
|
|||
|
||||
<!-- Languages -->
|
||||
<!-- <load module="mod_spidermonkey"/> -->
|
||||
<load module="mod_v8"/>
|
||||
<!-- <load module="mod_perl"/> -->
|
||||
<!-- <load module="mod_python"/> -->
|
||||
<!-- <load module="mod_java"/> -->
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
<configuration name="v8.conf" description="Google V8 JavaScript Plug-Ins">
|
||||
<modules>
|
||||
<!-- <load module="mod_v8_skel"/> -->
|
||||
</modules>
|
||||
</configuration>
|
|
@ -1162,6 +1162,7 @@ AC_CONFIG_FILES([Makefile
|
|||
src/mod/legacy/languages/mod_lua/Makefile
|
||||
src/mod/languages/mod_python/Makefile
|
||||
src/mod/languages/mod_spidermonkey/Makefile
|
||||
src/mod/languages/mod_v8/Makefile
|
||||
src/mod/event_handlers/mod_erlang_event/Makefile
|
||||
src/include/switch_am_config.h
|
||||
build/getsounds.sh
|
||||
|
|
|
@ -115,6 +115,7 @@ getlibs () {
|
|||
getlib http://files.freeswitch.org/downloads/libs/lame-3.98.4.tar.gz
|
||||
getlib http://files.freeswitch.org/downloads/libs/libshout-2.2.2.tar.gz
|
||||
getlib http://files.freeswitch.org/downloads/libs/mpg123-1.13.2.tar.gz
|
||||
getlib http://files.freeswitch.org/downloads/libs/v8-3.24.14.tar.bz2
|
||||
# cleanup mongo
|
||||
(
|
||||
cd mongo-cxx-driver-v1.8
|
||||
|
|
|
@ -38,6 +38,7 @@ that much better:
|
|||
Juan Jose Comellas <juanjo@comellas.org> - Patch to switch_utils for arg parsing.
|
||||
Dale Thatcher <freeswitch at dalethatcher dot com> - Additions to mod_conference.
|
||||
Simon Perreault & Marc Blanchet from Viagenie.ca - IPv6 Support.
|
||||
Peter Olsson <peter@olssononline.se> - mod_v8, and other various patches.
|
||||
|
||||
A big THANK YOU goes to:
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# spec file for package freeswitch
|
||||
#
|
||||
# includes module(s): freeswitch-devel freeswitch-codec-passthru-amr freeswitch-codec-passthru-amrwb freeswitch-codec-passthru-g729
|
||||
# freeswitch-codec-passthru-g7231 freeswitch-lua freeswitch-perl freeswitch-python freeswitch-spidermonkey
|
||||
# freeswitch-codec-passthru-g7231 freeswitch-lua freeswitch-perl freeswitch-python freeswitch-spidermonkey freeswitch-v8
|
||||
# freeswitch-lan-de freeswitch-lang-en freeswitch-lang-fr freeswitch-lang-hu freeswitch-lang-ru freeswitch-freetdm
|
||||
#
|
||||
# Initial Version Copyright (C) 2007 Peter Nixon and Michal Bielicki, All Rights Reserved.
|
||||
|
@ -127,6 +127,7 @@ Source9: http://files.freeswitch.org/downloads/libs/communicator_semi_6000_20080
|
|||
Source10: http://files.freeswitch.org/downloads/libs/libmemcached-0.32.tar.gz
|
||||
Source11: http://files.freeswitch.org/downloads/libs/json-c-0.9.tar.gz
|
||||
Source12: http://files.freeswitch.org/downloads/libs/opus-1.1.tar.gz
|
||||
Source13: http://files.freeswitch.org/downloads/libs/v8-3.24.14.tar.bz2
|
||||
Prefix: %{prefix}
|
||||
|
||||
|
||||
|
@ -1102,10 +1103,17 @@ Requires: python
|
|||
%package spidermonkey
|
||||
Summary: JavaScript support for the FreeSWITCH open source telephony platform
|
||||
Group: System/Libraries
|
||||
Requires: %{name} = %{version}-%{release}
|
||||
Requires: %{name} = %{version}-%{release}
|
||||
|
||||
%description spidermonkey
|
||||
|
||||
%package v8
|
||||
Summary: JavaScript support for the FreeSWITCH open source telephony platform, using Google V8 JavaScript engine
|
||||
Group: System/Libraries
|
||||
Requires: %{name} = %{version}-%{release}
|
||||
|
||||
%description v8
|
||||
|
||||
######################################################################################################################
|
||||
# FreeSWITCH Say Modules
|
||||
######################################################################################################################
|
||||
|
@ -1421,7 +1429,7 @@ FORMATS_MODULES+=" formats/mod_ssml"
|
|||
# Embedded Languages
|
||||
#
|
||||
######################################################################################################################
|
||||
LANGUAGES_MODULES="languages/mod_lua languages/mod_perl languages/mod_python languages/mod_spidermonkey"
|
||||
LANGUAGES_MODULES="languages/mod_lua languages/mod_perl languages/mod_python languages/mod_spidermonkey languages/mod_v8"
|
||||
|
||||
######################################################################################################################
|
||||
#
|
||||
|
@ -2302,6 +2310,15 @@ fi
|
|||
%dir %attr(0750, freeswitch, daemon) %{sysconfdir}/autoload_configs
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/spidermonkey.conf.xml
|
||||
|
||||
%files v8
|
||||
%defattr(-,freeswitch,daemon)
|
||||
%{MODINSTDIR}/mod_v8*.so*
|
||||
%{LIBDIR}/libv8.so
|
||||
%{LIBDIR}/libicui18n.so
|
||||
%{LIBDIR}/libicuuc.so
|
||||
%dir %attr(0750, freeswitch, daemon) %{sysconfdir}/autoload_configs
|
||||
%config(noreplace) %attr(0640, freeswitch, daemon) %{sysconfdir}/autoload_configs/v8.conf.xml
|
||||
|
||||
######################################################################################################################
|
||||
#
|
||||
# Language Modules
|
||||
|
@ -2427,6 +2444,8 @@ fi
|
|||
#
|
||||
######################################################################################################################
|
||||
%changelog
|
||||
* Mon Jan 13 2014 - peter@olssononline.se
|
||||
- Add mod_v8
|
||||
* Mon Dec 09 2013 - crienzo@grasshopper.com
|
||||
- Add mod_ssml, mod_rayo
|
||||
- Fix build on master
|
||||
|
|
|
@ -980,6 +980,7 @@ opal
|
|||
|
||||
/zeromq-*/
|
||||
/jpeg-8d/
|
||||
/v8-*/
|
||||
|
||||
# build products we should remove
|
||||
!/apr-util/xml/expat/conftools/config.guess
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectName>Download V8</ProjectName>
|
||||
<ProjectGuid>{13077E43-E5DF-4EF6-9EB1-2A0B22E8DFAF}</ProjectGuid>
|
||||
<RootNamespace>Download V8</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Utility</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Utility</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<Import Project="$(SolutionDir)\w32\extdll.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(PlatformName)\V8\$(Configuration)\</IntDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(PlatformName)\V8\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<BuildLog>
|
||||
<Path>$(IntDir)BuildLog $(ProjectName).htm</Path>
|
||||
</BuildLog>
|
||||
<PreBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<BuildLog>
|
||||
<Path>$(IntDir)BuildLog $(ProjectName).htm</Path>
|
||||
</BuildLog>
|
||||
<PreBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="cleancount">
|
||||
<FileType>Document</FileType>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Downloading V8.</Message>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">if not exist "$(ProjectDir)..\v8-3.24.14" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/downloads/libs/v8-3.24.14.tar.bz2 "$(ProjectDir).."
|
||||
if not exist "$(ProjectDir)..\v8-3.24.14\third_party\cygwin" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/downloads/libs/v8-3.24.14-win.tar.bz2 "$(ProjectDir).."
|
||||
</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)..\v8-3.24.14;%(Outputs)</Outputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Downloading V8.</Message>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">if not exist "$(ProjectDir)..\v8-3.24.14" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/downloads/libs/v8-3.24.14.tar.bz2 "$(ProjectDir).."
|
||||
if not exist "$(ProjectDir)..\v8-3.24.14\third_party\cygwin" cscript /nologo "$(ProjectDir)util.vbs" GetUnzip http://files.freeswitch.org/downloads/libs/v8-3.24.14-win.tar.bz2 "$(ProjectDir).."
|
||||
</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)..\v8-3.24.14;%(Outputs)</Outputs>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,59 @@
|
|||
@ECHO OFF
|
||||
|
||||
IF "%1" == "" GOTO Fail
|
||||
IF "%2" == "" GOTO Fail
|
||||
IF "%3" == "" GOTO Fail
|
||||
|
||||
cd "%3"
|
||||
|
||||
SET /P LAST_BUILD_INFO=<last_build
|
||||
|
||||
IF "%1-%2" == "%LAST_BUILD_INFO%" (
|
||||
ECHO V8 is already built!
|
||||
SET COPY_FILES_ONLY=1
|
||||
)
|
||||
|
||||
SET LIB_DEST_DIR=
|
||||
|
||||
IF "%1" == "x64" (
|
||||
IF NOT "%COPY_FILES_ONLY%" == "1" .\third_party\python_26\python.exe build\gyp_v8 -Dtarget_arch=x64 -Dcomponent=shared_library
|
||||
IF NOT ERRORLEVEL 0 GOTO Fail
|
||||
SET LIB_DEST_DIR=..\..\x64\%2\
|
||||
)
|
||||
|
||||
IF "%1" == "x86" (
|
||||
IF NOT "%COPY_FILES_ONLY%" == "1" .\third_party\python_26\python.exe build\gyp_v8 -Dcomponent=shared_library
|
||||
IF NOT ERRORLEVEL 0 GOTO Fail
|
||||
SET LIB_DEST_DIR=..\..\Win32\%2\
|
||||
)
|
||||
|
||||
IF "%LIB_DEST_DIR%" == "" GOTO Fail
|
||||
|
||||
IF "%COPY_FILES_ONLY%" == "1" GOTO CopyFiles
|
||||
|
||||
devenv.com /clean %2 tools\gyp\v8.sln
|
||||
IF NOT ERRORLEVEL 0 GOTO Fail
|
||||
|
||||
devenv.com /build %2 tools\gyp\v8.sln
|
||||
IF NOT ERRORLEVEL 0 GOTO Fail
|
||||
|
||||
:CopyFiles
|
||||
|
||||
REM xcopy /C /F /R /Y .\build\%2\icudt.dll %LIB_DEST_DIR%
|
||||
REM IF NOT ERRORLEVEL 0 GOTO Fail
|
||||
|
||||
xcopy /C /F /R /Y .\build\%2\icui18n.dll %LIB_DEST_DIR%
|
||||
IF NOT ERRORLEVEL 0 GOTO Fail
|
||||
|
||||
xcopy /C /F /R /Y .\build\%2\icuuc.dll %LIB_DEST_DIR%
|
||||
IF NOT ERRORLEVEL 0 GOTO Fail
|
||||
|
||||
xcopy /C /F /R /Y .\build\%2\v8.dll %LIB_DEST_DIR%
|
||||
IF NOT ERRORLEVEL 0 GOTO Fail
|
||||
|
||||
ECHO %1-%2> last_build
|
||||
|
||||
exit
|
||||
|
||||
:Fail
|
||||
exit /b 1
|
|
@ -0,0 +1,144 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectName>libv8</ProjectName>
|
||||
<ProjectGuid>{AB03E82B-48B1-4374-B32A-A1AF83DDC6C2}</ProjectGuid>
|
||||
<RootNamespace>libv8</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Utility</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Utility</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Utility</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Utility</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<Import Project="$(SolutionDir)\w32\extdll.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(PlatformName)\V8\$(Configuration)\</IntDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(PlatformName)\V8\$(Configuration)\</IntDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(PlatformName)\V8\$(Configuration)\</IntDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(PlatformName)\V8\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<BuildLog>
|
||||
<Path>$(IntDir)BuildLog $(ProjectName).htm</Path>
|
||||
</BuildLog>
|
||||
<PreBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<BuildLog>
|
||||
<Path>$(IntDir)BuildLog $(ProjectName).htm</Path>
|
||||
</BuildLog>
|
||||
<PreBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<BuildLog>
|
||||
<Path>$(IntDir)BuildLog $(ProjectName).htm</Path>
|
||||
</BuildLog>
|
||||
<PreBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<BuildLog>
|
||||
<Path>$(IntDir)BuildLog $(ProjectName).htm</Path>
|
||||
</BuildLog>
|
||||
<PreBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
</PreBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="cleancount">
|
||||
<FileType>Document</FileType>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Building Google V8</Message>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)build-v8.bat x86 Release "$(ProjectDir)..\..\v8-3.24.14"
|
||||
</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(ProjectDir)..\..\v8-3.24.14;%(Outputs)</Outputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Building Google V8</Message>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)build-v8.bat x86 Debug "$(ProjectDir)..\..\v8-3.24.14"
|
||||
</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectDir)..\..\v8-3.24.14;%(Outputs)</Outputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Building Google V8</Message>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)build-v8.bat x64 Release "$(ProjectDir)..\..\v8-3.24.14"
|
||||
</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(ProjectDir)..\..\v8-3.24.14;%(Outputs)</Outputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Building Google V8</Message>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)build-v8.bat x64 Debug "$(ProjectDir)..\..\v8-3.24.14"
|
||||
</Command>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectDir)..\..\v8-3.24.14;%(Outputs)</Outputs>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Download V8.2012.vcxproj">
|
||||
<Project>{13077E43-E5DF-4EF6-9EB1-2A0B22E8DFAF}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,59 @@
|
|||
include $(top_srcdir)/build/modmake.rulesam
|
||||
|
||||
V8=v8-3.24.14
|
||||
|
||||
V8_DIR=$(switch_srcdir)/libs/$(V8)
|
||||
V8_BUILDDIR=$(switch_builddir)/libs/$(V8)
|
||||
V8SO=$(V8_DIR)/out/native/lib.target/libv8.so
|
||||
|
||||
CURL_DIR=$(switch_srcdir)/libs/curl
|
||||
CURL_BUILDDIR=$(switch_builddir)/libs/curl
|
||||
CURLLA=${switch_builddir}/libs/curl/lib/libcurl.la
|
||||
|
||||
MODNAME=mod_v8
|
||||
|
||||
AM_CFLAGS += -I. -I./include -I$(V8_DIR)/include
|
||||
AM_CPPFLAGS += -I. -I./include -I$(V8_DIR)/include
|
||||
AM_LIBADD = $(switch_builddir)/libfreeswitch.la -lv8 -licuuc -licui18n
|
||||
AM_LDFLAGS += -avoid-version -module -no-undefined -shared
|
||||
AM_LDFLAGS += -L$(V8_DIR)/out/native/lib.target
|
||||
BUILT_SOURCES = $(V8SO) $(LIBCURL_DEPS)
|
||||
|
||||
if HAVE_ODBC
|
||||
AM_CFLAGS += -DHAVE_ODBC $(ODBC_INC_FLAGS)
|
||||
AM_CPPFLAGS += -DHAVE_ODBC $(ODBC_INC_FLAGS)
|
||||
AM_LDFLAGS += -DHAVE_ODBC
|
||||
endif
|
||||
|
||||
mod_LTLIBRARIES = mod_v8.la
|
||||
mod_v8_la_SOURCES = mod_v8.cpp ./src/fscoredb.cpp ./src/fscurl.cpp ./src/fsdtmf.cpp ./src/fsevent.cpp ./src/fsfileio.cpp ./src/fsglobal.cpp ./src/fsodbc.cpp ./src/fspcre.cpp ./src/fsrequest.cpp ./src/fssession.cpp ./src/fssocket.cpp ./src/fsteletone.cpp ./src/fsxml.cpp ./src/fsfile.cpp ./src/jsbase.cpp ./src/jsmain.cpp
|
||||
mod_v8_la_CFLAGS = $(AM_CFLAGS) $(LIBCURL_CPPFLAGS) -I$(switch_srcdir)/libs/libteletone/src
|
||||
mod_v8_la_CPPFLAGS = $(AM_CPPFLAGS) $(LIBCURL_CPPFLAGS) -I$(switch_srcdir)/libs/libteletone/src
|
||||
mod_v8_la_LIBADD = $(AM_LIBADD)
|
||||
mod_v8_la_LDFLAGS = $(AM_LDFLAGS) $(LIBCURL)
|
||||
|
||||
#mod_LTLIBRARIES += mod_v8_skel.la
|
||||
#mod_v8_skel_la_SOURCES = mod_v8_skel.cpp
|
||||
#mod_v8_skel_la_CFLAGS = $(AM_CFLAGS) -DJSMOD_IMPORT
|
||||
#mod_v8_skel_la_CPPFLAGS = $(AM_CPPFLAGS) -DJSMOD_IMPORT
|
||||
#mod_v8_skel_la_LIBADD = $(AM_LIBADD)
|
||||
#mod_v8_skel_la_LDFLAGS = $(AM_LDFLAGS)
|
||||
|
||||
$(SOURCES): $(BUILT_SOURCES)
|
||||
|
||||
$(V8_DIR):
|
||||
$(GETLIB) $(V8).tar.bz2
|
||||
|
||||
$(V8SO): $(V8_DIR)
|
||||
cd $(V8_BUILDDIR) && $(MAKE) library=shared native
|
||||
|
||||
$(CURLLA):
|
||||
@cd $(CURL_BUILDDIR) && $(MAKE)
|
||||
$(TOUCH_TARGET)
|
||||
|
||||
install-exec-local: $(DESTDIR)$(libdir)/libv8.so
|
||||
|
||||
$(DESTDIR)$(libdir)/libv8.so: $(V8SO)
|
||||
rm -f $(DESTDIR)$(libdir)/libv8.so && cp -a $(V8_DIR)/out/native/lib.target/libv8.so $(DESTDIR)$(libdir)/libv8.so
|
||||
rm -f $(DESTDIR)$(libdir)/libicuuc.so && cp -a $(V8_DIR)/out/native/lib.target/libicuuc.so $(DESTDIR)$(libdir)/libicuuc.so
|
||||
rm -f $(DESTDIR)$(libdir)/libicui18n.so && cp -a $(V8_DIR)/out/native/lib.target/libicui18n.so $(DESTDIR)$(libdir)/libicui18n.so
|
|
@ -0,0 +1,5 @@
|
|||
<configuration name="v8.conf" description="Google V8 JavaScript Plug-Ins">
|
||||
<modules>
|
||||
<!-- <load module="mod_v8_skel"/> -->
|
||||
</modules>
|
||||
</configuration>
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* 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 Original Code is mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* fscoredb.hpp -- JavaScript CoreDB class header
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FS_COREDB_H
|
||||
#define FS_COREDB_H
|
||||
|
||||
#include "mod_v8.h"
|
||||
|
||||
/* Macros for easier V8 callback definitions */
|
||||
#define JS_COREDB_GET_PROPERTY_DEF(method_name) JS_GET_PROPERTY_DEF(method_name, FSCoreDB)
|
||||
#define JS_COREDB_SET_PROPERTY_DEF(method_name) JS_SET_PROPERTY_DEF(method_name, FSCoreDB)
|
||||
#define JS_COREDB_FUNCTION_DEF(method_name) JS_FUNCTION_DEF(method_name, FSCoreDB)
|
||||
#define JS_COREDB_GET_PROPERTY_IMPL(method_name) JS_GET_PROPERTY_IMPL(method_name, FSCoreDB)
|
||||
#define JS_COREDB_SET_PROPERTY_IMPL(method_name) JS_SET_PROPERTY_IMPL(method_name, FSCoreDB)
|
||||
#define JS_COREDB_FUNCTION_IMPL(method_name) JS_FUNCTION_IMPL(method_name, FSCoreDB)
|
||||
|
||||
class FSCoreDB : public JSBase
|
||||
{
|
||||
private:
|
||||
switch_memory_pool_t *_pool;
|
||||
switch_core_db_t *_db;
|
||||
switch_core_db_stmt_t *_stmt;
|
||||
const char *_dbname;
|
||||
v8::Persistent<v8::Function> _callback;
|
||||
|
||||
void Init();
|
||||
void DoClose();
|
||||
void StepEx(const v8::FunctionCallbackInfo<v8::Value>& info, int stepSuccessCode);
|
||||
static int Callback(void *pArg, int argc, char **argv, char **columnNames);
|
||||
public:
|
||||
FSCoreDB(JSMain *owner) : JSBase(owner) { Init(); }
|
||||
FSCoreDB(const v8::FunctionCallbackInfo<v8::Value>& info) : JSBase(info) { Init(); }
|
||||
virtual ~FSCoreDB(void);
|
||||
virtual std::string GetJSClassName();
|
||||
|
||||
static const v8_mod_interface_t *GetModuleInterface();
|
||||
|
||||
/* Methods available from JavaScript */
|
||||
static void *Construct(const v8::FunctionCallbackInfo<v8::Value>& info);
|
||||
JS_COREDB_FUNCTION_DEF(Exec);
|
||||
JS_COREDB_FUNCTION_DEF(Close);
|
||||
JS_COREDB_FUNCTION_DEF(Next);
|
||||
JS_COREDB_FUNCTION_DEF(Step);
|
||||
JS_COREDB_FUNCTION_DEF(Fetch);
|
||||
JS_COREDB_FUNCTION_DEF(Prepare);
|
||||
JS_COREDB_FUNCTION_DEF(BindText);
|
||||
JS_COREDB_FUNCTION_DEF(BindInt);
|
||||
JS_COREDB_GET_PROPERTY_DEF(GetProperty);
|
||||
};
|
||||
|
||||
#endif /* FS_COREDB_H */
|
||||
|
||||
/* 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 noet:
|
||||
*/
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* 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 Original Code is mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* fscurl.hpp -- JavaScript CURL class header
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FS_CURL_H
|
||||
#define FS_CURL_H
|
||||
|
||||
#include "mod_v8.h"
|
||||
#include <switch_curl.h>
|
||||
|
||||
/* Macros for easier V8 callback definitions */
|
||||
#define JS_CURL_GET_PROPERTY_DEF(method_name) JS_GET_PROPERTY_DEF(method_name, FSCURL)
|
||||
#define JS_CURL_SET_PROPERTY_DEF(method_name) JS_SET_PROPERTY_DEF(method_name, FSCURL)
|
||||
#define JS_CURL_FUNCTION_DEF(method_name) JS_FUNCTION_DEF(method_name, FSCURL)
|
||||
#define JS_CURL_GET_PROPERTY_IMPL(method_name) JS_GET_PROPERTY_IMPL(method_name, FSCURL)
|
||||
#define JS_CURL_SET_PROPERTY_IMPL(method_name) JS_SET_PROPERTY_IMPL(method_name, FSCURL)
|
||||
#define JS_CURL_FUNCTION_IMPL(method_name) JS_FUNCTION_IMPL(method_name, FSCURL)
|
||||
|
||||
class FSCURL : public JSBase
|
||||
{
|
||||
private:
|
||||
switch_CURL *_curl_handle;
|
||||
v8::Persistent<v8::Function> _function;
|
||||
v8::Persistent<v8::Object> _user_data;
|
||||
v8::Persistent<v8::Value> _ret;
|
||||
|
||||
void Init(void);
|
||||
static size_t FileCallback(void *ptr, size_t size, size_t nmemb, void *data);
|
||||
public:
|
||||
FSCURL(JSMain *owner) : JSBase(owner) { Init(); }
|
||||
FSCURL(const v8::FunctionCallbackInfo<v8::Value>& info) : JSBase(info) { Init(); }
|
||||
virtual ~FSCURL(void);
|
||||
virtual std::string GetJSClassName();
|
||||
|
||||
static const v8_mod_interface_t *GetModuleInterface();
|
||||
|
||||
/* Methods available from JavaScript */
|
||||
static void *Construct(const v8::FunctionCallbackInfo<v8::Value>& info);
|
||||
JS_CURL_FUNCTION_DEF(Run);
|
||||
};
|
||||
|
||||
#endif /* FS_CURL_H */
|
||||
|
||||
/* 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 noet:
|
||||
*/
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* 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 Original Code is mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* fsdtmf.hpp -- JavaScript DTMF class header
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FS_DTMF_H
|
||||
#define FS_DTMF_H
|
||||
|
||||
#include "javascript.hpp"
|
||||
#include <switch.h>
|
||||
|
||||
/* Macros for easier V8 callback definitions */
|
||||
#define JS_DTMF_GET_PROPERTY_DEF(method_name) JS_GET_PROPERTY_DEF(method_name, FSDTMF)
|
||||
#define JS_DTMF_SET_PROPERTY_DEF(method_name) JS_SET_PROPERTY_DEF(method_name, FSDTMF)
|
||||
#define JS_DTMF_FUNCTION_DEF(method_name) JS_FUNCTION_DEF(method_name, FSDTMF)
|
||||
#define JS_DTMF_GET_PROPERTY_IMPL(method_name) JS_GET_PROPERTY_IMPL(method_name, FSDTMF)
|
||||
#define JS_DTMF_SET_PROPERTY_IMPL(method_name) JS_SET_PROPERTY_IMPL(method_name, FSDTMF)
|
||||
#define JS_DTMF_FUNCTION_IMPL(method_name) JS_FUNCTION_IMPL(method_name, FSDTMF)
|
||||
|
||||
class FSDTMF : public JSBase
|
||||
{
|
||||
private:
|
||||
switch_dtmf_t *_dtmf;
|
||||
public:
|
||||
FSDTMF(JSMain *owner) : JSBase(owner) { _dtmf = NULL; }
|
||||
FSDTMF(const v8::FunctionCallbackInfo<v8::Value>& info) : JSBase(info) { _dtmf = NULL; }
|
||||
virtual ~FSDTMF(void);
|
||||
virtual std::string GetJSClassName();
|
||||
|
||||
static const js_class_definition_t *GetClassDefinition();
|
||||
|
||||
/* Methods available from JavaScript */
|
||||
static void *Construct(const v8::FunctionCallbackInfo<v8::Value>& info);
|
||||
static v8::Handle<v8::Object> New(switch_dtmf_t *dtmf, const char *name, JSMain *js);
|
||||
JS_DTMF_GET_PROPERTY_DEF(GetProperty);
|
||||
};
|
||||
|
||||
#endif /* FS_DTMF_H */
|
||||
|
||||
/* 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 noet:
|
||||
*/
|
|
@ -0,0 +1,93 @@
|
|||
/*
|
||||
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* 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 Original Code is mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* fsevent.hpp -- JavaScript Event class header
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FS_EVENT_H
|
||||
#define FS_EVENT_H
|
||||
|
||||
#include "javascript.hpp"
|
||||
#include <switch.h>
|
||||
|
||||
/* Macros for easier V8 callback definitions */
|
||||
#define JS_EVENT_GET_PROPERTY_DEF(method_name) JS_GET_PROPERTY_DEF(method_name, FSEvent)
|
||||
#define JS_EVENT_SET_PROPERTY_DEF(method_name) JS_SET_PROPERTY_DEF(method_name, FSEvent)
|
||||
#define JS_EVENT_FUNCTION_DEF(method_name) JS_FUNCTION_DEF(method_name, FSEvent)
|
||||
#define JS_EVENT_GET_PROPERTY_IMPL(method_name) JS_GET_PROPERTY_IMPL(method_name, FSEvent)
|
||||
#define JS_EVENT_SET_PROPERTY_IMPL(method_name) JS_SET_PROPERTY_IMPL(method_name, FSEvent)
|
||||
#define JS_EVENT_FUNCTION_IMPL(method_name) JS_FUNCTION_IMPL(method_name, FSEvent)
|
||||
|
||||
#define JS_EVENT_GET_PROPERTY_IMPL_STATIC(method_name) JS_GET_PROPERTY_IMPL_STATIC(method_name, FSEvent)
|
||||
#define JS_EVENT_SET_PROPERTY_IMPL_STATIC(method_name) JS_SET_PROPERTY_IMPL_STATIC(method_name, FSEvent)
|
||||
#define JS_EVENT_FUNCTION_IMPL_STATIC(method_name) JS_FUNCTION_IMPL_STATIC(method_name, FSEvent)
|
||||
|
||||
class FSEvent : public JSBase
|
||||
{
|
||||
private:
|
||||
switch_event_t *_event;
|
||||
int _freed;
|
||||
|
||||
void Init();
|
||||
public:
|
||||
FSEvent(JSMain *owner) : JSBase(owner) { Init(); }
|
||||
FSEvent(const v8::FunctionCallbackInfo<v8::Value>& info) : JSBase(info) { Init(); }
|
||||
virtual ~FSEvent(void);
|
||||
virtual std::string GetJSClassName();
|
||||
|
||||
static const js_class_definition_t *GetClassDefinition();
|
||||
|
||||
void SetEvent(switch_event_t *event, int freed = 0);
|
||||
switch_event_t **GetEvent();
|
||||
|
||||
/* Methods available from JavaScript */
|
||||
static void *Construct(const v8::FunctionCallbackInfo<v8::Value>& info);
|
||||
static v8::Handle<v8::Object> New(switch_event_t *event, const char *name, JSMain *js);
|
||||
JS_EVENT_FUNCTION_DEF(AddHeader);
|
||||
JS_EVENT_FUNCTION_DEF(GetHeader);
|
||||
JS_EVENT_FUNCTION_DEF(AddBody);
|
||||
JS_EVENT_FUNCTION_DEF(GetBody);
|
||||
JS_EVENT_FUNCTION_DEF(GetType);
|
||||
JS_EVENT_FUNCTION_DEF(Serialize);
|
||||
JS_EVENT_FUNCTION_DEF(ChatExecute);
|
||||
JS_FUNCTION_DEF_STATIC(Fire); // This will also destroy the C++ object
|
||||
JS_FUNCTION_DEF_STATIC(Destroy); // This will also destroy the C++ object
|
||||
JS_EVENT_GET_PROPERTY_DEF(GetProperty);
|
||||
};
|
||||
|
||||
#endif /* FS_EVENT_H */
|
||||
|
||||
/* 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 noet:
|
||||
*/
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* 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 Original Code is mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* fsfile.hpp -- JavaScript File class header
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FS_FILE_H
|
||||
#define FS_FILE_H
|
||||
|
||||
#include "mod_v8.h"
|
||||
|
||||
/* Macros for easier V8 callback definitions */
|
||||
#define JS_FILE_GET_PROPERTY_DEF(method_name) JS_GET_PROPERTY_DEF(method_name, FSFile)
|
||||
#define JS_FILE_SET_PROPERTY_DEF(method_name) JS_SET_PROPERTY_DEF(method_name, FSFile)
|
||||
#define JS_FILE_FUNCTION_DEF(method_name) JS_FUNCTION_DEF(method_name, FSFile)
|
||||
#define JS_FILE_GET_PROPERTY_IMPL(method_name) JS_GET_PROPERTY_IMPL(method_name, FSFile)
|
||||
#define JS_FILE_SET_PROPERTY_IMPL(method_name) JS_SET_PROPERTY_IMPL(method_name, FSFile)
|
||||
#define JS_FILE_FUNCTION_IMPL(method_name) JS_FUNCTION_IMPL(method_name, FSFile)
|
||||
|
||||
class FSFile : public JSBase
|
||||
{
|
||||
private:
|
||||
void Init();
|
||||
public:
|
||||
FSFile(JSMain *owner) : JSBase(owner) { }
|
||||
FSFile(const v8::FunctionCallbackInfo<v8::Value>& info) : JSBase(info) { }
|
||||
virtual ~FSFile(void);
|
||||
virtual std::string GetJSClassName();
|
||||
|
||||
static const v8_mod_interface_t *GetModuleInterface();
|
||||
|
||||
/* Methods available from JavaScript */
|
||||
static void *Construct(const v8::FunctionCallbackInfo<v8::Value>& info);
|
||||
JS_FILE_FUNCTION_DEF(Close);
|
||||
JS_FILE_FUNCTION_DEF(CopyTo);
|
||||
JS_FILE_FUNCTION_DEF(Flush);
|
||||
JS_FILE_FUNCTION_DEF(List);
|
||||
JS_FILE_FUNCTION_DEF(MkDir);
|
||||
JS_FILE_FUNCTION_DEF(Open);
|
||||
JS_FILE_FUNCTION_DEF(Read);
|
||||
JS_FILE_FUNCTION_DEF(ReadAll);
|
||||
JS_FILE_FUNCTION_DEF(ReadLn);
|
||||
JS_FILE_FUNCTION_DEF(Remove);
|
||||
JS_FILE_FUNCTION_DEF(RenameTo);
|
||||
JS_FILE_FUNCTION_DEF(Seek);
|
||||
JS_FILE_FUNCTION_DEF(ToString);
|
||||
JS_FILE_FUNCTION_DEF(ToURL);
|
||||
JS_FILE_FUNCTION_DEF(Write);
|
||||
JS_FILE_FUNCTION_DEF(WriteAll);
|
||||
JS_FILE_FUNCTION_DEF(WriteLn);
|
||||
|
||||
JS_FILE_GET_PROPERTY_DEF(GetPropCanAppend);
|
||||
JS_FILE_GET_PROPERTY_DEF(GetPropCanRead);
|
||||
JS_FILE_GET_PROPERTY_DEF(GetPropCanReplace);
|
||||
JS_FILE_GET_PROPERTY_DEF(GetPropCanWrite);
|
||||
JS_FILE_GET_PROPERTY_DEF(GetPropCreationTime);
|
||||
JS_FILE_GET_PROPERTY_DEF(GetPropExists);
|
||||
JS_FILE_GET_PROPERTY_DEF(GetPropHasAutoFlush);
|
||||
JS_FILE_GET_PROPERTY_DEF(GetPropHasRandomAccess);
|
||||
JS_FILE_GET_PROPERTY_DEF(GetPropIsDirectory);
|
||||
JS_FILE_GET_PROPERTY_DEF(GetPropIsFile);
|
||||
JS_FILE_GET_PROPERTY_DEF(GetPropIsNative);
|
||||
JS_FILE_GET_PROPERTY_DEF(GetPropIsOpen);
|
||||
JS_FILE_GET_PROPERTY_DEF(GetPropLastModified);
|
||||
JS_FILE_GET_PROPERTY_DEF(GetPropLength);
|
||||
JS_FILE_GET_PROPERTY_DEF(GetPropMode);
|
||||
JS_FILE_GET_PROPERTY_DEF(GetPropName);
|
||||
JS_FILE_GET_PROPERTY_DEF(GetPropParent);
|
||||
JS_FILE_GET_PROPERTY_DEF(GetPropPath);
|
||||
JS_FILE_GET_PROPERTY_DEF(GetPropPosition);
|
||||
JS_FILE_SET_PROPERTY_DEF(SetPropPosition);
|
||||
JS_FILE_GET_PROPERTY_DEF(GetPropSize);
|
||||
JS_FILE_GET_PROPERTY_DEF(GetPropType);
|
||||
};
|
||||
|
||||
#endif /* FS_FILE_H */
|
||||
|
||||
/* 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 noet:
|
||||
*/
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* 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 Original Code is mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* fsfileio.hpp -- JavaScript FileIO class header
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FS_FILEIO_H
|
||||
#define FS_FILEIO_H
|
||||
|
||||
#include "javascript.hpp"
|
||||
#include <switch.h>
|
||||
|
||||
/* Macros for easier V8 callback definitions */
|
||||
#define JS_FILEIO_GET_PROPERTY_DEF(method_name) JS_GET_PROPERTY_DEF(method_name, FSFileIO)
|
||||
#define JS_FILEIO_SET_PROPERTY_DEF(method_name) JS_SET_PROPERTY_DEF(method_name, FSFileIO)
|
||||
#define JS_FILEIO_FUNCTION_DEF(method_name) JS_FUNCTION_DEF(method_name, FSFileIO)
|
||||
#define JS_FILEIO_GET_PROPERTY_IMPL(method_name) JS_GET_PROPERTY_IMPL(method_name, FSFileIO)
|
||||
#define JS_FILEIO_SET_PROPERTY_IMPL(method_name) JS_SET_PROPERTY_IMPL(method_name, FSFileIO)
|
||||
#define JS_FILEIO_FUNCTION_IMPL(method_name) JS_FUNCTION_IMPL(method_name, FSFileIO)
|
||||
|
||||
class FSFileIO : public JSBase
|
||||
{
|
||||
private:
|
||||
char *_path;
|
||||
unsigned int _flags;
|
||||
switch_file_t *_fd;
|
||||
switch_memory_pool_t *_pool;
|
||||
char *_buf;
|
||||
switch_size_t _buflen;
|
||||
int32_t _bufsize;
|
||||
|
||||
void Init();
|
||||
public:
|
||||
FSFileIO(JSMain *owner) : JSBase(owner) { Init(); }
|
||||
FSFileIO(const v8::FunctionCallbackInfo<v8::Value>& info) : JSBase(info) { Init(); }
|
||||
virtual ~FSFileIO(void);
|
||||
virtual std::string GetJSClassName();
|
||||
|
||||
static const js_class_definition_t *GetClassDefinition();
|
||||
|
||||
/* Methods available from JavaScript */
|
||||
static void *Construct(const v8::FunctionCallbackInfo<v8::Value>& info);
|
||||
JS_FILEIO_FUNCTION_DEF(Read);
|
||||
JS_FILEIO_FUNCTION_DEF(Write);
|
||||
JS_FILEIO_FUNCTION_DEF(GetData);
|
||||
JS_FILEIO_GET_PROPERTY_DEF(GetProperty);
|
||||
};
|
||||
|
||||
#endif /* FS_FILEIO_H */
|
||||
|
||||
/* 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 noet:
|
||||
*/
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* 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 Original Code is mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* fsglobal.hpp -- JavaScript Global functions
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FS_GLOBAL_H
|
||||
#define FS_GLOBAL_H
|
||||
|
||||
#include "javascript.hpp"
|
||||
#include <switch.h>
|
||||
|
||||
/* Macros for easier V8 callback definitions */
|
||||
#define JS_GLOBAL_FUNCTION_IMPL_STATIC(method_name) JS_FUNCTION_IMPL_STATIC(method_name, FSGlobal)
|
||||
|
||||
/* All globally available functions (not related to objects) */
|
||||
class FSGlobal
|
||||
{
|
||||
private:
|
||||
static size_t HashCallback(void *ptr, size_t size, size_t nmemb, void *data);
|
||||
static size_t FileCallback(void *ptr, size_t size, size_t nmemb, void *data);
|
||||
static size_t FetchUrlCallback(void *ptr, size_t size, size_t nmemb, void *data);
|
||||
public:
|
||||
static const js_function_t *GetFunctionDefinitions();
|
||||
|
||||
/* Methods available from JavaScript */
|
||||
JS_FUNCTION_DEF_STATIC(Log);
|
||||
JS_FUNCTION_DEF_STATIC(GlobalGet);
|
||||
JS_FUNCTION_DEF_STATIC(GlobalSet);
|
||||
JS_FUNCTION_DEF_STATIC(Exit);
|
||||
JS_FUNCTION_DEF_STATIC(Include);
|
||||
JS_FUNCTION_DEF_STATIC(Bridge);
|
||||
JS_FUNCTION_DEF_STATIC(Email);
|
||||
JS_FUNCTION_DEF_STATIC(ApiExecute);
|
||||
JS_FUNCTION_DEF_STATIC(Use);
|
||||
JS_FUNCTION_DEF_STATIC(Sleep);
|
||||
JS_FUNCTION_DEF_STATIC(FileDelete);
|
||||
JS_FUNCTION_DEF_STATIC(System);
|
||||
JS_FUNCTION_DEF_STATIC(FetchURL);
|
||||
JS_FUNCTION_DEF_STATIC(FetchURLHash);
|
||||
JS_FUNCTION_DEF_STATIC(FetchURLFile);
|
||||
};
|
||||
|
||||
#endif /* FS_GLOBAL_H */
|
||||
|
||||
/* 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 noet:
|
||||
*/
|
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* 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 Original Code is mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* fsodbc.hpp -- JavaScript ODBC class header
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FS_ODBC_H
|
||||
#define FS_ODBC_H
|
||||
|
||||
#include "mod_v8.h"
|
||||
|
||||
#if defined(WIN32) && !defined(HAVE_ODBC)
|
||||
#define HAVE_ODBC
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ODBC
|
||||
|
||||
#include <sql.h>
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4201)
|
||||
#include <sqlext.h>
|
||||
#pragma warning(pop)
|
||||
#else
|
||||
#include <sqlext.h>
|
||||
#endif
|
||||
#include <sqltypes.h>
|
||||
|
||||
/* Macros for easier V8 callback definitions */
|
||||
#define JS_ODBC_GET_PROPERTY_DEF(method_name) JS_GET_PROPERTY_DEF(method_name, FSODBC)
|
||||
#define JS_ODBC_SET_PROPERTY_DEF(method_name) JS_SET_PROPERTY_DEF(method_name, FSODBC)
|
||||
#define JS_ODBC_FUNCTION_DEF(method_name) JS_FUNCTION_DEF(method_name, FSODBC)
|
||||
#define JS_ODBC_GET_PROPERTY_IMPL(method_name) JS_GET_PROPERTY_IMPL(method_name, FSODBC)
|
||||
#define JS_ODBC_SET_PROPERTY_IMPL(method_name) JS_SET_PROPERTY_IMPL(method_name, FSODBC)
|
||||
#define JS_ODBC_FUNCTION_IMPL(method_name) JS_FUNCTION_IMPL(method_name, FSODBC)
|
||||
|
||||
#define JS_ODBC_GET_PROPERTY_IMPL_STATIC(method_name) JS_GET_PROPERTY_IMPL_STATIC(method_name, FSODBC)
|
||||
#define JS_ODBC_SET_PROPERTY_IMPL_STATIC(method_name) JS_SET_PROPERTY_IMPL_STATIC(method_name, FSODBC)
|
||||
#define JS_ODBC_FUNCTION_IMPL_STATIC(method_name) JS_FUNCTION_IMPL_STATIC(method_name, FSODBC)
|
||||
|
||||
class FSODBC : public JSBase
|
||||
{
|
||||
private:
|
||||
switch_odbc_handle_t *_handle;
|
||||
SQLHSTMT _stmt;
|
||||
SQLCHAR *_colbuf;
|
||||
int32_t _cblen;
|
||||
std::string _dsn;
|
||||
|
||||
void Init();
|
||||
public:
|
||||
FSODBC(JSMain *owner) : JSBase(owner) { Init(); }
|
||||
FSODBC(const v8::FunctionCallbackInfo<v8::Value>& info) : JSBase(info) { Init(); }
|
||||
virtual ~FSODBC(void);
|
||||
virtual std::string GetJSClassName();
|
||||
|
||||
static const v8_mod_interface_t *GetModuleInterface();
|
||||
|
||||
static FSODBC *New(char *dsn, char *username, char *password, const v8::FunctionCallbackInfo<v8::Value>& info);
|
||||
switch_odbc_status_t Connect();
|
||||
|
||||
/* Methods available from JavaScript */
|
||||
static void *Construct(const v8::FunctionCallbackInfo<v8::Value>& info);
|
||||
JS_ODBC_FUNCTION_DEF(Connect);
|
||||
JS_ODBC_FUNCTION_DEF(Disconnect);
|
||||
JS_ODBC_FUNCTION_DEF(Exec);
|
||||
JS_ODBC_FUNCTION_DEF(Execute);
|
||||
JS_ODBC_FUNCTION_DEF(NumRows);
|
||||
JS_ODBC_FUNCTION_DEF(NumCols);
|
||||
JS_ODBC_FUNCTION_DEF(NextRow);
|
||||
JS_ODBC_FUNCTION_DEF(GetData);
|
||||
JS_FUNCTION_DEF_STATIC(Close); // This will also destroy the C++ object
|
||||
JS_ODBC_GET_PROPERTY_DEF(GetProperty);
|
||||
|
||||
};
|
||||
|
||||
#endif /* HAVE_ODBC */
|
||||
|
||||
#endif /* FS_ODBC_H */
|
||||
|
||||
/* 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 noet:
|
||||
*/
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* 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 Original Code is mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* fspcre.hpp -- JavaScript PCRE class header
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FS_PCRE_H
|
||||
#define FS_PCRE_H
|
||||
|
||||
#include "javascript.hpp"
|
||||
#include <switch.h>
|
||||
|
||||
/* Macros for easier V8 callback definitions */
|
||||
#define JS_PCRE_GET_PROPERTY_DEF(method_name) JS_GET_PROPERTY_DEF(method_name, FSPCRE)
|
||||
#define JS_PCRE_SET_PROPERTY_DEF(method_name) JS_SET_PROPERTY_DEF(method_name, FSPCRE)
|
||||
#define JS_PCRE_FUNCTION_DEF(method_name) JS_FUNCTION_DEF(method_name, FSPCRE)
|
||||
#define JS_PCRE_GET_PROPERTY_IMPL(method_name) JS_GET_PROPERTY_IMPL(method_name, FSPCRE)
|
||||
#define JS_PCRE_SET_PROPERTY_IMPL(method_name) JS_SET_PROPERTY_IMPL(method_name, FSPCRE)
|
||||
#define JS_PCRE_FUNCTION_IMPL(method_name) JS_FUNCTION_IMPL(method_name, FSPCRE)
|
||||
|
||||
class FSPCRE : public JSBase
|
||||
{
|
||||
private:
|
||||
switch_regex_t *_re;
|
||||
char *_str;
|
||||
int _proceed;
|
||||
int _ovector[30];
|
||||
int _freed;
|
||||
|
||||
void Init();
|
||||
public:
|
||||
FSPCRE(JSMain *owner) : JSBase(owner) { Init(); }
|
||||
FSPCRE(const v8::FunctionCallbackInfo<v8::Value>& info) : JSBase(info) { Init(); }
|
||||
virtual ~FSPCRE(void);
|
||||
virtual std::string GetJSClassName();
|
||||
|
||||
static const js_class_definition_t *GetClassDefinition();
|
||||
|
||||
/* Methods available from JavaScript */
|
||||
static void *Construct(const v8::FunctionCallbackInfo<v8::Value>& info);
|
||||
JS_PCRE_FUNCTION_DEF(Compile);
|
||||
JS_PCRE_FUNCTION_DEF(Substitute);
|
||||
JS_PCRE_GET_PROPERTY_DEF(GetProperty);
|
||||
};
|
||||
|
||||
#endif /* FS_PCRE_H */
|
||||
|
||||
/* 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 noet:
|
||||
*/
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* 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 Original Code is mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* fsrequest.hpp -- JavaScript Request class header
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FS_REQUEST_H
|
||||
#define FS_REQUEST_H
|
||||
|
||||
#include "javascript.hpp"
|
||||
#include <switch.h>
|
||||
|
||||
/* Macros for easier V8 callback definitions */
|
||||
#define JS_REQUEST_GET_PROPERTY_DEF(method_name) JS_GET_PROPERTY_DEF(method_name, FSRequest)
|
||||
#define JS_REQUEST_SET_PROPERTY_DEF(method_name) JS_SET_PROPERTY_DEF(method_name, FSRequest)
|
||||
#define JS_REQUEST_FUNCTION_DEF(method_name) JS_FUNCTION_DEF(method_name, FSRequest)
|
||||
#define JS_REQUEST_GET_PROPERTY_IMPL(method_name) JS_GET_PROPERTY_IMPL(method_name, FSRequest)
|
||||
#define JS_REQUEST_SET_PROPERTY_IMPL(method_name) JS_SET_PROPERTY_IMPL(method_name, FSRequest)
|
||||
#define JS_REQUEST_FUNCTION_IMPL(method_name) JS_FUNCTION_IMPL(method_name, FSRequest)
|
||||
|
||||
class FSRequest : public JSBase
|
||||
{
|
||||
private:
|
||||
const char *_cmd;
|
||||
switch_stream_handle_t *_stream;
|
||||
|
||||
void Init();
|
||||
public:
|
||||
FSRequest(JSMain *owner) : JSBase(owner) { Init(); }
|
||||
FSRequest(const v8::FunctionCallbackInfo<v8::Value>& info) : JSBase(info) { Init(); }
|
||||
virtual ~FSRequest(void);
|
||||
virtual std::string GetJSClassName();
|
||||
|
||||
static const js_class_definition_t *GetClassDefinition();
|
||||
|
||||
void Init(const char *cmd, switch_stream_handle_t *stream);
|
||||
|
||||
/* Methods available from JavaScript */
|
||||
JS_REQUEST_FUNCTION_DEF(Write);
|
||||
JS_REQUEST_FUNCTION_DEF(GetHeader);
|
||||
JS_REQUEST_FUNCTION_DEF(AddHeader);
|
||||
JS_REQUEST_FUNCTION_DEF(DumpEnv);
|
||||
JS_REQUEST_GET_PROPERTY_DEF(GetProperty);
|
||||
};
|
||||
|
||||
#endif /* FS_REQUEST_H */
|
||||
|
||||
/* 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 noet:
|
||||
*/
|
|
@ -0,0 +1,165 @@
|
|||
/*
|
||||
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* 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 Original Code is mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* fssession.hpp -- JavaScript Session class header
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FS_SESSION_H
|
||||
#define FS_SESSION_H
|
||||
|
||||
#include "javascript.hpp"
|
||||
#include <switch.h>
|
||||
|
||||
typedef struct {
|
||||
switch_speech_handle_t sh;
|
||||
switch_codec_t codec;
|
||||
int speaking;
|
||||
} js_session_speech_t;
|
||||
|
||||
typedef enum {
|
||||
S_HUP = (1 << 0),
|
||||
} session_flag_t;
|
||||
|
||||
/* Macros for easier V8 callback definitions */
|
||||
#define JS_SESSION_GET_PROPERTY_DEF(method_name) JS_GET_PROPERTY_DEF(method_name, FSSession)
|
||||
#define JS_SESSION_SET_PROPERTY_DEF(method_name) JS_SET_PROPERTY_DEF(method_name, FSSession)
|
||||
#define JS_SESSION_FUNCTION_DEF(method_name) JS_FUNCTION_DEF(method_name, FSSession)
|
||||
#define JS_SESSION_GET_PROPERTY_IMPL(method_name) JS_GET_PROPERTY_IMPL(method_name, FSSession)
|
||||
#define JS_SESSION_SET_PROPERTY_IMPL(method_name) JS_SET_PROPERTY_IMPL(method_name, FSSession)
|
||||
#define JS_SESSION_FUNCTION_IMPL(method_name) JS_FUNCTION_IMPL(method_name, FSSession)
|
||||
|
||||
class FSSession : public JSBase
|
||||
{
|
||||
private:
|
||||
switch_core_session_t *_session; // The FS session
|
||||
unsigned int flags; // Flags related to this session
|
||||
switch_call_cause_t _cause; // Hangup cause
|
||||
v8::Persistent<v8::Function> _on_hangup;// Hangup hook
|
||||
int _stack_depth;
|
||||
switch_channel_state_t _hook_state;
|
||||
char *_destination_number;
|
||||
char *_dialplan;
|
||||
char *_caller_id_name;
|
||||
char *_caller_id_number;
|
||||
char *_network_addr;
|
||||
char *_ani;
|
||||
char *_aniii;
|
||||
char *_rdnis;
|
||||
char *_context;
|
||||
char *_username;
|
||||
int _check_state;
|
||||
js_session_speech_t *_speech;
|
||||
|
||||
void Init(void);
|
||||
switch_status_t InitSpeechEngine(const char *engine, const char *voice);
|
||||
void DestroySpeechEngine();
|
||||
static switch_status_t CommonCallback(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen);
|
||||
static switch_status_t StreamInputCallback(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen);
|
||||
static switch_status_t RecordInputCallback(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen);
|
||||
static bool CheckHangupHook(FSSession *obj, bool *ret);
|
||||
static switch_status_t HangupHook(switch_core_session_t *session);
|
||||
public:
|
||||
FSSession(JSMain *owner) : JSBase(owner) { Init(); }
|
||||
FSSession(const v8::FunctionCallbackInfo<v8::Value>& info) : JSBase(info) { Init(); }
|
||||
virtual ~FSSession(void);
|
||||
virtual std::string GetJSClassName();
|
||||
|
||||
static const js_class_definition_t *GetClassDefinition();
|
||||
|
||||
switch_core_session_t *GetSession();
|
||||
void Init(switch_core_session_t *session, unsigned int flags);
|
||||
static switch_status_t CollectInputCallback(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen);
|
||||
|
||||
/* Methods available from JavaScript */
|
||||
static void *Construct(const v8::FunctionCallbackInfo<v8::Value>& info);
|
||||
JS_SESSION_FUNCTION_DEF(Originate);
|
||||
JS_SESSION_FUNCTION_DEF(SetCallerdata);
|
||||
JS_SESSION_FUNCTION_DEF(SetHangupHook);
|
||||
JS_SESSION_FUNCTION_DEF(SetAutoHangup);
|
||||
JS_SESSION_FUNCTION_DEF(SayPhrase);
|
||||
JS_SESSION_FUNCTION_DEF(StreamFile);
|
||||
JS_SESSION_FUNCTION_DEF(CollectInput);
|
||||
JS_SESSION_FUNCTION_DEF(RecordFile);
|
||||
JS_SESSION_FUNCTION_DEF(FlushEvents);
|
||||
JS_SESSION_FUNCTION_DEF(FlushDigits);
|
||||
JS_SESSION_FUNCTION_DEF(Speak);
|
||||
JS_SESSION_FUNCTION_DEF(SetVariable);
|
||||
JS_SESSION_FUNCTION_DEF(GetVariable);
|
||||
JS_SESSION_FUNCTION_DEF(GetDigits);
|
||||
JS_SESSION_FUNCTION_DEF(Answer);
|
||||
JS_SESSION_FUNCTION_DEF(PreAnswer);
|
||||
JS_SESSION_FUNCTION_DEF(GenerateXmlCdr);
|
||||
JS_SESSION_FUNCTION_DEF(Ready);
|
||||
JS_SESSION_FUNCTION_DEF(Answered);
|
||||
JS_SESSION_FUNCTION_DEF(MediaReady);
|
||||
JS_SESSION_FUNCTION_DEF(RingReady);
|
||||
JS_SESSION_FUNCTION_DEF(WaitForAnswer);
|
||||
JS_SESSION_FUNCTION_DEF(WaitForMedia);
|
||||
JS_SESSION_FUNCTION_DEF(GetEvent);
|
||||
JS_SESSION_FUNCTION_DEF(SendEvent);
|
||||
JS_SESSION_FUNCTION_DEF(Hangup);
|
||||
JS_SESSION_FUNCTION_DEF(Execute);
|
||||
JS_SESSION_FUNCTION_DEF(Detach);
|
||||
JS_SESSION_FUNCTION_DEF(Sleep);
|
||||
JS_SESSION_FUNCTION_DEF(Bridge);
|
||||
JS_SESSION_GET_PROPERTY_DEF(GetProperty);
|
||||
};
|
||||
|
||||
class FSInputCallbackState
|
||||
{
|
||||
public:
|
||||
FSSession *session_state;
|
||||
char code_buffer[1024];
|
||||
size_t code_buffer_len;
|
||||
char ret_buffer[1024];
|
||||
int ret_buffer_len;
|
||||
int digit_count;
|
||||
v8::Persistent<v8::Function> function;
|
||||
v8::Persistent<v8::Value> arg;
|
||||
v8::Persistent<v8::Value> ret;
|
||||
void *extra;
|
||||
FSSession *jss_a;
|
||||
FSSession *jss_b;
|
||||
v8::Persistent<v8::Object> session_obj_a;
|
||||
v8::Persistent<v8::Object> session_obj_b;
|
||||
|
||||
FSInputCallbackState(void);
|
||||
~FSInputCallbackState(void);
|
||||
};
|
||||
|
||||
#endif /* FS_SESSION_H */
|
||||
|
||||
/* 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 noet:
|
||||
*/
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* 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 Original Code is mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* fssocket.hpp -- JavaScript Socket class header
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FS_SOCKET_H
|
||||
#define FS_SOCKET_H
|
||||
|
||||
#include "mod_v8.h"
|
||||
|
||||
/* Macros for easier V8 callback definitions */
|
||||
#define JS_SOCKET_GET_PROPERTY_DEF(method_name) JS_GET_PROPERTY_DEF(method_name, FSSocket)
|
||||
#define JS_SOCKET_SET_PROPERTY_DEF(method_name) JS_SET_PROPERTY_DEF(method_name, FSSocket)
|
||||
#define JS_SOCKET_FUNCTION_DEF(method_name) JS_FUNCTION_DEF(method_name, FSSocket)
|
||||
#define JS_SOCKET_GET_PROPERTY_IMPL(method_name) JS_GET_PROPERTY_IMPL(method_name, FSSocket)
|
||||
#define JS_SOCKET_SET_PROPERTY_IMPL(method_name) JS_SET_PROPERTY_IMPL(method_name, FSSocket)
|
||||
#define JS_SOCKET_FUNCTION_IMPL(method_name) JS_FUNCTION_IMPL(method_name, FSSocket)
|
||||
|
||||
class FSSocket : public JSBase
|
||||
{
|
||||
private:
|
||||
switch_socket_t *_socket;
|
||||
switch_memory_pool_t *_pool;
|
||||
char *_read_buffer;
|
||||
switch_size_t _buffer_size;
|
||||
int _state;
|
||||
|
||||
void Init();
|
||||
public:
|
||||
FSSocket(JSMain *owner) : JSBase(owner) { Init(); }
|
||||
FSSocket(const v8::FunctionCallbackInfo<v8::Value>& info) : JSBase(info) { Init(); }
|
||||
virtual ~FSSocket(void);
|
||||
virtual std::string GetJSClassName();
|
||||
|
||||
static const v8_mod_interface_t *GetModuleInterface();
|
||||
|
||||
/* Methods available from JavaScript */
|
||||
static void *Construct(const v8::FunctionCallbackInfo<v8::Value>& info);
|
||||
JS_SOCKET_FUNCTION_DEF(Connect);
|
||||
JS_SOCKET_FUNCTION_DEF(Close);
|
||||
JS_SOCKET_FUNCTION_DEF(Send);
|
||||
JS_SOCKET_FUNCTION_DEF(ReadBytes);
|
||||
JS_SOCKET_FUNCTION_DEF(Read);
|
||||
JS_SOCKET_GET_PROPERTY_DEF(GetProperty);
|
||||
};
|
||||
|
||||
#endif /* FS_SOCKET_H */
|
||||
|
||||
/* 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 noet:
|
||||
*/
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* 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 Original Code is mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* fsteletone.hpp -- JavaScript TeleTone class header
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FS_TELETONE_H
|
||||
#define FS_TELETONE_H
|
||||
|
||||
#include "mod_v8.h"
|
||||
#include <libteletone.h>
|
||||
|
||||
/* Macros for easier V8 callback definitions */
|
||||
#define JS_TELETONE_GET_PROPERTY_DEF(method_name) JS_GET_PROPERTY_DEF(method_name, FSTeleTone)
|
||||
#define JS_TELETONE_SET_PROPERTY_DEF(method_name) JS_SET_PROPERTY_DEF(method_name, FSTeleTone)
|
||||
#define JS_TELETONE_FUNCTION_DEF(method_name) JS_FUNCTION_DEF(method_name, FSTeleTone)
|
||||
#define JS_TELETONE_GET_PROPERTY_IMPL(method_name) JS_GET_PROPERTY_IMPL(method_name, FSTeleTone)
|
||||
#define JS_TELETONE_SET_PROPERTY_IMPL(method_name) JS_SET_PROPERTY_IMPL(method_name, FSTeleTone)
|
||||
#define JS_TELETONE_FUNCTION_IMPL(method_name) JS_FUNCTION_IMPL(method_name, FSTeleTone)
|
||||
|
||||
class FSTeleTone : public JSBase
|
||||
{
|
||||
private:
|
||||
teletone_generation_session_t _ts;
|
||||
switch_core_session_t *_session;
|
||||
switch_codec_t _codec;
|
||||
switch_buffer_t *_audio_buffer;
|
||||
switch_memory_pool_t *_pool;
|
||||
switch_timer_t *_timer;
|
||||
switch_timer_t _timer_base;
|
||||
v8::Persistent<v8::Function> _function;
|
||||
v8::Persistent<v8::Value> _arg;
|
||||
unsigned int flags;
|
||||
|
||||
void Init();
|
||||
public:
|
||||
FSTeleTone(JSMain *owner) : JSBase(owner) { Init(); }
|
||||
FSTeleTone(const v8::FunctionCallbackInfo<v8::Value>& info) : JSBase(info) { Init(); }
|
||||
virtual ~FSTeleTone(void);
|
||||
virtual std::string GetJSClassName();
|
||||
|
||||
static const v8_mod_interface_t *GetModuleInterface();
|
||||
|
||||
static int Handler(teletone_generation_session_t *ts, teletone_tone_map_t *map);
|
||||
|
||||
/* Methods available from JavaScript */
|
||||
static void *Construct(const v8::FunctionCallbackInfo<v8::Value>& info);
|
||||
JS_TELETONE_FUNCTION_DEF(Generate);
|
||||
JS_TELETONE_FUNCTION_DEF(OnDTMF);
|
||||
JS_TELETONE_FUNCTION_DEF(AddTone);
|
||||
JS_TELETONE_GET_PROPERTY_DEF(GetNameProperty);
|
||||
};
|
||||
|
||||
#endif /* FS_TELETONE_H */
|
||||
|
||||
/* 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 noet:
|
||||
*/
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* 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 Original Code is mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* fsxml.hpp -- JavaScript XML class header
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FS_XML_H
|
||||
#define FS_XML_H
|
||||
|
||||
#include "mod_v8.h"
|
||||
|
||||
/* Macros for easier V8 callback definitions */
|
||||
#define JS_XML_GET_PROPERTY_DEF(method_name) JS_GET_PROPERTY_DEF(method_name, FSXML)
|
||||
#define JS_XML_SET_PROPERTY_DEF(method_name) JS_SET_PROPERTY_DEF(method_name, FSXML)
|
||||
#define JS_XML_FUNCTION_DEF(method_name) JS_FUNCTION_DEF(method_name, FSXML)
|
||||
#define JS_XML_GET_PROPERTY_IMPL(method_name) JS_GET_PROPERTY_IMPL(method_name, FSXML)
|
||||
#define JS_XML_SET_PROPERTY_IMPL(method_name) JS_SET_PROPERTY_IMPL(method_name, FSXML)
|
||||
#define JS_XML_FUNCTION_IMPL(method_name) JS_FUNCTION_IMPL(method_name, FSXML)
|
||||
#define JS_XML_IMPL_STATIC(method_name) JS_FUNCTION_IMPL_STATIC(method_name, FSXML)
|
||||
|
||||
class FSXML : public JSBase
|
||||
{
|
||||
private:
|
||||
switch_xml_t _xml;
|
||||
v8::Persistent<v8::Object> _rootJSObject; /* Always keep a reference to the root, so JS doesn't try to clean it up in GC */
|
||||
FSXML *_rootObject;
|
||||
switch_hash_t *_obj_hash;
|
||||
switch_memory_pool_t *_pool;
|
||||
|
||||
void Init();
|
||||
void InitRootObject();
|
||||
v8::Handle<v8::Value> GetJSObjFromXMLObj(const switch_xml_t xml, const v8::FunctionCallbackInfo<v8::Value>& info);
|
||||
void StoreObjectInHash(switch_xml_t xml, FSXML *obj);
|
||||
FSXML *FindObjectInHash(switch_xml_t xml);
|
||||
void DeleteObjectInHash(switch_xml_t xml);
|
||||
void DestroyHash();
|
||||
public:
|
||||
FSXML(JSMain *owner) : JSBase(owner) { Init(); }
|
||||
FSXML(const v8::FunctionCallbackInfo<v8::Value>& info) : JSBase(info) { Init(); }
|
||||
virtual ~FSXML(void);
|
||||
virtual std::string GetJSClassName();
|
||||
|
||||
static const v8_mod_interface_t *GetModuleInterface();
|
||||
|
||||
/* Methods available from JavaScript */
|
||||
static void *Construct(const v8::FunctionCallbackInfo<v8::Value>& info);
|
||||
JS_XML_FUNCTION_DEF(GetChild);
|
||||
JS_XML_FUNCTION_DEF(AddChild);
|
||||
JS_XML_FUNCTION_DEF(Next);
|
||||
JS_XML_FUNCTION_DEF(GetAttribute);
|
||||
JS_XML_FUNCTION_DEF(SetAttribute);
|
||||
JS_FUNCTION_DEF_STATIC(Remove);
|
||||
JS_XML_FUNCTION_DEF(Copy);
|
||||
JS_XML_FUNCTION_DEF(Serialize);
|
||||
JS_XML_GET_PROPERTY_DEF(GetNameProperty);
|
||||
JS_XML_GET_PROPERTY_DEF(GetDataProperty);
|
||||
JS_XML_SET_PROPERTY_DEF(SetDataProperty);
|
||||
JS_XML_GET_PROPERTY_DEF(GetXmlErrorProperty);
|
||||
};
|
||||
|
||||
#endif /* FS_XML_H */
|
||||
|
||||
/* 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 noet:
|
||||
*/
|
|
@ -0,0 +1,356 @@
|
|||
/*
|
||||
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* 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 Original Code is mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* javascript.hpp -- Header file for main JavaScript classes
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef V8_JAVASCRIPT_H
|
||||
#define V8_JAVASCRIPT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <v8.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <assert.h>
|
||||
|
||||
/* Enable this define enable V8 debugging protocol, this is not yet working */
|
||||
//#define V8_ENABLE_DEBUGGING
|
||||
|
||||
/*
|
||||
* Enable this define to force a GC after the script has finished execution.
|
||||
* This is only to help debug memory leaks, and should not be needed for anything else
|
||||
*/
|
||||
//#define V8_FORCE_GC_AFTER_EXECUTION
|
||||
|
||||
|
||||
/* Macro for easy V8 "get property" callback definition */
|
||||
#define JS_GET_PROPERTY_DEF(method_name, class_name) \
|
||||
static void method_name(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value>& info)\
|
||||
{\
|
||||
JS_CHECK_SCRIPT_STATE();\
|
||||
class_name *obj = JSBase::GetInstance<class_name>(info.Holder());\
|
||||
if (obj) {\
|
||||
obj->method_name##Impl(property, info);\
|
||||
} else {\
|
||||
int line;\
|
||||
char *file = JSMain::GetStackInfo(info.GetIsolate(), &line);\
|
||||
v8::String::Utf8Value str(info.Holder());\
|
||||
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "mod_v8", line, NULL, SWITCH_LOG_DEBUG, "No valid internal data available for %s when calling %s\n", *str ? *str : "[unknown]", #class_name "::" #method_name "()");\
|
||||
free(file);\
|
||||
info.GetReturnValue().Set(false);\
|
||||
}\
|
||||
}\
|
||||
void method_name##Impl(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value>& info)
|
||||
|
||||
/* Macro for easy V8 "set property" callback definition */
|
||||
#define JS_SET_PROPERTY_DEF(method_name, class_name) \
|
||||
static void method_name(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info)\
|
||||
{\
|
||||
JS_CHECK_SCRIPT_STATE();\
|
||||
class_name *obj = JSBase::GetInstance<class_name>(info.Holder());\
|
||||
if (obj) {\
|
||||
obj->method_name##Impl(property, value, info);\
|
||||
} else {\
|
||||
int line;\
|
||||
char *file = JSMain::GetStackInfo(info.GetIsolate(), &line);\
|
||||
v8::String::Utf8Value str(info.Holder());\
|
||||
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "mod_v8", line, NULL, SWITCH_LOG_DEBUG, "No valid internal data available for %s when calling %s\n", *str ? *str : "[unknown]", #class_name "::" #method_name "()");\
|
||||
free(file);\
|
||||
info.GetReturnValue().Set(false);\
|
||||
}\
|
||||
}\
|
||||
void method_name##Impl(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info)
|
||||
|
||||
/* Macro for easy V8 "function" callback definition */
|
||||
#define JS_FUNCTION_DEF(method_name, class_name) \
|
||||
static void method_name(const v8::FunctionCallbackInfo<v8::Value>& info)\
|
||||
{\
|
||||
JS_CHECK_SCRIPT_STATE();\
|
||||
class_name *obj = JSBase::GetInstance<class_name>(info.Holder());\
|
||||
if (obj) {\
|
||||
obj->method_name##Impl(info);\
|
||||
} else {\
|
||||
int line;\
|
||||
char *file = JSMain::GetStackInfo(info.GetIsolate(), &line);\
|
||||
v8::String::Utf8Value str(info.Holder());\
|
||||
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "mod_v8", line, NULL, SWITCH_LOG_DEBUG, "No valid internal data available for %s when calling %s\n", *str ? *str : "[unknown]", #class_name "::" #method_name "()");\
|
||||
free(file);\
|
||||
info.GetReturnValue().Set(false);\
|
||||
}\
|
||||
}\
|
||||
void method_name##Impl(const v8::FunctionCallbackInfo<v8::Value>& info)
|
||||
|
||||
/* Macros for V8 callback implementations */
|
||||
#define JS_GET_PROPERTY_IMPL(method_name, class_name) void class_name::method_name##Impl(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value>& info)
|
||||
#define JS_SET_PROPERTY_IMPL(method_name, class_name) void class_name::method_name##Impl(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info)
|
||||
#define JS_FUNCTION_IMPL(method_name, class_name) void class_name::method_name##Impl(const v8::FunctionCallbackInfo<v8::Value>& info)
|
||||
|
||||
/* Macros for V8 callback definitions (class static version) */
|
||||
#define JS_GET_PROPERTY_DEF_STATIC(method_name) static void method_name(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value>& info)
|
||||
#define JS_SET_PROPERTY_DEF_STATIC(method_name) static void method_name(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info)
|
||||
#define JS_FUNCTION_DEF_STATIC(method_name) static void method_name(const v8::FunctionCallbackInfo<v8::Value>& info)
|
||||
|
||||
/* Macros for V8 callback implementations (class static version) */
|
||||
#define JS_GET_PROPERTY_IMPL_STATIC(method_name, class_name) void class_name::method_name(v8::Local<v8::String> property, const v8::PropertyCallbackInfo<v8::Value>& info)
|
||||
#define JS_SET_PROPERTY_IMPL_STATIC(method_name, class_name) void class_name::method_name(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info)
|
||||
#define JS_FUNCTION_IMPL_STATIC(method_name, class_name) void class_name::method_name(const v8::FunctionCallbackInfo<v8::Value>& info)
|
||||
|
||||
/* Macro for basic script state check (to know if the script is being terminated), should be called before calling any callback actual code */
|
||||
#define JS_CHECK_SCRIPT_STATE() \
|
||||
if (v8::V8::IsExecutionTerminating(info.GetIsolate())) return;\
|
||||
if (JSMain::GetScriptInstanceFromIsolate(info.GetIsolate()) && JSMain::GetScriptInstanceFromIsolate(info.GetIsolate())->GetForcedTermination()) return
|
||||
|
||||
/* strdup function for all platforms */
|
||||
#ifdef NDEBUG
|
||||
#if (_MSC_VER >= 1500) // VC9+
|
||||
#define js_strdup(ptr, s) (void)( (!!(ptr = _strdup(s))) || (fprintf(stderr,"ABORT! Malloc failure at: %s:%d", __FILE__, __LINE__),abort(), 0), ptr)
|
||||
#else
|
||||
#define js_strdup(ptr, s) (void)( (!!(ptr = strdup(s))) || (fprintf(stderr,"ABORT! Malloc failure at: %s:%d", __FILE__, __LINE__),abort(), 0), ptr)
|
||||
#endif
|
||||
#else
|
||||
#if (_MSC_VER >= 1500) // VC9+
|
||||
#define js_strdup(ptr, s) (void)(assert(((ptr) = _strdup(s))),ptr);__analysis_assume( ptr )
|
||||
#else
|
||||
#define js_strdup(ptr, s) (void)(assert(((ptr) = strdup((s)))),ptr)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Makes sure to return a valid char pointer */
|
||||
#define js_safe_str(s) (s ? s : "")
|
||||
|
||||
/* JS Constructor callback definition */
|
||||
typedef void * void_pointer_t;
|
||||
typedef void_pointer_t (*ConstructorCallback)(const v8::FunctionCallbackInfo<v8::Value>& info);
|
||||
|
||||
/* JS Function definition */
|
||||
typedef struct {
|
||||
const char *name; /* Name of the function */
|
||||
v8::FunctionCallback func; /* Function callback */
|
||||
} js_function_t;
|
||||
|
||||
/* JS Property definition */
|
||||
typedef struct {
|
||||
const char *name; /* Name of the property */
|
||||
v8::AccessorGetterCallback get; /* The property getter */
|
||||
v8::AccessorSetterCallback set; /* The property setter */
|
||||
} js_property_t;
|
||||
|
||||
/* JS Class definition */
|
||||
typedef struct {
|
||||
const char *name; /* The name of the class */
|
||||
ConstructorCallback constructor; /* The constructor definition */
|
||||
const js_function_t *functions; /* An array of function definitions */
|
||||
const js_property_t *properties; /* An array of property definitions */
|
||||
} js_class_definition_t;
|
||||
|
||||
/* Import/export definitions (used by extra loadable modules) */
|
||||
#ifdef WIN32
|
||||
/* WIN32 */
|
||||
#ifdef JSMOD_IMPORT
|
||||
#define JSMOD_EXPORT __declspec(dllimport)
|
||||
#else
|
||||
#define JSMOD_EXPORT __declspec(dllexport)
|
||||
#endif
|
||||
#else
|
||||
/* Not WIN32 */
|
||||
#ifdef JSMOD_IMPORT
|
||||
#define JSMOD_EXPORT
|
||||
#else
|
||||
#if (HAVE_VISIBILITY != 1)
|
||||
#define JSMOD_EXPORT
|
||||
#else
|
||||
#define JSMOD_EXPORT __attribute__ ((visibility("default")))
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* JSMain class prototype */
|
||||
class JSMOD_EXPORT JSMain;
|
||||
|
||||
/* Base class used by all C++ classes implemented in JS */
|
||||
class JSMOD_EXPORT JSBase
|
||||
{
|
||||
private:
|
||||
v8::Persistent<v8::Object> *persistentHandle; /* The persistent handle of the JavaScript object for this instance */
|
||||
bool autoDestroy; /* flag to tell if this instance should be auto destroyed during JavaScript GC */
|
||||
JSMain *js; /* The "owner" of this instance */
|
||||
|
||||
/* The callback that happens when the V8 GC cleans up object instances */
|
||||
static void WeakCallback(const v8::WeakCallbackData<v8::Object, JSBase>& data);
|
||||
|
||||
/* Internal basic constructor when creating a new instance from JS. It will call the actual user code inside */
|
||||
static void CreateInstance(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
|
||||
/* Store a C++ instance to a JS object's private data */
|
||||
static void AddInstance(v8::Isolate *isolate, const v8::Handle<v8::Object>& handle, const v8::Handle<v8::External>& object, bool autoDestroy);
|
||||
public:
|
||||
JSBase(JSMain *owner);
|
||||
JSBase(const v8::FunctionCallbackInfo<v8::Value>& info);
|
||||
virtual ~JSBase(void);
|
||||
|
||||
/* Returns the JS object related to the C++ instance */
|
||||
v8::Handle<v8::Object> GetJavaScriptObject();
|
||||
|
||||
/* Register a C++ class inside V8 (must be called within a entered isolate, and context) */
|
||||
static void Register(v8::Isolate *isolate, const js_class_definition_t *desc);
|
||||
|
||||
/* Register an existing C++ class instance inside V8 (must be called within a entered isolate, and context) */
|
||||
void RegisterInstance(v8::Isolate *isolate, std::string name, bool autoDestroy);
|
||||
|
||||
/* Get a JSBase instance from JavaScript callback arguments */
|
||||
template <typename T> static T *GetInstance(const v8::FunctionCallbackInfo<v8::Value>& info)
|
||||
{
|
||||
v8::HandleScope scope(info.GetIsolate());
|
||||
return GetInstance<T>(info.Holder());
|
||||
}
|
||||
|
||||
/* Get a JSBase instance from a JavaScript object */
|
||||
template <typename T> static T *GetInstance(const v8::Local<v8::Object>& self)
|
||||
{
|
||||
v8::Local<v8::Value> val = self->GetInternalField(0);
|
||||
|
||||
if (!val.IsEmpty() && val->IsExternal()) {
|
||||
v8::Local<v8::External> wrap = v8::Local<v8::External>::Cast(val);
|
||||
JSBase *ptr = static_cast<JSBase*>(wrap->Value());
|
||||
return dynamic_cast<T*>(ptr); /* If we're trying to cast to the wrong type, dynamic_cast will return NULL */
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get a JavaScript function from a JavaScript argument (can be either a string or the actual function) */
|
||||
static v8::Handle<v8::Function> GetFunctionFromArg(v8::Isolate *isolate, const v8::Local<v8::Value>& arg);
|
||||
|
||||
/* Default JS setter callback, to be used for read only values */
|
||||
static void DefaultSetProperty(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info);
|
||||
|
||||
/* Get the name of the JavaScript class - must be overridden by the actual implementation */
|
||||
virtual std::string GetJSClassName() = 0;
|
||||
|
||||
/* Get the JavaScript class instance that owns this instance */
|
||||
JSMain *GetOwner();
|
||||
|
||||
/* Get the JavaScript isolate that's active for the current context */
|
||||
v8::Isolate *GetIsolate();
|
||||
|
||||
/* Get autoDestroy variable */
|
||||
bool GetAutoDestroy();
|
||||
};
|
||||
|
||||
/* Definition of the class registration method */
|
||||
typedef void (*JSExtenderRegisterMethod)(js_class_definition_t *class_definition);
|
||||
|
||||
/* The struct holding a C++ class instance, to be used in JS */
|
||||
typedef struct {
|
||||
JSBase *obj; /* The class instance to be used in JS */
|
||||
char *name; /* The name of the instance within JS */
|
||||
bool auto_destroy; /* Flag to know if the instance should be auto destroyed when not needed by JS anymore */
|
||||
} registered_instance_t;
|
||||
|
||||
/* Main class for executing a V8 JavaScript */
|
||||
class JSMOD_EXPORT JSMain
|
||||
{
|
||||
private:
|
||||
v8::Isolate* isolate; /* The V8 isolate for this script instance */
|
||||
|
||||
std::vector<const js_class_definition_t *> *extenderClasses;/* List holding C++ classes to be registered in JS on execution */
|
||||
std::vector<js_function_t *> *extenderFunctions; /* List holding C++ functions to be registered in JS on execution */
|
||||
std::vector<registered_instance_t*> *extenderInstances; /* List holding C++ class instances to be registered in JS on execution */
|
||||
std::set<JSBase *> *activeInstances; /* List holding all active instances right now (in a running script) */
|
||||
|
||||
bool forcedTermination; /* Is set to true if script is triggering a forced termination of the script */
|
||||
char *forcedTerminationMessage; /* The message given during forced termination */
|
||||
int forcedTerminationLineNumber; /* The JS line number that called the exit function */
|
||||
char *forcedTerminationScriptFile; /* The JS script file that called the exit function */
|
||||
|
||||
/* Internal Log function accessable from JS - used just for testing */
|
||||
static void Log(const v8::FunctionCallbackInfo<v8::Value>& args);
|
||||
public:
|
||||
JSMain(void);
|
||||
~JSMain(void);
|
||||
|
||||
void AddJSExtenderFunction(v8::FunctionCallback func, const std::string& name); /* Add a C++ function to be registered when running the script */
|
||||
void AddJSExtenderClass(const js_class_definition_t *method); /* Add a C++ class to be registered when running the script */
|
||||
void AddJSExtenderInstance(JSBase *instance, const std::string& objectName, bool autoDestroy); /* Add a C++ class instance to be registered when running the script */
|
||||
|
||||
static JSMain *GetScriptInstanceFromIsolate(v8::Isolate* isolate); /* Get the JavaScript C++ instance from a V8 isolate */
|
||||
v8::Isolate *GetIsolate(); /* Get the V8 isolate from the current instance */
|
||||
|
||||
const std::string ExecuteScript(const std::string& filename, bool *resultIsError);
|
||||
const std::string ExecuteString(const std::string& scriptData, const std::string& fileName, bool *resultIsError);
|
||||
|
||||
static void Initialize(); /* Initialize the V8 engine */
|
||||
static void Dispose(); /* Deinitialize the V8 engine */
|
||||
|
||||
static void Include(const v8::FunctionCallbackInfo<v8::Value>& args); /* Adds functionality to include another JavaScript from the running script */
|
||||
static void Version(const v8::FunctionCallbackInfo<v8::Value>& args); /* Internal Version function accessable from JS - used to get the current V( version */
|
||||
static const std::string GetExceptionInfo(v8::Isolate* isolate, v8::TryCatch* try_catch); /* Get the exception information from a V8 TryCatch instance */
|
||||
|
||||
const std::vector<const js_class_definition_t *>& GetExtenderClasses() const;/* Returns the list of class definitions */
|
||||
const std::vector<js_function_t *>& GetExtenderFunctions() const; /* Returns the list of function definitions */
|
||||
const std::vector<registered_instance_t*>& GetExtenderInstances() const; /* Returns the list of class instance definitions */
|
||||
|
||||
/* Methods to keep track of all created C++ instances within JS */
|
||||
void AddActiveInstance(JSBase *obj);
|
||||
void RemoveActiveInstance(JSBase *obj);
|
||||
void DisposeActiveInstances();
|
||||
|
||||
static bool FileExists(const char *file);
|
||||
static const std::string LoadFileToString(const std::string& filename);
|
||||
|
||||
/* Data related to forced script termination */
|
||||
bool GetForcedTermination(void);
|
||||
void ResetForcedTermination(void);
|
||||
const char *GetForcedTerminationMessage(void);
|
||||
const char *GetForcedTerminationScriptFile(void);
|
||||
int GetForcedTerminationLineNumber(void);
|
||||
|
||||
/* Method to force termination of a script */
|
||||
static void ExitScript(v8::Isolate *isolate, const char *msg);
|
||||
|
||||
/* Get the filename and line number of the current JS stack */
|
||||
static char *GetStackInfo(v8::Isolate *isolate, int *lineNumber);
|
||||
};
|
||||
|
||||
#ifdef V8_ENABLE_DEBUGGING
|
||||
void V8DispatchDebugMessages();
|
||||
#endif
|
||||
|
||||
#endif /* V8_JAVASCRIPT_H */
|
||||
|
||||
/* 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 noet:
|
||||
*/
|
|
@ -0,0 +1,225 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectName>mod_v8</ProjectName>
|
||||
<ProjectGuid>{9B9D2551-D6BD-4F20-8BE5-DE30E154A064}</ProjectGuid>
|
||||
<RootNamespace>mod_v8</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\..\..\w32\module_release.props" />
|
||||
<Import Project="..\..\..\..\w32\v8.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\..\..\w32\module_debug.props" />
|
||||
<Import Project="..\..\..\..\w32\v8.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\..\..\w32\module_release.props" />
|
||||
<Import Project="..\..\..\..\w32\v8.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\..\..\w32\module_debug.props" />
|
||||
<Import Project="..\..\..\..\w32\v8.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<CodeAnalysisRuleSet>NativeMinimumRules.ruleset</CodeAnalysisRuleSet>
|
||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<CodeAnalysisRuleSet>NativeMinimumRules.ruleset</CodeAnalysisRuleSet>
|
||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<CodeAnalysisRuleSet>NativeMinimumRules.ruleset</CodeAnalysisRuleSet>
|
||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<CodeAnalysisRuleSet>NativeMinimumRules.ruleset</CodeAnalysisRuleSet>
|
||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<EnablePREfast>false</EnablePREfast>
|
||||
<TreatWarningAsError>false</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<ImportLibrary>$(Platform)\$(Configuration)\$(ProjectName).lib</ImportLibrary>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<EnablePREfast>false</EnablePREfast>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<ImportLibrary>$(Platform)\$(Configuration)\$(ProjectName).lib</ImportLibrary>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<EnablePREfast>false</EnablePREfast>
|
||||
<TreatWarningAsError>false</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<ImportLibrary>$(Platform)\$(Configuration)\$(ProjectName).lib</ImportLibrary>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<EnablePREfast>false</EnablePREfast>
|
||||
<TreatWarningAsError>false</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<ImportLibrary>$(Platform)\$(Configuration)\$(ProjectName).lib</ImportLibrary>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include=".\src\jsmain.cpp" />
|
||||
<ClCompile Include=".\src\jsbase.cpp" />
|
||||
<ClCompile Include=".\src\fscoredb.cpp" />
|
||||
<ClCompile Include=".\src\fscurl.cpp" />
|
||||
<ClCompile Include=".\src\fsdtmf.cpp" />
|
||||
<ClCompile Include=".\src\fsevent.cpp" />
|
||||
<ClCompile Include=".\src\fsfileio.cpp" />
|
||||
<ClCompile Include=".\src\fsodbc.cpp" />
|
||||
<ClCompile Include=".\src\fspcre.cpp" />
|
||||
<ClCompile Include=".\src\fsrequest.cpp" />
|
||||
<ClCompile Include=".\src\fssession.cpp" />
|
||||
<ClCompile Include=".\src\fssocket.cpp" />
|
||||
<ClCompile Include=".\src\fsglobal.cpp" />
|
||||
<ClCompile Include=".\src\fsteletone.cpp" />
|
||||
<ClCompile Include="mod_v8.cpp" />
|
||||
<ClCompile Include="src\fsfile.cpp" />
|
||||
<ClCompile Include="src\fsxml.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include=".\include\javascript.hpp" />
|
||||
<ClInclude Include=".\include\fscoredb.hpp" />
|
||||
<ClInclude Include=".\include\fscurl.hpp" />
|
||||
<ClInclude Include=".\include\fsdtmf.hpp" />
|
||||
<ClInclude Include=".\include\fsevent.hpp" />
|
||||
<ClInclude Include=".\include\fsfileio.hpp" />
|
||||
<ClInclude Include=".\include\fsodbc.hpp" />
|
||||
<ClInclude Include=".\include\fspcre.hpp" />
|
||||
<ClInclude Include=".\include\fsrequest.hpp" />
|
||||
<ClInclude Include=".\include\fssession.hpp" />
|
||||
<ClInclude Include=".\include\fssocket.hpp" />
|
||||
<ClInclude Include=".\include\fsglobal.hpp" />
|
||||
<ClInclude Include=".\include\fsteletone.hpp" />
|
||||
<ClInclude Include="include\fsfile.hpp" />
|
||||
<ClInclude Include="include\fsxml.hpp" />
|
||||
<ClInclude Include="mod_v8.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\libs\libteletone\libteletone.2012.vcxproj">
|
||||
<Project>{89385c74-5860-4174-9caf-a39e7c48909c}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\..\libs\win32\v8\libv8.2012.vcxproj">
|
||||
<Project>{AB03E82B-48B1-4374-B32A-A1AF83DDC6C2}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\..\libs\win32\curl\curllib.2012.vcxproj">
|
||||
<Project>{87ee9da4-de1e-4448-8324-183c98dca588}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\..\w32\Library\FreeSwitchCore.2012.vcxproj">
|
||||
<Project>{202d7a4e-760d-4d0e-afa1-d7459ced30ff}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,116 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClCompile Include="mod_v8.cpp" />
|
||||
<ClCompile Include=".\src\jsmain.cpp">
|
||||
<Filter>BaseClasses</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include=".\src\jsbase.cpp">
|
||||
<Filter>BaseClasses</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include=".\src\fscoredb.cpp">
|
||||
<Filter>FSClasses</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include=".\src\fscurl.cpp">
|
||||
<Filter>FSClasses</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include=".\src\fsdtmf.cpp">
|
||||
<Filter>FSClasses</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include=".\src\fsevent.cpp">
|
||||
<Filter>FSClasses</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\fsfile.cpp">
|
||||
<Filter>FSClasses</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include=".\src\fsfileio.cpp">
|
||||
<Filter>FSClasses</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include=".\src\fsglobal.cpp">
|
||||
<Filter>FSClasses</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include=".\src\fsodbc.cpp">
|
||||
<Filter>FSClasses</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include=".\src\fspcre.cpp">
|
||||
<Filter>FSClasses</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include=".\src\fsrequest.cpp">
|
||||
<Filter>FSClasses</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include=".\src\fssession.cpp">
|
||||
<Filter>FSClasses</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include=".\src\fssocket.cpp">
|
||||
<Filter>FSClasses</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include=".\src\fsteletone.cpp">
|
||||
<Filter>FSClasses</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\fsxml.cpp">
|
||||
<Filter>FSClasses</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="mod_v8.h" />
|
||||
<ClInclude Include=".\include\javascript.hpp">
|
||||
<Filter>BaseClasses\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include=".\include\fscoredb.hpp">
|
||||
<Filter>FSClasses\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include=".\include\fscurl.hpp">
|
||||
<Filter>FSClasses\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include=".\include\fsdtmf.hpp">
|
||||
<Filter>FSClasses\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include=".\include\fsevent.hpp">
|
||||
<Filter>FSClasses\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\fsfile.hpp">
|
||||
<Filter>FSClasses\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include=".\include\fsfileio.hpp">
|
||||
<Filter>FSClasses\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include=".\include\fsglobal.hpp">
|
||||
<Filter>FSClasses\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include=".\include\fsodbc.hpp">
|
||||
<Filter>FSClasses\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include=".\include\fspcre.hpp">
|
||||
<Filter>FSClasses\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include=".\include\fsrequest.hpp">
|
||||
<Filter>FSClasses\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include=".\include\fssession.hpp">
|
||||
<Filter>FSClasses\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include=".\include\fssocket.hpp">
|
||||
<Filter>FSClasses\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include=".\include\fsteletone.hpp">
|
||||
<Filter>FSClasses\include</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\fsxml.hpp">
|
||||
<Filter>FSClasses\include</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="BaseClasses">
|
||||
<UniqueIdentifier>{57f55a0b-1790-4632-95e6-19acbe9015d3}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="FSClasses">
|
||||
<UniqueIdentifier>{dcda9b2f-890a-4820-84e3-4bbcf8f0b62c}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="FSClasses\include">
|
||||
<UniqueIdentifier>{ed9652cf-79bd-4567-9a98-1ed5077d5805}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="BaseClasses\include">
|
||||
<UniqueIdentifier>{3efc073f-f052-4e3d-921c-8d6b6a5a7215}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,779 @@
|
|||
/*
|
||||
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* 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 Original Code is ported from FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* William King <william.king@quentustech.com>
|
||||
*
|
||||
* mod_v8.cpp -- JavaScript FreeSWITCH module
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* This module executes JavaScript using Google's V8 JavaScript engine.
|
||||
*
|
||||
* It extends the available JavaScript classes with the following FS related classes;
|
||||
* CoreDB Adds features to access the core DB (SQLite) in FreeSWITCH. (on request only)
|
||||
* CURL Adds some extra methods for CURL access. (on request only)
|
||||
* DTMF Object that holds information about a DTMF event.
|
||||
* Event Object that holds information about a FreeSWITCH event.
|
||||
* File Class to reflect the Spidermonkey built-in class "File". Not yet implemented! (on request only)
|
||||
* FileIO Simple class for basic file IO.
|
||||
* ODBC Adds features to access any ODBC available database in the system. (on request only)
|
||||
* PCRE Adds features to do regexp using the PCRE implementeation.
|
||||
* Request Class for extra features during API call from FS (using 'jsapi' function). This class cannot be constructed from JS code!
|
||||
* The Request class is only availble when started from 'jsapi' FS command, and only inside the predefined variable 'request'.
|
||||
* Session Main FS class, includes all functions to handle a session.
|
||||
* Socket Class for communicating over a TCP/IP socket. (on request only)
|
||||
* TeleTone Class used to play tones to a FS channel. (on request only)
|
||||
* XML XML parsing class, using the features from switch_xml. (on request only)
|
||||
*
|
||||
* Some of the classes above are available on request only, using the command [use('Class');] before using the class for the first time.
|
||||
*
|
||||
* It also adds quite a few global functions, directly available for the user (see fsglobal.cpp for the implementation).
|
||||
*
|
||||
* Depedning on how the script was started from FreeSWITCH, some variables might be defined already;
|
||||
* session If the script is started from the dialplan, the variable 'session' holds the session for the current call.
|
||||
* request If the script is started using 'jsapi' function, the variable 'request' is an instance of the Request class.
|
||||
* message If the script is started as a chat application, the actual FreeSWITCH event will be available in the variable 'message'.
|
||||
*
|
||||
* All classes are implemented in a pair of hpp/cpp files, named after the class. For instance; class "File" is implemented in fsfile.cpp.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mod_v8.h"
|
||||
#include <fstream>
|
||||
|
||||
#ifdef V8_ENABLE_DEBUGGING
|
||||
#include <v8-debug.h>
|
||||
#endif
|
||||
|
||||
/* Global JavaScript functions */
|
||||
#include "fsglobal.hpp"
|
||||
|
||||
/* Common JavaScript classes */
|
||||
#include "fsrequest.hpp" /* Only loaded during 'jsapi' call */
|
||||
#include "fspcre.hpp"
|
||||
#include "fsevent.hpp"
|
||||
#include "fssession.hpp"
|
||||
#include "fsdtmf.hpp"
|
||||
#include "fsfileio.hpp"
|
||||
|
||||
/* Optional JavaScript classes (loaded on demand) */
|
||||
#include "fscoredb.hpp"
|
||||
#include "fscurl.hpp"
|
||||
#include "fsteletone.hpp"
|
||||
#include "fssocket.hpp"
|
||||
#include "fsodbc.hpp"
|
||||
#include "fsxml.hpp"
|
||||
#include "fsfile.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace v8;
|
||||
|
||||
SWITCH_BEGIN_EXTERN_C
|
||||
|
||||
/* FreeSWITCH module load definitions */
|
||||
SWITCH_MODULE_LOAD_FUNCTION(mod_v8_load);
|
||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_v8_shutdown);
|
||||
SWITCH_MODULE_DEFINITION_EX(mod_v8, mod_v8_load, mod_v8_shutdown, NULL, SMODF_GLOBAL_SYMBOLS);
|
||||
|
||||
/* API interfaces */
|
||||
static switch_api_interface_t *jsrun_interface = NULL;
|
||||
static switch_api_interface_t *jsapi_interface = NULL;
|
||||
|
||||
/* Module manager for loadable modules */
|
||||
module_manager_t module_manager = { 0 };
|
||||
|
||||
/* Loadable module struct */
|
||||
typedef struct {
|
||||
char *filename;
|
||||
void *lib;
|
||||
const v8_mod_interface_t *module_interface;
|
||||
v8_mod_init_t v8_mod_init;
|
||||
} v8_loadable_module_t;
|
||||
|
||||
#ifdef V8_ENABLE_DEBUGGING
|
||||
static bool debug_enable_callback = false;
|
||||
static int debug_listen_port = 9999;
|
||||
static bool debug_wait_for_connection = true;
|
||||
static bool debug_manual_break = true;
|
||||
#endif
|
||||
|
||||
using namespace v8;
|
||||
|
||||
static switch_status_t v8_mod_init_built_in(const v8_mod_interface_t *mod_interface)
|
||||
{
|
||||
switch_assert(mod_interface);
|
||||
|
||||
switch_core_hash_insert(module_manager.load_hash, (char *) mod_interface->name, mod_interface);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Successfully Loaded [%s]\n", mod_interface->name);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t v8_mod_load_file(const char *filename)
|
||||
{
|
||||
v8_loadable_module_t *module = NULL;
|
||||
switch_dso_lib_t dso = NULL;
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
switch_loadable_module_function_table_t *function_handle = NULL;
|
||||
v8_mod_init_t v8_mod_init = NULL;
|
||||
const v8_mod_interface_t *module_interface = NULL, *mp;
|
||||
char *derr = NULL;
|
||||
const char *err = NULL;
|
||||
|
||||
switch_assert(filename != NULL);
|
||||
|
||||
if (!(dso = switch_dso_open(filename, 1, &derr))) {
|
||||
status = SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
if (derr || status != SWITCH_STATUS_SUCCESS) {
|
||||
err = derr;
|
||||
goto err;
|
||||
}
|
||||
|
||||
function_handle = (switch_loadable_module_function_table_t *)switch_dso_data_sym(dso, "v8_mod_init", &derr);
|
||||
|
||||
if (!function_handle || derr) {
|
||||
status = SWITCH_STATUS_FALSE;
|
||||
err = derr;
|
||||
goto err;
|
||||
}
|
||||
|
||||
v8_mod_init = (v8_mod_init_t) (intptr_t) function_handle;
|
||||
|
||||
if (v8_mod_init == NULL) {
|
||||
err = "Cannot Load";
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (v8_mod_init(&module_interface) != SWITCH_STATUS_SUCCESS) {
|
||||
err = "Module load routine returned an error";
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!(module = (v8_loadable_module_t *) switch_core_permanent_alloc(sizeof(*module)))) {
|
||||
err = "Could not allocate memory\n";
|
||||
}
|
||||
|
||||
err:
|
||||
|
||||
if (err || !module) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Loading module %s\n**%s**\n", filename, switch_str_nil(err));
|
||||
switch_safe_free(derr);
|
||||
return SWITCH_STATUS_GENERR;
|
||||
}
|
||||
|
||||
module->filename = switch_core_permanent_strdup(filename);
|
||||
module->v8_mod_init = v8_mod_init;
|
||||
module->module_interface = module_interface;
|
||||
|
||||
module->lib = dso;
|
||||
|
||||
if ((mp = module->module_interface)) {
|
||||
switch_core_hash_insert(module_manager.load_hash, (char *) mp->name, (void *) mp);
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Successfully Loaded [%s]\n", module->filename);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static switch_status_t v8_load_module(const char *dir, const char *fname)
|
||||
{
|
||||
switch_size_t len = 0;
|
||||
char *path;
|
||||
char *file;
|
||||
|
||||
#ifdef WIN32
|
||||
const char *ext = ".dll";
|
||||
#else
|
||||
const char *ext = ".so";
|
||||
#endif
|
||||
|
||||
if ((file = switch_core_strdup(module_manager.pool, fname)) == 0) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
if (*file == '/') {
|
||||
path = switch_core_strdup(module_manager.pool, file);
|
||||
} else {
|
||||
if (strchr(file, '.')) {
|
||||
len = strlen(dir);
|
||||
len += strlen(file);
|
||||
len += 4;
|
||||
path = (char *) switch_core_alloc(module_manager.pool, len);
|
||||
switch_snprintf(path, len, "%s%s%s", dir, SWITCH_PATH_SEPARATOR, file);
|
||||
} else {
|
||||
len = strlen(dir);
|
||||
len += strlen(file);
|
||||
len += 8;
|
||||
path = (char *) switch_core_alloc(module_manager.pool, len);
|
||||
switch_snprintf(path, len, "%s%s%s%s", dir, SWITCH_PATH_SEPARATOR, file, ext);
|
||||
}
|
||||
}
|
||||
|
||||
return v8_mod_load_file(path);
|
||||
}
|
||||
|
||||
SWITCH_END_EXTERN_C
|
||||
|
||||
static switch_status_t load_modules(void)
|
||||
{
|
||||
const char *cf = "v8.conf";
|
||||
switch_xml_t cfg, xml;
|
||||
unsigned int count = 0;
|
||||
|
||||
#ifdef WIN32
|
||||
const char *ext = ".dll";
|
||||
const char *EXT = ".DLL";
|
||||
#elif defined (MACOSX) || defined (DARWIN)
|
||||
const char *ext = ".dylib";
|
||||
const char *EXT = ".DYLIB";
|
||||
#else
|
||||
const char *ext = ".so";
|
||||
const char *EXT = ".SO";
|
||||
#endif
|
||||
|
||||
memset(&module_manager, 0, sizeof(module_manager));
|
||||
switch_core_new_memory_pool(&module_manager.pool);
|
||||
|
||||
switch_core_hash_init(&module_manager.load_hash, module_manager.pool);
|
||||
|
||||
if ((xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
|
||||
switch_xml_t mods, ld;
|
||||
|
||||
if ((mods = switch_xml_child(cfg, "modules"))) {
|
||||
for (ld = switch_xml_child(mods, "load"); ld; ld = ld->next) {
|
||||
const char *val = switch_xml_attr_soft(ld, "module");
|
||||
if (!zstr(val) && strchr(val, '.') && !strstr(val, ext) && !strstr(val, EXT)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Invalid extension for %s\n", val);
|
||||
continue;
|
||||
}
|
||||
v8_load_module(SWITCH_GLOBAL_dirs.mod_dir, val);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
switch_xml_free(xml);
|
||||
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Open of %s failed\n", cf);
|
||||
}
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static int env_init(JSMain *js)
|
||||
{
|
||||
/* Init all "global" functions first */
|
||||
const js_function_t *fs_proc = FSGlobal::GetFunctionDefinitions();
|
||||
for (int i = 0; fs_proc[i].name && fs_proc[i].func; i++) {
|
||||
js->AddJSExtenderFunction(fs_proc[i].func, fs_proc[i].name);
|
||||
}
|
||||
|
||||
/* Init all basic classes made available from FreeSWITCH */
|
||||
js->AddJSExtenderClass(FSSession::GetClassDefinition());
|
||||
js->AddJSExtenderClass(FSFileIO::GetClassDefinition());
|
||||
js->AddJSExtenderClass(FSEvent::GetClassDefinition());
|
||||
js->AddJSExtenderClass(FSDTMF::GetClassDefinition());
|
||||
js->AddJSExtenderClass(FSPCRE::GetClassDefinition());
|
||||
/* To add a class that will always be available inside JS, add the definition here */
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void v8_error(Isolate* isolate, TryCatch* try_catch)
|
||||
{
|
||||
HandleScope handle_scope(isolate);
|
||||
String::Utf8Value exception(try_catch->Exception());
|
||||
const char *exception_string = js_safe_str(*exception);
|
||||
Handle<Message> message = try_catch->Message();
|
||||
const char *msg = "";
|
||||
string filename = __FILE__;
|
||||
int line = __LINE__;
|
||||
string text = "";
|
||||
JSMain *js = JSMain::GetScriptInstanceFromIsolate(isolate);
|
||||
|
||||
if (js && js->GetForcedTermination()) {
|
||||
js->ResetForcedTermination();
|
||||
switch_log_printf(SWITCH_CHANNEL_ID_LOG, js->GetForcedTerminationScriptFile(), modname, js->GetForcedTerminationLineNumber(), NULL, SWITCH_LOG_NOTICE, "Script exited with info [%s]\n", js->GetForcedTerminationMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
if (!message.IsEmpty()) {
|
||||
String::Utf8Value fname(message->GetScriptResourceName());
|
||||
|
||||
if (*fname) {
|
||||
filename = *fname;
|
||||
}
|
||||
|
||||
line = message->GetLineNumber();
|
||||
msg = exception_string;
|
||||
|
||||
String::Utf8Value sourceline(message->GetSourceLine());
|
||||
if (*sourceline) {
|
||||
text = *sourceline;
|
||||
}
|
||||
} else {
|
||||
msg = exception_string;
|
||||
}
|
||||
|
||||
if (!msg) {
|
||||
msg = "";
|
||||
}
|
||||
|
||||
if (text.length() > 0) {
|
||||
switch_log_printf(SWITCH_CHANNEL_ID_LOG, filename.c_str(), modname, line, NULL, SWITCH_LOG_ERROR, "Exception: %s (near: \"%s\")\n", msg, text.c_str());
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_ID_LOG, filename.c_str(), modname, line, NULL, SWITCH_LOG_ERROR, "Exception: %s\n", msg);
|
||||
}
|
||||
}
|
||||
|
||||
static char *v8_get_script_path(const char *script_file)
|
||||
{
|
||||
const char *p;
|
||||
char *ret = NULL;
|
||||
const char delims[] = "/\\";
|
||||
const char *i;
|
||||
|
||||
if (script_file) {
|
||||
for (i = delims; *i; i++) {
|
||||
if ((p = strrchr(script_file, *i))) {
|
||||
js_strdup(ret, script_file);
|
||||
*(ret + (p - script_file)) = '\0';
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
js_strdup(ret, ".");
|
||||
return ret;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int v8_parse_and_execute(switch_core_session_t *session, const char *input_code, switch_stream_handle_t *api_stream, switch_event_t *message)
|
||||
{
|
||||
string res;
|
||||
JSMain *js;
|
||||
Isolate *isolate;
|
||||
char *arg, *argv[512];
|
||||
int argc = 0, x = 0, y = 0;
|
||||
unsigned int flags = 0;
|
||||
char *path = NULL;
|
||||
string result_string;
|
||||
int result = 0;
|
||||
|
||||
if (zstr(input_code)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
js = new JSMain();
|
||||
isolate = js->GetIsolate();
|
||||
|
||||
env_init(js);
|
||||
|
||||
/* Try to read lock the session first */
|
||||
if (session) {
|
||||
if (switch_core_session_read_lock_hangup(session) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Read Lock Failure.\n");
|
||||
session = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Execute the actual script */
|
||||
//isolate->Enter();
|
||||
{
|
||||
Locker lock(isolate);
|
||||
Isolate::Scope iscope(isolate);
|
||||
{
|
||||
const char *script;
|
||||
|
||||
// Create a stack-allocated handle scope.
|
||||
HandleScope scope(isolate);
|
||||
|
||||
// Store our object internally
|
||||
isolate->SetData(0, js);
|
||||
|
||||
// New global template
|
||||
Handle<ObjectTemplate> global = ObjectTemplate::New();
|
||||
|
||||
if (global.IsEmpty()) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create JS global object template\n");
|
||||
} else {
|
||||
/* Function to print current V8 version */
|
||||
global->Set(String::NewFromUtf8(isolate, "version"), FunctionTemplate::New(isolate, JSMain::Version));
|
||||
|
||||
/* Add all global functions */
|
||||
for (size_t i = 0; i < js->GetExtenderFunctions().size(); i++) {
|
||||
js_function_t *proc = js->GetExtenderFunctions()[i];
|
||||
global->Set(String::NewFromUtf8(isolate, proc->name), FunctionTemplate::New(isolate, proc->func));
|
||||
}
|
||||
|
||||
// Create a new context.
|
||||
Local<Context> context = Context::New(isolate, NULL, global);
|
||||
|
||||
if (context.IsEmpty()) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create JS context\n");
|
||||
} else {
|
||||
// Enter the created context for compiling and running the script.
|
||||
Context::Scope context_scope(context);
|
||||
|
||||
#ifdef V8_ENABLE_DEBUGGING
|
||||
Persistent<Context> *debug_context = new Persistent<Context>();
|
||||
isolate->SetData(1, debug_context);
|
||||
debug_context->Reset(isolate, context);
|
||||
|
||||
//v8::Locker lck(isolate);
|
||||
|
||||
if (debug_enable_callback) {
|
||||
Debug::SetDebugMessageDispatchHandler(V8DispatchDebugMessages, true);
|
||||
}
|
||||
|
||||
if (debug_listen_port > 0) {
|
||||
char *name = switch_mprintf("mod_v8-%d", (int)switch_thread_self());
|
||||
Debug::EnableAgent(name, debug_listen_port, debug_wait_for_connection);
|
||||
switch_safe_free(name);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Register all plugin classes */
|
||||
for (size_t i = 0; i < js->GetExtenderClasses().size(); i++) {
|
||||
JSBase::Register(isolate, js->GetExtenderClasses()[i]);
|
||||
}
|
||||
|
||||
/* Register all instances of specific plugin classes */
|
||||
for (size_t i = 0; i < js->GetExtenderInstances().size(); i++) {
|
||||
registered_instance_t *inst = js->GetExtenderInstances()[i];
|
||||
inst->obj->RegisterInstance(isolate, inst->name, inst->auto_destroy);
|
||||
}
|
||||
|
||||
/* Emaculent conception of session object into the script if one is available */
|
||||
if (session) {
|
||||
FSSession *obj = new FSSession(js);
|
||||
obj->Init(session, flags);
|
||||
obj->RegisterInstance(isolate, "session", true);
|
||||
} else {
|
||||
/* Add a session object as a boolean instead, just to make it safe to check if it exists as expected */
|
||||
context->Global()->Set(String::NewFromUtf8(isolate, "session"), Boolean::New(isolate, false));
|
||||
}
|
||||
|
||||
if (message) {
|
||||
FSEvent::New(message, "message", js);
|
||||
}
|
||||
|
||||
if (api_stream) {
|
||||
/* The JS class "Request" is only needed when a api_stream object is passed here */
|
||||
JSBase::Register(isolate, FSRequest::GetClassDefinition());
|
||||
|
||||
FSRequest *ptr = new FSRequest(js);
|
||||
ptr->Init(input_code, api_stream);
|
||||
ptr->RegisterInstance(isolate, "request", true);
|
||||
}
|
||||
|
||||
script = input_code;
|
||||
|
||||
if (*script != '~') {
|
||||
if ((arg = (char *)strchr(script, ' '))) {
|
||||
*arg++ = '\0';
|
||||
argc = switch_separate_string(arg, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
|
||||
}
|
||||
|
||||
// Add arguments before running script.
|
||||
Local<Array> arguments = Array::New(isolate, argc);
|
||||
for (y = 0; y < argc; y++) {
|
||||
arguments->Set(Integer::New(isolate, y), String::NewFromUtf8(isolate, argv[y]));
|
||||
}
|
||||
context->Global()->Set(String::NewFromUtf8(isolate, "argv"), arguments);
|
||||
context->Global()->Set(String::NewFromUtf8(isolate, "argc"), Integer::New(isolate, argc));
|
||||
}
|
||||
|
||||
const char *script_data = NULL;
|
||||
const char *script_file = NULL;
|
||||
string s;
|
||||
|
||||
if (*script == '~') {
|
||||
script_data = script + 1;
|
||||
script_file = "inline";
|
||||
} else {
|
||||
const char *script_name = NULL;
|
||||
|
||||
if (switch_is_file_path(script)) {
|
||||
script_name = script;
|
||||
} else if ((path = switch_mprintf("%s%s%s", SWITCH_GLOBAL_dirs.script_dir, SWITCH_PATH_SEPARATOR, script))) {
|
||||
script_name = path;
|
||||
}
|
||||
|
||||
if (script_name) {
|
||||
if (JSMain::FileExists(script_name)) {
|
||||
s = JSMain::LoadFileToString(script_name);
|
||||
script_data = s.c_str();
|
||||
script_file = script_name;
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot Open File: %s\n", script_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!script_data) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No script to execute!\n");
|
||||
} else {
|
||||
/* Store our base directoy in variable 'scriptPath' */
|
||||
char *path = v8_get_script_path(script_file);
|
||||
if (path) {
|
||||
context->Global()->Set(String::NewFromUtf8(isolate, "scriptPath"), String::NewFromUtf8(isolate, path));
|
||||
free(path);
|
||||
}
|
||||
// Create a string containing the JavaScript source code.
|
||||
Handle<String> source = String::NewFromUtf8(isolate, script_data);
|
||||
|
||||
TryCatch try_catch;
|
||||
|
||||
// Compile the source code.
|
||||
Handle<Script> v8_script = Script::Compile(source, Handle<Value>::New(isolate, String::NewFromUtf8(isolate, script_file)));
|
||||
|
||||
if (try_catch.HasCaught()) {
|
||||
v8_error(isolate, &try_catch);
|
||||
} else {
|
||||
// Run the script
|
||||
#ifdef V8_ENABLE_DEBUGGING
|
||||
/* Break before we actually start executing the script */
|
||||
if (debug_manual_break) {
|
||||
Debug::DebugBreak(isolate);
|
||||
}
|
||||
#endif
|
||||
Handle<Value> result = v8_script->Run();
|
||||
if (try_catch.HasCaught()) {
|
||||
v8_error(isolate, &try_catch);
|
||||
} else {
|
||||
if (js->GetForcedTermination()) {
|
||||
js->ResetForcedTermination();
|
||||
switch_log_printf(SWITCH_CHANNEL_ID_LOG, js->GetForcedTerminationScriptFile(), modname, js->GetForcedTerminationLineNumber(), NULL, SWITCH_LOG_NOTICE, "Script exited with info [%s]\n", js->GetForcedTerminationMessage());
|
||||
}
|
||||
|
||||
if (!result.IsEmpty()) {
|
||||
// Return result as string
|
||||
String::Utf8Value ascii(result);
|
||||
if (*ascii) {
|
||||
res = *ascii;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef V8_FORCE_GC_AFTER_EXECUTION
|
||||
/* Clear up all destroyable C++ instances */
|
||||
js->DisposeActiveInstances();
|
||||
#endif
|
||||
}
|
||||
#ifdef V8_ENABLE_DEBUGGING
|
||||
isolate->SetData(1, NULL);
|
||||
if (debug_listen_port > 0) {
|
||||
Debug::DisableAgent();
|
||||
}
|
||||
debug_context->Reset();
|
||||
delete debug_context;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
isolate->SetData(0, NULL);
|
||||
}
|
||||
|
||||
#ifdef V8_FORCE_GC_AFTER_EXECUTION
|
||||
/* Force GC to run. This should not be needed, but is left here for reference */
|
||||
V8::ContextDisposedNotification();
|
||||
while (!V8::IdleNotification()) {}
|
||||
js->DisposeActiveInstances();
|
||||
#endif
|
||||
}
|
||||
//isolate->Exit();
|
||||
|
||||
if (res.length() == 0) {
|
||||
result = -1;
|
||||
} else {
|
||||
result = 0;
|
||||
|
||||
if (strcasecmp(res.c_str(), "undefined")) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Javascript result: [%s]\n", res.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
switch_safe_free(path);
|
||||
delete js;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
SWITCH_BEGIN_EXTERN_C
|
||||
|
||||
SWITCH_STANDARD_APP(v8_dp_function)
|
||||
{
|
||||
v8_parse_and_execute(session, data, NULL, NULL);
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_CHAT_APP(v8_chat_function)
|
||||
{
|
||||
v8_parse_and_execute(NULL, data, NULL, message);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
SWITCH_END_EXTERN_C
|
||||
|
||||
typedef struct {
|
||||
switch_memory_pool_t *pool;
|
||||
char *code;
|
||||
} v8_task_t;
|
||||
|
||||
static void *SWITCH_THREAD_FUNC v8_thread_run(switch_thread_t *thread, void *obj)
|
||||
{
|
||||
v8_task_t *task = (v8_task_t *) obj;
|
||||
switch_memory_pool_t *pool;
|
||||
|
||||
v8_parse_and_execute(NULL, task->code, NULL, NULL);
|
||||
|
||||
if ((pool = task->pool)) {
|
||||
switch_core_destroy_memory_pool(&pool);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void v8_thread_launch(const char *text)
|
||||
{
|
||||
switch_thread_t *thread;
|
||||
switch_threadattr_t *thd_attr = NULL;
|
||||
v8_task_t *task;
|
||||
switch_memory_pool_t *pool;
|
||||
|
||||
if (zstr(text)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "missing required input!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n");
|
||||
return;
|
||||
}
|
||||
|
||||
task = (v8_task_t *)switch_core_alloc(pool, sizeof(*task));
|
||||
task->pool = pool;
|
||||
task->code = switch_core_strdup(pool, text);
|
||||
|
||||
switch_threadattr_create(&thd_attr, pool);
|
||||
switch_threadattr_detach_set(thd_attr, 1);
|
||||
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
|
||||
switch_thread_create(&thread, thd_attr, v8_thread_run, task, pool);
|
||||
}
|
||||
|
||||
SWITCH_BEGIN_EXTERN_C
|
||||
|
||||
SWITCH_STANDARD_API(jsapi_function)
|
||||
{
|
||||
char *path_info = NULL;
|
||||
|
||||
if (stream->param_event) {
|
||||
path_info = switch_event_get_header(stream->param_event, "http-path-info");
|
||||
}
|
||||
|
||||
if (zstr(cmd) && path_info) {
|
||||
cmd = path_info;
|
||||
}
|
||||
|
||||
if (zstr(cmd)) {
|
||||
stream->write_function(stream, "USAGE: %s\n", jsapi_interface->syntax);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
v8_parse_and_execute(session, (char *) cmd, stream, NULL);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_API(launch_async)
|
||||
{
|
||||
if (zstr(cmd)) {
|
||||
stream->write_function(stream, "USAGE: %s\n", jsrun_interface->syntax);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
v8_thread_launch(cmd);
|
||||
stream->write_function(stream, "+OK\n");
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
SWITCH_MODULE_LOAD_FUNCTION(mod_v8_load)
|
||||
{
|
||||
switch_application_interface_t *app_interface;
|
||||
switch_chat_application_interface_t *chat_app_interface;
|
||||
|
||||
if (load_modules() != SWITCH_STATUS_SUCCESS) {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
JSMain::Initialize();
|
||||
|
||||
/* Make all "built in" modules available to load on demand */
|
||||
v8_mod_init_built_in(FSCoreDB::GetModuleInterface());
|
||||
v8_mod_init_built_in(FSCURL::GetModuleInterface());
|
||||
#ifdef HAVE_ODBC
|
||||
/* Only add ODBC class if ODBC is available in the system */
|
||||
v8_mod_init_built_in(FSODBC::GetModuleInterface());
|
||||
#endif
|
||||
v8_mod_init_built_in(FSSocket::GetModuleInterface());
|
||||
v8_mod_init_built_in(FSTeleTone::GetModuleInterface());
|
||||
v8_mod_init_built_in(FSXML::GetModuleInterface());
|
||||
v8_mod_init_built_in(FSFile::GetModuleInterface());
|
||||
|
||||
/* connect my internal structure to the blank pointer passed to me */
|
||||
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
|
||||
SWITCH_ADD_API(jsrun_interface, "jsrun", "run a script", launch_async, "jsrun <script> [additional_vars [...]]");
|
||||
SWITCH_ADD_API(jsapi_interface, "jsapi", "execute an api call", jsapi_function, "jsapi <script> [additional_vars [...]]");
|
||||
SWITCH_ADD_APP(app_interface, "javascript", "Launch JS ivr", "Run a javascript ivr on a channel", v8_dp_function, "<script> [additional_vars [...]]", SAF_SUPPORT_NOMEDIA);
|
||||
SWITCH_ADD_CHAT_APP(chat_app_interface, "javascript", "execute a js script", "execute a js script", v8_chat_function, "<script>", SCAF_NONE);
|
||||
|
||||
/* indicate that the module should continue to be loaded */
|
||||
return SWITCH_STATUS_NOUNLOAD;
|
||||
}
|
||||
|
||||
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_v8_shutdown)
|
||||
{
|
||||
switch_core_hash_destroy(&module_manager.load_hash);
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
SWITCH_END_EXTERN_C
|
||||
|
||||
/* 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 noet:
|
||||
*/
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* 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 Original Code is ported from FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* mod_v8.h -- JavaScript FreeSWITCH module header file
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MOD_V8_H
|
||||
#define MOD_V8_H
|
||||
|
||||
#include "javascript.hpp"
|
||||
#include <switch.h>
|
||||
|
||||
SWITCH_BEGIN_EXTERN_C
|
||||
|
||||
#define JS_BUFFER_SIZE 1024 * 32
|
||||
#define JS_BLOCK_SIZE JS_BUFFER_SIZE
|
||||
|
||||
typedef switch_status_t (*v8_mod_load_t) (const v8::FunctionCallbackInfo<v8::Value>& info);
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
v8_mod_load_t v8_mod_load;
|
||||
} v8_mod_interface_t;
|
||||
|
||||
typedef switch_status_t (*v8_mod_init_t) (const v8_mod_interface_t **module_interface);
|
||||
|
||||
typedef struct {
|
||||
switch_hash_t *load_hash;
|
||||
switch_memory_pool_t *pool;
|
||||
} module_manager_t;
|
||||
|
||||
extern module_manager_t module_manager;
|
||||
|
||||
SWITCH_END_EXTERN_C
|
||||
|
||||
#endif /* MOD_V8_H */
|
||||
|
||||
/* 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 noet:
|
||||
*/
|
|
@ -0,0 +1,212 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectName>mod_v8_skel</ProjectName>
|
||||
<ProjectGuid>{8B754330-A434-4791-97E5-1EE67060BAC0}</ProjectGuid>
|
||||
<RootNamespace>mod_v8_skel</RootNamespace>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
<PlatformToolset>v110</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\..\..\w32\winlibs.props" />
|
||||
<Import Project="..\..\..\..\w32\module_release.props" />
|
||||
<Import Project="..\..\..\..\w32\v8.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\..\..\w32\winlibs.props" />
|
||||
<Import Project="..\..\..\..\w32\module_debug.props" />
|
||||
<Import Project="..\..\..\..\w32\v8.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\..\..\w32\winlibs.props" />
|
||||
<Import Project="..\..\..\..\w32\module_release.props" />
|
||||
<Import Project="..\..\..\..\w32\v8.props" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
<Import Project="..\..\..\..\w32\winlibs.props" />
|
||||
<Import Project="..\..\..\..\w32\module_debug.props" />
|
||||
<Import Project="..\..\..\..\w32\v8.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(PlatformName)\$(Configuration)\mod_v8_skel\</IntDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(PlatformName)\$(Configuration)\mod_v8_skel\</IntDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(PlatformName)\$(Configuration)\mod_v8_skel\</IntDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(PlatformName)\$(Configuration)\mod_v8_skel\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<CodeAnalysisRuleSet>NativeMinimumRules.ruleset</CodeAnalysisRuleSet>
|
||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<CodeAnalysisRuleSet>NativeMinimumRules.ruleset</CodeAnalysisRuleSet>
|
||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<CodeAnalysisRuleSet>NativeMinimumRules.ruleset</CodeAnalysisRuleSet>
|
||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<CodeAnalysisRuleSet>NativeMinimumRules.ruleset</CodeAnalysisRuleSet>
|
||||
<RunCodeAnalysis>false</RunCodeAnalysis>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<PreBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
</PreBuildEvent>
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>JSMOD_IMPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<EnablePREfast>false</EnablePREfast>
|
||||
<TreatWarningAsError>false</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<PreBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
</PreBuildEvent>
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>JSMOD_IMPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<EnablePREfast>false</EnablePREfast>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<OutputFile>$(SolutionDir)$(Platform)\$(Configuration)/mod/$(ProjectName).dll</OutputFile>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<PreBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
</PreBuildEvent>
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>JSMOD_IMPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<EnablePREfast>false</EnablePREfast>
|
||||
<TreatWarningAsError>false</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<PreBuildEvent>
|
||||
<Command>
|
||||
</Command>
|
||||
</PreBuildEvent>
|
||||
<Midl>
|
||||
<TargetEnvironment>X64</TargetEnvironment>
|
||||
</Midl>
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>JSMOD_IMPORT;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<EnablePREfast>false</EnablePREfast>
|
||||
<TreatWarningAsError>false</TreatWarningAsError>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<OutputFile>$(SolutionDir)$(Platform)\$(Configuration)/mod/$(ProjectName).dll</OutputFile>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<DataExecutionPrevention>
|
||||
</DataExecutionPrevention>
|
||||
<TargetMachine>MachineX64</TargetMachine>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="mod_v8_skel.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\..\libs\win32\v8\libv8.2012.vcxproj">
|
||||
<Project>{AB03E82B-48B1-4374-B32A-A1AF83DDC6C2}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\..\libs\win32\curl\curllib.2012.vcxproj">
|
||||
<Project>{87ee9da4-de1e-4448-8324-183c98dca588}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\..\w32\Library\FreeSwitchCore.2012.vcxproj">
|
||||
<Project>{202d7a4e-760d-4d0e-afa1-d7459ced30ff}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="mod_v8.2012.vcxproj">
|
||||
<Project>{9B9D2551-D6BD-4F20-8BE5-DE30E154A064}</Project>
|
||||
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
|
@ -0,0 +1,211 @@
|
|||
/*
|
||||
* mod_v8_skel for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* 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 Original Code is mod_v8_skel for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* mod_v8_skel.cpp -- JavaScript example extension module
|
||||
*
|
||||
*/
|
||||
|
||||
/* This class is only to demonstrate how to create an external loadable extension module to mod_v8. */
|
||||
|
||||
#include "mod_v8.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace v8;
|
||||
|
||||
static const char js_class_name[] = "Skel";
|
||||
|
||||
/* Macros for easier V8 callback definitions */
|
||||
#define JS_SKEL_GET_PROPERTY_DEF(method_name) JS_GET_PROPERTY_DEF(method_name, FSSkel)
|
||||
#define JS_SKEL_SET_PROPERTY_DEF(method_name) JS_SET_PROPERTY_DEF(method_name, FSSkel)
|
||||
#define JS_SKEL_FUNCTION_DEF(method_name) JS_FUNCTION_DEF(method_name, FSSkel)
|
||||
#define JS_SKEL_GET_PROPERTY_IMPL(method_name) JS_GET_PROPERTY_IMPL(method_name, FSSkel)
|
||||
#define JS_SKEL_SET_PROPERTY_IMPL(method_name) JS_SET_PROPERTY_IMPL(method_name, FSSkel)
|
||||
#define JS_SKEL_FUNCTION_IMPL(method_name) JS_FUNCTION_IMPL(method_name, FSSkel)
|
||||
|
||||
class FSSkel : public JSBase
|
||||
{
|
||||
private:
|
||||
int x;
|
||||
string y;
|
||||
public:
|
||||
FSSkel(const v8::FunctionCallbackInfo<Value>& info);
|
||||
virtual ~FSSkel(void);
|
||||
|
||||
virtual string GetJSClassName() { return js_class_name; }
|
||||
|
||||
/* JS methods */
|
||||
|
||||
static void *Construct(const v8::FunctionCallbackInfo<Value>& info);
|
||||
|
||||
JS_SKEL_GET_PROPERTY_DEF(GetPropertyX);
|
||||
JS_SKEL_SET_PROPERTY_DEF(SetPropertyX);
|
||||
JS_SKEL_GET_PROPERTY_DEF(GetPropertyY);
|
||||
JS_SKEL_SET_PROPERTY_DEF(SetPropertyY);
|
||||
JS_SKEL_GET_PROPERTY_DEF(GetPropertyZ);
|
||||
JS_SKEL_FUNCTION_DEF(MyFunction);
|
||||
JS_SKEL_FUNCTION_DEF(MyFunction2);
|
||||
};
|
||||
|
||||
/* =============================================================================== */
|
||||
|
||||
FSSkel::FSSkel(const v8::FunctionCallbackInfo<Value>& info) : JSBase(info)
|
||||
{
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "FSSkel::FSSkel()\n");
|
||||
|
||||
x = 0;
|
||||
y = "";
|
||||
}
|
||||
|
||||
FSSkel::~FSSkel(void)
|
||||
{
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "FSSkel::~FSSkel()\n");
|
||||
}
|
||||
|
||||
void *FSSkel::Construct(const v8::FunctionCallbackInfo<Value>& info)
|
||||
{
|
||||
FSSkel *obj;
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "FSSkel::Constructor\n");
|
||||
|
||||
obj = new FSSkel(info);
|
||||
|
||||
/* Parse input variables */
|
||||
if (info.Length() > 0) {
|
||||
if (!info[0].IsEmpty() && info[0]->IsInt32()) {
|
||||
obj->x = info[0]->Int32Value();
|
||||
}
|
||||
|
||||
if (!info[1].IsEmpty() && info[1]->IsString()) {
|
||||
String::Utf8Value str(info[1]);
|
||||
if (*str) {
|
||||
obj->y = *str;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
JS_SKEL_GET_PROPERTY_IMPL(GetPropertyX)
|
||||
{
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "FSSkel::GetPropertyX (%d)\n", x);
|
||||
info.GetReturnValue().Set(x);
|
||||
}
|
||||
|
||||
JS_SKEL_SET_PROPERTY_IMPL(SetPropertyX)
|
||||
{
|
||||
x = value->Int32Value();
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "FSSkel::SetPropertyX to %d\n", x);
|
||||
}
|
||||
|
||||
JS_SKEL_GET_PROPERTY_IMPL(GetPropertyY)
|
||||
{
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "FSSkel::GetPropertyY (%s)\n", y.c_str());
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), y.c_str()));
|
||||
}
|
||||
|
||||
JS_SKEL_SET_PROPERTY_IMPL(SetPropertyY)
|
||||
{
|
||||
String::Utf8Value str(value);
|
||||
|
||||
y = js_safe_str(*str);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "FSSkel::SetPropertyY to '%s'\n", y.c_str());
|
||||
}
|
||||
|
||||
JS_SKEL_GET_PROPERTY_IMPL(GetPropertyZ)
|
||||
{
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "FSSkel::GetPropertyZ (z)\n");
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), "z"));
|
||||
}
|
||||
|
||||
JS_SKEL_FUNCTION_IMPL(MyFunction)
|
||||
{
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "FSSkel::MyFunction\n");
|
||||
}
|
||||
|
||||
JS_SKEL_FUNCTION_IMPL(MyFunction2)
|
||||
{
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "FSSkel::MyFunction2 - will twrow a JavaScript exception\n");
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Error in MyFunction2()"));
|
||||
}
|
||||
|
||||
/* Add the JS methods here */
|
||||
static const js_function_t skel_methods[] = {
|
||||
{"myFunction", FSSkel::MyFunction},
|
||||
{"myFunction2", FSSkel::MyFunction2},
|
||||
{0}
|
||||
};
|
||||
|
||||
/* Add the JS properties here */
|
||||
static const js_property_t skel_props[] = {
|
||||
{"x", FSSkel::GetPropertyX, FSSkel::SetPropertyX},
|
||||
{"y", FSSkel::GetPropertyY, FSSkel::SetPropertyY},
|
||||
{"z", FSSkel::GetPropertyZ, JSBase::DefaultSetProperty},
|
||||
{0}
|
||||
};
|
||||
|
||||
/* The main definition of the JS Class, holding the name of the class, the constructor and the moethods and properties */
|
||||
static const js_class_definition_t skel_desc = {
|
||||
js_class_name,
|
||||
FSSkel::Construct,
|
||||
skel_methods,
|
||||
skel_props
|
||||
};
|
||||
|
||||
SWITCH_BEGIN_EXTERN_C
|
||||
|
||||
/* Called from mod_v8 when user scripts [use('Skel');] inside the script. This will load the class into the current JS execution */
|
||||
static switch_status_t skel_load(const v8::FunctionCallbackInfo<Value>& info)
|
||||
{
|
||||
JSBase::Register(info.GetIsolate(), &skel_desc);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/* The module interface that mod_v8 will get when loading this module */
|
||||
static const v8_mod_interface_t skel_module_interface = {
|
||||
/*.name = */ js_class_name,
|
||||
/*.js_mod_load */ skel_load
|
||||
};
|
||||
|
||||
/* The exported method called from the module to get this module's inteface */
|
||||
SWITCH_MOD_DECLARE_NONSTD(switch_status_t) v8_mod_init(const v8_mod_interface_t **module_interface)
|
||||
{
|
||||
*module_interface = &skel_module_interface;
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
SWITCH_END_EXTERN_C
|
||||
|
||||
/* 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 noet:
|
||||
*/
|
|
@ -0,0 +1,457 @@
|
|||
/*
|
||||
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Ported from the Original Code in FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* fscoredb.cpp -- JavaScript CoreDB class
|
||||
*
|
||||
*/
|
||||
|
||||
#include "fscoredb.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace v8;
|
||||
|
||||
static const char js_class_name[] = "CoreDB";
|
||||
|
||||
FSCoreDB::~FSCoreDB(void)
|
||||
{
|
||||
_callback.Reset();
|
||||
|
||||
DoClose();
|
||||
switch_core_destroy_memory_pool(&_pool);
|
||||
}
|
||||
|
||||
string FSCoreDB::GetJSClassName()
|
||||
{
|
||||
return js_class_name;
|
||||
}
|
||||
|
||||
void FSCoreDB::Init()
|
||||
{
|
||||
_pool = NULL;
|
||||
_db = NULL;
|
||||
_stmt = NULL;
|
||||
_dbname = NULL;
|
||||
}
|
||||
|
||||
void FSCoreDB::DoClose()
|
||||
{
|
||||
if (_stmt) {
|
||||
switch_core_db_finalize(_stmt);
|
||||
_stmt = NULL;
|
||||
}
|
||||
if (_db) {
|
||||
switch_core_db_close(_db);
|
||||
_db = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void *FSCoreDB::Construct(const v8::FunctionCallbackInfo<Value>& info)
|
||||
{
|
||||
switch_memory_pool_t *pool;
|
||||
switch_core_db_t *db;
|
||||
|
||||
if (info.Length() > 0) {
|
||||
String::Utf8Value str(info[0]);
|
||||
const char *dbname = js_safe_str(*str);
|
||||
|
||||
switch_core_new_memory_pool(&pool);
|
||||
|
||||
if (!(db = switch_core_db_open_file(dbname))) {
|
||||
switch_core_destroy_memory_pool(&pool);
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Cannot Open DB!"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FSCoreDB *dbo = new FSCoreDB(info);
|
||||
dbo->_pool = pool;
|
||||
dbo->_db = db;
|
||||
dbo->_dbname = switch_core_strdup(pool, dbname);
|
||||
|
||||
return dbo;
|
||||
}
|
||||
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid arguments"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int FSCoreDB::Callback(void *pArg, int argc, char **argv, char **columnNames)
|
||||
{
|
||||
FSCoreDB *dbo = static_cast<FSCoreDB *>(pArg);
|
||||
HandleScope handle_scope(dbo->GetIsolate());
|
||||
int x = 0;
|
||||
|
||||
if (!dbo) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (dbo->_callback.IsEmpty()) {
|
||||
dbo->GetIsolate()->ThrowException(String::NewFromUtf8(dbo->GetIsolate(), "No callback specified"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
Handle<Array> arg = Array::New(dbo->GetIsolate(), argc);
|
||||
|
||||
for (x = 0; x < argc; x++) {
|
||||
if (columnNames[x] && argv[x]) {
|
||||
arg->Set(String::NewFromUtf8(dbo->GetIsolate(), columnNames[x]), String::NewFromUtf8(dbo->GetIsolate(), argv[x]));
|
||||
}
|
||||
}
|
||||
|
||||
HandleScope scope(dbo->GetIsolate());
|
||||
Handle<Function> func = Handle<Function>::New(dbo->GetIsolate(), dbo->_callback);
|
||||
Handle<Value> jsargv[1] = { arg };
|
||||
|
||||
func->Call(dbo->GetIsolate()->GetCurrentContext()->Global(), 1, jsargv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
JS_COREDB_FUNCTION_IMPL(Close)
|
||||
{
|
||||
DoClose();
|
||||
}
|
||||
|
||||
JS_COREDB_FUNCTION_IMPL(Exec)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
|
||||
info.GetReturnValue().Set(0);
|
||||
|
||||
if (!_db) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Database is not connected"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (info.Length() > 0) {
|
||||
String::Utf8Value str(info[0]);
|
||||
const char *sql = js_safe_str(*str);
|
||||
char *err = NULL;
|
||||
void *arg = NULL;
|
||||
switch_core_db_callback_func_t cb_func = NULL;
|
||||
|
||||
if (info.Length() > 1) {
|
||||
Handle<Function> func = JSBase::GetFunctionFromArg(info.GetIsolate(), info[1]);
|
||||
if (!func.IsEmpty()) {
|
||||
_callback.Reset(info.GetIsolate(), func);
|
||||
cb_func = FSCoreDB::Callback;
|
||||
arg = this;
|
||||
}
|
||||
}
|
||||
|
||||
switch_core_db_exec(_db, sql, cb_func, arg, &err);
|
||||
|
||||
/* Make sure to release the callback handle again */
|
||||
_callback.Reset();
|
||||
|
||||
if (err) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error %s\n", err);
|
||||
switch_core_db_free(err);
|
||||
info.GetReturnValue().Set(-1);
|
||||
} else {
|
||||
info.GetReturnValue().Set(switch_core_db_changes(_db));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Evaluate a prepared statement
|
||||
stepSuccessCode expected success code from switch_core_db_step()
|
||||
return true if step return expected success code, false otherwise
|
||||
*/
|
||||
void FSCoreDB::StepEx(const v8::FunctionCallbackInfo<Value>& info, int stepSuccessCode)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
|
||||
info.GetReturnValue().Set(false);
|
||||
|
||||
if (!_db) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Database is not connected"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (_stmt) {
|
||||
int running = 1;
|
||||
while (running < 5000) {
|
||||
int result = switch_core_db_step(_stmt);
|
||||
if (result == stepSuccessCode) {
|
||||
info.GetReturnValue().Set(true);
|
||||
break;
|
||||
} else if (result == SWITCH_CORE_DB_BUSY) {
|
||||
running++;
|
||||
switch_cond_next(); /* wait a bit before retrying */
|
||||
continue;
|
||||
}
|
||||
if (switch_core_db_finalize(_stmt) != SWITCH_CORE_DB_OK) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error %s\n", switch_core_db_errmsg(_db));
|
||||
}
|
||||
_stmt = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Evaluate a prepared statement, to be used with statements that return data
|
||||
return true while data is available, false when done or error
|
||||
*/
|
||||
JS_COREDB_FUNCTION_IMPL(Next)
|
||||
{
|
||||
/* return true until no more rows available */
|
||||
StepEx(info, SWITCH_CORE_DB_ROW);
|
||||
}
|
||||
|
||||
/* Evaluate a prepared statement, to be used with statements that return no data
|
||||
return true if statement has finished executing successfully, false otherwise
|
||||
*/
|
||||
JS_COREDB_FUNCTION_IMPL(Step)
|
||||
{
|
||||
/* return true when the statement has finished executing successfully */
|
||||
StepEx(info, SWITCH_CORE_DB_DONE);
|
||||
}
|
||||
|
||||
JS_COREDB_FUNCTION_IMPL(Fetch)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
int colcount;
|
||||
int x;
|
||||
|
||||
if (!_db) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Database is not connected"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_stmt) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "No query is active"));
|
||||
return;
|
||||
}
|
||||
|
||||
colcount = switch_core_db_column_count(_stmt);
|
||||
Handle<Array> arg = Array::New(info.GetIsolate(), colcount);
|
||||
|
||||
for (x = 0; x < colcount; x++) {
|
||||
const char *var = (char *) switch_core_db_column_name(_stmt, x);
|
||||
const char *val = (char *) switch_core_db_column_text(_stmt, x);
|
||||
|
||||
if (var && val) {
|
||||
arg->Set(String::NewFromUtf8(info.GetIsolate(), var), String::NewFromUtf8(info.GetIsolate(), val));
|
||||
}
|
||||
}
|
||||
|
||||
info.GetReturnValue().Set(arg);
|
||||
}
|
||||
|
||||
JS_COREDB_FUNCTION_IMPL(Prepare)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
|
||||
info.GetReturnValue().Set(false);
|
||||
|
||||
if (!_db) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Database is not connected"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (_stmt) {
|
||||
switch_core_db_finalize(_stmt);
|
||||
_stmt = NULL;
|
||||
}
|
||||
|
||||
if (info.Length() > 0) {
|
||||
String::Utf8Value str(info[0]);
|
||||
const char *sql = js_safe_str(*str);
|
||||
if (switch_core_db_prepare(_db, sql, -1, &_stmt, 0)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error %s\n", switch_core_db_errmsg(_db));
|
||||
} else {
|
||||
info.GetReturnValue().Set(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JS_COREDB_FUNCTION_IMPL(BindText)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
bool status;
|
||||
int32_t param_index = -1;
|
||||
string param_value;
|
||||
|
||||
info.GetReturnValue().Set(false);
|
||||
|
||||
if (!_db) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Database is not connected"));
|
||||
return;
|
||||
}
|
||||
|
||||
/* db_prepare() must be called first */
|
||||
if (!_stmt) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "prepare() must be called first"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (info.Length() < 2) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid arguments"));
|
||||
return;
|
||||
}
|
||||
|
||||
/* convert args */
|
||||
status = !info[0].IsEmpty() && info[0]->IsInt32() ? true : false;
|
||||
param_index = info[0]->Int32Value();
|
||||
String::Utf8Value str(info[1]);
|
||||
param_value = js_safe_str(*str);
|
||||
if ((param_index < 1) || (param_value.length() == 0)) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid arguments"));
|
||||
return;
|
||||
}
|
||||
|
||||
/* bind param */
|
||||
if (switch_core_db_bind_text(_stmt, param_index, param_value.c_str(), -1, SWITCH_CORE_DB_TRANSIENT)) {
|
||||
char *err = switch_mprintf("Database error %s", switch_core_db_errmsg(_db));
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), err));
|
||||
free(err);
|
||||
return;
|
||||
} else {
|
||||
info.GetReturnValue().Set(true);
|
||||
}
|
||||
}
|
||||
|
||||
JS_COREDB_FUNCTION_IMPL(BindInt)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
bool status;
|
||||
int32_t param_index = -1;
|
||||
int32_t param_value = -1;
|
||||
|
||||
info.GetReturnValue().Set(false);
|
||||
|
||||
if (!_db) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Database is not connected"));
|
||||
return;
|
||||
}
|
||||
|
||||
/* db_prepare() must be called first */
|
||||
if (!_stmt) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "prepare() must be called first"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (info.Length() < 2) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid arguments"));
|
||||
return;
|
||||
}
|
||||
|
||||
/* convert args */
|
||||
status = !info[0].IsEmpty() && info[0]->IsInt32() ? true : false;
|
||||
param_index = info[0]->Int32Value();
|
||||
|
||||
status = !info[1].IsEmpty() && info[1]->IsInt32() ? true : false;
|
||||
param_value = info[1]->Int32Value();
|
||||
|
||||
if (param_index < 1) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid arguments"));
|
||||
return;
|
||||
}
|
||||
|
||||
/* bind param */
|
||||
if (switch_core_db_bind_int(_stmt, param_index, param_value)) {
|
||||
char *err = switch_mprintf("Database error %s", switch_core_db_errmsg(_db));
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), err));
|
||||
free(err);
|
||||
return;
|
||||
} else {
|
||||
info.GetReturnValue().Set(true);
|
||||
}
|
||||
}
|
||||
|
||||
JS_COREDB_GET_PROPERTY_IMPL(GetProperty)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
|
||||
if (!this) {
|
||||
info.GetReturnValue().Set(false);
|
||||
return;
|
||||
}
|
||||
|
||||
String::Utf8Value str(property);
|
||||
|
||||
if (!strcmp(js_safe_str(*str), "path")) {
|
||||
if (_dbname) {
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), _dbname));
|
||||
} else {
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), ""));
|
||||
}
|
||||
} else {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Bad property"));
|
||||
}
|
||||
}
|
||||
|
||||
static const js_function_t db_methods[] = {
|
||||
{"exec", FSCoreDB::Exec},
|
||||
{"close", FSCoreDB::Close},
|
||||
{"next", FSCoreDB::Next},
|
||||
{"step", FSCoreDB::Step},
|
||||
{"fetch", FSCoreDB::Fetch},
|
||||
{"prepare", FSCoreDB::Prepare},
|
||||
{"bindText", FSCoreDB::BindText},
|
||||
{"bindInt", FSCoreDB::BindInt},
|
||||
{0}
|
||||
};
|
||||
|
||||
static const js_property_t db_props[] = {
|
||||
{"path", FSCoreDB::GetProperty, JSBase::DefaultSetProperty},
|
||||
{0}
|
||||
};
|
||||
|
||||
static const js_class_definition_t db_desc = {
|
||||
js_class_name,
|
||||
FSCoreDB::Construct,
|
||||
db_methods,
|
||||
db_props
|
||||
};
|
||||
|
||||
static switch_status_t db_load(const v8::FunctionCallbackInfo<Value>& info)
|
||||
{
|
||||
JSBase::Register(info.GetIsolate(), &db_desc);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static const v8_mod_interface_t db_module_interface = {
|
||||
/*.name = */ js_class_name,
|
||||
/*.js_mod_load */ db_load
|
||||
};
|
||||
|
||||
const v8_mod_interface_t *FSCoreDB::GetModuleInterface()
|
||||
{
|
||||
return &db_module_interface;
|
||||
}
|
||||
|
||||
/* 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 noet:
|
||||
*/
|
|
@ -0,0 +1,270 @@
|
|||
/*
|
||||
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Ported from the Original Code in FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* fscurl.cpp -- JavaScript CURL class
|
||||
*
|
||||
*/
|
||||
|
||||
#include "fscurl.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace v8;
|
||||
|
||||
static const char js_class_name[] = "CURL";
|
||||
|
||||
FSCURL::~FSCURL(void)
|
||||
{
|
||||
_function.Reset();
|
||||
_user_data.Reset();
|
||||
_ret.Reset();
|
||||
|
||||
if (_curl_handle) {
|
||||
switch_curl_easy_cleanup(_curl_handle);
|
||||
}
|
||||
}
|
||||
|
||||
void FSCURL::Init(void)
|
||||
{
|
||||
_curl_handle = NULL;
|
||||
}
|
||||
|
||||
string FSCURL::GetJSClassName()
|
||||
{
|
||||
return js_class_name;
|
||||
}
|
||||
|
||||
size_t FSCURL::FileCallback(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
{
|
||||
FSCURL *obj = static_cast<FSCURL *>(data);
|
||||
HandleScope handle_scope(obj->GetIsolate());
|
||||
register unsigned int realsize = (unsigned int) (size * nmemb);
|
||||
uint32_t argc = 0;
|
||||
Handle<Value> argv[4];
|
||||
|
||||
if (!obj) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Handle<Function> func;
|
||||
|
||||
if (!obj->_function.IsEmpty()) {
|
||||
func = Handle<Function>::New(obj->GetIsolate(), obj->_function);
|
||||
}
|
||||
|
||||
if (!func.IsEmpty()) {
|
||||
char *ret;
|
||||
if (ptr) {
|
||||
argv[argc++] = String::NewFromUtf8(obj->GetIsolate(), (char *)ptr);
|
||||
} else {
|
||||
argv[argc++] = String::NewFromUtf8(obj->GetIsolate(), "");
|
||||
}
|
||||
if (!obj->_user_data.IsEmpty()) {
|
||||
argv[argc++] = Handle<Value>::New(obj->GetIsolate(), Persistent<Value>::Cast(obj->_user_data));
|
||||
}
|
||||
|
||||
Handle<Value> res = func->Call(obj->GetIsolate()->GetCurrentContext()->Global(), argc, argv);
|
||||
|
||||
if (!res.IsEmpty()){
|
||||
obj->_ret.Reset(obj->GetIsolate(), res);
|
||||
} else {
|
||||
obj->_ret.Reset();
|
||||
}
|
||||
|
||||
String::Utf8Value str(Handle<Value>::New(obj->GetIsolate(), res));
|
||||
|
||||
if ((ret = *str)) {
|
||||
if (!strcmp(ret, "true") || !strcmp(ret, "undefined")) {
|
||||
return realsize;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return realsize;
|
||||
}
|
||||
|
||||
void *FSCURL::Construct(const v8::FunctionCallbackInfo<Value>& info)
|
||||
{
|
||||
FSCURL *obj = new FSCURL(info);
|
||||
|
||||
switch_assert(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
JS_CURL_FUNCTION_IMPL(Run)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
const char *method, *url;
|
||||
const char *url_p = NULL;
|
||||
char *durl = NULL;
|
||||
string data, cred;
|
||||
long httpRes = 0;
|
||||
struct curl_slist *headers = NULL;
|
||||
int32_t timeout = 0;
|
||||
char ct[80] = "Content-Type: application/x-www-form-urlencoded";
|
||||
|
||||
if (info.Length() < 2) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid arguments"));
|
||||
return;
|
||||
}
|
||||
|
||||
String::Utf8Value str1(info[0]);
|
||||
String::Utf8Value str2(info[1]);
|
||||
|
||||
method = js_safe_str(*str1);
|
||||
url = js_safe_str(*str2);
|
||||
|
||||
_curl_handle = switch_curl_easy_init();
|
||||
if (!strncasecmp(url, "https", 5)) {
|
||||
switch_curl_easy_setopt(_curl_handle, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
switch_curl_easy_setopt(_curl_handle, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
}
|
||||
|
||||
if (info.Length() > 2) {
|
||||
String::Utf8Value str3(info[2]);
|
||||
data = js_safe_str(*str3);
|
||||
}
|
||||
|
||||
if (info.Length() > 3) {
|
||||
Handle<Function> func = JSBase::GetFunctionFromArg(info.GetIsolate(), info[3]);
|
||||
if (!func.IsEmpty() && func->IsFunction()) {
|
||||
_function.Reset(info.GetIsolate(), func);
|
||||
}
|
||||
}
|
||||
|
||||
if (info.Length() > 4) {
|
||||
_user_data.Reset(info.GetIsolate(), Handle<Object>::Cast(info[4]));
|
||||
}
|
||||
|
||||
if (info.Length() > 5) {
|
||||
String::Utf8Value str4(info[5]);
|
||||
cred = js_safe_str(*str4);
|
||||
if (cred.length() > 0) {
|
||||
switch_curl_easy_setopt(_curl_handle, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
|
||||
switch_curl_easy_setopt(_curl_handle, CURLOPT_USERPWD, cred.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (info.Length() > 6) {
|
||||
timeout = info[6]->Int32Value();
|
||||
if (timeout > 0) {
|
||||
switch_curl_easy_setopt(_curl_handle, CURLOPT_TIMEOUT, timeout);
|
||||
}
|
||||
}
|
||||
|
||||
if (info.Length() > 7) {
|
||||
String::Utf8Value str5(info[7]);
|
||||
const char *content_type = js_safe_str(*str5);
|
||||
switch_snprintf(ct, sizeof(ct), "Content-Type: %s", content_type);
|
||||
}
|
||||
|
||||
headers = curl_slist_append(headers, ct);
|
||||
|
||||
switch_curl_easy_setopt(_curl_handle, CURLOPT_HTTPHEADER, headers);
|
||||
|
||||
url_p = url;
|
||||
|
||||
if (!strcasecmp(method, "post")) {
|
||||
switch_curl_easy_setopt(_curl_handle, CURLOPT_POST, 1);
|
||||
if (!data.c_str()) {
|
||||
data = "";
|
||||
}
|
||||
switch_curl_easy_setopt(_curl_handle, CURLOPT_POSTFIELDS, data.c_str());
|
||||
} else if (data.length() > 0) {
|
||||
durl = switch_mprintf("%s?%s", url, data.c_str());
|
||||
url_p = durl;
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Running: method: [%s] url: [%s] data: [%s] cred=[%s] cb: [%s]\n",
|
||||
method, url_p, data.c_str(), switch_str_nil(cred.c_str()), !_function.IsEmpty() ? "yes" : "no");
|
||||
|
||||
switch_curl_easy_setopt(_curl_handle, CURLOPT_URL, url_p);
|
||||
switch_curl_easy_setopt(_curl_handle, CURLOPT_NOSIGNAL, 1);
|
||||
switch_curl_easy_setopt(_curl_handle, CURLOPT_WRITEFUNCTION, FSCURL::FileCallback);
|
||||
switch_curl_easy_setopt(_curl_handle, CURLOPT_WRITEDATA, (void *) this);
|
||||
|
||||
switch_curl_easy_setopt(_curl_handle, CURLOPT_USERAGENT, "freeswitch-v8-curl/1.0");
|
||||
|
||||
switch_curl_easy_perform(_curl_handle);
|
||||
|
||||
switch_curl_easy_getinfo(_curl_handle, CURLINFO_RESPONSE_CODE, &httpRes);
|
||||
switch_curl_easy_cleanup(_curl_handle);
|
||||
curl_slist_free_all(headers);
|
||||
_curl_handle = NULL;
|
||||
_function.Reset();
|
||||
_user_data.Reset();
|
||||
switch_safe_free(durl);
|
||||
|
||||
if (!_ret.IsEmpty()) {
|
||||
info.GetReturnValue().Set(_ret);
|
||||
_ret.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
static const js_function_t curl_methods[] = {
|
||||
{"run", FSCURL::Run},
|
||||
{0}
|
||||
};
|
||||
|
||||
static const js_property_t curl_props[] = {
|
||||
{0}
|
||||
};
|
||||
|
||||
static const js_class_definition_t curl_desc = {
|
||||
js_class_name,
|
||||
FSCURL::Construct,
|
||||
curl_methods,
|
||||
curl_props
|
||||
};
|
||||
|
||||
static switch_status_t curl_load(const v8::FunctionCallbackInfo<Value>& info)
|
||||
{
|
||||
JSBase::Register(info.GetIsolate(), &curl_desc);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static const v8_mod_interface_t curl_module_interface = {
|
||||
/*.name = */ js_class_name,
|
||||
/*.js_mod_load */ curl_load
|
||||
};
|
||||
|
||||
const v8_mod_interface_t *FSCURL::GetModuleInterface()
|
||||
{
|
||||
return &curl_module_interface;
|
||||
}
|
||||
|
||||
/* 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 noet:
|
||||
*/
|
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Ported from the Original Code in FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* William King <william.king@quentustech.com>
|
||||
*
|
||||
* fsdtmf.cpp -- JavaScript DTMF class
|
||||
*
|
||||
*/
|
||||
|
||||
#include "fsdtmf.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace v8;
|
||||
|
||||
static const char js_class_name[] = "DTMF";
|
||||
|
||||
FSDTMF::~FSDTMF(void)
|
||||
{
|
||||
switch_safe_free(_dtmf);
|
||||
}
|
||||
|
||||
string FSDTMF::GetJSClassName()
|
||||
{
|
||||
return js_class_name;
|
||||
}
|
||||
|
||||
Handle<Object> FSDTMF::New(switch_dtmf_t *dtmf, const char *name, JSMain *js)
|
||||
{
|
||||
FSDTMF *obj;
|
||||
switch_dtmf_t *ddtmf;
|
||||
|
||||
if ((obj = new FSDTMF(js))) {
|
||||
if ((ddtmf = (switch_dtmf_t *)malloc(sizeof(*ddtmf)))) {
|
||||
*ddtmf = *dtmf;
|
||||
obj->_dtmf = ddtmf;
|
||||
obj->RegisterInstance(obj->GetIsolate(), js_safe_str(name), true);
|
||||
return obj->GetJavaScriptObject();
|
||||
} else {
|
||||
delete obj;
|
||||
}
|
||||
}
|
||||
|
||||
return Handle<Object>();
|
||||
}
|
||||
|
||||
void *FSDTMF::Construct(const v8::FunctionCallbackInfo<Value>& info)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
switch_dtmf_t *dtmf;
|
||||
int32_t duration = switch_core_default_dtmf_duration(0);
|
||||
const char *dtmf_char;
|
||||
|
||||
if (info.Length() <= 0) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid Args"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
String::Utf8Value str(info[0]);
|
||||
dtmf_char = *str;
|
||||
|
||||
if (info.Length() > 1) {
|
||||
duration = info[1]->Int32Value();
|
||||
if (duration <= 0) {
|
||||
duration = switch_core_default_dtmf_duration(0);
|
||||
}
|
||||
}
|
||||
|
||||
if ((dtmf = (switch_dtmf_t *)malloc(sizeof(*dtmf)))) {
|
||||
FSDTMF *obj = new FSDTMF(info);
|
||||
obj->_dtmf = dtmf;
|
||||
|
||||
if (dtmf_char && *dtmf_char) {
|
||||
obj->_dtmf->digit = *dtmf_char;
|
||||
}
|
||||
|
||||
obj->_dtmf->duration = duration;
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Memory error"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JS_DTMF_GET_PROPERTY_IMPL(GetProperty)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
FSDTMF *obj = JSBase::GetInstance<FSDTMF>(info.Holder());
|
||||
|
||||
if (!obj) {
|
||||
info.GetReturnValue().Set(false);
|
||||
return;
|
||||
}
|
||||
|
||||
String::Utf8Value str(property);
|
||||
const char *prop = js_safe_str(*str);
|
||||
|
||||
if (!strcmp(prop, "digit")) {
|
||||
char tmp[2] = { obj->_dtmf->digit, '\0' };
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), tmp));
|
||||
} else if (!strcmp(prop, "duration")) {
|
||||
info.GetReturnValue().Set(Integer::New(info.GetIsolate(), obj->_dtmf->duration));
|
||||
} else {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Bad property"));
|
||||
}
|
||||
}
|
||||
|
||||
static const js_function_t dtmf_proc[] = {
|
||||
{0}
|
||||
};
|
||||
|
||||
static const js_property_t dtmf_prop[] = {
|
||||
{"digit", FSDTMF::GetProperty, JSBase::DefaultSetProperty},
|
||||
{"duration", FSDTMF::GetProperty, JSBase::DefaultSetProperty},
|
||||
{0}
|
||||
};
|
||||
|
||||
static const js_class_definition_t dtmf_desc = {
|
||||
js_class_name,
|
||||
FSDTMF::Construct,
|
||||
dtmf_proc,
|
||||
dtmf_prop
|
||||
};
|
||||
|
||||
const js_class_definition_t *FSDTMF::GetClassDefinition()
|
||||
{
|
||||
return &dtmf_desc;
|
||||
}
|
||||
|
||||
/* 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 noet:
|
||||
*/
|
|
@ -0,0 +1,394 @@
|
|||
/*
|
||||
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Ported from the Original Code in FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* William King <william.king@quentustech.com>
|
||||
*
|
||||
* fsevent.cpp -- JavaScript Event class
|
||||
*
|
||||
*/
|
||||
|
||||
#include "fsevent.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace v8;
|
||||
|
||||
static const char js_class_name[] = "Event";
|
||||
|
||||
FSEvent::~FSEvent(void)
|
||||
{
|
||||
if (!_freed && _event) {
|
||||
switch_event_destroy(&_event);
|
||||
}
|
||||
}
|
||||
|
||||
string FSEvent::GetJSClassName()
|
||||
{
|
||||
return js_class_name;
|
||||
}
|
||||
|
||||
void FSEvent::Init()
|
||||
{
|
||||
_event = NULL;
|
||||
_freed = 0;
|
||||
}
|
||||
|
||||
void FSEvent::SetEvent(switch_event_t *event, int freed)
|
||||
{
|
||||
/* Free existing event if it exists already */
|
||||
if (!this->_freed && this->_event) {
|
||||
switch_event_destroy(&this->_event);
|
||||
}
|
||||
|
||||
this->_event = event;
|
||||
this->_freed = freed;
|
||||
}
|
||||
|
||||
switch_event_t **FSEvent::GetEvent()
|
||||
{
|
||||
return &_event;
|
||||
}
|
||||
|
||||
Handle<Object> FSEvent::New(switch_event_t *event, const char *name, JSMain *js)
|
||||
{
|
||||
FSEvent *obj;
|
||||
|
||||
if ((obj = new FSEvent(js))) {
|
||||
obj->_event = event;
|
||||
obj->_freed = 1;
|
||||
obj->RegisterInstance(js->GetIsolate(), js_safe_str(name), true);
|
||||
return obj->GetJavaScriptObject();
|
||||
}
|
||||
|
||||
return Handle<Object>();
|
||||
}
|
||||
|
||||
void *FSEvent::Construct(const v8::FunctionCallbackInfo<Value>& info)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
|
||||
if (info.Length() > 0) {
|
||||
switch_event_t *event;
|
||||
FSEvent *obj;
|
||||
switch_event_types_t etype;
|
||||
String::Utf8Value str(info[0]);
|
||||
const char *ename = js_safe_str(*str);
|
||||
|
||||
if ((obj = new FSEvent(info))) {
|
||||
if (switch_name_event(ename, &etype) != SWITCH_STATUS_SUCCESS) {
|
||||
char *err = switch_mprintf("Unknown event %s", ename);
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), err));
|
||||
free(err);
|
||||
delete obj;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (etype == SWITCH_EVENT_CUSTOM) {
|
||||
string subclass_name;
|
||||
if (info.Length() > 1) {
|
||||
String::Utf8Value str2(info[1]);
|
||||
if (*str2) {
|
||||
subclass_name = js_safe_str(*str2);
|
||||
}
|
||||
} else {
|
||||
subclass_name = "none";
|
||||
}
|
||||
|
||||
if (switch_event_create_subclass(&event, etype, subclass_name.c_str()) != SWITCH_STATUS_SUCCESS) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Failed to create sub class"));
|
||||
delete obj;
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
if (switch_event_create(&event, etype) != SWITCH_STATUS_SUCCESS) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Failed to create event"));
|
||||
delete obj;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
obj->_event = event;
|
||||
obj->_freed = 0;
|
||||
|
||||
return obj;
|
||||
}
|
||||
}
|
||||
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid Args"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JS_EVENT_FUNCTION_IMPL(AddHeader)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
|
||||
if (!_event || _freed) {
|
||||
info.GetReturnValue().Set(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (info.Length() > 1) {
|
||||
String::Utf8Value str1(info[0]);
|
||||
String::Utf8Value str2(info[1]);
|
||||
const char *hname = js_safe_str(*str1);
|
||||
const char *hval = js_safe_str(*str2);
|
||||
switch_event_add_header_string(_event, SWITCH_STACK_BOTTOM, hname, hval);
|
||||
info.GetReturnValue().Set(true);
|
||||
return;
|
||||
}
|
||||
|
||||
info.GetReturnValue().Set(false);
|
||||
}
|
||||
|
||||
JS_EVENT_FUNCTION_IMPL(GetHeader)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
|
||||
if (!_event) {
|
||||
info.GetReturnValue().Set(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (info.Length() > 0) {
|
||||
String::Utf8Value str(info[0]);
|
||||
const char *hname = js_safe_str(*str);
|
||||
const char *val = switch_event_get_header(_event, hname);
|
||||
if (!val) val = "";
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), val));
|
||||
return;
|
||||
}
|
||||
|
||||
info.GetReturnValue().Set(false);
|
||||
}
|
||||
|
||||
JS_EVENT_FUNCTION_IMPL(AddBody)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
|
||||
if (!_event || _freed) {
|
||||
info.GetReturnValue().Set(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (info.Length() > 0) {
|
||||
String::Utf8Value str(info[0]);
|
||||
const char *body = js_safe_str(*str);
|
||||
switch_event_add_body(_event, "%s", body);
|
||||
info.GetReturnValue().Set(true);
|
||||
return;
|
||||
}
|
||||
|
||||
info.GetReturnValue().Set(false);
|
||||
}
|
||||
|
||||
JS_EVENT_FUNCTION_IMPL(GetBody)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
const char *body;
|
||||
|
||||
if (!_event) {
|
||||
info.GetReturnValue().Set(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((body = switch_event_get_body(_event))) {
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), body));
|
||||
} else {
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), ""));
|
||||
}
|
||||
}
|
||||
|
||||
JS_EVENT_FUNCTION_IMPL(GetType)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
const char *event_name;
|
||||
|
||||
if (!_event) {
|
||||
info.GetReturnValue().Set(false);
|
||||
return;
|
||||
}
|
||||
|
||||
event_name = switch_event_name(_event->event_id);
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), js_safe_str(event_name)));
|
||||
}
|
||||
|
||||
JS_EVENT_FUNCTION_IMPL(Serialize)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
char *buf;
|
||||
uint8_t isxml = 0, isjson = 0;
|
||||
|
||||
if (!_event) {
|
||||
info.GetReturnValue().Set(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (info.Length() > 0) {
|
||||
String::Utf8Value str(info[0]);
|
||||
const char *arg = js_safe_str(*str);
|
||||
if (!strcasecmp(arg, "xml")) {
|
||||
isxml++;
|
||||
} else if (!strcasecmp(arg, "json")) {
|
||||
isjson++;
|
||||
}
|
||||
}
|
||||
|
||||
if (isxml) {
|
||||
switch_xml_t xml;
|
||||
char *xmlstr;
|
||||
if ((xml = switch_event_xmlize(_event, SWITCH_VA_NONE))) {
|
||||
xmlstr = switch_xml_toxml(xml, SWITCH_FALSE);
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), js_safe_str(xmlstr)));
|
||||
switch_xml_free(xml);
|
||||
switch_safe_free(xmlstr);
|
||||
} else {
|
||||
info.GetReturnValue().Set(false);
|
||||
}
|
||||
} else if (isjson) {
|
||||
if (switch_event_serialize_json(_event, &buf) == SWITCH_STATUS_SUCCESS) {
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), js_safe_str(buf)));
|
||||
switch_safe_free(buf);
|
||||
}
|
||||
} else {
|
||||
if (switch_event_serialize(_event, &buf, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) {
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), js_safe_str(buf)));
|
||||
switch_safe_free(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JS_EVENT_FUNCTION_IMPL_STATIC(Fire)
|
||||
{
|
||||
JS_CHECK_SCRIPT_STATE();
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
FSEvent *obj = JSBase::GetInstance<FSEvent>(info.Holder());
|
||||
|
||||
if (obj && obj->_event) {
|
||||
switch_event_fire(&obj->_event);
|
||||
obj->_freed = 1;
|
||||
delete obj;
|
||||
info.GetReturnValue().Set(true);
|
||||
return;
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No valid event to fire away\n");
|
||||
info.GetReturnValue().Set(false);
|
||||
}
|
||||
|
||||
JS_EVENT_FUNCTION_IMPL(ChatExecute)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
|
||||
if (_event) {
|
||||
if (info.Length() > 0) {
|
||||
String::Utf8Value str(info[0]);
|
||||
const char *app = js_safe_str(*str);
|
||||
string arg;
|
||||
|
||||
if (info.Length() > 1) {
|
||||
String::Utf8Value str2(info[1]);
|
||||
if (*str2) {
|
||||
arg = js_safe_str(*str2);
|
||||
}
|
||||
}
|
||||
|
||||
switch_core_execute_chat_app(_event, app, arg.c_str());
|
||||
|
||||
info.GetReturnValue().Set(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
info.GetReturnValue().Set(false);
|
||||
}
|
||||
|
||||
JS_EVENT_FUNCTION_IMPL_STATIC(Destroy)
|
||||
{
|
||||
JS_CHECK_SCRIPT_STATE();
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
FSEvent *obj = JSBase::GetInstance<FSEvent>(info.Holder());
|
||||
|
||||
if (obj) {
|
||||
delete obj;
|
||||
info.GetReturnValue().Set(true);
|
||||
return;
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Object already destroyed\n");
|
||||
info.GetReturnValue().Set(false);
|
||||
}
|
||||
|
||||
JS_EVENT_GET_PROPERTY_IMPL(GetProperty)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
String::Utf8Value str(property);
|
||||
|
||||
if (!strcmp(js_safe_str(*str), "ready")) {
|
||||
info.GetReturnValue().Set(_event ? true : false);
|
||||
} else {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Bad property"));
|
||||
}
|
||||
}
|
||||
|
||||
static const js_function_t event_proc[] = {
|
||||
{"addHeader", FSEvent::AddHeader},
|
||||
{"getHeader", FSEvent::GetHeader},
|
||||
{"addBody", FSEvent::AddBody},
|
||||
{"getBody", FSEvent::GetBody},
|
||||
{"getType", FSEvent::GetType},
|
||||
{"serialize", FSEvent::Serialize},
|
||||
{"fire", FSEvent::Fire},
|
||||
{"chatExecute", FSEvent::ChatExecute},
|
||||
{"destroy", FSEvent::Destroy},
|
||||
{0}
|
||||
};
|
||||
|
||||
static const js_property_t event_prop[] = {
|
||||
{"ready", FSEvent::GetProperty, JSBase::DefaultSetProperty},
|
||||
{0}
|
||||
};
|
||||
|
||||
static const js_class_definition_t event_desc = {
|
||||
js_class_name,
|
||||
FSEvent::Construct,
|
||||
event_proc,
|
||||
event_prop
|
||||
};
|
||||
|
||||
const js_class_definition_t *FSEvent::GetClassDefinition()
|
||||
{
|
||||
return &event_desc;
|
||||
}
|
||||
|
||||
/* 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 noet:
|
||||
*/
|
|
@ -0,0 +1,341 @@
|
|||
/*
|
||||
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* 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 Original Code is mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* fsfile.cpp -- JavaScript File class - implements a class similar to the Spidermonkey built-in File class.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "fsfile.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace v8;
|
||||
|
||||
static const char js_class_name[] = "File";
|
||||
|
||||
FSFile::~FSFile(void)
|
||||
{
|
||||
// Cleanup local objects
|
||||
}
|
||||
|
||||
void FSFile::Init()
|
||||
{
|
||||
// Init local objects
|
||||
}
|
||||
|
||||
string FSFile::GetJSClassName()
|
||||
{
|
||||
return js_class_name;
|
||||
}
|
||||
|
||||
void *FSFile::Construct(const v8::FunctionCallbackInfo<Value>& info)
|
||||
{
|
||||
return new FSFile(info);
|
||||
|
||||
// TODO: Implement the actual constructor code */
|
||||
}
|
||||
|
||||
JS_FILE_FUNCTION_IMPL(Close)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_FUNCTION_IMPL(CopyTo)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_FUNCTION_IMPL(Flush)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_FUNCTION_IMPL(List)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_FUNCTION_IMPL(MkDir)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_FUNCTION_IMPL(Open)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_FUNCTION_IMPL(Read)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_FUNCTION_IMPL(ReadAll)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_FUNCTION_IMPL(ReadLn)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_FUNCTION_IMPL(Remove)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_FUNCTION_IMPL(RenameTo)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_FUNCTION_IMPL(Seek)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_FUNCTION_IMPL(ToString)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_FUNCTION_IMPL(ToURL)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_FUNCTION_IMPL(Write)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_FUNCTION_IMPL(WriteAll)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_FUNCTION_IMPL(WriteLn)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_GET_PROPERTY_IMPL(GetPropCanAppend)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_GET_PROPERTY_IMPL(GetPropCanRead)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_GET_PROPERTY_IMPL(GetPropCanReplace)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_GET_PROPERTY_IMPL(GetPropCanWrite)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_GET_PROPERTY_IMPL(GetPropCreationTime)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_GET_PROPERTY_IMPL(GetPropExists)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_GET_PROPERTY_IMPL(GetPropHasAutoFlush)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_GET_PROPERTY_IMPL(GetPropHasRandomAccess)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_GET_PROPERTY_IMPL(GetPropIsDirectory)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_GET_PROPERTY_IMPL(GetPropIsFile)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_GET_PROPERTY_IMPL(GetPropIsNative)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_GET_PROPERTY_IMPL(GetPropIsOpen)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_GET_PROPERTY_IMPL(GetPropLastModified)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_GET_PROPERTY_IMPL(GetPropLength)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_GET_PROPERTY_IMPL(GetPropMode)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_GET_PROPERTY_IMPL(GetPropName)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_GET_PROPERTY_IMPL(GetPropParent)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_GET_PROPERTY_IMPL(GetPropPath)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_GET_PROPERTY_IMPL(GetPropPosition)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_SET_PROPERTY_IMPL(SetPropPosition)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_GET_PROPERTY_IMPL(GetPropSize)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
JS_FILE_GET_PROPERTY_IMPL(GetPropType)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Not yet implemented"));
|
||||
}
|
||||
|
||||
static const js_function_t file_proc[] = {
|
||||
{"close", FSFile::Close},
|
||||
{"copyTo", FSFile::CopyTo},
|
||||
{"flush", FSFile::Flush},
|
||||
{"list", FSFile::List},
|
||||
{"mkdir", FSFile::MkDir},
|
||||
{"open", FSFile::Open},
|
||||
{"read", FSFile::Read},
|
||||
{"readAll", FSFile::ReadAll},
|
||||
{"readln", FSFile::ReadLn},
|
||||
{"remove", FSFile::Remove},
|
||||
{"renameTo", FSFile::RenameTo},
|
||||
{"seek", FSFile::Seek},
|
||||
{"toString", FSFile::ToString},
|
||||
{"toURL", FSFile::ToURL},
|
||||
{"write", FSFile::Write},
|
||||
{"writeAll", FSFile::WriteAll},
|
||||
{"writeln", FSFile::WriteLn},
|
||||
{0}
|
||||
};
|
||||
|
||||
static const js_property_t file_prop[] = {
|
||||
{"canAppend", FSFile::GetPropCanAppend, JSBase::DefaultSetProperty},
|
||||
{"canRead", FSFile::GetPropCanRead, JSBase::DefaultSetProperty},
|
||||
{"canReplace", FSFile::GetPropCanReplace, JSBase::DefaultSetProperty},
|
||||
{"canWrite", FSFile::GetPropCanWrite, JSBase::DefaultSetProperty},
|
||||
{"creationTime", FSFile::GetPropCreationTime, JSBase::DefaultSetProperty},
|
||||
{"exists", FSFile::GetPropExists, JSBase::DefaultSetProperty},
|
||||
{"hasAutoFlush", FSFile::GetPropHasAutoFlush, JSBase::DefaultSetProperty},
|
||||
{"hasRandomAccess", FSFile::GetPropHasRandomAccess, JSBase::DefaultSetProperty},
|
||||
{"isDirectory", FSFile::GetPropIsDirectory, JSBase::DefaultSetProperty},
|
||||
{"isFile", FSFile::GetPropIsFile, JSBase::DefaultSetProperty},
|
||||
{"isNative", FSFile::GetPropIsNative, JSBase::DefaultSetProperty},
|
||||
{"isOpen", FSFile::GetPropIsOpen, JSBase::DefaultSetProperty},
|
||||
{"lastModified", FSFile::GetPropLastModified, JSBase::DefaultSetProperty},
|
||||
{"length", FSFile::GetPropLength, JSBase::DefaultSetProperty},
|
||||
{"mode", FSFile::GetPropMode, JSBase::DefaultSetProperty},
|
||||
{"name", FSFile::GetPropName, JSBase::DefaultSetProperty},
|
||||
{"parent", FSFile::GetPropParent, JSBase::DefaultSetProperty},
|
||||
{"path", FSFile::GetPropPath, JSBase::DefaultSetProperty},
|
||||
{"position", FSFile::GetPropPosition, FSFile::SetPropPosition},
|
||||
{"size", FSFile::GetPropSize, JSBase::DefaultSetProperty},
|
||||
{"type", FSFile::GetPropType, JSBase::DefaultSetProperty},
|
||||
{0}
|
||||
};
|
||||
|
||||
/*
|
||||
- currentDir
|
||||
- error
|
||||
- input
|
||||
- output
|
||||
- separator
|
||||
*/
|
||||
|
||||
static const js_class_definition_t file_desc = {
|
||||
js_class_name,
|
||||
FSFile::Construct,
|
||||
file_proc,
|
||||
file_prop
|
||||
};
|
||||
|
||||
static switch_status_t file_load(const v8::FunctionCallbackInfo<Value>& info)
|
||||
{
|
||||
JSBase::Register(info.GetIsolate(), &file_desc);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static const v8_mod_interface_t file_module_interface = {
|
||||
/*.name = */ js_class_name,
|
||||
/*.js_mod_load */ file_load
|
||||
};
|
||||
|
||||
const v8_mod_interface_t *FSFile::GetModuleInterface()
|
||||
{
|
||||
return &file_module_interface;
|
||||
}
|
||||
|
||||
/* 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 noet:
|
||||
*/
|
|
@ -0,0 +1,240 @@
|
|||
/*
|
||||
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Ported from the Original Code in FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* William King <william.king@quentustech.com>
|
||||
*
|
||||
* fsfileio.cpp -- JavaScript FileIO class
|
||||
*
|
||||
*/
|
||||
|
||||
#include "fsfileio.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace v8;
|
||||
|
||||
static const char js_class_name[] = "FileIO";
|
||||
|
||||
FSFileIO::~FSFileIO(void)
|
||||
{
|
||||
if (_fd) {
|
||||
switch_file_close(_fd);
|
||||
}
|
||||
switch_core_destroy_memory_pool(&_pool);
|
||||
}
|
||||
|
||||
string FSFileIO::GetJSClassName()
|
||||
{
|
||||
return js_class_name;
|
||||
}
|
||||
|
||||
void FSFileIO::Init()
|
||||
{
|
||||
_path = NULL;
|
||||
_flags = 0;
|
||||
_fd = NULL;
|
||||
_pool = NULL;
|
||||
_buf = NULL;
|
||||
_buflen = 0;
|
||||
_bufsize = 0;
|
||||
}
|
||||
|
||||
void *FSFileIO::Construct(const v8::FunctionCallbackInfo<Value>& info)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
switch_memory_pool_t *pool;
|
||||
switch_file_t *fd;
|
||||
unsigned int flags = 0;
|
||||
FSFileIO *fio;
|
||||
|
||||
if (info.Length() > 1) {
|
||||
const char *path, *flags_str;
|
||||
String::Utf8Value str1(info[0]);
|
||||
String::Utf8Value str2(info[1]);
|
||||
path = js_safe_str(*str1);
|
||||
flags_str = js_safe_str(*str2);
|
||||
|
||||
if (strchr(flags_str, 'r')) {
|
||||
flags |= SWITCH_FOPEN_READ;
|
||||
}
|
||||
|
||||
if (strchr(flags_str, 'w')) {
|
||||
flags |= SWITCH_FOPEN_WRITE;
|
||||
}
|
||||
|
||||
if (strchr(flags_str, 'c')) {
|
||||
flags |= SWITCH_FOPEN_CREATE;
|
||||
}
|
||||
|
||||
if (strchr(flags_str, 'a')) {
|
||||
flags |= SWITCH_FOPEN_APPEND;
|
||||
}
|
||||
|
||||
if (strchr(flags_str, 't')) {
|
||||
flags |= SWITCH_FOPEN_TRUNCATE;
|
||||
}
|
||||
|
||||
if (strchr(flags_str, 'b')) {
|
||||
flags |= SWITCH_FOPEN_BINARY;
|
||||
}
|
||||
|
||||
switch_core_new_memory_pool(&pool);
|
||||
|
||||
if (switch_file_open(&fd, path, flags, SWITCH_FPROT_UREAD | SWITCH_FPROT_UWRITE, pool) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_core_destroy_memory_pool(&pool);
|
||||
char *err = switch_mprintf("Cannot Open File: %s", path);
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), err));
|
||||
free(err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fio = new FSFileIO(info);
|
||||
fio->_fd = fd;
|
||||
fio->_pool = pool;
|
||||
fio->_path = switch_core_strdup(pool, path);
|
||||
fio->_flags = flags;
|
||||
|
||||
return fio;
|
||||
}
|
||||
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid Args"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JS_FILEIO_FUNCTION_IMPL(Read)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
int32_t bytes = 0;
|
||||
switch_size_t read = 0;
|
||||
|
||||
if (!(_flags & SWITCH_FOPEN_READ)) {
|
||||
info.GetReturnValue().Set(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (info.Length() > 0) {
|
||||
bytes = info[0]->Int32Value();
|
||||
}
|
||||
|
||||
if (bytes) {
|
||||
if (!_buf || _bufsize < bytes) {
|
||||
_buf = (char *)switch_core_alloc(_pool, bytes);
|
||||
_bufsize = bytes;
|
||||
}
|
||||
|
||||
read = bytes;
|
||||
switch_file_read(_fd, _buf, &read);
|
||||
_buflen = read;
|
||||
info.GetReturnValue().Set((read > 0) ? true : false);
|
||||
} else {
|
||||
info.GetReturnValue().Set(false);
|
||||
}
|
||||
}
|
||||
|
||||
JS_FILEIO_FUNCTION_IMPL(GetData)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), js_safe_str(_buf)));
|
||||
}
|
||||
|
||||
JS_FILEIO_FUNCTION_IMPL(Write)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
switch_size_t wrote = 0;
|
||||
|
||||
if (!(_flags & SWITCH_FOPEN_WRITE)) {
|
||||
info.GetReturnValue().Set(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (info.Length() > 0) {
|
||||
char *data = NULL;
|
||||
String::Utf8Value str(info[0]);
|
||||
data = *str;
|
||||
|
||||
if (data) {
|
||||
wrote = strlen(data);
|
||||
info.GetReturnValue().Set((switch_file_write(_fd, data, &wrote) == SWITCH_STATUS_SUCCESS) ? true : false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
info.GetReturnValue().Set(false);
|
||||
}
|
||||
|
||||
JS_FILEIO_GET_PROPERTY_IMPL(GetProperty)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
String::Utf8Value str(property);
|
||||
const char *prop = js_safe_str(*str);
|
||||
|
||||
if (!strcmp(prop, "path")) {
|
||||
if (_path) {
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), _path));
|
||||
} else {
|
||||
info.GetReturnValue().Set(false);
|
||||
}
|
||||
} else if (!strcmp(prop, "open")) {
|
||||
info.GetReturnValue().Set(_fd ? true : false);
|
||||
} else {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Bad property"));
|
||||
}
|
||||
}
|
||||
|
||||
static const js_function_t fileio_proc[] = {
|
||||
{"read", FSFileIO::Read},
|
||||
{"write", FSFileIO::Write},
|
||||
{"data", FSFileIO::GetData},
|
||||
{0}
|
||||
};
|
||||
|
||||
static const js_property_t fileio_prop[] = {
|
||||
{"path", FSFileIO::GetProperty, JSBase::DefaultSetProperty},
|
||||
{"open", FSFileIO::GetProperty, JSBase::DefaultSetProperty},
|
||||
{0}
|
||||
};
|
||||
|
||||
static const js_class_definition_t fileio_desc = {
|
||||
js_class_name,
|
||||
FSFileIO::Construct,
|
||||
fileio_proc,
|
||||
fileio_prop
|
||||
};
|
||||
|
||||
const js_class_definition_t *FSFileIO::GetClassDefinition()
|
||||
{
|
||||
return &fileio_desc;
|
||||
}
|
||||
|
||||
/* 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 noet:
|
||||
*/
|
|
@ -0,0 +1,776 @@
|
|||
/*
|
||||
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Ported from the Original Code in FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* William King <william.king@quentustech.com>
|
||||
*
|
||||
* fsglobal.cpp -- JavaScript Global functions
|
||||
*
|
||||
*/
|
||||
|
||||
#include "mod_v8.h"
|
||||
#include "fsglobal.hpp"
|
||||
#include "fssession.hpp"
|
||||
#include <switch_curl.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace v8;
|
||||
|
||||
class CURLCallbackData
|
||||
{
|
||||
public:
|
||||
Isolate *isolate;
|
||||
Persistent<Array> hashObject;
|
||||
int fileHandle;
|
||||
switch_size_t bufferSize;
|
||||
switch_size_t bufferDataLength;
|
||||
char *buffer;
|
||||
|
||||
CURLCallbackData() {
|
||||
isolate = NULL;
|
||||
fileHandle = 0;
|
||||
bufferSize = 0;
|
||||
bufferDataLength = 0;
|
||||
buffer = NULL;
|
||||
}
|
||||
|
||||
~CURLCallbackData() {
|
||||
hashObject.Reset();
|
||||
}
|
||||
};
|
||||
|
||||
size_t FSGlobal::HashCallback(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
{
|
||||
register size_t realsize = size * nmemb;
|
||||
char *line, lineb[2048], *nextline = NULL, *val = NULL, *p = NULL;
|
||||
CURLCallbackData *config_data = (CURLCallbackData *)data;
|
||||
|
||||
if (!config_data->hashObject.IsEmpty()) {
|
||||
switch_copy_string(lineb, (char *) ptr, sizeof(lineb));
|
||||
line = lineb;
|
||||
|
||||
HandleScope scope(config_data->isolate);
|
||||
|
||||
/* Get the array object to store data in */
|
||||
Local<Array> args = Local<Array>::New(config_data->isolate, config_data->hashObject);
|
||||
|
||||
while (line) {
|
||||
if ((nextline = strchr(line, '\n'))) {
|
||||
*nextline = '\0';
|
||||
nextline++;
|
||||
}
|
||||
|
||||
if ((val = strchr(line, '='))) {
|
||||
*val = '\0';
|
||||
val++;
|
||||
if (val[0] == '>') {
|
||||
*val = '\0';
|
||||
val++;
|
||||
}
|
||||
|
||||
for (p = line; p && *p == ' '; p++);
|
||||
line = p;
|
||||
for (p = line + strlen(line) - 1; *p == ' '; p--)
|
||||
*p = '\0';
|
||||
for (p = val; p && *p == ' '; p++);
|
||||
val = p;
|
||||
for (p = val + strlen(val) - 1; *p == ' '; p--)
|
||||
*p = '\0';
|
||||
|
||||
// Add data to hash
|
||||
args->Set(String::NewFromUtf8(config_data->isolate, line), String::NewFromUtf8(config_data->isolate, js_safe_str(val)));
|
||||
}
|
||||
|
||||
line = nextline;
|
||||
}
|
||||
}
|
||||
|
||||
return realsize;
|
||||
}
|
||||
|
||||
size_t FSGlobal::FileCallback(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
{
|
||||
register unsigned int realsize = (unsigned int) (size * nmemb);
|
||||
CURLCallbackData *config_data = (CURLCallbackData *)data;
|
||||
|
||||
if ((write(config_data->fileHandle, ptr, realsize) != (int) realsize)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to write all bytes!\n");
|
||||
}
|
||||
|
||||
return realsize;
|
||||
}
|
||||
|
||||
size_t FSGlobal::FetchUrlCallback(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
{
|
||||
register unsigned int realsize = (unsigned int) (size * nmemb);
|
||||
CURLCallbackData *config_data = (CURLCallbackData *)data;
|
||||
|
||||
/* Too much data. Do not increase buffer, but abort fetch instead. */
|
||||
if (config_data->bufferDataLength + realsize >= config_data->bufferSize) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Data do not fit in the allocated buffer\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(config_data->buffer + config_data->bufferDataLength, ptr, realsize);
|
||||
config_data->bufferDataLength += realsize;
|
||||
config_data->buffer[config_data->bufferDataLength] = 0;
|
||||
|
||||
return realsize;
|
||||
}
|
||||
|
||||
JS_GLOBAL_FUNCTION_IMPL_STATIC(FetchURLHash)
|
||||
{
|
||||
JS_CHECK_SCRIPT_STATE();
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
switch_CURL *curl_handle = NULL;
|
||||
CURLCallbackData config_data;
|
||||
int saveDepth = 0;
|
||||
|
||||
if (info.Length() > 0) {
|
||||
String::Utf8Value url(info[0]);
|
||||
|
||||
if (info.Length() > 1 && info[1]->IsString()) {
|
||||
/* Cast to string */
|
||||
Local<String> str = Local<String>::Cast(info[1]);
|
||||
|
||||
/* Try to get existing variable */
|
||||
Local<Value> obj = info.GetIsolate()->GetCurrentContext()->Global()->Get(str);
|
||||
|
||||
if (!obj.IsEmpty() && obj->IsArray()) {
|
||||
/* The existing var is an array, use it */
|
||||
config_data.hashObject.Reset(info.GetIsolate(), Local<Array>::Cast(obj));
|
||||
} else if (obj.IsEmpty() || obj->IsUndefined()) {
|
||||
/* No existing var (or an existing that is undefined), create a new one */
|
||||
Local<Array> arguments = Array::New(info.GetIsolate());
|
||||
info.GetIsolate()->GetCurrentContext()->Global()->Set(str, arguments);
|
||||
config_data.hashObject.Reset(info.GetIsolate(), arguments);
|
||||
} else {
|
||||
/* The var exists, but is wrong type - exit with error */
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Second argument is the name of an existing var of the wrong type"));
|
||||
return;
|
||||
}
|
||||
} else if (info.Length() > 1 && info[1]->IsArray()) {
|
||||
/* The var is an array, use it */
|
||||
config_data.hashObject.Reset(info.GetIsolate(), Local<Array>::Cast(info[1]));
|
||||
} else if (info.Length() > 1) {
|
||||
/* The var exists, but is wrong type - exit with error */
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Second argument is of the wrong type"));
|
||||
return;
|
||||
} else {
|
||||
/* Second argument doesn't exist, this is also ok. The hash will be returned as the result */
|
||||
Local<Array> arguments = Array::New(info.GetIsolate());
|
||||
config_data.hashObject.Reset(info.GetIsolate(), arguments);
|
||||
}
|
||||
|
||||
curl_handle = switch_curl_easy_init();
|
||||
|
||||
if (!strncasecmp(js_safe_str(*url), "https", 5)) {
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
}
|
||||
|
||||
config_data.isolate = info.GetIsolate();
|
||||
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_URL, js_safe_str(*url));
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1);
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_NOSIGNAL, 1);
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 10);
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, FSGlobal::HashCallback);
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *) &config_data);
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-v8/1.0");
|
||||
|
||||
switch_curl_easy_perform(curl_handle);
|
||||
|
||||
switch_curl_easy_cleanup(curl_handle);
|
||||
|
||||
/* Return the hash */
|
||||
info.GetReturnValue().Set(config_data.hashObject);
|
||||
} else {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid arguments"));
|
||||
}
|
||||
}
|
||||
|
||||
JS_GLOBAL_FUNCTION_IMPL_STATIC(FetchURLFile)
|
||||
{
|
||||
JS_CHECK_SCRIPT_STATE();
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
switch_CURL *curl_handle = NULL;
|
||||
CURLCallbackData config_data;
|
||||
int saveDepth = 0;
|
||||
|
||||
if (info.Length() > 1) {
|
||||
const char *url = NULL, *filename = NULL;
|
||||
String::Utf8Value str1(info[0]);
|
||||
String::Utf8Value str2(info[1]);
|
||||
url = js_safe_str(*str1);
|
||||
filename = js_safe_str(*str2);
|
||||
|
||||
curl_handle = switch_curl_easy_init();
|
||||
if (!strncasecmp(url, "https", 5)) {
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
}
|
||||
config_data.isolate = info.GetIsolate();
|
||||
|
||||
if ((config_data.fileHandle = open(filename, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR)) > -1) {
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_URL, url);
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1);
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 10);
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, FSGlobal::FileCallback);
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *) &config_data);
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-v8/1.0");
|
||||
|
||||
switch_curl_easy_perform(curl_handle);
|
||||
|
||||
switch_curl_easy_cleanup(curl_handle);
|
||||
close(config_data.fileHandle);
|
||||
info.GetReturnValue().Set(true);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to open file [%s]\n", filename);
|
||||
info.GetReturnValue().Set(false);
|
||||
}
|
||||
} else {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid arguments"));
|
||||
}
|
||||
}
|
||||
|
||||
JS_GLOBAL_FUNCTION_IMPL_STATIC(FetchURL)
|
||||
{
|
||||
JS_CHECK_SCRIPT_STATE();
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
switch_CURL *curl_handle = NULL;
|
||||
CURLCallbackData config_data;
|
||||
int32_t buffer_size = 65535;
|
||||
switch_CURLcode code = (switch_CURLcode)0;
|
||||
int saveDepth = 0;
|
||||
|
||||
if (info.Length() >= 1) {
|
||||
const char *url;
|
||||
String::Utf8Value str(info[0]);
|
||||
url = js_safe_str(*str);
|
||||
if (info.Length() > 1) {
|
||||
buffer_size = info[1]->Int32Value();
|
||||
}
|
||||
|
||||
curl_handle = switch_curl_easy_init();
|
||||
if (!strncasecmp(url, "https", 5)) {
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0);
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYHOST, 0);
|
||||
}
|
||||
|
||||
config_data.isolate = info.GetIsolate();
|
||||
config_data.bufferSize = buffer_size;
|
||||
config_data.buffer = (char *)malloc(config_data.bufferSize);
|
||||
config_data.bufferDataLength = 0;
|
||||
|
||||
if (config_data.buffer == NULL) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Failed to allocate data buffer."));
|
||||
switch_curl_easy_cleanup(curl_handle);
|
||||
return;
|
||||
}
|
||||
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_URL, url);
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_FOLLOWLOCATION, 1);
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_MAXREDIRS, 10);
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, FSGlobal::FetchUrlCallback);
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *) &config_data);
|
||||
switch_curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "freeswitch-v8/1.0");
|
||||
|
||||
code = switch_curl_easy_perform(curl_handle);
|
||||
|
||||
switch_curl_easy_cleanup(curl_handle);
|
||||
|
||||
if (code == CURLE_OK) {
|
||||
config_data.buffer[config_data.bufferDataLength] = 0;
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), js_safe_str(config_data.buffer)));
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Curl returned error %u\n", (unsigned) code);
|
||||
info.GetReturnValue().Set(false);
|
||||
}
|
||||
|
||||
free(config_data.buffer);
|
||||
} else {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid arguments"));
|
||||
}
|
||||
}
|
||||
|
||||
JS_GLOBAL_FUNCTION_IMPL_STATIC(Exit)
|
||||
{
|
||||
JS_CHECK_SCRIPT_STATE();
|
||||
|
||||
if (info.Length() > 0) {
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
String::Utf8Value str(info[0]);
|
||||
|
||||
if (*str) {
|
||||
JSMain::ExitScript(info.GetIsolate(), *str);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
JSMain::ExitScript(info.GetIsolate(), NULL);
|
||||
}
|
||||
|
||||
JS_GLOBAL_FUNCTION_IMPL_STATIC(Log)
|
||||
{
|
||||
JS_CHECK_SCRIPT_STATE();
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
char *level_str, *msg;
|
||||
switch_log_level_t level = SWITCH_LOG_DEBUG;
|
||||
char *file = NULL;
|
||||
int line = 0;
|
||||
|
||||
if (info.Length() > 0) {
|
||||
/* Get filename and line number from stack */
|
||||
file = JSMain::GetStackInfo(info.GetIsolate(), &line);
|
||||
}
|
||||
|
||||
if (info.Length() > 1) {
|
||||
String::Utf8Value str(info[0]);
|
||||
|
||||
if ((level_str = *str)) {
|
||||
level = switch_log_str2level(level_str);
|
||||
if (level == SWITCH_LOG_INVALID) {
|
||||
level = SWITCH_LOG_DEBUG;
|
||||
}
|
||||
}
|
||||
|
||||
String::Utf8Value str2(info[1]);
|
||||
if ((msg = *str2) && *msg != '\0') {
|
||||
const char lastchar = msg[strlen(msg)-1];
|
||||
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "console_log", line, NULL, level, "%s%s", msg, lastchar != '\n' ? "\n" : "");
|
||||
switch_safe_free(file);
|
||||
return;
|
||||
}
|
||||
} else if (info.Length() > 0) {
|
||||
String::Utf8Value str(info[0]);
|
||||
if ((msg = *str) && *msg != '\0') {
|
||||
const char lastchar = msg[strlen(msg)-1];
|
||||
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, "console_log", line, NULL, level, "%s%s", msg, lastchar != '\n' ? "\n" : "");
|
||||
switch_safe_free(file);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch_safe_free(file);
|
||||
}
|
||||
|
||||
JS_GLOBAL_FUNCTION_IMPL_STATIC(GlobalSet)
|
||||
{
|
||||
JS_CHECK_SCRIPT_STATE();
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
const char *var_name = NULL, *val = NULL, *val2 = NULL;
|
||||
bool tf = true;
|
||||
|
||||
if (info.Length() > 1) {
|
||||
String::Utf8Value str1(info[0]);
|
||||
String::Utf8Value str2(info[1]);
|
||||
var_name = js_safe_str(*str1);
|
||||
val = js_safe_str(*str2);
|
||||
if (info.Length() == 2) {
|
||||
switch_core_set_variable(var_name, val);
|
||||
info.GetReturnValue().Set(true);
|
||||
return;
|
||||
} else {
|
||||
String::Utf8Value str3(info[2]);
|
||||
val2 = js_safe_str(*str3);
|
||||
if (switch_core_set_var_conditional(var_name, val, val2) != SWITCH_TRUE) {
|
||||
tf = false;
|
||||
}
|
||||
info.GetReturnValue().Set(tf);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "var name not supplied!"));
|
||||
}
|
||||
|
||||
JS_GLOBAL_FUNCTION_IMPL_STATIC(GlobalGet)
|
||||
{
|
||||
JS_CHECK_SCRIPT_STATE();
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
const char *var_name = NULL;
|
||||
char *val = NULL;
|
||||
|
||||
if (info.Length() > 0) {
|
||||
String::Utf8Value str(info[0]);
|
||||
var_name = js_safe_str(*str);
|
||||
val = switch_core_get_variable_dup(var_name);
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), js_safe_str(val)));
|
||||
switch_safe_free(val);
|
||||
return;
|
||||
}
|
||||
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "var name not supplied!"));
|
||||
}
|
||||
|
||||
JS_GLOBAL_FUNCTION_IMPL_STATIC(Include)
|
||||
{
|
||||
JS_CHECK_SCRIPT_STATE();
|
||||
if (info.Length() < 1) {
|
||||
/* Bad arguments, return exception */
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid arguments"));
|
||||
} else {
|
||||
/* Try to get the current script path */
|
||||
string scriptPath = "";
|
||||
Handle<Value> val = info.GetIsolate()->GetCurrentContext()->Global()->Get(String::NewFromUtf8(info.GetIsolate(), "scriptPath"));
|
||||
if (!val.IsEmpty() && val->IsString()) {
|
||||
String::Utf8Value tmp(val);
|
||||
if (*tmp) {
|
||||
scriptPath = *tmp;
|
||||
}
|
||||
}
|
||||
|
||||
/* Loop all arguments until we find a valid file */
|
||||
for (int i = 0; i < info.Length(); i++) {
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
String::Utf8Value str(info[i]);
|
||||
char *path = NULL;
|
||||
const char *script_name = NULL;
|
||||
|
||||
if (*str) {
|
||||
if (switch_is_file_path(*str)) {
|
||||
script_name = *str;
|
||||
} else {
|
||||
/* First try to use the same path as the executing script */
|
||||
if (scriptPath.length() > 0) {
|
||||
path = switch_mprintf("%s%s%s", scriptPath.c_str(), SWITCH_PATH_SEPARATOR, *str);
|
||||
if (path && JSMain::FileExists(path)) {
|
||||
script_name = path;
|
||||
} else {
|
||||
switch_safe_free(path);
|
||||
}
|
||||
}
|
||||
|
||||
/* At last, use FS script directory */
|
||||
if (!script_name && (path = switch_mprintf("%s%s%s", SWITCH_GLOBAL_dirs.script_dir, SWITCH_PATH_SEPARATOR, *str))) {
|
||||
script_name = path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (script_name && JSMain::FileExists(script_name)) {
|
||||
string js_file = JSMain::LoadFileToString(script_name);
|
||||
|
||||
if (js_file.length() > 0) {
|
||||
Handle<String> source = String::NewFromUtf8(info.GetIsolate(), js_file.c_str());
|
||||
Handle<Script> script = Script::Compile(source, info[i]);
|
||||
info.GetReturnValue().Set(script->Run());
|
||||
switch_safe_free(path);
|
||||
return;
|
||||
}
|
||||
}
|
||||
switch_safe_free(path);
|
||||
}
|
||||
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Failed to include javascript file"));
|
||||
}
|
||||
}
|
||||
|
||||
JS_GLOBAL_FUNCTION_IMPL_STATIC(Sleep)
|
||||
{
|
||||
JS_CHECK_SCRIPT_STATE();
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
int32_t msec = 0;
|
||||
|
||||
if (info.Length() > 0) {
|
||||
msec = info[0]->Int32Value();
|
||||
}
|
||||
|
||||
if (msec) {
|
||||
switch_yield(msec * 1000);
|
||||
} else {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "No time specified"));
|
||||
}
|
||||
}
|
||||
|
||||
JS_GLOBAL_FUNCTION_IMPL_STATIC(Use)
|
||||
{
|
||||
JS_CHECK_SCRIPT_STATE();
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
|
||||
if (info.Length() > 0) {
|
||||
String::Utf8Value str(info[0]);
|
||||
char *mod_name = *str;
|
||||
|
||||
if (mod_name) {
|
||||
const v8_mod_interface_t *mp;
|
||||
|
||||
if ((mp = (v8_mod_interface_t *)switch_core_hash_find(module_manager.load_hash, mod_name))) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Loading %s\n", mod_name);
|
||||
mp->v8_mod_load(info);
|
||||
} else {
|
||||
char *err = switch_mprintf("Error loading %s", mod_name);
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), err));
|
||||
free(err);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid arguments"));
|
||||
}
|
||||
}
|
||||
|
||||
JS_GLOBAL_FUNCTION_IMPL_STATIC(ApiExecute)
|
||||
{
|
||||
JS_CHECK_SCRIPT_STATE();
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
|
||||
if (info.Length() > 0) {
|
||||
String::Utf8Value str(info[0]);
|
||||
const char *cmd = js_safe_str(*str);
|
||||
string arg;
|
||||
switch_core_session_t *session = NULL;
|
||||
switch_stream_handle_t stream = { 0 };
|
||||
|
||||
if (!strcasecmp(cmd, "jsapi")) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid API Call!\n");
|
||||
info.GetReturnValue().Set(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (info.Length() > 1) {
|
||||
String::Utf8Value str2(info[1]);
|
||||
arg = js_safe_str(*str2);
|
||||
}
|
||||
|
||||
if (info.Length() > 2) {
|
||||
if (!info[2].IsEmpty() && info[2]->IsObject()) {
|
||||
Handle<Object> session_obj = Handle<Object>::Cast(info[2]);
|
||||
FSSession *obj = JSBase::GetInstance<FSSession>(session_obj);
|
||||
if (obj) {
|
||||
session = obj->GetSession();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SWITCH_STANDARD_STREAM(stream);
|
||||
switch_api_execute(cmd, arg.c_str(), session, &stream);
|
||||
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), switch_str_nil((char *) stream.data)));
|
||||
switch_safe_free(stream.data);
|
||||
} else {
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), ""));
|
||||
}
|
||||
}
|
||||
|
||||
JS_GLOBAL_FUNCTION_IMPL_STATIC(Email)
|
||||
{
|
||||
JS_CHECK_SCRIPT_STATE();
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
string to, from, headers, body, file, convert_cmd, convert_ext;
|
||||
|
||||
if (info.Length() > 0) {
|
||||
String::Utf8Value str(info[0]);
|
||||
to = js_safe_str(*str);
|
||||
}
|
||||
|
||||
if (info.Length() > 1) {
|
||||
String::Utf8Value str(info[1]);
|
||||
from = js_safe_str(*str);
|
||||
}
|
||||
|
||||
if (info.Length() > 2) {
|
||||
String::Utf8Value str(info[2]);
|
||||
headers = js_safe_str(*str);
|
||||
}
|
||||
|
||||
if (info.Length() > 3) {
|
||||
String::Utf8Value str(info[3]);
|
||||
body = js_safe_str(*str);
|
||||
}
|
||||
|
||||
if (info.Length() > 4) {
|
||||
String::Utf8Value str(info[4]);
|
||||
file = js_safe_str(*str);
|
||||
}
|
||||
|
||||
if (info.Length() > 5) {
|
||||
String::Utf8Value str(info[5]);
|
||||
convert_cmd = js_safe_str(*str);
|
||||
}
|
||||
|
||||
if (info.Length() > 6) {
|
||||
String::Utf8Value str(info[6]);
|
||||
convert_ext = js_safe_str(*str);
|
||||
}
|
||||
|
||||
if (to.c_str() && from.c_str() && headers.c_str() && body.c_str() && switch_simple_email(to.c_str(), from.c_str(), headers.c_str(), body.c_str(), file.c_str(), convert_cmd.c_str(), convert_ext.c_str()) == SWITCH_TRUE) {
|
||||
info.GetReturnValue().Set(true);
|
||||
return;
|
||||
}
|
||||
|
||||
info.GetReturnValue().Set(false);
|
||||
}
|
||||
|
||||
JS_GLOBAL_FUNCTION_IMPL_STATIC(Bridge)
|
||||
{
|
||||
JS_CHECK_SCRIPT_STATE();
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
FSSession *jss_a = NULL, *jss_b = NULL;
|
||||
Handle<Object> obj_a;
|
||||
Handle<Object> obj_b;
|
||||
void *bp = NULL;
|
||||
switch_input_callback_function_t dtmf_func = NULL;
|
||||
FSInputCallbackState cb_state;
|
||||
|
||||
info.GetReturnValue().Set(false);
|
||||
|
||||
if (info.Length() > 1) {
|
||||
if (info[0]->IsObject()) {
|
||||
obj_a = Handle<Object>::Cast(info[0]);
|
||||
|
||||
if (!(jss_a = JSBase::GetInstance<FSSession>(obj_a))) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Cannot find session A"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (info[1]->IsObject()) {
|
||||
obj_b = Handle<Object>::Cast(info[1]);
|
||||
if (!(jss_b = JSBase::GetInstance<FSSession>(obj_b))) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Cannot find session B"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!(jss_a && jss_a->GetSession())) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "session A is not ready!"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!(jss_b && jss_b->GetSession())) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "session B is not ready!"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (info.Length() > 2) {
|
||||
Handle<Function> func = JSBase::GetFunctionFromArg(info.GetIsolate(), info[2]);
|
||||
|
||||
if (!func.IsEmpty()) {
|
||||
cb_state.function.Reset(info.GetIsolate(), func);
|
||||
|
||||
if (info.Length() > 3 && !info[3].IsEmpty()) {
|
||||
cb_state.arg.Reset(info.GetIsolate(), info[3]);
|
||||
}
|
||||
|
||||
cb_state.jss_a = jss_a;
|
||||
cb_state.jss_b = jss_b;
|
||||
cb_state.session_obj_a.Reset(info.GetIsolate(), obj_a);
|
||||
cb_state.session_obj_b.Reset(info.GetIsolate(), obj_b);
|
||||
cb_state.session_state = jss_a;
|
||||
dtmf_func = FSSession::CollectInputCallback;
|
||||
bp = &cb_state;
|
||||
}
|
||||
}
|
||||
|
||||
switch_ivr_multi_threaded_bridge(jss_a->GetSession(), jss_b->GetSession(), dtmf_func, bp, bp);
|
||||
|
||||
info.GetReturnValue().Set(true);
|
||||
}
|
||||
|
||||
/* Replace this with more robust version later */
|
||||
JS_GLOBAL_FUNCTION_IMPL_STATIC(System)
|
||||
{
|
||||
JS_CHECK_SCRIPT_STATE();
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
char *cmd;
|
||||
int result;
|
||||
info.GetReturnValue().Set(false);
|
||||
|
||||
if (info.Length() > 0) {
|
||||
String::Utf8Value str(info[0]);
|
||||
cmd = *str;
|
||||
if (cmd) {
|
||||
result = switch_system(cmd, SWITCH_TRUE);
|
||||
info.GetReturnValue().Set(Integer::New(info.GetIsolate(), result));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid arguments"));
|
||||
}
|
||||
|
||||
JS_GLOBAL_FUNCTION_IMPL_STATIC(FileDelete)
|
||||
{
|
||||
JS_CHECK_SCRIPT_STATE();
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
const char *path;
|
||||
|
||||
info.GetReturnValue().Set(false);
|
||||
|
||||
if (info.Length() > 0) {
|
||||
String::Utf8Value str(info[0]);
|
||||
path = *str;
|
||||
if (path) {
|
||||
if ((switch_file_remove(path, NULL)) == SWITCH_STATUS_SUCCESS) {
|
||||
info.GetReturnValue().Set(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid arguments"));
|
||||
}
|
||||
|
||||
static const js_function_t fs_proc[] = {
|
||||
{"console_log", FSGlobal::Log}, // Deprecated
|
||||
{"consoleLog", FSGlobal::Log},
|
||||
{"log", FSGlobal::Log}, // Short version of 'consoleLog()'
|
||||
{"getGlobalVariable", FSGlobal::GlobalGet},
|
||||
{"setGlobalVariable", FSGlobal::GlobalSet},
|
||||
{"exit", FSGlobal::Exit},
|
||||
{"include", FSGlobal::Include},
|
||||
{"require", FSGlobal::Include}, // Extra version of 'include()'
|
||||
{"bridge", FSGlobal::Bridge},
|
||||
{"email", FSGlobal::Email},
|
||||
{"apiExecute", FSGlobal::ApiExecute},
|
||||
{"use", FSGlobal::Use},
|
||||
{"msleep", FSGlobal::Sleep},
|
||||
{"fileDelete", FSGlobal::FileDelete},
|
||||
{"system", FSGlobal::System},
|
||||
{"fetchURL", FSGlobal::FetchURL}, // Deprecated
|
||||
{"fetchURLHash", FSGlobal::FetchURLHash}, // Deprecated
|
||||
{"fetchURLFile", FSGlobal::FetchURLFile}, // Deprecated
|
||||
{"fetchUrl", FSGlobal::FetchURL},
|
||||
{"fetchUrlHash", FSGlobal::FetchURLHash},
|
||||
{"fetchUrlFile", FSGlobal::FetchURLFile},
|
||||
{0}
|
||||
};
|
||||
|
||||
const js_function_t *FSGlobal::GetFunctionDefinitions()
|
||||
{
|
||||
return fs_proc;
|
||||
}
|
||||
|
||||
/* 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 noet:
|
||||
*/
|
|
@ -0,0 +1,430 @@
|
|||
/*
|
||||
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Ported from the Original Code in FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* fsodbc.cpp -- JavaScript ODBC class
|
||||
*
|
||||
*/
|
||||
|
||||
#include "fsodbc.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace v8;
|
||||
|
||||
#ifdef HAVE_ODBC
|
||||
|
||||
static const char js_class_name[] = "ODBC";
|
||||
|
||||
FSODBC::~FSODBC(void)
|
||||
{
|
||||
if (_stmt) {
|
||||
SQLFreeHandle(SQL_HANDLE_STMT, _stmt);
|
||||
}
|
||||
|
||||
if (_handle) {
|
||||
switch_odbc_handle_destroy(&_handle);
|
||||
}
|
||||
|
||||
switch_safe_free(_colbuf);
|
||||
}
|
||||
|
||||
string FSODBC::GetJSClassName()
|
||||
{
|
||||
return js_class_name;
|
||||
}
|
||||
|
||||
void FSODBC::Init()
|
||||
{
|
||||
_handle = NULL;
|
||||
_stmt = NULL;
|
||||
_colbuf = NULL;
|
||||
_cblen = 0;
|
||||
}
|
||||
|
||||
FSODBC *FSODBC::New(char *dsn, char *username, char *password, const v8::FunctionCallbackInfo<Value>& info)
|
||||
{
|
||||
FSODBC *new_obj = NULL;
|
||||
|
||||
if (!(new_obj = new FSODBC(info))) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!(new_obj->_handle = switch_odbc_handle_new(dsn, username, password))) {
|
||||
goto err;
|
||||
}
|
||||
|
||||
new_obj->_dsn = dsn;
|
||||
return new_obj;
|
||||
|
||||
err:
|
||||
if (new_obj) {
|
||||
if (new_obj->_handle) {
|
||||
switch_odbc_handle_destroy(&new_obj->_handle);
|
||||
}
|
||||
delete new_obj;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch_odbc_status_t FSODBC::Connect()
|
||||
{
|
||||
return switch_odbc_handle_connect(_handle);
|
||||
}
|
||||
|
||||
void *FSODBC::Construct(const v8::FunctionCallbackInfo<Value>& info)
|
||||
{
|
||||
FSODBC *odbc_obj = NULL;
|
||||
char *dsn, *username, *password;
|
||||
int32_t blen = 1024;
|
||||
|
||||
if (info.Length() < 3) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid parameters"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
String::Utf8Value str1(info[0]);
|
||||
String::Utf8Value str2(info[1]);
|
||||
String::Utf8Value str3(info[2]);
|
||||
dsn = *str1;
|
||||
username = *str2;
|
||||
password = *str3;
|
||||
|
||||
if (info.Length() > 3) {
|
||||
int32_t len = info[3]->Int32Value();
|
||||
|
||||
if (len > 0) {
|
||||
blen = len;
|
||||
}
|
||||
}
|
||||
|
||||
if (zstr(username)) {
|
||||
username = NULL;
|
||||
}
|
||||
|
||||
if (zstr(password)) {
|
||||
password = NULL;
|
||||
}
|
||||
|
||||
if (dsn) {
|
||||
odbc_obj = New(dsn, username, password, info);
|
||||
}
|
||||
|
||||
if (!odbc_obj) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Failed to create new ODBC instance"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(odbc_obj->_colbuf = (SQLCHAR *) malloc(blen))) {
|
||||
delete odbc_obj;
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Memory error"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
odbc_obj->_cblen = blen;
|
||||
|
||||
return odbc_obj;
|
||||
}
|
||||
|
||||
JS_ODBC_FUNCTION_IMPL(Connect)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
bool tf = true;
|
||||
|
||||
if (Connect() == SWITCH_ODBC_SUCCESS) {
|
||||
tf = true;
|
||||
} else {
|
||||
tf = false;
|
||||
}
|
||||
|
||||
info.GetReturnValue().Set(tf);
|
||||
}
|
||||
|
||||
JS_ODBC_FUNCTION_IMPL(Execute)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
const char *sql;
|
||||
bool tf = false;
|
||||
SQLHSTMT local_stmt;
|
||||
String::Utf8Value str(info[0]);
|
||||
|
||||
if (info.Length() < 1) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (switch_odbc_handle_get_state(_handle) != SWITCH_ODBC_STATE_CONNECTED) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Database is not connected!\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
sql = js_safe_str(*str);
|
||||
|
||||
if (switch_odbc_handle_exec(_handle, sql, &local_stmt, NULL) != SWITCH_ODBC_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "[ODBC] Execute failed for: %s\n", sql);
|
||||
goto done;
|
||||
}
|
||||
|
||||
SQLFreeHandle(SQL_HANDLE_STMT, local_stmt);
|
||||
|
||||
tf = true;
|
||||
|
||||
done:
|
||||
|
||||
info.GetReturnValue().Set(tf);
|
||||
}
|
||||
|
||||
JS_ODBC_FUNCTION_IMPL(Exec)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
const char *sql;
|
||||
bool tf = false;
|
||||
String::Utf8Value str(info[0]);
|
||||
|
||||
if (info.Length() < 1) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (switch_odbc_handle_get_state(_handle) != SWITCH_ODBC_STATE_CONNECTED) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Database is not connected!\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (_stmt) {
|
||||
SQLFreeHandle(SQL_HANDLE_STMT, _stmt);
|
||||
_stmt = NULL;
|
||||
}
|
||||
|
||||
sql = js_safe_str(*str);
|
||||
|
||||
if (switch_odbc_handle_exec(_handle, sql, &_stmt, NULL) != SWITCH_ODBC_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "[ODBC] query failed: %s\n", sql);
|
||||
goto done;
|
||||
}
|
||||
|
||||
tf = true;
|
||||
|
||||
done:
|
||||
|
||||
info.GetReturnValue().Set(tf);
|
||||
}
|
||||
|
||||
JS_ODBC_FUNCTION_IMPL(NumRows)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
SQLLEN row_count = 0;
|
||||
|
||||
if (switch_odbc_handle_get_state(_handle) != SWITCH_ODBC_STATE_CONNECTED) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Database is not connected!\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (_stmt) {
|
||||
SQLRowCount(_stmt, &row_count);
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
info.GetReturnValue().Set(Integer::New(info.GetIsolate(), (int32_t)row_count));
|
||||
}
|
||||
|
||||
JS_ODBC_FUNCTION_IMPL(NumCols)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
|
||||
SQLSMALLINT cols = 0;
|
||||
|
||||
if (switch_odbc_handle_get_state(_handle) != SWITCH_ODBC_STATE_CONNECTED) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Database is not connected!\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (_stmt) {
|
||||
SQLNumResultCols(_stmt, &cols);
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
info.GetReturnValue().Set(cols);
|
||||
}
|
||||
|
||||
JS_ODBC_FUNCTION_IMPL(NextRow)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
int result = 0;
|
||||
bool tf = false;
|
||||
|
||||
if (switch_odbc_handle_get_state(_handle) != SWITCH_ODBC_STATE_CONNECTED) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Database is not connected!\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (_stmt) {
|
||||
if ((result = SQLFetch(_stmt) == SQL_SUCCESS)) {
|
||||
tf = true;
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
info.GetReturnValue().Set(tf);
|
||||
}
|
||||
|
||||
JS_ODBC_FUNCTION_IMPL(GetData)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
|
||||
if (switch_odbc_handle_get_state(_handle) != SWITCH_ODBC_STATE_CONNECTED) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Database is not connected!\n");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (_stmt) {
|
||||
SQLSMALLINT nColumns = 0, x = 0;
|
||||
|
||||
if (SQLNumResultCols(_stmt, &nColumns) != SQL_SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
Handle<Array> arg = Array::New(GetIsolate(), nColumns);
|
||||
|
||||
for (x = 1; x <= nColumns; x++) {
|
||||
SQLSMALLINT NameLength, DataType, DecimalDigits, Nullable;
|
||||
SQLULEN ColumnSize;
|
||||
SQLCHAR name[1024] = "";
|
||||
SQLCHAR *data = _colbuf;
|
||||
|
||||
SQLDescribeCol(_stmt, x, name, sizeof(name), &NameLength, &DataType, &ColumnSize, &DecimalDigits, &Nullable);
|
||||
SQLGetData(_stmt, x, SQL_C_CHAR, _colbuf, _cblen, NULL);
|
||||
|
||||
if (name) {
|
||||
arg->Set(String::NewFromUtf8(GetIsolate(), (const char *)name), String::NewFromUtf8(GetIsolate(), data ? (const char *)data : ""));
|
||||
}
|
||||
}
|
||||
|
||||
info.GetReturnValue().Set(arg);
|
||||
return;
|
||||
}
|
||||
|
||||
done:
|
||||
|
||||
info.GetReturnValue().Set(false);
|
||||
}
|
||||
|
||||
JS_ODBC_FUNCTION_IMPL_STATIC(Close)
|
||||
{
|
||||
JS_CHECK_SCRIPT_STATE();
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
FSODBC *obj = JSBase::GetInstance<FSODBC>(info);
|
||||
|
||||
if (obj) {
|
||||
delete obj;
|
||||
}
|
||||
}
|
||||
|
||||
JS_ODBC_FUNCTION_IMPL(Disconnect)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
|
||||
if (switch_odbc_handle_get_state(_handle) != SWITCH_ODBC_STATE_CONNECTED) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Database is not connected!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_stmt) {
|
||||
SQLFreeHandle(SQL_HANDLE_STMT, _stmt);
|
||||
_stmt = NULL;
|
||||
}
|
||||
|
||||
switch_odbc_handle_disconnect(_handle);
|
||||
}
|
||||
|
||||
JS_ODBC_GET_PROPERTY_IMPL(GetProperty)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
|
||||
String::Utf8Value str(property);
|
||||
|
||||
if (!strcmp(js_safe_str(*str), "name")) {
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), _dsn.length() > 0 ? _dsn.c_str() : ""));
|
||||
} else {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Bad property"));
|
||||
}
|
||||
}
|
||||
|
||||
static const js_function_t odbc_methods[] = {
|
||||
{"connect", FSODBC::Connect},
|
||||
{"disconnect", FSODBC::Disconnect},
|
||||
{"exec", FSODBC::Exec}, // Deprecated
|
||||
{"query", FSODBC::Exec},
|
||||
{"execute", FSODBC::Execute},
|
||||
{"numRows", FSODBC::NumRows},
|
||||
{"numCols", FSODBC::NumCols},
|
||||
{"nextRow", FSODBC::NextRow},
|
||||
{"getData", FSODBC::GetData},
|
||||
{"close", FSODBC::Close},
|
||||
{0}
|
||||
};
|
||||
|
||||
static const js_property_t odbc_props[] = {
|
||||
{"name", FSODBC::GetProperty, JSBase::DefaultSetProperty},
|
||||
{0}
|
||||
};
|
||||
|
||||
static const js_class_definition_t odbc_desc = {
|
||||
js_class_name,
|
||||
FSODBC::Construct,
|
||||
odbc_methods,
|
||||
odbc_props
|
||||
};
|
||||
|
||||
static switch_status_t odbc_load(const v8::FunctionCallbackInfo<Value>& info)
|
||||
{
|
||||
JSBase::Register(info.GetIsolate(), &odbc_desc);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static const v8_mod_interface_t odbc_module_interface = {
|
||||
/*.name = */ js_class_name,
|
||||
/*.js_mod_load */ odbc_load
|
||||
};
|
||||
|
||||
const v8_mod_interface_t *FSODBC::GetModuleInterface()
|
||||
{
|
||||
return &odbc_module_interface;
|
||||
}
|
||||
|
||||
#endif /* HAVE_ODBC */
|
||||
|
||||
/* 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 noet:
|
||||
*/
|
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Ported from the Original Code in FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* William King <william.king@quentustech.com>
|
||||
*
|
||||
* fspcre.cpp -- JavaScript PCRE class
|
||||
*
|
||||
*/
|
||||
|
||||
#include "fspcre.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace v8;
|
||||
|
||||
static const char js_class_name[] = "PCRE";
|
||||
|
||||
FSPCRE::~FSPCRE(void)
|
||||
{
|
||||
if (!_freed && _re) {
|
||||
switch_regex_safe_free(_re);
|
||||
switch_safe_free(_str);
|
||||
}
|
||||
}
|
||||
|
||||
string FSPCRE::GetJSClassName()
|
||||
{
|
||||
return js_class_name;
|
||||
}
|
||||
|
||||
void FSPCRE::Init()
|
||||
{
|
||||
_re = NULL;
|
||||
_str = NULL;
|
||||
_proceed = 0;
|
||||
memset(&_ovector, 0, sizeof(_ovector));
|
||||
_freed = 0;
|
||||
}
|
||||
|
||||
void *FSPCRE::Construct(const v8::FunctionCallbackInfo<Value>& info)
|
||||
{
|
||||
return new FSPCRE(info);
|
||||
}
|
||||
|
||||
JS_PCRE_FUNCTION_IMPL(Compile)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
const char *string, *regex_string;
|
||||
|
||||
if (info.Length() > 1) {
|
||||
String::Utf8Value str1(info[0]);
|
||||
String::Utf8Value str2(info[1]);
|
||||
string = js_safe_str(*str1);
|
||||
regex_string = js_safe_str(*str2);
|
||||
switch_regex_safe_free(this->_re);
|
||||
switch_safe_free(this->_str);
|
||||
js_strdup(this->_str, string);
|
||||
this->_proceed = switch_regex_perform(this->_str, regex_string, &this->_re, this->_ovector,
|
||||
sizeof(this->_ovector) / sizeof(this->_ovector[0]));
|
||||
info.GetReturnValue().Set(this->_proceed ? true : false);
|
||||
} else {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid args"));
|
||||
}
|
||||
}
|
||||
|
||||
JS_PCRE_FUNCTION_IMPL(Substitute)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
const char *subst_string;
|
||||
char *substituted;
|
||||
|
||||
if (!this->_proceed) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "REGEX is not compiled or has no matches"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (info.Length() > 0) {
|
||||
uint32_t len;
|
||||
String::Utf8Value str(info[0]);
|
||||
subst_string = js_safe_str(*str);
|
||||
len = (uint32_t) (strlen(this->_str) + strlen(subst_string) + 10) * this->_proceed;
|
||||
substituted = (char *)malloc(len);
|
||||
switch_assert(substituted != NULL);
|
||||
switch_perform_substitution(this->_re, this->_proceed, subst_string, this->_str, substituted, len, this->_ovector);
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), substituted));
|
||||
free(substituted);
|
||||
} else {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid Args"));
|
||||
}
|
||||
}
|
||||
|
||||
JS_PCRE_GET_PROPERTY_IMPL(GetProperty)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
String::Utf8Value str(property);
|
||||
|
||||
if (!strcmp(js_safe_str(*str), "ready")) {
|
||||
info.GetReturnValue().Set(true);
|
||||
} else {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Bad property"));
|
||||
}
|
||||
}
|
||||
|
||||
static const js_function_t pcre_proc[] = {
|
||||
{"compile", FSPCRE::Compile},
|
||||
{"substitute", FSPCRE::Substitute},
|
||||
{0}
|
||||
};
|
||||
|
||||
static const js_property_t pcre_prop[] = {
|
||||
{"ready", FSPCRE::GetProperty, JSBase::DefaultSetProperty},
|
||||
{0}
|
||||
};
|
||||
|
||||
static const js_class_definition_t pcre_desc = {
|
||||
js_class_name,
|
||||
FSPCRE::Construct,
|
||||
pcre_proc,
|
||||
pcre_prop
|
||||
};
|
||||
|
||||
const js_class_definition_t *FSPCRE::GetClassDefinition()
|
||||
{
|
||||
return &pcre_desc;
|
||||
}
|
||||
|
||||
/* 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 noet:
|
||||
*/
|
|
@ -0,0 +1,204 @@
|
|||
/*
|
||||
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Ported from the Original Code in FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* William King <william.king@quentustech.com>
|
||||
*
|
||||
* fsrequest.cpp -- JavaScript Request class
|
||||
*
|
||||
*/
|
||||
|
||||
#include "fsrequest.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace v8;
|
||||
|
||||
static const char js_class_name[] = "Request";
|
||||
|
||||
FSRequest::~FSRequest(void)
|
||||
{
|
||||
}
|
||||
|
||||
string FSRequest::GetJSClassName()
|
||||
{
|
||||
return js_class_name;
|
||||
}
|
||||
|
||||
void FSRequest::Init()
|
||||
{
|
||||
_cmd = NULL;
|
||||
_stream = NULL;
|
||||
}
|
||||
|
||||
void FSRequest::Init(const char *cmd, switch_stream_handle_t *stream)
|
||||
{
|
||||
this->_cmd = cmd;
|
||||
this->_stream = stream;
|
||||
}
|
||||
|
||||
JS_REQUEST_FUNCTION_IMPL(Write)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
|
||||
if (info.Length() > 0) {
|
||||
String::Utf8Value str(info[0]);
|
||||
if (*str) this->_stream->write_function(this->_stream, "%s", *str);
|
||||
info.GetReturnValue().Set(true);
|
||||
return;
|
||||
}
|
||||
|
||||
info.GetReturnValue().Set(false);
|
||||
}
|
||||
|
||||
JS_REQUEST_FUNCTION_IMPL(AddHeader)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
|
||||
if (info.Length() > 1) {
|
||||
String::Utf8Value str1(info[0]);
|
||||
String::Utf8Value str2(info[1]);
|
||||
const char *hname = js_safe_str(*str1);
|
||||
const char *hval = js_safe_str(*str2);
|
||||
switch_event_add_header_string(this->_stream->param_event, SWITCH_STACK_BOTTOM, hname, hval);
|
||||
info.GetReturnValue().Set(true);
|
||||
return;
|
||||
}
|
||||
|
||||
info.GetReturnValue().Set(false);
|
||||
}
|
||||
|
||||
JS_REQUEST_FUNCTION_IMPL(GetHeader)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
|
||||
if (info.Length() > 0) {
|
||||
String::Utf8Value str(info[0]);
|
||||
const char *hname = js_safe_str(*str);
|
||||
char *val = switch_event_get_header(this->_stream->param_event, hname);
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), js_safe_str(val)));
|
||||
return;
|
||||
}
|
||||
|
||||
info.GetReturnValue().Set(false);
|
||||
}
|
||||
|
||||
JS_REQUEST_FUNCTION_IMPL(DumpEnv)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
string how = "text";
|
||||
|
||||
if (info.Length() > 0) {
|
||||
String::Utf8Value str(info[0]);
|
||||
how = js_safe_str(*str);
|
||||
}
|
||||
|
||||
if (!strcasecmp(how.c_str(), "xml")) {
|
||||
switch_xml_t xml;
|
||||
if ((xml = switch_event_xmlize(this->_stream->param_event, SWITCH_VA_NONE))) {
|
||||
char *xmlstr;
|
||||
if ((xmlstr = switch_xml_toxml(xml, SWITCH_FALSE))) {
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), xmlstr));
|
||||
switch_safe_free(xmlstr);
|
||||
switch_xml_free(xml);
|
||||
return;
|
||||
} else {
|
||||
switch_xml_free(xml);
|
||||
}
|
||||
}
|
||||
} else if (!strcasecmp(how.c_str(), "json")) {
|
||||
char *buf = NULL;
|
||||
if (switch_event_serialize_json(this->_stream->param_event, &buf) == SWITCH_STATUS_SUCCESS) {
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), js_safe_str(buf)));
|
||||
switch_safe_free(buf);
|
||||
return;
|
||||
} else {
|
||||
switch_safe_free(buf);
|
||||
}
|
||||
} else {
|
||||
char *buf = NULL;
|
||||
if (switch_event_serialize(this->_stream->param_event, &buf, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) {
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), js_safe_str(buf)));
|
||||
switch_safe_free(buf);
|
||||
return;
|
||||
} else {
|
||||
switch_safe_free(buf);
|
||||
}
|
||||
}
|
||||
|
||||
info.GetReturnValue().Set(false);
|
||||
}
|
||||
|
||||
JS_REQUEST_GET_PROPERTY_IMPL(GetProperty)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
String::Utf8Value str(property);
|
||||
|
||||
if (!strcmp(js_safe_str(*str), "command")) {
|
||||
if (this->_cmd) {
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), this->_cmd));
|
||||
} else {
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), ""));
|
||||
}
|
||||
} else {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Bad property"));
|
||||
}
|
||||
}
|
||||
|
||||
static const js_function_t request_proc[] = {
|
||||
{"write", FSRequest::Write},
|
||||
{"getHeader", FSRequest::GetHeader},
|
||||
{"addHeader", FSRequest::AddHeader},
|
||||
{"dumpENV", FSRequest::DumpEnv}, // Deprecated
|
||||
{"dumpEnv", FSRequest::DumpEnv},
|
||||
{0}
|
||||
};
|
||||
|
||||
static const js_property_t request_prop[] = {
|
||||
{"command", FSRequest::GetProperty, JSBase::DefaultSetProperty},
|
||||
{0}
|
||||
};
|
||||
|
||||
static const js_class_definition_t request_desc = {
|
||||
js_class_name,
|
||||
NULL, /* No constructor given, since it's not allowed to construct this from JS code */
|
||||
request_proc,
|
||||
request_prop
|
||||
};
|
||||
|
||||
const js_class_definition_t *FSRequest::GetClassDefinition()
|
||||
{
|
||||
return &request_desc;
|
||||
}
|
||||
|
||||
/* 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 noet:
|
||||
*/
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,337 @@
|
|||
/*
|
||||
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Ported from the Original Code in Spidermonkey Socket Module
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Jonas Gauffin <jonas.gauffin@gmail.com>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
* Jonas Gauffin <jonas.gauffin@gmail.com>
|
||||
*
|
||||
* fssocket.cpp -- JavaScript Socket class
|
||||
*
|
||||
*/
|
||||
|
||||
#include "fssocket.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace v8;
|
||||
|
||||
static const char js_class_name[] = "Socket";
|
||||
|
||||
FSSocket::~FSSocket(void)
|
||||
{
|
||||
if (_socket) {
|
||||
switch_socket_shutdown(_socket, SWITCH_SHUTDOWN_READWRITE);
|
||||
switch_socket_close(_socket);
|
||||
}
|
||||
|
||||
if (_pool) {
|
||||
switch_core_destroy_memory_pool(&_pool);
|
||||
}
|
||||
}
|
||||
|
||||
string FSSocket::GetJSClassName()
|
||||
{
|
||||
return js_class_name;
|
||||
}
|
||||
|
||||
void FSSocket::Init()
|
||||
{
|
||||
_socket = NULL;
|
||||
_pool = NULL;
|
||||
_read_buffer = NULL;
|
||||
_buffer_size = 0;
|
||||
_state = 0;
|
||||
}
|
||||
|
||||
void *FSSocket::Construct(const v8::FunctionCallbackInfo<Value>& info)
|
||||
{
|
||||
FSSocket *js_socket_obj = NULL;
|
||||
switch_memory_pool_t *pool;
|
||||
switch_socket_t *socket;
|
||||
switch_status_t ret;
|
||||
|
||||
switch_core_new_memory_pool(&pool);
|
||||
|
||||
ret = switch_socket_create(&socket, AF_INET, SOCK_STREAM, SWITCH_PROTO_TCP, pool);
|
||||
|
||||
if (ret != SWITCH_STATUS_SUCCESS) {
|
||||
switch_core_destroy_memory_pool(&pool);
|
||||
char *err = switch_mprintf("Failed to create socket, reason: %d", ret);
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), err));
|
||||
free(err);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
js_socket_obj = new FSSocket(info);
|
||||
js_socket_obj->_pool = pool;
|
||||
js_socket_obj->_socket = socket;
|
||||
|
||||
return js_socket_obj;
|
||||
}
|
||||
|
||||
JS_SOCKET_FUNCTION_IMPL(Connect)
|
||||
{
|
||||
if (info.Length() == 2) {
|
||||
String::Utf8Value str(info[0]);
|
||||
const char *host = js_safe_str(*str);
|
||||
int32_t port;
|
||||
switch_sockaddr_t *addr;
|
||||
switch_status_t ret;
|
||||
|
||||
port = info[1]->Int32Value();
|
||||
|
||||
/* Recreate socket if it has been closed */
|
||||
if (!this->_socket) {
|
||||
if ((ret = switch_socket_create(&this->_socket, AF_INET, SOCK_STREAM, SWITCH_PROTO_TCP, this->_pool)) != SWITCH_STATUS_SUCCESS) {
|
||||
char *err = switch_mprintf("Failed to create socket, reason: %d", ret);
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), err));
|
||||
free(err);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ret = switch_sockaddr_info_get(&addr, host, AF_INET, (switch_port_t) port, 0, this->_pool);
|
||||
|
||||
if (ret != SWITCH_STATUS_SUCCESS) {
|
||||
char *err = switch_mprintf("switch_sockaddr_info_get failed: %d", ret);
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), err));
|
||||
free(err);
|
||||
return;
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Connecting to: %s:%d.\n", host, port);
|
||||
ret = switch_socket_connect(this->_socket, addr);
|
||||
|
||||
if (ret != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "switch_socket_connect failed: %d.\n", ret);
|
||||
info.GetReturnValue().Set(false);
|
||||
} else
|
||||
info.GetReturnValue().Set(true);
|
||||
}
|
||||
}
|
||||
|
||||
JS_SOCKET_FUNCTION_IMPL(Send)
|
||||
{
|
||||
if (!this->_socket) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Socket is not active"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (info.Length() == 1) {
|
||||
switch_status_t ret;
|
||||
String::Utf8Value str(info[0]);
|
||||
const char *buffer = js_safe_str(*str);
|
||||
switch_size_t len = strlen(buffer);
|
||||
ret = switch_socket_send(this->_socket, buffer, &len);
|
||||
|
||||
if (ret != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "switch_socket_send failed: %d.\n", ret);
|
||||
info.GetReturnValue().Set(false);
|
||||
} else
|
||||
info.GetReturnValue().Set(true);
|
||||
} else {
|
||||
info.GetReturnValue().Set(false);
|
||||
}
|
||||
}
|
||||
|
||||
JS_SOCKET_FUNCTION_IMPL(ReadBytes)
|
||||
{
|
||||
if (!this->_socket) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Socket is not active"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (info.Length() == 1) {
|
||||
int32_t bytes_to_read;
|
||||
switch_status_t ret;
|
||||
switch_size_t len;
|
||||
|
||||
bytes_to_read = info[0]->Int32Value();
|
||||
len = (switch_size_t) bytes_to_read;
|
||||
|
||||
if (this->_buffer_size < len) {
|
||||
this->_read_buffer = (char *)switch_core_alloc(this->_pool, len + 1);
|
||||
this->_buffer_size = bytes_to_read + 1;
|
||||
}
|
||||
|
||||
ret = switch_socket_recv(this->_socket, this->_read_buffer, &len);
|
||||
if (ret != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "switch_socket_send failed: %d.\n", ret);
|
||||
info.GetReturnValue().Set(false);
|
||||
return;
|
||||
} else {
|
||||
this->_read_buffer[len] = 0;
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), js_safe_str(this->_read_buffer)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
info.GetReturnValue().Set(false);
|
||||
}
|
||||
|
||||
JS_SOCKET_FUNCTION_IMPL(Read)
|
||||
{
|
||||
string delimiter = "\n";
|
||||
switch_status_t ret = SWITCH_STATUS_FALSE;
|
||||
switch_size_t len = 1;
|
||||
switch_size_t total_length = 0;
|
||||
int can_run = TRUE;
|
||||
char tempbuf[2];
|
||||
|
||||
if (!this->_socket) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Socket is not active"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (info.Length() == 1) {
|
||||
String::Utf8Value str(info[0]);
|
||||
delimiter = js_safe_str(*str);
|
||||
}
|
||||
|
||||
if (this->_read_buffer == 0) {
|
||||
this->_read_buffer = (char *)switch_core_alloc(this->_pool, this->_buffer_size);
|
||||
}
|
||||
|
||||
while (can_run == TRUE) {
|
||||
ret = switch_socket_recv(this->_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 == this->_buffer_size - 1) {
|
||||
switch_size_t new_size = this->_buffer_size + 4196;
|
||||
char *new_buffer = (char *)switch_core_alloc(this->_pool, this->_buffer_size);
|
||||
memcpy(new_buffer, this->_read_buffer, total_length);
|
||||
this->_buffer_size = new_size;
|
||||
this->_read_buffer = new_buffer;
|
||||
}
|
||||
this->_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);
|
||||
info.GetReturnValue().Set(false);
|
||||
} else {
|
||||
this->_read_buffer[total_length] = 0;
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), js_safe_str(this->_read_buffer)));
|
||||
}
|
||||
}
|
||||
|
||||
JS_SOCKET_FUNCTION_IMPL(Close)
|
||||
{
|
||||
switch_socket_shutdown(this->_socket, SWITCH_SHUTDOWN_READWRITE);
|
||||
switch_socket_close(this->_socket);
|
||||
this->_socket = NULL;
|
||||
}
|
||||
|
||||
JS_SOCKET_GET_PROPERTY_IMPL(GetProperty)
|
||||
{
|
||||
HandleScope handle_scope(info.GetIsolate());
|
||||
String::Utf8Value str(property);
|
||||
|
||||
if (!this->_socket) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Socket is not active"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(js_safe_str(*str), "address")) {
|
||||
switch_sockaddr_t *sa = NULL;
|
||||
char tmp[30];
|
||||
|
||||
switch_socket_addr_get(&sa, SWITCH_TRUE, this->_socket);
|
||||
|
||||
if (sa && switch_get_addr(tmp, sizeof(tmp), sa) && !zstr(tmp)) {
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), tmp));
|
||||
} else {
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), "unknown"));
|
||||
}
|
||||
} else if (!strcmp(js_safe_str(*str), "port")) {
|
||||
switch_sockaddr_t *sa = NULL;
|
||||
|
||||
switch_socket_addr_get(&sa, SWITCH_TRUE, this->_socket);
|
||||
|
||||
if (sa) {
|
||||
info.GetReturnValue().Set(Integer::New(info.GetIsolate(), switch_sockaddr_get_port(sa)));
|
||||
} else {
|
||||
info.GetReturnValue().Set(Integer::New(info.GetIsolate(), 0));
|
||||
}
|
||||
} else {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Bad property"));
|
||||
}
|
||||
}
|
||||
|
||||
static const js_function_t socket_methods[] = {
|
||||
{"connect", FSSocket::Connect},
|
||||
{"close", FSSocket::Close},
|
||||
{"send", FSSocket::Send},
|
||||
{"readBytes", FSSocket::ReadBytes},
|
||||
{"read", FSSocket::Read},
|
||||
{0}
|
||||
};
|
||||
|
||||
static const js_property_t socket_props[] = {
|
||||
{"address", FSSocket::GetProperty, JSBase::DefaultSetProperty},
|
||||
{"port", FSSocket::GetProperty, JSBase::DefaultSetProperty},
|
||||
{0}
|
||||
};
|
||||
|
||||
static const js_class_definition_t socket_desc = {
|
||||
js_class_name,
|
||||
FSSocket::Construct,
|
||||
socket_methods,
|
||||
socket_props
|
||||
};
|
||||
|
||||
static switch_status_t socket_load(const v8::FunctionCallbackInfo<Value>& info)
|
||||
{
|
||||
JSBase::Register(info.GetIsolate(), &socket_desc);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static const v8_mod_interface_t socket_module_interface = {
|
||||
/*.name = */ js_class_name,
|
||||
/*.js_mod_load */ socket_load
|
||||
};
|
||||
|
||||
const v8_mod_interface_t *FSSocket::GetModuleInterface()
|
||||
{
|
||||
return &socket_module_interface;
|
||||
}
|
||||
|
||||
/* 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 noet:
|
||||
*/
|
|
@ -0,0 +1,378 @@
|
|||
/*
|
||||
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Ported from the Original Code in FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
*
|
||||
* fsteletone.cpp -- JavaScript TeleTone class
|
||||
*
|
||||
*/
|
||||
|
||||
#include "fsteletone.hpp"
|
||||
#include "fssession.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace v8;
|
||||
|
||||
static const char js_class_name[] = "TeleTone";
|
||||
|
||||
FSTeleTone::~FSTeleTone(void)
|
||||
{
|
||||
/* Release persistent JS handles */
|
||||
_function.Reset();
|
||||
_arg.Reset();
|
||||
|
||||
if (_timer) {
|
||||
switch_core_timer_destroy(_timer);
|
||||
}
|
||||
|
||||
teletone_destroy_session(&_ts);
|
||||
switch_buffer_destroy(&_audio_buffer);
|
||||
switch_core_codec_destroy(&_codec);
|
||||
|
||||
if (_pool) {
|
||||
switch_core_destroy_memory_pool(&_pool);
|
||||
}
|
||||
}
|
||||
|
||||
string FSTeleTone::GetJSClassName()
|
||||
{
|
||||
return js_class_name;
|
||||
}
|
||||
|
||||
void FSTeleTone::Init()
|
||||
{
|
||||
memset(&_ts, 0, sizeof(_ts));
|
||||
_session = NULL;
|
||||
memset(&_codec, 0, sizeof(_codec));
|
||||
_audio_buffer = NULL;
|
||||
_pool = NULL;
|
||||
_timer = NULL;
|
||||
memset(&_timer_base, 0, sizeof(_timer_base));
|
||||
flags = 0;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
TTF_DTMF = (1 << 0)
|
||||
} teletone_flag_t;
|
||||
|
||||
int FSTeleTone::Handler(teletone_generation_session_t *ts, teletone_tone_map_t *map)
|
||||
{
|
||||
FSTeleTone *tto = (FSTeleTone *)ts->user_data;
|
||||
int wrote;
|
||||
|
||||
if (!tto) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
wrote = teletone_mux_tones(ts, map);
|
||||
switch_buffer_write(tto->_audio_buffer, ts->buffer, wrote * 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void *FSTeleTone::Construct(const v8::FunctionCallbackInfo<Value>& info)
|
||||
{
|
||||
FSTeleTone *tto = NULL;
|
||||
FSSession *jss = NULL;
|
||||
switch_memory_pool_t *pool;
|
||||
string timer_name;
|
||||
switch_codec_implementation_t read_impl;
|
||||
|
||||
memset(&read_impl, 0, sizeof(read_impl));
|
||||
|
||||
if (info.Length() > 0 && info[0]->IsObject()) {
|
||||
Handle<Object> session_obj(Handle<Object>::Cast(info[0]));
|
||||
|
||||
if (!session_obj.IsEmpty()) {
|
||||
if (!(jss = JSBase::GetInstance<FSSession>(session_obj)) || !jss->GetSession()) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Cannot Find Session [1]"));
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Cannot Find Session [2]"));
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Missing Session Arg"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (info.Length() > 1) {
|
||||
String::Utf8Value str(info[1]);
|
||||
timer_name = js_safe_str(*str);
|
||||
}
|
||||
|
||||
switch_core_new_memory_pool(&pool);
|
||||
|
||||
if (!(tto = new FSTeleTone(info))) {
|
||||
switch_core_destroy_memory_pool(&pool);
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Memory Error"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch_core_session_get_read_impl(jss->GetSession(), &read_impl);
|
||||
|
||||
if (switch_core_codec_init(&tto->_codec,
|
||||
"L16",
|
||||
NULL,
|
||||
read_impl.actual_samples_per_second,
|
||||
read_impl.microseconds_per_packet / 1000,
|
||||
read_impl.number_of_channels, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, pool) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Raw Codec Activated\n");
|
||||
} else {
|
||||
switch_core_destroy_memory_pool(&pool);
|
||||
delete tto;
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Raw codec activation failed"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (timer_name.length() > 0) {
|
||||
unsigned int ms = read_impl.microseconds_per_packet / 1000;
|
||||
if (switch_core_timer_init(&tto->_timer_base,
|
||||
timer_name.c_str(), ms, (read_impl.samples_per_second / 50) * read_impl.number_of_channels, pool) == SWITCH_STATUS_SUCCESS) {
|
||||
tto->_timer = &tto->_timer_base;
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Timer INIT Success %u\n", ms);
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Timer INIT Failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
switch_buffer_create_dynamic(&tto->_audio_buffer, JS_BLOCK_SIZE, JS_BUFFER_SIZE, 0);
|
||||
tto->_pool = pool;
|
||||
tto->_session = jss->GetSession();
|
||||
teletone_init_session(&tto->_ts, 0, FSTeleTone::Handler, tto);
|
||||
|
||||
return tto;
|
||||
}
|
||||
|
||||
JS_TELETONE_FUNCTION_IMPL(AddTone)
|
||||
{
|
||||
if (info.Length() > 2) {
|
||||
int x;
|
||||
int nmax = info.Length();
|
||||
const char *map_str;
|
||||
String::Utf8Value str(info[0]);
|
||||
map_str = js_safe_str(*str);
|
||||
|
||||
if ( TELETONE_MAX_TONES < nmax ) {
|
||||
nmax = TELETONE_MAX_TONES;
|
||||
}
|
||||
|
||||
for (x = 1; x < nmax; x++) {
|
||||
String::Utf8Value fval(info[x]);
|
||||
if (*fval) {
|
||||
_ts.TONES[(int) *map_str].freqs[x - 1] = strtod(*fval, NULL);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid arguments"));
|
||||
}
|
||||
|
||||
JS_TELETONE_FUNCTION_IMPL(OnDTMF)
|
||||
{
|
||||
/* Clear callbacks first */
|
||||
_function.Reset();
|
||||
_arg.Reset();
|
||||
switch_clear_flag(this, TTF_DTMF);
|
||||
|
||||
info.GetReturnValue().Set(false);
|
||||
|
||||
if (info.Length() > 0) {
|
||||
Handle<Function> func = JSBase::GetFunctionFromArg(info.GetIsolate(), info[0]);
|
||||
|
||||
if (!func.IsEmpty()) {
|
||||
_function.Reset(info.GetIsolate(), func);
|
||||
if (info.Length() > 1 && !info[1].IsEmpty()) {
|
||||
_arg.Reset(info.GetIsolate(), info[1]);
|
||||
}
|
||||
switch_set_flag(this, TTF_DTMF);
|
||||
info.GetReturnValue().Set(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
JS_TELETONE_FUNCTION_IMPL(Generate)
|
||||
{
|
||||
int32_t loops = 0;
|
||||
|
||||
if (info.Length() > 0) {
|
||||
const char *script;
|
||||
switch_core_session_t *session;
|
||||
switch_frame_t write_frame = { 0 };
|
||||
unsigned char *fdata[1024];
|
||||
switch_frame_t *read_frame;
|
||||
switch_channel_t *channel;
|
||||
|
||||
if (info.Length() > 1) {
|
||||
if (!info[1]->IsInt32() || !(loops = info[1]->Int32Value())) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Cannot get second argument (should be int)"));
|
||||
return;
|
||||
}
|
||||
loops--;
|
||||
}
|
||||
|
||||
if (_audio_buffer) {
|
||||
switch_buffer_zero(_audio_buffer);
|
||||
}
|
||||
|
||||
_ts.debug = 1;
|
||||
_ts.debug_stream = switch_core_get_console();
|
||||
|
||||
String::Utf8Value str(info[0]);
|
||||
script = js_safe_str(*str);
|
||||
teletone_run(&_ts, script);
|
||||
|
||||
session = this->_session;
|
||||
write_frame.codec = &_codec;
|
||||
write_frame.data = fdata;
|
||||
write_frame.buflen = sizeof(fdata);
|
||||
|
||||
channel = switch_core_session_get_channel(session);
|
||||
|
||||
if (_timer) {
|
||||
switch_core_service_session(session);
|
||||
}
|
||||
|
||||
if (_audio_buffer && loops) {
|
||||
switch_buffer_set_loops(_audio_buffer, loops);
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
if (switch_test_flag(this, TTF_DTMF)) {
|
||||
char dtmf[128];
|
||||
const char *ret;
|
||||
|
||||
if (switch_channel_has_dtmf(channel)) {
|
||||
HandleScope hs(info.GetIsolate());
|
||||
uint32_t aargc = 0;
|
||||
Handle<Value> aargv[4];
|
||||
|
||||
switch_channel_dequeue_dtmf_string(channel, dtmf, sizeof(dtmf));
|
||||
aargv[aargc++] = String::NewFromUtf8(info.GetIsolate(), dtmf);
|
||||
|
||||
if (!_arg.IsEmpty()) {
|
||||
aargv[aargc++] = Handle<Value>::New(info.GetIsolate(), _arg);
|
||||
}
|
||||
|
||||
Handle<Function> func = Handle<Function>::New(info.GetIsolate(), _function);
|
||||
Handle<Value> res = func->Call(info.GetIsolate()->GetCurrentContext()->Global(), aargc, aargv);
|
||||
|
||||
String::Utf8Value tmp(res);
|
||||
ret = js_safe_str(*tmp);
|
||||
|
||||
if (strcmp(ret, "true") && strcmp(ret, "undefined")) {
|
||||
info.GetReturnValue().Set(res);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_timer) {
|
||||
if (switch_core_timer_next(_timer) != SWITCH_STATUS_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
|
||||
} else {
|
||||
switch_status_t status;
|
||||
status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
|
||||
|
||||
if (!SWITCH_READ_ACCEPTABLE(status)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ((write_frame.datalen = (uint32_t) switch_buffer_read_loop(_audio_buffer,
|
||||
fdata, write_frame.codec->implementation->decoded_bytes_per_packet)) <= 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
write_frame.samples = write_frame.datalen / 2;
|
||||
if (switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Bad Write\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_timer) {
|
||||
switch_core_thread_session_end(session);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid arguments"));
|
||||
}
|
||||
|
||||
JS_TELETONE_GET_PROPERTY_IMPL(GetNameProperty)
|
||||
{
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), "TeleTone"));
|
||||
}
|
||||
|
||||
static const js_function_t teletone_methods[] = {
|
||||
{"generate", FSTeleTone::Generate},
|
||||
{"onDTMF", FSTeleTone::OnDTMF},
|
||||
{"addTone", FSTeleTone::AddTone},
|
||||
{0}
|
||||
};
|
||||
|
||||
static const js_property_t teletone_props[] = {
|
||||
{"name", FSTeleTone::GetNameProperty, JSBase::DefaultSetProperty},
|
||||
{0}
|
||||
};
|
||||
|
||||
static const js_class_definition_t teletone_desc = {
|
||||
js_class_name,
|
||||
FSTeleTone::Construct,
|
||||
teletone_methods,
|
||||
teletone_props
|
||||
};
|
||||
|
||||
static switch_status_t teletone_load(const v8::FunctionCallbackInfo<Value>& info)
|
||||
{
|
||||
JSBase::Register(info.GetIsolate(), &teletone_desc);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static const v8_mod_interface_t teletone_module_interface = {
|
||||
/*.name = */ js_class_name,
|
||||
/*.js_mod_load */ teletone_load
|
||||
};
|
||||
|
||||
const v8_mod_interface_t *FSTeleTone::GetModuleInterface()
|
||||
{
|
||||
return &teletone_module_interface;
|
||||
}
|
||||
|
||||
/* 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 noet:
|
||||
*/
|
|
@ -0,0 +1,462 @@
|
|||
/*
|
||||
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* 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 Original Code is mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Anthony Minessale II <anthm@freeswitch.org>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* fsxml.cpp -- JavaScript XML class
|
||||
*
|
||||
*/
|
||||
|
||||
#include "fsxml.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace v8;
|
||||
|
||||
static const char js_class_name[] = "XML";
|
||||
|
||||
FSXML::~FSXML(void)
|
||||
{
|
||||
if (!_rootObject) {
|
||||
/* This is the root object */
|
||||
|
||||
/* Free the xml struct if it still exists */
|
||||
if (_xml) {
|
||||
switch_xml_free(_xml);
|
||||
}
|
||||
|
||||
/* Free all sub-objects in the hash and destroy the hash */
|
||||
DestroyHash();
|
||||
} else if (_rootObject && _xml && _rootObject->_obj_hash) {
|
||||
/* This is not the root object. Remove this object from the root oject's hash */
|
||||
_rootObject->DeleteObjectInHash(_xml);
|
||||
}
|
||||
|
||||
/* Clear JS reference to the root node */
|
||||
_rootJSObject.Reset();
|
||||
|
||||
if (_pool) {
|
||||
switch_core_destroy_memory_pool(&_pool);
|
||||
}
|
||||
}
|
||||
|
||||
string FSXML::GetJSClassName()
|
||||
{
|
||||
return js_class_name;
|
||||
}
|
||||
|
||||
void FSXML::Init()
|
||||
{
|
||||
_xml = NULL;
|
||||
_obj_hash = NULL;
|
||||
_pool = NULL;
|
||||
_rootObject = NULL;
|
||||
}
|
||||
|
||||
void FSXML::InitRootObject()
|
||||
{
|
||||
/* Create hash and pool - for the root object only */
|
||||
if (switch_core_new_memory_pool(&_pool) == SWITCH_STATUS_SUCCESS && _pool) {
|
||||
if (switch_core_hash_init(&_obj_hash, _pool) != SWITCH_STATUS_SUCCESS) {
|
||||
switch_core_destroy_memory_pool(&_pool);
|
||||
_obj_hash = NULL;
|
||||
_pool = NULL;
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to init hash\n");
|
||||
}
|
||||
} else {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create memory pool\n");
|
||||
}
|
||||
}
|
||||
|
||||
void *FSXML::Construct(const v8::FunctionCallbackInfo<Value>& info)
|
||||
{
|
||||
String::Utf8Value data(info[0]);
|
||||
switch_xml_t xml;
|
||||
|
||||
if (*data && (xml = switch_xml_parse_str_dynamic(*data, SWITCH_TRUE))) {
|
||||
FSXML *obj = new FSXML(info);
|
||||
obj->_xml = xml;
|
||||
obj->InitRootObject();
|
||||
return obj;
|
||||
}
|
||||
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Bad arguments!"));
|
||||
return NULL;
|
||||
/*
|
||||
var xml = new XML(XML_FS_CONF, fs_config_name_string);
|
||||
var xml = new XML(XML_FILE, file_name_string);
|
||||
var xml = new XML(XML_NEW, new);
|
||||
*/
|
||||
}
|
||||
|
||||
Handle<Value> FSXML::GetJSObjFromXMLObj(const switch_xml_t xml, const v8::FunctionCallbackInfo<Value>& info)
|
||||
{
|
||||
FSXML *newObj, *rootObj = NULL;
|
||||
|
||||
if (!_rootObject) {
|
||||
rootObj = this;
|
||||
} else {
|
||||
rootObj = _rootObject;
|
||||
}
|
||||
|
||||
if (!rootObj) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Could not find XML root node\n");
|
||||
return Handle<Value>();
|
||||
}
|
||||
|
||||
/* Try to find an existing object in the hash */
|
||||
if (!(newObj = rootObj->FindObjectInHash(xml))) {
|
||||
/* Create a new object if it wasn't found in the hash */
|
||||
if ((newObj = new FSXML(info))) {
|
||||
if (_rootJSObject.IsEmpty()) {
|
||||
newObj->_rootJSObject.Reset(info.GetIsolate(), info.Holder()); /* The caller is the owner */
|
||||
} else {
|
||||
newObj->_rootJSObject.Reset(info.GetIsolate(), _rootJSObject); /* The owner is stored in the persistent object */
|
||||
}
|
||||
|
||||
newObj->_xml = xml;
|
||||
newObj->_rootObject = rootObj;
|
||||
rootObj->StoreObjectInHash(xml, newObj);
|
||||
newObj->RegisterInstance(info.GetIsolate(), "", true);
|
||||
}
|
||||
}
|
||||
|
||||
if (newObj) {
|
||||
return newObj->GetJavaScriptObject();
|
||||
}
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create new object - memory error?\n");
|
||||
return Handle<Value>();
|
||||
}
|
||||
|
||||
void FSXML::StoreObjectInHash(switch_xml_t xml, FSXML *obj)
|
||||
{
|
||||
if (!_obj_hash) {
|
||||
return;
|
||||
}
|
||||
|
||||
char *key = switch_mprintf("%p", xml);
|
||||
switch_core_hash_insert(_obj_hash, key, (void *) obj);
|
||||
switch_safe_free(key);
|
||||
}
|
||||
|
||||
FSXML *FSXML::FindObjectInHash(switch_xml_t xml)
|
||||
{
|
||||
if (!_obj_hash) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *key = switch_mprintf("%p", xml);
|
||||
FSXML *obj = (FSXML *)switch_core_hash_find(_obj_hash, key);
|
||||
switch_safe_free(key);
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
void FSXML::DeleteObjectInHash(switch_xml_t xml)
|
||||
{
|
||||
if (!_obj_hash) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (FindObjectInHash(xml)) {
|
||||
char *key = switch_mprintf("%p", xml);
|
||||
switch_core_hash_delete(_obj_hash, key);
|
||||
switch_safe_free(key);
|
||||
}
|
||||
}
|
||||
|
||||
void FSXML::DestroyHash()
|
||||
{
|
||||
switch_hash_index_t *hi;
|
||||
switch_hash_t *tmp = _obj_hash;
|
||||
|
||||
_obj_hash = NULL; /* NULL this, so nothing else tries to modify the hash during cleanup */
|
||||
|
||||
if (!tmp) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* First destroy all objects in the hash */
|
||||
for (hi = switch_hash_first(NULL, tmp); hi; hi = switch_hash_next(hi)) {
|
||||
const void *var = NULL;
|
||||
void *val = NULL;
|
||||
FSXML *obj;
|
||||
|
||||
switch_hash_this(hi, &var, NULL, &val);
|
||||
|
||||
if (val) {
|
||||
obj = static_cast<FSXML *>(val);
|
||||
delete obj;
|
||||
}
|
||||
}
|
||||
|
||||
/* And finally destroy the hash itself */
|
||||
switch_core_hash_destroy(&tmp);
|
||||
}
|
||||
|
||||
JS_XML_FUNCTION_IMPL(GetChild)
|
||||
{
|
||||
if (info.Length() > 0) {
|
||||
String::Utf8Value name(info[0]);
|
||||
string attr_name, attr_value;
|
||||
switch_xml_t xml = NULL;
|
||||
|
||||
/* Check if attribute name/value was provided as well */
|
||||
if (info.Length() > 1) {
|
||||
String::Utf8Value str(info[1]);
|
||||
attr_name = js_safe_str(*str);
|
||||
|
||||
if (info.Length() > 2) {
|
||||
String::Utf8Value str2(info[2]);
|
||||
attr_value = js_safe_str(*str2);
|
||||
}
|
||||
}
|
||||
|
||||
/* Find the XML child */
|
||||
if (*name && !attr_name.length()) {
|
||||
xml = switch_xml_child(_xml, *name);
|
||||
} else if (*name) {
|
||||
xml = switch_xml_find_child(_xml, *name, attr_name.c_str(), attr_value.c_str());
|
||||
}
|
||||
|
||||
/* Return the JS object */
|
||||
if (xml) {
|
||||
Handle<Value> jsObj = GetJSObjFromXMLObj(xml, info);
|
||||
|
||||
if (jsObj.IsEmpty()) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Failed!"));
|
||||
} else {
|
||||
info.GetReturnValue().Set(jsObj);
|
||||
}
|
||||
} else {
|
||||
info.GetReturnValue().Set(Null(info.GetIsolate()));
|
||||
}
|
||||
} else {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid arguments"));
|
||||
}
|
||||
}
|
||||
|
||||
JS_XML_FUNCTION_IMPL(AddChild)
|
||||
{
|
||||
if (info.Length() > 0) {
|
||||
String::Utf8Value name(info[0]);
|
||||
switch_xml_t xml;
|
||||
int offset = 0;
|
||||
|
||||
if (info.Length() > 1) {
|
||||
offset = info[1]->Int32Value();
|
||||
}
|
||||
|
||||
/* Add new child */
|
||||
xml = switch_xml_add_child_d(_xml, js_safe_str(*name), offset);
|
||||
|
||||
/* Return the JS object */
|
||||
if (xml) {
|
||||
Handle<Value> jsObj = GetJSObjFromXMLObj(xml, info);
|
||||
|
||||
if (jsObj.IsEmpty()) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Failed!"));
|
||||
} else {
|
||||
info.GetReturnValue().Set(jsObj);
|
||||
}
|
||||
} else {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "XML error"));
|
||||
}
|
||||
} else {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid arguments"));
|
||||
}
|
||||
}
|
||||
|
||||
JS_XML_FUNCTION_IMPL(Next)
|
||||
{
|
||||
switch_xml_t xml;
|
||||
|
||||
/* Get next */
|
||||
xml = switch_xml_next(_xml);
|
||||
|
||||
/* Return the JS object */
|
||||
if (xml) {
|
||||
Handle<Value> jsObj = GetJSObjFromXMLObj(xml, info);
|
||||
|
||||
if (jsObj.IsEmpty()) {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Failed!"));
|
||||
} else {
|
||||
info.GetReturnValue().Set(jsObj);
|
||||
}
|
||||
} else {
|
||||
info.GetReturnValue().Set(Null(info.GetIsolate()));
|
||||
}
|
||||
}
|
||||
|
||||
JS_XML_FUNCTION_IMPL(GetAttribute)
|
||||
{
|
||||
if (info.Length() > 0) {
|
||||
String::Utf8Value name(info[0]);
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), switch_xml_attr_soft(_xml, js_safe_str(*name))));
|
||||
} else {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid arguments"));
|
||||
}
|
||||
}
|
||||
|
||||
JS_XML_FUNCTION_IMPL(SetAttribute)
|
||||
{
|
||||
if (info.Length() > 0) {
|
||||
String::Utf8Value name(info[0]);
|
||||
string val;
|
||||
|
||||
if (info.Length() > 1) {
|
||||
String::Utf8Value str(info[1]);
|
||||
val = js_safe_str(*str);
|
||||
}
|
||||
|
||||
if (switch_xml_set_attr_d(_xml, js_safe_str(*name), val.c_str())) {
|
||||
info.GetReturnValue().Set(true);
|
||||
} else {
|
||||
info.GetReturnValue().Set(false);
|
||||
}
|
||||
} else {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "Invalid arguments"));
|
||||
}
|
||||
}
|
||||
|
||||
JS_XML_IMPL_STATIC(Remove)
|
||||
{
|
||||
JS_CHECK_SCRIPT_STATE();
|
||||
|
||||
FSXML *obj = JSBase::GetInstance<FSXML>(info);
|
||||
|
||||
if (obj) {
|
||||
switch_xml_remove(obj->_xml);
|
||||
if (!obj->_rootObject) {
|
||||
/* If this is the root node, make sure we don't try to free _xml again */
|
||||
obj->_xml = NULL;
|
||||
}
|
||||
delete obj;
|
||||
} else {
|
||||
String::Utf8Value str(info.Holder());
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "No valid internal data available for %s when calling FSXML::Remove()\n", *str ? *str : "[unknown]");
|
||||
}
|
||||
}
|
||||
|
||||
JS_XML_FUNCTION_IMPL(Copy)
|
||||
{
|
||||
FSXML *obj;
|
||||
switch_xml_t xml;
|
||||
|
||||
/* Create a new xml object from the existing. The new object will be a new root object */
|
||||
xml = switch_xml_dup(_xml);
|
||||
|
||||
if (xml && (obj = new FSXML(info))) {
|
||||
obj->_xml = xml;
|
||||
obj->InitRootObject();
|
||||
obj->RegisterInstance(info.GetIsolate(), "", true);
|
||||
info.GetReturnValue().Set(obj->GetJavaScriptObject());
|
||||
} else {
|
||||
info.GetIsolate()->ThrowException(String::NewFromUtf8(info.GetIsolate(), "XML error"));
|
||||
}
|
||||
}
|
||||
|
||||
JS_XML_FUNCTION_IMPL(Serialize)
|
||||
{
|
||||
char *data = switch_xml_toxml(_xml, SWITCH_FALSE);
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), js_safe_str(data)));
|
||||
switch_safe_free(data);
|
||||
}
|
||||
|
||||
JS_XML_GET_PROPERTY_IMPL(GetNameProperty)
|
||||
{
|
||||
const char *data = switch_xml_name(_xml);
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), js_safe_str(data)));
|
||||
}
|
||||
|
||||
JS_XML_GET_PROPERTY_IMPL(GetDataProperty)
|
||||
{
|
||||
const char *data = switch_xml_txt(_xml);
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), js_safe_str(data)));
|
||||
}
|
||||
|
||||
JS_XML_SET_PROPERTY_IMPL(SetDataProperty)
|
||||
{
|
||||
String::Utf8Value str(value);
|
||||
switch_xml_set_txt_d(_xml, js_safe_str(*str));
|
||||
}
|
||||
|
||||
JS_XML_GET_PROPERTY_IMPL(GetXmlErrorProperty)
|
||||
{
|
||||
const char *data = switch_xml_error(_xml);
|
||||
info.GetReturnValue().Set(String::NewFromUtf8(info.GetIsolate(), js_safe_str(data)));
|
||||
}
|
||||
|
||||
static const js_function_t xml_methods[] = {
|
||||
{"getChild", FSXML::GetChild},
|
||||
{"addChild", FSXML::AddChild},
|
||||
{"next", FSXML::Next},
|
||||
{"getAttribute", FSXML::GetAttribute},
|
||||
{"setAttribute", FSXML::SetAttribute},
|
||||
{"remove", FSXML::Remove},
|
||||
{"copy", FSXML::Copy},
|
||||
{"serialize", FSXML::Serialize},
|
||||
{0}
|
||||
};
|
||||
|
||||
static const js_property_t xml_props[] = {
|
||||
{"name", FSXML::GetNameProperty, JSBase::DefaultSetProperty},
|
||||
{"data", FSXML::GetDataProperty, FSXML::SetDataProperty},
|
||||
{"xmlError", FSXML::GetXmlErrorProperty, JSBase::DefaultSetProperty},
|
||||
{0}
|
||||
};
|
||||
|
||||
static const js_class_definition_t xml_desc = {
|
||||
js_class_name,
|
||||
FSXML::Construct,
|
||||
xml_methods,
|
||||
xml_props
|
||||
};
|
||||
|
||||
static switch_status_t xml_load(const v8::FunctionCallbackInfo<Value>& info)
|
||||
{
|
||||
JSBase::Register(info.GetIsolate(), &xml_desc);
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
static const v8_mod_interface_t xml_module_interface = {
|
||||
/*.name = */ js_class_name,
|
||||
/*.js_mod_load */ xml_load
|
||||
};
|
||||
|
||||
const v8_mod_interface_t *FSXML::GetModuleInterface()
|
||||
{
|
||||
return &xml_module_interface;
|
||||
}
|
||||
|
||||
/* 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 noet:
|
||||
*/
|
|
@ -0,0 +1,269 @@
|
|||
/*
|
||||
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* 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 Original Code is mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* jsbase.cpp -- JavaScript Base class (all other JS class implementations must inherit JSBase)
|
||||
*
|
||||
*/
|
||||
|
||||
#include "javascript.hpp"
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
using namespace std;
|
||||
using namespace v8;
|
||||
|
||||
JSBase::JSBase(JSMain *owner)
|
||||
{
|
||||
persistentHandle = new Persistent<Object>();
|
||||
|
||||
autoDestroy = false;
|
||||
|
||||
if ((js = owner)) {
|
||||
js->AddActiveInstance(this);
|
||||
}
|
||||
}
|
||||
|
||||
JSBase::JSBase(const v8::FunctionCallbackInfo<Value>& info)
|
||||
{
|
||||
persistentHandle = new Persistent<Object>();
|
||||
|
||||
autoDestroy = false;
|
||||
|
||||
if ((js = JSMain::GetScriptInstanceFromIsolate(info.GetIsolate()))) {
|
||||
js->AddActiveInstance(this);
|
||||
}
|
||||
}
|
||||
|
||||
JSBase::~JSBase(void)
|
||||
{
|
||||
if (js) {
|
||||
js->RemoveActiveInstance(this);
|
||||
}
|
||||
|
||||
if (persistentHandle->IsEmpty()) {
|
||||
delete persistentHandle;
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the object is still alive inside V8, set the internal field to NULL. But only if we're actually inside a JS context */
|
||||
if (!persistentHandle->IsNearDeath() && !GetIsolate()->GetCurrentContext().IsEmpty()) {
|
||||
Handle<Object> jsObj = GetJavaScriptObject();
|
||||
jsObj->SetInternalField(0, Null(GetIsolate()));
|
||||
}
|
||||
|
||||
persistentHandle->ClearWeak();
|
||||
persistentHandle->Reset();
|
||||
|
||||
delete persistentHandle;
|
||||
}
|
||||
|
||||
Handle<Object> JSBase::GetJavaScriptObject()
|
||||
{
|
||||
/* Returns the javascript object related to this C++ instance */
|
||||
return Handle<Object>::New(GetIsolate(), *persistentHandle);
|
||||
}
|
||||
|
||||
void JSBase::AddInstance(Isolate *isolate, const Handle<Object>& handle, const Handle<External>& object, bool autoDestroy)
|
||||
{
|
||||
// Get the actual C++ class pointer
|
||||
JSBase *obj = static_cast<JSBase*>(object->Value());
|
||||
|
||||
// Sanity check
|
||||
assert(obj->persistentHandle->IsEmpty());
|
||||
|
||||
// Store the C++ instance in JavaScript engine.
|
||||
assert(handle->InternalFieldCount() > 0);
|
||||
handle->SetInternalField(0, object);
|
||||
|
||||
obj->autoDestroy = autoDestroy;
|
||||
|
||||
// Make the handle weak
|
||||
obj->persistentHandle->Reset(isolate, handle);
|
||||
obj->persistentHandle->SetWeak<JSBase>(obj, WeakCallback);
|
||||
obj->persistentHandle->MarkIndependent();
|
||||
}
|
||||
|
||||
void JSBase::WeakCallback(const WeakCallbackData<Object, JSBase>& data)
|
||||
{
|
||||
JSBase *wrap = data.GetParameter();
|
||||
Local<Object> pobj = data.GetValue();
|
||||
|
||||
if (wrap->autoDestroy) {
|
||||
HandleScope scope(data.GetIsolate());
|
||||
assert(pobj == *wrap->persistentHandle);
|
||||
delete wrap;
|
||||
} else if (!wrap->persistentHandle->IsEmpty()) {
|
||||
wrap->persistentHandle->ClearWeak();
|
||||
wrap->persistentHandle->Reset();
|
||||
}
|
||||
}
|
||||
|
||||
void JSBase::CreateInstance(const v8::FunctionCallbackInfo<Value>& args)
|
||||
{
|
||||
Handle<External> external;
|
||||
bool autoDestroy = true;
|
||||
bool constructorFailed = false;
|
||||
|
||||
if (!args.IsConstructCall()) {
|
||||
args.GetIsolate()->ThrowException(String::NewFromUtf8(args.GetIsolate(), "Seems you forgot the 'new' operator."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (args[0]->IsExternal()) {
|
||||
// The argument is an existing object, just use that.
|
||||
external = Handle<External>::Cast(args[0]);
|
||||
autoDestroy = args[1]->BooleanValue();
|
||||
} else {
|
||||
// Create a new C++ instance
|
||||
Handle<External> ex = Handle<External>::Cast(args.Callee()->GetHiddenValue(String::NewFromUtf8(args.GetIsolate(), "constructor_method")));
|
||||
|
||||
if (ex->Value()) {
|
||||
ConstructorCallback cb = (ConstructorCallback)ex->Value();
|
||||
void *p = cb(args);
|
||||
|
||||
if (p) {
|
||||
external = External::New(args.GetIsolate(), p);
|
||||
} else {
|
||||
constructorFailed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add this instance to Javascript.
|
||||
if (!external.IsEmpty()) {
|
||||
AddInstance(args.GetIsolate(), args.This(), external, autoDestroy);
|
||||
|
||||
// Return the newly created object
|
||||
args.GetReturnValue().Set(args.This());
|
||||
} else if (!constructorFailed) {
|
||||
args.GetIsolate()->ThrowException(String::NewFromUtf8(args.GetIsolate(), "This class cannot be created from javascript."));
|
||||
} else {
|
||||
/* Use whatever was set from the constructor */
|
||||
}
|
||||
}
|
||||
|
||||
void JSBase::Register(Isolate *isolate, const js_class_definition_t *desc)
|
||||
{
|
||||
// Get the context's global scope (that's where we'll put the constructor)
|
||||
Handle<Object> global = isolate->GetCurrentContext()->Global();
|
||||
|
||||
// Create function template for our constructor it will call the JSBase::createInstance method
|
||||
Handle<FunctionTemplate> function = FunctionTemplate::New(isolate, JSBase::CreateInstance);
|
||||
function->SetClassName(String::NewFromUtf8(isolate, desc->name));
|
||||
|
||||
// Make room for saving the C++ object reference somewhere
|
||||
function->InstanceTemplate()->SetInternalFieldCount(1);
|
||||
|
||||
// Add methods to the object
|
||||
for (int i = 0;; i++) {
|
||||
if (!desc->functions[i].func) break;
|
||||
function->InstanceTemplate()->Set(String::NewFromUtf8(isolate, desc->functions[i].name), FunctionTemplate::New(isolate, desc->functions[i].func));
|
||||
}
|
||||
|
||||
// Add properties to the object
|
||||
for (int i = 0;; i++) {
|
||||
if (!desc->properties[i].get) break;
|
||||
function->InstanceTemplate()->SetAccessor(String::NewFromUtf8(isolate, desc->properties[i].name), desc->properties[i].get, desc->properties[i].set);
|
||||
}
|
||||
|
||||
function->GetFunction()->SetHiddenValue(String::NewFromUtf8(isolate, "constructor_method"), External::New(isolate, (void *)desc->constructor));
|
||||
|
||||
// Set the function in the global scope, to make it available
|
||||
global->Set(v8::String::NewFromUtf8(isolate, desc->name), function->GetFunction());
|
||||
}
|
||||
|
||||
void JSBase::RegisterInstance(Isolate *isolate, string name, bool autoDestroy)
|
||||
{
|
||||
// Get the context's global scope (that's where we'll put the constructor)
|
||||
Handle<Object> global = isolate->GetCurrentContext()->Global();
|
||||
|
||||
Local<Function> func = Local<Function>::Cast(global->Get(v8::String::NewFromUtf8(isolate, this->GetJSClassName().c_str())));
|
||||
|
||||
// Add the C++ instance as an argument, so it won't try to create another one.
|
||||
Handle<Value> args[] = { External::New(isolate, this), Boolean::New(isolate, autoDestroy) };
|
||||
Handle<Object> newObj = func->NewInstance(2, args);
|
||||
|
||||
// Add the instance to JavaScript.
|
||||
if (name.size() > 0) {
|
||||
global->Set(String::NewFromUtf8(isolate, name.c_str()), newObj);
|
||||
}
|
||||
}
|
||||
|
||||
JSMain *JSBase::GetOwner()
|
||||
{
|
||||
return js;
|
||||
}
|
||||
|
||||
Isolate *JSBase::GetIsolate()
|
||||
{
|
||||
return (js && js->GetIsolate()) ? js->GetIsolate() : NULL;
|
||||
}
|
||||
|
||||
bool JSBase::GetAutoDestroy()
|
||||
{
|
||||
return autoDestroy;
|
||||
}
|
||||
|
||||
Handle<Function> JSBase::GetFunctionFromArg(Isolate *isolate, const Local<Value>& arg)
|
||||
{
|
||||
Handle<Function> func;
|
||||
|
||||
if (!arg.IsEmpty() && arg->IsFunction()) {
|
||||
// Cast the argument directly to a function
|
||||
func = Handle<Function>::Cast(arg);
|
||||
} else if (!arg.IsEmpty() && arg->IsString()) {
|
||||
Handle<String> tmp = Handle<String>::Cast(arg);
|
||||
if (!tmp.IsEmpty() && *tmp) {
|
||||
// Fetch the actual function pointer from the global context (by function name)
|
||||
Handle<Value> val = isolate->GetCurrentContext()->Global()->Get(tmp);
|
||||
if (!val.IsEmpty() && val->IsFunction()) {
|
||||
func = Handle<Function>::Cast(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!func.IsEmpty() && func->IsFunction()) {
|
||||
return func;
|
||||
} else {
|
||||
return Handle<Function>();
|
||||
}
|
||||
}
|
||||
|
||||
void JSBase::DefaultSetProperty(v8::Local<v8::String> property, v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info)
|
||||
{
|
||||
info.GetIsolate()->ThrowException(v8::String::NewFromUtf8(info.GetIsolate(), "this property cannot be changed!"));
|
||||
}
|
||||
|
||||
/* 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 noet:
|
||||
*/
|
|
@ -0,0 +1,593 @@
|
|||
/*
|
||||
* mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
* Copyright (C) 2013-2014, Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* 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 Original Code is mod_v8 for FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
* Portions created by the Initial Developer are Copyright (C)
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Olsson <peter@olssononline.se>
|
||||
*
|
||||
* jsmain.cpp -- JavaScript Main V8 script runner
|
||||
*
|
||||
*/
|
||||
|
||||
#include "javascript.hpp"
|
||||
|
||||
#ifdef V8_ENABLE_DEBUGGING
|
||||
#include <v8-debug.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
|
||||
using namespace std;
|
||||
using namespace v8;
|
||||
|
||||
#ifdef V8_ENABLE_DEBUGGING
|
||||
void V8DispatchDebugMessages()
|
||||
{
|
||||
Isolate* isolate = Isolate::GetCurrent();
|
||||
Persistent<Context> *persistent_contect = (Persistent<Context> *)isolate->GetData(1);
|
||||
HandleScope handle_scope(isolate);
|
||||
Local<Context> context = Local<Context>::New(isolate, *persistent_contect);
|
||||
Context::Scope scope(context);
|
||||
|
||||
Debug::ProcessDebugMessages();
|
||||
}
|
||||
#endif
|
||||
|
||||
bool JSMain::FileExists(const char *file)
|
||||
{
|
||||
ifstream fh(file);
|
||||
bool file_exists = false;
|
||||
|
||||
if (fh) {
|
||||
fh.close();
|
||||
file_exists = true;
|
||||
}
|
||||
|
||||
return file_exists;
|
||||
}
|
||||
|
||||
const string JSMain::LoadFileToString(const string& filename)
|
||||
{
|
||||
if (filename.length() == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
ifstream in(filename.c_str(), std::ios::in | std::ios::binary);
|
||||
|
||||
if (in) {
|
||||
string contents;
|
||||
|
||||
in.seekg(0, std::ios::end);
|
||||
contents.resize((size_t)in.tellg());
|
||||
|
||||
in.seekg(0, std::ios::beg);
|
||||
in.read(&contents[0], contents.size());
|
||||
in.close();
|
||||
|
||||
return contents;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
JSMain::JSMain(void)
|
||||
{
|
||||
isolate = Isolate::New();
|
||||
|
||||
extenderClasses = new vector<const js_class_definition_t *>();
|
||||
extenderFunctions = new vector<js_function_t *>();
|
||||
extenderInstances = new vector<registered_instance_t*>();
|
||||
activeInstances = new set<JSBase *>();
|
||||
|
||||
forcedTermination = false;
|
||||
forcedTerminationMessage = NULL;
|
||||
forcedTerminationLineNumber = 0;
|
||||
forcedTerminationScriptFile = NULL;
|
||||
}
|
||||
|
||||
JSMain::~JSMain(void)
|
||||
{
|
||||
bool enteredIsolate = false;
|
||||
|
||||
for (size_t i = 0; i < extenderInstances->size(); i++) {
|
||||
registered_instance_t *inst = (*extenderInstances)[i];
|
||||
|
||||
if (inst) {
|
||||
if (inst->name) free(inst->name);
|
||||
free(inst);
|
||||
}
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < extenderFunctions->size(); i++) {
|
||||
js_function_t *proc = (*extenderFunctions)[i];
|
||||
|
||||
if (proc) {
|
||||
if (proc->name) free((char *)proc->name);
|
||||
free(proc);
|
||||
}
|
||||
}
|
||||
|
||||
extenderInstances->clear();
|
||||
extenderClasses->clear();
|
||||
extenderFunctions->clear();
|
||||
|
||||
if (!Isolate::GetCurrent()) {
|
||||
enteredIsolate = true;
|
||||
isolate->Enter();
|
||||
}
|
||||
|
||||
/* It's probably not totally safe to call this here, but it whould always be empty by now anyway */
|
||||
DisposeActiveInstances();
|
||||
|
||||
if (enteredIsolate) {
|
||||
isolate->Exit();
|
||||
}
|
||||
|
||||
delete extenderClasses;
|
||||
delete extenderFunctions;
|
||||
delete extenderInstances;
|
||||
delete activeInstances;
|
||||
|
||||
if (forcedTerminationMessage) free(forcedTerminationMessage);
|
||||
if (forcedTerminationScriptFile) free(forcedTerminationScriptFile);
|
||||
|
||||
isolate->Dispose();
|
||||
}
|
||||
|
||||
const string JSMain::GetExceptionInfo(Isolate* isolate, TryCatch* try_catch)
|
||||
{
|
||||
HandleScope handle_scope(isolate);
|
||||
String::Utf8Value exception(try_catch->Exception());
|
||||
const char *exception_string = js_safe_str(*exception);
|
||||
Handle<Message> message = try_catch->Message();
|
||||
string res;
|
||||
|
||||
if (message.IsEmpty()) {
|
||||
// V8 didn't provide any extra information about this error; just return the exception.
|
||||
res = exception_string;
|
||||
} else {
|
||||
String::Utf8Value filename(message->GetScriptResourceName());
|
||||
const char *filename_string = js_safe_str(*filename);
|
||||
int linenum = message->GetLineNumber();
|
||||
|
||||
ostringstream ss;
|
||||
|
||||
ss << filename_string << ":" << linenum << ": " << exception_string << "\r\n";
|
||||
|
||||
// Print line of source code.
|
||||
String::Utf8Value sourceline(message->GetSourceLine());
|
||||
const char *sourceline_string = js_safe_str(*sourceline);
|
||||
|
||||
ss << sourceline_string << "\r\n";
|
||||
|
||||
// Print wavy underline.
|
||||
int start = message->GetStartColumn();
|
||||
|
||||
for (int i = 0; i < start; i++) {
|
||||
ss << " ";
|
||||
}
|
||||
|
||||
int end = message->GetEndColumn();
|
||||
|
||||
for (int i = start; i < end; i++) {
|
||||
ss << "^";
|
||||
}
|
||||
|
||||
res = ss.str();
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void JSMain::Include(const v8::FunctionCallbackInfo<Value>& args)
|
||||
{
|
||||
for (int i = 0; i < args.Length(); i++) {
|
||||
HandleScope handle_scope(args.GetIsolate());
|
||||
String::Utf8Value str(args[i]);
|
||||
|
||||
// load_file loads the file with this name into a string
|
||||
string js_file = LoadFileToString(js_safe_str(*str));
|
||||
|
||||
if (js_file.length() > 0) {
|
||||
Handle<String> source = String::NewFromUtf8(args.GetIsolate(), js_file.c_str());
|
||||
|
||||
Handle<Script> script = Script::Compile(source, args[i]);
|
||||
|
||||
args.GetReturnValue().Set(script->Run());
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
args.GetReturnValue().Set(Undefined(args.GetIsolate()));
|
||||
}
|
||||
|
||||
void JSMain::Log(const v8::FunctionCallbackInfo<Value>& args)
|
||||
{
|
||||
HandleScope handle_scope(args.GetIsolate());
|
||||
String::Utf8Value str(args[0]);
|
||||
|
||||
printf("%s\r\n", js_safe_str(*str));
|
||||
|
||||
args.GetReturnValue().Set(Undefined(args.GetIsolate()));
|
||||
}
|
||||
|
||||
void JSMain::Version(const v8::FunctionCallbackInfo<Value>& args)
|
||||
{
|
||||
args.GetReturnValue().Set(String::NewFromUtf8(args.GetIsolate(), V8::GetVersion()));
|
||||
}
|
||||
|
||||
const string JSMain::ExecuteScript(const string& filename, bool *resultIsError)
|
||||
{
|
||||
// Get the file and load into a string.
|
||||
string data = LoadFileToString(filename);
|
||||
|
||||
return ExecuteString(data, filename, resultIsError);
|
||||
}
|
||||
|
||||
const string JSMain::ExecuteString(const string& scriptData, const string& fileName, bool *resultIsError)
|
||||
{
|
||||
string res;
|
||||
bool isError = false;
|
||||
|
||||
//solate->Enter();
|
||||
{
|
||||
Locker lock(isolate);
|
||||
Isolate::Scope iscope(isolate);
|
||||
{
|
||||
// Create a stack-allocated handle scope.
|
||||
HandleScope scope(isolate);
|
||||
|
||||
isolate->SetData(0, this);
|
||||
|
||||
Handle<ObjectTemplate> global = ObjectTemplate::New();
|
||||
global->Set(String::NewFromUtf8(isolate, "include"), FunctionTemplate::New(isolate, Include));
|
||||
global->Set(String::NewFromUtf8(isolate, "require"), FunctionTemplate::New(isolate, Include));
|
||||
global->Set(String::NewFromUtf8(isolate, "log"), FunctionTemplate::New(isolate, Log));
|
||||
|
||||
for (int i = 0; i < extenderFunctions->size(); i++) {
|
||||
js_function_t *proc = (*extenderFunctions)[i];
|
||||
global->Set(String::NewFromUtf8(isolate, proc->name), FunctionTemplate::New(isolate, proc->func));
|
||||
}
|
||||
|
||||
// Create a new context.
|
||||
Local<Context> context = Context::New(isolate, NULL, global);
|
||||
|
||||
if (context.IsEmpty()) {
|
||||
return "Failed to create new JS context";
|
||||
}
|
||||
|
||||
// Enter the created context for compiling and running the script.
|
||||
Context::Scope context_scope(context);
|
||||
|
||||
// Register all plugins.
|
||||
for (int i = 0; i < extenderClasses->size(); i++) {
|
||||
JSBase::Register(isolate, (*extenderClasses)[i]);
|
||||
}
|
||||
|
||||
// Register all instances.
|
||||
for (int i = 0; i < extenderInstances->size(); i++) {
|
||||
registered_instance_t *inst = (*extenderInstances)[i];
|
||||
inst->obj->RegisterInstance(isolate, inst->name, inst->auto_destroy);
|
||||
}
|
||||
|
||||
// Create a string containing the JavaScript source code.
|
||||
Handle<String> source = String::NewFromUtf8(isolate, scriptData.c_str());
|
||||
|
||||
TryCatch try_catch;
|
||||
|
||||
// Compile the source code.
|
||||
Handle<Script> script = Script::Compile(source, Handle<Value>::New(isolate, String::NewFromUtf8(isolate, fileName.c_str())));
|
||||
|
||||
if (try_catch.HasCaught()) {
|
||||
res = JSMain::GetExceptionInfo(isolate, &try_catch);
|
||||
isError = true;
|
||||
} else {
|
||||
// Run the script
|
||||
Handle<Value> result = script->Run();
|
||||
if (try_catch.HasCaught()) {
|
||||
res = JSMain::GetExceptionInfo(isolate, &try_catch);
|
||||
isError = true;
|
||||
} else {
|
||||
if (forcedTermination) {
|
||||
forcedTermination = false;
|
||||
res = GetForcedTerminationMessage();
|
||||
}
|
||||
|
||||
// return result as string.
|
||||
String::Utf8Value ascii(result);
|
||||
if (*ascii) {
|
||||
res = *ascii;
|
||||
}
|
||||
#ifndef V8_FORCE_GC_AFTER_EXECUTION
|
||||
DisposeActiveInstances();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
isolate->SetData(0, NULL);
|
||||
}
|
||||
|
||||
#ifdef V8_FORCE_GC_AFTER_EXECUTION
|
||||
V8::ContextDisposedNotification();
|
||||
while (!V8::IdleNotification()) {}
|
||||
DisposeActiveInstances();
|
||||
#endif
|
||||
}
|
||||
//isolate->Exit();
|
||||
|
||||
if (resultIsError) {
|
||||
*resultIsError = isError;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/** Add a class to be used in JS, the definition passed here must never be destroyed */
|
||||
void JSMain::AddJSExtenderClass(const js_class_definition_t *method)
|
||||
{
|
||||
extenderClasses->push_back(method);
|
||||
}
|
||||
|
||||
void JSMain::AddJSExtenderFunction(FunctionCallback func, const string& name)
|
||||
{
|
||||
if (!func || name.length() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
js_function_t *proc = (js_function_t *)malloc(sizeof(*proc));
|
||||
|
||||
if (proc) {
|
||||
memset(proc, 0, sizeof(*proc));
|
||||
|
||||
proc->func = func;
|
||||
js_strdup(proc->name, name.c_str());
|
||||
|
||||
extenderFunctions->push_back(proc);
|
||||
}
|
||||
}
|
||||
|
||||
void JSMain::AddJSExtenderInstance(JSBase *instance, const string& objectName, bool autoDestroy)
|
||||
{
|
||||
registered_instance_t *inst = (registered_instance_t *)malloc(sizeof(*inst));
|
||||
|
||||
if (inst) {
|
||||
memset(inst, 0, sizeof(*inst));
|
||||
|
||||
inst->obj = instance;
|
||||
if (objectName.size() > 0) js_strdup(inst->name, objectName.c_str());
|
||||
inst->auto_destroy = autoDestroy;
|
||||
|
||||
extenderInstances->push_back(inst);
|
||||
}
|
||||
}
|
||||
|
||||
JSMain *JSMain::GetScriptInstanceFromIsolate(Isolate* isolate)
|
||||
{
|
||||
if (isolate) {
|
||||
void *p = isolate->GetData(0);
|
||||
if (p) {
|
||||
return static_cast<JSMain *>(p);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Isolate *JSMain::GetIsolate()
|
||||
{
|
||||
return isolate;
|
||||
}
|
||||
|
||||
void JSMain::Initialize()
|
||||
{
|
||||
V8::InitializeICU(); // Initialize();
|
||||
}
|
||||
|
||||
void JSMain::Dispose()
|
||||
{
|
||||
// Make sure to cleanup properly!
|
||||
V8::LowMemoryNotification();
|
||||
while (!V8::IdleNotification()) {}
|
||||
|
||||
V8::Dispose();
|
||||
}
|
||||
|
||||
const vector<const js_class_definition_t *>& JSMain::GetExtenderClasses() const
|
||||
{
|
||||
return *extenderClasses;
|
||||
}
|
||||
|
||||
const vector<js_function_t *>& JSMain::GetExtenderFunctions() const
|
||||
{
|
||||
return *extenderFunctions;
|
||||
}
|
||||
|
||||
const vector<registered_instance_t*>& JSMain::GetExtenderInstances() const
|
||||
{
|
||||
return *extenderInstances;
|
||||
}
|
||||
|
||||
void JSMain::AddActiveInstance(JSBase *obj)
|
||||
{
|
||||
activeInstances->insert(obj);
|
||||
}
|
||||
|
||||
void JSMain::RemoveActiveInstance(JSBase *obj)
|
||||
{
|
||||
if (obj) {
|
||||
set<JSBase *>::iterator it = activeInstances->find(obj);
|
||||
|
||||
if (it != activeInstances->end()) {
|
||||
activeInstances->erase(it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void JSMain::DisposeActiveInstances()
|
||||
{
|
||||
set<JSBase *>::iterator it = activeInstances->begin();
|
||||
size_t c = activeInstances->size();
|
||||
|
||||
while (it != activeInstances->end()) {
|
||||
JSBase *obj = *it;
|
||||
delete obj; /* After this, the iteratior might be invalid, since the slot in the set might be removed already */
|
||||
|
||||
if (c == activeInstances->size()) {
|
||||
/* Nothing changed in the set, make sure to manually remove this instance from the set */
|
||||
activeInstances->erase(it);
|
||||
}
|
||||
|
||||
it = activeInstances->begin();
|
||||
c = activeInstances->size();
|
||||
}
|
||||
}
|
||||
|
||||
bool JSMain::GetForcedTermination(void)
|
||||
{
|
||||
return forcedTermination;
|
||||
}
|
||||
|
||||
void JSMain::ResetForcedTermination(void)
|
||||
{
|
||||
forcedTermination = false;
|
||||
}
|
||||
|
||||
const char *JSMain::GetForcedTerminationMessage(void)
|
||||
{
|
||||
return js_safe_str(forcedTerminationMessage);
|
||||
}
|
||||
|
||||
const char *JSMain::GetForcedTerminationScriptFile(void)
|
||||
{
|
||||
return js_safe_str(forcedTerminationScriptFile);
|
||||
}
|
||||
|
||||
int JSMain::GetForcedTerminationLineNumber(void)
|
||||
{
|
||||
return forcedTerminationLineNumber;
|
||||
}
|
||||
|
||||
void JSMain::ExitScript(Isolate *isolate, const char *msg)
|
||||
{
|
||||
if (!isolate) {
|
||||
return;
|
||||
}
|
||||
|
||||
JSMain *js = JSMain::GetScriptInstanceFromIsolate(isolate);
|
||||
|
||||
if (js) {
|
||||
js->forcedTermination = true;
|
||||
|
||||
/* Free old data if it exists already */
|
||||
if (js->forcedTerminationMessage) {
|
||||
free(js->forcedTerminationMessage);
|
||||
js->forcedTerminationMessage = NULL;
|
||||
}
|
||||
|
||||
if (js->forcedTerminationScriptFile) {
|
||||
free(js->forcedTerminationScriptFile);
|
||||
js->forcedTerminationScriptFile = NULL;
|
||||
}
|
||||
|
||||
/* Save message for later use */
|
||||
if (msg) {
|
||||
js_strdup(js->forcedTerminationMessage, msg);
|
||||
}
|
||||
|
||||
js->forcedTerminationScriptFile = GetStackInfo(isolate, &js->forcedTerminationLineNumber);
|
||||
}
|
||||
|
||||
V8::TerminateExecution(isolate);
|
||||
}
|
||||
|
||||
char *JSMain::GetStackInfo(Isolate *isolate, int *lineNumber)
|
||||
{
|
||||
HandleScope handle_scope(isolate);
|
||||
const char *file = __FILE__; /* Use current filename if we can't find the correct from JS stack */
|
||||
int line = __LINE__; /* Use current line number if we can't find the correct from JS stack */
|
||||
char *ret = NULL;
|
||||
|
||||
/* Try to get the current stack trace (script file) */
|
||||
Local<StackTrace> stFile = StackTrace::CurrentStackTrace(isolate, 1, StackTrace::kScriptName);
|
||||
|
||||
if (!stFile.IsEmpty()) {
|
||||
Local<StackFrame> sf = stFile->GetFrame(0);
|
||||
|
||||
if (!sf.IsEmpty()) {
|
||||
Local<String> fn = sf->GetScriptName();
|
||||
|
||||
if (!fn.IsEmpty()) {
|
||||
String::Utf8Value str(fn);
|
||||
|
||||
if (*str) {
|
||||
js_strdup(ret, *str); // We must dup here
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* dup current filename if we got nothing from stack */
|
||||
if (ret == NULL) {
|
||||
js_strdup(ret, file);
|
||||
}
|
||||
|
||||
/* Try to get the current stack trace (line number) */
|
||||
if (lineNumber) {
|
||||
*lineNumber = 0;
|
||||
|
||||
Local<StackTrace> stLine = StackTrace::CurrentStackTrace(isolate, 1, StackTrace::kLineNumber);
|
||||
|
||||
if (!stLine.IsEmpty()) {
|
||||
Local<StackFrame> sf = stLine->GetFrame(0);
|
||||
|
||||
if (!sf.IsEmpty()) {
|
||||
*lineNumber = sf->GetLineNumber();
|
||||
}
|
||||
}
|
||||
|
||||
/* Use current file number if we got nothing from stack */
|
||||
if (*lineNumber == 0) {
|
||||
*lineNumber = line;
|
||||
}
|
||||
}
|
||||
|
||||
/* Return dup'ed value - this must be freed by the calling function */
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* 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 noet:
|
||||
*/
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="curl.props" Condition=" '$(CurlPropsImported)' == '' "/>
|
||||
</ImportGroup>
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<TreatWarningAsError>true</TreatWarningAsError>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)libs\v8-3.24.14\include;$(SolutionDir)src\mod\languages\mod_v8;$(SolutionDir)src\mod\languages\mod_v8\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories>$(SolutionDir)libs\v8-3.24.14\build\$(Configuration)\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>icui18n.lib;icuuc.lib;v8.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
</Project>
|
Loading…
Reference in New Issue