Skip to content

Commit

Permalink
moved cython server string parse to c
Browse files Browse the repository at this point in the history
  • Loading branch information
kentslaney committed Nov 28, 2023
1 parent db189f1 commit e54938f
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 40 deletions.
8 changes: 7 additions & 1 deletion include/Common.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,9 +225,15 @@ typedef enum {
QUIT_OP,
} op_code_t;

struct ServerSpec {
char* host;
char* port;
char* alias;
};

const char* errCodeToString(err_code_t err);
bool isLocalSocket(const char* host);
char** splitServerString(char* input);
ServerSpec splitServerString(char* input);

} // namespace mc
} // namespace douban
46 changes: 16 additions & 30 deletions libmc/_client.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# cython: profile=False, c_string_type=unicode, c_string_encoding=utf8

from libc.stdint cimport uint8_t, uint32_t, uint64_t, int64_t
from libc.stdlib cimport atoi
from libcpp cimport bool as bool_t
from libcpp.string cimport string
from libcpp.vector cimport vector
Expand Down Expand Up @@ -45,7 +46,12 @@ cdef extern from "Common.h" namespace "douban::mc":
VERSION_OP
QUIT_OP

#bool isLocalSocket(const char* host) nogil
cdef struct ServerSpec:
char* host
char* port
char* alias

ServerSpec splitServerString(char* input) nogil


cdef extern from "Export.h":
Expand Down Expand Up @@ -380,39 +386,19 @@ cdef class PyClient:

servers_ = []
for srv in servers:
addr_alias = srv.rsplit(' ', 1)
addr = addr_alias[0]
if len(addr_alias) == 1:
alias = None
elif (len(addr) - len(addr.rstrip("\\"))) % 2 == 1:
addr = srv
alias = None
else:
alias = addr_alias[1]

if addr.startswith("/"):
port = 0
else:
host_port = addr.split(':')
host = host_port[0]
if len(host_port) == 1:
port = MC_DEFAULT_PORT
else:
port = int(host_port[1])
if PY_MAJOR_VERSION > 2:
host = PyUnicode_AsUTF8String(host)
alias = PyUnicode_AsUTF8String(alias) if alias else None
servers_.append((host, port, alias))
srv = PyUnicode_AsUTF8String(srv)
srv = PyString_AsString(srv)
servers_.append(srv)

Py_INCREF(servers_)
for i in range(n):
host, port, alias = servers_[i]
c_hosts[i] = PyString_AsString(host)
c_ports[i] = PyInt_AsLong(port)
if alias is None:
c_aliases[i] = NULL
else:
c_aliases[i] = PyString_AsString(alias)
c_split = splitServerString(servers_[i])
host, port, alias = c_split

c_hosts[i] = c_split.host
c_ports[i] = MC_DEFAULT_PORT if c_split.port == NULL else atoi(c_split.port)
c_aliases[i] = c_split.alias

if init:
rv = self._imp.init(c_hosts, c_ports, n, c_aliases)
Expand Down
24 changes: 16 additions & 8 deletions src/Common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,28 +50,36 @@ const char* errCodeToString(err_code_t err) {
}
}

bool isLocalPath(const char* host) {
bool isLocalSocket(const char* host) {
return host[0] == '/';
}

char** splitServerString(char* input) {
bool escaped = false;
char *res[3] = { input--, NULL, NULL };
ServerSpec splitServerString(char* input) {
bool escaped = false, num = false;
ServerSpec res = { input--, NULL, NULL };
for (;;) {
switch (*(++input))
{
case ':': // invalid in a UNIX path
*input = '\0';
res[1] = input + 1;
res.port = input + 1;
num = true;
case '\0':
break;
return res;
case ' ':
if (!escaped) {
*input = '\0';
res[2] = input + 1;
break;
res.alias = input + 1;
return res;
}
default:
if (num) {
*res.port = ':';
res.port = NULL;
num = false;
}
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
escaped = false;
continue;
case '\\':
Expand Down
1 change: 1 addition & 0 deletions src/Connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <fcntl.h>
#include <queue>

#include "Common.h"
#include "Connection.h"
#include "Keywords.h"

Expand Down
2 changes: 1 addition & 1 deletion tests/test_unix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ TEST(test_unix, establish_connection) {
Client* client = newUnixClient();
EXPECT_TRUE(client != NULL);
delete client;
}
}

0 comments on commit e54938f

Please sign in to comment.