KDB_API K K_DECL testSerial(K a) { K k = kpn("000001.SZ", 9); //K s = b9(-1, k); K s = b9(1, k); for (G* i = kG(s); i < kG(s) + s->n; ++i) { std::cout << std::setiosflags(std::ios::uppercase) << std::setfill('0') << std::setw(2) << std::hex << static_cast<int>(*i) << ','; } std::cout << std::endl; # if KX_HAS_OKX std::cout << "okx = " << okx(s) << std::endl; # endif if (a->g) { r0(s); return k; } else { r0(k); return s; } }
std::vector<long long> q::qList2Dec(K data) throw(std::string) { if (data == K_NIL) { throw std::string("nil decimal list"); } else if (data->t <= 0) { throw std::string("not a decimal list"); } assert(data->n >= 0); std::vector<long long> result(static_cast<std::size_t>(data->n), 0L); switch (data->t) { case KB: { struct Converter { long long operator()(G x) const { return x ? 1 : 0; } }; std::transform(kG(data), kG(data) + data->n, result.begin(), Converter()); break; } case KG: std::copy(kG(data), kG(data) + data->n, result.begin()); break; case KH: std::copy(kH(data), kH(data) + data->n, result.begin()); break; case KI: std::copy(kI(data), kI(data) + data->n, result.begin()); break; case KJ: std::copy(kJ(data), kJ(data) + data->n, result.begin()); break; default: throw std::string("not a decimal list"); } return result; }
int main(int argc,char*argv[]) { K flip,result,columnNames,columnData; int row,col,nCols,nRows; int handle=khpu("localhost",1234,"user:password"); if(handle<0) exit(1); result = k(handle,"`asc",(K)0); std::string str = "([]a:til 10;b:reverse til 10;c:10#01010101010b;d:`a)"; result = k(handle,str.c_str(),(K)0); if(!result) printf("Network Error\n"),perror("Network"),exit(1); if(result->t==-128) printf("Server Error %s\n",result->s),kclose(handle),exit(1); // kclose(handle); if(result->t!=99&&result->t!=98) { printf("type %d\n",result->t); r0(result); exit(1); } flip = ktd(result); // if keyed table, unkey it. ktd decrements ref count of arg. // table (flip) is column names!list of columns (data) columnNames = kK(flip->k)[0]; columnData = kK(flip->k)[1]; nCols = columnNames->n; nRows = kK(columnData)[0]->n; for(row=0;row<nRows;row++) { if(0==row) { for(col=0;col<nCols;col++) { if(col>0)printf(","); printf("%s",kS(columnNames)[col]); } printf("\n"); } for(col=0;col<nCols;col++) { K obj=kK(columnData)[col]; if(col>0)printf(","); switch(obj->t) { case(1):{printf("%d",kG(obj)[row]);}break; case(4):{printf("%d",kG(obj)[row]);}break; case(5):{printf("%d",kH(obj)[row]);}break; case(6):{printf("%d",kI(obj)[row]);}break; case(7):{printf("%lld",kJ(obj)[row]);}break; case(8):{printf("%f",kE(obj)[row]);}break; case(9):{printf("%f",kF(obj)[row]);}break; case(11):{printf("%s",kS(obj)[row]);}break; default:{printf("unknown type");}break; } } printf("\n"); } r0(flip); return 0; }
//create ,pass and recieve a simple table. int eg7() { K cc,d,e,v,tab; K flip,result,columnNames,columnData; int row,col,nCols,nRows; cc=ktn(KS,2);kS(cc)[0]=ss("pid");kS(cc)[1]=ss("uid"); d=ktn(KS,3);kS(d)[0]=ss("ibm");kS(d)[1]=ss("gte");kS(d)[2]=ss("kvm"); e=ktn(KI,3);kI(e)[0]=1;kI(e)[1]=2;kI(e)[2]=3; v=knk(2,d,e); tab=xT(xD(cc,v)); flip=k(c,"{[x]a:update t:.z.t,y:.z.d from x;.tst.t:a;a}",tab,(K)0); //Turn into a dictionary. flip->k [transpose?] //Display table. [Borrowed from code.kx.com: // https://code.kx.com/trac/attachment/wiki/Cookbook/InterfacingWithC/csv.c ] columnNames=kK(flip->k)[0]; columnData=kK(flip->k)[1]; nCols=columnNames->n; nRows=kK(columnData)[0]->n; for(row=0;row<nRows;row++) { if(0==row) { for(col=0;col<nCols;col++) { if(col>0)printf(","); printf("%s",kS(columnNames)[col]); } printf("\n"); } for(col=0;col<nCols;col++) { K obj=kK(columnData)[col]; if(col>0)printf(","); switch(obj->t) { case(1):{printf("%d",kG(obj)[row]);}break; case(4):{printf("%d",kG(obj)[row]);}break; case(5):{printf("%d",kH(obj)[row]);}break; case(6):{printf("%d",kI(obj)[row]);}break; case(7):{printf("%lld",kJ(obj)[row]);}break; case(8):{printf("%f",kE(obj)[row]);}break; case(9):{printf("%f",kF(obj)[row]);}break; case(11):{printf("%s",kS(obj)[row]);}break; case(19):{printf("%i",kI(obj)[row]);}break; case(14):{printf("%i",kI(obj)[row]);}break; default:{printf("unknown type");}break; } } printf("\n"); } return 1; }
// Data processor (executed within q's main thread) K invokeCallback(I socket) { static_assert(sizeof(::SOCKET) == sizeof(I), "SOCKET vs I: type mismatch!"); ::SOCKET sock = socket; assert(sock != INVALID_SOCKET); // Receive (WQID, len, serialized_K) from subscription thread # define RECV_CHECK(expectedSize, errorMsg) \ if (recvd != (expectedSize)) { \ std::cerr << "<recv> " << (errorMsg) << ": " << recvd << " < " << (expectedSize) << std::endl; \ return K_NIL; \ } ::WQID qid = 0; int recvd = ::recv(sock, reinterpret_cast<char*>(&qid), sizeof(::WQID), 0); RECV_CHECK(sizeof(::WQID), "WQID incomplete"); std::size_t len = 0; recvd = ::recv(sock, reinterpret_cast<char*>(&len), sizeof(len), 0); RECV_CHECK(sizeof(len), "size incomplete"); if (len > static_cast<std::size_t>(std::numeric_limits<int>::max())) { std::cerr << "<recv> serialized data (" << len << ") > 2G" << std::endl; return K_NIL; } q::K_ptr serialized(ktn(KB, len)); std::memset(kG(serialized.get()), 0, len); recvd = ::recv(sock, reinterpret_cast<char*>(kG(serialized.get())), len, 0); RECV_CHECK(len, "data incomplete"); # undef RECV_CHECK // Deserialize K object # if KX_USE_OKX //@ref https://groups.google.com/forum/#!topic/personal-kdbplus/pjsugT7590A if (!okx(serialized.get())) { std::cerr << "<recv> bad data: [" << util::hexBytes(kG(serialized.get()), static_cast<std::size_t>(serialized->n)) << ']' << std::endl; return K_NIL; } # endif q::K_ptr result(d9(serialized.get())); // Identify the origial query and callback std::string const callback = REGISTRY[qid]; if (callback.empty()) { std::cerr << "unknown WQID: " << qid << std::endl; return K_NIL; } static_assert(std::is_same<::WQID, J>::value, "WQID data type mismatch"); q::K_ptr output(k(0, const_cast<S>(callback.c_str()), kj(qid), result.release(), K_NIL)); if (output->t == -128) { std::cerr << "<q> '" << output->s << std::endl; } return output.release(); }
K recieve_data(I x) { static char buf[BUFFER_SIZE]; read_bytes(sizeof(int), &buf); int tnamesize = 0; memcpy(&tnamesize, buf, sizeof(int)); read_bytes(tnamesize, &buf); buf[tnamesize] = '\0'; K tname = ks(buf); read_bytes(sizeof(J), &buf); J size = 0; memcpy(&size, buf, sizeof(J)); read_bytes(size, &buf); K bytes = ktn(KG, size); memcpy(kG(bytes), &buf, (size_t) size); K result = k(0, ".u.upd", tname, d9(bytes), (K) 0); r0(bytes); if (result != 0) { r0(result); } return (K) 0; }
int mlput(K x,K y){ int fstype=y->t,fsint=y->i,i=0,funcerr=0; K z; char b[2]={0,0}; mlint64 j={0,0}; //printf("%s:%d,%d\n","mlput",x->t,x->n); switch(x->t){ case -KB: case -KG: case -KC:b[0]=x->g;R MLPutString(ml_lp,b); case -KH:R MLPutInteger16(ml_lp,x->h); case -KI:R MLPutInteger32(ml_lp,x->i); case -KJ:*(J*)&j=x->j;R MLPutInteger64(ml_lp,j); case -KE:R MLPutReal32(ml_lp,x->e); case -KF:R MLPutReal64(ml_lp,x->f); case -KS:R MLPutSymbol(ml_lp,x->s); case KB: case KG: case KC:R MLPutByteString(ml_lp,kG(x),x->n); case KH:R MLPutInteger16List(ml_lp,kH(x),x->n); case KI:R MLPutInteger32List(ml_lp,kI(x),x->n); case KJ:R MLPutInteger64List(ml_lp,(mlint64*)kJ(x),x->n); case KE:R MLPutReal32List(ml_lp,kE(x),x->n); case KF:R MLPutReal64List(ml_lp,kF(x),x->n); case KS:if(!MLPutFunction(ml_lp,"List",x->n)){ R 0; }else{ for(i=0;i<x->n;i++)if(!MLPutSymbol(ml_lp,kS(x)[i]))R 0; } break; case 0: if(0==x->n){ R MLPutFunction(ml_lp, "List",0); }else if((3==x->n)&&(fstype==kK(x)[0]->t)){ z=kK(x)[2]; if(!MLPutFunction(ml_lp,kK(x)[1]->s,z->n)){R 0;}else{ switch(z->t){ case 0:for(i=0;i<z->n;i++)if(!mlput(kK(z)[i],y))R 0;break; case KH:for(i=0;i<z->n;i++)if(!MLPutInteger16(ml_lp,kH(z)[i]))R 0;break; case KI:for(i=0;i<z->n;i++)if(!MLPutInteger32(ml_lp,kI(z)[i]))R 0;break; case KJ:for(i=0;i<z->n;i++){*(J*)&j=kJ(z)[i];if(!MLPutInteger64(ml_lp,j))R 0;}break; case KE:for(i=0;i<z->n;i++)if(!MLPutReal32(ml_lp,kE(z)[i]))R 0;break; case KF:for(i=0;i<z->n;i++)if(!MLPutReal64(ml_lp,kF(z)[i]))R 0;break; case KS:for(i=0;i<z->n;i++)if(!MLPutSymbol(ml_lp,kS(z)[i]))R 0;break; case KC:for(i=0;i<z->n;i++){b[0]=kC(z)[i];if(!MLPutString(ml_lp,b))R 0;}break; default:break; } } }else{ if(!MLPutFunction(ml_lp,"List",x->n)){R 0;}else{for(i=0;i<x->n;i++)if(!mlput(kK(x)[i],y)){MLPutSymbol(ml_lp,"ParaErr");funcerr=1;}if(funcerr)R 0;} } break; default: R 0; } R 1; }
int ei_x_encode_same_list_byte(ei_x_buff* types, ei_x_buff* values, const char* t, K r, QOpts* opts) { EI(ei_x_encode_tuple_header(types, 2)); EI(ei_x_encode_atom(types, "list")); EI(ei_x_encode_atom(types, t)); if(r->n == 0) { EI(ei_x_encode_empty_list(values)); } else { EI(ei_x_encode_string_len(values, (const char*)kG(r), r->n)); } return 0; }
K hash(K x,K y){ int lenx,leny,i; lenx=x->n; leny=y->n; char message[lenx+1]; char hashfunction[leny+1]; if(10==(x->t)){ for(i=0;i<lenx;i++){ message[i]=kC(x)[i]; } message[lenx]=0; } if(10==(y->t)){ for(i=0;i<leny;i++){ hashfunction[i]=kC(y)[i]; } hashfunction[leny]=0; } int bytelength; unsigned char* (*foo)(const unsigned char*, size_t, unsigned char*); if(strcmp("sha1",hashfunction)==0){ bytelength=SHA_DIGEST_LENGTH; foo=&SHA1; } else if(strcmp("sha224",hashfunction)==0){ bytelength=SHA224_DIGEST_LENGTH; foo=&SHA224; } else if(strcmp("sha256",hashfunction)==0){ bytelength=SHA256_DIGEST_LENGTH; foo=&SHA256; } else if(strcmp("sha384",hashfunction)==0){ bytelength=SHA384_DIGEST_LENGTH; foo=&SHA384; } else if(strcmp("sha512",hashfunction)==0){ bytelength=SHA512_DIGEST_LENGTH; foo=&SHA512; } else if(strcmp("md5",hashfunction)==0){ bytelength=MD5_DIGEST_LENGTH; foo=&MD5; } else{ krr("Please choose a supported hash function"); return (K)0; } unsigned char result[bytelength]; foo((unsigned char*) message, strlen(message), result); K output=ktn(KG,bytelength); for(i=0;i<bytelength;i++){ kG(output)[i]=result[i]; } return output; }
K hmac(K x,K y,K f) { int lenx,leny,lenf,i; lenx=x->n; leny=y->n; lenf=f->n; unsigned char secret[lenx+1]; unsigned char message[leny+1]; unsigned char hashfunction[lenf+1]; // copy x and y into regular cstrings if(10==(x->t)){ for(i=0;i<lenx;i++){ secret[i] =kC(x)[i]; } secret[lenx]=0; } if(10==(y->t)){ for(i=0;i<leny;i++){ message[i] =kC(y)[i]; } message[leny]=0; } if(10==(f->t)){ for(i=0;i<lenf;i++){ hashfunction[i]=kC(f)[i]; } hashfunction[lenf]=0; } unsigned int bytelength; const EVP_MD* (*evp_fn)(void); if(strcmp("sha1",hashfunction)==0){ bytelength=SHA_DIGEST_LENGTH; evp_fn=&EVP_sha1; } else if(strcmp("sha224",hashfunction)==0){ bytelength=SHA224_DIGEST_LENGTH; evp_fn=&EVP_sha224; } else if(strcmp("sha256",hashfunction)==0){ bytelength=SHA256_DIGEST_LENGTH; evp_fn=&EVP_sha256; } else if(strcmp("sha384",hashfunction)==0){ bytelength=SHA384_DIGEST_LENGTH; evp_fn=&EVP_sha384; } else if(strcmp("sha512",hashfunction)==0){ bytelength=SHA512_DIGEST_LENGTH; evp_fn=&EVP_sha512; } else if(strcmp("md5",hashfunction)==0){ bytelength=MD5_DIGEST_LENGTH; evp_fn=&EVP_md5; } else{ krr("Please choose a supported hash function"); return (K)0; } unsigned char* result; result=calloc(bytelength,sizeof(char)); HMAC(evp_fn(),secret,strlen(secret),message,strlen(message),result,NULL); K output=ktn(KG,bytelength); for(i=0;i<bytelength;i++){ kG(output)[i]=result[i]; } free(result); return output; }
K pbkdf2(K qpassword,K qsalt,K qiterations, K qdklen){ int iterations,dklen,passlen,saltlen,i,retv; passlen=qpassword->n; saltlen=qsalt->n; char password[passlen]; unsigned char salt[saltlen]; iterations=qiterations->i; dklen=qdklen->i; unsigned char result[dklen]; if(10==(qpassword->t)){ for(i=0;i<passlen;i++){ password[i]=kC(qpassword)[i]; } password[passlen]=0; } if(4==(qsalt->t)){ for(i=0;i<saltlen;i++){ salt[i]=kG(qsalt)[i]; } } retv=PKCS5_PBKDF2_HMAC_SHA1(password,strlen(password),salt,sizeof(salt),iterations,dklen,result); if(retv==0){ krr("PKCS5_PBKDF2_HMAC_SHA1 failed"); return (K)0; } K output=ktn(KG,dklen); for(i=0;i<dklen;i++){ kG(output)[i]=result[i]; } return output; }
static int dec(lua_State* L,K x) { if(xt >= 0) { switch(xt) { case 0: LD(kK,dec); break; case 1: LD(kG,lua_pushboolean);break; //case 2: /* guid */ case 4: LD(kG,lua_pushinteger);break; case 5: LD(kH,lua_pushinteger);break; case 6: LD(kI,lua_pushinteger);break; case 7: LD(kJ,lua_pushnumber);break; case 8: LD(kE,lua_pushinteger);break; case 9: LD(kF,lua_pushinteger);break; case 10:lua_pushlstring(L,kG(x),xn);break; case 11:LD(kS,lua_pushstring);break; //case 12: /* timestamp */ //case 13: /* month */ //case 14: /* date */ //case 15: /* datetime */ //case 16: /* timespan */ //case 17: /* minute */ //case 18: /* second */ //case 19: /* time */ //case 98: /* dict */ //case 99: /* table */ default:luaL_error(L, "unsupported array %d (nyi?)", xt);R 0; }; R 1; /* create table */ } switch(xt) { case -1: lua_pushboolean(L,x->g); break; //case -2: /* scalar guid */ case -4: lua_pushinteger(L,x->g); break; case -5: lua_pushinteger(L,x->h); break; case -6: lua_pushinteger(L,x->i); break; case -7: lua_pushnumber(L,x->j); break; case -8: lua_pushnumber(L,x->e); break; case -9: lua_pushnumber(L,x->f); break; case -10: lua_pushlstring(L,&x->g,1); break; case -11: lua_pushstring(L,x->s); break; case -128:luaL_error(L,"K: %s",kS(x));R 0; default:luaL_error(L, "unsupported scalar %d (nyi?)", xt);R 0; }; R 1; }
// Result publisher (executed within subscription thread) bool publishResult(Event const& event, SockPair::SOCKET_ptr const* socks) { // Convert Wind event into K object std::string error; q::K_ptr data; if (event.ErrCode != WQERR_OK) { std::cerr << "<WQ> subscription error: " << util::error2Text(event.ErrCode) << std::endl; return false; } try { data.reset(event.parse()); } catch (std::string const& ex) { std::cerr << "<WQ> response format error: " << ex << std::endl; return false; } // Serialize K object into bytes static_assert(std::is_same<::WQID, J>::value, "WQID data type mismatch"); # if KX_USE_OKX q::K_ptr serialized(b9(1, data.get())); # else q::K_ptr serialized(b9(-1, data.get())); # endif assert((serialized->t == KG) && (serialized->n > 0)); // Send tuple (WQID, len, serialized_K) over to the main thread # define SEND_CHECK(expectedSize, errorMsg) \ if (sent != (expectedSize)) { \ std::cerr << "<send> " << (errorMsg) << ": " << sent << " < " << (expectedSize) << std::endl; \ return false; \ } int sent = ::send(*socks[SERVER], reinterpret_cast<char const*>(&event.RequestID), sizeof(::WQID), 0); SEND_CHECK(sizeof(::WQID), "WQID incomplete"); std::size_t const len = static_cast<std::size_t>(serialized->n); if (len > static_cast<std::size_t>(std::numeric_limits<int>::max())) { std::cerr << "<send> serialized data (" << len << ") > 2G" << std::endl; return false; } sent = ::send(*socks[SERVER], reinterpret_cast<char const*>(&len), sizeof(len), 0); SEND_CHECK(sizeof(len), "size incomplete"); sent = ::send(*socks[SERVER], reinterpret_cast<char const*>(kG(serialized.get())), len, 0); SEND_CHECK(serialized->n, "data incomplete"); # undef SEND_CHECK return true; }
K qrand(K x){ int saltlength,i; saltlength=x->i; unsigned char salt[saltlength]; if (RAND_bytes(salt,saltlength)==0){ krr("Random number generation failure"); return (K)0; } K output=ktn(KG,saltlength); for(i=0;i<saltlength;i++){ kG(output)[i]=salt[i]; } return output; }
double *getklist(K p) { double *r; r=g_malloc(p->n*sizeof(double)); switch(p->t){ case 1 : case 4 : DO(p->n,r[i]=kG(p)[i]);break; case 5 : DO(p->n,r[i]=kH(p)[i]);break; case 6 : case 13 : case 14 : case 17 : case 18 : DO(p->n,r[i]=kI(p)[i]);break; case 7 : case 16 : DO(p->n,r[i]=kJ(p)[i]);break; case 8 : DO(p->n,r[i]=kE(p)[i]);break; case 9 : case 15 : DO(p->n,r[i]=kF(p)[i]);break; case 10 : DO(p->n,r[i]=kC(p)[i]);break; default : g_free(r);return (double *)kerr("invalid numeric type"); } return r; }
void SendToKDB(char *table, K data) { static char buf[BUFFER_SIZE]; K bytes = b9(-1, data); r0(data); int len = strlen(table); // write the table name into the buffer as a string first. memcpy(buf, (char *) &len, sizeof(int)); memcpy(&buf[sizeof(int)], table, len); // copy the data into the buffer to be sent. memcpy(&buf[sizeof(int) + len], (char *) &bytes->n, sizeof(J)); memcpy(&buf[sizeof(int) + len + sizeof(J)], kG(bytes), (size_t) bytes->n); send(sockets[0], buf, (int) (sizeof(int) + len + sizeof(J) + bytes->n), 0); r0(bytes); }
K hmac_sha256_k (K x, K y){ TC(x, KC); TC(y, KC); int lenmsg, lenkey, i; lenmsg=x->n; lenkey=y->n; unsigned char message[lenmsg+1], key[lenkey+1]; for(i=0;i<lenmsg;i++){ message[i]=kC(x)[i]; } for(i=0;i<lenkey;i++){ key[i]=kC(y)[i]; } int bytelength=SHA256_DIGEST_LENGTH; unsigned char result[bytelength]; hmac_sha256(message, lenmsg, key, lenkey, result); K output=ktn(KG, bytelength); for(i=0;i<bytelength;i++){ kG(output)[i]=result[i]; } return output; }
extern "C" K qHMAC512(K data, K key) { unsigned int SHA512_DIGEST_LENGTH=64; unsigned char md[SHA512_DIGEST_LENGTH]; unsigned char result[SHA512_DIGEST_LENGTH]; unsigned int len=0; K ret = ktn(KG,SHA512_DIGEST_LENGTH); HMAC_CTX ctx; HMAC_CTX_init(&ctx); HMAC_Init_ex(&ctx, key->s, strlen(key->s), EVP_sha512(), NULL); HMAC_Update(&ctx, (unsigned char*)(data->s), strlen(data->s)); HMAC_Final(&ctx, result, &len); HMAC_CTX_cleanup(&ctx); for(int i=0; i < len ; i++) kG(ret)[i]=result[i]; return (ret); }
ZK gb(D d,H j,I t){H c=ct[t],g=c?c:-2,m=512;K x=ktn(c?KC:KG,m),y=ktn(xt,0);SQLULEN n=0;SQLRETURN r;while(1){r=SQLGetData(d,j,g,kG(x),xn=m,&n);if(SQL_SUCCEEDED(r))xn=n==SQL_NULL_DATA?0:n==SQL_NO_TOTAL||n>xn?xn:n,xn-=xn&&c&&!kG(x)[xn-1],jv(&y,x);else/*if(r==SQL_NO_DATA)*/break;}r0(x);R y;}
K threads_init(K x) { unsigned char bytes[]={0x01,0x00,0x00,0x00,0x0a,0x00,0x00,0x00,0x65,0x13}; K s=ktn(KG,sizeof(bytes));memcpy(kG(s),bytes,sizeof(bytes)); if(!okx(s))R krr("serialization");value_fn=d9(s); if(!(threadpool=threadpool_create(NUMTHREADS,QUEUESIZE,0)))R krr("threadpool"); if(pipe(mainloop_pipe)==-1)R krr("pipe");sd1(mainloop_pipe[0],threads_q_callback);R(K)0;}
static int enc(K*k,lua_State *L) { switch (lua_type(L, -1)) { case LUA_TSTRING: { size_t len;const char *str = lua_tolstring(L,-1,&len);(*k)=kpn(str,len);R 1;} break; case LUA_TNUMBER: { F num = lua_tonumber(L,-1);(*k) = (num==floor(num))?kj((J)num):kf(num);R 1;} break; case LUA_TBOOLEAN: { (*k)=kb( lua_toboolean(L,-1) );R 1;} break; case LUA_TNIL: { (*k)=ktn(0,0);R 1;} break; case LUA_TTABLE: { double p; int max = 0; int items = 0; int t_integer = 0, t_number = 0, t_boolean = 0, t_other= 0; lua_pushnil(L); /* table, startkey */ while (lua_next(L, -2) != 0) { items++; /* table, key, value */ switch (lua_type(L, -1)) { case LUA_TNUMBER: t_number++; p = lua_tonumber(L,-1); t_integer += (floor(p) == p); break; case LUA_TBOOLEAN: t_boolean++; break; default: t_other++; break; /* or anything else */ }; if (lua_type(L, -2) == LUA_TNUMBER && (p = lua_tonumber(L, -2))) { /* Integer >= 1 ? */ if (floor(p) == p && p >= 1) { if (p > max) max = p; lua_pop(L, 1); continue; } } /* Must not be an array (non integer key) */ for (lua_pop(L,1); lua_next(L, -2) != 0; lua_pop(L,1)) ++items; max = 0; break; } lua_pushnil(L); if (max != items) { /* build K dictionary */ K keys = ktn(KS,items); K values = ktn(0,items); int n = 0; /* table, startkey */ while (lua_next(L, -2) != 0) { kS(keys)[n] = ss(lua_tostring(L, -2)); if(!enc(kK(values)+n,L))R 0; lua_pop(L,1); ++n; } *k = xD(keys,values); R 1; } /* build K list */ if(t_other || ((!!t_boolean)+(!!t_number)) > 1) { K a = ktn(0,items); while (lua_next(L, -2) != 0) { p = lua_tonumber(L, -2); if(!enc(kK(a)+LI(p),L))R 0; lua_pop(L, 1); } *k = a; R 1; } if(t_boolean) { K a = ktn(KB,items); while (lua_next(L, -2) != 0) { p = lua_tonumber(L, -2); kG(a)[LI(p)] = lua_toboolean(L,-1); lua_pop(L, 1); } *k = a; R 1; } if(t_number == t_integer) { K a = ktn(KJ,items); while (lua_next(L, -2) != 0) { p = lua_tonumber(L, -2); kJ(a)[LI(p)] = (int)floor(lua_tonumber(L,-1)); lua_pop(L, 1); } *k = a; R 1; } if(t_number) { K a = ktn(KF,items); while (lua_next(L, -2) != 0) { p = lua_tonumber(L, -2); kF(a)[LI(p)] = lua_tonumber(L,-1); lua_pop(L, 1); } *k = a; R 1; } *k = ktn(0,0); R 1; }; break; default: luaL_error(L, "Cannot serialise %s: %s", lua_typename(L, lua_type(L, -1)), "can't serialize type"); R 0; }; }
K py(K f, K x, K lib) { int argc; char **argv; char *error, *p, *buf; void *h; K r; #ifdef PY3K char *oldloc; #endif h = dlopen((const char *)kG(lib), RTLD_NOW|RTLD_GLOBAL); if (!h) R krr(dlerror()); dlerror(); /* Clear any existing error */ Py_Main = dlsym(h, "Py_Main"); P((error = dlerror()),krr(error)); P(xt, krr("argv type")); I m = 0; /* buf length */ DO(xn, K y; P((y = kK(x)[i])->t!=KC, krr("arg type")); m += y->n+1); argc = xn+1; argv = malloc(sizeof(char*) * argc); P(!argv, krr("memory")); buf = malloc(m); P(!buf,(free(argv),krr("memory"))); argv[0] = f->s; p = buf; DO(xn, K y = kK(x)[i]; argv[i+1] = memcpy(p, kG(y), y->n); p += y->n; *p++ = '\0'); #ifdef PY3K dlerror(); /* Clear any existing error */ #if PY3K < 35 c2w = dlsym(h, "_Py_char2wchar"); #else c2w = dlsym(h, "Py_DecodeLocale"); #endif P((error = dlerror()),krr(error)); dlerror(); /* Clear any existing error */ #if PY3K < 34 PyMem_Free = dlsym(h, "PyMem_Free"); #else PyMem_Free = dlsym(h, "PyMem_RawFree"); #endif P((error = dlerror()),krr(error)); wchar_t **wargv = malloc(sizeof(wchar_t*)*(argc+1)); wchar_t **wargv_copy = malloc(sizeof(wchar_t*)*(argc+1)); oldloc = strdup(setlocale(LC_ALL, NULL)); setlocale(LC_ALL, ""); DO(argc,P(!(wargv[i]=c2w(argv[i],NULL)),krr("decode"))); memcpy(wargv_copy, wargv, sizeof(wchar_t*)*argc); setlocale(LC_ALL, oldloc); free(oldloc); wargv[argc] = wargv_copy[argc] = NULL; r = ki(Py_Main(argc, wargv)); DO(argc,PyMem_Free(wargv_copy[i])); free(wargv_copy); free(wargv); #else r = ki(Py_Main(argc, argv)); #endif dlclose(h); free(argv); free(buf); R r; }
Z K1(zmsgpopC){PC(x);if(zmsg_size(VSK(x))==0)R krr("empty");zframe_t* f=zmsg_pop(VSK(x));size_t msz=zframe_size(f);K r=ktn(KC,(J)msz);memcpy(kG(r),zframe_data(f),msz);R r;}