Mercurial > hg > jgplsrc
view xb.c @ 0:e0bbaa717f41 draft default tip
lol J
author | Jordi Gutiérrez Hermoso <jordigh@octave.org> |
---|---|
date | Mon, 25 Nov 2013 11:56:30 -0500 (2013-11-25) |
parents | |
children |
line wrap: on
line source
/* Copyright 1990-2011, Jsoftware Inc. All rights reserved. */ /* License in license.txt. */ /* */ /* Xenos: Binary Representation */ #include "j.h" #include "x.h" F1(jtstype){RZ(w); R sc(AT(w));} /* 3!:0 w */ /* binary and hex representation formats differ per J version */ /* pre J6.01 */ /* (type, flag, #elements, rank, shape; ravel) */ /* flag is set to 0 for 32 bits and _1 for 64 bits */ /* J6.01 and later */ /* (flag, type, #elements, rank, shape; ravel) */ /* first byte of flag is */ /* e0 32 bits, reversed byte order */ /* e1 32 bits, reversed byte order */ /* e2 64 bits, standard byte order */ /* e3 64 bits, reversed byte order */ /* other pre 601 header */ #define WS(d) (d?8:4) /* word size in bytes */ #define BH(d) (4*WS(d)) /* # non-shape header bytes in A */ #define BF(d,a) ((C*)(a) ) /* flag */ #define BT(d,a) ((C*)(a)+ WS(d)) /* type */ #define BTX(d,pre601,a) ((C*)(a)+ WS(d)*!pre601) #define BN(d,a) ((C*)(a)+2*WS(d)) /* # elements in ravel */ #define BR(d,a) ((C*)(a)+3*WS(d)) /* rank */ #define BS(d,a) ((C*)(a)+4*WS(d)) /* shape */ #define BV(d,a,r) (BS(d,a)+(r)*WS(d)) /* value */ #define BU (SYS & SYS_LILENDIAN ? 1 : 0) static I bsize(B d,B tb,I t,I n,I r,I*s){I c,k,m,w,z; w=WS(d); z=BH(d)+w*r; if(t&BIT){ c=r?s[r-1]:1; m=c?n/c:0; R z+w*m*((c+w*BB-1)/(w*BB)); }else{ k=t&INT+SBT+BOX+XNUM?w:t&RAT?w+w:bp(t); R z+w*((n*k+(tb&&t&LAST0)+w-1)/w); }} /* size in byte of binary representation */ /* n: # of words */ /* v: ptr to result */ /* u: ptr to argument */ /* bv: 1 iff v is little-endian */ /* bu: 1 iff u is little-endian */ /* dv: 1 iff v is 64-bit */ /* du: 1 iff u is 64-bit */ #define MVCS(a,b,c,d) (8*(a)+4*(b)+2*(c)+(d)) static B jtmvw(J jt,C*v,C*u,I n,B bv,B bu,B dv,B du){C c; switch((dv?8:0)+(du?4:0)+(bv?2:0)+bu){ case MVCS(0,0,0,0): MC(v,u,n*4); break; case MVCS(0,0,0,1): DO(n, DO(4, v[3-i]=u[i];); v+=4; u+=4;); break; case MVCS(0,0,1,0): DO(n, DO(4, v[3-i]=u[i];); v+=4; u+=4;); break; case MVCS(0,0,1,1): MC(v,u,n*4); break; case MVCS(0,1,0,0): DO(n, c=0>u[0]?CFF:C0; DO(4, ASSERT(c==u[ i],EVLIMIT); v[i]=u[4+i];); v+=4; u+=8;); break; case MVCS(0,1,0,1): DO(n, c=0>u[7]?CFF:C0; DO(4, ASSERT(c==u[7-i],EVLIMIT); v[i]=u[3-i];); v+=4; u+=8;); break; case MVCS(0,1,1,0): DO(n, c=0>u[0]?CFF:C0; DO(4, ASSERT(c==u[3-i],EVLIMIT); v[i]=u[7-i];); v+=4; u+=8;); break; case MVCS(0,1,1,1): DO(n, c=0>u[7]?CFF:C0; DO(4, ASSERT(c==u[4+i],EVLIMIT); v[i]=u[ i];); v+=4; u+=8;); break; case MVCS(1,0,0,0): DO(n, c=0>u[0]?CFF:C0; DO(4, v[ i]=c; v[4+i]=u[i];); v+=8; u+=4;); break; case MVCS(1,0,0,1): DO(n, c=0>u[3]?CFF:C0; DO(4, v[3-i]=c; v[7-i]=u[i];); v+=8; u+=4;); break; case MVCS(1,0,1,0): DO(n, c=0>u[0]?CFF:C0; DO(4, v[7-i]=c; v[3-i]=u[i];); v+=8; u+=4;); break; case MVCS(1,0,1,1): DO(n, c=0>u[3]?CFF:C0; DO(4, v[4+i]=c; v[ i]=u[i];); v+=8; u+=4;); break; case MVCS(1,1,0,0): MC(v,u,n*8); break; case MVCS(1,1,0,1): DO(n, DO(8, v[7-i]=u[i];); v+=8; u+=8;); break; case MVCS(1,1,1,0): DO(n, DO(8, v[7-i]=u[i];); v+=8; u+=8;); break; case MVCS(1,1,1,1): MC(v,u,n*8); break; } R 1; } /* move n words from u to v */ static C*jtbrephdr(J jt,B b,B d,A w,A y){A q;I f,r; q=(A)AV(y); r=AR(w); f=0; RZ(mvw(BF(d,q),(C*)&f, 1L,b,BU,d,SY_64)); *CAV(y)=d?(b?0xe3:0xe2):(b?0xe1:0xe0); RZ(mvw(BT(d,q),(C*)&AT(w),1L,b,BU,d,SY_64)); RZ(mvw(BN(d,q),(C*)&AN(w),1L,b,BU,d,SY_64)); RZ(mvw(BR(d,q),(C*)&AR(w),1L,b,BU,d,SY_64)); RZ(mvw(BS(d,q),(C*) AS(w),r, b,BU,d,SY_64)); R BV(d,q,r); } static A jtbreps(J jt,B b,B d,A w){A q,y,z,*zv;C*v;I c=0,kk,m,n;P*wp; wp=PAV(w); n=1+sizeof(P)/SZI; kk=WS(d); GA(z,BOX,n,1,0); zv=AAV(z); GA(y,LIT,bsize(d,1,INT,n,AR(w),AS(w)),1,0); v=brephdr(b,d,w,y); RZ(mvw(v,(C*)&c,1L,BU,b,d,SY_64)); /* reserved for flag */ zv[0]=y; m=AN(y); RZ(zv[1]=q=brep(b,d,SPA(wp,a))); RZ(mvw(v+ kk,(C*)&m,1L,b,BU,d,SY_64)); m+=AN(q); RZ(zv[2]=q=brep(b,d,SPA(wp,e))); RZ(mvw(v+2*kk,(C*)&m,1L,b,BU,d,SY_64)); m+=AN(q); RZ(zv[3]=q=brep(b,d,SPA(wp,i))); RZ(mvw(v+3*kk,(C*)&m,1L,b,BU,d,SY_64)); m+=AN(q); RZ(zv[4]=q=brep(b,d,SPA(wp,x))); RZ(mvw(v+4*kk,(C*)&m,1L,b,BU,d,SY_64)); R raze(z); } /* 3!:1 w for sparse w */ A jtbrep(J jt,B b,B d,A w){A q,*wv,y,z,*zv;C*u,*v;I e,k,kk,m,n,t,wd; RZ(w); e=n=AN(w); t=AT(w); u=CAV(w); k=bp(t); kk=WS(d); if(t&SPARSE)R breps(b,d,w); GA(y,LIT,bsize(d,1,t,n,AR(w),AS(w)),1,0); v=brephdr(b,d,w,y); if(t&DIRECT)switch(t){ case SBT: case INT: RZ(mvw(v,u,n, b,BU,d,SY_64)); R y; case FL: RZ(mvw(v,u,n, b,BU,1,1 )); R y; case CMPX: RZ(mvw(v,u,n+n,b,BU,1,1 )); R y; default: if(n){int*u=(int*)v+(n*k-1)/sizeof(int); *u++=0; *u=0;} MC(v,u,n*k); R y; } if(t&RAT){e+=n; GA(q,XNUM,e,1,0); MC(AV(q),u,n*k);} else RZ(q=1<AR(w)?ravel(w):w); m=AN(y); wv=AAV(w); wd=(I)w*ARELATIVE(w); GA(z,BOX,1+e,1,0); zv=AAV(z); *zv++=y; DO(e, RZ(*zv++=q=brep(b,d,WVR(i))); RZ(mvw(v+i*kk,(C*)&m,1L,b,BU,d,SY_64)); m+=AN(q);); R raze(z); } /* b iff reverse the bytes; d iff 64-bit */ static A jthrep(J jt,B b,B d,A w){A y,z;C c,*hex="0123456789abcdef",*u,*v;I n,s[2]; RZ(y=brep(b,d,w)); n=AN(y); s[0]=n/WS(d); s[1]=2*WS(d); GA(z,LIT,2*n,2,s); u=CAV(y); v=CAV(z); DO(n, c=*u++; *v++=hex[(c&0xf0)>>4]; *v++=hex[c&0x0f];); R z; } F1(jtbinrep1){RZ(w); ASSERT(NOUN&AT(w),EVDOMAIN); R brep(BU,SY_64,w);} /* 3!:1 w */ F1(jthexrep1){RZ(w); ASSERT(NOUN&AT(w),EVDOMAIN); R hrep(BU,SY_64,w);} /* 3!:3 w */ F2(jtbinrep2){I k; RZ(a&&w); RE(k=i0(a)); if(10<=k)k-=8; ASSERT(k<=0||k<=3,EVDOMAIN); R brep((B)(k%2),(B)(2<=k),w); } /* a 3!:1 w */ F2(jthexrep2){I k; RZ(a&&w); RE(k=i0(a)); if(10<=k)k-=8; ASSERT(k<=0||k<=3,EVDOMAIN); R hrep((B)(k%2),(B)(2<=k),w); } /* a 3!:3 w */ static S jtunh(J jt,C c){ if('0'<=c&&c<='9')R c-'0'; if('a'<=c&&c<='f')R 10+c-'a'; ASSERT(0,EVDOMAIN); } static F1(jtunhex){A z;C*u;I c,n;UC p,q,*v; RZ(w); c=*(1+AS(w)); ASSERT(c==8||c==16,EVLENGTH); n=AN(w)/2; u=CAV(w); GA(z,LIT,n,1,0); v=UAV(z); DO(n, p=*u++; q=*u++; *v++=16*unh(p)+unh(q);); RE(z); R z; } static A jtunbinr(J jt,B b,B d,B pre601,I m,A w){A y,z;C*u=(C*)w,*v;I e,j,kk,n,p,r,*s,t,*vv; ASSERT(m>BH(d),EVLENGTH); RZ(mvw((C*)&t,BTX(d,pre601,w),1L,BU,b,SY_64,d)); RZ(mvw((C*)&n,BN(d,w),1L,BU,b,SY_64,d)); RZ(mvw((C*)&r,BR(d,w),1L,BU,b,SY_64,d)); kk=WS(d); v=BV(d,w,r); ASSERT(t==B01||t==INT||t==FL||t==CMPX||t==BOX||t==XNUM||t==RAT||t==LIT||t==C2T|| t==SB01||t==SLIT||t==SINT||t==SFL||t==SCMPX||t==SBOX||t==SBT,EVDOMAIN); ASSERT(0<=n,EVDOMAIN); ASSERT(0<=r&&r<=RMAX,EVRANK); p=bsize(d,0,t,n,r,0L); e=t&RAT?n+n:t&SPARSE?1+sizeof(P)/SZI:n; ASSERT(m>=p,EVLENGTH); GA(z,t,n,r,0); s=AS(z); RZ(mvw((C*)s,BS(d,w),r,BU,b,SY_64,d)); j=1; DO(r, ASSERT(0<=s[i],EVLENGTH); if(t&DENSE)j*=s[i];); ASSERT(j==n,EVLENGTH); if(t&BOX+XNUM+RAT+SPARSE){GA(y,INT,e,1,0); vv=AV(y); RZ(mvw((C*)vv,v,e,BU,b,SY_64,d));} if(t&BOX+XNUM+RAT){A*zv=AAV(z);I i,k=0,*iv; RZ(y=indexof(y,y)); iv=AV(y); for(i=0;i<e;++i){ j=vv[i]; ASSERT(0<=j&&j<m,EVINDEX); if(i>iv[i])zv[i]=zv[iv[i]]; else{while(k<e&&j>=vv[k])++k; zv[i]=unbinr(b,d,pre601,k<e?vv[k]-j:m-j,(A)(u+j));} }}else if(t&SPARSE){P*zp=PAV(z); j=vv[1]; ASSERT(0<=j&&j<m,EVINDEX); SPB(zp,a,unbinr(b,d,pre601,vv[2]-j,(A)(u+j))); j=vv[2]; ASSERT(0<=j&&j<m,EVINDEX); SPB(zp,e,unbinr(b,d,pre601,vv[3]-j,(A)(u+j))); j=vv[3]; ASSERT(0<=j&&j<m,EVINDEX); SPB(zp,i,unbinr(b,d,pre601,vv[4]-j,(A)(u+j))); j=vv[4]; ASSERT(0<=j&&j<m,EVINDEX); SPB(zp,x,unbinr(b,d,pre601,m -j,(A)(u+j))); }else if(n)switch(t){ case B01: {B c,*zv=BAV(z); DO(n, c=v[i]; ASSERT(c==C0||c==C1,EVDOMAIN); zv[i]=c;);} break; case SBT: case INT: RZ(mvw(CAV(z),v,n, BU,b,SY_64,d)); break; case FL: RZ(mvw(CAV(z),v,n, BU,b,1, 1)); break; case CMPX: RZ(mvw(CAV(z),v,n+n,BU,b,1, 1)); break; default: e=n*bp(t); ASSERTSYS(e<=AM(z),"unbinr"); MC(CAV(z),v,e); } RE(z); R z; } /* b iff reverse the bytes; d iff argument is 64-bits */ F1(jtunbin){A q;B b,d;C*v;I c,i,k,m,n,r,t; RZ(w); ASSERT(LIT&AT(w),EVDOMAIN); if(2==AR(w))RZ(w=unhex(w)); ASSERT(1==AR(w),EVRANK); m=AN(w); ASSERT(m>=8,EVLENGTH); q=(A)AV(w); switch(*CAV(w)){ case (C)0xe0: R unbinr(0,0,0,m,q); case (C)0xe1: R unbinr(1,0,0,m,q); case (C)0xe2: R unbinr(0,1,0,m,q); case (C)0xe3: R unbinr(1,1,0,m,q); } /* code to handle pre 601 headers */ d=1; v=8+CAV(w); DO(8, if(CFF!=*v++){d=0; break;}); /* detect 64-bit */ ASSERT(m>=1+BH(d),EVLENGTH); b=0; if(!mvw((C*)&t,BTX(d,1,q),1L,BU,0,SY_64,d)){RESETERR; b=1;} /* detect reverse bytes */ if(!mvw((C*)&n,BN(d,q),1L,BU,0,SY_64,d)){RESETERR; b=1;} if(!mvw((C*)&r,BR(d,q),1L,BU,0,SY_64,d)){RESETERR; b=1;} b=b||!(t&NOUN&&0<=n&&0<=r&&(r||1==n)&&m>=BH(d)+r*WS(d)); if(t&DENSE){ v=BS(d,q); c=1; for(i=0;!b&&i<r;++i){ if(!mvw((C*)&k,v,1L,BU,0,SY_64,d)){RESETERR; b=1;} v+=WS(d); c*=k; if(!(0<=k&&(!n||0<=c&&k<=n&&c<=n)))b=1; } b=b||n!=c; } R unbinr(b,d,1,m,q); } /* 3!:2 w, inverse for binrep/hexrep */ F2(jtic2){A z;I j,m,n,p,*v,*x,zt;I4*y;S*s;U short*u; RZ(a&&w); ASSERT(1>=AR(w),EVRANK); n=AN(w); RE(j=i0(a)); ASSERT(ABS(j)<=2+SY_64,EVDOMAIN); p=3==j||-3==j?8:2==j||-2==j?4:2; if(0<j){m=n*p; zt=LIT; if(!(INT&AT(w)))RZ(w=cvt(INT,w));} else {m=n/p; zt=INT; ASSERT(!n||LIT&AT(w),EVDOMAIN); ASSERT(!(n%p),EVLENGTH);} GA(z,zt,m,1,0); v=AV(z); x=AV(w); switch(j){ default: ASSERT(0,EVDOMAIN); case -3: ICPY(v,x,m); R z; case 3: MC(v,x,m); R z; case -2: y=(I4*)x; DO(m, *v++= *y++;); R z; case 2: y=(I4*)v; DO(n, *y++=(I4)*x++;); R z; case -1: s=(S*)x; DO(m, *v++= *s++;); R z; case 1: s=(S*)v; DO(n, *s++=(S) *x++;); R z; case 0: u=(U short*)x; DO(m, *v++= *u++;); R z; }} F2(jtfc2){A z;D*x,*v;I j,m,n,p,zt;float*s; RZ(a&&w); ASSERT(1>=AR(w),EVRANK); n=AN(w); RE(j=i0(a)); p=2==j||-2==j?sizeof(D):sizeof(float); if(0<j){m=n*p; zt=LIT; if(!(FL&AT(w)))RZ(w=cvt(FL,w));} else {m=n/p; zt=FL; ASSERT(!n||LIT&AT(w),EVDOMAIN); ASSERT(!(n%p),EVLENGTH);} GA(z,zt,m,1,0); v=DAV(z); x=DAV(w); switch(j){ default: ASSERT(0,EVDOMAIN); case -2: MC(v,x,n); R z; case 2: MC(v,x,m); R z; case -1: s=(float*)x; DO(m, *v++= *s++;); R z; case 1: s=(float*)v; DO(n, *s++=(float)*x++;); R z; }} static B jtisnanq(J jt,A w){A q,*u,x,x1,*xv,y,*yv;D*v;I m,n,t,top,yd; RZ(w); GA(x,INT,BOX&AT(w)?2*AN(w):1,1,0); xv=AAV(x); *xv=w; top=1; while(top){ --top; y=xv[top]; n=AN(y); t=AT(y); if(t&FL+CMPX){v=DAV(y); DO(t&CMPX?n+n:n, if(_isnan(*v++))R 1;);} else if(t&BOX){ m=top+n; yv=AAV(y); yd=(I)y*ARELATIVE(y); if(m>AN(y)){GA(x1,INT,2*m,1,0); u=AAV(x1); ICPY(u,xv,top); fa(x); x=x1; xv=u;} u=xv+top; DO(n, q=YVR(i); if(AT(q)&FL+CMPX+BOX)*u++=q;); top=u-xv; }} R 0; } F1(jtisnan){A*wv,z;B*u;D*v;I n,t,wd; RZ(w); n=AN(w); t=AT(w); ASSERT(t&DENSE,EVNONCE); GA(z,B01,n,AR(w),AS(w)); u=BAV(z); if (t&FL ){v=DAV(w); DO(n, *u++=_isnan(*v++););} else if(t&CMPX){v=DAV(w); DO(n, *u++=_isnan(*v)||_isnan(*(v+1)); v+=2;);} else if(t&BOX ){wv=AAV(w); wd=(I)w*ARELATIVE(w); DO(n, *u++=isnanq(WVR(i));); RE(0);} else memset(u,C0,n); R z; } F1(jtbit1){A z;B*wv;BT*zv;I c,i,j,n,p,q,r,*s;UI x,y; RZ(w); if(!(B01&AT(w)))RZ(w=cvt(B01,w)); n=AN(w); r=AR(w); wv=BAV(w); s=AS(w); GA(z,BIT,n,AR(w),AS(w)); zv=(BT*)AV(z); if(!r)*zv=*wv?'\200':0; else if(n){ c=8*SZI; i=s[r-1]; r= p=n/i; q=i/c; r=i-c*q; for(i=0;i<p;++i){ for(j=0;j<q;++j){ x=0; y=1+(UI)IMAX; DO(c, if(*wv++)x^=y; y>>=1;); *zv++=x; } x=0; y=1+(UI)IMAX; DO(r, if(*wv++)x^=y; y>>=1;); *zv++=x; } } R z; } /* convert byte booleans to bit booleans */ F2(jtbit2){ ASSERT(0,EVNONCE); } /* convert byte booleans to bit booleans */