ffi-nats-core 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
|