···11+## Ignore Visual Studio temporary files, build results, and
22+## files generated by popular Visual Studio add-ons.
33+44+# User-specific files
55+*.suo
66+*.user
77+*.userosscache
88+*.sln.docstates
99+1010+# User-specific files (MonoDevelop/Xamarin Studio)
1111+*.userprefs
1212+1313+# Build results
1414+[Dd]ebug/
1515+[Dd]ebugPublic/
1616+[Rr]elease/
1717+[Rr]eleases/
1818+x64/
1919+x86/
2020+bld/
2121+[Bb]in/
2222+[Oo]bj/
2323+[Ll]og/
2424+2525+# Visual Studio 2015 cache/options directory
2626+.vs/
2727+# Uncomment if you have tasks that create the project's static files in wwwroot
2828+#wwwroot/
2929+3030+# MSTest test Results
3131+[Tt]est[Rr]esult*/
3232+[Bb]uild[Ll]og.*
3333+3434+# NUNIT
3535+*.VisualState.xml
3636+TestResult.xml
3737+3838+# Build Results of an ATL Project
3939+[Dd]ebugPS/
4040+[Rr]eleasePS/
4141+dlldata.c
4242+4343+# DNX
4444+project.lock.json
4545+artifacts/
4646+4747+*_i.c
4848+*_p.c
4949+*_i.h
5050+*.ilk
5151+*.meta
5252+*.obj
5353+*.pch
5454+*.pdb
5555+*.pgc
5656+*.pgd
5757+*.rsp
5858+*.sbr
5959+*.tlb
6060+*.tli
6161+*.tlh
6262+*.tmp
6363+*.tmp_proj
6464+*.log
6565+*.vspscc
6666+*.vssscc
6767+.builds
6868+*.pidb
6969+*.svclog
7070+*.scc
7171+7272+# Chutzpah Test files
7373+_Chutzpah*
7474+7575+# Visual C++ cache files
7676+ipch/
7777+*.aps
7878+*.ncb
7979+*.opendb
8080+*.opensdf
8181+*.sdf
8282+*.cachefile
8383+*.VC.db
8484+*.VC.VC.opendb
8585+8686+# Visual Studio profiler
8787+*.psess
8888+*.vsp
8989+*.vspx
9090+*.sap
9191+9292+# TFS 2012 Local Workspace
9393+$tf/
9494+9595+# Guidance Automation Toolkit
9696+*.gpState
9797+9898+# ReSharper is a .NET coding add-in
9999+_ReSharper*/
100100+*.[Rr]e[Ss]harper
101101+*.DotSettings.user
102102+103103+# JustCode is a .NET coding add-in
104104+.JustCode
105105+106106+# TeamCity is a build add-in
107107+_TeamCity*
108108+109109+# DotCover is a Code Coverage Tool
110110+*.dotCover
111111+112112+# NCrunch
113113+_NCrunch_*
114114+.*crunch*.local.xml
115115+nCrunchTemp_*
116116+117117+# MightyMoose
118118+*.mm.*
119119+AutoTest.Net/
120120+121121+# Web workbench (sass)
122122+.sass-cache/
123123+124124+# Installshield output folder
125125+[Ee]xpress/
126126+127127+# DocProject is a documentation generator add-in
128128+DocProject/buildhelp/
129129+DocProject/Help/*.HxT
130130+DocProject/Help/*.HxC
131131+DocProject/Help/*.hhc
132132+DocProject/Help/*.hhk
133133+DocProject/Help/*.hhp
134134+DocProject/Help/Html2
135135+DocProject/Help/html
136136+137137+# Click-Once directory
138138+publish/
139139+140140+# Publish Web Output
141141+*.[Pp]ublish.xml
142142+*.azurePubxml
143143+# TODO: Comment the next line if you want to checkin your web deploy settings
144144+# but database connection strings (with potential passwords) will be unencrypted
145145+*.pubxml
146146+*.publishproj
147147+148148+# Microsoft Azure Web App publish settings. Comment the next line if you want to
149149+# checkin your Azure Web App publish settings, but sensitive information contained
150150+# in these scripts will be unencrypted
151151+PublishScripts/
152152+153153+# NuGet Packages
154154+*.nupkg
155155+# The packages folder can be ignored because of Package Restore
156156+**/packages/*
157157+# except build/, which is used as an MSBuild target.
158158+!**/packages/build/
159159+# Uncomment if necessary however generally it will be regenerated when needed
160160+#!**/packages/repositories.config
161161+# NuGet v3's project.json files produces more ignoreable files
162162+*.nuget.props
163163+*.nuget.targets
164164+165165+# Microsoft Azure Build Output
166166+csx/
167167+*.build.csdef
168168+169169+# Microsoft Azure Emulator
170170+ecf/
171171+rcf/
172172+173173+# Windows Store app package directories and files
174174+AppPackages/
175175+BundleArtifacts/
176176+Package.StoreAssociation.xml
177177+_pkginfo.txt
178178+179179+# Visual Studio cache files
180180+# files ending in .cache can be ignored
181181+*.[Cc]ache
182182+# but keep track of directories ending in .cache
183183+!*.[Cc]ache/
184184+185185+# Others
186186+ClientBin/
187187+~$*
188188+*~
189189+*.dbmdl
190190+*.dbproj.schemaview
191191+*.pfx
192192+*.publishsettings
193193+node_modules/
194194+orleans.codegen.cs
195195+196196+# Since there are multiple workflows, uncomment next line to ignore bower_components
197197+# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
198198+#bower_components/
199199+200200+# RIA/Silverlight projects
201201+Generated_Code/
202202+203203+# Backup & report files from converting an old project file
204204+# to a newer Visual Studio version. Backup files are not needed,
205205+# because we have git ;-)
206206+_UpgradeReport_Files/
207207+Backup*/
208208+UpgradeLog*.XML
209209+UpgradeLog*.htm
210210+211211+# SQL Server files
212212+*.mdf
213213+*.ldf
214214+215215+# Business Intelligence projects
216216+*.rdl.data
217217+*.bim.layout
218218+*.bim_*.settings
219219+220220+# Microsoft Fakes
221221+FakesAssemblies/
222222+223223+# GhostDoc plugin setting file
224224+*.GhostDoc.xml
225225+226226+# Node.js Tools for Visual Studio
227227+.ntvs_analysis.dat
228228+229229+# Visual Studio 6 build log
230230+*.plg
231231+232232+# Visual Studio 6 workspace options file
233233+*.opt
234234+235235+# Visual Studio LightSwitch build output
236236+**/*.HTMLClient/GeneratedArtifacts
237237+**/*.DesktopClient/GeneratedArtifacts
238238+**/*.DesktopClient/ModelManifest.xml
239239+**/*.Server/GeneratedArtifacts
240240+**/*.Server/ModelManifest.xml
241241+_Pvt_Extensions
242242+243243+# Paket dependency manager
244244+.paket/paket.exe
245245+paket-files/
246246+247247+# FAKE - F# Make
248248+.fake/
249249+250250+# JetBrains Rider
251251+.idea/
252252+*.sln.iml
253253+*.out
254254+*.o
255255+/test
256256+257257+# Gradle
258258+.gradle/
···11+MIT License
22+33+Copyright (c) 2016 Mitchell Dowd
44+55+Permission is hereby granted, free of charge, to any person obtaining a copy
66+of this software and associated documentation files (the "Software"), to deal
77+in the Software without restriction, including without limitation the rights
88+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
99+copies of the Software, and to permit persons to whom the Software is
1010+furnished to do so, subject to the following conditions:
1111+1212+The above copyright notice and this permission notice shall be included in all
1313+copies or substantial portions of the Software.
1414+1515+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1616+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1717+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1818+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1919+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2020+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2121+SOFTWARE.
+107
src/external/jnipp/README.md
···11+# Java Native Interface for C++
22+33+## Overview
44+55+JNIPP is just a C++ wrapper for the standard Java Native Interface (JNI). It
66+tries to take some of the long-winded annoyance out of integrating your Java
77+and C++ code.
88+99+While this project has so far just been a utility library for my own usage,
1010+it seems to have caught the eye of some others who have also been looking for
1111+a suitable C++ JNI layer. If you have feature requests, do not hesitate to
1212+submit them as Github issues. Please be descriptive in your feature request.
1313+The more useful information you provide - along with justification on why it
1414+should be implemented - the more likely it is that I will add your feature.
1515+1616+## Requirements
1717+1818+To compile you will need:
1919+2020+- A C++11 compatible compiler
2121+- An installation of the Java Development Kit (JDK)
2222+- The `JAVA_HOME` environment variable, directed to your JDK installation.
2323+2424+## Usage
2525+2626+> For comprehensive examples on how to use *jnipp*, see the `tests` project
2727+> in the project source code.
2828+2929+There are two situations where the Java Native Interface would be needed.
3030+3131+- A Java application calling C/C++ functions; or
3232+- A C/C++ application calling Java methods
3333+3434+### Calling Java from C++
3535+3636+The following is an example of calling Java from C++.
3737+3838+```C++
3939+#include <jnipp.h>
4040+4141+int main()
4242+{
4343+ // An instance of the Java VM needs to be created.
4444+ jni::Vm vm;
4545+4646+ // Create an instance of java.lang.Integer
4747+ jni::Class Integer = jni::Class("java/lang/Integer");
4848+ jni::Object i = Integer.newInstance("1000");
4949+5050+ // Call the `toString` method on that integer
5151+ std::string str = i.call<std::string>("toString");
5252+5353+ // The Java VM is automatically destroyed when it goes out of scope.
5454+ return 0;
5555+}
5656+```
5757+5858+### Calling C++ from Java
5959+6060+Consider a basic Java program:
6161+6262+```Java
6363+package com.example;
6464+6565+class Demo {
6666+ public int value;
6767+6868+ public static void main(String[] args) {
6969+ Demo demo = new Demo();
7070+ demo.value = 1000;
7171+ demo.run();
7272+ }
7373+7474+ public native void run();
7575+}
7676+```
7777+7878+A matching C++ library which uses *jnipp* could look like:
7979+8080+```C++
8181+#include <jnipp.h>
8282+#include <iostream>
8383+8484+/*
8585+ The signature here is defind by the JNI standard, so must be adhered to.
8686+ Although, to prevent pollution of the global namespace, the JNIEnv and
8787+ jobject types defind by the standard JNI have been placed into the
8888+ jni namespace.
8989+ */
9090+extern "C" void Java_com_example_Demo_run(jni::JNIEnv* env, jni::jobject obj)
9191+{
9292+ // jnipp only needs initialising once, but it doesn't hurt to do it again.
9393+ jni::init(env);
9494+9595+ // Capture the supplied object.
9696+ jni::Object demo(obj);
9797+9898+ // Print the contents of the `value` field to stdout.
9999+ std::cout << demo.get<int>("value") << std::endl;
100100+}
101101+```
102102+103103+## Configuration
104104+105105+By default, *jnipp* uses std::runtime_error as the base exception class. If you wish,
106106+you can define `JNIPP_EXCEPTION_CLASS` to be the exception class you wish to use, before
107107+including `jnipp.h`. It just needs a `const char*` constructor.
···11+#ifndef _JNIPP_H_
22+#define _JNIPP_H_ 1
33+44+// Standard Dependencies
55+#include <cstring>
66+#include <stdexcept> // For std::runtime_error
77+#include <string>
88+99+// Forward Declarations
1010+struct JNIEnv_;
1111+struct _JNIEnv;
1212+struct JavaVM_;
1313+struct _JavaVM;
1414+struct _jmethodID;
1515+struct _jfieldID;
1616+class _jobject;
1717+class _jclass;
1818+class _jarray;
1919+2020+namespace jni
2121+{
2222+ // JNI Base Types
2323+#ifdef __ANDROID__
2424+ typedef _JNIEnv JNIEnv;
2525+ typedef _JavaVM JavaVM;
2626+#else
2727+ typedef JNIEnv_ JNIEnv;
2828+ typedef JavaVM_ JavaVM;
2929+#endif
3030+3131+ typedef _jobject* jobject;
3232+ typedef _jclass* jclass;
3333+ typedef _jarray* jarray;
3434+3535+ /**
3636+ You can save a method via its handle using Class::getMethod() if it is
3737+ going to be used often. This saves Object::call() from having to locate
3838+ the method each time by name.
3939+4040+ Note that these handles are global and do not need to be deleted.
4141+ */
4242+ typedef _jmethodID* method_t;
4343+4444+ /**
4545+ You can save a field via its handle using Class::getField() if it is
4646+ going to be used often. This saves Object::set() and Object::get() from
4747+ having to locate the field each time by name.
4848+4949+ Note that these handles are global and do not need to be deleted.
5050+ */
5151+ typedef _jfieldID* field_t;
5252+5353+ /**
5454+ Type used to denote the Java byte type.
5555+ */
5656+ typedef unsigned char byte_t;
5757+5858+#ifdef JNIPP_EXCEPTION_CLASS
5959+6060+ /**
6161+ Base class for thrown Exceptions.
6262+ */
6363+ typedef JNIPP_EXCEPTION_CLASS Exception;
6464+6565+#else
6666+6767+ /**
6868+ Base class for thrown Exceptions.
6969+ */
7070+ typedef std::runtime_error Exception;
7171+7272+#endif // JNIPP_EXCEPTION_CLASS
7373+7474+ // Foward Declarations
7575+ class Object;
7676+7777+ /**
7878+ This namespace is for messy implementation details only. It is not a part
7979+ of the external API and is subject to change at any time. It is only in a
8080+ header file due to the fact it is required by some template functions.
8181+8282+ Long story short... this stuff be messy, yo.
8383+ */
8484+ namespace internal
8585+ {
8686+ /*
8787+ Signature Generation
8888+ */
8989+9090+ inline std::string valueSig(const void*) { return "V"; }
9191+ inline std::string valueSig(const bool*) { return "Z"; }
9292+ inline std::string valueSig(const byte_t*) { return "B"; }
9393+ inline std::string valueSig(const wchar_t*) { return "C"; }
9494+ inline std::string valueSig(const short*) { return "S"; }
9595+ inline std::string valueSig(const int*) { return "I"; }
9696+ inline std::string valueSig(const long long*) { return "J"; }
9797+ inline std::string valueSig(const float*) { return "F"; }
9898+ inline std::string valueSig(const double*) { return "D"; }
9999+ inline std::string valueSig(const std::string*) { return "Ljava/lang/String;"; }
100100+ inline std::string valueSig(const std::wstring*) { return "Ljava/lang/String;"; }
101101+ inline std::string valueSig(const char* const*) { return "Ljava/lang/String;"; }
102102+ inline std::string valueSig(const wchar_t* const*) { return "Ljava/lang/String;"; }
103103+ std::string valueSig(const Object* obj);
104104+ inline std::string valueSig(const Object* const* obj) { return valueSig(obj ? *obj : nullptr); }
105105+106106+ template <int n, class TArg>
107107+ inline std::string valueSig(const TArg(*arg)[n]) { return valueSig((const TArg* const*)arg); }
108108+109109+ inline std::string sig() { return ""; }
110110+111111+ template <class TArg, class... TArgs>
112112+ std::string sig(const TArg& arg, const TArgs&... args) {
113113+ return valueSig(&arg) + sig(args...);
114114+ }
115115+116116+ /*
117117+ Argument Conversion
118118+ */
119119+120120+ typedef long long value_t;
121121+122122+ void valueArg(value_t* v, bool a);
123123+ void valueArg(value_t* v, byte_t a);
124124+ void valueArg(value_t* v, wchar_t a);
125125+ void valueArg(value_t* v, short a);
126126+ void valueArg(value_t* v, int a);
127127+ void valueArg(value_t* v, long long a);
128128+ void valueArg(value_t* v, float a);
129129+ void valueArg(value_t* v, double a);
130130+ void valueArg(value_t* v, jobject a);
131131+ void valueArg(value_t* v, const Object& a);
132132+ void valueArg(value_t* v, const Object* const& a);
133133+ void valueArg(value_t* v, const std::string& a);
134134+ void valueArg(value_t* v, const char* a);
135135+ void valueArg(value_t* v, const std::wstring& a);
136136+ void valueArg(value_t* v, const wchar_t* a);
137137+138138+ inline void args(value_t*) {}
139139+140140+ template <class TArg, class... TArgs>
141141+ void args(value_t* values, const TArg& arg, const TArgs&... args) {
142142+ valueArg(values, arg);
143143+ internal::args(values + 1, args...);
144144+ }
145145+146146+ template <class TArg> void cleanupArg(value_t* /* value */) {}
147147+ template <> void cleanupArg<std::string>(value_t* value);
148148+ template <> void cleanupArg<std::wstring>(value_t* value);
149149+ template <> void cleanupArg<const char*>(value_t* value);
150150+ template <> void cleanupArg<const wchar_t*>(value_t* value);
151151+152152+ template <class TArg = void, class... TArgs>
153153+ void cleanupArgs(value_t* values) {
154154+ cleanupArg<TArg>(values);
155155+ cleanupArgs<TArgs...>(values + 1);
156156+ }
157157+158158+ template <>
159159+ inline void cleanupArgs<void>(value_t* /* values */) {}
160160+161161+ template <class... TArgs>
162162+ class ArgArray
163163+ {
164164+ public:
165165+ ArgArray(const TArgs&... args) {
166166+ std::memset(this, 0, sizeof(ArgArray<TArgs...>));
167167+ internal::args(values, args...);
168168+ }
169169+170170+ ~ArgArray() {
171171+ cleanupArgs<TArgs...>(values);
172172+ }
173173+174174+ value_t values[sizeof...(TArgs)];
175175+ };
176176+177177+ long getArrayLength(jarray array);
178178+ }
179179+180180+ /**
181181+ Initialises the Java Native Interface with the given JNIEnv handle, which
182182+ gets passed into a native function which is called from Java. This only
183183+ needs to be done once per process - further calls are no-ops.
184184+ \param env A JNI environment handle.
185185+ */
186186+ void init(JNIEnv* env);
187187+ /**
188188+ Initialises the Java Native Interface with the given JavaVM handle,
189189+ which may be accessible. This (or the other overload) only needs to be
190190+ done once per process - further calls are no-ops.
191191+ \param vm A JNI VM handle.
192192+ */
193193+ void init(JavaVM* vm);
194194+195195+ /**
196196+ Get the appropriate JNI environment for this thread.
197197+ */
198198+ JNIEnv* env();
199199+200200+ /**
201201+ Object corresponds with a `java.lang.Object` instance. With an Object,
202202+ you can then call Java methods, and access fields on the Object. To
203203+ instantiate an Object of a given class, use the `Class` class.
204204+ */
205205+ class Object
206206+ {
207207+ public:
208208+ /** Flags which can be passed to the Object constructor. */
209209+ enum ScopeFlags
210210+ {
211211+ Temporary = 1, ///< Temporary object. Do not create a global reference.
212212+ DeleteLocalInput = 2 ///< The input reference is temporary and can be deleted.
213213+ };
214214+215215+ /** Default constructor. Creates a `null` object. */
216216+ Object() noexcept;
217217+218218+ /**
219219+ Copies a reference to another Object. Note that this is not a deep
220220+ copy operation, and both Objects will reference the same Java
221221+ Object.
222222+ \param other The Object to copy.
223223+ */
224224+ Object(const Object& other);
225225+226226+ /**
227227+ Move constructor. Copies the Object reference from the supplied
228228+ Object, and then nulls the supplied Object reference.
229229+ \param other The Object to move.
230230+ */
231231+ Object(Object&& other) noexcept;
232232+233233+ /**
234234+ Creates an Object from a local JNI reference.
235235+ \param ref The local JNI reference.
236236+ \param scopeFlags Bitmask of ScopeFlags values.
237237+ */
238238+ Object(jobject ref, int scopeFlags = 0);
239239+240240+ /**
241241+ Destructor. Releases this reference on the Java Object so it can be
242242+ picked up by the garbage collector.
243243+ */
244244+ virtual ~Object() noexcept;
245245+246246+ /**
247247+ Assignment operator. Copies the object reference from the supplied
248248+ Object. They will now both point to the same Java Object.
249249+ \param other The Object to copy.
250250+ \return This Object.
251251+ */
252252+ Object& operator=(const Object& other);
253253+254254+ /**
255255+ Assignment operator. Moves the object reference from the supplied
256256+ Object to this one, and leaves the other one as a null.
257257+ \param other The Object to move.
258258+ \return This Object.
259259+ */
260260+ Object& operator=(Object&& other);
261261+262262+ /**
263263+ Tells whether the two Objects refer to the same Java Object.
264264+ \param other the Object to compare with.
265265+ \return `true` if the same, `false` otherwise.
266266+ */
267267+ bool operator==(const Object& other) const;
268268+269269+ /**
270270+ Tells whether the two Objects refer to the same Java Object.
271271+ \param other the Object to compare with.
272272+ \return `true` if the different, `false` otherwise.
273273+ */
274274+ bool operator!=(const Object& other) const { return !operator==(other); }
275275+276276+ /**
277277+ Calls the given method on this Object. The method should have no
278278+ parameters. Note that the return type should be explicitly stated
279279+ in the function call.
280280+ \param method A method handle which applies to this Object.
281281+ \return The method's return value.
282282+ */
283283+ template <class TReturn>
284284+ TReturn call(method_t method) const { return callMethod<TReturn>(method, nullptr); }
285285+286286+ /**
287287+ Calls the method on this Object with the given name, and no arguments.
288288+ Note that the return type should be explicitly stated in the function
289289+ call.
290290+ \param name The name of the method to call (with optional signature).
291291+ \return The method's return value.
292292+ */
293293+ template <class TReturn>
294294+ TReturn call(const char* name) const {
295295+ if (std::strstr(name, "()"))
296296+ return call<TReturn>(getMethod(name));
297297+298298+ // No signature supplied. Generate our own.
299299+ method_t method = getMethod(name, ("()" + internal::valueSig((TReturn*) nullptr)).c_str());
300300+ return call<TReturn>(method);
301301+ }
302302+303303+ /**
304304+ Calls the method on this Object and supplies the given arguments.
305305+ Note that the return type should be explicitly stated in the function
306306+ call.
307307+ \param method The method to call.
308308+ \param args Arguments to supply to the method.
309309+ \return The method's return value.
310310+ */
311311+ template <class TReturn, class... TArgs>
312312+ TReturn call(method_t method, const TArgs&... args) const {
313313+ internal::ArgArray<TArgs...> transform(args...);
314314+ return callMethod<TReturn>(method, transform.values);
315315+ }
316316+317317+ /**
318318+ Calls the method on this Object and supplies the given arguments.
319319+ Note that the return type should be explicitly stated in the function
320320+ call. The type signature of the method is calculated by the types of
321321+ the supplied arguments.
322322+ \param name The name of the method to call (and optional signature).
323323+ \param args Arguments to supply to the method.
324324+ \return The method's return value.
325325+ */
326326+ template <class TReturn, class... TArgs>
327327+ TReturn call(const char* name, const TArgs&... args) const {
328328+ if (std::strchr(name, '('))
329329+ return call<TReturn>(getMethod(name), args...);
330330+331331+ std::string sig = "(" + internal::sig(args...) + ")" + internal::valueSig((TReturn*) nullptr);
332332+ method_t method = getMethod(name, sig.c_str());
333333+ return call<TReturn>(method, args...);
334334+ }
335335+336336+ /**
337337+ Gets a field value from this Object. The field must belong to the
338338+ Object's class. Note that the field type should be explicitly stated
339339+ in the function call.
340340+ \param field Identifier for the field to retrieve.
341341+ \return The field's value.
342342+ */
343343+ template <class TType>
344344+ TType get(field_t field) const;
345345+346346+ /**
347347+ Gets a field value from this Object. The field must belong to the
348348+ Object's class. Note that the field type should be explicitly stated
349349+ in the function call.
350350+ \param name The name of the field to retrieve.
351351+ \return The field's value.
352352+ */
353353+ template <class TType>
354354+ TType get(const char* name) const {
355355+ field_t field = getField(name, internal::valueSig((TType*) nullptr).c_str());
356356+ return get<TType>(field);
357357+ }
358358+359359+ /**
360360+ Sets a field's value on this Object. The field must belong to the
361361+ Object's class, and the parameter's type should correspond to the
362362+ type of the field.
363363+ \param field The field to set the value to.
364364+ \param value The value to set.
365365+ */
366366+ template <class TType>
367367+ void set(field_t field, const TType& value);
368368+369369+ /**
370370+ Sets a field's value on this Object. The field must belong to the
371371+ Object's class, and the parameter's type should correspond to the
372372+ type of the field.
373373+ \param name The name of the field to set the value to.
374374+ \param value The value to set.
375375+ */
376376+ template <class TType>
377377+ void set(const char* name, const TType& value) {
378378+ field_t field = getField(name, internal::valueSig((TType*) nullptr).c_str());
379379+ set(field, value);
380380+ }
381381+382382+ /**
383383+ Tells whether this Object is currently a `null` pointer.
384384+ \return `true` if `null`, `false` if it references an object.
385385+ */
386386+ bool isNull() const noexcept;
387387+388388+ /**
389389+ Gets a handle for this Object's class. Ideally, this should just return a Class,
390390+ but C++ won't let us do that that.
391391+ \return The Object's Class's handle.
392392+ */
393393+ jclass getClass() const;
394394+395395+ /**
396396+ Gets the underlying JNI jobject handle.
397397+ \return The JNI handle.
398398+ */
399399+ jobject getHandle() const noexcept { return _handle; }
400400+401401+ /**
402402+ Create a local reference for the underlying JNI handle.
403403+ \return The local reference.
404404+ */
405405+ jobject makeLocalReference() const;
406406+407407+ private:
408408+ // Helper Functions
409409+ method_t getMethod(const char* name, const char* signature) const;
410410+ method_t getMethod(const char* nameAndSignature) const;
411411+ field_t getField(const char* name, const char* signature) const;
412412+ template <class TType> TType callMethod(method_t method, internal::value_t* values) const;
413413+414414+ // Instance Variables
415415+ jobject _handle;
416416+ mutable jclass _class;
417417+ bool _isGlobal;
418418+ };
419419+420420+ /**
421421+ Class corresponds with `java.lang.Class`, and allows you to instantiate
422422+ Objects and get class members such as methods and fields.
423423+ */
424424+ class Class : protected Object
425425+ {
426426+ public:
427427+ /**
428428+ Creates a null class reference.
429429+ */
430430+ Class() : Object() {}
431431+432432+ /**
433433+ Obtains a class reference to the Java class with the given qualified
434434+ name.
435435+ \param name The qualified class name (e.g. "java/lang/String").
436436+ */
437437+ Class(const char* name);
438438+439439+ /**
440440+ Creates a Class object by JNI reference.
441441+ \param ref The JNI class reference.
442442+ \param scopeFlags Bitmask of Object::ScopeFlags.
443443+ */
444444+ Class(jclass ref, int scopeFlags = Temporary);
445445+446446+ /**
447447+ Tells whether this Class is null or valid.
448448+ \return `true` if null, `false` if valid.
449449+ */
450450+ bool isNull() const noexcept { return Object::isNull(); }
451451+452452+ /**
453453+ Creates a new instance of this Java class and returns a reference to
454454+ it. The item's parameterless constructor is called.
455455+ \return The created instance.
456456+ */
457457+ Object newInstance() const;
458458+459459+ /**
460460+ Creates a new instance of this Java class and returns a reference to
461461+ it.
462462+ \param constructor The constructor to call.
463463+ \param args Arguments to supply to the constructor.
464464+ \return The created instance.
465465+ */
466466+ template <class... TArgs>
467467+ Object newInstance(method_t constructor, const TArgs&... args) const {
468468+ internal::ArgArray<TArgs...> transform(args...);
469469+ return newObject(constructor, transform.values);
470470+ }
471471+472472+ /**
473473+ Creates a new instance of this Java class and returns a reference to
474474+ it. The constructor signature is determined by the supplied parameters,
475475+ and the parameters are then passed to the constructor.
476476+ \param args Arguments to supply to the constructor.
477477+ \return The created instance.
478478+ */
479479+ template <class... TArgs>
480480+ Object newInstance(const TArgs&... args) const {
481481+ method_t constructor = getMethod("<init>", ("(" + internal::sig(args...) + ")V").c_str());
482482+ return newInstance(constructor, args...);
483483+ }
484484+485485+ /**
486486+ Gets a handle to the field with the given name and type signature.
487487+ This handle can then be stored so that the field does not need to
488488+ be looked up by name again. It does not need to be deleted.
489489+ \param name The name of the field.
490490+ \param signature The JNI type signature of the field.
491491+ \return The field ID.
492492+ */
493493+ field_t getField(const char* name, const char* signature) const;
494494+495495+ /**
496496+ Gets a handle to the field with the given name and the supplied type.
497497+ This handle can then be stored so that the field does not need to
498498+ be looked up by name again. It does not need to be deleted.
499499+ \param name The name of the field.
500500+ \return The field ID.
501501+ */
502502+ template<typename TType>
503503+ field_t getField(const char* name) const {
504504+ return getField(name, internal::valueSig((TType*) nullptr).c_str());
505505+ }
506506+507507+ /**
508508+ Gets a handle to the static field with the given name and type signature.
509509+ This handle can then be stored so that the field does not need to
510510+ be looked up by name again. It does not need to be deleted.
511511+ \param name The name of the field.
512512+ \param signature The JNI type signature of the field.
513513+ \return The field ID.
514514+ */
515515+ field_t getStaticField(const char* name, const char* signature) const;
516516+517517+ /**
518518+ Gets a handle to the static field with the given name and the supplied type.
519519+ This handle can then be stored so that the field does not need to
520520+ be looked up by name again. It does not need to be deleted.
521521+ \param name The name of the field.
522522+ \return The field ID.
523523+ */
524524+ template<typename TType>
525525+ field_t getStaticField(const char* name) const {
526526+ return getStaticField(name, internal::valueSig((TType*)nullptr).c_str());
527527+ }
528528+529529+ /**
530530+ Gets a handle to the method with the given name and signature.
531531+ This handle can then be stored so that the method does not need
532532+ to be looked up by name again. It does not need to be deleted.
533533+ \param name The name of the method.
534534+ \param signature The JNI method signature.
535535+ \return The method ID.
536536+ */
537537+ method_t getMethod(const char* name, const char* signature) const;
538538+539539+ /**
540540+ Gets a handle to the method with the given name and signature.
541541+ This handle can then be stored so that the method does not need
542542+ to be looked up by name again. It does not need to be deleted.
543543+ \param nameAndSignature Name and signature identifier (e.g. "toString()Ljava/lang/String;").
544544+ \return The method ID.
545545+ */
546546+ method_t getMethod(const char* nameAndSignature) const;
547547+548548+ /**
549549+ Gets a handle to the static method with the given name and signature.
550550+ This handle can then be stored so that the method does not need
551551+ to be looked up by name again. It does not need to be deleted.
552552+ \param name The name of the method.
553553+ \param signature The JNI method signature.
554554+ \return The method ID.
555555+ */
556556+ method_t getStaticMethod(const char* name, const char* signature) const;
557557+558558+ /**
559559+ Gets a handle to the static method with the given name and signature.
560560+ This handle can then be stored so that the method does not need
561561+ to be looked up by name again. It does not need to be deleted.
562562+ \param nameAndSignature Name and signature identifier (e.g. "toString()Ljava/lang/String;").
563563+ \return The method ID.
564564+ */
565565+ method_t getStaticMethod(const char* nameAndSignature) const;
566566+567567+ /**
568568+ Gets a handle to the constructor for this Class with the given
569569+ signature. Note that the return type should always be `void` ("V").
570570+ \param signature The JNI method signature for the constructor.
571571+ \return The constructor method ID.
572572+ */
573573+ method_t getConstructor(const char* signature) const { return getMethod("<init>", signature); }
574574+575575+ /**
576576+ Gets the parent Class of this Class.
577577+ \return The parent class.
578578+ */
579579+ Class getParent() const;
580580+581581+ /**
582582+ Gets the JNI-qualified name of this Class.
583583+ \return The Class name.
584584+ */
585585+ std::string getName() const;
586586+587587+ /**
588588+ Calls a static method on this Class. The method should have no
589589+ parameters. Note that the return type should be explicitly stated
590590+ in the function call.
591591+ \param method A method handle which applies to this Object.
592592+ \return The method's return value.
593593+ */
594594+ template <class TReturn>
595595+ TReturn call(method_t method) const { return callStaticMethod<TReturn>(method, nullptr); }
596596+597597+ /**
598598+ Calls a static method on this Class with the given name, and no arguments.
599599+ Note that the return type should be explicitly stated in the function
600600+ call.
601601+ \param name The name of the method to call.
602602+ \return The method's return value.
603603+ */
604604+ template <class TReturn>
605605+ TReturn call(const char* name) const {
606606+ method_t method = getStaticMethod(name, ("()" + internal::valueSig((TReturn*) nullptr)).c_str());
607607+ return call<TReturn>(method);
608608+ }
609609+610610+ /**
611611+ Calls a static method on this Class and supplies the given arguments.
612612+ Note that the return type should be explicitly stated in the function
613613+ call.
614614+ \param method The method to call.
615615+ \param args Arguments to supply to the method.
616616+ \return The method's return value.
617617+ */
618618+ template <class TReturn, class... TArgs>
619619+ TReturn call(method_t method, const TArgs&... args) const {
620620+ internal::ArgArray<TArgs...> transform(args...);
621621+ return callStaticMethod<TReturn>(method, transform.values);
622622+ }
623623+624624+ /**
625625+ Calls a static method on this Class and supplies the given arguments.
626626+ Note that the return type should be explicitly stated in the function
627627+ call. The type signature of the method is calculated by the types of
628628+ the supplied arguments.
629629+ \param name The name of the method to call.
630630+ \param args Arguments to supply to the method.
631631+ \return The method's return value.
632632+ */
633633+ template <class TReturn, class... TArgs>
634634+ TReturn call(const char* name, const TArgs&... args) const {
635635+ if (std::strchr(name, '('))
636636+ return call<TReturn>(getStaticMethod(name), args...);
637637+638638+ std::string sig = "(" + internal::sig(args...) + ")" + internal::valueSig((TReturn*) nullptr);
639639+ method_t method = getStaticMethod(name, sig.c_str());
640640+ return call<TReturn>(method, args...);
641641+ }
642642+643643+ /**
644644+ Calls a non-static method on this Class, applying it to the supplied
645645+ Object. The difference between this and Object.call() is that the
646646+ specific class implementation of the method is called, rather than
647647+ doing a virtual method lookup.
648648+ \param obj The Object to call the method on.
649649+ \param method The method to call.
650650+ \return The method's return value.
651651+ */
652652+ template <class TReturn>
653653+ TReturn call(const Object& obj, method_t method) const {
654654+ return callExactMethod<TReturn>(obj.getHandle(), method, nullptr);
655655+ }
656656+657657+ /**
658658+ Calls a non-static method on this Class, applying it to the supplied
659659+ Object. The difference between this and Object.call() is that the
660660+ specific class implementation of the method is called, rather than
661661+ doing a virtual method lookup.
662662+ \param obj The Object to call the method on.
663663+ \param name The name of the method to call.
664664+ \return The method's return value.
665665+ */
666666+ template <class TReturn>
667667+ TReturn call(const Object& obj, const char* name) const {
668668+ method_t method = getMethod(name, ("()" + internal::valueSig((TReturn*) nullptr)).c_str());
669669+ return call<TReturn>(obj, method);
670670+ }
671671+ template <class TReturn>
672672+ TReturn call(const Object* obj, const char* name) const {
673673+ return call<TReturn>(obj, name);
674674+ }
675675+676676+ /**
677677+ Calls a non-static method on this Class, applying it to the supplied
678678+ Object. The difference between this and Object.call() is that the
679679+ specific class implementation of the method is called, rather than
680680+ doing a virtual method lookup.
681681+ \param obj The Object to call the method on.
682682+ \param method The method to call.
683683+ \param args Arguments to pass to the method.
684684+ \return The method's return value.
685685+ */
686686+ template <class TReturn, class... TArgs>
687687+ TReturn call(const Object& obj, method_t method, const TArgs&... args) const {
688688+ internal::ArgArray<TArgs...> transform(args...);
689689+ return callExactMethod<TReturn>(obj.getHandle(), method, transform.values);
690690+ }
691691+ template <class TReturn, class... TArgs>
692692+ TReturn call(const Object* obj, method_t method, const TArgs&... args) const {
693693+ return call<TReturn>(*obj, method, args...);
694694+ }
695695+696696+ /**
697697+ Calls a non-static method on this Class, applying it to the supplied
698698+ Object. The difference between this and Object.call() is that the
699699+ specific class implementation of the method is called, rather than
700700+ doing a virtual method lookup.
701701+ \param obj The Object to call the method on.
702702+ \param name The name of the method to call.
703703+ \param args Arguments to pass to the method.
704704+ \return The method's return value.
705705+ */
706706+ template <class TReturn, class... TArgs>
707707+ TReturn call(const Object& obj, const char* name, const TArgs&... args) const {
708708+ std::string sig = "(" + internal::sig(args...) + ")" + internal::valueSig((TReturn*) nullptr);
709709+ method_t method = getMethod(name, sig.c_str());
710710+ return call<TReturn>(obj, method, args...);
711711+ }
712712+ template <class TReturn, class... TArgs>
713713+ TReturn call(const Object* obj, const char* name, const TArgs&... args) const {
714714+ return call<TReturn>(*obj, name, args...);
715715+ }
716716+717717+ /**
718718+ Gets a static field value from this Class. Note that the field type
719719+ should be explicitly stated in the function call.
720720+ \param field Identifier for the field to retrieve.
721721+ \return The field's value.
722722+ */
723723+ template <class TType>
724724+ TType get(field_t field) const;
725725+726726+ /**
727727+ Gets a static field value from this Class. Note that the field type
728728+ should be explicitly stated in the function call.
729729+ \param name The name of the field to retrieve.
730730+ \return The field's value.
731731+ */
732732+ template <class TType>
733733+ TType get(const char* name) const {
734734+ field_t field = getStaticField(name, internal::valueSig((TType*) nullptr).c_str());
735735+ return get<TType>(field);
736736+ }
737737+738738+ /**
739739+ Sets a static field's value on this Class. The parameter's type should
740740+ correspond to the type of the field.
741741+ \param field The field to set the value to.
742742+ \param value The value to set.
743743+ */
744744+ template <class TType>
745745+ void set(field_t field, const TType& value);
746746+747747+ /**
748748+ Sets a static field's value on this Class. The parameter's type
749749+ should correspond to the type of the field.
750750+ \param name The name of the field to set the value to.
751751+ \param value The value to set.
752752+ */
753753+ template <class TType>
754754+ void set(const char* name, const TType& value) {
755755+ field_t field = getStaticField(name, internal::valueSig((TType*) nullptr).c_str());
756756+ set(field, value);
757757+ }
758758+759759+ /**
760760+ Gets the underlying JNI jclass handle.
761761+ \return The JNI handle.
762762+ */
763763+ jclass getHandle() const noexcept { return jclass(Object::getHandle()); }
764764+765765+ private:
766766+ // Helper Functions
767767+ template <class TType> TType callStaticMethod(method_t method, internal::value_t* values) const;
768768+ template <class TType> TType callExactMethod(jobject obj, method_t method, internal::value_t* values) const;
769769+ Object newObject(method_t constructor, internal::value_t* args) const;
770770+ };
771771+772772+ /**
773773+ Convenience class for dealing with Java enums.
774774+ */
775775+ class Enum : protected Class
776776+ {
777777+ public:
778778+ /**
779779+ Loads the Enum with the given JNI-formatted name.
780780+ \param name The name of the enum.
781781+ */
782782+ Enum(const char* name);
783783+784784+ /**
785785+ Gets the enum value with the given name.
786786+ \param name The name of the enum value.
787787+ \return The enum value identifier.
788788+ */
789789+ Object get(const char* name) const;
790790+791791+ private:
792792+ // Instance Variables
793793+ std::string _name;
794794+ };
795795+796796+ /**
797797+ Used to interact with native Java arrays. The element type can be any primitive
798798+ type, jni::Object, std::string or std::wstring.
799799+ */
800800+ template <class TElement>
801801+ class Array : public Object
802802+ {
803803+ public:
804804+ /**
805805+ Default constructor. Creates a null array reference.
806806+ */
807807+ Array() noexcept;
808808+809809+ /**
810810+ Creates a Array object by JNI reference.
811811+ \param ref The JNI array reference.
812812+ \param scopeFlags Bitmask of Object::ScopeFlags.
813813+ */
814814+ Array(jarray ref, int scopeFlags = Temporary);
815815+816816+ /**
817817+ Creates an Array of the given length. The elements are default initialised
818818+ to zero / null values.
819819+ \param length The Array length.
820820+ */
821821+ Array(long length);
822822+823823+ /**
824824+ Creates an Array of the given length. A Class type is also specified, but can
825825+ be left null to default to "java.lang.Object".
826826+ \param length The Array length.
827827+ \param type The element type.
828828+829829+ */
830830+ Array(long length, const Class& type);
831831+832832+ /**
833833+ Copy constructor. Shares a reference to the Java array with the
834834+ copied Array object.
835835+ \param other The Array to copy.
836836+ */
837837+ Array(const Array<TElement>& other);
838838+839839+ /**
840840+ Move constructor. Moves the array reference to the new Array, and leaves
841841+ the previous Array as a null reference.
842842+ \param other The Array to move.
843843+ */
844844+ Array(Array<TElement>&& other) noexcept;
845845+846846+ /**
847847+ Assignment operator. Copies the array reference from the supplied
848848+ Array. They will now both point to the same Java array.
849849+ \param other The Array to copy.
850850+ \return This Array.
851851+ */
852852+ Array<TElement>& operator=(const Array<TElement>& other);
853853+854854+ /**
855855+ Assignment operator. Moves the array reference from the supplied
856856+ Array to this one, and leaves the other one as a null.
857857+ \param other The Array to move.
858858+ \return This Array.
859859+ */
860860+ Array<TElement>& operator=(Array<TElement>&& other);
861861+862862+ /**
863863+ Checks whether these Arrays both reference the same java array.
864864+ \param other The Array to compare with.
865865+ \return true if the same (or both null), false otherwise.
866866+ */
867867+ bool operator==(const Array<TElement>& other) const { return Object::operator==(other); }
868868+869869+ /**
870870+ Checks whether these Arrays reference different the java arrays.
871871+ \param other The Array to compare with.
872872+ \return false if the same (or both null), true otherwise.
873873+ */
874874+ bool operator!=(const Array<TElement>& other) const { return !operator==(other); }
875875+876876+ /**
877877+ Sets the element value at the given index in the Array.
878878+ \param index The zero-based index.
879879+ \param value The value to set.
880880+ */
881881+ void setElement(long index, TElement value);
882882+883883+ /**
884884+ Gets the value at the given index within the Array.
885885+ \param index The zero-based index.
886886+ \return The element at the given index.
887887+ */
888888+ TElement getElement(long index) const;
889889+ TElement operator[](long index) const { return getElement(index); }
890890+891891+ /**
892892+ Gets the length of this Array.
893893+ \return The array length.
894894+ */
895895+ long getLength() const;
896896+897897+ /**
898898+ Gets the underlying JNI jarray handle.
899899+ \return The JNI handle.
900900+ */
901901+ jarray getHandle() const noexcept { return jarray(Object::getHandle()); }
902902+903903+ private:
904904+ // Instance Variables
905905+ mutable long _length; ///< Mutable as it may only finally get set in a getLength() call.
906906+ };
907907+908908+ /**
909909+ When the application's entry point is in C++ rather than in Java, it will
910910+ need to spin up its own instance of the Java Virtual Machine (JVM) before
911911+ it can initialize the Java Native Interface. Vm is used to create and
912912+ destroy a running JVM instance.
913913+914914+ It uses the RAII idiom, so when the destructor is called, the Vm is shut
915915+ down.
916916+917917+ Note that currently only one instance is supported. Attempts to create
918918+ more will result in an InitializationException.
919919+ */
920920+ class Vm final
921921+ {
922922+ public:
923923+ /**
924924+ Starts the Java Virtual Machine.
925925+ \param path The path to the jvm.dll (or null for auto-detect).
926926+ */
927927+ Vm(const char* path = nullptr);
928928+929929+ /** Destroys the running instance of the JVM. */
930930+ ~Vm();
931931+ };
932932+933933+ /**
934934+ A Java method call threw an Exception.
935935+ */
936936+ class InvocationException : public Exception
937937+ {
938938+ public:
939939+ /**
940940+ Constructor with an error message.
941941+ \param msg Message to pass to the Exception.
942942+ */
943943+ InvocationException(const char* msg = "Java Exception detected") : Exception(msg) {}
944944+ };
945945+946946+ /**
947947+ A supplied name or type signature could not be resolved.
948948+ */
949949+ class NameResolutionException : public Exception
950950+ {
951951+ public:
952952+ /**
953953+ Constructor with an error message.
954954+ \param name The name of the unresolved symbol.
955955+ */
956956+ NameResolutionException(const char* name) : Exception(name) {}
957957+ };
958958+959959+ /**
960960+ The Java Native Interface was not properly initialized.
961961+ */
962962+ class InitializationException : public Exception
963963+ {
964964+ public:
965965+ /**
966966+ Constructor with an error message.
967967+ \param msg Message to pass to the Exception.
968968+ */
969969+ InitializationException(const char* msg) : Exception(msg) {}
970970+ };
971971+972972+ /*
973973+ Array Implementation
974974+ */
975975+976976+ template <class TElement>
977977+ Array<TElement>::Array() noexcept : Object(), _length(0)
978978+ {
979979+ }
980980+981981+ template <class TElement>
982982+ Array<TElement>::Array(jarray ref, int scopeFlags) : Object((jobject) ref, scopeFlags), _length(-1)
983983+ {
984984+ }
985985+986986+ template <class TElement>
987987+ Array<TElement>::Array(const Array<TElement>& other) : Object(other), _length(other._length)
988988+ {
989989+ }
990990+991991+ template <class TElement>
992992+ Array<TElement>::Array(Array<TElement>&& other) noexcept : Object((Object&&)other), _length(other._length)
993993+ {
994994+ other._length = 0;
995995+ }
996996+997997+ template <class TElement>
998998+ Array<TElement>& Array<TElement>::operator=(const Array<TElement>& other)
999999+ {
10001000+ if (&other != this)
10011001+ {
10021002+ Object::operator=(other);
10031003+ _length = other._length;
10041004+ }
10051005+10061006+ return *this;
10071007+ }
10081008+10091009+ template <class TElement>
10101010+ Array<TElement>& Array<TElement>::operator=(Array<TElement>&& other)
10111011+ {
10121012+ if (&other != this)
10131013+ {
10141014+ Object::operator=((Object&&) other);
10151015+ _length = other._length;
10161016+10171017+ other._length = 0;
10181018+ }
10191019+10201020+ return *this;
10211021+ }
10221022+10231023+ template <class TElement>
10241024+ long Array<TElement>::getLength() const
10251025+ {
10261026+ if (_length < 0)
10271027+ {
10281028+ _length = internal::getArrayLength(getHandle());
10291029+ }
10301030+10311031+ return _length;
10321032+ }
10331033+}
10341034+10351035+#endif // _JNIPP_H_
10361036+