and let us know that you're interested in Couchbase on mobile.
26 |
27 | These instructions require you to have installed Eclipse and the Android SDK, the [Android developer website](http://developer.android.com/sdk/installing.html) has instructions.
28 |
29 | ## Installing Couchbase into your Application
30 |
31 | NOTE: You do not need the source of this repository to use Mobile Couchbase in your Android application.
32 |
33 | 1. Create a new Android project or select an existing project
34 |
35 | 2. Download the Android-Couchbase.zip
36 | - http://files.couchbase.com/developer-previews/mobile/android/android-couchbase-dp.zip
37 |
38 | 3. Extract Android-Couchbase.zip, you will see 3 files
39 | - Couchbase.zip
40 | - couchbase.xml
41 | - README.txt
42 |
43 | 4. Place Couchbase.zip and couchbase.xml into the top-level of your project
44 |
45 | 5. Right-click on couchbase.xml and select Run As > Ant Build
46 |
47 | 6. Refresh your project
48 |
49 | ## Starting Couchbase
50 |
51 | Now that your project supports Couchbase, starting Cocuhbase is accomplished by adding a few things to your application's Main Activity.
52 |
53 | 1. Create an instance of ICouchbaseDelegate, you can implement these methods to respond to Couchbase events
54 |
55 | private final ICouchbaseDelegate mDelegate = new ICouchbaseDelegate() {
56 | @Override
57 | public void couchbaseStarted(String host, int port) {}
58 |
59 | @Override
60 | public void exit(String error) {}
61 | };
62 |
63 |
64 | 2. Declare a ServiceConnection instance to keep a reference to the Couchbase service
65 |
66 | private ServiceConnection couchServiceConnection;
67 |
68 |
69 | 3. Add a method to start Couchbase
70 |
71 | public void startCouchbase() {
72 | CouchbaseMobile couch = new CouchbaseMobile(getBaseContext(), mCallback);
73 | couchServiceConnection = couch.startCouchbase();
74 | }
75 |
76 |
77 | 4. Call the startCouchbase method from the appropriate Activity lifecycle methods. For many applications the onCreate method is appropriate
78 |
79 | public void onCreate(Bundle savedInstanceState) {
80 | super.onCreate(savedInstanceState);
81 |
82 | ...
83 |
84 | startCouchbase();
85 | }
86 |
87 |
88 | ## Broadcast Intents
89 |
90 | A Broadcast Receiver registered to listen for the right events can now be used instead of a delegate.
91 |
92 | 1. Optionally, use the CouchbaseMobile constructor without the delegate parameter
93 |
94 |
95 | CouchbaseMobile couch = new CouchbaseMobile(getBaseContext());
96 |
97 |
98 | 2. Declare a Broadcast Receiver
99 |
100 |
101 | private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
102 |
103 | @Override
104 | public void onReceive(Context context, Intent intent) {
105 | if(CouchbaseStarted.ACTION.equals(intent.getAction())) {
106 | String host = CouchbaseStarted.getHost(intent);
107 | int port = CouchbaseStarted.getPort(intent);
108 | }
109 | else if(CouchbaseError.ACTION.equals(intent.getAction())) {
110 | String message = CouchbaseError.getMessage(intent);
111 | }
112 | }
113 | };
114 |
115 |
116 | 3. Register the receiver to listen for the appropriate events
117 |
118 |
119 | public void onCreate(Bundle savedInstanceState) {
120 | super.onCreate(savedInstanceState);
121 |
122 | ...
123 |
124 | registerReceiver(mReceiver, new IntentFilter(CouchbaseStarted.ACTION));
125 | registerReceiver(mReceiver, new IntentFilter(CouchbaseError.ACTION));
126 | }
127 |
128 |
129 | ## Examples
130 |
131 | For examples please look at:
132 |
133 | * https://github.com/couchbase/Android-EmptyApp
134 | * https://github.com/daleharvey/Android-MobileFuton
135 | * https://github.com/couchbaselabs/AndroidGrocerySync
136 |
137 | ## Build information
138 |
139 | To build the Android-Couchbase project from source run the following ant command:
140 |
141 | ant -Dsdk.dir=/path/to/android/sdk dist
142 |
143 | Replacing the value for sdk.dir with the path to the Android SDK on the build server.
144 |
145 | The current build of Android Couchbase embed the CouchDB binaries. There is information on how to build these binaries on the [SourceBuild](https://github.com/couchbase/Android-Couchbase-SourceBuild) project.
146 |
147 | ## Manual Installation
148 |
149 | In some environments it may not be possible to use the couchbase.xml ant script installer. Couchbase can be installed manually using the following steps.
150 |
151 | 1. Unzip the Couchbase.zip archive. This will produce another zip file named overlay.zip.
152 | 2. Remove any existing couchbase*.jar file from /libs
153 | 3. Extract the contents of the overlay.zip file into your project. This will place all assets and libraries in the correct location within the structure of your project.
154 |
155 | cd
156 | unzip //overlay.zip
157 |
158 | 4. Update the project's AndroidManifest.xml to declare the Couchbase service and request the required permissions.
159 |
160 | Within the "application" section add:
161 |
162 |
163 |
164 | Within the "manifest" section add:
165 |
166 |
167 |
168 |
169 |
170 | ## Requirements
171 |
172 | - Android 2.1 or newer
173 | - Eclipse 3.6.2 or newer (if using Eclipse)
174 | - Ant 1.7.1 or newer (if using Ant outside of Eclipse)
175 | - When testing in the emulator, be sure to create an SD Card with sufficient space for your databases
176 | - If using views in the emulator, create an AVD with CPU/ABI set to armeabi-v7a
177 |
178 | ## License
179 |
180 | Portions under Apache, Erlang, and other licenses.
181 |
182 | The overall package is released under the Apache license, 2.0.
183 |
184 | Copyright 2011, Couchbase, Inc.
185 |
--------------------------------------------------------------------------------
/src/com/couchbase/android/CouchbaseInstaller.java:
--------------------------------------------------------------------------------
1 | package com.couchbase.android;
2 |
3 | import java.io.BufferedInputStream;
4 | import java.io.BufferedOutputStream;
5 | import java.io.BufferedReader;
6 | import java.io.File;
7 | import java.io.FileInputStream;
8 | import java.io.FileOutputStream;
9 | import java.io.FileReader;
10 | import java.io.FileWriter;
11 | import java.io.IOException;
12 | import java.io.InputStream;
13 | import java.io.ObjectInputStream;
14 | import java.io.ObjectOutputStream;
15 | import java.io.OutputStream;
16 | import java.util.Arrays;
17 | import java.util.Enumeration;
18 | import java.util.HashMap;
19 | import java.util.zip.ZipEntry;
20 | import java.util.zip.ZipFile;
21 |
22 | import android.os.Handler;
23 | import android.os.Message;
24 | import android.util.Log;
25 |
26 | /**
27 | * A thread which can install the requested version of Couchbase
28 | *
29 | */
30 | public class CouchbaseInstaller extends Thread {
31 |
32 | /**
33 | * Prefix of files in the APK needing to be installed
34 | */
35 | private static final String INSTALL_ASSET_PREFIX = "assets/install/";
36 |
37 | /**
38 | * Files needing to have variables replaced
39 | */
40 | private static final String[] FILES_NEEDING_REPLACEMENTS = {
41 | "couchdb/bin/couchjs_wrapper",
42 | "couchdb/etc/couchdb/android.default.ini"
43 | };
44 |
45 | /**
46 | * Variables to be replaced
47 | */
48 | private static String[][] replacements = new String[][] {
49 | { "%couch_data_dir%", CouchbaseMobile.externalPath() },
50 | { "%couch_installation_dir%", CouchbaseMobile.dataPath() }
51 | };
52 |
53 | /**
54 | * The path to the APK
55 | */
56 | private String apkPath;
57 |
58 | /**
59 | * The handler for communicating with the service thread
60 | */
61 | private Handler handler;
62 |
63 | /**
64 | * Has this installation been cancelled
65 | */
66 | private boolean cancelled = false;
67 |
68 | /**
69 | * Create a new Thread to install Couchbase
70 | *
71 | * @param apkPath the path to the APK file
72 | * @param handler the handler for communicating with the service
73 | */
74 | public CouchbaseInstaller(String apkPath, Handler handler) {
75 | this.apkPath = apkPath;
76 | this.handler = handler;
77 | }
78 |
79 | /**
80 | * Cancel this installation
81 | */
82 | public void cancelInstallation() {
83 | cancelled = true;
84 | }
85 |
86 | @Override
87 | public void run() {
88 | try {
89 | doInstall();
90 | } catch (IOException e) {
91 | Log.e(CouchbaseMobile.TAG, "Error installing Couchbase", e);
92 | Message.obtain(handler, CouchbaseService.ERROR, e).sendToTarget();
93 | }
94 | }
95 |
96 | /**
97 | * Utility function to return the path to a file where we record the files installed
98 | *
99 | * @return the path to the index file
100 | */
101 | public static String indexFile() {
102 | return CouchbaseMobile.dataPath() + "/installedfiles.ser";
103 | }
104 |
105 | /**
106 | * Get a HashMap containing the CRCs of the files currently installed
107 | *
108 | * If no file can be found with the serialized HashMap, return a new empty one
109 | *
110 | * @return HashMap with String key (filename) and Long value (CRC)
111 | */
112 | @SuppressWarnings("unchecked")
113 | public HashMap getInstalledFilesCRC() {
114 | FileInputStream fis = null;
115 | ObjectInputStream ois = null;
116 | try {
117 | fis = new FileInputStream(indexFile());
118 | ois = new ObjectInputStream(fis);
119 | HashMap fileCRCs = (HashMap)ois.readObject();
120 | return fileCRCs;
121 | } catch (Exception e) {
122 | return new HashMap();
123 | }
124 | finally {
125 | try {
126 | if(ois != null) {
127 | ois.close();
128 | }
129 | if(fis != null) {
130 | fis.close();
131 | }
132 | } catch (IOException e) {
133 | Log.v(CouchbaseMobile.TAG, "Exception closing installed files CRC streams");
134 | }
135 | }
136 | }
137 |
138 | /**
139 | * Update the HashMap containing the CRCs of the files installed
140 | *
141 | * @param fileCRCs the updated HashMap
142 | * @throws IOException
143 | */
144 | public void setInstalledFilesCRC(HashMap fileCRCs) throws IOException {
145 | FileOutputStream fos = null;
146 | ObjectOutputStream oos = null;
147 | try {
148 | File indexFile = new File(indexFile());
149 | createFileAndParentDirectoriesIfNecessary(indexFile);
150 | fos = new FileOutputStream(indexFile());
151 | oos = new ObjectOutputStream(fos);
152 | oos.writeObject(fileCRCs);
153 | }
154 | finally {
155 | try {
156 | oos.close();
157 | fos.close();
158 | } catch (IOException e) {
159 | Log.e(CouchbaseMobile.TAG, "Exception closing installed files CRC streams");
160 | }
161 | }
162 | }
163 |
164 | /**
165 | * Perform the installation
166 | *
167 | * @throws IOException
168 | */
169 | public void doInstall() throws IOException {
170 |
171 | HashMap installedFilesCRCs = getInstalledFilesCRC();
172 |
173 | ZipFile apk = new ZipFile(apkPath);
174 | int numberOfFilesUpdated = 0;
175 |
176 | Enumeration extends ZipEntry> e = apk.entries();
177 | while(e.hasMoreElements() && !cancelled) {
178 | ZipEntry entry = e.nextElement();
179 | String name = entry.getName();
180 | if(name.startsWith(INSTALL_ASSET_PREFIX)) {
181 | String restOfName = name.substring(INSTALL_ASSET_PREFIX.length());
182 | String fullName = CouchbaseMobile.dataPath() + "/" + restOfName;
183 |
184 | Log.v(CouchbaseMobile.TAG, "Checking CRC of " + fullName);
185 |
186 | Long crc = entry.getCrc();
187 | Long installedCRC = installedFilesCRCs.get(fullName);
188 | if(!crc.equals(installedCRC)) {
189 | if(installedCRC != null) {
190 | Log.v(CouchbaseMobile.TAG, "Need to update. Installed: " + Long.toHexString(installedCRC) + " APK: " + Long.toHexString(crc));
191 | }
192 | else {
193 | Log.v(CouchbaseMobile.TAG, "Need to update, new file with CRC: " + Long.toHexString(crc));
194 | }
195 | //need to update the file
196 | File file = new File(fullName);
197 | createFileAndParentDirectoriesIfNecessary(file);
198 |
199 | FileOutputStream fos = new FileOutputStream(fullName);
200 | copy(apk.getInputStream(entry), fos);
201 |
202 | //if this file needs replacement, do it now
203 | if(Arrays.asList(FILES_NEEDING_REPLACEMENTS).contains(restOfName)) {
204 | Log.v(CouchbaseMobile.TAG, "Performing replacements in " + restOfName);
205 | replace(fullName, replacements);
206 | }
207 |
208 | //now update the hash
209 | installedFilesCRCs.put(fullName, crc);
210 | numberOfFilesUpdated++;
211 | }
212 | else {
213 | Log.v(CouchbaseMobile.TAG, "CRCs match. Installed: " + Long.toHexString(installedCRC) + " APK: " + Long.toHexString(crc));
214 | }
215 | }
216 |
217 | }
218 |
219 | if(!cancelled) {
220 | //now write our installed CRCs back to disk
221 | setInstalledFilesCRC(installedFilesCRCs);
222 |
223 | Log.v(CouchbaseMobile.TAG, "Updated " + numberOfFilesUpdated + " files");
224 |
225 | Message done = Message.obtain();
226 | done.what = CouchbaseService.COMPLETE;
227 | handler.sendMessage(done);
228 | }
229 |
230 | }
231 |
232 | /**
233 | * Utility to copy bytes from an InputStream to an OutputStream
234 | * @param is the InputStream
235 | * @param os the OutputStream
236 | * @throws IOException
237 | */
238 | public static void copy(InputStream is, OutputStream os) throws IOException {
239 |
240 | final int COPY_BUFFER = 2048;
241 |
242 | BufferedOutputStream bos = new BufferedOutputStream(os, COPY_BUFFER);
243 | BufferedInputStream bis = new BufferedInputStream(is);
244 |
245 | int count;
246 | byte data[] = new byte[COPY_BUFFER];
247 |
248 | while ((count = bis.read(data, 0, COPY_BUFFER)) != -1) {
249 | bos.write(data, 0, count);
250 | }
251 | bos.flush();
252 | bos.close();
253 | }
254 |
255 | /**
256 | * Utility to create a file and all parent directories if necesary
257 | *
258 | * @param file the file to be created
259 | * @throws IOException
260 | */
261 | public static void createFileAndParentDirectoriesIfNecessary(File file) throws IOException {
262 | if(!file.exists()) {
263 | File parent = file.getParentFile();
264 | parent.mkdirs();
265 |
266 | file.createNewFile();
267 | Runtime.getRuntime().exec("chmod 755 " + file.getAbsolutePath());
268 | }
269 | }
270 |
271 | /**
272 | * Utilty to process a file line by line, replacing strings with values
273 | *
274 | * @param fileName the name of the file to process
275 | * @param replacements array of 2 element string arrays, 0 is string to match, 1 is replacement
276 | * @throws IOException
277 | */
278 | static void replace(String fileName, String[][] replacements)
279 | throws IOException {
280 | File file = new File(fileName);
281 | BufferedReader reader = new BufferedReader(new FileReader(file));
282 | String line = "", content = "";
283 | while ((line = reader.readLine()) != null) {
284 | content += line + "\n";
285 | }
286 |
287 | for (int i = 0; i < replacements.length; i++) {
288 | content = content
289 | .replaceAll(replacements[i][0], replacements[i][1]);
290 | }
291 | reader.close();
292 | FileWriter writer = new FileWriter(fileName);
293 | writer.write(content);
294 | writer.close();
295 | Runtime.getRuntime().exec("chmod 755 " + fileName);
296 | }
297 |
298 | }
299 |
--------------------------------------------------------------------------------
/jni/erl_nif_api_funcs.h:
--------------------------------------------------------------------------------
1 | /*
2 | * %CopyrightBegin%
3 | *
4 | * Copyright Ericsson AB 2009-2011. All Rights Reserved.
5 | *
6 | * The contents of this file are subject to the Erlang Public License,
7 | * Version 1.1, (the "License"); you may not use this file except in
8 | * compliance with the License. You should have received a copy of the
9 | * Erlang Public License along with this software. If not, it can be
10 | * retrieved online at http://www.erlang.org/.
11 | *
12 | * Software distributed under the License is distributed on an "AS IS"
13 | * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14 | * the License for the specific language governing rights and limitations
15 | * under the License.
16 | *
17 | * %CopyrightEnd%
18 | */
19 |
20 | #if !defined(ERL_NIF_API_FUNC_DECL) && !defined(ERL_NIF_API_FUNC_MACRO)
21 | # error This file should not be included directly
22 | #endif
23 |
24 | /*
25 | ** WARNING: add new ERL_NIF_API_FUNC_DECL entries at the bottom of the list
26 | ** to keep compatibility on Windows!!!
27 | **
28 | ** And don't forget to increase ERL_NIF_MINOR_VERSION in erl_nif.h
29 | ** when adding functions to the API.
30 | */
31 | #ifdef ERL_NIF_API_FUNC_DECL
32 | ERL_NIF_API_FUNC_DECL(void*,enif_priv_data,(ErlNifEnv*));
33 | ERL_NIF_API_FUNC_DECL(void*,enif_alloc,(size_t size));
34 | ERL_NIF_API_FUNC_DECL(void,enif_free,(void* ptr));
35 | ERL_NIF_API_FUNC_DECL(int,enif_is_atom,(ErlNifEnv*, ERL_NIF_TERM term));
36 | ERL_NIF_API_FUNC_DECL(int,enif_is_binary,(ErlNifEnv*, ERL_NIF_TERM term));
37 | ERL_NIF_API_FUNC_DECL(int,enif_is_ref,(ErlNifEnv*, ERL_NIF_TERM term));
38 | ERL_NIF_API_FUNC_DECL(int,enif_inspect_binary,(ErlNifEnv*, ERL_NIF_TERM bin_term, ErlNifBinary* bin));
39 | ERL_NIF_API_FUNC_DECL(int,enif_alloc_binary,(size_t size, ErlNifBinary* bin));
40 | ERL_NIF_API_FUNC_DECL(int,enif_realloc_binary,(ErlNifBinary* bin, size_t size));
41 | ERL_NIF_API_FUNC_DECL(void,enif_release_binary,(ErlNifBinary* bin));
42 | ERL_NIF_API_FUNC_DECL(int,enif_get_int,(ErlNifEnv*, ERL_NIF_TERM term, int* ip));
43 | ERL_NIF_API_FUNC_DECL(int,enif_get_ulong,(ErlNifEnv*, ERL_NIF_TERM term, unsigned long* ip));
44 | ERL_NIF_API_FUNC_DECL(int,enif_get_double,(ErlNifEnv*, ERL_NIF_TERM term, double* dp));
45 | ERL_NIF_API_FUNC_DECL(int,enif_get_list_cell,(ErlNifEnv* env, ERL_NIF_TERM term, ERL_NIF_TERM* head, ERL_NIF_TERM* tail));
46 | ERL_NIF_API_FUNC_DECL(int,enif_get_tuple,(ErlNifEnv* env, ERL_NIF_TERM tpl, int* arity, const ERL_NIF_TERM** array));
47 | ERL_NIF_API_FUNC_DECL(int,enif_is_identical,(ERL_NIF_TERM lhs, ERL_NIF_TERM rhs));
48 | ERL_NIF_API_FUNC_DECL(int,enif_compare,(ERL_NIF_TERM lhs, ERL_NIF_TERM rhs));
49 | ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_binary,(ErlNifEnv* env, ErlNifBinary* bin));
50 | ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_badarg,(ErlNifEnv* env));
51 | ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_int,(ErlNifEnv* env, int i));
52 | ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_ulong,(ErlNifEnv* env, unsigned long i));
53 | ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_double,(ErlNifEnv* env, double d));
54 | ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_atom,(ErlNifEnv* env, const char* name));
55 | ERL_NIF_API_FUNC_DECL(int,enif_make_existing_atom,(ErlNifEnv* env, const char* name, ERL_NIF_TERM* atom, ErlNifCharEncoding));
56 | ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_tuple,(ErlNifEnv* env, unsigned cnt, ...));
57 | ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_list,(ErlNifEnv* env, unsigned cnt, ...));
58 | ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_list_cell,(ErlNifEnv* env, ERL_NIF_TERM car, ERL_NIF_TERM cdr));
59 | ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_string,(ErlNifEnv* env, const char* string, ErlNifCharEncoding));
60 | ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_ref,(ErlNifEnv* env));
61 |
62 | ERL_NIF_API_FUNC_DECL(ErlNifMutex*,enif_mutex_create,(char *name));
63 | ERL_NIF_API_FUNC_DECL(void,enif_mutex_destroy,(ErlNifMutex *mtx));
64 | ERL_NIF_API_FUNC_DECL(int,enif_mutex_trylock,(ErlNifMutex *mtx));
65 | ERL_NIF_API_FUNC_DECL(void,enif_mutex_lock,(ErlNifMutex *mtx));
66 | ERL_NIF_API_FUNC_DECL(void,enif_mutex_unlock,(ErlNifMutex *mtx));
67 | ERL_NIF_API_FUNC_DECL(ErlNifCond*,enif_cond_create,(char *name));
68 | ERL_NIF_API_FUNC_DECL(void,enif_cond_destroy,(ErlNifCond *cnd));
69 | ERL_NIF_API_FUNC_DECL(void,enif_cond_signal,(ErlNifCond *cnd));
70 | ERL_NIF_API_FUNC_DECL(void,enif_cond_broadcast,(ErlNifCond *cnd));
71 | ERL_NIF_API_FUNC_DECL(void,enif_cond_wait,(ErlNifCond *cnd, ErlNifMutex *mtx));
72 | ERL_NIF_API_FUNC_DECL(ErlNifRWLock*,enif_rwlock_create,(char *name));
73 | ERL_NIF_API_FUNC_DECL(void,enif_rwlock_destroy,(ErlNifRWLock *rwlck));
74 | ERL_NIF_API_FUNC_DECL(int,enif_rwlock_tryrlock,(ErlNifRWLock *rwlck));
75 | ERL_NIF_API_FUNC_DECL(void,enif_rwlock_rlock,(ErlNifRWLock *rwlck));
76 | ERL_NIF_API_FUNC_DECL(void,enif_rwlock_runlock,(ErlNifRWLock *rwlck));
77 | ERL_NIF_API_FUNC_DECL(int,enif_rwlock_tryrwlock,(ErlNifRWLock *rwlck));
78 | ERL_NIF_API_FUNC_DECL(void,enif_rwlock_rwlock,(ErlNifRWLock *rwlck));
79 | ERL_NIF_API_FUNC_DECL(void,enif_rwlock_rwunlock,(ErlNifRWLock *rwlck));
80 | ERL_NIF_API_FUNC_DECL(int,enif_tsd_key_create,(char *name, ErlNifTSDKey *key));
81 | ERL_NIF_API_FUNC_DECL(void,enif_tsd_key_destroy,(ErlNifTSDKey key));
82 | ERL_NIF_API_FUNC_DECL(void,enif_tsd_set,(ErlNifTSDKey key, void *data));
83 | ERL_NIF_API_FUNC_DECL(void*,enif_tsd_get,(ErlNifTSDKey key));
84 | ERL_NIF_API_FUNC_DECL(ErlNifThreadOpts*,enif_thread_opts_create,(char *name));
85 | ERL_NIF_API_FUNC_DECL(void,enif_thread_opts_destroy,(ErlNifThreadOpts *opts));
86 | ERL_NIF_API_FUNC_DECL(int,enif_thread_create,(char *name,ErlNifTid *tid,void * (*func)(void *),void *args,ErlNifThreadOpts *opts));
87 | ERL_NIF_API_FUNC_DECL(ErlNifTid,enif_thread_self,(void));
88 | ERL_NIF_API_FUNC_DECL(int,enif_equal_tids,(ErlNifTid tid1, ErlNifTid tid2));
89 | ERL_NIF_API_FUNC_DECL(void,enif_thread_exit,(void *resp));
90 | ERL_NIF_API_FUNC_DECL(int,enif_thread_join,(ErlNifTid, void **respp));
91 |
92 | ERL_NIF_API_FUNC_DECL(void*,enif_realloc,(void* ptr, size_t size));
93 | ERL_NIF_API_FUNC_DECL(void,enif_system_info,(ErlNifSysInfo *sip, size_t si_size));
94 | ERL_NIF_API_FUNC_DECL(int,enif_fprintf,(void/* FILE* */ *filep, const char *format, ...));
95 | ERL_NIF_API_FUNC_DECL(int,enif_inspect_iolist_as_binary,(ErlNifEnv*, ERL_NIF_TERM term, ErlNifBinary* bin));
96 | ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_sub_binary,(ErlNifEnv*, ERL_NIF_TERM bin_term, size_t pos, size_t size));
97 | ERL_NIF_API_FUNC_DECL(int,enif_get_string,(ErlNifEnv*, ERL_NIF_TERM list, char* buf, unsigned len, ErlNifCharEncoding));
98 | ERL_NIF_API_FUNC_DECL(int,enif_get_atom,(ErlNifEnv*, ERL_NIF_TERM atom, char* buf, unsigned len, ErlNifCharEncoding));
99 | ERL_NIF_API_FUNC_DECL(int,enif_is_fun,(ErlNifEnv*, ERL_NIF_TERM term));
100 | ERL_NIF_API_FUNC_DECL(int,enif_is_pid,(ErlNifEnv*, ERL_NIF_TERM term));
101 | ERL_NIF_API_FUNC_DECL(int,enif_is_port,(ErlNifEnv*, ERL_NIF_TERM term));
102 | ERL_NIF_API_FUNC_DECL(int,enif_get_uint,(ErlNifEnv*, ERL_NIF_TERM term, unsigned* ip));
103 | ERL_NIF_API_FUNC_DECL(int,enif_get_long,(ErlNifEnv*, ERL_NIF_TERM term, long* ip));
104 | ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_uint,(ErlNifEnv*, unsigned i));
105 | ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_long,(ErlNifEnv*, long i));
106 | ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_tuple_from_array,(ErlNifEnv*, const ERL_NIF_TERM arr[], unsigned cnt));
107 | ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_list_from_array,(ErlNifEnv*, const ERL_NIF_TERM arr[], unsigned cnt));
108 | ERL_NIF_API_FUNC_DECL(int,enif_is_empty_list,(ErlNifEnv*, ERL_NIF_TERM term));
109 | ERL_NIF_API_FUNC_DECL(ErlNifResourceType*,enif_open_resource_type,(ErlNifEnv*, const char* module_str, const char* name_str, void (*dtor)(ErlNifEnv*,void *), ErlNifResourceFlags flags, ErlNifResourceFlags* tried));
110 | ERL_NIF_API_FUNC_DECL(void*,enif_alloc_resource,(ErlNifResourceType* type, size_t size));
111 | ERL_NIF_API_FUNC_DECL(void,enif_release_resource,(void* obj));
112 | ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_resource,(ErlNifEnv*, void* obj));
113 | ERL_NIF_API_FUNC_DECL(int,enif_get_resource,(ErlNifEnv*, ERL_NIF_TERM term, ErlNifResourceType* type, void** objp));
114 | ERL_NIF_API_FUNC_DECL(size_t,enif_sizeof_resource,(void* obj));
115 | ERL_NIF_API_FUNC_DECL(unsigned char*,enif_make_new_binary,(ErlNifEnv*,size_t size,ERL_NIF_TERM* termp));
116 | ERL_NIF_API_FUNC_DECL(int,enif_is_list,(ErlNifEnv*, ERL_NIF_TERM term));
117 | ERL_NIF_API_FUNC_DECL(int,enif_is_tuple,(ErlNifEnv*, ERL_NIF_TERM term));
118 | ERL_NIF_API_FUNC_DECL(int,enif_get_atom_length,(ErlNifEnv*, ERL_NIF_TERM atom, unsigned* len, ErlNifCharEncoding));
119 | ERL_NIF_API_FUNC_DECL(int,enif_get_list_length,(ErlNifEnv* env, ERL_NIF_TERM term, unsigned* len));
120 | ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM, enif_make_atom_len,(ErlNifEnv* env, const char* name, size_t len));
121 | ERL_NIF_API_FUNC_DECL(int, enif_make_existing_atom_len,(ErlNifEnv* env, const char* name, size_t len, ERL_NIF_TERM* atom, ErlNifCharEncoding));
122 | ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_string_len,(ErlNifEnv* env, const char* string, size_t len, ErlNifCharEncoding));
123 | ERL_NIF_API_FUNC_DECL(ErlNifEnv*,enif_alloc_env,(void));
124 | ERL_NIF_API_FUNC_DECL(void,enif_free_env,(ErlNifEnv* env));
125 | ERL_NIF_API_FUNC_DECL(void,enif_clear_env,(ErlNifEnv* env));
126 | ERL_NIF_API_FUNC_DECL(int,enif_send,(ErlNifEnv* env, const ErlNifPid* to_pid, ErlNifEnv* msg_env, ERL_NIF_TERM msg));
127 | ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_copy,(ErlNifEnv* dst_env, ERL_NIF_TERM src_term));
128 | ERL_NIF_API_FUNC_DECL(ErlNifPid*,enif_self,(ErlNifEnv* caller_env, ErlNifPid* pid));
129 | ERL_NIF_API_FUNC_DECL(int,enif_get_local_pid,(ErlNifEnv* env, ERL_NIF_TERM, ErlNifPid* pid));
130 | ERL_NIF_API_FUNC_DECL(void,enif_keep_resource,(void* obj));
131 | ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_resource_binary,(ErlNifEnv*,void* obj,const void* data, size_t size));
132 | #if SIZEOF_LONG != 8
133 | ERL_NIF_API_FUNC_DECL(int,enif_get_int64,(ErlNifEnv*, ERL_NIF_TERM term, ErlNifSInt64* ip));
134 | ERL_NIF_API_FUNC_DECL(int,enif_get_uint64,(ErlNifEnv*, ERL_NIF_TERM term, ErlNifUInt64* ip));
135 | ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_int64,(ErlNifEnv*, ErlNifSInt64));
136 | ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_uint64,(ErlNifEnv*, ErlNifUInt64));
137 | #endif
138 | ERL_NIF_API_FUNC_DECL(int,enif_is_exception,(ErlNifEnv*, ERL_NIF_TERM term));
139 |
140 | /*
141 | ** Add new entries here to keep compatibility on Windows!!!
142 | */
143 | #endif
144 |
145 | /*
146 | ** Please keep the ERL_NIF_API_FUNC_MACRO list below in the same order
147 | ** as the ERL_NIF_API_FUNC_DECL list above
148 | */
149 | #ifdef ERL_NIF_API_FUNC_MACRO
150 | # define enif_priv_data ERL_NIF_API_FUNC_MACRO(enif_priv_data)
151 | # define enif_alloc ERL_NIF_API_FUNC_MACRO(enif_alloc)
152 | # define enif_free ERL_NIF_API_FUNC_MACRO(enif_free)
153 | # define enif_is_atom ERL_NIF_API_FUNC_MACRO(enif_is_atom)
154 | # define enif_is_binary ERL_NIF_API_FUNC_MACRO(enif_is_binary)
155 | # define enif_is_ref ERL_NIF_API_FUNC_MACRO(enif_is_ref)
156 | # define enif_inspect_binary ERL_NIF_API_FUNC_MACRO(enif_inspect_binary)
157 | # define enif_alloc_binary ERL_NIF_API_FUNC_MACRO(enif_alloc_binary)
158 | # define enif_realloc_binary ERL_NIF_API_FUNC_MACRO(enif_realloc_binary)
159 | # define enif_release_binary ERL_NIF_API_FUNC_MACRO(enif_release_binary)
160 | # define enif_get_int ERL_NIF_API_FUNC_MACRO(enif_get_int)
161 | # define enif_get_ulong ERL_NIF_API_FUNC_MACRO(enif_get_ulong)
162 | # define enif_get_double ERL_NIF_API_FUNC_MACRO(enif_get_double)
163 | # define enif_get_tuple ERL_NIF_API_FUNC_MACRO(enif_get_tuple)
164 | # define enif_get_list_cell ERL_NIF_API_FUNC_MACRO(enif_get_list_cell)
165 | # define enif_is_identical ERL_NIF_API_FUNC_MACRO(enif_is_identical)
166 | # define enif_compare ERL_NIF_API_FUNC_MACRO(enif_compare)
167 |
168 | # define enif_make_binary ERL_NIF_API_FUNC_MACRO(enif_make_binary)
169 | # define enif_make_badarg ERL_NIF_API_FUNC_MACRO(enif_make_badarg)
170 | # define enif_make_int ERL_NIF_API_FUNC_MACRO(enif_make_int)
171 | # define enif_make_ulong ERL_NIF_API_FUNC_MACRO(enif_make_ulong)
172 | # define enif_make_double ERL_NIF_API_FUNC_MACRO(enif_make_double)
173 | # define enif_make_atom ERL_NIF_API_FUNC_MACRO(enif_make_atom)
174 | # define enif_make_existing_atom ERL_NIF_API_FUNC_MACRO(enif_make_existing_atom)
175 | # define enif_make_tuple ERL_NIF_API_FUNC_MACRO(enif_make_tuple)
176 | # define enif_make_list ERL_NIF_API_FUNC_MACRO(enif_make_list)
177 | # define enif_make_list_cell ERL_NIF_API_FUNC_MACRO(enif_make_list_cell)
178 | # define enif_make_string ERL_NIF_API_FUNC_MACRO(enif_make_string)
179 | # define enif_make_ref ERL_NIF_API_FUNC_MACRO(enif_make_ref)
180 |
181 | # define enif_mutex_create ERL_NIF_API_FUNC_MACRO(enif_mutex_create)
182 | # define enif_mutex_destroy ERL_NIF_API_FUNC_MACRO(enif_mutex_destroy)
183 | # define enif_mutex_trylock ERL_NIF_API_FUNC_MACRO(enif_mutex_trylock)
184 | # define enif_mutex_lock ERL_NIF_API_FUNC_MACRO(enif_mutex_lock)
185 | # define enif_mutex_unlock ERL_NIF_API_FUNC_MACRO(enif_mutex_unlock)
186 | # define enif_cond_create ERL_NIF_API_FUNC_MACRO(enif_cond_create)
187 | # define enif_cond_destroy ERL_NIF_API_FUNC_MACRO(enif_cond_destroy)
188 | # define enif_cond_signal ERL_NIF_API_FUNC_MACRO(enif_cond_signal)
189 | # define enif_cond_broadcast ERL_NIF_API_FUNC_MACRO(enif_cond_broadcast)
190 | # define enif_cond_wait ERL_NIF_API_FUNC_MACRO(enif_cond_wait)
191 | # define enif_rwlock_create ERL_NIF_API_FUNC_MACRO(enif_rwlock_create)
192 | # define enif_rwlock_destroy ERL_NIF_API_FUNC_MACRO(enif_rwlock_destroy)
193 | # define enif_rwlock_tryrlock ERL_NIF_API_FUNC_MACRO(enif_rwlock_tryrlock)
194 | # define enif_rwlock_rlock ERL_NIF_API_FUNC_MACRO(enif_rwlock_rlock)
195 | # define enif_rwlock_runlock ERL_NIF_API_FUNC_MACRO(enif_rwlock_runlock)
196 | # define enif_rwlock_tryrwlock ERL_NIF_API_FUNC_MACRO(enif_rwlock_tryrwlock)
197 | # define enif_rwlock_rwlock ERL_NIF_API_FUNC_MACRO(enif_rwlock_rwlock)
198 | # define enif_rwlock_rwunlock ERL_NIF_API_FUNC_MACRO(enif_rwlock_rwunlock)
199 | # define enif_tsd_key_create ERL_NIF_API_FUNC_MACRO(enif_tsd_key_create)
200 | # define enif_tsd_key_destroy ERL_NIF_API_FUNC_MACRO(enif_tsd_key_destroy)
201 | # define enif_tsd_set ERL_NIF_API_FUNC_MACRO(enif_tsd_set)
202 | # define enif_tsd_get ERL_NIF_API_FUNC_MACRO(enif_tsd_get)
203 | # define enif_thread_opts_create ERL_NIF_API_FUNC_MACRO(enif_thread_opts_create)
204 | # define enif_thread_opts_destroy ERL_NIF_API_FUNC_MACRO(enif_thread_opts_destroy)
205 | # define enif_thread_create ERL_NIF_API_FUNC_MACRO(enif_thread_create)
206 | # define enif_thread_self ERL_NIF_API_FUNC_MACRO(enif_thread_self)
207 | # define enif_equal_tids ERL_NIF_API_FUNC_MACRO(enif_equal_tids)
208 | # define enif_thread_exit ERL_NIF_API_FUNC_MACRO(enif_thread_exit)
209 | # define enif_thread_join ERL_NIF_API_FUNC_MACRO(enif_thread_join)
210 |
211 | # define enif_realloc ERL_NIF_API_FUNC_MACRO(enif_realloc)
212 | # define enif_system_info ERL_NIF_API_FUNC_MACRO(enif_system_info)
213 | # define enif_fprintf ERL_NIF_API_FUNC_MACRO(enif_fprintf)
214 | # define enif_inspect_iolist_as_binary ERL_NIF_API_FUNC_MACRO(enif_inspect_iolist_as_binary)
215 | # define enif_make_sub_binary ERL_NIF_API_FUNC_MACRO(enif_make_sub_binary)
216 | # define enif_get_string ERL_NIF_API_FUNC_MACRO(enif_get_string)
217 | # define enif_get_atom ERL_NIF_API_FUNC_MACRO(enif_get_atom)
218 | # define enif_is_fun ERL_NIF_API_FUNC_MACRO(enif_is_fun)
219 | # define enif_is_pid ERL_NIF_API_FUNC_MACRO(enif_is_pid)
220 | # define enif_is_port ERL_NIF_API_FUNC_MACRO(enif_is_port)
221 | # define enif_get_uint ERL_NIF_API_FUNC_MACRO(enif_get_uint)
222 | # define enif_get_long ERL_NIF_API_FUNC_MACRO(enif_get_long)
223 | # define enif_make_uint ERL_NIF_API_FUNC_MACRO(enif_make_uint)
224 | # define enif_make_long ERL_NIF_API_FUNC_MACRO(enif_make_long)
225 | # define enif_make_tuple_from_array ERL_NIF_API_FUNC_MACRO(enif_make_tuple_from_array)
226 | # define enif_make_list_from_array ERL_NIF_API_FUNC_MACRO(enif_make_list_from_array)
227 | # define enif_is_empty_list ERL_NIF_API_FUNC_MACRO(enif_is_empty_list)
228 | # define enif_open_resource_type ERL_NIF_API_FUNC_MACRO(enif_open_resource_type)
229 | # define enif_alloc_resource ERL_NIF_API_FUNC_MACRO(enif_alloc_resource)
230 | # define enif_release_resource ERL_NIF_API_FUNC_MACRO(enif_release_resource)
231 | # define enif_make_resource ERL_NIF_API_FUNC_MACRO(enif_make_resource)
232 | # define enif_get_resource ERL_NIF_API_FUNC_MACRO(enif_get_resource)
233 | # define enif_sizeof_resource ERL_NIF_API_FUNC_MACRO(enif_sizeof_resource)
234 | # define enif_make_new_binary ERL_NIF_API_FUNC_MACRO(enif_make_new_binary)
235 | # define enif_is_list ERL_NIF_API_FUNC_MACRO(enif_is_list)
236 | # define enif_is_tuple ERL_NIF_API_FUNC_MACRO(enif_is_tuple)
237 | # define enif_get_atom_length ERL_NIF_API_FUNC_MACRO(enif_get_atom_length)
238 | # define enif_get_list_length ERL_NIF_API_FUNC_MACRO(enif_get_list_length)
239 | # define enif_make_atom_len ERL_NIF_API_FUNC_MACRO(enif_make_atom_len)
240 | # define enif_make_existing_atom_len ERL_NIF_API_FUNC_MACRO(enif_make_existing_atom_len)
241 | # define enif_make_string_len ERL_NIF_API_FUNC_MACRO(enif_make_string_len)
242 | # define enif_alloc_env ERL_NIF_API_FUNC_MACRO(enif_alloc_env)
243 | # define enif_free_env ERL_NIF_API_FUNC_MACRO(enif_free_env)
244 | # define enif_clear_env ERL_NIF_API_FUNC_MACRO(enif_clear_env)
245 | # define enif_send ERL_NIF_API_FUNC_MACRO(enif_send)
246 | # define enif_make_copy ERL_NIF_API_FUNC_MACRO(enif_make_copy)
247 | # define enif_self ERL_NIF_API_FUNC_MACRO(enif_self)
248 | # define enif_get_local_pid ERL_NIF_API_FUNC_MACRO(enif_get_local_pid)
249 | # define enif_keep_resource ERL_NIF_API_FUNC_MACRO(enif_keep_resource)
250 | # define enif_make_resource_binary ERL_NIF_API_FUNC_MACRO(enif_make_resource_binary)
251 | #if SIZEOF_LONG != 8
252 | # define enif_get_int64 ERL_NIF_API_FUNC_MACRO(enif_get_int64)
253 | # define enif_get_uint64 ERL_NIF_API_FUNC_MACRO(enif_get_uint64)
254 | # define enif_make_int64 ERL_NIF_API_FUNC_MACRO(enif_make_int64)
255 | # define enif_make_uint64 ERL_NIF_API_FUNC_MACRO(enif_make_uint64)
256 | #endif
257 |
258 | # define enif_is_exception ERL_NIF_API_FUNC_MACRO(enif_is_exception)
259 |
260 | /*
261 | ** Add new entries here
262 | */
263 | #endif
264 |
265 | #ifndef enif_make_list1
266 | # define enif_make_list1(ENV,E1) enif_make_list(ENV,1,E1)
267 | # define enif_make_list2(ENV,E1,E2) enif_make_list(ENV,2,E1,E2)
268 | # define enif_make_list3(ENV,E1,E2,E3) enif_make_list(ENV,3,E1,E2,E3)
269 | # define enif_make_list4(ENV,E1,E2,E3,E4) enif_make_list(ENV,4,E1,E2,E3,E4)
270 | # define enif_make_list5(ENV,E1,E2,E3,E4,E5) enif_make_list(ENV,5,E1,E2,E3,E4,E5)
271 | # define enif_make_list6(ENV,E1,E2,E3,E4,E5,E6) enif_make_list(ENV,6,E1,E2,E3,E4,E5,E6)
272 | # define enif_make_list7(ENV,E1,E2,E3,E4,E5,E6,E7) enif_make_list(ENV,7,E1,E2,E3,E4,E5,E6,E7)
273 | # define enif_make_list8(ENV,E1,E2,E3,E4,E5,E6,E7,E8) enif_make_list(ENV,8,E1,E2,E3,E4,E5,E6,E7,E8)
274 | # define enif_make_list9(ENV,E1,E2,E3,E4,E5,E6,E7,E8,E9) enif_make_list(ENV,9,E1,E2,E3,E4,E5,E6,E7,E8,E9)
275 | # define enif_make_tuple1(ENV,E1) enif_make_tuple(ENV,1,E1)
276 | # define enif_make_tuple2(ENV,E1,E2) enif_make_tuple(ENV,2,E1,E2)
277 | # define enif_make_tuple3(ENV,E1,E2,E3) enif_make_tuple(ENV,3,E1,E2,E3)
278 | # define enif_make_tuple4(ENV,E1,E2,E3,E4) enif_make_tuple(ENV,4,E1,E2,E3,E4)
279 | # define enif_make_tuple5(ENV,E1,E2,E3,E4,E5) enif_make_tuple(ENV,5,E1,E2,E3,E4,E5)
280 | # define enif_make_tuple6(ENV,E1,E2,E3,E4,E5,E6) enif_make_tuple(ENV,6,E1,E2,E3,E4,E5,E6)
281 | # define enif_make_tuple7(ENV,E1,E2,E3,E4,E5,E6,E7) enif_make_tuple(ENV,7,E1,E2,E3,E4,E5,E6,E7)
282 | # define enif_make_tuple8(ENV,E1,E2,E3,E4,E5,E6,E7,E8) enif_make_tuple(ENV,8,E1,E2,E3,E4,E5,E6,E7,E8)
283 | # define enif_make_tuple9(ENV,E1,E2,E3,E4,E5,E6,E7,E8,E9) enif_make_tuple(ENV,9,E1,E2,E3,E4,E5,E6,E7,E8,E9)
284 |
285 | # define enif_make_pid(ENV, PID) ((const ERL_NIF_TERM)((PID)->pid))
286 |
287 | #if SIZEOF_LONG == 8
288 | # define enif_get_int64 enif_get_long
289 | # define enif_get_uint64 enif_get_ulong
290 | # define enif_make_int64 enif_make_long
291 | # define enif_make_uint64 enif_make_ulong
292 | #endif
293 |
294 | #endif
295 |
296 |
--------------------------------------------------------------------------------