├── .github └── workflows │ └── lua-poco-linux-build.yaml ├── .gitignore ├── CMakeLists.txt ├── LICENSE ├── README.md ├── appveyor.yml ├── examples ├── base32decoder.lua ├── base32encoder.lua ├── base64decoder.lua ├── base64encoder.lua ├── checksum.lua ├── compress.lua ├── condition.lua ├── decompress.lua ├── environment.lua ├── example_data.txt ├── example_data.txt.gz ├── file.lua ├── hexbinarydecoder.lua ├── hexbinaryencoder.lua ├── memoryistream.lua ├── memoryostream.lua ├── notificationqueue.lua ├── path.lua ├── process.lua ├── random.lua ├── regex.lua ├── sharedmemory.lua ├── streamcopier.lua ├── teeistream.lua ├── teeostream.lua ├── temporaryfile.lua ├── thread.lua └── timestamp.lua └── src ├── CMakeLists.txt ├── LuaPoco.h ├── LuaPocoUtils.h ├── StateTransfer.cpp ├── StateTransfer.h ├── Userdata.cpp ├── Userdata.h └── foundation ├── Base32Decoder.cpp ├── Base32Decoder.h ├── Base32Encoder.cpp ├── Base32Encoder.h ├── Base64Decoder.cpp ├── Base64Decoder.h ├── Base64Encoder.cpp ├── Base64Encoder.h ├── Buffer.cpp ├── Buffer.h ├── Checksum.cpp ├── Checksum.h ├── Compress.cpp ├── Compress.h ├── Condition.cpp ├── Condition.h ├── Decompress.cpp ├── Decompress.h ├── DeflatingIStream.cpp ├── DeflatingIStream.h ├── DeflatingOStream.cpp ├── DeflatingOStream.h ├── DynamicAny.cpp ├── DynamicAny.h ├── Environment.cpp ├── Environment.h ├── Event.cpp ├── Event.h ├── FastMutex.cpp ├── FastMutex.h ├── File.cpp ├── File.h ├── FileIStream.cpp ├── FileIStream.h ├── FileOStream.cpp ├── FileOStream.h ├── HexBinaryDecoder.cpp ├── HexBinaryDecoder.h ├── HexBinaryEncoder.cpp ├── HexBinaryEncoder.h ├── IStream.cpp ├── IStream.h ├── InflatingIStream.cpp ├── InflatingIStream.h ├── InflatingOStream.cpp ├── InflatingOStream.h ├── JSON.cpp ├── JSON.h ├── MemoryIStream.cpp ├── MemoryIStream.h ├── MemoryOStream.cpp ├── MemoryOStream.h ├── Mutex.cpp ├── Mutex.h ├── NamedEvent.cpp ├── NamedEvent.h ├── NamedMutex.cpp ├── NamedMutex.h ├── Notification.cpp ├── Notification.h ├── NotificationFactory.cpp ├── NotificationFactory.h ├── NotificationQueue.cpp ├── NotificationQueue.h ├── OStream.cpp ├── OStream.h ├── Path.cpp ├── Path.h ├── Pipe.cpp ├── Pipe.h ├── PipeIStream.cpp ├── PipeIStream.h ├── PipeOStream.cpp ├── PipeOStream.h ├── Process.cpp ├── Process.h ├── ProcessHandle.cpp ├── ProcessHandle.h ├── Random.cpp ├── Random.h ├── RegularExpression.cpp ├── RegularExpression.h ├── Semaphore.cpp ├── Semaphore.h ├── SharedMemory.cpp ├── SharedMemory.h ├── StreamCopier.cpp ├── StreamCopier.h ├── TaskManager.cpp ├── TaskManager.h ├── TeeIStream.cpp ├── TeeIStream.h ├── TeeOStream.cpp ├── TeeOStream.h ├── TemporaryFile.cpp ├── TemporaryFile.h ├── Thread.cpp ├── Thread.h ├── Timestamp.cpp └── Timestamp.h /.github/workflows/lua-poco-linux-build.yaml: -------------------------------------------------------------------------------- 1 | name: lua-poco linux build 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | branches: [ master ] 8 | 9 | jobs: 10 | build-lua-poco-53: 11 | runs-on: ubuntu-latest 12 | steps: 13 | - uses: actions/checkout@v2 14 | - name: install dependencies 15 | run: sudo apt install -y cmake liblua5.3-dev libpoco-dev 16 | - name: cmake 17 | run: cmake -S ./ -B ./build -DCMAKE_BUILD_TYPE=Release -DUSE_EMBEDDED_POCO=OFF -DLUA_INCLUDE=/usr/include/lua5.3/ -DLUA_LIB_NAME=lua5.3 18 | - name: make 19 | run: cd build && make install 20 | 21 | build-lua-poco-52: 22 | runs-on: ubuntu-latest 23 | steps: 24 | - uses: actions/checkout@v2 25 | - name: install dependencies 26 | run: sudo apt install -y cmake liblua5.2-dev libpoco-dev 27 | - name: cmake 28 | run: cmake -S ./ -B ./build -DCMAKE_BUILD_TYPE=Release -DUSE_EMBEDDED_POCO=OFF -DLUA_INCLUDE=/usr/include/lua5.2/ -DLUA_LIB_NAME=lua5.2 29 | - name: make 30 | run: cd build && make install 31 | 32 | build-lua-poco-51: 33 | runs-on: ubuntu-latest 34 | steps: 35 | - uses: actions/checkout@v2 36 | - name: install dependencies 37 | run: sudo apt install -y cmake liblua5.1-dev libpoco-dev 38 | - name: cmake 39 | run: cmake -S ./ -B ./build -DCMAKE_BUILD_TYPE=Release -DUSE_EMBEDDED_POCO=OFF -DLUA_INCLUDE=/usr/include/lua5.1/ -DLUA_LIB_NAME=lua5.1 40 | - name: make 41 | run: cd build && make install 42 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | 6 | # Compiled Dynamic libraries 7 | *.so 8 | *.dylib 9 | 10 | # Compiled Static libraries 11 | *.lai 12 | *.la 13 | *.a 14 | build 15 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 3.5) 2 | project(luapoco) 3 | include(ExternalProject) 4 | 5 | ### Note if this option is off, POCO libraries are expected to be found on the linker path. 6 | option(USE_EMBEDDED_POCO "build poco library and static link into lua-poco." ON) 7 | 8 | ### Pick Lua implementation to use. 9 | if (LUA_INCLUDE) 10 | ### On Windows and Linux, specify where to find the Lua header files. 11 | include_directories(${LUA_INCLUDE}) 12 | ### These are mostly only useful for windows to specify: 13 | ### The name of the Lua DLL to link against. 14 | ### The path where the Lua DLL resides. 15 | if (LUA_LIB_PATH AND LUA_LIB_NAME) 16 | find_library(LUA_LIB ${LUA_LIB_NAME} PATHS ${LUA_LIB_PATH} NO_DEFAULT_PATH) 17 | endif() 18 | else() 19 | ### For a generic unixy build that assumes the lua.h resides some where in a default CMAKE path. 20 | find_path(LUA_INCLUDE lua.h) 21 | endif() 22 | 23 | message(STATUS "lua-poco using Lua headers: ${LUA_INCLUDE}") 24 | message(STATUS "lua-poco using Lua library: ${LUA_LIB}") 25 | 26 | if (MSVC) 27 | ### lua-poco on Windows will by default use a static/interal copy of the Poco C++ library. 28 | ### It will also use a statically linked C/C++ runtime to avoid the redistributable mess. 29 | if (CMAKE_BUILD_TYPE STREQUAL "Debug") 30 | set(PocoInternalSuffix "d") 31 | else() 32 | set(PocoInternalSuffix "") 33 | endif() 34 | 35 | set(CompilerFlags 36 | CMAKE_CXX_FLAGS 37 | CMAKE_CXX_FLAGS_DEBUG 38 | CMAKE_CXX_FLAGS_RELEASE 39 | CMAKE_C_FLAGS 40 | CMAKE_C_FLAGS_DEBUG 41 | CMAKE_C_FLAGS_RELEASE 42 | ) 43 | foreach(CompilerFlag ${CompilerFlags}) 44 | string(REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}") 45 | endforeach() 46 | 47 | set(PocoInternalSuffix "mt${PocoInternalSuffix}") 48 | elseif(MINGW) 49 | ## mingw-w64's build links against supplied Lua and POCO, so no suffix is present. 50 | ## currently mingw-w64 cannot build the embedded poco without patches. 51 | set(PocoInternalSuffix "") 52 | elseif(UNIX) 53 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") 54 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") 55 | endif() 56 | 57 | if (USE_EMBEDDED_POCO) 58 | ### Setup internal Poco C++ library. 59 | #### POCO_URL can be defined at cmake invocation via a file:// URI to point at a local version of 60 | #### the poco-x.x.x-all.tar.gz file. ie: file://c:/users/username/src/poco-1.11.1-all.tar.gz 61 | 62 | if(NOT POCO_URL) 63 | set(POCO_URL https://pocoproject.org/releases/poco-1.11.1/poco-1.11.1-all.tar.gz) 64 | endif() 65 | 66 | set(POCO_DIR ${CMAKE_CURRENT_BINARY_DIR}/poco_internal) 67 | set(POCO_INSTALL_DIR ${POCO_DIR}/install) 68 | 69 | include_directories(${POCO_INSTALL_DIR}/include) 70 | 71 | ExternalProject_Add(poco_static 72 | PREFIX ${POCO_DIR} 73 | URL ${POCO_URL} 74 | CMAKE_COMMAND "${CMAKE_COMMAND}" -E env "CXXFLAGS=${CMAKE_CXX_FLAGS}" "CFLAGS=${CMAKE_C_FLAGS}" "${CMAKE_COMMAND}" 75 | INSTALL_DIR ${POCO_INSTALL_DIR} 76 | CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX=${POCO_INSTALL_DIR} -DPOCO_STATIC=ON -DPOCO_UNBUNDLED=OFF -DPOCO_MT=ON -DENABLE_MONGODB=OFF -DENABLE_PAGECOMPILER=OFF -DENABLE_PAGECOMPILER_FILE2PAGE=OFF -DENABLE_JWT=OFF -DENABLE_APACHECONNECTOR=OFF -DENABLE_DATA_MYSQL=OFF -DENABLE_DATA_POSTGRESQL=OFF -DENABLE_DATA_ODBC=OFF -DENABLE_DATA_SQLITE=OFF -DENABLE_REDIS=OFF -DENABLE_PDF=OFF -DENABLE_POCODOC=OFF -DENABLE_ACTIVERECORD=OFF -DENABLE_ACTIVERECORD_COMPILER=OFF 77 | ) 78 | 79 | find_library(POCO_FOUNDATION_LIB PocoFoundation${PocoInternalSuffix} PATHS ${POCO_INSTALL_DIR} NO_DEFAULT_PATH) 80 | find_library(POCO_JSON_LIB PocoJSON${PocoInternalSuffix} PATHS ${POCO_INSTALL_DIR} NO_DEFAULT_PATH) 81 | find_library(POCO_ZIP_LIB PocoZip${PocoInternalSuffix} PATHS ${POCO_INSTALL_DIR} NO_DEFAULT_PATH) 82 | else() 83 | find_path(POCO_HEADERS_DIR "Poco/Poco.h") 84 | find_library(POCO_FOUNDATION_LIB PocoFoundation${PocoInternalSuffix}) 85 | find_library(POCO_JSON_LIB PocoJSON${PocoInternalSuffix}) 86 | find_library(POCO_ZIP_LIB PocoZip${PocoInternalSuffix}) 87 | include_directories(${POCO_HEADERS_DIR}) 88 | endif() 89 | 90 | 91 | 92 | add_subdirectory(src) 93 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013, Matt Boney 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | Redistributions in binary form must reproduce the above copyright notice, this 11 | list of conditions and the following disclaimer in the documentation and/or 12 | other materials provided with the distribution. 13 | 14 | Neither the name of the developer nor the names of its 15 | contributors may be used to endorse or promote products derived from 16 | this software without specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://github.com/ma-bo/lua-poco/actions/workflows/lua-poco-linux-build.yaml/badge.svg)](https://github.com/ma-bo/lua-poco/actions/workflows/lua-poco-linux-build.yaml) 2 | [![Build Status](https://ci.appveyor.com/api/projects/status/github/ma-bo/lua-poco?branch=master&svg=true)](https://ci.appveyor.com/project/ma-bo/lua-poco/history) 3 | lua-poco 4 | ======== 5 | 6 | Lua bindings for the POCO C++ library 7 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | platform: 2 | - x64 3 | 4 | configuration: 5 | - Release 6 | 7 | version: 1.0.{build} 8 | os: Visual Studio 2017 9 | clone_depth: 1 10 | 11 | install: 12 | - appveyor DownloadFile https://github.com/xpol/luavm/releases/download/0.5.4/LuaVM-0.5.4-vs2017-x64.exe 13 | - LuaVM-0.5.4-vs2017-x64.exe /verysilent /dir=C:\luavm 14 | 15 | before_build: 16 | - call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars64.bat" 17 | - cmake -S . -B build -G "Visual Studio 15 2017 Win64" -DLUA_LIB_NAME=lua51 -DLUA_LIB_PATH="C:\luavm\versions\5.1" -DLUA_INCLUDE="C:\luavm\versions\5.1\include" 18 | 19 | build_script: 20 | - cmake --build build --config Release 21 | -------------------------------------------------------------------------------- /examples/base32decoder.lua: -------------------------------------------------------------------------------- 1 | --[[ base32decoder.lua 2 | This example shows how base32encoder module is used as an ostream to output decoded base32 data. 3 | --]] 4 | 5 | -- prerequisite modules 6 | local path = assert(require("poco.path")) 7 | local base32decoder = assert(require("poco.base32decoder")) 8 | local fileistream = assert(require("poco.fileistream")) 9 | local fileostream = assert(require("poco.fileostream")) 10 | local streamcopier = assert(require("poco.streamcopier")) 11 | local temporaryfile = assert(require("poco.temporaryfile")) 12 | 13 | -- filesystem locations 14 | -- re-use output file from base32encoder.lua 15 | local example_file_name = "example_data.base32.txt" 16 | local example_file_path = string.format("%s%s", path.temp(), example_file_name) 17 | 18 | -- instances 19 | local output_tempfile = assert(temporaryfile()) 20 | local output_file_path = output_tempfile:path() 21 | local input_data_is = assert(fileistream(example_file_path)) 22 | local output_data_os = assert(fileostream(output_file_path)) 23 | local base32_filter_is = assert(base32decoder(input_data_is)) 24 | -- use streamcopier to send read all base32 data through the filter, and send it to the output stream. 25 | local bytes_copied = assert(streamcopier.copyStream(base32_filter_is, output_data_os)) 26 | output_data_os:close() 27 | 28 | print("input file: ", example_file_path) 29 | print("output file: ", output_file_path) 30 | print(string.format("wrote %d bytes from source to output stream.", bytes_copied)) 31 | 32 | -------------------------------------------------------------------------------- /examples/base32encoder.lua: -------------------------------------------------------------------------------- 1 | --[[ base32encoder.lua 2 | This example shows how compress module is used as an ostream to output base32 data. 3 | --]] 4 | 5 | -- prerequisite modules 6 | local path = assert(require("poco.path")) 7 | local base32encoder = assert(require("poco.base32encoder")) 8 | local fileistream = assert(require("poco.fileistream")) 9 | local fileostream = assert(require("poco.fileostream")) 10 | local streamcopier = assert(require("poco.streamcopier")) 11 | -- filesystem locations 12 | local example_file_name = "example_data.txt.gz" 13 | local output_file_name = "example_data.base32.txt" 14 | local example_file_path = string.format("%s%s", path.current(), example_file_name) 15 | local output_file_path = string.format("%s%s", path.temp(), output_file_name) 16 | -- instances 17 | local input_data_is = assert(fileistream(example_file_path)) 18 | local output_data_os = assert(fileostream(output_file_path)) 19 | local base32_filter_os = assert(base32encoder(output_data_os)) 20 | -- use streamcopier to send all of example_data.txt.gz through the base32 encoder. 21 | local bytes_copied = assert(streamcopier.copyStream(input_data_is, base32_filter_os)) 22 | 23 | -- flush data to output file 24 | base32_filter_os:close() 25 | print("input file: ", example_file_path) 26 | print("output file: ", output_file_path) 27 | print(string.format("wrote %d bytes from source to output stream.", bytes_copied)) 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /examples/base64decoder.lua: -------------------------------------------------------------------------------- 1 | --[[ base64decoder.lua 2 | This example shows how base64decoder module is used as an ostream to output decoded data. 3 | --]] 4 | 5 | -- prerequisite modules 6 | local path = assert(require("poco.path")) 7 | local base64decoder = assert(require("poco.base64decoder")) 8 | local fileistream = assert(require("poco.fileistream")) 9 | local fileostream = assert(require("poco.fileostream")) 10 | local streamcopier = assert(require("poco.streamcopier")) 11 | local temporaryfile = assert(require("poco.temporaryfile")) 12 | 13 | -- filesystem locations 14 | -- re-use output file from base64encoder.lua 15 | local example_file_name = "example_data.base64.txt" 16 | local example_file_path = string.format("%s%s", path.temp(), example_file_name) 17 | 18 | -- instances 19 | local output_tempfile = assert(temporaryfile()) 20 | local output_file_path = output_tempfile:path() 21 | local input_data_is = assert(fileistream(example_file_path)) 22 | local output_data_os = assert(fileostream(output_file_path)) 23 | local base64_filter_is = assert(base64decoder(input_data_is)) 24 | -- use streamcopier to send read all base64 data through the filter, and send it to the output stream. 25 | local bytes_copied = assert(streamcopier.copyStream(base64_filter_is, output_data_os)) 26 | output_data_os:close() 27 | 28 | print("input file: ", example_file_path) 29 | print("output file: ", output_file_path) 30 | print(string.format("wrote %d bytes from source to output stream.", bytes_copied)) 31 | 32 | -------------------------------------------------------------------------------- /examples/base64encoder.lua: -------------------------------------------------------------------------------- 1 | --[[ base64encoder.lua 2 | This example shows how base64encoder module is used as an ostream to output base64 encoded data. 3 | --]] 4 | 5 | -- prerequisite modules 6 | local path = assert(require("poco.path")) 7 | local base64encoder = assert(require("poco.base64encoder")) 8 | local fileistream = assert(require("poco.fileistream")) 9 | local fileostream = assert(require("poco.fileostream")) 10 | local streamcopier = assert(require("poco.streamcopier")) 11 | -- filesystem locations 12 | local example_file_name = "example_data.txt.gz" 13 | local output_file_name = "example_data.base64.txt" 14 | local example_file_path = string.format("%s%s", path.current(), example_file_name) 15 | local output_file_path = string.format("%s%s", path.temp(), output_file_name) 16 | -- instances 17 | local input_data_is = assert(fileistream(example_file_path)) 18 | local output_data_os = assert(fileostream(output_file_path)) 19 | local base64_filter_os = assert(base64encoder(output_data_os)) 20 | -- use streamcopier to send all of example_data.txt.gz through the base64 encoder. 21 | local bytes_copied = assert(streamcopier.copyStream(input_data_is, base64_filter_os)) 22 | 23 | -- flush data to output file 24 | base64_filter_os:close() 25 | print("input file: ", example_file_path) 26 | print("output file: ", output_file_path) 27 | print(string.format("wrote %d bytes from source to output stream.", bytes_copied)) 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /examples/checksum.lua: -------------------------------------------------------------------------------- 1 | -- load the poco.checksum module 2 | local checksum = assert(require("poco.checksum")) 3 | 4 | -- these are equivalent to the following: 5 | -- local adler = assert(checksum.new("Adler-32")) 6 | -- local crc = assert(checksum.new("CRC-32")) 7 | local adler = assert(checksum("ADLER32")) 8 | local crc = assert(checksum("CRC32")) 9 | 10 | local hash_string = "hello world." 11 | print(string.format("hash_string:\t'%s'", hash_string)) 12 | crc:update(hash_string) 13 | adler:update(hash_string) 14 | print("\tCRC-32: ", string.format("0x%x", crc:checksum())) 15 | print("\tAdler-32:", string.format("0x%x", adler:checksum())) 16 | 17 | -- create new hashes with just "hello " and output. 18 | hash_string = "hello " 19 | print(string.format("\nhash_string:\t'%s'", hash_string)) 20 | adler = assert(checksum("ADLER32")) 21 | crc = assert(checksum("CRC32")) 22 | crc:update(hash_string) 23 | adler:update(hash_string) 24 | print("\tCRC-32: ", string.format("0x%x", crc:checksum())) 25 | print("\tAdler-32:", string.format("0x%x", adler:checksum())) 26 | 27 | -- update the existing hash with "world." and output. 28 | hash_string = "world." 29 | print(string.format("\nupdating with:\t'%s'", hash_string)) 30 | crc:update(hash_string) 31 | adler:update(hash_string) 32 | print("\tCRC-32: ", string.format("0x%x", crc:checksum())) 33 | print("\tAdler-32:", string.format("0x%x", adler:checksum())) 34 | -------------------------------------------------------------------------------- /examples/compress.lua: -------------------------------------------------------------------------------- 1 | --[[ compress.lua 2 | This example shows how a the compress module can be used to create zip files and write them to 3 | a compatible ostream. Files and directories can be added via istreams and filesystem paths. 4 | --]] 5 | 6 | -- the ostream could be other types, such as pipeostream, teeostream, memoryostream, etc. 7 | local fostream = assert(require("poco.fileostream")) 8 | local compress = assert(require("poco.zip.compress")) 9 | local path = assert(require("poco.path")) 10 | 11 | -- write the zip file to the output stream in the temp directory. 12 | local output_zip_path = path(path.temp()) 13 | output_zip_path:setFileName("compress_example.zip") 14 | local zfs = assert(fostream(output_zip_path:toString())) 15 | 16 | -- create compress instance with the fileostream. 17 | --- compress stores a reference to the fileostream to prevent GC, 18 | --- so a reference does not need to be maintained by the caller. 19 | --- additionally, the default true parameter for seekable must be false for 20 | --- non-seekable istreams such as pipeistream, socketistream, etc. 21 | local c = assert(compress(zfs)) 22 | 23 | -- print the list of file extensions that will get stored in the zipfile 24 | -- via the STORE method rather than DEFLATE. 25 | print("\nFile extensions using STORE method: ") 26 | for k,v in pairs(c:getStoreExtensions()) do print(k,v) end 27 | 28 | -- store a comment for the zip file and print it out. 29 | c:setZipComment("example comment") 30 | print("\nZip file comment:", c:getZipComment()) 31 | 32 | -- assume current working directory is the directory containing the examples. 33 | local examples_path = assert(path(path.current())) 34 | -- add all files and directories under the 'examples' directory to the zip file. 35 | io.write(string.format("\nAdding recursive directory: %s\nto: %s\n", examples_path:toString(), output_zip_path:toString())) 36 | assert(c:addRecursive(examples_path, "examples")) 37 | 38 | -- add README.md to readme/README.md via the addFile function. 39 | examples_path:popDirectory() 40 | examples_path:setFileName("README.md") 41 | io.write(string.format("\nAdding File: %s\nto: %s\n", examples_path:toString(), output_zip_path:toString())) 42 | assert(c:addFile(examples_path, "readme/README.md")) 43 | 44 | --[[ alternatively one could add a file via an poco istream via the addIStream function. 45 | -- note that this source could be a memoryistream, pipeistream, socketistream, etc. 46 | local fistream = assert(require("poco.fileistream")) 47 | local fis = assert(fistream(examples_path:toString())) 48 | --]] 49 | 50 | -- finalize the zip file. 51 | c:close() 52 | -------------------------------------------------------------------------------- /examples/condition.lua: -------------------------------------------------------------------------------- 1 | --[[ condition.lua 2 | This example shows how to use the condition module to signal threads. This module differs from 3 | the event module in that conditions accept a mutex as an argument. 4 | 5 | In the example, the main thread reads stdin to trigger the condition. The threads do some work 6 | with a shared resource under the protection of a mutex. The mutex is unlocked when 7 | condition:wait() is called, and locked when condition:wait() returns. 8 | --]] 9 | 10 | -- this function will be copied to its own lua state, and thread_main will be run from a thread. 11 | -- no upvalues are copied to the new lua state, but function parameters are copied from main. 12 | local function thread_main(id, condition, mutex, data_file, quit_event) 13 | print("thread starting: ", id) 14 | while true do 15 | condition:wait(mutex) 16 | if quit_event:tryWait(0) then break end 17 | -- do lots of important work on the shared resource below! 18 | local df = assert(io.open(data_file:path(), "a")) 19 | df:write(string.format("%d: %s %f\n", id, os.date(), os.clock()), "\n") 20 | df:close() 21 | end 22 | -- release mutex on quit. 23 | print("thread exiting: ", id) 24 | mutex:unlock() 25 | end 26 | 27 | -- prerequisite modules 28 | local thread = assert(require("poco.thread")) 29 | local fmutex = assert(require("poco.fastmutex")) 30 | local condition = assert(require("poco.condition")) 31 | local event = assert(require("poco.event")) 32 | local temporaryfile = assert(require("poco.temporaryfile")) 33 | 34 | -- module instances 35 | local worker_thread1 = assert(thread()) 36 | local worker_thread2 = assert(thread()) 37 | local mtx = assert(fmutex()) 38 | local dowork_cond = assert(condition()) 39 | local data_file = assert(temporaryfile()) 40 | -- use a non-auto resetting event to enable all threads to quit when signaled. 41 | local quit_event = assert(event(false)) 42 | 43 | -- lock access to the shared resource. the mutex will be unlocked when calling condition:wait() 44 | -- and locked again when condition:wait() returns. 45 | mtx:lock() 46 | 47 | -- start worker threads. 48 | print("threads will output data to: ", data_file:path()) 49 | assert(worker_thread1:start(thread_main, worker_thread1:id(), dowork_cond, mtx, data_file, quit_event)) 50 | assert(worker_thread2:start(thread_main, worker_thread2:id(), dowork_cond, mtx, data_file, quit_event)) 51 | 52 | -- main loop to trigger conditions. 53 | print("main: enter any data to trigger threads to do work, or enter an empty line to quit.") 54 | repeat 55 | line = io.read() 56 | if line == "" then quit_event:set() end 57 | dowork_cond:broadcast() 58 | print("main: broadcasting condition.") 59 | until quit_event:tryWait(0) 60 | 61 | print("main: stopping.") 62 | worker_thread1:join() 63 | worker_thread2:join() 64 | print("main: threads completed.") 65 | 66 | -- print out data from the temporary file before it gets removed. 67 | mtx:lock() 68 | for line in io.lines(data_file:path()) do 69 | print(line) 70 | end 71 | mtx:unlock() 72 | -------------------------------------------------------------------------------- /examples/decompress.lua: -------------------------------------------------------------------------------- 1 | --[[ compress.lua 2 | This example shows how a the compress module can be used to create zip files and write them to 3 | a compatible ostream. Files and directories can be added via istreams and filesystem paths. 4 | --]] 5 | 6 | local decompress = assert(require("poco.zip.decompress")) 7 | local fileistream = assert(require("poco.fileistream")) 8 | local path = assert(require("poco.path")) 9 | 10 | -- re-use the zip file from the compress.lua example. 11 | -- note: the istream does not have to be a file, it could be pipeistream, socketistream, memoryistream, etc. 12 | local input_zip_path = path(path.temp()) 13 | input_zip_path:setFileName("compress_example.zip") 14 | local zfs = assert(fileistream(input_zip_path:toString())) 15 | 16 | -- Construct decompress instance. There are two additional optional default parameters available: (by default false) 17 | --- flattenDirs = true, which does not recreate the embedded directory structure. 18 | --- keepIncompleteFiles = true, which leaves incomplete files on the filesystem. 19 | local output_path = path(path.temp()) 20 | output_path:pushDirectory("decompress-example") 21 | local dc = assert(decompress(zfs, output_path)) 22 | 23 | -- decompress all entries in the zip file. 24 | -- the function returns (true, "success", good count, fail count) even when there are problems extractinig some files. 25 | -- if a critical error occurs other than failure to write an entry to the filesystem (nil, "msg") will be returned. 26 | print(string.format("Decompressing %s to %s\n", input_zip_path:toString(), output_path:toString())) 27 | local rv, msg, good_count, fail_count = dc:decompressAll() 28 | if rv then 29 | print("entries decompressed: ", good_count) 30 | print("entries failed: ", fail_count) 31 | else 32 | print("error when decompressing files: ", msg) 33 | end 34 | 35 | -- iterate ZipLocalFileHeader's and print the absolute path to their location along with some other attributes. 36 | for path, zflh in dc:decompressed() do 37 | path:makeAbsolute() 38 | print("file name: ", zflh.fileName) 39 | print("full path: ", path:toString()) 40 | print("uncompressedSize: ", zflh.uncompressedSize) 41 | print("method: ", zflh.method) 42 | print("level: ", zflh.level) 43 | print("headerstartPos: ", zflh.startPos) 44 | print("dataStartPos: ", zflh.dataStartPos) 45 | end 46 | 47 | -------------------------------------------------------------------------------- /examples/environment.lua: -------------------------------------------------------------------------------- 1 | -- load the environment module from the poco library. 2 | local environment = assert(require("poco.environment")) 3 | 4 | -- print out environment attributes 5 | print("\npoco.environment functions:\n") 6 | print("nodeId: \t", environment.nodeId()) 7 | print("nodeName: \t", environment.nodeName()) 8 | print("osArchitecture:\t", environment.osArchitecture()) 9 | print("osName: \t", environment.osName()) 10 | print("osVerison: \t", environment.osVersion()) 11 | 12 | print("\nchecking environment variables...\n") 13 | print("has TEMP: \t", environment.has("TEMP")) 14 | if (environment.has("TEMP")) then 15 | print(environment.get("TEMP")) 16 | end 17 | 18 | print("has HOME: \t", environment.has("HOME")) 19 | if (environment.has("HOME")) then 20 | print(environment.get("HOME")) 21 | end 22 | 23 | print("has USERPROFILE:", environment.has("USERPROFILE")) 24 | if (environment.has("USERPROFILE")) then 25 | print(environment.get("USERPROFILE")) 26 | end 27 | -------------------------------------------------------------------------------- /examples/example_data.txt: -------------------------------------------------------------------------------- 1 | 1 Hello World! 2 | 2 Hello World! 3 | 3 Hello World! 4 | 4 Hello World! 5 | 5 Hello World! 6 | 6 Hello World! 7 | 7 Hello World! 8 | 8 Hello World! 9 | 9 Hello World! 10 | 10 Hello World! 11 | 11 Hello World! 12 | 12 Hello World! 13 | 13 Hello World! 14 | 14 Hello World! 15 | 15 Hello World! 16 | 16 Hello World! 17 | 17 Hello World! 18 | 18 Hello World! 19 | 19 Hello World! 20 | 20 Hello World! 21 | 21 Hello World! 22 | 22 Hello World! 23 | 23 Hello World! 24 | 24 Hello World! 25 | 25 Hello World! 26 | 26 Hello World! 27 | 27 Hello World! 28 | 28 Hello World! 29 | 29 Hello World! 30 | 30 Hello World! 31 | 31 Hello World! 32 | 32 Hello World! 33 | 33 Hello World! 34 | 34 Hello World! 35 | 35 Hello World! 36 | 36 Hello World! 37 | 37 Hello World! 38 | 38 Hello World! 39 | 39 Hello World! 40 | 40 Hello World! 41 | 41 Hello World! 42 | 42 Hello World! 43 | 43 Hello World! 44 | 44 Hello World! 45 | 45 Hello World! 46 | 46 Hello World! 47 | 47 Hello World! 48 | 48 Hello World! 49 | 49 Hello World! 50 | 50 Hello World! 51 | 51 Hello World! 52 | 52 Hello World! 53 | 53 Hello World! 54 | 54 Hello World! 55 | 55 Hello World! 56 | 56 Hello World! 57 | 57 Hello World! 58 | 58 Hello World! 59 | 59 Hello World! 60 | 60 Hello World! 61 | 61 Hello World! 62 | 62 Hello World! 63 | 63 Hello World! 64 | 64 Hello World! 65 | 65 Hello World! 66 | 66 Hello World! 67 | 67 Hello World! 68 | 68 Hello World! 69 | 69 Hello World! 70 | 70 Hello World! 71 | 71 Hello World! 72 | 72 Hello World! 73 | 73 Hello World! 74 | 74 Hello World! 75 | 75 Hello World! 76 | 76 Hello World! 77 | 77 Hello World! 78 | 78 Hello World! 79 | 79 Hello World! 80 | 80 Hello World! 81 | 81 Hello World! 82 | 82 Hello World! 83 | 83 Hello World! 84 | 84 Hello World! 85 | 85 Hello World! 86 | 86 Hello World! 87 | 87 Hello World! 88 | 88 Hello World! 89 | 89 Hello World! 90 | 90 Hello World! 91 | 91 Hello World! 92 | 92 Hello World! 93 | 93 Hello World! 94 | 94 Hello World! 95 | 95 Hello World! 96 | 96 Hello World! 97 | 97 Hello World! 98 | 98 Hello World! 99 | 99 Hello World! 100 | 100 Hello World! 101 | -------------------------------------------------------------------------------- /examples/example_data.txt.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ma-bo/lua-poco/c2ecf75ac7dafb341ceb3e0a1db798934314b36e/examples/example_data.txt.gz -------------------------------------------------------------------------------- /examples/file.lua: -------------------------------------------------------------------------------- 1 | -- load the poco.file module 2 | local file = assert(require("poco.file")) 3 | 4 | local example_file_name = "example.file.txt" 5 | print("\nexample_file_name: ", example_file_name) 6 | -- if a module's table has a new() function, you can also use a function call on 7 | -- the that table to call the new() function. 8 | local example_file = assert(file(example_file_name)) 9 | print("\texists: ", example_file:exists()) 10 | print("\tcreateFile: ", example_file:createFile()) 11 | print("\texists: ", example_file:exists()) 12 | print("\tsize: ", example_file:size()) 13 | print("\tsetSize(99):", example_file:setSize(99)) 14 | print("\tsize: ", example_file:size()) 15 | print("\tcanRead: ", example_file:canRead()) 16 | print("\tcanWrite: ", example_file:canWrite()) 17 | print("\tcanExecute: ", example_file:canExecute()) 18 | print("\tisFile: ", example_file:isFile()) 19 | print("\tisDevice: ", example_file:isDevice()) 20 | print("\tisDirectory:", example_file:isDirectory()) 21 | print("\tisHidden: ", example_file:isHidden()) 22 | print("\tisLink: ", example_file:isLink()) 23 | -- created() returns a poco.timestamp userdata, which we will use epochTime() to 24 | -- get a time value compatible with os.date(). 25 | print("\tcreated: ", os.date("%c", example_file:created():epochTime())) 26 | print("\tremove: ", example_file:remove()) 27 | print("\texists: ", example_file:exists()) 28 | 29 | print("\nexample_directory: .") 30 | local example_dir = assert(file(".")) 31 | print("\tpath: ", example_dir:path()) 32 | print("\texists: ", example_dir:exists()) 33 | print("\tisFile: ", example_dir:isFile()) 34 | print("\tisDirectory:", example_dir:isDirectory()) 35 | local files = example_dir:listNames() 36 | print("\tlistFiles: ", files) 37 | print("\tentries: ", #files) 38 | for i=1, #files do print("\t" .. files[i]) end 39 | -------------------------------------------------------------------------------- /examples/hexbinarydecoder.lua: -------------------------------------------------------------------------------- 1 | --[[ hexbinarydecoder.lua 2 | This example shows how the hexbinarydecoder module is used as an istream to decode hexbinary data. 3 | --]] 4 | 5 | -- prerequisite modules 6 | local path = assert(require("poco.path")) 7 | local hexbinarydecoder = assert(require("poco.hexbinarydecoder")) 8 | local fileistream = assert(require("poco.fileistream")) 9 | local fileostream = assert(require("poco.fileostream")) 10 | local streamcopier = assert(require("poco.streamcopier")) 11 | local temporaryfile = assert(require("poco.temporaryfile")) 12 | 13 | -- filesystem locations 14 | -- re-use output file from hexbinaryencoder.lua 15 | local example_file_name = "example_data.hexbinary.txt" 16 | local example_file_path = string.format("%s%s", path.temp(), example_file_name) 17 | 18 | -- instances 19 | local output_tempfile = assert(temporaryfile()) 20 | local output_file_path = output_tempfile:path() 21 | local input_data_is = assert(fileistream(example_file_path)) 22 | local output_data_os = assert(fileostream(output_file_path)) 23 | local hexbinary_filter_is = assert(hexbinarydecoder(input_data_is)) 24 | -- use streamcopier to send read all hexbinary data through the filter, and send it to the output stream. 25 | local bytes_copied = assert(streamcopier.copyStream(hexbinary_filter_is, output_data_os)) 26 | output_data_os:close() 27 | 28 | print("input file: ", example_file_path) 29 | print("output file: ", output_file_path) 30 | print(string.format("wrote %d bytes from source to output stream.", bytes_copied)) 31 | 32 | -------------------------------------------------------------------------------- /examples/hexbinaryencoder.lua: -------------------------------------------------------------------------------- 1 | --[[ hexbinaryencoder.lua 2 | This example shows how the hexbinaryencoder module is used as an ostream to output hexbinary data. 3 | --]] 4 | 5 | -- prerequisite modules 6 | local path = assert(require("poco.path")) 7 | local hexbinaryencoder = assert(require("poco.hexbinaryencoder")) 8 | local fileistream = assert(require("poco.fileistream")) 9 | local fileostream = assert(require("poco.fileostream")) 10 | local streamcopier = assert(require("poco.streamcopier")) 11 | -- filesystem locations 12 | local example_file_name = "example_data.txt.gz" 13 | local output_file_name = "example_data.hexbinary.txt" 14 | local example_file_path = string.format("%s%s", path.current(), example_file_name) 15 | local output_file_path = string.format("%s%s", path.temp(), output_file_name) 16 | -- instances 17 | local input_data_is = assert(fileistream(example_file_path)) 18 | local output_data_os = assert(fileostream(output_file_path)) 19 | local hexbinary_filter_os = assert(hexbinaryencoder(output_data_os)) 20 | -- use streamcopier to send all of example_data.txt.gz through the base32 encoder. 21 | local bytes_copied = assert(streamcopier.copyStream(input_data_is, hexbinary_filter_os)) 22 | output_data_os:close() 23 | 24 | print("input file: ", example_file_path) 25 | print("output file: ", output_file_path) 26 | print(string.format("wrote %d bytes from source to output stream.", bytes_copied)) 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /examples/memoryistream.lua: -------------------------------------------------------------------------------- 1 | --[[ memoryistream.lua 2 | This example shows how a memoryistream can be used with data from an arbitrary 3 | source like a file, socket, http request, or other mechanism to create an 4 | istream from a buffer. 5 | 6 | The example uses the memoryistream as a data source for the inflatingistream 7 | filter to read compressed data and inflate it. 8 | 9 | The compressed file contains lines in the format: 10 | 1 Hello World!\n 11 | 2 Hello World!\n 12 | --]] 13 | 14 | -- require modules needed for this task. 15 | local buffer = require("poco.buffer") 16 | local memoryistream = require("poco.memoryistream") 17 | local inflatingistream = require("poco.inflatingistream") 18 | 19 | -- read all compressed data from the example file. 20 | -- note that this data could have come from a socket, file, or some other API, 21 | -- provided that the data is returned as a string, it can be used with memoryistream. 22 | local data = assert(io.open("example_data.txt.gz", "rb")):read("*a") 23 | 24 | -- store the data from the file in a buffer, and use the memoryistream as the source 25 | -- istream for the inflatingistream filter in order to decompress the data that is read through it. 26 | 27 | -- note that the memoryistream holds a reference to the buffer, and the 28 | -- inflatingistream holds a reference to the memoryistream, so the programmer 29 | -- does not need to keep the userdata in variables to prevent garbage collection. 30 | local is = assert(inflatingistream(memoryistream(buffer(data)),"STREAM_GZIP")) 31 | 32 | local hello_world_count = 0 33 | for line in is:lines() do 34 | if line:find("%d+ Hello World!") then 35 | hello_world_count = hello_world_count + 1 36 | end 37 | end 38 | 39 | io.write("read ", tostring(hello_world_count), " Hello World!'s from example_data.txt.gz.\n") 40 | -------------------------------------------------------------------------------- /examples/memoryostream.lua: -------------------------------------------------------------------------------- 1 | --[[ memoryostream.lua 2 | This example shows how a memoryostream can be used as an endpoint/sink for 3 | other filtering ostreams. In this instance, it will be used to hold the 4 | output of the deflatingostream in memory. The buffer could then later be used 5 | to send the compressed data elsewhere. 6 | --]] 7 | 8 | -- require modules needed for this task. 9 | local buffer = require("poco.buffer") 10 | local memoryostream = require("poco.memoryostream") 11 | local deflatingostream = require("poco.deflatingostream") 12 | 13 | -- read all example data from the example file. 14 | -- note that this data could have come from a socket, file, or some other API, 15 | -- provided that the data is returned as a string, it can be used with memoryistream. 16 | local data = assert(io.open("example_data.txt", "rb")):read("*a") 17 | 18 | -- allocate a buffer a bit larger than the input data in the case of 0% compression + gzip header. 19 | local deflate_buffer = buffer(#data * 2) 20 | 21 | -- note that the memoryostream holds a reference to the buffer, and the 22 | -- inflatingistream holds a reference to the memoryistream, so the programmer 23 | -- does not need to keep the linked userdata in variables to prevent garbage collection. 24 | local mos = memoryostream(deflate_buffer) 25 | local os = assert(deflatingostream(mos,"STREAM_GZIP")) 26 | 27 | -- writing all the data to the ostream will send it through the links resulting in compression 28 | -- and outputting it to the poco buffer. 29 | -- note that the data could be sent directly to a file instead, however, using the buffer highlights 30 | -- the ability to then send the data to miscellaneous output mechanisms afterwards. 31 | assert(os:write(data)) 32 | -- flush the data to the output stream by calling close(). 33 | os:close() 34 | 35 | local edd_file = assert(io.open("example_data_deflated.txt.gz", "wb")) 36 | assert(edd_file:write(deflate_buffer:data():sub(1, mos:bytesWritten()))) 37 | edd_file:close() 38 | io.write("wrote ", mos:bytesWritten(), " bytes to example_data_deflated.txt.gz.\n") 39 | 40 | 41 | -------------------------------------------------------------------------------- /examples/notificationqueue.lua: -------------------------------------------------------------------------------- 1 | --[[ notificationqueue.lua 2 | 3 | This example shows how a notificationqueue can be used in two threads to 4 | pass mostly arbitrary lua values between threads and via the notificationqueue. 5 | 6 | Notifications are enqueued as: "notificiation_type", ... 7 | The first parameter is always a string which identifies the type of notification. 8 | The additional parameters can be of any type sharable/copyable between threads. 9 | --]] 10 | 11 | -- require modules needed for the main thread. 12 | local notificationqueue = assert(require("poco.notificationqueue")) 13 | local thread = assert(require("poco.thread")) 14 | 15 | -- function to be run in another thread and separate lua_State. 16 | function worker(notification_queue) 17 | -- wait for up to 500ms for a notification. 18 | repeat 19 | local notification_type, notification = notification_queue:waitDequeue(500) 20 | print("notification received:", notification_type, type(notification)) 21 | 22 | if notification_type == "quit" then 23 | quit = true 24 | else 25 | -- do work on notifications. 26 | end 27 | until quit 28 | end 29 | 30 | -- create worker thread, and a notification queue. 31 | local wt = assert(thread()) 32 | local q = assert(notificationqueue()) 33 | 34 | -- functions with no upvalues can be copied to a new lua_State. 35 | -- poco.notificationqueue can be shared in the new lua_State and 36 | -- is passed to the thread's function a parameter. 37 | -- tables are fully copied, provided all keys and values are also copyable. 38 | print("posting notifications to thread.") 39 | assert(q:enqueue("hello world")) 40 | assert(q:enqueue("table", { "hello", "world" })) 41 | 42 | print("queue size: ", q:size()) 43 | print("hasIdleThreads: ", q:hasIdleThreads()) 44 | 45 | assert(wt:start(worker, q)) 46 | assert(q:enqueue("quit")) 47 | 48 | -- join the thread 49 | assert(wt:join()) 50 | print("thread complete, result: ", wt:result()) 51 | -------------------------------------------------------------------------------- /examples/path.lua: -------------------------------------------------------------------------------- 1 | local path = require("poco.path") 2 | 3 | -- freestanding path related functions 4 | print("\n-- Platform information:") 5 | print("Path Seperator: ", path.pathSeparator()) 6 | print("Directory Seperator: ", path.separator()) 7 | print("Temporary Directory: ", path.temp()) 8 | print("Null Device: ", path.nullDevice()) 9 | print("Home Directory: ", path.home()) 10 | print("Current Working Directory: ", path.current()) 11 | print("Filesystem Roots:") 12 | local roots = path.listRoots() 13 | for i = 1, #roots do 14 | print(i, roots[i]) 15 | end 16 | 17 | -- Windows style path. 18 | local windows_path_string = "C:\\Windows\\System32\\kernel32.dll" 19 | print("\n-- Sample Windows Path: ", windows_path_string) 20 | -- create a Windows style path userdata and print information about it. 21 | local wp = assert(path(windows_path_string, "WINDOWS", true)) 22 | print("depth: ", wp:depth()) 23 | print("isAbsolute: ", wp:isAbsolute()) 24 | print("isRelative: ", wp:isRelative()) 25 | print("isDirectory: ", wp:isDirectory()) 26 | print("isFile: ", wp:isFile()) 27 | print("Device: ", wp:getDevice()) 28 | print("FileName: ", wp:getFileName()) 29 | 30 | -- Unix style path. 31 | local unix_path_string = "/usr/include/lua5.1/" 32 | -- create a Unix style path userdata and print information about it. 33 | print("\n-- Sample Unix Path: ", unix_path_string) 34 | local up = assert(path(unix_path_string, "UNIX", true)) 35 | print("depth: ", up:depth()) 36 | print("isAbsolute: ", up:isAbsolute()) 37 | print("isRelative: ", up:isRelative()) 38 | print("isDirectory: ", up:isDirectory()) 39 | print("isFile: ", up:isFile()) 40 | print("FileName: ", up:getFileName()) 41 | 42 | -- perform some operations/manipulations to the unix style path and print. 43 | print("\n-- Path Operations: ", up:toString()) 44 | 45 | -- create a new relative unix path and append it to the first unix path. 46 | local up2 = assert(path("extra/directory/", "UNIX")) 47 | up:append(up2) 48 | print("append relative: ", up2:toString()) 49 | 50 | -- print out each directory in the appended path. 51 | print("iterate directories: ", up:toString()) 52 | for i = 1, up:depth() do 53 | print(i, up:directory(i)) 54 | end 55 | 56 | -- pop the two appended directories. 57 | up:popDirectory() 58 | print("popDirectory: ", up:toString()) 59 | up:popDirectory() 60 | print("popDirectory: ", up:toString()) 61 | -------------------------------------------------------------------------------- /examples/process.lua: -------------------------------------------------------------------------------- 1 | --[[ process.lua 2 | This example shows how to spawn an external process, send and receive input to it via pipes. 3 | In this example, the environment.lua example will be run in a separate process. 4 | --]] 5 | 6 | local lua_cmd = os.getenv("LUACMD") or "/bin/lua" 7 | 8 | -- require prerequisites. 9 | local process = assert(require("poco.process")) 10 | local pipe = assert(require("poco.pipe")) 11 | local path = assert(require("poco.path")) 12 | local pipeistream = assert(require("poco.pipeistream")) 13 | 14 | -- construct anonymous pipes to attach to the process. 15 | local read_pipe = assert(pipe()) 16 | local err_pipe = assert(pipe()) 17 | 18 | -- Table containing process to launch, and all the optional parameters. 19 | local filename = "environment.lua" 20 | local worker_config = { 21 | command = lua_cmd, 22 | workingDir = path.current(), 23 | args = { filename }, 24 | outPipe = read_pipe, 25 | errPipe = err_pipe 26 | } 27 | 28 | -- attempt to launch the process 29 | local handle, error_msg = assert(process.launch(worker_config)) 30 | io.write(string.format("%s spawned with ID: %d\n", worker_config.command, handle:id())) 31 | 32 | local pipeis = assert(pipeistream(read_pipe)) 33 | local output = pipeis:read("*a") 34 | if output then io.write(output) end 35 | 36 | -- clean up after spawned process and retrieve the result with wait(). 37 | local result = handle:wait() 38 | -- check for a clean exit, or print out the error result and the error message. 39 | if result == 0 then 40 | io.write(string.format("\n%s completed successfully.\n", worker_config.command)) 41 | else 42 | local amount, msg = err_pipe:readBytes() 43 | io.write(string.format("\n%s failed status: %d msg: %s\n", worker_config.command, result, msg)) 44 | end 45 | -------------------------------------------------------------------------------- /examples/random.lua: -------------------------------------------------------------------------------- 1 | --[[ random.lua 2 | This example shows how the random pseudo random number generator module is used. 3 | --]] 4 | local random = assert(require("poco.random")) 5 | 6 | -- explicit construction using state_size, and a seed value 7 | -- local prng = assert(random(256, os.time())) 8 | 9 | -- explicit construction using just state_size and default internal Poco RandomInputStream seed. 10 | -- local prng = assert(random(256)) 11 | 12 | -- construction using default state_size of 256 and internal Poco RandomInputStream seed. 13 | local prng = assert(random()) 14 | 15 | 16 | -- generate some random numbers. 17 | for i = 1, 15 do 18 | print("\ninteger: ", prng:next()) 19 | print("modulo 100: ", prng:next(100)) 20 | print("number: ", prng:nextNumber()) 21 | print("byte: ", prng:nextByte()) 22 | print("bool: ", prng:nextBool()) 23 | end 24 | -------------------------------------------------------------------------------- /examples/regex.lua: -------------------------------------------------------------------------------- 1 | --[[ regex.lua 2 | This example shows how the regex module functions in a very similar fashion 3 | when compared to Lua patterns. 4 | --]] 5 | 6 | local regex = require("poco.regex") 7 | 8 | local url_test_port = "ftp://host.example.org:21/example/directory" 9 | local url_test_noport = "ftp://host.example.org/example/directory" 10 | 11 | -- using the [[string literal]] format for your regex enables you to avoid 12 | -- escaping backslashes. 13 | local url_pattern = [[(https?|ftp|smtp)://([^:/]+)(:\d+)?(/.*)]] 14 | local url_regex = regex(url_pattern) 15 | print("\nurl_pattern: ", url_pattern) 16 | 17 | -- use find to determine if pattern matches 18 | if url_regex:find(url_test_port) then 19 | print(string.format("\nurl_regex:find(\"%s\"): %s", url_test_port, tostring(true))) 20 | end 21 | 22 | if url_regex:find(url_test_noport) then 23 | print(string.format("\nurl_regex:find(\"%s\"): %s", url_test_noport, tostring(true))) 24 | end 25 | 26 | -- use match to extract matches. 27 | local url_prefix, url_host, url_port, url_path = url_regex:match(url_test_port) 28 | if url_prefix then 29 | print(string.format("\nurl_regex:match(\"%s\"):", url_test_port)) 30 | print("proto: ", url_prefix) 31 | print("host: ", url_host) 32 | print("port: ", url_port) 33 | print("path: ", url_path) 34 | end 35 | 36 | -- use gmatch to iterate through matches in a string 37 | local multi_urls = 38 | [[http://www.example.org:80/some/path 39 | http://www.example.org/some/other/path 40 | https://www.example.org:443/some/ssl/path]] 41 | 42 | print(string.format("\nmulti_urls:\n%s\n", multi_urls)) 43 | local gmatch_count = 0 44 | print("\nurl_regex:gmatch(multi_urls)") 45 | for url_prefix, url_host, url_port, url_path in url_regex:gmatch(multi_urls) do 46 | gmatch_count = gmatch_count + 1 47 | print("match:", gmatch_count) 48 | print("proto: ", url_prefix) 49 | print("host: ", url_host) 50 | print("port: ", url_port) 51 | print("path: ", url_path) 52 | end 53 | 54 | -- use gsub to convert certain types of urls listed in the table to another. 55 | local imap_test = "imap://mail.example.org/something" 56 | local replacements = { ["imap"] = "pop3", ["ftp"] = "http" } 57 | local proto_regex = regex([[^(\w+)(?=://)]]) 58 | print(string.format("\nproto_regex:gsub(\"%s\"):\n%s.", url_test_noport, proto_regex:gsub(url_test_noport, replacements))) 59 | print(string.format("\nproto_regex:gsub(\"%s\"):\n%s.", imap_test, proto_regex:gsub(imap_test, replacements))) 60 | -------------------------------------------------------------------------------- /examples/sharedmemory.lua: -------------------------------------------------------------------------------- 1 | --[[ sharedmemory.lua 2 | This example demonstrates how to utilize the sharedmemory module for inter process communication. 3 | The sharedmemory.lua file contains the controller and the worker code. The controller obtains and 4 | transmits data, while the worker processes it when signaled by the controller. 5 | --]] 6 | 7 | -- load prerequisite modules. 8 | local sharedmemory = assert(require("poco.sharedmemory")) 9 | local namedmutex = assert(require("poco.namedmutex")) 10 | local namedevent = assert(require("poco.namedevent")) 11 | 12 | local data_memory_name = "sharedmemory_data_example" 13 | local data_event_name = "sharedmemory_event" 14 | local data_mutex_name = "sharedmemory_mutex" 15 | local filename = "sharedmemory.lua" 16 | local shared_memory_size = 10000 17 | -- local lua_interpreter_path = "/usr/bin/lua" 18 | local lua_interpreter_path = "c:/msys64/mingw64/bin/lua.exe" 19 | 20 | -- construct synchronization mechanisms. 21 | local data_event = assert(namedevent(data_event_name)) 22 | local data_mutex = assert(namedmutex(data_mutex_name)) 23 | 24 | 25 | -- begin worker code. 26 | if arg[1] == "worker" then 27 | -- open the named sharedmemory region. 28 | local data_mem = assert(sharedmemory(data_memory_name, "read", shared_memory_size, false)) 29 | -- create a memoryistream for reading from the sharedmemory region. 30 | local memoryistream = assert(require("poco.memoryistream")) 31 | local mis = assert(memoryistream(data_mem)) 32 | local shutdown = false 33 | 34 | repeat 35 | -- set the read pointer to the beginning of the memory region. 36 | mis:seek("set", 0) 37 | -- wait for the data available event to be set, lock the mutex associated with 38 | -- the sharedmemory region. 39 | data_event:wait() 40 | data_mutex:lock() 41 | -- get the amount of data present in the shared memory encoded as text. 42 | -- if framing amount is 0 or the framing number is not present, 43 | -- interpret this condition as the sentinel value to shutdown. 44 | local line = mis:read("*l") 45 | local read_amount = tonumber(line or "") 46 | local data = nil 47 | 48 | if read_amount and read_amount ~= 0 then data = mis:read(read_amount) 49 | else shutdown = true end 50 | data_mutex:unlock() 51 | 52 | if data then print("worker: ", data) 53 | else shutdown = true end 54 | 55 | until shutdown 56 | print("worker: exiting!") 57 | -- begin controller code. 58 | else 59 | -- load prerequisite controller modules. 60 | local memoryostream = assert(require("poco.memoryostream")) 61 | local process = assert(require("poco.process")) 62 | local path = assert(require("poco.path")) 63 | -- construct sharedmemory and memoryostream for outputting to shared memory region. 64 | local data_mem = assert(sharedmemory(data_memory_name, "write", shared_memory_size, true)) 65 | local mos = assert(memoryostream(data_mem)) 66 | -- table containing process to launch and parameters. 67 | local worker_process = { 68 | command = lua_interpreter_path, 69 | workingDir = path.current(), 70 | args = { filename, "worker" }, 71 | } 72 | -- attempt to launch the process. 73 | local handle = assert(process.launch(worker_process)) 74 | io.write(string.format("controller: launched '%s %s %s' with ID: %d\n", 75 | worker_process.command, filename, "worker", handle:id())) 76 | 77 | print("controller: enter data to submit to worker, or an empty line to shutdown.") 78 | 79 | for line in io.lines() do 80 | -- transmit data overshared memory, then signal the worker to process it. 81 | local data = string.format("%d\n%s", #line, line) 82 | if #data <= shared_memory_size then 83 | data_mutex:lock() 84 | mos:write(data) 85 | mos:flush() 86 | data_mutex:unlock() 87 | data_event:set() 88 | else 89 | print("controller: entry is too big for buffer size: ", shared_memory_size) 90 | end 91 | -- reset the write position to the beginning. 92 | mos:seek("set", 0) 93 | -- if an empty line was sent, shutdown. 94 | if #line == 0 then break end 95 | end 96 | 97 | -- check for a clean exit, or print out the error result and the error message. 98 | local result = handle:wait() 99 | if result == 0 then print("controller: worker completed successfully.") 100 | else print("controller: worker failed with status: ", result) end 101 | end 102 | -------------------------------------------------------------------------------- /examples/streamcopier.lua: -------------------------------------------------------------------------------- 1 | --[[ streamcopier.lua 2 | This example shows how to use the streamcopier module to copy all data from an istream to an 3 | ostream. 4 | --]] 5 | 6 | -- require modules needed for this task. 7 | local fileostream = assert(require("poco.fileostream")) 8 | local fileistream = assert(require("poco.fileistream")) 9 | local deflatingostream = assert(require("poco.deflatingostream")) 10 | local streamcopier = assert(require("poco.streamcopier")) 11 | 12 | -- construct a source istream, destination ostream, and deflating ostream filter to be used in 13 | -- front of the destination. 14 | local filename = "example_data.txt" 15 | local fis = assert(fileistream(filename)) 16 | local dos = assert(deflatingostream(assert(fileostream(filename .. ".gz")),"STREAM_GZIP")) 17 | 18 | -- copy all data from input stream, through output stream filter, and to the destination. 19 | local bytes_copied = assert(streamcopier.copyStream(fis, dos)) 20 | -- close the filter to make sure all data is flushed to the destination. 21 | dos:close() 22 | 23 | print(string.format("%d bytes sent to %s", bytes_copied, filename .. ".gz")) 24 | 25 | 26 | -------------------------------------------------------------------------------- /examples/teeistream.lua: -------------------------------------------------------------------------------- 1 | --[[ teeistream.lua 2 | This example shows how a teeistream can be used to split an all data from an input stream 3 | into one or more ostream channels. 4 | --]] 5 | 6 | -- require modules needed for this task. 7 | local buffer = require("poco.buffer") 8 | local memoryistream = require("poco.memoryistream") 9 | local teeistream = require("poco.teeistream") 10 | local fileostream = require("poco.fileostream") 11 | 12 | -- note that this data could have come from any type of istream, memory, socket, file, or some other API. 13 | local mis = assert(memoryistream(buffer("Some data coming from an input stream.\nSome other data."))) 14 | 15 | -- adding several ostreams to a single teeistream, such that all read data gets copied to all ostreams. 16 | local tis = assert(teeistream(mis)) 17 | -- these output streams could be a deflating stream, encrypting stream, pipe, socket, etc. 18 | tis:addStream(fileostream("file1.txt"), fileostream("file2.txt")) 19 | 20 | print(tis:read("*a")) 21 | print("\ndone writing from teeistream, file1.txt and file2.txt written.") 22 | -------------------------------------------------------------------------------- /examples/teeostream.lua: -------------------------------------------------------------------------------- 1 | --[[ teeostream.lua 2 | This example shows how a teeostream can be used to split an output into one or more 3 | ostream channels. 4 | --]] 5 | 6 | -- require modules needed for this task. 7 | local teeostream = require("poco.teeostream") 8 | local fileostream = require("poco.fileostream") 9 | 10 | -- read all example data from the example file. 11 | -- note that this data could have come from a socket, file, or some other API, 12 | -- provided that the data is returned as a string, it can be used with memoryistream. 13 | local data = assert(io.open("example_data.txt", "rb")):read("*a") 14 | 15 | -- adding several ostreams to a single teeostream, such that all writes go to all ostreams. 16 | local tos = teeostream(assert(fileostream("file1.txt")), assert(fileostream("file2.txt"))) 17 | assert(tos:write("Hello World from teeostream.lua.")) 18 | assert(tos:flush()) 19 | print("done writing to teeostream, file1.txt and file2.txt written.") 20 | -------------------------------------------------------------------------------- /examples/temporaryfile.lua: -------------------------------------------------------------------------------- 1 | --[[ temporaryfile.lua 2 | This example demonstrates the temporaryfile module. It generates a temporary file path, that 3 | is automatically removed upon destruction of the userdata. 4 | 5 | The temporaryfile userdata inherits all methods from the file module. 6 | --]] 7 | 8 | temporaryfile = assert(require("poco.temporaryfile")) 9 | -- generate a temporary file. 10 | local tf1 = assert(temporaryfile()) 11 | print("path: ", tf1:path()) 12 | print("exists: ", tf1:exists()) 13 | 14 | -- create the file on the filesystem, and set its size to 100. 15 | print("createFile: ", tf1:createFile()) 16 | print("exists: ", tf1:exists()) 17 | print("setSize: ", tf1:setSize(100)) 18 | print("size: ", tf1:size()) 19 | 20 | -- generate a temporary name: 21 | print("temporary name: ", temporaryfile.tempName()) 22 | -------------------------------------------------------------------------------- /examples/thread.lua: -------------------------------------------------------------------------------- 1 | --[[ thread.lua 2 | This example shows how to run Lua code in a separate Lua state via a native thread. 3 | --]] 4 | 5 | -- worker_thread() 6 | -- The thread entrypoint function. The name is arbitrary. 7 | 8 | -- Note: lexically captured variables (upvalues) of the thread entrypoint function 9 | -- are not preserved in the new Lua state which hosts the thread, only the values 10 | -- passed as arguments. 11 | local function worker_thread(output_file) 12 | local env = assert(require("poco.environment")) 13 | local of = assert(io.open(output_file, "w")) 14 | of:write("osName: ", env.osName(), "\n") 15 | of:write("osArchitecture: ", env.osArchitecture(), "\n") 16 | of:write("osDisplayName: ", env.osDisplayName(), "\n") 17 | of:write("osVersion: ", env.osVersion(), "\n") 18 | of:write("libraryVersion:", env.libraryVersion(), "\n") 19 | of:close() 20 | return 21 | end 22 | 23 | -- Main code that spawns the thread to do some work, then waits for it to complete. 24 | -- Add a local namespace for poco modules. 25 | local poco = {} 26 | poco.path = assert(require("poco.path")) 27 | poco.thread = assert(require("poco.thread")) 28 | 29 | -- Construct a new thread 30 | local wt = assert(poco.thread()) 31 | 32 | -- Start the thread and pass a path as a parameter for it to write to. 33 | local worker_output_file = poco.path.temp() .. "wtdata.txt" 34 | print(string.format("starting worker_thread %s outputting to %s", wt, worker_output_file)) 35 | assert(wt:start(worker_thread, worker_output_file)) 36 | 37 | print("waiting for thread to finish.") 38 | assert(wt:join()) 39 | 40 | print("thread finished with status: ", wt:result()) 41 | -------------------------------------------------------------------------------- /examples/timestamp.lua: -------------------------------------------------------------------------------- 1 | --[[ timestamp.lua 2 | This example shows how the varius capabilities of the timestamp module. 3 | Timestamps are represented in UTC time values. 4 | 5 | Any time timestamp value is returned to Lua, they are returned as 64-bit integers encoded in 6 | strings. The rationale for this is due to lua_Number size limitations. 7 | --]] 8 | 9 | -- load the poco.timestamp module. 10 | local timestamp = assert(require("poco.timestamp")) 11 | 12 | -- capture the current timestamp. 13 | local ts1 = timestamp() 14 | -- print out the microseconds since UTC epoch. 15 | print(string.format("\nmicroseconds since the UTC epoch (%s)", os.date("!%c", 0))) 16 | print("\t", ts1:epochMicroseconds(), "\n") 17 | 18 | -- The epochTime function's return value is equivalent to os.time()'s return value 19 | -- as the microsecond resolution is truncated to seconds. 20 | print("\nlocal date and time: (UTC)") 21 | print("\t", os.date("!%c", ts1:epochTime()), "\n") 22 | print("local date and time:") 23 | print("\t", os.date("%c", ts1:epochTime()), "\n") 24 | 25 | -- count how many loop iterations pass before a change is noticed. 26 | -- note: on Windows, the elapsed value will be a bit higher due to minimum OS scheduling latencies. 27 | -- on Linux and else where, there should only be a single loop pass with some 28 | -- small number of microseconds elapsed. 29 | 30 | -- Note that values used for adding/subtracting from a timestamp, and the values themselves inside 31 | -- of Lua are 64-bit integers, but in string representation. The rationale for the string representation 32 | -- is that luajit, Lua 5.1 and 5.2 do not have a 64-bit capable number type. 33 | local elapsed = "0" 34 | local counter = 0 35 | repeat 36 | elapsed = ts1:elapsed() 37 | counter = counter + 1 38 | until elapsed ~= "0" 39 | 40 | print("\nmicroseconds taken to notice a timestamp delta:") 41 | print("\t", elapsed, "\n") 42 | print("loop iterations to notice a timestamp delta:") 43 | print("\t", counter, "\n") 44 | 45 | local ts2 = timestamp() 46 | 47 | -- timestamp userdata can tested for equality or compared. 48 | print("\ntimestamp 1 comparisons with timestamp 2:") 49 | print("ts1 == ts2:\t", ts1 == ts2) 50 | print("ts1 < ts2:\t", ts1 < ts2) 51 | print("ts2 < ts1:\t", ts2 < ts1) 52 | 53 | -- timestamp userdata can be shifted with addition or subtraction of microseconds. 54 | -- the value passed is an 64-bit integer in the form of a string. 55 | print("\ntimestamp shifting via addition and subtraction:") 56 | print("ts2 + 20000:\t", (ts2 + tostring(20000)):epochMicroseconds()) 57 | print("ts2 - 10000:\t", (ts2 - tostring(10000)):epochMicroseconds()) 58 | 59 | -- one timestamp can be subtracted from another in order to create a delta. 60 | print("\ntimestamp deltas:") 61 | print("ts2 - ts1:\t", (ts2 - ts1):epochMicroseconds()) 62 | 63 | -- even more granular timestamp's are possible by calling utcTime() 64 | print("\n100s of nanosecond intervals since midnight, October 15, 1582:") 65 | print("timestamp():utcTime():\t", timestamp():utcTime()) 66 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(LUAPOCO_SRC 2 | Userdata.cpp 3 | StateTransfer.cpp) 4 | 5 | set(FOUNDATION_SRC 6 | foundation/File.cpp 7 | foundation/Timestamp.cpp 8 | foundation/DynamicAny.cpp 9 | foundation/RegularExpression.cpp 10 | foundation/Checksum.cpp 11 | foundation/Environment.cpp 12 | foundation/Pipe.cpp 13 | foundation/NamedEvent.cpp 14 | foundation/NamedMutex.cpp 15 | foundation/ProcessHandle.cpp 16 | foundation/Process.cpp 17 | foundation/Semaphore.cpp 18 | foundation/FastMutex.cpp 19 | foundation/Mutex.cpp 20 | foundation/Thread.cpp 21 | foundation/Event.cpp 22 | foundation/IStream.cpp 23 | foundation/OStream.cpp 24 | foundation/PipeOStream.cpp 25 | foundation/PipeIStream.cpp 26 | foundation/FileIStream.cpp 27 | foundation/FileOStream.cpp 28 | foundation/InflatingIStream.cpp 29 | foundation/InflatingOStream.cpp 30 | foundation/DeflatingIStream.cpp 31 | foundation/DeflatingOStream.cpp 32 | foundation/Path.cpp 33 | foundation/Notification.cpp 34 | foundation/NotificationFactory.cpp 35 | foundation/NotificationQueue.cpp 36 | foundation/Buffer.cpp 37 | foundation/MemoryIStream.cpp 38 | foundation/MemoryOStream.cpp 39 | foundation/TeeOStream.cpp 40 | foundation/TeeIStream.cpp 41 | foundation/TaskManager.cpp 42 | foundation/JSON.cpp 43 | foundation/Compress.cpp 44 | foundation/Decompress.cpp 45 | foundation/StreamCopier.cpp 46 | foundation/SharedMemory.cpp 47 | foundation/TemporaryFile.cpp 48 | foundation/Condition.cpp 49 | foundation/Base64Encoder.cpp 50 | foundation/Base64Decoder.cpp 51 | foundation/Base32Encoder.cpp 52 | foundation/Base32Decoder.cpp 53 | foundation/HexBinaryEncoder.cpp 54 | foundation/HexBinaryDecoder.cpp 55 | foundation/Random.cpp 56 | ) 57 | 58 | include_directories(${CMAKE_CURRENT_SOURCE_DIR}) 59 | 60 | if(WIN32) 61 | add_definitions(-DPOCO_NO_AUTOMATIC_LIBS) 62 | if(MSVC) 63 | find_library(LIBIPHLPAPI iphlpapi) 64 | set(PLATFORM_EXTRAS ${LIBIPHLPAPI}) 65 | endif() 66 | elseif(UNIX) 67 | find_library(LIBPTHREAD pthread) 68 | find_library(LIBRT rt) 69 | set(PLATFORM_EXTRAS ${LIBPTHREAD} ${LIBRT}) 70 | endif() 71 | 72 | set(CXX_STANDARD_REQUIRED ON) 73 | 74 | if(USE_EMBEDDED_POCO) 75 | link_directories(${POCO_INSTALL_DIR}/lib) 76 | endif() 77 | 78 | add_library(poco SHARED ${LUAPOCO_SRC} ${FOUNDATION_SRC}) 79 | 80 | if(USE_EMBEDDED_POCO) 81 | add_dependencies(poco poco_static) 82 | target_link_libraries(poco ${LUA_LIB} PocoFoundation${PocoInternalSuffix} PocoJSON${PocoInternalSuffix} PocoZip${PocoInternalSuffix} ${PLATFORM_EXTRAS}) 83 | else() 84 | target_link_libraries(poco ${LUA_LIB} ${POCO_FOUNDATION_LIB} ${POCO_JSON_LIB} ${POCO_ZIP_LIB} ${PLATFORM_EXTRAS}) 85 | endif() 86 | 87 | set_target_properties(poco PROPERTIES PREFIX "" CXX_STANDARD 14) 88 | 89 | install(TARGETS poco RUNTIME DESTINATION ${CMAKE_BINARY_DIR} LIBRARY DESTINATION ${CMAKE_BINARY_DIR}) 90 | -------------------------------------------------------------------------------- /src/LuaPoco.h: -------------------------------------------------------------------------------- 1 | #ifndef LUAPOCO_H 2 | #define LUAPOCO_H 3 | 4 | #ifdef _WIN32 5 | #ifdef poco_EXPORTS 6 | #define LUAPOCO_API __declspec(dllexport) 7 | #else 8 | #define LUAPOCO_API __declspec(dllimport) 9 | #endif 10 | #else 11 | #define LUAPOCO_API 12 | #endif 13 | 14 | #ifdef USE_LUA_AS_CPP 15 | // define variable via CMAKE configure time to 16 | // link against a C++ compilation of Lua 17 | #include "lua.h" 18 | #include "lualib.h" 19 | #include "lauxlib.h" 20 | 21 | #else 22 | // include as a C library 23 | extern "C" 24 | { 25 | #include "lua.h" 26 | #include "lualib.h" 27 | #include "lauxlib.h" 28 | } 29 | 30 | #endif 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /src/LuaPocoUtils.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "LuaPoco.h" 4 | 5 | namespace LuaPoco 6 | { 7 | 8 | template 9 | bool checkUnsignedToLuaInteger(T num, lua_Integer& li) 10 | { 11 | static_assert(std::numeric_limits::radix == 2, 12 | "checkUnsignedToLuaInteger requires binary representation for source type."); 13 | 14 | if (num <= (std::numeric_limits::max)()) 15 | { 16 | li = static_cast(num); 17 | #if LUA_VERSION_NUM < 503 18 | // corollary to Javascript's MAX_SAFE_INTEGER. 19 | // As Lua 5.1, and 5.2 use doubles to store numbers, make sure this lua_Integer can be 20 | // stored without losing precision. 21 | 22 | // if the lua_Integer type has more bits than lua_Number, calculate the delta in bits, and 23 | // shift the maximum lua_Integer value down to match the number of bits available in the 24 | // lua_Number, and see if the current value is within range. 25 | const int delta = std::numeric_limits::digits - std::numeric_limits::digits; 26 | if (delta > 0 && (num < ((std::numeric_limits::max)() >> delta))) { return true; } 27 | #else 28 | return true; 29 | #endif 30 | } 31 | 32 | return false; 33 | } 34 | 35 | template 36 | bool checkSignedToLuaInteger(T num, lua_Integer& li) 37 | { 38 | static_assert(std::numeric_limits::radix == 2, 39 | "checkSignedToLuaInteger requires binary representation for source type."); 40 | 41 | if (num > 0) return checkUnsignedToLuaInteger(num, li); 42 | else if (num >= (std::numeric_limits::min)()) 43 | { 44 | li = static_cast(num); 45 | #if LUA_VERSION_NUM < 503 46 | // corollary to Javascript's MIN_SAFE_INTEGER, see decription for checkUnsignedToLuaInteger. 47 | const int delta = std::numeric_limits::digits - std::numeric_limits::digits; 48 | if (delta > 0 && (num > ((std::numeric_limits::min)() >> delta))) { return true; } 49 | #else 50 | return true; 51 | #endif 52 | } 53 | 54 | return false; 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /src/StateTransfer.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_STATETRANSFER_H 2 | #define LUA_POCO_STATETRANSFER_H 3 | 4 | #include "LuaPoco.h" 5 | 6 | namespace LuaPoco 7 | { 8 | 9 | int functionWriter(lua_State* L, const void* p, size_t sz, void* ud); 10 | const char* functionReader(lua_State* L, void* data, size_t* size); 11 | bool transferFunction(lua_State* toL, lua_State* fromL); 12 | bool transferValue(lua_State* toL, lua_State* fromL); 13 | 14 | } // LuaPoco 15 | 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /src/Userdata.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_USERDATA_H 2 | #define LUA_POCO_USERDATA_H 3 | 4 | #include "LuaPoco.h" 5 | #include 6 | #include 7 | 8 | #define USERDATA_PRIVATE_TABLE "poco_userdata_private" 9 | 10 | namespace LuaPoco 11 | { 12 | 13 | // a utility class for doing RAII style cleanup of a Lua state due to early returns. 14 | class LuaStateHolder 15 | { 16 | public: 17 | lua_State* state; 18 | LuaStateHolder(lua_State* L); 19 | ~LuaStateHolder(); 20 | lua_State* extract(); 21 | }; 22 | 23 | // base class for all userdata 24 | class Userdata 25 | { 26 | public: 27 | Userdata(); 28 | virtual ~Userdata(); 29 | virtual bool copyToState(lua_State *L); 30 | protected: 31 | // generic gc metamethod to reduce code duplication between derived classes. 32 | static int metamethod__gc(lua_State* L); 33 | private: 34 | Userdata(const Userdata& disabledCopy); 35 | Userdata& operator=(const Userdata& disabledAssignment); 36 | }; 37 | 38 | // generic functions to reduce the amount of copy and paste code. 39 | int pushPocoException(lua_State* L, const Poco::Exception& e); 40 | int pushException(lua_State* L, const std::exception& e); 41 | int pushUnknownException(lua_State* L); 42 | 43 | struct CFunctions 44 | { 45 | const char* name; 46 | lua_CFunction fn; 47 | }; 48 | 49 | // installs methods into table at the top of the stack. 50 | void setCFunctions(lua_State* L, CFunctions* methods); 51 | 52 | // since the register functions between 5.1, and 5.2 changed, use an agnostic version. 53 | // creates a new metatable with metatableName, and installs methods into it. 54 | void setupUserdataMetatable(lua_State* L, const char* metatableName, CFunctions* methods); 55 | 56 | // NOTE: requires that the userdata value be on the top of the Lua stack. 57 | // attaches the appropriate metatable to the userdata 58 | // and stores the Userdata* in the private table. 59 | void setupPocoUserdata(lua_State* L, Userdata* ud, const char* metatableName); 60 | 61 | // constructs the private table for mapping a specific Userdata pointer to the base Userdata pointer. 62 | void setupPrivateUserdata(lua_State* L); 63 | 64 | // prepares the module table for the normal userdata contructor pattern 65 | // that most modules use for creating a userdata via 66 | // module.new() or module() 67 | int loadConstructor(lua_State*L, lua_CFunction cons); 68 | 69 | // sets the association between a specific Userdata pointer and the base Userdata pointer. 70 | void setPrivateUserdata(lua_State* L, int userdataIdx, Userdata* ud); 71 | 72 | // gets the base Userdata pointer associated with a specific Userdata pointer. 73 | Userdata* getPrivateUserdata(lua_State* L, int userdataIdx); 74 | 75 | // generic to validate that a Userdata* can be dynamic_cast to a specific Userdata pointer, lua_error() if not. 76 | template 77 | T* checkPrivateUserdata(lua_State* L, int userdataIdx) 78 | { 79 | T* derived = NULL; 80 | userdataIdx = userdataIdx < 0 ? lua_gettop(L) + 1 + userdataIdx : userdataIdx; 81 | 82 | luaL_checktype(L, userdataIdx, LUA_TUSERDATA); 83 | // 1. getPrivateUserdata returns NULL if passed an userdata which is not present in the 84 | // poco_userdata_private table in the registry. 85 | // 2. in getPrivateUserdata, lua_touserdata() returns NULL when passed nil. (ie: not found) 86 | // 3. dynamic_cast applied to NULL results in NULL. 87 | derived = dynamic_cast(getPrivateUserdata(L, userdataIdx)); 88 | if (derived == NULL) luaL_error(L, "invalid userdata, expected: %s", typeid(T).name()); 89 | 90 | return derived; 91 | } 92 | 93 | } // LuaPoco 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /src/foundation/Base32Decoder.cpp: -------------------------------------------------------------------------------- 1 | /// base32decoder 2 | // An istream interface for inputting base32 encoded data. 3 | // @module base32decoder 4 | #include "Base32Decoder.h" 5 | #include 6 | #include 7 | #include 8 | 9 | int luaopen_poco_base32decoder(lua_State* L) 10 | { 11 | LuaPoco::Base32DecoderUserdata::registerBase32Decoder(L); 12 | return LuaPoco::loadConstructor(L, LuaPoco::Base32DecoderUserdata::Base32Decoder); 13 | } 14 | 15 | namespace LuaPoco 16 | { 17 | 18 | const char* POCO_BASE32DECODER_METATABLE_NAME = "Poco.Base32Decoder.metatable"; 19 | 20 | Base32DecoderUserdata::Base32DecoderUserdata(std::istream & istream, int ref) 21 | : mBase32Decoder(istream) 22 | , mUdReference(ref) 23 | , mClosed(false) 24 | { 25 | } 26 | 27 | Base32DecoderUserdata::~Base32DecoderUserdata() 28 | { 29 | } 30 | 31 | std::istream& Base32DecoderUserdata::istream() 32 | { 33 | return mBase32Decoder; 34 | } 35 | 36 | // register metatable for this class 37 | bool Base32DecoderUserdata::registerBase32Decoder(lua_State* L) 38 | { 39 | struct CFunctions methods[] = 40 | { 41 | { "__gc", metamethod__gc }, 42 | { "__tostring", metamethod__tostring }, 43 | { "read", read }, 44 | { "lines", lines }, 45 | { "seek", seek }, 46 | { NULL, NULL} 47 | }; 48 | 49 | setupUserdataMetatable(L, POCO_BASE32DECODER_METATABLE_NAME, methods); 50 | return true; 51 | } 52 | 53 | /// Constructs a new base32decoder userdata. 54 | // @tparam userdata istream destination for base32 encoded data. 55 | // @return userdata or nil. (error) 56 | // @return error message. 57 | // @function new 58 | // @see istream 59 | int Base32DecoderUserdata::Base32Decoder(lua_State* L) 60 | { 61 | int firstArg = lua_istable(L, 1) ? 2 : 1; 62 | IStream* is = checkPrivateUserdata(L, firstArg); 63 | 64 | lua_pushvalue(L, firstArg); 65 | int ref = luaL_ref(L, LUA_REGISTRYINDEX); 66 | 67 | Base32DecoderUserdata* b32dud = NULL; 68 | void* p = lua_newuserdata(L, sizeof *b32dud); 69 | 70 | try 71 | { 72 | b32dud = new(p) Base32DecoderUserdata(is->istream(), ref); 73 | } 74 | catch (const std::exception& e) 75 | { 76 | luaL_unref(L, LUA_REGISTRYINDEX, ref); 77 | return pushException(L, e); 78 | } 79 | 80 | setupPocoUserdata(L, b32dud, POCO_BASE32DECODER_METATABLE_NAME); 81 | return 1; 82 | } 83 | 84 | // metamethod infrastructure 85 | int Base32DecoderUserdata::metamethod__tostring(lua_State* L) 86 | { 87 | Base32DecoderUserdata* b32dud = checkPrivateUserdata(L, 1); 88 | lua_pushfstring(L, "Poco.Base32Decoder (%p)", static_cast(b32dud)); 89 | 90 | return 1; 91 | } 92 | 93 | int Base32DecoderUserdata::metamethod__gc(lua_State* L) 94 | { 95 | Base32DecoderUserdata* b32dud = checkPrivateUserdata(L, 1); 96 | luaL_unref(L, LUA_REGISTRYINDEX, b32dud->mUdReference); 97 | b32dud->~Base32DecoderUserdata(); 98 | 99 | return 0; 100 | } 101 | /// 102 | // @type base32decoder 103 | 104 | } // LuaPoco 105 | -------------------------------------------------------------------------------- /src/foundation/Base32Decoder.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_BASE32DECODER_H 2 | #define LUA_POCO_BASE32DECODER_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include "IStream.h" 7 | #include 8 | 9 | extern "C" 10 | { 11 | LUAPOCO_API int luaopen_poco_base32decoder(lua_State* L); 12 | } 13 | 14 | namespace LuaPoco 15 | { 16 | 17 | extern const char* POCO_BASE32DECODER_METATABLE_NAME; 18 | 19 | class Base32DecoderUserdata : public Userdata, public IStream 20 | { 21 | public: 22 | Base32DecoderUserdata(std::istream & istr, int ref); 23 | virtual ~Base32DecoderUserdata(); 24 | virtual std::istream& istream(); 25 | // register metatable for this class 26 | static bool registerBase32Decoder(lua_State* L); 27 | // constructor function 28 | static int Base32Decoder(lua_State* L); 29 | 30 | Poco::Base32Decoder mBase32Decoder; 31 | private: 32 | int mUdReference; 33 | bool mClosed; 34 | // metamethod infrastructure 35 | static int metamethod__tostring(lua_State* L); 36 | static int metamethod__gc(lua_State* L); 37 | // methods 38 | static int close(lua_State* L); 39 | }; 40 | 41 | } // LuaPoco 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/foundation/Base32Encoder.cpp: -------------------------------------------------------------------------------- 1 | /// base32encoder 2 | // An ostream interface for outputting base32 encoded data. 3 | // @module base32encoder 4 | #include "Base32Encoder.h" 5 | #include 6 | #include 7 | 8 | int luaopen_poco_base32encoder(lua_State* L) 9 | { 10 | LuaPoco::Base32EncoderUserdata::registerBase32Encoder(L); 11 | return LuaPoco::loadConstructor(L, LuaPoco::Base32EncoderUserdata::Base32Encoder); 12 | } 13 | 14 | namespace LuaPoco 15 | { 16 | 17 | const char* POCO_BASE32ENCODER_METATABLE_NAME = "Poco.Base32Encoder.metatable"; 18 | 19 | Base32EncoderUserdata::Base32EncoderUserdata(std::ostream & ostream, bool padding, int ref) 20 | : mBase32Encoder(ostream, padding) 21 | , mUdReference(ref) 22 | , mClosed(false) 23 | { 24 | } 25 | 26 | Base32EncoderUserdata::~Base32EncoderUserdata() 27 | { 28 | } 29 | 30 | std::ostream& Base32EncoderUserdata::ostream() 31 | { 32 | return mBase32Encoder; 33 | } 34 | 35 | // register metatable for this class 36 | bool Base32EncoderUserdata::registerBase32Encoder(lua_State* L) 37 | { 38 | struct CFunctions methods[] = 39 | { 40 | { "__gc", metamethod__gc }, 41 | { "__tostring", metamethod__tostring }, 42 | { "write", write }, 43 | { "flush", flush }, 44 | { "seek", seek }, 45 | { "close", close }, 46 | { NULL, NULL} 47 | }; 48 | 49 | setupUserdataMetatable(L, POCO_BASE32ENCODER_METATABLE_NAME, methods); 50 | return true; 51 | } 52 | 53 | /// Constructs a new base32encoder userdata. 54 | // @tparam userdata ostream destination for base 32 encoded data. 55 | // @bool[opt] padding specifies to use padding or not. 56 | // @return userdata or nil. (error) 57 | // @return error message. 58 | // @function new 59 | // @see ostream 60 | int Base32EncoderUserdata::Base32Encoder(lua_State* L) 61 | { 62 | int firstArg = lua_istable(L, 1) ? 2 : 1; 63 | OStream* os = checkPrivateUserdata(L, firstArg); 64 | int options = 0; 65 | int padding = true; 66 | if (lua_isboolean(L, firstArg + 1)) { padding = lua_toboolean(L, firstArg + 1); } 67 | 68 | lua_pushvalue(L, firstArg); 69 | int ref = luaL_ref(L, LUA_REGISTRYINDEX); 70 | 71 | Base32EncoderUserdata* b32eud = NULL; 72 | void* p = lua_newuserdata(L, sizeof *b32eud); 73 | 74 | try 75 | { 76 | b32eud = new(p) Base32EncoderUserdata(os->ostream(), padding, ref); 77 | } 78 | catch (const std::exception& e) 79 | { 80 | luaL_unref(L, LUA_REGISTRYINDEX, ref); 81 | return pushException(L, e); 82 | } 83 | 84 | setupPocoUserdata(L, b32eud, POCO_BASE32ENCODER_METATABLE_NAME); 85 | return 1; 86 | } 87 | 88 | // metamethod infrastructure 89 | int Base32EncoderUserdata::metamethod__tostring(lua_State* L) 90 | { 91 | Base32EncoderUserdata* b32eud = checkPrivateUserdata(L, 1); 92 | lua_pushfstring(L, "Poco.Base32Encoder (%p)", static_cast(b32eud)); 93 | 94 | return 1; 95 | } 96 | 97 | int Base32EncoderUserdata::metamethod__gc(lua_State* L) 98 | { 99 | Base32EncoderUserdata* b32eud = checkPrivateUserdata(L, 1); 100 | if (!b32eud->mClosed) { b32eud->mBase32Encoder.close(); } 101 | luaL_unref(L, LUA_REGISTRYINDEX, b32eud->mUdReference); 102 | b32eud->~Base32EncoderUserdata(); 103 | 104 | return 0; 105 | } 106 | /// 107 | // @type base32encoder 108 | 109 | /// Closes base32encoder 110 | // Flushes all encoded output to the destination ostream. 111 | // @function close 112 | int Base32EncoderUserdata::close(lua_State* L) 113 | { 114 | Base32EncoderUserdata* b32eud = checkPrivateUserdata(L, 1); 115 | if (!b32eud->mClosed) { b32eud->mClosed = true; b32eud->mBase32Encoder.close(); } 116 | return 0; 117 | } 118 | 119 | } // LuaPoco 120 | -------------------------------------------------------------------------------- /src/foundation/Base32Encoder.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_BASE32ENCODER_H 2 | #define LUA_POCO_BASE32ENCODER_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include "OStream.h" 7 | #include 8 | 9 | extern "C" 10 | { 11 | LUAPOCO_API int luaopen_poco_base32encoder(lua_State* L); 12 | } 13 | 14 | namespace LuaPoco 15 | { 16 | 17 | extern const char* POCO_BASE32ENCODER_METATABLE_NAME; 18 | 19 | class Base32EncoderUserdata : public Userdata, public OStream 20 | { 21 | public: 22 | Base32EncoderUserdata(std::ostream & ostr, bool padding, int ref); 23 | virtual ~Base32EncoderUserdata(); 24 | virtual std::ostream& ostream(); 25 | // register metatable for this class 26 | static bool registerBase32Encoder(lua_State* L); 27 | // constructor function 28 | static int Base32Encoder(lua_State* L); 29 | 30 | Poco::Base32Encoder mBase32Encoder; 31 | private: 32 | int mUdReference; 33 | bool mClosed; 34 | // metamethod infrastructure 35 | static int metamethod__tostring(lua_State* L); 36 | static int metamethod__gc(lua_State* L); 37 | // methods 38 | static int close(lua_State* L); 39 | }; 40 | 41 | } // LuaPoco 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/foundation/Base64Decoder.cpp: -------------------------------------------------------------------------------- 1 | /// base64decoder 2 | // An istream interface for inputting base64 encoded data. 3 | // @module base64decoder 4 | #include "Base64Decoder.h" 5 | #include 6 | #include 7 | #include 8 | 9 | int luaopen_poco_base64decoder(lua_State* L) 10 | { 11 | LuaPoco::Base64DecoderUserdata::registerBase64Decoder(L); 12 | return LuaPoco::loadConstructor(L, LuaPoco::Base64DecoderUserdata::Base64Decoder); 13 | } 14 | 15 | namespace LuaPoco 16 | { 17 | 18 | const char* POCO_BASE64DECODER_METATABLE_NAME = "Poco.Base64Decoder.metatable"; 19 | 20 | Base64DecoderUserdata::Base64DecoderUserdata(std::istream & istream, int options, int ref) 21 | : mBase64Decoder(istream, options) 22 | , mUdReference(ref) 23 | , mClosed(false) 24 | { 25 | } 26 | 27 | Base64DecoderUserdata::~Base64DecoderUserdata() 28 | { 29 | } 30 | 31 | std::istream& Base64DecoderUserdata::istream() 32 | { 33 | return mBase64Decoder; 34 | } 35 | 36 | // register metatable for this class 37 | bool Base64DecoderUserdata::registerBase64Decoder(lua_State* L) 38 | { 39 | struct CFunctions methods[] = 40 | { 41 | { "__gc", metamethod__gc }, 42 | { "__tostring", metamethod__tostring }, 43 | { "read", read }, 44 | { "lines", lines }, 45 | { "seek", seek }, 46 | { NULL, NULL} 47 | }; 48 | 49 | setupUserdataMetatable(L, POCO_BASE64DECODER_METATABLE_NAME, methods); 50 | return true; 51 | } 52 | 53 | /// Constructs a new base64decoder userdata. 54 | // @tparam userdata istream destination for base64 encoded data. 55 | // @string[opt] options "url_encoding", "no_padding", or both separated by space or commas. 56 | // @return userdata or nil. (error) 57 | // @return error message. 58 | // @function new 59 | // @see istream 60 | int Base64DecoderUserdata::Base64Decoder(lua_State* L) 61 | { 62 | int firstArg = lua_istable(L, 1) ? 2 : 1; 63 | IStream* is = checkPrivateUserdata(L, firstArg); 64 | int options = 0; 65 | const char* optionsStr = lua_tostring(L, firstArg + 1); 66 | if (optionsStr) 67 | { 68 | if (std::strstr(optionsStr, "url_encoding")) { options |= Poco::BASE64_URL_ENCODING; } 69 | if (std::strstr(optionsStr, "no_padding")) { options |= Poco::BASE64_NO_PADDING; } 70 | } 71 | 72 | lua_pushvalue(L, firstArg); 73 | int ref = luaL_ref(L, LUA_REGISTRYINDEX); 74 | 75 | Base64DecoderUserdata* b64dud = NULL; 76 | void* p = lua_newuserdata(L, sizeof *b64dud); 77 | 78 | try 79 | { 80 | b64dud = new(p) Base64DecoderUserdata(is->istream(), options, ref); 81 | } 82 | catch (const std::exception& e) 83 | { 84 | luaL_unref(L, LUA_REGISTRYINDEX, ref); 85 | return pushException(L, e); 86 | } 87 | 88 | setupPocoUserdata(L, b64dud, POCO_BASE64DECODER_METATABLE_NAME); 89 | return 1; 90 | } 91 | 92 | // metamethod infrastructure 93 | int Base64DecoderUserdata::metamethod__tostring(lua_State* L) 94 | { 95 | Base64DecoderUserdata* b64dud = checkPrivateUserdata(L, 1); 96 | lua_pushfstring(L, "Poco.Base64Decoder (%p)", static_cast(b64dud)); 97 | 98 | return 1; 99 | } 100 | 101 | int Base64DecoderUserdata::metamethod__gc(lua_State* L) 102 | { 103 | Base64DecoderUserdata* b64dud = checkPrivateUserdata(L, 1); 104 | luaL_unref(L, LUA_REGISTRYINDEX, b64dud->mUdReference); 105 | b64dud->~Base64DecoderUserdata(); 106 | 107 | return 0; 108 | } 109 | /// 110 | // @type base64decoder 111 | 112 | } // LuaPoco 113 | -------------------------------------------------------------------------------- /src/foundation/Base64Decoder.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_BASE64DECODER_H 2 | #define LUA_POCO_BASE64DECODER_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include "IStream.h" 7 | #include 8 | 9 | extern "C" 10 | { 11 | LUAPOCO_API int luaopen_poco_base64decoder(lua_State* L); 12 | } 13 | 14 | namespace LuaPoco 15 | { 16 | 17 | extern const char* POCO_BASE64DECODER_METATABLE_NAME; 18 | 19 | class Base64DecoderUserdata : public Userdata, public IStream 20 | { 21 | public: 22 | Base64DecoderUserdata(std::istream & istr, int options, int ref); 23 | virtual ~Base64DecoderUserdata(); 24 | virtual std::istream& istream(); 25 | // register metatable for this class 26 | static bool registerBase64Decoder(lua_State* L); 27 | // constructor function 28 | static int Base64Decoder(lua_State* L); 29 | 30 | Poco::Base64Decoder mBase64Decoder; 31 | private: 32 | int mUdReference; 33 | bool mClosed; 34 | // metamethod infrastructure 35 | static int metamethod__tostring(lua_State* L); 36 | static int metamethod__gc(lua_State* L); 37 | // methods 38 | static int close(lua_State* L); 39 | }; 40 | 41 | } // LuaPoco 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/foundation/Base64Encoder.cpp: -------------------------------------------------------------------------------- 1 | /// base64encoder 2 | // An ostream interface for outputting base64 encoded data. 3 | // @module base64encoder 4 | #include "Base64Encoder.h" 5 | #include 6 | #include 7 | 8 | int luaopen_poco_base64encoder(lua_State* L) 9 | { 10 | LuaPoco::Base64EncoderUserdata::registerBase64Encoder(L); 11 | return LuaPoco::loadConstructor(L, LuaPoco::Base64EncoderUserdata::Base64Encoder); 12 | } 13 | 14 | namespace LuaPoco 15 | { 16 | 17 | const char* POCO_BASE64ENCODER_METATABLE_NAME = "Poco.Base64Encoder.metatable"; 18 | 19 | Base64EncoderUserdata::Base64EncoderUserdata(std::ostream & ostream, int options, int ref) 20 | : mBase64Encoder(ostream, options) 21 | , mUdReference(ref) 22 | , mClosed(false) 23 | { 24 | } 25 | 26 | Base64EncoderUserdata::~Base64EncoderUserdata() 27 | { 28 | } 29 | 30 | std::ostream& Base64EncoderUserdata::ostream() 31 | { 32 | return mBase64Encoder; 33 | } 34 | 35 | // register metatable for this class 36 | bool Base64EncoderUserdata::registerBase64Encoder(lua_State* L) 37 | { 38 | struct CFunctions methods[] = 39 | { 40 | { "__gc", metamethod__gc }, 41 | { "__tostring", metamethod__tostring }, 42 | { "write", write }, 43 | { "flush", flush }, 44 | { "seek", seek }, 45 | { "close", close }, 46 | { NULL, NULL} 47 | }; 48 | 49 | setupUserdataMetatable(L, POCO_BASE64ENCODER_METATABLE_NAME, methods); 50 | return true; 51 | } 52 | 53 | /// Constructs a new base64encoder userdata. 54 | // @tparam userdata ostream destination for base 64 encoded data. 55 | // @string[opt] options "url_encoding", "no_padding", or both separated by space or commas. 56 | // @return userdata or nil. (error) 57 | // @return error message. 58 | // @function new 59 | // @see ostream 60 | int Base64EncoderUserdata::Base64Encoder(lua_State* L) 61 | { 62 | int firstArg = lua_istable(L, 1) ? 2 : 1; 63 | OStream* os = checkPrivateUserdata(L, firstArg); 64 | int options = 0; 65 | const char* optionsStr = lua_tostring(L, firstArg + 1); 66 | if (optionsStr) 67 | { 68 | if (std::strstr(optionsStr, "url_encoding")) { options |= Poco::BASE64_URL_ENCODING; } 69 | if (std::strstr(optionsStr, "no_padding")) { options |= Poco::BASE64_NO_PADDING; } 70 | } 71 | 72 | lua_pushvalue(L, firstArg); 73 | int ref = luaL_ref(L, LUA_REGISTRYINDEX); 74 | 75 | Base64EncoderUserdata* b64eud = NULL; 76 | void* p = lua_newuserdata(L, sizeof *b64eud); 77 | 78 | try 79 | { 80 | b64eud = new(p) Base64EncoderUserdata(os->ostream(), options, ref); 81 | } 82 | catch (const std::exception& e) 83 | { 84 | luaL_unref(L, LUA_REGISTRYINDEX, ref); 85 | return pushException(L, e); 86 | } 87 | 88 | setupPocoUserdata(L, b64eud, POCO_BASE64ENCODER_METATABLE_NAME); 89 | return 1; 90 | } 91 | 92 | // metamethod infrastructure 93 | int Base64EncoderUserdata::metamethod__tostring(lua_State* L) 94 | { 95 | Base64EncoderUserdata* b64eud = checkPrivateUserdata(L, 1); 96 | lua_pushfstring(L, "Poco.Base64Encoder (%p)", static_cast(b64eud)); 97 | 98 | return 1; 99 | } 100 | 101 | int Base64EncoderUserdata::metamethod__gc(lua_State* L) 102 | { 103 | Base64EncoderUserdata* b64eud = checkPrivateUserdata(L, 1); 104 | if (!b64eud->mClosed) { b64eud->mBase64Encoder.close(); } 105 | luaL_unref(L, LUA_REGISTRYINDEX, b64eud->mUdReference); 106 | b64eud->~Base64EncoderUserdata(); 107 | 108 | return 0; 109 | } 110 | /// 111 | // @type base64encoder 112 | 113 | /// Closes base64encoder 114 | // Flushes all encoded output to the destination ostream. 115 | // @function close 116 | int Base64EncoderUserdata::close(lua_State* L) 117 | { 118 | Base64EncoderUserdata* b64eud = checkPrivateUserdata(L, 1); 119 | if (!b64eud->mClosed) { b64eud->mClosed = true; b64eud->mBase64Encoder.close(); } 120 | return 0; 121 | } 122 | 123 | } // LuaPoco 124 | -------------------------------------------------------------------------------- /src/foundation/Base64Encoder.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_BASE64ENCODER_H 2 | #define LUA_POCO_BASE64ENCODER_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include "OStream.h" 7 | #include 8 | 9 | extern "C" 10 | { 11 | LUAPOCO_API int luaopen_poco_base64encoder(lua_State* L); 12 | } 13 | 14 | namespace LuaPoco 15 | { 16 | 17 | extern const char* POCO_BASE64ENCODER_METATABLE_NAME; 18 | 19 | class Base64EncoderUserdata : public Userdata, public OStream 20 | { 21 | public: 22 | Base64EncoderUserdata(std::ostream & ostr, int options, int ref); 23 | virtual ~Base64EncoderUserdata(); 24 | virtual std::ostream& ostream(); 25 | // register metatable for this class 26 | static bool registerBase64Encoder(lua_State* L); 27 | // constructor function 28 | static int Base64Encoder(lua_State* L); 29 | 30 | Poco::Base64Encoder mBase64Encoder; 31 | private: 32 | int mUdReference; 33 | bool mClosed; 34 | // metamethod infrastructure 35 | static int metamethod__tostring(lua_State* L); 36 | static int metamethod__gc(lua_State* L); 37 | // methods 38 | static int close(lua_State* L); 39 | }; 40 | 41 | } // LuaPoco 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/foundation/Buffer.cpp: -------------------------------------------------------------------------------- 1 | /// Mutable buffers. 2 | // A module that implements mutable buffers for use with memoryostream and memoryistream. 3 | // Note: buffer userdata are copyable between threads. 4 | // @module buffer 5 | 6 | #include 7 | #include "Buffer.h" 8 | #include 9 | 10 | int luaopen_poco_buffer(lua_State* L) 11 | { 12 | LuaPoco::BufferUserdata::registerBuffer(L); 13 | return LuaPoco::loadConstructor(L, LuaPoco::BufferUserdata::Buffer); 14 | } 15 | 16 | namespace LuaPoco 17 | { 18 | 19 | const char* POCO_BUFFER_METATABLE_NAME = "Poco.Buffer.metatable"; 20 | 21 | BufferUserdata::BufferUserdata(size_t size) : 22 | mBuffer(size), 23 | mCapacity(size) 24 | { 25 | } 26 | 27 | BufferUserdata::~BufferUserdata() 28 | { 29 | } 30 | 31 | bool BufferUserdata::copyToState(lua_State *L) 32 | { 33 | registerBuffer(L); 34 | BufferUserdata* bud = NULL; 35 | void* p = lua_newuserdata(L, sizeof *bud); 36 | 37 | try 38 | { 39 | bud = new(p) BufferUserdata(mCapacity); 40 | } 41 | catch (const std::exception& e) 42 | { 43 | lua_pop(L, 1); 44 | return false; 45 | } 46 | 47 | bud->mCapacity = mCapacity; 48 | std::memcpy(bud->mBuffer.begin(), mBuffer.begin(), mCapacity); 49 | 50 | setupPocoUserdata(L, bud, POCO_BUFFER_METATABLE_NAME); 51 | return true; 52 | } 53 | 54 | // register metatable for this class 55 | bool BufferUserdata::registerBuffer(lua_State* L) 56 | { 57 | struct CFunctions methods[] = 58 | { 59 | { "__gc", metamethod__gc }, 60 | { "__tostring", metamethod__tostring }, 61 | { "clear", clear }, 62 | { "size", size }, 63 | { "data", data }, 64 | { NULL, NULL } 65 | }; 66 | 67 | setupUserdataMetatable(L, POCO_BUFFER_METATABLE_NAME, methods); 68 | 69 | return true; 70 | } 71 | 72 | /// constructs a new buffer userdata. 73 | // @param init number specifying the size of the empty buffer in bytes, or a string 74 | // of bytes that will be used to initialize the buffer of the same size as the string. 75 | // @return userdata or nil. (error) 76 | // @return error message 77 | // @function new 78 | int BufferUserdata::Buffer(lua_State* L) 79 | { 80 | int top = lua_gettop(L); 81 | int firstArg = lua_istable(L, 1) ? 2 : 1; 82 | 83 | luaL_checkany(L, firstArg); 84 | size_t dataSize = 0; 85 | const char* dataInit = NULL; 86 | 87 | if (lua_type(L, firstArg) == LUA_TSTRING) dataInit = luaL_checklstring(L, firstArg, &dataSize); 88 | else dataSize = static_cast(luaL_checknumber(L, firstArg)); 89 | 90 | BufferUserdata* bud = NULL; 91 | void* p = lua_newuserdata(L, sizeof *bud); 92 | 93 | try 94 | { 95 | bud = new(p) BufferUserdata(dataSize); 96 | } 97 | catch (const std::exception& e) 98 | { 99 | return pushException(L, e); 100 | } 101 | 102 | setupPocoUserdata(L, bud, POCO_BUFFER_METATABLE_NAME); 103 | if (dataInit) std::memcpy(bud->mBuffer.begin(), dataInit, dataSize); 104 | 105 | return 1; 106 | } 107 | 108 | /// 109 | // @type buffer 110 | 111 | // metamethod infrastructure 112 | int BufferUserdata::metamethod__tostring(lua_State* L) 113 | { 114 | BufferUserdata* bud = checkPrivateUserdata(L, 1); 115 | lua_pushfstring(L, "Poco.Buffer (%p)", static_cast(bud)); 116 | return 1; 117 | } 118 | 119 | // userdata methods 120 | 121 | /// Sets all bytes of the buffer to '\0'. 122 | // @function clear 123 | int BufferUserdata::clear(lua_State* L) 124 | { 125 | BufferUserdata* bud = checkPrivateUserdata(L, 1); 126 | std::memset(bud->mBuffer.begin(), '\0', bud->mBuffer.size()); 127 | return 0; 128 | } 129 | 130 | /// Gets the capacity of the buffer. 131 | // @return number indicating the capacity of the buffer. 132 | // @function size 133 | int BufferUserdata::size(lua_State* L) 134 | { 135 | BufferUserdata* bud = checkPrivateUserdata(L, 1); 136 | lua_pushinteger(L, bud->mCapacity); 137 | return 1; 138 | } 139 | /// Gets the entire buffer as a string. 140 | // @return string containing all bytes of the buffer. 141 | // @function data 142 | int BufferUserdata::data(lua_State* L) 143 | { 144 | BufferUserdata* bud = checkPrivateUserdata(L, 1); 145 | lua_pushlstring(L, bud->mBuffer.begin(), bud->mCapacity); 146 | return 1; 147 | } 148 | 149 | } // LuaPoco 150 | -------------------------------------------------------------------------------- /src/foundation/Buffer.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_BUFFER_H 2 | #define LUA_POCO_BUFFER_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include 7 | 8 | extern "C" 9 | { 10 | LUAPOCO_API int luaopen_poco_buffer(lua_State* L); 11 | } 12 | 13 | namespace LuaPoco 14 | { 15 | 16 | extern const char* POCO_BUFFER_METATABLE_NAME; 17 | 18 | class BufferUserdata : public Userdata 19 | { 20 | public: 21 | BufferUserdata(size_t size); 22 | virtual ~BufferUserdata(); 23 | virtual bool copyToState(lua_State *L); 24 | // register metatable for this class 25 | static bool registerBuffer(lua_State* L); 26 | // constructor function 27 | static int Buffer(lua_State* L); 28 | 29 | Poco::Buffer mBuffer; 30 | size_t mCapacity; 31 | private: 32 | // metamethod infrastructure 33 | static int metamethod__tostring(lua_State* L); 34 | 35 | // userdata methods 36 | static int clear(lua_State* L); 37 | static int size(lua_State* L); 38 | static int data(lua_State* L); 39 | }; 40 | 41 | } // LuaPoco 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/foundation/Checksum.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_CHECKSUM_H 2 | #define LUA_POCO_CHECKSUM_H 3 | 4 | #include "Userdata.h" 5 | #include 6 | 7 | extern "C" 8 | { 9 | LUAPOCO_API int luaopen_poco_checksum(lua_State* L); 10 | } 11 | 12 | namespace LuaPoco 13 | { 14 | 15 | extern const char* POCO_CHECKSUM_METATABLE_NAME; 16 | 17 | class ChecksumUserdata : public Userdata 18 | { 19 | public: 20 | ChecksumUserdata(Poco::Checksum::Type t); 21 | virtual ~ChecksumUserdata(); 22 | virtual bool copyToState(lua_State *L); 23 | // register metatable for this class 24 | static bool registerChecksum(lua_State* L); 25 | // constructor function 26 | static int Checksum(lua_State* L); 27 | private: 28 | ChecksumUserdata(); 29 | 30 | // metamethod infrastructure 31 | static int metamethod__tostring(lua_State* L); 32 | 33 | // userdata methods 34 | static int update(lua_State* L); 35 | static int checksum(lua_State* L); 36 | static int type(lua_State* L); 37 | 38 | Poco::Checksum mChecksum; 39 | }; 40 | 41 | } // LuaPoco 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/foundation/Compress.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_COMPRESS_H 2 | #define LUA_POCO_COMPRESS_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include 7 | 8 | extern "C" 9 | { 10 | LUAPOCO_API int luaopen_poco_zip_compress(lua_State* L); 11 | } 12 | 13 | namespace LuaPoco 14 | { 15 | namespace Zip 16 | { 17 | 18 | class CompressUserdata : public Userdata 19 | { 20 | public: 21 | CompressUserdata(std::ostream& ostream, int ref, bool seekable, bool forceZip64); 22 | virtual ~CompressUserdata(); 23 | // register metatables 24 | static bool registerCompress(lua_State* L); 25 | // constructor lua_CFunction 26 | static int Compress(lua_State* L); 27 | private: 28 | int mUdReference; 29 | Poco::Zip::Compress mCompress; 30 | bool mClosed; 31 | 32 | static int metamethod__tostring(lua_State* L); 33 | static int metamethod__gc(lua_State* L); 34 | 35 | static int addDirectory(lua_State* L); 36 | static int addFile(lua_State* L); 37 | static int addIStream(lua_State* L); 38 | static int addRecursive(lua_State* L); 39 | static int close(lua_State* L); 40 | static int getStoreExtensions(lua_State* L); 41 | static int getZipComment(lua_State* L); 42 | static int setStoreExtensions(lua_State* L); 43 | static int setZipComment(lua_State* L); 44 | }; 45 | 46 | } 47 | } // LuaPoco 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /src/foundation/Condition.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_CONDITION_H 2 | #define LUA_POCO_CONDITION_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include 7 | #include 8 | 9 | extern "C" 10 | { 11 | 12 | LUAPOCO_API int luaopen_poco_condition(lua_State* L); 13 | 14 | } 15 | 16 | namespace LuaPoco 17 | { 18 | class ConditionUserdata : public Userdata 19 | { 20 | public: 21 | ConditionUserdata(); 22 | ConditionUserdata(const Poco::SharedPtr& condition); 23 | virtual ~ConditionUserdata(); 24 | virtual bool copyToState(lua_State* L); 25 | // constructor 26 | static int Condition(lua_State* L); 27 | static bool registerCondition(lua_State* L); 28 | private: 29 | // metamethod infrastructure 30 | static int metamethod__tostring(lua_State* L); 31 | // userdata methods 32 | static int broadcast(lua_State* L); 33 | static int signal(lua_State* L); 34 | static int wait(lua_State* L); 35 | static int tryWait(lua_State* L); 36 | 37 | Poco::SharedPtr mCondition; 38 | }; 39 | 40 | } // LuaPoco 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/foundation/Decompress.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_DECOMPRESS_H 2 | #define LUA_POCO_DECOMPRESS_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | extern "C" 14 | { 15 | LUAPOCO_API int luaopen_poco_zip_decompress(lua_State* L); 16 | } 17 | 18 | namespace LuaPoco 19 | { 20 | namespace Zip 21 | { 22 | 23 | class DecompressUserdata : public Userdata 24 | { 25 | public: 26 | DecompressUserdata(std::istream& istream, int ref, const Poco::Path& dirPath, bool flattenDirs, bool keepIncompleteFiles); 27 | virtual ~DecompressUserdata(); 28 | // register metatables 29 | static bool registerDecompress(lua_State* L); 30 | // constructor lua_CFunction 31 | static int Decompress(lua_State* L); 32 | private: 33 | int mUdReference; 34 | Poco::Zip::Decompress mDecompress; 35 | 36 | static int metamethod__tostring(lua_State* L); 37 | static int metamethod__gc(lua_State* L); 38 | 39 | static int decompressAll(lua_State* L); 40 | static int decompressed(lua_State* L); 41 | static int failed(lua_State* L); 42 | static int good_iter(lua_State* L); 43 | static int fail_iter(lua_State* L); 44 | 45 | bool zipLocalFileHeaderToTable(lua_State* L, const Poco::Zip::ZipLocalFileHeader& zflh); 46 | void onError(const void* dp, std::pair& entry); 47 | void onDecompress(const void* dp, std::pair& entry); 48 | 49 | std::vector> mGood; 50 | std::vector> mFail; 51 | size_t mGoodIdx; 52 | size_t mFailIdx; 53 | }; 54 | 55 | } 56 | } // LuaPoco 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /src/foundation/DeflatingIStream.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_DEFLATINGISTREAM_H 2 | #define LUA_POCO_DEFLATINGISTREAM_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include "IStream.h" 7 | #include 8 | 9 | extern "C" 10 | { 11 | LUAPOCO_API int luaopen_poco_deflatingistream(lua_State* L); 12 | } 13 | 14 | namespace LuaPoco 15 | { 16 | 17 | extern const char* POCO_DEFLATINGISTREAM_METATABLE_NAME; 18 | 19 | class DeflatingIStreamUserdata : public Userdata, public IStream 20 | { 21 | public: 22 | DeflatingIStreamUserdata(std::istream& istream, Poco::DeflatingStreamBuf::StreamType type, int level, int ref); 23 | DeflatingIStreamUserdata(std::istream& istream, int windowBits, int level, int ref); 24 | virtual ~DeflatingIStreamUserdata(); 25 | virtual std::istream& istream(); 26 | // register metatable for this class 27 | static bool registerDeflatingIStream(lua_State* L); 28 | // constructor function 29 | static int DeflatingIStream(lua_State* L); 30 | 31 | Poco::DeflatingInputStream mDeflatingInputStream; 32 | private: 33 | // metamethod infrastructure 34 | static int metamethod__gc(lua_State* L); 35 | static int metamethod__tostring(lua_State* L); 36 | 37 | int mUdReference; 38 | }; 39 | 40 | } // LuaPoco 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/foundation/DeflatingOStream.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_DEFLATINGOSTREAM_H 2 | #define LUA_POCO_DEFLATINGOSTREAM_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include "OStream.h" 7 | #include 8 | 9 | extern "C" 10 | { 11 | LUAPOCO_API int luaopen_poco_deflatingostream(lua_State* L); 12 | } 13 | 14 | namespace LuaPoco 15 | { 16 | 17 | extern const char* POCO_DEFLATINGOSTREAM_METATABLE_NAME; 18 | 19 | class DeflatingOStreamUserdata : public Userdata, public OStream 20 | { 21 | public: 22 | DeflatingOStreamUserdata(std::ostream& ostream, Poco::DeflatingStreamBuf::StreamType type, int level, int ref); 23 | DeflatingOStreamUserdata(std::ostream& ostream, int windowBits, int level, int ref); 24 | virtual ~DeflatingOStreamUserdata(); 25 | virtual std::ostream& ostream(); 26 | // register metatable for this class 27 | static bool registerDeflatingOStream(lua_State* L); 28 | // constructor function 29 | static int DeflatingOStream(lua_State* L); 30 | 31 | Poco::DeflatingOutputStream mDeflatingOutputStream; 32 | private: 33 | // metamethod infrastructure 34 | static int metamethod__gc(lua_State* L); 35 | static int metamethod__tostring(lua_State* L); 36 | // methods 37 | static int close(lua_State* L); 38 | int mUdReference; 39 | }; 40 | 41 | } // LuaPoco 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/foundation/DynamicAny.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_DYNAMICANY_H 2 | #define LUA_POCO_DYNAMICANY_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include 7 | 8 | extern "C" 9 | { 10 | LUAPOCO_API int luaopen_poco_dynamicany(lua_State* L); 11 | } 12 | 13 | namespace LuaPoco 14 | { 15 | 16 | extern const char* POCO_DYNAMICANY_METATABLE_NAME; 17 | 18 | class DynamicAnyUserdata : public Userdata 19 | { 20 | public: 21 | template 22 | DynamicAnyUserdata(T val) : mDynamicAny(val) {} 23 | DynamicAnyUserdata(const Poco::DynamicAny& da); 24 | virtual ~DynamicAnyUserdata(); 25 | virtual bool copyToState(lua_State* L); 26 | // register metatable for this class 27 | static bool registerDynamicAny(lua_State* L); 28 | // Lua constructor 29 | static int DynamicAny(lua_State* L); 30 | 31 | Poco::DynamicAny mDynamicAny; 32 | private: 33 | DynamicAnyUserdata(); 34 | DynamicAnyUserdata(const DynamicAnyUserdata& disabledCopy); 35 | DynamicAnyUserdata& operator=(const DynamicAnyUserdata& disabledAssignment); 36 | 37 | // metamethod infrastructure 38 | static int metamethod__tostring(lua_State* L); 39 | 40 | // methods 41 | static int convert(lua_State* L); 42 | static int isNumeric(lua_State* L); 43 | static int isInteger(lua_State* L); 44 | static int isSigned(lua_State* L); 45 | static int isString(lua_State* L); 46 | static int toNumber(lua_State* L); 47 | static int toString(lua_State* L); 48 | static int toBoolean(lua_State* L); 49 | static int metamethod__add(lua_State* L); 50 | static int metamethod__sub(lua_State* L); 51 | static int metamethod__mul(lua_State* L); 52 | static int metamethod__div(lua_State* L); 53 | static int metamethod__eq(lua_State* L); 54 | static int metamethod__lt(lua_State* L); 55 | static int metamethod__le(lua_State* L); 56 | }; 57 | 58 | } // LuaPoco 59 | 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /src/foundation/Environment.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_ENVIRONMENT_H 2 | #define LUA_POCO_ENVIRONMENT_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include 7 | 8 | extern "C" 9 | { 10 | LUAPOCO_API int luaopen_poco_environment(lua_State* L); 11 | } 12 | 13 | namespace LuaPoco 14 | { 15 | namespace Environment 16 | { 17 | 18 | int get(lua_State* L); 19 | int has(lua_State* L); 20 | int set(lua_State* L); 21 | int libraryVersion(lua_State* L); 22 | int nodeId(lua_State* L); 23 | int nodeName(lua_State* L); 24 | int osArchitecture(lua_State* L); 25 | int osDisplayName(lua_State* L); 26 | int osName(lua_State* L); 27 | int osVersion(lua_State* L); 28 | int processorCount(lua_State* L); 29 | 30 | } 31 | } // LuaPoco 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /src/foundation/Event.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_EVENT_H 2 | #define LUA_POCO_EVENT_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include 7 | #include 8 | 9 | extern "C" 10 | { 11 | LUAPOCO_API int luaopen_poco_event(lua_State* L); 12 | } 13 | 14 | namespace LuaPoco 15 | { 16 | 17 | extern const char* POCO_EVENT_METATABLE_NAME; 18 | 19 | class EventUserdata : public Userdata 20 | { 21 | public: 22 | EventUserdata(bool autoReset = true); 23 | EventUserdata(const Poco::SharedPtr& event); 24 | virtual ~EventUserdata(); 25 | virtual bool copyToState(lua_State *L); 26 | // register metatable for this class 27 | static bool registerEvent(lua_State* L); 28 | // constructor function 29 | static int Event(lua_State* L); 30 | 31 | private: 32 | // metamethod infrastructure 33 | static int metamethod__tostring(lua_State* L); 34 | 35 | // userdata methods 36 | static int set(lua_State* L); 37 | static int tryWait(lua_State* L); 38 | static int wait(lua_State* L); 39 | static int reset(lua_State* L); 40 | 41 | Poco::SharedPtr mEvent; 42 | }; 43 | 44 | } // LuaPoco 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /src/foundation/FastMutex.cpp: -------------------------------------------------------------------------------- 1 | /// Non-recursive synchronization mechanism used to control access to a shared resource. 2 | // Note: A deadlock will occur if the same thread tries to lock a mutex that has already locked. 3 | // Note: fastmutex userdata are copyable/sharable between threads. 4 | // @module fastmutex 5 | 6 | #include "FastMutex.h" 7 | #include 8 | 9 | int luaopen_poco_fastmutex(lua_State* L) 10 | { 11 | LuaPoco::FastMutexUserdata::registerFastMutex(L); 12 | return LuaPoco::loadConstructor(L, LuaPoco::FastMutexUserdata::FastMutex); 13 | } 14 | 15 | namespace LuaPoco 16 | { 17 | 18 | const char* POCO_FASTMUTEX_METATABLE_NAME = "Poco.FastMutex.metatable"; 19 | 20 | FastMutexUserdata::FastMutexUserdata() : 21 | mFastMutex(new Poco::FastMutex()) 22 | { 23 | } 24 | 25 | // construct new Ud from existing SharedPtr 26 | FastMutexUserdata::FastMutexUserdata(const Poco::SharedPtr& fm) : 27 | mFastMutex(fm) 28 | { 29 | } 30 | 31 | FastMutexUserdata::~FastMutexUserdata() 32 | { 33 | } 34 | 35 | bool FastMutexUserdata::copyToState(lua_State *L) 36 | { 37 | registerFastMutex(L); 38 | FastMutexUserdata* fmud = NULL; 39 | void *p = lua_newuserdata(L, sizeof *fmud); 40 | 41 | try 42 | { 43 | fmud = new(p) FastMutexUserdata(mFastMutex); 44 | } 45 | catch (const std::exception& e) 46 | { 47 | lua_pop(L, 1); 48 | return false; 49 | } 50 | 51 | setupPocoUserdata(L, fmud, POCO_FASTMUTEX_METATABLE_NAME); 52 | return true; 53 | } 54 | 55 | // register metatable for this class 56 | bool FastMutexUserdata::registerFastMutex(lua_State* L) 57 | { 58 | struct CFunctions methods[] = 59 | { 60 | { "__gc", metamethod__gc }, 61 | { "__tostring", metamethod__tostring }, 62 | { "lock", lock }, 63 | { "tryLock", tryLock }, 64 | { "unlock", unlock }, 65 | { NULL, NULL} 66 | }; 67 | 68 | setupUserdataMetatable(L, POCO_FASTMUTEX_METATABLE_NAME, methods); 69 | 70 | return true; 71 | } 72 | 73 | /// constructs a new fastmutex userdata. 74 | // @return userdata or nil. (error) 75 | // @return error message 76 | // @function new 77 | int FastMutexUserdata::FastMutex(lua_State* L) 78 | { 79 | 80 | FastMutexUserdata* fmud = NULL; 81 | void* p = lua_newuserdata(L, sizeof *fmud); 82 | 83 | try 84 | { 85 | fmud = new(p) FastMutexUserdata(); 86 | } 87 | catch (const std::exception& e) 88 | { 89 | return pushException(L, e); 90 | } 91 | 92 | setupPocoUserdata(L, fmud, POCO_FASTMUTEX_METATABLE_NAME); 93 | return 1; 94 | } 95 | 96 | /// 97 | // @type fastmutex 98 | 99 | // metamethod infrastructure 100 | int FastMutexUserdata::metamethod__tostring(lua_State* L) 101 | { 102 | FastMutexUserdata* fmud = checkPrivateUserdata(L, 1); 103 | lua_pushfstring(L, "Poco.FastMutex (%p)", static_cast(fmud)); 104 | return 1; 105 | } 106 | 107 | /// Locks the mutex. Blocks if the mutex is already held. 108 | // @function lock 109 | 110 | // userdata methods 111 | int FastMutexUserdata::lock(lua_State* L) 112 | { 113 | FastMutexUserdata* fmud = checkPrivateUserdata(L, 1); 114 | 115 | try 116 | { 117 | fmud->mFastMutex->lock(); 118 | } 119 | catch (const std::exception& e) 120 | { 121 | pushException(L, e); 122 | lua_error(L); 123 | } 124 | 125 | return 0; 126 | } 127 | 128 | /// Attempts to lock the mutex. 129 | // @int[opt] ms optional number of milliseconds to try to acquire the mutex. 130 | // @return boolean indicating if lock was acquired or timeout occured. 131 | // @function tryLock 132 | int FastMutexUserdata::tryLock(lua_State* L) 133 | { 134 | FastMutexUserdata* fmud = checkPrivateUserdata(L, 1); 135 | int top = lua_gettop(L); 136 | long ms = 0; 137 | 138 | if (top > 1) 139 | ms = luaL_checkinteger(L, 2); 140 | 141 | bool result = false; 142 | 143 | try 144 | { 145 | if (ms > 0) 146 | result = fmud->mFastMutex->tryLock(ms); 147 | else 148 | result = fmud->mFastMutex->tryLock(); 149 | } 150 | catch (const std::exception& e) 151 | { 152 | return pushException(L, e); 153 | } 154 | 155 | lua_pushboolean(L, result); 156 | return 1; 157 | } 158 | 159 | /// Unlocks the mutex so that it can be acquired by other threads. 160 | // @function unlock 161 | int FastMutexUserdata::unlock(lua_State* L) 162 | { 163 | FastMutexUserdata* fmud = checkPrivateUserdata(L, 1); 164 | 165 | try 166 | { 167 | fmud->mFastMutex->unlock(); 168 | } 169 | catch (const std::exception& e) 170 | { 171 | pushException(L, e); 172 | lua_error(L); 173 | } 174 | 175 | return 0; 176 | } 177 | 178 | } // LuaPoco 179 | -------------------------------------------------------------------------------- /src/foundation/FastMutex.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_FASTMUTEX_H 2 | #define LUA_POCO_FASTMUTEX_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include 7 | #include 8 | 9 | extern "C" 10 | { 11 | LUAPOCO_API int luaopen_poco_fastmutex(lua_State* L); 12 | } 13 | 14 | namespace LuaPoco 15 | { 16 | 17 | extern const char* POCO_FASTMUTEX_METATABLE_NAME; 18 | 19 | class FastMutexUserdata : public Userdata 20 | { 21 | public: 22 | FastMutexUserdata(); 23 | FastMutexUserdata(const Poco::SharedPtr& mtx); 24 | virtual ~FastMutexUserdata(); 25 | virtual bool copyToState(lua_State *L); 26 | // register metatable for this class 27 | static bool registerFastMutex(lua_State* L); 28 | // constructor function 29 | static int FastMutex(lua_State* L); 30 | 31 | Poco::SharedPtr mFastMutex; 32 | private: 33 | // metamethod infrastructure 34 | static int metamethod__tostring(lua_State* L); 35 | 36 | // userdata methods 37 | static int lock(lua_State* L); 38 | static int tryLock(lua_State* L); 39 | static int unlock(lua_State* L); 40 | }; 41 | 42 | } // LuaPoco 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /src/foundation/File.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_FILE_H 2 | #define LUA_POCO_FILE_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include 7 | 8 | extern "C" 9 | { 10 | 11 | LUAPOCO_API int luaopen_poco_file(lua_State* L); 12 | 13 | } 14 | 15 | namespace LuaPoco 16 | { 17 | 18 | extern const char* POCO_FILE_METATABLE_NAME; 19 | 20 | class FileUserdata : public Userdata 21 | { 22 | public: 23 | FileUserdata(); 24 | FileUserdata(const char *path); 25 | FileUserdata(const Poco::File& file); 26 | virtual ~FileUserdata(); 27 | virtual bool copyToState(lua_State* L); 28 | virtual Poco::File& getFile(); 29 | // register metatable for this class 30 | static bool registerFile(lua_State* L); 31 | // constructor 32 | static int File(lua_State* L); 33 | protected: 34 | // metamethod infrastructure 35 | static int metamethod__tostring(lua_State* L); 36 | // userdata methods 37 | static int copyTo(lua_State* L); 38 | static int createDirectories(lua_State* L); 39 | static int createDirectory(lua_State* L); 40 | static int createFile(lua_State* L); 41 | static int listNames(lua_State* L); 42 | static int listFiles(lua_State* L); 43 | static int moveTo(lua_State* L); 44 | static int remove(lua_State* L); 45 | static int renameTo(lua_State* L); 46 | static int canExecute(lua_State* L); 47 | static int canRead(lua_State* L); 48 | static int canWrite(lua_State* L); 49 | static int created(lua_State* L); 50 | static int exists(lua_State* L); 51 | static int getLastModified(lua_State* L); 52 | static int getSize(lua_State* L); 53 | static int isDevice(lua_State* L); 54 | static int isDirectory(lua_State* L); 55 | static int isFile(lua_State* L); 56 | static int isHidden(lua_State* L); 57 | static int isLink(lua_State* L); 58 | static int path(lua_State* L); 59 | static int setExecutable(lua_State* L); 60 | static int setLastModified(lua_State* L); 61 | static int setReadOnly(lua_State* L); 62 | static int setSize(lua_State* L); 63 | static int setWritable(lua_State* L); 64 | private: 65 | Poco::File mFile; 66 | }; 67 | 68 | } // LuaPoco 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /src/foundation/FileIStream.cpp: -------------------------------------------------------------------------------- 1 | /// fileistream 2 | // An istream interface for reading files. 3 | // @module fileistream 4 | #include "FileIStream.h" 5 | #include 6 | 7 | int luaopen_poco_fileistream(lua_State* L) 8 | { 9 | LuaPoco::FileIStreamUserdata::registerFileIStream(L); 10 | return LuaPoco::loadConstructor(L, LuaPoco::FileIStreamUserdata::FileIStream); 11 | } 12 | 13 | namespace LuaPoco 14 | { 15 | 16 | const char* POCO_FILEISTREAM_METATABLE_NAME = "Poco.FileIStream.metatable"; 17 | 18 | FileIStreamUserdata::FileIStreamUserdata(const std::string& path) 19 | : mFileInputStream(path) 20 | { 21 | } 22 | 23 | FileIStreamUserdata::~FileIStreamUserdata() 24 | { 25 | } 26 | 27 | std::istream& FileIStreamUserdata::istream() 28 | { 29 | return mFileInputStream; 30 | } 31 | 32 | // register metatable for this class 33 | bool FileIStreamUserdata::registerFileIStream(lua_State* L) 34 | { 35 | struct CFunctions methods[] = 36 | { 37 | { "__gc", metamethod__gc }, 38 | { "__tostring", metamethod__tostring }, 39 | { "read", read }, 40 | { "lines", lines }, 41 | { "seek", seek }, 42 | { "close", close }, 43 | { NULL, NULL} 44 | }; 45 | 46 | setupUserdataMetatable(L, POCO_FILEISTREAM_METATABLE_NAME, methods); 47 | return true; 48 | } 49 | 50 | /// Constructs a new fileistream userdata. 51 | // @string path to file. 52 | // @return userdata or nil. (error) 53 | // @return error message. 54 | // @function new 55 | // @see istream 56 | int FileIStreamUserdata::FileIStream(lua_State* L) 57 | { 58 | int firstArg = lua_istable(L, 1) ? 2 : 1; 59 | const char* path = luaL_checkstring(L, firstArg); 60 | 61 | FileIStreamUserdata* fisud = NULL; 62 | void* p = lua_newuserdata(L, sizeof *fisud); 63 | 64 | try 65 | { 66 | fisud = new(p) FileIStreamUserdata(path); 67 | } 68 | catch (const std::exception& e) 69 | { 70 | return pushException(L, e); 71 | } 72 | 73 | setupPocoUserdata(L, fisud, POCO_FILEISTREAM_METATABLE_NAME); 74 | return 1; 75 | } 76 | 77 | // metamethod infrastructure 78 | int FileIStreamUserdata::metamethod__tostring(lua_State* L) 79 | { 80 | FileIStreamUserdata* fisud = checkPrivateUserdata(L, 1); 81 | lua_pushfstring(L, "Poco.FileIStream (%p)", static_cast(fisud)); 82 | 83 | return 1; 84 | } 85 | 86 | // methods 87 | 88 | /// Closes fileistream. 89 | // @function close 90 | int FileIStreamUserdata::close(lua_State* L) 91 | { 92 | FileIStreamUserdata* fisud = checkPrivateUserdata(L, 1); 93 | fisud->mFileInputStream.close(); 94 | 95 | return 0; 96 | } 97 | 98 | } // LuaPoco 99 | -------------------------------------------------------------------------------- /src/foundation/FileIStream.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_FILEISTREAM_H 2 | #define LUA_POCO_FILEISTREAM_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include "IStream.h" 7 | #include 8 | 9 | extern "C" 10 | { 11 | LUAPOCO_API int luaopen_poco_fileistream(lua_State* L); 12 | } 13 | 14 | namespace LuaPoco 15 | { 16 | 17 | extern const char* POCO_FILEISTREAM_METATABLE_NAME; 18 | 19 | class FileIStreamUserdata : public Userdata, public IStream 20 | { 21 | public: 22 | FileIStreamUserdata(const std::string& path); 23 | virtual ~FileIStreamUserdata(); 24 | virtual std::istream& istream(); 25 | // register metatable for this class 26 | static bool registerFileIStream(lua_State* L); 27 | // constructor function 28 | static int FileIStream(lua_State* L); 29 | 30 | Poco::FileInputStream mFileInputStream; 31 | private: 32 | // metamethod infrastructure 33 | static int metamethod__tostring(lua_State* L); 34 | // methods 35 | static int close(lua_State* L); 36 | }; 37 | 38 | } // LuaPoco 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/foundation/FileOStream.cpp: -------------------------------------------------------------------------------- 1 | /// fileostream 2 | // An ostream interface for reading files. 3 | // @module fileostream 4 | #include "FileOStream.h" 5 | #include 6 | 7 | int luaopen_poco_fileostream(lua_State* L) 8 | { 9 | LuaPoco::FileOStreamUserdata::registerFileOStream(L); 10 | return LuaPoco::loadConstructor(L, LuaPoco::FileOStreamUserdata::FileOStream); 11 | } 12 | 13 | namespace LuaPoco 14 | { 15 | 16 | const char* POCO_FILEOSTREAM_METATABLE_NAME = "Poco.FileOStream.metatable"; 17 | 18 | FileOStreamUserdata::FileOStreamUserdata(const std::string& path) 19 | : mFileOutputStream(path) 20 | { 21 | } 22 | 23 | FileOStreamUserdata::~FileOStreamUserdata() 24 | { 25 | } 26 | 27 | std::ostream& FileOStreamUserdata::ostream() 28 | { 29 | return mFileOutputStream; 30 | } 31 | 32 | // register metatable for this class 33 | bool FileOStreamUserdata::registerFileOStream(lua_State* L) 34 | { 35 | struct CFunctions methods[] = 36 | { 37 | { "__gc", metamethod__gc }, 38 | { "__tostring", metamethod__tostring }, 39 | { "write", write }, 40 | { "flush", flush }, 41 | { "seek", seek }, 42 | { "close", close }, 43 | { NULL, NULL} 44 | }; 45 | 46 | setupUserdataMetatable(L, POCO_FILEOSTREAM_METATABLE_NAME, methods); 47 | return true; 48 | } 49 | 50 | /// Constructs a new fileostream userdata. 51 | // @string path to file. 52 | // @return userdata or nil. (error) 53 | // @return error message. 54 | // @function new 55 | // @see ostream 56 | int FileOStreamUserdata::FileOStream(lua_State* L) 57 | { 58 | int firstArg = lua_istable(L, 1) ? 2 : 1; 59 | const char* path = luaL_checkstring(L, firstArg); 60 | 61 | FileOStreamUserdata* fosud = NULL; 62 | void* p = lua_newuserdata(L, sizeof *fosud); 63 | 64 | try 65 | { 66 | fosud = new(p) FileOStreamUserdata(path); 67 | } 68 | catch (const Poco::Exception& e) 69 | { 70 | return pushException(L, e); 71 | } 72 | 73 | setupPocoUserdata(L, fosud, POCO_FILEOSTREAM_METATABLE_NAME); 74 | return 1; 75 | } 76 | 77 | // metamethod infrastructure 78 | int FileOStreamUserdata::metamethod__tostring(lua_State* L) 79 | { 80 | FileOStreamUserdata* fosud = checkPrivateUserdata(L, 1); 81 | lua_pushfstring(L, "Poco.FileOStream (%p)", static_cast(fosud)); 82 | 83 | return 1; 84 | } 85 | 86 | // methods 87 | 88 | /// Closes fileostream. 89 | // @function close 90 | int FileOStreamUserdata::close(lua_State* L) 91 | { 92 | FileOStreamUserdata* fosud = checkPrivateUserdata(L, 1); 93 | fosud->mFileOutputStream.close(); 94 | 95 | return 0; 96 | } 97 | 98 | } // LuaPoco 99 | -------------------------------------------------------------------------------- /src/foundation/FileOStream.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_FILEOSTREAM_H 2 | #define LUA_POCO_FILEOSTREAM_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include "OStream.h" 7 | #include 8 | 9 | extern "C" 10 | { 11 | LUAPOCO_API int luaopen_poco_fileostream(lua_State* L); 12 | } 13 | 14 | namespace LuaPoco 15 | { 16 | 17 | extern const char* POCO_FILEOSTREAM_METATABLE_NAME; 18 | 19 | class FileOStreamUserdata : public Userdata, public OStream 20 | { 21 | public: 22 | FileOStreamUserdata(const std::string& path); 23 | virtual ~FileOStreamUserdata(); 24 | virtual std::ostream& ostream(); 25 | // register metatable for this class 26 | static bool registerFileOStream(lua_State* L); 27 | // constructor function 28 | static int FileOStream(lua_State* L); 29 | 30 | Poco::FileOutputStream mFileOutputStream; 31 | private: 32 | // metamethod infrastructure 33 | static int metamethod__tostring(lua_State* L); 34 | // methods 35 | static int close(lua_State* L); 36 | }; 37 | 38 | } // LuaPoco 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/foundation/HexBinaryDecoder.cpp: -------------------------------------------------------------------------------- 1 | /// hexbinarydecoder 2 | // An istream interface for inputting hexbinary encoded data. 3 | // @module hexbinarydecoder 4 | #include "HexBinaryDecoder.h" 5 | #include 6 | 7 | int luaopen_poco_hexbinarydecoder(lua_State* L) 8 | { 9 | LuaPoco::HexBinaryDecoderUserdata::registerHexBinaryDecoder(L); 10 | return LuaPoco::loadConstructor(L, LuaPoco::HexBinaryDecoderUserdata::HexBinaryDecoder); 11 | } 12 | 13 | namespace LuaPoco 14 | { 15 | 16 | const char* POCO_HEXBINARYDECODER_METATABLE_NAME = "Poco.HexBinaryDecoder.metatable"; 17 | 18 | HexBinaryDecoderUserdata::HexBinaryDecoderUserdata(std::istream & istream, int ref) 19 | : mHexBinaryDecoder(istream) 20 | , mUdReference(ref) 21 | { 22 | } 23 | 24 | HexBinaryDecoderUserdata::~HexBinaryDecoderUserdata() 25 | { 26 | } 27 | 28 | std::istream& HexBinaryDecoderUserdata::istream() 29 | { 30 | return mHexBinaryDecoder; 31 | } 32 | 33 | // register metatable for this class 34 | bool HexBinaryDecoderUserdata::registerHexBinaryDecoder(lua_State* L) 35 | { 36 | struct CFunctions methods[] = 37 | { 38 | { "__gc", metamethod__gc }, 39 | { "__tostring", metamethod__tostring }, 40 | { "read", read }, 41 | { "lines", lines }, 42 | { "seek", seek }, 43 | { NULL, NULL} 44 | }; 45 | 46 | setupUserdataMetatable(L, POCO_HEXBINARYDECODER_METATABLE_NAME, methods); 47 | return true; 48 | } 49 | 50 | /// Constructs a new hexbinarydecoder userdata. 51 | // @tparam userdata istream destination for hexbinary encoded data. 52 | // @return userdata or nil. (error) 53 | // @return error message. 54 | // @function new 55 | // @see istream 56 | int HexBinaryDecoderUserdata::HexBinaryDecoder(lua_State* L) 57 | { 58 | int firstArg = lua_istable(L, 1) ? 2 : 1; 59 | IStream* is = checkPrivateUserdata(L, firstArg); 60 | 61 | lua_pushvalue(L, firstArg); 62 | int ref = luaL_ref(L, LUA_REGISTRYINDEX); 63 | 64 | HexBinaryDecoderUserdata* hbdud = NULL; 65 | void* p = lua_newuserdata(L, sizeof *hbdud); 66 | 67 | try 68 | { 69 | hbdud = new(p) HexBinaryDecoderUserdata(is->istream(), ref); 70 | } 71 | catch (const std::exception& e) 72 | { 73 | luaL_unref(L, LUA_REGISTRYINDEX, ref); 74 | return pushException(L, e); 75 | } 76 | 77 | setupPocoUserdata(L, hbdud, POCO_HEXBINARYDECODER_METATABLE_NAME); 78 | return 1; 79 | } 80 | 81 | // metamethod infrastructure 82 | int HexBinaryDecoderUserdata::metamethod__tostring(lua_State* L) 83 | { 84 | HexBinaryDecoderUserdata* hbdud = checkPrivateUserdata(L, 1); 85 | lua_pushfstring(L, "Poco.HexBinaryDecoder (%p)", static_cast(hbdud)); 86 | 87 | return 1; 88 | } 89 | 90 | int HexBinaryDecoderUserdata::metamethod__gc(lua_State* L) 91 | { 92 | HexBinaryDecoderUserdata* hbdud = checkPrivateUserdata(L, 1); 93 | luaL_unref(L, LUA_REGISTRYINDEX, hbdud->mUdReference); 94 | hbdud->~HexBinaryDecoderUserdata(); 95 | 96 | return 0; 97 | } 98 | /// 99 | // @type hexbinarydecoder 100 | 101 | } // LuaPoco 102 | -------------------------------------------------------------------------------- /src/foundation/HexBinaryDecoder.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_HEXBINARYDECODER_H 2 | #define LUA_POCO_HEXBINARYDECODER_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include "IStream.h" 7 | #include 8 | 9 | extern "C" 10 | { 11 | LUAPOCO_API int luaopen_poco_hexbinarydecoder(lua_State* L); 12 | } 13 | 14 | namespace LuaPoco 15 | { 16 | 17 | extern const char* POCO_HEXBINARYDECODER_METATABLE_NAME; 18 | 19 | class HexBinaryDecoderUserdata : public Userdata, public IStream 20 | { 21 | public: 22 | HexBinaryDecoderUserdata(std::istream & istr, int ref); 23 | virtual ~HexBinaryDecoderUserdata(); 24 | virtual std::istream& istream(); 25 | // register metatable for this class 26 | static bool registerHexBinaryDecoder(lua_State* L); 27 | // constructor function 28 | static int HexBinaryDecoder(lua_State* L); 29 | 30 | Poco::HexBinaryDecoder mHexBinaryDecoder; 31 | private: 32 | int mUdReference; 33 | // metamethod infrastructure 34 | static int metamethod__tostring(lua_State* L); 35 | static int metamethod__gc(lua_State* L); 36 | }; 37 | 38 | } // LuaPoco 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/foundation/HexBinaryEncoder.cpp: -------------------------------------------------------------------------------- 1 | /// hexbinaryencoder 2 | // An ostream interface for outputting base32 encoded data. 3 | // @module hexbinaryencoder 4 | #include "HexBinaryEncoder.h" 5 | #include 6 | 7 | int luaopen_poco_hexbinaryencoder(lua_State* L) 8 | { 9 | LuaPoco::HexBinaryEncoderUserdata::registerHexBinaryEncoder(L); 10 | return LuaPoco::loadConstructor(L, LuaPoco::HexBinaryEncoderUserdata::HexBinaryEncoder); 11 | } 12 | 13 | namespace LuaPoco 14 | { 15 | 16 | const char* POCO_HEXBINARYENCODER_METATABLE_NAME = "Poco.HexBinaryEncoder.metatable"; 17 | 18 | HexBinaryEncoderUserdata::HexBinaryEncoderUserdata(std::ostream & ostream, int ref) 19 | : mHexBinaryEncoder(ostream) 20 | , mUdReference(ref) 21 | { 22 | } 23 | 24 | HexBinaryEncoderUserdata::~HexBinaryEncoderUserdata() 25 | { 26 | } 27 | 28 | std::ostream& HexBinaryEncoderUserdata::ostream() 29 | { 30 | return mHexBinaryEncoder; 31 | } 32 | 33 | // register metatable for this class 34 | bool HexBinaryEncoderUserdata::registerHexBinaryEncoder(lua_State* L) 35 | { 36 | struct CFunctions methods[] = 37 | { 38 | { "__gc", metamethod__gc }, 39 | { "__tostring", metamethod__tostring }, 40 | { "write", write }, 41 | { "flush", flush }, 42 | { "seek", seek }, 43 | { NULL, NULL} 44 | }; 45 | 46 | setupUserdataMetatable(L, POCO_HEXBINARYENCODER_METATABLE_NAME, methods); 47 | return true; 48 | } 49 | 50 | /// Constructs a new hexbinaryencoder userdata. 51 | // @tparam userdata ostream destination for base 32 encoded data. 52 | // @bool[opt] padding specifies to use padding or not. 53 | // @return userdata or nil. (error) 54 | // @return error message. 55 | // @function new 56 | // @see ostream 57 | int HexBinaryEncoderUserdata::HexBinaryEncoder(lua_State* L) 58 | { 59 | int firstArg = lua_istable(L, 1) ? 2 : 1; 60 | OStream* os = checkPrivateUserdata(L, firstArg); 61 | 62 | lua_pushvalue(L, firstArg); 63 | int ref = luaL_ref(L, LUA_REGISTRYINDEX); 64 | 65 | HexBinaryEncoderUserdata* hbeud = NULL; 66 | void* p = lua_newuserdata(L, sizeof *hbeud); 67 | 68 | try 69 | { 70 | hbeud = new(p) HexBinaryEncoderUserdata(os->ostream(), ref); 71 | } 72 | catch (const std::exception& e) 73 | { 74 | luaL_unref(L, LUA_REGISTRYINDEX, ref); 75 | return pushException(L, e); 76 | } 77 | 78 | setupPocoUserdata(L, hbeud, POCO_HEXBINARYENCODER_METATABLE_NAME); 79 | return 1; 80 | } 81 | 82 | // metamethod infrastructure 83 | int HexBinaryEncoderUserdata::metamethod__tostring(lua_State* L) 84 | { 85 | HexBinaryEncoderUserdata* hbeud = checkPrivateUserdata(L, 1); 86 | lua_pushfstring(L, "Poco.HexBinaryEncoder (%p)", static_cast(hbeud)); 87 | 88 | return 1; 89 | } 90 | 91 | int HexBinaryEncoderUserdata::metamethod__gc(lua_State* L) 92 | { 93 | HexBinaryEncoderUserdata* hbeud = checkPrivateUserdata(L, 1); 94 | luaL_unref(L, LUA_REGISTRYINDEX, hbeud->mUdReference); 95 | hbeud->~HexBinaryEncoderUserdata(); 96 | 97 | return 0; 98 | } 99 | /// 100 | // @type hexbinaryencoder 101 | 102 | } // LuaPoco 103 | 104 | -------------------------------------------------------------------------------- /src/foundation/HexBinaryEncoder.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_HEXBINARYENCODER_H 2 | #define LUA_POCO_HEXBINARYENCODER_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include "OStream.h" 7 | #include 8 | 9 | extern "C" 10 | { 11 | LUAPOCO_API int luaopen_poco_hexbinaryencoder(lua_State* L); 12 | } 13 | 14 | namespace LuaPoco 15 | { 16 | 17 | extern const char* POCO_HEXBINARYENCODER_METATABLE_NAME; 18 | 19 | class HexBinaryEncoderUserdata : public Userdata, public OStream 20 | { 21 | public: 22 | HexBinaryEncoderUserdata(std::ostream & ostr, int ref); 23 | virtual ~HexBinaryEncoderUserdata(); 24 | virtual std::ostream& ostream(); 25 | // register metatable for this class 26 | static bool registerHexBinaryEncoder(lua_State* L); 27 | // constructor function 28 | static int HexBinaryEncoder(lua_State* L); 29 | 30 | Poco::HexBinaryEncoder mHexBinaryEncoder; 31 | private: 32 | int mUdReference; 33 | // metamethod infrastructure 34 | static int metamethod__tostring(lua_State* L); 35 | static int metamethod__gc(lua_State* L); 36 | }; 37 | 38 | } // LuaPoco 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/foundation/IStream.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_ISTREAM_H 2 | #define LUA_POCO_ISTREAM_H 3 | 4 | #include 5 | #include "LuaPoco.h" 6 | #include "Userdata.h" 7 | 8 | namespace LuaPoco 9 | { 10 | 11 | extern const char* POCO_ISTREAM_METATABLE_NAME; 12 | 13 | class IStream 14 | { 15 | public: 16 | virtual std::istream& istream() = 0; 17 | protected: 18 | // userdata methods 19 | static int read(lua_State* L); 20 | static int lines(lua_State* L); 21 | static int line_iterator(lua_State* L); 22 | static int seek(lua_State* L); 23 | }; 24 | 25 | // represents a generic ostream to Lua when a POCO API returns an std::istream 26 | // for i/o purposes. 27 | class IStreamUserdata : public Userdata, public IStream 28 | { 29 | public: 30 | // as IStreamUserdata has no Lua constructor, it is expected that whichever 31 | // class creates an instance of this, that it will create a reference in the 32 | // registry to whatever userdata that owns the std::istream reference in order 33 | // to prevent usage after collection. 34 | IStreamUserdata(std::istream& istream, int udReference = LUA_NOREF); 35 | virtual ~IStreamUserdata(); 36 | virtual std::istream& istream(); 37 | // register metatable for this class 38 | static bool registerIStream(lua_State* L); 39 | private: 40 | // metamethod infrastructure 41 | static int metamethod__gc(lua_State* L); 42 | static int metamethod__tostring(lua_State* L); 43 | int mIStreamReference; 44 | std::istream& mIStream; 45 | }; 46 | 47 | } // LuaPoco 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /src/foundation/InflatingIStream.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_INFLATINGISTREAM_H 2 | #define LUA_POCO_INFLATINGISTREAM_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include "IStream.h" 7 | #include 8 | 9 | extern "C" 10 | { 11 | LUAPOCO_API int luaopen_poco_inflatingistream(lua_State* L); 12 | } 13 | 14 | namespace LuaPoco 15 | { 16 | 17 | extern const char* POCO_INFLATINGISTREAM_METATABLE_NAME; 18 | 19 | class InflatingIStreamUserdata : public Userdata, public IStream 20 | { 21 | public: 22 | InflatingIStreamUserdata(std::istream& istream, Poco::InflatingStreamBuf::StreamType type, int ref); 23 | InflatingIStreamUserdata(std::istream& istream, int windowBits, int ref); 24 | virtual ~InflatingIStreamUserdata(); 25 | virtual std::istream& istream(); 26 | // register metatable for this class 27 | static bool registerInflatingIStream(lua_State* L); 28 | // constructor function 29 | static int InflatingIStream(lua_State* L); 30 | 31 | Poco::InflatingInputStream mInflatingInputStream; 32 | private: 33 | // metamethod infrastructure 34 | static int metamethod__gc(lua_State* L); 35 | static int metamethod__tostring(lua_State* L); 36 | // methods 37 | static int reset(lua_State* L); 38 | int mUdReference; 39 | }; 40 | 41 | } // LuaPoco 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/foundation/InflatingOStream.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_INFLATINGOSTREAM_H 2 | #define LUA_POCO_INFLATINGOSTREAM_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include "OStream.h" 7 | #include 8 | 9 | extern "C" 10 | { 11 | LUAPOCO_API int luaopen_poco_inflatingostream(lua_State* L); 12 | } 13 | 14 | namespace LuaPoco 15 | { 16 | 17 | extern const char* POCO_INFLATINGOSTREAM_METATABLE_NAME; 18 | 19 | class InflatingOStreamUserdata : public Userdata, public OStream 20 | { 21 | public: 22 | InflatingOStreamUserdata(std::ostream& ostream, Poco::InflatingStreamBuf::StreamType type, int ref); 23 | InflatingOStreamUserdata(std::ostream& ostream, int windowBits, int ref); 24 | virtual ~InflatingOStreamUserdata(); 25 | virtual std::ostream& ostream(); 26 | // register metatable for this class 27 | static bool registerInflatingOStream(lua_State* L); 28 | // constructor function 29 | static int InflatingOStream(lua_State* L); 30 | 31 | Poco::InflatingOutputStream mInflatingOutputStream; 32 | private: 33 | // metamethod infrastructure 34 | static int metamethod__gc(lua_State* L); 35 | static int metamethod__tostring(lua_State* L); 36 | // methods 37 | static int close(lua_State* L); 38 | int mUdReference; 39 | }; 40 | 41 | } // LuaPoco 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/foundation/JSON.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_JSON_H 2 | #define LUA_POCO_JSON_H 3 | 4 | #include "LuaPoco.h" 5 | 6 | extern "C" 7 | { 8 | LUAPOCO_API int luaopen_poco_json(lua_State* L); 9 | } 10 | 11 | namespace LuaPoco 12 | { 13 | namespace JSON 14 | { 15 | 16 | int decode(lua_State* L); 17 | int encode(lua_State* L); 18 | int getNull(lua_State* L); 19 | int getEmptyObject(lua_State* L); 20 | int getEmptyArray(lua_State* L); 21 | 22 | } 23 | } // LuaPoco 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /src/foundation/MemoryIStream.cpp: -------------------------------------------------------------------------------- 1 | /// memoryistream 2 | // An istream interface for pipe userdata. 3 | // @module memoryistream 4 | #include "MemoryIStream.h" 5 | #include "Buffer.h" 6 | #include "SharedMemory.h" 7 | #include 8 | 9 | int luaopen_poco_memoryistream(lua_State* L) 10 | { 11 | LuaPoco::MemoryIStreamUserdata::registerMemoryIStream(L); 12 | return LuaPoco::loadConstructor(L, LuaPoco::MemoryIStreamUserdata::MemoryIStream); 13 | } 14 | 15 | namespace LuaPoco 16 | { 17 | 18 | const char* POCO_MEMORYISTREAM_METATABLE_NAME = "Poco.MemoryIStream.metatable"; 19 | 20 | MemoryIStreamUserdata::MemoryIStreamUserdata(const char* buffer, size_t bufferSize) 21 | : mMemoryInputStream(buffer, bufferSize) 22 | , mUdReference(0) 23 | { 24 | } 25 | 26 | MemoryIStreamUserdata::~MemoryIStreamUserdata() 27 | { 28 | } 29 | 30 | std::istream& MemoryIStreamUserdata::istream() 31 | { 32 | return mMemoryInputStream; 33 | } 34 | 35 | // register metatable for this class 36 | bool MemoryIStreamUserdata::registerMemoryIStream(lua_State* L) 37 | { 38 | struct CFunctions methods[] = 39 | { 40 | { "__gc", metamethod__gc }, 41 | { "__tostring", metamethod__tostring }, 42 | { "read", read }, 43 | { "lines", lines }, 44 | { "seek", seek }, 45 | { NULL, NULL} 46 | }; 47 | 48 | setupUserdataMetatable(L, POCO_MEMORYISTREAM_METATABLE_NAME, methods); 49 | return true; 50 | } 51 | 52 | /// Constructs a new memoryistream userdata. 53 | // memoryistream holds a reference to a buffer/sharedmemory userdata to prevent the buffer from 54 | // being garbage collected while the memoryistream is still trying to use it. 55 | // @tparam userdata buffer buffer userdata or sharedmemory userdata. 56 | // @return istream userdata or nil. (error) 57 | // @return error message. 58 | // @function new 59 | // @see buffer 60 | // @see sharedmemory 61 | // @see istream 62 | int MemoryIStreamUserdata::MemoryIStream(lua_State* L) 63 | { 64 | int firstArg = lua_istable(L, 1) ? 2 : 1; 65 | 66 | const char* errorMsg = "invalid userdata, expected: buffer userdata or sharedmemory userdata."; 67 | const char* buffer = NULL; 68 | size_t bufferSize = 0; 69 | Userdata* ud = getPrivateUserdata(L, firstArg); 70 | 71 | BufferUserdata* bud = dynamic_cast(ud); 72 | SharedMemoryUserdata* smud = dynamic_cast(ud); 73 | 74 | if (bud) 75 | { 76 | buffer = bud->mBuffer.begin(); 77 | bufferSize = bud->mCapacity; 78 | } 79 | else if (smud) 80 | { 81 | buffer = smud->mSharedMemory.begin(); 82 | bufferSize = smud->mSize; 83 | } 84 | 85 | if (buffer == NULL || bufferSize == 0) 86 | { 87 | lua_pushnil(L); 88 | lua_pushstring(L, errorMsg); 89 | return 2; 90 | } 91 | 92 | MemoryIStreamUserdata* misud = NULL; 93 | void* p = lua_newuserdata(L, sizeof *misud); 94 | 95 | try 96 | { 97 | misud = new(p) MemoryIStreamUserdata(buffer, bufferSize); 98 | } 99 | catch (const std::exception& e) 100 | { 101 | return pushException(L, e); 102 | } 103 | 104 | // store a reference to the Buffer/SharedMemory to prevent it from being 105 | // garbage collected while the memoryostream is using it. 106 | lua_pushvalue(L, firstArg); 107 | misud->mUdReference = luaL_ref(L, LUA_REGISTRYINDEX); 108 | 109 | setupPocoUserdata(L, misud, POCO_MEMORYISTREAM_METATABLE_NAME); 110 | return 1; 111 | } 112 | 113 | int MemoryIStreamUserdata::metamethod__gc(lua_State* L) 114 | { 115 | MemoryIStreamUserdata* misud = checkPrivateUserdata(L, 1); 116 | 117 | luaL_unref(L, LUA_REGISTRYINDEX, misud->mUdReference); 118 | misud->~MemoryIStreamUserdata(); 119 | 120 | return 0; 121 | } 122 | 123 | // metamethod infrastructure 124 | int MemoryIStreamUserdata::metamethod__tostring(lua_State* L) 125 | { 126 | MemoryIStreamUserdata* misud = checkPrivateUserdata(L, 1); 127 | lua_pushfstring(L, "Poco.MemoryIStream (%p)", static_cast(misud)); 128 | 129 | return 1; 130 | } 131 | 132 | } // LuaPoco 133 | -------------------------------------------------------------------------------- /src/foundation/MemoryIStream.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_MEMORYISTREAM_H 2 | #define LUA_POCO_MEMORYISTREAM_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include "IStream.h" 7 | #include 8 | 9 | extern "C" 10 | { 11 | LUAPOCO_API int luaopen_poco_memoryistream(lua_State* L); 12 | } 13 | 14 | namespace LuaPoco 15 | { 16 | 17 | extern const char* POCO_MEMORYISTREAM_METATABLE_NAME; 18 | 19 | class MemoryIStreamUserdata : public Userdata, public IStream 20 | { 21 | public: 22 | MemoryIStreamUserdata(const char* buffer, size_t size); 23 | virtual ~MemoryIStreamUserdata(); 24 | virtual std::istream& istream(); 25 | // register metatable for this class 26 | static bool registerMemoryIStream(lua_State* L); 27 | // constructor function 28 | static int MemoryIStream(lua_State* L); 29 | 30 | Poco::MemoryInputStream mMemoryInputStream; 31 | private: 32 | // metamethod infrastructure 33 | static int metamethod__gc(lua_State* L); 34 | static int metamethod__tostring(lua_State* L); 35 | 36 | int mUdReference; 37 | }; 38 | 39 | } // LuaPoco 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/foundation/MemoryOStream.cpp: -------------------------------------------------------------------------------- 1 | /// memoryostream 2 | // An ostream interface for pipe userdata. 3 | // @module memoryostream 4 | #include "MemoryOStream.h" 5 | #include "Buffer.h" 6 | #include "SharedMemory.h" 7 | #include 8 | 9 | int luaopen_poco_memoryostream(lua_State* L) 10 | { 11 | LuaPoco::MemoryOStreamUserdata::registerMemoryOStream(L); 12 | return LuaPoco::loadConstructor(L, LuaPoco::MemoryOStreamUserdata::MemoryOStream); 13 | } 14 | 15 | namespace LuaPoco 16 | { 17 | 18 | const char* POCO_MEMORYOSTREAM_METATABLE_NAME = "Poco.MemoryOStream.metatable"; 19 | 20 | MemoryOStreamUserdata::MemoryOStreamUserdata(char* buffer, size_t bufferSize) 21 | : mMemoryOutputStream(buffer, bufferSize) 22 | , mUdReference(0) 23 | { 24 | } 25 | 26 | MemoryOStreamUserdata::~MemoryOStreamUserdata() 27 | { 28 | } 29 | 30 | std::ostream& MemoryOStreamUserdata::ostream() 31 | { 32 | return mMemoryOutputStream; 33 | } 34 | 35 | // register metatable for this class 36 | bool MemoryOStreamUserdata::registerMemoryOStream(lua_State* L) 37 | { 38 | struct CFunctions methods[] = 39 | { 40 | { "__gc", metamethod__gc }, 41 | { "__tostring", metamethod__tostring }, 42 | { "write", write }, 43 | { "seek", seek }, 44 | { "flush", flush }, 45 | { "bytesWritten", bytesWritten }, 46 | { NULL, NULL} 47 | }; 48 | 49 | setupUserdataMetatable(L, POCO_MEMORYOSTREAM_METATABLE_NAME, methods); 50 | return true; 51 | } 52 | 53 | /// Constructs a new memoryostream userdata. 54 | // memoryostream holds a reference to a buffer/sharedmemory userdata to prevent the buffer from 55 | // being garbage collected while the memoryostream is still trying to use it. 56 | // @tparam userdata buffer buffer userdata or sharedmemory userdata. 57 | // @return ostream userdata or nil. (error) 58 | // @return error message. 59 | // @function new 60 | // @see buffer 61 | // @see sharedmemory 62 | // @see ostream 63 | int MemoryOStreamUserdata::MemoryOStream(lua_State* L) 64 | { 65 | int firstArg = lua_istable(L, 1) ? 2 : 1; 66 | 67 | const char* errorMsg = "invalid userdata, expected: buffer userdata or sharedmemory userdata."; 68 | char* buffer = NULL; 69 | size_t bufferSize = 0; 70 | Userdata* ud = getPrivateUserdata(L, firstArg); 71 | 72 | BufferUserdata* bud = dynamic_cast(ud); 73 | SharedMemoryUserdata* smud = dynamic_cast(ud); 74 | 75 | if (bud) 76 | { 77 | buffer = bud->mBuffer.begin(); 78 | bufferSize = bud->mCapacity; 79 | } 80 | else if (smud) 81 | { 82 | errorMsg = "read only sharedmemory cannot be used with memoryostream."; 83 | 84 | if (smud->mMode == Poco::SharedMemory::AM_WRITE) 85 | { 86 | buffer = smud->mSharedMemory.begin(); 87 | bufferSize = smud->mSize; 88 | } 89 | } 90 | 91 | if (buffer == NULL || bufferSize == 0) 92 | { 93 | lua_pushnil(L); 94 | lua_pushstring(L, errorMsg); 95 | return 2; 96 | } 97 | 98 | 99 | MemoryOStreamUserdata* mosud = NULL; 100 | void* p = lua_newuserdata(L, sizeof *mosud); 101 | 102 | try 103 | { 104 | mosud = new(p) MemoryOStreamUserdata(buffer, bufferSize); 105 | } 106 | catch (const Poco::Exception& e) 107 | { 108 | return pushException(L, e); 109 | } 110 | 111 | // store a reference to the Buffer/SharedMemory to prevent it from being 112 | // garbage collected while the memoryostream is using it. 113 | lua_pushvalue(L, firstArg); 114 | mosud->mUdReference = luaL_ref(L, LUA_REGISTRYINDEX); 115 | 116 | setupPocoUserdata(L, mosud, POCO_MEMORYOSTREAM_METATABLE_NAME); 117 | return 1; 118 | } 119 | 120 | // metamethod infrastructure 121 | int MemoryOStreamUserdata::metamethod__gc(lua_State* L) 122 | { 123 | MemoryOStreamUserdata* mosud = checkPrivateUserdata(L, 1); 124 | 125 | luaL_unref(L, LUA_REGISTRYINDEX, mosud->mUdReference); 126 | mosud->~MemoryOStreamUserdata(); 127 | 128 | return 0; 129 | } 130 | 131 | int MemoryOStreamUserdata::metamethod__tostring(lua_State* L) 132 | { 133 | MemoryOStreamUserdata* mosud = checkPrivateUserdata(L, 1); 134 | lua_pushfstring(L, "Poco.MemoryOStream (%p)", static_cast(mosud)); 135 | 136 | return 1; 137 | } 138 | 139 | int MemoryOStreamUserdata::bytesWritten(lua_State* L) 140 | { 141 | MemoryOStreamUserdata* mosud = checkPrivateUserdata(L, 1); 142 | lua_pushinteger(L, static_cast(mosud->mMemoryOutputStream.charsWritten())); 143 | 144 | return 1; 145 | } 146 | 147 | } // LuaPoco 148 | -------------------------------------------------------------------------------- /src/foundation/MemoryOStream.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_MEMORYOSTREAM_H 2 | #define LUA_POCO_MEMORYOSTREAM_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include "OStream.h" 7 | #include 8 | 9 | extern "C" 10 | { 11 | LUAPOCO_API int luaopen_poco_memoryostream(lua_State* L); 12 | } 13 | 14 | namespace LuaPoco 15 | { 16 | 17 | extern const char* POCO_MEMORYISTREAM_METATABLE_NAME; 18 | 19 | class MemoryOStreamUserdata : public Userdata, public OStream 20 | { 21 | public: 22 | MemoryOStreamUserdata(char* buffer, size_t size); 23 | virtual ~MemoryOStreamUserdata(); 24 | virtual std::ostream& ostream(); 25 | // register metatable for this class 26 | static bool registerMemoryOStream(lua_State* L); 27 | // constructor function 28 | static int MemoryOStream(lua_State* L); 29 | 30 | Poco::MemoryOutputStream mMemoryOutputStream; 31 | private: 32 | // metamethod infrastructure 33 | static int metamethod__gc(lua_State* L); 34 | static int metamethod__tostring(lua_State* L); 35 | static int bytesWritten(lua_State* L); 36 | 37 | int mUdReference; 38 | }; 39 | 40 | } // LuaPoco 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/foundation/Mutex.cpp: -------------------------------------------------------------------------------- 1 | /// Synchronization mechanism used to control access to a shared resource. 2 | // Note: Mutexes are recursive, that is, the same mutex can be locked multiple times by the same thread (but, of course, not by other threads). Also note that recursive mutexes are heavier and slower than the fastmutex module. 3 | // Note: mutex userdata are copyable/sharable between threads. 4 | // @module mutex 5 | 6 | #include "Mutex.h" 7 | #include 8 | 9 | int luaopen_poco_mutex(lua_State* L) 10 | { 11 | LuaPoco::MutexUserdata::registerMutex(L); 12 | return LuaPoco::loadConstructor(L, LuaPoco::MutexUserdata::Mutex); 13 | } 14 | 15 | namespace LuaPoco 16 | { 17 | 18 | const char* POCO_MUTEX_METATABLE_NAME = "Poco.Mutex.metatable"; 19 | 20 | MutexUserdata::MutexUserdata() : 21 | mMutex(new Poco::Mutex()) 22 | { 23 | } 24 | 25 | // construct new Ud from existing SharedPtr (only useful for 26 | MutexUserdata::MutexUserdata(const Poco::SharedPtr& fm) : 27 | mMutex(fm) 28 | { 29 | } 30 | 31 | MutexUserdata::~MutexUserdata() 32 | { 33 | } 34 | 35 | bool MutexUserdata::copyToState(lua_State *L) 36 | { 37 | registerMutex(L); 38 | MutexUserdata* mud = NULL; 39 | void* p = lua_newuserdata(L, sizeof *mud); 40 | 41 | try 42 | { 43 | mud = new(p) MutexUserdata(mMutex); 44 | } 45 | catch (const std::exception& e) 46 | { 47 | lua_pop(L, 1); 48 | return false; 49 | } 50 | 51 | setupPocoUserdata(L, mud, POCO_MUTEX_METATABLE_NAME); 52 | return true; 53 | } 54 | 55 | // register metatable for this class 56 | bool MutexUserdata::registerMutex(lua_State* L) 57 | { 58 | struct CFunctions methods[] = 59 | { 60 | { "__gc", metamethod__gc }, 61 | { "__tostring", metamethod__tostring }, 62 | { "lock", lock }, 63 | { "tryLock", tryLock }, 64 | { "unlock", unlock }, 65 | { NULL, NULL} 66 | }; 67 | 68 | setupUserdataMetatable(L, POCO_MUTEX_METATABLE_NAME, methods); 69 | return true; 70 | } 71 | 72 | /// create a new mutex userdata. 73 | // @return userdata or nil. (error) 74 | // @return error message. 75 | // @function new 76 | int MutexUserdata::Mutex(lua_State* L) 77 | { 78 | MutexUserdata* mud = NULL; 79 | void* p = lua_newuserdata(L, sizeof *mud); 80 | 81 | try 82 | { 83 | mud = new(p) MutexUserdata(); 84 | } 85 | catch (const std::exception& e) 86 | { 87 | return pushException(L, e); 88 | } 89 | 90 | setupPocoUserdata(L, mud, POCO_MUTEX_METATABLE_NAME); 91 | return 1; 92 | } 93 | 94 | /// 95 | // @type mutex 96 | 97 | // metamethod infrastructure 98 | int MutexUserdata::metamethod__tostring(lua_State* L) 99 | { 100 | MutexUserdata* mud = checkPrivateUserdata(L, 1); 101 | 102 | lua_pushfstring(L, "Poco.Mutex (%p)", static_cast(mud)); 103 | return 1; 104 | } 105 | 106 | /// Locks the mutex. Blocks if the mutex is held by another thread. 107 | // @function lock 108 | 109 | // userdata methods 110 | int MutexUserdata::lock(lua_State* L) 111 | { 112 | int rv = 0; 113 | MutexUserdata* mud = checkPrivateUserdata(L, 1); 114 | 115 | try 116 | { 117 | mud->mMutex->lock(); 118 | } 119 | catch (const std::exception& e) 120 | { 121 | pushException(L, e); 122 | lua_error(L); 123 | } 124 | 125 | return rv; 126 | } 127 | 128 | /// Attempts to lock the mutex. 129 | // @int[opt] ms optional number of milliseconds to try to acquire the mutex. 130 | // @return boolean indicating if lock was acquired or timeout occured. 131 | // @function tryLock 132 | int MutexUserdata::tryLock(lua_State* L) 133 | { 134 | int rv = 0; 135 | MutexUserdata* mud = checkPrivateUserdata(L, 1); 136 | 137 | int top = lua_gettop(L); 138 | 139 | long ms; 140 | if (top > 1) 141 | ms = luaL_checkinteger(L, 2); 142 | 143 | try 144 | { 145 | bool result = false; 146 | if (top > 1) 147 | result = mud->mMutex->tryLock(ms); 148 | else 149 | result = mud->mMutex->tryLock(); 150 | 151 | lua_pushboolean(L, result); 152 | rv = 1; 153 | } 154 | catch (const std::exception& e) 155 | { 156 | rv = pushException(L, e); 157 | } 158 | 159 | return rv; 160 | } 161 | 162 | /// Unlocks the mutex so that it can be acquired by other threads. 163 | // @function unlock 164 | int MutexUserdata::unlock(lua_State* L) 165 | { 166 | int rv = 0; 167 | MutexUserdata* mud = checkPrivateUserdata(L, 1); 168 | 169 | try 170 | { 171 | mud->mMutex->unlock(); 172 | lua_pushboolean(L, 1); 173 | rv = 1; 174 | } 175 | catch (const std::exception& e) 176 | { 177 | rv = pushException(L, e); 178 | } 179 | 180 | return rv; 181 | } 182 | 183 | } // LuaPoco 184 | -------------------------------------------------------------------------------- /src/foundation/Mutex.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_MUTEX_H 2 | #define LUA_POCO_MUTEX_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include 7 | #include 8 | 9 | extern "C" 10 | { 11 | LUAPOCO_API int luaopen_poco_mutex(lua_State* L); 12 | } 13 | 14 | namespace LuaPoco 15 | { 16 | 17 | extern const char* POCO_MUTEX_METATABLE_NAME; 18 | 19 | class MutexUserdata : public Userdata 20 | { 21 | public: 22 | MutexUserdata(); 23 | MutexUserdata(const Poco::SharedPtr& mtx); 24 | virtual ~MutexUserdata(); 25 | virtual bool copyToState(lua_State *L); 26 | // register metatable for this class 27 | static bool registerMutex(lua_State* L); 28 | // constructor function 29 | static int Mutex(lua_State* L); 30 | 31 | Poco::SharedPtr mMutex; 32 | private: 33 | // metamethod infrastructure 34 | static int metamethod__tostring(lua_State* L); 35 | 36 | // userdata methods 37 | static int lock(lua_State* L); 38 | static int tryLock(lua_State* L); 39 | static int unlock(lua_State* L); 40 | }; 41 | 42 | } // LuaPoco 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /src/foundation/NamedEvent.cpp: -------------------------------------------------------------------------------- 1 | /// Global synchronization object for one process to signal another of an event. 2 | // Note: namedevent is always autoresetting. 3 | // 4 | // Note: There should not be more than one instance of namedevent for a given name in a process. Otherwise, the instances may interfere with each other. 5 | // @module namedevent 6 | 7 | #include "NamedEvent.h" 8 | #include 9 | #include 10 | 11 | int luaopen_poco_namedevent(lua_State* L) 12 | { 13 | LuaPoco::NamedEventUserdata::registerNamedEvent(L); 14 | return LuaPoco::loadConstructor(L, LuaPoco::NamedEventUserdata::NamedEvent); 15 | } 16 | 17 | namespace LuaPoco 18 | { 19 | 20 | const char* POCO_NAMEDEVENT_METATABLE_NAME = "Poco.NamedEvent.metatable"; 21 | 22 | NamedEventUserdata::NamedEventUserdata(const std::string& name) : 23 | mNamedEvent(name) 24 | { 25 | } 26 | 27 | NamedEventUserdata::~NamedEventUserdata() 28 | { 29 | } 30 | 31 | // register metatable for this class 32 | bool NamedEventUserdata::registerNamedEvent(lua_State* L) 33 | { 34 | struct CFunctions methods[] = 35 | { 36 | { "__gc", metamethod__gc }, 37 | { "__tostring", metamethod__tostring }, 38 | { "set", set }, 39 | { "wait", wait }, 40 | { NULL, NULL} 41 | }; 42 | 43 | setupUserdataMetatable(L, POCO_NAMEDEVENT_METATABLE_NAME, methods); 44 | 45 | return true; 46 | } 47 | 48 | /// constructs a new namedevent userdata. 49 | // @string name global event name. 50 | // @return userdata. 51 | // @function new 52 | 53 | int NamedEventUserdata::NamedEvent(lua_State* L) 54 | { 55 | int firstArg = lua_istable(L, 1) ? 2 : 1; 56 | const char* name = luaL_checkstring(L, firstArg); 57 | 58 | NamedEventUserdata* neud = NULL; 59 | void* p = lua_newuserdata(L, sizeof *neud); 60 | 61 | try 62 | { 63 | neud = new(p) NamedEventUserdata(name); 64 | } 65 | catch (const std::exception& e) 66 | { 67 | return pushException(L, e); 68 | } 69 | 70 | setupPocoUserdata(L, neud, POCO_NAMEDEVENT_METATABLE_NAME); 71 | return 1; 72 | } 73 | 74 | /// 75 | // @type namedevent 76 | 77 | // metamethod infrastructure 78 | int NamedEventUserdata::metamethod__tostring(lua_State* L) 79 | { 80 | NamedEventUserdata* neud = checkPrivateUserdata(L, 1); 81 | 82 | lua_pushfstring(L, "Poco.NamedEvent (%p)", static_cast(neud)); 83 | return 1; 84 | } 85 | 86 | // userdata methods 87 | 88 | /// Signals the event. 89 | // The process waiting for the event can resume execution. 90 | // @function set 91 | int NamedEventUserdata::set(lua_State* L) 92 | { 93 | NamedEventUserdata* neud = checkPrivateUserdata(L, 1); 94 | 95 | neud->mNamedEvent.set(); 96 | 97 | return 0; 98 | } 99 | 100 | /// Waits for the event to become signaled. 101 | // Blocks the process until the event has become signaled. 102 | // @function wait 103 | int NamedEventUserdata::wait(lua_State* L) 104 | { 105 | NamedEventUserdata* neud = checkPrivateUserdata(L, 1); 106 | 107 | neud->mNamedEvent.wait(); 108 | 109 | return 0; 110 | } 111 | 112 | } // LuaPoco 113 | -------------------------------------------------------------------------------- /src/foundation/NamedEvent.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_NAMEDEVENT_H 2 | #define LUA_POCO_NAMEDEVENT_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include 7 | #include 8 | 9 | extern "C" 10 | { 11 | LUAPOCO_API int luaopen_poco_namedevent(lua_State* L); 12 | } 13 | 14 | namespace LuaPoco 15 | { 16 | 17 | extern const char* POCO_NAMEDEVENT_METATABLE_NAME; 18 | 19 | class NamedEventUserdata : public Userdata 20 | { 21 | public: 22 | NamedEventUserdata(const std::string& name); 23 | virtual ~NamedEventUserdata(); 24 | // register metatable for this class 25 | static bool registerNamedEvent(lua_State* L); 26 | // constructor function 27 | static int NamedEvent(lua_State* L); 28 | private: 29 | // metamethod infrastructure 30 | static int metamethod__tostring(lua_State* L); 31 | 32 | // userdata methods 33 | static int set(lua_State* L); 34 | static int wait(lua_State* L); 35 | 36 | Poco::NamedEvent mNamedEvent; 37 | }; 38 | 39 | } // LuaPoco 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/foundation/NamedMutex.cpp: -------------------------------------------------------------------------------- 1 | /// Global synchronization mechanism used to control access to a shared resource. 2 | // Note: There should not be more than one instance of namedmutex for a given name in a process. Otherwise, the instances may interfere with each other. 3 | // @module namedmutex 4 | 5 | #include "NamedMutex.h" 6 | #include 7 | 8 | int luaopen_poco_namedmutex(lua_State* L) 9 | { 10 | LuaPoco::NamedMutexUserdata::registerNamedMutex(L); 11 | return LuaPoco::loadConstructor(L, LuaPoco::NamedMutexUserdata::NamedMutex); 12 | } 13 | 14 | namespace LuaPoco 15 | { 16 | 17 | const char* POCO_NAMEDMUTEX_METATABLE_NAME = "Poco.NamedMutex.metatable"; 18 | 19 | NamedMutexUserdata::NamedMutexUserdata(const std::string& name) : 20 | mNamedMutex(name) 21 | { 22 | } 23 | 24 | NamedMutexUserdata::~NamedMutexUserdata() 25 | { 26 | } 27 | 28 | // register metatable for this class 29 | bool NamedMutexUserdata::registerNamedMutex(lua_State* L) 30 | { 31 | struct CFunctions methods[] = 32 | { 33 | { "__gc", metamethod__gc }, 34 | { "__tostring", metamethod__tostring }, 35 | { "lock", lock }, 36 | { "tryLock", tryLock }, 37 | { "unlock", unlock }, 38 | { NULL, NULL} 39 | }; 40 | 41 | setupUserdataMetatable(L, POCO_NAMEDMUTEX_METATABLE_NAME, methods); 42 | return true; 43 | } 44 | 45 | /// constructs a new namedevent userdata. 46 | // @string name global mutex name. 47 | // @return userdata. 48 | // @function new 49 | int NamedMutexUserdata::NamedMutex(lua_State* L) 50 | { 51 | int firstArg = lua_istable(L, 1) ? 2 : 1; 52 | const char* name = luaL_checkstring(L, firstArg); 53 | 54 | NamedMutexUserdata* nmud = NULL; 55 | void* p = lua_newuserdata(L, sizeof *nmud); 56 | try 57 | { 58 | nmud = new(p) NamedMutexUserdata(name); 59 | } 60 | catch (const std::exception& e) 61 | { 62 | return pushException(L, e); 63 | } 64 | 65 | setupPocoUserdata(L, nmud, POCO_NAMEDMUTEX_METATABLE_NAME); 66 | return 1; 67 | } 68 | 69 | /// 70 | // @type namedmutex 71 | 72 | // metamethod infrastructure 73 | int NamedMutexUserdata::metamethod__tostring(lua_State* L) 74 | { 75 | NamedMutexUserdata* nmud = checkPrivateUserdata(L, 1); 76 | 77 | lua_pushfstring(L, "Poco.NamedMutex (%p)", static_cast(nmud)); 78 | return 1; 79 | } 80 | 81 | // userdata methods 82 | 83 | /// Locks the namedmutex. 84 | // Blocks if the mutex is held by another thread. 85 | // @function lock 86 | int NamedMutexUserdata::lock(lua_State* L) 87 | { 88 | NamedMutexUserdata* nmud = checkPrivateUserdata(L, 1); 89 | 90 | nmud->mNamedMutex.lock(); 91 | 92 | return 0; 93 | } 94 | 95 | /// Attempts to lock the namedmutex. 96 | // Returns false immediately if the mutex is already held by another process. 97 | // @return boolean indicating if lock was acquired or not. 98 | // @function tryLock 99 | int NamedMutexUserdata::tryLock(lua_State* L) 100 | { 101 | NamedMutexUserdata* nmud = checkPrivateUserdata(L, 1); 102 | 103 | bool locked = nmud->mNamedMutex.tryLock(); 104 | lua_pushboolean(L, locked); 105 | 106 | return 1; 107 | } 108 | 109 | /// Unlocks the mutex so that it can be acquired by other threads. 110 | // @function unlock 111 | int NamedMutexUserdata::unlock(lua_State* L) 112 | { 113 | NamedMutexUserdata* nmud = checkPrivateUserdata(L, 1); 114 | 115 | nmud->mNamedMutex.unlock(); 116 | 117 | return 0; 118 | } 119 | 120 | } // LuaPoco 121 | -------------------------------------------------------------------------------- /src/foundation/NamedMutex.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_NAMEDMUTEX_H 2 | #define LUA_POCO_NAMEDMUTEX_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include 7 | #include 8 | 9 | extern "C" 10 | { 11 | LUAPOCO_API int luaopen_poco_namedmutex(lua_State* L); 12 | } 13 | 14 | namespace LuaPoco 15 | { 16 | 17 | extern const char* POCO_NAMEDMUTEX_METATABLE; 18 | 19 | class NamedMutexUserdata : public Userdata 20 | { 21 | public: 22 | NamedMutexUserdata(const std::string& name); 23 | virtual ~NamedMutexUserdata(); 24 | // register metatable for this class 25 | static bool registerNamedMutex(lua_State* L); 26 | // constructor function 27 | static int NamedMutex(lua_State* L); 28 | 29 | private: 30 | // metamethod infrastructure 31 | static int metamethod__tostring(lua_State* L); 32 | 33 | // userdata methods 34 | static int lock(lua_State* L); 35 | static int tryLock(lua_State* L); 36 | static int unlock(lua_State* L); 37 | 38 | Poco::NamedMutex mNamedMutex; 39 | }; 40 | 41 | } // LuaPoco 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/foundation/Notification.cpp: -------------------------------------------------------------------------------- 1 | #include "Userdata.h" 2 | #include "Notification.h" 3 | 4 | namespace LuaPoco 5 | { 6 | 7 | int transferNotification(lua_State* L, Poco::AutoPtr& n) 8 | { 9 | int top = lua_gettop(n->state); 10 | for (int i = 1; i <= top; ++i) 11 | { 12 | lua_pushvalue(n->state, i); 13 | if (!transferValue(L, n->state)) 14 | { 15 | lua_pushnil(L); 16 | lua_pushfstring(L, "non-copyable value at parameter %d\n", i); 17 | top = 2; 18 | break; 19 | } 20 | lua_pop(n->state, 1); 21 | } 22 | return top; 23 | } 24 | 25 | Notification::Notification() 26 | { 27 | state = luaL_newstate(); 28 | } 29 | 30 | Notification::~Notification() 31 | { 32 | lua_close(state); 33 | } 34 | 35 | bool Notification::setupState() 36 | { 37 | setupPrivateUserdata(state); 38 | return true; 39 | } 40 | 41 | } // LuaPoco 42 | -------------------------------------------------------------------------------- /src/foundation/Notification.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_NOTIFICATION_H 2 | #define LUA_POCO_NOTIFICATION_H 3 | 4 | #include "LuaPoco.h" 5 | #include "StateTransfer.h" 6 | #include 7 | 8 | namespace LuaPoco 9 | { 10 | 11 | class Notification : public Poco::Notification 12 | { 13 | public: 14 | Notification(); 15 | virtual ~Notification(); 16 | bool setupState(); 17 | lua_State* state; 18 | }; 19 | 20 | // utility function for transferring a Notification to a destination lua_State. 21 | int transferNotification(lua_State* L, Poco::AutoPtr& n); 22 | 23 | } // LuaPoco 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /src/foundation/NotificationFactory.cpp: -------------------------------------------------------------------------------- 1 | #include "NotificationFactory.h" 2 | #include 3 | 4 | namespace LuaPoco 5 | { 6 | 7 | Poco::AutoPtr NotificationFactory::createObject() 8 | { 9 | return new Notification; 10 | } 11 | 12 | bool NotificationFactory::validateObject(Poco::AutoPtr notification) 13 | { 14 | // this function could be used to do some sanity checking on the state, 15 | // but as of now there is nothing to check. 16 | return true; 17 | } 18 | 19 | void NotificationFactory::activateObject(Poco::AutoPtr notification) 20 | { 21 | // make sure all required LuaPoco structures are prepared in the state. 22 | notification->setupState(); 23 | // guarantee a clean stack before transferring data. 24 | lua_settop(notification->state, 0); 25 | } 26 | 27 | void NotificationFactory::deactivateObject(Poco::AutoPtr notification) 28 | { 29 | // clean the state in preparation for next use. 30 | lua_settop(notification->state, 0); 31 | lua_gc(notification->state, LUA_GCCOLLECT, 0); 32 | } 33 | 34 | void NotificationFactory::destroyObject(Poco::AutoPtr notification) 35 | { 36 | // no action is required to destruct the Notification as it will be destructed 37 | // via ~Poco::AutoPtr() when the ObjectPool vector is destructed. 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/foundation/NotificationFactory.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_NOTIFICATION_FACTORY_H 2 | #define LUA_POCO_NOTIFICATION_FACTORY_H 3 | 4 | #include "LuaPoco.h" 5 | #include 6 | #include 7 | #include "Notification.h" 8 | 9 | namespace LuaPoco 10 | { 11 | 12 | class NotificationFactory 13 | { 14 | public: 15 | Poco::AutoPtr createObject(); 16 | bool validateObject(Poco::AutoPtr notification); 17 | void activateObject(Poco::AutoPtr notification); 18 | void deactivateObject(Poco::AutoPtr notification); 19 | void destroyObject(Poco::AutoPtr notification); 20 | }; 21 | 22 | } // LuaPoco 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /src/foundation/NotificationQueue.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_NOTIFICATION_QUEUE_H 2 | #define LUA_POCO_NOTIFICATION_QUEUE_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include 7 | #include 8 | #include 9 | #include "Notification.h" 10 | #include "NotificationFactory.h" 11 | 12 | extern "C" 13 | { 14 | LUAPOCO_API int luaopen_poco_notificationqueue(lua_State* L); 15 | } 16 | 17 | namespace LuaPoco 18 | { 19 | 20 | extern const char* POCO_NOTIFICATIONQUEUE_METATABLE_NAME; 21 | 22 | class NotificationQueueUserdata : public Userdata 23 | { 24 | public: 25 | NotificationQueueUserdata(); 26 | NotificationQueueUserdata( 27 | const Poco::SharedPtr& nq, 28 | const Poco::SharedPtr, NotificationFactory> >& op); 29 | virtual ~NotificationQueueUserdata(); 30 | virtual bool copyToState(lua_State *L); 31 | // register metatable for this class 32 | static bool registerNotificationQueue(lua_State* L); 33 | // constructor function 34 | static int NotificationQueue(lua_State* L); 35 | 36 | private: 37 | // metamethod infrastructure 38 | static int metamethod__tostring(lua_State* L); 39 | 40 | // userdata methods 41 | static int clear(lua_State* L); 42 | static int dequeue(lua_State* L); 43 | static int empty(lua_State* L); 44 | static int enqueue(lua_State* L); 45 | static int hasIdleThreads(lua_State* L); 46 | static int size(lua_State* L); 47 | static int waitDequeue(lua_State* L); 48 | static int wakeUpAll(lua_State* L); 49 | 50 | 51 | Poco::SharedPtr mQueue; 52 | Poco::SharedPtr, NotificationFactory> > mPool; 53 | }; 54 | 55 | } // LuaPoco 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /src/foundation/OStream.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_OSTREAM_H 2 | #define LUA_POCO_OSTREAM_H 3 | 4 | #include 5 | #include "LuaPoco.h" 6 | #include "Userdata.h" 7 | 8 | namespace LuaPoco 9 | { 10 | 11 | extern const char* POCO_OSTREAM_METATABLE_NAME; 12 | 13 | // for use by other OStream classes to provide their metamethods and access 14 | // to the underlying std::ostream handle. 15 | class OStream 16 | { 17 | public: 18 | virtual std::ostream& ostream() = 0; 19 | protected: 20 | // userdata methods 21 | static int write(lua_State* L); 22 | static int flush(lua_State* L); 23 | static int seek(lua_State* L); 24 | }; 25 | 26 | // represents a generic ostream to Lua when a POCO API returns an std::ostream 27 | // for i/o purposes. 28 | class OStreamUserdata : public Userdata, public OStream 29 | { 30 | public: 31 | // as OStreamUserdata has no Lua constructor, it is expected that whichever 32 | // class creates an instance of this, that it will create a reference in the 33 | // registry to whatever userdata that owns the std::ostream reference in order 34 | // to prevent usage after collection. 35 | OStreamUserdata(std::ostream& ostream, int udReference = LUA_NOREF); 36 | virtual ~OStreamUserdata(); 37 | virtual std::ostream& ostream(); 38 | // register metatable for this class 39 | static bool registerOStream(lua_State* L); 40 | private: 41 | // metamethod infrastructure 42 | static int metamethod__gc(lua_State* L); 43 | static int metamethod__tostring(lua_State* L); 44 | int mOStreamReference; 45 | std::ostream& mOStream; 46 | }; 47 | 48 | } // LuaPoco 49 | 50 | #endif 51 | -------------------------------------------------------------------------------- /src/foundation/Path.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_PATH_H 2 | #define LUA_POCO_PATH_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include 7 | 8 | extern "C" 9 | { 10 | LUAPOCO_API int luaopen_poco_path(lua_State* L); 11 | } 12 | 13 | namespace LuaPoco 14 | { 15 | 16 | extern const char* POCO_PATH_METATABLE_NAME; 17 | 18 | class PathUserdata : public Userdata 19 | { 20 | public: 21 | PathUserdata(); 22 | PathUserdata(const char* path, Poco::Path::Style style, bool absolute); 23 | PathUserdata(Poco::Path path); 24 | virtual ~PathUserdata(); 25 | virtual bool copyToState(lua_State *L); 26 | // register metatable for this class 27 | static bool registerPath(lua_State* L); 28 | // constructor function 29 | static int Path(lua_State* L); 30 | 31 | // external static functions 32 | static int current(lua_State* L); 33 | static int expand(lua_State* L); 34 | static int find(lua_State* L); 35 | static int home(lua_State* L); 36 | static int listRoots(lua_State* L); 37 | static int nullDevice(lua_State* L); 38 | static int pathSeparator(lua_State* L); 39 | static int separator(lua_State* L); 40 | static int temp(lua_State* L); 41 | static int transcode(lua_State* L); 42 | 43 | // public for append 44 | Poco::Path mPath; 45 | private: 46 | // metamethod infrastructure 47 | static int metamethod__tostring(lua_State* L); 48 | 49 | // userdata methods 50 | static int absolute(lua_State* L); 51 | static int append(lua_State* L); 52 | static int clear(lua_State* L); 53 | static int depth(lua_State* L); 54 | static int directory(lua_State* L); 55 | static int getBaseName(lua_State* L); 56 | static int getDevice(lua_State* L); 57 | static int getExtension(lua_State* L); 58 | static int getFileName(lua_State* L); 59 | static int getNode(lua_State* L); 60 | static int isAbsolute(lua_State* L); 61 | static int isDirectory(lua_State* L); 62 | static int isFile(lua_State* L); 63 | static int isRelative(lua_State* L); 64 | static int makeAbsolute(lua_State* L); 65 | static int makeFile(lua_State* L); 66 | static int makeParent(lua_State* L); 67 | static int parent(lua_State* L); 68 | static int popDirectory(lua_State* L); 69 | static int popFrontDirectory(lua_State* L); 70 | static int pushDirectory(lua_State* L); 71 | static int setBaseName(lua_State* L); 72 | static int setDevice(lua_State* L); 73 | static int setExtension(lua_State* L); 74 | static int setFileName(lua_State* L); 75 | static int setNode(lua_State* L); 76 | static int toString(lua_State* L); 77 | }; 78 | 79 | } // LuaPoco 80 | 81 | #endif 82 | -------------------------------------------------------------------------------- /src/foundation/Pipe.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_PIPE_H 2 | #define LUA_POCO_PIPE_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include 7 | #include 8 | 9 | extern "C" 10 | { 11 | LUAPOCO_API int luaopen_poco_pipe(lua_State* L); 12 | } 13 | 14 | namespace LuaPoco 15 | { 16 | 17 | extern const char* POCO_PIPE_METATABLE_NAME; 18 | 19 | class PipeUserdata : public Userdata 20 | { 21 | public: 22 | PipeUserdata(); 23 | PipeUserdata(const Poco::Pipe& p); 24 | virtual ~PipeUserdata(); 25 | virtual bool copyToState(lua_State *L); 26 | // register metatable for this class 27 | static bool registerPipe(lua_State* L); 28 | // constructor function 29 | static int Pipe(lua_State* L); 30 | 31 | Poco::Pipe mPipe; 32 | private: 33 | // metamethod infrastructure 34 | static int metamethod__tostring(lua_State* L); 35 | 36 | // userdata methods 37 | static int readBytes(lua_State* L); 38 | static int writeBytes(lua_State* L); 39 | static int close(lua_State* L); 40 | }; 41 | 42 | } // LuaPoco 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /src/foundation/PipeIStream.cpp: -------------------------------------------------------------------------------- 1 | /// pipeistream 2 | // An istream interface for pipe userdata. 3 | // @module pipeistream 4 | #include "PipeIStream.h" 5 | #include "Pipe.h" 6 | #include 7 | #include 8 | 9 | int luaopen_poco_pipeistream(lua_State* L) 10 | { 11 | LuaPoco::PipeIStreamUserdata::registerPipeIStream(L); 12 | return LuaPoco::loadConstructor(L, LuaPoco::PipeIStreamUserdata::PipeIStream); 13 | } 14 | 15 | namespace LuaPoco 16 | { 17 | 18 | const char* POCO_PIPEISTREAM_METATABLE_NAME = "Poco.PipeIStream.metatable"; 19 | 20 | PipeIStreamUserdata::PipeIStreamUserdata(const Poco::Pipe& p) 21 | : mPipeInputStream(p) 22 | , mPipeReference(0) 23 | { 24 | } 25 | 26 | PipeIStreamUserdata::~PipeIStreamUserdata() 27 | { 28 | } 29 | 30 | std::istream& PipeIStreamUserdata::istream() 31 | { 32 | return mPipeInputStream; 33 | } 34 | 35 | // register metatable for this class 36 | bool PipeIStreamUserdata::registerPipeIStream(lua_State* L) 37 | { 38 | struct CFunctions methods[] = 39 | { 40 | { "__gc", metamethod__gc }, 41 | { "__tostring", metamethod__tostring }, 42 | { "read", read }, 43 | { "lines", lines }, 44 | { "seek", seek }, 45 | { NULL, NULL} 46 | }; 47 | 48 | setupUserdataMetatable(L, POCO_PIPEISTREAM_METATABLE_NAME, methods); 49 | return true; 50 | } 51 | 52 | /// Constructs a new pipeistream userdata. 53 | // pipeistream holds a reference to a pipe userdata to prevent the pipe from 54 | // being garbage collected while the pipeistream is still trying to use it. 55 | // @param pipe userdata. 56 | // @return userdata or nil. (error) 57 | // @return error message. 58 | // @function new 59 | // @see istream 60 | // @see pipe 61 | int PipeIStreamUserdata::PipeIStream(lua_State* L) 62 | { 63 | int firstArg = lua_istable(L, 1) ? 2 : 1; 64 | PipeUserdata* pud = checkPrivateUserdata(L, firstArg); 65 | 66 | PipeIStreamUserdata* pisud = NULL; 67 | void* p = lua_newuserdata(L, sizeof *pisud); 68 | 69 | try 70 | { 71 | pisud = new(p) PipeIStreamUserdata(pud->mPipe); 72 | } 73 | catch (const std::exception& e) 74 | { 75 | return pushException(L, e); 76 | } 77 | 78 | // store a reference to the PipeUserdata to prevent it from being 79 | // garbage collected while the PipeOutputStream is using it. 80 | lua_pushvalue(L, firstArg); 81 | pisud->mPipeReference = luaL_ref(L, LUA_REGISTRYINDEX); 82 | 83 | setupPocoUserdata(L, pisud, POCO_PIPEISTREAM_METATABLE_NAME); 84 | return 1; 85 | } 86 | 87 | int PipeIStreamUserdata::metamethod__gc(lua_State* L) 88 | { 89 | PipeIStreamUserdata* pud = checkPrivateUserdata(L, 1); 90 | 91 | luaL_unref(L, LUA_REGISTRYINDEX, pud->mPipeReference); 92 | pud->~PipeIStreamUserdata(); 93 | 94 | return 0; 95 | } 96 | 97 | // metamethod infrastructure 98 | int PipeIStreamUserdata::metamethod__tostring(lua_State* L) 99 | { 100 | PipeIStreamUserdata* pud = checkPrivateUserdata(L, 1); 101 | lua_pushfstring(L, "Poco.PipeIStream (%p)", static_cast(pud)); 102 | 103 | return 1; 104 | } 105 | 106 | } // LuaPoco 107 | -------------------------------------------------------------------------------- /src/foundation/PipeIStream.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_PIPEISTREAM_H 2 | #define LUA_POCO_PIPEISTREAM_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include "IStream.h" 7 | #include 8 | 9 | extern "C" 10 | { 11 | LUAPOCO_API int luaopen_poco_pipeistream(lua_State* L); 12 | } 13 | 14 | namespace LuaPoco 15 | { 16 | 17 | extern const char* POCO_PIPEISTREAM_METATABLE_NAME; 18 | 19 | class PipeIStreamUserdata : public Userdata, public IStream 20 | { 21 | public: 22 | PipeIStreamUserdata(const Poco::Pipe& p); 23 | virtual ~PipeIStreamUserdata(); 24 | virtual std::istream& istream(); 25 | // register metatable for this class 26 | static bool registerPipeIStream(lua_State* L); 27 | // constructor function 28 | static int PipeIStream(lua_State* L); 29 | 30 | Poco::PipeInputStream mPipeInputStream; 31 | private: 32 | // metamethod infrastructure 33 | static int metamethod__gc(lua_State* L); 34 | static int metamethod__tostring(lua_State* L); 35 | int mPipeReference; 36 | }; 37 | 38 | } // LuaPoco 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/foundation/PipeOStream.cpp: -------------------------------------------------------------------------------- 1 | /// pipeostream 2 | // An ostream interface for pipe userdata. 3 | // @module pipeostream 4 | #include "PipeOStream.h" 5 | #include "Pipe.h" 6 | #include 7 | #include 8 | 9 | int luaopen_poco_pipeostream(lua_State* L) 10 | { 11 | LuaPoco::PipeOStreamUserdata::registerPipeOStream(L); 12 | return LuaPoco::loadConstructor(L, LuaPoco::PipeOStreamUserdata::PipeOStream); 13 | } 14 | 15 | namespace LuaPoco 16 | { 17 | 18 | const char* POCO_PIPEOSTREAM_METATABLE_NAME = "Poco.PipeOStream.metatable"; 19 | 20 | PipeOStreamUserdata::PipeOStreamUserdata(const Poco::Pipe& p) 21 | : mPipeOutputStream(p) 22 | , mPipeReference(0) 23 | { 24 | } 25 | 26 | PipeOStreamUserdata::~PipeOStreamUserdata() 27 | { 28 | } 29 | 30 | std::ostream& PipeOStreamUserdata::ostream() 31 | { 32 | return mPipeOutputStream; 33 | } 34 | 35 | // register metatable for this class 36 | bool PipeOStreamUserdata::registerPipeOStream(lua_State* L) 37 | { 38 | struct CFunctions methods[] = 39 | { 40 | { "__gc", metamethod__gc }, 41 | { "__tostring", metamethod__tostring }, 42 | { "write", write }, 43 | { "seek", seek }, 44 | { "flush", flush }, 45 | { NULL, NULL} 46 | }; 47 | 48 | setupUserdataMetatable(L, POCO_PIPEOSTREAM_METATABLE_NAME, methods); 49 | return true; 50 | } 51 | 52 | /// Constructs a new pipeostream userdata. 53 | // pipeostream holds a reference to a pipe userdata to prevent the pipe from 54 | // being garbage collected while the pipeostream is still trying to use it. 55 | // @param pipe userdata. 56 | // @return userdata or nil. (error) 57 | // @return error message. 58 | // @function new 59 | // @see ostream 60 | // @see pipe 61 | int PipeOStreamUserdata::PipeOStream(lua_State* L) 62 | { 63 | int firstArg = lua_istable(L, 1) ? 2 : 1; 64 | PipeUserdata* pud = checkPrivateUserdata(L, firstArg); 65 | 66 | PipeOStreamUserdata* posud = NULL; 67 | void* p = lua_newuserdata(L, sizeof *posud); 68 | 69 | try 70 | { 71 | posud = new(p) PipeOStreamUserdata(pud->mPipe); 72 | } 73 | catch (const std::exception& e) 74 | { 75 | return pushException(L, e); 76 | } 77 | 78 | // store a reference to the PipeUserdata to prevent it from being 79 | // garbage collected while the PipeOutputStream is using it. 80 | lua_pushvalue(L, firstArg); 81 | posud->mPipeReference = luaL_ref(L, LUA_REGISTRYINDEX); 82 | 83 | setupPocoUserdata(L, posud, POCO_PIPEOSTREAM_METATABLE_NAME); 84 | return 1; 85 | } 86 | 87 | int PipeOStreamUserdata::metamethod__gc(lua_State* L) 88 | { 89 | PipeOStreamUserdata* pud = checkPrivateUserdata(L, 1); 90 | 91 | luaL_unref(L, LUA_REGISTRYINDEX, pud->mPipeReference); 92 | pud->~PipeOStreamUserdata(); 93 | 94 | return 0; 95 | } 96 | 97 | // metamethod infrastructure 98 | int PipeOStreamUserdata::metamethod__tostring(lua_State* L) 99 | { 100 | PipeOStreamUserdata* pud = checkPrivateUserdata(L, 1); 101 | lua_pushfstring(L, "Poco.PipeOStream (%p)", static_cast(pud)); 102 | 103 | return 1; 104 | } 105 | 106 | } // LuaPoco 107 | -------------------------------------------------------------------------------- /src/foundation/PipeOStream.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_PIPEOSTREAM_H 2 | #define LUA_POCO_PIPEOSTREAM_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include "OStream.h" 7 | #include 8 | 9 | extern "C" 10 | { 11 | LUAPOCO_API int luaopen_poco_pipeostream(lua_State* L); 12 | } 13 | 14 | namespace LuaPoco 15 | { 16 | 17 | extern const char* POCO_PIPEOSTREAM_METATABLE_NAME; 18 | 19 | class PipeOStreamUserdata : public Userdata, public OStream 20 | { 21 | public: 22 | PipeOStreamUserdata(const Poco::Pipe& p); 23 | virtual ~PipeOStreamUserdata(); 24 | virtual std::ostream& ostream(); 25 | // register metatable for this class 26 | static bool registerPipeOStream(lua_State* L); 27 | // constructor function 28 | static int PipeOStream(lua_State* L); 29 | 30 | Poco::PipeOutputStream mPipeOutputStream; 31 | private: 32 | // metamethod infrastructure 33 | static int metamethod__gc(lua_State* L); 34 | static int metamethod__tostring(lua_State* L); 35 | int mPipeReference; 36 | }; 37 | 38 | } // LuaPoco 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /src/foundation/Process.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_PROCESS_H 2 | #define LUA_POCO_PROCESS_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include 7 | 8 | extern "C" 9 | { 10 | LUAPOCO_API int luaopen_poco_process(lua_State* L); 11 | } 12 | 13 | namespace LuaPoco 14 | { 15 | namespace Process 16 | { 17 | 18 | bool registerProcess(lua_State* L); 19 | 20 | int kill(lua_State* L); 21 | int id(lua_State* L); 22 | int launch(lua_State* L); 23 | int requestTermination(lua_State* L); 24 | int times(lua_State* L); 25 | 26 | } 27 | } // LuaPoco 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /src/foundation/ProcessHandle.cpp: -------------------------------------------------------------------------------- 1 | /// A userdata handle for a process created with poco.process.launch(). 2 | // This handle can be used to determine the process ID of the newly created process and it can be used to wait for the completion of a process. 3 | // @module processhandle 4 | 5 | #include "ProcessHandle.h" 6 | #include 7 | 8 | namespace LuaPoco 9 | { 10 | 11 | const char* POCO_PROCESSHANDLE_METATABLE_NAME = "Poco.ProcessHandle.metatable"; 12 | 13 | ProcessHandleUserdata::ProcessHandleUserdata(const Poco::ProcessHandle& ph) : 14 | mProcessHandle(ph) 15 | { 16 | } 17 | 18 | ProcessHandleUserdata::~ProcessHandleUserdata() 19 | { 20 | } 21 | 22 | // register metatable for this class 23 | bool ProcessHandleUserdata::registerProcessHandle(lua_State* L) 24 | { 25 | struct CFunctions methods[] = 26 | { 27 | { "__gc", metamethod__gc }, 28 | { "__tostring", metamethod__tostring }, 29 | { "id", id }, 30 | { "wait", wait }, 31 | { "kill", kill }, 32 | { NULL, NULL} 33 | }; 34 | 35 | setupUserdataMetatable(L, POCO_PROCESSHANDLE_METATABLE_NAME, methods); 36 | return true; 37 | } 38 | 39 | /// 40 | // @type processhandle 41 | 42 | // metamethod infrastructure 43 | int ProcessHandleUserdata::metamethod__tostring(lua_State* L) 44 | { 45 | int rv = 0; 46 | ProcessHandleUserdata* phud = checkPrivateUserdata(L, 1); 47 | 48 | try 49 | { 50 | lua_pushfstring(L, "Poco.ProcessHandle (%p)", static_cast(phud)); 51 | rv = 1; 52 | } 53 | catch (const std::exception& e) 54 | { 55 | rv = pushException(L, e); 56 | } 57 | 58 | return rv; 59 | } 60 | 61 | // userdata methods 62 | 63 | /// Gets the process id associated with the handle. 64 | // @return id as a Lua number. 65 | // @function id 66 | int ProcessHandleUserdata::id(lua_State* L) 67 | { 68 | int rv = 0; 69 | ProcessHandleUserdata* phud = checkPrivateUserdata(L, 1); 70 | 71 | try 72 | { 73 | lua_pushinteger(L, phud->mProcessHandle.id()); 74 | rv = 1; 75 | } 76 | catch (const std::exception& e) 77 | { 78 | rv = pushException(L, e); 79 | } 80 | 81 | return rv; 82 | } 83 | 84 | /// Waits for the process to terminate and returns the exit code of the process. 85 | // @return exit code as a Lua number. 86 | // @function wait 87 | int ProcessHandleUserdata::wait(lua_State* L) 88 | { 89 | ProcessHandleUserdata* phud = checkPrivateUserdata(L, 1); 90 | 91 | lua_pushinteger(L, phud->mProcessHandle.wait()); 92 | 93 | return 1; 94 | } 95 | 96 | /// Kills the process associated with the handle. 97 | // This is preferable on Windows where process IDs may be reused. 98 | // @function kill 99 | int ProcessHandleUserdata::kill(lua_State* L) 100 | { 101 | ProcessHandleUserdata* phud = checkPrivateUserdata(L, 1); 102 | 103 | Poco::Process::kill(phud->mProcessHandle.id()); 104 | 105 | return 0; 106 | } 107 | 108 | } // LuaPoco 109 | -------------------------------------------------------------------------------- /src/foundation/ProcessHandle.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_PROCESSHANDLE_H 2 | #define LUA_POCO_PROCESSHANDLE_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include 7 | 8 | namespace LuaPoco 9 | { 10 | 11 | extern const char* POCO_PROCESSHANDLE_METATABLE_NAME; 12 | 13 | class ProcessHandleUserdata : public Userdata 14 | { 15 | public: 16 | ProcessHandleUserdata(const Poco::ProcessHandle& ph); 17 | virtual ~ProcessHandleUserdata(); 18 | // register metatable for this class 19 | static bool registerProcessHandle(lua_State* L); 20 | private: 21 | ProcessHandleUserdata(); 22 | // no constructor function due to Poco::Process::launch() 23 | // metamethod infrastructure 24 | static int metamethod__tostring(lua_State* L); 25 | 26 | // userdata methods 27 | static int id(lua_State* L); 28 | static int wait(lua_State* L); 29 | static int kill(lua_State* L); 30 | 31 | Poco::ProcessHandle mProcessHandle; 32 | }; 33 | 34 | } // LuaPoco 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /src/foundation/Random.cpp: -------------------------------------------------------------------------------- 1 | /// random 2 | // Random implements a pseudo random number generator (PRNG). 3 | // The PRNG is a nonlinear additive feedback random number generator using 256 bytes of state 4 | // information and a period of up to 2^69. 5 | // @module random 6 | #include "Random.h" 7 | #include 8 | 9 | int luaopen_poco_random(lua_State* L) 10 | { 11 | LuaPoco::RandomUserdata::registerRandom(L); 12 | return LuaPoco::loadConstructor(L, LuaPoco::RandomUserdata::Random); 13 | } 14 | 15 | namespace LuaPoco 16 | { 17 | 18 | const char* POCO_RANDOM_METATABLE_NAME = "Poco.Random.metatable"; 19 | 20 | RandomUserdata::RandomUserdata(int stateSize) 21 | : mRandom(stateSize) 22 | { 23 | } 24 | 25 | RandomUserdata::~RandomUserdata() 26 | { 27 | } 28 | 29 | // register metatable for this class 30 | bool RandomUserdata::registerRandom(lua_State* L) 31 | { 32 | struct CFunctions methods[] = 33 | { 34 | { "__gc", metamethod__gc }, 35 | { "__tostring", metamethod__tostring }, 36 | { "next", next }, 37 | { "nextNumber", nextNumber }, 38 | { "nextByte", nextByte }, 39 | { "nextBool", nextBool }, 40 | { NULL, NULL} 41 | }; 42 | 43 | setupUserdataMetatable(L, POCO_RANDOM_METATABLE_NAME, methods); 44 | return true; 45 | } 46 | 47 | /// Constructs a new random userdata. 48 | // @tparam[opt] number stateSize (default: 256) state buffer size: 8, 16, 32, 64, 128, or 256. 49 | // @tparam[opt] number seed seed for prng, if unspecified an internal RandomNumberStream is used. 50 | // @return userdata or nil. (error) 51 | // @return error message. 52 | // @function new 53 | int RandomUserdata::Random(lua_State* L) 54 | { 55 | int firstArg = lua_istable(L, 1) ? 2 : 1; 56 | 57 | lua_Integer stateSize = 256; 58 | lua_Integer seed = lua_isnumber(L, firstArg + 1) ? lua_tointeger(L, firstArg + 1) : 0; 59 | 60 | if (lua_isnumber(L, firstArg)) { stateSize = lua_tointeger(L, firstArg); } 61 | if (stateSize != 256 && stateSize != 128 && stateSize != 64 && stateSize != 32 && 62 | stateSize != 16 && stateSize != 8) 63 | { 64 | lua_pushnil(L); lua_pushfstring(L, "invalid stateSize: %d", stateSize); 65 | return 2; 66 | } 67 | 68 | RandomUserdata* rud = NULL; 69 | void* p = lua_newuserdata(L, sizeof *rud); 70 | 71 | try 72 | { 73 | rud = new(p) RandomUserdata(stateSize); 74 | } 75 | catch (const std::exception& e) 76 | { 77 | return pushException(L, e); 78 | } 79 | 80 | if (seed) { rud->mRandom.seed(seed); } 81 | else { rud->mRandom.seed(); } 82 | 83 | setupPocoUserdata(L, rud, POCO_RANDOM_METATABLE_NAME); 84 | return 1; 85 | } 86 | 87 | // metamethod infrastructure 88 | int RandomUserdata::metamethod__tostring(lua_State* L) 89 | { 90 | RandomUserdata* rud = checkPrivateUserdata(L, 1); 91 | lua_pushfstring(L, "Poco.Random (%p)", static_cast(rud)); 92 | 93 | return 1; 94 | } 95 | 96 | int RandomUserdata::metamethod__gc(lua_State* L) 97 | { 98 | RandomUserdata* rud = checkPrivateUserdata(L, 1); 99 | rud->~RandomUserdata(); 100 | 101 | return 0; 102 | } 103 | /// 104 | // @type random 105 | 106 | /// Returns the next 31-bit pseudo random number. (modulo n, if supplied) 107 | // @tparam[opt] integer n modulo value. 108 | // @function next 109 | int RandomUserdata::next(lua_State* L) 110 | { 111 | RandomUserdata* rud = checkPrivateUserdata(L, 1); 112 | lua_Integer rval = 0; 113 | 114 | if (lua_isnumber(L, 2)) 115 | { rval = static_cast(rud->mRandom.next(lua_tointeger(L, 2))); } 116 | else { rval = rud->mRandom.next(); } 117 | 118 | lua_pushinteger(L, rval); 119 | return 1; 120 | } 121 | 122 | /// Returns the next pseudo random number between 0.0 and 1.0 as a double. 123 | // @function nextNumber 124 | int RandomUserdata::nextNumber(lua_State* L) 125 | { 126 | RandomUserdata* rud = checkPrivateUserdata(L, 1); 127 | lua_pushnumber(L, static_cast(rud->mRandom.nextDouble())); 128 | return 1; 129 | } 130 | 131 | /// Returns the next pseudo random byte. 132 | // @function nextByte 133 | int RandomUserdata::nextByte(lua_State* L) 134 | { 135 | RandomUserdata* rud = checkPrivateUserdata(L, 1); 136 | unsigned char rval = static_cast(rud->mRandom.nextChar()); 137 | lua_pushinteger(L, static_cast(rval)); 138 | return 1; 139 | } 140 | 141 | /// Returns the next pseudo random boolean value. 142 | // @function nextBool 143 | int RandomUserdata::nextBool(lua_State* L) 144 | { 145 | RandomUserdata* rud = checkPrivateUserdata(L, 1); 146 | lua_pushboolean(L, static_cast(rud->mRandom.nextBool())); 147 | return 1; 148 | } 149 | 150 | } // LuaPoco 151 | 152 | -------------------------------------------------------------------------------- /src/foundation/Random.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_RANDOM_H 2 | #define LUA_POCO_RANDOM_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include "OStream.h" 7 | #include 8 | 9 | extern "C" 10 | { 11 | LUAPOCO_API int luaopen_poco_random(lua_State* L); 12 | } 13 | 14 | namespace LuaPoco 15 | { 16 | 17 | class RandomUserdata : public Userdata 18 | { 19 | public: 20 | RandomUserdata(int stateSize); 21 | virtual ~RandomUserdata(); 22 | // register metatable for this class 23 | static bool registerRandom(lua_State* L); 24 | // constructor function 25 | static int Random(lua_State* L); 26 | 27 | Poco::Random mRandom; 28 | private: 29 | // metamethod infrastructure 30 | static int metamethod__tostring(lua_State* L); 31 | static int metamethod__gc(lua_State* L); 32 | // methods 33 | static int next(lua_State* L); 34 | static int nextNumber(lua_State* L); 35 | static int nextByte(lua_State* L); 36 | static int nextBool(lua_State* L); 37 | }; 38 | 39 | } // LuaPoco 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /src/foundation/RegularExpression.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_REGULAREXPRESSION_H 2 | #define LUA_POCO_REGULAREXPRESSION_H 3 | 4 | #include 5 | #include "Userdata.h" 6 | #include 7 | 8 | extern "C" 9 | { 10 | LUAPOCO_API int luaopen_poco_regex(lua_State* L); 11 | } 12 | 13 | namespace LuaPoco 14 | { 15 | 16 | extern const char* POCO_REGULAREXPRESSION_METATABLE_NAME; 17 | 18 | class RegularExpressionUserdata : public Userdata 19 | { 20 | public: 21 | RegularExpressionUserdata(const std::string& pattern, int options, bool study); 22 | virtual ~RegularExpressionUserdata(); 23 | 24 | // register metatable for this class 25 | static bool registerRegularExpression(lua_State* L); 26 | // constructor function 27 | static int RegularExpression(lua_State* L); 28 | private: 29 | RegularExpressionUserdata(); 30 | RegularExpressionUserdata(const RegularExpressionUserdata& disable); 31 | RegularExpressionUserdata operator=(const RegularExpressionUserdata& disable); 32 | 33 | // metamethod infrastructure 34 | static int metamethod__tostring(lua_State* L); 35 | 36 | // userdata methods 37 | 38 | // iterator fucntion for gmatch 39 | static int gmatch_iter(lua_State* L); 40 | // pattern compatible userdata methods 41 | static int find(lua_State* L); 42 | static int match(lua_State* L); 43 | static int gmatch(lua_State* L); 44 | static int gsub(lua_State* L); 45 | 46 | Poco::RegularExpression mRegularExpression; 47 | }; 48 | 49 | } // LuaPoco 50 | 51 | #endif 52 | 53 | -------------------------------------------------------------------------------- /src/foundation/Semaphore.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_SEMAPHORE_H 2 | #define LUA_POCO_SEMAPHORE_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include 7 | #include 8 | 9 | extern "C" 10 | { 11 | LUAPOCO_API int luaopen_poco_semaphore(lua_State* L); 12 | } 13 | 14 | namespace LuaPoco 15 | { 16 | 17 | extern const char* POCO_SEMAPHORE_METATABLE_NAME; 18 | 19 | class SemaphoreUserdata : public Userdata 20 | { 21 | public: 22 | SemaphoreUserdata(int n); 23 | SemaphoreUserdata(int n, int max); 24 | SemaphoreUserdata(const Poco::SharedPtr& sem); 25 | virtual ~SemaphoreUserdata(); 26 | virtual bool copyToState(lua_State *L); 27 | // register metatable for this class 28 | static bool registerSemaphore(lua_State* L); 29 | // constructor function 30 | static int Semaphore(lua_State* L); 31 | 32 | private: 33 | // metamethod infrastructure 34 | static int metamethod__tostring(lua_State* L); 35 | 36 | // userdata methods 37 | static int set(lua_State* L); 38 | static int tryWait(lua_State* L); 39 | static int wait(lua_State* L); 40 | 41 | Poco::SharedPtr mSemaphore; 42 | }; 43 | 44 | } // LuaPoco 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /src/foundation/SharedMemory.cpp: -------------------------------------------------------------------------------- 1 | /// SharedMemory memory mapped inter process communication. 2 | // This module that provides access to named shared memory and memory mapped files. 3 | // This is a fairly low level module which requires the use of platform level synchronization primitives 4 | // in order to use safely. See namedmutex, namedevent, memoryistream, and memoryostream in particular. 5 | // 6 | // Some practical uses cases for this module: Sharing a large amount of data between 7 | // two processes, where making copies across pipes/sockets would incur a performance penalty. Having 8 | // multiple client processes reading from shared memory without having to copy the data to each 9 | // process. 10 | // @module sharedmemory 11 | 12 | #include "SharedMemory.h" 13 | #include "File.h" 14 | #include 15 | #include 16 | 17 | int luaopen_poco_sharedmemory(lua_State* L) 18 | { 19 | LuaPoco::FileUserdata::registerFile(L); 20 | LuaPoco::SharedMemoryUserdata::registerSharedMemory(L); 21 | return LuaPoco::loadConstructor(L, LuaPoco::SharedMemoryUserdata::SharedMemory); 22 | } 23 | 24 | namespace LuaPoco 25 | { 26 | 27 | const char* POCO_SHAREDMEMORY_METATABLE_NAME = "Poco.SharedMemory.metatable"; 28 | 29 | /// Creates a new SharedMemory userdata instance. 30 | // @string name specifies the shared memory name, or a file userdata specifing the file to map into memory. 31 | // @string mode access mode either "read" or "write" 32 | // @tparam number size shared memory region size in bytes. 33 | // This parameter is ignored for File userdata. 34 | // @bool[opt] server boolean specifying if this instance should unlink the shared memory on destruction. 35 | // (only POSIX platforms) when true, the shared memory region will be unlinked by calling shm_unlink() 36 | // when the sharedmemory userdata is destroyed. Parameter is ignored on Windows. 37 | // @return userdata or nil. (error) 38 | // @return error message. 39 | // @function new 40 | int SharedMemoryUserdata::SharedMemory(lua_State* L) 41 | { 42 | int firstArg = lua_istable(L, 1) ? 2 : 1; 43 | 44 | const char *sharedMemoryName = NULL; 45 | FileUserdata* fud = NULL; 46 | Poco::SharedMemory::AccessMode mode = Poco::SharedMemory::AM_READ; 47 | lua_Integer mappingSize = 0; 48 | bool serverMapping = false; 49 | int top = lua_gettop(L); 50 | 51 | if (lua_isstring(L, firstArg)) { sharedMemoryName = lua_tostring(L, firstArg); } 52 | else { fud = checkPrivateUserdata(L, firstArg); } 53 | 54 | if (top > firstArg && std::strcmp("write", luaL_checkstring(L, firstArg + 1)) == 0) 55 | { mode = Poco::SharedMemory::AM_WRITE; } 56 | if (top > firstArg + 1) { mappingSize = luaL_checkinteger(L, firstArg + 2); } 57 | if (top > 2) { serverMapping = static_cast(lua_toboolean(L, firstArg + 3)); } 58 | 59 | SharedMemoryUserdata* smud = NULL; 60 | void* p = lua_newuserdata(L, sizeof *smud); 61 | try 62 | { 63 | if (sharedMemoryName) 64 | { 65 | smud = new(p) SharedMemoryUserdata(sharedMemoryName, mappingSize, mode, serverMapping); 66 | } 67 | else 68 | { 69 | smud = new(p) SharedMemoryUserdata(fud->getFile(), mode); 70 | } 71 | } 72 | catch (const std::exception& e) 73 | { 74 | return pushException(L, e); 75 | } 76 | 77 | setupPocoUserdata(L, smud, POCO_SHAREDMEMORY_METATABLE_NAME); 78 | return 1; 79 | } 80 | 81 | // register metatable for this class 82 | bool SharedMemoryUserdata::registerSharedMemory(lua_State* L) 83 | { 84 | struct CFunctions methods[] = 85 | { 86 | { "__gc", metamethod__gc }, 87 | { "__tostring", metamethod__tostring }, 88 | { NULL, NULL} 89 | }; 90 | 91 | setupUserdataMetatable(L, POCO_SHAREDMEMORY_METATABLE_NAME, methods); 92 | return true; 93 | } 94 | 95 | SharedMemoryUserdata::SharedMemoryUserdata(const Poco::File& f, Poco::SharedMemory::AccessMode mode) 96 | : mSharedMemory(f, mode) 97 | , mSize(f.getSize()) 98 | , mMode(mode) 99 | { 100 | } 101 | 102 | SharedMemoryUserdata::SharedMemoryUserdata(const char* name, size_t size, Poco::SharedMemory::AccessMode mode, bool server) 103 | : mSharedMemory(name, size, mode, 0, server) 104 | , mSize(size) 105 | , mMode(mode) 106 | { 107 | } 108 | 109 | SharedMemoryUserdata::~SharedMemoryUserdata() 110 | { 111 | } 112 | 113 | // metamethod infrastructure 114 | int SharedMemoryUserdata::metamethod__tostring(lua_State* L) 115 | { 116 | SharedMemoryUserdata* smud = checkPrivateUserdata(L, 1); 117 | lua_pushfstring(L, "Poco.SharedMemoryUserdata (%p)", static_cast(smud)); 118 | 119 | return 1; 120 | } 121 | 122 | 123 | /// 124 | // @type sharedmemory 125 | 126 | 127 | } // LuaPoco 128 | -------------------------------------------------------------------------------- /src/foundation/SharedMemory.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_SHAREDMEMORY_H 2 | #define LUA_POCO_SHAREDMEMORY_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include 7 | #include 8 | 9 | extern "C" 10 | { 11 | LUAPOCO_API int luaopen_poco_sharedmemory(lua_State* L); 12 | } 13 | 14 | namespace LuaPoco 15 | { 16 | 17 | class SharedMemoryUserdata : public Userdata 18 | { 19 | public: 20 | SharedMemoryUserdata(); 21 | virtual ~SharedMemoryUserdata(); 22 | // register metatables 23 | static bool registerSharedMemory(lua_State* L); 24 | // constructor lua_CFunction 25 | static int SharedMemory(lua_State* L); 26 | 27 | size_t mSize; 28 | Poco::SharedMemory mSharedMemory; 29 | Poco::SharedMemory::AccessMode mMode; 30 | private: 31 | SharedMemoryUserdata(const Poco::File& f, Poco::SharedMemory::AccessMode mode); 32 | SharedMemoryUserdata(const char* name, size_t size, Poco::SharedMemory::AccessMode mode, bool server); 33 | 34 | static int metamethod__tostring(lua_State* L); 35 | }; 36 | 37 | } // LuaPoco 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /src/foundation/StreamCopier.cpp: -------------------------------------------------------------------------------- 1 | /// StreamCopier copying istreams to ostreams. 2 | // @module streamcopier 3 | 4 | #include "StreamCopier.h" 5 | #include "Userdata.h" 6 | #include "LuaPocoUtils.h" 7 | #include "IStream.h" 8 | #include "OStream.h" 9 | #include 10 | 11 | int luaopen_poco_streamcopier(lua_State* L) 12 | { 13 | struct LuaPoco::CFunctions methods[] = 14 | { 15 | { "copyStream", LuaPoco::StreamCopier::copyStream }, 16 | { "copyStreamUnbuffered", LuaPoco::StreamCopier::copyStreamUnbuffered }, 17 | { "copyToString", LuaPoco::StreamCopier::copyToString }, 18 | { NULL, NULL} 19 | }; 20 | 21 | lua_createtable(L, 0, 3); 22 | setCFunctions(L, methods); 23 | 24 | return 1; 25 | } 26 | 27 | namespace LuaPoco 28 | { 29 | 30 | /// Copies all data from an istream to an ostream. 31 | // @tparam userdata istream source of data to copy from. 32 | // @tparam userdata ostream destination for data to be copied to. 33 | // @tparam[opt] number buffer_size internal buffer size to use. (default: 8192) 34 | // @return bytes number of bytes copied, or nil. (error) 35 | // @return error message. 36 | // @function copyStream 37 | int StreamCopier::copyStream(lua_State* L) 38 | { 39 | int rv = 0; 40 | size_t bufferSize = 8192; 41 | 42 | IStream* isud = checkPrivateUserdata(L, 1); 43 | OStream* osud = checkPrivateUserdata(L, 2); 44 | int top = lua_gettop(L); 45 | if (top > 2) { bufferSize = static_cast(luaL_checkinteger(L, 3)); } 46 | 47 | try 48 | { 49 | lua_Integer result = 0; 50 | Poco::UInt64 bytesCopied = Poco::StreamCopier::copyStream64(isud->istream(), osud->ostream(), bufferSize); 51 | if (checkUnsignedToLuaInteger(bytesCopied, result)) 52 | { 53 | lua_pushinteger(L, result); 54 | rv = 1; 55 | } 56 | else 57 | { 58 | lua_pushnil(L); 59 | lua_pushstring(L, "bytesCopied value is out of range for lua_Integer."); 60 | rv = 2; 61 | } 62 | } 63 | catch (const std::exception& e) 64 | { 65 | rv = pushException(L, e); 66 | } 67 | 68 | return rv; 69 | } 70 | 71 | int copyToString (lua_State* L); 72 | 73 | /// Copies all data from an istream to an ostream without internal buffering. 74 | // @tparam userdata istream source of data to copy from. 75 | // @tparam userdata ostream destination for data to be copied to. 76 | // @return bytes number of bytes copied, or nil. (error) 77 | // @return error message. 78 | // @function copyStream 79 | int StreamCopier::copyStreamUnbuffered(lua_State* L) 80 | { 81 | int rv = 0; 82 | 83 | IStream* isud = checkPrivateUserdata(L, 1); 84 | OStream* osud = checkPrivateUserdata(L, 2); 85 | 86 | try 87 | { 88 | lua_Integer result = 0; 89 | Poco::UInt64 bytesCopied = Poco::StreamCopier::copyStreamUnbuffered64(isud->istream(), osud->ostream()); 90 | if (checkUnsignedToLuaInteger(bytesCopied, result)) 91 | { 92 | lua_pushinteger(L, result); 93 | rv = 1; 94 | } 95 | else 96 | { 97 | lua_pushnil(L); 98 | lua_pushstring(L, "bytesCopied value is out of range for lua_Integer."); 99 | rv = 2; 100 | } 101 | } 102 | catch (const std::exception& e) 103 | { 104 | rv = pushException(L, e); 105 | } 106 | 107 | return rv; 108 | } 109 | 110 | /// Copies an istream's data to a string. 111 | // @tparam userdata istream source of data to copy from. 112 | // @tparam[opt] number buffer_size internal buffer size to use. (default: 8192) 113 | // @return string containing data copied or nil. (error) 114 | // @return error message. 115 | // @function copyToString 116 | int StreamCopier::copyToString(lua_State* L) 117 | { 118 | int rv = 0; 119 | size_t bufferSize = 8192; 120 | 121 | IStream* isud = checkPrivateUserdata(L, 1); 122 | int top = lua_gettop(L); 123 | if (top > 1) { bufferSize = static_cast(luaL_checkinteger(L, 2)); } 124 | 125 | try 126 | { 127 | lua_Integer result = 0; 128 | std::string data; 129 | 130 | Poco::UInt64 bytesCopied = Poco::StreamCopier::copyToString(isud->istream(), data); 131 | if (checkUnsignedToLuaInteger(bytesCopied, result)) 132 | { 133 | lua_pushlstring(L, data.c_str(), static_cast(result)); 134 | rv = 1; 135 | } 136 | else 137 | { 138 | lua_pushnil(L); 139 | lua_pushstring(L, "bytesCopied value is out of range for lua_Integer."); 140 | rv = 2; 141 | } 142 | } 143 | catch (const std::exception& e) 144 | { 145 | rv = pushException(L, e); 146 | } 147 | 148 | return rv; 149 | } 150 | 151 | } // LuaPoco 152 | -------------------------------------------------------------------------------- /src/foundation/StreamCopier.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_STREAMCOPIER_H 2 | #define LUA_POCO_STREAMCOPIER_H 3 | 4 | #include "LuaPoco.h" 5 | 6 | extern "C" 7 | { 8 | LUAPOCO_API int luaopen_poco_streamcopier(lua_State* L); 9 | } 10 | 11 | namespace LuaPoco 12 | { 13 | namespace StreamCopier 14 | { 15 | 16 | int copyStream(lua_State* L); 17 | int copyStreamUnbuffered(lua_State* L); 18 | int copyToString (lua_State* L); 19 | 20 | } // StreamCopier 21 | } // LuaPoco 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /src/foundation/TeeIStream.cpp: -------------------------------------------------------------------------------- 1 | /// teeistream 2 | // An istream interface that will copy all read data to all ostreams added to it. 3 | // All ostreams added to the teeistream will be referenced to avoid garbage collection. 4 | // @module teeistream 5 | #include "TeeIStream.h" 6 | #include "TeeOStream.h" 7 | #include "Buffer.h" 8 | #include 9 | 10 | int luaopen_poco_teeistream(lua_State* L) 11 | { 12 | LuaPoco::TeeIStreamUserdata::registerTeeIStream(L); 13 | return LuaPoco::loadConstructor(L, LuaPoco::TeeIStreamUserdata::TeeIStream); 14 | } 15 | 16 | namespace LuaPoco 17 | { 18 | 19 | const char* POCO_TEEISTREAM_METATABLE_NAME = "Poco.TeeIStream.metatable"; 20 | 21 | TeeIStreamUserdata::TeeIStreamUserdata(std::istream& is) : mTeeInputStream(is) 22 | { 23 | } 24 | 25 | TeeIStreamUserdata::~TeeIStreamUserdata() 26 | { 27 | } 28 | 29 | std::istream& TeeIStreamUserdata::istream() 30 | { 31 | return mTeeInputStream; 32 | } 33 | 34 | // register metatable for this class 35 | bool TeeIStreamUserdata::registerTeeIStream(lua_State* L) 36 | { 37 | struct CFunctions methods[] = 38 | { 39 | { "__gc", metamethod__gc }, 40 | { "__tostring", metamethod__tostring }, 41 | { "read", read }, 42 | { "lines", lines }, 43 | { "seek", seek }, 44 | { "addStream", addStream }, 45 | { NULL, NULL} 46 | }; 47 | 48 | setupUserdataMetatable(L, POCO_TEEISTREAM_METATABLE_NAME, methods); 49 | return true; 50 | } 51 | 52 | /// Constructs a new teeistream userdata. 53 | // @param the source istream to be read from, which will be copied to attached ostreams. 54 | // @return userdata 55 | // @function new 56 | int TeeIStreamUserdata::TeeIStream(lua_State* L) 57 | { 58 | int firstArg = lua_istable(L, 1) ? 2 : 1; 59 | int top = lua_gettop(L); 60 | 61 | IStream* isud = checkPrivateUserdata(L, firstArg); 62 | TeeIStreamUserdata* tisud = NULL; 63 | void* p = lua_newuserdata(L, sizeof *tisud); 64 | 65 | try 66 | { 67 | tisud = new(p) TeeIStreamUserdata(isud->istream()); 68 | } 69 | catch (const std::exception& e) 70 | { 71 | return pushException(L, e); 72 | } 73 | 74 | // copy the value to the top of the stack, such that luaL_ref can pop it back off. 75 | lua_pushvalue(L, firstArg); 76 | tisud->mUdReference.push_back(luaL_ref(L, LUA_REGISTRYINDEX)); 77 | 78 | setupPocoUserdata(L, tisud, POCO_TEEISTREAM_METATABLE_NAME); 79 | return 1; 80 | } 81 | 82 | // metamethod infrastructure 83 | int TeeIStreamUserdata::metamethod__gc(lua_State* L) 84 | { 85 | TeeIStreamUserdata* tisud = checkPrivateUserdata(L, 1); 86 | 87 | // unreference all userdata that have been added. 88 | for (size_t i = 0; i < tisud->mUdReference.size(); ++i) 89 | { 90 | luaL_unref(L, LUA_REGISTRYINDEX, tisud->mUdReference[i]); 91 | } 92 | tisud->~TeeIStreamUserdata(); 93 | 94 | return 0; 95 | } 96 | 97 | int TeeIStreamUserdata::metamethod__tostring(lua_State* L) 98 | { 99 | TeeIStreamUserdata* tisud = checkPrivateUserdata(L, 1); 100 | lua_pushfstring(L, "Poco.TeeIStream (%p)", static_cast(tisud)); 101 | 102 | return 1; 103 | } 104 | /// Adds an ostream to the teeistream. 105 | // @param array containing ostream userdata, or one or more ostream 106 | // userdata passed as parameters. 107 | // @function addStream 108 | // @see ostream 109 | int TeeIStreamUserdata::addStream(lua_State* L) 110 | { 111 | int top = lua_gettop(L); 112 | TeeIStreamUserdata* tisud = checkPrivateUserdata(L, 1); 113 | 114 | // check for the second arg to be a table, and iterate it for userdata. 115 | if (top > 1 && lua_istable(L, 2)) 116 | { 117 | int tableIndex = 2; 118 | for (int i = 1; ; ++i) 119 | { 120 | lua_pushinteger(L, i); 121 | lua_gettable(L, tableIndex); 122 | if (lua_isnil(L, -1)) break; 123 | OStreamUserdata* osud = checkPrivateUserdata(L, -1); 124 | tisud->mTeeInputStream.addStream(osud->ostream()); 125 | tisud->mUdReference.push_back(luaL_ref(L, LUA_REGISTRYINDEX)); 126 | } 127 | } 128 | // run through arguments. 129 | else 130 | { 131 | for (int i = 2; i <= top; ++i) 132 | { 133 | if (lua_isnil(L, i)) break; 134 | OStream* osud = checkPrivateUserdata(L, i); 135 | tisud->mTeeInputStream.addStream(osud->ostream()); 136 | // copy the value to the top of the stack, such that luaL_ref can pop it back off. 137 | lua_pushvalue(L, i); 138 | tisud->mUdReference.push_back(luaL_ref(L, LUA_REGISTRYINDEX)); 139 | } 140 | } 141 | 142 | return 0; 143 | } 144 | 145 | } // LuaPoco 146 | -------------------------------------------------------------------------------- /src/foundation/TeeIStream.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_TEEISTREAM_H 2 | #define LUA_POCO_TEEISTREAM_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include "IStream.h" 7 | #include 8 | 9 | extern "C" 10 | { 11 | LUAPOCO_API int luaopen_poco_teeistream(lua_State* L); 12 | } 13 | 14 | namespace LuaPoco 15 | { 16 | 17 | extern const char* POCO_TEEISTREAM_METATABLE_NAME; 18 | 19 | class TeeIStreamUserdata : public Userdata, public IStream 20 | { 21 | public: 22 | TeeIStreamUserdata(std::istream& is); 23 | virtual ~TeeIStreamUserdata(); 24 | virtual std::istream& istream(); 25 | // register metatable for this class 26 | static bool registerTeeIStream(lua_State* L); 27 | // constructor function 28 | static int TeeIStream(lua_State* L); 29 | 30 | Poco::TeeInputStream mTeeInputStream; 31 | private: 32 | // metamethod infrastructure 33 | static int metamethod__gc(lua_State* L); 34 | static int metamethod__tostring(lua_State* L); 35 | static int addStream(lua_State* L); 36 | 37 | std::vector mUdReference; 38 | }; 39 | 40 | } // LuaPoco 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/foundation/TeeOStream.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_TEEOSTREAM_H 2 | #define LUA_POCO_TEEOSTREAM_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include "OStream.h" 7 | #include 8 | 9 | extern "C" 10 | { 11 | LUAPOCO_API int luaopen_poco_teeostream(lua_State* L); 12 | } 13 | 14 | namespace LuaPoco 15 | { 16 | 17 | extern const char* POCO_TEEOSTREAM_METATABLE_NAME; 18 | 19 | class TeeOStreamUserdata : public Userdata, public OStream 20 | { 21 | public: 22 | TeeOStreamUserdata(); 23 | virtual ~TeeOStreamUserdata(); 24 | virtual std::ostream& ostream(); 25 | // register metatable for this class 26 | static bool registerTeeOStream(lua_State* L); 27 | // constructor function 28 | static int TeeOStream(lua_State* L); 29 | 30 | Poco::TeeOutputStream mTeeOutputStream; 31 | private: 32 | // metamethod infrastructure 33 | static int metamethod__gc(lua_State* L); 34 | static int metamethod__tostring(lua_State* L); 35 | static int addStream(lua_State* L); 36 | 37 | std::vector mUdReference; 38 | }; 39 | 40 | } // LuaPoco 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /src/foundation/TemporaryFile.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_TEMPORARYFILE_H 2 | #define LUA_POCO_TEMPORARYFILE_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include "File.h" 7 | #include 8 | 9 | extern "C" 10 | { 11 | 12 | LUAPOCO_API int luaopen_poco_temporaryfile(lua_State* L); 13 | 14 | } 15 | 16 | namespace LuaPoco 17 | { 18 | class TemporaryFileUserdata : public FileUserdata 19 | { 20 | public: 21 | TemporaryFileUserdata(const char *path); 22 | TemporaryFileUserdata(const Poco::TemporaryFile& file); 23 | virtual ~TemporaryFileUserdata(); 24 | virtual bool copyToState(lua_State* L); 25 | virtual Poco::File& getFile(); 26 | // constructor 27 | static int TemporaryFile(lua_State* L); 28 | static bool registerTemporaryFile(lua_State* L); 29 | static int registerForDeletion(lua_State* L); 30 | static int tempName(lua_State* L); 31 | private: 32 | // metamethod infrastructure 33 | static int metamethod__tostring(lua_State* L); 34 | // userdata methods 35 | static int keep(lua_State* L); 36 | static int keepUntilExit(lua_State* L); 37 | 38 | Poco::TemporaryFile mTemporaryFile; 39 | }; 40 | 41 | } // LuaPoco 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/foundation/Thread.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_THREAD_H 2 | #define LUA_POCO_THREAD_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include 7 | #include 8 | #include 9 | 10 | extern "C" 11 | { 12 | LUAPOCO_API int luaopen_poco_thread(lua_State* L); 13 | } 14 | 15 | namespace LuaPoco 16 | { 17 | 18 | extern const char* POCO_THREAD_METATABLE_NAME; 19 | 20 | class ThreadUserdata : public Userdata, public Poco::Runnable 21 | { 22 | public: 23 | ThreadUserdata(); 24 | virtual ~ThreadUserdata(); 25 | // register metatable for this class 26 | static bool registerThread(lua_State* L); 27 | void run(); 28 | // constructor function 29 | static int Thread(lua_State* L); 30 | 31 | private: 32 | // metamethod infrastructure 33 | static int metamethod__tostring(lua_State* L); 34 | 35 | // userdata methods 36 | static int name(lua_State* L); 37 | static int priority(lua_State* L); 38 | static int id(lua_State* L); 39 | static int isRunning(lua_State* L); 40 | static int join(lua_State* L); 41 | static int tryJoin(lua_State* L); 42 | static int stackSize(lua_State* L); 43 | static int start(lua_State* L); 44 | static int result(lua_State* L); 45 | 46 | Poco::FastMutex mThreadMutex; 47 | Poco::Thread mThread; 48 | lua_State* mThreadState; 49 | int mParamCount; 50 | int mThreadResult; 51 | std::string mErrorMsg; 52 | }; 53 | 54 | } // LuaPoco 55 | 56 | #endif 57 | -------------------------------------------------------------------------------- /src/foundation/Timestamp.h: -------------------------------------------------------------------------------- 1 | #ifndef LUA_POCO_TIMESTAMP_H 2 | #define LUA_POCO_TIMESTAMP_H 3 | 4 | #include "LuaPoco.h" 5 | #include "Userdata.h" 6 | #include 7 | 8 | extern "C" 9 | { 10 | LUAPOCO_API int luaopen_poco_timestamp(lua_State* L); 11 | } 12 | 13 | namespace LuaPoco 14 | { 15 | 16 | extern const char* POCO_TIMESTAMP_METATABLE_NAME; 17 | 18 | class TimestampUserdata : public Userdata 19 | { 20 | public: 21 | TimestampUserdata(); 22 | TimestampUserdata(Poco::Timestamp::TimeVal tv); 23 | TimestampUserdata(const Poco::Timestamp& ts); 24 | virtual ~TimestampUserdata(); 25 | virtual bool copyToState(lua_State* L); 26 | Poco::Timestamp mTimestamp; 27 | 28 | // register metatable for this class 29 | static bool registerTimestamp(lua_State* L); 30 | // standalone functions that create a TimestampUserdata 31 | static int TimestampFromEpoch(lua_State* L); 32 | static int TimestampFromUtc(lua_State* L); 33 | // Lua constructor 34 | static int Timestamp(lua_State* L); 35 | private: 36 | 37 | // metamethod infrastructure 38 | static int metamethod__tostring(lua_State* L); 39 | static int metamethod__add(lua_State* L); 40 | static int metamethod__sub(lua_State* L); 41 | static int metamethod__lt(lua_State* L); 42 | static int metamethod__le(lua_State* L); 43 | static int metamethod__eq(lua_State* L); 44 | 45 | // userdata methods 46 | static int elapsed(lua_State* L); 47 | static int epochMicroseconds(lua_State* L); 48 | static int epochTime(lua_State* L); 49 | static int isElapsed(lua_State* L); 50 | static int resolution(lua_State* L); 51 | static int update(lua_State* L); 52 | static int utcTime(lua_State* L); 53 | }; 54 | 55 | } // LuaPoco 56 | 57 | #endif 58 | --------------------------------------------------------------------------------