ffi-nats-core 0.3.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ffi-nats-core.gemspec +8 -0
- data/lib/ffi/nats/core/version.rb +1 -1
- data/vendor/cnats/CMakeLists.txt +137 -0
- data/vendor/cnats/adapters/libevent.h +220 -0
- data/vendor/cnats/adapters/libuv.h +472 -0
- data/vendor/cnats/examples/CMakeLists.txt +56 -0
- data/vendor/cnats/examples/asynctimeout.c +83 -0
- data/vendor/cnats/examples/examples.h +322 -0
- data/vendor/cnats/examples/libevent-pub.c +136 -0
- data/vendor/cnats/examples/libevent-sub.c +104 -0
- data/vendor/cnats/examples/libuv-pub.c +120 -0
- data/vendor/cnats/examples/libuv-sub.c +114 -0
- data/vendor/cnats/examples/publisher.c +62 -0
- data/vendor/cnats/examples/queuegroup.c +132 -0
- data/vendor/cnats/examples/replier.c +149 -0
- data/vendor/cnats/examples/requestor.c +75 -0
- data/vendor/cnats/examples/subscriber.c +133 -0
- data/vendor/cnats/src/CMakeLists.txt +31 -0
- data/vendor/cnats/src/asynccb.c +66 -0
- data/vendor/cnats/src/asynccb.h +42 -0
- data/vendor/cnats/src/buf.c +246 -0
- data/vendor/cnats/src/buf.h +116 -0
- data/vendor/cnats/src/comsock.c +474 -0
- data/vendor/cnats/src/comsock.h +81 -0
- data/vendor/cnats/src/conn.c +2725 -0
- data/vendor/cnats/src/conn.h +75 -0
- data/vendor/cnats/src/err.h +31 -0
- data/vendor/cnats/src/gc.h +27 -0
- data/vendor/cnats/src/hash.c +725 -0
- data/vendor/cnats/src/hash.h +141 -0
- data/vendor/cnats/src/include/n-unix.h +56 -0
- data/vendor/cnats/src/include/n-win.h +59 -0
- data/vendor/cnats/src/mem.h +20 -0
- data/vendor/cnats/src/msg.c +155 -0
- data/vendor/cnats/src/msg.h +43 -0
- data/vendor/cnats/src/nats.c +1734 -0
- data/vendor/cnats/src/nats.h +2024 -0
- data/vendor/cnats/src/natsp.h +518 -0
- data/vendor/cnats/src/natstime.c +79 -0
- data/vendor/cnats/src/natstime.h +27 -0
- data/vendor/cnats/src/nuid.c +265 -0
- data/vendor/cnats/src/nuid.h +21 -0
- data/vendor/cnats/src/opts.c +1030 -0
- data/vendor/cnats/src/opts.h +19 -0
- data/vendor/cnats/src/parser.c +869 -0
- data/vendor/cnats/src/parser.h +87 -0
- data/vendor/cnats/src/pub.c +293 -0
- data/vendor/cnats/src/srvpool.c +380 -0
- data/vendor/cnats/src/srvpool.h +71 -0
- data/vendor/cnats/src/stats.c +54 -0
- data/vendor/cnats/src/stats.h +21 -0
- data/vendor/cnats/src/status.c +60 -0
- data/vendor/cnats/src/status.h +95 -0
- data/vendor/cnats/src/sub.c +956 -0
- data/vendor/cnats/src/sub.h +34 -0
- data/vendor/cnats/src/timer.c +86 -0
- data/vendor/cnats/src/timer.h +57 -0
- data/vendor/cnats/src/unix/cond.c +103 -0
- data/vendor/cnats/src/unix/mutex.c +107 -0
- data/vendor/cnats/src/unix/sock.c +105 -0
- data/vendor/cnats/src/unix/thread.c +162 -0
- data/vendor/cnats/src/url.c +134 -0
- data/vendor/cnats/src/url.h +24 -0
- data/vendor/cnats/src/util.c +823 -0
- data/vendor/cnats/src/util.h +75 -0
- data/vendor/cnats/src/version.h +29 -0
- data/vendor/cnats/src/version.h.in +29 -0
- data/vendor/cnats/src/win/cond.c +86 -0
- data/vendor/cnats/src/win/mutex.c +54 -0
- data/vendor/cnats/src/win/sock.c +158 -0
- data/vendor/cnats/src/win/strings.c +108 -0
- data/vendor/cnats/src/win/thread.c +180 -0
- data/vendor/cnats/test/CMakeLists.txt +35 -0
- data/vendor/cnats/test/certs/ca.pem +38 -0
- data/vendor/cnats/test/certs/client-cert.pem +30 -0
- data/vendor/cnats/test/certs/client-key.pem +51 -0
- data/vendor/cnats/test/certs/server-cert.pem +31 -0
- data/vendor/cnats/test/certs/server-key.pem +51 -0
- data/vendor/cnats/test/dylib/CMakeLists.txt +10 -0
- data/vendor/cnats/test/dylib/nonats.c +13 -0
- data/vendor/cnats/test/list.txt +125 -0
- data/vendor/cnats/test/test.c +11655 -0
- data/vendor/cnats/test/tls.conf +15 -0
- data/vendor/cnats/test/tlsverify.conf +19 -0
- metadata +83 -1
@@ -0,0 +1,75 @@
|
|
1
|
+
// Copyright 2015 Apcera Inc. All rights reserved.
|
2
|
+
|
3
|
+
#ifndef UTIL_H_
|
4
|
+
#define UTIL_H_
|
5
|
+
|
6
|
+
#include "natsp.h"
|
7
|
+
|
8
|
+
#define TYPE_NOT_SET (0)
|
9
|
+
#define TYPE_STR (1)
|
10
|
+
#define TYPE_BOOL (2)
|
11
|
+
#define TYPE_NUM (3)
|
12
|
+
#define TYPE_INT (4)
|
13
|
+
#define TYPE_LONG (5)
|
14
|
+
#define TYPE_DOUBLE (6)
|
15
|
+
#define TYPE_ARRAY (7)
|
16
|
+
|
17
|
+
typedef struct
|
18
|
+
{
|
19
|
+
void **values;
|
20
|
+
int typ;
|
21
|
+
int eltSize;
|
22
|
+
int size;
|
23
|
+
int cap;
|
24
|
+
|
25
|
+
} nats_JSONArray;
|
26
|
+
|
27
|
+
typedef struct
|
28
|
+
{
|
29
|
+
char *name;
|
30
|
+
int typ;
|
31
|
+
union
|
32
|
+
{
|
33
|
+
char *vstr;
|
34
|
+
bool vbool;
|
35
|
+
long double vdec;
|
36
|
+
nats_JSONArray *varr;
|
37
|
+
} value;
|
38
|
+
|
39
|
+
} nats_JSONField;
|
40
|
+
|
41
|
+
typedef struct
|
42
|
+
{
|
43
|
+
char *str;
|
44
|
+
natsStrHash *fields;
|
45
|
+
|
46
|
+
} nats_JSON;
|
47
|
+
|
48
|
+
int64_t
|
49
|
+
nats_ParseInt64(const char *d, int dLen);
|
50
|
+
|
51
|
+
natsStatus
|
52
|
+
nats_ParseControl(natsControl *control, const char *line);
|
53
|
+
|
54
|
+
natsStatus
|
55
|
+
nats_CreateStringFromBuffer(char **newStr, natsBuffer *buf);
|
56
|
+
|
57
|
+
const char*
|
58
|
+
nats_GetBoolStr(bool value);
|
59
|
+
|
60
|
+
void
|
61
|
+
nats_NormalizeErr(char *error);
|
62
|
+
|
63
|
+
natsStatus
|
64
|
+
nats_JSONParse(nats_JSON **json, const char *str, int strLen);
|
65
|
+
|
66
|
+
natsStatus
|
67
|
+
nats_JSONGetValue(nats_JSON *json, const char *fieldName, int fieldType, void **addr);
|
68
|
+
|
69
|
+
natsStatus
|
70
|
+
nats_JSONGetArrayValue(nats_JSON *json, const char *fieldName, int fieldType, void ***array, int *arraySize);
|
71
|
+
|
72
|
+
void
|
73
|
+
nats_JSONDestroy(nats_JSON *json);
|
74
|
+
|
75
|
+
#endif /* UTIL_H_ */
|
@@ -0,0 +1,29 @@
|
|
1
|
+
/*
|
2
|
+
* DO NOT EDIT! Generated during make process.
|
3
|
+
* Copyright 2015 Apcera Inc. All rights reserved.
|
4
|
+
*/
|
5
|
+
|
6
|
+
#ifndef VERSION_H_
|
7
|
+
#define VERSION_H_
|
8
|
+
|
9
|
+
#ifdef __cplusplus
|
10
|
+
extern "C" {
|
11
|
+
#endif
|
12
|
+
|
13
|
+
#define NATS_VERSION_MAJOR 1
|
14
|
+
#define NATS_VERSION_MINOR 5
|
15
|
+
#define NATS_VERSION_PATCH 0
|
16
|
+
|
17
|
+
#define NATS_VERSION_STRING "1.5.0"
|
18
|
+
|
19
|
+
#define NATS_VERSION_NUMBER ((NATS_VERSION_MAJOR << 16) | \
|
20
|
+
(NATS_VERSION_MINOR << 8) | \
|
21
|
+
NATS_VERSION_PATCH)
|
22
|
+
|
23
|
+
#define NATS_VERSION_REQUIRED_NUMBER 0x010100
|
24
|
+
|
25
|
+
#ifdef __cplusplus
|
26
|
+
}
|
27
|
+
#endif
|
28
|
+
|
29
|
+
#endif /* VERSION_H_ */
|
@@ -0,0 +1,29 @@
|
|
1
|
+
/*
|
2
|
+
* DO NOT EDIT! Generated during make process.
|
3
|
+
* Copyright 2015 Apcera Inc. All rights reserved.
|
4
|
+
*/
|
5
|
+
|
6
|
+
#ifndef VERSION_H_
|
7
|
+
#define VERSION_H_
|
8
|
+
|
9
|
+
#ifdef __cplusplus
|
10
|
+
extern "C" {
|
11
|
+
#endif
|
12
|
+
|
13
|
+
#define NATS_VERSION_MAJOR @NATS_VERSION_MAJOR@
|
14
|
+
#define NATS_VERSION_MINOR @NATS_VERSION_MINOR@
|
15
|
+
#define NATS_VERSION_PATCH @NATS_VERSION_PATCH@
|
16
|
+
|
17
|
+
#define NATS_VERSION_STRING "@NATS_VERSION_MAJOR@.@NATS_VERSION_MINOR@.@NATS_VERSION_PATCH@@NATS_VERSION_SUFFIX@"
|
18
|
+
|
19
|
+
#define NATS_VERSION_NUMBER ((NATS_VERSION_MAJOR << 16) | \
|
20
|
+
(NATS_VERSION_MINOR << 8) | \
|
21
|
+
NATS_VERSION_PATCH)
|
22
|
+
|
23
|
+
#define NATS_VERSION_REQUIRED_NUMBER @NATS_VERSION_REQUIRED_NUMBER@
|
24
|
+
|
25
|
+
#ifdef __cplusplus
|
26
|
+
}
|
27
|
+
#endif
|
28
|
+
|
29
|
+
#endif /* VERSION_H_ */
|
@@ -0,0 +1,86 @@
|
|
1
|
+
// Copyright 2015 Apcera Inc. All rights reserved.
|
2
|
+
|
3
|
+
#include "../natsp.h"
|
4
|
+
#include "../mem.h"
|
5
|
+
|
6
|
+
natsStatus
|
7
|
+
natsCondition_Create(natsCondition **cond)
|
8
|
+
{
|
9
|
+
natsCondition *c = (natsCondition*) NATS_CALLOC(1, sizeof(natsCondition));
|
10
|
+
natsStatus s = NATS_OK;
|
11
|
+
|
12
|
+
if (c == NULL)
|
13
|
+
return nats_setDefaultError(NATS_NO_MEMORY);
|
14
|
+
|
15
|
+
InitializeConditionVariable(c);
|
16
|
+
*cond = c;
|
17
|
+
|
18
|
+
return s;
|
19
|
+
}
|
20
|
+
|
21
|
+
void
|
22
|
+
natsCondition_Wait(natsCondition *cond, natsMutex *mutex)
|
23
|
+
{
|
24
|
+
if (SleepConditionVariableCS(cond, mutex, INFINITE) == 0)
|
25
|
+
abort();
|
26
|
+
}
|
27
|
+
|
28
|
+
natsStatus
|
29
|
+
natsCondition_TimedWait(natsCondition *cond, natsMutex *mutex, int64_t timeout)
|
30
|
+
{
|
31
|
+
if (timeout <= 0)
|
32
|
+
return NATS_TIMEOUT;
|
33
|
+
|
34
|
+
if (SleepConditionVariableCS(cond, mutex, (DWORD) timeout) == 0)
|
35
|
+
{
|
36
|
+
if (GetLastError() == ERROR_TIMEOUT)
|
37
|
+
return NATS_TIMEOUT;
|
38
|
+
|
39
|
+
abort();
|
40
|
+
}
|
41
|
+
|
42
|
+
return NATS_OK;
|
43
|
+
}
|
44
|
+
|
45
|
+
natsStatus
|
46
|
+
natsCondition_AbsoluteTimedWait(natsCondition *cond, natsMutex *mutex, int64_t absoluteTime)
|
47
|
+
{
|
48
|
+
int64_t now = nats_Now();;
|
49
|
+
int64_t sleepTime = absoluteTime - now;
|
50
|
+
|
51
|
+
if (sleepTime <= 0)
|
52
|
+
return NATS_TIMEOUT;
|
53
|
+
|
54
|
+
if (SleepConditionVariableCS(cond, mutex, (DWORD) sleepTime) == 0)
|
55
|
+
{
|
56
|
+
if (GetLastError() == ERROR_TIMEOUT)
|
57
|
+
return NATS_TIMEOUT;
|
58
|
+
|
59
|
+
return nats_setError(NATS_SYS_ERROR,
|
60
|
+
"SleepConditionVariableCS error: %d",
|
61
|
+
GetLastError());
|
62
|
+
}
|
63
|
+
|
64
|
+
return NATS_OK;
|
65
|
+
}
|
66
|
+
|
67
|
+
void
|
68
|
+
natsCondition_Signal(natsCondition *cond)
|
69
|
+
{
|
70
|
+
WakeConditionVariable(cond);
|
71
|
+
}
|
72
|
+
|
73
|
+
void
|
74
|
+
natsCondition_Broadcast(natsCondition *cond)
|
75
|
+
{
|
76
|
+
WakeAllConditionVariable(cond);
|
77
|
+
}
|
78
|
+
|
79
|
+
void
|
80
|
+
natsCondition_Destroy(natsCondition *cond)
|
81
|
+
{
|
82
|
+
if (cond == NULL)
|
83
|
+
return;
|
84
|
+
|
85
|
+
NATS_FREE(cond);
|
86
|
+
}
|
@@ -0,0 +1,54 @@
|
|
1
|
+
// Copyright 2015 Apcera Inc. All rights reserved.
|
2
|
+
|
3
|
+
#include "../natsp.h"
|
4
|
+
#include "../mem.h"
|
5
|
+
|
6
|
+
natsStatus
|
7
|
+
natsMutex_Create(natsMutex **newMutex)
|
8
|
+
{
|
9
|
+
natsMutex *m = NATS_CALLOC(1, sizeof(natsMutex));
|
10
|
+
|
11
|
+
if (m == NULL)
|
12
|
+
return nats_setDefaultError(NATS_NO_MEMORY);
|
13
|
+
|
14
|
+
if (gLockSpinCount > 0)
|
15
|
+
InitializeCriticalSectionAndSpinCount(m, (DWORD) gLockSpinCount);
|
16
|
+
else
|
17
|
+
InitializeCriticalSection(m);
|
18
|
+
*newMutex = m;
|
19
|
+
|
20
|
+
return NATS_OK;
|
21
|
+
}
|
22
|
+
|
23
|
+
bool
|
24
|
+
natsMutex_TryLock(natsMutex *m)
|
25
|
+
{
|
26
|
+
if (TryEnterCriticalSection(m) == 0)
|
27
|
+
return false;
|
28
|
+
|
29
|
+
return true;
|
30
|
+
}
|
31
|
+
|
32
|
+
void
|
33
|
+
natsMutex_Lock(natsMutex *m)
|
34
|
+
{
|
35
|
+
// If gLockSpinCount > 0, the mutex has been created as as spin lock,
|
36
|
+
// so we don't have to do anything special here.
|
37
|
+
EnterCriticalSection(m);
|
38
|
+
}
|
39
|
+
|
40
|
+
void
|
41
|
+
natsMutex_Unlock(natsMutex *m)
|
42
|
+
{
|
43
|
+
LeaveCriticalSection(m);
|
44
|
+
}
|
45
|
+
|
46
|
+
void
|
47
|
+
natsMutex_Destroy(natsMutex *m)
|
48
|
+
{
|
49
|
+
if (m == NULL)
|
50
|
+
return;
|
51
|
+
|
52
|
+
DeleteCriticalSection(m);
|
53
|
+
NATS_FREE(m);
|
54
|
+
}
|
@@ -0,0 +1,158 @@
|
|
1
|
+
// Copyright 2015 Apcera Inc. All rights reserved.
|
2
|
+
|
3
|
+
#include "../natsp.h"
|
4
|
+
|
5
|
+
#include <errno.h>
|
6
|
+
#include <io.h>
|
7
|
+
|
8
|
+
#include "../mem.h"
|
9
|
+
#include "../comsock.h"
|
10
|
+
|
11
|
+
void
|
12
|
+
natsSys_Init(void)
|
13
|
+
{
|
14
|
+
WSADATA wsaData;
|
15
|
+
int errorno;
|
16
|
+
|
17
|
+
/* Initialize winsock */
|
18
|
+
errorno = WSAStartup(MAKEWORD(2, 2), &wsaData);
|
19
|
+
if (errorno != 0)
|
20
|
+
{
|
21
|
+
printf("FATAL: Unable to initialize winsock!\n");
|
22
|
+
abort();
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
26
|
+
natsStatus
|
27
|
+
natsSock_Init(natsSockCtx *ctx)
|
28
|
+
{
|
29
|
+
natsStatus s;
|
30
|
+
|
31
|
+
memset(ctx, 0, sizeof(natsSockCtx));
|
32
|
+
|
33
|
+
ctx->fd = NATS_SOCK_INVALID;
|
34
|
+
|
35
|
+
s = natsSock_CreateFDSet(&ctx->fdSet);
|
36
|
+
if (s == NATS_OK)
|
37
|
+
{
|
38
|
+
s = natsSock_CreateFDSet(&ctx->errSet);
|
39
|
+
if (s != NATS_OK)
|
40
|
+
{
|
41
|
+
natsSock_DestroyFDSet(ctx->fdSet);
|
42
|
+
ctx->fdSet = NULL;
|
43
|
+
}
|
44
|
+
}
|
45
|
+
return s;
|
46
|
+
}
|
47
|
+
|
48
|
+
void
|
49
|
+
natsSock_Clear(natsSockCtx *ctx)
|
50
|
+
{
|
51
|
+
natsSock_DestroyFDSet(ctx->fdSet);
|
52
|
+
natsSock_DestroyFDSet(ctx->errSet);
|
53
|
+
}
|
54
|
+
|
55
|
+
natsStatus
|
56
|
+
natsSock_WaitReady(int waitMode, natsSockCtx *ctx)
|
57
|
+
{
|
58
|
+
struct timeval *timeout = NULL;
|
59
|
+
int res;
|
60
|
+
fd_set *fdSet = ctx->fdSet;
|
61
|
+
fd_set *errSet = ctx->errSet;
|
62
|
+
natsSock sock = ctx->fd;
|
63
|
+
natsDeadline *deadline = &(ctx->deadline);
|
64
|
+
|
65
|
+
FD_ZERO(fdSet);
|
66
|
+
FD_SET(sock, fdSet);
|
67
|
+
|
68
|
+
FD_ZERO(errSet);
|
69
|
+
FD_SET(sock, errSet);
|
70
|
+
|
71
|
+
if (deadline != NULL)
|
72
|
+
timeout = natsDeadline_GetTimeout(deadline);
|
73
|
+
|
74
|
+
switch (waitMode)
|
75
|
+
{
|
76
|
+
case WAIT_FOR_READ: res = select((int) (sock + 1), fdSet, NULL, NULL, timeout); break;
|
77
|
+
case WAIT_FOR_WRITE: res = select((int) (sock + 1), NULL, fdSet, NULL, timeout); break;
|
78
|
+
// On Windows, we will know if the non-blocking connect has failed
|
79
|
+
// by using the exception set, not the write set.
|
80
|
+
case WAIT_FOR_CONNECT: res = select((int) (sock + 1), NULL, fdSet, errSet, timeout); break;
|
81
|
+
default: abort();
|
82
|
+
}
|
83
|
+
|
84
|
+
if (res == NATS_SOCK_ERROR)
|
85
|
+
return nats_setError(NATS_IO_ERROR, "select error: %d", res);
|
86
|
+
|
87
|
+
// Not ready if select returned no socket, the socket is not in the
|
88
|
+
// given fdSet, or for connect, the socket is set in the error set.
|
89
|
+
if ((res == 0)
|
90
|
+
|| !FD_ISSET(sock, fdSet)
|
91
|
+
|| ((waitMode == WAIT_FOR_CONNECT) && FD_ISSET(sock, errSet)))
|
92
|
+
{
|
93
|
+
return nats_setDefaultError(NATS_TIMEOUT);
|
94
|
+
}
|
95
|
+
|
96
|
+
return NATS_OK;
|
97
|
+
}
|
98
|
+
|
99
|
+
natsStatus
|
100
|
+
natsSock_SetBlocking(natsSock fd, bool blocking)
|
101
|
+
{
|
102
|
+
u_long iMode = 0;
|
103
|
+
|
104
|
+
// If iMode = 0, blocking is enabled;
|
105
|
+
// If iMode != 0, non-blocking mode is enabled.
|
106
|
+
if (!blocking)
|
107
|
+
iMode = 1;
|
108
|
+
|
109
|
+
if (ioctlsocket(fd, FIONBIO, &iMode) != NO_ERROR)
|
110
|
+
return nats_setError(NATS_SYS_ERROR,
|
111
|
+
"ioctlsocket error: %d",
|
112
|
+
NATS_SOCK_GET_ERROR);
|
113
|
+
|
114
|
+
return NATS_OK;
|
115
|
+
}
|
116
|
+
|
117
|
+
bool
|
118
|
+
natsSock_IsConnected(natsSock fd)
|
119
|
+
{
|
120
|
+
int res;
|
121
|
+
int error = 0;
|
122
|
+
int errorLen = (socklen_t) sizeof(int);
|
123
|
+
|
124
|
+
res = getsockopt(fd, SOL_SOCKET, SO_ERROR, (char*)&error, &errorLen);
|
125
|
+
if ((res == NATS_SOCK_ERROR) || (error != 0))
|
126
|
+
return false;
|
127
|
+
|
128
|
+
return true;
|
129
|
+
}
|
130
|
+
|
131
|
+
natsStatus
|
132
|
+
natsSock_Flush(natsSock fd)
|
133
|
+
{
|
134
|
+
HANDLE fh = (HANDLE)_get_osfhandle((int) fd);
|
135
|
+
|
136
|
+
if (fh == INVALID_HANDLE_VALUE)
|
137
|
+
{
|
138
|
+
errno = EBADF;
|
139
|
+
return nats_setError(NATS_INVALID_ARG, "%s",
|
140
|
+
"Error setting flushing socket. Invalid handle");
|
141
|
+
}
|
142
|
+
|
143
|
+
if (!FlushFileBuffers(fh))
|
144
|
+
{
|
145
|
+
DWORD code = GetLastError();
|
146
|
+
|
147
|
+
if (code == ERROR_INVALID_HANDLE)
|
148
|
+
errno = EINVAL;
|
149
|
+
else
|
150
|
+
errno = EIO;
|
151
|
+
|
152
|
+
return nats_setError(NATS_IO_ERROR,
|
153
|
+
"Error setting flushing socket. Error: %d",
|
154
|
+
NATS_SOCK_GET_ERROR);
|
155
|
+
}
|
156
|
+
|
157
|
+
return NATS_OK;
|
158
|
+
}
|
@@ -0,0 +1,108 @@
|
|
1
|
+
// Copyright 2015 Apcera Inc. All rights reserved.
|
2
|
+
|
3
|
+
#include "../natsp.h"
|
4
|
+
|
5
|
+
#include "../mem.h"
|
6
|
+
|
7
|
+
int
|
8
|
+
nats_asprintf(char **newStr, const char *fmt, ...)
|
9
|
+
{
|
10
|
+
char tmp[256];
|
11
|
+
char *str;
|
12
|
+
int n, size;
|
13
|
+
va_list ap;
|
14
|
+
|
15
|
+
size = sizeof(tmp);
|
16
|
+
str = (char*) tmp;
|
17
|
+
|
18
|
+
do
|
19
|
+
{
|
20
|
+
va_start(ap, fmt);
|
21
|
+
n = vsnprintf(str, size, fmt, ap);
|
22
|
+
va_end(ap);
|
23
|
+
|
24
|
+
if ((n < 0) || (n >= size))
|
25
|
+
{
|
26
|
+
// We failed, but we don't know how much we need, so start with
|
27
|
+
// doubling the size and see if it's better.
|
28
|
+
if (n < 0)
|
29
|
+
{
|
30
|
+
size *= 2;
|
31
|
+
}
|
32
|
+
else
|
33
|
+
{
|
34
|
+
// We know exactly how much we need.
|
35
|
+
size = (n + 1);
|
36
|
+
|
37
|
+
// now set n to -1 so that we loop again.
|
38
|
+
n = -1;
|
39
|
+
}
|
40
|
+
|
41
|
+
if (str != tmp)
|
42
|
+
{
|
43
|
+
char *realloced = NULL;
|
44
|
+
|
45
|
+
realloced = NATS_REALLOC(str, size);
|
46
|
+
if (realloced == NULL)
|
47
|
+
{
|
48
|
+
NATS_FREE(str);
|
49
|
+
str = NULL;
|
50
|
+
}
|
51
|
+
else
|
52
|
+
{
|
53
|
+
str = realloced;
|
54
|
+
}
|
55
|
+
}
|
56
|
+
else
|
57
|
+
{
|
58
|
+
str = NATS_MALLOC(size);
|
59
|
+
}
|
60
|
+
}
|
61
|
+
}
|
62
|
+
while ((n < 0) && (str != NULL));
|
63
|
+
|
64
|
+
if (str != NULL)
|
65
|
+
{
|
66
|
+
if (str != tmp)
|
67
|
+
*newStr = str;
|
68
|
+
else
|
69
|
+
*newStr = NATS_STRDUP(str);
|
70
|
+
|
71
|
+
if (*newStr == NULL)
|
72
|
+
n = -1;
|
73
|
+
}
|
74
|
+
|
75
|
+
return n;
|
76
|
+
}
|
77
|
+
|
78
|
+
char*
|
79
|
+
nats_strcasestr(const char *haystack, const char *needle)
|
80
|
+
{
|
81
|
+
char *lowHaystack = NATS_STRDUP(haystack);
|
82
|
+
char *lowNeedle = NATS_STRDUP(needle);
|
83
|
+
char *res = NULL;
|
84
|
+
int offset = 0;
|
85
|
+
|
86
|
+
if ((lowHaystack == NULL) || (lowNeedle == NULL))
|
87
|
+
{
|
88
|
+
NATS_FREE(lowHaystack);
|
89
|
+
NATS_FREE(lowNeedle);
|
90
|
+
return NULL;
|
91
|
+
}
|
92
|
+
|
93
|
+
_strlwr(lowHaystack);
|
94
|
+
_strlwr(lowNeedle);
|
95
|
+
|
96
|
+
res = strstr((const char*) lowHaystack, (const char*) lowNeedle);
|
97
|
+
if (res != NULL)
|
98
|
+
{
|
99
|
+
offset = (int) (res - lowHaystack);
|
100
|
+
res = (char *) (haystack + offset);
|
101
|
+
}
|
102
|
+
|
103
|
+
NATS_FREE(lowHaystack);
|
104
|
+
NATS_FREE(lowNeedle);
|
105
|
+
|
106
|
+
return res;
|
107
|
+
}
|
108
|
+
|