pax_global_header00006660000000000000000000000064131672055410014516gustar00rootroot0000000000000052 comment=2ff25a380adae17b28f627b7ee6f55657429ecba jnr-ffi-jnr-ffi-2.1.7/000077500000000000000000000000001316720554100144115ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/.gitignore000066400000000000000000000001721316720554100164010ustar00rootroot00000000000000*.orig$ *.rej$ *.class$ *~ .idea *.iml *.iws *.ipr nbproject/private build dist target lib/nblibraries-private.properties jnr-ffi-jnr-ffi-2.1.7/.mvn/000077500000000000000000000000001316720554100152675ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/.mvn/wrapper/000077500000000000000000000000001316720554100167475ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/.mvn/wrapper/maven-wrapper.jar000066400000000000000000001405361316720554100222420ustar00rootroot00000000000000PK F3org/apache/maven/wrapper/BootstrapMainStarter.classVYwV.-G$$ఙ%`gR M )B &tX K$}kyqr)}oEEhvpl99;}3sGo<1`?˸ # IS`2˸" A5s 2^ %!z9MFFFBA2r 8XڼX n( CF!Sl-e8;fq+:ɧJ /k$ՌY{U(yaH$-{!l' "7lXveK/n\v=wĖat.yC[f.$R #n%Pi˜͋x*gfe|74IZZ0\9`r7qe&Y8MOİ.'""[9:<&*:Yb-]nO g Kj%l{dvEH\׽ i5 nM0li9=d2E*Y~snUɸpT< j&ZQQR[2T,UxCśxKx0uWS2jc|B>/fnPe|3|N3<_K_uKPxuʧ-k[2zpdzU2rr#5#nG&H-c3ݬJs:Oϔ>`\w^pa]aա֕jhbMoe2I PwSˎ pC qȴfsfM6kjqJ Z^\ )[{׺pwŠ>&\A6&e(|ZscJ6iۢ [D|<5Pc*7M=JG_3\n=Qrׅb"Q )X蔉Δ&>7THY\CtU!y&-RZ[:y󁉹LAzKГ߿v65 {UdYaL2p~ /#Z\Fpm*TưR4ѱΫJ* C'ۂ2 Fp7@WzThuaى}e(QDaurE^ L<\_gG!);JFD/TS ŶQ}&Z'\IBhJdx{O[Dڕ?PKy]7TPK FIorg/apache/maven/wrapper/cli/AbstractPropertiesCommandLineConverter.classWmWE~&ٰɲRB BQjӆMi+v,a! _K*zHZlB#=9swܹgܙ׏%@BĬnf^ސ&{%bQB Kx[2>]?J@c]Py';Yr].be\7tgXd̔О m.Yw iB SU2~I)800tL*R5#c)٬fԌ\KQ$k)ȔilRimhw>p<2PXF1ұcFLL5G3ZT1[ǀjkz:gQ" bلԒuF:%[NܰP {pgbJ,I=m(ەz"5ET°p?nX c5!z& SJmjJ&䳖f.-F)*\)a䄊EB e9ɓkgufRK:I3\?"6ax/Y?$fӣHίnhC&QWziؓQW}՜HI3gMgCpnq:jxgd㌈-0D2xOY>bR4 -^'"n-cy2[2>G2>42> >W2p# p ?9p4is[ᔏ 6m90p}/>y]4h#C0u׭R^b3ng{1ۼUkz9:&T^?Dw=znGԍ_c7 =]ԗCŀgqxxwR8H/_W$j_^$}OP*;q~E l$rI6Ri$E}?ó,\H|CQW,lj{{>Ao[ՅvQ-F>J#cHD_sصdPոE ɕ(_@k1̝C7v'\PG˾C 9/Iyþw apiCHm < !Ijp= \!&("_Ae\qyZ)󴂫ƹˑs LwxOD~C44BcxDT4<]9tr s:&)"4zo졸R9" 7KIxT`qەwPKQ+j PK F?org/apache/maven/wrapper/cli/CommandLineArgumentException.classJ1'ZmłboI*) mF6%Z |J0|pPoC݆Kv O':nHeSe9(1#Pd154Ru ':^ԟ0W)L8fC"!k 2dz8K<p8 &*i7~ѧY ~)q (C,*F/7L`KhAH=YӞy1KF=&l⩱B}P,(624d<>C' dQK>UaX5ݵOPK^F?SgPK F7org/apache/maven/wrapper/cli/CommandLineConverter.classJAϘi?^$+BXA x?mdwvGٺzhaYruof|w8}}|@ N8rbR6g4d" %62ŧ}޿('*S3mN)Ev`YmufkwW2,a+҈Q7ɒ%CNG>j}ݗskӕTt^x`~_L`m uv:P]kvx&}|v;z Xth#m$PmH&/VJ]&@T$E*WQ[6R(UlYmX]Aܗ}80PK$5HPK F4org/apache/maven/wrapper/cli/CommandLineOption.classV[wUݓ4^%-P҄6]ZʥzR[E&c:% /xMyA],d-O<p}&trS!3}}$p_ez;v`ocA#nxܖq'w𮌻b[Fg%+#FY1=ȅ.WC'2 2 Yu(I^U﫩SiОsj-M`xeW\*m[`ZrA3GE&mDMR!=k j;d$D%KY(FYhiU/FF51nJnOH{lRՄzf˅e͚{Q 4]>}oUS6- +: zpڴr)fVTAZ,jV*S)98UbTX[N3U-Zӑ̽:7e%$3(W8sn0;|"+j R<dAjiEz6ڨK7|1𑫀rk蠥y pҹjo1)&1JwTf'$q?4ir_fhuXQAU0g7{zI- v5cR`L[)iW,㑂!nN%BUo)^cCb >tkSoH?oInm~)ps0j0ehX>p!Չ_0u6%0t^ \LWjyjp^֮Pwd5+o ­#MʧLkF^qMImV0 "* 9a?Ou:?3羇7{wc<ٯ#SH-= h[C0 ;9h3³yO^!8n|r֋.lG$1Ҙ &{rO1Hq4h%XỲrco%28!M֡R ø0řHou8&#U6 )ML9Ӟ؊0 ;G);kw$i 49L#MA Q/D9&qM>hqHq&r bj7d\`L~skɨxc"'ױKYLF=uј}}N: ~I ".j#=5H}LWyY\p wH\i!a%V DXn"+wE] v5B7UyѾxJ;o{"sZ<# gC^_o%G$gj'[QBpτ3Ur:3aCcsr/N: ZC- IXYQ"hˮ_F̉P>-^u? a|6K?tOPKM/oPK FIorg/apache/maven/wrapper/cli/CommandLineParser$AfterFirstSubCommand.classVNA VZ` xAH)w E$,f/5$&>1-PR@!\9>ddԡ^葉v?x(ᑄ~!!.ቄA ɐ0,!Pe/p!2\]֔5ʦyRԜ$͵5n,tCVAD7t{Am|#Tg'%^f5%_1e<7-]DH)֬1*ؙŢIahV2 F=>*U$KY2ԚF斝ۺiHehp׮cbdy=7FVؖndYy*%.No:bI"jɧ::<_^+tML =benAΘ떪i[dE݃hą Bh0&%L1C23{ j!]z++*Nng-G1jr J"91 #nǭx,O +@a&h_As0_$ڹ:cIT(ZBJ:06VBX½) `p+iϕ(gΪөXu۩؈䶎ԭDN v&>)qF6jk]kUk+=0ƽu~g;RO\7ԻbSrhTQ߭%^?Rx7Ub-y-+Uw+j"C#C:zr3+-zTzԖITr#זbJfq "r{D:7= ƒ[@Ϙz9iVt0t0G̵"JgKvTƛ:nq Ct9o)v#4QatPGEbLqQƐn(^.?\^ q%W};PGOu;I] Kii4L }FlT h<E.`Ed6tG_R@ghV^Z} +u0F> (# 9baׇ}|k 0*,Ip!~l($=TC2L-dU_ ʟ0s`;1Lp6% yv 0itK^h>W9yfd7uPKv3PK FJorg/apache/maven/wrapper/cli/CommandLineParser$BeforeFirstSubCommand.classWmWG~&YX,RB-- $!/FPAFm},cXMvs6C=mVneQ闝;w}?, %Qd+9\a2⊌evUk27qSA?VeDdz 1fH-ꚾS57SVs;WԒUiz0f7 p _2MaupLV2oi*Q"yKתw4Q1D}+prK&z4T Nl+> *|wY_N;-hS;eʸ0=ʹ䍉푖jf%Utlì:)~D]NN`Nomвg9w8;jڜZhi 0(Ei"/:xbUǰ!+sk\ʸK|ŐwY*7 W}m>4MKoKI ك[+7:oɖVNUoˊӍ$Cx7 \wd* >ͽC7J+oYl~_tQ,>;P:P!>\+Fcl&ME`wp4'* wδE拳]6+Zk(PG?âA,:H@,BZ>}=BK#2hCG!pgԅδ>ȷ! O="PJqZbį>F)rT JS0l815,|k{2=OP/`])6"rXc.s b6IB$s3$VR%-#39\J4ʮخz`t<2}0wv]Č{CYW,>q9HD$Ps;iF P+ϣ9_[RҨIʿPKqU^ PK FTorg/apache/maven/wrapper/cli/CommandLineParser$CaseInsensitiveStringComparator.classS[OAf{ٶnW J)RSBb4$)}X26[x&ogv75ćsܾs=ǧbK̑A6Ƽb㉍5.CvK*n3* $ZRAP}~%K{{4ĘOdh@@LC-U\ NS)]ZϽP[}]+]qudz:zuۋnRuϸƑQrr~(}U3Ӎ 4<>f`Sl{ ^ /Z n2P3 ra2)5o1۲x80mmA(oFڦR?Оx) 's#pk&AW԰Ђ?K9ƌg wA.a1̌a}R&kaafhN7G{GeC7$2Տ>bHgw\%݉02̲I4R?7zRDZ@<+UƙIUb.B*:inR[qG ¿"_dU.=;Ľ8pWGpE%*Q{~NJXaY3TSx/Q$Z4E`%e$J_PK`vltPK FKorg/apache/maven/wrapper/cli/CommandLineParser$KnownOptionParserState.classXk|UdL&%lI]%%I"%QHM 0i73l'FTR[Aɦ! BW?on^[&~˽{92V)!!  s?p!XBb.te|0~o$ғ8e0T5 53(!k3ǡ7bmuSD}E5k@<I&zqitgTzܳ/NAp7܏}` Q1*jnڇv{3*ؔ1Fqa|T"mhJr ms% էaji4= J6{%U-S (#UE2[q:N70).xg[w9% q6bw§}YGN>K( 堐T}Zd:ihl T@[bև\5o4$%+C$JH w{N:b.t&pl;.@RXFT+iP/lh-+ph#KOt}; pác ᔤ "(SOm9f[l+a܊P3(Ƿڧ32K3BMa4,g2l!d v;hnPQ!8Yh8)Y\MG|/PK樸PK FKorg/apache/maven/wrapper/cli/CommandLineParser$OptionAwareParserState.classUmOP~6֭+n"P .`If෻.m!~I(㹥R_zy{soϹ?a)PpM*I 7dH$e$Q0#&CJ;n5e0xkm:5Mo w\YQf{k+ۓ8"w޴L>69,|!Vɴ0,w7d:o׹c =0Ϻi[ j<_ylYSis5(QǥStۆA0 MT_ jcZrC;-A~m-.@jO맼럞Zr^wtc=0%((H#4n))1,ᎂ9%+ jJHj /=Y2׫77afQ>C8vҫ  ' s-0vr$Lwo6x|uuusEsfBbjxmf1Q虉`P)Ɉ%K13U)"J2T ur A.(l2EalYQ5"y"*"q/Nq # p6G/TInCZ\ T[QS,S{ꖂi-!2D Ih]>0sS$9MEfI"PK5PK FEorg/apache/maven/wrapper/cli/CommandLineParser$OptionComparator.classTYOQn;eJilUpӖmZ,VH0!ѷK)C3t /1ΤZ"Շ9,/c;fC=S A|l *U,rOU,K*1t1=%knZy_دAUu){J9ԫ ݊[f*WfLSYW<6]xVټRV4t"LjE9GPݳ#)B'lw  .Urwp^'#>(6N'NnRu^p@ N>iqױ, gun8_=e>g}bC0@ OaNgp1BQgE4H iD`7PKVPK FForg/apache/maven/wrapper/cli/CommandLineParser$OptionParserState.classSN@=L T}QA ,0bAS*"@ bnbF {l'X!uG!8{q=>{XQ<,3TJ%C~vs0ەJ'Sg<>Zq53eF\n<DMu$RY&t2Iչu4HfRE6|בG{F-T001WQ3ZLH}?xPg-Mf0*vZevçtCS6p6m5L e?{Կ!e* F%\أ fA* ab & 5pS\xY^ذe:cqoƈ0/xW/ԫӮY:kB'PKe=$PK FAorg/apache/maven/wrapper/cli/CommandLineParser$OptionString.classTNQNز,?Q" BPT0&&wIYlwQ|o!H4|"oD .:gf73/`ILH"'ͩ,y4LАbFnh~!UnZ}-3y\R 3g= زW ]++Vw+[ɷBVl^#3n; `|_. t%W- ժ-X^ݢ,GFq%>vjXړ6s=gp!zk "Ն )[Ga-`0' Qה%}mđk@).!e n) t!ESrDE/ҮS. <40A3p1_`ԟjk[;ϹNN(#7!n36Do1I(ȐkAO'/"B>+_7}=dmlDAGUĀOV=i'sy7PK82dPK FKorg/apache/maven/wrapper/cli/CommandLineParser$OptionStringComparator.classT]OP~Y@NLlҍJFdQC`2Cwlŭ]+p7M=]Eq3f=yޯoO XŢM*2*jP`#"/I.(XalXm2 { J90˖mt\73Yv'\KځSV!,ǮxeJN%\9.mۦ[jv$ պi4ői]jQmXE6} K?ntSԪoQ 8FC5,{),}e]w\pO'V0»f+{da&wfp'o*V|Qf # jX'mRiVG$WnIӱ{*3 qImmm˳5BOF! V^H#aj aaôk^Niˀ}($pB# I{R8H'W']0)]%"/ʜ"n)ch ¼<1J# #]J ߠxc\CbH18 |ohW4hHjqor WI\3F9H:i i}zߢqnC]bJE*:S]E?BVq0G0$Rɿo4K0C:w jnx.wwu /Th!H9HVP-UL iH@BovEIhl6EP܅M$Ca>}):Ӫ[[z)K >iU>.y)k{hyq(K]\ @T'HKUڍd\na2#RDbk=H@aaJVQ#]c/@jplPUoO0BD}码C8#&|!cH S^'~5m0$#&FeP2D(BY E2J}FRlZ&8C&&~OPbm29 %jdFd!3LTGI.5DxRڙSVT,ŠJ>29Ր kb3PN/jK2Ґ,2\QbCX&ϐQXfj+M SΔw! ps YuJt}@(\  hFջ0 )Ŧ\" T*qba;w1kh! EZkmvNDc\&\kǝUm@"A:s-.5q'ڱkH ǐ&J<(s͂9[uxٚX-5N‘zP,hh^mvD1XlƜlJ;fs 6S`#e[mvUG" B;v ٳܟa;Z2X:kNU͉TmN9J:q\E.v8^$]! x^pi9Ͷ3e]I(Z6B&QT塸vMP$X"+-[/F[e:ժhkrb+BZmXHNzCTcq[R4eRA%p׮V^4e.XKkO~?FD;T gfP^nic;+X6DMQw"-"*h4jr1\S6$V5C3J1\$\y/յv$M--%ь6FR#.M3呋kr' ^0{)wTx?V.ءI(~g[I#sߙNr%h$6;S *3 kv@rވ~*bŜKJG'#u|777Wqߩ"uS ǩ '-/_eQ_sAYN~Mr.[س\r|w=IVPރ|3{PyZ3{0lo.$pVic\Iw+x*\=*|~ ƈglZ ViV؅ݜ}e"O1{, o 0|/zQ$Cqcy`L^ey z{1NKR_ q.y:+ЍP؇Ij.y%8yƓ2#nLݘF+I0] ws.e1)f(Z#h{^[E+L/:Yz}IR iϡ|7I=ԻQЇ nTwD~evߋYkOJ$jCSI*PEFNE<vju iP ̥*ة+{i)fT,$K3rn u.A]<&0Xz)"So]gWvc~3:BT<= ~7b.T\8M8`+tbA+l3!ǰ{9=S׈}D.aXe"R)v9;r-Rq\e'=V}A^čnVGC>]7-qÈVd6| _LCxǘlj̠f;K]\:Ҧ< S8|jդg rz+>H в?aŞ3g&W]x7N'tO[o FS=ÞE(<3𼁽1f=RaRXr'8s~v37 [s90(J\仟f<|Fvf!x8'{~#}Xp0K+xԋ3<Ї joe/.-`T[w,WlVFfș)&+,fr'W$*y”` WNbuarGEg9BV+@ `~E}7ϧuYiWzIbyvoԒs/iO/9Oy z~REޗQnlA *R\@S EFI#Utg0r&Ie 9 xaao'܋L{2W "c|q/0+&Gr^xUjuَ7v)-yo[q)Jn\KtZS2Cr;;G쇘kAZ 7}mi0d1?u؈W%G=:NK^&#({#j9r?b)e/mOil]='LtWO94וo#Tog1s`DV6*4"+SRH!$1q3O?q6#bǬXGbfh},z,E=7zaf yE"Oy&]u;rң=P* !f\N- PJYUl՞)zP?WgV>Ѱ߹9dInXC2\=û(g ޼Q NjaKe-|kk9Ƴ :%ƙ" \vl;9>l?Jlz!\G~t_PKB *PK F4org/apache/maven/wrapper/cli/ParsedCommandLine.classWi{~G`ca0lE M55$8uҖ 5b41mҦomh y t> ?},Y=s9Y?TbjA?.cDYC%*XR+`Y<+6܊W⣭^*>'c؆Ot ]x6ω[%, WT|5Ѓo+hJiǗg,ə/Ꙋc2SziXAˌ/N65dA/3Ig72 Q,zdؙl\ n&j ?OT7zUL=J(W5(p<XEx͓Nj%~Чag4CNï>j ~`_`BՃW7d߁r_h9ɜqELpohoo\lITe6ܚ )9#:u׫3M@;;TDvVʖF !r^?j6 rѲtxҧO_xk#kw[{sl$n  wr8LЂJ+w C`2eT.\B]*J߅bm)u(t6:"`(b% E~PW+tA̮se͛ w9V>zЍ=8}ৼIj >#0$ w1 n1r=5gn@Č1"F'v9\VT1┊xZ$;E>.%#Z2='$^GfBb?` +w2.דe@3/kA#䝽.=uS3JЏzxkt||uӷƺLck'9B(1F'iRSTx-L76LJN?^PsFC>T²s!*;?@wۧÎ{虋<(z!p=.c>zkngI`.bmYoZ}EcࢇdF" E/|]ه=nLy>nLOyYքu ~[KVsW%鮐)x^w74-'-ZGZMB`]N\ejI+1|* mPK:cHPK F:org/apache/maven/wrapper/cli/ParsedCommandLineOption.classS]OA=ӯ"|(PeU~"*&5|Imv(M| 2]3w=sg'F^D!h$-7Lơ%nvS=|rW=bh !]\kuǝaHݦ-FN}7Zɵu:3G%Y9pn|!hUE.W|ݠHhm]`ĭĤP\Zo S{gFCZеvDeѪ׹Y+ WLj wUaʍ%Vrys:&+m氤Ղ3sx`Wua ݹYҏ8?J_Ɲ@!YvY<%sOJ$aL;5;K!S]Ҟ@E!L;  WD>{ٗh,"B5S|\Fߏ+vUCtme=  >R!KacqRGP[Dj%F'GBb^p& Q*}<J})cH^y4.Zߍ ;P"ɂOG}-3-R%H#2PK0aPK FHorg/apache/maven/wrapper/cli/ProjectPropertiesCommandLineConverter.classN@"\`\@.$ qE~ZeLi)ҕ 2B55wߙ3ͼ=!l`'YBADB1HC!bOxzn{+c3b ۓ1y1o+Lf_;5 9Z#=hd:fPr#4>jѻSnẃVw(Zo[c~ Ce㥈lhd!ǀ" \ P|gV*CѰBᎌFNhY;fShSB[o]VDOXthk2Ij #@jfnV`ja ݘPV +K4n%e -%e0[>OUPKDo5PK FGorg/apache/maven/wrapper/cli/SystemPropertiesCommandLineConverter.classN@p"( t…@\$C91mJW&.|8-1gq?wd>> 5nrgc@i d|}#G)>3X t\&5Aӥ3'A}i9J .w]#ܛ))26o}ɸG4tFMz9y6~Y{()spL a/+|*,da_Zk #P "+Pt?>V~5֛ضzsw>6οMQ *pY5‘S52U&*g^I *" EK npz^B?7DfQ=U:rm}PK,n&PK F2org/apache/maven/wrapper/DefaultDownloader$1.class= @-D\#b dL"nDP⊥3{|0|`^ @HbYZm97= -snlKX*.8D*F8 6ƈ[h.K) G4T'+g4S O 4}7P~PK*8PK FSorg/apache/maven/wrapper/DefaultDownloader$SystemPropertiesProxyAuthenticator.classSmoA~(ǵETQZ\j4BI-p#{K)JF?8 $އyyٙ&ș3]+XM`-%3&  <`p}Wd}X5hŚ7Gt-soKWGƘj!^?T+!iJW:Wd^U@6pHNO8#zj;^B_fXj K@6|n3'~_(gzPJ,Jeݶ&Cq<s/ʺqu/3gby,0aϰRSμ4BMOl(Yx-]᱁' HIIO86fiCjq 2$ vm,DIogM Ϧ^055i#*HɉDTSJT.j,ӏlAQD b.!I[ "_H Eg|`pNk4!(BV~GC:vtjc#W(h85(ObOhxU9Ђ44 3E_e<+h*&VO_Wo *[BEAyQŷUeQqQwU\R ~ ~$ehp]ӕ=qQΛ1]_8XMˤ v$4j,8=$Hq zMقY'\0rᱩӉ1vHh6Д #gJ1YÚOxNƚ&Blt\N"2VƻWgS:%G4m4g,s1cLַjd> 3n;sFH͛9i/8ttF!mMޞ\1fC8Ҙ#F>0X|*DgbӎҵjQ8m^ l5UOytXBˊٸ噎ed_ɮQ<ΓMtΙLav$S#t*L~sޱwvA(e= ?:'S[:w];:&Rw.LvͥmLQl!Ӹ">h[v;m;abS.ə3,U;4R= meV/}~ `⥨u=Yo劍Xmc*KkV۱y^(JAZ5{A®}-x-{ǀTAiX͹J1g\I6yPޖSnȑt ٳKZ)֎XGV*xM̗U mktV5(Û2+Qt=´m_85lG FYbSe(9q2*9]!A%{k(95֪gV?6 #SDTgEs>3(÷ ں!uu_G: _qƺ!M4EtkIJ ? IJ ކ|[hZ@Wku@ehm DK;|Y1 "Il)B{pn(B?ݳƲR<|!>a"xq?m#i*!.dxdŋTHMiBh,9$h]Dt")m(,oRbƘRĦX!uwMuHbrL-bs+k)cPۤm@,W%-ۋO2ޘZ^^%x[oAE{ ElCzM"1E8.?Rga |Peط3MLi:0+G1Wg0\$w+7.S]G|L N+C4`2/ӀzuVq s߸a1TZU|W_K7ƣw8q(%&9[Lhhg&u<J$݉H,H*1%T{ɖH/Vr%4bhV: "@G=eJpUq^dk9"x7KTGGbZTzXPK$ PK F)org/apache/maven/wrapper/Downloader.classEM @ _< 7q.ݪ  ΔͅPTB%/y`UZ`ȋs]/&_)O;Bcv 8cN7l.ͨ$dp`qVjdؤREbO8 rwt PcfMoPK ]StPK F(org/apache/maven/wrapper/Installer.classX |Uy?7977(pE!C@ %H@$9+{υZVkk?-XVڭXM(mnnv6ݺkvmgKϹHb%y?~oS~b¿i~jc?~.?~f?~Wu t_1^o|x]4,oqkD8$%6%R$6>+_ J|bdvK 2CNX&s.Vj' GY+)>Yh"C$ tuMr6KR-|ܐCV֏eΐz?Z&iI#rʐU~\! YG>Y&?^ur\6d~7 n٤%"bHd_ڔ`!2dv5 ]/.ٮ+w!݂@k֖ގ[{vhܻ}{[ư=$BĢINJ:pU`H4āF+n #a;x$avuN(lI&HNjξ;[6!g-6;W+v [b`vG(jw"vbEuEl !OLz`%i rPlz wP@*a9Xtt,BƭH|O(#AU`^--MPݱ/F` *D/ ҔD?D8Fv{w F=3=C9aumk/Cvpc4wG#l1ht|9v4VTtfG1*zD :Fy7өUP9#yJc|Nլ+!Ă& ΂#uB;S8Z+ܓ#:<8h XrP4hEG2b 8bak We5l Tgo￞ӦGnVw`-r) M % F~_U*ޒHX#&~Є0Ca:h,ϲt0!FbϺkM34.1ǔۡg98K43~U3c13Qz͔#*|, VqbzT'OLc)TEo -TxMڴ;l[I{1ź #Ti\gČX!J6אOi)G׎۔䳦/gfD4:)ʃ6S>T̰jCJr$>j$r!j2=&#wI|Q)QC3q`_Ry1Ӓ _^:9WGl7dr3&'MLHOCcWflY(2:[:95y]vnzeO2W݌i`=,v[O8iZd`מwdf>'6bx1c/F88tHyM쁞T8xK*f`C'u{LFR !M wƘSRҽd[$ e&3Z.{㍺N#-X8ؚKKg0xT/[d.kQ7v^obX1RJNc NŤ Q+Xisjf^"_U2W+8bRrͻ˩K*"4ڙ5>i6#O{iO<4DY sdyWDZ=_r40N#vXœ6+#fFR{xY*}%Ӂ!t|c6Ӿ3v@Ɣ*2#ү\u9g m ipLP1Vڣ1&QjܙpH"g}.\CAaD rT~>;qAaHwvv({#6/(E(* s&ކ=#nOn/L@\9 o'lOÞ\(d,<@(q_2o _:elF1g ;o J.֍GuI̧w|!d;ڀo 5WP^=F'q(Nho"jbo.ɑ@(.HR%cXs.T4YRDNMcY_r<cZms+ T1)u=3 )9_an|c!ۋQ e ̄Z_^l^lb\[т;B>8m%\J%:edK\%}%7j7n,n{p3%ʻQx/aLf{m̪B;`&06-(>i+RGjP_cc>q1>I&g̽Y 3)6G 7M,a}䳯ct1w+xN_ߖq42. (>5?4VVzBpus0E'o/g^mp-w-?ս sy s |,"9G^*Go=}1oؐˎaINQmLW{c86>%o1li.G+75ޭ};1/`+]'_(`_ h:+-Iw;_]Ses|;'hx%|u'Y7rbۃM< v%z (8jAna{w='[P/J BPJ N0q=y}!{Oi=F]%25/*<ÞZ8I~7Esu6!qob :E>Cy\:`]arr^8rTgpՓ1;G[0 OxpiusNTUi<=$M1_5(_&>ChU[Vb?:=֝zԺy[p5 sRVdUZB ,*3U͂eq3<դzхR柰0=ܳ o˄b if&J |[LD^K"$6}+pu:Ob,=l_9yj\yϒ^m3׍b]ьa` y\XDO)={*ig~ʠXgM[zlYAAS2%ӌլp^'L~Ąv^7? NkiTJoWa~ ?aPKU/~PK F/org/apache/maven/wrapper/MavenWrapperMain.classW XV, ql &:Q6 `\Z,XU{mһM[nJ:I+hhJHz}߷]! !QI;3o9o.TA\>^!T*Z^ V^W͵[U܆+x7z&fޢm*v5xwho ޥ g[E\l{>~PA/Ϊw.9||X>2^L{1#[*{psOq'|J*gxPSy9|Hn>,=%/ye_*zqU|T-/-NjJ#q{r~5/~${9T{_pHwC݃^O願nNdԜ-ࡁc=ݣuci܋ɻG\ʪ=Q3jhmtZc_5t֏ Š=E=M {DHOI#ק 3t2'F2'ߎ/}z$tO֣ s 2/-fԓK]]HZܴFJ(I˲KNF| G@d,+IOkxd>}*b$(] 6'SP}I+vX yVG,sg ,&euZnIv1!HΗ,ι60u;^.{R,\KX*D:2`Z ]4 ;txiOIoi ˒rv#'NɲGd90'y~d+SsuI#e#⮡sX.HuTWc&=)$l*{z@'é{nG%QU칫XDR6_dA TxlI t, 10G*͘BKD&< Enp(PSp ExvnࢯjMF&jRE,DX&EEN`U>ӦMF#L+$n8DX)S7MrGbz*`ǭ?ϫ?z; S;hCǯ7"&*)q&Hqe-:l/I}" +^h{VZ!緈,mQxCI-¯betdMF$:5Q<FĈ&l\I`%ED}iynL!mqtNYVghbA0).zWI2s4IlCmh6 CcB8U.y O&nRH$'3g° +ֶrAEc1vCE7*]X$_[/ +ぢڇIoI5y>ves\RA /_s%ywyyaj-5O1x2tRKJ`xKz3?]fO`U(3n3PwU6WfQ3: mW;X6,ohFc+X6Q& 8 `)XC~l6 au?k ⯦-}1hz17q:ƜS4&uͳh"h渪/%9`mCd \F3@.G#vbv9P.,T/Z`!Auh HCc ?:Jm4,r0hb`)oǥqyeoti60jF 5%S9,])k͠mbvWkʱgiPHG0Z= B=:ƶs .+2=1Zy. f4vud1.m$uqmh!5 -7 \A ੎vix:oC q W%X2F߷'@q ԕA }WeٷeKRlVw]96{8{W3u#ͥ;tArO9*n PPKdMTdj;iLLT;@ A*3x[\R(˚"y4)x#X ^t E>Ϸ|#JlIzf;S$'wq':rʀɧE 1Rb炬oq*NY[r#v'ճw)k||d0td0^K~PKo vPK F>org/apache/maven/wrapper/PathAssembler$LocalDistribution.classR]KA=wj\5~ĵv })Z-(> L1FA??QBf~sϽ?n|F\o|,X$uɏU0Y9"VYU%rSMY@(W2݈E[Ԛ2nsZR?EV5g|mhРAofuITw[U a%Hhe~5 6ǣhU*K 4z7ܚK 2 +nugsuuM9@a4Q˄O5YAHꙬB٬um8N,G=lFP*6ûߓhnDz(D=Ww0e9LM$N1JYd6bez92M%~Gk.{6ز]AI?v0gyV 8'PK<\tPK F,org/apache/maven/wrapper/PathAssembler.classV_=F`!ؕvd Pحkf`:4efMu}I״NDrCwҿy3B"Ao{ss]Foxp7C!)gĵ% 'MQV%!XGd<>|4w' >!>OnyqxA>#b/R__ BE|M}#o緂v/|Wм#i57ێ/4$(IЬjۚ-3uanl˓3SɉKꊚȩF61M}#{VBˈi؎j8sjIsej򉱑VK^]ьY[.y!YE=Bny s|#fb㺡M5.4^@S-]+>gI'iejAM/i a▥ :KY |f5g''7Uo٢ $@nKB!K.6 ͖i20;O5 a6֤>tuB.Z˪$!DnSSXwu[mYmTj#'dk颥;kה/9x%H cձմV]0)Ve`iysE4v3\$2%%gN<>{+JBzU S , ?8fVD8m&. ; mPh(ygqNƏ i xR1nYO 7$E1\sRS!3$"NC_ݯo3KW$zNeZ۶L..ki)-~ǩ=%c]?5$U]bX& G e!0%S%nm/{Fb.1L'ĢFD /lO M/֚٪ 24ټEn, ,[Qg",nGMüE,NW`ڜ&k+x_v=ZjB&\yPA1s3^Мdyp?l( bp7L(=u[-䑷|HJ_4:;Π>E(2Cs°+x DMG4Yldff2oy̿V'ou&9;~eQ)(홢km|mg+َHb̷ 9؈.Ԁ8g>;_u_r.鏕!ꊾkOи a#| ))dC@,:!,E:=%1ld>o%4KOe6 ϋW26/'.]>.%vƿ)wlxR l`|(}N7\Z1H0ǰnh=nX+xI梁Z+xFҝ&5#'~iA%7>>ň2:'p`1>=ԝb墊yUT\(ƤA|*~_ w#)3?P ;ʈEJ8@|stk0˦X;Y8m^z[$ Sf23Yq?n4UxE?}ҢkX^(xX ܁?o)!v#c.%tD<ݪv|&S=U -['T>GMa<OzA:_?{ؖNF f+dVb>@ڭ!m%4X a*p^Ahl5QIJ"YLeOAPK¾2LPK F6org/apache/maven/wrapper/SystemPropertiesHandler.classVkwU&!-P@ +*PHPt&LNh 7 '2]KcpIi& 69gsY? ` Cp@"A0NG  a)xQrB-'CR/``L%0Y ԒVTZ3S8LYX l!3N2j##|{qaYܴP>;&XƸ42#c9M5n;3igr\N:̤+)'xF:1 S]հ6?e5ofdwLt.hZ בFVC ;`nQEIsMۢQyڌa43U"k™wȔJ`8|VZnS2R_c>aEW:k+ۇr骨)(XCb R,f +!lezHIpyU-EULu&w$R&\#yW Ng {J`ZÒ 7%켓EZ[z=TzD 0&Ӽ9ryU)˫ [%YɛqՌvZj8u ]:XvxoMom;'i8hgt :$:>9ࢎT3+R+_㒎o-k2h_{maǔ[^]=iǞ*g=Z/d[)gνlrX &UêU@Q2cOG@h \cs~kEH%*ī/v6pNfBREy9O2xicrHN6? ӥ{]ϴ-Y77S*w IU!C\][6-[a_ Ț}@iў{mC<[19TFCe+9?6,ᝎہB6[] kE)?=y5<&h=^R}۾exJ r۰Q&?l#MIM 7zU۪Bc$tMhv7E\sFq\,ݡَaCC~Ʀ\bWZea Xm5\A~j!aN,b kge1!UG4T0:fꋪ3ݪm Nw\Tx}wN j/.g1RIPR |Ie.sebPhN'g$ >GDN-dzX!?EMbk~WuBHS9J%nZ4_dB$]?A|e~9w_. )koϢR`F;Q7xA An+A j r|F̄ 7<; d -8Ť L>OF uz @2H|#@W2.+AAe lɅ KJM+AWh2Ki A+A&d_  2ȯ?PK9R'$ PK F.org/apache/maven/wrapper/WrapperExecutor.classW~>YKƀ$#y IY)n6 1 г|dz:amh0BM:.`Ӹ M޻/i|;g!F~;Gu<1Tฎ1Td N:NG.I'j<tfd5)'e a!Hi9yFVF1?.'̟(i>Q|NtǐĪ/Kr_kBsNny_o.bTp ߌyG- u[R]mz:tmѹWC|̘dsz 36;ټgf]f`iX8E! uOuwtm-ֹ{[yXurV^<߾ggs8s~;C#gx1bY:Qr(J1f"J;{PCr&͜!+qMYQ\ӳ,YkfG4t6N7Զ.P$E6;trv;k,[HeC0I,lF3wj{5Sփ(\ï]4 ]o=rfofd7_,\/`ʜkLb癳}f7f-/&;7= 7&U4,EZfd3+n  jgYP9\D:Y :]芪%13X0x,NK.Ìˢ7QnR73BkCj[dݩzN|"}nVLb 3cu̾9拈'.&rsh8| üQWFQ7Xg-٭Y:?[-Ug΢~]DApA@PÊir)0zD0̸ٰOb F(ܝ"N"pэ"؅ 3 DM$c*JCū^{t<MC Hʇb]F˕/N%Ԍ"52sM+ci\r'6J~%o+XDwI_OK9oEG)2׍a9Z[+5~uWbCZ/@1qG/qsGS(wYena+X3QKZ:Z[a!+ tbgRlk9cPҠ aq1xI%{l&eKTM>"\Y<9*φP(hϟ +b,2;xef׾v]9r$1G,!H8UZSC) XOM ԅGB4Fz::_Cr-96K0WOG0O''„/pQPVoJR(si5*^,TXѹΠ֫~27)ʉ[!hxPKSZPK Forg/PKPK F org/apache/PKPK Forg/apache/maven/PKPK Forg/apache/maven/wrapper/PKPK Forg/apache/maven/wrapper/cli/PKPK F5META-INF/maven/io.takari/maven-wrapper/pom.properties+K-*ϳ533J//-L+IN,J,*LKL. &%qPKj4:9PK FMETA-INF/MANIFEST.MF} 0DC~ `7멂 XJHM6V[+*T̛vXB֥"VgykhFQjHE{pJ{/ӻ!RZζ$s lUЕ&,`mVlj) 8݆%{:/rg<<߹"sv88PK'b*PK Fn 3org/apache/maven/wrapper/BootstrapMainStarter.classPK Fy]7T?org/apache/maven/wrapper/cli/AbstractCommandLineConverter.classPK FQ+j I2 org/apache/maven/wrapper/cli/AbstractPropertiesCommandLineConverter.classPK F^F?Sg?org/apache/maven/wrapper/cli/CommandLineArgumentException.classPK F$5H7Morg/apache/maven/wrapper/cli/CommandLineConverter.classPK F0I* 4org/apache/maven/wrapper/cli/CommandLineOption.classPK FM/o6org/apache/maven/wrapper/cli/CommandLineParser$1.classPK F'P)\ Iorg/apache/maven/wrapper/cli/CommandLineParser$AfterFirstSubCommand.classPK Fv3Aorg/apache/maven/wrapper/cli/CommandLineParser$AfterOptions.classPK FqU^ Jorg/apache/maven/wrapper/cli/CommandLineParser$BeforeFirstSubCommand.classPK F`vltTB$org/apache/maven/wrapper/cli/CommandLineParser$CaseInsensitiveStringComparator.classPK FO`K0'org/apache/maven/wrapper/cli/CommandLineParser$KnownOptionParserState.classPK F樸Jx/org/apache/maven/wrapper/cli/CommandLineParser$MissingOptionArgState.classPK F5K2org/apache/maven/wrapper/cli/CommandLineParser$OptionAwareParserState.classPK FVE5org/apache/maven/wrapper/cli/CommandLineParser$OptionComparator.classPK Fe=$F)9org/apache/maven/wrapper/cli/CommandLineParser$OptionParserState.classPK F82dAS;org/apache/maven/wrapper/cli/CommandLineParser$OptionString.classPK F% K~>org/apache/maven/wrapper/cli/CommandLineParser$OptionStringComparator.classPK F+ 5@Aorg/apache/maven/wrapper/cli/CommandLineParser$ParserState.classPK FF{jM-Dorg/apache/maven/wrapper/cli/CommandLineParser$UnknownOptionParserState.classPK FB *4Gorg/apache/maven/wrapper/cli/CommandLineParser.classPK F:cH4Yorg/apache/maven/wrapper/cli/ParsedCommandLine.classPK F0a:^aorg/apache/maven/wrapper/cli/ParsedCommandLineOption.classPK FDo5Hdorg/apache/maven/wrapper/cli/ProjectPropertiesCommandLineConverter.classPK F,n&Gforg/apache/maven/wrapper/cli/SystemPropertiesCommandLineConverter.classPK F*82horg/apache/maven/wrapper/DefaultDownloader$1.classPK F:#"Siorg/apache/maven/wrapper/DefaultDownloader$SystemPropertiesProxyAuthenticator.classPK F$ 0Wlorg/apache/maven/wrapper/DefaultDownloader.classPK F ]St)torg/apache/maven/wrapper/Downloader.classPK FU/~(uorg/apache/maven/wrapper/Installer.classPK Fo v/org/apache/maven/wrapper/MavenWrapperMain.classPK F<\t>Ɛorg/apache/maven/wrapper/PathAssembler$LocalDistribution.classPK F¾2L,org/apache/maven/wrapper/PathAssembler.classPK F=N: 6org/apache/maven/wrapper/SystemPropertiesHandler.classPK F9R'$ 3.org/apache/maven/wrapper/WrapperConfiguration.classPK FSZ.org/apache/maven/wrapper/WrapperExecutor.classPK Frorg/PK F org/apache/PK Forg/apache/maven/PK F"org/apache/maven/wrapper/PK Fkorg/apache/maven/wrapper/cli/PK Fj4:95META-INF/maven/io.takari/maven-wrapper/pom.propertiesPK F'b*UMETA-INF/MANIFEST.MFPK++Ajnr-ffi-jnr-ffi-2.1.7/.mvn/wrapper/maven-wrapper.properties000066400000000000000000000001561316720554100236530ustar00rootroot00000000000000distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.9/apache-maven-3.3.9-bin.zip jnr-ffi-jnr-ffi-2.1.7/.travis.yml000066400000000000000000000006021316720554100165200ustar00rootroot00000000000000language: java notifications: irc: channels: - "irc.freenode.org#jnr" on_success: change on_failure: always template: - "%{repository} (%{branch}:%{commit} by %{author}): %{message} (%{build_url})" matrix: include: - os: os x - os: linux jdk: oraclejdk8 - os: linux jdk: oraclejdk7 sudo: false cache: directories: - $HOME/.m2 jnr-ffi-jnr-ffi-2.1.7/LICENSE000066400000000000000000000022531316720554100154200ustar00rootroot00000000000000 Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Alternatively, you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License version 3 for more details. You should have received a copy of the GNU Lesser General Public License version 3 along with this work. If not, see . jnr-ffi-jnr-ffi-2.1.7/README.md000066400000000000000000000027031316720554100156720ustar00rootroot00000000000000jnr-ffi [![Build Status](https://travis-ci.org/jnr/jnr-ffi.svg)](https://travis-ci.org/jnr/jnr-ffi) ====== [jnr-ffi](https://github.com/jnr/jnr-ffi) is a java library for loading native libraries without writing JNI code by hand, or using tools such as SWIG. Example ------ package helloworld; import jnr.ffi.LibraryLoader; public class HelloWorld { public static interface LibC { int puts(String s); } public static void main(String[] args) { LibC libc = LibraryLoader.create(LibC.class).load("c"); libc.puts("Hello, World"); } } Supported Types ------ All java primitives are mapped simply to the equivalent C types. * byte - 8 bit signed integer * short - 16 bit signed integer * int - 32 bit signed integer * long - natural long (i.e. 32 bits wide on 32 bit systems, 64 bit wide on 64bit systems) * float - 32 bit float * double - 64 bit float The width and/or signed-ness of these basic types can be specified using one of the type alias annotations. e.g. // Use the correct width for the result from getpid(3) @pid_t long getpid(); // read(2) returns a signed long result, and its length parameter is an unsigned long @ssize_t long read(int fd, Pointer data, @size_t long len); In addition, the following java types are mapped to a C pointer * String - equivalent to "const char *" * Pointer - equivalent to "void *" * Buffer - equivalent to "void *" jnr-ffi-jnr-ffi-2.1.7/libtest/000077500000000000000000000000001316720554100160575ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/libtest/Benchmark.c000066400000000000000000000014461316720554100201220ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ void returnVoid() { } void returnVoidI(int arg) { (void)(arg); } int returnInt() { return 0; } int returnIntI(int arg) { return arg; } jnr-ffi-jnr-ffi-2.1.7/libtest/BufferTest.c000066400000000000000000000024421316720554100202760ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #define MEMSET(buf, value, size) do { \ int i; for (i = 0; i < size; ++i) buf[i] = value; \ } while(0) #define MEMCPY(dst, src, size) do { \ int i; for (i = 0; i < size; ++i) dst[i] = src[i]; \ } while(0) #define FILL(JTYPE, CTYPE) \ void fill##JTYPE##Buffer(CTYPE* buf, CTYPE value, int size) { MEMSET(buf, value, size); } #define COPY(JTYPE, CTYPE) \ void copy##JTYPE##Buffer(CTYPE* dst, CTYPE* src, int size) { MEMCPY(dst, src, size); } #define FUNC(JTYPE, CTYPE) \ FILL(JTYPE, CTYPE); \ COPY(JTYPE, CTYPE) FUNC(Byte, char); FUNC(Short, short); FUNC(Int, int); FUNC(Long, long long); FUNC(Float, float); FUNC(Double, double); jnr-ffi-jnr-ffi-2.1.7/libtest/ClosureTest.c000066400000000000000000000057511316720554100205070ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ int testClosureNull(int (*closure)(void), int defaultValue) { return closure ? (*closure)() : defaultValue; } void testClosureVrV(void (*closure)(void)) { (*closure)(); } char testClosureVrB(char (*closure)(void)) { return (*closure)(); } short testClosureVrS(short (*closure)(void)) { return (*closure)(); } int testClosureVrI(int (*closure)(void)) { return (*closure)(); } long long testClosureVrL(long long (*closure)(void)) { return (*closure)(); } float testClosureVrF(float (*closure)(void)) { return (*closure)(); } double testClosureVrD(double (*closure)(void)) { return (*closure)(); } void testClosureBrV(void (*closure)(char), char a1) { (*closure)(a1); } void testClosureSrV(void (*closure)(short), short a1) { (*closure)(a1); } void testClosureIrV(void (*closure)(int), int a1) { (*closure)(a1); } void testClosureLrV(void (*closure)(long long), long long a1) { (*closure)(a1); } void testClosureFrV(void (*closure)(float), float a1) { (*closure)(a1); } void testClosureDrV(void (*closure)(double), double a1) { (*closure)(a1); } struct StructClosureIrV { void (*closure)(int); }; void testStructClosureIrV(struct StructClosureIrV *s, int a1) { (*s->closure)(a1); } // // These macros produce functions of the form: // testClosureBIrV(void (*closure)(char, int), char a1, int a2) {} // #define C2_(J1, J2, N1, N2) \ void testClosure##J1##J2##rV(void (*closure)(N1, N2), N1 a1, N2 a2) \ { \ (*closure)(a1, a2); \ } #define C2(J, N) \ C2_(B, J, char, N) \ C2_(S, J, short, N) \ C2_(I, J, int, N) \ C2_(L, J, long long, N) \ C2_(F, J, float, N) \ C2_(D, J, double, N) \ C2(B, char); C2(S, short); C2(I, int); C2(L, long long); C2(F, float); C2(D, double); #define C3_(J1, J2, J3, N1, N2, N3) \ void testClosure##J1##J2##J3##rV(void (*closure)(N1, N2, N3), N1 a1, N2 a2, N3 a3) \ { \ (*closure)(a1, a2, a3); \ } #define C3(J, N) \ C3_(B, J, B, char, N, char) \ C3_(S, J, S, short, N, short) \ C3_(I, J, I, int, N, int) \ C3_(L, J, L, long long, N, long long) \ C3_(F, J, F, float, N, float) \ C3_(D, J, D, double, N, double) \ C3(B, char); C3(S, short); C3(I, int); C3(L, long long); C3(F, float); C3(D, double); C3_(B, S, I, char, short, int); C3_(B, S, L, char, short, long long); C3_(L, S, B, long long, short, char); C3_(L, B, S, long long, char, short); jnr-ffi-jnr-ffi-2.1.7/libtest/GNUmakefile000066400000000000000000000060621316720554100201350ustar00rootroot00000000000000# -*- makefile -*- BUILD_OS := $(strip $(shell uname -s | tr '[:upper:]' '[:lower:]')) OS ?= $(BUILD_OS) CPU = $(shell uname -m | sed -e 's/i[345678]86/i386/') MODEL = 32 # Default to 32bit compiles PLATFORM = $(CPU)-$(OS) ifeq ($(OS), sunos) OS = solaris endif # Default value of $OS on Windows is Windows_NT ifeq ($(OS), Windows_NT) # that's how we detect x64... ifdef CommonProgramFiles(x86) OS = win64 else OS = win32 endif endif SRC_DIR = libtest BUILD_DIR ?= build TEST_BUILD_DIR = $(BUILD_DIR)/libtest # Set defaults to unix (linux/solaris/bsd) PREFIX = lib LIBEXT = so LIBNAME = $(PREFIX)test.$(LIBEXT) export MACOSX_DEPLOYMENT_TARGET=10.5 CCACHE := $(strip $(realpath $(shell which ccache 2> /dev/null))) TEST_SRCS = $(wildcard $(SRC_DIR)/*.c) TEST_OBJS := $(patsubst $(SRC_DIR)/%.c, $(TEST_BUILD_DIR)/%.o, $(TEST_SRCS)) # # Compiler/linker flags from: # http://weblogs.java.net/blog/kellyohair/archive/2006/01/compilation_of_1.html JFLAGS = -fno-omit-frame-pointer -fno-strict-aliasing OFLAGS = -O2 $(JFLAGS) WFLAGS = -W -Wall -Wno-unused -Wno-parentheses PICFLAGS = -fPIC SOFLAGS = -shared -Wl,-O1 LDFLAGS += $(SOFLAGS) IFLAGS = -I"$(BUILD_DIR)" CFLAGS = $(OFLAGS) $(WFLAGS) $(IFLAGS) $(PICFLAGS) -D_REENTRANT ifeq ($(OS), win32) CC = i686-w64-mingw32-gcc LDFLAGS += -Wl,--add-stdcall-alias -static-libgcc PREFIX = LIBEXT = dll PICFLAGS = endif ifeq ($(OS), win64) CC = x86_64-w64-mingw32-gcc LDFLAGS += -Wl,--add-stdcall-alias -static-libgcc PREFIX = LIBEXT = dll PICFLAGS = endif ifeq ($(OS), darwin) CC = gcc ifneq ($(findstring $(CPU), i386 x86_64),) ARCHFLAGS = -arch i386 -arch x86_64 endif ifneq ($(findstring $(CPU), ppc powerpc),) ARCHFLAGS = -arch ppc endif CFLAGS += -fno-common $(ARCHFLAGS) LDFLAGS = $(ARCHFLAGS) -dynamiclib LIBEXT = dylib PICFLAGS = SOFLAGS = endif ifeq ($(OS), linux) SOFLAGS += -Wl,-soname,$(LIBNAME) endif ifeq ($(OS), solaris) CC = /usr/sfw/bin/gcc -std=c99 LD = /usr/ccs/bin/ld SOFLAGS = -shared -static-libgcc endif ifeq ($(OS), aix) LIBEXT = a SOFLAGS = -shared -static-libgcc PICFLAGS += -pthread endif ifneq ($(findstring cygwin, $(OS)),) CFLAGS += -mno-cygwin -mwin32 LIBEXT = dll # PREFIX = PICFLAGS= endif ifneq ($(findstring mingw, $(OS)),) LIBEXT = dll PICFLAGS= endif ifeq ($(CPU), sparcv9) MODEL = 64 endif ifeq ($(CPU), amd64) MODEL = 64 endif ifeq ($(CPU), x86_64) MODEL = 64 endif # On platforms (linux, solaris) that support both 32bit and 64bit, force building for one or the other ifneq ($(strip $(findstring $(OS), solaris)),) # Change the CC/LD instead of CFLAGS/LDFLAGS, incase other things in the flags # makes the libffi build choke CC += -m$(MODEL) LD += -m$(MODEL) endif LIBTEST = $(BUILD_DIR)/$(LIBNAME) all: $(LIBTEST) $(TEST_BUILD_DIR)/%.o : $(SRC_DIR)/%.c @mkdir -p $(@D) $(CCACHE) $(CC) $(CFLAGS) -c $< -o "$@" $(LIBTEST): $(TEST_OBJS) $(CC) -o $@ $(LDFLAGS) $(TEST_OBJS) -lm clean:: # nothing to do - ant will delete the build dir debug:: @echo "SRCS=$(TEST_SRCS)" print-%: @echo '$*=$($*)' jnr-ffi-jnr-ffi-2.1.7/libtest/GlobalVariable.c000066400000000000000000000030431316720554100210710ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include typedef int8_t s8; typedef uint8_t u8; typedef int16_t s16; typedef uint16_t u16; typedef int32_t s32; typedef uint32_t u32; typedef int64_t s64; typedef uint64_t u64; typedef signed long sL; typedef unsigned long uL; typedef float f32; typedef double f64; #if !defined(__OpenBSD__) typedef unsigned long ulong; #endif typedef void* pointer; typedef void* P; #define GVAR(T) \ extern T gvar_##T; \ T gvar_##T = (T) -1; \ T gvar_##T##_get() { return gvar_##T; }; \ void gvar_##T##_set(T v) { gvar_##T = v; } GVAR(s8); GVAR(u8); GVAR(s16); GVAR(u16); GVAR(s32); GVAR(u32); GVAR(s64); GVAR(u64); GVAR(long); GVAR(ulong); GVAR(pointer); struct gstruct { long data; }; struct gstruct gvar_gstruct = { -1 }; struct gstruct* gvar_gstruct_get(void) { return &gvar_gstruct; } void gvar_gstruct_set(const struct gstruct* val) { gvar_gstruct = *val; } jnr-ffi-jnr-ffi-2.1.7/libtest/LastErrorTest.c000066400000000000000000000015041316720554100210000ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #ifdef _WIN32 #include #endif int setLastError(int error) { #ifdef _WIN32 SetLastError(error); #else errno = error; #endif return -1; } jnr-ffi-jnr-ffi-2.1.7/libtest/NumberTest.c000066400000000000000000000036101316720554100203130ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #ifndef __mips__ # include #endif #if !defined(_STDINT_H) && !defined(_SYS__STDINT_H_) typedef signed char int8_t; typedef signed short int16_t; typedef signed int int32_t; typedef signed long long int64_t; typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; typedef unsigned long long uint64_t; #endif typedef char Signed8; typedef short Signed16; typedef int Signed32; typedef long long Signed64; typedef float Float32; typedef double Float64; typedef long SignedLong; typedef void* pointer; typedef unsigned long ulong; #define ADD(T) T add_##T(T arg1, T arg2) { return arg1 + arg2; } #define SUB(T) T sub_##T(T arg1, T arg2) { return arg1 - arg2; } #define MUL(T) T mul_##T(T arg1, T arg2) { return arg1 * arg2; } #define DIV(T) T div_##T(T arg1, T arg2) { return arg1 / arg2; } #define RET(T) T ret_##T(T arg1) { return arg1; } typedef char* ptr; #define TEST(T) ADD(T) SUB(T) MUL(T) DIV(T) RET(T) TEST(int8_t); TEST(int16_t); TEST(int32_t); TEST(int64_t); TEST(uint8_t); TEST(uint16_t); TEST(uint32_t); TEST(uint64_t); TEST(float); TEST(double); TEST(long); TEST(ulong); TEST(Signed8); TEST(Signed16); TEST(Signed32); TEST(Signed64); TEST(SignedLong); TEST(Float32); TEST(Float64); RET(pointer); jnr-ffi-jnr-ffi-2.1.7/libtest/PointerTest.c000066400000000000000000000051051316720554100205040ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #ifndef __mips__ # include #endif #include #include #include typedef void* ptr; typedef void* pointer; #ifdef _WIN32 typedef char* caddr_t; #endif #if !defined(_STDINT_H) && !defined(_SYS__STDINT_H_) typedef signed char int8_t; typedef signed short int16_t; typedef signed int int32_t; typedef signed long long int64_t; #endif #define RET(T) T ptr_ret_##T(void* arg1, int offset) { \ T tmp; memcpy(&tmp, (caddr_t) arg1 + offset, sizeof(tmp)); return tmp; \ } #define SET(T) void ptr_set_##T(void* arg1, int offset, T value) { \ memcpy((caddr_t) arg1 + offset, &value, sizeof(value)); \ } #define TEST(T) SET(T) RET(T) TEST(int8_t); TEST(int16_t); TEST(int32_t); TEST(int64_t); TEST(float); TEST(double); TEST(pointer); void* ptr_return_array_element(void **ptrArray, int arrayIndex) { return ptrArray[arrayIndex]; } void ptr_set_array_element(void **ptrArray, int arrayIndex, void *value) { ptrArray[arrayIndex] = value; } void* ptr_from_buffer(void* ptr) { return ptr; } void* ptr_malloc(int size) { void* ptr = malloc(size); memset(ptr, 0, size); return ptr; } void ptr_free(void* ptr) { free(ptr); } #define swap(p1, p2) do { typeof(*p1) tmp__ = *p1; *p1 = *p2; *p2 = tmp__; } while (0) void ptr_reverse_l6(long* l1, long* l2, long* l3, long* l4, long* l5, long* l6) { swap(l1, l6); swap(l2, l5); swap(l3, l4); } void ptr_reverse_l5(long* l1, long* l2, long* l3, long* l4, long* l5) { swap(l1, l5); (void)(l3); swap(l2, l4); } void ptr_rotate_l5(long* l1, long* l2, long* l3, long* l4, long* l5) { long tmp = *l1; swap(l5, l1); swap(l4, l5); swap(l3, l4); swap(l2, l3); *l2 = tmp; } void ptr_rotate_l6(long* l1, long* l2, long* l3, long* l4, long* l5, long* l6) { long t = *l1; swap(l6, l1); swap(l5, l6); swap(l4, l5); swap(l3, l4); swap(l2, l3); *l2 = t; } jnr-ffi-jnr-ffi-2.1.7/libtest/ReferenceTest.c000066400000000000000000000026221316720554100207630ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef __mips__ # include #endif #if !defined(_STDINT_H) && !defined(_SYS__STDINT_H_) typedef signed char int8_t; typedef signed short int16_t; typedef signed int int32_t; typedef signed long long int64_t; #endif #define REF(T) void ref_##T(T arg, T* result) { *result = arg; } #define ADD(T) void ref_add_##T(T arg1, T arg2, T* result) { *result = arg1 + arg2; } #define SUB(T) void ref_sub_##T(T arg1, T arg2, T* result) { *result = arg1 - arg2; } #define MUL(T) void ref_mul_##T(T arg1, T arg2, T* result) { *result = arg1 * arg2; } #define DIV(T) void ref_div_##T(T arg1, T arg2, T* result) { *result = arg1 / arg2; } #define TEST(T) ADD(T) SUB(T) MUL(T) DIV(T) REF(T) TEST(int8_t); TEST(int16_t); TEST(int32_t); TEST(int64_t); TEST(float); TEST(double); jnr-ffi-jnr-ffi-2.1.7/libtest/StringTest.c000066400000000000000000000017711316720554100203370ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include int string_equals(const char* s1, const char* s2) { return strcmp(s1, s2) == 0; } void string_set(char* s1, const char* s2) { strcpy(s1, s2); } void string_concat(char* dst, const char* src) { char* ep = dst; while (*ep) ep++; strcpy(ep, src); } char* string_duplicate(const char* s1) { return strdup(s1); } jnr-ffi-jnr-ffi-2.1.7/libtest/StructTest.c000077500000000000000000000321461316720554100203600ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include typedef char Signed8; typedef short Signed16; typedef int Signed32; typedef long long Signed64; typedef float Float32; typedef double Float64; typedef long SignedLong; struct test1 { char b; short s; int i; long long j; SignedLong l; float f; double d; char string[32]; }; #define T(x, type) \ type struct_field_##type(struct test1* t) { return t->x; } \ struct type##Align { char first; type value; }; \ type struct_align_##type(struct type##Align* a) { return a->value; } T(b, Signed8); T(s, Signed16); T(i, Signed32); T(j, Signed64); T(f, Float32); T(d, Float64); long struct_field_SignedLong(struct test1* t) { return t->l; } struct SignedLongAlign { char first; SignedLong value; }; long struct_align_SignedLong(struct SignedLongAlign* a) { return a->value; } void struct_set_string(struct test1* t, char* s) { strcpy(t->string, s); } struct test1* struct_make_struct(char b, short s, int i, long long ll, float f, double d) { static struct test1 t; memset(&t, 0, sizeof(t)); t.b = b; t.s = s; t.i = i; t.j = ll; t.f = f; t.d = d; return &t; } struct foo { unsigned long l1,l2, l3; }; int fill_struct_from_longs(unsigned long l1, unsigned long l2, struct foo* s, unsigned long l3) { s->l1 = l1; s->l2 = l2; s->l3 = l3; return 0; } #define STRUCT_ALIGNMENT(alignment) \ struct StructAlignment##alignment { \ uint8_t f0; \ uint16_t f1; \ uint32_t f2; \ uint64_t f3; \ void *f4; \ }; \ \ int struct_alignment_size_##alignment() { \ return sizeof(struct StructAlignment##alignment); \ } \ \ int struct_alignment_field_offset_##alignment(int field) { \ switch(field) { \ case 0: \ return offsetof(struct StructAlignment##alignment, f0); \ case 1: \ return offsetof(struct StructAlignment##alignment, f1); \ case 2: \ return offsetof(struct StructAlignment##alignment, f2); \ case 3: \ return offsetof(struct StructAlignment##alignment, f3); \ case 4: \ return offsetof(struct StructAlignment##alignment, f4); \ default: \ return -1; \ } \ } \ \ struct InnerStructAlignment1_##alignment { \ uint8_t f0; \ uint16_t f1; \ uint32_t f2; \ uint64_t f3; \ void *f4; \ struct InnerStructAlignment2_##alignment { \ uint8_t f0; \ uint16_t f1; \ uint32_t f2; \ uint64_t f3; \ void *f4; \ struct InnerStructAlignment3_##alignment { \ uint8_t f0; \ uint16_t f1; \ uint32_t f2; \ uint64_t f3; \ void *f4; \ } f5; \ } f5; \ }; \ \ int inner_struct_alignment_size_##alignment() { \ return sizeof(struct InnerStructAlignment1_##alignment); \ } \ \ int inner_struct_alignment_field_offset_##alignment(int level, int field) { \ switch(field) { \ case 0: \ switch(level) { \ case 0: \ return offsetof(struct InnerStructAlignment1_##alignment, f0); \ case 1: \ return offsetof(struct InnerStructAlignment1_##alignment, f5.f0); \ case 2: \ return offsetof(struct InnerStructAlignment1_##alignment, f5.f5.f0); \ default: \ return -1; \ } \ case 1: \ switch(level) { \ case 0: \ return offsetof(struct InnerStructAlignment1_##alignment, f1); \ case 1: \ return offsetof(struct InnerStructAlignment1_##alignment, f5.f1); \ case 2: \ return offsetof(struct InnerStructAlignment1_##alignment, f5.f5.f1); \ default: \ return -1; \ } \ case 2: \ switch(level) { \ case 0: \ return offsetof(struct InnerStructAlignment1_##alignment, f2); \ case 1: \ return offsetof(struct InnerStructAlignment1_##alignment, f5.f2); \ case 2: \ return offsetof(struct InnerStructAlignment1_##alignment, f5.f5.f2); \ default: \ return -1; \ } \ case 3: \ switch(level) { \ case 0: \ return offsetof(struct InnerStructAlignment1_##alignment, f3); \ case 1: \ return offsetof(struct InnerStructAlignment1_##alignment, f5.f3); \ case 2: \ return offsetof(struct InnerStructAlignment1_##alignment, f5.f5.f3); \ default: \ return -1; \ } \ case 4: \ switch(level) { \ case 0: \ return offsetof(struct InnerStructAlignment1_##alignment, f4); \ case 1: \ return offsetof(struct InnerStructAlignment1_##alignment, f5.f4); \ case 2: \ return offsetof(struct InnerStructAlignment1_##alignment, f5.f5.f4); \ default: \ return -1; \ } \ case 5: \ switch(level) { \ case 0: \ return offsetof(struct InnerStructAlignment1_##alignment, f5); \ case 1: \ return offsetof(struct InnerStructAlignment1_##alignment, f5.f5); \ default: \ return -1; \ } \ default: \ return -1; \ } \ } #pragma pack(push, 1) STRUCT_ALIGNMENT(1) #pragma pack(pop) #pragma pack(push, 2) STRUCT_ALIGNMENT(2) #pragma pack(pop) #pragma pack(push, 4) STRUCT_ALIGNMENT(4) #pragma pack(pop) #pragma pack(push, 8) STRUCT_ALIGNMENT(8) #pragma pack(pop) #pragma pack(push, 16) STRUCT_ALIGNMENT(16) #pragma pack(pop) jnr-ffi-jnr-ffi-2.1.7/mvnw000077500000000000000000000156431316720554100153370ustar00rootroot00000000000000#!/bin/sh # ---------------------------------------------------------------------------- # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # ---------------------------------------------------------------------------- # ---------------------------------------------------------------------------- # Maven2 Start Up Batch script # # Required ENV vars: # ------------------ # JAVA_HOME - location of a JDK home dir # # Optional ENV vars # ----------------- # M2_HOME - location of maven2's installed home dir # MAVEN_OPTS - parameters passed to the Java VM when running Maven # e.g. to debug Maven itself, use # set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 # MAVEN_SKIP_RC - flag to disable loading of mavenrc files # ---------------------------------------------------------------------------- if [ -z "$MAVEN_SKIP_RC" ] ; then if [ -f /etc/mavenrc ] ; then . /etc/mavenrc fi if [ -f "$HOME/.mavenrc" ] ; then . "$HOME/.mavenrc" fi fi # OS specific support. $var _must_ be set to either true or false. cygwin=false; darwin=false; mingw=false case "`uname`" in CYGWIN*) cygwin=true ;; MINGW*) mingw=true;; Darwin*) darwin=true # # Look for the Apple JDKs first to preserve the existing behaviour, and then look # for the new JDKs provided by Oracle. # if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then # # Apple JDKs # export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home fi if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then # # Apple JDKs # export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home fi if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then # # Oracle JDKs # export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home fi if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then # # Apple JDKs # export JAVA_HOME=`/usr/libexec/java_home` fi ;; esac if [ -z "$JAVA_HOME" ] ; then if [ -r /etc/gentoo-release ] ; then JAVA_HOME=`java-config --jre-home` fi fi if [ -z "$M2_HOME" ] ; then ## resolve links - $0 may be a link to maven's home PRG="$0" # need this for relative symlinks while [ -h "$PRG" ] ; do ls=`ls -ld "$PRG"` link=`expr "$ls" : '.*-> \(.*\)$'` if expr "$link" : '/.*' > /dev/null; then PRG="$link" else PRG="`dirname "$PRG"`/$link" fi done saveddir=`pwd` M2_HOME=`dirname "$PRG"`/.. # make it fully qualified M2_HOME=`cd "$M2_HOME" && pwd` cd "$saveddir" # echo Using m2 at $M2_HOME fi # For Cygwin, ensure paths are in UNIX format before anything is touched if $cygwin ; then [ -n "$M2_HOME" ] && M2_HOME=`cygpath --unix "$M2_HOME"` [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` [ -n "$CLASSPATH" ] && CLASSPATH=`cygpath --path --unix "$CLASSPATH"` fi # For Migwn, ensure paths are in UNIX format before anything is touched if $mingw ; then [ -n "$M2_HOME" ] && M2_HOME="`(cd "$M2_HOME"; pwd)`" [ -n "$JAVA_HOME" ] && JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" # TODO classpath? fi if [ -z "$JAVA_HOME" ]; then javaExecutable="`which javac`" if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then # readlink(1) is not available as standard on Solaris 10. readLink=`which readlink` if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then if $darwin ; then javaHome="`dirname \"$javaExecutable\"`" javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" else javaExecutable="`readlink -f \"$javaExecutable\"`" fi javaHome="`dirname \"$javaExecutable\"`" javaHome=`expr "$javaHome" : '\(.*\)/bin'` JAVA_HOME="$javaHome" export JAVA_HOME fi fi fi if [ -z "$JAVACMD" ] ; then if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables JAVACMD="$JAVA_HOME/jre/sh/java" else JAVACMD="$JAVA_HOME/bin/java" fi else JAVACMD="`which java`" fi fi if [ ! -x "$JAVACMD" ] ; then echo "Error: JAVA_HOME is not defined correctly." >&2 echo " We cannot execute $JAVACMD" >&2 exit 1 fi if [ -z "$JAVA_HOME" ] ; then echo "Warning: JAVA_HOME environment variable is not set." fi CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher # For Cygwin, switch paths to Windows format before running java if $cygwin; then [ -n "$M2_HOME" ] && M2_HOME=`cygpath --path --windows "$M2_HOME"` [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` [ -n "$CLASSPATH" ] && CLASSPATH=`cygpath --path --windows "$CLASSPATH"` fi # traverses directory structure from process work directory to filesystem root # first directory with .mvn subdirectory is considered project base directory find_maven_basedir() { local basedir=$(pwd) local wdir=$(pwd) while [ "$wdir" != '/' ] ; do if [ -d "$wdir"/.mvn ] ; then basedir=$wdir break fi wdir=$(cd "$wdir/.."; pwd) done echo "${basedir}" } # concatenates all lines of a file concat_lines() { if [ -f "$1" ]; then echo "$(tr -s '\n' ' ' < "$1")" fi } export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)} MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" # Provide a "standardized" way to retrieve the CLI args that will # work with both Windows and non-Windows executions. MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" export MAVEN_CMD_LINE_ARGS WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain exec "$JAVACMD" \ $MAVEN_OPTS \ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ ${WRAPPER_LAUNCHER} $MAVEN_CMD_LINE_ARGS jnr-ffi-jnr-ffi-2.1.7/pom.xml000066400000000000000000000177571316720554100157470ustar00rootroot00000000000000 4.0.0 org.sonatype.oss oss-parent 7 com.github.jnr jnr-ffi jar 2.1.7 jnr-ffi A library for invoking native functions from java http://github.com/jnr/jnr-ffi The Apache Software License, Version 2.0 http://www.apache.org/licenses/LICENSE-2.0.txt repo scm:git:git@github.com:jnr/jnr-ffi.git scm:git:git@github.com:jnr/jnr-ffi.git git@github.com:jnr/jnr-ffi.git HEAD wmeissner Wayne Meissner wmeissner@gmail.com headius Charles Oliver Nutter headius@headius.com UTF-8 1.6 1.6 github 5.0.3 make junit junit 4.11 test com.github.jnr jffi 1.2.16 compile com.github.jnr jffi 1.2.16 runtime native org.ow2.asm asm ${asm.version} compile org.ow2.asm asm-commons ${asm.version} compile org.ow2.asm asm-analysis ${asm.version} compile org.ow2.asm asm-tree ${asm.version} compile org.ow2.asm asm-util ${asm.version} compile com.github.jnr jnr-x86asm 1.0.2 compile maven-antrun-plugin 1.1 test-compile run org.apache.felix maven-bundle-plugin 2.3.7 <_nouses>true bundle-manifest process-classes manifest org.apache.maven.plugins maven-jar-plugin 2.3.1 ${project.build.outputDirectory}/META-INF/MANIFEST.MF org.apache.maven.plugins maven-surefire-plugin 2.4.2 jnr.ffi.library.path ${project.build.directory} com.github.github site-maven-plugin 0.6 Creating site for ${project.version} site site org.apache.maven.plugins maven-javadoc-plugin 2.9.1 attach-javadocs jar org.apache.maven.plugins maven-source-plugin 2.2.1 attach-sources jar release-sign-artifacts performRelease true org.apache.maven.plugins maven-gpg-plugin 1.4 sign-artifacts verify sign org.apache.maven.plugins maven-javadoc-plugin 2.8 jnr.ffi.provider:jnr.ffi.util jnr-ffi-jnr-ffi-2.1.7/src/000077500000000000000000000000001316720554100152005ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/000077500000000000000000000000001316720554100161245ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/000077500000000000000000000000001316720554100170455ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/000077500000000000000000000000001316720554100176365ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/000077500000000000000000000000001316720554100204025ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/Address.java000066400000000000000000000145601316720554100226400ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; /** * The {@code Address} class wraps a native address in an object. Both 32 bit and 64 * bit native address values are wrapped in a singular {@code Address} type. * *

This class extends {@link java.lang.Number} and implements all {@code Number} methods for * converting to primitive integer types. * *

An {@code Address} instance is lighter weight than most {@link Pointer} * instances, and may be used when a native address needs to be stored in java, * but no other operations (such as reading/writing values) need be performed on * the native memory. For most cases, a {@link Pointer} offers more flexibility * and should be preferred instead. */ public final class Address extends Number implements Comparable

{ /** A global instance of this class representing the C NULL value */ private static final Address NULL = new Address(0L); /** The native numeric value of this {@code Address} */ private final long address; /** * Creates a new address representation. * * @param address the native address. */ private Address(long address) { this.address = address; } /** * Creates a new address representation. * * @param address the native address. */ public Address(final Address address) { this.address = address.address; } /** * Gets the native memory address represented by this {@code Address} as a {@code long} integer. * * @return the native memory address */ public final long address() { return address; } /** * Returns the value of this {@code Address} as an {@code int}. * On 64bit systems, this will result in the upper 32bits of the address being truncated. * * @return the numeric value of this {@code Address} after conversion to an {@code int}. */ @Override public final int intValue() { return (int) address; } /** * Returns the value of this {@code Address} as a {@code long}. * * @return the numeric value of this {@code Address} after conversion to a {@code long}. */ @Override public final long longValue() { return address; } /** * Returns the value of this {@code Address} as a {@code float}. * * This method is not particularly useful, and is here to fulfill the {@link java.lang.Number} interface contract. * * @return the numeric value of this {@code Address} after conversion to a {@code float}. */ @Override public final float floatValue() { return (float) address; } /** * Returns the value of this {@code Address} as a {@code double}. * * This method is not particularly useful, and is here to fulfill the {@link java.lang.Number} interface contract. * * @return the numeric value of this {@code Address} after conversion to a {@code double}. */ @Override public final double doubleValue() { return (double) address; } /** * Returns the native value of this address. * * @return an {@code long} value representing the native value of this address. */ public final long nativeAddress() { return address; } /** * Returns a hash code for this {@code Address}. * * @return a hash code for this {@code Address}. */ @Override public final int hashCode() { return (int)(address ^ (address >>> 32)); } /** * Compares this address to another address. * * @param obj the other address to compare to. * @return {@code true} if this Address is equal to the other address, else false. */ @Override public final boolean equals(Object obj) { return ((obj instanceof Address) && address == ((Address) obj).address) || (obj == null && address == 0); } /** * Returns a {@code String} object representing this {@code Address} as a decimal value. * * @return a string representation of this {@code Address}. */ @Override public final String toString() { return Long.toString(address, 10); } /** * Returns a {@code String} object representing this {@code Address} as a hex value. * * @return a string representation of this {@code Address}. */ public final String toHexString() { return Long.toString(address, 16); } /** * Compares two {@code Address} instances numerically. * * @param other the other Address to compare to. * @return {@code 0} if {@code other} is equal to this instance, -1 if this * instance is numerically less than {@code other} or 1 if this instance is * numerically greater than {@code other}. */ public final int compareTo(Address other) { return address < other.address ? -1 : address > other.address ? 1 : 0; } /** * Tests if this Address is equivalent to C NULL * * @return true if the address is 0 */ public final boolean isNull() { return address == 0; } /** * Returns a Address instance representing the specified {@code long} value. * * @param address a {@code long} value * @return an {@code Address} instance representing {@code address} */ public static Address valueOf(long address) { return address == 0 ? NULL : new Address(address); } /** * Returns a Address instance representing the specified {@code int} value. * * @param address an {@code int} value * @return an {@code Address} instance representing {@code address} */ public static Address valueOf(int address) { return address == 0 ? NULL : new Address((long) address & 0xffffffffL); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/CallingConvention.java000066400000000000000000000017621316720554100246670ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; /** * Native function calling conventions. * *

This is only needed on windows platforms - all platforms assume * {@link #DEFAULT} as the calling convention. */ public enum CallingConvention { /** * The default C calling convention */ DEFAULT, /** * Windows stdcall calling convention */ STDCALL } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/LastError.java000066400000000000000000000025231316720554100231640ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; /** * Provides access to the unix errno and windows GetLastError() value. */ public final class LastError { private LastError() {} /** * Gets the value of errno from the last native call. * * @param runtime FFI runtime to get errno for. * @return An integer containing the errno value. */ public static int getLastError(Runtime runtime) { return runtime.getLastError(); } /** * Sets the native errno value. * * @param runtime FFI runtime to set errno for. * @param error The value to set errno to. */ public static void setLastError(Runtime runtime, int error) { runtime.setLastError(error); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/Library.java000066400000000000000000000146151316720554100226600ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; import jnr.ffi.provider.FFIProvider; import jnr.ffi.provider.LoadedLibrary; import java.io.File; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; /** * @deprecated Use {@link LibraryLoader} instead. */ public final class Library { private static final Map> customSearchPaths = new ConcurrentHashMap>(); /** The name of this library */ private final String name; private Library(String libraryName) { name = libraryName; } /** * Gets the {@link Runtime} that loaded the library interface. * * @deprecated Use {@link Runtime#getRuntime(Object)} * @param library A library implementation as returned from {@link LibraryLoader#load()} * @return The runtime that loaded the library. */ public static Runtime getRuntime(Object library) { return ((LoadedLibrary) library).getRuntime(); } /** * Loads a native library and links the methods defined in {@code interfaceClass} * to native methods in the library. * * @deprecated see {@link LibraryLoader} for the preferred interface to loading libraries. * @param the interface class. * @param libraryName the name of the library to load * @param interfaceClass the interface that describes the native library interface * @return an instance of {@code interfaceclass} that will call the native methods. */ public static T loadLibrary(String libraryName, Class interfaceClass) { return loadLibrary(interfaceClass, libraryName); } /** * Loads a native library and links the methods defined in {@code interfaceClass} * to native methods in the library. * * @deprecated see {@link LibraryLoader} for the preferred interface to loading libraries. * @param the interface type. * @param libraryNames the name of the library to load * @param interfaceClass the interface that describes the native library interface * @return an instance of {@code interfaceclass} that will call the native methods. */ public static T loadLibrary(Class interfaceClass, String... libraryNames) { final Map options = Collections.emptyMap(); return loadLibrary(interfaceClass, options, libraryNames); } /** * Loads a native library and links the methods defined in {@code interfaceClass} * to native methods in the library. * * @deprecated see {@link LibraryLoader} for the preferred interface to loading libraries. * @param the interface type. * @param libraryName the name of the library to load * @param interfaceClass the interface that describes the native library interface * @param libraryOptions options * @return an instance of {@code interfaceclass} that will call the native methods. */ public static T loadLibrary(String libraryName, Class interfaceClass, Map libraryOptions) { return loadLibrary(interfaceClass, libraryOptions, libraryName); } /** * Loads a native library and links the methods defined in {@code interfaceClass} * to native methods in the library. * * @deprecated see {@link LibraryLoader} for the preferred interface to loading libraries. * @param the interface type. * @param libraryNames the name of the library to load * @param interfaceClass the interface that describes the native library interface * @param libraryOptions options * @return an instance of {@code interfaceclass} that will call the native methods. */ public static T loadLibrary(Class interfaceClass, Map libraryOptions, String... libraryNames) { LibraryLoader loader = FFIProvider.getSystemProvider().createLibraryLoader(interfaceClass); for (String libraryName : libraryNames) { loader.library(libraryName); for (String path : getLibraryPath(libraryName)) { loader.search(path); } } for (Map.Entry option : libraryOptions.entrySet()) { loader.option(option.getKey(), option.getValue()); } return loader.failImmediately().load(); } /** * Adds a custom search path for a library * * @deprecated see {@link LibraryLoader} for the preferred interface to loading libraries. * @param libraryName the name of the library to search for * @param path the path to search for the library in */ public static synchronized void addLibraryPath(String libraryName, File path) { List customPaths = customSearchPaths.get(libraryName); if (customPaths == null) { customPaths = new CopyOnWriteArrayList(); customSearchPaths.put(libraryName, customPaths); } customPaths.add(path.getAbsolutePath()); } /** * Gets the custom search path for a library. * * @deprecated see {@link LibraryLoader} for the preferred interface to loading libraries. * @param libraryName The library to retrieve the path for. * @return A List of String instances. */ public static List getLibraryPath(String libraryName) { List customPaths = customSearchPaths.get(libraryName); if (customPaths != null) { return customPaths; } return Collections.emptyList(); } @Deprecated public static Library getInstance(String libraryName) { return new Library(libraryName); } @Deprecated public String getName() { return name; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/LibraryLoader.java000066400000000000000000000400311316720554100237760ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; import jnr.ffi.mapper.*; import jnr.ffi.provider.FFIProvider; import jnr.ffi.provider.LoadedLibrary; import jnr.ffi.provider.NativeInvocationHandler; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.*; /** * Loads a native library and maps it to a java interface. * *

Example usage

*
 * {@code
 *
 * public interface LibC {
 *    int puts(String str);
 * }
 *
 * LibC libc = LibraryLoader.create(LibC.class).load("c");
 *
 * libc.puts("Hello, World");
 *
 * }
 * 
*/ public abstract class LibraryLoader { private final List searchPaths = new ArrayList(); private final List libraryNames = new ArrayList(); private final List typeMappers = new ArrayList(); private final List functionMappers = new ArrayList(); private final Map optionMap = new EnumMap(LibraryOption.class); private final TypeMapper.Builder typeMapperBuilder = new TypeMapper.Builder(); private final FunctionMapper.Builder functionMapperBuilder = new FunctionMapper.Builder(); private final Class interfaceClass; private boolean failImmediately = false; /** * Creates a new {@code LibraryLoader} instance. * * @param The library type. * @param interfaceClass the interface that describes the native library functions * @return A {@code LibraryLoader} instance. */ public static LibraryLoader create(Class interfaceClass) { return FFIProvider.getSystemProvider().createLibraryLoader(interfaceClass); } protected LibraryLoader(Class interfaceClass) { this.interfaceClass = interfaceClass; } /** * When either the {@link jnr.ffi.annotations.SaveError} or * {@link jnr.ffi.annotations.IgnoreError} annotations are used, the * following matrix applies: * * (SL = save at library level, IM = ignore at method level, etc) * *
     *         | none |  SL  |  IL  | SL+IL|
     * -------------------------------------
     * none    | save | save | ignr | save |
     * SM      | save | save | save | save |
     * IM      | ignr | ignr | ignr | ignr |
     * SM + IM | save | save | save | save |
     * 
*/ public static boolean saveError(Map options, boolean methodHasSave, boolean methodHasIgnore) { // default to save boolean saveError = options.containsKey(LibraryOption.SaveError) || !options.containsKey(LibraryOption.IgnoreError); // toggle only according to above matrix if (saveError) { if (methodHasIgnore && !methodHasSave) { saveError = false; } } else { if (methodHasSave) { saveError = true; } } return saveError; } /** * Adds a library to be loaded. Multiple libraries can be specified using additional calls * to this method, and all libraries will be searched to resolve symbols (e.g. functions, variables). * * @param libraryName The name or path of library to load. * @return The {@code LibraryLoader} instance. */ public LibraryLoader library(String libraryName) { this.libraryNames.add(libraryName); return this; } /** * Adds a path to search for libraries. Multiple paths can be specified using multiple calls * to this method, and all paths will be searched.. * * @param path A directory to search. * @return The {@code LibraryLoader} instance. */ public LibraryLoader search(String path) { searchPaths.add(path); return this; } /** * Sets an option when loading libraries. * * @see LibraryOption * * @param option The option to set. * @param value The value for the option. * @return The {@code LibraryLoader} instance. */ public LibraryLoader option(LibraryOption option, Object value) { switch (option) { case TypeMapper: if (value instanceof SignatureTypeMapper) { mapper((SignatureTypeMapper) value); } else if (value instanceof TypeMapper) { mapper((TypeMapper) value); } else if (value != null) { throw new IllegalArgumentException("invalid TypeMapper: " + value.getClass()); } break; case FunctionMapper: mapper((FunctionMapper) value); break; default: optionMap.put(option, value); } return this; } /** * Adds a type mapper to use when resolving method parameter and result types. * * Multiple type mappers can be specified by additional calls to this method, and * each mapper will be tried in order until one is successful. * * @param typeMapper The type mapper to use. * @return The {@code LibraryLoader} instance. */ public LibraryLoader mapper(TypeMapper typeMapper) { typeMappers.add(new SignatureTypeMapperAdapter(typeMapper)); return this; } /** * Adds a type mapper to use when resolving method parameter and result types. * * Multiple type mappers can be specified by additional calls to this method, and * each mapper will be tried in order until one is successful. * * @param typeMapper The type mapper to use. * @return The {@code LibraryLoader} instance. */ public LibraryLoader mapper(SignatureTypeMapper typeMapper) { typeMappers.add(typeMapper); return this; } /** * Adds a custom java type mapping. * * @param The Java type. * @param javaType The java type to convert to a native type. * @param toNativeConverter A {@link jnr.ffi.mapper.ToNativeConverter} that will convert from the java type to a native type. * @return The {@code LibraryLoader} instance. */ public LibraryLoader map(Class javaType, ToNativeConverter toNativeConverter) { typeMapperBuilder.map(javaType, toNativeConverter); return this; } /** * Adds a custom java type mapping. * * @param The Java type. * @param javaType The java type to convert to a native type. * @param fromNativeConverter A {@link jnr.ffi.mapper.ToNativeConverter} that will convert from the native type to a java type. * @return The {@code LibraryLoader} instance. */ public LibraryLoader map(Class javaType, FromNativeConverter fromNativeConverter) { typeMapperBuilder.map(javaType, fromNativeConverter); return this; } public LibraryLoader map(Class javaType, DataConverter dataConverter) { typeMapperBuilder.map(javaType, dataConverter); return this; } /** * Adds a function mapper to use when resolving symbols in this library. * * Multiple function mappers can be specified by additional calls to this method, and * each mapper will be tried in order, until one is successful. * * @param functionMapper The function mapper to use. * @return The {@code LibraryLoader} instance. */ public LibraryLoader mapper(FunctionMapper functionMapper) { functionMappers.add(functionMapper); return this; } /** * Adds a function name mapping to use when resolving symbols in this library. * * @param javaName The java method name. * @param nativeFunction The native library symbol to map the java method name to. * @return The {@code LibraryLoader} instance. */ public LibraryLoader map(String javaName, String nativeFunction) { functionMapperBuilder.map(javaName, nativeFunction); return this; } /** * Sets the native function calling convention. * *

This is only needed on windows platforms - unless explicitly specified, all platforms assume * {@link CallingConvention#DEFAULT} as the calling convention. * * @param convention The calling convention. * @return The {@code LibraryLoader} instance. */ public LibraryLoader convention(CallingConvention convention) { optionMap.put(LibraryOption.CallingConvention, convention); return this; } /** * Sets the calling convention of the library to the Windows stdcall calling convention * * @return This {@code LibraryLoader} instance. */ public final LibraryLoader stdcall() { return convention(CallingConvention.STDCALL); } /** * Turns off lazy propagation of load failures. By default, {@link jnr.ffi.LibraryLoader#load()} will not fail * immediately if any libraries cannot be loaded - instead, it will create an instance of the library interface * that re-throws any load errors when invoked. * * Calling this method will make {@link jnr.ffi.LibraryLoader#load()} throw errors immediately. * * @return This {@code LibraryLoader} instance. */ public final LibraryLoader failImmediately() { failImmediately = true; return this; } /** * Loads a native library and links the methods defined in {@code interfaceClass} * to native methods in the library. * * @param libraryName The name or path of library to load. * @return an implementation of the interface provided to {@link #create(Class)} that will call the native methods. */ public T load(String libraryName) { return library(libraryName).load(); } /** * Loads a native library and links the methods defined in {@code interfaceClass} * to native methods in the library. * * @return an implementation of the interface provided to {@link #create(Class)} that will call the native methods. */ public T load() { if (libraryNames.isEmpty()) { throw new UnsatisfiedLinkError("no library names specified"); } typeMappers.add(0, new SignatureTypeMapperAdapter(typeMapperBuilder.build())); optionMap.put(LibraryOption.TypeMapper, typeMappers.size() > 1 ? new CompositeTypeMapper(typeMappers) : typeMappers.get(0)); functionMappers.add(0, functionMapperBuilder.build()); optionMap.put(LibraryOption.FunctionMapper, functionMappers.size() > 1 ? new CompositeFunctionMapper(functionMappers) : functionMappers.get(0)); try { return loadLibrary(interfaceClass, Collections.unmodifiableList(libraryNames), getSearchPaths(), Collections.unmodifiableMap(optionMap)); } catch (LinkageError error) { if (failImmediately) throw error; return createErrorProxy(error); } catch (Exception ex) { RuntimeException re = ex instanceof RuntimeException ? (RuntimeException) ex : new RuntimeException(ex); if (failImmediately) throw re; return createErrorProxy(re); } } private T createErrorProxy(final Throwable ex) { return interfaceClass.cast(Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class[] { interfaceClass, LoadedLibrary.class }, new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { throw ex; } }) ); } private Collection getSearchPaths() { List paths = new ArrayList(searchPaths); paths.addAll(StaticDataHolder.USER_LIBRARY_PATH); return Collections.unmodifiableList(paths); } /** * Implemented by FFI providers to load the actual library. * * @param interfaceClass The java class that describes the functions to be mapped. * @param libraryNames A list of libraries to load and search for symbols. * @param searchPaths The paths to search for libraries to be loaded. * @param options The options to apply when loading the library. * @return an instance of {@code interfaceClass} that will call the native methods. */ protected abstract T loadLibrary(Class interfaceClass, Collection libraryNames, Collection searchPaths, Map options); private static final class StaticDataHolder { private static final List USER_LIBRARY_PATH; private static void addPaths(List paths, File file) { if (!file.isFile() || !file.exists()) return; BufferedReader in = null; try { in = new BufferedReader(new FileReader(file)); String line = in.readLine(); while( line != null ) { if (new File(line).exists()) { paths.add(line); } line = in.readLine(); } } catch(IOException ignored) { } finally { if (in != null) { try { in.close(); } catch(IOException ignored) {} } } } static { List paths = new ArrayList(); try { paths.addAll(getPropertyPaths("jnr.ffi.library.path")); paths.addAll(getPropertyPaths("jaffl.library.path")); // Add JNA paths for compatibility paths.addAll(getPropertyPaths("jna.library.path")); paths.addAll(getPropertyPaths("java.library.path")); } catch (Exception ignored) { } switch (Platform.getNativePlatform().getOS()) { case FREEBSD: case OPENBSD: case NETBSD: case LINUX: case ZLINUX: // only for oracle jdk on Linux and non-OSX BSD parse /etc/ld.so.conf and /etc/ld.so.conf.d/* // more details: // https://github.com/jruby/jruby/issues/2913 // https://github.com/jruby/jruby/issues/3145 // https://github.com/elastic/logstash/issues/3127#issuecomment-101068714 File ldSoConf = new File("/etc/ld.so.conf"); File ldSoConfD = new File("/etc/ld.so.conf.d"); if (ldSoConf.exists()) { addPaths(paths, ldSoConf); } if (ldSoConfD.isDirectory()) { for (File file : ldSoConfD.listFiles()) { addPaths(paths, file); } } break; } USER_LIBRARY_PATH = Collections.unmodifiableList(new ArrayList(paths)); } } private static List getPropertyPaths(String propName) { String value = System.getProperty(propName); if (value != null) { String[] paths = value.split(File.pathSeparator); return new ArrayList(Arrays.asList(paths)); } return Collections.emptyList(); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/LibraryOption.java000066400000000000000000000034401316720554100240430ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; import java.util.Map; /** * Options that apply to a library */ public enum LibraryOption { /** * Function calls should save the errno/last error after the call. * This option can be overridden on individual methods by use of the * {@link jnr.ffi.annotations.IgnoreError} annotation. * * @see LibraryLoader#saveError(Map, boolean, boolean) */ SaveError, /** * Function calls should NOT save the errno/last error after the call. * This option can be overridden on individual methods by use of the * {@link jnr.ffi.annotations.SaveError} annotation. * * @see LibraryLoader#saveError(Map, boolean, boolean) */ IgnoreError, /** * A type mapper which maps java types to native types is present. */ TypeMapper, /** * A function mapper which maps from java function names to native function names. */ FunctionMapper, /** * The type of calling convention. * @see CallingConvention */ CallingConvention, /** * Load the library into memory immediately, instead of lazily loading it */ LoadNow } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/Memory.java000066400000000000000000000147711316720554100225270ustar00rootroot00000000000000/* * Copyright (C) 2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; /** * A utility for allocating memory that can be passed to native functions. */ public final class Memory { private Memory() { } /** * Allocates a new block of java memory and wraps it in a {@link Pointer} * accessor. * * @param runtime The current runtime. * @param size The size in bytes of memory to allocate. * * @return a {@code Pointer} instance that can access the memory. */ public static Pointer allocate(Runtime runtime, int size) { return runtime.getMemoryManager().allocate(size); } /** * Allocates a new block of java memory and wraps it in a {@link Pointer} * accessor. * * @param runtime The current runtime. * @param type The native type to allocate memory for. * * @return a {@code Pointer} instance that can access the memory. */ public static Pointer allocate(Runtime runtime, NativeType type) { return runtime.getMemoryManager().allocate(runtime.findType(type).size()); } /** * Allocates a new block of java memory and wraps it in a {@link Pointer} * accessor. * * @param runtime The current runtime. * @param type The type to allocate memory for. * * @return a {@code Pointer} instance that can access the memory. */ public static Pointer allocate(Runtime runtime, Type type) { return runtime.getMemoryManager().allocate(type.size()); } /** * Allocates a new block of java memory and wraps it in a {@link Pointer} * accessor. * * @param runtime The current runtime. * @param type The type alias to allocate memory for. * * @return a {@code Pointer} instance that can access the memory. */ public static Pointer allocate(Runtime runtime, TypeAlias type) { return runtime.getMemoryManager().allocate(runtime.findType(type).size()); } /** * Allocates a new block of native memory and wraps it in a {@link Pointer} * accessor. * * @param runtime The current runtime. * @param size The size in bytes of memory to allocate. * * @return a {@code Pointer} instance that can access the memory. */ public static Pointer allocateDirect(Runtime runtime, int size) { return runtime.getMemoryManager().allocateDirect(size); } /** * Allocates a new block of native memory and wraps it in a {@link Pointer} * accessor. * * @param runtime The current runtime. * @param type The native type to allocate memory for. * * @return a {@code Pointer} instance that can access the memory. */ public static Pointer allocateDirect(Runtime runtime, NativeType type) { return runtime.getMemoryManager().allocateDirect(runtime.findType(type).size()); } /** * Allocates a new block of native memory and wraps it in a {@link Pointer} * accessor. * * @param runtime The current runtime. * @param type The type alias to allocate memory for. * * @return a {@code Pointer} instance that can access the memory. */ public static Pointer allocateDirect(Runtime runtime, TypeAlias type) { return runtime.getMemoryManager().allocateDirect(runtime.findType(type).size()); } /** * Allocates a new block of native memory and wraps it in a {@link Pointer} * accessor. * * @param runtime The current runtime. * @param size The size in bytes of memory to allocate. * @param clear Whether the memory contents should be cleared, or left as * random data. * * @return a {@code Pointer} instance that can access the memory. */ public static Pointer allocateDirect(Runtime runtime, int size, boolean clear) { return runtime.getMemoryManager().allocateDirect(size, clear); } /** * Allocates a new block of transient native memory and wraps it in a {@link Pointer} * accessor. The memory returned by this method should not be passed to native methods * that store the address for later use, as it may change each time it is passed to native code. * * @param runtime The current runtime. * @param type The native type to allocate memory for. * * @return a {@code Pointer} instance that can access the memory. */ public static Pointer allocateTemporary(Runtime runtime, NativeType type) { return runtime.getMemoryManager().allocateTemporary(runtime.findType(type).size(), true); } /** * Allocates a new block of transient native memory and wraps it in a {@link Pointer} * accessor. The memory returned by this method should not be passed to native methods * that store the address for later use, as it may change each time it is passed to native code. * * @param runtime The current runtime. * @param type The type alias to allocate memory for. * * @return a {@code Pointer} instance that can access the memory. */ public static Pointer allocateTemporary(Runtime runtime, TypeAlias type) { return runtime.getMemoryManager().allocateTemporary(runtime.findType(type).size(), true); } /** * Allocates a new block of transient native memory and wraps it in a {@link Pointer} * accessor. The memory returned by this method should not be passed to native methods * that store the address for later use, as it may change each time it is passed to native code. * * @param runtime The current runtime. * @param type The native type to allocate memory for. * @param clear Whether the memory contents should be cleared, or left as * random data. * * @return a {@code Pointer} instance that can access the memory. */ public static Pointer allocateTemporary(Runtime runtime, NativeType type, boolean clear) { return runtime.getMemoryManager().allocateTemporary(runtime.findType(type).size(), clear); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/NativeLong.java000066400000000000000000000127471316720554100233260ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; /** * Represents a C long. *

* In C, a long can be either 32 bits or 64bits, depending on the platform. *

* Replace any function parameters which are long in the C definition with * a NativeLong. */ public final class NativeLong extends Number implements Comparable { private static final NativeLong ZERO = new NativeLong(0); private static final NativeLong ONE = new NativeLong(1); private static final NativeLong MINUS_ONE = new NativeLong(-1); private final long value; /** * Creates a new NativeLong instance with the supplied value. * * @param value a long or integer. */ public NativeLong(long value) { this.value = value; } /** * Creates a new NativeLong instance with the supplied value. * * @param value an integer. */ public NativeLong(int value) { this.value = value; } /** * Returns an integer representation of this NativeLong. * * @return an integer value for this NativeLong. */ @Override public final int intValue() { return (int) value; } /** * Returns an {@code long} representation of this NativeLong. * * @return an {@code long} value for this NativeLong. */ @Override public final long longValue() { return value; } /** * Returns an {@code float} representation of this NativeLong. * * @return an {@code float} value for this NativeLong. */ @Override public final float floatValue() { return (float) value; } /** * Returns an {@code double} representation of this NativeLong. * * @return an {@code double} value for this NativeLong. */ @Override public final double doubleValue() { return (double) value; } /** * Gets a hash code for this {@code NativeLong}. * * @return a hash code for this {@code NativeLong}. */ @Override public final int hashCode() { return (int)(value ^ (value >>> 32)); } /** * Compares this NativeLong to another NativeLong. * * @param obj the other NativeLong to compare to. * @return {@code true} if this NativeLong is equal to the other * NativeLong, else false. */ @Override public final boolean equals(Object obj) { return ((obj instanceof NativeLong) && value == ((NativeLong) obj).value); } /** * Returns a string representation of this NativeLong. * * @return a string representation of this NativeLong. */ @Override public String toString() { return String.valueOf(value); } /** * Compares two {@code NativeLong} instances numerically. * * @param other the other NativeLong to compare to. * * @return {@code 0} if {@code other} is equal to this instance, -1 if this * instance is numerically less than {@code other} or 1 if this instance is * numerically greater than {@code other}. */ public final int compareTo(NativeLong other) { return value < other.value ? -1 : value > other.value ? 1 : 0; } /** * Internal cache of common native long values */ private static final class Cache { private Cache() {} static final NativeLong[] cache = new NativeLong[256]; static { for (int i = 0; i < cache.length; ++i) { cache[i] = new NativeLong(i - 128); } cache[128 + 0] = ZERO; cache[128 + 1] = ONE; cache[128 - 1] = MINUS_ONE; } } private static NativeLong _valueOf(final long value) { return value >= -128 && value <= 127 ? Cache.cache[128 + (int) value] : new NativeLong(value); } private static NativeLong _valueOf(final int value) { return value >= -128 && value <= 127 ? Cache.cache[128 + value] : new NativeLong(value); } /** * Returns a NativeLong instance representing the specified long value * * @param value a long value * @return a NativeLong instance representing value */ public static NativeLong valueOf(final long value) { return value == 0 ? ZERO : value == 1 ? ONE : value == -1 ? MINUS_ONE : _valueOf(value); } /** * Returns a NativeLong instance representing the specified int value * * @param value a 32bit integer value * @return a NativeLong instance representing value */ public static NativeLong valueOf(final int value) { return value == 0 ? ZERO : value == 1 ? ONE : value == -1 ? MINUS_ONE : _valueOf(value); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/NativeType.java000066400000000000000000000053131316720554100233370ustar00rootroot00000000000000/* * Copyright (C) 2009-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; /** * NativeType defines the primitive types supported internally. * * Usually you will not use these types directly, and should instead use the standard * types such as {@link Pointer}, {@link NativeLong}, or any of the normal java * types such as {@code int}, {@code short}. * * All other types are defined in terms of these primitive types. */ public enum NativeType { /** Void type. Only used for function return types. */ VOID, /** Signed char. Equivalent to a C char or signed char type. Usually 1 byte in size. */ SCHAR, /** Unsigned char. Equivalent to a C unsigned char type. Usually 1 byte in size */ UCHAR, /** Signed short integer. Equivalent to a C short or signed short type. Usually 2 bytes in size. */ SSHORT, /** Unsigned short integer. Equivalent to a C unsigned short type. Usually 2 bytes in size. */ USHORT, /** Signed integer. Equivalent to a C int or signed int type. Usually 4 bytes in size. */ SINT, /** Unsigned integer. Equivalent to a C unsigned int type. Usually 4 bytes in size. */ UINT, /** Signed long integer. Equivalent to a C long or signed long type. Can be either 4 or 8 bytes in size, depending on the platform. */ SLONG, /** Unsigned long integer. Equivalent to a C unsigned long type. Can be either 4 or 8 bytes in size, depending on the platform. */ ULONG, /** Signed long long integer. Equivalent to a C long long or signed long long type. Usually 8 bytes in size. */ SLONGLONG, /** Unsigned long long integer. Equivalent to a C unsigned long long type. Usually 8 bytes in size. */ ULONGLONG, /** Single precision floating point. Equivalent to a C float type. Usually 4 bytes in size. */ FLOAT, /** Double precision floating point. Equivalent to a C double type. Usually 8 bytes in size. */ DOUBLE, /** Native struct type */ STRUCT, /** Native memory address. Equivalent to a C void* or char* pointer type. Can be either 4 or 8 bytes in size, depending on the platform. */ ADDRESS } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/ObjectReferenceManager.java000066400000000000000000000115771316720554100256000ustar00rootroot00000000000000/* * Copyright (C) 2011 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; /** * Provides a mapping between java objects and unique native addresses. * *

* The native addresses generated by this class do not relate to the object's true native address * (since that is not supported by most java virtual machines), but is guaranteed to be unique within * an ObjectReferenceManager instance. *

* This would be commonly used to create a unique native pointer that can be used to retrieve an object * from within a callback. * e.g. *

 *       
 *
 *       public interface MyLib {
 *         public static interface MyCallback {
 *           {@literal @}Delegate public void call(Pointer value);
 *         }
 *
 *         public void do_something_with_callback(MyCallback cb, Pointer cb_argument);
 *       }
 *
 *       MyLib lib = LibraryLoader.create(MyLib.class).load("mylib");
 *       final ObjectReferenceManager referenceManager = Runtime.getRuntime(lib).newObjectReferenceManager();
 *
 *       MyCallback cb = new MyCallback {
 *         public void call(Pointer cb_argument) {
 *           Object javaCallbackArgument = referenceManager.get(cb_argument);
 *           System.out.println("java callback parameter=" + javaCallbackArgument);
 *         }
 *       }
 *
 *       String callbackArgument = "Hello, World";
 *       Pointer cb_argument = referenceManager.add(callback);
 *       lib.do_something_with_callback(cb, cb_argument);
 *       referenceManager.remove(cb_argument);
 *
 *       
 *     
* * Note *

* Each call to {@link #add(Object)} will return a unique native address, even for the same object, so each call to * {@link #add(Object)} must be matched with a call to {@link #remove(Pointer)}. */ public abstract class ObjectReferenceManager { public static ObjectReferenceManager newInstance(Runtime runtime) { return runtime.newObjectReferenceManager(); } /** * Adds a mapping from a java object to a unique native address. * * Each call to this method is guaranteed to produce a memory address unique within the ObjectReferenceManager * instance, even for the same object. * *

* A strong reference to {@code object} is maintained internally, until {@link #remove(Pointer)} is called. *

* * @param object The java object to generate a reference for * @return A pointer representing the unique id. * @deprecated use {@link #add(Object)} */ @Deprecated public Pointer newReference(T object) { return add(object); } /** * Removes a mapping from java object to native pointer. * * @param reference a native memory pointer. * @deprecated use {@link #remove(Pointer)} */ @Deprecated public void freeReference(Pointer reference) { remove(reference); } /** * Gets the java object that is mapped to the native memory address referred to by {@code reference}. * * @param reference a native memory pointer. * @return The java object corresponding to {@code pointer}. * @deprecated use {@link #get(Pointer)} */ @Deprecated public T getObject(Pointer reference) { return get(reference); } /** * Adds a mapping from a java object to a unique native address. * * Each call to this method is guaranteed to produce a memory address unique within the ObjectReferenceManager * instance, even for the same object. * *

* A strong reference to {@code object} is maintained internally, until {@link #remove(Pointer)} is called. *

* * @param object The java object to generate a reference for * @return A pointer representing the unique id. */ public abstract Pointer add(T object); /** * Removes a mapping from java object to native pointer. * * @param reference a native memory pointer. * @return true if the mapping was removed. */ public abstract boolean remove(Pointer reference); /** * Gets the java object that is mapped to the native memory address referred to by {@code reference}. * * @param reference a native memory pointer. * @return The java object corresponding to {@code pointer}. */ public abstract T get(Pointer reference); } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/Platform.java000066400000000000000000000434231316720554100230370ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; import java.io.File; import java.io.FilenameFilter; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; public abstract class Platform { private static final java.util.Locale LOCALE = java.util.Locale.ENGLISH; private final OS os; private final CPU cpu; private final int addressSize; private final int longSize; protected final Pattern libPattern; private static final class SingletonHolder { static final Platform PLATFORM = determinePlatform(); } /** * The common names of supported operating systems. */ public enum OS { /* * Note The names of the enum values are used in other parts of the * code to determine where to find the native stub library. Do not rename. */ /** MacOSX */ DARWIN, /** FreeBSD */ FREEBSD, /** NetBSD */ NETBSD, /** OpenBSD */ OPENBSD, /** Linux */ LINUX, /** Solaris (and OpenSolaris) */ SOLARIS, /** The evil borg operating system */ WINDOWS, /** IBM AIX */ AIX, /** IBM zOS **/ ZLINUX, /** No idea what the operating system is */ UNKNOWN; @Override public String toString() { return name().toLowerCase(LOCALE); } } /** * The supported CPU architectures. */ public enum CPU { /* * Note The names of the enum values are used in other parts of the * code to determine where to find the native stub library. Do NOT rename. */ /** 32 bit legacy Intel */ I386, /** 64 bit AMD (aka EM64T/X64) */ X86_64, /** 32 bit Power PC */ PPC, /** 64 bit Power PC */ PPC64, /** 64 bit Power PC little endian */ PPC64LE, /** 32 bit Sun sparc */ SPARC, /** 64 bit Sun sparc */ SPARCV9, /** IBM zSeries S/390 */ S390X, /** 32 bit MIPS (used by nestedvm) */ MIPS32, /** 32 bit ARM */ ARM, /** 64 bit ARM */ AARCH64, /** * Unknown CPU architecture. A best effort will be made to infer architecture * specific values such as address and long size. */ UNKNOWN; /** * Returns a {@code String} object representing this {@code CPU} object. * * @return the name of the cpu architecture as a lower case {@code String}. */ @Override public String toString() { return name().toLowerCase(LOCALE); } } /** * Determines the operating system jffi is running on * * @return An member of the OS enum. */ private static OS determineOS() { String osName = System.getProperty("os.name").split(" ")[0]; if (startsWithIgnoreCase(osName, "mac") || startsWithIgnoreCase(osName, "darwin")) { return OS.DARWIN; } else if (startsWithIgnoreCase(osName, "linux")) { return OS.LINUX; } else if (startsWithIgnoreCase(osName, "sunos") || startsWithIgnoreCase(osName, "solaris")) { return OS.SOLARIS; } else if (startsWithIgnoreCase(osName, "aix")) { return OS.AIX; } else if (startsWithIgnoreCase(osName, "openbsd")) { return OS.OPENBSD; } else if (startsWithIgnoreCase(osName, "freebsd")) { return OS.FREEBSD; } else if (startsWithIgnoreCase(osName, "windows")) { return OS.WINDOWS; } else { return OS.UNKNOWN; } } /** * Determines the Platform that best describes the OS * * @param os The operating system. * @return An instance of Platform */ private static Platform determinePlatform(OS os) { switch (os) { case DARWIN: return new Darwin(); case LINUX: return new Linux(); case WINDOWS: return new Windows(); case UNKNOWN: return new Unsupported(os); default: return new Default(os); } } private static Platform determinePlatform() { String providerName = System.getProperty("jnr.ffi.provider"); try { Class c = Class.forName(providerName + "$Platform"); return (Platform) c.newInstance(); } catch (ClassNotFoundException ex) { return determinePlatform(determineOS()); } catch (IllegalAccessException ex) { throw new ExceptionInInitializerError(ex); } catch (InstantiationException ex) { throw new ExceptionInInitializerError(ex); } } private static CPU determineCPU() { String archString = System.getProperty("os.arch"); if (equalsIgnoreCase("x86", archString) || equalsIgnoreCase("i386", archString) || equalsIgnoreCase("i86pc", archString) || equalsIgnoreCase("i686", archString)) { return CPU.I386; } else if (equalsIgnoreCase("x86_64", archString) || equalsIgnoreCase("amd64", archString)) { return CPU.X86_64; } else if (equalsIgnoreCase("ppc", archString) || equalsIgnoreCase("powerpc", archString)) { return CPU.PPC; } else if (equalsIgnoreCase("ppc64", archString) || equalsIgnoreCase("powerpc64", archString)) { if ("little".equals(System.getProperty("sun.cpu.endian"))) { return CPU.PPC64LE; } return CPU.PPC64; } else if (equalsIgnoreCase("ppc64le", archString) || equalsIgnoreCase("powerpc64le", archString)) { return CPU.PPC64LE; } else if (equalsIgnoreCase("s390", archString) || equalsIgnoreCase("s390x", archString)) { return CPU.S390X; } else if (equalsIgnoreCase("aarch64", archString)) { return CPU.AARCH64; } // Try to find by lookup up in the CPU list for (CPU cpu : CPU.values()) { if (equalsIgnoreCase(cpu.name(), archString)) { return cpu; } } return CPU.UNKNOWN; } public Platform(OS os, CPU cpu, int addressSize, int longSize, String libPattern) { this.os = os; this.cpu = cpu; this.addressSize = addressSize; this.longSize = longSize; this.libPattern = Pattern.compile(libPattern); } private Platform(OS os) { this.os = os; this.cpu = determineCPU(); String libpattern; switch (os) { case WINDOWS: libpattern = ".*\\.dll$"; break; case DARWIN: libpattern = "lib.*\\.(dylib|jnilib)$"; break; default: libpattern = "lib.*\\.so.*$"; break; } libPattern = Pattern.compile(libpattern); this.addressSize = calculateAddressSize(cpu); this.longSize = os == OS.WINDOWS ? 32 : addressSize; } private static int calculateAddressSize(CPU cpu) { int dataModel = Integer.getInteger("sun.arch.data.model"); if (dataModel != 32 && dataModel != 64) { switch (cpu) { case I386: case PPC: case SPARC: dataModel = 32; break; case X86_64: case PPC64: case PPC64LE: case SPARCV9: case S390X: case AARCH64: dataModel = 64; break; default: throw new ExceptionInInitializerError("Cannot determine cpu address size"); } } return dataModel; } /** * Gets the native Platform * * @return The current platform. */ public static Platform getNativePlatform() { return SingletonHolder.PLATFORM; } @Deprecated public static Platform getPlatform() { return SingletonHolder.PLATFORM; } /** * Gets the current Operating System. * * @return A OS value representing the current Operating System. */ public final OS getOS() { return os; } /** * Gets the current processor architecture the JVM is running on. * * @return A CPU value representing the current processor architecture. */ public final CPU getCPU() { return cpu; } public final boolean isBSD() { return os == OS.FREEBSD || os == OS.OPENBSD || os == OS.NETBSD || os == OS.DARWIN; } public final boolean isUnix() { return os != OS.WINDOWS; } /** * Gets the size of a C 'long' on the native platform. * * @return the size of a long in bits * @deprecated Use {@link Runtime#longSize()} instead. */ public final int longSize() { return longSize; } /** * Gets the size of a C address/pointer on the native platform. * * @return the size of a pointer in bits * @deprecated Use {@link Runtime#addressSize()} instead. */ public final int addressSize() { return addressSize; } /** * Gets the name of this Platform. * * @return The name of this platform. */ public String getName() { return cpu + "-" + os; } /** * Returns the platform specific standard C library name * * @return The standard C library name */ public String getStandardCLibraryName() { switch (os) { case LINUX: return "libc.so.6"; case SOLARIS: return "c"; case FREEBSD: case NETBSD: return "c"; case AIX: return addressSize == 32 ? "libc.a(shr.o)" : "libc.a(shr_64.o)"; case WINDOWS: return "msvcrt"; default: return "c"; } } /** * Maps from a generic library name (e.g. "c") to the platform specific library name. * * @param libName The library name to map * @return The mapped library name. */ public String mapLibraryName(String libName) { // // A specific version was requested - use as is for search // if (libPattern.matcher(libName).find()) { return libName; } return System.mapLibraryName(libName); } /** * Searches through a list of directories for a native library. * * @param libName the base name (e.g. "c") of the library to locate * @param libraryPath the list of directories to search * @return the path of the library */ public String locateLibrary(String libName, List libraryPath) { String mappedName = mapLibraryName(libName); for (String path : libraryPath) { File libFile = new File(path, mappedName); if (libFile.exists()) { return libFile.getAbsolutePath(); } } // Default to letting the system search for it return mappedName; } private static class Supported extends Platform { public Supported(OS os) { super(os); } } private static class Unsupported extends Platform { public Unsupported(OS os) { super(os); } } private static final class Default extends Supported { public Default(OS os) { super(os); } } /** * A {@link Platform} subclass representing the MacOS system. */ private static final class Darwin extends Supported { public Darwin() { super(OS.DARWIN); } @Override public String mapLibraryName(String libName) { // // A specific version was requested - use as is for search // if (libPattern.matcher(libName).find()) { return libName; } return "lib" + libName + ".dylib"; } @Override public String getName() { return "Darwin"; } } /** * A {@link Platform} subclass representing the Linux operating system. */ static final class Linux extends Supported { public Linux() { super(OS.LINUX); } @Override public String locateLibrary(final String libName, List libraryPaths) { Pattern exclude; // there are /libx32 directories in wild on ubuntu 14.04 and the // oracle-java8-installer package if (getCPU() == CPU.X86_64) { exclude = Pattern.compile(".*(lib[a-z]*32|i[0-9]86).*"); } else { exclude = Pattern.compile(".*(lib[a-z]*64|amd64|x86_64).*"); } final Pattern versionedLibPattern = Pattern.compile("lib" + libName + "\\.so((?:\\.[0-9]+)*)$"); FilenameFilter filter = new FilenameFilter() { public boolean accept(File dir, String name) { return versionedLibPattern.matcher(name).matches(); } }; Map matches = new LinkedHashMap(); for (String path : libraryPaths) { if (exclude.matcher(path).matches()) { continue; } File libraryPath = new File(path); File[] files = libraryPath.listFiles(filter); if (files == null) { continue; } for (File file : files) { Matcher matcher = versionedLibPattern.matcher(file.getName()); String versionString = matcher.matches() ? matcher.group(1) : ""; int[] version; if (versionString == null || versionString.isEmpty()) { version = new int[0]; } else { String[] parts = versionString.split("\\."); version = new int[parts.length - 1]; for (int i = 1; i < parts.length; i++) { version[i - 1] = Integer.parseInt(parts[i]); } } matches.put(file.getAbsolutePath(), version); } } // // Search through the results and return the highest numbered version // i.e. libc.so.6 is preferred over libc.so.5 // int[] bestVersion = null; String bestMatch = null; for (Map.Entry entry : matches.entrySet()) { String file = entry.getKey(); int[] fileVersion = entry.getValue(); if (compareVersions(fileVersion, bestVersion) > 0) { bestMatch = file; bestVersion = fileVersion; } } return bestMatch != null ? bestMatch : mapLibraryName(libName); } private static int compareVersions(int[] version1, int[] version2) { // Null is always smallest if (version1 == null) { return version2 == null ? 0 : -1; } if (version2 == null) { return 1; } // Compare component by component int commonLength = Math.min(version1.length, version2.length); for (int i = 0; i < commonLength; i++) { if (version1[i] < version2[i]) { return -1; } else if (version1[i] > version2[i]) { return 1; } } // If all components are equal, version with fewest components is smallest if (version1.length < version2.length) { return -1; } else if (version1.length > version2.length) { return 1; } else { return 0; } } @Override public String mapLibraryName(String libName) { // Older JDK on linux map 'c' to 'libc.so' which doesn't work return "c".equals(libName) || "libc.so".equals(libName) ? "libc.so.6" : super.mapLibraryName(libName); } } /** * A {@link Platform} subclass representing the Windows system. */ private static class Windows extends Supported { public Windows() { super(OS.WINDOWS); } } private static boolean startsWithIgnoreCase(String s1, String s2) { return s1.startsWith(s2) || s1.toUpperCase(LOCALE).startsWith(s2.toUpperCase(LOCALE)) || s1.toLowerCase(LOCALE).startsWith(s2.toLowerCase(LOCALE)); } private static boolean equalsIgnoreCase(String s1, String s2) { return s1.equalsIgnoreCase(s2) || s1.toUpperCase(LOCALE).equals(s2.toUpperCase(LOCALE)) || s1.toLowerCase(LOCALE).equals(s2.toLowerCase(LOCALE)); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/Pointer.java000066400000000000000000000767531316720554100227070ustar00rootroot00000000000000/* * Copyright (C) 2008-2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; import java.nio.ByteBuffer; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; /** * A native memory address. * * This class provides operations on a native memory address. Most Pointerinstances will represent direct * memory (that is, a fixed address in the process address space, directly accessible by native code), however, * it is possible to wrap a java byte array in a Pointerinstance to pass to a native function * as a memory address. See {@link #isDirect()} for more information. */ abstract public class Pointer { private final Runtime runtime; private final long address; private final boolean isDirect; /** * Wraps a native address in a {@link Pointer} instance. * * @param runtime the {@code Runtime} of the pointer. * @param address the {@code address} to wrap in a Pointer instance. * * @return a {@code Pointer} instance. */ public static Pointer wrap(Runtime runtime, long address) { return runtime.getMemoryManager().newPointer(address); } /** * Wraps a native address in a {@link Pointer} instance. * * @param runtime the {@code Runtime} of the pointer. * @param address the {@code address} to wrap in a Pointer instance. * @param size the size of the native memory region. * * @return a {@code Pointer} instance. */ public static Pointer wrap(Runtime runtime, long address, long size) { return runtime.getMemoryManager().newPointer(address, size); } /** * Wraps an existing ByteBuffer in a {@link Pointer} implementation so it can * be used as a parameter to native functions. * *

Wrapping a ByteBuffer is only neccessary if the native function parameter * was declared as a {@code Pointer}. The if the method will always be used * with {@code ByteBuffer} parameters, then the parameter type can just be declared * as {@code ByteBuffer} and the conversion will be performed automatically. * * @param runtime the {@code Runtime} the wrapped {@code ByteBuffer} will * be used with. * @param buffer the {@code ByteBuffer} to wrap. * * @return a {@code Pointer} instance that will proxy all accesses to the ByteBuffer contents. */ public static Pointer wrap(Runtime runtime, ByteBuffer buffer) { return runtime.getMemoryManager().newPointer(buffer); } /** * Wraps an integer value in an opaque {@link Pointer} instance. This is a Pointer instance that * throws errors when any of the memory access methods are used, but can be otherwise used interchangeably * with a real Pointer. * * @param runtime the {@code Runtime} of the pointer. * @param address the {@code address} to wrap in a Pointer instance. * * @return a {@code Pointer} instance. */ public static Pointer newIntPointer(Runtime runtime, long address) { return runtime.getMemoryManager().newOpaquePointer(address); } protected Pointer(Runtime runtime, long address, boolean direct) { this.runtime = runtime; this.address = address; isDirect = direct; } /** * Indicates whether or not this memory object represents a native memory address. * *

Memory objects can be either direct (representing native memory), or * non-direct (representing java heap memory). * *

Non-direct memory objects can still be passed to native functions as pointer * (void *, char *, etc) parameters, but the java memory will first be copied * to a temporary native memory area. The temporary memory area will then be * used as the parameter value for the call. If needed, the java memory * will be automatically reloaded from the temporary native memory after the * native function returns. *

Note: the transient nature of the temporary memory allocated for * non-direct memory means native functions which store the address value * passed to them will fail in unpredictable ways when using non-direct memory. * You will need to explicitly allocate direct memory to use those types of * functions. * * @return true if, and only if, this memory object represents a native address. */ public final boolean isDirect() { return isDirect; } /** * Gets the native address of this memory object (optional operation). * * @return the native address of this memory object. If this object is not * a native memory address, an address of zero is returned. */ public final long address() { return address; } /** * Gets the {@link Runtime} this {@code Pointer} instance belongs to. * * @return the {@code Runtime} instance of this {@code Pointer}. */ public final Runtime getRuntime() { return runtime; } public String toString() { StringBuilder sb = new StringBuilder(); sb.append(getClass().getName()); sb.append(String.format("[address=%#x", address())); if (size() != Long.MAX_VALUE) { sb.append(String.format(" size=%d", size())); } sb.append(']'); return sb.toString(); } /** * Gets the size of this memory object in bytes (optional operation). * * @return the size of the memory area this {@code Pointer} points to. If * the size is unknown, {@link java.lang.Long#MAX_VALUE} is returned}. */ abstract public long size(); /** * Indicates whether this Pointer instance is backed by an array. * * @return true if, and only if, this memory object is backed by an array */ abstract public boolean hasArray(); /** * Returns the array that backs this pointer. * * @return The array that backs this pointer. * @throws java.lang.UnsupportedOperationException if this pointer does not have a backing array. */ abstract public Object array(); /** * Returns the offset within this pointer's backing array of the first element. * * @throws java.lang.UnsupportedOperationException if this pointer does not have a backing array * @return The offset of the first element on the backing array */ abstract public int arrayOffset(); /** * Returns the length of this pointer's backing array that is used by this pointer. * * @throws UnsupportedOperationException if this pointer does not have a backing array * @return The length of the backing array used */ abstract public int arrayLength(); /** * Reads an {@code byte} (8 bit) value at the given offset. * * @param offset The offset from the start of the memory this {@code Pointer} represents at which the value will be read. * @return the {@code byte} value at the offset. */ abstract public byte getByte(long offset); /** * Reads a {@code short} (16 bit) value at the given offset. * * @param offset The offset from the start of the memory this {@code Pointer} represents at which the value will be read. * @return the {@code short} value at the offset. */ abstract public short getShort(long offset); /** * Reads an {@code int} (32 bit) value at the given offset. * * @param offset The offset from the start of the memory this {@code Pointer} represents at which the value will be read. * @return the {@code int} value contained in the memory at the offset. */ abstract public int getInt(long offset); /** * Reads a {@code long} (64 bit) value at the given offset. * * @param offset The offset from the start of the memory this {@code Pointer} represents at which the value will be read. * @return the {@code long} value at the offset. */ abstract public long getLong(long offset); /** * Reads a {@code long} (64 bit) value at the given offset. * * @param offset The offset from the start of the memory this {@code Pointer} represents at which the value will be read. * @return the {@code long} value at the offset. */ abstract public long getLongLong(long offset); /** * Reads a {@code float} (32 bit) value at the given offset. * * @param offset The offset from the start of the memory this {@code Pointer} represents at which the value will be read. * @return the {@code float} value at the offset. */ abstract public float getFloat(long offset); /** * Reads a {@code double} (64 bit) value at the given offset. * * @param offset The offset from the start of the memory this {@code Pointer} represents at which the value will be read. * @return the {@code double} value at the offset. */ abstract public double getDouble(long offset); /** * Reads a native {@code long} value at the given offset. *

A native {@code long} can be either 32 or 64 bits in size, depending * on the cpu architecture, and the C ABI in use. * *

For windows, a long is always 32 bits (4 bytes) in size, but on unix * systems, a long on a 32bit system is 32 bits, and on a 64bit system, is 64 bits. * * @param offset The offset from the start of the memory this {@code Pointer} represents at which the value will be read. * @return the native {@code long} value at the offset. * * @see NativeLong */ abstract public long getNativeLong(long offset); /** * Reads an integer value of the given type, at the given offset. * * @param type Type of integer to read. * @param offset The offset from the start of the memory this {@code Pointer} represents at which the value will be read. * @return the {@code int} value contained in the memory at the offset. */ abstract public long getInt(Type type, long offset); /** * Writes a {@code byte} (8 bit) value at the given offset. * * @param offset The offset from the start of the memory this {@code Pointer} represents at which the value will be written. * @param value the {@code byte} value to be written. */ abstract public void putByte(long offset, byte value); /** * Writes a {@code short} (16 bit) value at the given offset. * * @param offset The offset from the start of the memory this {@code Pointer} represents at which the value will be written. * @param value the {@code short} value to be written. */ abstract public void putShort(long offset, short value); /** * Writes an {@code int} (32 bit) value at the given offset. * * @param offset The offset from the start of the memory this {@code Pointer} represents at which the value will be written. * @param value the {@code int} value to be written. */ abstract public void putInt(long offset, int value); /** * Writes a {@code native long} value at the given offset. * * @param offset The offset from the start of the memory this {@code Pointer} represents at which the value will be written. * @param value the {@code long} value to be written. */ abstract public void putLong(long offset, long value); /** * Writes a {@code long} (64 bit) value at the given offset. * * @param offset The offset from the start of the memory this {@code Pointer} represents at which the value will be written. * @param value the {@code long} value to be written. */ abstract public void putLongLong(long offset, long value); /** * Writes a {@code float} (32 bit, single precision) value at the given offset. * * @param offset The offset from the start of the memory this {@code Pointer} represents at which the value will be written. * @param value the {@code float} value to be written. */ abstract public void putFloat(long offset, float value); /** * Writes a {@code double} (64 bit, double precision) value at the given offset. * * @param offset The offset from the start of the memory this {@code Pointer} represents at which the value will be written. * @param value the {@code double} value to be written. */ abstract public void putDouble(long offset, double value); /** * Writes a native {@code long} value at the given offset. * *

A native {@code long} can be either 32 or 64 bits in size, depending * on the cpu architecture, and the C ABI in use. * *

For windows, a long is always 32 bits (4 bytes) in size, but on unix * systems, a long on a 32bit system is 32 bits, and on a 64bit system, is 64 bits. * * @param offset The offset from the start of the memory this {@code Pointer} represents at which the value will be written. * @param value the native {@code long} value to be written. */ abstract public void putNativeLong(long offset, long value); /** * Writes an integer of a specific type, at the given offset. * * @param type The integer type. * @param offset The offset from the start of the memory this {@code Pointer} represents at which the value will be written. * @param value the {@code int} value to be written. */ abstract public void putInt(Type type, long offset, long value); /** * Reads a native memory address value at the given offset. *

A native address can be either 32 or 64 bits in size, depending * on the cpu architecture. * * @param offset The offset from the start of the memory this {@code Pointer} represents at which the value will be read. * @return the native address value contained in the memory at the offset * * @see Address */ abstract public long getAddress(long offset); /** * Writes a native memory address value at the given offset. *

A native address can be either 32 or 64 bits in size, depending * on the cpu architecture. * * @param offset The offset from the start of the memory this {@code Pointer} represents at which the value will be written. * @param value The native address value to be written. * * @see Address */ abstract public void putAddress(long offset, long value); /** * Writes a native memory address value at the given offset. *

A native address can be either 32 or 64 bits in size, depending * on the cpu architecture. * * @param offset The offset from the start of the memory this {@code Pointer} represents at which the value will be written. * @param value The native address value to be written. * * @see Address */ abstract public void putAddress(long offset, Address value); /** * Bulk get method for multiple {@code byte} values. * * This method reads multiple {@code byte} values from consecutive addresses, * beginning at the given offset, and stores them in an array. * * @param offset the offset from the start of the memory this {@code Pointer} represents at which the first value will be read. * @param dst the array into which values are to be stored. * @param idx the start index in the {@code dst} array to begin storing the values. * @param len the number of values to be read. */ abstract public void get(long offset, byte[] dst, int idx, int len); /** * Bulk put method for multiple {@code byte} values. * * This method writes multiple {@code byte} values to consecutive addresses, * beginning at the given offset, from an array. * * @param offset the offset from the start of the memory this {@code Pointer} represents at which the first value will be written. * @param src the array to get values from. * @param idx the start index in the {@code dst} array to begin reading values. * @param len the number of values to be written. */ abstract public void put(long offset, byte[] src, int idx, int len); /** * Bulk get method for multiple {@code short} values. * * This method reads multiple {@code short} values from consecutive addresses, * beginning at the given offset, and stores them in an array. * * @param offset The offset from the start of the memory this {@code Pointer} represents at which the first value will be read. * @param dst The array into which values are to be stored. * @param idx the start index in the {@code dst} array to begin storing the values. * @param len the number of values to be read. */ abstract public void get(long offset, short[] dst, int idx, int len); /** * Bulk put method for multiple {@code short} values. * * This method writes multiple {@code short} values to consecutive addresses, * beginning at the given offset, from an array. * * @param offset the offset from the start of the memory this {@code Pointer} represents at which the first value will be written. * @param src the array to get values from. * @param idx the start index in the {@code dst} array to begin reading values. * @param len the number of values to be written. */ abstract public void put(long offset, short[] src, int idx, int len); /** * Bulk get method for multiple {@code int} values. * * This method reads multiple {@code int} values from consecutive addresses, * beginning at the given offset, and stores them in an array. * * @param offset The offset from the start of the memory this {@code Pointer} represents at which the first value will be read. * @param dst The array into which values are to be stored. * @param idx the start index in the {@code dst} array to begin storing the values. * @param len the number of values to be read. */ abstract public void get(long offset, int[] dst, int idx, int len); /** * Bulk put method for multiple {@code int} values. * * This method writes multiple {@code int} values to consecutive addresses, * beginning at the given offset, from an array. * * @param offset the offset from the start of the memory this {@code Pointer} represents at which the first value will be written. * @param src the array to get values from. * @param idx the start index in the {@code dst} array to begin reading values. * @param len the number of values to be written. */ abstract public void put(long offset, int[] src, int idx, int len); /** * Bulk get method for multiple {@code long} values. * * This method reads multiple {@code long} values from consecutive addresses, * beginning at the given offset, and stores them in an array. * * @param offset The offset from the start of the memory this {@code Pointer} represents at which the first value will be read. * @param dst The array into which values are to be stored. * @param idx the start index in the {@code dst} array to begin storing the values. * @param len the number of values to be read. */ abstract public void get(long offset, long[] dst, int idx, int len); /** * Bulk put method for multiple {@code long} values. * * This method writes multiple {@code long} values to consecutive addresses, * beginning at the given offset, from an array. * * @param offset the offset from the start of the memory this {@code Pointer} represents at which the first value will be written. * @param src the array to get values from. * @param idx the start index in the {@code dst} array to begin reading values. * @param len the number of values to be written. */ abstract public void put(long offset, long[] src, int idx, int len); /** * Bulk get method for multiple {@code float} values. * * This method reads multiple {@code float} values from consecutive addresses, * beginning at the given offset, and stores them in an array. * * @param offset The offset from the start of the memory this {@code Pointer} represents at which the first value will be read. * @param dst The array into which values are to be stored. * @param idx the start index in the {@code dst} array to begin storing the values. * @param len the number of values to be read. */ abstract public void get(long offset, float[] dst, int idx, int len); /** * Bulk put method for multiple {@code float} values. * * This method writes multiple {@code float} values to consecutive addresses, * beginning at the given offset, from an array. * * @param offset the offset from the start of the memory this {@code Pointer} represents at which the first value will be written. * @param src the array to get values from. * @param idx the start index in the {@code dst} array to begin reading values. * @param len the number of values to be written. */ abstract public void put(long offset, float[] src, int idx, int len); /** * Bulk get method for multiple {@code double} values. * * This method reads multiple {@code double} values from consecutive addresses, * beginning at the given offset, and stores them in an array. * * @param offset The offset from the start of the memory this {@code Pointer} represents at which the first value will be read. * @param dst The array into which values are to be stored. * @param idx the start index in the {@code dst} array to begin storing the values. * @param len the number of values to be read. */ abstract public void get(long offset, double[] dst, int idx, int len); /** * Bulk put method for multiple {@code double} values. * * This method writes multiple {@code double} values to consecutive addresses, * beginning at the given offset, from an array. * * @param offset the offset from the start of the memory this {@code Pointer} represents at which the first value will be written. * @param src the array to get values from. * @param idx the start index in the {@code dst} array to begin reading values. * @param len the number of values to be written. */ abstract public void put(long offset, double[] src, int idx, int len); /** * Reads an {@code Pointer} value at the given offset. * * @param offset the offset from the start of the memory this {@code Pointer} represents at which the value will be read. * @return the {@code Pointer} value read from memory. */ abstract public Pointer getPointer(long offset); /** * Reads an {@code Pointer} value at the given offset. * * @param offset the offset from the start of the memory this {@code Pointer} represents at which the value will be read. * @param size the maximum size of the memory location the returned {@code Pointer} represents. * @return the {@code Pointer} value read from memory. */ abstract public Pointer getPointer(long offset, long size); /** * Writes a {@code Pointer} value at the given offset. * * @param offset The offset from the start of the memory this {@code Pointer} represents at which the value will be written. * @param value the {@code Pointer} value to be written to memory. */ abstract public void putPointer(long offset, Pointer value); /** * Reads an {@code String} value at the given offset. * * @param offset the offset from the start of the memory this {@code Pointer} represents at which the value will be read. * @return the {@code String} value read from memory. */ abstract public String getString(long offset); /** * Reads a {@code String} value at the given offset, using a specific {@code Charset} * * @param offset the offset from the start of the memory this {@code Pointer} represents at which the value will be read. * @param maxLength the maximum size of memory to search for a NUL byte. * @param cs the {@code Charset} to use to decode the string. * @return the {@code String} value read from memory. */ abstract public String getString(long offset, int maxLength, Charset cs); /** * Writes a {@code String} value at the given offset, using a specific {@code Charset} * * @param offset the offset from the start of the memory this {@code Pointer} represents at which the value will be written. * @param string the string to be written. * @param maxLength the maximum size of memory to use to store the string. * @param cs the {@code Charset} to use to decode the string. */ abstract public void putString(long offset, String string, int maxLength, Charset cs); /** * Creates a new {@code Pointer} representing a sub-region of the memory * referred to by this {@code Pointer}. * * @param offset the offset from the start of the memory this {@code Pointer} * represents at which the new {@code Pointer} will start. * @return a {@code Pointer} instance representing the new sub-region. */ abstract public Pointer slice(long offset); /** * Creates a new {@code Pointer} representing a sub-region of the memory * referred to by this {@code Pointer}. * * @param offset the offset from the start of the memory this {@code Pointer} * represents at which the new {@code Pointer} will start. * @param size the maximum size of the memory sub-region. * * @return a {@code Pointer} instance representing the new sub-region. */ abstract public Pointer slice(long offset, long size); /** * Bulk data transfer from one memory location to another. * * @param offset the offset from the start of the memory location this {@code Pointer} represents to begin copying from. * @param dst the destination memory location to transfer data to. * @param dstOffset the offset from the start of the memory location the destination {@code Pointer} represents to begin copying to. * @param count the number of bytes to transfer. */ abstract public void transferTo(long offset, Pointer dst, long dstOffset, long count); /** * Bulk data transfer from one memory location to another. * * @param offset the offset from the start of the memory location this {@code Pointer} represents to begin copying to. * @param src the destination memory location to transfer data from. * @param srcOffset the offset from the start of the memory location the destination {@code Pointer} represents to begin copying from. * @param count the number of bytes to transfer. */ abstract public void transferFrom(long offset, Pointer src, long srcOffset, long count); /** * Checks that the memory region is within the bounds of this memory object * * @param offset the starting point within this memory region. * @param length the length of the memory region in bytes * @throws java.lang.IndexOutOfBoundsException if the memory region is not within the bounds. */ abstract public void checkBounds(long offset, long length); /** * Sets the value of each byte in the memory area represented by this {@code Pointer}. * to a specified value. * * @param offset the offset from the start of the memory location this {@code Pointer} represents to begin writing to. * @param size the number of bytes to set to the value. * @param value the value to set each byte to. */ abstract public void setMemory(long offset, long size, byte value); /** * Returns the location of a byte value within the memory area represented by this {@code Pointer}. * * @param offset the offset from the start of the memory location this {@code Pointer} represents to begin searching. * @param value the {@code byte} value to locate. * @return the offset from the start of the search area (i.e. relative to the offset parameter), or -1 if not found. */ abstract public int indexOf(long offset, byte value); /** * Returns the location of a byte value within the memory area represented by this {@code Pointer}. * * @param offset the offset from the start of the memory location this {@code Pointer} represents to begin searching. * @param value the {@code byte} value to locate. * @param maxlen the maximum number of bytes to search for the desired value. * @return the offset from the start of the search area (i.e. relative to the offset parameter), or -1 if not found. */ abstract public int indexOf(long offset, byte value, int maxlen); /** * Bulk get method for multiple {@code Pointer} values. * * This method reads multiple {@code Pointer} values from consecutive addresses, * beginning at the given offset, and stores them in an array. * * @param offset The offset from the start of the memory this {@code Pointer} represents at which the first value will be read. * @param dst The array into which values are to be stored. * @param idx the start index in the {@code dst} array to begin storing the values. * @param len the number of values to be read. */ public void get(long offset, Pointer[] dst, int idx, int len) { final int pointerSize = getRuntime().addressSize(); for (int i = 0; i < len; i++) { dst[idx + i] = getPointer(offset + (i * pointerSize)); } } /** * Bulk put method for multiple {@code Pointer} values. * * This method writes multiple {@code Pointer} values to consecutive addresses, * beginning at the given offset, from an array. * * @param offset the offset from the start of the memory this {@code Pointer} represents at which the first value will be written. * @param src the array to get values from. * @param idx the start index in the {@code src} array to begin reading values. * @param len the number of values to be written. */ public void put(long offset, Pointer[] src, int idx, int len) { final int pointerSize = getRuntime().addressSize(); for (int i = 0; i < len; i++) { putPointer(offset + (i * pointerSize), src[idx + i]); } } public String[] getNullTerminatedStringArray(long offset) { Pointer ptr; if ((ptr = getPointer(offset)) == null) { return new String[0]; } final int pointerSize = getRuntime().addressSize(); List array = new ArrayList(); array.add(ptr.getString(0)); for (int off = pointerSize; (ptr = getPointer(offset + off)) != null; off += pointerSize) { array.add(ptr.getString(0)); } return array.toArray(new String[array.size()]); } public Pointer[] getNullTerminatedPointerArray(long offset) { Pointer ptr; if ((ptr = getPointer(offset)) == null) { return new Pointer[0]; } final int pointerSize = getRuntime().addressSize(); List array = new ArrayList(); array.add(ptr); for (int off = pointerSize; (ptr = getPointer(offset + off)) != null; off += pointerSize) { array.add(ptr); } return array.toArray(new Pointer[array.size()]); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/Runtime.java000066400000000000000000000126351316720554100226770ustar00rootroot00000000000000/* * Copyright (C) 2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; import jnr.ffi.provider.FFIProvider; import jnr.ffi.provider.LoadedLibrary; import jnr.ffi.provider.MemoryManager; import jnr.ffi.provider.ClosureManager; import java.nio.ByteOrder; /** * Access JNR runtime functionality. * *

* This class is needed by many classes to correctly initialize internal data structures, and each library loaded * has its own instance of this class. *

* To obtain an instance of this class, use {@link #getRuntime(Object)} on a loaded library. *

* Example *

 *     {@code
 *
 *     public interface LibC {
 *         public long write(int fd, Pointer data, long len);
 *     }
 *
 *     LibC library = LibraryLoader.create(LibC.class).load("c");
 *
 *     byte[] bytes = "Hello, World\n".getBytes("UTF-8");
 *
 *     // Use the loaded library's Runtime to allocate memory for the string
 *     jnr.ffi.Runtime runtime = jnr.ffi.Runtime.getRuntime(library);
 *     Pointer buffer = Memory.allocateDirect(runtime, bytes.length);
 *
 *     // Copy the java string data to the native memory, then write the contents to STDOUT
 *     buffer.put(0, bytes, 0, bytes.length);
 *     library.write(1, buffer, bytes.length);
 *     }
 *     
*/ public abstract class Runtime { /** * Gets the global Runtime for the current FFI provider * * @return The system runtime */ public static Runtime getSystemRuntime() { return SingletonHolder.SYSTEM_RUNTIME; } /** * Returns the runtime associated with the library instance. * * @param library A loaded library instance as returned from {@link LibraryLoader#load()} * @return The runtime that loaded the library */ public static Runtime getRuntime(Object library) { return ((LoadedLibrary) library).getRuntime(); } /** singleton holder for the default Runtime */ private static final class SingletonHolder { public static final Runtime SYSTEM_RUNTIME = FFIProvider.getSystemProvider().getRuntime(); } /** * Looks up the runtime-specific type that corresponds to the pseudo-type * * @param type The native pseudo-type. * @return A {@code Type} instance. */ public abstract Type findType(NativeType type); /** * Looks up the runtime-specific type that corresponds to the type alias * * @param type the type alias. * @return A {@code Type} instance */ public abstract Type findType(TypeAlias type); /** * Gets the native memory manager for this runtime * * @return The {@link MemoryManager} of the runtime */ public abstract MemoryManager getMemoryManager(); /** * Gets the native closure manager for this runtime * * @return The {@link ClosureManager} of the runtime */ public abstract ClosureManager getClosureManager(); /** * Creates a new {@code ObjectReferenceManager} * * @param the type parameter of the {@code ObjectReferenceManager}. * @return A new {@link ObjectReferenceManager} */ public abstract ObjectReferenceManager newObjectReferenceManager(); /** * Gets the last native error code. *

* This returns the errno value that was set at the time of the last native * function call. * * @return The errno value. */ public abstract int getLastError(); /** * Sets the native error code. * * @param error The value to set errno to. */ public abstract void setLastError(int error); /** * Gets the address mask for this runtime * * @return The address mask for the runtime. */ public abstract long addressMask(); /** * Gets the size of an address (e.g. a pointer) for this runtime * * @return The size of an address in bytes. */ public abstract int addressSize(); /** * Gets the size of a C long integer for this runtime * * @return The size of a C long integer in bytes. */ public abstract int longSize(); /** * Gets the native byte order of the runtime. * * @return The byte order of the runtime */ public abstract ByteOrder byteOrder(); /** * Indicates whether this Runtime instance is compatible with another Runtime instance. * *

* This is not the same as calling {@link #equals} - this method only indicates whether or not artifacts from the * runtime (e.g. memory addresses) are compatible with artifacts from this one. *

* *

* This is mostly for internal use. *

* * @param other the other runtime to test for compatibility * @return true if the other runtime is compatible with this one */ public abstract boolean isCompatible(jnr.ffi.Runtime other); } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/Struct.java000077500000000000000000002253671316720554100225530ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * Some of the design and code of this class is from the javolution project. * * Copyright (C) 2006 - Javolution (http://javolution.org/) * All rights reserved. * * Permission to use, copy, modify, and distribute this software is * freely granted, provided that this notice is preserved. */ package jnr.ffi; import jnr.ffi.provider.ParameterFlags; import jnr.ffi.provider.jffi.ArrayMemoryIO; import jnr.ffi.util.EnumMapper; import java.lang.reflect.Array; import java.lang.reflect.Constructor; import java.nio.charset.Charset; /** * Representation of C structures in java. * * Note: This class is not threadsafe. */ public abstract class Struct { static final Charset ASCII = Charset.forName("ASCII"); static final Charset UTF8 = Charset.forName("UTF-8"); static final class Info { private final Runtime runtime; private jnr.ffi.Pointer memory = null; Struct enclosing = null; int offset = 0; // offset within enclosing Struct int size = 0; int minAlign = 1; boolean isUnion = false; boolean resetIndex = false; Alignment alignment = new Alignment(0); public Info(Runtime runtime) { this.runtime = runtime; } public final int getOffset() { return enclosing == null ? 0 : offset + enclosing.__info.getOffset(); } public final jnr.ffi.Pointer getMemory(int flags) { return enclosing != null ? enclosing.__info.getMemory(flags) : memory != null ? memory : (memory = allocateMemory(flags)); } public final jnr.ffi.Pointer getMemory() { return getMemory(ParameterFlags.TRANSIENT); } final boolean isDirect() { return (enclosing != null && enclosing.__info.isDirect()) || (memory != null && memory.isDirect()); } final int size() { return this.alignment.intValue() > 0 ? size + ((-this.size) & (this.minAlign - 1)) : size; } final int getMinimumAlignment() { return minAlign; } private jnr.ffi.Pointer allocateMemory(int flags) { if (ParameterFlags.isDirect(flags)) { return runtime.getMemoryManager().allocateDirect(size(), true); } else { return runtime.getMemoryManager().allocate(size()); } } public final void useMemory(jnr.ffi.Pointer io) { this.memory = io; } protected final int addField(int sizeBits, int alignBits, Offset offset) { this.size = Math.max(this.size, offset.intValue() + (sizeBits >> 3)); this.minAlign = Math.max(this.minAlign, alignBits >> 3); return offset.intValue(); } protected final int addField(int sizeBits, int alignBits) { final int alignment = this.alignment.intValue() > 0 ? Math.min(this.alignment.intValue(), (alignBits >> 3)) : (alignBits >> 3); final int offset = resetIndex ? 0 : align(this.size, alignment); this.size = Math.max(this.size, offset + (sizeBits >> 3)); this.minAlign = Math.max(this.minAlign, alignment); return offset; } } final Info __info; /** * Creates a new {@code Struct}. * * @param runtime The current runtime. */ protected Struct(Runtime runtime) { this.__info = new Info(runtime); } protected Struct(Runtime runtime, Alignment alignment) { this(runtime); __info.alignment = alignment; } protected Struct(Runtime runtime, Struct enclosing) { this(runtime); __info.alignment = enclosing.__info.alignment; } /** * Creates a new Struct. * * @param isUnion if this Struct is a Union */ protected Struct(Runtime runtime, final boolean isUnion) { this(runtime); __info.resetIndex = isUnion; __info.isUnion = isUnion; } public final Runtime getRuntime() { return __info.runtime; } /** * Uses the specified memory address as the backing store for this structure. * * @param address the native memory area. */ public final void useMemory(jnr.ffi.Pointer address) { __info.useMemory(address); } public static jnr.ffi.Pointer getMemory(Struct struct) { return struct.__info.getMemory(0); } public static jnr.ffi.Pointer getMemory(Struct struct, int flags) { return struct.__info.getMemory(flags); } public static int size(Struct struct) { return struct.__info.size(); } public static int alignment(Struct struct) { return struct.__info.getMinimumAlignment(); } public static boolean isDirect(Struct struct) { return struct.__info.isDirect(); } private static int align(int offset, int align) { return (offset + align - 1) & ~(align - 1); } @SuppressWarnings("unchecked") public static T[] arrayOf(Runtime runtime, Class type, int length) { try { T[] array = (T[]) Array.newInstance(type, length); Constructor c = type.getConstructor(Runtime.class); for (int i = 0; i < length; ++i) { array[i] = c.newInstance(runtime); } if (array.length > 0) { final int structSize = align(Struct.size(array[0]), Struct.alignment(array[0])); jnr.ffi.Pointer memory = runtime.getMemoryManager().allocateDirect(structSize * length); for (int i = 0; i < array.length; ++i) { array[i].useMemory(memory.slice(structSize * i, structSize)); } } return array; } catch (RuntimeException ex) { throw ex; } catch (Exception ex) { throw new RuntimeException(ex); } } /** * Returns a human readable {@link java.lang.String} representation of the structure. * * @return a {@code String} representation of this structure. */ @Override public java.lang.String toString() { StringBuilder sb = new StringBuilder(); java.lang.reflect.Field[] fields = getClass().getDeclaredFields(); sb.append(getClass().getSimpleName()).append(" { \n"); final java.lang.String fieldPrefix = " "; for (java.lang.reflect.Field field : fields) { try { sb.append(fieldPrefix); sb.append(field.getName()).append(" = "); sb.append(field.get(this).toString()); sb.append("\n"); } catch (Throwable ex) { throw new RuntimeException(ex); } } sb.append("}\n"); return sb.toString(); } public static final class Offset extends java.lang.Number { private final int offset; public Offset(int offset) { this.offset = offset; } @Override public int intValue() { return offset; } @Override public long longValue() { return offset; } @Override public float floatValue() { return offset; } @Override public double doubleValue() { return offset; } } public static final class Alignment extends Number { private final int alignment; public Alignment(int alignment) { this.alignment = alignment; } @Override public int intValue() { return alignment; } @Override public long longValue() { return alignment; } @Override public float floatValue() { return alignment; } @Override public double doubleValue() { return alignment; } } /** * Interface all Struct members must implement. */ protected abstract class Member { /** * Gets the {@code Struct} this {@code Member} is a member of. * * @return a {@code Struct}. */ abstract Struct struct(); /** * Gets the memory object used to store this {@code Member} * * @return a {@code Pointer} */ abstract jnr.ffi.Pointer getMemory(); /** * Gets the offset within the structure for this field. * * @return the offset within the structure for this field. */ abstract long offset(); } /** * Starts an array construction session */ protected final void arrayBegin() { __info.resetIndex = false; } /** * Ends an array construction session */ protected final void arrayEnd() { __info.resetIndex = __info.isUnion; } /** * Creates an array of Member instances. * * @param The type of the Member subclass to create. * @param array the array to store the instances in * @return the array that was passed in */ @SuppressWarnings("unchecked") protected T[] array(T[] array) { arrayBegin(); try { Class arrayClass = array.getClass().getComponentType(); Constructor ctor = arrayClass.getDeclaredConstructor(new Class[] { arrayClass.getEnclosingClass() }); Object[] parameters = { Struct.this }; for (int i = 0; i < array.length; ++i) { array[i] = (T) ctor.newInstance(parameters); } } catch (Exception ex) { throw new RuntimeException(ex); } arrayEnd(); return array; } /** * Creates an array of Enum8 instances. * * @param array the array to store the instances in * @param enumClass class of java.lang.Enum, these Enum8 instances will represent * @param The type of the java.lang.Enum * @return the array that was passed in */ protected > Enum8[] array(Enum8[] array, Class enumClass) { arrayBegin(); for (int i = 0; i < array.length; i++) { array[i] = new Enum8(enumClass); } arrayEnd(); return array; } /** * Creates an array of Enum16 instances. * * @param array the array to store the instances in * @param enumClass class of java.lang.Enum, these Enum16 instances will represent * @param The type of the java.lang.Enum * @return the array that was passed in */ protected > Enum16[] array(Enum16[] array, Class enumClass) { arrayBegin(); for (int i = 0; i < array.length; i++) { array[i] = new Enum16(enumClass); } arrayEnd(); return array; } /** * Creates an array of Enum32 instances. * * @param array the array to store the instances in * @param enumClass class of java.lang.Enum, these Enum32 instances will represent * @param The type of the java.lang.Enum * @return the array that was passed in */ protected > Enum32[] array(Enum32[] array, Class enumClass) { arrayBegin(); for (int i = 0; i < array.length; i++) { array[i] = new Enum32(enumClass); } arrayEnd(); return array; } /** * Creates an array of Enum64 instances. * * @param array the array to store the instances in * @param enumClass class of java.lang.Enum, these Enum64 instances will represent * @param The type of the java.lang.Enum * @return the array that was passed in */ protected > Enum64[] array(Enum64[] array, Class enumClass) { arrayBegin(); for (int i = 0; i < array.length; i++) { array[i] = new Enum64(enumClass); } arrayEnd(); return array; } /** * Creates an array of Enum instances. * * @param array the array to store the instances in * @param enumClass class of java.lang.Enum, these Enum instances will represent * @param The type of the java.lang.Enum * @return the array that was passed in */ protected > Enum[] array(Enum[] array, Class enumClass) { arrayBegin(); for (int i = 0; i < array.length; i++) { array[i] = new Enum(enumClass); } arrayEnd(); return array; } /** * Creates an array of Struct instances. * * @param array the array to store the instances in * @param the type of Struct * @return the array that was passed in */ protected T[] array(T[] array) { arrayBegin(); try { Class type = array.getClass().getComponentType(); Constructor c = type.getConstructor(Runtime.class); for (int i = 0; i < array.length; i++) { array[i] = inner((T) c.newInstance(getRuntime())); } } catch (Exception ex) { throw new RuntimeException(ex); } arrayEnd(); return array; } /** * Creates an array of Signed8 instances. * * @param array the array to store the instances in * @return the array that was passed in */ protected final Signed8[] array(Signed8[] array) { arrayBegin(); for (int i = 0; i < array.length; ++i) { array[i] = new Signed8(); } arrayEnd(); return array; } /** * Creates an array of Unsigned8 instances. * * @param array the array to store the instances in * @return the array that was passed in */ protected final Unsigned8[] array(Unsigned8[] array) { arrayBegin(); for (int i = 0; i < array.length; ++i) { array[i] = new Unsigned8(); } arrayEnd(); return array; } /** * Creates an array of Signed16 instances. * * @param array the array to store the instances in * @return the array that was passed in */ protected final Signed16[] array(Signed16[] array) { arrayBegin(); for (int i = 0; i < array.length; ++i) { array[i] = new Signed16(); } arrayEnd(); return array; } /** * Creates an array of Unsigned16 instances. * * @param array the array to store the instances in * @return the array that was passed in */ protected final Unsigned16[] array(Unsigned16[] array) { arrayBegin(); for (int i = 0; i < array.length; ++i) { array[i] = new Unsigned16(); } arrayEnd(); return array; } /** * Creates an array of Signed32 instances. * * @param array the array to store the instances in * @return the array that was passed in */ protected final Signed32[] array(Signed32[] array) { arrayBegin(); for (int i = 0; i < array.length; ++i) { array[i] = new Signed32(); } arrayEnd(); return array; } /** * Creates an array of Unsigned32 instances. * * @param array the array to store the instances in * @return the array that was passed in */ protected final Unsigned32[] array(Unsigned32[] array) { arrayBegin(); for (int i = 0; i < array.length; ++i) { array[i] = new Unsigned32(); } arrayEnd(); return array; } /** * Creates an array of Signed64 instances. * * @param array the array to store the instances in * @return the array that was passed in */ protected final Signed64[] array(Signed64[] array) { arrayBegin(); for (int i = 0; i < array.length; ++i) { array[i] = new Signed64(); } arrayEnd(); return array; } /** * Creates an array of Unsigned64 instances. * * @param array the array to store the instances in * @return the array that was passed in */ protected final Unsigned64[] array(Unsigned64[] array) { arrayBegin(); for (int i = 0; i < array.length; ++i) { array[i] = new Unsigned64(); } arrayEnd(); return array; } /** * Creates an array of SignedLong instances. * * @param array the array to store the instances in * @return the array that was passed in */ protected final SignedLong[] array(SignedLong[] array) { arrayBegin(); for (int i = 0; i < array.length; ++i) { array[i] = new SignedLong(); } arrayEnd(); return array; } /** * Creates an array of UnsignedLong instances. * * @param array the array to store the instances in * @return the array that was passed in */ protected final UnsignedLong[] array(UnsignedLong[] array) { arrayBegin(); for (int i = 0; i < array.length; ++i) { array[i] = new UnsignedLong(); } arrayEnd(); return array; } /** * Creates an array of Float instances. * * @param array the array to store the instances in * @return the array that was passed in */ protected final Float[] array(Float[] array) { arrayBegin(); for (int i = 0; i < array.length; ++i) { array[i] = new Float(); } arrayEnd(); return array; } /** * Creates an array of Double instances. * * @param array the array to store the instances in * @return the array that was passed in */ protected final Double[] array(Double[] array) { arrayBegin(); for (int i = 0; i < array.length; ++i) { array[i] = new Double(); } arrayEnd(); return array; } /** * Creates an array of Address instances. * * @param array the array to store the instances in * @return the array that was passed in */ protected final Address[] array(Address[] array) { arrayBegin(); for (int i = 0; i < array.length; ++i) { array[i] = new Address(); } arrayEnd(); return array; } /** * Creates an array of Pointer instances. * * @param array the array to store the instances in * @return the array that was passed in */ protected final Pointer[] array(Pointer[] array) { arrayBegin(); for (int i = 0; i < array.length; ++i) { array[i] = new Pointer(); } arrayEnd(); return array; } /** * Creates an array of UTF8String instances. * * @param array the array to store the instances in * @param stringLength length of each string in array * @return the array that was passed in */ protected UTF8String[] array(UTF8String[] array, int stringLength) { arrayBegin(); for (int i = 0; i < array.length; i++) { array[i] = new UTF8String(stringLength); } arrayEnd(); return array; } protected final T inner(T struct) { int alignment = __info.alignment.intValue() > 0 ? Math.min(__info.alignment.intValue(), struct.__info.getMinimumAlignment()) : struct.__info.getMinimumAlignment(); int offset = __info.resetIndex ? 0 : align(__info.size, alignment); struct.__info.enclosing = this; struct.__info.offset = offset; __info.size = Math.max(__info.size, offset + struct.__info.size); return struct; } /** * Base implementation of Member */ protected abstract class AbstractMember extends Member { private final int offset; protected AbstractMember(int size) { this(size, size); } protected AbstractMember(int size, int align, Offset offset) { this.offset = __info.addField(size, align, offset); } protected AbstractMember(int size, int align) { this.offset = __info.addField(size, align); } protected AbstractMember(NativeType type) { final Type t = getRuntime().findType(type); this.offset = __info.addField(t.size() * 8, t.alignment() * 8); } protected AbstractMember(NativeType type, Offset offset) { final Type t = getRuntime().findType(type); this.offset = __info.addField(t.size() * 8, t.alignment() * 8, offset); } public final jnr.ffi.Pointer getMemory() { return __info.getMemory(); } /** * Gets the Struct this Member is a member of. * * @return a Struct. */ public final Struct struct() { return Struct.this; } /** * Gets the offset within the structure for this field. */ public final long offset() { return offset + __info.getOffset(); } } /** * Base class for Boolean fields */ protected abstract class AbstractBoolean extends AbstractMember { protected AbstractBoolean(NativeType type) { super(type); } protected AbstractBoolean(NativeType type, Offset offset) { super(type, offset); } /** * Gets the value for this field. * * @return a boolean. */ public abstract boolean get(); /** * Sets the field to a new value. * * @param value The new value. */ public abstract void set(boolean value); /** * Returns a string representation of this Address. * * @return a string representation of this Address. */ @Override public java.lang.String toString() { return java.lang.Boolean.toString(get()); } } /** * A normal C boolean - 1 byte in size */ public final class Boolean extends AbstractBoolean { public Boolean() { super(NativeType.SCHAR); } public final boolean get() { return (getMemory().getByte(offset()) & 0x1) != 0; } public final void set(boolean value) { getMemory().putByte(offset(), (byte) (value ? 1 : 0)); } } /** * A Windows BOOL - 4 bytes */ public final class WBOOL extends AbstractBoolean { public WBOOL() { super(NativeType.SINT); } public final boolean get() { return (getMemory().getInt(offset()) & 0x1) != 0; } public final void set(boolean value) { getMemory().putInt(offset(), value ? 1 : 0); } } public final class BOOL16 extends AbstractBoolean { public BOOL16() { super(NativeType.SSHORT); } public final boolean get() { return (getMemory().getShort(offset()) & 0x1) != 0; } public final void set(boolean value) { getMemory().putShort(offset(), (short) (value ? 1 : 0)); } } public final class BYTE extends Unsigned8 { public BYTE() { } public BYTE(Offset offset) { super(offset); } } public final class WORD extends Unsigned16 { public WORD() { } public WORD(Offset offset) { super(offset); } } public final class DWORD extends Unsigned32 { public DWORD() { } public DWORD(Offset offset) { super(offset); } } public final class LONG extends Signed32 { public LONG() { } public LONG(Offset offset) { super(offset); } } /** * Base class for all Number structure fields. */ public abstract class NumberField extends Member { /** * Offset from the start of the Struct memory this field is located at. */ private final int offset; protected final Type type; protected NumberField(NativeType type) { Type t = this.type = getRuntime().findType(type); this.offset = __info.addField(t.size() * 8, t.alignment() * 8); } protected NumberField(NativeType type, Offset offset) { Type t = this.type = getRuntime().findType(type); this.offset = __info.addField(t.size() * 8, t.alignment() * 8, offset); } protected NumberField(TypeAlias type) { Type t = this.type = getRuntime().findType(type); this.offset = __info.addField(t.size() * 8, t.alignment() * 8); } protected NumberField(TypeAlias type, Offset offset) { Type t = this.type = getRuntime().findType(type); this.offset = __info.addField(t.size() * 8, t.alignment() * 8, offset); } public final jnr.ffi.Pointer getMemory() { return __info.getMemory(); } /** * Gets the Struct this Member is in. * * @return a Struct. */ public final Struct struct() { return Struct.this; } /** * Gets the offset within the structure for this field. */ public final long offset() { return offset + __info.getOffset(); } /** * Sets the field to a new value. * * @param value The new value. */ public abstract void set(java.lang.Number value); /** * Returns an {@code float} representation of this Number. * * @return an {@code float} value for this Number. */ public double doubleValue() { return (double) longValue(); } /** * Returns an {@code float} representation of this Number. * * @return an {@code float} value for this Number. */ public float floatValue() { return (float) intValue(); } /** * Returns a {@code byte} representation of this Number. * * @return a {@code byte} value for this Number. */ public byte byteValue() { return (byte) intValue(); } /** * Returns a {@code short} representation of this Number. * * @return a {@code short} value for this Number. */ public short shortValue() { return (short) intValue(); } /** * Returns a {@code int} representation of this Number. * * @return a {@code int} value for this Number. */ public abstract int intValue(); /** * Returns a {@code long} representation of this Number. * * @return a {@code long} value for this Number. */ public long longValue() { return intValue(); } /** * Returns a string representation of this Number. * * @return a string representation of this Number. */ @Override public java.lang.String toString() { return java.lang.Integer.toString(intValue(), 10); } } public abstract class IntegerAlias extends NumberField { IntegerAlias(TypeAlias type) { super(type); } IntegerAlias(TypeAlias type, Offset offset) { super(type, offset); } @Override public void set(Number value) { getMemory().putInt(type, offset(), value.longValue()); } public void set(long value) { getMemory().putInt(type, offset(), value); } /** * Gets the value for this field. * * @return a long. */ public final long get() { return getMemory().getInt(type, offset()); } @Override public int intValue() { return (int) get(); } @Override public long longValue() { return get(); } /** * Returns a string representation of this field. * * @return a string representation of this field. */ @Override public final java.lang.String toString() { return java.lang.Long.toString(get()); } } /** * An 8 bit signed integer */ public class Signed8 extends NumberField { /** * Creates a new 8 bit integer field. */ public Signed8() { super(NativeType.SCHAR); } /** * Creates a new 8 bit integer field at a specific offset * * @param offset The offset within the memory area */ public Signed8(Offset offset) { super(NativeType.SCHAR, offset); } /** * Gets the value for this field. * * @return a byte. */ public final byte get() { return getMemory().getByte(offset()); } /** * Sets the value for this field. * * @param value the 8 bit value to set. */ public final void set(byte value) { getMemory().putByte(offset(), value); } public void set(java.lang.Number value) { getMemory().putByte(offset(), value.byteValue()); } /** * Returns a java byte representation of this field. * * @return a java byte value for this field. */ @Override public final byte byteValue() { return get(); } /** * Returns a java short representation of this field. * * @return a java short value for this field. */ @Override public final short shortValue() { return get(); } /** * Returns a java int representation of this field. * * @return a java int value for this field. */ @Override public final int intValue() { return get(); } } /** * An 8 bit unsigned integer */ public class Unsigned8 extends NumberField { /** * Creates a new 8 bit unsigned integer field. */ public Unsigned8() { super(NativeType.UCHAR); } /** * Creates a new 8 bit unsigned integer field at a specific offset * * @param offset The offset within the memory area for this field. */ public Unsigned8(Offset offset) { super(NativeType.UCHAR, offset); } /** * Gets the value for this field. * * @return a byte. */ public final short get() { short value = getMemory().getByte(offset()); return value < 0 ? (short) ((value & 0x7F) + 0x80) : value; } /** * Sets the value for this field. * * @param value the 8 bit value to set. */ public final void set(short value) { getMemory().putByte(offset(), (byte) value); } public void set(java.lang.Number value) { getMemory().putByte(offset(), value.byteValue()); } /** * Returns a java short representation of this field. * * @return a java short value for this field. */ @Override public final short shortValue() { return get(); } /** * Returns a java int representation of this field. * * @return a java int value for this field. */ @Override public final int intValue() { return get(); } } /** * A 16 bit signed integer field. */ public class Signed16 extends NumberField { /** * Creates a new 16 bit integer field. */ public Signed16() { super(NativeType.SSHORT); } /** * Creates a new 16 bit signed integer field at a specific offset * * @param offset The offset within the memory area for this field. */ public Signed16(Offset offset) { super(NativeType.SSHORT, offset); } /** * Gets the value for this field. * * @return a short. */ public final short get() { return getMemory().getShort(offset()); } /** * Sets the value for this field. * * @param value the 16 bit value to set. */ public final void set(short value) { getMemory().putShort(offset(), value); } public void set(java.lang.Number value) { getMemory().putShort(offset(), value.shortValue()); } /** * Returns a java short representation of this field. * * @return a java short value for this field. */ @Override public final short shortValue() { return get(); } /** * Returns a java int representation of this field. * * @return a java int value for this field. */ @Override public final int intValue() { return get(); } } /** * A 16 bit signed integer field. */ public class Unsigned16 extends NumberField { /** * Creates a new 16 bit integer field. */ public Unsigned16() { super(NativeType.USHORT); } /** * Creates a new 16 bit unsigned integer field at a specific offset * * @param offset The offset within the memory area for this field. */ public Unsigned16(Offset offset) { super(NativeType.USHORT, offset); } /** * Gets the value for this field. * * @return a short. */ public final int get() { int value = getMemory().getShort(offset()); return value < 0 ? (int)((value & 0x7FFF) + 0x8000) : value; } /** * Sets the value for this field. * * @param value the 16 bit unsigned value to set. */ public final void set(int value) { getMemory().putShort(offset(), (short) value); } public void set(Number value) { getMemory().putShort(offset(), value.shortValue()); } /** * Returns a java int representation of this field. * * @return a java int value for this field. */ @Override public final int intValue() { return get(); } } /** * A 32 bit signed integer field. */ public class Signed32 extends NumberField { /** * Creates a new 32 bit integer field. */ public Signed32() { super(NativeType.SINT); } /** * Creates a new 32 bit signed integer field at a specific offset * * @param offset The offset within the memory area for this field. */ public Signed32(Offset offset) { super(NativeType.SINT, offset); } /** * Gets the value for this field. * * @return a int. */ public final int get() { return getMemory().getInt(offset()); } /** * Sets the value for this field. * * @param value the 32 bit value to set. */ public final void set(int value) { getMemory().putInt(offset(), value); } public void set(java.lang.Number value) { getMemory().putInt(offset(), value.intValue()); } /** * Returns a java int representation of this field. * * @return a java int value for this field. */ @Override public final int intValue() { return get(); } } /** * A 32 bit signed integer field. */ public class Unsigned32 extends NumberField { /** * Creates a new 32 bit integer field. */ public Unsigned32() { super(NativeType.UINT); } /** * Creates a new 32 bit unsigned integer field at a specific offset * * @param offset The offset within the memory area for this field. */ public Unsigned32(Offset offset) { super(NativeType.UINT, offset); } /** * Gets the value for this field. * * @return a long. */ public final long get() { long value = getMemory().getInt(offset()); return value < 0 ? (long)((value & 0x7FFFFFFFL) + 0x80000000L) : value; } /** * Sets the value for this field. * * @param value the 32 bit unsigned value to set. */ public final void set(long value) { getMemory().putInt(offset(), (int) value); } public void set(java.lang.Number value) { getMemory().putInt(offset(), value.intValue()); } /** * Returns a java int representation of this field. * * @return a java int value for this field. */ @Override public final int intValue() { return (int) get(); } /** * Returns a java long representation of this field. * * @return a java long value for this field. */ @Override public final long longValue() { return get(); } /** * Returns a string representation of this field. * * @return a string representation of this field. */ @Override public final java.lang.String toString() { return java.lang.Long.toString(get()); } } /** * A 64 bit signed integer field. */ public class Signed64 extends NumberField { /** * Creates a new 64 bit integer field. */ public Signed64() { super(NativeType.SLONGLONG); } /** * Creates a new 64 bit signed integer field at a specific offset * * @param offset The offset within the memory area for this field. */ public Signed64(Offset offset) { super(NativeType.SLONGLONG, offset); } /** * Gets the value for this field. * * @return a long. */ public final long get() { return getMemory().getLongLong(offset()); } /** * Sets the value for this field. * * @param value the 64 bit value to set. */ public final void set(long value) { getMemory().putLongLong(offset(), value); } public void set(java.lang.Number value) { getMemory().putLongLong(offset(), value.longValue()); } /** * Returns a java int representation of this field. * * @return a java int value for this field. */ @Override public final int intValue() { return (int) get(); } /** * Returns a java long representation of this field. * * @return a java long value for this field. */ @Override public final long longValue() { return get(); } /** * Returns a string representation of this field. * * @return a string representation of this field. */ @Override public final java.lang.String toString() { return java.lang.Long.toString(get()); } } /** * A 64 bit unsigned integer field. */ public class Unsigned64 extends NumberField { /** * Creates a new 64 bit integer field. */ public Unsigned64() { super(NativeType.ULONGLONG); } /** * Creates a new 64 bit unsigned integer field at a specific offset * * @param offset The offset within the memory area for this field. */ public Unsigned64(Offset offset) { super(NativeType.ULONGLONG, offset); } /** * Gets the value for this field. * * @return a long. */ public final long get() { return getMemory().getLongLong(offset()); } /** * Sets the value for this field. * * @param value the 64 bit value to set. */ public final void set(long value) { getMemory().putLongLong(offset(), value); } public void set(java.lang.Number value) { getMemory().putLongLong(offset(), value.longValue()); } /** * Returns a java int representation of this field. * * @return a java int value for this field. */ @Override public final int intValue() { return (int) get(); } /** * Returns a java long representation of this field. * * @return a java long value for this field. */ @Override public final long longValue() { return get(); } /** * Returns a string representation of this field. * * @return a string representation of this field. */ @Override public final java.lang.String toString() { return java.lang.Long.toString(get()); } } /** * A native long integer field. */ public class SignedLong extends NumberField { /** * Creates a new native long field. */ public SignedLong() { super(NativeType.SLONG); } /** * Creates a new signed native long field at a specific offset * * @param offset The offset within the memory area for this field. */ public SignedLong(Offset offset) { super(NativeType.SLONG, offset); } /** * Gets the value for this field. * * @return a long. */ public final long get() { return getMemory().getNativeLong(offset()); } /** * Sets the value for this field. * * @param value the 32/64 bit value to set. */ public final void set(long value) { getMemory().putNativeLong(offset(), value); } public void set(java.lang.Number value) { getMemory().putNativeLong(offset(), value.longValue()); } /** * Returns a java int representation of this field. * * @return a java int value for this field. */ @Override public final int intValue() { return (int) get(); } /** * Returns a java long representation of this field. * * @return a java long value for this field. */ @Override public final long longValue() { return get(); } /** * Returns a string representation of this field. * * @return a string representation of this field. */ @Override public final java.lang.String toString() { return java.lang.Long.toString(get()); } } /** * A native long integer field. */ public class UnsignedLong extends NumberField { /** * Creates a new native long field. */ public UnsignedLong() { super(NativeType.ULONG); } /** * Creates a new unsigned native long field at a specific offset * * @param offset The offset within the memory area for this field. */ public UnsignedLong(Offset offset) { super(NativeType.ULONG, offset); } /** * Gets the value for this field. * * @return a int. */ public final long get() { long value = getMemory().getNativeLong(offset()); final long mask = getRuntime().findType(NativeType.SLONG).size() == 32 ? 0xffffffffL : 0xffffffffffffffffL; return value < 0 ? (long) ((value & mask) + mask + 1) : value; } /** * Sets the value for this field. * * @param value the 32/64 bit value to set. */ public final void set(long value) { getMemory().putNativeLong(offset(), value); } public void set(java.lang.Number value) { getMemory().putNativeLong(offset(), value.longValue()); } /** * Returns a java int representation of this field. * * @return a java int value for this field. */ @Override public final int intValue() { return (int) get(); } /** * Returns a java long representation of this field. * * @return a java long value for this field. */ @Override public final long longValue() { return get(); } /** * Returns a string representation of this field. * * @return a string representation of this field. */ @Override public final java.lang.String toString() { return java.lang.Long.toString(get()); } } public class Float extends NumberField { public Float() { super(NativeType.FLOAT); } /** * Creates a new float field at a specific offset * * @param offset The offset within the memory area for this field. */ public Float(Offset offset) { super(NativeType.FLOAT, offset); } public final float get() { return getMemory().getFloat(offset()); } public final void set(float value) { getMemory().putFloat(offset(), value); } public void set(java.lang.Number value) { getMemory().putFloat(offset(), value.floatValue()); } @Override public final int intValue() { return (int) get(); } @Override public final double doubleValue() { return get(); } @Override public final float floatValue() { return get(); } @Override public final long longValue() { return (long) get(); } @Override public final java.lang.String toString() { return java.lang.String.valueOf(get()); } } public final class Double extends NumberField { public Double() { super(NativeType.DOUBLE); } public Double(Offset offset) { super(NativeType.DOUBLE, offset); } public final double get() { return getMemory().getDouble(offset()); } public final void set(double value) { getMemory().putDouble(offset(), value); } public void set(java.lang.Number value) { getMemory().putDouble(offset(), value.doubleValue()); } @Override public final int intValue() { return (int) get(); } @Override public final long longValue() { return (long) get(); } @Override public final float floatValue() { return (float) get(); } @Override public final double doubleValue() { return get(); } @Override public final java.lang.String toString() { return java.lang.String.valueOf(get()); } } /** * Represents a native memory address. */ public class Address extends NumberField { /** * Creates a new Address field. */ public Address() { super(NativeType.ADDRESS); } public Address(Offset offset) { super(NativeType.ADDRESS, offset); } /** * Reads an {@code Address} value from the struct. * * @return a {@link jnr.ffi.Address}. */ public final jnr.ffi.Address get() { return jnr.ffi.Address.valueOf(getMemory().getAddress(offset())); } /** * Puts a {@link jnr.ffi.Address} value into the native memory. * * @param value the value to write. */ public final void set(jnr.ffi.Address value) { getMemory().putAddress(offset(), value != null ? value.nativeAddress() : 0); } public void set(java.lang.Number value) { getMemory().putAddress(offset(), value.longValue()); } /** * Returns an integer representation of this address. * * @return an integer value for this address. */ @Override public final int intValue() { return get().intValue(); } /** * Returns an {@code long} representation of this address. * * @return an {@code long} value for this address. */ @Override public final long longValue() { return get().longValue(); } /** * Returns a string representation of this Address. * * @return a string representation of this Address. */ @Override public final java.lang.String toString() { return get().toString(); } } public abstract class PointerField extends NumberField { /** * Creates a new Address field. */ public PointerField() { super(NativeType.ADDRESS); } public PointerField(Offset offset) { super(NativeType.ADDRESS, offset); } /** * Gets the {@link jnr.ffi.Pointer} value from the native memory. * * @return a {@link jnr.ffi.Pointer}. */ protected final jnr.ffi.Pointer getPointer() { return getMemory().getPointer(offset()); } /** * Gets the size of a Pointer in bits * * @return the size of the Pointer */ public final int size() { return getRuntime().findType(NativeType.ADDRESS).size() * 8; } /** * Puts a {@link jnr.ffi.Address} value into the native memory. * * @param value the value to write. */ public final void set(jnr.ffi.Pointer value) { jnr.ffi.Pointer finalPointer = value; if (value instanceof ArrayMemoryIO) { ArrayMemoryIO arrayMemory = (ArrayMemoryIO) value; byte[] valueArray = arrayMemory.array(); finalPointer = Memory.allocateDirect(getRuntime(), valueArray.length); finalPointer.put(0, valueArray, 0, valueArray.length); } getMemory().putPointer(offset(), finalPointer); } public void set(java.lang.Number value) { getMemory().putAddress(offset(), value.longValue()); } /** * Returns an integer representation of this Pointer. * * @return an integer value for this Pointer. */ @Override public int intValue() { return (int) getMemory().getAddress(offset()); } /** * Returns an {@code long} representation of this Pointer. * * @return an {@code long} value for this Pointer. */ @Override public long longValue() { return getMemory().getAddress(offset()); } /** * Returns a string representation of this Pointer. * * @return a string representation of this Pointer. */ @Override public java.lang.String toString() { return getPointer().toString(); } } /** * Represents a native memory address. */ public class Pointer extends PointerField { /** * Creates a new Address field. */ public Pointer() { } public Pointer(Offset offset) { super(offset); } /** * Gets the {@link jnr.ffi.Pointer} value from the native memory. * * @return a {@link jnr.ffi.Pointer}. */ public final jnr.ffi.Pointer get() { return getPointer(); } /** * Returns an integer representation of this Pointer. * * @return an integer value for this Pointer. */ @Override public final int intValue() { return super.intValue(); } /** * Returns an {@code long} representation of this Pointer. * * @return an {@code long} value for this Pointer. */ @Override public final long longValue() { return super.longValue(); } /** * Returns a string representation of this Pointer. * * @return a string representation of this Pointer. */ @Override public final java.lang.String toString() { return super.toString(); } } /** * Represents a reference to a Struct or and array of Structs * @param - Struct type */ public class StructRef extends PointerField { private final Constructor structConstructor; private final Class structType; private final int size; public StructRef(Class structType) { this.structType = structType; try { structConstructor = structType.getDeclaredConstructor(Runtime.class); size = Struct.size(structConstructor.newInstance(getRuntime())); } catch (Exception ex) { throw new RuntimeException(ex); } } /** * @param structType Struct type * @param initialStructCount the number of struct instances. Use this to allocate memory without setting value. */ public StructRef(Class structType, int initialStructCount) { this(structType); set(Memory.allocateDirect(getRuntime(), size * initialStructCount)); } public StructRef(Offset offset, Class structType) { super(offset); this.structType = structType; try { structConstructor = structType.getDeclaredConstructor(Runtime.class); size = Struct.size(structConstructor.newInstance(getRuntime())); } catch (Exception ex) { throw new RuntimeException(ex); } } /** * @param offset offset of the field * @param structType Struct type * @param initialStructCount the number of struct instances. Use this to allocate memory without setting value. */ public StructRef(Offset offset, Class structType, int initialStructCount) { this(offset, structType); set(Memory.allocateDirect(getRuntime(), size * initialStructCount)); } public final void set(T struct) { jnr.ffi.Pointer structMemory = Struct.getMemory(struct); set(structMemory); } public final void set(T[] structs) { if (structs.length == 0) { set(Memory.allocateDirect(getRuntime(), 0)); return; } jnr.ffi.Pointer value = Memory.allocateDirect(getRuntime(), size * structs.length); byte[] data = new byte[size]; for (int i = 0; i < structs.length; i++) { Struct.getMemory(structs[i]).get(0L, data, 0, size); value.put(size * i, data, 0, size); } set(value); } /** * @return struct from memory */ public final T get() { T struct; try { struct = structConstructor.newInstance(getRuntime()); } catch (Exception ex) { throw new RuntimeException(ex); } struct.useMemory(getPointer()); return struct; } /** * @return struct from memory */ public final T[] get(int length) { try { T[] array = (T[]) Array.newInstance(structType, length); for (int i = 0; i < length; ++i) { array[i] = structConstructor.newInstance(getRuntime()); array[i].useMemory(getPointer().slice(Struct.size(array[i]) * i)); } return array; } catch (Exception ex) { throw new RuntimeException(ex); } } @Override public java.lang.String toString() { return "struct @ " + super.toString() + '\n' + get(); } } /** * Base for all the Enum fields. * * @param the type of {@link java.lang.Enum} */ protected abstract class EnumField extends NumberField { protected final Class enumClass; /** * Constructs a new Enum field. * * @param type the native type of the enum. * @param enumClass the Enum class. */ public EnumField(NativeType type, Class enumClass) { super(type); this.enumClass = enumClass; } /** * Gets a java Enum value representing the native integer value. * * @return a java Enum value. */ public abstract E get(); /** * Returns a string representation of this field. * * @return a string representation of this field. */ @Override public final java.lang.String toString() { return get().toString(); } } /** * An 8 bit enum field. * * @param the {@link java.lang.Enum} to translate to/from. */ public class Enum8> extends EnumField { /** * Creates a new 8 bit enum field. * * @param enumClass the class of the {@link java.lang.Enum}. */ public Enum8(Class enumClass) { super(NativeType.SCHAR, enumClass); } /** * Gets a java Enum value representing the native integer value. * * @return a java Enum value. */ public final E get() { return enumClass.cast(EnumMapper.getInstance(enumClass).valueOf(intValue())); } /** * Sets the native integer value using a java Enum value. * * @param value the java Enum value. */ public final void set(E value) { getMemory().putByte(offset(), (byte) EnumMapper.getInstance(enumClass).intValue(value)); } public void set(java.lang.Number value) { getMemory().putByte(offset(), value.byteValue()); } /** * Returns an integer representation of this enum field. * * @return an integer value for this enum field. */ @Override public final int intValue() { return getMemory().getByte(offset()); } } public class Enum16> extends EnumField { public Enum16(Class enumClass) { super(NativeType.SSHORT, enumClass); } public final E get() { return enumClass.cast(EnumMapper.getInstance(enumClass).valueOf(intValue())); } public final void set(E value) { getMemory().putShort(offset(), (short) EnumMapper.getInstance(enumClass).intValue(value)); } public void set(java.lang.Number value) { getMemory().putShort(offset(), value.shortValue()); } @Override public final int intValue() { return getMemory().getShort(offset()); } } public class Enum32> extends EnumField { public Enum32(Class enumClass) { super(NativeType.SINT, enumClass); } public final E get() { return enumClass.cast(EnumMapper.getInstance(enumClass).valueOf(intValue())); } public final void set(E value) { getMemory().putInt(offset(), EnumMapper.getInstance(enumClass).intValue(value)); } public void set(java.lang.Number value) { getMemory().putInt(offset(), value.intValue()); } @Override public final int intValue() { return getMemory().getInt(offset()); } } public class Enum64> extends EnumField { public Enum64(Class enumClass) { super(NativeType.SLONGLONG, enumClass); } public final E get() { return enumClass.cast(EnumMapper.getInstance(enumClass).valueOf(intValue())); } public final void set(E value) { getMemory().putLongLong(offset(), EnumMapper.getInstance(enumClass).intValue(value)); } public void set(java.lang.Number value) { getMemory().putLongLong(offset(), value.longValue()); } @Override public final int intValue() { return (int) longValue(); } @Override public final long longValue() { return getMemory().getLongLong(offset()); } } public class EnumLong> extends EnumField { public EnumLong(Class enumClass) { super(NativeType.SLONG, enumClass); } public final E get() { return enumClass.cast(EnumMapper.getInstance(enumClass).valueOf(intValue())); } public final void set(E value) { getMemory().putNativeLong(offset(), EnumMapper.getInstance(enumClass).intValue(value)); } public void set(java.lang.Number value) { getMemory().putNativeLong(offset(), value.longValue()); } @Override public final int intValue() { return (int) longValue(); } @Override public final long longValue() { return getMemory().getNativeLong(offset()); } } public class Enum> extends Enum32 { public Enum(Class enumClass) { super(enumClass); } } abstract public class String extends AbstractMember { protected final Charset charset; protected final int length; protected String(int size, int align, int length, Charset cs) { super(size, align); this.length = length; this.charset = cs; } protected String(int size, int align, Offset offset, int length, Charset cs) { super(size, align, offset); this.length = length; this.charset = cs; } public final int length() { return length; } protected abstract jnr.ffi.Pointer getStringMemory(); public abstract java.lang.String get(); public abstract void set(java.lang.String value); @Override public final java.lang.String toString() { return get(); } } public class UTFString extends String { public UTFString(int length, Charset cs) { super(length * 8, 8, length, cs); // FIXME: This won't work for non-ASCII } protected jnr.ffi.Pointer getStringMemory() { return getMemory().slice(offset(), length()); } public final java.lang.String get() { return getStringMemory().getString(0, length, charset); } public final void set(java.lang.String value) { getStringMemory().putString(0, value, length, charset); } } public class UTF8String extends UTFString { public UTF8String(int size) { super(size, UTF8); } } public class AsciiString extends UTFString { public AsciiString(int size) { super(size, ASCII); } } public class UTFStringRef extends String { private jnr.ffi.Pointer valueHolder; public UTFStringRef(int length, Charset cs) { super(getRuntime().findType(NativeType.ADDRESS).size() * 8, getRuntime().findType(NativeType.ADDRESS).alignment() * 8, length, cs); } public UTFStringRef(Charset cs) { this(Integer.MAX_VALUE, cs); } protected jnr.ffi.Pointer getStringMemory() { return getMemory().getPointer(offset(), length()); } public final java.lang.String get() { jnr.ffi.Pointer ptr = getStringMemory(); return ptr != null ? ptr.getString(0, length, charset) : null; } public final void set(java.lang.String value) { if (value != null) { valueHolder = getRuntime().getMemoryManager().allocateDirect(length() * 4); valueHolder.putString(0, value, length() * 4, charset); getMemory().putPointer(offset(), valueHolder); } else { this.valueHolder = null; getMemory().putAddress(offset(), 0); } } } public class UTF8StringRef extends UTFStringRef { public UTF8StringRef(int size) { super(size, UTF8); } public UTF8StringRef() { super(Integer.MAX_VALUE, UTF8); } } public class AsciiStringRef extends UTFStringRef { public AsciiStringRef(int size) { super(size, ASCII); } public AsciiStringRef() { super(Integer.MAX_VALUE, ASCII); } } /** * Specialized padding fields for structs. Use this instead of arrays of other * members for more efficient struct construction. */ protected final class Padding extends AbstractMember { public Padding(Type type, int length) { super(type.size() * 8 * length, type.alignment() * 8); } public Padding(NativeType type, int length) { super(getRuntime().findType(type).size() * 8 * length, getRuntime().findType(type).alignment() * 8); } } public final class Function extends AbstractMember { private final Class closureClass; private T instance; public Function(Class closureClass) { super(NativeType.ADDRESS); this.closureClass = closureClass; } public final void set(T value) { getMemory().putPointer(offset(), getRuntime().getClosureManager().getClosurePointer(closureClass, instance = value)); } } protected final Function function(Class closureClass) { return new Function(closureClass); } public final class int8_t extends IntegerAlias { public int8_t() { super(TypeAlias.int8_t); } public int8_t(Offset offset) { super(TypeAlias.int8_t, offset); } } public final class u_int8_t extends IntegerAlias { public u_int8_t() { super(TypeAlias.u_int8_t); } public u_int8_t(Offset offset) { super(TypeAlias.u_int8_t, offset); } } public final class int16_t extends IntegerAlias { public int16_t() { super(TypeAlias.int16_t); } public int16_t(Offset offset) { super(TypeAlias.int16_t, offset); } } public final class u_int16_t extends IntegerAlias { public u_int16_t() { super(TypeAlias.u_int16_t); } public u_int16_t(Offset offset) { super(TypeAlias.u_int16_t, offset); } } public final class int32_t extends IntegerAlias { public int32_t() { super(TypeAlias.int32_t); } public int32_t(Offset offset) { super(TypeAlias.int32_t, offset); } } public final class u_int32_t extends IntegerAlias { public u_int32_t() { super(TypeAlias.u_int32_t); } public u_int32_t(Offset offset) { super(TypeAlias.u_int32_t, offset); } } public final class int64_t extends IntegerAlias { public int64_t() { super(TypeAlias.int64_t); } public int64_t(Offset offset) { super(TypeAlias.int64_t, offset); } } public final class u_int64_t extends IntegerAlias { public u_int64_t() { super(TypeAlias.u_int64_t); } public u_int64_t(Offset offset) { super(TypeAlias.u_int64_t, offset); } } public final class intptr_t extends IntegerAlias { public intptr_t() { super(TypeAlias.intptr_t); } public intptr_t(Offset offset) { super(TypeAlias.intptr_t, offset); } } public final class uintptr_t extends IntegerAlias { public uintptr_t() { super(TypeAlias.uintptr_t); } public uintptr_t(Offset offset) { super(TypeAlias.uintptr_t, offset); } } public final class caddr_t extends IntegerAlias { public caddr_t() { super(TypeAlias.caddr_t); } public caddr_t(Offset offset) { super(TypeAlias.caddr_t, offset); } } public final class dev_t extends IntegerAlias { public dev_t() { super(TypeAlias.dev_t); } public dev_t(Offset offset) { super(TypeAlias.dev_t, offset); } } public final class blkcnt_t extends IntegerAlias { public blkcnt_t() { super(TypeAlias.blkcnt_t); } public blkcnt_t(Offset offset) { super(TypeAlias.blkcnt_t, offset); } } public final class blksize_t extends IntegerAlias { public blksize_t() { super(TypeAlias.blksize_t); } public blksize_t(Offset offset) { super(TypeAlias.blksize_t, offset); } } public final class gid_t extends IntegerAlias { public gid_t() { super(TypeAlias.gid_t); } public gid_t(Offset offset) { super(TypeAlias.gid_t, offset); } } public final class in_addr_t extends IntegerAlias { public in_addr_t() { super(TypeAlias.in_addr_t); } public in_addr_t(Offset offset) { super(TypeAlias.in_addr_t, offset); } } public final class in_port_t extends IntegerAlias { public in_port_t() { super(TypeAlias.in_port_t); } public in_port_t(Offset offset) { super(TypeAlias.in_port_t, offset); } } public final class ino_t extends IntegerAlias { public ino_t() { super(TypeAlias.ino_t); } public ino_t(Offset offset) { super(TypeAlias.ino_t, offset); } } public final class ino64_t extends IntegerAlias { public ino64_t() { super(TypeAlias.ino64_t); } public ino64_t(Offset offset) { super(TypeAlias.ino64_t, offset); } } public final class key_t extends IntegerAlias { public key_t() { super(TypeAlias.key_t); } public key_t(Offset offset) { super(TypeAlias.key_t, offset); } } public final class mode_t extends IntegerAlias { public mode_t() { super(TypeAlias.mode_t); } public mode_t(Offset offset) { super(TypeAlias.mode_t, offset); } } public final class nlink_t extends IntegerAlias { public nlink_t() { super(TypeAlias.nlink_t); } public nlink_t(Offset offset) { super(TypeAlias.nlink_t, offset); } } public final class id_t extends IntegerAlias { public id_t() { super(TypeAlias.id_t); } public id_t(Offset offset) { super(TypeAlias.id_t, offset); } } public final class pid_t extends IntegerAlias { public pid_t() { super(TypeAlias.pid_t); } public pid_t(Offset offset) { super(TypeAlias.pid_t, offset); } } public final class off_t extends IntegerAlias { public off_t() { super(TypeAlias.off_t); } public off_t(Offset offset) { super(TypeAlias.off_t, offset); } } public final class swblk_t extends IntegerAlias { public swblk_t() { super(TypeAlias.swblk_t); } public swblk_t(Offset offset) { super(TypeAlias.swblk_t, offset); } } public final class uid_t extends IntegerAlias { public uid_t() { super(TypeAlias.uid_t); } public uid_t(Offset offset) { super(TypeAlias.uid_t, offset); } } public final class clock_t extends IntegerAlias { public clock_t() { super(TypeAlias.clock_t); } public clock_t(Offset offset) { super(TypeAlias.clock_t, offset); } } public final class size_t extends IntegerAlias { public size_t() { super(TypeAlias.size_t); } public size_t(Offset offset) { super(TypeAlias.size_t, offset); } } public final class ssize_t extends IntegerAlias { public ssize_t() { super(TypeAlias.ssize_t); } public ssize_t(Offset offset) { super(TypeAlias.ssize_t, offset); } } public final class time_t extends IntegerAlias { public time_t() { super(TypeAlias.time_t); } public time_t(Offset offset) { super(TypeAlias.time_t, offset); } } public final class fsblkcnt_t extends IntegerAlias { public fsblkcnt_t() { super(TypeAlias.fsblkcnt_t); } public fsblkcnt_t(Offset offset) { super(TypeAlias.fsblkcnt_t, offset); } } public final class fsfilcnt_t extends IntegerAlias { public fsfilcnt_t() { super(TypeAlias.fsfilcnt_t); } public fsfilcnt_t(Offset offset) { super(TypeAlias.fsfilcnt_t, offset); } } public final class sa_family_t extends IntegerAlias { public sa_family_t() { super(TypeAlias.sa_family_t); } public sa_family_t(Offset offset) { super(TypeAlias.sa_family_t, offset); } } public final class socklen_t extends IntegerAlias { public socklen_t() { super(TypeAlias.socklen_t); } public socklen_t(Offset offset) { super(TypeAlias.socklen_t, offset); } } public final class rlim_t extends IntegerAlias { public rlim_t() { super(TypeAlias.rlim_t); } public rlim_t(Offset offset) { super(TypeAlias.rlim_t, offset); } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/StructLayout.java000066400000000000000000001616651316720554100237460ustar00rootroot00000000000000/* * Copyright (C) 2011 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; import jnr.ffi.util.EnumMapper; import java.lang.reflect.Constructor; import java.nio.charset.Charset; /** * */ public class StructLayout extends Type { static final Charset ASCII = Charset.forName("ASCII"); static final Charset UTF8 = Charset.forName("UTF-8"); private final Runtime runtime; private final boolean isUnion = false; private boolean resetIndex = false; StructLayout enclosing = null; int offset = 0; int size = 0; int alignment = 1; int paddedSize = 0; /** * Creates a new StructLayout. * * @param runtime The current runtime. */ protected StructLayout(Runtime runtime) { this.runtime = runtime; } protected StructLayout(Runtime runtime, int structSize) { this.runtime = runtime; this.size = this.paddedSize = structSize; } public final Runtime getRuntime() { return this.runtime; } public final int size() { return paddedSize; } public final int alignment() { return alignment; } public final int offset() { return offset; } public NativeType getNativeType() { return NativeType.STRUCT; } /** * Returns a human readable {@link java.lang.String} representation of the structure. * * @return a {@code String} representation of this structure. */ @Override public java.lang.String toString() { StringBuilder sb = new StringBuilder(); java.lang.reflect.Field[] fields = getClass().getDeclaredFields(); sb.append(getClass().getSimpleName()).append(" { \n"); final java.lang.String fieldPrefix = " "; for (java.lang.reflect.Field field : fields) { try { sb.append(fieldPrefix).append('\n'); } catch (Throwable ex) { throw new RuntimeException(ex); } } sb.append("}\n"); return sb.toString(); } private static int align(int offset, int alignment) { return (offset + alignment - 1) & ~(alignment - 1); } protected final int addField(int size, int align) { final int off = resetIndex ? 0 : align(this.size, align); this.size = Math.max(this.size, off + size); this.alignment = Math.max(this.alignment, align); this.paddedSize = align(this.size, this.alignment); return off; } protected final int addField(int size, int align, Offset offset) { this.size = Math.max(this.size, offset.intValue() + size); this.alignment = Math.max(this.alignment, align); this.paddedSize = align(this.size, this.alignment); return offset.intValue(); } protected final int addField(Type t) { return addField(t.size(), t.alignment()); } protected final int addField(Type t, Offset offset) { return addField(t.size(), t.alignment(), offset); } protected final Offset at(int offset) { return new Offset(offset); } /** * Interface all Struct members must implement. */ protected abstract class Field { private final int offset; protected Field(int offset) { this.offset = offset; } /** * Gets the Struct this Member is a member of. * * @return a Struct. */ public final StructLayout enclosing() { return StructLayout.this; } /** * Gets the offset within the structure for this field. * * @return the offset within the structure. */ public final long offset() { return offset + StructLayout.this.offset; } } /** * Starts an array construction session */ protected final void arrayBegin() { resetIndex = false; } /** * Ends an array construction session */ protected final void arrayEnd() { resetIndex = isUnion; } /** * Creates an array of Member instances. * * @param The type of the Member subclass to create. * @param array the array to store the instances in * @return the array that was passed in */ @SuppressWarnings("unchecked") protected T[] array(T[] array) { arrayBegin(); try { Class arrayClass = array.getClass().getComponentType(); Constructor ctor = arrayClass.getDeclaredConstructor(new Class[] { arrayClass.getEnclosingClass() }); Object[] parameters = { StructLayout.this }; for (int i = 0; i < array.length; ++i) { array[i] = (T) ctor.newInstance(parameters); } } catch (Exception ex) { throw new RuntimeException(ex); } arrayEnd(); return array; } protected final T inner(T structLayout) { structLayout.enclosing = this; structLayout.offset = align(this.size, structLayout.alignment); this.size = structLayout.offset + structLayout.size; this.paddedSize = align(this.size, this.alignment()); return structLayout; } protected static final class Offset extends java.lang.Number { private final int offset; public Offset(int offset) { this.offset = offset; } @Override public int intValue() { return offset; } @Override public long longValue() { return offset; } @Override public float floatValue() { return offset; } @Override public double doubleValue() { return offset; } } /** * Base implementation of Member */ protected abstract class AbstractField extends Field { protected AbstractField(int size, int align, Offset offset) { super(addField(size, align, offset)); } protected AbstractField(int size, int align) { super(addField(size, align)); } protected AbstractField(NativeType type) { super(addField(getRuntime().findType(type))); } protected AbstractField(Type type) { super(addField(type)); } protected AbstractField(NativeType type, Offset offset) { super(addField(getRuntime().findType(type), offset)); } protected AbstractField(Type type, Offset offset) { super(addField(type, offset)); } } /** * Base class for Boolean fields */ protected abstract class AbstractBoolean extends AbstractField { protected AbstractBoolean(NativeType type) { super(type); } protected AbstractBoolean(NativeType type, Offset offset) { super(type, offset); } /** * Gets the value for this field. * * @param ptr The pointer to the field. * @return a boolean. */ public abstract boolean get(jnr.ffi.Pointer ptr); /** * Sets the field to a new value. * * @param ptr The pointer to the field. * @param value The new value. */ public abstract void set(jnr.ffi.Pointer ptr, boolean value); /** * Returns a string representation of this Boolean. * * @param ptr The pointer to the field. * @return a string representation of this Boolean. */ public java.lang.String toString(jnr.ffi.Pointer ptr) { return java.lang.Boolean.toString(get(ptr)); } } /** * A normal C boolean - 1 byte in size */ protected final class Boolean extends AbstractBoolean { protected Boolean() { super(NativeType.SCHAR); } protected Boolean(Offset offset) { super(NativeType.SCHAR, offset); } public final boolean get(jnr.ffi.Pointer ptr) { return (ptr.getByte(offset()) & 0x1) != 0; } public final void set(jnr.ffi.Pointer ptr, boolean value) { ptr.putByte(offset(), (byte) (value ? 1 : 0)); } } /** * A Windows BOOL - 4 bytes */ protected final class WBOOL extends AbstractBoolean { protected WBOOL() { super(NativeType.SINT); } protected WBOOL(Offset offset) { super(NativeType.SINT, offset); } public final boolean get(jnr.ffi.Pointer ptr) { return (ptr.getInt(offset()) & 0x1) != 0; } public final void set(jnr.ffi.Pointer ptr, boolean value) { ptr.putInt(offset(), value ? 1 : 0); } } /** * Base class for all Number structure fields. */ protected abstract class NumberField extends Field { protected final Type type; protected NumberField(NativeType nativeType) { this(getRuntime().findType(nativeType)); } protected NumberField(Type type) { super(addField(type)); this.type = type; } protected NumberField(NativeType nativeType, Offset offset) { this(getRuntime().findType(nativeType), offset); } protected NumberField(Type type, Offset offset) { super(addField(type, offset)); this.type = type; } /** * Sets the field to a new value. * * @param ptr The pointer to the field. * @param value The new value. */ public abstract void set(jnr.ffi.Pointer ptr, java.lang.Number value); /** * Returns an {@code float} representation of this Number. * * @param ptr The pointer to the field. * @return an {@code float} value for this Number. */ public double doubleValue(jnr.ffi.Pointer ptr) { return (double) longValue(ptr); } /** * Returns an {@code float} representation of this Number. * * @param ptr The pointer to the field. * @return an {@code float} value for this Number. */ public float floatValue(jnr.ffi.Pointer ptr) { return (float) intValue(ptr); } /** * Returns a {@code byte} representation of this Number. * * @param ptr The pointer to the field. * @return a {@code byte} value for this Number. */ public byte byteValue(jnr.ffi.Pointer ptr) { return (byte) intValue(ptr); } /** * Returns a {@code short} representation of this Number. * * @param ptr The pointer to the field. * @return a {@code short} value for this Number. */ public short shortValue(jnr.ffi.Pointer ptr) { return (short) intValue(ptr); } /** * Returns a {@code int} representation of this Number. * * @param ptr The pointer to the field. * @return a {@code int} value for this Number. */ public abstract int intValue(jnr.ffi.Pointer ptr); /** * Returns a {@code long} representation of this Number. * * @param ptr The pointer to the field. * @return a {@code long} value for this Number. */ public long longValue(jnr.ffi.Pointer ptr) { return intValue(ptr); } /** * Returns a string representation of this Number. * * @param ptr The pointer to the field. * @return a string representation of this Number. */ public java.lang.String toString(jnr.ffi.Pointer ptr) { return java.lang.Integer.toString(intValue(ptr), 10); } } public abstract class IntegerAlias extends NumberField { protected IntegerAlias(TypeAlias type) { super(getRuntime().findType(type)); } protected IntegerAlias(TypeAlias type, Offset offset) { super(getRuntime().findType(type), offset); } @Override public void set(jnr.ffi.Pointer ptr, Number value) { ptr.putInt(type, offset(), value.longValue()); } public void set(jnr.ffi.Pointer ptr, long value) { ptr.putInt(type, offset(), value); } /** * Gets the value for this field. * * @param ptr The pointer to the field. * @return a long. */ public final long get(jnr.ffi.Pointer ptr) { return ptr.getInt(type, offset()); } @Override public int intValue(jnr.ffi.Pointer ptr) { return (int) get(ptr); } @Override public long longValue(jnr.ffi.Pointer ptr) { return get(ptr); } } /** * An 8 bit signed integer */ public class Signed8 extends NumberField { /** * Creates a new 8 bit integer field. */ public Signed8() { super(NativeType.SCHAR); } /** * Creates a new 8 bit integer field at a specific offset * * @param offset The offset within the memory area */ public Signed8(Offset offset) { super(NativeType.SCHAR, offset); } /** * Gets the value for this field. * * @param ptr The pointer to the field. * @return a byte. */ public final byte get(jnr.ffi.Pointer ptr) { return ptr.getByte(offset()); } /** * Sets the value for this field. * * @param ptr The memory to set the value in. * @param value the 8 bit value to set. */ public final void set(jnr.ffi.Pointer ptr, byte value) { ptr.putByte(offset(), value); } public void set(jnr.ffi.Pointer ptr, java.lang.Number value) { ptr.putByte(offset(), value.byteValue()); } /** * Returns a java byte representation of this field. * * @return a java byte value for this field. */ @Override public final byte byteValue(jnr.ffi.Pointer ptr) { return get(ptr); } /** * Returns a java short representation of this field. * * @return a java short value for this field. */ @Override public final short shortValue(jnr.ffi.Pointer ptr) { return get(ptr); } /** * Returns a java int representation of this field. * * @return a java int value for this field. */ @Override public final int intValue(jnr.ffi.Pointer ptr) { return get(ptr); } } /** * An 8 bit unsigned integer */ public class Unsigned8 extends NumberField { /** * Creates a new 8 bit unsigned integer field. */ public Unsigned8() { super(NativeType.UCHAR); } /** * Creates a new 8 bit unsigned integer field at a specific offset * * @param offset The offset within the memory area for this field. */ public Unsigned8(Offset offset) { super(NativeType.UCHAR, offset); } /** * Gets the value for this field. * * @param ptr The pointer to the field. * @return a byte. */ public final short get(jnr.ffi.Pointer ptr) { short value = ptr.getByte(offset()); return value < 0 ? (short) ((value & 0x7F) + 0x80) : value; } /** * Sets the value for this field. * * @param ptr The pointer to the field. * @param value the 8 bit value to set. */ public final void set(jnr.ffi.Pointer ptr, short value) { ptr.putByte(offset(), (byte) value); } public void set(jnr.ffi.Pointer ptr, java.lang.Number value) { ptr.putByte(offset(), value.byteValue()); } /** * Returns a java short representation of this field. * * @return a java short value for this field. */ @Override public final short shortValue(jnr.ffi.Pointer ptr) { return get(ptr); } /** * Returns a java int representation of this field. * * @return a java int value for this field. */ @Override public final int intValue(jnr.ffi.Pointer ptr) { return get(ptr); } } /** * A 16 bit signed integer field. */ public class Signed16 extends NumberField { /** * Creates a new 16 bit integer field. */ public Signed16() { super(NativeType.SSHORT); } /** * Creates a new 16 bit signed integer field at a specific offset * * @param offset The offset within the memory area for this field. */ public Signed16(Offset offset) { super(NativeType.SSHORT, offset); } /** * Gets the value for this field. * * @param ptr The pointer to the field. * @return a short. */ public final short get(jnr.ffi.Pointer ptr) { return ptr.getShort(offset()); } /** * Sets the value for this field. * * @param ptr The pointer to the field. * @param value the 16 bit value to set. */ public final void set(jnr.ffi.Pointer ptr, short value) { ptr.putShort(offset(), value); } public void set(jnr.ffi.Pointer ptr, java.lang.Number value) { ptr.putShort(offset(), value.shortValue()); } /** * Returns a java short representation of this field. * * @return a java short value for this field. */ @Override public final short shortValue(jnr.ffi.Pointer ptr) { return get(ptr); } /** * Returns a java int representation of this field. * * @return a java int value for this field. */ @Override public final int intValue(jnr.ffi.Pointer ptr) { return get(ptr); } } /** * A 16 bit signed integer field. */ public class Unsigned16 extends NumberField { /** * Creates a new 16 bit integer field. */ public Unsigned16() { super(NativeType.USHORT); } /** * Creates a new 16 bit unsigned integer field at a specific offset * * @param offset The offset within the memory area for this field. */ public Unsigned16(Offset offset) { super(NativeType.USHORT, offset); } /** * Gets the value for this field. * * @param ptr The pointer to the field. * @return a short. */ public final int get(jnr.ffi.Pointer ptr) { int value = ptr.getShort(offset()); return value < 0 ? (int)((value & 0x7FFF) + 0x8000) : value; } /** * Sets the value for this field. * * @param ptr The pointer to the field. * @param value the 16 bit unsigned value to set. */ public final void set(jnr.ffi.Pointer ptr, int value) { ptr.putShort(offset(), (short) value); } public void set(jnr.ffi.Pointer ptr, Number value) { ptr.putShort(offset(), value.shortValue()); } /** * Returns a java int representation of this field. * * @param ptr The pointer to the field. * @return a java int value for this field. */ @Override public final int intValue(jnr.ffi.Pointer ptr) { return get(ptr); } } /** * A 32 bit signed integer field. */ public class Signed32 extends NumberField { /** * Creates a new 32 bit integer field. */ public Signed32() { super(NativeType.SINT); } /** * Creates a new 32 bit signed integer field at a specific offset * * @param offset The offset within the memory area for this field. */ public Signed32(Offset offset) { super(NativeType.SINT, offset); } /** * Gets the value for this field. * * @param ptr The pointer to the field. * @return a int. */ public final int get(jnr.ffi.Pointer ptr) { return ptr.getInt(offset()); } /** * Sets the value for this field. * * @param ptr The pointer to the field. * @param value the 32 bit value to set. */ public final void set(jnr.ffi.Pointer ptr, int value) { ptr.putInt(offset(), value); } public void set(jnr.ffi.Pointer ptr, java.lang.Number value) { ptr.putInt(offset(), value.intValue()); } /** * Returns a java int representation of this field. * * @param ptr The pointer to the field. * @return a java int value for this field. */ @Override public final int intValue(jnr.ffi.Pointer ptr) { return get(ptr); } } /** * A 32 bit signed integer field. */ public class Unsigned32 extends NumberField { /** * Creates a new 32 bit integer field. */ public Unsigned32() { super(NativeType.UINT); } /** * Creates a new 32 bit unsigned integer field at a specific offset * * @param offset The offset within the memory area for this field. */ public Unsigned32(Offset offset) { super(NativeType.SINT, offset); } /** * Gets the value for this field. * * @param ptr The pointer to the field. * @return a long. */ public final long get(jnr.ffi.Pointer ptr) { long value = ptr.getInt(offset()); return value < 0 ? (long)((value & 0x7FFFFFFFL) + 0x80000000L) : value; } /** * Sets the value for this field. * * @param ptr The pointer to the field. * @param value the 32 bit unsigned value to set. */ public final void set(jnr.ffi.Pointer ptr, long value) { ptr.putInt(offset(), (int) value); } public void set(jnr.ffi.Pointer ptr, java.lang.Number value) { ptr.putInt(offset(), value.intValue()); } /** * Returns a java int representation of this field. * * @param ptr The pointer to the field. * @return a java int value for this field. */ @Override public final int intValue(jnr.ffi.Pointer ptr) { return (int) get(ptr); } /** * Returns a java long representation of this field. * * @param ptr The pointer to the field. * @return a java long value for this field. */ @Override public final long longValue(jnr.ffi.Pointer ptr) { return get(ptr); } } /** * A 64 bit signed integer field. */ public class Signed64 extends NumberField { /** * Creates a new 64 bit integer field. */ public Signed64() { super(NativeType.SLONGLONG); } /** * Creates a new 64 bit signed integer field at a specific offset * * @param offset The offset within the memory area for this field. */ public Signed64(Offset offset) { super(NativeType.SLONGLONG, offset); } /** * Gets the value for this field. * * @param ptr The pointer to the field. * @return a long. */ public final long get(jnr.ffi.Pointer ptr) { return ptr.getLongLong(offset()); } /** * Sets the value for this field. * * @param ptr The pointer to the field. * @param value the 64 bit value to set. */ public final void set(jnr.ffi.Pointer ptr, long value) { ptr.putLongLong(offset(), value); } public void set(jnr.ffi.Pointer ptr, java.lang.Number value) { ptr.putLongLong(offset(), value.longValue()); } /** * Returns a java int representation of this field. * * @param ptr The pointer to the field. * @return a java int value for this field. */ @Override public final int intValue(jnr.ffi.Pointer ptr) { return (int) get(ptr); } /** * Returns a java long representation of this field. * * @param ptr The pointer to the field. * @return a java long value for this field. */ @Override public final long longValue(jnr.ffi.Pointer ptr) { return get(ptr); } /** * Returns a string representation of this field. * * @param ptr The pointer to the field. * @return a string representation of this field. */ @Override public final java.lang.String toString(jnr.ffi.Pointer ptr) { return java.lang.Long.toString(get(ptr)); } } /** * A 64 bit unsigned integer field. */ public class Unsigned64 extends NumberField { /** * Creates a new 64 bit integer field. */ public Unsigned64() { super(NativeType.ULONGLONG); } /** * Creates a new 64 bit unsigned integer field at a specific offset * * @param offset The offset within the memory area for this field. */ public Unsigned64(Offset offset) { super(NativeType.ULONGLONG, offset); } /** * Gets the value for this field. * * @param ptr The pointer to the field. * @return a long. */ public final long get(jnr.ffi.Pointer ptr) { return ptr.getLongLong(offset()); } /** * Sets the value for this field. * * @param ptr The pointer to the field. * @param value the 64 bit value to set. */ public final void set(jnr.ffi.Pointer ptr, long value) { ptr.putLongLong(offset(), value); } public void set(jnr.ffi.Pointer ptr, java.lang.Number value) { ptr.putLongLong(offset(), value.longValue()); } /** * Returns a java int representation of this field. * * @param ptr The pointer to the field. * @return a java int value for this field. */ @Override public final int intValue(jnr.ffi.Pointer ptr) { return (int) get(ptr); } /** * Returns a java long representation of this field. * * @param ptr The pointer to the field. * @return a java long value for this field. */ @Override public final long longValue(jnr.ffi.Pointer ptr) { return get(ptr); } /** * Returns a string representation of this field. * * @param ptr The pointer to the field. * @return a string representation of this field. */ @Override public final java.lang.String toString(jnr.ffi.Pointer ptr) { return java.lang.Long.toString(get(ptr)); } } /** * A native long integer field. */ public class SignedLong extends NumberField { /** * Creates a new native long field. */ public SignedLong() { super(NativeType.SLONG); } /** * Creates a new signed native long field at a specific offset * * @param offset The offset within the memory area for this field. */ public SignedLong(Offset offset) { super(NativeType.SLONG, offset); } /** * Gets the value for this field. * * @param ptr The pointer to the field. * @return a long. */ public final long get(jnr.ffi.Pointer ptr) { return ptr.getNativeLong(offset()); } /** * Sets the value for this field. * * @param ptr The pointer to the field. * @param value the 32/64 bit value to set. */ public final void set(jnr.ffi.Pointer ptr, long value) { ptr.putNativeLong(offset(), value); } public void set(jnr.ffi.Pointer ptr, java.lang.Number value) { ptr.putNativeLong(offset(), value.longValue()); } /** * Returns a java int representation of this field. * * @param ptr The pointer to the field. * @return a java int value for this field. */ @Override public final int intValue(jnr.ffi.Pointer ptr) { return (int) get(ptr); } /** * Returns a java long representation of this field. * * @param ptr The pointer to the field. * @return a java long value for this field. */ @Override public final long longValue(jnr.ffi.Pointer ptr) { return get(ptr); } /** * Returns a string representation of this field. * * @param ptr The pointer to the field. * @return a string representation of this field. */ @Override public final java.lang.String toString(jnr.ffi.Pointer ptr) { return java.lang.Long.toString(get(ptr)); } } /** * A native long integer field. */ public class UnsignedLong extends NumberField { /** * Creates a new native long field. */ public UnsignedLong() { super(NativeType.ULONG); } /** * Creates a new unsigned native long field at a specific offset * * @param offset The offset within the memory area for this field. */ public UnsignedLong(Offset offset) { super(NativeType.ULONG, offset); } /** * Gets the value for this field. * * @param ptr The pointer to the field. * @return a int. */ public final long get(jnr.ffi.Pointer ptr) { long value = ptr.getNativeLong(offset()); final long mask = getRuntime().findType(NativeType.SLONG).size() == 4 ? 0xffffffffL : 0xffffffffffffffffL; return value < 0 ? (long) ((value & mask) + mask + 1) : value; } /** * Sets the value for this field. * * @param ptr The pointer to the field. * @param value the 32/64 bit value to set. */ public final void set(jnr.ffi.Pointer ptr, long value) { ptr.putNativeLong(offset(), value); } public void set(jnr.ffi.Pointer ptr, java.lang.Number value) { ptr.putNativeLong(offset(), value.longValue()); } /** * Returns a java int representation of this field. * * @return a java int value for this field. */ @Override public final int intValue(jnr.ffi.Pointer ptr) { return (int) get(ptr); } /** * Returns a java long representation of this field. * * @return a java long value for this field. */ @Override public final long longValue(jnr.ffi.Pointer ptr) { return get(ptr); } /** * Returns a string representation of this field. * * @return a string representation of this field. */ @Override public final java.lang.String toString(jnr.ffi.Pointer ptr) { return java.lang.Long.toString(get(ptr)); } } public class Float extends NumberField { public Float() { super(NativeType.FLOAT); } /** * Creates a new float field at a specific offset * * @param offset The offset within the memory area for this field. */ public Float(Offset offset) { super(NativeType.FLOAT, offset); } public final float get(jnr.ffi.Pointer ptr) { return ptr.getFloat(offset()); } public final void set(jnr.ffi.Pointer ptr, float value) { ptr.putFloat(offset(), value); } public void set(jnr.ffi.Pointer ptr, java.lang.Number value) { ptr.putFloat(offset(), value.floatValue()); } @Override public final int intValue(jnr.ffi.Pointer ptr) { return (int) get(ptr); } @Override public final double doubleValue(jnr.ffi.Pointer ptr) { return get(ptr); } @Override public final float floatValue(jnr.ffi.Pointer ptr) { return get(ptr); } @Override public final long longValue(jnr.ffi.Pointer ptr) { return (long) get(ptr); } @Override public final java.lang.String toString(jnr.ffi.Pointer ptr) { return java.lang.String.valueOf(get(ptr)); } } public final class Double extends NumberField { public Double() { super(NativeType.DOUBLE); } public Double(Offset offset) { super(NativeType.DOUBLE, offset); } public final double get(jnr.ffi.Pointer ptr) { return ptr.getDouble(offset()); } public final void set(jnr.ffi.Pointer ptr, double value) { ptr.putDouble(offset(), value); } public void set(jnr.ffi.Pointer ptr, java.lang.Number value) { ptr.putDouble(offset(), value.doubleValue()); } @Override public final int intValue(jnr.ffi.Pointer ptr) { return (int) get(ptr); } @Override public final long longValue(jnr.ffi.Pointer ptr) { return (long) get(ptr); } @Override public final float floatValue(jnr.ffi.Pointer ptr) { return (float) get(ptr); } @Override public final double doubleValue(jnr.ffi.Pointer ptr) { return get(ptr); } @Override public final java.lang.String toString(jnr.ffi.Pointer ptr) { return java.lang.String.valueOf(get(ptr)); } } /** * Represents a native memory address. */ public class Pointer extends NumberField { /** * Creates a new Address field. */ public Pointer() { super(NativeType.ADDRESS); } public Pointer(Offset offset) { super(NativeType.ADDRESS, offset); } /** * Gets the {@link jnr.ffi.Pointer} value from the native memory. * * @param ptr The pointer to the field. * @return a {@link jnr.ffi.Pointer}. */ public final jnr.ffi.Pointer get(jnr.ffi.Pointer ptr) { return ptr.getPointer(offset()); } /** * Gets the size of a Pointer in bits * * @return the size of the Pointer */ public final int size() { return getRuntime().findType(NativeType.ADDRESS).size(); } /** * Sets a {@link jnr.ffi.Pointer} value in the native memory. * * @param ptr The pointer to the write location. * @param value The value to set. */ public final void set(jnr.ffi.Pointer ptr, jnr.ffi.Pointer value) { ptr.putPointer(offset(), value); } public void set(jnr.ffi.Pointer ptr, java.lang.Number value) { ptr.putAddress(offset(), value.longValue()); } /** * Returns an integer representation of this Pointer. * * @return an integer value for this Pointer. */ @Override public final int intValue(jnr.ffi.Pointer ptr) { return (int) ptr.getAddress(offset()); } /** * Returns an {@code long} representation of this Pointer. * * @return an {@code long} value for this Pointer. */ @Override public final long longValue(jnr.ffi.Pointer ptr) { return ptr.getAddress(offset()); } /** * Returns a string representation of this Pointer. * * @return a string representation of this Pointer. */ @Override public final java.lang.String toString(jnr.ffi.Pointer ptr) { return get(ptr).toString(); } } /** * Base for all the Enum fields. * * @param the type of {@link java.lang.Enum} */ protected abstract class EnumField> extends NumberField { protected final Class enumClass; protected final EnumMapper enumMapper; /** * Constructs a new Enum field. * * @param type the native type of the enum. * @param enumClass the Enum class. */ public EnumField(NativeType type, Class enumClass) { super(type); this.enumClass = enumClass; this.enumMapper = EnumMapper.getInstance(enumClass); } /** * Constructs a new Enum field. * * @param type the native type of the enum. * @param enumClass the Enum class. * @param offset the offset. */ public EnumField(NativeType type, Class enumClass, Offset offset) { super(type, offset); this.enumClass = enumClass; this.enumMapper = EnumMapper.getInstance(enumClass); } /** * Gets a java Enum value representing the native integer value. * * @param ptr The pointer to the field. * @return a java Enum value. */ public E get(jnr.ffi.Pointer ptr) { return enumClass.cast(enumMapper.valueOf(intValue(ptr))); } /** * Returns a string representation of this field. * * @param ptr The pointer to the field. * @return a string representation of this field. */ @Override public final java.lang.String toString(jnr.ffi.Pointer ptr) { return get(ptr).toString(); } } /** * An 8 bit enum field. * * @param the {@link java.lang.Enum} to translate to/from. */ public class Enum8> extends EnumField { /** * Creates a new 8 bit enum field. * * @param enumClass the class of the {@link java.lang.Enum}. */ public Enum8(Class enumClass) { super(NativeType.SCHAR, enumClass); } /** * Creates a new 8 bit enum field. * * @param enumClass the class of the {@link java.lang.Enum}. * @param offset the offset of the enum field. */ public Enum8(Class enumClass, Offset offset) { super(NativeType.SCHAR, enumClass, offset); } /** * Sets the native integer value using a java Enum value. * * @param ptr The pointer to the field. * @param value the java Enum value. */ public final void set(jnr.ffi.Pointer ptr, E value) { ptr.putByte(offset(), (byte) enumMapper.intValue(value)); } public void set(jnr.ffi.Pointer ptr, java.lang.Number value) { ptr.putByte(offset(), value.byteValue()); } /** * Returns an integer representation of this enum field. * * @return an integer value for this enum field. */ @Override public final int intValue(jnr.ffi.Pointer ptr) { return ptr.getByte(offset()); } } public class Enum16> extends EnumField { public Enum16(Class enumClass) { super(NativeType.SSHORT, enumClass); } public Enum16(Class enumClass, Offset offset) { super(NativeType.SSHORT, enumClass, offset); } public void set(jnr.ffi.Pointer ptr, E value) { ptr.putShort(offset(), (short) enumMapper.intValue(value)); } public void set(jnr.ffi.Pointer ptr, java.lang.Number value) { ptr.putShort(offset(), value.shortValue()); } @Override public final int intValue(jnr.ffi.Pointer ptr) { return ptr.getShort(offset()); } } public class Enum32> extends EnumField { public Enum32(Class enumClass) { super(NativeType.SINT, enumClass); } public Enum32(Class enumClass, Offset offset) { super(NativeType.SINT, enumClass, offset); } public void set(jnr.ffi.Pointer ptr, E value) { ptr.putInt(offset(), enumMapper.intValue(value)); } public void set(jnr.ffi.Pointer ptr, java.lang.Number value) { ptr.putInt(offset(), value.intValue()); } @Override public final int intValue(jnr.ffi.Pointer ptr) { return ptr.getInt(offset()); } } public class Enum64> extends EnumField { public Enum64(Class enumClass) { super(NativeType.SLONGLONG, enumClass); } public Enum64(Class enumClass, Offset offset) { super(NativeType.SLONGLONG, enumClass, offset); } public final void set(jnr.ffi.Pointer ptr, E value) { ptr.putLongLong(offset(), enumMapper.intValue(value)); } public void set(jnr.ffi.Pointer ptr, java.lang.Number value) { ptr.putLongLong(offset(), value.longValue()); } @Override public final int intValue(jnr.ffi.Pointer ptr) { return (int) longValue(ptr); } @Override public final long longValue(jnr.ffi.Pointer ptr) { return ptr.getLongLong(offset()); } } public class EnumLong> extends EnumField { public EnumLong(Class enumClass) { super(NativeType.SLONG, enumClass); } public EnumLong(Class enumClass, Offset offset) { super(NativeType.SLONG, enumClass, offset); } public final void set(jnr.ffi.Pointer ptr, E value) { ptr.putNativeLong(offset(), enumMapper.intValue(value)); } public void set(jnr.ffi.Pointer ptr, java.lang.Number value) { ptr.putNativeLong(offset(), value.longValue()); } @Override public final int intValue(jnr.ffi.Pointer ptr) { return (int) longValue(ptr); } @Override public final long longValue(jnr.ffi.Pointer ptr) { return ptr.getNativeLong(offset()); } } public class Enum> extends Enum32 { public Enum(Class enumClass) { super(enumClass); } public Enum(Class enumClass, Offset offset) { super(enumClass, offset); } } abstract public class String extends AbstractField { protected final Charset charset; protected final int length; protected String(int size, int align, int length, Charset cs) { super(size, align); this.length = length; this.charset = cs; } protected String(int size, int align, Offset offset, int length, Charset cs) { super(size, align, offset); this.length = length; this.charset = cs; } public final int length() { return length; } protected abstract jnr.ffi.Pointer getStringMemory(jnr.ffi.Pointer ptr); public abstract java.lang.String get(jnr.ffi.Pointer ptr); public abstract void set(jnr.ffi.Pointer ptr, java.lang.String value); public final java.lang.String toString(jnr.ffi.Pointer ptr) { return get(ptr); } } public class UTFString extends String { public UTFString(int length, Charset cs) { super(length, 1, length, cs); // FIXME: This won't work for non-ASCII } public UTFString(int length, Charset cs, Offset offset) { super(length, 1, offset, length, cs); // FIXME: This won't work for non-ASCII } protected jnr.ffi.Pointer getStringMemory(jnr.ffi.Pointer ptr) { return ptr.slice(offset(), length()); } public final java.lang.String get(jnr.ffi.Pointer ptr) { return getStringMemory(ptr).getString(0, length, charset); } public final void set(jnr.ffi.Pointer ptr, java.lang.String value) { getStringMemory(ptr).putString(0, value, length, charset); } } public class UTF8String extends UTFString { public UTF8String(int size) { super(size, UTF8); } public UTF8String(int size, Offset offset) { super(size, UTF8, offset); } } public class AsciiString extends UTFString { public AsciiString(int size) { super(size, ASCII); } public AsciiString(int size, Offset offset) { super(size, ASCII, offset); } } public class UTFStringRef extends String { private jnr.ffi.Pointer valueHolder; public UTFStringRef(int length, Charset cs) { super(getRuntime().findType(NativeType.ADDRESS).size(), getRuntime().findType(NativeType.ADDRESS).alignment(), length, cs); } public UTFStringRef(int length, Charset cs, Offset offset) { super(getRuntime().findType(NativeType.ADDRESS).size(), getRuntime().findType(NativeType.ADDRESS).alignment(), offset, length, cs); } public UTFStringRef(Charset cs) { this(Integer.MAX_VALUE, cs); } protected jnr.ffi.Pointer getStringMemory(jnr.ffi.Pointer ptr) { return ptr.getPointer(offset(), length()); } public final java.lang.String get(jnr.ffi.Pointer ptr) { jnr.ffi.Pointer memory = getStringMemory(ptr); return memory != null ? memory.getString(0, length, charset) : null; } public final void set(jnr.ffi.Pointer ptr, java.lang.String value) { if (value != null) { valueHolder = getRuntime().getMemoryManager().allocateDirect(length() * 4); valueHolder.putString(0, value, length() * 4, charset); ptr.putPointer(offset(), valueHolder); } else { this.valueHolder = null; ptr.putAddress(offset(), 0); } } } public class UTF8StringRef extends UTFStringRef { public UTF8StringRef(int size) { super(size, UTF8); } public UTF8StringRef(int size, Offset offset) { super(size, UTF8, offset); } public UTF8StringRef() { super(Integer.MAX_VALUE, UTF8); } } public class AsciiStringRef extends UTFStringRef { public AsciiStringRef(int size) { super(size, ASCII); } public AsciiStringRef(int size, Offset offset) { super(size, ASCII, offset); } public AsciiStringRef() { super(Integer.MAX_VALUE, ASCII); } } /** * Specialized padding fields for structs. Use this instead of arrays of other * members for more efficient struct construction. */ protected final class Padding extends AbstractField { public Padding(Type type, int length) { super(type.size() * length, type.alignment()); } public Padding(Type type, int length, Offset offset) { super(type.size() * length, type.alignment(), offset); } public Padding(NativeType type, int length) { this(getRuntime().findType(type), length); } public Padding(NativeType type, int length, Offset offset) { this(getRuntime().findType(type), length); } } protected final class Function extends AbstractField { private final Class closureClass; private T instance; public Function(Class closureClass) { super(NativeType.ADDRESS); this.closureClass = closureClass; } public Function(Class closureClass, Offset offset) { super(NativeType.ADDRESS, offset); this.closureClass = closureClass; } public final void set(jnr.ffi.Pointer ptr, T value) { ptr.putPointer(offset(), getRuntime().getClosureManager().getClosurePointer(closureClass, instance = value)); } } protected final Function function(Class closureClass) { return new Function(closureClass); } protected final Function function(Class closureClass, Offset offset) { return new Function(closureClass, offset); } public final class int8_t extends IntegerAlias { public int8_t() { super(TypeAlias.int8_t); } public int8_t(Offset offset) { super(TypeAlias.int8_t, offset); } } public final class u_int8_t extends IntegerAlias { public u_int8_t() { super(TypeAlias.u_int8_t); } public u_int8_t(Offset offset) { super(TypeAlias.u_int8_t, offset); } } public final class int16_t extends IntegerAlias { public int16_t() { super(TypeAlias.int16_t); } public int16_t(Offset offset) { super(TypeAlias.int16_t, offset); } } public final class u_int16_t extends IntegerAlias { public u_int16_t() { super(TypeAlias.u_int16_t); } public u_int16_t(Offset offset) { super(TypeAlias.u_int16_t, offset); } } public final class int32_t extends IntegerAlias { public int32_t() { super(TypeAlias.int32_t); } public int32_t(Offset offset) { super(TypeAlias.int32_t, offset); } } public final class u_int32_t extends IntegerAlias { public u_int32_t() { super(TypeAlias.u_int32_t); } public u_int32_t(Offset offset) { super(TypeAlias.u_int32_t, offset); } } public final class int64_t extends IntegerAlias { public int64_t() { super(TypeAlias.int64_t); } public int64_t(Offset offset) { super(TypeAlias.int64_t, offset); } } public final class u_int64_t extends IntegerAlias { public u_int64_t() { super(TypeAlias.u_int64_t); } public u_int64_t(Offset offset) { super(TypeAlias.u_int64_t, offset); } } public final class intptr_t extends IntegerAlias { public intptr_t() { super(TypeAlias.intptr_t); } public intptr_t(Offset offset) { super(TypeAlias.intptr_t, offset); } } public final class uintptr_t extends IntegerAlias { public uintptr_t() { super(TypeAlias.uintptr_t); } public uintptr_t(Offset offset) { super(TypeAlias.uintptr_t, offset); } } public final class caddr_t extends IntegerAlias { public caddr_t() { super(TypeAlias.caddr_t); } public caddr_t(Offset offset) { super(TypeAlias.caddr_t, offset); } } public final class dev_t extends IntegerAlias { public dev_t() { super(TypeAlias.dev_t); } public dev_t(Offset offset) { super(TypeAlias.dev_t, offset); } } public final class blkcnt_t extends IntegerAlias { public blkcnt_t() { super(TypeAlias.blkcnt_t); } public blkcnt_t(Offset offset) { super(TypeAlias.blkcnt_t, offset); } } public final class blksize_t extends IntegerAlias { public blksize_t() { super(TypeAlias.blksize_t); } public blksize_t(Offset offset) { super(TypeAlias.blksize_t, offset); } } public final class gid_t extends IntegerAlias { public gid_t() { super(TypeAlias.gid_t); } public gid_t(Offset offset) { super(TypeAlias.gid_t, offset); } } public final class in_addr_t extends IntegerAlias { public in_addr_t() { super(TypeAlias.in_addr_t); } public in_addr_t(Offset offset) { super(TypeAlias.in_addr_t, offset); } } public final class in_port_t extends IntegerAlias { public in_port_t() { super(TypeAlias.in_port_t); } public in_port_t(Offset offset) { super(TypeAlias.in_port_t, offset); } } public final class ino_t extends IntegerAlias { public ino_t() { super(TypeAlias.ino_t); } public ino_t(Offset offset) { super(TypeAlias.ino_t, offset); } } public final class ino64_t extends IntegerAlias { public ino64_t() { super(TypeAlias.ino64_t); } public ino64_t(Offset offset) { super(TypeAlias.ino64_t, offset); } } public final class key_t extends IntegerAlias { public key_t() { super(TypeAlias.key_t); } public key_t(Offset offset) { super(TypeAlias.key_t, offset); } } public final class mode_t extends IntegerAlias { public mode_t() { super(TypeAlias.mode_t); } public mode_t(Offset offset) { super(TypeAlias.mode_t, offset); } } public final class nlink_t extends IntegerAlias { public nlink_t() { super(TypeAlias.nlink_t); } public nlink_t(Offset offset) { super(TypeAlias.nlink_t, offset); } } public final class id_t extends IntegerAlias { public id_t() { super(TypeAlias.id_t); } public id_t(Offset offset) { super(TypeAlias.id_t, offset); } } public final class pid_t extends IntegerAlias { public pid_t() { super(TypeAlias.pid_t); } public pid_t(Offset offset) { super(TypeAlias.pid_t, offset); } } public final class off_t extends IntegerAlias { public off_t() { super(TypeAlias.off_t); } public off_t(Offset offset) { super(TypeAlias.off_t, offset); } } public final class swblk_t extends IntegerAlias { public swblk_t() { super(TypeAlias.swblk_t); } public swblk_t(Offset offset) { super(TypeAlias.swblk_t, offset); } } public final class uid_t extends IntegerAlias { public uid_t() { super(TypeAlias.uid_t); } public uid_t(Offset offset) { super(TypeAlias.uid_t, offset); } } public final class clock_t extends IntegerAlias { public clock_t() { super(TypeAlias.clock_t); } public clock_t(Offset offset) { super(TypeAlias.clock_t, offset); } } public final class size_t extends IntegerAlias { public size_t() { super(TypeAlias.size_t); } public size_t(Offset offset) { super(TypeAlias.size_t, offset); } } public final class ssize_t extends IntegerAlias { public ssize_t() { super(TypeAlias.ssize_t); } public ssize_t(Offset offset) { super(TypeAlias.ssize_t, offset); } } public final class time_t extends IntegerAlias { public time_t() { super(TypeAlias.time_t); } public time_t(Offset offset) { super(TypeAlias.time_t, offset); } } public final class fsblkcnt_t extends IntegerAlias { public fsblkcnt_t() { super(TypeAlias.fsblkcnt_t); } public fsblkcnt_t(Offset offset) { super(TypeAlias.fsblkcnt_t, offset); } } public final class fsfilcnt_t extends IntegerAlias { public fsfilcnt_t() { super(TypeAlias.fsfilcnt_t); } public fsfilcnt_t(Offset offset) { super(TypeAlias.fsfilcnt_t, offset); } } public final class sa_family_t extends IntegerAlias { public sa_family_t() { super(TypeAlias.sa_family_t); } public sa_family_t(Offset offset) { super(TypeAlias.sa_family_t, offset); } } public final class socklen_t extends IntegerAlias { public socklen_t() { super(TypeAlias.socklen_t); } public socklen_t(Offset offset) { super(TypeAlias.socklen_t, offset); } } public final class rlim_t extends IntegerAlias { public rlim_t() { super(TypeAlias.rlim_t); } public rlim_t(Offset offset) { super(TypeAlias.rlim_t, offset); } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/Type.java000066400000000000000000000031731316720554100221720ustar00rootroot00000000000000/* * Copyright (C) 2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; /** * Type is the superclass for all internal types used by jnr-ffi. * *

* Use this type to access meta-data about a native type, such as its size or natural alignment. *

* To obtain an instance of this class, use {@link jnr.ffi.Runtime#findType(NativeType)} or * {@link jnr.ffi.Runtime#findType(TypeAlias)}. *

* Example *

 * {@code
 *
 *    Type pointerType = runtime.findType(NativeType.ADDRESS);
 *
 *    System.out.println("The size of a pointer on this platform is " + pointerType.size());
 * }
 * 
*/ public abstract class Type { /** * The size in bytes of this type. * * @return An integer */ public abstract int size(); /** * The native alignment of this type, in bytes * * @return An integer */ public abstract int alignment(); /** * The native type of this type * * @return the native type of this type */ public abstract NativeType getNativeType(); } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/TypeAlias.java000066400000000000000000000022151316720554100231400ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; public enum TypeAlias { int8_t, u_int8_t, int16_t, u_int16_t, int32_t, u_int32_t, int64_t, u_int64_t, intptr_t, uintptr_t, caddr_t, dev_t, blkcnt_t, blksize_t, gid_t, in_addr_t, in_port_t, ino_t, ino64_t, key_t, mode_t, nlink_t, id_t, pid_t, off_t, swblk_t, uid_t, clock_t, size_t, ssize_t, time_t, fsblkcnt_t, fsfilcnt_t, sa_family_t, socklen_t, rlim_t, } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/Union.java000066400000000000000000000021451316720554100223370ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * Some of the design and code of this class is from the javolution project. * * Copyright (C) 2006 - Javolution (http://javolution.org/) * All rights reserved. * * Permission to use, copy, modify, and distribute this software is * freely granted, provided that this notice is preserved. */ package jnr.ffi; /** * Represents a C union */ public abstract class Union extends Struct { protected Union(Runtime runtime) { super(runtime, true); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/Variable.java000066400000000000000000000027171316720554100230010ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; /** * Access library global variables. * *

* To access global variables, declare a method with a parameterized return type of this class. *

* Example *

 *     {@code
 *
 *     public interface MyLib {
 *         public Variable my_int_var();
 *     }
 *
 *     MyLib lib = LibraryLoader.create(MyLib.class).load("mylib"):
 *     System.out.println("native value=" + lib.my_int_var().get())
 *
 *     lib.my_int_var().set(0xdeadbeef);
 *     }
 * 
*/ public interface Variable { /** * Gets the current value of the global variable * * @return The value of the variable */ public T get(); /** * Sets the global variable to a value * * @param value The value to set the global variable to. */ public void set(T value); } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/annotations/000077500000000000000000000000001316720554100227375ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/annotations/Clear.java000066400000000000000000000033211316720554100246270ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Indicates that the temporary native memory allocated for an {@code @Out} paramneter * should be cleared before passing to the native function. * *

By default, parameters that are annotated as {@code @Out} only do not clear * the data in the temporary native memory area allocated when a java heap object * is passed in as the parameter, so the memory passed to the native function is * full of garbage data. After the native method returns, the native memory is * copied back to java, which is usually not a problem, since the native function * will have updated the memory with valid data. However, if the native function * fails, the garbage data that was in the temporary native memory will be copied * back to java. * * @see In * @see Out */ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.PARAMETER, ElementType.ANNOTATION_TYPE }) public @interface Clear { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/annotations/Delegate.java000066400000000000000000000020321316720554100253110ustar00rootroot00000000000000/* * Copyright (C) 2011 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.annotations; import jnr.ffi.CallingConvention; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Delegate { CallingConvention convention() default CallingConvention.DEFAULT; } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/annotations/Direct.java000066400000000000000000000027551316720554100250250ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Indicates that a {@link jnr.ffi.Struct}} parameter should be * backed by a persistent native memory block. * *

Without the {@code @Direct} annotation, the native code will allocate a * temporary native memory block for the parameter, and free it immediately after * the call. * *

By using {@code @Direct}, the native memory block is permanently associated * with the {@link jnr.ffi.Struct} instance, and will remain allocated * for as long as the {@code Struct} instance remains strongly referenced by java code. * */ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.PARAMETER, ElementType.ANNOTATION_TYPE }) public @interface Direct { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/annotations/Encoding.java000066400000000000000000000021701316720554100253300ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Used to specify the {@link java.nio.charset.Charset} to use for encoding/decoding a {@link String} */ @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD, ElementType.TYPE, ElementType.ANNOTATION_TYPE }) public @interface Encoding { String value(); } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/annotations/IgnoreError.java000066400000000000000000000034201316720554100260360ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.annotations; import jnr.ffi.LibraryLoader; import jnr.ffi.LibraryOption; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Map; /** * Indicates that the errno value for a native function need not be saved after * the function returns. * *

Due to the nature of the Java Virtual Machine, the errno value must be saved * immediately after the native function is called, otherwise internal jvm operations * may overwrite it before control is returned to java code. * *

Since it is not possible for jnr-ffi to infer in a generic way whether a native * function has succeeded or failed, the C errno value is saved after every native * function call - even for the ones that succeed. This can have a significant * performance impact, so for those functions which either don't fail, or for which * the errno value can be ignored, can be annotated with {@code @IgnoreError} to * avoid unneccessary saving of the errno value. * * @see SaveError * @see LibraryLoader#saveError(Map, boolean, boolean) */ @Retention(RetentionPolicy.RUNTIME) public @interface IgnoreError { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/annotations/In.java000066400000000000000000000034531316720554100241550ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Indicates that the parameter is an IN parameter. * *

When a java object is passed to a native function as a pointer * (for example {@link jnr.ffi.Pointer}, {@link jnr.ffi.Struct}, {@link java.nio.ByteBuffer}), * then a temporary native memory block is allocated, the java data is copied to * the temporary memory and the address of the temporary memory is passed to the function. * After the function returns, the java data is automatically updated from the * contents of the native memory. * *

As this extra copying can be expensive, parameters can be annotated with {@code @In} * so the data is only copied from java {@code IN} to native memory, but not copied * back {@code OUT} from native memory to java memory. * *

Parameters with neither a {@code @In} nor a {@code @Out} annotation will copy both ways. * */ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.PARAMETER, ElementType.METHOD, ElementType.ANNOTATION_TYPE }) public @interface In { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/annotations/LongLong.java000066400000000000000000000022301316720554100253160ustar00rootroot00000000000000/* * Copyright (C) 2011 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.annotations; import jnr.ffi.TypeAlias; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Indicates that a long parameter should be treated as native long-long (64bit) * instead of the platform-dependent long size. */ @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.int64_t) public @interface LongLong { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/annotations/Meta.java000066400000000000000000000016601316720554100244730ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Meta { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/annotations/NulTerminate.java000066400000000000000000000021551316720554100262140ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Indicates that a byte array or ByteBuffer should be terminated with a zero byte * before passing it to a native function. */ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.PARAMETER, ElementType.METHOD, ElementType.ANNOTATION_TYPE }) public @interface NulTerminate { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/annotations/Out.java000066400000000000000000000037531316720554100243610ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Indicates that the parameter is an OUT parameter. * *

When a java object is passed to a native function as a pointer * (for example {@link jnr.ffi.Pointer}, {@link jnr.ffi.Struct}, {@link java.nio.ByteBuffer}), * then a temporary native memory block is allocated, the java data is copied to * the temporary memory and the address of the temporary memory is passed to the function. * After the function returns, the java data is automatically updated from the * contents of the native memory. * *

As this extra copying can be expensive, for native functions which only * write to the passed in memory block and do not use the existing contents, * parameters can be annotated with {@code @Out} so there is only copied {@code OUT} * from native memory to java memory after the call, and the unneccessary copy {@code IN} * from java to native memory before the call can be avoided. * *

Parameters with neither a {@code @In} nor a {@code @Out} annotation will copy both ways. * * @see In * @see Clear */ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.PARAMETER, ElementType.METHOD, ElementType.ANNOTATION_TYPE }) public @interface Out { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/annotations/Pinned.java000066400000000000000000000025161316720554100250230ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Marks a method parameter as being pinnable. *

* This means the data for the parameter is not copied to/from native memory. * Instead, the JVM memory is locked and passed directly to the native code. *

*

* IMPORTANT: This should not be used for functions that may block on * network or filesystem access such as read(2), write(2), stat(2). *

*/ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.PARAMETER, ElementType.ANNOTATION_TYPE }) public @interface Pinned { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/annotations/SaveError.java000066400000000000000000000021501316720554100255100ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.annotations; import jnr.ffi.LibraryLoader; import jnr.ffi.LibraryOption; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Map; /** * Tags a library method as requiring any error codes as returned * by errno on unix, or GetLastError on windows be saved. * * @see IgnoreError * @see LibraryLoader#saveError(Map, boolean, boolean) */ @Retention(RetentionPolicy.RUNTIME) public @interface SaveError { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/annotations/StdCall.java000066400000000000000000000016521316720554100251340ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface StdCall { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/annotations/Synchronized.java000066400000000000000000000020261316720554100262610ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.annotations; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** * Indicates that a library or a library method requires all calls to be * synchronized. * * i.e. calls from multiple threads will synchronize on a monitor object, * then call the native method. */ @Retention(RetentionPolicy.RUNTIME) public @interface Synchronized { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/annotations/Transient.java000066400000000000000000000022361316720554100255540ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Indicates that the parameter is transient. * * This means it can be backed by a temporarily allocated native memory block, * and after the method call, the native memory can be freed again. */ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.PARAMETER, ElementType.ANNOTATION_TYPE }) public @interface Transient { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/annotations/TypeDefinition.java000066400000000000000000000021261316720554100265350ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.annotations; import jnr.ffi.TypeAlias; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * This is used internally by jnr-ffi to define type aliases, e.g. {@code ssize_t => long}. */ @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.ANNOTATION_TYPE }) public @interface TypeDefinition { TypeAlias alias(); } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/byref/000077500000000000000000000000001316720554100215115ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/byref/AbstractNumberReference.java000066400000000000000000000035261316720554100271150ustar00rootroot00000000000000/* * Copyright (C) 2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.byref; /** * An abstract class for common PrimitiveReference functionality */ abstract public class AbstractNumberReference extends Number implements ByReference { T value; protected AbstractNumberReference(T value) { this.value = value; } protected static T checkNull(T value) { if (value == null) { throw new NullPointerException("reference value cannot be null"); } return value; } /** * Gets the current value the reference points to. * * @return the current value. */ public T getValue() { return value; } @Override public final byte byteValue() { return value.byteValue(); } @Override public final short shortValue() { return value.byteValue(); } public final int intValue() { return value.intValue(); } @Override public final long longValue() { return value.longValue(); } @Override public final float floatValue() { return value.floatValue(); } @Override public final double doubleValue() { return value.doubleValue(); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/byref/AbstractReference.java000066400000000000000000000023711316720554100257410ustar00rootroot00000000000000/* * Copyright (C) 2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.byref; /** * An abstract class for common PrimitiveReference functionality */ abstract public class AbstractReference implements ByReference { T value; protected AbstractReference(T value) { this.value = value; } protected static T checkNull(T value) { if (value == null) { throw new NullPointerException("reference value cannot be null"); } return value; } /** * Gets the current value the reference points to. * * @return the current value. */ public T getValue() { return value; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/byref/AddressByReference.java000066400000000000000000000055321316720554100260600ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.byref; import jnr.ffi.Address; import jnr.ffi.Pointer; import jnr.ffi.Runtime; /** * AddressByReference is used when the address of a primitive pointer value must be passed * as a parameter to a function. * *

For example, the following C code, *

 * 
 *
 * extern void get_a(void** ap);
 *
 * void* foo(void) {
 *     void* a;
 *     // pass a reference to 'a' so get_a() can fill it out
 *     get_a({@literal &}a);
 *
 *     return a;
 * }
 *
 * 
 * 
* *

* Would be declared in java as * *

 * 
 *
 * interface Lib {
 *     void get_a(@Out AddressByReference ap);
 * }
 *
 * 
 * 
*

* and used like this * *

 * 
 *
 * AddressByReference ap = new AddressByReference();
 * lib.get_a(ap);
 * System.out.println("a from lib=" + a.getValue());
 *
 * 
 * 
*/ public final class AddressByReference extends AbstractReference
{ /** * Creates a new reference to an integer value */ public AddressByReference() { super(Address.valueOf(0)); } /** * Creates a new reference to an address value * * @param value the initial native value */ public AddressByReference(Address value) { super(checkNull(value)); } /** * Copies the address value to native memory * * @param runtime The current runtime. * @param memory The native memory buffer * @param offset The offset. */ public void toNative(Runtime runtime, Pointer memory, long offset) { memory.putAddress(offset, value.nativeAddress()); } /** * Copies the address value from native memory * * @param runtime The current runtime. * @param memory The native memory buffer. * @param offset The offset. */ public void fromNative(Runtime runtime, Pointer memory, long offset) { value = Address.valueOf(memory.getAddress(offset)); } /** * Gets the native size of type of reference * * @param runtime The current runtime. * @return The size of the native type this reference points to */ public int nativeSize(Runtime runtime) { return runtime.addressSize(); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/byref/ByReference.java000066400000000000000000000043561316720554100245550ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.byref; import jnr.ffi.Pointer; import jnr.ffi.Runtime; /** * A ByReference subclass is used when a primitive parameter must be passed * by-reference. * *

* For example, the following C code, * *

 * 
 *
 * extern void get_a(int * ap);
 *
 * int foo(void) {
 *     int a;
 *     // pass a reference to 'a' so get_a() can fill it out
 *     get_a({@literal &}a);
 *
 *     return a;
 * }
 *  
 * 
* *

* Would be declared in java as *

 * 
 *
 * interface Lib {
 *     void get_a(@Out IntByReference ap);
 * }
 *
 * 
 * 
*

* and used like this *

 * 
 *
 * IntByReference ap = new IntByReference();
 * lib.get_a(ap);
 * System.out.printf("a from lib=%d\n", a.getValue());
 *
 * 
 * 
*/ public interface ByReference { /** * Gets the size of the native buffer required to store the value * * @param runtime The current runtime. * @return the size in bytes of the native type */ int nativeSize(Runtime runtime); /** * Copies the java value to native memory * * @param runtime The current runtime. * @param memory The native memory buffer. * @param offset The offset of the field. */ void toNative(Runtime runtime, Pointer memory, long offset); /** * Copies the java value from native memory * * @param runtime The current runtime. * @param memory the native memory buffer. * @param offset The offset of the field. */ void fromNative(Runtime runtime, Pointer memory, long offset); T getValue(); } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/byref/ByteByReference.java000066400000000000000000000053671316720554100254040ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.byref; import jnr.ffi.Pointer; import jnr.ffi.Runtime; /** * ByteByReference is used when the address of a primitive byte value must be passed * as a parameter to a function. * *

For example, the following C code, *

 * {@code
 * extern void get_a(char *ap);
 *
 * int foo(void) {
 *     char a;
 *     // pass a reference to 'a' so get_a() can fill it out
 *     get_a(&a);
 *
 *     return a;
 * }
 * }
 * 
*

* Would be declared in java as *

 * {@code
 * interface Lib {
 *     void get_a(@Out ByteByReference ap);
 * }
 * }
 * 
*

* and used like this *

 * ByteByReference ap = new ByteByReference();
 * lib.get_a(ap);
 * System.out.printf("a from lib=%d\n", a.byteValue());
 * 
*/ public final class ByteByReference extends AbstractNumberReference { /** * Creates a new reference to a byte value initialized to zero. */ public ByteByReference() { super(Byte.valueOf((byte) 0)); } /** * Creates a new reference to a byte value * * @param value the initial native value */ public ByteByReference(Byte value) { super(checkNull(value)); } /** * Creates a new reference to a byte value * * @param value the initial native value */ public ByteByReference(byte value) { super(value); } /** * Copies the Byte value to native memory * * @param runtime The current runtime. * @param buffer the native memory buffer */ public void toNative(Runtime runtime, Pointer buffer, long offset) { buffer.putByte(offset, value); } /** * Copies the Byte value from native memory * * @param runtime The current runtime. * @param buffer the native memory buffer. */ public void fromNative(Runtime runtime, Pointer buffer, long offset) { this.value = buffer.getByte(offset); } /** * Gets the native size of type of reference in bytes. * * @return the size of a byte in bytes */ public final int nativeSize(Runtime runtime) { return 1; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/byref/DoubleByReference.java000066400000000000000000000044321316720554100257030ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.byref; import jnr.ffi.Pointer; import jnr.ffi.Runtime; /** * */ public final class DoubleByReference extends AbstractNumberReference { private static final Double DEFAULT = Double.valueOf(0d); /** * Creates a new reference to a double value initialized to zero. */ public DoubleByReference() { super(DEFAULT); } /** * Creates a new reference to a double value * * @param value the initial native value */ public DoubleByReference(Double value) { super(checkNull(value)); } /** * Creates a new reference to a double value * * @param value the initial native value */ public DoubleByReference(double value) { super(value); } /** * Copies the double value to native memory * * @param runtime the current runtime. * @param buffer the native memory buffer. * @param offset the memory offset. */ public void toNative(Runtime runtime, Pointer buffer, long offset) { buffer.putDouble(offset, value); } /** * Copies the double value from native memory * * @param runtime the current runtime. * @param buffer the native memory buffer. * @param offset the memory offset. */ public void fromNative(Runtime runtime, Pointer buffer, long offset) { this.value = buffer.getDouble(offset); } /** * Gets the native size of type of reference in bytes. * * @param runtime the current runtime. * @return the size of a byte in bytes. */ public final int nativeSize(Runtime runtime) { return 8; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/byref/FloatByReference.java000066400000000000000000000044171316720554100255410ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.byref; import jnr.ffi.Pointer; import jnr.ffi.Runtime; /** * */ public final class FloatByReference extends AbstractNumberReference { private static final Float DEFAULT = Float.valueOf(0f); /** * Creates a new reference to a short value initialized to zero. */ public FloatByReference() { super(DEFAULT); } /** * Creates a new reference to a float value * * @param value the initial native value */ public FloatByReference(Float value) { super(checkNull(value)); } /** * Creates a new reference to a float value * * @param value the initial native value */ public FloatByReference(float value) { super(value); } /** * Copies the float value to native memory * * @param runtime the current runtime. * @param buffer the native memory buffer. * @param offset the memory offset. */ public void toNative(Runtime runtime, Pointer buffer, long offset) { buffer.putFloat(offset, value); } /** * Copies the float value from native memory * * @param runtime the current runtime. * @param buffer the native memory buffer. * @param offset the memory offset. */ public void fromNative(Runtime runtime, Pointer buffer, long offset) { this.value = buffer.getFloat(offset); } /** * Gets the native size of type of reference in bytes. * * @param runtime the current runtime. * @return the size of a byte in bytes */ public final int nativeSize(Runtime runtime) { return 4; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/byref/IntByReference.java000066400000000000000000000054611316720554100252260ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.byref; import jnr.ffi.Pointer; import jnr.ffi.Runtime; /** * IntByReference is used when the address of a primitive int must be passed * as a parameter to a function. * *

* For example, the following C code, *

 * {@code
 * extern void get_a(int * ap);
 *
 * int foo(void) {
 *     int a;
 *     // pass a reference to 'a' so get_a() can fill it out
 *     get_a(&a);
 *
 *     return a;
 * }
 * }
 * 
*

* Would be declared in java as *

 * {@code
 * interface Lib {
 *     void get_a(@Out IntByReference ap);
 * }
 * }
 * 
*

* and used like this *

 * IntByReference ap = new IntByReference();
 * lib.get_a(ap);
 * System.out.printf("a from lib=%d\n", a.intValue());
 * 
*/ public final class IntByReference extends AbstractNumberReference { /** * Creates a new reference to an integer value initialized to zero. */ public IntByReference() { super(Integer.valueOf(0)); } /** * Creates a new reference to an integer value * * @param value the initial native value */ public IntByReference(Integer value) { super(checkNull(value)); } /** * Creates a new reference to an integer value * * @param value the initial native value */ public IntByReference(int value) { super(value); } /** * Copies the integer value to native memory * * @param runtime the current runtime. * @param buffer the native memory buffer. * @param offset the memory offset. */ public void toNative(Runtime runtime, Pointer buffer, long offset) { buffer.putInt(offset, value); } /** * Copies the integer value from native memory * * @param runtime the current runtime. * @param buffer the native memory buffer. * @param offset the memory offset. */ public void fromNative(Runtime runtime, Pointer buffer, long offset) { this.value = buffer.getInt(offset); } /** * Gets the native size of type of reference * * @return Integer.SIZE */ public int nativeSize(Runtime runtime) { return 4; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/byref/LongLongByReference.java000066400000000000000000000057101316720554100262100ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.byref; import jnr.ffi.Pointer; import jnr.ffi.Runtime; /** * LongLongByReference is used when the address of a native long long value must be passed * as a parameter to a function. * *

* For example, the following C code, *

 * {@code
 * extern void get_a(long long * ap);
 *
 * long long foo(void) {
 *     long long a;
 *     // pass a reference to 'a' so get_a() can fill it out
 *     get_a(&a);
 *
 *     return a;
 * }
 * }
 * 
*

* Would be declared in java as *

 * {@code
 * interface Lib {
 *     void get_a(@Out LongLongByReference ap);
 * }
 * }
 * 
*

* and used like this *

 * LongLongByReference ap = new LongLongByReference();
 * lib.get_a(ap);
 * System.out.printf("a from lib=%d\n", a.longValue());
 * 
*/ public final class LongLongByReference extends AbstractNumberReference { /** * Creates a new reference to a long long value initialized to zero. */ public LongLongByReference() { super(Long.valueOf(0)); } /** * Creates a new reference to a native longlong value * * @param value the initial native value */ public LongLongByReference(Long value) { super(checkNull(value)); } /** * Creates a new reference to a native longlong value * * @param value the initial native value */ public LongLongByReference(long value) { super(value); } /** * Copies the value to native memory * * @param runtime the current runtime. * @param memory the native memory buffer. * @param offset the memory offset. */ public void toNative(Runtime runtime, Pointer memory, long offset) { memory.putLongLong(offset, value); } /** * Copies the value from native memory * * @param runtime the current runtime. * @param memory the native memory buffer. * @param offset the memory offset. */ public void fromNative(Runtime runtime, Pointer memory, long offset) { this.value = memory.getLongLong(offset); } /** * Gets the native size of type of reference in bytes. * * @param runtime the current runtime. * @return the size of a byte in bytes */ public final int nativeSize(Runtime runtime) { return 8; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/byref/NativeLongByReference.java000066400000000000000000000060721316720554100265410ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.byref; import jnr.ffi.NativeLong; import jnr.ffi.Pointer; import jnr.ffi.Runtime; /** * NativeLongByReference is used when the address of a primitive C long must be passed * as a parameter to a function. * *

For example, the following C code, *

 * {@code
 * extern void get_a(long * ap);
 *
 * long foo(void) {
 *     long a;
 *     // pass a reference to 'a' so get_a() can fill it out
 *     get_a(&a);
 *
 *     return a;
 * }
 * }
 * 
*

* Would be declared in java as *

 * {@code
 * interface Lib {
 *     void get_a(@Out NativeLongByReference ap);
 * }
 * }
 * 
*

* and used like this *

 * NativeLongByReference ap = new NativeLongByReference();
 * lib.get_a(ap);
 * System.out.printf("a from lib=%d\n", a.longValue());
 * 
*/ public final class NativeLongByReference extends AbstractNumberReference { /** * Creates a new reference to a native long value initialized to zero. */ public NativeLongByReference() { super(NativeLong.valueOf(0)); } /** * Creates a new reference to a native long value * * @param value the initial native value */ public NativeLongByReference(NativeLong value) { super(checkNull(value)); } /** * Creates a new reference to a native long value * * @param value the initial native value */ public NativeLongByReference(long value) { super(NativeLong.valueOf(value)); } /** * Copies the long value to native memory * * @param runtime the current runtime. * @param memory the native memory buffer. * @param offset the memory offset. */ public void toNative(Runtime runtime, Pointer memory, long offset) { memory.putNativeLong(offset, value.longValue()); } /** * Copies the long value from native memory * * @param runtime the current runtime. * @param memory the native memory buffer. * @param offset the memory offset. */ public void fromNative(Runtime runtime, Pointer memory, long offset) { this.value = NativeLong.valueOf(memory.getNativeLong(offset)); } /** * Gets the native size of type of reference in bytes. * * @param runtime the current runtime. * @return the size of a byte in bytes */ public final int nativeSize(Runtime runtime) { return runtime.longSize(); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/byref/NumberByReference.java000066400000000000000000000106071316720554100257220ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.byref; import jnr.ffi.*; import jnr.ffi.Runtime; /** * NumberByReference is used when the address of a primitive integral value must be passed * as a parameter to a function, but the exact type is system dependent. * *

For example, the following C code, *

 * {@code
 *
 * extern void get_size(ssize_t *sp);
 *
 * ssize_t foo(void) {
 *     ssize_t n;
 *     // pass a reference to 'n' so get_size() can fill it out
 *     get_size(&n);
 *
 *     return n;
 * }
 * }
 * 
*

* Would be declared in java as *

 * {@code
 *
 * interface Lib {
 *     void get_size(@Out NumberByReference ap);
 * }
 *
 * }
 * 
*

* and used like this *

 * {@code
 *
 * NumberByReference size = new NumberByReference(ssize_t);
 * lib.get_size(size);
 * System.out.printf("size from lib=%d\n", size.longValue());
 *
 * }
 * 
*/ public class NumberByReference extends AbstractNumberReference { private final TypeAlias typeAlias; public NumberByReference(TypeAlias typeAlias, Number value) { super(checkNull(value)); this.typeAlias = typeAlias; } public NumberByReference(TypeAlias typeAlias) { super(0); this.typeAlias = typeAlias; } @Override public int nativeSize(jnr.ffi.Runtime runtime) { return runtime.findType(typeAlias).size(); } @Override public void fromNative(Runtime runtime, Pointer memory, long offset) { switch (runtime.findType(typeAlias).getNativeType()) { case SCHAR: case UCHAR: value = memory.getByte(offset); break; case SSHORT: case USHORT: value = memory.getShort(offset); break; case SINT: case UINT: value = memory.getInt(offset); break; case SLONG: case ULONG: value = memory.getLong(offset); break; case SLONGLONG: case ULONGLONG: value = memory.getLongLong(offset); break; case ADDRESS: value = memory.getAddress(offset); break; case FLOAT: value = memory.getFloat(offset); break; case DOUBLE: value = memory.getDouble(offset); break; default: throw new UnsupportedOperationException("unsupported type: " + typeAlias); } } @Override public void toNative(Runtime runtime, Pointer memory, long offset) { switch (runtime.findType(typeAlias).getNativeType()) { case SCHAR: case UCHAR: memory.putByte(offset, value.byteValue()); break; case SSHORT: case USHORT: memory.putShort(offset, value.shortValue()); break; case SINT: case UINT: memory.putInt(offset, value.intValue()); break; case SLONG: case ULONG: memory.putLong(offset, value.longValue()); break; case SLONGLONG: case ULONGLONG: memory.putLongLong(offset, value.longValue()); break; case ADDRESS: memory.putAddress(offset, value.longValue()); break; case FLOAT: memory.putFloat(offset, value.floatValue()); break; case DOUBLE: memory.putDouble(offset, value.doubleValue()); break; default: throw new UnsupportedOperationException("unsupported type: " + typeAlias); } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/byref/PointerByReference.java000066400000000000000000000044061316720554100261120ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.byref; import jnr.ffi.Pointer; import jnr.ffi.Runtime; /** * AddressByReference is used when the address of a pointer must be passed * as a parameter to a function. * *

* For example, the following C code, *

 * {@code
 * extern void get_a(void** ap);
 *
 * void* foo(void) {
 *     void* a;
 *     // pass a reference to 'a' so get_a() can fill it out
 *     get_a(&a);
 *
 *     return a;
 * }
 * }
 * 
*

* Would be declared in java as *

 * {@code
 * interface Lib {
 *     void get_a(@Out PointerByReference ap);
 * }
 * }
 * 
*

* and used like this *

 * {@code
 * PointerByReference ap = new PointerByReference();
 * lib.get_a(ap);
 * Pointer ptr = ap.getValue();
 * System.out.println("ptr from lib=" + a.getValue());
 * System.out.println("ptr contents=" + ptr.getInt(0));
 * }
 * 
*/ public final class PointerByReference extends AbstractReference{ /** * Creates a new reference to a pointer value with a null default value. */ public PointerByReference() { super(null); } /** * Creates a new reference to a pointer value * * @param value the initial pointer value */ public PointerByReference(Pointer value) { super(value); } public final void toNative(Runtime runtime, Pointer memory, long offset) { memory.putPointer(offset, this.value); } public final void fromNative(Runtime runtime, Pointer memory, long offset) { this.value = memory.getPointer(offset); } public final int nativeSize(Runtime runtime) { return runtime.addressSize(); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/byref/ShortByReference.java000066400000000000000000000056311316720554100255720ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.byref; import jnr.ffi.Pointer; import jnr.ffi.Runtime; /** * ShortByReference is used when the address of a primitive short value must be passed * as a parameter to a function. * *

* For example, the following C code, *

 * {@code
 * extern void get_a(short * ap);
 *
 * short foo(void) {
 *     short a;
 *     // pass a reference to 'a' so get_a() can fill it out
 *     get_a(&a);
 *
 *     return a;
 * }
 * }
 * 
*

* Would be declared in java as *

 * {@code
 * interface Lib {
 *     void get_a(@Out ShortByReference ap);
 * }
 * }
 * 
*

* and used like this *

 * ShortByReference ap = new ShortByReference();
 * lib.get_a(ap);
 * System.out.printf("a from lib=%d\n", a.getValue());
 * 
*/ public final class ShortByReference extends AbstractNumberReference { /** * Creates a new reference to a short value initialized to zero. */ public ShortByReference() { super(Short.valueOf((short) 0)); } /** * Creates a new reference to a short value. * * @param value the initial native value */ public ShortByReference(Short value) { super(checkNull(value)); } /** * Creates a new reference to a short value. * * @param value the initial native value */ public ShortByReference(short value) { super(value); } /** * Copies the short value to native memory * * @param runtime the current runtime. * @param buffer the native memory buffer. * @param offset the memory offset. */ public void toNative(Runtime runtime, Pointer buffer, long offset) { buffer.putShort(offset, value); } /** * Copies the short value from native memory * * @param runtime the current runtime. * @param buffer the native memory buffer. * @param offset the memory offset. */ public void fromNative(Runtime runtime, Pointer buffer, long offset) { this.value = buffer.getShort(offset); } /** * Gets the native size of type of reference in bytes. * * @param runtime the current runtime. * @return the size of a byte in bytes */ public final int nativeSize(Runtime runtime) { return 2; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/mapper/000077500000000000000000000000001316720554100216665ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/mapper/AbstractDataConverter.java000066400000000000000000000013771316720554100267660ustar00rootroot00000000000000/* * Copyright (C) 2011 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.mapper; /** * */ abstract public class AbstractDataConverter implements DataConverter { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/mapper/AbstractFromNativeType.java000066400000000000000000000017671316720554100271440ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.mapper; /** * */ abstract public class AbstractFromNativeType implements FromNativeType { private final FromNativeConverter converter; AbstractFromNativeType(FromNativeConverter converter) { this.converter = converter; } @Override public FromNativeConverter getFromNativeConverter() { return converter; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/mapper/AbstractSignatureTypeMapper.java000066400000000000000000000020071316720554100301640ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.mapper; /** * */ abstract public class AbstractSignatureTypeMapper implements SignatureTypeMapper { @Override public FromNativeType getFromNativeType(SignatureType type, FromNativeContext context) { return null; } @Override public ToNativeType getToNativeType(SignatureType type, ToNativeContext context) { return null; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/mapper/AbstractToNativeType.java000066400000000000000000000017511316720554100266140ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.mapper; /** * */ abstract public class AbstractToNativeType implements ToNativeType { private final ToNativeConverter converter; AbstractToNativeType(ToNativeConverter converter) { this.converter = converter; } @Override public ToNativeConverter getToNativeConverter() { return converter; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/mapper/CachingTypeMapper.java000066400000000000000000000106501316720554100260760ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.mapper; import java.util.*; /** * Caches native converter lookups by class. */ public final class CachingTypeMapper extends AbstractSignatureTypeMapper implements SignatureTypeMapper { private final SignatureTypeMapper mapper; private volatile Map toNativeTypeMap = Collections.emptyMap(); private volatile Map fromNativeTypeMap = Collections.emptyMap(); private static final InvalidType UNCACHEABLE_TYPE = new InvalidType(); private static final InvalidType NO_TYPE = new InvalidType(); public CachingTypeMapper(SignatureTypeMapper mapper) { this.mapper = mapper; } @Override public FromNativeType getFromNativeType(SignatureType type, FromNativeContext context) { FromNativeType fromNativeType = fromNativeTypeMap.get(type); if (fromNativeType == UNCACHEABLE_TYPE) { return mapper.getFromNativeType(type, context); } else if (fromNativeType == NO_TYPE) { return null; } return fromNativeType != null ? fromNativeType : lookupAndCacheFromNativeType(type, context); } @Override public ToNativeType getToNativeType(SignatureType type, ToNativeContext context) { ToNativeType toNativeType = toNativeTypeMap.get(type); if (toNativeType == UNCACHEABLE_TYPE) { return mapper.getToNativeType(type, context); } else if (toNativeType == NO_TYPE) { return null; } return toNativeType != null ? toNativeType : lookupAndCacheToNativeType(type, context); } private synchronized FromNativeType lookupAndCacheFromNativeType(SignatureType signature, FromNativeContext context) { FromNativeType fromNativeType = fromNativeTypeMap.get(signature); if (fromNativeType == null) { fromNativeType = mapper.getFromNativeType(signature, context); FromNativeType typeForCaching = fromNativeType; if (fromNativeType == null) { typeForCaching = NO_TYPE; } else if (!fromNativeType.getClass().isAnnotationPresent(FromNativeType.Cacheable.class)) { typeForCaching = UNCACHEABLE_TYPE; } Map m = new HashMap(fromNativeTypeMap.size() + 1); m.putAll(fromNativeTypeMap); m.put(signature, typeForCaching); fromNativeTypeMap = Collections.unmodifiableMap(m); } return fromNativeType != NO_TYPE ? fromNativeType : null; } private synchronized ToNativeType lookupAndCacheToNativeType(SignatureType signature, ToNativeContext context) { ToNativeType toNativeType = toNativeTypeMap.get(signature); if (toNativeType == null) { toNativeType = mapper.getToNativeType(signature, context); ToNativeType typeForCaching = toNativeType; if (toNativeType == null) { typeForCaching = NO_TYPE; } else if (!toNativeType.getClass().isAnnotationPresent(ToNativeType.Cacheable.class)) { typeForCaching = UNCACHEABLE_TYPE; } Map m = new HashMap(toNativeTypeMap.size() + 1); m.putAll(toNativeTypeMap); m.put(signature, typeForCaching); toNativeTypeMap = Collections.unmodifiableMap(m); } return toNativeType != NO_TYPE ? toNativeType : null; } private static final class InvalidType implements ToNativeType, FromNativeType { @Override public FromNativeConverter getFromNativeConverter() { return null; } @Override public ToNativeConverter getToNativeConverter() { return null; } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/mapper/CompositeFunctionMapper.java000066400000000000000000000030101316720554100273400ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.mapper; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; /** * */ public final class CompositeFunctionMapper implements FunctionMapper { private final Collection functionMappers; public CompositeFunctionMapper(Collection functionMappers) { this.functionMappers = Collections.unmodifiableList(new ArrayList(functionMappers)); } @Override public String mapFunctionName(String functionName, Context context) { for (FunctionMapper functionMapper : functionMappers) { String mappedName = functionMapper.mapFunctionName(functionName, context); if (mappedName != functionName) { // A translation was explicit in this mapper. return mappedName; } } return functionName; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/mapper/CompositeTypeMapper.java000066400000000000000000000040541316720554100265050ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.mapper; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; public final class CompositeTypeMapper implements SignatureTypeMapper { private final Collection signatureTypeMappers; public CompositeTypeMapper(SignatureTypeMapper... signatureTypeMappers) { this.signatureTypeMappers = Collections.unmodifiableList(Arrays.asList(signatureTypeMappers.clone())); } public CompositeTypeMapper(Collection signatureTypeMappers) { this.signatureTypeMappers = Collections.unmodifiableList(new ArrayList(signatureTypeMappers)); } @Override public FromNativeType getFromNativeType(SignatureType type, FromNativeContext context) { for (SignatureTypeMapper m : signatureTypeMappers) { FromNativeType fromNativeType = m.getFromNativeType(type, context); if (fromNativeType != null) { return fromNativeType; } } return null; } @Override public ToNativeType getToNativeType(SignatureType type, ToNativeContext context) { for (SignatureTypeMapper m : signatureTypeMappers) { ToNativeType toNativeType = m.getToNativeType(type, context); if (toNativeType != null) { return toNativeType; } } return null; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/mapper/DataConverter.java000066400000000000000000000014231316720554100252720ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.mapper; /** * */ public interface DataConverter extends ToNativeConverter, FromNativeConverter { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/mapper/DefaultSignatureType.java000066400000000000000000000060571316720554100266510ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.mapper; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.Collection; import static jnr.ffi.util.Annotations.sortedAnnotationCollection; /** * */ public final class DefaultSignatureType implements SignatureType { private final Class declaredClass; private final Collection annotations; private final Type genericType; public DefaultSignatureType(Class declaredClass, Collection annotations, Type genericType) { this.declaredClass = declaredClass; this.annotations = sortedAnnotationCollection(annotations); this.genericType = genericType; } public Class getDeclaredType() { return declaredClass; } public Collection getAnnotations() { return annotations; } public Type getGenericType() { return genericType; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; DefaultSignatureType signature = (DefaultSignatureType) o; return declaredClass == signature.declaredClass && genericType.equals(signature.genericType) && annotations.equals(signature.annotations) ; } @Override public int hashCode() { int result = declaredClass.hashCode(); result = 31 * result + annotations.hashCode(); if (genericType != null) result = 31 * result + genericType.hashCode(); return result; } public static DefaultSignatureType create(Class type, FromNativeContext context) { Type genericType = !type.isPrimitive() && context instanceof MethodResultContext ? ((MethodResultContext) context).getMethod().getGenericReturnType() : type; return new DefaultSignatureType(type, context.getAnnotations(), genericType); } public static DefaultSignatureType create(Class type, ToNativeContext context) { Type genericType = type; if (!type.isPrimitive() && context instanceof MethodParameterContext) { MethodParameterContext methodParameterContext = (MethodParameterContext) context; genericType = methodParameterContext.getMethod().getGenericParameterTypes()[methodParameterContext.getParameterIndex()]; } return new DefaultSignatureType(type, context.getAnnotations(), genericType); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/mapper/DefaultTypeMapper.java000066400000000000000000000034531316720554100261310ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.mapper; import java.util.LinkedHashMap; import java.util.Map; /** * */ public final class DefaultTypeMapper implements TypeMapper { private final Map toNativeConverters; private final Map fromNativeConverters; public DefaultTypeMapper() { toNativeConverters = new LinkedHashMap(); fromNativeConverters = new LinkedHashMap(); } public final void put(Class javaClass, DataConverter converter) { toNativeConverters.put(javaClass, converter); fromNativeConverters.put(javaClass, converter); } public final void put(Class javaClass, ToNativeConverter converter) { toNativeConverters.put(javaClass, converter); } public final void put(Class javaClass, FromNativeConverter converter) { fromNativeConverters.put(javaClass, converter); } public FromNativeConverter getFromNativeConverter(Class type) { return fromNativeConverters.get(type); } public ToNativeConverter getToNativeConverter(Class type) { return toNativeConverters.get(type); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/mapper/FromNativeContext.java000066400000000000000000000023141316720554100261500ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.mapper; import java.lang.annotation.Annotation; import java.util.Collection; import java.util.List; /** * Context for conversion from native to Java. */ public interface FromNativeContext { /** * Gets a sorted list of annotations * * @return a sorted list of annotations for this native type */ public abstract Collection getAnnotations(); /** * Gets the Runtime used for the conversion. * * @return The runtime used for the conversion. */ public jnr.ffi.Runtime getRuntime(); } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/mapper/FromNativeConverter.java000066400000000000000000000026361316720554100265020ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.mapper; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Converts data from a native type to a java type */ public interface FromNativeConverter { public J fromNative(N nativeValue, FromNativeContext context); public Class nativeType(); @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) public static @interface NoContext { } @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public static @interface Cacheable { } @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) @interface FromNative { Class nativeType(); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/mapper/FromNativeType.java000066400000000000000000000020371316720554100254470ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.mapper; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * */ public interface FromNativeType { public FromNativeConverter getFromNativeConverter(); @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public static @interface Cacheable { } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/mapper/FromNativeTypes.java000066400000000000000000000025671316720554100256420ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.mapper; /** * */ public final class FromNativeTypes { public static FromNativeType create(FromNativeConverter converter) { if (converter == null) { return null; } return converter.getClass().isAnnotationPresent(FromNativeConverter.Cacheable.class) ? new Cacheable(converter) : new UnCacheable(converter); } @FromNativeType.Cacheable static class Cacheable extends AbstractFromNativeType { public Cacheable(FromNativeConverter converter) { super(converter); } } static class UnCacheable extends AbstractFromNativeType { public UnCacheable(FromNativeConverter converter) { super(converter); } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/mapper/FunctionMapper.java000066400000000000000000000044551316720554100254730ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.mapper; import jnr.ffi.Library; import java.lang.annotation.Annotation; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Map; public interface FunctionMapper { public static interface Context { @Deprecated public abstract Library getLibrary(); public abstract boolean isSymbolPresent(String name); public Collection getAnnotations(); } /** * Translate the (Java) function name into its (native) equivalent. If the * name is not present in the map, it is to return the supplied name (same * object exactly). * * @param functionName to translate * @param context for translation * @return native equivalent or functionName if not in map */ public String mapFunctionName(String functionName, Context context); public static final class Builder { private final Map functionNameMap = Collections.synchronizedMap(new HashMap()); public Builder map(String javaName, String nativeFunction) { functionNameMap.put(javaName, nativeFunction); return this; } public FunctionMapper build() { return new SimpleFunctionMapper(functionNameMap); } } /** * An implementation of {@link jnr.ffi.mapper.FunctionMapper} that maps 1:1 between java symbols and native functions */ public static final FunctionMapper IDENTITY = new FunctionMapper() { @Override public String mapFunctionName(String functionName, Context context) { return functionName; } }; } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/mapper/MethodParameterContext.java000066400000000000000000000064111316720554100271610ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.mapper; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.Collection; import static jnr.ffi.util.Annotations.sortedAnnotationCollection; /** * Holds context for a method parameter from Java to native conversion. */ public final class MethodParameterContext implements ToNativeContext { private final jnr.ffi.Runtime runtime; private final Method method; private final int parameterIndex; private Collection annotations; private Annotation[] annotationArray; public MethodParameterContext(jnr.ffi.Runtime runtime, Method method, int parameterIndex) { this.runtime = runtime; this.method = method; this.parameterIndex = parameterIndex; } public MethodParameterContext(jnr.ffi.Runtime runtime, Method method, int parameterIndex, Annotation[] annotationArray) { this.runtime = runtime; this.method = method; this.parameterIndex = parameterIndex; this.annotationArray = annotationArray.clone(); } public MethodParameterContext(jnr.ffi.Runtime runtime, Method method, int parameterIndex, Collection annotations) { this.runtime = runtime; this.method = method; this.parameterIndex = parameterIndex; this.annotations = sortedAnnotationCollection(annotations); } public Method getMethod() { return method; } public int getParameterIndex() { return parameterIndex; } public Collection getAnnotations() { return annotations != null ? annotations : buildAnnotationCollection(); } public jnr.ffi.Runtime getRuntime() { return runtime; } private Collection buildAnnotationCollection() { if (annotationArray != null) { return annotations = sortedAnnotationCollection(annotationArray); } else { return annotations = sortedAnnotationCollection(annotationArray = method.getParameterAnnotations()[parameterIndex]); } } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; MethodParameterContext that = (MethodParameterContext) o; return parameterIndex == that.parameterIndex && method.equals(that.method) && getAnnotations().equals(that.getAnnotations()); } @Override public int hashCode() { int result = method.hashCode(); result = 31 * result + parameterIndex; result = 31 * result + getAnnotations().hashCode(); return result; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/mapper/MethodResultContext.java000066400000000000000000000027531316720554100265240ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.mapper; import jnr.ffi.*; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.*; import static jnr.ffi.util.Annotations.sortedAnnotationCollection; /** * */ public class MethodResultContext implements FromNativeContext { private final jnr.ffi.Runtime runtime; private final Method method; private Collection annotations; public MethodResultContext(jnr.ffi.Runtime runtime, Method method) { this.runtime = runtime; this.method = method; } public Method getMethod() { return method; } public Collection getAnnotations() { return annotations != null ? annotations : (annotations = sortedAnnotationCollection(method.getAnnotations())); } public jnr.ffi.Runtime getRuntime() { return runtime; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/mapper/SignatureType.java000066400000000000000000000020001316720554100253240ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.mapper; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.Collection; import static jnr.ffi.util.Annotations.sortedAnnotationCollection; /** * */ public interface SignatureType { public Class getDeclaredType(); public Collection getAnnotations(); public java.lang.reflect.Type getGenericType(); } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/mapper/SignatureTypeMapper.java000066400000000000000000000016021316720554100265000ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.mapper; /** */ public interface SignatureTypeMapper { public FromNativeType getFromNativeType(SignatureType type, FromNativeContext context); public ToNativeType getToNativeType(SignatureType type, ToNativeContext context); } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/mapper/SignatureTypeMapperAdapter.java000066400000000000000000000025541316720554100300100ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.mapper; /** * Adapts a {@link jnr.ffi.mapper.TypeMapper} to a SignatureTypeMapper */ public class SignatureTypeMapperAdapter implements SignatureTypeMapper { private final TypeMapper typeMapper; public SignatureTypeMapperAdapter(TypeMapper typeMapper) { this.typeMapper = typeMapper; } @Override public FromNativeType getFromNativeType(SignatureType type, FromNativeContext context) { return FromNativeTypes.create(typeMapper.getFromNativeConverter(type.getDeclaredType())); } @Override public ToNativeType getToNativeType(SignatureType type, ToNativeContext context) { return ToNativeTypes.create(typeMapper.getToNativeConverter(type.getDeclaredType())); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/mapper/SimpleFunctionMapper.java000066400000000000000000000023161316720554100266370ustar00rootroot00000000000000/* * Copyright (C) 2013 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.mapper; import java.util.Collections; import java.util.HashMap; import java.util.Map; class SimpleFunctionMapper implements FunctionMapper { private final Map functionNameMap; SimpleFunctionMapper(Map map) { functionNameMap = Collections.unmodifiableMap(new HashMap(map)); } public String mapFunctionName(String functionName, Context context) { String nativeFunction = functionNameMap.get(functionName); return nativeFunction != null ? nativeFunction : functionName; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/mapper/SimpleTypeMapper.java000066400000000000000000000031761316720554100260000ustar00rootroot00000000000000/* * Copyright (C) 2013 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.mapper; import java.util.Collections; import java.util.IdentityHashMap; import java.util.Map; final class SimpleTypeMapper implements TypeMapper { private final Map> toNativeConverters; private final Map> fromNativeConverters; public SimpleTypeMapper(Map> toNativeConverters, Map> fromNativeConverters) { this.toNativeConverters = Collections.unmodifiableMap(new IdentityHashMap>(toNativeConverters)); this.fromNativeConverters = Collections.unmodifiableMap(new IdentityHashMap>(fromNativeConverters)); } @Override public FromNativeConverter getFromNativeConverter(Class type) { return fromNativeConverters.get(type); } @Override public ToNativeConverter getToNativeConverter(Class type) { return toNativeConverters.get(type); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/mapper/ToNativeContext.java000066400000000000000000000021741316720554100256330ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.mapper; import java.lang.annotation.Annotation; import java.util.Collection; public interface ToNativeContext { /** * Gets a sorted list of annotations * * @return a sorted list of annotations for this native type */ public abstract Collection getAnnotations(); /** * Gets the Runtime used for the conversion. * * @return The runtime used for the conversion. */ public jnr.ffi.Runtime getRuntime(); } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/mapper/ToNativeConverter.java000066400000000000000000000032151316720554100261530ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.mapper; import jnr.ffi.Pointer; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; public interface ToNativeConverter { public N toNative(J value, ToNativeContext context); public Class nativeType(); /** * Used to reload a parameter converted to a native type via a custom {@link jnr.ffi.mapper.ToNativeConverter} */ public static interface PostInvocation extends ToNativeConverter { public void postInvoke(J j, N n, ToNativeContext context); } @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) public static @interface NoContext { } @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public static @interface Cacheable { } @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) @interface ToNative { Class nativeType(); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/mapper/ToNativeType.java000066400000000000000000000020311316720554100251200ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.mapper; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * */ public interface ToNativeType { public ToNativeConverter getToNativeConverter(); @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public static @interface Cacheable { } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/mapper/ToNativeTypes.java000066400000000000000000000025451316720554100253150ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.mapper; /** * */ public final class ToNativeTypes { public static ToNativeType create(ToNativeConverter converter) { if (converter == null) { return null; } return converter.getClass().isAnnotationPresent(ToNativeConverter.Cacheable.class) ? new Cacheable(converter) : new UnCacheable(converter); } @ToNativeType.Cacheable static class Cacheable extends AbstractToNativeType { public Cacheable(ToNativeConverter converter) { super(converter); } } static class UnCacheable extends AbstractToNativeType { public UnCacheable(ToNativeConverter converter) { super(converter); } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/mapper/TypeMapper.java000066400000000000000000000037721316720554100246300ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.mapper; import java.util.HashMap; import java.util.Map; public interface TypeMapper { public FromNativeConverter getFromNativeConverter(Class type); public ToNativeConverter getToNativeConverter(Class type); public static final class Builder { private final Map> toNativeConverterMap = new HashMap>(); private final Map> fromNativeConverterMap = new HashMap>(); public Builder map(Class javaType, ToNativeConverter toNativeConverter) { toNativeConverterMap.put(javaType, toNativeConverter); return this; } public Builder map(Class javaType, FromNativeConverter fromNativeConverter) { fromNativeConverterMap.put(javaType, fromNativeConverter); return this; } public Builder map(Class javaType, DataConverter dataConverter) { toNativeConverterMap.put(javaType, dataConverter); fromNativeConverterMap.put(javaType, dataConverter); return this; } public TypeMapper build() { return new SimpleTypeMapper(toNativeConverterMap, fromNativeConverterMap); } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/mapper/Util.java000066400000000000000000000012571316720554100234530ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.mapper; class Util { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/000077500000000000000000000000001316720554100222345ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/AbstractArrayMemoryIO.java000066400000000000000000000367561316720554100273030ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider; import jnr.ffi.Runtime; import jnr.ffi.util.BufferUtil; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.charset.Charset; import java.util.Arrays; public abstract class AbstractArrayMemoryIO extends AbstractMemoryIO { private final ArrayIO io; protected final byte[] buffer; protected final int offset, length; protected AbstractArrayMemoryIO(Runtime runtime, byte[] buffer, int offset, int length) { super(runtime, 0, false); this.io = ArrayIO.getArrayIO(runtime); this.buffer = buffer; this.offset = offset; this.length = length; } protected AbstractArrayMemoryIO(Runtime runtime, byte[] buffer) { this(runtime, buffer, 0, buffer.length); } protected AbstractArrayMemoryIO(Runtime runtime, int size) { this(runtime, new byte[size], 0, size); } protected final ArrayIO getArrayIO() { return io; } public final byte[] array() { return buffer; } public final int offset() { return offset; } public final int length() { return length; } @Override public final int arrayLength() { return length; } @Override public final int arrayOffset() { return offset; } @Override public final boolean hasArray() { return true; } public final long size() { return this.length; } protected final int index(long off) { return this.offset + (int) off; } protected final int remaining(long offset) { return length - (int) offset; } public final boolean isNull() { return false; } public String getString(long offset) { return BufferUtil.getString(ByteBuffer.wrap(buffer, index(offset), length - (int) offset), Charset.defaultCharset()); } public String getString(long offset, int maxLength, Charset cs) { return BufferUtil.getString(ByteBuffer.wrap(buffer, index(offset), Math.min(length - (int) offset, maxLength)), cs); } public void putString(long offset, String string, int maxLength, Charset cs) { ByteBuffer buf = cs.encode(string); int len = Math.min(maxLength - 1, Math.min(buf.remaining(), remaining(offset))); buf.get(buffer, index(offset), len); buffer[index(offset) + len] = (byte) 0; } public void putZeroTerminatedByteArray(long offset, byte[] src, int off, int len) { System.arraycopy(src, off, buffer, index(offset), length - (int) offset); buffer[index(offset) + len] = (byte) 0; } public final byte getByte(long offset) { return (byte) (buffer[index(offset)] & 0xff); } public final short getShort(long offset) { return io.getInt16(buffer, index(offset)); } public final int getInt(long offset) { return io.getInt32(buffer, index(offset)); } public final long getLongLong(long offset) { return io.getInt64(buffer, index(offset)); } @Override public final long getAddress(long offset) { return io.getAddress(buffer, index(offset)); } public final float getFloat(long offset) { return io.getFloat32(buffer, index(offset)); } public final double getDouble(long offset) { return io.getFloat64(buffer, index(offset)); } public final void putByte(long offset, byte value) { buffer[index(offset)] = value; } public final void putShort(long offset, short value) { io.putInt16(buffer, index(offset), value); } public final void putInt(long offset, int value) { io.putInt32(buffer, index(offset), value); } public final void putLongLong(long offset, long value) { io.putInt64(buffer, index(offset), value); } @Override public final void putAddress(long offset, long value) { io.putAddress(buffer, index(offset), value); } public final void putFloat(long offset, float value) { io.putFloat32(buffer, index(offset), value); } public final void putDouble(long offset, double value) { io.putFloat64(buffer, index(offset), value); } public final void get(long offset, byte[] dst, int off, int len) { System.arraycopy(buffer, index(offset), dst, off, len); } public final void put(long offset, byte[] src, int off, int len) { System.arraycopy(src, off, buffer, index(offset), len); } public final void get(long offset, short[] dst, int off, int len) { int begin = index(offset); for (int i = 0; i < len; ++i) { dst[off + i] = io.getInt16(buffer, begin + (i << 1)); } } public final void put(long offset, short[] src, int off, int len) { int begin = index(offset); for (int i = 0; i < len; ++i) { io.putInt16(buffer, begin + (i << 1), src[off + i]); } } public final void get(long offset, int[] dst, int off, int len) { int begin = index(offset); for (int i = 0; i < len; ++i) { dst[off + i] = io.getInt32(buffer, begin + (i << 2)); } } public final void put(long offset, int[] src, int off, int len) { int begin = index(offset); for (int i = 0; i < len; ++i) { io.putInt32(buffer, begin + (i << 2), src[off + i]); } } public final void get(long offset, long[] dst, int off, int len) { int begin = index(offset); for (int i = 0; i < len; ++i) { dst[off + i] = io.getInt64(buffer, begin + (i << 3)); } } public final void put(long offset, long[] src, int off, int len) { int begin = index(offset); for (int i = 0; i < len; ++i) { io.putInt64(buffer, begin + (i << 3), src[off + i]); } } public final void get(long offset, float[] dst, int off, int len) { int begin = index(offset); for (int i = 0; i < len; ++i) { dst[off + i] = io.getFloat32(buffer, begin + (i << 2)); } } public final void put(long offset, float[] src, int off, int len) { int begin = index(offset); for (int i = 0; i < len; ++i) { io.putFloat32(buffer, begin + (i << 2), src[off + i]); } } public final void get(long offset, double[] dst, int off, int len) { int begin = index(offset); for (int i = 0; i < len; ++i) { dst[off + i] = io.getFloat64(buffer, begin + (i << 3)); } } public final void put(long offset, double[] src, int off, int len) { int begin = index(offset); for (int i = 0; i < len; ++i) { io.putFloat64(buffer, begin + (i << 3), src[off + i]); } } @Override public final int indexOf(long offset, byte value) { int off = index(offset); for (int i = 0; i < length; ++i) { if (buffer[off + i] == value) { return i; } } return -1; } public final int indexOf(long offset, byte value, int maxlen) { int off = index(offset); for (int i = 0; i < Math.min(length, maxlen); ++i) { if (buffer[off + i] == value) { return i; } } return -1; } public final void setMemory(long offset, long size, byte value) { Arrays.fill(buffer, index(offset), (int) size, value); } public final void clear() { Arrays.fill(buffer, offset, length, (byte) 0); } protected static abstract class ArrayIO { public static ArrayIO getArrayIO(Runtime runtime) { if (runtime.byteOrder().equals(ByteOrder.BIG_ENDIAN)) { return runtime.addressSize() == 8 ? BE64ArrayIO.INSTANCE : BE32ArrayIO.INSTANCE; } else { return runtime.addressSize() == 8 ? LE64ArrayIO.INSTANCE : LE32ArrayIO.INSTANCE; } } public abstract short getInt16(byte[] buffer, int offset); public abstract int getInt32(byte[] buffer, int offset); public abstract long getInt64(byte[] buffer, int offset); public abstract long getAddress(byte[] buffer, int offset); public abstract void putInt16(byte[] buffer, int offset, int value); public abstract void putInt32(byte[] buffer, int offset, int value); public abstract void putInt64(byte[] buffer, int offset, long value); public abstract void putAddress(byte[] buffer, int offset, long value); public final float getFloat32(byte[] buffer, int offset) { return Float.intBitsToFloat(getInt32(buffer, offset)); } public final void putFloat32(byte[] buffer, int offset, float value) { putInt32(buffer, offset, Float.floatToRawIntBits(value)); } public final double getFloat64(byte[] buffer, int offset) { return Double.longBitsToDouble(getInt64(buffer, offset)); } public final void putFloat64(byte[] buffer, int offset, double value) { putInt64(buffer, offset, Double.doubleToRawLongBits(value)); } } private static abstract class LittleEndianArrayIO extends ArrayIO { public final short getInt16(byte[] array, int offset) { return (short) ((array[offset] & 0xff) | ((array[offset + 1] & 0xff) << 8)); } public final int getInt32(byte[] array, int offset) { return ((array[offset + 0] & 0xff) << 0) | ((array[offset + 1] & 0xff) << 8) | ((array[offset + 2] & 0xff) << 16) | ((array[offset + 3] & 0xff) << 24); } public final long getInt64(byte[] array, int offset) { return (((long)array[offset + 0] & 0xff) << 0) | (((long)array[offset + 1] & 0xff) << 8) | (((long)array[offset + 2] & 0xff) << 16) | (((long)array[offset + 3] & 0xff) << 24) | (((long)array[offset + 4] & 0xff) << 32) | (((long)array[offset + 5] & 0xff) << 40) | (((long)array[offset + 6] & 0xff) << 48) | (((long)array[offset + 7] & 0xff) << 56); } public final void putInt16(byte[] buffer, int offset, int value) { buffer[offset + 0] = (byte) (value >> 0); buffer[offset + 1] = (byte) (value >> 8); } public final void putInt32(byte[] buffer, int offset, int value) { buffer[offset + 0] = (byte) (value >> 0); buffer[offset + 1] = (byte) (value >> 8); buffer[offset + 2] = (byte) (value >> 16); buffer[offset + 3] = (byte) (value >> 24); } public final void putInt64(byte[] buffer, int offset, long value) { buffer[offset + 0] = (byte) (value >> 0); buffer[offset + 1] = (byte) (value >> 8); buffer[offset + 2] = (byte) (value >> 16); buffer[offset + 3] = (byte) (value >> 24); buffer[offset + 4] = (byte) (value >> 32); buffer[offset + 5] = (byte) (value >> 40); buffer[offset + 6] = (byte) (value >> 48); buffer[offset + 7] = (byte) (value >> 56); } } private static abstract class BigEndianArrayIO extends ArrayIO { public short getInt16(byte[] array, int offset) { return (short) (((array[offset + 0] & 0xff) << 8) | (array[offset + 1] & 0xff)); } public int getInt32(byte[] array, int offset) { return ((array[offset + 0] & 0xff) << 24) | ((array[offset + 1] & 0xff) << 16) | ((array[offset + 2] & 0xff) << 8) | ((array[offset + 3] & 0xff) << 0); } public long getInt64(byte[] array, int offset) { return (((long)array[offset + 0] & 0xff) << 56) | (((long)array[offset + 1] & 0xff) << 48) | (((long)array[offset + 2] & 0xff) << 40) | (((long)array[offset + 3] & 0xff) << 32) | (((long)array[offset + 4] & 0xff) << 24) | (((long)array[offset + 5] & 0xff) << 16) | (((long)array[offset + 6] & 0xff) << 8) | (((long)array[offset + 7] & 0xff) << 0); } public final void putInt16(byte[] buffer, int offset, int value) { buffer[offset + 0] = (byte) (value >> 8); buffer[offset + 1] = (byte) (value >> 0); } public final void putInt32(byte[] buffer, int offset, int value) { buffer[offset + 0] = (byte) (value >> 24); buffer[offset + 1] = (byte) (value >> 16); buffer[offset + 2] = (byte) (value >> 8); buffer[offset + 3] = (byte) (value >> 0); } public final void putInt64(byte[] buffer, int offset, long value) { buffer[offset + 0] = (byte) (value >> 56); buffer[offset + 1] = (byte) (value >> 48); buffer[offset + 2] = (byte) (value >> 40); buffer[offset + 3] = (byte) (value >> 32); buffer[offset + 4] = (byte) (value >> 24); buffer[offset + 5] = (byte) (value >> 16); buffer[offset + 6] = (byte) (value >> 8); buffer[offset + 7] = (byte) (value >> 0); } } private static final class LE32ArrayIO extends LittleEndianArrayIO { public static final ArrayIO INSTANCE = new LE32ArrayIO(); public final long getAddress(byte[] buffer, int offset) { return (long) getInt32(buffer, offset) & 0xffffffffL; } public final void putAddress(byte[] buffer, int offset, long value) { putInt32(buffer, offset, (int) value); } } private static final class LE64ArrayIO extends LittleEndianArrayIO { public static final ArrayIO INSTANCE = new LE64ArrayIO(); public final long getAddress(byte[] buffer, int offset) { return getInt64(buffer, offset); } public final void putAddress(byte[] buffer, int offset, long value) { putInt64(buffer, offset, value); } } private static final class BE32ArrayIO extends BigEndianArrayIO { public static final ArrayIO INSTANCE = new BE32ArrayIO(); public final long getAddress(byte[] buffer, int offset) { return (long) getInt32(buffer, offset) & 0xffffffffL; } public final void putAddress(byte[] buffer, int offset, long value) { putInt32(buffer, offset, (int) value); } } private static final class BE64ArrayIO extends BigEndianArrayIO { public static final ArrayIO INSTANCE = new BE64ArrayIO(); public final long getAddress(byte[] buffer, int offset) { return getInt64(buffer, offset); } public final void putAddress(byte[] buffer, int offset, long value) { putInt64(buffer, offset, value); } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/AbstractBufferMemoryIO.java000066400000000000000000000143531316720554100274230ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider; import jnr.ffi.Runtime; import jnr.ffi.util.BufferUtil; import java.nio.ByteBuffer; import java.nio.charset.Charset; /** * */ abstract public class AbstractBufferMemoryIO extends AbstractMemoryIO { protected final ByteBuffer buffer; public AbstractBufferMemoryIO(Runtime runtime, ByteBuffer buffer, long address) { super(runtime, address, buffer.isDirect()); this.buffer = buffer; } public long size() { return buffer.remaining(); } public final ByteBuffer getByteBuffer() { return buffer; } @Override public int arrayLength() { return getByteBuffer().remaining(); } @Override public int arrayOffset() { return getByteBuffer().arrayOffset(); } @Override public Object array() { return getByteBuffer().array(); } @Override public boolean hasArray() { return getByteBuffer().hasArray(); } public byte getByte(long offset) { return buffer.get((int) offset); } public short getShort(long offset) { return buffer.getShort((int) offset); } public int getInt(long offset) { return buffer.getInt((int) offset); } public long getLongLong(long offset) { return buffer.getLong((int) offset); } public float getFloat(long offset) { return buffer.getFloat((int) offset); } public double getDouble(long offset) { return buffer.getDouble((int) offset); } public void putByte(long offset, byte value) { buffer.put((int) offset, value); } public void putShort(long offset, short value) { buffer.putShort((int) offset, value); } public void putInt(long offset, int value) { buffer.putInt((int) offset, value); } public void putLongLong(long offset, long value) { buffer.putLong((int) offset, value); } public void putFloat(long offset, float value) { buffer.putFloat((int) offset, value); } public void putDouble(long offset, double value) { buffer.putDouble((int) offset, value); } public String getString(long offset, int size) { return BufferUtil.getString(BufferUtil.slice(buffer, (int) offset), Charset.defaultCharset()); } public void putString(long offset, String string) { BufferUtil.putString(BufferUtil.slice(buffer, (int) offset), Charset.defaultCharset(), string); } @Override public void get(long offset, byte[] dst, int off, int len) { BufferUtil.slice(buffer, (int) offset, len).get(dst, off, len); } @Override public void get(long offset, short[] dst, int off, int len) { BufferUtil.slice(buffer, (int) offset, len * Short.SIZE / 8).asShortBuffer().get(dst, off, len); } @Override public void get(long offset, int[] dst, int off, int len) { BufferUtil.slice(buffer, (int) offset, len * Integer.SIZE / 8).asIntBuffer().get(dst, off, len); } @Override public void get(long offset, long[] dst, int off, int len) { BufferUtil.slice(buffer, (int) offset, len * Long.SIZE / 8).asLongBuffer().get(dst, off, len); } @Override public void get(long offset, float[] dst, int off, int len) { BufferUtil.slice(buffer, (int) offset, len * Float.SIZE / 8).asFloatBuffer().get(dst, off, len); } @Override public void get(long offset, double[] dst, int off, int len) { BufferUtil.slice(buffer, (int) offset, len * Double.SIZE / 8).asDoubleBuffer().get(dst, off, len); } @Override public void put(long offset, byte[] dst, int off, int len) { BufferUtil.slice(buffer, (int) offset, len).put(dst, off, len); } @Override public void put(long offset, short[] dst, int off, int len) { BufferUtil.slice(buffer, (int) offset, len * Short.SIZE / 8).asShortBuffer().put(dst, off, len); } @Override public void put(long offset, int[] src, int off, int len) { BufferUtil.slice(buffer, (int) offset, len * Integer.SIZE / 8).asIntBuffer().put(src, off, len); } @Override public void put(long offset, long[] src, int off, int len) { BufferUtil.slice(buffer, (int) offset, len * Long.SIZE / 8).asLongBuffer().put(src, off, len); } @Override public void put(long offset, float[] src, int off, int len) { BufferUtil.slice(buffer, (int) offset, len * Float.SIZE / 8).asFloatBuffer().put(src, off, len); } @Override public void put(long offset, double[] src, int off, int len) { BufferUtil.slice(buffer, (int) offset, len * Double.SIZE / 8).asDoubleBuffer().put(src, off, len); } @Override public String getString(long offset) { return BufferUtil.getString(BufferUtil.slice(buffer, (int) offset), Charset.defaultCharset()); } @Override public String getString(long offset, int maxLength, Charset cs) { return BufferUtil.getString(BufferUtil.slice(buffer, (int) offset, maxLength), cs); } @Override public void putString(long offset, String string, int maxLength, Charset cs) { BufferUtil.putString(BufferUtil.slice(buffer, (int) offset, maxLength), cs, string); } @Override public int indexOf(long offset, byte value, int maxlen) { for (; offset > -1; ++offset) { if (buffer.get((int) offset) == value) { return (int) offset; } } return -1; } @Override public void setMemory(long offset, long size, byte value) { for (int i = 0; i < size; ++i) { buffer.put((int) offset + i, value); } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/AbstractMemoryIO.java000066400000000000000000000145061316720554100262710ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider; import jnr.ffi.Address; import jnr.ffi.Pointer; import jnr.ffi.Runtime; import jnr.ffi.Type; import java.nio.ByteBuffer; /** * Base implementations of some MemoryIO operations. */ abstract public class AbstractMemoryIO extends Pointer { protected static void checkBounds(long size, long off, long len) { if ((off | len | (off + len) | (size - (off + len))) < 0) { throw new IndexOutOfBoundsException(); } } protected AbstractMemoryIO(Runtime runtime, long address, boolean isDirect) { super(runtime, address, isDirect); } public int indexOf(long offset, byte value) { return indexOf(offset, value, Integer.MAX_VALUE); } public long getAddress(long offset) { return getRuntime().addressSize() == 4 ? getInt(offset) : getLongLong(offset); } public void putAddress(long offset, long value) { if (getRuntime().addressSize() == 4) { putInt(offset, (int) value); } else { putLongLong(offset, value); } } public void checkBounds(long offset, long size) { // No bounds checking by default } public void putAddress(long offset, Address value) { if (getRuntime().addressSize() == 4) { putInt(offset, value.intValue()); } else { putLongLong(offset, value.longValue()); } } public final long getNativeLong(long offset) { return getRuntime().longSize() == 4 ? getInt(offset) : getLongLong(offset); } public void putNativeLong(long offset, long value) { if (getRuntime().longSize() == 4) { putInt(offset, (int) value); } else { putLongLong(offset, value); } } public long getLong(long offset) { return getRuntime().longSize() == 4 ? getInt(offset) : getLongLong(offset); } public void putLong(long offset, long value) { if (getRuntime().longSize() == 4) { putInt(offset, (int) value); } else { putLongLong(offset, value); } } @Override public void putInt(Type type, long offset, long value) { switch (type.getNativeType()) { case SCHAR: case UCHAR: putByte(offset, (byte) value); break; case SSHORT: case USHORT: putShort(offset, (short) value); break; case SINT: case UINT: putInt(offset, (int) value); break; case SLONG: case ULONG: putNativeLong(offset, value); break; case SLONGLONG: case ULONGLONG: putLongLong(offset, value); break; default: throw new IllegalArgumentException("unsupported integer type: " + type.getNativeType()); } } @Override public long getInt(Type type, long offset) { switch (type.getNativeType()) { case SCHAR: case UCHAR: return getByte(offset); case SSHORT: case USHORT: return getShort(offset); case SINT: case UINT: return getInt(offset); case SLONG: case ULONG: return getNativeLong(offset); case SLONGLONG: case ULONGLONG: return getLongLong(offset); default: throw new IllegalArgumentException("unsupported integer type: " + type.getNativeType()); } } public AbstractMemoryIO slice(long offset) { return new ShareMemoryIO(this, offset); } public AbstractMemoryIO slice(long offset, long size) { return new BoundedMemoryIO(this, offset, size); } public void transferTo(long offset, Pointer other, long otherOffset, long count) { Pointer dst = other instanceof DelegatingMemoryIO ? ((DelegatingMemoryIO) other).getDelegatedMemoryIO() : other; dst.checkBounds(otherOffset, count); if (dst instanceof AbstractArrayMemoryIO) { AbstractArrayMemoryIO aio = (AbstractArrayMemoryIO) dst; get(offset, aio.array(), aio.offset() + (int) otherOffset, (int) count); } else if (dst instanceof AbstractBufferMemoryIO && ((AbstractBufferMemoryIO) dst).getByteBuffer().hasArray()) { ByteBuffer buf = ((AbstractBufferMemoryIO) dst).getByteBuffer(); get(offset, buf.array(), buf.arrayOffset() + buf.position() + (int) otherOffset, (int) count); } else { for (long i = 0; i < count; ++i) { other.putByte(otherOffset + i, getByte(offset + i)); } } } public void transferFrom(long offset, Pointer other, long otherOffset, long count) { Pointer src = other instanceof DelegatingMemoryIO ? ((DelegatingMemoryIO) other).getDelegatedMemoryIO() : other; src.checkBounds(otherOffset, count); if (src instanceof AbstractArrayMemoryIO) { AbstractArrayMemoryIO aio = (AbstractArrayMemoryIO) src; put(offset, aio.array(), aio.offset() + (int) otherOffset, (int) count); } else if (src instanceof AbstractBufferMemoryIO && ((AbstractBufferMemoryIO) src).getByteBuffer().hasArray()) { ByteBuffer buf = ((AbstractBufferMemoryIO) src).getByteBuffer(); put(offset, buf.array(), buf.arrayOffset() + buf.position() + (int) otherOffset, (int) count); } else { // Do a byte-at-a-time copy for (long i = 0; i < count; ++i) { putByte(offset + i, other.getByte(otherOffset + i)); } } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/AbstractRuntime.java000066400000000000000000000062021316720554100262060ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider; import jnr.ffi.NativeType; import jnr.ffi.Runtime; import jnr.ffi.Type; import java.nio.ByteOrder; import java.util.EnumMap; import java.util.EnumSet; /** * */ public abstract class AbstractRuntime extends Runtime { private final Type[] types; private final long addressMask; private final int addressSize; private final int longSize; private final ByteOrder byteOrder; public AbstractRuntime(ByteOrder byteOrder, EnumMap typeMap) { this.byteOrder = byteOrder; EnumSet nativeTypes = EnumSet.allOf(NativeType.class); types = new Type[nativeTypes.size()]; for (NativeType t : nativeTypes) { types[t.ordinal()] = typeMap.containsKey(t) ? typeMap.get(t) : new BadType(t.toString()); } this.addressSize = types[NativeType.ADDRESS.ordinal()].size(); this.longSize = types[NativeType.SLONG.ordinal()].size(); this.addressMask = addressSize == 4 ? 0xffffffffL : 0xffffffffffffffffL; } /** Looks up the runtime-specific that corresponds to the pseudo-type */ public final Type findType(NativeType type) { return types[type.ordinal()]; } /** * Gets the native memory manager instance for this runtime * * @return a {@link MemoryManager} */ public abstract MemoryManager getMemoryManager(); /** * Gets the last native error code. *

* This returns the errno value that was set at the time of the last native * function call. * * @return The errno value. */ public abstract int getLastError(); /** * Sets the native error code. * * @param error The value to set errno to. */ public abstract void setLastError(int error); /** Gets the address mask for this runtime */ public final long addressMask() { return addressMask; } /** * Gets the size of an address (e.g. a pointer) for this runtime * * @return The size of an address in bytes. */ public final int addressSize() { return addressSize; } /** * Gets the size of a C long integer for this runtime * * @return The size of a C long integer in bytes. */ public final int longSize() { return longSize; } /** * Retrieves this runtime's native byte order. * * @return this runtime's byte order */ public final ByteOrder byteOrder() { return byteOrder; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/BadType.java000066400000000000000000000022651316720554100244340ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider; import jnr.ffi.NativeType; /** * */ public final class BadType extends jnr.ffi.Type { private final String typeName; public BadType(String typeName) { this.typeName = typeName; } public final int alignment() { throw new RuntimeException("invalid type: " + typeName); } public final int size() { throw new RuntimeException("invalid type: " + typeName); } public NativeType getNativeType() { throw new RuntimeException("invalid type: " + typeName); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/BoundedMemoryIO.java000066400000000000000000000212731316720554100261050ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider; import jnr.ffi.Address; import jnr.ffi.Pointer; import java.nio.charset.Charset; public final class BoundedMemoryIO extends AbstractMemoryIO implements DelegatingMemoryIO { private final long base, size; private final Pointer io; public BoundedMemoryIO(Pointer parent, long offset, long size) { super(parent.getRuntime(), parent.address() != 0L ? parent.address() + offset : 0L, parent.isDirect()); this.io = parent; this.base = offset; this.size = size; } public long size() { return this.size; } @Override public final boolean hasArray() { return io.hasArray(); } @Override public final Object array() { return io.array(); } @Override public final int arrayOffset() { return io.arrayOffset() + (int) base; } @Override public final int arrayLength() { return (int) size; } @Override public void checkBounds(long offset, long length) { checkBounds(this.size, offset, length); getDelegatedMemoryIO().checkBounds(base + offset, length); } public Pointer getDelegatedMemoryIO() { return io; } @Override public int hashCode() { return getDelegatedMemoryIO().hashCode(); } @Override public boolean equals(Object obj) { return (obj instanceof BoundedMemoryIO && io.equals(((BoundedMemoryIO) obj).io) && ((BoundedMemoryIO) obj).base == base && ((BoundedMemoryIO) obj).size == size) || io.equals(obj); } @Override public byte getByte(long offset) { checkBounds(size, offset, 1); return io.getByte(base + offset); } @Override public short getShort(long offset) { checkBounds(size, offset, 2); return io.getShort(base + offset); } @Override public int getInt(long offset) { checkBounds(size, offset, 4); return io.getInt(base + offset); } @Override public long getLongLong(long offset) { checkBounds(size, offset, 8); return io.getLongLong(base + offset); } @Override public float getFloat(long offset) { checkBounds(size, offset, 4); return io.getFloat(base + offset); } @Override public double getDouble(long offset) { checkBounds(size, offset, 8); return io.getDouble(base + offset); } public Pointer getPointer(long offset) { checkBounds(size, offset, getRuntime().addressSize()); return io.getPointer(base + offset); } public Pointer getPointer(long offset, long size) { checkBounds(this.size, base + offset, getRuntime().addressSize()); return io.getPointer(base + offset, size); } @Override public void putByte(long offset, byte value) { checkBounds(size, offset, 1); io.putByte(base + offset, value); } @Override public void putShort(long offset, short value) { checkBounds(size, offset, 2); io.putShort(base + offset, value); } @Override public void putInt(long offset, int value) { checkBounds(size, offset, 4); io.putInt(base + offset, value); } @Override public void putLongLong(long offset, long value) { checkBounds(size, offset, 8); io.putLongLong(base + offset, value); } @Override public void putFloat(long offset, float value) { checkBounds(size, offset, 4); io.putFloat(base + offset, value); } @Override public void putDouble(long offset, double value) { checkBounds(size, offset, 8); io.putDouble(base + offset, value); } public void putPointer(long offset, Pointer value) { checkBounds(size, offset, getRuntime().addressSize()); io.putPointer(base + offset, value); } @Override public void get(long offset, byte[] dst, int off, int len) { checkBounds(size, offset, len); io.get(base + offset, dst, off, len); } @Override public void put(long offset, byte[] dst, int off, int len) { checkBounds(size, offset, len); io.put(base + offset, dst, off, len); } @Override public void get(long offset, short[] dst, int off, int len) { checkBounds(size, offset, len * Short.SIZE / 8); io.get(base + offset, dst, off, len); } @Override public void put(long offset, short[] dst, int off, int len) { checkBounds(size, offset, len * Short.SIZE / 8); io.put(base + offset, dst, off, len); } @Override public void get(long offset, int[] dst, int off, int len) { checkBounds(size, offset, len * Integer.SIZE / 8); io.get(base + offset, dst, off, len); } @Override public void put(long offset, int[] src, int off, int len) { checkBounds(size, offset, len * Integer.SIZE / 8); io.put(base + offset, src, off, len); } @Override public void get(long offset, long[] dst, int off, int len) { checkBounds(size, offset, len * Long.SIZE / 8); io.get(base + offset, dst, off, len); } @Override public void put(long offset, long[] src, int off, int len) { checkBounds(size, offset, len * Long.SIZE / 8); io.put(base + offset, src, off, len); } @Override public void get(long offset, float[] dst, int off, int len) { checkBounds(size, offset, len * Float.SIZE / 8); io.get(base + offset, dst, off, len); } @Override public void put(long offset, float[] src, int off, int len) { checkBounds(size, offset, len * Float.SIZE / 8); io.put(base + offset, src, off, len); } @Override public void get(long offset, double[] dst, int off, int len) { checkBounds(size, offset, len * Double.SIZE / 8); io.get(base + offset, dst, off, len); } @Override public void put(long offset, double[] src, int off, int len) { checkBounds(size, offset, len * Double.SIZE / 8); io.put(base + offset, src, off, len); } @Override public long getAddress(long offset) { checkBounds(size, offset, getRuntime().addressSize()); return io.getAddress(base + offset); } @Override public String getString(long offset, int maxLength, Charset cs) { checkBounds(size, offset, maxLength); return io.getString(base + offset, maxLength, cs); } @Override public String getString(long offset) { return io.getString(base + offset, (int) size, Charset.defaultCharset()); } @Override public void putAddress(long offset, long value) { checkBounds(size, offset, getRuntime().addressSize()); io.putAddress(base + offset, value); } @Override public void putAddress(long offset, Address value) { checkBounds(size, offset, getRuntime().addressSize()); io.putAddress(base + offset, value); } @Override public void putString(long offset, String string, int maxLength, Charset cs) { checkBounds(size, offset, maxLength); io.putString(base + offset, string, maxLength, cs); } @Override public int indexOf(long offset, byte value) { return io.indexOf(base + offset, value, (int) size); } @Override public int indexOf(long offset, byte value, int maxlen) { checkBounds(size, offset, maxlen); return io.indexOf(base + offset, value, maxlen); } @Override public void setMemory(long offset, long size, byte value) { checkBounds(this.size, base + offset, size); io.setMemory(base + offset, size, value); } @Override public void transferFrom(long offset, Pointer other, long otherOffset, long count) { checkBounds(this.size, base + offset, count); getDelegatedMemoryIO().transferFrom(offset, other, otherOffset, count); } @Override public void transferTo(long offset, Pointer other, long otherOffset, long count) { checkBounds(this.size, base + offset, count); getDelegatedMemoryIO().transferTo(offset, other, otherOffset, count); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/ClosureManager.java000066400000000000000000000016131316720554100260070ustar00rootroot00000000000000/* * Copyright (C) 2011 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider; /** * */ public interface ClosureManager { public abstract T newClosure(Class closureClass, T instance); public abstract jnr.ffi.Pointer getClosurePointer(Class closureClass, T instance); } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/DefaultObjectReferenceManager.java000066400000000000000000000054241316720554100307310ustar00rootroot00000000000000/* * Copyright (C) 2011 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider; import jnr.ffi.ObjectReferenceManager; import jnr.ffi.Pointer; import jnr.ffi.Runtime; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicLong; /** * */ public final class DefaultObjectReferenceManager extends ObjectReferenceManager { private final Runtime runtime; private final ConcurrentMap references = new ConcurrentHashMap(); public DefaultObjectReferenceManager(Runtime runtime) { this.runtime = runtime; } public Pointer add(Object obj) { if (obj == null) { throw new IllegalArgumentException("reference to null value not allowed"); } long nextId = id(obj); ObjectReference ptr; while (references.putIfAbsent(nextId, ptr = new ObjectReference(runtime, nextId, obj)) != null) { // A collision on the identity hash is extremely rare, but possible, so probe for a vacant slot ++nextId; } return ptr; } public boolean remove(Pointer reference) { ObjectReference entry = references.remove(reference.address()); return entry != null; } public Object get(Pointer reference) { ObjectReference ptr = references.get(reference.address()); return ptr != null ? ptr.referent : null; } private long id(Object obj) { return ((0xcafebabeL << 32) | (System.identityHashCode(obj) & 0xffffffffL)) & runtime.addressMask(); } private static final class ObjectReference extends InAccessibleMemoryIO { private final Object referent; public ObjectReference(jnr.ffi.Runtime runtime, long address, Object referent) { super(runtime, address, true); this.referent = referent; } public long size() { return 0; } @Override public int hashCode() { return (int) address(); } @Override public boolean equals(Object obj) { return obj instanceof Pointer && ((Pointer) obj).address() == address(); } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/DelegatingMemoryIO.java000066400000000000000000000014221316720554100265620ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider; import jnr.ffi.Pointer; public interface DelegatingMemoryIO { public Pointer getDelegatedMemoryIO(); } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/FFIProvider.java000066400000000000000000000050131316720554100252150ustar00rootroot00000000000000/* * Copyright (C) 2008-2011 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider; import jnr.ffi.*; /** * This class defines the facilities a JNR FFI provider must provide. * * You most likely do NOT want to use this class directly */ public abstract class FFIProvider { /** * Gets an instance of FFIProvider * * @return an instance of FFIProvider */ public static FFIProvider getSystemProvider() { return SystemProviderSingletonHolder.INSTANCE; } protected FFIProvider() {} /** * Gets the default Runtime for this provider. * * @return the runtime. */ public abstract jnr.ffi.Runtime getRuntime(); /** * Creates a new {@link LibraryLoader} instance. * * @param The library type. * @param interfaceClass The library interface class. * @return the {@code LibraryLoader} instance. */ public abstract LibraryLoader createLibraryLoader(Class interfaceClass); private static final class SystemProviderSingletonHolder { private static final FFIProvider INSTANCE = getInstance(); static FFIProvider getInstance() { String providerName = System.getProperty("jnr.ffi.provider"); if (providerName == null) { Package pkg = FFIProvider.class.getPackage(); String pkgName = pkg != null && pkg.getName() != null ? pkg.getName() : "jnr.ffi.provider"; providerName = pkgName + ".jffi.Provider"; } try { return (FFIProvider) Class.forName(providerName).newInstance(); } catch (Throwable ex) { return newInvalidProvider("could not load FFI provider " + providerName, ex); } } } private static FFIProvider newInvalidProvider(String message, Throwable cause) { return new InvalidProvider(message, cause); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/FromNativeType.java000066400000000000000000000032671316720554100260230ustar00rootroot00000000000000/* * Copyright (C) 2013 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider; import jnr.ffi.NativeType; import jnr.ffi.mapper.FromNativeContext; import jnr.ffi.mapper.FromNativeConverter; import java.lang.annotation.Annotation; import java.util.Collection; /** * */ public class FromNativeType extends SigType implements jnr.ffi.mapper.FromNativeType { private final FromNativeConverter fromNativeConverter; private final FromNativeContext fromNativeContext; public FromNativeType(Class javaType, NativeType nativeType, Collection annotations, FromNativeConverter fromNativeConverter, FromNativeContext fromNativeContext) { super(javaType, nativeType, annotations, fromNativeConverter != null ? fromNativeConverter.nativeType() : javaType); this.fromNativeConverter = fromNativeConverter; this.fromNativeContext = fromNativeContext; } @Override public FromNativeConverter getFromNativeConverter() { return fromNativeConverter; } public FromNativeContext getFromNativeContext() { return fromNativeContext; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/IdentityFunctionMapper.java000066400000000000000000000023111316720554100275400ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider; import jnr.ffi.mapper.FunctionMapper; /** * An implementation of {@link FunctionMapper} that just returns the same name as input */ public class IdentityFunctionMapper implements FunctionMapper { private static final class SingletonHolder { public static final FunctionMapper INSTANCE = new IdentityFunctionMapper(); } public static FunctionMapper getInstance() { return SingletonHolder.INSTANCE; } public String mapFunctionName(String functionName, Context context) { return functionName; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/InAccessibleMemoryIO.java000066400000000000000000000107251316720554100270510ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider; import jnr.ffi.Pointer; import jnr.ffi.Runtime; import java.nio.charset.Charset; abstract public class InAccessibleMemoryIO extends AbstractMemoryIO { private static final String msg = "attempted access to inaccessible memory"; protected InAccessibleMemoryIO(Runtime runtime, long address, boolean isDirect) { super(runtime, address, isDirect); } protected RuntimeException error() { return new IndexOutOfBoundsException(msg); } @Override public boolean hasArray() { return false; } @Override public Object array() { return null; } @Override public int arrayOffset() { return 0; } @Override public int arrayLength() { return 0; } public final byte getByte(long offset) { throw error(); } public final short getShort(long offset) { throw error(); } public final int getInt(long offset) { throw error(); } public final long getLong(long offset) { throw error(); } public final long getLongLong(long offset) { throw error(); } public final float getFloat(long offset) { throw error(); } public final double getDouble(long offset) { throw error(); } public final void putByte(long offset, byte value) { throw error(); } public final void putShort(long offset, short value) { throw error(); } public final void putInt(long offset, int value) { throw error(); } public final void putLong(long offset, long value) { throw error(); } public final void putLongLong(long offset, long value) { throw error(); } public final void putFloat(long offset, float value) { throw error(); } public final void putDouble(long offset, double value) { throw error(); } public final void get(long offset, byte[] dst, int off, int len) { throw error(); } public final void put(long offset, byte[] dst, int off, int len) { throw error(); } public final void get(long offset, short[] dst, int off, int len) { throw error(); } public final void put(long offset, short[] dst, int off, int len) { throw error(); } public final void get(long offset, int[] dst, int off, int len) { throw error(); } public final void put(long offset, int[] src, int off, int len) { throw error(); } public final void get(long offset, long[] dst, int off, int len) { throw error(); } public final void put(long offset, long[] src, int off, int len) { throw error(); } public final void get(long offset, float[] dst, int off, int len) { throw error(); } public final void put(long offset, float[] src, int off, int len) { throw error(); } public final void get(long offset, double[] dst, int off, int len) { throw error(); } public final void put(long offset, double[] src, int off, int len) { throw error(); } public final Pointer getPointer(long offset, long size) { throw error(); } public final Pointer getPointer(long offset) { throw error(); } public final void putPointer(long offset, Pointer value) { throw error(); } public String getString(long offset) { throw error(); } public String getString(long offset, int maxLength, Charset cs) { throw error(); } public void putString(long offset, String string, int maxLength, Charset cs) { throw error(); } public final int indexOf(long offset, byte value, int maxlen) { throw error(); } public final void setMemory(long offset, long size, byte value) { throw error(); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/IntPointer.java000066400000000000000000000023731316720554100251770ustar00rootroot00000000000000/* * Copyright (C) 2011 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider; import jnr.ffi.Pointer; /** * */ public final class IntPointer extends InAccessibleMemoryIO { public IntPointer(jnr.ffi.Runtime runtime, long address) { super(runtime, address, true); } public IntPointer(jnr.ffi.Runtime runtime, int address) { super(runtime, address & 0xffffffffL, true); } public long size() { return 0; } @Override public int hashCode() { return (int) address(); } @Override public boolean equals(Object obj) { return obj instanceof Pointer && ((Pointer) obj).address() == address(); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/InterfaceScanner.java000066400000000000000000000125701316720554100263160ustar00rootroot00000000000000/* * Copyright (C) 2013 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider; import jnr.ffi.CallingConvention; import jnr.ffi.Variable; import jnr.ffi.annotations.StdCall; import jnr.ffi.mapper.SignatureTypeMapper; import java.lang.reflect.Method; import java.util.AbstractCollection; import java.util.Collection; import java.util.Iterator; public class InterfaceScanner { private final Class interfaceClass; private final SignatureTypeMapper typeMapper; private final CallingConvention callingConvention; private final Method[] methods; public InterfaceScanner(Class interfaceClass, SignatureTypeMapper typeMapper, CallingConvention callingConvention) { this.interfaceClass = interfaceClass; this.typeMapper = typeMapper; this.methods = interfaceClass.getMethods(); this.callingConvention = interfaceClass.isAnnotationPresent(StdCall.class) ? CallingConvention.STDCALL : callingConvention; } public Collection functions() { return new AbstractCollection() { @Override public Iterator iterator() { return new FunctionsIterator(methods); } @Override public int size() { return 0; } }; } public Collection variables() { return new AbstractCollection() { @Override public Iterator iterator() { return new VariablesIterator(methods); } @Override public int size() { return 0; } }; } private static final Method methodIsDefault; static { Method isDefault = null; try { isDefault = Method.class.getMethod("isDefault", null); } catch (NoSuchMethodException e) { // expected for jre < 1.8 } methodIsDefault = isDefault; } private static boolean isDefault(Method method) { if (methodIsDefault == null) { return false; } try { return Boolean.TRUE.equals(methodIsDefault.invoke(method)); } catch (Exception e) { // e can throw one of: // * IllegalAccessException, but we know isDefault is public. // * InvocationTargetException, but we know isDefault doesn't throw. // but java doesn't let us prove this invariants, so we do this. // And we can't catch ReflectiveOperationException as it was // introduced in Java SE 1.7, so we have to catch the next common // superclass (Exception). throw new RuntimeException("Unexpected error attempting to call isDefault method", e); } } private final class FunctionsIterator implements Iterator { private final java.lang.reflect.Method[] methods; private int nextIndex; private FunctionsIterator(Method[] methods) { this.methods = methods; this.nextIndex = 0; } @Override public boolean hasNext() { for (; nextIndex < methods.length; nextIndex++) { if (!Variable.class.isAssignableFrom(methods[nextIndex].getReturnType()) && !isDefault(methods[nextIndex])) { return true; } } return false; } @Override public NativeFunction next() { // Allow individual methods to set the calling convention to stdcall CallingConvention callingConvention = methods[nextIndex].isAnnotationPresent(StdCall.class) ? CallingConvention.STDCALL : InterfaceScanner.this.callingConvention; return new NativeFunction(methods[nextIndex++], callingConvention); } @Override public void remove() { throw new UnsupportedOperationException(); } } private final class VariablesIterator implements Iterator { private final java.lang.reflect.Method[] methods; private int nextIndex; private VariablesIterator(Method[] methods) { this.methods = methods; this.nextIndex = 0; } @Override public boolean hasNext() { for (; nextIndex < methods.length; nextIndex++) { if (Variable.class == methods[nextIndex].getReturnType()) { return true; } } return false; } @Override public NativeVariable next() { return new NativeVariable(methods[nextIndex++]); } @Override public void remove() { throw new UnsupportedOperationException(); } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/InvalidProvider.java000066400000000000000000000032521316720554100262020ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider; import jnr.ffi.*; import jnr.ffi.Runtime; import java.util.Collection; import java.util.Map; final class InvalidProvider extends FFIProvider { private final String message; private final Throwable cause; private final jnr.ffi.Runtime runtime; InvalidProvider(String message, Throwable cause) { this.message = message; this.cause = cause; this.runtime = new InvalidRuntime(message, cause); } @Override public Runtime getRuntime() { return runtime; } @Override public LibraryLoader createLibraryLoader(Class interfaceClass) { return new LibraryLoader(interfaceClass) { @Override protected T loadLibrary(Class interfaceClass, Collection libraryNames, Collection searchPaths, Map options) { UnsatisfiedLinkError error = new UnsatisfiedLinkError(message); error.initCause(cause); throw error; } }; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/InvalidRuntime.java000066400000000000000000000046031316720554100260340ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider; import jnr.ffi.*; import jnr.ffi.Runtime; import jnr.ffi.provider.MemoryManager; import jnr.ffi.provider.ClosureManager; import java.nio.ByteOrder; /** * A {@link jnr.ffi.Runtime} subclass that throws exceptions for all methods */ class InvalidRuntime extends jnr.ffi.Runtime { private final String message; private final Throwable cause; InvalidRuntime(String message, Throwable cause) { this.message = message; this.cause = cause; } @Override public Type findType(NativeType type) { throw newLoadError(); } @Override public Type findType(TypeAlias type) { throw newLoadError(); } @Override public MemoryManager getMemoryManager() { throw newLoadError(); } @Override public ClosureManager getClosureManager() { throw newLoadError(); } @Override public ObjectReferenceManager newObjectReferenceManager() { throw newLoadError(); } @Override public int getLastError() { throw newLoadError(); } @Override public void setLastError(int error) { throw newLoadError(); } @Override public long addressMask() { throw newLoadError(); } @Override public int addressSize() { throw newLoadError(); } @Override public int longSize() { throw newLoadError(); } @Override public ByteOrder byteOrder() { throw newLoadError(); } @Override public boolean isCompatible(Runtime other) { throw newLoadError(); } private UnsatisfiedLinkError newLoadError() { UnsatisfiedLinkError error = new UnsatisfiedLinkError(message); error.initCause(cause); throw error; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/InvocationSession.java000066400000000000000000000030171316720554100265550ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider; import java.util.ArrayList; /** * Holds information for each invocation of a native function */ public class InvocationSession { private ArrayList list; private ArrayList liveObjects; public InvocationSession() { } public static interface PostInvoke { void postInvoke(); } public void finish() { if (list != null) for (PostInvoke p : list) { try { p.postInvoke(); } catch (Throwable t) {} } } public void addPostInvoke(PostInvoke postInvoke) { if (list == null) { list = new ArrayList(); } list.add(postInvoke); } public void keepAlive(Object obj) { if (liveObjects == null) { liveObjects = new ArrayList(); } liveObjects.add(obj); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/Invoker.java000066400000000000000000000014501316720554100245140ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider; /** * Interface for any invocable function */ public interface Invoker { Object invoke(Object self, Object[] parameters); } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/LoadedLibrary.java000066400000000000000000000014601316720554100256150ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider; /** * All loaded libraries must implement this interface */ public interface LoadedLibrary { public jnr.ffi.Runtime getRuntime(); } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/MemoryManager.java000066400000000000000000000024461316720554100256500ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider; import jnr.ffi.Pointer; import java.nio.ByteBuffer; /** * Manages access to various types of java and native memory. */ public interface MemoryManager { public abstract Pointer allocate(int size); public abstract Pointer allocateDirect(int size); public abstract Pointer allocateDirect(int size, boolean clear); public abstract Pointer allocateTemporary(int size, boolean clear); public abstract Pointer newPointer(ByteBuffer buffer); public abstract Pointer newPointer(long address); public abstract Pointer newPointer(long address, long size); public abstract Pointer newOpaquePointer(long address); } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/NativeFunction.java000066400000000000000000000044771316720554100260470ustar00rootroot00000000000000/* * Copyright (C) 2013 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider; import jnr.ffi.CallingConvention; import jnr.ffi.annotations.IgnoreError; import jnr.ffi.annotations.SaveError; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.Arrays; import java.util.Collection; import java.util.Collections; public final class NativeFunction { private final Method method; private final Collection annotations; private final boolean saveError; private final boolean ignoreError; private final CallingConvention callingConvention; public NativeFunction(Method method, CallingConvention callingConvention) { this.method = method; this.annotations = Collections.unmodifiableCollection(Arrays.asList(method.getAnnotations())); this.saveError = hasSaveError(method); this.ignoreError = hasIgnoreError(method); this.callingConvention = callingConvention; } public Collection annotations() { return annotations; } public CallingConvention convention() { return callingConvention; } public String name() { return method.getName(); } public boolean isErrnoRequired() { return !ignoreError || saveError; } public boolean hasSaveError() { return saveError; } public boolean hasIgnoreError() { return ignoreError; } public Method getMethod() { return method; } public static boolean hasSaveError(Method method) { return method.getAnnotation(SaveError.class) != null; } public static boolean hasIgnoreError(Method method) { return method.getAnnotation(IgnoreError.class) != null; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/NativeInvocationHandler.java000066400000000000000000000043011316720554100276530ustar00rootroot00000000000000/* * Copyright (C) 2008-2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.util.Collections; import java.util.IdentityHashMap; import java.util.Map; /** * InvocationHandler used to map invocations on a java interface to the correct native function. */ public class NativeInvocationHandler implements InvocationHandler { private volatile Map fastLookupTable; private final Map invokerMap; /** * Creates a new InvocationHandler instance. * * @param invokers A map of method invokers * */ public NativeInvocationHandler(Map invokers) { this.invokerMap = invokers; this.fastLookupTable = Collections.emptyMap(); } public Object invoke(Object self, Method method, Object[] argArray) throws Throwable { Invoker invoker = fastLookupTable.get(method); return invoker != null ? invoker.invoke(self, argArray) : lookupAndCacheInvoker(method).invoke(self, argArray); } private synchronized Invoker lookupAndCacheInvoker(Method method) { Invoker invoker; if ((invoker = fastLookupTable.get(method)) != null) { return invoker; } Map map = new IdentityHashMap(fastLookupTable); map.put(method, invoker = invokerMap.get(method)); if (invoker == null) { throw new UnsatisfiedLinkError("no invoker for native method " + method.getName()); } fastLookupTable = map; return invoker; } }jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/NativeVariable.java000066400000000000000000000016221316720554100257740ustar00rootroot00000000000000/* * Copyright (C) 2013 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider; import java.lang.reflect.Method; public class NativeVariable { private final Method method; public NativeVariable(Method method) { this.method = method; } public Method getMethod() { return method; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/NullMemoryIO.java000066400000000000000000000021151316720554100254310ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider; import jnr.ffi.Runtime; public final class NullMemoryIO extends InAccessibleMemoryIO { private static final String msg = "attempted access to a NULL memory address"; public NullMemoryIO(Runtime runtime) { super(runtime, 0, true); } protected final NullPointerException error() { return new NullPointerException(msg); } public long size() { return Long.MAX_VALUE; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/NullTypeMapper.java000066400000000000000000000024761316720554100260310ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider; import jnr.ffi.mapper.*; /** * An instance of {@link TypeMapper} which always returns null */ public class NullTypeMapper extends AbstractSignatureTypeMapper implements TypeMapper, SignatureTypeMapper { public FromNativeConverter getFromNativeConverter(Class type) { return null; } public ToNativeConverter getToNativeConverter(Class type) { return null; } @Override public FromNativeType getFromNativeType(SignatureType type, FromNativeContext context) { return null; } @Override public ToNativeType getToNativeType(SignatureType type, ToNativeContext context) { return null; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/ParameterFlags.java000066400000000000000000000065061316720554100260030ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider; import jnr.ffi.annotations.*; import java.lang.annotation.Annotation; import java.util.Collection; /** * */ public final class ParameterFlags { private ParameterFlags() {} /** Contents of the parameter memory will be copied from native memory back to java */ public static final int OUT = 0x01; /** Contents of the parameter memory will be copied from from java to native memory */ public static final int IN = 0x02; /** The java array memory should be pinned by the JVM during the function call */ public static final int PINNED = 0x04; /** The contents of the java array should have a zero byte appended */ public static final int NULTERMINATE = 0x08; /** When allocating memory for the parameter, a temporary memory block can be used */ public static final int TRANSIENT = 0x10; /** When allocating memory for the parameter, allocate a persistent memory block */ public static final int DIRECT = 0x20; public static int parse(Annotation annotation) { int flags = 0; flags |= annotation instanceof Out ? OUT : 0; flags |= annotation instanceof In ? IN : 0; flags |= annotation instanceof Transient ? TRANSIENT : 0; flags |= annotation instanceof Direct ? DIRECT : 0; flags |= annotation instanceof Pinned ? PINNED : 0; flags |= annotation instanceof NulTerminate ? NULTERMINATE : 0; return flags; } public static int parse(Annotation[] annotations) { int flags = 0; for (Annotation a : annotations) { flags |= parse(a); } return flags; } public static int parse(Collection annotations) { int flags = 0; for (Annotation a : annotations) { flags |= parse(a); } return flags; } /** * Checks if the annotation is a recognised parameter flag. * * @param annotation the annotation to check. * @return true if the annotation is a parameter flag */ public static boolean isFlag(Annotation annotation) { return parse(annotation) != 0; } public static boolean isPinned(int flags) { return (flags & PINNED) != 0; } public static boolean isTransient(int flags) { return (flags & TRANSIENT) != 0; } public static boolean isDirect(int flags) { return (flags & DIRECT) != 0; } public static boolean isNulTerminate(int flags) { return (flags & NULTERMINATE) != 0; } public static boolean isOut(int flags) { return (flags & (OUT | IN)) != IN; } public static boolean isIn(int flags) { return (flags & (OUT | IN)) != OUT; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/ParameterType.java000066400000000000000000000022551316720554100256650ustar00rootroot00000000000000/* * Copyright (C) 2013 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider; import jnr.ffi.NativeType; import jnr.ffi.mapper.ToNativeContext; import jnr.ffi.mapper.ToNativeConverter; import java.lang.annotation.Annotation; import java.util.Collection; /** * */ public class ParameterType extends ToNativeType { public ParameterType(Class javaType, NativeType nativeType, Collection annotations, ToNativeConverter toNativeConverter, ToNativeContext toNativeContext) { super(javaType, nativeType, annotations, toNativeConverter, toNativeContext); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/ResultType.java000066400000000000000000000022661316720554100252250ustar00rootroot00000000000000/* * Copyright (C) 2013 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider; import jnr.ffi.NativeType; import jnr.ffi.mapper.FromNativeContext; import jnr.ffi.mapper.FromNativeConverter; import java.lang.annotation.Annotation; import java.util.Collection; /** * */ public class ResultType extends FromNativeType { public ResultType(Class javaType, NativeType nativeType, Collection annotations, FromNativeConverter fromNativeConverter, FromNativeContext fromNativeContext) { super(javaType, nativeType, annotations, fromNativeConverter, fromNativeContext); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/ShareMemoryIO.java000066400000000000000000000133301316720554100255620ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider; import jnr.ffi.Pointer; import java.nio.charset.Charset; /** * */ public class ShareMemoryIO extends AbstractMemoryIO implements DelegatingMemoryIO { private final Pointer ptr; private final long base; public ShareMemoryIO(Pointer parent, long offset) { super(parent.getRuntime(), parent.address() != 0L ? parent.address() + offset : 0L, parent.isDirect()); this.ptr = parent; this.base = offset; } public long size() { return ptr.size() - base; } @Override public final boolean hasArray() { return ptr.hasArray(); } @Override public final Object array() { return ptr.array(); } @Override public final int arrayOffset() { return ptr.arrayOffset() + (int) base; } @Override public final int arrayLength() { return ptr.arrayLength() - (int) base; } public final Pointer getDelegatedMemoryIO() { return ptr; } @Override public byte getByte(long offset) { return ptr.getByte(base + offset); } @Override public short getShort(long offset) { return ptr.getShort(base + offset); } @Override public int getInt(long offset) { return ptr.getInt(base + offset); } @Override public long getLong(long offset) { return ptr.getLong(base + offset); } @Override public long getLongLong(long offset) { return ptr.getLongLong(base + offset); } @Override public float getFloat(long offset) { return ptr.getFloat(base + offset); } @Override public double getDouble(long offset) { return ptr.getDouble(base + offset); } public Pointer getPointer(long offset) { return ptr.getPointer(base + offset); } public Pointer getPointer(long offset, long size) { return ptr.getPointer(base + offset, size); } @Override public String getString(long offset) { return ptr.getString(base + offset); } @Override public String getString(long offset, int maxLength, Charset cs) { return ptr.getString(base + offset, maxLength, cs); } @Override public void putByte(long offset, byte value) { ptr.putByte(base + offset, value); } @Override public void putShort(long offset, short value) { ptr.putShort(base + offset, value); } @Override public void putInt(long offset, int value) { ptr.putInt(base + offset, value); } @Override public void putLong(long offset, long value) { ptr.putLong(base + offset, value); } @Override public void putLongLong(long offset, long value) { ptr.putLongLong(base + offset, value); } @Override public void putFloat(long offset, float value) { ptr.putFloat(base + offset, value); } @Override public void putDouble(long offset, double value) { ptr.putDouble(base + offset, value); } public void putPointer(long offset, Pointer value) { ptr.putPointer(base + offset, value); } @Override public void putString(long offset, String string, int maxLength, Charset cs) { ptr.putString(base + offset, string, maxLength, cs); } @Override public void get(long offset, byte[] dst, int off, int len) { ptr.get(base + offset, dst, off, len); } @Override public void put(long offset, byte[] dst, int off, int len) { ptr.put(base + offset, dst, off, len); } @Override public void get(long offset, short[] dst, int off, int len) { ptr.get(base + offset, dst, off, len); } @Override public void put(long offset, short[] dst, int off, int len) { ptr.put(base + offset, dst, off, len); } @Override public void get(long offset, int[] dst, int off, int len) { ptr.get(base + offset, dst, off, len); } @Override public void put(long offset, int[] src, int off, int len) { ptr.put(base + offset, src, off, len); } @Override public void get(long offset, long[] dst, int off, int len) { ptr.get(base + offset, dst, off, len); } @Override public void put(long offset, long[] src, int off, int len) { ptr.put(base + offset, src, off, len); } @Override public void get(long offset, float[] dst, int off, int len) { ptr.get(base + offset, dst, off, len); } @Override public void put(long offset, float[] src, int off, int len) { ptr.put(base + offset, src, off, len); } @Override public void get(long offset, double[] dst, int off, int len) { ptr.get(base + offset, dst, off, len); } @Override public void put(long offset, double[] src, int off, int len) { ptr.put(base + offset, src, off, len); } @Override public int indexOf(long offset, byte value, int maxlen) { return ptr.indexOf(base + offset, value, maxlen); } @Override public void setMemory(long offset, long size, byte value) { ptr.setMemory(base + offset, size, value); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/SigType.java000066400000000000000000000037351316720554100244730ustar00rootroot00000000000000/* * Copyright (C) 2013 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider; import jnr.ffi.NativeType; import jnr.ffi.mapper.SignatureType; import java.lang.annotation.Annotation; import java.lang.reflect.Type; import java.util.Collection; /** * */ abstract public class SigType implements SignatureType { private final Class javaType, convertedType; private final Collection annotations; private final NativeType nativeType; public SigType(Class javaType, NativeType nativeType, Collection annotations, Class convertedType) { this.javaType = javaType; this.annotations = annotations; this.convertedType = convertedType; this.nativeType = nativeType; } public final Class getDeclaredType() { return javaType; } public final Class effectiveJavaType() { return convertedType; } public final Collection annotations() { return annotations; } public final Collection getAnnotations() { return annotations; } @Override public Type getGenericType() { return getDeclaredType(); } public final String toString() { return String.format("declared: %s, effective: %s, native: %s", getDeclaredType(), effectiveJavaType(), getNativeType()); } public NativeType getNativeType() { return nativeType; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/ToNativeType.java000066400000000000000000000032111316720554100254670ustar00rootroot00000000000000/* * Copyright (C) 2013 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider; import jnr.ffi.NativeType; import jnr.ffi.mapper.ToNativeContext; import jnr.ffi.mapper.ToNativeConverter; import java.lang.annotation.Annotation; import java.util.Collection; /** * */ public class ToNativeType extends SigType implements jnr.ffi.mapper.ToNativeType { private final ToNativeConverter toNativeConverter; private final ToNativeContext toNativeContext; public ToNativeType(Class javaType, NativeType nativeType, Collection annotations, ToNativeConverter toNativeConverter, ToNativeContext toNativeContext) { super(javaType, nativeType, annotations, toNativeConverter != null ? toNativeConverter.nativeType() : javaType); this.toNativeConverter = toNativeConverter; this.toNativeContext = toNativeContext; } @Override public final ToNativeConverter getToNativeConverter() { return toNativeConverter; } public ToNativeContext getToNativeContext() { return toNativeContext; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/converters/000077500000000000000000000000001316720554100244265ustar00rootroot00000000000000BoxedBooleanArrayParameterConverter.java000066400000000000000000000056671316720554100343210ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/converters/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.converters; import jnr.ffi.mapper.ToNativeContext; import jnr.ffi.mapper.ToNativeConverter; import jnr.ffi.provider.ParameterFlags; /** * Converts a Boolean[] array to a primitive boolean[] array parameter */ @ToNativeConverter.NoContext @ToNativeConverter.Cacheable public class BoxedBooleanArrayParameterConverter implements ToNativeConverter { private static final ToNativeConverter IN = new BoxedBooleanArrayParameterConverter(ParameterFlags.IN); private static final ToNativeConverter OUT = new BoxedBooleanArrayParameterConverter.Out(ParameterFlags.OUT); private static final ToNativeConverter INOUT = new BoxedBooleanArrayParameterConverter.Out(ParameterFlags.IN | ParameterFlags.OUT); private final int parameterFlags; public static ToNativeConverter getInstance(ToNativeContext toNativeContext) { int parameterFlags = ParameterFlags.parse(toNativeContext.getAnnotations()); return ParameterFlags.isOut(parameterFlags) ? ParameterFlags.isIn(parameterFlags) ? INOUT : OUT : IN; } public BoxedBooleanArrayParameterConverter(int parameterFlags) { this.parameterFlags = parameterFlags; } @Override public boolean[] toNative(Boolean[] array, ToNativeContext context) { if (array == null) { return null; } boolean[] primitive = new boolean[array.length]; if (ParameterFlags.isIn(parameterFlags)) { for (int i = 0; i < array.length; i++) { primitive[i] = array[i] != null ? array[i] : false; } } return primitive; } public static final class Out extends BoxedBooleanArrayParameterConverter implements PostInvocation { Out(int parameterFlags) { super(parameterFlags); } @Override public void postInvoke(Boolean[] array, boolean[] primitive, ToNativeContext context) { if (array != null && primitive != null) { for (int i = 0; i < array.length; i++) { array[i] = primitive[i]; } } } } @Override public Class nativeType() { return boolean[].class; } } BoxedByteArrayParameterConverter.java000066400000000000000000000055161316720554100336360ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/converters/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.converters; import jnr.ffi.mapper.ToNativeContext; import jnr.ffi.mapper.ToNativeConverter; import jnr.ffi.provider.ParameterFlags; /** * Converts a Byte[] array to a byte[] array parameter */ @ToNativeConverter.NoContext @ToNativeConverter.Cacheable public class BoxedByteArrayParameterConverter implements ToNativeConverter { private static final ToNativeConverter IN = new BoxedByteArrayParameterConverter(ParameterFlags.IN); private static final ToNativeConverter OUT = new BoxedByteArrayParameterConverter.Out(ParameterFlags.OUT); private static final ToNativeConverter INOUT = new BoxedByteArrayParameterConverter.Out(ParameterFlags.IN | ParameterFlags.OUT); private final int parameterFlags; public static ToNativeConverter getInstance(ToNativeContext toNativeContext) { int parameterFlags = ParameterFlags.parse(toNativeContext.getAnnotations()); return ParameterFlags.isOut(parameterFlags) ? ParameterFlags.isIn(parameterFlags) ? INOUT : OUT : IN; } BoxedByteArrayParameterConverter(int parameterFlags) { this.parameterFlags = parameterFlags; } @Override public byte[] toNative(Byte[] array, ToNativeContext context) { if (array == null) { return null; } byte[] primitive = new byte[array.length]; if (ParameterFlags.isIn(parameterFlags)) { for (int i = 0; i < array.length; i++) { primitive[i] = array[i] != null ? array[i] : 0; } } return primitive; } public static final class Out extends BoxedByteArrayParameterConverter implements PostInvocation { Out(int parameterFlags) { super(parameterFlags); } @Override public void postInvoke(Byte[] array, byte[] primitive, ToNativeContext context) { if (array != null && primitive != null) { for (int i = 0; i < array.length; i++) { array[i] = primitive[i]; } } } } @Override public Class nativeType() { return byte[].class; } } BoxedDoubleArrayParameterConverter.java000066400000000000000000000056071316720554100341460ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/converters/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.converters; import jnr.ffi.mapper.ToNativeContext; import jnr.ffi.mapper.ToNativeConverter; import jnr.ffi.provider.ParameterFlags; /** * Converts a Double[] array to a double[] array parameter */ @ToNativeConverter.NoContext @ToNativeConverter.Cacheable public class BoxedDoubleArrayParameterConverter implements ToNativeConverter { private static final ToNativeConverter IN = new BoxedDoubleArrayParameterConverter(ParameterFlags.IN); private static final ToNativeConverter OUT = new BoxedDoubleArrayParameterConverter.Out(ParameterFlags.OUT); private static final ToNativeConverter INOUT = new BoxedDoubleArrayParameterConverter.Out(ParameterFlags.IN | ParameterFlags.OUT); private final int parameterFlags; public static ToNativeConverter getInstance(ToNativeContext toNativeContext) { int parameterFlags = ParameterFlags.parse(toNativeContext.getAnnotations()); return ParameterFlags.isOut(parameterFlags) ? ParameterFlags.isIn(parameterFlags) ? INOUT : OUT : IN; } BoxedDoubleArrayParameterConverter(int parameterFlags) { this.parameterFlags = parameterFlags; } @Override public double[] toNative(Double[] array, ToNativeContext context) { if (array == null) { return null; } double[] primitive = new double[array.length]; if (ParameterFlags.isIn(parameterFlags)) { for (int i = 0; i < array.length; i++) { primitive[i] = array[i] != null ? array[i] : 0; } } return primitive; } public static final class Out extends BoxedDoubleArrayParameterConverter implements PostInvocation { Out(int parameterFlags) { super(parameterFlags); } @Override public void postInvoke(Double[] array, double[] primitive, ToNativeContext context) { if (array != null && primitive != null) { for (int i = 0; i < array.length; i++) { array[i] = primitive[i]; } } } } @Override public Class nativeType() { return double[].class; } } BoxedFloatArrayParameterConverter.java000066400000000000000000000055531316720554100340010ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/converters/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.converters; import jnr.ffi.mapper.ToNativeContext; import jnr.ffi.mapper.ToNativeConverter; import jnr.ffi.provider.ParameterFlags; /** * Converts a Float[] array to a float[] array parameter */ @ToNativeConverter.NoContext @ToNativeConverter.Cacheable public class BoxedFloatArrayParameterConverter implements ToNativeConverter { private static final ToNativeConverter IN = new BoxedFloatArrayParameterConverter(ParameterFlags.IN); private static final ToNativeConverter OUT = new BoxedFloatArrayParameterConverter.Out(ParameterFlags.OUT); private static final ToNativeConverter INOUT = new BoxedFloatArrayParameterConverter.Out(ParameterFlags.IN | ParameterFlags.OUT); private final int parameterFlags; public static ToNativeConverter getInstance(ToNativeContext toNativeContext) { int parameterFlags = ParameterFlags.parse(toNativeContext.getAnnotations()); return ParameterFlags.isOut(parameterFlags) ? ParameterFlags.isIn(parameterFlags) ? INOUT : OUT : IN; } BoxedFloatArrayParameterConverter(int parameterFlags) { this.parameterFlags = parameterFlags; } @Override public float[] toNative(Float[] array, ToNativeContext context) { if (array == null) { return null; } float[] primitive = new float[array.length]; if (ParameterFlags.isIn(parameterFlags)) { for (int i = 0; i < array.length; i++) { primitive[i] = array[i] != null ? array[i] : 0; } } return primitive; } public static final class Out extends BoxedFloatArrayParameterConverter implements PostInvocation { Out(int parameterFlags) { super(parameterFlags); } @Override public void postInvoke(Float[] array, float[] primitive, ToNativeContext context) { if (array != null && primitive != null) { for (int i = 0; i < array.length; i++) { array[i] = primitive[i]; } } } } @Override public Class nativeType() { return float[].class; } } BoxedIntegerArrayParameterConverter.java000066400000000000000000000056001316720554100343220ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/converters/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.converters; import jnr.ffi.mapper.ToNativeContext; import jnr.ffi.mapper.ToNativeConverter; import jnr.ffi.provider.ParameterFlags; /** * Converts a Integer[] array to a primitive int[] array parameter */ @ToNativeConverter.NoContext @ToNativeConverter.Cacheable public class BoxedIntegerArrayParameterConverter implements ToNativeConverter { private static final ToNativeConverter IN = new BoxedIntegerArrayParameterConverter(ParameterFlags.IN); private static final ToNativeConverter OUT = new BoxedIntegerArrayParameterConverter.Out(ParameterFlags.OUT); private static final ToNativeConverter INOUT = new BoxedIntegerArrayParameterConverter.Out(ParameterFlags.IN | ParameterFlags.OUT); private final int parameterFlags; public static ToNativeConverter getInstance(ToNativeContext toNativeContext) { int parameterFlags = ParameterFlags.parse(toNativeContext.getAnnotations()); return ParameterFlags.isOut(parameterFlags) ? ParameterFlags.isIn(parameterFlags) ? INOUT : OUT : IN; } public BoxedIntegerArrayParameterConverter(int parameterFlags) { this.parameterFlags = parameterFlags; } @Override public int[] toNative(Integer[] array, ToNativeContext context) { if (array == null) { return null; } int[] primitive = new int[array.length]; if (ParameterFlags.isIn(parameterFlags)) { for (int i = 0; i < array.length; i++) { primitive[i] = array[i] != null ? array[i] : 0; } } return primitive; } public static final class Out extends BoxedIntegerArrayParameterConverter implements PostInvocation { Out(int parameterFlags) { super(parameterFlags); } @Override public void postInvoke(Integer[] array, int[] primitive, ToNativeContext context) { if (array != null && primitive != null) { for (int i = 0; i < array.length; i++) { array[i] = primitive[i]; } } } } @Override public Class nativeType() { return int[].class; } } BoxedLong32ArrayParameterConverter.java000066400000000000000000000055611316720554100337770ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/converters/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.converters; import jnr.ffi.mapper.ToNativeContext; import jnr.ffi.mapper.ToNativeConverter; import jnr.ffi.provider.ParameterFlags; /** * Converts a Long[] array to a primitive int[] array parameter */ @ToNativeConverter.NoContext @ToNativeConverter.Cacheable public class BoxedLong32ArrayParameterConverter implements ToNativeConverter { private static final ToNativeConverter IN = new BoxedLong32ArrayParameterConverter(ParameterFlags.IN); private static final ToNativeConverter OUT = new BoxedLong32ArrayParameterConverter.Out(ParameterFlags.OUT); private static final ToNativeConverter INOUT = new BoxedLong32ArrayParameterConverter.Out(ParameterFlags.IN | ParameterFlags.OUT); private final int parameterFlags; public static ToNativeConverter getInstance(ToNativeContext toNativeContext) { int parameterFlags = ParameterFlags.parse(toNativeContext.getAnnotations()); return ParameterFlags.isOut(parameterFlags) ? ParameterFlags.isIn(parameterFlags) ? INOUT : OUT : IN; } public BoxedLong32ArrayParameterConverter(int parameterFlags) { this.parameterFlags = parameterFlags; } @Override public int[] toNative(Long[] array, ToNativeContext context) { if (array == null) { return null; } int[] primitive = new int[array.length]; if (ParameterFlags.isIn(parameterFlags)) { for (int i = 0; i < array.length; i++) { primitive[i] = array[i] != null ? array[i].intValue() : 0; } } return primitive; } public static final class Out extends BoxedLong32ArrayParameterConverter implements PostInvocation { Out(int parameterFlags) { super(parameterFlags); } @Override public void postInvoke(Long[] array, int[] primitive, ToNativeContext context) { if (array != null && primitive != null) { for (int i = 0; i < array.length; i++) { array[i] = (long) primitive[i]; } } } } @Override public Class nativeType() { return int[].class; } } BoxedLong64ArrayParameterConverter.java000066400000000000000000000056451316720554100340070ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/converters/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.converters; import jnr.ffi.annotations.LongLong; import jnr.ffi.mapper.ToNativeContext; import jnr.ffi.mapper.ToNativeConverter; import jnr.ffi.provider.ParameterFlags; /** * Converts a Long[] array to a primitive 64bit long[] array parameter */ @ToNativeConverter.NoContext @ToNativeConverter.Cacheable public class BoxedLong64ArrayParameterConverter implements ToNativeConverter { private static final ToNativeConverter IN = new BoxedLong64ArrayParameterConverter(ParameterFlags.IN); private static final ToNativeConverter OUT = new BoxedLong64ArrayParameterConverter.Out(ParameterFlags.OUT); private static final ToNativeConverter INOUT = new BoxedLong64ArrayParameterConverter.Out(ParameterFlags.IN | ParameterFlags.OUT); private final int parameterFlags; public static ToNativeConverter getInstance(ToNativeContext toNativeContext) { int parameterFlags = ParameterFlags.parse(toNativeContext.getAnnotations()); return ParameterFlags.isOut(parameterFlags) ? ParameterFlags.isIn(parameterFlags) ? INOUT : OUT : IN; } public BoxedLong64ArrayParameterConverter(int parameterFlags) { this.parameterFlags = parameterFlags; } @Override public long[] toNative(Long[] array, ToNativeContext context) { if (array == null) { return null; } long[] primitive = new long[array.length]; if (ParameterFlags.isIn(parameterFlags)) { for (int i = 0; i < array.length; i++) { primitive[i] = array[i] != null ? array[i] : 0; } } return primitive; } public static final class Out extends BoxedLong64ArrayParameterConverter implements PostInvocation { Out(int parameterFlags) { super(parameterFlags); } @Override public void postInvoke(Long[] array, long[] primitive, ToNativeContext context) { if (array != null && primitive != null) { for (int i = 0; i < array.length; i++) { array[i] = primitive[i]; } } } } @Override @LongLong public Class nativeType() { return long[].class; } } BoxedShortArrayParameterConverter.java000066400000000000000000000055731316720554100340350ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/converters/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.converters; import jnr.ffi.mapper.ToNativeContext; import jnr.ffi.mapper.ToNativeConverter; import jnr.ffi.provider.ParameterFlags; /** * Converts a Short[] array to a primitive short[] array parameter */ @ToNativeConverter.NoContext @ToNativeConverter.Cacheable public class BoxedShortArrayParameterConverter implements ToNativeConverter { private static final ToNativeConverter IN = new BoxedShortArrayParameterConverter(ParameterFlags.IN); private static final ToNativeConverter OUT = new BoxedShortArrayParameterConverter.Out(ParameterFlags.OUT); private static final ToNativeConverter INOUT = new BoxedShortArrayParameterConverter.Out(ParameterFlags.IN | ParameterFlags.OUT); private final int parameterFlags; public static ToNativeConverter getInstance(ToNativeContext toNativeContext) { int parameterFlags = ParameterFlags.parse(toNativeContext.getAnnotations()); return ParameterFlags.isOut(parameterFlags) ? ParameterFlags.isIn(parameterFlags) ? INOUT : OUT : IN; } public BoxedShortArrayParameterConverter(int parameterFlags) { this.parameterFlags = parameterFlags; } @Override public short[] toNative(Short[] array, ToNativeContext context) { if (array == null) { return null; } short[] primitive = new short[array.length]; if (ParameterFlags.isIn(parameterFlags)) { for (int i = 0; i < array.length; i++) { primitive[i] = array[i] != null ? array[i] : 0; } } return primitive; } public static final class Out extends BoxedShortArrayParameterConverter implements PostInvocation { Out(int parameterFlags) { super(parameterFlags); } @Override public void postInvoke(Short[] array, short[] primitive, ToNativeContext context) { if (array != null && primitive != null) { for (int i = 0; i < array.length; i++) { array[i] = primitive[i]; } } } } @Override public Class nativeType() { return short[].class; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/converters/ByReferenceParameterConverter.java000066400000000000000000000054511316720554100332200ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.converters; import jnr.ffi.Memory; import jnr.ffi.Pointer; import jnr.ffi.byref.ByReference; import jnr.ffi.mapper.ToNativeContext; import jnr.ffi.mapper.ToNativeConverter; import jnr.ffi.provider.ParameterFlags; /** * */ @ToNativeConverter.Cacheable public class ByReferenceParameterConverter implements ToNativeConverter { private static final ToNativeConverter IN = new ByReferenceParameterConverter(ParameterFlags.IN); private static final ToNativeConverter OUT = new ByReferenceParameterConverter.Out(ParameterFlags.OUT); private static final ToNativeConverter INOUT = new ByReferenceParameterConverter.Out(ParameterFlags.IN | ParameterFlags.OUT); private final int parameterFlags; private ByReferenceParameterConverter(int parameterFlags) { this.parameterFlags = parameterFlags; } public static ToNativeConverter getInstance(ToNativeContext toNativeContext) { int parameterFlags = ParameterFlags.parse(toNativeContext.getAnnotations()); return ParameterFlags.isOut(parameterFlags) ? ParameterFlags.isIn(parameterFlags) ? INOUT : OUT : IN; } public Pointer toNative(ByReference value, ToNativeContext context) { if (value == null) { return null; } Pointer memory = Memory.allocate(context.getRuntime(), value.nativeSize(context.getRuntime())); if (ParameterFlags.isIn(parameterFlags)) { value.toNative(context.getRuntime(), memory, 0); } return memory; } public Class nativeType() { return Pointer.class; } public static final class Out extends ByReferenceParameterConverter implements ToNativeConverter.PostInvocation { public Out(int parameterFlags) { super(parameterFlags); } public void postInvoke(ByReference byReference, Pointer pointer, ToNativeContext context) { if (byReference != null && pointer != null) { byReference.fromNative(context.getRuntime(), pointer, 0); } } } } CharSequenceArrayParameterConverter.java000066400000000000000000000112051316720554100343070ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/converters/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.converters; import jnr.ffi.*; import jnr.ffi.Runtime; import jnr.ffi.mapper.ToNativeContext; import jnr.ffi.mapper.ToNativeConverter; import jnr.ffi.provider.InAccessibleMemoryIO; import jnr.ffi.provider.ParameterFlags; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; import java.util.ArrayList; import java.util.List; /** * Converts a CharSequence[] array to a Pointer parameter */ @ToNativeConverter.NoContext @ToNativeConverter.Cacheable public class CharSequenceArrayParameterConverter implements ToNativeConverter { private final jnr.ffi.Runtime runtime; private final int parameterFlags; public static ToNativeConverter getInstance(ToNativeContext toNativeContext) { int parameterFlags = ParameterFlags.parse(toNativeContext.getAnnotations()); return !ParameterFlags.isOut(parameterFlags) ? new CharSequenceArrayParameterConverter(toNativeContext.getRuntime(), parameterFlags) : new CharSequenceArrayParameterConverter.Out(toNativeContext.getRuntime(), parameterFlags); } CharSequenceArrayParameterConverter(jnr.ffi.Runtime runtime, int parameterFlags) { this.runtime = runtime; this.parameterFlags = parameterFlags; } @Override public Pointer toNative(CharSequence[] array, ToNativeContext context) { if (array == null) { return null; } StringArray stringArray = StringArray.allocate(runtime, array.length + 1); if (ParameterFlags.isIn(parameterFlags)) { for (int i = 0; i < array.length; i++) { stringArray.put(i, array[i]); } } return stringArray; } public static final class Out extends CharSequenceArrayParameterConverter implements PostInvocation { Out(jnr.ffi.Runtime runtime, int parameterFlags) { super(runtime, parameterFlags); } @Override public void postInvoke(CharSequence[] array, Pointer primitive, ToNativeContext context) { if (array != null && primitive != null) { StringArray stringArray = (StringArray) primitive; for (int i = 0; i < array.length; i++) { array[i] = stringArray.get(i); } } } } @Override public Class nativeType() { return Pointer.class; } private final static class StringArray extends InAccessibleMemoryIO { private final Pointer memory; private List stringMemory; private final Charset charset = Charset.defaultCharset(); private StringArray(Runtime runtime, Pointer memory, int capacity) { super(runtime, memory.address(), memory.isDirect()); this.memory = memory; this.stringMemory = new ArrayList(capacity); } String get(int idx) { Pointer ptr = memory.getPointer(idx * getRuntime().addressSize()); return ptr != null ? ptr.getString(0) : null; } void put(int idx, CharSequence str) { if (str == null) { memory.putAddress(idx * getRuntime().addressSize(), 0L); stringMemory.add(idx, null); } else { ByteBuffer buf = charset.encode(CharBuffer.wrap(str)); Pointer ptr = Memory.allocateDirect(getRuntime(), buf.remaining() + 4, true); ptr.put(0, buf.array(), 0, buf.remaining()); stringMemory.add(idx, ptr); memory.putPointer(idx * getRuntime().addressSize(), ptr); } } @Override public long size() { return memory.size(); } static StringArray allocate(Runtime runtime, int capacity) { Pointer memory = Memory.allocateDirect(runtime, capacity * runtime.addressSize()); return new StringArray(runtime, memory, capacity); } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/converters/CharSequenceParameterConverter.java000066400000000000000000000116611316720554100333750ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.converters; import jnr.ffi.annotations.Encoding; import jnr.ffi.annotations.In; import jnr.ffi.annotations.NulTerminate; import jnr.ffi.mapper.MethodParameterContext; import jnr.ffi.mapper.ToNativeContext; import jnr.ffi.mapper.ToNativeConverter; import java.lang.annotation.Annotation; import java.lang.ref.Reference; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.*; import java.util.Arrays; import java.util.Collection; import static jnr.ffi.provider.converters.StringUtil.getEncoder; import static jnr.ffi.provider.converters.StringUtil.throwException; /** * Converts a CharSequence (e.g. String) to a primitive ByteBuffer array parameter */ @ToNativeConverter.NoContext @ToNativeConverter.Cacheable public class CharSequenceParameterConverter implements ToNativeConverter { private static final ToNativeConverter DEFAULT = new CharSequenceParameterConverter(Charset.defaultCharset()); private final ThreadLocal> localEncoder = new ThreadLocal>(); private final Charset charset; public static ToNativeConverter getInstance(Charset charset, ToNativeContext toNativeContext) { return Charset.defaultCharset().equals(charset) ? DEFAULT : new CharSequenceParameterConverter(charset); } public static ToNativeConverter getInstance(ToNativeContext toNativeContext) { Charset charset = Charset.defaultCharset(); if (toNativeContext instanceof MethodParameterContext) { // See if the interface class has a global @Encoding declaration Charset cs = getEncodingCharset(Arrays.asList(((MethodParameterContext) toNativeContext).getMethod().getDeclaringClass().getAnnotations())); if (cs != null) { charset = cs; } // Allow each method to override the default cs = getEncodingCharset(Arrays.asList(((MethodParameterContext) toNativeContext).getMethod().getAnnotations())); if (cs != null) { charset = cs; } } // Override on a per-parameter basis Charset cs = getEncodingCharset(toNativeContext.getAnnotations()); if (cs != null) { charset = cs; } return getInstance(charset, toNativeContext); } private static Charset getEncodingCharset(Collection annotations) { for (Annotation a : annotations) { if (a instanceof Encoding) { return Charset.forName(((Encoding) a).value()); } } return null; } private CharSequenceParameterConverter(Charset charset) { this.charset = charset; } @Override public ByteBuffer toNative(CharSequence string, ToNativeContext context) { if (string == null) { return null; } CharsetEncoder encoder = getEncoder(charset, localEncoder); ByteBuffer byteBuffer = ByteBuffer.wrap(new byte[(int) (string.length() * encoder.averageBytesPerChar()) + 4]); CharBuffer charBuffer = CharBuffer.wrap(string); encoder.reset(); while (charBuffer.hasRemaining()) { CoderResult result = encoder.encode(charBuffer, byteBuffer, true); if (result.isUnderflow() && (result = encoder.flush(byteBuffer)).isUnderflow()) { break; } else if (result.isOverflow()) { // Output buffer is full; expand and continue encoding byteBuffer = grow(byteBuffer); } else { throwException(result); } } // ensure native memory is NUL terminated (assume max wchar_t 4 byte termination needed) if (byteBuffer.remaining() <= 4) byteBuffer = grow(byteBuffer); byteBuffer.position(byteBuffer.position() + 4); byteBuffer.flip(); return byteBuffer; } private static ByteBuffer grow(ByteBuffer oldBuffer) { ByteBuffer buf = ByteBuffer.wrap(new byte[oldBuffer.capacity() * 2]); oldBuffer.flip(); buf.put(oldBuffer); return buf; } @Override @In @NulTerminate public Class nativeType() { return ByteBuffer.class; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/converters/EnumConverter.java000066400000000000000000000030241316720554100300640ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.converters; import jnr.ffi.mapper.*; import jnr.ffi.util.EnumMapper; @ToNativeConverter.NoContext @FromNativeConverter.NoContext @ToNativeConverter.Cacheable @FromNativeConverter.Cacheable public final class EnumConverter implements DataConverter { private final EnumMapper mapper; public static EnumConverter getInstance(Class enumClass) { return new EnumConverter(enumClass); } private EnumConverter(Class enumClass) { this.mapper = EnumMapper.getInstance(enumClass); } public Enum fromNative(Integer nativeValue, FromNativeContext context) { return mapper.valueOf(nativeValue); } public Integer toNative(Enum value, ToNativeContext context) { return mapper.integerValue(value); } public Class nativeType() { return Integer.class; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/converters/EnumSetConverter.java000066400000000000000000000062611316720554100305460ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.converters; import jnr.ffi.mapper.*; import jnr.ffi.util.EnumMapper; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.util.EnumSet; import java.util.Set; @FromNativeConverter.Cacheable @ToNativeConverter.Cacheable public final class EnumSetConverter implements DataConverter, Integer> { private final Class enumClass; private final EnumMapper enumMapper; private final EnumSet allValues; private EnumSetConverter(Class enumClass) { this.enumClass = enumClass; this.enumMapper = EnumMapper.getInstance(enumClass); this.allValues = EnumSet.allOf(enumClass); } public static ToNativeConverter, Integer> getToNativeConverter(SignatureType type, ToNativeContext toNativeContext) { return getInstance(type.getGenericType()); } public static FromNativeConverter, Integer> getFromNativeConverter(SignatureType type, FromNativeContext fromNativeContext) { return getInstance(type.getGenericType()); } @SuppressWarnings("unchecked") private static EnumSetConverter getInstance(Type parameterizedType) { if (!(parameterizedType instanceof ParameterizedType)) { return null; } if (((ParameterizedType) parameterizedType).getActualTypeArguments().length < 1) { return null; } Type enumType = ((ParameterizedType) parameterizedType).getActualTypeArguments()[0]; if (!(enumType instanceof Class) || !Enum.class.isAssignableFrom((Class) enumType)) { return null; } return new EnumSetConverter(((Class) enumType).asSubclass(Enum.class)); } @Override @SuppressWarnings("unchecked") public Set fromNative(Integer nativeValue, FromNativeContext context) { EnumSet enums = EnumSet.noneOf(enumClass); for (Enum e : allValues) { int enumValue = enumMapper.intValue(e); if ((nativeValue & enumValue) == enumValue) { enums.add(e); } } return enums; } @Override @SuppressWarnings("unchecked") public Integer toNative(Set value, ToNativeContext context) { int intValue = 0; for (Enum e : value) { intValue |= enumMapper.intValue(e); } return intValue; } @Override public Class nativeType() { return Integer.class; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/converters/Long32ArrayParameterConverter.java000066400000000000000000000054511316720554100330720ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.converters; import jnr.ffi.mapper.ToNativeContext; import jnr.ffi.mapper.ToNativeConverter; import jnr.ffi.provider.ParameterFlags; /** * Converts a long[] array to a primitive int[] array parameter */ @ToNativeConverter.NoContext @ToNativeConverter.Cacheable public class Long32ArrayParameterConverter implements ToNativeConverter { private static final Long32ArrayParameterConverter IN = new Long32ArrayParameterConverter(ParameterFlags.IN); private static final Long32ArrayParameterConverter OUT = new Long32ArrayParameterConverter.Out(ParameterFlags.OUT); private static final Long32ArrayParameterConverter INOUT = new Long32ArrayParameterConverter.Out(ParameterFlags.IN | ParameterFlags.OUT); private final int parameterFlags; public static ToNativeConverter getInstance(ToNativeContext toNativeContext) { int parameterFlags = ParameterFlags.parse(toNativeContext.getAnnotations()); return ParameterFlags.isOut(parameterFlags) ? ParameterFlags.isIn(parameterFlags) ? INOUT : OUT : IN; } private Long32ArrayParameterConverter(int parameterFlags) { this.parameterFlags = parameterFlags; } @Override public int[] toNative(long[] array, ToNativeContext context) { if (array == null) { return null; } int[] primitive = new int[array.length]; if (ParameterFlags.isIn(parameterFlags)) { for (int i = 0; i < array.length; i++) { primitive[i] = (int) array[i]; } } return primitive; } public static final class Out extends Long32ArrayParameterConverter implements PostInvocation { Out(int parameterFlags) { super(parameterFlags); } @Override public void postInvoke(long[] array, int[] primitive, ToNativeContext context) { if (array != null && primitive != null) { for (int i = 0; i < array.length; i++) { array[i] = primitive[i]; } } } } @Override public Class nativeType() { return int[].class; } } NativeLong32ArrayParameterConverter.java000066400000000000000000000057161316720554100341660ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/converters/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.converters; import jnr.ffi.NativeLong; import jnr.ffi.mapper.ToNativeContext; import jnr.ffi.mapper.ToNativeConverter; import jnr.ffi.provider.ParameterFlags; /** * Converts a NativeLong[] array to a primitive int[] array parameter */ @ToNativeConverter.NoContext @ToNativeConverter.Cacheable public class NativeLong32ArrayParameterConverter implements ToNativeConverter { private static final ToNativeConverter IN = new NativeLong32ArrayParameterConverter(ParameterFlags.IN); private static final ToNativeConverter OUT = new NativeLong32ArrayParameterConverter.Out(ParameterFlags.OUT); private static final ToNativeConverter INOUT = new NativeLong32ArrayParameterConverter.Out(ParameterFlags.IN | ParameterFlags.OUT); private final int parameterFlags; public static ToNativeConverter getInstance(ToNativeContext toNativeContext) { int parameterFlags = ParameterFlags.parse(toNativeContext.getAnnotations()); return ParameterFlags.isOut(parameterFlags) ? ParameterFlags.isIn(parameterFlags) ? INOUT : OUT : IN; } NativeLong32ArrayParameterConverter(int parameterFlags) { this.parameterFlags = parameterFlags; } @Override public int[] toNative(NativeLong[] array, ToNativeContext context) { if (array == null) { return null; } int[] primitive = new int[array.length]; if (ParameterFlags.isIn(parameterFlags)) { for (int i = 0; i < array.length; i++) { primitive[i] = array[i] != null ? array[i].intValue() : 0; } } return primitive; } public static final class Out extends NativeLong32ArrayParameterConverter implements PostInvocation { Out(int parameterFlags) { super(parameterFlags); } @Override public void postInvoke(NativeLong[] array, int[] primitive, ToNativeContext context) { if (array != null && primitive != null) { for (int i = 0; i < array.length; i++) { array[i] = NativeLong.valueOf(primitive[i]); } } } } @Override public Class nativeType() { return int[].class; } } NativeLong64ArrayParameterConverter.java000066400000000000000000000060261316720554100341660ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/converters/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.converters; import jnr.ffi.NativeLong; import jnr.ffi.annotations.LongLong; import jnr.ffi.mapper.ToNativeContext; import jnr.ffi.mapper.ToNativeConverter; import jnr.ffi.provider.ParameterFlags; /** * Converts a NativeLong[] array to a primitive long[] array parameter */ @ToNativeConverter.NoContext @ToNativeConverter.Cacheable public class NativeLong64ArrayParameterConverter implements ToNativeConverter { private static final ToNativeConverter IN = new NativeLong64ArrayParameterConverter(ParameterFlags.IN); private static final ToNativeConverter OUT = new NativeLong64ArrayParameterConverter.Out(ParameterFlags.OUT); private static final ToNativeConverter INOUT = new NativeLong64ArrayParameterConverter.Out(ParameterFlags.IN | ParameterFlags.OUT); private final int parameterFlags; public static ToNativeConverter getInstance(ToNativeContext toNativeContext) { int parameterFlags = ParameterFlags.parse(toNativeContext.getAnnotations()); return ParameterFlags.isOut(parameterFlags) ? ParameterFlags.isIn(parameterFlags) ? INOUT : OUT : IN; } private NativeLong64ArrayParameterConverter(int parameterFlags) { this.parameterFlags = parameterFlags; } @Override public long[] toNative(NativeLong[] array, ToNativeContext context) { if (array == null) { return null; } long[] primitive = new long[array.length]; if (ParameterFlags.isIn(parameterFlags)) { for (int i = 0; i < array.length; i++) { primitive[i] = array[i] != null ? array[i].intValue() : 0; } } return primitive; } public static final class Out extends NativeLong64ArrayParameterConverter implements PostInvocation { Out(int parameterFlags) { super(parameterFlags); } @Override public void postInvoke(NativeLong[] array, long[] primitive, ToNativeContext context) { if (array != null && primitive != null) { for (int i = 0; i < array.length; i++) { array[i] = NativeLong.valueOf(primitive[i]); } } } } @Override @LongLong public Class nativeType() { return long[].class; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/converters/NativeLongConverter.java000066400000000000000000000027611316720554100312350ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.converters; import jnr.ffi.NativeLong; /** * Parameter and return type support for the old NativeLong type */ import jnr.ffi.mapper.*; @ToNativeConverter.NoContext @FromNativeConverter.NoContext @ToNativeConverter.Cacheable @FromNativeConverter.Cacheable public final class NativeLongConverter extends AbstractDataConverter { private static final DataConverter INSTANCE = new NativeLongConverter(); public static DataConverter getInstance() { return INSTANCE; } public Class nativeType() { return Long.class; } public Long toNative(NativeLong value, ToNativeContext toNativeContext) { return value.longValue(); } public NativeLong fromNative(Long value, FromNativeContext fromNativeContext) { return NativeLong.valueOf(value); } } Pointer32ArrayParameterConverter.java000066400000000000000000000062311316720554100335310ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/converters/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.converters; import jnr.ffi.*; import jnr.ffi.mapper.ToNativeContext; import jnr.ffi.mapper.ToNativeConverter; import jnr.ffi.provider.MemoryManager; import jnr.ffi.provider.ParameterFlags; /** * Converts a Pointer[] array to a int[] array parameter */ @ToNativeConverter.NoContext @ToNativeConverter.Cacheable public class Pointer32ArrayParameterConverter implements ToNativeConverter { protected final jnr.ffi.Runtime runtime; protected final int parameterFlags; public static ToNativeConverter getInstance(ToNativeContext toNativeContext) { int parameterFlags = ParameterFlags.parse(toNativeContext.getAnnotations()); return !ParameterFlags.isOut(parameterFlags) ? new Pointer32ArrayParameterConverter(toNativeContext.getRuntime(), parameterFlags) : new Pointer32ArrayParameterConverter.Out(toNativeContext.getRuntime(), parameterFlags); } Pointer32ArrayParameterConverter(jnr.ffi.Runtime runtime, int parameterFlags) { this.runtime = runtime; this.parameterFlags = parameterFlags; } @Override public Class nativeType() { return int[].class; } @Override public int[] toNative(Pointer[] pointers, ToNativeContext context) { if (pointers == null) { return null; } int[] primitive = new int[pointers.length]; if (ParameterFlags.isIn(parameterFlags)) { for (int i = 0; i < pointers.length; i++) { if (pointers[i] != null && !pointers[i].isDirect()) { throw new IllegalArgumentException("invalid pointer in array at index " + i); } primitive[i] = pointers[i] != null ? (int) pointers[i].address() : 0; } } return primitive; } public static final class Out extends Pointer32ArrayParameterConverter implements ToNativeConverter.PostInvocation { public Out(jnr.ffi.Runtime runtime, int parameterFlags) { super(runtime, parameterFlags); } @Override public void postInvoke(Pointer[] pointers, int[] primitive, ToNativeContext context) { if (pointers != null && primitive != null && ParameterFlags.isOut(parameterFlags)) { MemoryManager mm = runtime.getMemoryManager(); for (int i = 0; i < pointers.length; i++) { pointers[i] = mm.newPointer(primitive[i]); } } } } } Pointer64ArrayParameterConverter.java000066400000000000000000000062511316720554100335400ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/converters/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.converters; import jnr.ffi.Pointer; import jnr.ffi.annotations.LongLong; import jnr.ffi.mapper.ToNativeContext; import jnr.ffi.mapper.ToNativeConverter; import jnr.ffi.provider.MemoryManager; import jnr.ffi.provider.ParameterFlags; /** * Converts a Pointer[] array to a long[] array parameter */ @ToNativeConverter.NoContext @ToNativeConverter.Cacheable public class Pointer64ArrayParameterConverter implements ToNativeConverter { protected final jnr.ffi.Runtime runtime; protected final int parameterFlags; public static ToNativeConverter getInstance(ToNativeContext toNativeContext) { int parameterFlags = ParameterFlags.parse(toNativeContext.getAnnotations()); return !ParameterFlags.isOut(parameterFlags) ? new Pointer64ArrayParameterConverter(toNativeContext.getRuntime(), parameterFlags) : new Pointer64ArrayParameterConverter.Out(toNativeContext.getRuntime(), parameterFlags); } Pointer64ArrayParameterConverter(jnr.ffi.Runtime runtime, int parameterFlags) { this.runtime = runtime; this.parameterFlags = parameterFlags; } @Override @LongLong public Class nativeType() { return long[].class; } @Override public long[] toNative(Pointer[] pointers, ToNativeContext context) { if (pointers == null) { return null; } long[] primitive = new long[pointers.length]; if (ParameterFlags.isIn(parameterFlags)) { for (int i = 0; i < pointers.length; i++) { if (pointers[i] != null && !pointers[i].isDirect()) { throw new IllegalArgumentException("invalid pointer in array at index " + i); } primitive[i] = pointers[i] != null ? pointers[i].address() : 0L; } } return primitive; } public static final class Out extends Pointer64ArrayParameterConverter implements ToNativeConverter.PostInvocation { Out(jnr.ffi.Runtime runtime, int parameterFlags) { super(runtime, parameterFlags); } @Override public void postInvoke(Pointer[] pointers, long[] primitive, ToNativeContext context) { if (pointers != null && primitive != null) { MemoryManager mm = runtime.getMemoryManager(); for (int i = 0; i < pointers.length; i++) { pointers[i] = mm.newPointer(primitive[i]); } } } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/converters/StringBufferParameterConverter.java000066400000000000000000000057711316720554100334340ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.converters; import jnr.ffi.mapper.ToNativeContext; import jnr.ffi.mapper.ToNativeConverter; import jnr.ffi.provider.ParameterFlags; import jnr.ffi.util.BufferUtil; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; @ToNativeConverter.NoContext @ToNativeConverter.Cacheable public class StringBufferParameterConverter implements ToNativeConverter, ToNativeConverter.PostInvocation { private final Charset charset; private final int parameterFlags; private StringBufferParameterConverter(Charset charset, int parameterFlags) { this.charset = charset; this.parameterFlags = parameterFlags; } public Class nativeType() { return ByteBuffer.class; } public static StringBufferParameterConverter getInstance(int parameterFlags, ToNativeContext toNativeContext) { return new StringBufferParameterConverter(Charset.defaultCharset(), parameterFlags); } public static StringBufferParameterConverter getInstance(Charset charset, int parameterFlags, ToNativeContext toNativeContext) { return new StringBufferParameterConverter(charset, parameterFlags); } public ByteBuffer toNative(StringBuffer parameter, ToNativeContext context) { if (parameter == null) { return null; } else { ByteBuffer buf = ParameterFlags.isIn(parameterFlags) ? charset.encode(CharBuffer.wrap(parameter)) : ByteBuffer.allocate(parameter.capacity() + 1); if ((ParameterFlags.isOut(parameterFlags) && buf.capacity() < parameter.capacity() + 1) || !buf.hasArray()) { byte[] array = new byte[parameter.capacity() + 1]; buf.get(array, 0, buf.remaining()); return ByteBuffer.wrap(array); } else { return buf; } } } public void postInvoke(StringBuffer stringBuffer, ByteBuffer buf, ToNativeContext context) { // // Copy the string back out if its an OUT parameter // if (ParameterFlags.isOut(parameterFlags) && stringBuffer != null && buf != null) { buf.limit(buf.capacity()); stringBuffer.delete(0, stringBuffer.length()).append(BufferUtil.getCharSequence(buf, charset)); } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/converters/StringBuilderParameterConverter.java000066400000000000000000000072671316720554100336130ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.converters; import jnr.ffi.mapper.ToNativeContext; import jnr.ffi.mapper.ToNativeConverter; import jnr.ffi.provider.ParameterFlags; import jnr.ffi.util.BufferUtil; import java.lang.ref.Reference; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.*; import static jnr.ffi.provider.converters.StringUtil.*; @ToNativeConverter.NoContext @ToNativeConverter.Cacheable public class StringBuilderParameterConverter implements ToNativeConverter, ToNativeConverter.PostInvocation { private final ThreadLocal> localEncoder = new ThreadLocal>(); private final ThreadLocal> localDecoder = new ThreadLocal>(); private final Charset charset; private final int parameterFlags; private final int terminatorWidth; private StringBuilderParameterConverter(Charset charset, int parameterFlags) { this.charset = charset; this.parameterFlags = parameterFlags; this.terminatorWidth = terminatorWidth(charset); } public Class nativeType() { return ByteBuffer.class; } public static StringBuilderParameterConverter getInstance(int parameterFlags, ToNativeContext toNativeContext) { return new StringBuilderParameterConverter(getCharset(toNativeContext), parameterFlags); } public static StringBuilderParameterConverter getInstance(Charset charset, int parameterFlags, ToNativeContext toNativeContext) { return new StringBuilderParameterConverter(charset, parameterFlags); } public ByteBuffer toNative(StringBuilder parameter, ToNativeContext context) { if (parameter == null) { return null; } else { CharsetEncoder encoder = getEncoder(charset, localEncoder); ByteBuffer byteBuffer = ByteBuffer.wrap(new byte[parameter.capacity() * (int) Math.ceil(encoder.maxBytesPerChar()) + 4]); if (ParameterFlags.isIn(parameterFlags)) { byteBuffer.mark(); encoder.reset(); CoderResult result = encoder.encode(CharBuffer.wrap(parameter), byteBuffer, true); if (result.isUnderflow()) result = encoder.flush(byteBuffer); if (result.isError()) throwException(result); byteBuffer.reset(); } return byteBuffer; } } public void postInvoke(StringBuilder stringBuilder, ByteBuffer buf, ToNativeContext context) { // // Copy the string back out if its an OUT parameter // if (ParameterFlags.isOut(parameterFlags) && stringBuilder != null && buf != null) { buf.limit(stringLength(buf, terminatorWidth)); try { stringBuilder.delete(0, stringBuilder.length()).append(getDecoder(charset, localDecoder).reset().decode(buf)); } catch (CharacterCodingException cce) { throw new RuntimeException(cce); } } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/converters/StringResultConverter.java000066400000000000000000000076021316720554100316330ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.converters; import jnr.ffi.Pointer; import jnr.ffi.annotations.Encoding; import jnr.ffi.mapper.*; import java.lang.annotation.Annotation; import java.lang.ref.Reference; import java.nio.ByteBuffer; import java.nio.charset.CharacterCodingException; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.util.Arrays; import java.util.Collection; import static jnr.ffi.provider.converters.StringUtil.getDecoder; /** * Converts a native pointer result into a java String */ @FromNativeConverter.NoContext @FromNativeConverter.Cacheable public class StringResultConverter implements FromNativeConverter { private static final FromNativeConverter DEFAULT = new StringResultConverter(Charset.defaultCharset()); private final ThreadLocal> localDecoder = new ThreadLocal>(); private final Charset charset; private final int terminatorWidth; private StringResultConverter(Charset charset) { this.charset = charset; this.terminatorWidth = StringUtil.terminatorWidth(charset); } public static FromNativeConverter getInstance(Charset cs) { return Charset.defaultCharset().equals(cs) ? DEFAULT : new StringResultConverter(cs); } public static FromNativeConverter getInstance(FromNativeContext fromNativeContext) { Charset charset = Charset.defaultCharset(); if (fromNativeContext instanceof MethodResultContext) { // See if the interface class has a global @Encoding declaration Encoding e = getEncoding(Arrays.asList(((MethodResultContext) fromNativeContext).getMethod().getDeclaringClass().getAnnotations())); if (e != null) { charset = Charset.forName(e.value()); } } // Allow each method to override the default Encoding e = getEncoding(fromNativeContext.getAnnotations()); if (e != null) { charset = Charset.forName(e.value()); } return getInstance(charset); } @Override public String fromNative(Pointer pointer, FromNativeContext context) { if (pointer == null) { return null; } Search: for (int idx = 0; ; ) { idx += pointer.indexOf(idx, (byte) 0); for (int tcount = 1; tcount < terminatorWidth; tcount++) { if (pointer.getByte(idx + tcount) != 0) { idx += tcount; continue Search; } } byte[] bytes = new byte[idx]; pointer.get(0, bytes, 0, bytes.length); try { return getDecoder(charset, localDecoder).reset().decode(ByteBuffer.wrap(bytes)).toString(); } catch (CharacterCodingException cce) { throw new RuntimeException(cce); } } } @Override public Class nativeType() { return Pointer.class; } private static Encoding getEncoding(Collection annotations) { for (Annotation a : annotations) { if (a instanceof Encoding) { return (Encoding) a; } } return null; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/converters/StringUtil.java000066400000000000000000000134501316720554100274000ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.converters; import jnr.ffi.annotations.Encoding; import jnr.ffi.mapper.MethodParameterContext; import jnr.ffi.mapper.ToNativeContext; import java.lang.annotation.Annotation; import java.lang.ref.Reference; import java.lang.ref.SoftReference; import java.nio.ByteBuffer; import java.nio.charset.*; import java.util.Arrays; import java.util.Collection; final class StringUtil { private StringUtil() {} static CharsetEncoder getEncoder(Charset charset, ThreadLocal> localEncoder) { Reference ref = localEncoder.get(); CharsetEncoder encoder; return ref != null && (encoder = ref.get()) != null && encoder.charset() == charset ? encoder : initEncoder(charset, localEncoder); } static CharsetDecoder getDecoder(Charset charset, ThreadLocal> localDecoder) { Reference ref = localDecoder.get(); CharsetDecoder decoder; return ref != null && (decoder = ref.get()) != null && decoder.charset() == charset ? decoder : initDecoder(charset, localDecoder); } private static CharsetEncoder initEncoder(Charset charset, ThreadLocal> localEncoder) { CharsetEncoder encoder = charset.newEncoder(); encoder.onMalformedInput(CodingErrorAction.REPLACE).onUnmappableCharacter(CodingErrorAction.REPLACE); localEncoder.set(new SoftReference(encoder)); return encoder; } private static CharsetDecoder initDecoder(Charset charset, ThreadLocal> localDecoder) { CharsetDecoder decoder = charset.newDecoder(); decoder.onMalformedInput(CodingErrorAction.REPLACE).onUnmappableCharacter(CodingErrorAction.REPLACE); localDecoder.set(new SoftReference(decoder)); return decoder; } static Charset getCharset(ToNativeContext toNativeContext) { Charset charset = Charset.defaultCharset(); if (toNativeContext instanceof MethodParameterContext) { // See if the interface class has a global @Encoding declaration Charset cs = getEncodingCharset(Arrays.asList(((MethodParameterContext) toNativeContext).getMethod().getDeclaringClass().getAnnotations())); if (cs != null) { charset = cs; } // Allow each method to override the default cs = getEncodingCharset(Arrays.asList(((MethodParameterContext) toNativeContext).getMethod().getAnnotations())); if (cs != null) { charset = cs; } } // Override on a per-parameter basis Charset cs = getEncodingCharset(toNativeContext.getAnnotations()); if (cs != null) { charset = cs; } return charset; } private static Charset getEncodingCharset(Collection annotations) { for (Annotation a : annotations) { if (a instanceof Encoding) { return Charset.forName(((Encoding) a).value()); } } return null; } static void throwException(CoderResult result) { try { result.throwException(); } catch (RuntimeException re) { throw re; } catch (CharacterCodingException cce) { throw new RuntimeException(cce); } } private static final Charset UTF8 = Charset.forName("UTF-8"); private static final Charset USASCII = Charset.forName("US-ASCII"); private static final Charset ISO8859_1 = Charset.forName("ISO-8859-1"); private static final Charset UTF16 = Charset.forName("UTF-16"); private static final Charset UTF16LE = Charset.forName("UTF-16LE"); private static final Charset UTF16BE = Charset.forName("UTF-16BE"); static int terminatorWidth(Charset charset) { if (charset.equals(UTF8) || charset.equals(USASCII) || charset.equals(ISO8859_1)) { return 1; } else if (charset.equals(UTF16) || charset.equals(UTF16LE) || charset.equals(UTF16BE)) { return 2; } else { return 4; } } static int stringLength(ByteBuffer in, int terminatorWidth) { if (in.hasArray()) { byte[] array = in.array(); int end = in.arrayOffset() + in.limit(); int tcount = 0; for (int idx = in.arrayOffset() + in.position(); idx < end; ) { if (array[idx++] == 0) { tcount++; } else { tcount = 0; } if (tcount == terminatorWidth) { return idx - terminatorWidth; } } } else { int begin = in.position(); int end = in.limit(); int tcount = 0; for (int idx = begin; idx < end; ) { if (in.get(idx++) == 0) { tcount++; } else { tcount = 0; } if (tcount == terminatorWidth) { return idx - terminatorWidth; } } } return -1; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/converters/StructArrayParameterConverter.java000066400000000000000000000105601316720554100333070ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.converters; import jnr.ffi.Pointer; import jnr.ffi.Struct; import jnr.ffi.annotations.LongLong; import jnr.ffi.mapper.ToNativeContext; import jnr.ffi.mapper.ToNativeConverter; import jnr.ffi.provider.DelegatingMemoryIO; import jnr.ffi.provider.ParameterFlags; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; /** * Converts a Pointer[] array to a long[] array parameter */ @ToNativeConverter.NoContext @ToNativeConverter.Cacheable public class StructArrayParameterConverter implements ToNativeConverter { protected final jnr.ffi.Runtime runtime; protected final int parameterFlags; public static ToNativeConverter getInstance(ToNativeContext toNativeContext, Class structClass) { int parameterFlags = ParameterFlags.parse(toNativeContext.getAnnotations()); return !ParameterFlags.isOut(parameterFlags) ? new StructArrayParameterConverter(toNativeContext.getRuntime(), parameterFlags) : new StructArrayParameterConverter.Out(toNativeContext.getRuntime(), structClass.asSubclass(Struct.class), parameterFlags); } StructArrayParameterConverter(jnr.ffi.Runtime runtime, int parameterFlags) { this.runtime = runtime; this.parameterFlags = parameterFlags; } @Override public Class nativeType() { return Pointer.class; } @Override public Pointer toNative(Struct[] structs, ToNativeContext context) { if (structs == null) { return null; } Pointer memory = Struct.getMemory(structs[0], parameterFlags); if (!(memory instanceof DelegatingMemoryIO)) { throw new RuntimeException("Struct array must be backed by contiguous array"); } return ((DelegatingMemoryIO) memory).getDelegatedMemoryIO(); } public static final class Out extends StructArrayParameterConverter implements PostInvocation { private final Constructor constructor; Out(jnr.ffi.Runtime runtime, Class structClass, int parameterFlags) { super(runtime, parameterFlags); Constructor cons; try { cons = structClass.getConstructor(jnr.ffi.Runtime.class); } catch (NoSuchMethodException nsme) { throw new RuntimeException(structClass.getName() + " has no constructor that accepts jnr.ffi.Runtime"); } catch (Throwable t) { throw new RuntimeException(t); } this.constructor = cons; } @Override public void postInvoke(Struct[] structs, Pointer primitive, ToNativeContext context) { if (structs != null && primitive != null) { try { int off = 0; for (int i = 0; i < structs.length; i++) { structs[i] = constructor.newInstance(runtime); int structSize = align(Struct.size(structs[i]), Struct.alignment(structs[i])); structs[i].useMemory(primitive.slice(off = align(off, Struct.alignment(structs[i])), structSize)); off += structSize; } } catch (InstantiationException ie) { throw new RuntimeException(ie); } catch (IllegalAccessException iae) { throw new RuntimeException(iae); } catch (InvocationTargetException ite) { throw new RuntimeException(ite); } } } } private static int align(int offset, int align) { return (offset + align - 1) & ~(align - 1); } } StructByReferenceFromNativeConverter.java000066400000000000000000000045341316720554100345010ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/converters/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.converters; import jnr.ffi.Pointer; import jnr.ffi.Struct; import jnr.ffi.mapper.FromNativeContext; import jnr.ffi.mapper.FromNativeConverter; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; /** * Converts a native pointer result into a {@link jnr.ffi.Struct} */ public class StructByReferenceFromNativeConverter implements FromNativeConverter { private final Constructor constructor; public static FromNativeConverter getInstance(Class structClass, FromNativeContext toNativeContext) { try { return new StructByReferenceFromNativeConverter(structClass.getConstructor(jnr.ffi.Runtime.class)); } catch (NoSuchMethodException nsme) { throw new RuntimeException(structClass.getName() + " has no constructor that accepts jnr.ffi.Runtime"); } catch (Throwable t) { throw new RuntimeException(t); } } StructByReferenceFromNativeConverter(Constructor constructor) { this.constructor = constructor; } @Override public Struct fromNative(Pointer nativeValue, FromNativeContext context) { try { Struct s = constructor.newInstance(context.getRuntime()); s.useMemory(nativeValue); return s; } catch (InstantiationException e) { throw new RuntimeException(e); } catch (IllegalAccessException e) { throw new RuntimeException(e); } catch (InvocationTargetException e) { throw new RuntimeException(e); } } @Override public Class nativeType() { return Pointer.class; } } StructByReferenceToNativeConverter.java000066400000000000000000000030401316720554100341470ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/converters/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.converters; import jnr.ffi.Pointer; import jnr.ffi.Struct; import jnr.ffi.mapper.ToNativeContext; import jnr.ffi.mapper.ToNativeConverter; import jnr.ffi.provider.ParameterFlags; @ToNativeConverter.NoContext @ToNativeConverter.Cacheable public final class StructByReferenceToNativeConverter implements ToNativeConverter { private final int flags; public static ToNativeConverter getInstance(ToNativeContext toNativeContext) { return new StructByReferenceToNativeConverter(ParameterFlags.parse(toNativeContext.getAnnotations())); } StructByReferenceToNativeConverter(int flags) { this.flags = flags; } public Class nativeType() { return Pointer.class; } public Pointer toNative(Struct value, ToNativeContext ctx) { return value != null ? Struct.getMemory(value, flags) : null; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/000077500000000000000000000000001316720554100231525ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/AbstractAsmLibraryInterface.java000066400000000000000000000024751316720554100313770ustar00rootroot00000000000000/* * Copyright (C) 2011 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import jnr.ffi.provider.LoadedLibrary; /** * */ public abstract class AbstractAsmLibraryInterface implements LoadedLibrary { public static final com.kenai.jffi.Invoker ffi = com.kenai.jffi.Invoker.getInstance(); protected final jnr.ffi.Runtime runtime; // Strong ref to keep the library alive protected final NativeLibrary library; public AbstractAsmLibraryInterface(jnr.ffi.Runtime runtime, NativeLibrary library) { this.runtime = runtime; this.library = library; } public final jnr.ffi.Runtime getRuntime() { return runtime; } final NativeLibrary getLibrary() { return library; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/AbstractFastNumericMethodGenerator.java000066400000000000000000000315351316720554100327400ustar00rootroot00000000000000/* * Copyright (C) 2011 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import com.kenai.jffi.*; import jnr.ffi.NativeType; import jnr.ffi.Pointer; import jnr.ffi.provider.ParameterType; import jnr.ffi.provider.ResultType; import org.objectweb.asm.Label; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.nio.*; import java.util.*; import static jnr.ffi.provider.jffi.AsmUtil.*; import static jnr.ffi.provider.jffi.CodegenUtils.ci; import static jnr.ffi.provider.jffi.CodegenUtils.p; import static jnr.ffi.provider.jffi.NumberUtil.*; /** * */ abstract class AbstractFastNumericMethodGenerator extends BaseMethodGenerator { public void generate(final AsmBuilder builder, final SkinnyMethodAdapter mv, LocalVariableAllocator localVariableAllocator, CallContext callContext, final ResultType resultType, final ParameterType[] parameterTypes, boolean ignoreError) { // [ stack contains: Invoker, Function ] final Class nativeIntType = getInvokerType(); final LocalVariable objCount = localVariableAllocator.allocate(int.class); final LocalVariable[] parameters = AsmUtil.getParameterVariables(parameterTypes); final LocalVariable[] converted = new LocalVariable[parameterTypes.length]; int pointerCount = 0; // Load, convert, and un-box parameters for (int i = 0; i < parameterTypes.length; ++i) { converted[i] = loadAndConvertParameter(builder, mv, localVariableAllocator, parameters[i], parameterTypes[i]); Class javaParameterType = parameterTypes[i].effectiveJavaType(); ToNativeOp op = ToNativeOp.get(parameterTypes[i]); if (op != null && op.isPrimitive()) { op.emitPrimitive(mv, getInvokerType(), parameterTypes[i].getNativeType()); } else if (hasPointerParameterStrategy(javaParameterType)) { pointerCount = emitDirectCheck(mv, javaParameterType, nativeIntType, converted[i], objCount, pointerCount); } else { throw new IllegalArgumentException("unsupported parameter type " + parameterTypes[i].getDeclaredType()); } } // stack now contains [ IntInvoker, Function, int/long args ] Label hasObjects = new Label(); Label convertResult = new Label(); if (pointerCount > 0) { mv.iload(objCount); mv.ifne(hasObjects); } mv.invokevirtual(p(com.kenai.jffi.Invoker.class), getInvokerMethodName(resultType, parameterTypes, ignoreError), getInvokerSignature(parameterTypes.length, nativeIntType)); if (pointerCount > 0) mv.label(convertResult); Class javaReturnType = resultType.effectiveJavaType(); Class nativeReturnType = nativeIntType; // Convert the result from long/int to the correct return type if (Float.class == javaReturnType || float.class == javaReturnType) { narrow(mv, nativeIntType, int.class); mv.invokestatic(Float.class, "intBitsToFloat", float.class, int.class); nativeReturnType = float.class; } else if (Double.class == javaReturnType || double.class == javaReturnType) { widen(mv, nativeIntType, long.class); mv.invokestatic(Double.class, "longBitsToDouble", double.class, long.class); nativeReturnType = double.class; } // box and/or narrow/widen the return value if needed final Class unboxedResultType = unboxedReturnType(javaReturnType); convertPrimitive(mv, nativeReturnType, unboxedResultType, resultType.getNativeType()); emitEpilogue(builder, mv, resultType, parameterTypes, parameters, converted, null); /* -- method returns above - below is an alternative path -- */ // Now implement heap object support if (pointerCount > 0) { mv.label(hasObjects); if (int.class == nativeIntType) { // For int invoker, need to convert all the int args to long LocalVariable[] tmp = new LocalVariable[parameterTypes.length]; for (int i = parameterTypes.length - 1; i > 0; i--) { tmp[i] = localVariableAllocator.allocate(int.class); mv.istore(tmp[i]); } if (parameterTypes.length > 0) mv.i2l(); // Now reload them back onto the parameter stack, and widen to long for (int i = 1; i < parameterTypes.length; i++) { mv.iload(tmp[i]); mv.i2l(); } } mv.iload(objCount); // Need to load all the converters onto the stack LocalVariable[] strategies = new LocalVariable[parameterTypes.length]; for (int i = 0; i < parameterTypes.length; i++) { Class javaParameterType = parameterTypes[i].effectiveJavaType(); if (hasPointerParameterStrategy(javaParameterType)) { mv.aload(converted[i]); emitParameterStrategyLookup(mv, javaParameterType); mv.astore(strategies[i] = localVariableAllocator.allocate(ParameterStrategy.class)); mv.aload(converted[i]); mv.aload(strategies[i]); mv.aload(0); ObjectParameterInfo info = ObjectParameterInfo.create(i, AsmUtil.getNativeArrayFlags(parameterTypes[i].annotations())); mv.getfield(builder.getClassNamePath(), builder.getObjectParameterInfoName(info), ci(ObjectParameterInfo.class)); } } mv.invokevirtual(p(com.kenai.jffi.Invoker.class), getObjectParameterMethodName(parameterTypes.length), getObjectParameterMethodSignature(parameterTypes.length, pointerCount)); narrow(mv, long.class, nativeIntType); mv.go_to(convertResult); } } static final Map, Method> STRATEGY_ADDRESS_METHODS; static final Map> STRATEGY_PARAMETER_TYPES; static { Map, Method> strategies = new HashMap, Method>(); addStrategyParameterType(strategies, BufferParameterStrategy.class, Buffer.class); addStrategyParameterType(strategies, PointerParameterStrategy.class, Pointer.class); STRATEGY_ADDRESS_METHODS = Collections.unmodifiableMap(strategies); Map> types = new LinkedHashMap>(); types.put(Pointer.class, PointerParameterStrategy.class); for (Class c : new Class[] { ByteBuffer.class, CharBuffer.class, ShortBuffer.class, IntBuffer.class, LongBuffer.class, FloatBuffer.class, DoubleBuffer.class, Buffer.class }) { types.put(c, BufferParameterStrategy.class); } for (Class c : new Class[] { byte[].class, short[].class, char[].class, int[].class, long[].class, float[].class, double[].class, boolean[].class }) { types.put(c, ParameterStrategy.class); } STRATEGY_PARAMETER_TYPES = Collections.unmodifiableMap(types); } private static void addStrategyParameterType(Map, Method> map, Class strategyClass, Class parameterType) { try { Method addressMethod = strategyClass.getDeclaredMethod("address", parameterType); if (Modifier.isPublic(addressMethod.getModifiers()) && Modifier.isPublic(addressMethod.getDeclaringClass().getModifiers())) { map.put(strategyClass, addressMethod); } } catch (NoSuchMethodException ignored) {} } @SuppressWarnings("unchecked") static boolean hasPointerParameterStrategy(Class javaType) { for (Class c : STRATEGY_PARAMETER_TYPES.keySet()) { if (c.isAssignableFrom(javaType)) { return true; } } return false; } static Class emitParameterStrategyLookup(SkinnyMethodAdapter mv, Class javaParameterType) { for (Map.Entry> e : STRATEGY_PARAMETER_TYPES.entrySet()) { if (e.getKey().isAssignableFrom(javaParameterType)) { mv.invokestatic(AsmRuntime.class, "pointerParameterStrategy", e.getValue(), e.getKey()); return e.getValue(); } } throw new RuntimeException("no conversion strategy for: " + javaParameterType); } static void emitParameterStrategyAddress(SkinnyMethodAdapter mv, Class nativeIntType, Class strategyClass, LocalVariable strategy, LocalVariable parameter) { // Get the native address (will return zero for heap objects) mv.aload(strategy); mv.aload(parameter); Method addressMethod = STRATEGY_ADDRESS_METHODS.get(strategyClass); if (addressMethod != null) { mv.invokevirtual(strategyClass, addressMethod.getName(), addressMethod.getReturnType(), addressMethod.getParameterTypes()); } else { mv.invokevirtual(PointerParameterStrategy.class, "address", long.class, Object.class); } narrow(mv, long.class, nativeIntType); } static int emitDirectCheck(SkinnyMethodAdapter mv, Class javaParameterClass, Class nativeIntType, LocalVariable parameter, LocalVariable objCount, int pointerCount) { if (pointerCount < 1) { mv.iconst_0(); mv.istore(objCount); } Label next = new Label(); Label nullPointer = new Label(); mv.ifnull(nullPointer); if (Pointer.class.isAssignableFrom(javaParameterClass)) { mv.aload(parameter); mv.invokevirtual(Pointer.class, "address", long.class); narrow(mv, long.class, nativeIntType); mv.aload(parameter); mv.invokevirtual(Pointer.class, "isDirect", boolean.class); mv.iftrue(next); } else if (Buffer.class.isAssignableFrom(javaParameterClass)) { mv.aload(parameter); mv.invokestatic(AsmRuntime.class, "longValue", long.class, Buffer.class); narrow(mv, long.class, nativeIntType); mv.aload(parameter); mv.invokevirtual(Buffer.class, "isDirect", boolean.class); mv.iftrue(next); } else if (javaParameterClass.isArray() && javaParameterClass.getComponentType().isPrimitive()) { // address of arrays is always zero - they have to be handled as objects if (long.class == nativeIntType) mv.lconst_0(); else mv.iconst_0(); } else { throw new UnsupportedOperationException("unsupported parameter type: " + javaParameterClass); } mv.iinc(objCount, 1); mv.go_to(next); mv.label(nullPointer); if (long.class == nativeIntType) mv.lconst_0(); else mv.iconst_0(); mv.label(next); return ++pointerCount; } static String getObjectParameterMethodName(int parameterCount) { return "invokeN" + parameterCount; } static String getObjectParameterMethodSignature(int parameterCount, int pointerCount) { StringBuilder sb = new StringBuilder(); sb.append('(').append(ci(CallContext.class)).append(ci(long.class)); for (int i = 0; i < parameterCount; i++) { sb.append('J'); } sb.append('I'); // objCount for (int n = 0; n < pointerCount; n++) { sb.append(ci(Object.class)); sb.append(ci(ObjectParameterStrategy.class)); sb.append(ci(ObjectParameterInfo.class)); } sb.append(")J"); return sb.toString(); } abstract String getInvokerMethodName(ResultType resultType, ParameterType[] parameterTypes, boolean ignoreErrno); abstract String getInvokerSignature(int parameterCount, Class nativeIntType); abstract Class getInvokerType(); } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/AbstractX86StubCompiler.java000066400000000000000000000142041316720554100304200ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import com.kenai.jffi.MemoryIO; import com.kenai.jffi.NativeMethod; import com.kenai.jffi.NativeMethods; import com.kenai.jffi.PageManager; import jnr.ffi.*; import jnr.ffi.Runtime; import jnr.x86asm.Assembler; import java.io.PrintStream; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.*; import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; import java.util.logging.Level; import java.util.logging.Logger; /** * Base class for most X86_32/X86_64 stub compilers */ abstract class AbstractX86StubCompiler extends StubCompiler { public final static boolean DEBUG = Boolean.getBoolean("jnr.ffi.compile.dump"); private final jnr.ffi.Runtime runtime; protected AbstractX86StubCompiler(jnr.ffi.Runtime runtime) { this.runtime = runtime; } public final Runtime getRuntime() { return runtime; } private static final class StaticDataHolder { // Keep a reference from the loaded class to the pages holding the code for that class. static final Map PAGES = Collections.synchronizedMap(new WeakHashMap()); } final List stubs = new LinkedList(); static final class Stub { final String name; final String signature; final Assembler assembler; public Stub(String name, String signature, Assembler assembler) { this.name = name; this.signature = signature; this.assembler = assembler; } } static final AtomicIntegerFieldUpdater PAGE_HOLDER_UPDATER = AtomicIntegerFieldUpdater.newUpdater(PageHolder.class, "disposed"); static final class PageHolder { final PageManager pm; final long memory; final long pageCount; volatile int disposed; public PageHolder(PageManager pm, long memory, long pageCount) { this.pm = pm; this.memory = memory; this.pageCount = pageCount; } @Override protected void finalize() throws Throwable { try { int disposed = PAGE_HOLDER_UPDATER.getAndSet(this, 1); if (disposed == 0) { pm.freePages(memory, (int) pageCount); } } catch (Throwable t) { Logger.getLogger(getClass().getName()).log(Level.WARNING, "Exception when freeing native pages: %s", t.getLocalizedMessage()); } finally { super.finalize(); } } } @Override void attach(Class clazz) { if (stubs.isEmpty()) { return; } long codeSize = 0; for (Stub stub : stubs) { // add 8 bytes for alignment codeSize += stub.assembler.codeSize() + 8; } PageManager pm = PageManager.getInstance(); long npages = (codeSize + pm.pageSize() - 1) / pm.pageSize(); // Allocate some native memory for it long code = pm.allocatePages((int) npages, PageManager.PROT_READ | PageManager.PROT_WRITE); if (code == 0) { throw new OutOfMemoryError("allocatePages failed for codeSize=" + codeSize); } PageHolder page = new PageHolder(pm, code, npages); // Now relocate/copy all the assembler stubs into the real code area List methods = new ArrayList(stubs.size()); long fn = code; PrintStream dbg = System.err; System.out.flush(); System.err.flush(); for (Stub stub : stubs) { Assembler asm = stub.assembler; // align the start of all functions on a 8 byte boundary fn = align(fn, 8); ByteBuffer buf = ByteBuffer.allocate(asm.codeSize()).order(ByteOrder.LITTLE_ENDIAN); stub.assembler.relocCode(buf, fn); buf.flip(); MemoryIO.getInstance().putByteArray(fn, buf.array(), buf.arrayOffset(), buf.limit()); if (DEBUG && X86Disassembler.isAvailable()) { dbg.println(clazz.getName() + "." + stub.name + " " + stub.signature); X86Disassembler disassembler = X86Disassembler.create(); disassembler.setMode(Platform.getNativePlatform().getCPU() == Platform.CPU.I386 ? X86Disassembler.Mode.I386 : X86Disassembler.Mode.X86_64); disassembler.setSyntax(X86Disassembler.Syntax.INTEL); disassembler.setInputBuffer(MemoryUtil.newPointer(runtime, fn), asm.offset()); while (disassembler.disassemble()) { dbg.printf("%8x: %s\n", disassembler.offset(), disassembler.insn()); } if (buf.remaining() > asm.offset()) { // libudis86 for some reason cannot understand the code asmjit emits for the trampolines dbg.printf("%8x: \n", asm.offset()); } dbg.println(); } methods.add(new NativeMethod(fn, stub.name, stub.signature)); fn += asm.codeSize(); } pm.protectPages(code, (int) npages, PageManager.PROT_READ | PageManager.PROT_EXEC); NativeMethods.register(clazz, methods); StaticDataHolder.PAGES.put(clazz, page); } static int align(int offset, int align) { return (offset + align - 1) & ~(align - 1); } static long align(long offset, long align) { return (offset + align - 1) & ~(align - 1); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/AllocatedDirectMemoryIO.java000066400000000000000000000037761316720554100304760ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import jnr.ffi.Runtime; import java.util.concurrent.atomic.AtomicBoolean; class AllocatedDirectMemoryIO extends DirectMemoryIO { private final AtomicBoolean allocated = new AtomicBoolean(true); private final int size; public AllocatedDirectMemoryIO(Runtime runtime, int size, boolean clear) { super(runtime, IO.allocateMemory(size, clear)); this.size = size; if (address() == 0L) { throw new OutOfMemoryError("Failed to allocate " + size + " bytes"); } } @Override public long size() { return this.size; } @Override public int hashCode() { return super.hashCode(); } @Override public boolean equals(Object obj) { if (obj instanceof AllocatedDirectMemoryIO) { AllocatedDirectMemoryIO mem = (AllocatedDirectMemoryIO) obj; return mem.size == size && mem.address() == address(); } return super.equals(obj); } public final void dispose() { if (allocated.getAndSet(false)) { IO.freeMemory(address()); } } @Override protected void finalize() throws Throwable { try { if (allocated.getAndSet(false)) { IO.freeMemory(address()); } } finally { super.finalize(); } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/AnnotationTypeMapper.java000066400000000000000000000110541316720554100301370ustar00rootroot00000000000000/* * Copyright (C) 2013 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import jnr.ffi.mapper.*; import java.lang.annotation.Annotation; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; public class AnnotationTypeMapper extends AbstractSignatureTypeMapper implements SignatureTypeMapper { @Override public FromNativeType getFromNativeType(SignatureType type, FromNativeContext context) { Method fromNativeMethod = findMethodWithAnnotation(type, FromNativeConverter.FromNative.class); if (fromNativeMethod == null) { return null; } if (!Modifier.isStatic(fromNativeMethod.getModifiers())) { throw new IllegalArgumentException(fromNativeMethod.getDeclaringClass().getName() + "." + fromNativeMethod.getName() + " should be declared static"); } return FromNativeTypes.create(new ReflectionFromNativeConverter(fromNativeMethod, fromNativeMethod.getAnnotation(FromNativeConverter.FromNative.class).nativeType())); } @Override public ToNativeType getToNativeType(SignatureType type, ToNativeContext context) { Method toNativeMethod = findMethodWithAnnotation(type, ToNativeConverter.ToNative.class); if (toNativeMethod == null) { return null; } if (!Modifier.isStatic(toNativeMethod.getModifiers())) { throw new IllegalArgumentException(toNativeMethod.getDeclaringClass().getName() + "." + toNativeMethod.getName() + " should be declared static"); } return ToNativeTypes.create(new ReflectionToNativeConverter(toNativeMethod, toNativeMethod.getAnnotation(ToNativeConverter.ToNative.class).nativeType())); } private static Method findMethodWithAnnotation(SignatureType type, Class annotationClass) { for (Class klass = type.getDeclaredType(); klass != null && klass != Object.class; klass = klass.getSuperclass()) { for (Method m : klass.getDeclaredMethods()) { if (m.isAnnotationPresent(annotationClass)) { return m; } } } return null; } public abstract class AbstractReflectionConverter { protected final Method method; protected final Class nativeType; public AbstractReflectionConverter(Method method, Class nativeType) { this.method = method; this.nativeType = nativeType; } protected final Object invoke(Object value, Object context) { try { return method.invoke(method.getDeclaringClass(), value, context); } catch (IllegalAccessException iae) { throw new RuntimeException(iae); } catch (InvocationTargetException ite) { throw new RuntimeException(ite); } } public final Class nativeType() { return nativeType; } } @FromNativeConverter.Cacheable public final class ReflectionFromNativeConverter extends AbstractReflectionConverter implements FromNativeConverter { public ReflectionFromNativeConverter(Method method, Class nativeType) { super(method, nativeType); } @Override public Object fromNative(Object nativeValue, FromNativeContext context) { return invoke(nativeValue, context); } } @ToNativeConverter.Cacheable public final class ReflectionToNativeConverter extends AbstractReflectionConverter implements ToNativeConverter { public ReflectionToNativeConverter(Method method, Class nativeType) { super(method, nativeType); } @Override public Object toNative(Object nativeValue, ToNativeContext context) { return invoke(nativeValue, context); } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/ArrayMemoryIO.java000066400000000000000000000027151316720554100265210ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import jnr.ffi.Pointer; import jnr.ffi.Runtime; import jnr.ffi.provider.AbstractArrayMemoryIO; public final class ArrayMemoryIO extends AbstractArrayMemoryIO { public ArrayMemoryIO(Runtime runtime, int size) { super(runtime, size); } public ArrayMemoryIO(Runtime runtime, byte[] bytes, int off, int len) { super(runtime, bytes, off, len); } public Pointer getPointer(long offset) { return MemoryUtil.newPointer(getRuntime(), getAddress(offset)); } @Override public Pointer getPointer(long offset, long size) { return MemoryUtil.newPointer(getRuntime(), getAddress(offset), size); } @Override public void putPointer(long offset, Pointer value) { putAddress(offset, value != null ? value.address() : 0L); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/AsmBuilder.java000066400000000000000000000215541316720554100260530ustar00rootroot00000000000000/* * Copyright (C) 2011 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import com.kenai.jffi.CallContext; import com.kenai.jffi.Function; import com.kenai.jffi.ObjectParameterInfo; import jnr.ffi.*; import jnr.ffi.Runtime; import jnr.ffi.mapper.FromNativeContext; import jnr.ffi.mapper.FromNativeConverter; import jnr.ffi.mapper.ToNativeContext; import jnr.ffi.mapper.ToNativeConverter; import org.objectweb.asm.ClassVisitor; import java.lang.reflect.Modifier; import java.util.*; import static jnr.ffi.provider.jffi.AsmUtil.boxedType; import static jnr.ffi.provider.jffi.AsmUtil.unboxNumber; import static jnr.ffi.provider.jffi.CodegenUtils.ci; import static org.objectweb.asm.Opcodes.ACC_FINAL; import static org.objectweb.asm.Opcodes.ACC_PRIVATE; /** * */ class AsmBuilder { private final jnr.ffi.Runtime runtime; private final String classNamePath; private final ClassVisitor classVisitor; private final AsmClassLoader classLoader; private final ObjectNameGenerator functionId = new ObjectNameGenerator("functionAddress"); private final ObjectNameGenerator contextId = new ObjectNameGenerator("callContext"); private final ObjectNameGenerator toNativeConverterId = new ObjectNameGenerator("toNativeConverter"); private final ObjectNameGenerator toNativeContextId = new ObjectNameGenerator("toNativeContext"); private final ObjectNameGenerator fromNativeConverterId = new ObjectNameGenerator("fromNativeConverter"); private final ObjectNameGenerator fromNativeContextId = new ObjectNameGenerator("fromNativeContext"); private final ObjectNameGenerator objectParameterInfoId = new ObjectNameGenerator("objectParameterInfo"); private final ObjectNameGenerator variableAccessorId = new ObjectNameGenerator("variableAccessor"); private final ObjectNameGenerator genericObjectId = new ObjectNameGenerator("objectField"); private final Map toNativeConverters = new IdentityHashMap(); private final Map toNativeContexts = new IdentityHashMap(); private final Map fromNativeConverters = new IdentityHashMap(); private final Map fromNativeContexts = new IdentityHashMap(); private final Map objectParameterInfo = new HashMap(); private final Map variableAccessors = new HashMap(); private final Map callContextMap = new HashMap(); private final Map functionAddresses = new HashMap(); private final Map genericObjects = new IdentityHashMap(); private final List objectFields = new ArrayList(); AsmBuilder(jnr.ffi.Runtime runtime, String classNamePath, ClassVisitor classVisitor, AsmClassLoader classLoader) { this.runtime = runtime; this.classNamePath = classNamePath; this.classVisitor = classVisitor; this.classLoader = classLoader; } public String getClassNamePath() { return classNamePath; } ClassVisitor getClassVisitor() { return classVisitor; } public AsmClassLoader getClassLoader() { return classLoader; } public jnr.ffi.Runtime getRuntime() { return runtime; } private static final class ObjectNameGenerator { private final String baseName; private int value; ObjectNameGenerator(String baseName) { this.baseName = baseName; this.value = 0; } String generateName() { return baseName + "_" + ++value; } } ObjectField addField(Map map, T value, Class klass, ObjectNameGenerator objectNameGenerator) { ObjectField field = new ObjectField(objectNameGenerator.generateName(), value, klass); objectFields.add(field); map.put(value, field); return field; } ObjectField getField(Map map, T value, Class klass, ObjectNameGenerator objectNameGenerator) { ObjectField field = map.get(value); return field != null ? field : addField(map, value, klass, objectNameGenerator); } String getCallContextFieldName(Function function) { return getField(callContextMap, function.getCallContext(), CallContext.class, contextId).name; } String getCallContextFieldName(CallContext callContext) { return getField(callContextMap, callContext, CallContext.class, contextId).name; } String getFunctionAddressFieldName(Function function) { return getField(functionAddresses, function.getFunctionAddress(), long.class, functionId).name; } ObjectField getRuntimeField() { return getObjectField(runtime, runtime.getClass()); } String getFromNativeConverterName(FromNativeConverter converter) { return getFromNativeConverterField(converter).name; } String getToNativeConverterName(ToNativeConverter converter) { return getToNativeConverterField(converter).name; } private static Class nearestClass(Object obj, Class defaultClass) { return Modifier.isPublic(obj.getClass().getModifiers()) ? obj.getClass() : defaultClass; } ObjectField getToNativeConverterField(ToNativeConverter converter) { return getField(toNativeConverters, converter, nearestClass(converter, ToNativeConverter.class), toNativeConverterId); } ObjectField getFromNativeConverterField(FromNativeConverter converter) { return getField(fromNativeConverters, converter, nearestClass(converter, FromNativeConverter.class), fromNativeConverterId); } ObjectField getToNativeContextField(ToNativeContext context) { return getField(toNativeContexts, context, nearestClass(context, ToNativeContext.class), toNativeContextId); } ObjectField getFromNativeContextField(FromNativeContext context) { return getField(fromNativeContexts, context, nearestClass(context, FromNativeContext.class), fromNativeContextId); } String getObjectParameterInfoName(ObjectParameterInfo info) { return getField(objectParameterInfo, info, ObjectParameterInfo.class, objectParameterInfoId).name; } String getObjectFieldName(Object obj, Class klass) { return getField(genericObjects, obj, klass, genericObjectId).name; } ObjectField getObjectField(Object obj, Class klass) { return getField(genericObjects, obj, klass, genericObjectId); } String getVariableName(Variable variableAccessor) { return getField(variableAccessors, variableAccessor, Variable.class, variableAccessorId).name; } public static final class ObjectField { public final String name; public final Object value; public final Class klass; public ObjectField(String fieldName, Object fieldValue, Class fieldClass) { this.name = fieldName; this.value = fieldValue; this.klass = fieldClass; } } ObjectField[] getObjectFieldArray() { return objectFields.toArray(new ObjectField[objectFields.size()]); } Object[] getObjectFieldValues() { Object[] fieldObjects = new Object[objectFields.size()]; int i = 0; for (ObjectField f : objectFields) { fieldObjects[i++] = f.value; } return fieldObjects; } void emitFieldInitialization(SkinnyMethodAdapter init, int objectsParameterIndex) { int i = 0; for (ObjectField f : objectFields) { getClassVisitor().visitField(ACC_PRIVATE | ACC_FINAL, f.name, ci(f.klass), null, null); init.aload(0); init.aload(objectsParameterIndex); init.pushInt(i++); init.aaload(); if (f.klass.isPrimitive()) { Class boxedType = boxedType(f.klass); init.checkcast(boxedType); unboxNumber(init, boxedType, f.klass); } else { init.checkcast(f.klass); } init.putfield(getClassNamePath(), f.name, ci(f.klass)); } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/AsmClassLoader.java000066400000000000000000000031231316720554100266510ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import static jnr.ffi.provider.jffi.CodegenUtils.ci; import static jnr.ffi.provider.jffi.CodegenUtils.p; final class AsmClassLoader extends ClassLoader { private final ConcurrentMap definedClasses = new ConcurrentHashMap(); public AsmClassLoader() { } public AsmClassLoader(ClassLoader parent) { super(parent); } public Class defineClass(String name, byte[] b) { Class klass = defineClass(name, b, 0, b.length); definedClasses.putIfAbsent(name, klass); resolveClass(klass); return klass; } @Override protected Class findClass(String name) throws ClassNotFoundException { Class klass = definedClasses.get(name); if (klass != null) { return klass; } return super.findClass(name); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/AsmLibraryLoader.java000066400000000000000000000421501316720554100272130ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import static jnr.ffi.provider.jffi.CodegenUtils.ci; import static jnr.ffi.provider.jffi.CodegenUtils.p; import static jnr.ffi.provider.jffi.CodegenUtils.sig; import static jnr.ffi.provider.jffi.InvokerUtil.getCallContext; import static jnr.ffi.provider.jffi.InvokerUtil.getCallingConvention; import static jnr.ffi.provider.jffi.InvokerUtil.getParameterTypes; import static jnr.ffi.provider.jffi.InvokerUtil.getResultType; import static jnr.ffi.util.Annotations.sortedAnnotationCollection; import static org.objectweb.asm.Opcodes.ACC_FINAL; import static org.objectweb.asm.Opcodes.ACC_PRIVATE; import static org.objectweb.asm.Opcodes.ACC_PUBLIC; import static org.objectweb.asm.Opcodes.ACC_STATIC; import static org.objectweb.asm.Opcodes.V1_6; import java.io.PrintWriter; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.util.Map; import java.util.concurrent.atomic.AtomicLong; import jnr.ffi.CallingConvention; import jnr.ffi.LibraryOption; import jnr.ffi.annotations.Synchronized; import jnr.ffi.mapper.CachingTypeMapper; import jnr.ffi.mapper.CompositeTypeMapper; import jnr.ffi.mapper.DefaultSignatureType; import jnr.ffi.mapper.FromNativeContext; import jnr.ffi.mapper.FunctionMapper; import jnr.ffi.mapper.MethodResultContext; import jnr.ffi.mapper.SignatureType; import jnr.ffi.mapper.SignatureTypeMapper; import jnr.ffi.mapper.SignatureTypeMapperAdapter; import jnr.ffi.mapper.TypeMapper; import jnr.ffi.provider.IdentityFunctionMapper; import jnr.ffi.provider.InterfaceScanner; import jnr.ffi.provider.Invoker; import jnr.ffi.provider.NativeFunction; import jnr.ffi.provider.NativeVariable; import jnr.ffi.provider.NullTypeMapper; import jnr.ffi.provider.ParameterType; import jnr.ffi.provider.ResultType; import jnr.ffi.provider.jffi.AsmBuilder.ObjectField; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassWriter; import com.kenai.jffi.Function; public class AsmLibraryLoader extends LibraryLoader { public final static boolean DEBUG = Boolean.getBoolean("jnr.ffi.compile.dump"); private static final AtomicLong nextClassID = new AtomicLong(0); private static final AtomicLong uniqueId = new AtomicLong(0); private static final ThreadLocal classLoader = new ThreadLocal(); private final NativeRuntime runtime = NativeRuntime.getInstance(); @Override T loadLibrary(NativeLibrary library, Class interfaceClass, Map libraryOptions) { AsmClassLoader oldClassLoader = classLoader.get(); // Only create a new class loader if this was not a recursive call (i.e. loading a library as a result of loading another library) if (oldClassLoader == null) { classLoader.set(new AsmClassLoader(interfaceClass.getClassLoader())); } try { return generateInterfaceImpl(library, interfaceClass, libraryOptions, classLoader.get()); } finally { if (oldClassLoader == null) classLoader.remove(); } } private T generateInterfaceImpl(final NativeLibrary library, Class interfaceClass, Map libraryOptions, AsmClassLoader classLoader) { boolean debug = DEBUG && !interfaceClass.isAnnotationPresent(NoTrace.class); ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); ClassVisitor cv = debug ? AsmUtil.newCheckClassAdapter(cw) : cw; AsmBuilder builder = new AsmBuilder(runtime, p(interfaceClass) + "$jnr$ffi$" + nextClassID.getAndIncrement(), cv, classLoader); cv.visit(V1_6, ACC_PUBLIC | ACC_FINAL, builder.getClassNamePath(), null, p(AbstractAsmLibraryInterface.class), new String[] { p(interfaceClass) }); FunctionMapper functionMapper = libraryOptions.containsKey(LibraryOption.FunctionMapper) ? (FunctionMapper) libraryOptions.get(LibraryOption.FunctionMapper) : IdentityFunctionMapper.getInstance(); SignatureTypeMapper typeMapper; if (libraryOptions.containsKey(LibraryOption.TypeMapper)) { Object tm = libraryOptions.get(LibraryOption.TypeMapper); if (tm instanceof SignatureTypeMapper) { typeMapper = (SignatureTypeMapper) tm; } else if (tm instanceof TypeMapper) { typeMapper = new SignatureTypeMapperAdapter((TypeMapper) tm); } else { throw new IllegalArgumentException("TypeMapper option is not a valid TypeMapper instance"); } } else { typeMapper = new NullTypeMapper(); } CompositeTypeMapper closureTypeMapper = new CompositeTypeMapper(typeMapper, new CachingTypeMapper(new InvokerTypeMapper(null, classLoader, NativeLibraryLoader.ASM_ENABLED)), new CachingTypeMapper(new AnnotationTypeMapper())); typeMapper = new CompositeTypeMapper(typeMapper, new CachingTypeMapper(new InvokerTypeMapper(new NativeClosureManager(runtime, closureTypeMapper, classLoader), classLoader, NativeLibraryLoader.ASM_ENABLED)), new CachingTypeMapper(new AnnotationTypeMapper())); CallingConvention libraryCallingConvention = getCallingConvention(interfaceClass, libraryOptions); StubCompiler compiler = StubCompiler.newCompiler(runtime); final MethodGenerator[] generators = { !interfaceClass.isAnnotationPresent(NoX86.class) ? new X86MethodGenerator(compiler) : new NotImplMethodGenerator(), new FastIntMethodGenerator(), new FastLongMethodGenerator(), new FastNumericMethodGenerator(), new BufferMethodGenerator() }; DefaultInvokerFactory invokerFactory = new DefaultInvokerFactory(runtime, library, typeMapper, functionMapper, libraryCallingConvention, libraryOptions, interfaceClass.isAnnotationPresent(Synchronized.class)); InterfaceScanner scanner = new InterfaceScanner(interfaceClass, typeMapper, libraryCallingConvention); for (NativeFunction function : scanner.functions()) { if (function.getMethod().isVarArgs()) { ObjectField field = builder.getObjectField(invokerFactory.createInvoker(function.getMethod()), Invoker.class); generateVarargsInvocation(builder, function.getMethod(), field); continue; } String functionName = functionMapper.mapFunctionName(function.name(), new NativeFunctionMapperContext(library, function.annotations())); try { long functionAddress = library.findSymbolAddress(functionName); FromNativeContext resultContext = new MethodResultContext(runtime, function.getMethod()); SignatureType signatureType = DefaultSignatureType.create(function.getMethod().getReturnType(), resultContext); ResultType resultType = getResultType(runtime, function.getMethod().getReturnType(), resultContext.getAnnotations(), typeMapper.getFromNativeType(signatureType, resultContext), resultContext); ParameterType[] parameterTypes = getParameterTypes(runtime, typeMapper, function.getMethod()); boolean saveError = jnr.ffi.LibraryLoader.saveError(libraryOptions, function.hasSaveError(), function.hasIgnoreError()); Function jffiFunction = new Function(functionAddress, getCallContext(resultType, parameterTypes,function.convention(), saveError)); for (MethodGenerator g : generators) { if (g.isSupported(resultType, parameterTypes, function.convention())) { g.generate(builder, function.getMethod().getName(), jffiFunction, resultType, parameterTypes, !saveError); break; } } } catch (SymbolNotFoundError ex) { String errorFieldName = "error_" + uniqueId.incrementAndGet(); cv.visitField(ACC_PRIVATE | ACC_FINAL | ACC_STATIC, errorFieldName, ci(String.class), null, ex.getMessage()); generateFunctionNotFound(cv, builder.getClassNamePath(), errorFieldName, functionName, function.getMethod().getReturnType(), function.getMethod().getParameterTypes()); } } // generate global variable accessors VariableAccessorGenerator variableAccessorGenerator = new VariableAccessorGenerator(runtime); for (NativeVariable v : scanner.variables()) { Method m = v.getMethod(); java.lang.reflect.Type variableType = ((ParameterizedType) m.getGenericReturnType()).getActualTypeArguments()[0]; if (!(variableType instanceof Class)) { throw new IllegalArgumentException("unsupported variable class: " + variableType); } String functionName = functionMapper.mapFunctionName(m.getName(), null); try { variableAccessorGenerator.generate(builder, interfaceClass, m.getName(), library.findSymbolAddress(functionName), (Class) variableType, sortedAnnotationCollection(m.getAnnotations()), typeMapper, classLoader); } catch (SymbolNotFoundError ex) { String errorFieldName = "error_" + uniqueId.incrementAndGet(); cv.visitField(ACC_PRIVATE | ACC_FINAL | ACC_STATIC, errorFieldName, ci(String.class), null, ex.getMessage()); generateFunctionNotFound(cv, builder.getClassNamePath(), errorFieldName, functionName, m.getReturnType(), m.getParameterTypes()); } } // Create the constructor to set the instance fields SkinnyMethodAdapter init = new SkinnyMethodAdapter(cv, ACC_PUBLIC, "", sig(void.class, jnr.ffi.Runtime.class, NativeLibrary.class, Object[].class), null, null); init.start(); // Invoke the super class constructor as super(Library) init.aload(0); init.aload(1); init.aload(2); init.invokespecial(p(AbstractAsmLibraryInterface.class), "", sig(void.class, jnr.ffi.Runtime.class, NativeLibrary.class)); builder.emitFieldInitialization(init, 3); init.voidreturn(); init.visitMaxs(10, 10); init.visitEnd(); cv.visitEnd(); try { byte[] bytes = cw.toByteArray(); if (debug) { ClassVisitor trace = AsmUtil.newTraceClassVisitor(new PrintWriter(System.err)); new ClassReader(bytes).accept(trace, 0); } Class implClass = classLoader.defineClass(builder.getClassNamePath().replace("/", "."), bytes); Constructor cons = implClass.getDeclaredConstructor(jnr.ffi.Runtime.class, NativeLibrary.class, Object[].class); T result = cons.newInstance(runtime, library, builder.getObjectFieldValues()); // Attach any native method stubs - we have to delay this until the // implementation class is loaded for it to work. System.err.flush(); System.out.flush(); compiler.attach(implClass); return result; } catch (Throwable ex) { throw new RuntimeException(ex); } } private void generateFunctionNotFound(ClassVisitor cv, String className, String errorFieldName, String functionName, Class returnType, Class[] parameterTypes) { SkinnyMethodAdapter mv = new SkinnyMethodAdapter(cv, ACC_PUBLIC | ACC_FINAL, functionName, sig(returnType, parameterTypes), null, null); mv.start(); mv.getstatic(className, errorFieldName, ci(String.class)); mv.invokestatic(AsmRuntime.class, "newUnsatisifiedLinkError", UnsatisfiedLinkError.class, String.class); mv.athrow(); mv.visitMaxs(10, 10); mv.visitEnd(); } private void generateVarargsInvocation(AsmBuilder builder, Method m, ObjectField field) { Class[] parameterTypes = m.getParameterTypes(); SkinnyMethodAdapter mv = new SkinnyMethodAdapter(builder.getClassVisitor(), ACC_PUBLIC | ACC_FINAL, m.getName(), sig(m.getReturnType(), parameterTypes), null, null); mv.start(); // Retrieve the invoker mv.aload(0); mv.getfield(builder.getClassNamePath(), field.name, ci(Invoker.class)); //Push ref to this mv.aload(0); //Construct the params array mv.pushInt(parameterTypes.length); mv.anewarray(p(Object.class)); int slot = 1; for (int i = 0; i < parameterTypes.length; i++) { mv.dup(); mv.pushInt(i); if (parameterTypes[i].equals(long.class)) { mv.lload(slot); mv.invokestatic(Long.class, "valueOf", Long.class, long.class); slot++; } else if (parameterTypes[i].equals(double.class)) { mv.dload(slot); mv.invokestatic(Double.class, "valueOf", Double.class, double.class); slot++; } else if (parameterTypes[i].equals(int.class)) { mv.iload(slot); mv.invokestatic(Integer.class, "valueOf", Integer.class, int.class); } else if (parameterTypes[i].equals(float.class)) { mv.fload(slot); mv.invokestatic(Float.class, "valueOf", Float.class, float.class); } else if (parameterTypes[i].equals(short.class)) { mv.iload(slot); mv.i2s(); mv.invokestatic(Short.class, "valueOf", Short.class, short.class); } else if (parameterTypes[i].equals(char.class)) { mv.iload(slot); mv.i2c(); mv.invokestatic(Character.class, "valueOf", Character.class, char.class); } else if (parameterTypes[i].equals(byte.class)) { mv.iload(slot); mv.i2b(); mv.invokestatic(Byte.class, "valueOf", Byte.class, byte.class); } else if (parameterTypes[i].equals(char.class)) { mv.iload(slot); mv.i2b(); mv.invokestatic(Boolean.class, "valueOf", Boolean.class, boolean.class); } else { mv.aload(slot); } mv.aastore(); slot++; } // call invoker(this, parameters) mv.invokeinterface(jnr.ffi.provider.Invoker.class, "invoke", Object.class, Object.class, Object[].class); Class returnType = m.getReturnType(); if (returnType.equals(long.class)) { mv.checkcast(Long.class); mv.invokevirtual(Long.class, "longValue", long.class); mv.lreturn(); } else if (returnType.equals(double.class)) { mv.checkcast(Double.class); mv.invokevirtual(Double.class, "doubleValue", double.class); mv.dreturn(); } else if (returnType.equals(int.class)) { mv.checkcast(Integer.class); mv.invokevirtual(Integer.class, "intValue", int.class); mv.ireturn(); } else if (returnType.equals(float.class)) { mv.checkcast(Float.class); mv.invokevirtual(Float.class, "floatValue", float.class); mv.freturn(); } else if (returnType.equals(short.class)) { mv.checkcast(Short.class); mv.invokevirtual(Short.class, "shortValue", short.class); mv.ireturn(); } else if (returnType.equals(char.class)) { mv.checkcast(Character.class); mv.invokevirtual(Character.class, "charValue", char.class); mv.ireturn(); } else if (returnType.equals(byte.class)) { mv.checkcast(Byte.class); mv.invokevirtual(Byte.class, "byteValue", byte.class); mv.ireturn(); } else if (returnType.equals(boolean.class)) { mv.checkcast(Boolean.class); mv.invokevirtual(Boolean.class, "booleanValue", boolean.class); mv.ireturn(); } else if (void.class.isAssignableFrom(m.getReturnType())) { mv.voidreturn(); } else { mv.checkcast(m.getReturnType()); mv.areturn(); } mv.visitMaxs(100, AsmUtil.calculateLocalVariableSpace(parameterTypes) + 1); mv.visitEnd(); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/AsmRuntime.java000066400000000000000000000203321316720554100261010ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import com.kenai.jffi.*; import jnr.ffi.Address; import jnr.ffi.Pointer; import jnr.ffi.mapper.ToNativeContext; import jnr.ffi.mapper.ToNativeConverter; import jnr.ffi.provider.*; import java.nio.*; import java.nio.charset.Charset; /** * Utility methods that are used at runtime by generated code. */ public final class AsmRuntime { public static final com.kenai.jffi.MemoryIO IO = com.kenai.jffi.MemoryIO.getInstance(); private AsmRuntime() {} public static UnsatisfiedLinkError newUnsatisifiedLinkError(String msg) { return new UnsatisfiedLinkError(msg); } public static HeapInvocationBuffer newHeapInvocationBuffer(Function function) { return new HeapInvocationBuffer(function); } public static HeapInvocationBuffer newHeapInvocationBuffer(CallContext callContext) { return new HeapInvocationBuffer(callContext); } public static HeapInvocationBuffer newHeapInvocationBuffer(CallContext callContext, int objCount) { return new HeapInvocationBuffer(callContext, objCount); } public static Pointer pointerValue(long ptr, jnr.ffi.Runtime runtime) { return ptr != 0 ? new DirectMemoryIO(runtime, ptr) : null; } public static Pointer pointerValue(int ptr, jnr.ffi.Runtime runtime) { return ptr != 0 ? new DirectMemoryIO(runtime, ptr) : null; } public static boolean isDirect(Pointer ptr) { return ptr == null || ptr.isDirect(); } public static int intValue(Pointer ptr) { return ptr != null ? (int) ptr.address() : 0; } public static long longValue(Pointer ptr) { return ptr != null ? ptr.address() : 0L; } public static long longValue(Address ptr) { return ptr != null ? ptr.longValue() : 0L; } public static int intValue(Address ptr) { return ptr != null ? ptr.intValue() : 0; } public static long longValue(Buffer ptr) { return ptr != null && ptr.isDirect() ? MemoryIO.getInstance().getDirectBufferAddress(ptr) : 0L; } public static int intValue(Buffer ptr) { return ptr != null && ptr.isDirect() ? (int) MemoryIO.getInstance().getDirectBufferAddress(ptr) : 0; } public static ParameterStrategy nullParameterStrategy() { return NullObjectParameterStrategy.NULL; } public static PointerParameterStrategy directPointerParameterStrategy() { return PointerParameterStrategy.DIRECT; } public static PointerParameterStrategy pointerParameterStrategy(Pointer pointer) { if (pointer == null || pointer.isDirect()) { return PointerParameterStrategy.DIRECT; } else { return otherPointerParameterStrategy(pointer); } } private static PointerParameterStrategy otherPointerParameterStrategy(Pointer pointer) { if (pointer.hasArray()) { return PointerParameterStrategy.HEAP; } else { throw new RuntimeException("cannot convert " + pointer.getClass() + " to native"); } } public static BufferParameterStrategy bufferParameterStrategy(Buffer buffer, ObjectParameterType.ComponentType componentType) { if (buffer == null || buffer.isDirect()) { return BufferParameterStrategy.direct(componentType); } else if (buffer.hasArray()) { return BufferParameterStrategy.heap(componentType); } else { throw new IllegalArgumentException("cannot marshal non-direct, non-array Buffer"); } } public static BufferParameterStrategy pointerParameterStrategy(Buffer buffer) { if (buffer instanceof ByteBuffer) { return bufferParameterStrategy(buffer, ObjectParameterType.BYTE); } else if (buffer instanceof ShortBuffer) { return bufferParameterStrategy(buffer, ObjectParameterType.SHORT); } else if (buffer instanceof CharBuffer) { return bufferParameterStrategy(buffer, ObjectParameterType.CHAR); } else if (buffer instanceof IntBuffer) { return bufferParameterStrategy(buffer, ObjectParameterType.INT); } else if (buffer instanceof LongBuffer) { return bufferParameterStrategy(buffer, ObjectParameterType.LONG); } else if (buffer instanceof FloatBuffer) { return bufferParameterStrategy(buffer, ObjectParameterType.FLOAT); } else if (buffer instanceof DoubleBuffer) { return bufferParameterStrategy(buffer, ObjectParameterType.DOUBLE); } else if (buffer == null) { return BufferParameterStrategy.direct(ObjectParameterType.BYTE); } else { throw new IllegalArgumentException("unsupported java.nio.Buffer subclass: " + buffer.getClass()); } } public static BufferParameterStrategy pointerParameterStrategy(ByteBuffer buffer) { return bufferParameterStrategy(buffer, ObjectParameterType.BYTE); } public static BufferParameterStrategy pointerParameterStrategy(ShortBuffer buffer) { return bufferParameterStrategy(buffer, ObjectParameterType.SHORT); } public static BufferParameterStrategy pointerParameterStrategy(CharBuffer buffer) { return bufferParameterStrategy(buffer, ObjectParameterType.CHAR); } public static BufferParameterStrategy pointerParameterStrategy(IntBuffer buffer) { return bufferParameterStrategy(buffer, ObjectParameterType.INT); } public static BufferParameterStrategy pointerParameterStrategy(LongBuffer buffer) { return bufferParameterStrategy(buffer, ObjectParameterType.LONG); } public static BufferParameterStrategy pointerParameterStrategy(FloatBuffer buffer) { return bufferParameterStrategy(buffer, ObjectParameterType.FLOAT); } public static BufferParameterStrategy pointerParameterStrategy(DoubleBuffer buffer) { return bufferParameterStrategy(buffer, ObjectParameterType.DOUBLE); } public static ParameterStrategy pointerParameterStrategy(byte[] array) { return array != null ? PrimitiveArrayParameterStrategy.BYTE : NullObjectParameterStrategy.NULL; } public static ParameterStrategy pointerParameterStrategy(short[] array) { return array != null ? PrimitiveArrayParameterStrategy.SHORT : NullObjectParameterStrategy.NULL; } public static ParameterStrategy pointerParameterStrategy(char[] array) { return array != null ? PrimitiveArrayParameterStrategy.CHAR : NullObjectParameterStrategy.NULL; } public static ParameterStrategy pointerParameterStrategy(int[] array) { return array != null ? PrimitiveArrayParameterStrategy.INT : NullObjectParameterStrategy.NULL; } public static ParameterStrategy pointerParameterStrategy(long[] array) { return array != null ? PrimitiveArrayParameterStrategy.LONG : NullObjectParameterStrategy.NULL; } public static ParameterStrategy pointerParameterStrategy(float[] array) { return array != null ? PrimitiveArrayParameterStrategy.FLOAT : NullObjectParameterStrategy.NULL; } public static ParameterStrategy pointerParameterStrategy(double[] array) { return array != null ? PrimitiveArrayParameterStrategy.DOUBLE : NullObjectParameterStrategy.NULL; } public static ParameterStrategy pointerParameterStrategy(boolean[] array) { return array != null ? PrimitiveArrayParameterStrategy.BOOLEAN : NullObjectParameterStrategy.NULL; } public static void postInvoke(ToNativeConverter.PostInvocation postInvocation, Object j, Object n, ToNativeContext context) { try { postInvocation.postInvoke(j, n, context); } catch (Throwable t) {} } } AsmStructByReferenceFromNativeConverter.java000066400000000000000000000157341316720554100336720ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import jnr.ffi.Pointer; import jnr.ffi.Runtime; import jnr.ffi.Struct; import jnr.ffi.mapper.FromNativeContext; import jnr.ffi.mapper.FromNativeConverter; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Label; import java.io.PrintWriter; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Modifier; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; import static jnr.ffi.provider.jffi.CodegenUtils.*; import static org.objectweb.asm.Opcodes.*; @FromNativeConverter.NoContext @FromNativeConverter.Cacheable abstract public class AsmStructByReferenceFromNativeConverter implements FromNativeConverter { private final jnr.ffi.Runtime runtime; private final int flags; protected AsmStructByReferenceFromNativeConverter(jnr.ffi.Runtime runtime, int flags) { this.runtime = runtime; this.flags = flags; } public final Class nativeType() { return Pointer.class; } // getRuntime() is called from generated code protected final jnr.ffi.Runtime getRuntime() { return runtime; } static final Map, Class> converterClasses = new ConcurrentHashMap, Class>(); static AsmStructByReferenceFromNativeConverter newStructByReferenceConverter(jnr.ffi.Runtime runtime, Class structClass, int flags, AsmClassLoader classLoader) { try { return newStructByReferenceClass(structClass, classLoader).getConstructor(jnr.ffi.Runtime.class, int.class).newInstance(runtime, flags); } catch (NoSuchMethodException nsme) { throw new RuntimeException(nsme); } catch (IllegalAccessException iae) { throw new RuntimeException(iae); } catch (InstantiationException ie) { throw new RuntimeException(ie); } catch (InvocationTargetException ite) { throw new RuntimeException(ite); } } private static final AtomicLong nextClassID = new AtomicLong(0); static Class newStructByReferenceClass(Class structClass, AsmClassLoader classLoader) { try { Constructor cons = structClass.asSubclass(Struct.class).getConstructor(jnr.ffi.Runtime.class); if (!Modifier.isPublic(cons.getModifiers())) { throw new RuntimeException(structClass.getName() + " constructor is not public"); } } catch (NoSuchMethodException ex) { throw new RuntimeException("struct subclass " + structClass.getName() + " has no constructor that takes a " + jnr.ffi.Runtime.class.getName(), ex); } ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); ClassVisitor cv = AsmLibraryLoader.DEBUG ? AsmUtil.newCheckClassAdapter(cw) : cw; final String className = p(structClass) + "$$jnr$$StructByReferenceFromNativeConverter$$" + nextClassID.getAndIncrement(); cv.visit(V1_5, ACC_PUBLIC | ACC_FINAL, className, null, p(AsmStructByReferenceFromNativeConverter.class), new String[0]); cv.visitAnnotation(ci(FromNativeConverter.NoContext.class), true); // Create the constructor to set the instance fields SkinnyMethodAdapter init = new SkinnyMethodAdapter(cv, ACC_PUBLIC, "", sig(void.class, jnr.ffi.Runtime.class, int.class), null, null); init.start(); // Invoke the super class constructor as super(Library) init.aload(0); init.aload(1); init.iload(2); init.invokespecial(p(AsmStructByReferenceFromNativeConverter.class), "", sig(void.class, jnr.ffi.Runtime.class, int.class)); init.voidreturn(); init.visitMaxs(10, 10); init.visitEnd(); SkinnyMethodAdapter fromNative = new SkinnyMethodAdapter(cv, ACC_PUBLIC | ACC_FINAL, "fromNative", sig(structClass, Pointer.class, FromNativeContext.class), null, null); fromNative.start(); Label nullPointer = new Label(); fromNative.aload(1); fromNative.ifnull(nullPointer); // Create an instance of the struct subclass fromNative.newobj(p(structClass)); fromNative.dup(); fromNative.aload(0); fromNative.invokevirtual(p(AsmStructByReferenceFromNativeConverter.class), "getRuntime", sig(Runtime.class)); fromNative.invokespecial(structClass, "", void.class, jnr.ffi.Runtime.class); // associate the memory with the struct and return the struct fromNative.dup(); fromNative.aload(1); fromNative.invokevirtual(structClass, "useMemory", void.class, Pointer.class); fromNative.areturn(); fromNative.label(nullPointer); fromNative.aconst_null(); fromNative.areturn(); fromNative.visitAnnotation(ci(FromNativeConverter.NoContext.class), true); fromNative.visitMaxs(10, 10); fromNative.visitEnd(); fromNative = new SkinnyMethodAdapter(cv, ACC_PUBLIC | ACC_FINAL, "fromNative", sig(Object.class, Object.class, FromNativeContext.class), null, null); fromNative.start(); fromNative.aload(0); fromNative.aload(1); fromNative.checkcast(Pointer.class); fromNative.aload(2); fromNative.invokevirtual(className, "fromNative", sig(structClass, Pointer.class, FromNativeContext.class)); fromNative.areturn(); fromNative.visitAnnotation(ci(FromNativeConverter.NoContext.class), true); fromNative.visitMaxs(10, 10); fromNative.visitEnd(); cv.visitEnd(); try { byte[] bytes = cw.toByteArray(); if (AsmLibraryLoader.DEBUG) { ClassVisitor trace = AsmUtil.newTraceClassVisitor(new PrintWriter(System.err)); new ClassReader(bytes).accept(trace, 0); } return classLoader.defineClass(className.replace("/", "."), bytes); } catch (Throwable ex) { throw new RuntimeException(ex); } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/AsmUtil.java000066400000000000000000000615711316720554100254050ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import com.kenai.jffi.Platform; import jnr.ffi.Address; import jnr.ffi.Pointer; import jnr.ffi.annotations.Delegate; import jnr.ffi.mapper.FromNativeContext; import jnr.ffi.mapper.FromNativeConverter; import jnr.ffi.mapper.ToNativeContext; import jnr.ffi.mapper.ToNativeConverter; import jnr.ffi.provider.*; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.Label; import org.objectweb.asm.MethodVisitor; import java.io.OutputStream; import java.io.PrintWriter; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Collection; import static jnr.ffi.provider.jffi.CodegenUtils.*; import static jnr.ffi.provider.jffi.CodegenUtils.p; import static jnr.ffi.provider.jffi.NumberUtil.*; final class AsmUtil { private AsmUtil() {} public static MethodVisitor newTraceMethodVisitor(MethodVisitor mv) { try { Class tmvClass = Class.forName("org.objectweb.asm.util.TraceMethodVisitor").asSubclass(MethodVisitor.class); Constructor c = tmvClass.getDeclaredConstructor(MethodVisitor.class); return c.newInstance(mv); } catch (Throwable t) { return mv; } } public static ClassVisitor newTraceClassVisitor(ClassVisitor cv, OutputStream out) { return newTraceClassVisitor(cv, new PrintWriter(out, true)); } public static ClassVisitor newTraceClassVisitor(ClassVisitor cv, PrintWriter out) { try { Class tmvClass = Class.forName("org.objectweb.asm.util.TraceClassVisitor").asSubclass(ClassVisitor.class); Constructor c = tmvClass.getDeclaredConstructor(ClassVisitor.class, PrintWriter.class); return c.newInstance(cv, out); } catch (Throwable t) { return cv; } } public static ClassVisitor newTraceClassVisitor(PrintWriter out) { try { Class tmvClass = Class.forName("org.objectweb.asm.util.TraceClassVisitor").asSubclass(ClassVisitor.class); Constructor c = tmvClass.getDeclaredConstructor(PrintWriter.class); return c.newInstance(out); } catch (Throwable t) { throw new RuntimeException(t); } } public static ClassVisitor newCheckClassAdapter(ClassVisitor cv) { try { Class tmvClass = Class.forName("org.objectweb.asm.util.CheckClassAdapter").asSubclass(ClassVisitor.class); Constructor c = tmvClass.getDeclaredConstructor(ClassVisitor.class); return c.newInstance(cv); } catch (Throwable t) { return cv; } } public static Class unboxedReturnType(Class type) { return unboxedType(type); } public static Class unboxedType(Class boxedType) { if (boxedType == Byte.class) { return byte.class; } else if (boxedType == Short.class) { return short.class; } else if (boxedType == Integer.class) { return int.class; } else if (boxedType == Long.class) { return long.class; } else if (boxedType == Float.class) { return float.class; } else if (boxedType == Double.class) { return double.class; } else if (boxedType == Boolean.class) { return boolean.class; } else if (Pointer.class.isAssignableFrom(boxedType)) { return Platform.getPlatform().addressSize() == 32 ? int.class : long.class; } else if (Address.class == boxedType) { return Platform.getPlatform().addressSize() == 32 ? int.class : long.class; } else { return boxedType; } } public static Class boxedType(Class type) { if (type == byte.class) { return Byte.class; } else if (type == short.class) { return Short.class; } else if (type == int.class) { return Integer.class; } else if (type == long.class) { return Long.class; } else if (type == float.class) { return Float.class; } else if (type == double.class) { return Double.class; } else if (type == boolean.class) { return Boolean.class; } else { return type; } } static void emitReturnOp(SkinnyMethodAdapter mv, Class returnType) { if (!returnType.isPrimitive()) { mv.areturn(); } else if (long.class == returnType) { mv.lreturn(); } else if (float.class == returnType) { mv.freturn(); } else if (double.class == returnType) { mv.dreturn(); } else if (void.class == returnType) { mv.voidreturn(); } else { mv.ireturn(); } } /** * Calculates the size of a local variable * * @param type The type of parameter * @return The size in parameter units */ static int calculateLocalVariableSpace(Class type) { return long.class == type || double.class == type ? 2 : 1; } /** * Calculates the size of a local variable * * @param type The type of parameter * @return The size in parameter units */ static int calculateLocalVariableSpace(SigType type) { return calculateLocalVariableSpace(type.getDeclaredType()); } /** * Calculates the size of a list of types in the local variable area. * * @param types The type of parameter * @return The size in parameter units */ static int calculateLocalVariableSpace(Class... types) { int size = 0; for (int i = 0; i < types.length; ++i) { size += calculateLocalVariableSpace(types[i]); } return size; } /** * Calculates the size of a list of types in the local variable area. * * @param types The type of parameter * @return The size in parameter units */ static int calculateLocalVariableSpace(SigType... types) { int size = 0; for (SigType type : types) { size += calculateLocalVariableSpace(type); } return size; } private static void unboxPointerOrStruct(final SkinnyMethodAdapter mv, final Class type, final Class nativeType) { mv.invokestatic(p(AsmRuntime.class), long.class == nativeType ? "longValue" : "intValue", sig(nativeType, type)); } static void unboxPointer(final SkinnyMethodAdapter mv, final Class nativeType) { unboxPointerOrStruct(mv, Pointer.class, nativeType); } static void unboxBoolean(final SkinnyMethodAdapter mv, Class boxedType, final Class nativeType) { mv.invokevirtual(p(boxedType), "booleanValue", "()Z"); widen(mv, boolean.class, nativeType); } static void unboxBoolean(final SkinnyMethodAdapter mv, final Class nativeType) { unboxBoolean(mv, Boolean.class, nativeType); } static void unboxNumber(final SkinnyMethodAdapter mv, final Class boxedType, final Class unboxedType, final jnr.ffi.NativeType nativeType) { if (Number.class.isAssignableFrom(boxedType)) { switch (nativeType) { case SCHAR: case UCHAR: mv.invokevirtual(p(boxedType), "byteValue", "()B"); convertPrimitive(mv, byte.class, unboxedType, nativeType); break; case SSHORT: case USHORT: mv.invokevirtual(p(boxedType), "shortValue", "()S"); convertPrimitive(mv, short.class, unboxedType, nativeType); break; case SINT: case UINT: case SLONG: case ULONG: case ADDRESS: if (sizeof(nativeType) == 4) { mv.invokevirtual(p(boxedType), "intValue", "()I"); convertPrimitive(mv, int.class, unboxedType, nativeType); } else { mv.invokevirtual(p(boxedType), "longValue", "()J"); convertPrimitive(mv, long.class, unboxedType, nativeType); } break; case SLONGLONG: case ULONGLONG: mv.invokevirtual(p(boxedType), "longValue", "()J"); narrow(mv, long.class, unboxedType); break; case FLOAT: mv.invokevirtual(p(boxedType), "floatValue", "()F"); break; case DOUBLE: mv.invokevirtual(p(boxedType), "doubleValue", "()D"); break; } } else if (Boolean.class.isAssignableFrom(boxedType)) { unboxBoolean(mv, unboxedType); } else { throw new IllegalArgumentException("unsupported boxed type: " + boxedType); } } static void unboxNumber(final SkinnyMethodAdapter mv, final Class boxedType, final Class nativeType) { if (Number.class.isAssignableFrom(boxedType)) { if (byte.class == nativeType) { mv.invokevirtual(p(boxedType), "byteValue", "()B"); } else if (short.class == nativeType) { mv.invokevirtual(p(boxedType), "shortValue", "()S"); } else if (int.class == nativeType) { mv.invokevirtual(p(boxedType), "intValue", "()I"); } else if (long.class == nativeType) { mv.invokevirtual(p(boxedType), "longValue", "()J"); } else if (float.class == nativeType) { mv.invokevirtual(p(boxedType), "floatValue", "()F"); } else if (double.class == nativeType) { mv.invokevirtual(p(boxedType), "doubleValue", "()D"); } else { throw new IllegalArgumentException("unsupported Number subclass: " + boxedType); } } else if (Boolean.class.isAssignableFrom(boxedType)) { unboxBoolean(mv, nativeType); } else { throw new IllegalArgumentException("unsupported boxed type: " + boxedType); } } static void boxValue(AsmBuilder builder, SkinnyMethodAdapter mv, Class boxedType, Class unboxedType) { if (boxedType == unboxedType || boxedType.isPrimitive()) { } else if (Boolean.class.isAssignableFrom(boxedType)) { narrow(mv, unboxedType, boolean.class); mv.invokestatic(Boolean.class, "valueOf", Boolean.class, boolean.class); } else if (Pointer.class.isAssignableFrom(boxedType)) { getfield(mv, builder, builder.getRuntimeField()); mv.invokestatic(AsmRuntime.class, "pointerValue", Pointer.class, unboxedType, jnr.ffi.Runtime.class); } else if (Address.class == boxedType) { mv.invokestatic(boxedType, "valueOf", boxedType, unboxedType); } else if (Number.class.isAssignableFrom(boxedType) && boxedType(unboxedType) == boxedType) { mv.invokestatic(boxedType, "valueOf", boxedType, unboxedType); } else { throw new IllegalArgumentException("cannot box value of type " + unboxedType + " to " + boxedType); } } static int getNativeArrayFlags(int flags) { int nflags = 0; nflags |= ParameterFlags.isIn(flags) ? com.kenai.jffi.ArrayFlags.IN : 0; nflags |= ParameterFlags.isOut(flags) ? com.kenai.jffi.ArrayFlags.OUT : 0; nflags |= (ParameterFlags.isNulTerminate(flags) || ParameterFlags.isIn(flags)) ? com.kenai.jffi.ArrayFlags.NULTERMINATE : 0; return nflags; } static int getNativeArrayFlags(Collection annotations) { return getNativeArrayFlags(ParameterFlags.parse(annotations)); } static LocalVariable[] getParameterVariables(ParameterType[] parameterTypes) { LocalVariable[] lvars = new LocalVariable[parameterTypes.length]; int lvar = 1; for (int i = 0; i < parameterTypes.length; i++) { lvars[i] = new LocalVariable(parameterTypes[i].getDeclaredType(), lvar); lvar += calculateLocalVariableSpace(parameterTypes[i]); } return lvars; } static LocalVariable[] getParameterVariables(Class[] parameterTypes) { LocalVariable[] lvars = new LocalVariable[parameterTypes.length]; int idx = 1; for (int i = 0; i < parameterTypes.length; i++) { lvars[i] = new LocalVariable(parameterTypes[i], idx); idx += calculateLocalVariableSpace(parameterTypes[i]); } return lvars; } static void load(SkinnyMethodAdapter mv, Class parameterType, LocalVariable parameter) { if (!parameterType.isPrimitive()) { mv.aload(parameter); } else if (long.class == parameterType) { mv.lload(parameter); } else if (float.class == parameterType) { mv.fload(parameter); } else if (double.class == parameterType) { mv.dload(parameter); } else { mv.iload(parameter); } } static void store(SkinnyMethodAdapter mv, Class type, LocalVariable var) { if (!type.isPrimitive()) { mv.astore(var); } else if (long.class == type) { mv.lstore(var); } else if (double.class == type) { mv.dstore(var); } else if (float.class == type) { mv.fstore(var); } else { mv.istore(var); } } static void emitReturn(AsmBuilder builder, SkinnyMethodAdapter mv, Class returnType, Class nativeIntType) { if (returnType.isPrimitive()) { if (long.class == returnType) { mv.lreturn(); } else if (float.class == returnType) { mv.freturn(); } else if (double.class == returnType) { mv.dreturn(); } else if (void.class == returnType) { mv.voidreturn(); } else { mv.ireturn(); } } else { boxValue(builder, mv, returnType, nativeIntType); mv.areturn(); } } static void getfield(SkinnyMethodAdapter mv, AsmBuilder builder, AsmBuilder.ObjectField field) { mv.aload(0); mv.getfield(builder.getClassNamePath(), field.name, ci(field.klass)); } static void tryfinally(SkinnyMethodAdapter mv, Runnable codeBlock, Runnable finallyBlock) { Label before = new Label(), after = new Label(), ensure = new Label(), done = new Label(); mv.trycatch(before, after, ensure, null); mv.label(before); codeBlock.run(); mv.label(after); if (finallyBlock != null) finallyBlock.run(); mv.go_to(done); if (finallyBlock != null) { mv.label(ensure); finallyBlock.run(); mv.athrow(); } mv.label(done); } static void emitToNativeConversion(AsmBuilder builder, SkinnyMethodAdapter mv, ToNativeType toNativeType) { ToNativeConverter parameterConverter = toNativeType.getToNativeConverter(); if (parameterConverter != null) { Method toNativeMethod = getToNativeMethod(toNativeType, builder.getClassLoader()); if (toNativeType.getDeclaredType().isPrimitive()) { boxValue(builder, mv, getBoxedClass(toNativeType.getDeclaredType()), toNativeType.getDeclaredType()); } if (!toNativeMethod.getParameterTypes()[0].isAssignableFrom(getBoxedClass(toNativeType.getDeclaredType()))) { mv.checkcast(toNativeMethod.getParameterTypes()[0]); } mv.aload(0); AsmBuilder.ObjectField toNativeConverterField = builder.getToNativeConverterField(parameterConverter); mv.getfield(builder.getClassNamePath(), toNativeConverterField.name, ci(toNativeConverterField.klass)); if (!toNativeMethod.getDeclaringClass().equals(toNativeConverterField.klass)) { mv.checkcast(toNativeMethod.getDeclaringClass()); } // Re-order so the value to be converted is on the top of the stack mv.swap(); // load context parameter (if there is one) if (toNativeType.getToNativeContext() != null) { getfield(mv, builder, builder.getToNativeContextField(toNativeType.getToNativeContext())); } else { mv.aconst_null(); } if (toNativeMethod.getDeclaringClass().isInterface()) { mv.invokeinterface(toNativeMethod.getDeclaringClass(), toNativeMethod.getName(), toNativeMethod.getReturnType(), toNativeMethod.getParameterTypes()); } else { mv.invokevirtual(toNativeMethod.getDeclaringClass(), toNativeMethod.getName(), toNativeMethod.getReturnType(), toNativeMethod.getParameterTypes()); } if (!parameterConverter.nativeType().isAssignableFrom(toNativeMethod.getReturnType())) { mv.checkcast(p(parameterConverter.nativeType())); } } } static void emitFromNativeConversion(AsmBuilder builder, SkinnyMethodAdapter mv, FromNativeType fromNativeType, Class nativeClass) { // If there is a result converter, retrieve it and put on the stack FromNativeConverter fromNativeConverter = fromNativeType.getFromNativeConverter(); if (fromNativeConverter != null) { convertPrimitive(mv, nativeClass, unboxedType(fromNativeConverter.nativeType()), fromNativeType.getNativeType()); boxValue(builder, mv, fromNativeConverter.nativeType(), nativeClass); Method fromNativeMethod = getFromNativeMethod(fromNativeType, builder.getClassLoader()); getfield(mv, builder, builder.getFromNativeConverterField(fromNativeConverter)); mv.swap(); if (fromNativeType.getFromNativeContext() != null) { getfield(mv, builder, builder.getFromNativeContextField(fromNativeType.getFromNativeContext())); } else { mv.aconst_null(); } if (fromNativeMethod.getDeclaringClass().isInterface()) { mv.invokeinterface(fromNativeMethod.getDeclaringClass(), fromNativeMethod.getName(), fromNativeMethod.getReturnType(), fromNativeMethod.getParameterTypes()); } else { mv.invokevirtual(fromNativeMethod.getDeclaringClass(), fromNativeMethod.getName(), fromNativeMethod.getReturnType(), fromNativeMethod.getParameterTypes()); } if (fromNativeType.getDeclaredType().isPrimitive()) { // The actual return type is a primitive, but there was a converter for it - extract the primitive value Class boxedType = getBoxedClass(fromNativeType.getDeclaredType()); if (!boxedType.isAssignableFrom(fromNativeMethod.getReturnType())) mv.checkcast(p(boxedType)); unboxNumber(mv, boxedType, fromNativeType.getDeclaredType(), fromNativeType.getNativeType()); } else if (!fromNativeType.getDeclaredType().isAssignableFrom(fromNativeMethod.getReturnType())) { mv.checkcast(p(fromNativeType.getDeclaredType())); } } else if (!fromNativeType.getDeclaredType().isPrimitive()) { Class unboxedType = unboxedType(fromNativeType.getDeclaredType()); convertPrimitive(mv, nativeClass, unboxedType, fromNativeType.getNativeType()); boxValue(builder, mv, fromNativeType.getDeclaredType(), unboxedType); } } static Method getToNativeMethod(ToNativeType toNativeType, AsmClassLoader classLoader) { ToNativeConverter toNativeConverter = toNativeType.getToNativeConverter(); if (toNativeConverter == null) { return null; } try { Class toNativeConverterClass = toNativeConverter.getClass(); if (Modifier.isPublic(toNativeConverterClass.getModifiers())) { for (Method method : toNativeConverterClass.getMethods()) { if (!method.getName().equals("toNative")) continue; Class[] methodParameterTypes = method.getParameterTypes(); if (toNativeConverter.nativeType().isAssignableFrom(method.getReturnType()) && methodParameterTypes.length == 2 && methodParameterTypes[0].isAssignableFrom(toNativeType.getDeclaredType()) && methodParameterTypes[1] == ToNativeContext.class && methodIsAccessible(method) && classIsVisible(classLoader, method.getDeclaringClass())) { return method; } } } Method method = toNativeConverterClass.getMethod("toNative", Object.class, ToNativeContext.class); return methodIsAccessible(method) && classIsVisible(classLoader, method.getDeclaringClass()) ? method : ToNativeConverter.class.getDeclaredMethod("toNative", Object.class, ToNativeContext.class); } catch (NoSuchMethodException nsme) { try { return ToNativeConverter.class.getDeclaredMethod("toNative", Object.class, ToNativeContext.class); } catch (NoSuchMethodException nsme2) { throw new RuntimeException("internal error. " + ToNativeConverter.class + " has no toNative() method"); } } } static Method getFromNativeMethod(FromNativeType fromNativeType, AsmClassLoader classLoader) { FromNativeConverter fromNativeConverter = fromNativeType.getFromNativeConverter(); if (fromNativeConverter == null) { return null; } try { Class fromNativeConverterClass = fromNativeConverter.getClass(); if (Modifier.isPublic(fromNativeConverterClass.getModifiers())) { for (Method method : fromNativeConverterClass.getMethods()) { if (!method.getName().equals("fromNative")) continue; Class[] methodParameterTypes = method.getParameterTypes(); Class javaType = fromNativeType.getDeclaredType().isPrimitive() ? boxedType(fromNativeType.getDeclaredType()) : fromNativeType.getDeclaredType(); if (javaType.isAssignableFrom(method.getReturnType()) && methodParameterTypes.length == 2 && methodParameterTypes[0].isAssignableFrom(fromNativeConverter.nativeType()) && methodParameterTypes[1] == FromNativeContext.class && methodIsAccessible(method) && classIsVisible(classLoader, method.getDeclaringClass())) { return method; } } } Method method = fromNativeConverterClass.getMethod("fromNative", Object.class, FromNativeContext.class); return methodIsAccessible(method) && classIsVisible(classLoader, method.getDeclaringClass()) ? method : FromNativeConverter.class.getDeclaredMethod("fromNative", Object.class, FromNativeContext.class); } catch (NoSuchMethodException nsme) { try { return FromNativeConverter.class.getDeclaredMethod("fromNative", Object.class, FromNativeContext.class); } catch (NoSuchMethodException nsme2) { throw new RuntimeException("internal error. " + FromNativeConverter.class + " has no fromNative() method"); } } } static boolean methodIsAccessible(Method method) { return Modifier.isPublic(method.getModifiers()) && Modifier.isPublic(method.getDeclaringClass().getModifiers()); } private static boolean classIsVisible(ClassLoader classLoader, Class klass) { try { return classLoader.loadClass(klass.getName()) == klass; } catch (ClassNotFoundException cnfe) { return false; } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/BaseMethodGenerator.java000066400000000000000000000151011316720554100276750ustar00rootroot00000000000000/* * Copyright (C) 2011 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import com.kenai.jffi.CallContext; import com.kenai.jffi.Function; import jnr.ffi.mapper.*; import jnr.ffi.provider.*; import static jnr.ffi.provider.jffi.AsmUtil.*; import static jnr.ffi.provider.jffi.CodegenUtils.*; import static org.objectweb.asm.Opcodes.ACC_FINAL; import static org.objectweb.asm.Opcodes.ACC_PUBLIC; /** * */ abstract class BaseMethodGenerator implements MethodGenerator { public void generate(AsmBuilder builder, String functionName, Function function, ResultType resultType, ParameterType[] parameterTypes, boolean ignoreError) { Class[] javaParameterTypes = new Class[parameterTypes.length]; for (int i = 0; i < parameterTypes.length; i++) { javaParameterTypes[i] = parameterTypes[i].getDeclaredType(); } SkinnyMethodAdapter mv = new SkinnyMethodAdapter(builder.getClassVisitor(), ACC_PUBLIC | ACC_FINAL, functionName, sig(resultType.getDeclaredType(), javaParameterTypes), null, null); mv.start(); // Retrieve the static 'ffi' Invoker instance mv.getstatic(p(AbstractAsmLibraryInterface.class), "ffi", ci(com.kenai.jffi.Invoker.class)); // retrieve the call context and function address mv.aload(0); mv.getfield(builder.getClassNamePath(), builder.getCallContextFieldName(function.getCallContext()), ci(CallContext.class)); mv.aload(0); mv.getfield(builder.getClassNamePath(), builder.getFunctionAddressFieldName(function), ci(long.class)); LocalVariableAllocator localVariableAllocator = new LocalVariableAllocator(parameterTypes); generate(builder, mv, localVariableAllocator, function.getCallContext(), resultType, parameterTypes, ignoreError); mv.visitMaxs(100, localVariableAllocator.getSpaceUsed()); mv.visitEnd(); } abstract void generate(AsmBuilder builder, SkinnyMethodAdapter mv, LocalVariableAllocator localVariableAllocator, CallContext callContext, ResultType resultType, ParameterType[] parameterTypes, boolean ignoreError); static LocalVariable loadAndConvertParameter(AsmBuilder builder, SkinnyMethodAdapter mv, LocalVariableAllocator localVariableAllocator, LocalVariable parameter, jnr.ffi.provider.ToNativeType parameterType) { AsmUtil.load(mv, parameterType.getDeclaredType(), parameter); emitToNativeConversion(builder, mv, parameterType); if (parameterType.getToNativeConverter() != null) { LocalVariable converted = localVariableAllocator.allocate(parameterType.getToNativeConverter().nativeType()); mv.astore(converted); mv.aload(converted); return converted; } return parameter; } static boolean isPostInvokeRequired(ParameterType[] parameterTypes) { for (ParameterType parameterType : parameterTypes) { if (parameterType.getToNativeConverter() instanceof ToNativeConverter.PostInvocation) { return true; } } return false; } static void emitEpilogue(final AsmBuilder builder, final SkinnyMethodAdapter mv, final ResultType resultType, final ParameterType[] parameterTypes, final LocalVariable[] parameters, final LocalVariable[] converted, final Runnable sessionCleanup) { final Class unboxedResultType = unboxedReturnType(resultType.effectiveJavaType()); if (isPostInvokeRequired(parameterTypes) || sessionCleanup != null) { tryfinally(mv, new Runnable() { public void run() { emitFromNativeConversion(builder, mv, resultType, unboxedResultType); // ensure there is always at least one instruction inside the try {} block mv.nop(); } }, new Runnable() { public void run() { emitPostInvoke(builder, mv, parameterTypes, parameters, converted); if (sessionCleanup != null) { sessionCleanup.run(); } } } ); } else { emitFromNativeConversion(builder, mv, resultType, unboxedResultType); } emitReturnOp(mv, resultType.getDeclaredType()); } static void emitPostInvoke(AsmBuilder builder, final SkinnyMethodAdapter mv, ParameterType[] parameterTypes, LocalVariable[] parameters, LocalVariable[] converted) { for (int i = 0; i < converted.length; ++i) { if (converted[i] != null && parameterTypes[i].getToNativeConverter() instanceof ToNativeConverter.PostInvocation) { mv.aload(0); AsmBuilder.ObjectField toNativeConverterField = builder.getToNativeConverterField(parameterTypes[i].getToNativeConverter()); mv.getfield(builder.getClassNamePath(), toNativeConverterField.name, ci(toNativeConverterField.klass)); if (!ToNativeConverter.PostInvocation.class.isAssignableFrom(toNativeConverterField.klass)) { mv.checkcast(ToNativeConverter.PostInvocation.class); } mv.aload(parameters[i]); mv.aload(converted[i]); if (parameterTypes[i].getToNativeContext() != null) { getfield(mv, builder, builder.getToNativeContextField(parameterTypes[i].getToNativeContext())); } else { mv.aconst_null(); } mv.invokestatic(AsmRuntime.class, "postInvoke", void.class, ToNativeConverter.PostInvocation.class, Object.class, Object.class, ToNativeContext.class); } } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/BufferMethodGenerator.java000066400000000000000000000234451316720554100302460ustar00rootroot00000000000000/* * Copyright (C) 2011 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import com.kenai.jffi.CallContext; import com.kenai.jffi.HeapInvocationBuffer; import com.kenai.jffi.Invoker; import com.kenai.jffi.ObjectParameterStrategy; import jnr.ffi.NativeType; import jnr.ffi.provider.InvocationSession; import jnr.ffi.CallingConvention; import jnr.ffi.provider.ParameterType; import jnr.ffi.provider.ResultType; import java.util.Collections; import java.util.EnumMap; import java.util.Map; import static jnr.ffi.provider.jffi.AbstractFastNumericMethodGenerator.emitParameterStrategyLookup; import static jnr.ffi.provider.jffi.AbstractFastNumericMethodGenerator.hasPointerParameterStrategy; import static jnr.ffi.provider.jffi.AsmUtil.unboxedReturnType; import static jnr.ffi.provider.jffi.CodegenUtils.*; import static jnr.ffi.provider.jffi.NumberUtil.convertPrimitive; import static jnr.ffi.provider.jffi.NumberUtil.sizeof; /** * */ final class BufferMethodGenerator extends BaseMethodGenerator { private static abstract class Operation { final String methodName; final Class primitiveClass; private Operation(String methodName, Class primitiveClass) { this.methodName = methodName; this.primitiveClass = primitiveClass; } } private static final class MarshalOp extends Operation { private MarshalOp(String methodName, Class primitiveClass) { super("put" + methodName, primitiveClass); } } private static final class InvokeOp extends Operation { private InvokeOp(String methodName, Class primitiveClass) { super("invoke" + methodName, primitiveClass); } } static final Map marshalOps; static final Map invokeOps; static { Map mops = new EnumMap(NativeType.class); Map iops = new EnumMap(NativeType.class); mops.put(NativeType.SCHAR, new MarshalOp("Byte", int.class)); mops.put(NativeType.UCHAR, new MarshalOp("Byte", int.class)); mops.put(NativeType.SSHORT, new MarshalOp("Short", int.class)); mops.put(NativeType.USHORT, new MarshalOp("Short", int.class)); mops.put(NativeType.SINT, new MarshalOp("Int", int.class)); mops.put(NativeType.UINT, new MarshalOp("Int", int.class)); mops.put(NativeType.SLONGLONG, new MarshalOp("Long", long.class)); mops.put(NativeType.ULONGLONG, new MarshalOp("Long", long.class)); mops.put(NativeType.FLOAT, new MarshalOp("Float", float.class)); mops.put(NativeType.DOUBLE, new MarshalOp("Double", double.class)); mops.put(NativeType.ADDRESS, new MarshalOp("Address", long.class)); if (sizeof(NativeType.SLONG) == 4) { mops.put(NativeType.SLONG, new MarshalOp("Int", int.class)); mops.put(NativeType.ULONG, new MarshalOp("Int", int.class)); } else { mops.put(NativeType.SLONG, new MarshalOp("Long", long.class)); mops.put(NativeType.ULONG, new MarshalOp("Long", long.class)); } iops.put(NativeType.SCHAR, new InvokeOp("Int", int.class)); iops.put(NativeType.UCHAR, new InvokeOp("Int", int.class)); iops.put(NativeType.SSHORT, new InvokeOp("Int", int.class)); iops.put(NativeType.USHORT, new InvokeOp("Int", int.class)); iops.put(NativeType.SINT, new InvokeOp("Int", int.class)); iops.put(NativeType.UINT, new InvokeOp("Int", int.class)); iops.put(NativeType.VOID, new InvokeOp("Int", int.class)); iops.put(NativeType.SLONGLONG, new InvokeOp("Long", long.class)); iops.put(NativeType.ULONGLONG, new InvokeOp("Long", long.class)); iops.put(NativeType.FLOAT, new InvokeOp("Float", float.class)); iops.put(NativeType.DOUBLE, new InvokeOp("Double", double.class)); iops.put(NativeType.ADDRESS, new InvokeOp("Address", long.class)); if (sizeof(NativeType.SLONG) == 4) { iops.put(NativeType.SLONG, new InvokeOp("Int", int.class)); iops.put(NativeType.ULONG, new InvokeOp("Int", int.class)); } else { iops.put(NativeType.SLONG, new InvokeOp("Long", long.class)); iops.put(NativeType.ULONG, new InvokeOp("Long", long.class)); } marshalOps = Collections.unmodifiableMap(mops); invokeOps = Collections.unmodifiableMap(iops); } @Override void generate(AsmBuilder builder, SkinnyMethodAdapter mv, LocalVariableAllocator localVariableAllocator, CallContext callContext, ResultType resultType, ParameterType[] parameterTypes, boolean ignoreError) { generateBufferInvocation(builder, mv, localVariableAllocator, callContext, resultType, parameterTypes); } public boolean isSupported(ResultType resultType, ParameterType[] parameterTypes, CallingConvention callingConvention) { // Buffer invocation supports everything return true; } private static void emitPrimitiveOp(final SkinnyMethodAdapter mv, ParameterType parameterType, ToNativeOp op) { MarshalOp marshalOp = marshalOps.get(parameterType.getNativeType()); if (marshalOp == null) { throw new IllegalArgumentException("unsupported parameter type " + parameterType); } op.emitPrimitive(mv, marshalOp.primitiveClass, parameterType.getNativeType()); mv.invokevirtual(HeapInvocationBuffer.class, marshalOp.methodName, void.class, marshalOp.primitiveClass); } static boolean isSessionRequired(ParameterType parameterType) { return false; } static boolean isSessionRequired(ParameterType[] parameterTypes) { for (ParameterType parameterType : parameterTypes) { if (isSessionRequired(parameterType)) { return true; } } return false; } void generateBufferInvocation(final AsmBuilder builder, final SkinnyMethodAdapter mv, LocalVariableAllocator localVariableAllocator, CallContext callContext, final ResultType resultType, final ParameterType[] parameterTypes) { // [ stack contains: Invoker, Function ] final boolean sessionRequired = isSessionRequired(parameterTypes); final LocalVariable session = localVariableAllocator.allocate(InvocationSession.class); if (sessionRequired) { mv.newobj(p(InvocationSession.class)); mv.dup(); mv.invokespecial(InvocationSession.class, "", void.class); mv.astore(session); } // Create a new InvocationBuffer mv.aload(0); mv.getfield(builder.getClassNamePath(), builder.getCallContextFieldName(callContext), ci(CallContext.class)); mv.invokestatic(AsmRuntime.class, "newHeapInvocationBuffer", HeapInvocationBuffer.class, CallContext.class); // [ stack contains: Invoker, Function, HeapInvocationBuffer ] final LocalVariable[] parameters = AsmUtil.getParameterVariables(parameterTypes); final LocalVariable[] converted = new LocalVariable[parameterTypes.length]; LocalVariable[] strategies = new LocalVariable[parameterTypes.length]; for (int i = 0; i < parameterTypes.length; ++i) { mv.dup(); // dup ref to HeapInvocationBuffer if (isSessionRequired(parameterTypes[i])) { mv.aload(session); } converted[i] = loadAndConvertParameter(builder, mv, localVariableAllocator, parameters[i], parameterTypes[i]); final Class javaParameterType = parameterTypes[i].effectiveJavaType(); ToNativeOp op = ToNativeOp.get(parameterTypes[i]); if (op != null && op.isPrimitive()) { emitPrimitiveOp(mv, parameterTypes[i], op); } else if (hasPointerParameterStrategy(javaParameterType)) { emitParameterStrategyLookup(mv, javaParameterType); mv.astore(strategies[i] = localVariableAllocator.allocate(PointerParameterStrategy.class)); mv.aload(converted[i]); mv.aload(strategies[i]); mv.pushInt(AsmUtil.getNativeArrayFlags(parameterTypes[i].annotations())); mv.invokevirtual(HeapInvocationBuffer.class, "putObject", void.class, Object.class, ObjectParameterStrategy.class, int.class); } else { throw new IllegalArgumentException("unsupported parameter type " + parameterTypes[i]); } } InvokeOp iop = invokeOps.get(resultType.getNativeType()); if (iop == null) { throw new IllegalArgumentException("unsupported return type " + resultType.getDeclaredType()); } mv.invokevirtual(Invoker.class, iop.methodName, iop.primitiveClass, CallContext.class, long.class, HeapInvocationBuffer.class); // box and/or narrow/widen the return value if needed convertPrimitive(mv, iop.primitiveClass, unboxedReturnType(resultType.effectiveJavaType()), resultType.getNativeType()); emitEpilogue(builder, mv, resultType, parameterTypes, parameters, converted, sessionRequired ? new Runnable() { public void run() { mv.aload(session); mv.invokevirtual(p(InvocationSession.class), "finish", "()V"); } } : null); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/BufferParameterStrategy.java000066400000000000000000000067421316720554100306230ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import com.kenai.jffi.MemoryIO; import com.kenai.jffi.ObjectParameterType; import java.nio.Buffer; import java.util.EnumSet; /** * */ public final class BufferParameterStrategy extends ParameterStrategy { private final int shift; private BufferParameterStrategy(StrategyType type, ObjectParameterType.ComponentType componentType) { super(type, ObjectParameterType.create(ObjectParameterType.ObjectType.ARRAY, componentType)); this.shift = calculateShift(componentType); } public long address(Buffer buffer) { return buffer != null && buffer.isDirect() ? MemoryIO.getInstance().getDirectBufferAddress(buffer) + (buffer.position() << shift) : 0L; } @Override public long address(Object o) { return address((Buffer) o); } @Override public Object object(Object o) { return ((Buffer) o).array(); } @Override public int offset(Object o) { Buffer buffer = (Buffer) o; return buffer.arrayOffset() + buffer.position(); } @Override public int length(Object o) { return ((Buffer) o).remaining(); } static int calculateShift(ObjectParameterType.ComponentType componentType) { switch (componentType) { case BYTE: return 0; case SHORT: case CHAR: return 1; case INT: case BOOLEAN: case FLOAT: return 2; case LONG: case DOUBLE: return 3; default: throw new IllegalArgumentException("unsupported component type: " + componentType); } } private static final BufferParameterStrategy[] DIRECT_BUFFER_PARAMETER_STRATEGIES; private static final BufferParameterStrategy[] HEAP_BUFFER_PARAMETER_STRATEGIES; static { EnumSet componentTypes = EnumSet.allOf(ObjectParameterType.ComponentType.class); DIRECT_BUFFER_PARAMETER_STRATEGIES = new BufferParameterStrategy[componentTypes.size()]; HEAP_BUFFER_PARAMETER_STRATEGIES = new BufferParameterStrategy[componentTypes.size()]; for (ObjectParameterType.ComponentType componentType : componentTypes) { DIRECT_BUFFER_PARAMETER_STRATEGIES[componentType.ordinal()] = new BufferParameterStrategy(DIRECT, componentType); HEAP_BUFFER_PARAMETER_STRATEGIES[componentType.ordinal()] = new BufferParameterStrategy(HEAP, componentType); } } static BufferParameterStrategy direct(ObjectParameterType.ComponentType componentType) { return DIRECT_BUFFER_PARAMETER_STRATEGIES[componentType.ordinal()]; } static BufferParameterStrategy heap(ObjectParameterType.ComponentType componentType) { return HEAP_BUFFER_PARAMETER_STRATEGIES[componentType.ordinal()]; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/ByteBufferMemoryIO.java000066400000000000000000000032311316720554100274720ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import com.kenai.jffi.MemoryIO; import jnr.ffi.Pointer; import jnr.ffi.provider.AbstractBufferMemoryIO; import java.nio.ByteBuffer; public class ByteBufferMemoryIO extends AbstractBufferMemoryIO { public ByteBufferMemoryIO(jnr.ffi.Runtime runtime, ByteBuffer buffer) { super(runtime, buffer, address(buffer)); } public Pointer getPointer(long offset) { return MemoryUtil.newPointer(getRuntime(), getAddress(offset)); } public Pointer getPointer(long offset, long size) { return MemoryUtil.newPointer(getRuntime(), getAddress(offset), size); } public void putPointer(long offset, Pointer value) { putAddress(offset, value != null ? value.address() : 0L); } private static long address(ByteBuffer buffer) { if (buffer.isDirect()) { long address = MemoryIO.getInstance().getDirectBufferAddress(buffer); return address != 0L ? address + buffer.position() : 0L; } return 0L; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/ClosureFromNativeConverter.java000066400000000000000000000207631316720554100313240ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import com.kenai.jffi.CallContext; import jnr.ffi.CallingConvention; import jnr.ffi.Pointer; import jnr.ffi.annotations.StdCall; import jnr.ffi.mapper.*; import jnr.ffi.provider.InAccessibleMemoryIO; import jnr.ffi.provider.ParameterType; import jnr.ffi.provider.ResultType; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassWriter; import java.io.PrintWriter; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.concurrent.atomic.AtomicLong; import static jnr.ffi.provider.jffi.ClosureUtil.getDelegateMethod; import static jnr.ffi.provider.jffi.CodegenUtils.*; import static jnr.ffi.provider.jffi.InvokerUtil.*; import static org.objectweb.asm.Opcodes.*; /** * */ abstract public class ClosureFromNativeConverter implements FromNativeConverter { @Override public Class nativeType() { return Pointer.class; } public static FromNativeConverter getInstance(jnr.ffi.Runtime runtime, SignatureType type, AsmClassLoader classLoader, SignatureTypeMapper typeMapper) { return newClosureConverter(runtime, classLoader, type.getDeclaredType(), typeMapper); } public static final class ProxyConverter extends ClosureFromNativeConverter { private final jnr.ffi.Runtime runtime; private final Constructor closureConstructor; private final Object[] initFields; public ProxyConverter(jnr.ffi.Runtime runtime, Constructor closureConstructor, Object[] initFields) { this.runtime = runtime; this.closureConstructor = closureConstructor; this.initFields = initFields.clone(); } @Override public Object fromNative(Pointer nativeValue, FromNativeContext context) { try { return closureConstructor.newInstance(runtime, nativeValue.address(), initFields); } catch (Throwable t) { throw new RuntimeException(t); } } } public static abstract class AbstractClosurePointer extends InAccessibleMemoryIO { public static final com.kenai.jffi.Invoker ffi = com.kenai.jffi.Invoker.getInstance(); protected final long functionAddress; protected AbstractClosurePointer(jnr.ffi.Runtime runtime, long functionAddress) { super(runtime, functionAddress, true); this.functionAddress = functionAddress; } @Override public final long size() { return 0; } } private static final AtomicLong nextClassID = new AtomicLong(0); private static FromNativeConverter newClosureConverter(jnr.ffi.Runtime runtime, AsmClassLoader classLoader, Class closureClass, SignatureTypeMapper typeMapper) { ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); ClassVisitor cv = AsmLibraryLoader.DEBUG ? AsmUtil.newCheckClassAdapter(cw) : cw; final String className = p(closureClass) + "$jnr$fromNativeConverter$" + nextClassID.getAndIncrement(); AsmBuilder builder = new AsmBuilder(runtime, className, cv, classLoader); cv.visit(V1_6, ACC_PUBLIC | ACC_FINAL, className, null, p(AbstractClosurePointer.class), new String[] { p(closureClass) } ); cv.visitAnnotation(ci(FromNativeConverter.NoContext.class), true); generateInvocation(runtime, builder, closureClass, typeMapper); // Create the constructor to set the instance fields SkinnyMethodAdapter init = new SkinnyMethodAdapter(cv, ACC_PUBLIC, "", sig(void.class, jnr.ffi.Runtime.class, long.class, Object[].class), null, null); init.start(); // Invoke the super class constructor as super(functionAddress) init.aload(0); init.aload(1); init.lload(2); init.invokespecial(p(AbstractClosurePointer.class), "", sig(void.class, jnr.ffi.Runtime.class, long.class)); builder.emitFieldInitialization(init, 4); init.voidreturn(); init.visitMaxs(10, 10); init.visitEnd(); Class implClass = loadClass(classLoader, className, cw); try { return new ProxyConverter(runtime, implClass.getConstructor(jnr.ffi.Runtime.class, long.class, Object[].class), builder.getObjectFieldValues()); } catch (Throwable ex) { throw new RuntimeException(ex); } } private static Class loadClass(AsmClassLoader classLoader, String className, ClassWriter cw) { try { byte[] bytes = cw.toByteArray(); if (AsmLibraryLoader.DEBUG) { ClassVisitor trace = AsmUtil.newTraceClassVisitor(new PrintWriter(System.err)); new ClassReader(bytes).accept(trace, 0); } return classLoader.defineClass(className.replace("/", "."), bytes); } catch (Throwable ex) { throw new RuntimeException(ex); } } private static void generateInvocation(jnr.ffi.Runtime runtime, AsmBuilder builder, Class closureClass, SignatureTypeMapper typeMapper) { Method closureMethod = getDelegateMethod(closureClass); FromNativeContext resultContext = new MethodResultContext(runtime, closureMethod); SignatureType signatureType = DefaultSignatureType.create(closureMethod.getReturnType(), resultContext); jnr.ffi.mapper.FromNativeType fromNativeType = typeMapper.getFromNativeType(signatureType, resultContext); FromNativeConverter fromNativeConverter = fromNativeType != null ? fromNativeType.getFromNativeConverter() : null; ResultType resultType = getResultType(runtime, closureMethod.getReturnType(), resultContext.getAnnotations(), fromNativeConverter, resultContext); ParameterType[] parameterTypes = getParameterTypes(runtime, typeMapper, closureMethod); // Allow individual methods to set the calling convention to stdcall CallingConvention callingConvention = closureClass.isAnnotationPresent(StdCall.class) ? CallingConvention.STDCALL : CallingConvention.DEFAULT; CallContext callContext = getCallContext(resultType, parameterTypes, callingConvention, true); LocalVariableAllocator localVariableAllocator = new LocalVariableAllocator(parameterTypes); Class[] javaParameterTypes = new Class[parameterTypes.length]; for (int i = 0; i < parameterTypes.length; i++) { javaParameterTypes[i] = parameterTypes[i].getDeclaredType(); } SkinnyMethodAdapter mv = new SkinnyMethodAdapter(builder.getClassVisitor(), ACC_PUBLIC | ACC_FINAL, closureMethod.getName(), sig(resultType.getDeclaredType(), javaParameterTypes), null, null); mv.start(); // Retrieve the static 'ffi' Invoker instance mv.getstatic(p(AbstractClosurePointer.class), "ffi", ci(com.kenai.jffi.Invoker.class)); // retrieve the call context and function address mv.aload(0); mv.getfield(builder.getClassNamePath(), builder.getCallContextFieldName(callContext), ci(CallContext.class)); mv.aload(0); mv.getfield(p(AbstractClosurePointer.class), "functionAddress", ci(long.class)); final BaseMethodGenerator[] generators = { new FastIntMethodGenerator(), new FastLongMethodGenerator(), new FastNumericMethodGenerator(), new BufferMethodGenerator() }; for (BaseMethodGenerator generator : generators) { if (generator.isSupported(resultType, parameterTypes, callingConvention)) { generator.generate(builder, mv, localVariableAllocator, callContext, resultType, parameterTypes, false); } } mv.visitMaxs(100, 10 + localVariableAllocator.getSpaceUsed()); mv.visitEnd(); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/ClosureTypeMapper.java000066400000000000000000000045401316720554100274430ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import jnr.ffi.Struct; import jnr.ffi.mapper.*; import jnr.ffi.mapper.FromNativeType; import jnr.ffi.mapper.ToNativeType; import jnr.ffi.provider.converters.EnumConverter; import jnr.ffi.provider.ParameterFlags; import jnr.ffi.provider.converters.StringResultConverter; import jnr.ffi.provider.converters.StructByReferenceToNativeConverter; final class ClosureTypeMapper implements SignatureTypeMapper { private FromNativeConverter getFromNativeConverter(SignatureType type, FromNativeContext context) { if (Enum.class.isAssignableFrom(type.getDeclaredType())) { return EnumConverter.getInstance(type.getDeclaredType().asSubclass(Enum.class)); } else if (CharSequence.class.isAssignableFrom(type.getDeclaredType())) { return StringResultConverter.getInstance(context); } else { return null; } } private ToNativeConverter getToNativeConverter(SignatureType type, ToNativeContext context) { if (Enum.class.isAssignableFrom(type.getDeclaredType())) { return EnumConverter.getInstance(type.getDeclaredType().asSubclass(Enum.class)); } else if (Struct.class.isAssignableFrom(type.getDeclaredType())) { return StructByReferenceToNativeConverter.getInstance(context); } else { return null; } } @Override public FromNativeType getFromNativeType(SignatureType type, FromNativeContext context) { return FromNativeTypes.create(getFromNativeConverter(type, context)); } @Override public ToNativeType getToNativeType(SignatureType type, ToNativeContext context) { return ToNativeTypes.create(getToNativeConverter(type, context)); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/ClosureUtil.java000066400000000000000000000070541316720554100262750ustar00rootroot00000000000000/* * Copyright (C) 2011 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import jnr.ffi.NativeType; import jnr.ffi.annotations.Delegate; import jnr.ffi.mapper.*; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Type; import java.util.Collection; import static jnr.ffi.util.Annotations.sortedAnnotationCollection; /** * */ final class ClosureUtil { private ClosureUtil() { } static jnr.ffi.provider.ToNativeType getResultType(jnr.ffi.Runtime runtime, Method m, SignatureTypeMapper typeMapper) { Collection annotations = sortedAnnotationCollection(m.getAnnotations()); ToNativeContext context = new SimpleNativeContext(runtime, annotations); SignatureType signatureType = DefaultSignatureType.create(m.getReturnType(), context); jnr.ffi.mapper.ToNativeType toNativeType = typeMapper.getToNativeType(signatureType, context); ToNativeConverter converter = toNativeType != null ? toNativeType.getToNativeConverter() : null; Class javaClass = converter != null ? converter.nativeType() : m.getReturnType(); NativeType nativeType = Types.getType(runtime, javaClass, annotations).getNativeType(); return new jnr.ffi.provider.ToNativeType(m.getReturnType(), nativeType, annotations, converter, context); } static jnr.ffi.provider.FromNativeType getParameterType(jnr.ffi.Runtime runtime, Method m, int idx, SignatureTypeMapper typeMapper) { Collection annotations = sortedAnnotationCollection(m.getParameterAnnotations()[idx]); Class declaredJavaClass = m.getParameterTypes()[idx]; FromNativeContext context = new SimpleNativeContext(runtime, annotations); SignatureType signatureType = new DefaultSignatureType(declaredJavaClass, context.getAnnotations(), m.getGenericParameterTypes()[idx]); jnr.ffi.mapper.FromNativeType fromNativeType = typeMapper.getFromNativeType(signatureType, context); FromNativeConverter converter = fromNativeType != null ? fromNativeType.getFromNativeConverter() : null; Class javaClass = converter != null ? converter.nativeType() : declaredJavaClass; NativeType nativeType = Types.getType(runtime, javaClass, annotations).getNativeType(); return new jnr.ffi.provider.FromNativeType(declaredJavaClass, nativeType, annotations, converter, context); } static Method getDelegateMethod(Class closureClass) { Method callMethod = null; for (Method m : closureClass.getMethods()) { if (m.isAnnotationPresent(Delegate.class) && Modifier.isPublic(m.getModifiers()) && !Modifier.isStatic(m.getModifiers())) { callMethod = m; break; } } if (callMethod == null) { throw new NoSuchMethodError("no public non-static delegate method defined in " + closureClass.getName()); } return callMethod; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/CodegenUtils.java000066400000000000000000000167111316720554100264100ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import org.objectweb.asm.AnnotationVisitor; import org.objectweb.asm.Type; import java.util.Arrays; import java.util.Map; public class CodegenUtils { /** * Creates a dotted class name from a path/package name. * * @param p The path/package name. * @return The dotted class name. */ public static String c(String p) { return p.replace('/', '.'); } /** * Creates a class path name, from a Class. * * @param n A class. * @return The class path name. */ public static String p(Class n) { return n.getName().replace('.','/'); } /** * Creates a class path name, from a class name. * * @param n A class name. * @return A class path name. */ public static String p(String n) { return n.replace('.', '/'); } /** * Creates a class identifier of form Labc/abc;, from a Class. * * @param n A class. * @return The class identifier. */ public static String ci(Class n) { if (n.isArray()) { n = n.getComponentType(); if (n.isPrimitive()) { if (n == Byte.TYPE) { return "[B"; } else if (n == Boolean.TYPE) { return "[Z"; } else if (n == Short.TYPE) { return "[S"; } else if (n == Character.TYPE) { return "[C"; } else if (n == Integer.TYPE) { return "[I"; } else if (n == Float.TYPE) { return "[F"; } else if (n == Double.TYPE) { return "[D"; } else if (n == Long.TYPE) { return "[J"; } else { throw new RuntimeException("Unrecognized type in compiler: " + n.getName()); } } else { return "[" + ci(n); } } else { if (n.isPrimitive()) { if (n == Byte.TYPE) { return "B"; } else if (n == Boolean.TYPE) { return "Z"; } else if (n == Short.TYPE) { return "S"; } else if (n == Character.TYPE) { return "C"; } else if (n == Integer.TYPE) { return "I"; } else if (n == Float.TYPE) { return "F"; } else if (n == Double.TYPE) { return "D"; } else if (n == Long.TYPE) { return "J"; } else if (n == Void.TYPE) { return "V"; } else { throw new RuntimeException("Unrecognized type in compiler: " + n.getName()); } } else { return "L" + p(n) + ";"; } } } /** * Creates a human-readable representation, from a Class. * * @param n A class. * @return A human-readable representation. */ public static String human(Class n) { return n.getCanonicalName(); } /** * Create a method signature from the given param types and return values. * * @param retval The return value class. * @param params The parameters. * @return A method signature. */ public static String sig(Class retval, Class... params) { return sigParams(params) + ci(retval); } public static String sig(Class retval, String descriptor, Class... params) { return sigParams(descriptor, params) + ci(retval); } public static String sigParams(Class... params) { StringBuilder signature = new StringBuilder("("); for (int i = 0; i < params.length; i++) { signature.append(ci(params[i])); } signature.append(")"); return signature.toString(); } public static String sigParams(String descriptor, Class... params) { StringBuilder signature = new StringBuilder("("); signature.append(descriptor); for (int i = 0; i < params.length; i++) { signature.append(ci(params[i])); } signature.append(")"); return signature.toString(); } public static String pretty(Class retval, Class... params) { return prettyParams(params) + human(retval); } public static String prettyParams(Class... params) { StringBuilder signature = new StringBuilder("("); for (int i = 0; i < params.length; i++) { signature.append(human(params[i])); if (i < params.length - 1) signature.append(','); } signature.append(")"); return signature.toString(); } public static Class[] params(Class... classes) { return classes; } public static Class[] params(Class cls, int times) { Class[] classes = new Class[times]; Arrays.fill(classes, cls); return classes; } public static Class[] params(Class cls1, Class clsFill, int times) { Class[] classes = new Class[times + 1]; Arrays.fill(classes, clsFill); classes[0] = cls1; return classes; } public static String getAnnotatedBindingClassName(String javaMethodName, String typeName, boolean isStatic, int required, int optional, boolean multi, boolean framed) { String commonClassSuffix; String marker = framed ? "$RUBYFRAMEDINVOKER$" : "$RUBYINVOKER$"; if (multi) { commonClassSuffix = (isStatic ? "$s" : "$i" ) + "_method_multi" + marker + javaMethodName; } else { commonClassSuffix = (isStatic ? "$s" : "$i" ) + "_method_" + required + "_" + optional + marker + javaMethodName; } return typeName + commonClassSuffix; } public static void visitAnnotationFields(AnnotationVisitor visitor, Map fields) { for (Map.Entry fieldEntry : fields.entrySet()) { Object value = fieldEntry.getValue(); if (value.getClass().isArray()) { Object[] values = (Object[]) value; AnnotationVisitor arrayV = visitor.visitArray(fieldEntry.getKey()); for (int i = 0; i < values.length; i++) { arrayV.visit(null, values[i]); } arrayV.visitEnd(); } else if (value.getClass().isEnum()) { visitor.visitEnum(fieldEntry.getKey(), ci(value.getClass()), value.toString()); } else if (value instanceof Class) { visitor.visit(fieldEntry.getKey(), Type.getType((Class)value)); } else { visitor.visit(fieldEntry.getKey(), value); } } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/ConverterMetaData.java000066400000000000000000000131121316720554100273630ustar00rootroot00000000000000/* * Copyright (C) 2013 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import jnr.ffi.mapper.FromNativeContext; import jnr.ffi.mapper.FromNativeConverter; import jnr.ffi.mapper.ToNativeContext; import jnr.ffi.mapper.ToNativeConverter; import jnr.ffi.util.Annotations; import java.lang.annotation.Annotation; import java.lang.ref.Reference; import java.lang.ref.SoftReference; import java.lang.reflect.Method; import java.util.*; /** * */ class ConverterMetaData { private static volatile Reference> cacheReference; final Collection classAnnotations; final Collection toNativeMethodAnnotations, fromNativeMethodAnnotations, nativeTypeMethodAnnotations; final Collection toNativeAnnotations, fromNativeAnnotations; ConverterMetaData(Class converterClass, Class nativeType) { classAnnotations = Annotations.sortedAnnotationCollection(converterClass.getAnnotations()); nativeTypeMethodAnnotations = getConverterMethodAnnotations(converterClass, "nativeType"); fromNativeMethodAnnotations = getConverterMethodAnnotations(converterClass, "fromNative", nativeType, FromNativeContext.class); toNativeMethodAnnotations = getConverterMethodAnnotations(converterClass, "toNative", nativeType, ToNativeContext.class);; toNativeAnnotations = Annotations.mergeAnnotations(classAnnotations, toNativeMethodAnnotations, nativeTypeMethodAnnotations); fromNativeAnnotations = Annotations.mergeAnnotations(classAnnotations, fromNativeMethodAnnotations, nativeTypeMethodAnnotations); } private static Collection getToNativeMethodAnnotations(Class converterClass, Class resultClass) { try { final Method baseMethod = converterClass.getMethod("toNative", Object.class, ToNativeContext.class); for (Method m : converterClass.getMethods()) { if (!m.getName().equals("toNative")) { continue; } if (!resultClass.isAssignableFrom(m.getReturnType())) { continue; } Class[] methodParameterTypes = m.getParameterTypes(); if (methodParameterTypes.length != 2 || !methodParameterTypes[1].isAssignableFrom(ToNativeContext.class)) { continue; } return Annotations.mergeAnnotations(Annotations.sortedAnnotationCollection(m.getAnnotations()), Annotations.sortedAnnotationCollection(baseMethod.getAnnotations())); } return Annotations.EMPTY_ANNOTATIONS; } catch (SecurityException se) { return Annotations.EMPTY_ANNOTATIONS; } catch (NoSuchMethodException ignored) { return Annotations.EMPTY_ANNOTATIONS; } } @SuppressWarnings("unchecked") private static Collection getConverterMethodAnnotations(Class converterClass, String methodName, Class... parameterClasses) { try { return Annotations.sortedAnnotationCollection(converterClass.getMethod(methodName).getAnnotations()); } catch (NoSuchMethodException ignored) { return Annotations.EMPTY_ANNOTATIONS; } catch (Throwable e) { throw new RuntimeException(e); } } private static ConverterMetaData getMetaData(Class converterClass, Class nativeType) { Map cache = cacheReference != null ? cacheReference.get() : null; ConverterMetaData metaData; if (cache != null && (metaData = cache.get(converterClass)) != null) { return metaData; } return addMetaData(converterClass, nativeType); } private static synchronized ConverterMetaData addMetaData(Class converterClass, Class nativeType) { Map cache = cacheReference != null ? cacheReference.get() : null; ConverterMetaData metaData; if (cache != null && (metaData = cache.get(converterClass)) != null) { return metaData; } Map m = new HashMap(cache != null ? cache : Collections.EMPTY_MAP); m.put(converterClass, metaData = new ConverterMetaData(converterClass, nativeType)); cacheReference = new SoftReference>(cache = new IdentityHashMap(m)); return metaData; } static Collection getAnnotations(ToNativeConverter toNativeConverter) { return toNativeConverter != null ? getMetaData(toNativeConverter.getClass(), toNativeConverter.nativeType()).toNativeAnnotations : Annotations.EMPTY_ANNOTATIONS; } static Collection getAnnotations(FromNativeConverter fromNativeConverter) { return fromNativeConverter != null ? getMetaData(fromNativeConverter.getClass(), fromNativeConverter.nativeType()).fromNativeAnnotations : Annotations.EMPTY_ANNOTATIONS; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/DefaultInvokerFactory.java000066400000000000000000001217731316720554100303020ustar00rootroot00000000000000/* * Copyright (C) 2008-2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import static jnr.ffi.provider.jffi.InvokerUtil.getCallContext; import static jnr.ffi.provider.jffi.InvokerUtil.getParameterTypes; import static jnr.ffi.provider.jffi.InvokerUtil.getResultType; import static jnr.ffi.provider.jffi.NumberUtil.getBoxedClass; import static jnr.ffi.provider.jffi.NumberUtil.sizeof; import static jnr.ffi.util.Annotations.sortedAnnotationCollection; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.nio.Buffer; import java.nio.ByteBuffer; import java.nio.DoubleBuffer; import java.nio.FloatBuffer; import java.nio.IntBuffer; import java.nio.LongBuffer; import java.nio.ShortBuffer; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.List; import java.util.Map; import jnr.ffi.Address; import jnr.ffi.CallingConvention; import jnr.ffi.LibraryLoader; import jnr.ffi.LibraryOption; import jnr.ffi.NativeType; import jnr.ffi.Pointer; import jnr.ffi.Runtime; import jnr.ffi.annotations.Meta; import jnr.ffi.annotations.StdCall; import jnr.ffi.annotations.Synchronized; import jnr.ffi.mapper.DataConverter; import jnr.ffi.mapper.DefaultSignatureType; import jnr.ffi.mapper.FromNativeContext; import jnr.ffi.mapper.FromNativeConverter; import jnr.ffi.mapper.FunctionMapper; import jnr.ffi.mapper.MethodResultContext; import jnr.ffi.mapper.SignatureType; import jnr.ffi.mapper.SignatureTypeMapper; import jnr.ffi.mapper.ToNativeContext; import jnr.ffi.mapper.ToNativeConverter; import jnr.ffi.mapper.ToNativeType; import jnr.ffi.provider.InvocationSession; import jnr.ffi.provider.Invoker; import jnr.ffi.provider.NativeFunction; import jnr.ffi.provider.ParameterType; import jnr.ffi.provider.ResultType; import jnr.ffi.provider.SigType; import jnr.ffi.util.AnnotationProxy; import com.kenai.jffi.Function; import com.kenai.jffi.HeapInvocationBuffer; import com.kenai.jffi.ObjectParameterStrategy; import com.kenai.jffi.ObjectParameterType; final class DefaultInvokerFactory { private final Runtime runtime; private final NativeLibrary library; private final SignatureTypeMapper typeMapper; private final FunctionMapper functionMapper; private final jnr.ffi.CallingConvention libraryCallingConvention; private final boolean libraryIsSynchronized; private final Map libraryOptions; public DefaultInvokerFactory( Runtime runtime, NativeLibrary library, SignatureTypeMapper typeMapper, FunctionMapper functionMapper, CallingConvention libraryCallingConvention, Map libraryOptions, boolean libraryIsSynchronized) { super(); this.runtime = runtime; this.library = library; this.typeMapper = typeMapper; this.functionMapper = functionMapper; this.libraryCallingConvention = libraryCallingConvention; this.libraryIsSynchronized = libraryIsSynchronized; this.libraryOptions = libraryOptions; } public Invoker createInvoker(Method method) { Collection annotations = sortedAnnotationCollection(method.getAnnotations()); String functionName = functionMapper.mapFunctionName(method.getName(), new NativeFunctionMapperContext(library, annotations)); long functionAddress = library.getSymbolAddress(functionName); if (functionAddress == 0L) { return new FunctionNotFoundInvoker(method, functionName); } FromNativeContext resultContext = new MethodResultContext(NativeRuntime.getInstance(), method); SignatureType signatureType = DefaultSignatureType.create(method.getReturnType(), resultContext); ResultType resultType = getResultType(runtime, method.getReturnType(), resultContext.getAnnotations(), typeMapper.getFromNativeType(signatureType, resultContext), resultContext); FunctionInvoker functionInvoker = getFunctionInvoker(resultType); if (resultType.getFromNativeConverter() != null) { functionInvoker = new ConvertingInvoker(resultType.getFromNativeConverter(), resultType.getFromNativeContext(), functionInvoker); } ParameterType[] parameterTypes = getParameterTypes(runtime, typeMapper, method); //Allow individual methods to set the calling convention to stdcall CallingConvention callingConvention = method.isAnnotationPresent(StdCall.class) ? CallingConvention.STDCALL : libraryCallingConvention; boolean saveError = LibraryLoader.saveError(libraryOptions, NativeFunction.hasSaveError(method), NativeFunction.hasIgnoreError(method)); Invoker invoker; if (method.isVarArgs()) { invoker = new VariadicInvoker(runtime, functionInvoker, typeMapper, parameterTypes, functionAddress, resultType, saveError, callingConvention); } else { Function function = new Function(functionAddress, getCallContext(resultType, parameterTypes, callingConvention, saveError)); Marshaller[] marshallers = new Marshaller[parameterTypes.length]; for (int i = 0; i < marshallers.length; ++i) { marshallers[i] = getMarshaller(parameterTypes[i]); } return new DefaultInvoker(runtime, library, function, functionInvoker, marshallers); } // // If either the method or the library is specified as requiring // synchronization, then wrap the raw invoker in a synchronized proxy // return libraryIsSynchronized || method.isAnnotationPresent(Synchronized.class) ? new SynchronizedInvoker(invoker) : invoker; } private static FunctionInvoker getFunctionInvoker(ResultType resultType) { Class returnType = resultType.effectiveJavaType(); if (Void.class.isAssignableFrom(returnType) || void.class == returnType) { return VoidInvoker.INSTANCE; } else if (Boolean.class.isAssignableFrom(returnType) || boolean.class == returnType) { return BooleanInvoker.INSTANCE; } else if (Number.class.isAssignableFrom(returnType) || returnType.isPrimitive()) { return new ConvertingInvoker(getNumberResultConverter(resultType), null, new ConvertingInvoker(getNumberDataConverter(resultType.getNativeType()), null, getNumberFunctionInvoker(resultType.getNativeType()))); } else if (Pointer.class.isAssignableFrom(returnType)) { return PointerInvoker.INSTANCE; } else { throw new IllegalArgumentException("Unknown return type: " + returnType); } } private static FunctionInvoker getNumberFunctionInvoker(NativeType nativeType) { switch (nativeType) { case SCHAR: case UCHAR: case SSHORT: case USHORT: case SINT: case UINT: case SLONG: case ULONG: case SLONGLONG: case ULONGLONG: case ADDRESS: return sizeof(nativeType) <= 4 ? IntInvoker.INSTANCE : LongInvoker.INSTANCE; case FLOAT: return Float32Invoker.INSTANCE; case DOUBLE: return Float64Invoker.INSTANCE; } throw new UnsupportedOperationException("unsupported numeric type: " + nativeType); } static Marshaller getMarshaller(ParameterType parameterType) { Marshaller marshaller = getMarshaller(parameterType.effectiveJavaType(), parameterType.getNativeType(), parameterType.getAnnotations()); return parameterType.getToNativeConverter() != null ? new ToNativeConverterMarshaller(parameterType.getToNativeConverter(), parameterType.getToNativeContext(), marshaller) : marshaller; } static Marshaller getMarshaller(Class type, NativeType nativeType, Collection annotations) { if (Number.class.isAssignableFrom(type) || (type.isPrimitive() && Number.class.isAssignableFrom(getBoxedClass(type)))) { switch (nativeType) { case SCHAR: return new Int8Marshaller(Signed8Converter.INSTANCE); case UCHAR: return new Int8Marshaller(Unsigned8Converter.INSTANCE); case SSHORT: return new Int16Marshaller(Signed16Converter.INSTANCE); case USHORT: return new Int16Marshaller(Unsigned16Converter.INSTANCE); case SINT: return new Int32Marshaller(Signed32Converter.INSTANCE); case UINT: return new Int32Marshaller(Unsigned32Converter.INSTANCE); case SLONG: case ULONG: case ADDRESS: return sizeof(nativeType) == 4 ? new Int32Marshaller(getNumberDataConverter(nativeType)): Int64Marshaller.INSTANCE; case SLONGLONG: case ULONGLONG: return Int64Marshaller.INSTANCE; case FLOAT: return Float32Marshaller.INSTANCE; case DOUBLE: return Float64Marshaller.INSTANCE; default: throw new IllegalArgumentException("Unsupported parameter type: " + type); } } else if (Boolean.class.isAssignableFrom(type) || boolean.class == type) { return BooleanMarshaller.INSTANCE; } else if (Pointer.class.isAssignableFrom(type)) { return new PointerMarshaller(annotations); } else if (ByteBuffer.class.isAssignableFrom(type)) { return new BufferMarshaller(ObjectParameterType.ComponentType.BYTE, annotations); } else if (ShortBuffer.class.isAssignableFrom(type)) { return new BufferMarshaller(ObjectParameterType.ComponentType.SHORT, annotations); } else if (IntBuffer.class.isAssignableFrom(type)) { return new BufferMarshaller(ObjectParameterType.ComponentType.INT, annotations); } else if (LongBuffer.class.isAssignableFrom(type)) { return new BufferMarshaller(ObjectParameterType.ComponentType.LONG, annotations); } else if (FloatBuffer.class.isAssignableFrom(type)) { return new BufferMarshaller(ObjectParameterType.ComponentType.FLOAT, annotations); } else if (DoubleBuffer.class.isAssignableFrom(type)) { return new BufferMarshaller(ObjectParameterType.ComponentType.DOUBLE, annotations); } else if (Buffer.class.isAssignableFrom(type)) { return new BufferMarshaller(null, annotations); } else if (type.isArray() && type.getComponentType() == byte.class) { return new PrimitiveArrayMarshaller(PrimitiveArrayParameterStrategy.BYTE, annotations); } else if (type.isArray() && type.getComponentType() == short.class) { return new PrimitiveArrayMarshaller(PrimitiveArrayParameterStrategy.SHORT, annotations); } else if (type.isArray() && type.getComponentType() == int.class) { return new PrimitiveArrayMarshaller(PrimitiveArrayParameterStrategy.INT, annotations); } else if (type.isArray() && type.getComponentType() == long.class) { return new PrimitiveArrayMarshaller(PrimitiveArrayParameterStrategy.LONG, annotations); } else if (type.isArray() && type.getComponentType() == float.class) { return new PrimitiveArrayMarshaller(PrimitiveArrayParameterStrategy.FLOAT, annotations); } else if (type.isArray() && type.getComponentType() == double.class) { return new PrimitiveArrayMarshaller(PrimitiveArrayParameterStrategy.DOUBLE, annotations); } else if (type.isArray() && type.getComponentType() == boolean.class) { return new PrimitiveArrayMarshaller(PrimitiveArrayParameterStrategy.BOOLEAN, annotations); } else { throw new IllegalArgumentException("Unsupported parameter type: " + type); } } static class VariadicInvoker implements jnr.ffi.provider.Invoker { private final jnr.ffi.Runtime runtime; private final FunctionInvoker functionInvoker; private final SignatureTypeMapper typeMapper; private final ParameterType[] fixedParameterTypes; private final long functionAddress; private final SigType resultType; private final boolean requiresErrno; private final CallingConvention callingConvention; VariadicInvoker(Runtime runtime, FunctionInvoker functionInvoker, SignatureTypeMapper typeMapper, ParameterType[] fixedParameterTypes, long functionAddress, SigType resultType, boolean requiresErrno, CallingConvention callingConvention) { super(); this.runtime = runtime; this.functionInvoker = functionInvoker; this.typeMapper = typeMapper; this.fixedParameterTypes = fixedParameterTypes; this.functionAddress = functionAddress; this.resultType = resultType; this.requiresErrno = requiresErrno; this.callingConvention = callingConvention; } public final Object invoke(Object self, Object[] parameters) { Object[] varParam = (Object[])parameters[parameters.length - 1]; ParameterType[] argTypes = new ParameterType[fixedParameterTypes.length + varParam.length]; System.arraycopy(fixedParameterTypes, 0, argTypes, 0, fixedParameterTypes.length - 1); Object[] variableArgs = new Object[varParam.length + 1]; int variableArgsCount = 0; List> paramAnnotations = new ArrayList>(); for (Object arg : varParam) { if (arg instanceof Class && Annotation.class.isAssignableFrom((Class)arg)) { paramAnnotations.add((Class)arg); } else { Class argClass; ToNativeConverter toNativeConverter = null; Collection annos = getAnnotations(paramAnnotations); paramAnnotations.clear(); ToNativeContext toNativeContext = new SimpleNativeContext(runtime, annos); if (arg != null) { ToNativeType toNativeType = typeMapper.getToNativeType(DefaultSignatureType.create(arg.getClass(), toNativeContext), toNativeContext); toNativeConverter = toNativeType == null ? null : toNativeType.getToNativeConverter(); argClass = toNativeConverter == null ? arg.getClass() : toNativeConverter.nativeType(); variableArgs[variableArgsCount] = arg; } else { argClass = Pointer.class; variableArgs[variableArgsCount] = arg; } argTypes[fixedParameterTypes.length + variableArgsCount - 1] = new ParameterType( argClass, Types.getType(runtime, argClass, annos).getNativeType(), annos, toNativeConverter, new SimpleNativeContext(runtime, annos)); variableArgsCount++; } } //Add one extra vararg of NULL to meet the common convention of ending //varargs with a NULL. Functions that get a length from the fixed arguments //will ignore the extra, and funtions that expect the extra NULL will get it. //This matches what JNA does. argTypes[fixedParameterTypes.length + variableArgsCount - 1] = new ParameterType( Pointer.class, Types.getType(runtime, Pointer.class, Collections.emptyList()).getNativeType(), Collections.emptyList(), null, new SimpleNativeContext(runtime, Collections.emptyList())); variableArgs[variableArgsCount] = null; variableArgsCount++; Function function = new Function(functionAddress, getCallContext(resultType, argTypes, variableArgsCount + fixedParameterTypes.length - 1, callingConvention, requiresErrno)); HeapInvocationBuffer buffer = new HeapInvocationBuffer(function.getCallContext()); InvocationSession session = new InvocationSession(); try { if (parameters != null) for (int i = 0; i < parameters.length - 1; ++i) { getMarshaller(argTypes[i]).marshal(session, buffer, parameters[i]); } for (int i = 0; i < variableArgsCount; ++i) { getMarshaller(argTypes[i + fixedParameterTypes.length - 1]).marshal(session, buffer, variableArgs[i]); } return functionInvoker.invoke(runtime, function, buffer); } finally { session.finish(); } } private static Collection getAnnotations(Collection> klasses) { List ret = new ArrayList(); for (Class klass : klasses) { if (klass.getAnnotation(Meta.class) != null) { for (Annotation anno : klass.getAnnotations()) { if (anno.annotationType().getName().startsWith("java") || Meta.class.equals(anno.annotationType())) { continue; } ret.add(anno); } } else { ret.add(AnnotationProxy.newProxy(klass)); } } return ret; } } static class DefaultInvoker implements jnr.ffi.provider.Invoker { protected final jnr.ffi.Runtime runtime; final Function function; final FunctionInvoker functionInvoker; final Marshaller[] marshallers; final NativeLibrary nativeLibrary; DefaultInvoker(jnr.ffi.Runtime runtime, NativeLibrary nativeLibrary, Function function, FunctionInvoker invoker, Marshaller[] marshallers) { this.runtime = runtime; this.nativeLibrary = nativeLibrary; this.function = function; this.functionInvoker = invoker; this.marshallers = marshallers; } public final Object invoke(Object self, Object[] parameters) { InvocationSession session = new InvocationSession(); HeapInvocationBuffer buffer = new HeapInvocationBuffer(function.getCallContext()); try { if (parameters != null) for (int i = 0; i < parameters.length; ++i) { marshallers[i].marshal(session, buffer, parameters[i]); } return functionInvoker.invoke(runtime, function, buffer); } finally { session.finish(); } } } private static final class SynchronizedInvoker implements Invoker { private final Invoker invoker; public SynchronizedInvoker(Invoker invoker) { this.invoker = invoker; } @SuppressWarnings("SynchronizationOnLocalVariableOrMethodParameter") public Object invoke(Object self, Object[] parameters) { synchronized (self) { return invoker.invoke(self, parameters); } } } private static final class FunctionNotFoundInvoker implements Invoker { private final Method method; private final String functionName; private FunctionNotFoundInvoker(Method method, String functionName) { this.method = method; this.functionName = functionName; } @Override public Object invoke(Object self, Object[] parameters) { throw new UnsatisfiedLinkError(String.format("native method '%s' not found for method %s", functionName, method)); } } static interface Marshaller { public abstract void marshal(InvocationSession session, HeapInvocationBuffer buffer, Object parameter); } static interface FunctionInvoker { Object invoke(Runtime runtime, Function function, HeapInvocationBuffer buffer); } static abstract class BaseInvoker implements FunctionInvoker { static com.kenai.jffi.Invoker invoker = com.kenai.jffi.Invoker.getInstance(); } static class ConvertingInvoker extends BaseInvoker { private final FromNativeConverter fromNativeConverter; private final FromNativeContext fromNativeContext; private final FunctionInvoker nativeInvoker; public ConvertingInvoker(FromNativeConverter converter, FromNativeContext context, FunctionInvoker nativeInvoker) { this.fromNativeConverter = converter; this.fromNativeContext = context; this.nativeInvoker = nativeInvoker; } public final Object invoke(Runtime runtime, Function function, HeapInvocationBuffer buffer) { return fromNativeConverter.fromNative(nativeInvoker.invoke(runtime, function, buffer), fromNativeContext); } } static class VoidInvoker extends BaseInvoker { static FunctionInvoker INSTANCE = new VoidInvoker(); public final Object invoke(Runtime runtime, Function function, HeapInvocationBuffer buffer) { invoker.invokeInt(function, buffer); return null; } } static class BooleanInvoker extends BaseInvoker { static FunctionInvoker INSTANCE = new BooleanInvoker(); public final Object invoke(Runtime runtime, Function function, HeapInvocationBuffer buffer) { return invoker.invokeInt(function, buffer) != 0; } } static class IntInvoker extends BaseInvoker { static final FunctionInvoker INSTANCE = new IntInvoker(); public final Object invoke(Runtime runtime, Function function, HeapInvocationBuffer buffer) { return invoker.invokeInt(function, buffer); } } static class LongInvoker extends BaseInvoker { static final FunctionInvoker INSTANCE = new LongInvoker(); public final Object invoke(Runtime runtime, Function function, HeapInvocationBuffer buffer) { return invoker.invokeLong(function, buffer); } } static class Float32Invoker extends BaseInvoker { static final FunctionInvoker INSTANCE = new Float32Invoker(); public final Object invoke(Runtime runtime, Function function, HeapInvocationBuffer buffer) { return invoker.invokeFloat(function, buffer); } } static class Float64Invoker extends BaseInvoker { static final FunctionInvoker INSTANCE = new Float64Invoker(); public final Object invoke(Runtime runtime, Function function, HeapInvocationBuffer buffer) { return invoker.invokeDouble(function, buffer); } } static class PointerInvoker extends BaseInvoker { static final FunctionInvoker INSTANCE = new PointerInvoker(); public final Object invoke(Runtime runtime, Function function, HeapInvocationBuffer buffer) { return MemoryUtil.newPointer(runtime, invoker.invokeAddress(function, buffer)); } } /* ---------------------------------------------------------------------- */ static class BooleanMarshaller implements Marshaller { static final Marshaller INSTANCE = new BooleanMarshaller(); public void marshal(InvocationSession session, HeapInvocationBuffer buffer, Object parameter) { buffer.putInt(((Boolean) parameter).booleanValue() ? 1 : 0); } } static class Int8Marshaller implements Marshaller { private final ToNativeConverter toNativeConverter; Int8Marshaller(ToNativeConverter toNativeConverter) { this.toNativeConverter = toNativeConverter; } public void marshal(InvocationSession session, HeapInvocationBuffer buffer, Object parameter) { buffer.putByte(toNativeConverter.toNative((Number) parameter, null).intValue()); } } static class Int16Marshaller implements Marshaller { private final ToNativeConverter toNativeConverter; Int16Marshaller(ToNativeConverter toNativeConverter) { this.toNativeConverter = toNativeConverter; } public void marshal(InvocationSession session, HeapInvocationBuffer buffer, Object parameter) { buffer.putShort(toNativeConverter.toNative((Number) parameter, null).intValue()); } } static class Int32Marshaller implements Marshaller { private final ToNativeConverter toNativeConverter; Int32Marshaller(ToNativeConverter toNativeConverter) { this.toNativeConverter = toNativeConverter; } public void marshal(InvocationSession session, HeapInvocationBuffer buffer, Object parameter) { buffer.putInt(toNativeConverter.toNative((Number) parameter, null).intValue()); } } static class Int64Marshaller implements Marshaller { static final Marshaller INSTANCE = new Int64Marshaller(); public void marshal(InvocationSession session, HeapInvocationBuffer buffer, Object parameter) { buffer.putLong(((Number) parameter).longValue()); } } static class Float32Marshaller implements Marshaller { static final Marshaller INSTANCE = new Float32Marshaller(); public void marshal(InvocationSession session, HeapInvocationBuffer buffer, Object parameter) { buffer.putFloat(((Number) parameter).floatValue()); } } static class Float64Marshaller implements Marshaller { static final Marshaller INSTANCE = new Float64Marshaller(); public void marshal(InvocationSession session, HeapInvocationBuffer buffer, Object parameter) { buffer.putDouble(((Number) parameter).doubleValue()); } } static class PointerMarshaller implements Marshaller { private final int flags; PointerMarshaller(Collection annotations) { this.flags = AsmUtil.getNativeArrayFlags(annotations); } public void marshal(InvocationSession session, HeapInvocationBuffer buffer, Object parameter) { buffer.putObject(parameter, AsmRuntime.pointerParameterStrategy((Pointer) parameter), flags); } } static class PrimitiveArrayMarshaller implements Marshaller { private final PrimitiveArrayParameterStrategy strategy; private final int flags; protected PrimitiveArrayMarshaller(PrimitiveArrayParameterStrategy strategy, Collection annotations) { this.strategy = strategy; this.flags = AsmUtil.getNativeArrayFlags(annotations); } public final void marshal(InvocationSession session, HeapInvocationBuffer buffer, Object parameter) { buffer.putObject(parameter, parameter != null ? strategy : NullObjectParameterStrategy.NULL, flags); } } static class BufferMarshaller implements Marshaller { private final ObjectParameterType.ComponentType componentType; private final int flags; BufferMarshaller(ObjectParameterType.ComponentType componentType, Collection annotations) { this.componentType = componentType; this.flags = AsmUtil.getNativeArrayFlags(annotations); } public final void marshal(InvocationSession session, HeapInvocationBuffer buffer, Object parameter) { ObjectParameterStrategy strategy = componentType != null ? AsmRuntime.bufferParameterStrategy((Buffer) parameter, componentType) : AsmRuntime.pointerParameterStrategy((Buffer) parameter); buffer.putObject(parameter, strategy, flags); } } static class ToNativeConverterMarshaller implements Marshaller { private final ToNativeConverter converter; private final ToNativeContext context; private final Marshaller marshaller; private final boolean isPostInvokeRequired; public ToNativeConverterMarshaller(ToNativeConverter toNativeConverter, ToNativeContext toNativeContext, Marshaller marshaller) { this.converter = toNativeConverter; this.context = toNativeContext; this.marshaller = marshaller; this.isPostInvokeRequired = converter instanceof ToNativeConverter.PostInvocation; } @Override public void marshal(InvocationSession session, HeapInvocationBuffer buffer, final Object parameter) { final Object nativeValue = converter.toNative(parameter, context); marshaller.marshal(session, buffer, nativeValue); if (isPostInvokeRequired) { session.addPostInvoke(new InvocationSession.PostInvoke() { @Override public void postInvoke() { ((ToNativeConverter.PostInvocation) converter).postInvoke(parameter, nativeValue, context); } }); } else { // hold on to the native value until the entire call session is complete session.keepAlive(nativeValue); } } } private static boolean isUnsigned(NativeType nativeType) { switch (nativeType) { case UCHAR: case USHORT: case UINT: case ULONG: return true; default: return false; } } static DataConverter getNumberDataConverter(NativeType nativeType) { switch (nativeType) { case SCHAR: return DefaultInvokerFactory.Signed8Converter.INSTANCE; case UCHAR: return DefaultInvokerFactory.Unsigned8Converter.INSTANCE; case SSHORT: return DefaultInvokerFactory.Signed16Converter.INSTANCE; case USHORT: return DefaultInvokerFactory.Unsigned16Converter.INSTANCE; case SINT: return DefaultInvokerFactory.Signed32Converter.INSTANCE; case UINT: return DefaultInvokerFactory.Unsigned32Converter.INSTANCE; case SLONG: return sizeof(nativeType) == 4 ? DefaultInvokerFactory.Signed32Converter.INSTANCE : DefaultInvokerFactory.LongLongConverter.INSTANCE; case ULONG: case ADDRESS: return sizeof(nativeType) == 4 ? DefaultInvokerFactory.Unsigned32Converter.INSTANCE : DefaultInvokerFactory.LongLongConverter.INSTANCE; case SLONGLONG: case ULONGLONG: return DefaultInvokerFactory.LongLongConverter.INSTANCE; case FLOAT: return DefaultInvokerFactory.FloatConverter.INSTANCE; case DOUBLE: return DefaultInvokerFactory.DoubleConverter.INSTANCE; } throw new UnsupportedOperationException("cannot convert " + nativeType); } static abstract class NumberDataConverter implements DataConverter { @Override public final Class nativeType() { return Number.class; } } static final class Signed8Converter extends NumberDataConverter { static final NumberDataConverter INSTANCE = new Signed8Converter(); @Override public Number fromNative(Number nativeValue, FromNativeContext context) { return nativeValue.byteValue(); } @Override public Number toNative(Number value, ToNativeContext context) { return value.byteValue(); } } static final class Unsigned8Converter extends NumberDataConverter { static final NumberDataConverter INSTANCE = new Unsigned8Converter(); @Override public Number fromNative(Number nativeValue, FromNativeContext context) { int value = nativeValue.byteValue(); return value < 0 ? ((value & 0x7f) + 0x80) : value; } @Override public Number toNative(Number value, ToNativeContext context) { return value.intValue() & 0xffff; } } static final class Signed16Converter extends NumberDataConverter { static final NumberDataConverter INSTANCE = new Signed16Converter(); @Override public Number fromNative(Number nativeValue, FromNativeContext context) { return nativeValue.shortValue(); } @Override public Number toNative(Number value, ToNativeContext context) { return value.shortValue(); } } static final class Unsigned16Converter extends NumberDataConverter { static final NumberDataConverter INSTANCE = new Unsigned16Converter(); @Override public Number fromNative(Number nativeValue, FromNativeContext context) { int value = nativeValue.shortValue(); return value < 0 ? ((value & 0x7fff) + 0x8000) : value; } @Override public Number toNative(Number value, ToNativeContext context) { return value.intValue() & 0xffff; } } static final class Signed32Converter extends NumberDataConverter { static final NumberDataConverter INSTANCE = new Signed32Converter(); @Override public Number fromNative(Number nativeValue, FromNativeContext context) { return nativeValue.intValue(); } @Override public Number toNative(Number value, ToNativeContext context) { return value.intValue(); } } static final class Unsigned32Converter extends NumberDataConverter { static final NumberDataConverter INSTANCE = new Unsigned32Converter(); @Override public Number fromNative(Number nativeValue, FromNativeContext context) { long value = nativeValue.intValue(); return value < 0 ? ((value & 0x7fffffffL) + 0x80000000L) : value; } @Override public Number toNative(Number value, ToNativeContext context) { return value.longValue() & 0xffffffffL; } } static final class LongLongConverter extends NumberDataConverter { static final NumberDataConverter INSTANCE = new LongLongConverter(); @Override public Number fromNative(Number nativeValue, FromNativeContext context) { return nativeValue.longValue(); } @Override public Number toNative(Number value, ToNativeContext context) { return value.longValue(); } } static final class FloatConverter extends NumberDataConverter { static final NumberDataConverter INSTANCE = new FloatConverter(); @Override public Number fromNative(Number nativeValue, FromNativeContext context) { return nativeValue.floatValue(); } @Override public Number toNative(Number value, ToNativeContext context) { return value.floatValue(); } } static final class DoubleConverter extends NumberDataConverter { static final NumberDataConverter INSTANCE = new DoubleConverter(); @Override public Number fromNative(Number nativeValue, FromNativeContext context) { return nativeValue.doubleValue(); } @Override public Number toNative(Number value, ToNativeContext context) { return value.doubleValue(); } } static final class BooleanConverter implements DataConverter { static final DataConverter INSTANCE = new BooleanConverter(); @Override public Boolean fromNative(Number nativeValue, FromNativeContext context) { return (nativeValue.intValue() & 0x1) != 0; } @Override public Number toNative(Boolean value, ToNativeContext context) { return value ? 1 : 0; } @Override public Class nativeType() { return Number.class; } } static interface ResultConverter extends FromNativeConverter { J fromNative(N value, FromNativeContext fromNativeContext); } static ResultConverter getNumberResultConverter(jnr.ffi.provider.FromNativeType fromNativeType) { if (Byte.class == fromNativeType.effectiveJavaType() || byte.class == fromNativeType.effectiveJavaType()) { return ByteResultConverter.INSTANCE; } else if (Short.class == fromNativeType.effectiveJavaType() || short.class == fromNativeType.effectiveJavaType()) { return ShortResultConverter.INSTANCE; } else if (Integer.class == fromNativeType.effectiveJavaType() || int.class == fromNativeType.effectiveJavaType()) { return IntegerResultConverter.INSTANCE; } else if (Long.class == fromNativeType.effectiveJavaType() || long.class == fromNativeType.effectiveJavaType()) { return LongResultConverter.INSTANCE; } else if (Float.class == fromNativeType.effectiveJavaType() || float.class == fromNativeType.effectiveJavaType()) { return FloatResultConverter.INSTANCE; } else if (Double.class == fromNativeType.effectiveJavaType() || double.class == fromNativeType.effectiveJavaType()) { return DoubleResultConverter.INSTANCE; } else if (Address.class == fromNativeType.effectiveJavaType()) { return AddressResultConverter.INSTANCE; } else { throw new UnsupportedOperationException("cannot convert to " + fromNativeType.effectiveJavaType()); } } static abstract class AbstractNumberResultConverter implements ResultConverter { @Override public final Class nativeType() { return Number.class; } } static final class ByteResultConverter extends AbstractNumberResultConverter { static final ResultConverter INSTANCE = new ByteResultConverter(); @Override public Byte fromNative(Number value, FromNativeContext fromNativeContext) { return value.byteValue(); } } static final class ShortResultConverter extends AbstractNumberResultConverter { static final ResultConverter INSTANCE = new ShortResultConverter(); @Override public Short fromNative(Number value, FromNativeContext fromNativeContext) { return value.shortValue(); } } static final class IntegerResultConverter extends AbstractNumberResultConverter { static final ResultConverter INSTANCE = new IntegerResultConverter(); @Override public Integer fromNative(Number value, FromNativeContext fromNativeContext) { return value.intValue(); } } static final class LongResultConverter extends AbstractNumberResultConverter { static final ResultConverter INSTANCE = new LongResultConverter(); @Override public Long fromNative(Number value, FromNativeContext fromNativeContext) { return value.longValue(); } } static final class FloatResultConverter extends AbstractNumberResultConverter { static final ResultConverter INSTANCE = new FloatResultConverter(); @Override public Float fromNative(Number value, FromNativeContext fromNativeContext) { return value.floatValue(); } } static final class DoubleResultConverter extends AbstractNumberResultConverter { static final ResultConverter INSTANCE = new DoubleResultConverter(); @Override public Double fromNative(Number value, FromNativeContext fromNativeContext) { return value.doubleValue(); } } static final class AddressResultConverter extends AbstractNumberResultConverter
{ static final ResultConverter INSTANCE = new AddressResultConverter(); @Override public Address fromNative(Number value, FromNativeContext fromNativeContext) { return Address.valueOf(value.longValue()); } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/DirectMemoryIO.java000066400000000000000000000146011316720554100266520ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import jnr.ffi.Pointer; import jnr.ffi.Runtime; import jnr.ffi.provider.AbstractMemoryIO; import java.nio.ByteBuffer; import java.nio.charset.Charset; class DirectMemoryIO extends AbstractMemoryIO { static final com.kenai.jffi.MemoryIO IO = com.kenai.jffi.MemoryIO.getInstance(); DirectMemoryIO(Runtime runtime, long address) { super(runtime, address, true); } DirectMemoryIO(Runtime runtime, int address) { super(runtime, (long) address & 0xffffffffL, true); } public long size() { return Long.MAX_VALUE; } @Override public boolean hasArray() { return false; } @Override public Object array() { throw new UnsupportedOperationException("no array"); } @Override public int arrayOffset() { throw new UnsupportedOperationException("no array"); } @Override public int arrayLength() { throw new UnsupportedOperationException("no array"); } @Override public int hashCode() { return (int) ((address() << 32L) ^ address()); } @Override public boolean equals(Object obj) { return obj instanceof Pointer && ((Pointer) obj).address() == address() && ((Pointer) obj).getRuntime().isCompatible(getRuntime()); } public final byte getByte(long offset) { return IO.getByte(address() + offset); } public final short getShort(long offset) { return IO.getShort(address() + offset); } public final int getInt(long offset) { return IO.getInt(address() + offset); } public final long getLongLong(long offset) { return IO.getLong(address() + offset); } public final float getFloat(long offset) { return IO.getFloat(address() + offset); } public final double getDouble(long offset) { return IO.getDouble(address() + offset); } public final void putByte(long offset, byte value) { IO.putByte(address() + offset, value); } public final void putShort(long offset, short value) { IO.putShort(address() + offset, value); } public final void putInt(long offset, int value) { IO.putInt(address() + offset, value); } public final void putLongLong(long offset, long value) { IO.putLong(address() + offset, value); } public final void putFloat(long offset, float value) { IO.putFloat(address() + offset, value); } public final void putDouble(long offset, double value) { IO.putDouble(address() + offset, value); } public final void get(long offset, byte[] dst, int off, int len) { IO.getByteArray(address() + offset, dst, off, len); } public final void put(long offset, byte[] src, int off, int len) { IO.putByteArray(address() + offset, src, off, len); } public final void get(long offset, short[] dst, int off, int len) { IO.getShortArray(address() + offset, dst, off, len); } public final void put(long offset, short[] src, int off, int len) { IO.putShortArray(address() + offset, src, off, len); } public final void get(long offset, int[] dst, int off, int len) { IO.getIntArray(address() + offset, dst, off, len); } public final void put(long offset, int[] src, int off, int len) { IO.putIntArray(address() + offset, src, off, len); } public final void get(long offset, long[] dst, int off, int len) { IO.getLongArray(address() + offset, dst, off, len); } public final void put(long offset, long[] src, int off, int len) { IO.putLongArray(address() + offset, src, off, len); } public final void get(long offset, float[] dst, int off, int len) { IO.getFloatArray(address() + offset, dst, off, len); } public final void put(long offset, float[] src, int off, int len) { IO.putFloatArray(address() + offset, src, off, len); } public final void get(long offset, double[] dst, int off, int len) { IO.getDoubleArray(address() + offset, dst, off, len); } public final void put(long offset, double[] src, int off, int len) { IO.putDoubleArray(address() + offset, src, off, len); } public Pointer getPointer(long offset) { return MemoryUtil.newPointer(getRuntime(), IO.getAddress(address() + offset)); } public Pointer getPointer(long offset, long size) { return MemoryUtil.newPointer(getRuntime(), IO.getAddress(this.address() + offset), size); } public void putPointer(long offset, Pointer value) { IO.putAddress(address() + offset, value != null ? value.address() : 0L); } public String getString(long offset) { return Charset.defaultCharset().decode(ByteBuffer.wrap(IO.getZeroTerminatedByteArray(address() + offset))).toString(); } public String getString(long offset, int maxLength, Charset cs) { final byte[] bytes = IO.getZeroTerminatedByteArray(address() + offset, maxLength); return cs.decode(ByteBuffer.wrap(bytes)).toString(); } public void putString(long offset, String string, int maxLength, Charset cs) { ByteBuffer buf = cs.encode(string); int len = Math.min(maxLength, buf.remaining()); IO.putZeroTerminatedByteArray(address() + offset, buf.array(), buf.arrayOffset() + buf.position(), len); } public void putZeroTerminatedByteArray(long offset, byte[] src, int off, int len) { IO.putZeroTerminatedByteArray(address() + offset, src, off, len); } public int indexOf(long offset, byte value, int maxlen) { return (int) IO.indexOf(address() + offset, value, maxlen); } public final void setMemory(long offset, long size, byte value) { IO.setMemory(this.address() + offset, size, value); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/FastIntMethodGenerator.java000066400000000000000000000124361316720554100304030ustar00rootroot00000000000000/* * Copyright (C) 2011 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import com.kenai.jffi.CallContext; import com.kenai.jffi.Platform; import jnr.ffi.NativeType; import jnr.ffi.Pointer; import jnr.ffi.CallingConvention; import jnr.ffi.provider.ParameterType; import jnr.ffi.provider.ResultType; import jnr.ffi.provider.SigType; import static jnr.ffi.provider.jffi.CodegenUtils.ci; import static jnr.ffi.provider.jffi.NumberUtil.sizeof; import static jnr.ffi.provider.jffi.Util.getBooleanProperty; /** * */ final class FastIntMethodGenerator extends AbstractFastNumericMethodGenerator { private static final boolean ENABLED = getBooleanProperty("jnr.ffi.fast-int.enabled", true); private static final int MAX_FASTINT_PARAMETERS = getMaximumFastIntParameters(); private static final String[] signatures; private static final String[] methodNames = { "invokeI0", "invokeI1", "invokeI2", "invokeI3", "invokeI4", "invokeI5", "invokeI6" }; static { signatures = new String[MAX_FASTINT_PARAMETERS + 1]; for (int i = 0; i <= MAX_FASTINT_PARAMETERS; i++) { StringBuilder sb = new StringBuilder(); sb.append('(').append(ci(CallContext.class)).append(ci(long.class)); for (int n = 0; n < i; n++) { sb.append('I'); } signatures[i] = sb.append(")I").toString(); } } @Override String getInvokerMethodName(ResultType resultType, ParameterType[] parameterTypes, boolean ignoreErrno) { final int parameterCount = parameterTypes.length; if (parameterCount <= MAX_FASTINT_PARAMETERS && parameterCount <= methodNames.length) { return methodNames[parameterCount]; } else { throw new IllegalArgumentException("invalid fast-int parameter count: " + parameterCount); } } @Override String getInvokerSignature(int parameterCount, Class nativeIntType) { if (parameterCount <= MAX_FASTINT_PARAMETERS && parameterCount <= signatures.length) { return signatures[parameterCount]; } throw new IllegalArgumentException("invalid fast-int parameter count: " + parameterCount); } final Class getInvokerType() { return int.class; } public boolean isSupported(ResultType resultType, ParameterType[] parameterTypes, CallingConvention callingConvention) { final int parameterCount = parameterTypes.length; if (!ENABLED) { return false; } if (!callingConvention.equals(CallingConvention.DEFAULT) || parameterCount > MAX_FASTINT_PARAMETERS) { return false; } final Platform platform = Platform.getPlatform(); if (platform.getOS().equals(Platform.OS.WINDOWS)) { return false; } if (!platform.getCPU().equals(Platform.CPU.I386) && !platform.getCPU().equals(Platform.CPU.X86_64)) { return false; } for (ParameterType parameterType : parameterTypes) { if (!isFastIntParameter(platform, parameterType)) { return false; } } return isFastIntResult(platform, resultType); } static int getMaximumFastIntParameters() { try { com.kenai.jffi.Invoker.class.getDeclaredMethod("invokeI6", CallContext.class, long.class, int.class, int.class, int.class, int.class, int.class, int.class); return 6; } catch (Throwable t) { return 0; } } static boolean isFastIntType(Platform platform, SigType type) { switch (type.getNativeType()) { case SCHAR: case UCHAR: case SSHORT: case USHORT: case SINT: case UINT: case SLONG: case ULONG: return sizeof(type.getNativeType()) <= 4; default: return false; } } private static boolean isSupportedPointerParameterType(Class javaParameterType) { return Pointer.class.isAssignableFrom(javaParameterType); } static boolean isFastIntResult(Platform platform, ResultType resultType) { return isFastIntType(platform, resultType) || resultType.getNativeType() == NativeType.VOID || (resultType.getNativeType() == NativeType.ADDRESS && sizeof(resultType)== 4) ; } static boolean isFastIntParameter(Platform platform, ParameterType parameterType) { return isFastIntType(platform, parameterType) || (parameterType.getNativeType() == NativeType.ADDRESS && sizeof(parameterType)== 4) && isSupportedPointerParameterType(parameterType.effectiveJavaType()); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/FastLongMethodGenerator.java000066400000000000000000000117401316720554100305450ustar00rootroot00000000000000/* * Copyright (C) 2011 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import com.kenai.jffi.CallContext; import com.kenai.jffi.Platform; import jnr.ffi.CallingConvention; import jnr.ffi.NativeType; import jnr.ffi.provider.ParameterType; import jnr.ffi.provider.ResultType; import jnr.ffi.provider.SigType; import static jnr.ffi.provider.jffi.CodegenUtils.ci; import static jnr.ffi.provider.jffi.FastIntMethodGenerator.isFastIntType; import static jnr.ffi.provider.jffi.NumberUtil.sizeof; import static jnr.ffi.provider.jffi.Util.getBooleanProperty; /** * */ public class FastLongMethodGenerator extends AbstractFastNumericMethodGenerator { private static final boolean ENABLED = getBooleanProperty("jnr.ffi.fast-long.enabled", true); private static final int MAX_PARAMETERS = getMaximumFastLongParameters(); private static final String[] signatures; private static final String[] methodNames = { "invokeL0", "invokeL1", "invokeL2", "invokeL3", "invokeL4", "invokeL5", "invokeL6" }; static { signatures = new String[MAX_PARAMETERS + 1]; for (int i = 0; i <= MAX_PARAMETERS; i++) { StringBuilder sb = new StringBuilder(); sb.append('(').append(ci(CallContext.class)).append(ci(long.class)); for (int n = 0; n < i; n++) { sb.append('J'); } signatures[i] = sb.append(")J").toString(); } } @Override String getInvokerMethodName(ResultType resultType, ParameterType[] parameterTypes, boolean ignoreErrno) { final int parameterCount = parameterTypes.length; if (parameterCount <= MAX_PARAMETERS && parameterCount <= methodNames.length) { return methodNames[parameterCount]; } else { throw new IllegalArgumentException("invalid fast-int parameter count: " + parameterCount); } } @Override String getInvokerSignature(int parameterCount, Class nativeIntType) { if (parameterCount <= MAX_PARAMETERS && parameterCount <= signatures.length) { return signatures[parameterCount]; } else { throw new IllegalArgumentException("invalid fast-int parameter count: " + parameterCount); } } @Override Class getInvokerType() { return long.class; } public boolean isSupported(ResultType resultType, ParameterType[] parameterTypes, CallingConvention callingConvention) { final int parameterCount = parameterTypes.length; if (!ENABLED) { return false; } if (callingConvention != CallingConvention.DEFAULT || parameterCount > MAX_PARAMETERS) { return false; } final Platform platform = Platform.getPlatform(); // Only supported on amd64 arches if (platform.getCPU() != Platform.CPU.X86_64) { return false; } if (platform.getOS().equals(Platform.OS.WINDOWS)) { return false; } for (ParameterType parameterType : parameterTypes) { if (!isFastLongParameter(platform, parameterType)) { return false; } } return isFastLongResult(platform, resultType); } static int getMaximumFastLongParameters() { try { com.kenai.jffi.Invoker.class.getDeclaredMethod("invokeL6", CallContext.class, long.class, long.class, long.class, long.class, long.class, long.class, long.class); return 6; } catch (Throwable t) { return 0; } } private static boolean isFastLongType(Platform platform, SigType type) { return isFastIntType(platform, type) || (type.getNativeType() == NativeType.ADDRESS && sizeof(NativeType.ADDRESS) == 8) || type.getNativeType() == NativeType.SLONG || type.getNativeType() == NativeType.ULONG || type.getNativeType() == NativeType.SLONGLONG || type.getNativeType() == NativeType.ULONGLONG; } static boolean isFastLongResult(Platform platform, ResultType resultType) { return isFastLongType(platform, resultType) || resultType.getNativeType() == NativeType.VOID || (resultType.getNativeType() == NativeType.ADDRESS && sizeof(NativeType.ADDRESS) == 8) ; } static boolean isFastLongParameter(Platform platform, ParameterType type) { return isFastLongType(platform, type); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/FastNumericMethodGenerator.java000066400000000000000000000142751316720554100312560ustar00rootroot00000000000000/* * Copyright (C) 2011 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import com.kenai.jffi.CallContext; import com.kenai.jffi.Platform; import com.kenai.jffi.Type; import jnr.ffi.CallingConvention; import jnr.ffi.NativeType; import jnr.ffi.Pointer; import jnr.ffi.provider.ParameterType; import jnr.ffi.provider.ResultType; import jnr.ffi.provider.SigType; import java.nio.*; import static jnr.ffi.provider.jffi.CodegenUtils.ci; import static jnr.ffi.provider.jffi.FastIntMethodGenerator.isFastIntType; import static jnr.ffi.provider.jffi.Util.getBooleanProperty; /** * */ class FastNumericMethodGenerator extends AbstractFastNumericMethodGenerator { private static final boolean ENABLED = getBooleanProperty("jnr.ffi.fast-numeric.enabled", true); private static final int MAX_PARAMETERS = getMaximumParameters(); private static final String[] signatures; private static final String[] methodNames = { "invokeN0", "invokeN1", "invokeN2", "invokeN3", "invokeN4", "invokeN5", "invokeN6" }; static { signatures = new String[MAX_PARAMETERS + 1]; for (int i = 0; i <= MAX_PARAMETERS; i++) { StringBuilder sb = new StringBuilder(); sb.append('(').append(ci(CallContext.class)).append(ci(long.class)); for (int n = 0; n < i; n++) { sb.append('J'); } signatures[i] = sb.append(")J").toString(); } } public boolean isSupported(ResultType resultType, ParameterType[] parameterTypes, CallingConvention callingConvention) { final int parameterCount = parameterTypes.length; if (!ENABLED) { return false; } if (callingConvention != CallingConvention.DEFAULT || parameterCount > MAX_PARAMETERS) { return false; } final Platform platform = Platform.getPlatform(); // Only supported on i386 and amd64 arches if (platform.getCPU() != Platform.CPU.I386 && platform.getCPU() != Platform.CPU.X86_64) { return false; } if (platform.getOS().equals(Platform.OS.WINDOWS)) { return false; } for (ParameterType parameterType : parameterTypes) { if (!isFastNumericParameter(platform, parameterType)) { return false; } } return isFastNumericResult(platform, resultType); } @Override String getInvokerMethodName(ResultType resultType, ParameterType[] parameterTypes, boolean ignoreErrno) { final int parameterCount = parameterTypes.length; if (parameterCount <= MAX_PARAMETERS && parameterCount <= methodNames.length) { return methodNames[parameterCount]; } else { throw new IllegalArgumentException("invalid fast-numeric parameter count: " + parameterCount); } } @Override String getInvokerSignature(int parameterCount, Class nativeIntType) { if (parameterCount <= MAX_PARAMETERS && parameterCount <= signatures.length) { return signatures[parameterCount]; } else { throw new IllegalArgumentException("invalid fast-numeric parameter count: " + parameterCount); } } @Override Class getInvokerType() { return long.class; } private static boolean isNumericType(Platform platform, SigType type) { return isFastIntType(platform, type) || type.getNativeType() == NativeType.SLONG || type.getNativeType() == NativeType.ULONG || type.getNativeType() == NativeType.SLONGLONG || type.getNativeType() == NativeType.ULONGLONG || type.getNativeType() == NativeType.FLOAT || type.getNativeType() == NativeType.DOUBLE ; } static boolean isFastNumericResult(Platform platform, ResultType type) { return isNumericType(platform, type) || NativeType.VOID == type.getNativeType() || NativeType.ADDRESS == type.getNativeType() ; } static boolean isFastNumericParameter(Platform platform, ParameterType parameterType) { return isNumericType(platform, parameterType) || (parameterType.getNativeType() == NativeType.ADDRESS && isSupportedPointerParameterType(parameterType.effectiveJavaType())); } private static boolean isSupportedPointerParameterType(Class javaParameterType) { return Pointer.class.isAssignableFrom(javaParameterType) || ByteBuffer.class.isAssignableFrom(javaParameterType) || ShortBuffer.class.isAssignableFrom(javaParameterType) || IntBuffer.class.isAssignableFrom(javaParameterType) || (LongBuffer.class.isAssignableFrom(javaParameterType) && Type.SLONG.size() == 8) || FloatBuffer.class.isAssignableFrom(javaParameterType) || DoubleBuffer.class.isAssignableFrom(javaParameterType) || byte[].class == javaParameterType || short[].class == javaParameterType || int[].class == javaParameterType || (long[].class == javaParameterType && Type.SLONG.size() == 8) || float[].class == javaParameterType || double[].class == javaParameterType || boolean[].class == javaParameterType ; } static int getMaximumParameters() { try { com.kenai.jffi.Invoker.class.getDeclaredMethod("invokeN6", CallContext.class, long.class, long.class, long.class, long.class, long.class, long.class, long.class); return 6; } catch (Throwable t) { return 0; } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/HeapBufferParameterStrategy.java000066400000000000000000000041201316720554100314050ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import com.kenai.jffi.ObjectParameterType; import java.nio.Buffer; import java.util.EnumSet; /** * */ final class HeapBufferParameterStrategy extends ParameterStrategy { public HeapBufferParameterStrategy(ObjectParameterType.ComponentType componentType) { super(HEAP, ObjectParameterType.create(ObjectParameterType.ARRAY, componentType)); } @Override public long address(Object o) { return 0; } @Override public Object object(Object o) { return ((Buffer) o).array(); } @Override public int offset(Object o) { Buffer buffer = (Buffer) o; return buffer.arrayOffset() + buffer.position(); } @Override public int length(Object o) { return ((Buffer) o).remaining(); } private static final HeapBufferParameterStrategy[] heapBufferStrategies; static { EnumSet componentTypes = EnumSet.allOf(ObjectParameterType.ComponentType.class); heapBufferStrategies = new HeapBufferParameterStrategy[componentTypes.size()]; for (ObjectParameterType.ComponentType componentType : componentTypes) { heapBufferStrategies[componentType.ordinal()] = new HeapBufferParameterStrategy(componentType); } } static HeapBufferParameterStrategy get(ObjectParameterType.ComponentType componentType) { return heapBufferStrategies[componentType.ordinal()]; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/InvokerTypeMapper.java000066400000000000000000000171721316720554100274510ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import jnr.ffi.NativeLong; import jnr.ffi.Pointer; import jnr.ffi.Struct; import jnr.ffi.annotations.Delegate; import jnr.ffi.byref.ByReference; import jnr.ffi.mapper.*; import jnr.ffi.mapper.FromNativeType; import jnr.ffi.mapper.ToNativeType; import jnr.ffi.provider.ParameterFlags; import jnr.ffi.provider.converters.*; import java.lang.reflect.Method; import java.util.EnumSet; import java.util.Set; final class InvokerTypeMapper extends AbstractSignatureTypeMapper implements SignatureTypeMapper { private final NativeClosureManager closureManager; private final AsmClassLoader classLoader; private final StructByReferenceResultConverterFactory structResultConverterFactory; public InvokerTypeMapper(NativeClosureManager closureManager, AsmClassLoader classLoader, boolean asmEnabled) { this.closureManager = closureManager; this.classLoader = classLoader; this.structResultConverterFactory = new StructByReferenceResultConverterFactory(classLoader, asmEnabled); } public FromNativeConverter getFromNativeConverter(SignatureType signatureType, FromNativeContext fromNativeContext) { FromNativeConverter converter; if (Enum.class.isAssignableFrom(signatureType.getDeclaredType())) { return EnumConverter.getInstance(signatureType.getDeclaredType().asSubclass(Enum.class)); } else if (Struct.class.isAssignableFrom(signatureType.getDeclaredType())) { return structResultConverterFactory.get(signatureType.getDeclaredType().asSubclass(Struct.class), fromNativeContext); } else if (closureManager != null && isDelegate(signatureType.getDeclaredType())) { return ClosureFromNativeConverter.getInstance(fromNativeContext.getRuntime(), signatureType, classLoader, this); } else if (NativeLong.class == signatureType.getDeclaredType()) { return NativeLongConverter.getInstance(); } else if (String.class == signatureType.getDeclaredType() || CharSequence.class == signatureType.getDeclaredType()) { return StringResultConverter.getInstance(fromNativeContext); } else if ((Set.class == signatureType.getDeclaredType() || EnumSet.class == signatureType.getDeclaredType()) && (converter = EnumSetConverter.getFromNativeConverter(signatureType, fromNativeContext)) != null) { return converter; } else { return null; } } public ToNativeConverter getToNativeConverter(SignatureType signatureType, ToNativeContext context) { Class javaType = signatureType.getDeclaredType(); ToNativeConverter converter; if (Enum.class.isAssignableFrom(javaType)) { return EnumConverter.getInstance(javaType.asSubclass(Enum.class)); } else if (Set.class.isAssignableFrom(javaType) && (converter = EnumSetConverter.getToNativeConverter(signatureType, context)) != null) { return converter; } else if (isDelegate(javaType)) { return closureManager.newClosureSite(javaType); } else if (ByReference.class.isAssignableFrom(javaType)) { return ByReferenceParameterConverter.getInstance(context); } else if (Struct.class.isAssignableFrom(javaType)) { return StructByReferenceToNativeConverter.getInstance(context); } else if (NativeLong.class.isAssignableFrom(javaType)) { return NativeLongConverter.getInstance(); } else if (StringBuilder.class.isAssignableFrom(javaType)) { return StringBuilderParameterConverter.getInstance(ParameterFlags.parse(context.getAnnotations()), context); } else if (StringBuffer.class.isAssignableFrom(javaType)) { return StringBufferParameterConverter.getInstance(ParameterFlags.parse(context.getAnnotations()), context); } else if (CharSequence.class.isAssignableFrom(javaType)) { return CharSequenceParameterConverter.getInstance(context); } else if (Byte[].class.isAssignableFrom(javaType)) { return BoxedByteArrayParameterConverter.getInstance(context); } else if (Short[].class.isAssignableFrom(javaType)) { return BoxedShortArrayParameterConverter.getInstance(context); } else if (Integer[].class.isAssignableFrom(javaType)) { return BoxedIntegerArrayParameterConverter.getInstance(context); } else if (Long[].class.isAssignableFrom(javaType)) { return Types.getType(context.getRuntime(), javaType.getComponentType(), context.getAnnotations()).size() == 4 ? BoxedLong32ArrayParameterConverter.getInstance(context) : BoxedLong64ArrayParameterConverter.getInstance(context); } else if (NativeLong[].class.isAssignableFrom(javaType)) { return Types.getType(context.getRuntime(), javaType.getComponentType(), context.getAnnotations()).size() == 4 ? NativeLong32ArrayParameterConverter.getInstance(context) : NativeLong64ArrayParameterConverter.getInstance(context); } else if (Float[].class.isAssignableFrom(javaType)) { return BoxedFloatArrayParameterConverter.getInstance(context); } else if (Double[].class.isAssignableFrom(javaType)) { return BoxedDoubleArrayParameterConverter.getInstance(context); } else if (Boolean[].class.isAssignableFrom(javaType)) { return BoxedBooleanArrayParameterConverter.getInstance(context); } else if (javaType.isArray() && Pointer.class.isAssignableFrom(javaType.getComponentType())) { return context.getRuntime().addressSize() == 4 ? Pointer32ArrayParameterConverter.getInstance(context) : Pointer64ArrayParameterConverter.getInstance(context); } else if (long[].class.isAssignableFrom(javaType) && Types.getType(context.getRuntime(), javaType.getComponentType(), context.getAnnotations()).size() == 4) { return Long32ArrayParameterConverter.getInstance(context); } else if (javaType.isArray() && Struct.class.isAssignableFrom(javaType.getComponentType())) { return StructArrayParameterConverter.getInstance(context, javaType.getComponentType()); } else if (javaType.isArray() && CharSequence.class.isAssignableFrom(javaType.getComponentType())) { return CharSequenceArrayParameterConverter.getInstance(context); } else { return null; } } @Override public FromNativeType getFromNativeType(SignatureType type, FromNativeContext context) { return FromNativeTypes.create(getFromNativeConverter(type, context)); } @Override public ToNativeType getToNativeType(SignatureType type, ToNativeContext context) { return ToNativeTypes.create(getToNativeConverter(type, context)); } private static boolean isDelegate(Class klass) { for (Method m : klass.getMethods()) { if (m.isAnnotationPresent(Delegate.class)) { return true; } } return false; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/InvokerUtil.java000066400000000000000000000260571316720554100263020ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import com.kenai.jffi.CallContext; import com.kenai.jffi.CallContextCache; import com.kenai.jffi.Type; import jnr.ffi.CallingConvention; import jnr.ffi.LibraryOption; import jnr.ffi.NativeType; import jnr.ffi.annotations.IgnoreError; import jnr.ffi.annotations.SaveError; import jnr.ffi.annotations.StdCall; import jnr.ffi.mapper.*; import jnr.ffi.provider.NativeFunction; import jnr.ffi.provider.ParameterType; import jnr.ffi.provider.ResultType; import jnr.ffi.provider.SigType; import jnr.ffi.util.Annotations; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.util.Collection; import java.util.Collections; import java.util.EnumMap; import java.util.Map; final class InvokerUtil { public static jnr.ffi.CallingConvention getCallingConvention(Map libraryOptions) { Object convention = libraryOptions.get(LibraryOption.CallingConvention); // If someone passed in the jffi calling convention, just use it. if (convention instanceof com.kenai.jffi.CallingConvention) { return com.kenai.jffi.CallingConvention.DEFAULT.equals(convention) ? jnr.ffi.CallingConvention.DEFAULT : jnr.ffi.CallingConvention.STDCALL; } if (convention instanceof jnr.ffi.CallingConvention) switch ((jnr.ffi.CallingConvention) convention) { case DEFAULT: return jnr.ffi.CallingConvention.DEFAULT; case STDCALL: return jnr.ffi.CallingConvention.STDCALL; } else if (convention != null) { throw new IllegalArgumentException("unknown calling convention: " + convention); } return jnr.ffi.CallingConvention.DEFAULT; } public static jnr.ffi.CallingConvention getCallingConvention(Class interfaceClass, Map options) { if (interfaceClass.isAnnotationPresent(StdCall.class)) { return jnr.ffi.CallingConvention.STDCALL; } return InvokerUtil.getCallingConvention(options); } public static boolean hasAnnotation(Collection annotations, Class annotationClass) { for (Annotation a : annotations) { if (annotationClass.isInstance(a)) { return true; } } return false; } static final Map jffiTypes; static { Map m = new EnumMap(jnr.ffi.NativeType.class); m.put(NativeType.VOID, Type.VOID); m.put(NativeType.SCHAR, Type.SCHAR); m.put(NativeType.UCHAR, Type.UCHAR); m.put(NativeType.SSHORT, Type.SSHORT); m.put(NativeType.USHORT, Type.USHORT); m.put(NativeType.SINT, Type.SINT); m.put(NativeType.UINT, Type.UINT); m.put(NativeType.SLONG, Type.SLONG); m.put(NativeType.ULONG, Type.ULONG); m.put(NativeType.SLONGLONG, Type.SLONG_LONG); m.put(NativeType.ULONGLONG, Type.ULONG_LONG); m.put(NativeType.FLOAT, Type.FLOAT); m.put(NativeType.DOUBLE, Type.DOUBLE); m.put(NativeType.ADDRESS, Type.POINTER); jffiTypes = Collections.unmodifiableMap(m); } static Type jffiType(jnr.ffi.NativeType jnrType) { Type jffiType = jffiTypes.get(jnrType); if (jffiType != null) { return jffiType; } throw new IllegalArgumentException("unsupported parameter type: " + jnrType); } static NativeType nativeType(jnr.ffi.Type jnrType) { return jnrType.getNativeType(); } static Collection getAnnotations(jnr.ffi.mapper.FromNativeType fromNativeType) { return fromNativeType != null ? ConverterMetaData.getAnnotations(fromNativeType.getFromNativeConverter()) : Annotations.EMPTY_ANNOTATIONS; } static Collection getAnnotations(jnr.ffi.mapper.ToNativeType toNativeType) { return toNativeType != null ? ConverterMetaData.getAnnotations(toNativeType.getToNativeConverter()) : Annotations.EMPTY_ANNOTATIONS; } static ResultType getResultType(jnr.ffi.Runtime runtime, Class type, Collection annotations, FromNativeConverter fromNativeConverter, FromNativeContext fromNativeContext) { Collection converterAnnotations = ConverterMetaData.getAnnotations(fromNativeConverter); Collection allAnnotations = Annotations.mergeAnnotations(annotations, converterAnnotations); NativeType nativeType = getMethodResultNativeType(runtime, fromNativeConverter != null ? fromNativeConverter.nativeType() : type, allAnnotations); boolean useContext = fromNativeConverter != null && !hasAnnotation(converterAnnotations, FromNativeConverter.NoContext.class); return new ResultType(type, nativeType, allAnnotations, fromNativeConverter, useContext ? fromNativeContext : null); } static ResultType getResultType(jnr.ffi.Runtime runtime, Class type, Collection annotations, jnr.ffi.mapper.FromNativeType fromNativeType, FromNativeContext fromNativeContext) { Collection converterAnnotations = getAnnotations(fromNativeType); Collection allAnnotations = Annotations.mergeAnnotations(annotations, converterAnnotations); FromNativeConverter fromNativeConverter = fromNativeType != null ? fromNativeType.getFromNativeConverter() : null; NativeType nativeType = getMethodResultNativeType(runtime, fromNativeConverter != null ? fromNativeConverter.nativeType() : type, allAnnotations); boolean useContext = fromNativeConverter != null && !hasAnnotation(converterAnnotations, FromNativeConverter.NoContext.class); return new ResultType(type, nativeType, allAnnotations, fromNativeConverter, useContext ? fromNativeContext : null); } private static ParameterType getParameterType(jnr.ffi.Runtime runtime, Class type, Collection annotations, ToNativeConverter toNativeConverter, ToNativeContext toNativeContext) { NativeType nativeType = getMethodParameterNativeType(runtime, toNativeConverter != null ? toNativeConverter.nativeType() : type, annotations); return new ParameterType(type, nativeType, annotations, toNativeConverter, toNativeContext); } private static ParameterType getParameterType(jnr.ffi.Runtime runtime, Class type, Collection annotations, jnr.ffi.mapper.ToNativeType toNativeType, ToNativeContext toNativeContext) { ToNativeConverter toNativeConverter = toNativeType != null ? toNativeType.getToNativeConverter() : null; NativeType nativeType = getMethodParameterNativeType(runtime, toNativeConverter != null ? toNativeConverter.nativeType() : type, annotations); return new ParameterType(type, nativeType, annotations, toNativeConverter, toNativeContext); } static ParameterType[] getParameterTypes(jnr.ffi.Runtime runtime, SignatureTypeMapper typeMapper, Method m) { final Class[] javaParameterTypes = m.getParameterTypes(); final Annotation[][] parameterAnnotations = m.getParameterAnnotations(); ParameterType[] parameterTypes = new ParameterType[javaParameterTypes.length]; for (int pidx = 0; pidx < javaParameterTypes.length; ++pidx) { Collection annotations = Annotations.sortedAnnotationCollection(parameterAnnotations[pidx]); ToNativeContext toNativeContext = new MethodParameterContext(runtime, m, pidx, annotations); SignatureType signatureType = DefaultSignatureType.create(javaParameterTypes[pidx], toNativeContext); jnr.ffi.mapper.ToNativeType toNativeType = typeMapper.getToNativeType(signatureType, toNativeContext); ToNativeConverter toNativeConverter = toNativeType != null ? toNativeType.getToNativeConverter() : null; Collection converterAnnotations = ConverterMetaData.getAnnotations(toNativeConverter); Collection allAnnotations = Annotations.mergeAnnotations(annotations, converterAnnotations); boolean contextRequired = toNativeConverter != null && !hasAnnotation(converterAnnotations, ToNativeConverter.NoContext.class); parameterTypes[pidx] = getParameterType(runtime, javaParameterTypes[pidx], allAnnotations, toNativeConverter, contextRequired ? toNativeContext : null); } return parameterTypes; } static CallContext getCallContext(SigType resultType, SigType[] parameterTypes, jnr.ffi.CallingConvention convention, boolean requiresErrno) { return getCallContext(resultType, parameterTypes, parameterTypes.length, convention, requiresErrno); } static CallContext getCallContext(SigType resultType, SigType[] parameterTypes, int paramTypesLength, jnr.ffi.CallingConvention convention, boolean requiresErrno) { com.kenai.jffi.Type[] nativeParamTypes = new com.kenai.jffi.Type[paramTypesLength]; for (int i = 0; i < nativeParamTypes.length; ++i) { nativeParamTypes[i] = jffiType(parameterTypes[i].getNativeType()); } return CallContextCache.getInstance().getCallContext(jffiType(resultType.getNativeType()), nativeParamTypes, jffiConvention(convention), requiresErrno); } public static jnr.ffi.CallingConvention getNativeCallingConvention(Method m) { if (m.isAnnotationPresent(StdCall.class) || m.getDeclaringClass().isAnnotationPresent(StdCall.class)) { return CallingConvention.STDCALL; } return CallingConvention.DEFAULT; } static NativeType getMethodParameterNativeType(jnr.ffi.Runtime runtime, Class parameterClass, Collection annotations) { return Types.getType(runtime, parameterClass, annotations).getNativeType(); } static NativeType getMethodResultNativeType(jnr.ffi.Runtime runtime, Class resultClass, Collection annotations) { return Types.getType(runtime, resultClass, annotations).getNativeType(); } public static final com.kenai.jffi.CallingConvention jffiConvention(jnr.ffi.CallingConvention callingConvention) { return callingConvention == jnr.ffi.CallingConvention.DEFAULT ? com.kenai.jffi.CallingConvention.DEFAULT : com.kenai.jffi.CallingConvention.STDCALL; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/JNIInvokeInterface.java000066400000000000000000000017621316720554100274400ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; /** * Indexes of JavaVM methods */ public class JNIInvokeInterface { public static final int DestroyJavaVM = 3; public static final int AttachCurrentThread = 4; public static final int DetachCurrentThread = 5; public static final int GetEnv = 6; public static final int AttachCurrentThreadAsDaemon = 7; } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/JNINativeInterface.java000066400000000000000000000323171316720554100274330ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; /** * * WARNING: Highly experimental!!! * * This class contains constants that are the indexes withing the JNINativeInterface_ * struct of each of the JNIEnv functions. To invoke one of the functions, the * index _must_ be multiplied by sizeof(void *), then used as an index into the table. * * These indexes are valid on both 32bit and 64bit linux and macos. Win32 also * seems to be the same. Other platforms may be completely different. */ public final class JNINativeInterface { private JNINativeInterface() { } public static final int GetVersion = 4; public static final int DefineClass = 5; public static final int FindClass = 6; public static final int FromReflectedMethod = 7; public static final int FromReflectedField = 8; public static final int ToReflectedMethod = 9; public static final int GetSuperclass = 10; public static final int IsAssignableFrom = 11; public static final int ToReflectedField = 12; public static final int Throw = 13; public static final int ThrowNew = 14; public static final int ExceptionOccurred = 15; public static final int ExceptionDescribe = 16; public static final int ExceptionClear = 17; public static final int FatalError = 18; public static final int PushLocalFrame = 19; public static final int PopLocalFrame = 20; public static final int NewGlobalRef = 21; public static final int DeleteGlobalRef = 22; public static final int DeleteLocalRef = 23; public static final int IsSameObject = 24; public static final int NewLocalRef = 25; public static final int EnsureLocalCapacity = 26; public static final int AllocObject = 27; public static final int NewObject = 28; public static final int NewObjectV = 29; public static final int NewObjectA = 30; public static final int GetObjectClass = 31; public static final int IsInstanceOf = 32; public static final int GetMethodID = 33; public static final int CallObjectMethod = 34; public static final int CallObjectMethodV = 35; public static final int CallObjectMethodA = 36; public static final int CallBooleanMethod = 37; public static final int CallBooleanMethodV = 38; public static final int CallBooleanMethodA = 39; public static final int CallByteMethod = 40; public static final int CallByteMethodV = 41; public static final int CallByteMethodA = 42; public static final int CallCharMethod = 43; public static final int CallCharMethodV = 44; public static final int CallCharMethodA = 45; public static final int CallShortMethod = 46; public static final int CallShortMethodV = 47; public static final int CallShortMethodA = 48; public static final int CallIntMethod = 49; public static final int CallIntMethodV = 50; public static final int CallIntMethodA = 51; public static final int CallLongMethod = 52; public static final int CallLongMethodV = 53; public static final int CallLongMethodA = 54; public static final int CallFloatMethod = 55; public static final int CallFloatMethodV = 56; public static final int CallFloatMethodA = 57; public static final int CallDoubleMethod = 58; public static final int CallDoubleMethodV = 59; public static final int CallDoubleMethodA = 60; public static final int CallVoidMethod = 61; public static final int CallVoidMethodV = 62; public static final int CallVoidMethodA = 63; public static final int CallNonvirtualObjectMethod = 64; public static final int CallNonvirtualObjectMethodV = 65; public static final int CallNonvirtualObjectMethodA = 66; public static final int CallNonvirtualBooleanMethod = 67; public static final int CallNonvirtualBooleanMethodV = 68; public static final int CallNonvirtualBooleanMethodA = 69; public static final int CallNonvirtualByteMethod = 70; public static final int CallNonvirtualByteMethodV = 71; public static final int CallNonvirtualByteMethodA = 72; public static final int CallNonvirtualCharMethod = 73; public static final int CallNonvirtualCharMethodV = 74; public static final int CallNonvirtualCharMethodA = 75; public static final int CallNonvirtualShortMethod = 76; public static final int CallNonvirtualShortMethodV = 77; public static final int CallNonvirtualShortMethodA = 78; public static final int CallNonvirtualIntMethod = 79; public static final int CallNonvirtualIntMethodV = 80; public static final int CallNonvirtualIntMethodA = 81; public static final int CallNonvirtualLongMethod = 82; public static final int CallNonvirtualLongMethodV = 83; public static final int CallNonvirtualLongMethodA = 84; public static final int CallNonvirtualFloatMethod = 85; public static final int CallNonvirtualFloatMethodV = 86; public static final int CallNonvirtualFloatMethodA = 87; public static final int CallNonvirtualDoubleMethod = 88; public static final int CallNonvirtualDoubleMethodV = 89; public static final int CallNonvirtualDoubleMethodA = 90; public static final int CallNonvirtualVoidMethod = 91; public static final int CallNonvirtualVoidMethodV = 92; public static final int CallNonvirtualVoidMethodA = 93; public static final int GetFieldID = 94; public static final int GetObjectField = 95; public static final int GetBooleanField = 96; public static final int GetByteField = 97; public static final int GetCharField = 98; public static final int GetShortField = 99; public static final int GetIntField = 100; public static final int GetLongField = 101; public static final int GetFloatField = 102; public static final int GetDoubleField = 103; public static final int SetObjectField = 104; public static final int SetBooleanField = 105; public static final int SetByteField = 106; public static final int SetCharField = 107; public static final int SetShortField = 108; public static final int SetIntField = 109; public static final int SetLongField = 110; public static final int SetFloatField = 111; public static final int SetDoubleField = 112; public static final int GetStaticMethodID = 113; public static final int CallStaticObjectMethod = 114; public static final int CallStaticObjectMethodV = 115; public static final int CallStaticObjectMethodA = 116; public static final int CallStaticBooleanMethod = 117; public static final int CallStaticBooleanMethodV = 118; public static final int CallStaticBooleanMethodA = 119; public static final int CallStaticByteMethod = 120; public static final int CallStaticByteMethodV = 121; public static final int CallStaticByteMethodA = 122; public static final int CallStaticCharMethod = 123; public static final int CallStaticCharMethodV = 124; public static final int CallStaticCharMethodA = 125; public static final int CallStaticShortMethod = 126; public static final int CallStaticShortMethodV = 127; public static final int CallStaticShortMethodA = 128; public static final int CallStaticIntMethod = 129; public static final int CallStaticIntMethodV = 130; public static final int CallStaticIntMethodA = 131; public static final int CallStaticLongMethod = 132; public static final int CallStaticLongMethodV = 133; public static final int CallStaticLongMethodA = 134; public static final int CallStaticFloatMethod = 135; public static final int CallStaticFloatMethodV = 136; public static final int CallStaticFloatMethodA = 137; public static final int CallStaticDoubleMethod = 138; public static final int CallStaticDoubleMethodV = 139; public static final int CallStaticDoubleMethodA = 140; public static final int CallStaticVoidMethod = 141; public static final int CallStaticVoidMethodV = 142; public static final int CallStaticVoidMethodA = 143; public static final int GetStaticFieldID = 144; public static final int GetStaticObjectField = 145; public static final int GetStaticBooleanField = 146; public static final int GetStaticByteField = 147; public static final int GetStaticCharField = 148; public static final int GetStaticShortField = 149; public static final int GetStaticIntField = 150; public static final int GetStaticLongField = 151; public static final int GetStaticFloatField = 152; public static final int GetStaticDoubleField = 153; public static final int SetStaticObjectField = 154; public static final int SetStaticBooleanField = 155; public static final int SetStaticByteField = 156; public static final int SetStaticCharField = 157; public static final int SetStaticShortField = 158; public static final int SetStaticIntField = 159; public static final int SetStaticLongField = 160; public static final int SetStaticFloatField = 161; public static final int SetStaticDoubleField = 162; public static final int NewString = 163; public static final int GetStringLength = 164; public static final int GetStringChars = 165; public static final int ReleaseStringChars = 166; public static final int NewStringUTF = 167; public static final int GetStringUTFLength = 168; public static final int GetStringUTFChars = 169; public static final int ReleaseStringUTFChars = 170; public static final int GetArrayLength = 171; public static final int NewObjectArray = 172; public static final int GetObjectArrayElement = 173; public static final int SetObjectArrayElement = 174; public static final int NewBooleanArray = 175; public static final int NewByteArray = 176; public static final int NewCharArray = 177; public static final int NewShortArray = 178; public static final int NewIntArray = 179; public static final int NewLongArray = 180; public static final int NewFloatArray = 181; public static final int NewDoubleArray = 182; public static final int GetBooleanArrayElements = 183; public static final int GetByteArrayElements = 184; public static final int GetCharArrayElements = 185; public static final int GetShortArrayElements = 186; public static final int GetIntArrayElements = 187; public static final int GetLongArrayElements = 188; public static final int GetFloatArrayElements = 189; public static final int GetDoubleArrayElements = 190; public static final int ReleaseBooleanArrayElements = 191; public static final int ReleaseByteArrayElements = 192; public static final int ReleaseCharArrayElements = 193; public static final int ReleaseShortArrayElements = 194; public static final int ReleaseIntArrayElements = 195; public static final int ReleaseLongArrayElements = 196; public static final int ReleaseFloatArrayElements = 197; public static final int ReleaseDoubleArrayElements = 198; public static final int GetBooleanArrayRegion = 199; public static final int GetByteArrayRegion = 200; public static final int GetCharArrayRegion = 201; public static final int GetShortArrayRegion = 202; public static final int GetIntArrayRegion = 203; public static final int GetLongArrayRegion = 204; public static final int GetFloatArrayRegion = 205; public static final int GetDoubleArrayRegion = 206; public static final int SetBooleanArrayRegion = 207; public static final int SetByteArrayRegion = 208; public static final int SetCharArrayRegion = 209; public static final int SetShortArrayRegion = 210; public static final int SetIntArrayRegion = 211; public static final int SetLongArrayRegion = 212; public static final int SetFloatArrayRegion = 213; public static final int SetDoubleArrayRegion = 214; public static final int RegisterNatives = 215; public static final int UnregisterNatives = 216; public static final int MonitorEnter = 217; public static final int MonitorExit = 218; public static final int GetJavaVM = 219; public static final int GetStringRegion = 220; public static final int GetStringUTFRegion = 221; public static final int GetPrimitiveArrayCritical = 222; public static final int ReleasePrimitiveArrayCritical = 223; public static final int GetStringCritical = 224; public static final int ReleaseStringCritical = 225; public static final int NewWeakGlobalRef = 226; public static final int DeleteWeakGlobalRef = 227; public static final int ExceptionCheck = 228; public static final int NewDirectByteBuffer = 229; public static final int GetDirectBufferAddress = 230; public static final int GetDirectBufferCapacity = 231; public static final int GetObjectRefType = 232; } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/LibraryLoader.java000066400000000000000000000016501316720554100265520ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import jnr.ffi.LibraryOption; import jnr.ffi.provider.NativeFunction; import java.util.Map; public abstract class LibraryLoader { abstract T loadLibrary(NativeLibrary library, Class interfaceClass, Map libraryOptions); } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/LocalVariable.java000066400000000000000000000015331316720554100265170ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; /** * */ class LocalVariable { final Class type; final int idx; public LocalVariable(Class type, int idx) { this.type = type; this.idx = idx; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/LocalVariableAllocator.java000066400000000000000000000026101316720554100303550ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import jnr.ffi.provider.SigType; /** * */ class LocalVariableAllocator { private int nextIndex; LocalVariableAllocator(SigType[] parameterTypes) { this.nextIndex = AsmUtil.calculateLocalVariableSpace(parameterTypes) + 1; } LocalVariableAllocator(Class... parameterTypes) { this.nextIndex = AsmUtil.calculateLocalVariableSpace(parameterTypes) + 1; } LocalVariableAllocator(int nextIndex) { this.nextIndex = nextIndex; } LocalVariable allocate(Class type) { LocalVariable var = new LocalVariable(type, nextIndex); this.nextIndex += AsmUtil.calculateLocalVariableSpace(type); return var; } int getSpaceUsed() { return nextIndex; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/MemoryUtil.java000066400000000000000000000024441316720554100261270ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import jnr.ffi.provider.BoundedMemoryIO; import jnr.ffi.provider.NullMemoryIO; public final class MemoryUtil { private MemoryUtil() {} static jnr.ffi.Pointer newPointer(jnr.ffi.Runtime runtime, long ptr) { return ptr != 0 ? new DirectMemoryIO(runtime, ptr) : null; } static jnr.ffi.Pointer newPointer(jnr.ffi.Runtime runtime, int ptr) { return ptr != 0 ? new DirectMemoryIO(runtime, ptr) : null; } static jnr.ffi.Pointer newPointer(jnr.ffi.Runtime runtime, long ptr, long size) { return ptr != 0 ? new BoundedMemoryIO(new DirectMemoryIO(runtime, ptr), 0, size) : null; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/MethodGenerator.java000066400000000000000000000022341316720554100271050ustar00rootroot00000000000000/* * Copyright (C) 2011 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import com.kenai.jffi.Function; import jnr.ffi.CallingConvention; import jnr.ffi.provider.ParameterType; import jnr.ffi.provider.ResultType; /** * */ public interface MethodGenerator { public boolean isSupported(ResultType resultType, ParameterType[] parameterTypes, CallingConvention callingConvention); public void generate(AsmBuilder builder, String functionName, Function function, ResultType resultType, ParameterType[] parameterTypes, boolean ignoreError); } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/NativeClosureFactory.java000066400000000000000000000201311316720554100301250ustar00rootroot00000000000000/* * Copyright (C) 2011 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import com.kenai.jffi.CallContext; import com.kenai.jffi.Closure; import com.kenai.jffi.ClosureMagazine; import com.kenai.jffi.ClosureManager; import jnr.ffi.Pointer; import jnr.ffi.annotations.Delegate; import jnr.ffi.mapper.SignatureTypeMapper; import jnr.ffi.provider.FromNativeType; import jnr.ffi.provider.ToNativeType; import jnr.ffi.util.ref.FinalizableWeakReference; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.ConcurrentMap; import static jnr.ffi.provider.jffi.ClosureUtil.getParameterType; import static jnr.ffi.provider.jffi.ClosureUtil.getResultType; import static jnr.ffi.provider.jffi.InvokerUtil.getCallContext; import static jnr.ffi.provider.jffi.InvokerUtil.getNativeCallingConvention; /** * */ public final class NativeClosureFactory { private final jnr.ffi.Runtime runtime; private final ConcurrentMap closures = new ConcurrentHashMap(); private final CallContext callContext; private final NativeClosureProxy.Factory closureProxyFactory; private final ConcurrentLinkedQueue freeQueue = new ConcurrentLinkedQueue(); private ClosureMagazine currentMagazine; protected NativeClosureFactory(jnr.ffi.Runtime runtime, CallContext callContext, NativeClosureProxy.Factory closureProxyFactory) { this.runtime = runtime; this.closureProxyFactory = closureProxyFactory; this.callContext = callContext; } static NativeClosureFactory newClosureFactory(jnr.ffi.Runtime runtime, Class closureClass, SignatureTypeMapper typeMapper, AsmClassLoader classLoader) { Method callMethod = null; for (Method m : closureClass.getMethods()) { if (m.isAnnotationPresent(Delegate.class) && Modifier.isPublic(m.getModifiers()) && !Modifier.isStatic(m.getModifiers())) { callMethod = m; break; } } if (callMethod == null) { throw new NoSuchMethodError("no public non-static delegate method defined in " + closureClass.getName()); } Class[] parameterTypes = callMethod.getParameterTypes(); FromNativeType[] parameterSigTypes = new FromNativeType[parameterTypes.length]; for (int i = 0; i < parameterTypes.length; ++i) { parameterSigTypes[i] = getParameterType(runtime, callMethod, i, typeMapper); } ToNativeType resultType = getResultType(runtime, callMethod, typeMapper); return new NativeClosureFactory(runtime, getCallContext(resultType, parameterSigTypes, getNativeCallingConvention(callMethod), false), NativeClosureProxy.newProxyFactory(runtime, callMethod, resultType, parameterSigTypes, classLoader)); } private void expunge(ClosureReference ref, Integer key) { // Fast case - no chained elements; can just remove from the hash map if (ref.next == null && closures.remove(key, ref)) { return; } // Remove from chained list synchronized (closures) { for (ClosureReference clref = closures.get(key), prev = clref; clref != null; prev = clref, clref = clref.next) { if (clref == ref) { if (prev != clref) { // if not first element in list, just remove this one prev.next = clref.next; } else { // first element in list, replace with the next if non-null, else remove from map if (clref.next != null) { closures.replace(key, clref, clref.next); } else { closures.remove(key, clref); } } break; } } } } private void recycle(NativeClosurePointer ptr) { freeQueue.add(ptr); } final class ClosureReference extends FinalizableWeakReference { volatile ClosureReference next; private final NativeClosureFactory factory; private final NativeClosurePointer pointer; private final Integer key; private ClosureReference(Object referent, Integer key, NativeClosureFactory factory, NativeClosurePointer pointer) { super(referent, NativeFinalizer.getInstance().getFinalizerQueue()); this.factory = factory; this.key = key; this.pointer = pointer; } public void finalizeReferent() { clear(); factory.expunge(this, key); factory.recycle(pointer); } Object getCallable() { return get(); } Pointer getPointer() { return pointer; } } NativeClosurePointer allocateClosurePointer() { NativeClosurePointer closurePointer = freeQueue.poll(); if (closurePointer != null) { return closurePointer; } NativeClosureProxy proxy = closureProxyFactory.newClosureProxy(); Closure.Handle closureHandle = null; synchronized (this) { do { if (currentMagazine == null || ((closureHandle = currentMagazine.allocate(proxy)) == null)) { currentMagazine = ClosureManager.getInstance().newClosureMagazine(callContext, closureProxyFactory.getInvokeMethod()); } } while (closureHandle == null); } return new NativeClosurePointer(runtime, closureHandle, proxy); } NativeClosurePointer newClosure(Object callable, Integer key) { return newClosureReference(callable, key).pointer; } ClosureReference newClosureReference(Object callable, Integer key) { NativeClosurePointer ptr = allocateClosurePointer(); ClosureReference ref = new ClosureReference(callable, key, this, ptr); ptr.proxy.closureReference = ref; if (closures.putIfAbsent(key, ref) == null) { return ref; } synchronized (closures) { do { // prepend and make new pointer the list head ref.next = closures.get(key); // If old value already removed (e.g. by expunge), just put the new value in if (ref.next == null && closures.putIfAbsent(key, ref) == null) { break; } } while (!closures.replace(key, ref.next, ref)); } return ref; } ClosureReference getClosureReference(Object callable) { Integer key = System.identityHashCode(callable); ClosureReference ref = closures.get(key); if (ref != null) { // Simple case - no identity hash code clash - just return the ptr if (ref.getCallable() == callable) { return ref; } // There has been a key clash, search the list synchronized (closures) { while ((ref = ref.next) != null) { if (ref.getCallable() == callable) { return ref; } } } } return newClosureReference(callable, key); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/NativeClosureManager.java000066400000000000000000000105311316720554100300730ustar00rootroot00000000000000/* * Copyright (C) 2011 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import jnr.ffi.Pointer; import jnr.ffi.mapper.*; import jnr.ffi.provider.ClosureManager; import java.util.IdentityHashMap; import java.util.Map; /** * */ final class NativeClosureManager implements ClosureManager { private volatile Map, NativeClosureFactory> factories = new IdentityHashMap, NativeClosureFactory>(); private final jnr.ffi.Runtime runtime; private final SignatureTypeMapper typeMapper; private final AsmClassLoader classLoader; NativeClosureManager(jnr.ffi.Runtime runtime, SignatureTypeMapper typeMapper, AsmClassLoader classLoader) { this.runtime = runtime; this.typeMapper = new CompositeTypeMapper(typeMapper, new CachingTypeMapper(new ClosureTypeMapper())); this.classLoader = classLoader; } NativeClosureFactory getClosureFactory(Class closureClass) { NativeClosureFactory factory = factories.get(closureClass); if (factory != null) { return factory; } return initClosureFactory(closureClass); } public T newClosure(Class closureClass, T instance) { NativeClosureFactory factory = factories.get(closureClass); if (factory != null) { //return factory.newClosure(instance); } return null; } public final jnr.ffi.Pointer getClosurePointer(Class closureClass, T instance) { return getClosureFactory(closureClass).getClosureReference(instance).getPointer(); } synchronized NativeClosureFactory initClosureFactory(Class closureClass) { NativeClosureFactory factory = factories.get(closureClass); if (factory != null) { return factory; } factory = NativeClosureFactory.newClosureFactory(runtime, closureClass, typeMapper, classLoader); Map, NativeClosureFactory> factories = new IdentityHashMap, NativeClosureFactory>(); factories.putAll(this.factories); factories.put(closureClass, factory); this.factories = factories; return factory; } ToNativeConverter newClosureSite(Class closureClass) { return new ClosureSite(getClosureFactory(closureClass)); } @ToNativeConverter.NoContext public static final class ClosureSite implements ToNativeConverter { private final NativeClosureFactory factory; private NativeClosureFactory.ClosureReference closureReference = null; private ClosureSite(NativeClosureFactory factory) { this.factory = factory; } public Pointer toNative(T value, ToNativeContext context) { if (value == null) { return null; } // If passing down a function pointer, don't re-wrap it if (value instanceof ClosureFromNativeConverter.AbstractClosurePointer) { return (ClosureFromNativeConverter.AbstractClosurePointer) value; } NativeClosureFactory.ClosureReference ref = closureReference; // Fast path - same delegate as last call to this site - just re-use the native closure if (ref != null && ref.getCallable() == value) { return ref.getPointer(); } ref = factory.getClosureReference(value); // Cache the new native closure, if this site has no valid native closure if (closureReference == null || closureReference.get() == null) { closureReference = ref; } return ref.getPointer(); } public Class nativeType() { return Pointer.class; } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/NativeClosurePointer.java000066400000000000000000000022501316720554100301400ustar00rootroot00000000000000/* * Copyright (C) 2011 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import jnr.ffi.provider.InAccessibleMemoryIO; /** * */ class NativeClosurePointer extends InAccessibleMemoryIO { private final com.kenai.jffi.Closure.Handle handle; final NativeClosureProxy proxy; public NativeClosurePointer(jnr.ffi.Runtime runtime, com.kenai.jffi.Closure.Handle handle, NativeClosureProxy proxy) { super(runtime, handle.getAddress(), true); this.handle = handle; this.proxy = proxy; } @Override public long size() { return 0; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/NativeClosureProxy.java000066400000000000000000000274401316720554100276510ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import jnr.ffi.NativeType; import jnr.ffi.Pointer; import jnr.ffi.provider.FromNativeType; import jnr.ffi.provider.ToNativeType; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassWriter; import java.io.PrintWriter; import java.lang.ref.Reference; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.concurrent.atomic.AtomicLong; import static jnr.ffi.provider.jffi.AsmUtil.*; import static jnr.ffi.provider.jffi.CodegenUtils.*; import static jnr.ffi.provider.jffi.NumberUtil.convertPrimitive; import static jnr.ffi.provider.jffi.NumberUtil.sizeof; import static org.objectweb.asm.Opcodes.*; /** * */ public abstract class NativeClosureProxy { protected final jnr.ffi.Runtime runtime; volatile Reference closureReference; protected NativeClosureProxy(NativeRuntime runtime) { this.runtime = runtime; } protected Object getCallable() { Object callable = closureReference != null ? closureReference.get() : null; if (callable != null) { return callable; } throw new NullPointerException("callable is null"); } static class Factory { private final jnr.ffi.Runtime runtime; private final Constructor constructor; private final Object[] objectFields; private final Method invokeMethod; Factory(jnr.ffi.Runtime runtime, Constructor constructor, Method invokeMethod, Object[] objectFields) { this.runtime = runtime; this.constructor = constructor; this.invokeMethod = invokeMethod; this.objectFields = objectFields; } NativeClosureProxy newClosureProxy() { try { return constructor.newInstance(runtime, objectFields); } catch (Throwable t) { throw new RuntimeException(t); } } Method getInvokeMethod() { return invokeMethod; } } public final static boolean DEBUG = Boolean.getBoolean("jnr.ffi.compile.dump"); private static final AtomicLong nextClassID = new AtomicLong(0); static Factory newProxyFactory(jnr.ffi.Runtime runtime, Method callMethod, ToNativeType resultType, FromNativeType[] parameterTypes, AsmClassLoader classLoader) { final String closureProxyClassName = p(NativeClosureProxy.class) + "$$impl$$" + nextClassID.getAndIncrement(); final ClassWriter closureClassWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES); final ClassVisitor closureClassVisitor = DEBUG ? AsmUtil.newCheckClassAdapter(closureClassWriter) : closureClassWriter; AsmBuilder builder = new AsmBuilder(runtime, closureProxyClassName, closureClassVisitor, classLoader); closureClassVisitor.visit(V1_6, ACC_PUBLIC | ACC_FINAL, closureProxyClassName, null, p(NativeClosureProxy.class), new String[]{ }); Class[] nativeParameterClasses = new Class[parameterTypes.length]; for (int i = 0; i < parameterTypes.length; i++) { nativeParameterClasses[i] = getNativeClass(parameterTypes[i].getNativeType()); } Class nativeResultClass = getNativeClass(resultType.getNativeType()); SkinnyMethodAdapter mv = new SkinnyMethodAdapter(closureClassVisitor, ACC_PUBLIC | ACC_FINAL, "invoke", sig(nativeResultClass, nativeParameterClasses), null, null); mv.start(); // Cast the callable instance to the correct class mv.aload(0); mv.invokevirtual(NativeClosureProxy.class, "getCallable", Object.class); mv.checkcast(p(callMethod.getDeclaringClass())); LocalVariable[] parameterVariables = AsmUtil.getParameterVariables(nativeParameterClasses); // Construct callback method LocalVariableAllocator localVariableAllocator = new LocalVariableAllocator(nativeParameterClasses); for (int i = 0; i < parameterTypes.length; ++i) { FromNativeType parameterType = parameterTypes[i]; Class parameterClass = parameterType.effectiveJavaType(); if (!isParameterTypeSupported(parameterClass)) { throw new IllegalArgumentException("unsupported closure parameter type " + parameterTypes[i].getDeclaredType()); } AsmUtil.load(mv, nativeParameterClasses[i], parameterVariables[i]); if (!parameterClass.isPrimitive()) { emitFromNativeConversion(builder, mv, parameterTypes[i], nativeParameterClasses[i]); } else { convertPrimitive(mv, nativeParameterClasses[i], parameterClass, parameterType.getNativeType()); } } // dispatch to java method if (callMethod.getDeclaringClass().isInterface()) { mv.invokeinterface(p(callMethod.getDeclaringClass()), callMethod.getName(), sig(callMethod.getReturnType(), callMethod.getParameterTypes())); } else { mv.invokevirtual(p(callMethod.getDeclaringClass()), callMethod.getName(), sig(callMethod.getReturnType(), callMethod.getParameterTypes())); } if (!isReturnTypeSupported(resultType.effectiveJavaType())) { throw new IllegalArgumentException("unsupported closure return type " + resultType.getDeclaredType()); } emitToNativeConversion(builder, mv, resultType); if (!resultType.effectiveJavaType().isPrimitive()) { if (Number.class.isAssignableFrom(resultType.effectiveJavaType())) { AsmUtil.unboxNumber(mv, resultType.effectiveJavaType(), nativeResultClass, resultType.getNativeType()); } else if (Boolean.class.isAssignableFrom(resultType.effectiveJavaType())) { AsmUtil.unboxBoolean(mv, nativeResultClass); } else if (Pointer.class.isAssignableFrom(resultType.effectiveJavaType())) { AsmUtil.unboxPointer(mv, nativeResultClass); } } emitReturnOp(mv, nativeResultClass); mv.visitMaxs(10, 10 + localVariableAllocator.getSpaceUsed()); mv.visitEnd(); SkinnyMethodAdapter closureInit = new SkinnyMethodAdapter(closureClassVisitor, ACC_PUBLIC, "", sig(void.class, NativeRuntime.class, Object[].class), null, null); closureInit.start(); closureInit.aload(0); closureInit.aload(1); closureInit.invokespecial(p(NativeClosureProxy.class), "", sig(void.class, NativeRuntime.class)); AsmBuilder.ObjectField[] fields = builder.getObjectFieldArray(); Object[] fieldObjects = new Object[fields.length]; for (int i = 0; i < fieldObjects.length; i++) { fieldObjects[i] = fields[i].value; String fieldName = fields[i].name; builder.getClassVisitor().visitField(ACC_PRIVATE | ACC_FINAL, fieldName, ci(fields[i].klass), null, null); closureInit.aload(0); closureInit.aload(2); closureInit.pushInt(i); closureInit.aaload(); if (fields[i].klass.isPrimitive()) { Class unboxedType = unboxedType(fields[i].klass); closureInit.checkcast(unboxedType); unboxNumber(closureInit, unboxedType, fields[i].klass); } else { closureInit.checkcast(fields[i].klass); } closureInit.putfield(builder.getClassNamePath(), fieldName, ci(fields[i].klass)); } closureInit.voidreturn(); closureInit.visitMaxs(10, 10); closureInit.visitEnd(); closureClassVisitor.visitEnd(); try { byte[] closureImpBytes = closureClassWriter.toByteArray(); if (DEBUG) { ClassVisitor trace = AsmUtil.newTraceClassVisitor(new PrintWriter(System.err)); new ClassReader(closureImpBytes).accept(trace, 0); } ClassLoader cl = NativeClosureFactory.class.getClassLoader(); if (cl == null) { cl = Thread.currentThread().getContextClassLoader(); } if (cl == null) { cl = ClassLoader.getSystemClassLoader(); } Class klass = builder.getClassLoader().defineClass(c(closureProxyClassName), closureImpBytes); Constructor constructor = null; try { constructor = klass.getConstructor(NativeRuntime.class, Object[].class); } catch(NoSuchMethodException e) { constructor = (Constructor) klass.getConstructors()[0]; } return new Factory(runtime, constructor, klass.getMethod("invoke", nativeParameterClasses), fieldObjects); } catch (Throwable ex) { throw new RuntimeException(ex); } } private static boolean isReturnTypeSupported(Class type) { return type.isPrimitive() || boolean.class == type || Boolean.class == type || Byte.class == type || Short.class == type || Integer.class == type || Long.class == type || Float.class == type || Double.class == type || Pointer.class == type ; } private static boolean isParameterTypeSupported(Class type) { return type.isPrimitive() || boolean.class == type || Boolean.class == type || Byte.class == type || Short.class == type || Integer.class == type || Long.class == type || Float.class == type || Double.class == type || Pointer.class == type /* || CharSequence.class == type || Buffer.class.isAssignableFrom(type) || (type.isArray() && type.getComponentType().isPrimitive()) || (type.isArray() && Struct.class.isAssignableFrom(type.getComponentType())) || (type.isArray() && Pointer.class.isAssignableFrom(type.getComponentType())) || (type.isArray() && CharSequence.class.isAssignableFrom(type.getComponentType())) || ByReference.class.isAssignableFrom(type) */ ; } static Class getNativeClass(NativeType nativeType) { switch (nativeType) { case SCHAR: case UCHAR: return byte.class; case SSHORT: case USHORT: return short.class; case SINT: case UINT: return int.class; case SLONG: case ULONG: case ADDRESS: return sizeof(nativeType) <= 4 ? int.class : long.class; case SLONGLONG: case ULONGLONG: return long.class; case FLOAT: return float.class; case DOUBLE: return double.class; case VOID: return void.class; default: throw new IllegalArgumentException("unsupported native type: " + nativeType); } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/NativeFinalizer.java000066400000000000000000000022571316720554100271150ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import jnr.ffi.util.ref.FinalizableReferenceQueue; /** * */ class NativeFinalizer { private final FinalizableReferenceQueue finalizerQueue = new FinalizableReferenceQueue(); private static final class SingletonHolder { private static final NativeFinalizer INSTANCE = new NativeFinalizer(); } public static NativeFinalizer getInstance() { return SingletonHolder.INSTANCE; } public FinalizableReferenceQueue getFinalizerQueue() { return finalizerQueue; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/NativeFunctionMapperContext.java000066400000000000000000000026271316720554100314720ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import jnr.ffi.Library; import jnr.ffi.mapper.FunctionMapper; import java.lang.annotation.Annotation; import java.util.Collection; public final class NativeFunctionMapperContext implements FunctionMapper.Context { private final NativeLibrary library; private final Collection annotations; public NativeFunctionMapperContext(NativeLibrary library, Collection annotations) { this.library = library; this.annotations = annotations; } public Library getLibrary() { return null; } public boolean isSymbolPresent(String name) { return library.getSymbolAddress(name) != 0L; } public Collection getAnnotations() { return annotations; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/NativeLibrary.java000066400000000000000000000117161316720554100265760ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import jnr.ffi.Platform; import java.io.*; import java.util.*; import java.util.concurrent.CopyOnWriteArrayList; import java.util.regex.Matcher; import java.util.regex.Pattern; public class NativeLibrary { private final List libraryNames; private final List searchPaths; private volatile List nativeLibraries = Collections.emptyList(); NativeLibrary(Collection libraryNames, Collection searchPaths) { this.libraryNames = Collections.unmodifiableList(new ArrayList(libraryNames)); this.searchPaths = Collections.unmodifiableList(new ArrayList(searchPaths)); } private String locateLibrary(String libraryName) { if (new File(libraryName).isAbsolute()) { return libraryName; } return Platform.getNativePlatform().locateLibrary(libraryName, searchPaths); } long getSymbolAddress(String name) { for (com.kenai.jffi.Library l : getNativeLibraries()) { long address = l.getSymbolAddress(name); if (address != 0) { return address; } } return 0; } long findSymbolAddress(String name) { long address = getSymbolAddress(name); if (address == 0) { throw new SymbolNotFoundError(com.kenai.jffi.Library.getLastError()); } return address; } private synchronized List getNativeLibraries() { if (!this.nativeLibraries.isEmpty()) { return nativeLibraries; } return nativeLibraries = loadNativeLibraries(); } private synchronized List loadNativeLibraries() { List libs = new ArrayList(); for (String libraryName : libraryNames) { com.kenai.jffi.Library lib; lib = openLibrary(libraryName); if (lib == null) { String path; if (libraryName != null && (path = locateLibrary(libraryName)) != null && !libraryName.equals(path)) { lib = openLibrary(path); } } if (lib == null) { throw new UnsatisfiedLinkError(com.kenai.jffi.Library.getLastError()); } libs.add(lib); } return Collections.unmodifiableList(libs); } private static final Pattern BAD_ELF = Pattern.compile("(.*): (invalid ELF header|file too short|invalid file format)"); private static final Pattern ELF_GROUP = Pattern.compile("GROUP\\s*\\(\\s*(\\S*).*\\)"); private static com.kenai.jffi.Library openLibrary(String path) { com.kenai.jffi.Library lib; lib = com.kenai.jffi.Library.getCachedInstance(path, com.kenai.jffi.Library.LAZY | com.kenai.jffi.Library.GLOBAL); if (lib != null) { return lib; } // If dlopen() fails with 'invalid ELF header', then it is likely to be a ld script - parse it for the real library path Matcher badElf = BAD_ELF.matcher(com.kenai.jffi.Library.getLastError()); if (badElf.lookingAt()) { File f = new File(badElf.group(1)); if (f.isFile() && f.length() < (4 * 1024)) { Matcher sharedObject = ELF_GROUP.matcher(readAll(f)); if (sharedObject.find()) { return com.kenai.jffi.Library.getCachedInstance(sharedObject.group(1), com.kenai.jffi.Library.LAZY | com.kenai.jffi.Library.GLOBAL); } } } return null; } private static String readAll(File f) { BufferedReader br = null; try { br = new BufferedReader(new InputStreamReader(new FileInputStream(f))); StringBuilder sb = new StringBuilder(); String line; while ((line = br.readLine()) != null) { sb.append(line); } return sb.toString(); } catch (FileNotFoundException e) { throw new RuntimeException(e); } catch (IOException ioe) { throw new RuntimeException(ioe); } finally { if (br != null) try { br.close(); } catch (IOException e) { throw new RuntimeException(e); } } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/NativeLibraryLoader.java000066400000000000000000000033021316720554100277150ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import jnr.ffi.*; import java.util.Collection; import java.util.Map; import static jnr.ffi.provider.jffi.Util.getBooleanProperty; /** * */ class NativeLibraryLoader extends jnr.ffi.LibraryLoader { static final boolean ASM_ENABLED = getBooleanProperty("jnr.ffi.asm.enabled", true); NativeLibraryLoader(Class interfaceClass) { super(interfaceClass); } public T loadLibrary(Class interfaceClass, Collection libraryNames, Collection searchPaths, Map options) { NativeLibrary nativeLibrary = new NativeLibrary(libraryNames, searchPaths); try { return ASM_ENABLED ? new AsmLibraryLoader().loadLibrary(nativeLibrary, interfaceClass, options) : new ReflectionLibraryLoader().loadLibrary(nativeLibrary, interfaceClass, options); } catch (RuntimeException ex) { throw ex; } catch (Exception ex) { throw new RuntimeException(ex); } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/NativeMemoryManager.java000066400000000000000000000045071316720554100277350ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import jnr.ffi.Pointer; import jnr.ffi.provider.BoundedMemoryIO; import jnr.ffi.provider.IntPointer; import java.nio.ByteBuffer; public class NativeMemoryManager implements jnr.ffi.provider.MemoryManager { private final jnr.ffi.Runtime runtime; private final long addressMask; public NativeMemoryManager(NativeRuntime runtime) { this.runtime = runtime; this.addressMask = runtime.addressMask(); } public Pointer allocate(int size) { return new ArrayMemoryIO(runtime, size); } public Pointer allocateDirect(int size) { return new BoundedMemoryIO(TransientNativeMemory.allocate(runtime, size, 8, true), 0, size); } public Pointer allocateDirect(int size, boolean clear) { return new BoundedMemoryIO(TransientNativeMemory.allocate(runtime, size, 8, clear), 0, size); } public Pointer allocateTemporary(int size) { return new BoundedMemoryIO(TransientNativeMemory.allocate(runtime, size, 8, true), 0, size); } public Pointer allocateTemporary(int size, boolean clear) { return new BoundedMemoryIO(TransientNativeMemory.allocate(runtime, size, 8, clear), 0, size); } public Pointer newPointer(ByteBuffer buffer) { return new ByteBufferMemoryIO(runtime, buffer); } public Pointer newPointer(long address) { return new DirectMemoryIO(runtime, address & addressMask); } public Pointer newPointer(long address, long size) { return new BoundedMemoryIO(new DirectMemoryIO(runtime, address & addressMask), 0, size); } public Pointer newOpaquePointer(long address) { return new IntPointer(runtime, address); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/NativeRuntime.java000066400000000000000000000200511316720554100266050ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import jnr.ffi.*; import jnr.ffi.Runtime; import jnr.ffi.mapper.DefaultTypeMapper; import jnr.ffi.mapper.SignatureTypeMapperAdapter; import jnr.ffi.provider.AbstractRuntime; import jnr.ffi.provider.BadType; import jnr.ffi.provider.DefaultObjectReferenceManager; import java.lang.reflect.Field; import java.nio.ByteOrder; import java.util.Arrays; import java.util.EnumMap; import java.util.EnumSet; import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; /** * */ public final class NativeRuntime extends AbstractRuntime { private final NativeMemoryManager mm = new NativeMemoryManager(this); private final NativeClosureManager closureManager = new NativeClosureManager(this, new SignatureTypeMapperAdapter(new DefaultTypeMapper()), new AsmClassLoader(getParentClassLoader())); private static ClassLoader getParentClassLoader() { ClassLoader cl = NativeRuntime.class.getClassLoader(); if (cl == null) { cl = ClassLoader.getSystemClassLoader(); } return cl; } private final Type[] aliases; public static NativeRuntime getInstance() { return SingletonHolder.INSTANCE; } private static final class SingletonHolder { public static final NativeRuntime INSTANCE = new NativeRuntime(); } private NativeRuntime() { super(ByteOrder.nativeOrder(), buildTypeMap()); NativeType[] nativeAliases = buildNativeTypeAliases(); EnumSet typeAliasSet = EnumSet.allOf(TypeAlias.class); aliases = new Type[typeAliasSet.size()]; for (TypeAlias alias : typeAliasSet) { if (nativeAliases.length > alias.ordinal() && nativeAliases[alias.ordinal()] != NativeType.VOID) { aliases[alias.ordinal()] = findType(nativeAliases[alias.ordinal()]); } else { aliases[alias.ordinal()] = new BadType(alias.name()); } } } private static EnumMap buildTypeMap() { EnumMap typeMap = new EnumMap(NativeType.class); EnumSet nativeTypes = EnumSet.allOf(NativeType.class); for (NativeType t : nativeTypes) { typeMap.put(t, jafflType(t)); } return typeMap; } private static NativeType[] buildNativeTypeAliases() { Platform platform = Platform.getNativePlatform(); Package pkg = NativeRuntime.class.getPackage(); String cpu = platform.getCPU().toString(); String os = platform.getOS().toString(); EnumSet typeAliases = EnumSet.allOf(TypeAlias.class); NativeType[] aliases = {}; Class cls; try { cls = Class.forName(pkg.getName() + ".platform." + cpu + "." + os + ".TypeAliases"); Field aliasesField = cls.getField("ALIASES"); Map aliasMap = Map.class.cast(aliasesField.get(cls)); aliases = new NativeType[typeAliases.size()]; for (TypeAlias t : typeAliases) { aliases[t.ordinal()] = (NativeType) aliasMap.get(t); if (aliases[t.ordinal()] == null) { aliases[t.ordinal()] = NativeType.VOID; } } } catch (ClassNotFoundException cne) { Logger.getLogger(NativeRuntime.class.getName()).log(Level.SEVERE, "failed to load type aliases: " + cne); } catch (NoSuchFieldException nsfe) { Logger.getLogger(NativeRuntime.class.getName()).log(Level.SEVERE, "failed to load type aliases: " + nsfe); } catch (IllegalAccessException iae) { Logger.getLogger(NativeRuntime.class.getName()).log(Level.SEVERE, "failed to load type aliases: " + iae); } return aliases; } @Override public Type findType(TypeAlias type) { return aliases[type.ordinal()]; } public final NativeMemoryManager getMemoryManager() { return mm; } public NativeClosureManager getClosureManager() { return closureManager; } @Override public ObjectReferenceManager newObjectReferenceManager() { return new DefaultObjectReferenceManager(this); } @Override public int getLastError() { return com.kenai.jffi.LastError.getInstance().get(); } @Override public void setLastError(int error) { com.kenai.jffi.LastError.getInstance().set(error); } @Override public boolean isCompatible(Runtime other) { return other instanceof NativeRuntime; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; NativeRuntime that = (NativeRuntime) o; return Arrays.equals(aliases, that.aliases) && closureManager.equals(that.closureManager) && mm.equals(that.mm); } @Override public int hashCode() { int result = mm.hashCode(); result = 31 * result + closureManager.hashCode(); result = 31 * result + Arrays.hashCode(aliases); return result; } private static final class TypeDelegate extends jnr.ffi.Type { private final com.kenai.jffi.Type type; private final NativeType nativeType; public TypeDelegate(com.kenai.jffi.Type type, NativeType nativeType) { this.type = type; this.nativeType = nativeType; } public int alignment() { return type.alignment(); } public int size() { return type.size(); } public NativeType getNativeType() { return nativeType; } public String toString() { return type.toString(); } } private static jnr.ffi.Type jafflType(NativeType type) { switch (type) { case VOID: return new TypeDelegate(com.kenai.jffi.Type.VOID, NativeType.VOID); case SCHAR: return new TypeDelegate(com.kenai.jffi.Type.SCHAR, NativeType.SCHAR); case UCHAR: return new TypeDelegate(com.kenai.jffi.Type.UCHAR, NativeType.UCHAR); case SSHORT: return new TypeDelegate(com.kenai.jffi.Type.SSHORT, NativeType.SSHORT); case USHORT: return new TypeDelegate(com.kenai.jffi.Type.USHORT, NativeType.USHORT); case SINT: return new TypeDelegate(com.kenai.jffi.Type.SINT, NativeType.SINT); case UINT: return new TypeDelegate(com.kenai.jffi.Type.UINT, NativeType.UINT); case SLONG: return new TypeDelegate(com.kenai.jffi.Type.SLONG, NativeType.SLONG); case ULONG: return new TypeDelegate(com.kenai.jffi.Type.ULONG, NativeType.ULONG); case SLONGLONG: return new TypeDelegate(com.kenai.jffi.Type.SINT64, NativeType.SLONGLONG); case ULONGLONG: return new TypeDelegate(com.kenai.jffi.Type.UINT64, NativeType.ULONGLONG); case FLOAT: return new TypeDelegate(com.kenai.jffi.Type.FLOAT, NativeType.FLOAT); case DOUBLE: return new TypeDelegate(com.kenai.jffi.Type.DOUBLE, NativeType.DOUBLE); case ADDRESS: return new TypeDelegate(com.kenai.jffi.Type.POINTER, NativeType.ADDRESS); default: return new BadType(type.toString()); } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/NoTrace.java000066400000000000000000000017351316720554100253560ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * Turns off debug tracing */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) public @interface NoTrace { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/NoX86.java000066400000000000000000000017031316720554100247000ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE, ElementType.METHOD}) public @interface NoX86 { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/NotImplMethodGenerator.java000066400000000000000000000024001316720554100304030ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import com.kenai.jffi.Function; import jnr.ffi.CallingConvention; import jnr.ffi.provider.ParameterType; import jnr.ffi.provider.ResultType; /** * */ class NotImplMethodGenerator implements MethodGenerator { public boolean isSupported(ResultType resultType, ParameterType[] parameterTypes, CallingConvention callingConvention) { return false; } public void generate(AsmBuilder builder, String functionName, Function function, ResultType resultType, ParameterType[] parameterTypes, boolean ignoreError) { throw new UnsupportedOperationException("not supported"); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/NullObjectParameterStrategy.java000066400000000000000000000025341316720554100314460ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; /** * */ public final class NullObjectParameterStrategy extends ParameterStrategy { public static final ParameterStrategy NULL = new NullObjectParameterStrategy(); public NullObjectParameterStrategy() { super(DIRECT); } @Override public long address(Object parameter) { return 0; } @Override public Object object(Object parameter) { throw new NullPointerException("null reference"); } @Override public int offset(Object parameter) { throw new NullPointerException("null reference"); } @Override public int length(Object parameter) { throw new NullPointerException("null reference"); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/NumberUtil.java000066400000000000000000000177671316720554100261250ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import jnr.ffi.NativeType; import jnr.ffi.provider.SigType; public final class NumberUtil { private NumberUtil() {} static Class getBoxedClass(Class c) { if (!c.isPrimitive()) { return c; } if (void.class == c) { return Void.class; } else if (byte.class == c) { return Byte.class; } else if (char.class == c) { return Character.class; } else if (short.class == c) { return Short.class; } else if (int.class == c) { return Integer.class; } else if (long.class == c) { return Long.class; } else if (float.class == c) { return Float.class; } else if (double.class == c) { return Double.class; } else if (boolean.class == c) { return Boolean.class; } else { throw new IllegalArgumentException("unknown primitive class"); } } static Class getPrimitiveClass(Class c) { if (Void.class == c) { return void.class; } else if (Boolean.class == c) { return boolean.class; } else if (Byte.class == c) { return byte.class; } else if (Character.class == c) { return char.class; } else if (Short.class == c) { return short.class; } else if (Integer.class == c) { return int.class; } else if (Long.class == c) { return long.class; } else if (Float.class == c) { return float.class; } else if (Double.class == c) { return double.class; } else if (c.isPrimitive()) { return c; } else { throw new IllegalArgumentException("unsupported number class"); } } public static boolean isPrimitiveInt(Class c) { return byte.class == c || char.class == c || short.class == c || int.class == c || boolean.class == c; } public static void widen(SkinnyMethodAdapter mv, Class from, Class to) { if (long.class == to && long.class != from && isPrimitiveInt(from)) { mv.i2l(); } else if (boolean.class == to && boolean.class != from && isPrimitiveInt(from)) { // Ensure only 0x0 and 0x1 values are used for boolean mv.iconst_1(); mv.iand(); } } public static void widen(SkinnyMethodAdapter mv, Class from, Class to, NativeType nativeType) { if (isPrimitiveInt(from)) { if (nativeType == NativeType.UCHAR) { mv.pushInt(0xff); mv.iand(); } else if (nativeType == NativeType.USHORT) { mv.pushInt(0xffff); mv.iand(); } if (long.class == to) { mv.i2l(); switch (nativeType) { case UINT: case ULONG: case ADDRESS: if (sizeof(nativeType) < 8) { // strip off bits 32:63 mv.ldc(0xffffffffL); mv.land(); } break; } } } } public static void narrow(SkinnyMethodAdapter mv, Class from, Class to) { if (!from.equals(to)) { if (byte.class == to || short.class == to || char.class == to || int.class == to || boolean.class == to) { if (long.class == from) { mv.l2i(); } if (byte.class == to) { mv.i2b(); } else if (short.class == to) { mv.i2s(); } else if (char.class == to) { mv.i2c(); } else if (boolean.class == to) { // Ensure only 0x0 and 0x1 values are used for boolean mv.iconst_1(); mv.iand(); } } } } public static void convertPrimitive(SkinnyMethodAdapter mv, final Class from, final Class to) { narrow(mv, from, to); widen(mv, from, to); } public static void convertPrimitive(SkinnyMethodAdapter mv, final Class from, final Class to, final NativeType nativeType) { if (boolean.class == to) { narrow(mv, from, to); return; } switch (nativeType) { case SCHAR: narrow(mv, from, byte.class); widen(mv, byte.class, to); break; case SSHORT: narrow(mv, from, short.class); widen(mv, short.class, to); break; case SINT: narrow(mv, from, int.class); widen(mv, int.class, to); break; case UCHAR: narrow(mv, from, int.class); mv.pushInt(0xff); mv.iand(); widen(mv, int.class, to); break; case USHORT: narrow(mv, from, int.class); mv.pushInt(0xffff); mv.iand(); widen(mv, int.class, to); break; case UINT: case ULONG: case ADDRESS: if (sizeof(nativeType) <= 4) { narrow(mv, from, int.class); if (long.class == to) { mv.i2l(); // strip off bits 32:63 mv.ldc(0xffffffffL); mv.land(); } } else { widen(mv, from, to); } break; case FLOAT: case DOUBLE: break; default: narrow(mv, from, to); widen(mv, from, to); break; } } static int sizeof(SigType type) { return sizeof(type.getNativeType()); } static int sizeof(NativeType nativeType) { switch (nativeType) { case SCHAR: return com.kenai.jffi.Type.SCHAR.size(); case UCHAR: return com.kenai.jffi.Type.UCHAR.size(); case SSHORT: return com.kenai.jffi.Type.SSHORT.size(); case USHORT: return com.kenai.jffi.Type.USHORT.size(); case SINT: return com.kenai.jffi.Type.SINT.size(); case UINT: return com.kenai.jffi.Type.UINT.size(); case SLONG: return com.kenai.jffi.Type.SLONG.size(); case ULONG: return com.kenai.jffi.Type.ULONG.size(); case SLONGLONG: return com.kenai.jffi.Type.SLONG_LONG.size(); case ULONGLONG: return com.kenai.jffi.Type.ULONG_LONG.size(); case FLOAT: return com.kenai.jffi.Type.FLOAT.size(); case DOUBLE: return com.kenai.jffi.Type.DOUBLE.size(); case ADDRESS: return com.kenai.jffi.Type.POINTER.size(); case VOID: return 0; default: throw new UnsupportedOperationException("cannot determine size of " + nativeType); } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/ParameterStrategy.java000066400000000000000000000023571316720554100274670ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import com.kenai.jffi.ObjectParameterStrategy; import com.kenai.jffi.ObjectParameterType; /** * */ abstract public class ParameterStrategy extends ObjectParameterStrategy { /* objectCount is accessed directly from asm code - do not change */ public final int objectCount; protected ParameterStrategy(StrategyType type) { super(type); objectCount = type == HEAP ? 1 : 0; } protected ParameterStrategy(StrategyType type, ObjectParameterType parameterType) { super(type, parameterType); objectCount = type == HEAP ? 1 : 0; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/PointerParameterStrategy.java000066400000000000000000000032431316720554100310230ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import com.kenai.jffi.ObjectParameterType; import jnr.ffi.Pointer; /** * */ public final class PointerParameterStrategy extends ParameterStrategy { public static final PointerParameterStrategy DIRECT = new PointerParameterStrategy(StrategyType.DIRECT); public static final PointerParameterStrategy HEAP = new PointerParameterStrategy(StrategyType.HEAP); PointerParameterStrategy(StrategyType type) { super(type, ObjectParameterType.create(ObjectParameterType.ARRAY, ObjectParameterType.BYTE)); } @Override public long address(Object o) { return address((Pointer) o); } public long address(Pointer pointer) { return pointer != null ? pointer.address() : 0L; } @Override public Object object(Object o) { return ((Pointer) o).array(); } @Override public int offset(Object o) { return ((Pointer) o).arrayOffset(); } @Override public int length(Object o) { return ((Pointer) o).arrayLength(); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/PrimitiveArrayParameterStrategy.java000066400000000000000000000056701316720554100323600ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import com.kenai.jffi.ObjectParameterType; /** * */ abstract public class PrimitiveArrayParameterStrategy extends ParameterStrategy { static final PrimitiveArrayParameterStrategy BYTE = new PrimitiveArrayParameterStrategy(ObjectParameterType.BYTE) { public int length(Object o) { return ((byte[]) o).length; } }; static final PrimitiveArrayParameterStrategy SHORT = new PrimitiveArrayParameterStrategy(ObjectParameterType.SHORT) { public int length(Object o) { return ((short[]) o).length; } }; static final PrimitiveArrayParameterStrategy CHAR = new PrimitiveArrayParameterStrategy(ObjectParameterType.CHAR) { public int length(Object o) { return ((char[]) o).length; } }; static final PrimitiveArrayParameterStrategy INT = new PrimitiveArrayParameterStrategy(ObjectParameterType.INT) { public int length(Object o) { return ((int[]) o).length; } }; static final PrimitiveArrayParameterStrategy LONG = new PrimitiveArrayParameterStrategy(ObjectParameterType.LONG) { public int length(Object o) { return ((long[]) o).length; } }; static final PrimitiveArrayParameterStrategy FLOAT = new PrimitiveArrayParameterStrategy(ObjectParameterType.FLOAT) { public int length(Object o) { return ((float[]) o).length; } }; static final PrimitiveArrayParameterStrategy DOUBLE = new PrimitiveArrayParameterStrategy(ObjectParameterType.DOUBLE) { public int length(Object o) { return ((double[]) o).length; } }; static final PrimitiveArrayParameterStrategy BOOLEAN = new PrimitiveArrayParameterStrategy(ObjectParameterType.BOOLEAN) { public int length(Object o) { return ((boolean[]) o).length; } }; PrimitiveArrayParameterStrategy(ObjectParameterType.ComponentType componentType) { super(HEAP, ObjectParameterType.create(ObjectParameterType.ObjectType.ARRAY, componentType)); } @Override public final long address(Object o) { return 0; } @Override public final Object object(Object o) { return o; } @Override public final int offset(Object o) { return 0; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/Provider.java000066400000000000000000000021761316720554100256150ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import jnr.ffi.Runtime; import jnr.ffi.provider.FFIProvider; public final class Provider extends FFIProvider { private final NativeRuntime runtime; public Provider() { this.runtime = NativeRuntime.getInstance(); } public final Runtime getRuntime() { return runtime; } public jnr.ffi.LibraryLoader createLibraryLoader(Class interfaceClass) { return new NativeLibraryLoader(interfaceClass); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/ReflectionLibraryLoader.java000066400000000000000000000164321316720554100305710ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import static jnr.ffi.provider.jffi.InvokerUtil.getCallingConvention; import static jnr.ffi.util.Annotations.sortedAnnotationCollection; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.AbstractMap; import java.util.Collection; import java.util.Map; import java.util.Set; import jnr.ffi.LibraryOption; import jnr.ffi.Runtime; import jnr.ffi.Variable; import jnr.ffi.annotations.Synchronized; import jnr.ffi.mapper.CachingTypeMapper; import jnr.ffi.mapper.CompositeTypeMapper; import jnr.ffi.mapper.FunctionMapper; import jnr.ffi.mapper.SignatureTypeMapper; import jnr.ffi.mapper.SignatureTypeMapperAdapter; import jnr.ffi.mapper.TypeMapper; import jnr.ffi.provider.IdentityFunctionMapper; import jnr.ffi.provider.Invoker; import jnr.ffi.provider.LoadedLibrary; import jnr.ffi.provider.NativeInvocationHandler; import jnr.ffi.provider.NullTypeMapper; /** * */ class ReflectionLibraryLoader extends LibraryLoader { @Override T loadLibrary(NativeLibrary library, Class interfaceClass, Map libraryOptions) { return interfaceClass.cast(Proxy.newProxyInstance(interfaceClass.getClassLoader(), new Class[]{ interfaceClass, LoadedLibrary.class }, new NativeInvocationHandler(new LazyLoader(library, interfaceClass, libraryOptions)))); } private static final class FunctionNotFoundInvoker implements Invoker { private final Method method; private final String functionName; private FunctionNotFoundInvoker(Method method, String functionName) { this.method = method; this.functionName = functionName; } @Override public Object invoke(Object self, Object[] parameters) { throw new UnsatisfiedLinkError(String.format("native method '%s' not found for method %s", functionName, method)); } } private static final class GetRuntimeInvoker implements Invoker { private final jnr.ffi.Runtime runtime; private GetRuntimeInvoker(Runtime runtime) { this.runtime = runtime; } @Override public Object invoke(Object self, Object[] parameters) { return runtime; } } private static final class LazyLoader extends AbstractMap { private final DefaultInvokerFactory invokerFactory; private final jnr.ffi.Runtime runtime = NativeRuntime.getInstance(); private final AsmClassLoader classLoader = new AsmClassLoader(); private final SignatureTypeMapper typeMapper; private final FunctionMapper functionMapper; private final jnr.ffi.CallingConvention libraryCallingConvention; private final boolean libraryIsSynchronized; private final NativeLibrary library; @SuppressWarnings("unused") private final Class interfaceClass; @SuppressWarnings("unused") private final Map libraryOptions; private LazyLoader(NativeLibrary library, Class interfaceClass, Map libraryOptions) { this.library = library; this.interfaceClass = interfaceClass; this.libraryOptions = libraryOptions; this.functionMapper = libraryOptions.containsKey(LibraryOption.FunctionMapper) ? (FunctionMapper) libraryOptions.get(LibraryOption.FunctionMapper) : IdentityFunctionMapper.getInstance(); SignatureTypeMapper typeMapper; if (libraryOptions.containsKey(LibraryOption.TypeMapper)) { Object tm = libraryOptions.get(LibraryOption.TypeMapper); if (tm instanceof SignatureTypeMapper) { typeMapper = (SignatureTypeMapper) tm; } else if (tm instanceof TypeMapper) { typeMapper = new SignatureTypeMapperAdapter((TypeMapper) tm); } else { throw new IllegalArgumentException("TypeMapper option is not a valid TypeMapper instance"); } } else { typeMapper = new NullTypeMapper(); } this.typeMapper = new CompositeTypeMapper(typeMapper, new CachingTypeMapper(new InvokerTypeMapper(new NativeClosureManager(runtime, typeMapper, classLoader), classLoader, NativeLibraryLoader.ASM_ENABLED))); libraryCallingConvention = getCallingConvention(interfaceClass, libraryOptions); libraryIsSynchronized = interfaceClass.isAnnotationPresent(Synchronized.class); invokerFactory = new DefaultInvokerFactory(runtime, library, this.typeMapper, functionMapper, libraryCallingConvention, libraryOptions, libraryIsSynchronized); } @Override public Set> entrySet() { throw new UnsupportedOperationException("not implemented"); } @Override public synchronized Invoker get(Object key) { if (!(key instanceof Method)) { throw new IllegalArgumentException("key not instance of Method"); } Method method = (Method) key; if (Variable.class.isAssignableFrom(method.getReturnType())) { return getVariableAccessor(method); } else if (method.getName().equals("getRuntime") && method.getReturnType().isAssignableFrom(NativeRuntime.class)) { return new GetRuntimeInvoker(runtime); } else { return invokerFactory.createInvoker(method); } } private Invoker getVariableAccessor(Method method) { Collection annotations = sortedAnnotationCollection(method.getAnnotations()); String functionName = functionMapper.mapFunctionName(method.getName(), new NativeFunctionMapperContext(library, annotations)); long symbolAddress = library.getSymbolAddress(functionName); if (symbolAddress == 0L) { return new FunctionNotFoundInvoker(method, functionName); } Variable variable = ReflectionVariableAccessorGenerator.createVariableAccessor(runtime, method, symbolAddress, typeMapper, annotations); return new VariableAcccessorInvoker(variable); } private static final class VariableAcccessorInvoker implements Invoker { private final Variable variable; private VariableAcccessorInvoker(Variable variable) { this.variable = variable; } @Override public Object invoke(Object self, Object[] parameters) { return variable; } } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/ReflectionVariableAccessorGenerator.java000066400000000000000000000244201316720554100331110ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import jnr.ffi.NativeType; import jnr.ffi.Pointer; import jnr.ffi.Variable; import jnr.ffi.mapper.*; import java.lang.annotation.Annotation; import java.lang.reflect.Method; import java.lang.reflect.ParameterizedType; import java.util.Collection; import static jnr.ffi.provider.jffi.DefaultInvokerFactory.getNumberDataConverter; import static jnr.ffi.provider.jffi.DefaultInvokerFactory.getNumberResultConverter; import static jnr.ffi.provider.jffi.NumberUtil.sizeof; /** * */ class ReflectionVariableAccessorGenerator { static Variable createVariableAccessor(jnr.ffi.Runtime runtime, Method method, long symbolAddress, SignatureTypeMapper typeMapper, Collection annotations) { java.lang.reflect.Type variableType = ((ParameterizedType) method.getGenericReturnType()).getActualTypeArguments()[0]; if (!(variableType instanceof Class)) { throw new IllegalArgumentException("unsupported variable class: " + variableType); } Class javaType = (Class) variableType; SimpleNativeContext context = new SimpleNativeContext(runtime, annotations); SignatureType signatureType = DefaultSignatureType.create(javaType, (FromNativeContext) context); jnr.ffi.mapper.FromNativeType mappedFromNativeType = typeMapper.getFromNativeType(signatureType, context); FromNativeConverter fromNativeConverter = mappedFromNativeType != null ? mappedFromNativeType.getFromNativeConverter() : null; jnr.ffi.mapper.ToNativeType mappedToNativeType = typeMapper.getToNativeType(signatureType, context); ToNativeConverter toNativeConverter = mappedToNativeType != null ? mappedToNativeType.getToNativeConverter() : null; Class boxedType = toNativeConverter != null ? toNativeConverter.nativeType() : javaType; NativeType nativeType = Types.getType(runtime, boxedType, annotations).getNativeType(); jnr.ffi.provider.ToNativeType toNativeType = new jnr.ffi.provider.ToNativeType(javaType, nativeType, annotations, toNativeConverter, null); jnr.ffi.provider.FromNativeType fromNativeType = new jnr.ffi.provider.FromNativeType(javaType, nativeType, annotations, fromNativeConverter, null); Variable variable; Pointer memory = MemoryUtil.newPointer(runtime, symbolAddress); variable = getNativeVariableAccessor(memory, toNativeType, fromNativeType); return toNativeType.getToNativeConverter() != null ? getConvertingVariable(variable, toNativeType.getToNativeConverter(), fromNativeType.getFromNativeConverter()) : variable; } static Variable getConvertingVariable(Variable nativeVariable, ToNativeConverter toNativeConverter, FromNativeConverter fromNativeConverter) { if ((toNativeConverter != null && fromNativeConverter == null) || toNativeConverter == null && fromNativeConverter != null) { throw new UnsupportedOperationException("convertible types must have both a ToNativeConverter and a FromNativeConverter"); } return new ConvertingVariable(nativeVariable, toNativeConverter, fromNativeConverter); } static Variable getNativeVariableAccessor(Pointer memory, jnr.ffi.provider.ToNativeType toNativeType, jnr.ffi.provider.FromNativeType fromNativeType) { if (Pointer.class == toNativeType.effectiveJavaType()) { return new PointerVariable(memory); } else if (Number.class.isAssignableFrom(toNativeType.effectiveJavaType())) { return new NumberVariable(memory, getPointerOp(toNativeType.getNativeType()), getNumberDataConverter(toNativeType.getNativeType()), getNumberResultConverter(fromNativeType)); } else { throw new UnsupportedOperationException("unsupported variable type: " + toNativeType.effectiveJavaType()); } } private static PointerOp getPointerOp(NativeType nativeType) { switch (nativeType) { case SCHAR: case UCHAR: return Int8PointerOp.INSTANCE; case SSHORT: case USHORT: return Int16PointerOp.INSTANCE; case SINT: case UINT: return Int32PointerOp.INSTANCE; case SLONGLONG: case ULONGLONG: return Int64PointerOp.INSTANCE; case SLONG: case ULONG: case ADDRESS: return sizeof(nativeType) == 4 ? Int32PointerOp.INSTANCE : Int64PointerOp.INSTANCE; case FLOAT: return FloatPointerOp.INSTANCE; case DOUBLE: return DoublePointerOp.INSTANCE; } throw new UnsupportedOperationException("cannot convert " + nativeType); } private static abstract class AbstractVariable implements Variable { protected final Pointer memory; protected AbstractVariable(Pointer memory) { this.memory = memory; } } private static final class ConvertingVariable implements Variable { private final Variable variable; private final ToNativeConverter toNativeConverter; private final FromNativeConverter fromNativeConverter; private ConvertingVariable(Variable variable, ToNativeConverter toNativeConverter, FromNativeConverter fromNativeConverter) { this.variable = variable; this.toNativeConverter = toNativeConverter; this.fromNativeConverter = fromNativeConverter; } @Override public Object get() { return fromNativeConverter.fromNative(variable.get(), null); } @Override public void set(Object value) { variable.set(toNativeConverter.toNative(value, null)); } } private static final class NumberVariable extends AbstractVariable { private final DataConverter dataConverter; private final DefaultInvokerFactory.ResultConverter resultConverter; private final PointerOp pointerOp; private NumberVariable(Pointer memory, PointerOp pointerOp, DataConverter dataConverter, DefaultInvokerFactory.ResultConverter resultConverter) { super(memory); this.pointerOp = pointerOp; this.dataConverter = dataConverter; this.resultConverter = resultConverter; } @Override public Number get() { return resultConverter.fromNative(dataConverter.fromNative(pointerOp.get(memory), null), null); } @Override public void set(Number value) { pointerOp.put(memory, dataConverter.toNative(value, null)); } } private static final class PointerVariable extends AbstractVariable { private PointerVariable(Pointer memory) { super(memory); } public Pointer get() { return memory.getPointer(0); } public void set(Pointer value) { if (value != null) memory.putPointer(0, value); else memory.putAddress(0, 0L); } } private static interface PointerOp { public T get(Pointer memory); public void put(Pointer memory, T value); } private static final class Int8PointerOp implements PointerOp { static final PointerOp INSTANCE = new Int8PointerOp(); @Override public Number get(Pointer memory) { return memory.getByte(0); } @Override public void put(Pointer memory, Number value) { memory.putByte(0, value.byteValue()); } } private static final class Int16PointerOp implements PointerOp { static final PointerOp INSTANCE = new Int16PointerOp(); @Override public Number get(Pointer memory) { return memory.getShort(0); } @Override public void put(Pointer memory, Number value) { memory.putShort(0, value.shortValue()); } } private static final class Int32PointerOp implements PointerOp { static final PointerOp INSTANCE = new Int32PointerOp(); @Override public Number get(Pointer memory) { return memory.getInt(0); } @Override public void put(Pointer memory, Number value) { memory.putInt(0, value.intValue()); } } private static final class Int64PointerOp implements PointerOp { static final PointerOp INSTANCE = new Int64PointerOp(); @Override public Number get(Pointer memory) { return memory.getLongLong(0); } @Override public void put(Pointer memory, Number value) { memory.putLongLong(0, value.longValue()); } } private static final class FloatPointerOp implements PointerOp { static final PointerOp INSTANCE = new FloatPointerOp(); @Override public Number get(Pointer memory) { return memory.getFloat(0); } @Override public void put(Pointer memory, Number value) { memory.putFloat(0, value.floatValue()); } } private static final class DoublePointerOp implements PointerOp { static final PointerOp INSTANCE = new DoublePointerOp(); @Override public Number get(Pointer memory) { return memory.getFloat(0); } @Override public void put(Pointer memory, Number value) { memory.putFloat(0, value.floatValue()); } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/SimpleNativeContext.java000066400000000000000000000024761316720554100277730ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import jnr.ffi.mapper.FromNativeContext; import jnr.ffi.mapper.ToNativeContext; import java.lang.annotation.Annotation; import java.util.Collection; public class SimpleNativeContext implements ToNativeContext, FromNativeContext { private final jnr.ffi.Runtime runtime; private final Collection annotations; SimpleNativeContext(jnr.ffi.Runtime runtime, Collection annotations) { this.runtime = runtime; this.annotations = annotations; } public Collection getAnnotations() { return annotations; } public final jnr.ffi.Runtime getRuntime() { return runtime; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/SkinnyMethodAdapter.java000066400000000000000000000640501316720554100277370ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import org.objectweb.asm.*; import java.io.PrintStream; import java.io.PrintWriter; import java.lang.reflect.Method; import java.util.Map; import static jnr.ffi.provider.jffi.CodegenUtils.*; /** * * @author headius */ public class SkinnyMethodAdapter extends MethodVisitor implements Opcodes { private final static boolean DEBUG = Boolean.getBoolean("jnr.ffi.compile.dump"); private MethodVisitor method; /** * Creates a new instance of SkinnyMethodAdapter. * * @param cv The class visitor instance. * @param flags The flags. * @param name The name. * @param signature The signature. * @param something Something. * @param exceptions The array of exceptions. */ public SkinnyMethodAdapter(ClassVisitor cv, int flags, String name, String signature, String something, String[] exceptions) { super(Opcodes.ASM4); setMethodVisitor(cv.visitMethod(flags, name, signature, something, exceptions)); } public MethodVisitor getMethodVisitor() { return method; } public void setMethodVisitor(MethodVisitor mv) { this.method = DEBUG ? AsmUtil.newTraceMethodVisitor(mv) : mv; } public void aload(int arg0) { getMethodVisitor().visitVarInsn(ALOAD, arg0); } public void aload(LocalVariable arg0) { getMethodVisitor().visitVarInsn(ALOAD, arg0.idx); } public void aload(int... args) { for (int arg : args) { getMethodVisitor().visitVarInsn(ALOAD, arg); } } public void aload(LocalVariable... args) { for (LocalVariable arg : args) { getMethodVisitor().visitVarInsn(ALOAD, arg.idx); } } public void iload(int arg0) { getMethodVisitor().visitVarInsn(ILOAD, arg0); } public void iload(LocalVariable arg0) { getMethodVisitor().visitVarInsn(ILOAD, arg0.idx); } public void iload(int... args) { for (int arg : args) { getMethodVisitor().visitVarInsn(ILOAD, arg); } } public void iload(LocalVariable... args) { for (LocalVariable arg : args) { getMethodVisitor().visitVarInsn(ILOAD, arg.idx); } } public void lload(int arg0) { getMethodVisitor().visitVarInsn(LLOAD, arg0); } public void lload(int... args) { for (int arg : args) { getMethodVisitor().visitVarInsn(LLOAD, arg); } } public void lload(LocalVariable... args) { for (LocalVariable arg : args) { getMethodVisitor().visitVarInsn(LLOAD, arg.idx); } } public void fload(int arg0) { getMethodVisitor().visitVarInsn(FLOAD, arg0); } public void fload(LocalVariable arg0) { getMethodVisitor().visitVarInsn(FLOAD, arg0.idx); } public void fload(int... args) { for (int arg : args) { getMethodVisitor().visitVarInsn(FLOAD, arg); } } public void dload(LocalVariable arg0) { getMethodVisitor().visitVarInsn(DLOAD, arg0.idx); } public void dload(int arg0) { getMethodVisitor().visitVarInsn(DLOAD, arg0); } public void dload(int... args) { for (int arg : args) { getMethodVisitor().visitVarInsn(DLOAD, arg); } } public void astore(int arg0) { getMethodVisitor().visitVarInsn(ASTORE, arg0); } public void astore(LocalVariable arg0) { getMethodVisitor().visitVarInsn(ASTORE, arg0.idx); } public void istore(int arg0) { getMethodVisitor().visitVarInsn(ISTORE, arg0); } public void istore(LocalVariable arg0) { getMethodVisitor().visitVarInsn(ISTORE, arg0.idx); } public void lstore(int arg0) { getMethodVisitor().visitVarInsn(LSTORE, arg0); } public void lstore(LocalVariable arg0) { getMethodVisitor().visitVarInsn(LSTORE, arg0.idx); } public void fstore(int arg0) { getMethodVisitor().visitVarInsn(FSTORE, arg0); } public void fstore(LocalVariable arg0) { getMethodVisitor().visitVarInsn(FSTORE, arg0.idx); } public void dstore(int arg0) { getMethodVisitor().visitVarInsn(DSTORE, arg0); } public void dstore(LocalVariable arg0) { getMethodVisitor().visitVarInsn(DSTORE, arg0.idx); } public void ldc(Object arg0) { getMethodVisitor().visitLdcInsn(arg0); } public void bipush(int arg) { getMethodVisitor().visitIntInsn(BIPUSH, arg); } public void sipush(int arg) { getMethodVisitor().visitIntInsn(SIPUSH, arg); } public void pushInt(int value) { if (value <= Byte.MAX_VALUE && value >= Byte.MIN_VALUE) { switch (value) { case -1: iconst_m1(); break; case 0: iconst_0(); break; case 1: iconst_1(); break; case 2: iconst_2(); break; case 3: iconst_3(); break; case 4: iconst_4(); break; case 5: iconst_5(); break; default: bipush(value); break; } } else if (value <= Short.MAX_VALUE && value >= Short.MIN_VALUE) { sipush(value); } else { ldc(value); } } public void pushBoolean(boolean bool) { if (bool) iconst_1(); else iconst_0(); } public void invokestatic(String arg1, String arg2, String arg3) { getMethodVisitor().visitMethodInsn(INVOKESTATIC, arg1, arg2, arg3); } public void invokestatic(Class recv, String methodName, Class returnType, Class... parameterTypes) { getMethodVisitor().visitMethodInsn(INVOKESTATIC, p(recv), methodName, sig(returnType, parameterTypes)); } public void invokespecial(String arg1, String arg2, String arg3) { getMethodVisitor().visitMethodInsn(INVOKESPECIAL, arg1, arg2, arg3); } public void invokespecial(Class recv, String methodName, Class returnType, Class... parameterTypes) { getMethodVisitor().visitMethodInsn(INVOKESPECIAL, p(recv), methodName, sig(returnType, parameterTypes)); } public void invokevirtual(String arg1, String arg2, String arg3) { getMethodVisitor().visitMethodInsn(INVOKEVIRTUAL, arg1, arg2, arg3); } public void invokevirtual(Class recv, String methodName, Class returnType, Class... parameterTypes) { getMethodVisitor().visitMethodInsn(INVOKEVIRTUAL, p(recv), methodName, sig(returnType, parameterTypes)); } public void invokeinterface(String arg1, String arg2, String arg3) { getMethodVisitor().visitMethodInsn(INVOKEINTERFACE, arg1, arg2, arg3); } public void invokeinterface(Class recv, String methodName, Class returnType, Class... parameterTypes) { getMethodVisitor().visitMethodInsn(INVOKEINTERFACE, p(recv), methodName, sig(returnType, parameterTypes)); } public void invokedynamic(String arg1, String arg2, String arg3) { getMethodVisitor().visitMethodInsn(INVOKEDYNAMIC, arg1, arg2, arg3); } public void aprintln() { dup(); getstatic(p(System.class), "out", ci(PrintStream.class)); swap(); invokevirtual(p(PrintStream.class), "println", sig(void.class, params(Object.class))); } public void areturn() { getMethodVisitor().visitInsn(ARETURN); } public void ireturn() { getMethodVisitor().visitInsn(IRETURN); } public void freturn() { getMethodVisitor().visitInsn(FRETURN); } public void lreturn() { getMethodVisitor().visitInsn(LRETURN); } public void dreturn() { getMethodVisitor().visitInsn(DRETURN); } public void newobj(String arg0) { getMethodVisitor().visitTypeInsn(NEW, arg0); } public void dup() { getMethodVisitor().visitInsn(DUP); } public void swap() { getMethodVisitor().visitInsn(SWAP); } public void swap2() { dup2_x2(); pop2(); } public void getstatic(String arg1, String arg2, String arg3) { getMethodVisitor().visitFieldInsn(GETSTATIC, arg1, arg2, arg3); } public void putstatic(String arg1, String arg2, String arg3) { getMethodVisitor().visitFieldInsn(PUTSTATIC, arg1, arg2, arg3); } public void getfield(String arg1, String arg2, String arg3) { getMethodVisitor().visitFieldInsn(GETFIELD, arg1, arg2, arg3); } public void putfield(String arg1, String arg2, String arg3) { getMethodVisitor().visitFieldInsn(PUTFIELD, arg1, arg2, arg3); } public void voidreturn() { getMethodVisitor().visitInsn(RETURN); } public void anewarray(String arg0) { getMethodVisitor().visitTypeInsn(ANEWARRAY, arg0); } public void multianewarray(String arg0, int dims) { getMethodVisitor().visitMultiANewArrayInsn(arg0, dims); } public void newarray(int arg0) { getMethodVisitor().visitIntInsn(NEWARRAY, arg0); } public void iconst_m1() { getMethodVisitor().visitInsn(ICONST_M1); } public void iconst_0() { getMethodVisitor().visitInsn(ICONST_0); } public void iconst_1() { getMethodVisitor().visitInsn(ICONST_1); } public void iconst_2() { getMethodVisitor().visitInsn(ICONST_2); } public void iconst_3() { getMethodVisitor().visitInsn(ICONST_3); } public void iconst_4() { getMethodVisitor().visitInsn(ICONST_4); } public void iconst_5() { getMethodVisitor().visitInsn(ICONST_5); } public void lconst_0() { getMethodVisitor().visitInsn(LCONST_0); } public void aconst_null() { getMethodVisitor().visitInsn(ACONST_NULL); } public void label(Label label) { getMethodVisitor().visitLabel(label); } public void nop() { getMethodVisitor().visitInsn(NOP); } public void pop() { getMethodVisitor().visitInsn(POP); } public void pop2() { getMethodVisitor().visitInsn(POP2); } public void arrayload() { getMethodVisitor().visitInsn(AALOAD); } public void arraystore() { getMethodVisitor().visitInsn(AASTORE); } public void iarrayload() { getMethodVisitor().visitInsn(IALOAD); } public void barrayload() { getMethodVisitor().visitInsn(BALOAD); } public void barraystore() { getMethodVisitor().visitInsn(BASTORE); } public void aaload() { getMethodVisitor().visitInsn(AALOAD); } public void aastore() { getMethodVisitor().visitInsn(AASTORE); } public void iaload() { getMethodVisitor().visitInsn(IALOAD); } public void iastore() { getMethodVisitor().visitInsn(IASTORE); } public void laload() { getMethodVisitor().visitInsn(LALOAD); } public void lastore() { getMethodVisitor().visitInsn(LASTORE); } public void baload() { getMethodVisitor().visitInsn(BALOAD); } public void bastore() { getMethodVisitor().visitInsn(BASTORE); } public void saload() { getMethodVisitor().visitInsn(SALOAD); } public void sastore() { getMethodVisitor().visitInsn(SASTORE); } public void caload() { getMethodVisitor().visitInsn(CALOAD); } public void castore() { getMethodVisitor().visitInsn(CASTORE); } public void faload() { getMethodVisitor().visitInsn(FALOAD); } public void fastore() { getMethodVisitor().visitInsn(FASTORE); } public void daload() { getMethodVisitor().visitInsn(DALOAD); } public void dastore() { getMethodVisitor().visitInsn(DASTORE); } public void fcmpl() { getMethodVisitor().visitInsn(FCMPL); } public void fcmpg() { getMethodVisitor().visitInsn(FCMPG); } public void dcmpl() { getMethodVisitor().visitInsn(DCMPL); } public void dcmpg() { getMethodVisitor().visitInsn(DCMPG); } public void dup_x2() { getMethodVisitor().visitInsn(DUP_X2); } public void dup_x1() { getMethodVisitor().visitInsn(DUP_X1); } public void dup2_x2() { getMethodVisitor().visitInsn(DUP2_X2); } public void dup2_x1() { getMethodVisitor().visitInsn(DUP2_X1); } public void dup2() { getMethodVisitor().visitInsn(DUP2); } public void trycatch(Label arg0, Label arg1, Label arg2, String arg3) { getMethodVisitor().visitTryCatchBlock(arg0, arg1, arg2, arg3); } public void trycatch(String type, Runnable body, Runnable catchBody) { Label before = new Label(); Label after = new Label(); Label catchStart = new Label(); Label done = new Label(); trycatch(before, after, catchStart, type); label(before); body.run(); label(after); go_to(done); if (catchBody != null) { label(catchStart); catchBody.run(); } label(done); } public void go_to(Label arg0) { getMethodVisitor().visitJumpInsn(GOTO, arg0); } public void lookupswitch(Label arg0, int[] arg1, Label[] arg2) { getMethodVisitor().visitLookupSwitchInsn(arg0, arg1, arg2); } public void athrow() { getMethodVisitor().visitInsn(ATHROW); } public void instance_of(String arg0) { getMethodVisitor().visitTypeInsn(INSTANCEOF, arg0); } public void ifeq(Label arg0) { getMethodVisitor().visitJumpInsn(IFEQ, arg0); } public void iffalse(Label arg0) { ifeq(arg0); } public void ifne(Label arg0) { getMethodVisitor().visitJumpInsn(IFNE, arg0); } public void iftrue(Label arg0) { ifne(arg0); } public void if_acmpne(Label arg0) { getMethodVisitor().visitJumpInsn(IF_ACMPNE, arg0); } public void if_acmpeq(Label arg0) { getMethodVisitor().visitJumpInsn(IF_ACMPEQ, arg0); } public void if_icmple(Label arg0) { getMethodVisitor().visitJumpInsn(IF_ICMPLE, arg0); } public void if_icmpgt(Label arg0) { getMethodVisitor().visitJumpInsn(IF_ICMPGT, arg0); } public void if_icmpge(Label arg0) { getMethodVisitor().visitJumpInsn(IF_ICMPGE, arg0); } public void if_icmplt(Label arg0) { getMethodVisitor().visitJumpInsn(IF_ICMPLT, arg0); } public void if_icmpne(Label arg0) { getMethodVisitor().visitJumpInsn(IF_ICMPNE, arg0); } public void if_icmpeq(Label arg0) { getMethodVisitor().visitJumpInsn(IF_ICMPEQ, arg0); } public void checkcast(String arg0) { getMethodVisitor().visitTypeInsn(CHECKCAST, arg0); } public void checkcast(Class clazz) { getMethodVisitor().visitTypeInsn(CHECKCAST, p(clazz)); } public void start() { getMethodVisitor().visitCode(); } private void dump() { PrintWriter pw = new PrintWriter(System.out); Class tmvClass = getMethodVisitor().getClass(); try { Method print = tmvClass.getDeclaredMethod("print", PrintWriter.class); pw.write("*** Dumping ***\n"); print.invoke(getMethodVisitor(), pw); } catch (Throwable ex) { } finally { pw.flush(); } } public void end() { if (DEBUG) { dump(); } getMethodVisitor().visitMaxs(1, 1); getMethodVisitor().visitEnd(); } public void line(int line) { Label label = new Label(); label(label); visitLineNumber(line, label); } public void line(int line, Label label) { visitLineNumber(line, label); } public void ifnonnull(Label arg0) { getMethodVisitor().visitJumpInsn(IFNONNULL, arg0); } public void ifnull(Label arg0) { getMethodVisitor().visitJumpInsn(IFNULL, arg0); } public void iflt(Label arg0) { getMethodVisitor().visitJumpInsn(IFLT, arg0); } public void ifle(Label arg0) { getMethodVisitor().visitJumpInsn(IFLE, arg0); } public void ifgt(Label arg0) { getMethodVisitor().visitJumpInsn(IFGT, arg0); } public void ifge(Label arg0) { getMethodVisitor().visitJumpInsn(IFGE, arg0); } public void arraylength() { getMethodVisitor().visitInsn(ARRAYLENGTH); } public void ishr() { getMethodVisitor().visitInsn(ISHR); } public void ishl() { getMethodVisitor().visitInsn(ISHL); } public void iushr() { getMethodVisitor().visitInsn(IUSHR); } public void lshr() { getMethodVisitor().visitInsn(LSHR); } public void lshl() { getMethodVisitor().visitInsn(LSHL); } public void lushr() { getMethodVisitor().visitInsn(LUSHR); } public void lcmp() { getMethodVisitor().visitInsn(LCMP); } public void iand() { getMethodVisitor().visitInsn(IAND); } public void ior() { getMethodVisitor().visitInsn(IOR); } public void ixor() { getMethodVisitor().visitInsn(IXOR); } public void land() { getMethodVisitor().visitInsn(LAND); } public void lor() { getMethodVisitor().visitInsn(LOR); } public void lxor() { getMethodVisitor().visitInsn(LXOR); } public void iadd() { getMethodVisitor().visitInsn(IADD); } public void ladd() { getMethodVisitor().visitInsn(LADD); } public void fadd() { getMethodVisitor().visitInsn(FADD); } public void dadd() { getMethodVisitor().visitInsn(DADD); } public void isub() { getMethodVisitor().visitInsn(ISUB); } public void lsub() { getMethodVisitor().visitInsn(LSUB); } public void fsub() { getMethodVisitor().visitInsn(FSUB); } public void dsub() { getMethodVisitor().visitInsn(DSUB); } public void idiv() { getMethodVisitor().visitInsn(IDIV); } public void irem() { getMethodVisitor().visitInsn(IREM); } public void ineg() { getMethodVisitor().visitInsn(INEG); } public void i2d() { getMethodVisitor().visitInsn(I2D); } public void i2l() { getMethodVisitor().visitInsn(I2L); } public void i2f() { getMethodVisitor().visitInsn(I2F); } public void i2s() { getMethodVisitor().visitInsn(I2S); } public void i2c() { getMethodVisitor().visitInsn(I2C); } public void i2b() { getMethodVisitor().visitInsn(I2B); } public void ldiv() { getMethodVisitor().visitInsn(LDIV); } public void lrem() { getMethodVisitor().visitInsn(LREM); } public void lneg() { getMethodVisitor().visitInsn(LNEG); } public void l2d() { getMethodVisitor().visitInsn(L2D); } public void l2i() { getMethodVisitor().visitInsn(L2I); } public void l2f() { getMethodVisitor().visitInsn(L2F); } public void fdiv() { getMethodVisitor().visitInsn(FDIV); } public void frem() { getMethodVisitor().visitInsn(FREM); } public void fneg() { getMethodVisitor().visitInsn(FNEG); } public void f2d() { getMethodVisitor().visitInsn(F2D); } public void f2i() { getMethodVisitor().visitInsn(F2D); } public void f2l() { getMethodVisitor().visitInsn(F2L); } public void ddiv() { getMethodVisitor().visitInsn(DDIV); } public void drem() { getMethodVisitor().visitInsn(DREM); } public void dneg() { getMethodVisitor().visitInsn(DNEG); } public void d2f() { getMethodVisitor().visitInsn(D2F); } public void d2i() { getMethodVisitor().visitInsn(D2I); } public void d2l() { getMethodVisitor().visitInsn(D2L); } public void imul() { getMethodVisitor().visitInsn(IMUL); } public void lmul() { getMethodVisitor().visitInsn(LMUL); } public void fmul() { getMethodVisitor().visitInsn(FMUL); } public void dmul() { getMethodVisitor().visitInsn(DMUL); } public void iinc(int arg0, int arg1) { getMethodVisitor().visitIincInsn(arg0, arg1); } public void iinc(LocalVariable arg0, int arg1) { getMethodVisitor().visitIincInsn(arg0.idx, arg1); } public void monitorenter() { getMethodVisitor().visitInsn(MONITORENTER); } public void monitorexit() { getMethodVisitor().visitInsn(MONITOREXIT); } public void jsr(Label branch) { getMethodVisitor().visitJumpInsn(JSR, branch); } public void ret(int arg0) { getMethodVisitor().visitVarInsn(RET, arg0); } public AnnotationVisitor visitAnnotationDefault() { return getMethodVisitor().visitAnnotationDefault(); } public AnnotationVisitor visitAnnotation(String arg0, boolean arg1) { return getMethodVisitor().visitAnnotation(arg0, arg1); } public AnnotationVisitor visitParameterAnnotation(int arg0, String arg1, boolean arg2) { return getMethodVisitor().visitParameterAnnotation(arg0, arg1, arg2); } public void visitAnnotationWithFields(String name, boolean visible, Map fields) { AnnotationVisitor visitor = visitAnnotation(name, visible); visitAnnotationFields(visitor, fields); visitor.visitEnd(); } public void visitParameterAnnotationWithFields(int param, String name, boolean visible, Map fields) { AnnotationVisitor visitor = visitParameterAnnotation(param, name, visible); visitAnnotationFields(visitor, fields); visitor.visitEnd(); } public void visitAttribute(Attribute arg0) { getMethodVisitor().visitAttribute(arg0); } public void visitCode() { getMethodVisitor().visitCode(); } public void visitInsn(int arg0) { getMethodVisitor().visitInsn(arg0); } public void visitIntInsn(int arg0, int arg1) { getMethodVisitor().visitIntInsn(arg0, arg1); } public void visitVarInsn(int arg0, int arg1) { getMethodVisitor().visitVarInsn(arg0, arg1); } public void visitTypeInsn(int arg0, String arg1) { getMethodVisitor().visitTypeInsn(arg0, arg1); } public void visitFieldInsn(int arg0, String arg1, String arg2, String arg3) { getMethodVisitor().visitFieldInsn(arg0, arg1, arg2, arg3); } public void visitMethodInsn(int arg0, String arg1, String arg2, String arg3) { getMethodVisitor().visitMethodInsn(arg0, arg1, arg2, arg3); } public void visitJumpInsn(int arg0, Label arg1) { getMethodVisitor().visitJumpInsn(arg0, arg1); } public void visitLabel(Label arg0) { getMethodVisitor().visitLabel(arg0); } public void visitLdcInsn(Object arg0) { getMethodVisitor().visitLdcInsn(arg0); } public void visitIincInsn(int arg0, int arg1) { getMethodVisitor().visitIincInsn(arg0, arg1); } public void visitTableSwitchInsn(int arg0, int arg1, Label arg2, Label[] arg3) { getMethodVisitor().visitTableSwitchInsn(arg0, arg1, arg2, arg3); } public void visitLookupSwitchInsn(Label arg0, int[] arg1, Label[] arg2) { getMethodVisitor().visitLookupSwitchInsn(arg0, arg1, arg2); } public void visitMultiANewArrayInsn(String arg0, int arg1) { getMethodVisitor().visitMultiANewArrayInsn(arg0, arg1); } public void visitTryCatchBlock(Label arg0, Label arg1, Label arg2, String arg3) { getMethodVisitor().visitTryCatchBlock(arg0, arg1, arg2, arg3); } public void visitLocalVariable(String arg0, String arg1, String arg2, Label arg3, Label arg4, int arg5) { getMethodVisitor().visitLocalVariable(arg0, arg1, arg2, arg3, arg4, arg5); } public void visitLineNumber(int arg0, Label arg1) { getMethodVisitor().visitLineNumber(arg0, arg1); } public void visitMaxs(int arg0, int arg1) { if (DEBUG) { dump(); } getMethodVisitor().visitMaxs(arg0, arg1); } public void visitEnd() { getMethodVisitor().visitEnd(); } public void tableswitch(int min, int max, Label defaultLabel, Label[] cases) { getMethodVisitor().visitTableSwitchInsn(min, max, defaultLabel, cases); } public void visitFrame(int arg0, int arg1, Object[] arg2, int arg3, Object[] arg4) { getMethodVisitor().visitFrame(arg0, arg1, arg2, arg3, arg4); } } StructByReferenceResultConverterFactory.java000066400000000000000000000052461316720554100337620ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/* * Copyright (C) 2013 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import jnr.ffi.*; import jnr.ffi.mapper.FromNativeContext; import jnr.ffi.mapper.FromNativeConverter; import jnr.ffi.provider.converters.StructByReferenceFromNativeConverter; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; final class StructByReferenceResultConverterFactory { private final Map, FromNativeConverter> converters = new ConcurrentHashMap, FromNativeConverter>(); private final AsmClassLoader classLoader; private final boolean asmEnabled; public StructByReferenceResultConverterFactory(AsmClassLoader classLoader, boolean asmEnabled) { this.classLoader = classLoader; this.asmEnabled = asmEnabled; } public final FromNativeConverter get(Class structClass, FromNativeContext fromNativeContext) { FromNativeConverter converter = converters.get(structClass); if (converter == null) { synchronized (converters) { if ((converter = converters.get(structClass)) == null) { converters.put(structClass, converter = createConverter(fromNativeContext.getRuntime(), structClass, fromNativeContext)); } } } return converter; } private FromNativeConverter createConverter(jnr.ffi.Runtime runtime, Class structClass, FromNativeContext fromNativeContext) { return asmEnabled ? AsmStructByReferenceFromNativeConverter.newStructByReferenceConverter(runtime, structClass, 0, classLoader) : StructByReferenceFromNativeConverter.getInstance(structClass, fromNativeContext); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/StubCompiler.java000066400000000000000000000101051316720554100264220ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import com.kenai.jffi.*; import jnr.ffi.CallingConvention; import jnr.ffi.provider.ParameterType; import jnr.ffi.provider.ResultType; import jnr.x86asm.Assembler; import jnr.x86asm.CPU; /** * Compiles asm trampoline stubs for java class methods */ abstract class StubCompiler { // If the version of jffi exports the jffi_save_errno function address, // then it is recent enough to support PageManager and NativeMethods as well. static final long errnoFunctionAddress = getErrnoSaveFunction(); static final boolean hasPageManager = hasPageManager(); static final boolean hasAssembler = hasAssembler(); public static StubCompiler newCompiler(jnr.ffi.Runtime runtime) { if (errnoFunctionAddress != 0 && hasPageManager && hasAssembler) { switch (Platform.getPlatform().getCPU()) { case I386: if (Platform.getPlatform().getOS() != Platform.OS.WINDOWS) { return new X86_32StubCompiler(runtime); } break; case X86_64: if (Platform.getPlatform().getOS() != Platform.OS.WINDOWS) { return new X86_64StubCompiler(runtime); } break; } } return new DummyStubCompiler(); } abstract boolean canCompile(ResultType returnType, ParameterType[] parameterTypes, CallingConvention convention); abstract void compile(Function function, String name, ResultType returnType, ParameterType[] parameterTypes, Class resultClass, Class[] parameterClasses, CallingConvention convention, boolean saveErrno); abstract void attach(Class clazz); static final class DummyStubCompiler extends StubCompiler { boolean canCompile(ResultType returnType, ParameterType[] parameterTypes, CallingConvention convention) { return false; } @Override void compile(Function function, String name, ResultType returnType, ParameterType[] parameterTypes, Class resultClass, Class[] parameterClasses, CallingConvention convention, boolean saveErrno) { throw new UnsupportedOperationException("Not supported yet."); } @Override void attach(Class clazz) { // do nothing } } private static long getErrnoSaveFunction() { try { return Internals.getErrnoSaveFunction(); } catch (Throwable t) { return 0; } } private static boolean hasPageManager() { try { // Just try and allocate/free a page to check the PageManager is working long page = PageManager.getInstance().allocatePages(1, PageManager.PROT_READ | PageManager.PROT_WRITE); PageManager.getInstance().freePages(page, 1); return true; } catch (Throwable t) { return false; } } private static boolean hasAssembler() { try { switch (Platform.getPlatform().getCPU()) { case I386: new Assembler(CPU.X86_32); return true; case X86_64: new Assembler(CPU.X86_64); return true; default: return false; } } catch (Throwable t) { return false; } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/SymbolNotFoundError.java000066400000000000000000000014771316720554100277620ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; public class SymbolNotFoundError extends java.lang.UnsatisfiedLinkError { public SymbolNotFoundError(String msg) { super(msg); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/ToNativeOp.java000066400000000000000000000121721316720554100260500ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import jnr.ffi.Address; import jnr.ffi.NativeType; import jnr.ffi.Pointer; import jnr.ffi.provider.ToNativeType; import java.util.Collections; import java.util.IdentityHashMap; import java.util.Map; import static jnr.ffi.provider.jffi.AsmUtil.*; import static jnr.ffi.provider.jffi.NumberUtil.narrow; import static jnr.ffi.provider.jffi.NumberUtil.widen; /** * Emits appropriate asm code to convert the parameter to a native value */ abstract class ToNativeOp { private final boolean isPrimitive; protected ToNativeOp(boolean primitive) { isPrimitive = primitive; } final boolean isPrimitive() { return isPrimitive; } abstract void emitPrimitive(SkinnyMethodAdapter mv, Class primitiveClass, NativeType nativeType); private static final Map operations; static { Map m = new IdentityHashMap(); for (Class c : new Class[] { byte.class, char.class, short.class, int.class, long.class, boolean.class }) { m.put(c, new Integral(c)); m.put(boxedType(c), new Integral(boxedType(c))); } m.put(float.class, new Float32(float.class)); m.put(Float.class, new Float32(Float.class)); m.put(double.class, new Float64(float.class)); m.put(Double.class, new Float64(Float.class)); m.put(Address.class, new AddressOp()); operations = Collections.unmodifiableMap(m); } static ToNativeOp get(ToNativeType type) { ToNativeOp op = operations.get(type.effectiveJavaType()); if (op != null) { return op; } else { return null; } } static abstract class Primitive extends ToNativeOp { protected final Class javaType; protected Primitive(Class javaType) { super(true); this.javaType = javaType; } } static class Integral extends Primitive { Integral(Class javaType) { super(javaType); } @Override public void emitPrimitive(SkinnyMethodAdapter mv, Class primitiveClass, NativeType nativeType) { if (javaType.isPrimitive()) { NumberUtil.convertPrimitive(mv, javaType, primitiveClass, nativeType); } else { unboxNumber(mv, javaType, primitiveClass, nativeType); } } } static class Float32 extends Primitive { Float32(Class javaType) { super(javaType); } @Override void emitPrimitive(SkinnyMethodAdapter mv, Class primitiveClass, NativeType nativeType) { if (!javaType.isPrimitive()) { unboxNumber(mv, javaType, float.class); } if (primitiveClass != float.class) { mv.invokestatic(Float.class, "floatToRawIntBits", int.class, float.class); widen(mv, int.class, primitiveClass); } } } static class Float64 extends Primitive { Float64(Class javaType) { super(javaType); } @Override void emitPrimitive(SkinnyMethodAdapter mv, Class primitiveClass, NativeType nativeType) { if (!javaType.isPrimitive()) { unboxNumber(mv, javaType, double.class); } if (primitiveClass != double.class) { mv.invokestatic(Double.class, "doubleToRawLongBits", long.class, double.class); narrow(mv, long.class, primitiveClass); } } } static class Delegate extends Primitive { static final ToNativeOp INSTANCE = new Delegate(); Delegate() { super(Pointer.class); } @Override void emitPrimitive(SkinnyMethodAdapter mv, Class primitiveClass, NativeType nativeType) { // delegates are always direct, so handle without the strategy processing unboxPointer(mv, primitiveClass); } } static class AddressOp extends Primitive { AddressOp() { super(Address.class); } @Override void emitPrimitive(SkinnyMethodAdapter mv, Class primitiveClass, NativeType nativeType) { if (long.class == primitiveClass) { mv.invokestatic(AsmRuntime.class, "longValue", long.class, Address.class); } else { mv.invokestatic(AsmRuntime.class, "intValue", int.class, Address.class); narrow(mv, int.class, primitiveClass); } } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/TransientNativeMemory.java000066400000000000000000000117611316720554100303320ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import com.kenai.jffi.PageManager; import jnr.ffi.util.ref.FinalizablePhantomReference; import jnr.ffi.util.ref.FinalizableReferenceQueue; import java.lang.ref.Reference; import java.lang.ref.WeakReference; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; /** * */ public class TransientNativeMemory extends DirectMemoryIO { /** Keeps strong references to the magazine until cleanup */ @SuppressWarnings("MismatchedQueryAndUpdateOfCollection") private static final Map referenceSet = new ConcurrentHashMap(); private static final ThreadLocal currentMagazine = new ThreadLocal(); private static final int PAGES_PER_MAGAZINE = 2; private final Sentinel sentinel; private final int size; public static DirectMemoryIO allocate(jnr.ffi.Runtime runtime, int size, int align, boolean clear) { if (size < 0) { throw new IllegalArgumentException("negative size: " + size); } if (size > 256) { /* Only use the transient allocator for small, short lived allocations */ return new AllocatedDirectMemoryIO(runtime, size, clear); } Magazine magazine = currentMagazine.get(); Sentinel sentinel = magazine != null ? magazine.sentinel() : null; long address; if (sentinel == null || (address = magazine.allocate(size, align)) == 0) { PageManager pm = PageManager.getInstance(); long memory; do { memory = pm.allocatePages(PAGES_PER_MAGAZINE, PageManager.PROT_READ | PageManager.PROT_WRITE); if (memory != 0L && memory != -1L) { break; } // No available pages; trigger a full GC to reclaim some memory System.gc(); FinalizableReferenceQueue.cleanUpAll(); } while (true); referenceSet.put(magazine = new Magazine(sentinel = new Sentinel(), pm, memory, PAGES_PER_MAGAZINE), Boolean.TRUE); currentMagazine.set(magazine); address = magazine.allocate(size, align); } return new TransientNativeMemory(runtime, sentinel, address, size); } TransientNativeMemory(jnr.ffi.Runtime runtime, Sentinel sentinel, long address, int size) { super(runtime, address); this.sentinel = sentinel; this.size = size; } private static long align(long offset, long align) { return (offset + align - 1L) & ~(align - 1L); } @Override public long size() { return this.size; } @Override public int hashCode() { return super.hashCode(); } @Override public boolean equals(Object obj) { if (obj instanceof TransientNativeMemory) { TransientNativeMemory mem = (TransientNativeMemory) obj; return mem.size == size && mem.address() == address(); } return super.equals(obj); } public final void dispose() { /* not-implemented */ } private static final class Sentinel {} /** * Holder for a group of memory allocations. */ private static final class Magazine extends FinalizablePhantomReference { private final Reference sentinelReference; private final PageManager pm; private final long page; private final long end; private final int pageCount; private long memory; Magazine(Sentinel sentinel, PageManager pm, long page, int pageCount) { super(sentinel, NativeFinalizer.getInstance().getFinalizerQueue()); this.sentinelReference = new WeakReference(sentinel); this.pm = pm; this.memory = this.page = page; this.pageCount = pageCount; this.end = memory + (pageCount * pm.pageSize()); } Sentinel sentinel() { return sentinelReference.get(); } long allocate(int size, int align) { long address = align(this.memory, align); if (address + size <= end) { memory = address + size; return address; } return 0L; } public final void finalizeReferent() { pm.freePages(page, pageCount); referenceSet.remove(this); } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/Types.java000077500000000000000000000121151316720554100251240ustar00rootroot00000000000000/* * Copyright (C) 2013 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import jnr.ffi.Address; import jnr.ffi.NativeType; import jnr.ffi.Pointer; import jnr.ffi.Type; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.Annotation; import java.lang.ref.Reference; import java.lang.ref.SoftReference; import java.nio.Buffer; import java.util.*; /** * */ class Types { private static Reference, Type>>> typeCacheReference; static Type getType(jnr.ffi.Runtime runtime, Class javaType, Collection annotations) { Map, Type>> cache = typeCacheReference != null ? typeCacheReference.get() : null; Map, Type> aliasCache = cache != null ? cache.get(javaType) : null; Type type = aliasCache != null ? aliasCache.get(annotations) : null; return type != null ? type : lookupAndCacheType(runtime, javaType, annotations); } @SuppressWarnings("unchecked") private static synchronized Type lookupAndCacheType(jnr.ffi.Runtime runtime, Class javaType, Collection annotations) { Map, Type>> cache = typeCacheReference != null ? typeCacheReference.get() : null; Map, Type> aliasCache = cache != null ? cache.get(javaType) : null; Type type = aliasCache != null ? aliasCache.get(annotations) : null; if (type != null) { return type; } cache = new HashMap, Type>>(cache != null ? cache : Collections.EMPTY_MAP); aliasCache = new HashMap, Type>(aliasCache != null ? aliasCache : Collections.EMPTY_MAP); aliasCache.put(annotations, type = lookupType(runtime, javaType, annotations)); cache.put(javaType, Collections.unmodifiableMap(aliasCache)); typeCacheReference = new SoftReference, Type>>>(Collections.unmodifiableMap(new IdentityHashMap, Type>>(cache))); return type; } private static Type lookupAliasedType(jnr.ffi.Runtime runtime, Collection annotations) { for (Annotation a : annotations) { TypeDefinition typedef = a.annotationType().getAnnotation(TypeDefinition.class); if (typedef != null) { return runtime.findType(typedef.alias()); } } return null; } static Type lookupType(jnr.ffi.Runtime runtime, Class type, Collection annotations) { Type aliasedType = type.isArray() ? null : lookupAliasedType(runtime, annotations); if (aliasedType != null) { return aliasedType; } else if (Void.class.isAssignableFrom(type) || void.class == type) { return runtime.findType(NativeType.VOID); } else if (Boolean.class.isAssignableFrom(type) || boolean.class == type) { return runtime.findType(NativeType.SINT); } else if (Byte.class.isAssignableFrom(type) || byte.class == type) { return runtime.findType(NativeType.SCHAR); } else if (Short.class.isAssignableFrom(type) || short.class == type) { return runtime.findType(NativeType.SSHORT); } else if (Integer.class.isAssignableFrom(type) || int.class == type) { return runtime.findType(NativeType.SINT); } else if (Long.class.isAssignableFrom(type) || long.class == type) { return runtime.findType(NativeType.SLONG); } else if (Float.class.isAssignableFrom(type) || float.class == type) { return runtime.findType(NativeType.FLOAT); } else if (Double.class.isAssignableFrom(type) || double.class == type) { return runtime.findType(NativeType.DOUBLE); } else if (Pointer.class.isAssignableFrom(type)) { return runtime.findType(NativeType.ADDRESS); } else if (Address.class.isAssignableFrom(type)) { return runtime.findType(NativeType.ADDRESS); } else if (Buffer.class.isAssignableFrom(type)) { return runtime.findType(NativeType.ADDRESS); } else if (CharSequence.class.isAssignableFrom(type)) { return runtime.findType(NativeType.ADDRESS); } else if (type.isArray()) { return runtime.findType(NativeType.ADDRESS); } else { throw new IllegalArgumentException("unsupported type: " + type); } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/Util.java000066400000000000000000000017561316720554100247430ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; /** */ final class Util { static boolean getBooleanProperty(String propertyName, boolean defaultValue) { try { return Boolean.valueOf(System.getProperty(propertyName, Boolean.valueOf(defaultValue).toString())); } catch (SecurityException se) { return defaultValue; } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/VariableAccessorGenerator.java000066400000000000000000000227311316720554100311010ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import jnr.ffi.NativeType; import jnr.ffi.Pointer; import jnr.ffi.Variable; import jnr.ffi.mapper.*; import org.objectweb.asm.ClassReader; import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.Label; import java.io.PrintWriter; import java.lang.annotation.Annotation; import java.lang.reflect.Constructor; import java.util.Collection; import java.util.Collections; import java.util.EnumMap; import java.util.Map; import java.util.concurrent.atomic.AtomicLong; import static jnr.ffi.provider.jffi.AsmUtil.*; import static jnr.ffi.provider.jffi.CodegenUtils.*; import static jnr.ffi.provider.jffi.InvokerUtil.hasAnnotation; import static org.objectweb.asm.Opcodes.*; /** * Generate global variable accessors */ public class VariableAccessorGenerator { private final AtomicLong nextClassID = new AtomicLong(0); private final jnr.ffi.Runtime runtime; static final Map pointerOperations; public VariableAccessorGenerator(jnr.ffi.Runtime runtime) { this.runtime = runtime; } public void generate(AsmBuilder builder, Class interfaceClass, String variableName, long address, Class javaType, Collection annotations, SignatureTypeMapper typeMapper, AsmClassLoader classLoader) { if (!NativeLibraryLoader.ASM_ENABLED) { throw new UnsupportedOperationException("asm bytecode generation not supported"); } SimpleNativeContext context = new SimpleNativeContext(builder.getRuntime(), annotations); SignatureType signatureType = DefaultSignatureType.create(javaType, (FromNativeContext) context); jnr.ffi.mapper.FromNativeType fromNativeType = typeMapper.getFromNativeType(signatureType, context); FromNativeConverter fromNativeConverter = fromNativeType != null ? fromNativeType.getFromNativeConverter() : null; jnr.ffi.mapper.ToNativeType toNativeType = typeMapper.getToNativeType(signatureType, context); ToNativeConverter toNativeConverter = toNativeType != null ? toNativeType.getToNativeConverter() : null; Variable variableAccessor = buildVariableAccessor(builder.getRuntime(), address, interfaceClass, javaType, annotations, toNativeConverter, fromNativeConverter, classLoader); SkinnyMethodAdapter mv = new SkinnyMethodAdapter(builder.getClassVisitor(), ACC_PUBLIC | ACC_FINAL, variableName, sig(Variable.class), null, null); mv.start(); mv.aload(0); mv.getfield(builder.getClassNamePath(), builder.getVariableName(variableAccessor), ci(Variable.class)); mv.areturn(); mv.visitMaxs(10, 10); mv.visitEnd(); } Variable buildVariableAccessor(jnr.ffi.Runtime runtime, long address, Class interfaceClass, Class javaType, Collection annotations, ToNativeConverter toNativeConverter, FromNativeConverter fromNativeConverter, AsmClassLoader classLoader) { boolean debug = AsmLibraryLoader.DEBUG && !hasAnnotation(annotations, NoTrace.class); ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); ClassVisitor cv = debug ? AsmUtil.newCheckClassAdapter(cw) : cw; AsmBuilder builder = new AsmBuilder(runtime, p(interfaceClass) + "$VariableAccessor$$" + nextClassID.getAndIncrement(), cv, classLoader); cv.visit(V1_6, ACC_PUBLIC | ACC_FINAL, builder.getClassNamePath(), null, p(Object.class), new String[] { p(Variable.class) }); SkinnyMethodAdapter set = new SkinnyMethodAdapter(builder.getClassVisitor(), ACC_PUBLIC | ACC_FINAL, "set", sig(void.class, Object.class), null, null); Class boxedType = toNativeConverter != null ? toNativeConverter.nativeType() : javaType; NativeType nativeType = Types.getType(runtime, boxedType, annotations).getNativeType(); jnr.ffi.provider.ToNativeType toNativeType = new jnr.ffi.provider.ToNativeType(javaType, nativeType, annotations, toNativeConverter, null); jnr.ffi.provider.FromNativeType fromNativeType = new jnr.ffi.provider.FromNativeType(javaType, nativeType, annotations, fromNativeConverter, null); PointerOp pointerOp = pointerOperations.get(nativeType); if (pointerOp == null) { throw new IllegalArgumentException("global variable type not supported: " + javaType); } set.start(); set.aload(0); Pointer pointer = DirectMemoryIO.wrap(runtime, address); set.getfield(builder.getClassNamePath(), builder.getObjectFieldName(pointer, Pointer.class), ci(Pointer.class)); set.lconst_0(); set.aload(1); set.checkcast(javaType); emitToNativeConversion(builder, set, toNativeType); ToNativeOp toNativeOp = ToNativeOp.get(toNativeType); if (toNativeOp != null && toNativeOp.isPrimitive()) { toNativeOp.emitPrimitive(set, pointerOp.nativeIntClass, toNativeType.getNativeType()); } else if (Pointer.class.isAssignableFrom(toNativeType.effectiveJavaType())) { pointerOp = POINTER_OP_POINTER; } else { throw new IllegalArgumentException("global variable type not supported: " + javaType); } pointerOp.put(set); set.voidreturn(); set.visitMaxs(10, 10); set.visitEnd(); SkinnyMethodAdapter get = new SkinnyMethodAdapter(builder.getClassVisitor(), ACC_PUBLIC | ACC_FINAL, "get", sig(Object.class), null, null); get.start(); get.aload(0); get.getfield(builder.getClassNamePath(), builder.getObjectFieldName(pointer, Pointer.class), ci(Pointer.class)); get.lconst_0(); pointerOp.get(get); emitFromNativeConversion(builder, get, fromNativeType, pointerOp.nativeIntClass); get.areturn(); get.visitMaxs(10, 10); get.visitEnd(); SkinnyMethodAdapter init = new SkinnyMethodAdapter(cv, ACC_PUBLIC, "", sig(void.class, Object[].class), null, null); init.start(); init.aload(0); init.invokespecial(p(Object.class), "", sig(void.class)); builder.emitFieldInitialization(init, 1); init.voidreturn(); init.visitMaxs(10, 10); init.visitEnd(); cv.visitEnd(); try { byte[] bytes = cw.toByteArray(); if (debug) { ClassVisitor trace = AsmUtil.newTraceClassVisitor(new PrintWriter(System.err)); new ClassReader(bytes).accept(trace, 0); } Class implClass = classLoader.defineClass(builder.getClassNamePath().replace("/", "."), bytes); Constructor cons = implClass.getDeclaredConstructor(Object[].class); return cons.newInstance(new Object[] { builder.getObjectFieldValues() }); } catch (Throwable ex) { throw new RuntimeException(ex); } } static { Map ops = new EnumMap(NativeType.class); op(ops, NativeType.SCHAR, "Byte", byte.class); op(ops, NativeType.UCHAR, "Byte", byte.class); op(ops, NativeType.SSHORT, "Short", short.class); op(ops, NativeType.USHORT, "Short", short.class); op(ops, NativeType.SINT, "Int", int.class); op(ops, NativeType.UINT, "Int", int.class); op(ops, NativeType.SLONG, "Long", long.class); op(ops, NativeType.ULONG, "Long", long.class); op(ops, NativeType.SLONGLONG, "LongLong", long.class); op(ops, NativeType.ULONGLONG, "LongLong", long.class); op(ops, NativeType.FLOAT, "Float", float.class); op(ops, NativeType.DOUBLE, "Double", double.class); op(ops, NativeType.ADDRESS, "Address", long.class); pointerOperations = Collections.unmodifiableMap(ops); } private static void op(Map ops, NativeType type, String name, Class nativeIntType) { ops.put(type, new PointerOp(name, nativeIntType)); } private static final PointerOp POINTER_OP_POINTER = new PointerOp("Pointer", Pointer.class); private static final class PointerOp { private final String getMethodName; private final String putMethodName; final Class nativeIntClass; private PointerOp(String name, Class nativeIntClass) { this.getMethodName = "get" + name; this.putMethodName = "put" + name; this.nativeIntClass = nativeIntClass; } void put(SkinnyMethodAdapter mv) { mv.invokevirtual(Pointer.class, putMethodName, void.class, long.class, nativeIntClass); } void get(SkinnyMethodAdapter mv) { mv.invokevirtual(Pointer.class, getMethodName, nativeIntClass, long.class); } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/X86Disassembler.java000066400000000000000000000106571316720554100267510ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import jnr.ffi.*; import jnr.ffi.LibraryLoader; import jnr.ffi.Runtime; import jnr.ffi.mapper.DefaultTypeMapper; import jnr.ffi.mapper.ToNativeContext; import jnr.ffi.mapper.ToNativeConverter; import jnr.ffi.types.intptr_t; import jnr.ffi.types.size_t; import jnr.ffi.types.u_int64_t; import jnr.ffi.types.u_int8_t; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; /** * */ class X86Disassembler { public enum Syntax { INTEL, ATT } public enum Mode { I386, X86_64 } private final UDis86 udis86; final Pointer ud; static final class SingletonHolder { static final UDis86 INSTANCE = loadUDis86(); static final long intel = ((AbstractAsmLibraryInterface) INSTANCE).getLibrary().findSymbolAddress("ud_translate_intel"); static final long att = ((AbstractAsmLibraryInterface) INSTANCE).getLibrary().findSymbolAddress("ud_translate_att"); } static UDis86 loadUDis86() { DefaultTypeMapper typeMapper = new DefaultTypeMapper(); typeMapper.put(X86Disassembler.class, new X86DisassemblerConverter()); return LibraryLoader.create(UDis86.class) .library("udis86") .search("/usr/local/lib") .search("/opt/local/lib") .search("/usr/lib") .mapper(typeMapper) .load(); } @ToNativeConverter.NoContext public static final class X86DisassemblerConverter implements ToNativeConverter { public Pointer toNative(X86Disassembler value, ToNativeContext context) { return value.ud; } public Class nativeType() { return Pointer.class; } } static boolean isAvailable() { try { return SingletonHolder.INSTANCE != null; } catch (Throwable ex) { return false; } } static X86Disassembler create() { return new X86Disassembler(SingletonHolder.INSTANCE); } private X86Disassembler(UDis86 udis86) { this.udis86 = udis86; this.ud = Memory.allocateDirect(Runtime.getRuntime(udis86), 1024, true); this.udis86.ud_init(this.ud); } public void setSyntax(Syntax syntax) { udis86.ud_set_syntax(this, syntax == Syntax.INTEL ? SingletonHolder.intel : SingletonHolder.att); } public void setMode(Mode mode) { udis86.ud_set_mode(this, mode == Mode.I386 ? 32 : 64); } public void setInputBuffer(Pointer buffer, int size) { udis86.ud_set_input_buffer(this, buffer, size); } public boolean disassemble() { return udis86.ud_disassemble(this) != 0; } public String insn() { return udis86.ud_insn_asm(this); } public long offset() { return udis86.ud_insn_off(this); } public String hex() { return udis86.ud_insn_hex(this); } @NoX86 @NoTrace public static interface UDis86 { void ud_init(Pointer ud); void ud_set_mode(X86Disassembler ud, @u_int8_t int mode); void ud_set_pc(X86Disassembler ud, @u_int64_t int pc); void ud_set_input_buffer(X86Disassembler ud, Pointer data, @size_t long len); void ud_set_vendor(X86Disassembler ud, int vendor); void ud_set_syntax(X86Disassembler ud, @intptr_t long translator); void ud_input_skip(X86Disassembler ud, @size_t long size); int ud_input_end(X86Disassembler ud); int ud_decode(X86Disassembler ud); int ud_disassemble(X86Disassembler ud); String ud_insn_asm(X86Disassembler ud); @intptr_t long ud_insn_ptr(X86Disassembler ud); @u_int64_t long ud_insn_off(X86Disassembler ud); String ud_insn_hex(X86Disassembler ud); int ud_insn_len(X86Disassembler ud); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/X86MethodGenerator.java000066400000000000000000000331611316720554100274160ustar00rootroot00000000000000/* * Copyright (C) 2011 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import com.kenai.jffi.*; import jnr.ffi.NativeType; import jnr.ffi.Pointer; import jnr.ffi.CallingConvention; import jnr.ffi.provider.ParameterType; import jnr.ffi.provider.ResultType; import jnr.ffi.provider.SigType; import org.objectweb.asm.Label; import java.util.concurrent.atomic.AtomicLong; import static jnr.ffi.provider.jffi.AbstractFastNumericMethodGenerator.*; import static jnr.ffi.provider.jffi.AsmUtil.unboxedReturnType; import static jnr.ffi.provider.jffi.BaseMethodGenerator.emitEpilogue; import static jnr.ffi.provider.jffi.BaseMethodGenerator.loadAndConvertParameter; import static jnr.ffi.provider.jffi.CodegenUtils.*; import static jnr.ffi.provider.jffi.NumberUtil.*; import static jnr.ffi.provider.jffi.Util.getBooleanProperty; import static org.objectweb.asm.Opcodes.*; /** * */ class X86MethodGenerator implements MethodGenerator { private static final boolean ENABLED = getBooleanProperty("jnr.ffi.x86asm.enabled", true); private final AtomicLong nextMethodID = new AtomicLong(0); private final StubCompiler compiler; X86MethodGenerator(StubCompiler compiler) { this.compiler = compiler; } public boolean isSupported(ResultType resultType, ParameterType[] parameterTypes, CallingConvention callingConvention) { if (!ENABLED) { return false; } final Platform platform = Platform.getPlatform(); if (platform.getOS().equals(Platform.OS.WINDOWS)) { return false; } if (!platform.getCPU().equals(Platform.CPU.I386) && !platform.getCPU().equals(Platform.CPU.X86_64)) { return false; } if (!callingConvention.equals(CallingConvention.DEFAULT)) { return false; } int objectCount = 0; for (int i = 0; i < parameterTypes.length; ++i) { if (!isSupportedParameter(parameterTypes[i])) { return false; } if (isSupportedObjectParameterType(parameterTypes[i])) { objectCount++; } } if (objectCount > 0) { if (parameterTypes.length > 4 || objectCount > 3) { return false; } } return isSupportedResult(resultType) && compiler.canCompile(resultType, parameterTypes, callingConvention); } public void generate(AsmBuilder builder, String functionName, Function function, ResultType resultType, ParameterType[] parameterTypes, boolean ignoreError) { Class[] nativeParameterTypes = new Class[parameterTypes.length]; boolean wrapperNeeded = false; for (int i = 0; i < parameterTypes.length; ++i) { wrapperNeeded |= parameterTypes[i].getToNativeConverter() != null || !parameterTypes[i].effectiveJavaType().isPrimitive(); if (!parameterTypes[i].effectiveJavaType().isPrimitive()) { nativeParameterTypes[i] = getNativeClass(parameterTypes[i].getNativeType()); } else { nativeParameterTypes[i] = parameterTypes[i].effectiveJavaType(); } } Class nativeReturnType; wrapperNeeded |= resultType.getFromNativeConverter() != null || !resultType.effectiveJavaType().isPrimitive(); if (resultType.effectiveJavaType().isPrimitive()) { nativeReturnType = resultType.effectiveJavaType(); } else { nativeReturnType = getNativeClass(resultType.getNativeType()); } String stubName = functionName + (wrapperNeeded ? "$jni$" + nextMethodID.incrementAndGet() : ""); builder.getClassVisitor().visitMethod(ACC_PUBLIC | ACC_FINAL | ACC_NATIVE | (wrapperNeeded ? ACC_STATIC : 0), stubName, sig(nativeReturnType, nativeParameterTypes), null, null); compiler.compile(function, stubName, resultType, parameterTypes, nativeReturnType, nativeParameterTypes, CallingConvention.DEFAULT, !ignoreError); // If unboxing of parameters is required, generate a wrapper if (wrapperNeeded) { generateWrapper(builder, functionName, function, resultType, parameterTypes, stubName, nativeReturnType, nativeParameterTypes); } } private static void generateWrapper(final AsmBuilder builder, String functionName, Function function, final ResultType resultType, final ParameterType[] parameterTypes, String nativeMethodName, Class nativeReturnType, Class[] nativeParameterTypes) { Class[] javaParameterTypes = new Class[parameterTypes.length]; for (int i = 0; i < parameterTypes.length; i++) { javaParameterTypes[i] = parameterTypes[i].getDeclaredType(); } final SkinnyMethodAdapter mv = new SkinnyMethodAdapter(builder.getClassVisitor(), ACC_PUBLIC | ACC_FINAL, functionName, sig(resultType.getDeclaredType(), javaParameterTypes), null, null); mv.setMethodVisitor(AsmUtil.newTraceMethodVisitor(mv.getMethodVisitor())); mv.start(); LocalVariableAllocator localVariableAllocator = new LocalVariableAllocator(parameterTypes); final LocalVariable objCount = localVariableAllocator.allocate(int.class); final LocalVariable[] parameters = AsmUtil.getParameterVariables(parameterTypes); final LocalVariable[] converted = new LocalVariable[parameterTypes.length]; int pointerCount = 0; for (int i = 0; i < parameterTypes.length; ++i) { Class javaParameterClass = parameterTypes[i].effectiveJavaType(); Class nativeParameterClass = nativeParameterTypes[i]; converted[i] = loadAndConvertParameter(builder, mv, localVariableAllocator, parameters[i], parameterTypes[i]); ToNativeOp toNativeOp = ToNativeOp.get(parameterTypes[i]); if (toNativeOp != null && toNativeOp.isPrimitive()) { toNativeOp.emitPrimitive(mv, nativeParameterClass, parameterTypes[i].getNativeType()); } else if (hasPointerParameterStrategy(javaParameterClass)) { pointerCount = emitDirectCheck(mv, javaParameterClass, nativeParameterClass, converted[i], objCount, pointerCount); } else if (!javaParameterClass.isPrimitive()) { throw new IllegalArgumentException("unsupported type " + javaParameterClass); } } Label hasObjects = new Label(); Label convertResult = new Label(); // If there are any objects, jump to the fast-object path if (pointerCount > 0) { mv.iload(objCount); mv.ifne(hasObjects); } // invoke the compiled stub mv.invokestatic(builder.getClassNamePath(), nativeMethodName, sig(nativeReturnType, nativeParameterTypes)); // If boxing is neccessary, perform conversions final Class unboxedResultType = unboxedReturnType(resultType.effectiveJavaType()); convertPrimitive(mv, nativeReturnType, unboxedResultType); if (pointerCount > 0) { mv.label(convertResult); } emitEpilogue(builder, mv, resultType, parameterTypes, parameters, converted, null); /* -- method returns above - below is the object path, which will jump back above to return -- */ // Now implement heap object support if (pointerCount > 0) { mv.label(hasObjects); // Store all the native args LocalVariable[] tmp = new LocalVariable[parameterTypes.length]; for (int i = parameterTypes.length - 1; i >= 0; i--) { tmp[i] = localVariableAllocator.allocate(long.class); if (float.class == nativeParameterTypes[i]) { mv.invokestatic(Float.class, "floatToRawIntBits", int.class, float.class); mv.i2l(); } else if (double.class == nativeParameterTypes[i]) { mv.invokestatic(Double.class, "doubleToRawLongBits", long.class, double.class); } else { convertPrimitive(mv, nativeParameterTypes[i], long.class, parameterTypes[i].getNativeType()); } mv.lstore(tmp[i]); } // Retrieve the static 'ffi' Invoker instance mv.getstatic(p(AbstractAsmLibraryInterface.class), "ffi", ci(com.kenai.jffi.Invoker.class)); // retrieve the call context and function address mv.aload(0); mv.getfield(builder.getClassNamePath(), builder.getCallContextFieldName(function), ci(CallContext.class)); mv.aload(0); mv.getfield(builder.getClassNamePath(), builder.getFunctionAddressFieldName(function), ci(long.class)); // Now reload the args back onto the parameter stack mv.lload(tmp); mv.iload(objCount); // Need to load all the converters onto the stack for (int i = 0; i < parameterTypes.length; i++) { LocalVariable[] strategies = new LocalVariable[parameterTypes.length]; Class javaParameterType = parameterTypes[i].effectiveJavaType(); if (hasPointerParameterStrategy(javaParameterType)) { mv.aload(converted[i]); emitParameterStrategyLookup(mv, javaParameterType); mv.astore(strategies[i] = localVariableAllocator.allocate(ParameterStrategy.class)); mv.aload(converted[i]); mv.aload(strategies[i]); ObjectParameterInfo info = ObjectParameterInfo.create(i, AsmUtil.getNativeArrayFlags(parameterTypes[i].annotations())); mv.aload(0); mv.getfield(builder.getClassNamePath(), builder.getObjectParameterInfoName(info), ci(ObjectParameterInfo.class)); } } mv.invokevirtual(p(com.kenai.jffi.Invoker.class), AbstractFastNumericMethodGenerator.getObjectParameterMethodName(parameterTypes.length), AbstractFastNumericMethodGenerator.getObjectParameterMethodSignature(parameterTypes.length, pointerCount)); // Convert the result from long/int to the correct return type if (float.class == nativeReturnType) { narrow(mv, long.class, int.class); mv.invokestatic(Float.class, "intBitsToFloat", float.class, int.class); } else if (double.class == nativeReturnType) { mv.invokestatic(Double.class, "longBitsToDouble", double.class, long.class); } else if (void.class == nativeReturnType) { mv.pop2(); } convertPrimitive(mv, long.class, unboxedResultType, resultType.getNativeType()); // Jump to the main conversion/boxing code above mv.go_to(convertResult); } mv.visitMaxs(100, localVariableAllocator.getSpaceUsed()); mv.visitEnd(); } void attach(Class clazz) { compiler.attach(clazz); } private static boolean isSupportedObjectParameterType(ParameterType type) { return Pointer.class.isAssignableFrom(type.effectiveJavaType()); } private static boolean isSupportedType(SigType type) { switch (type.getNativeType()) { case SCHAR: case UCHAR: case SSHORT: case USHORT: case SINT: case UINT: case SLONG: case ULONG: case SLONGLONG: case ULONGLONG: case FLOAT: case DOUBLE: return true; default: return false; } } static boolean isSupportedResult(ResultType resultType) { return isSupportedType(resultType) || void.class == resultType.effectiveJavaType() || resultType.getNativeType() == NativeType.ADDRESS ; } static boolean isSupportedParameter(ParameterType parameterType) { return isSupportedType(parameterType) || isSupportedObjectParameterType(parameterType) ; } static Class getNativeClass(NativeType nativeType) { switch (nativeType) { case SCHAR: case UCHAR: case SSHORT: case USHORT: case SINT: case UINT: case SLONG: case ULONG: case ADDRESS: case SLONGLONG: case ULONGLONG: // Since the asm code does any sign/zero extension, we can pass everything down as int/long // which potentially saves some java conversion ops return sizeof(nativeType) <= 4 ? int.class : long.class; case FLOAT: return float.class; case DOUBLE: return double.class; case VOID: return void.class; default: throw new IllegalArgumentException("unsupported native type: " + nativeType); } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/X86_32StubCompiler.java000066400000000000000000000252271316720554100272470ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import com.kenai.jffi.Function; import jnr.ffi.*; import jnr.ffi.provider.ParameterType; import jnr.ffi.provider.ResultType; import jnr.x86asm.Assembler; import jnr.x86asm.Mem; import jnr.x86asm.Register; import static jnr.ffi.provider.jffi.CodegenUtils.sig; import static jnr.x86asm.Asm.*; /** * Stub compiler for i386 unix */ final class X86_32StubCompiler extends AbstractX86StubCompiler { X86_32StubCompiler(jnr.ffi.Runtime runtime) { super(runtime); } boolean canCompile(ResultType returnType, ParameterType[] parameterTypes, CallingConvention convention) { switch (returnType.getNativeType()) { case VOID: case SCHAR: case UCHAR: case SSHORT: case USHORT: case SINT: case UINT: case SLONG: case ULONG: case SLONGLONG: case ULONGLONG: case FLOAT: case DOUBLE: case ADDRESS: break; default: return false; } // There is only one calling convention; SYSV, so abort if someone tries to use stdcall if (convention != CallingConvention.DEFAULT) { return false; } int fCount = 0; int iCount = 0; for (ParameterType t : parameterTypes) { switch (t.getNativeType()) { case SCHAR: case UCHAR: case SSHORT: case USHORT: case SINT: case UINT: case SLONG: case ULONG: case SLONGLONG: case ULONGLONG: case ADDRESS: ++iCount; break; case FLOAT: case DOUBLE: ++fCount; break; default: // Fail on anything else return false; } } // We can only safely compile methods with up to 6 integer and 8 floating point parameters return true; } @Override void compile(Function function, String name, ResultType resultType, ParameterType[] parameterTypes, Class resultClass, Class[] parameterClasses, CallingConvention convention, boolean saveErrno) { int psize = 0; for (ParameterType t : parameterTypes) { psize += parameterSize(t); } int rsize = resultSize(resultType); // // JNI functions all look like: // foo(JNIEnv* env, jobject self, arg...) // We need to align the stack to 16 bytes, then copy all the old args // into the new parameter space. // It already has 4 bytes pushed (the return address) so we need to account for that. // final int stackadj = align(Math.max(psize, rsize) + 4, 16) - 4; Assembler a = new Assembler(X86_32); a.sub(esp, imm(stackadj)); // copy and convert the parameters from the orig stack to the new location for (int i = 0, srcoff = 0, dstoff = 0; i < parameterTypes.length; i++) { int srcParameterSize = parameterSize(parameterClasses[i]); int dstParameterSize = parameterSize(parameterTypes[i]); int disp = stackadj + 4 + 8 + srcoff; switch (parameterTypes[i].getNativeType()) { case SCHAR: case SSHORT: a.movsx(eax, ptr(esp, disp, parameterTypes[i].getNativeType())); break; case UCHAR: case USHORT: a.movzx(eax, ptr(esp, disp, parameterTypes[i].getNativeType())); break; default: a.mov(eax, dword_ptr(esp, disp)); break; } a.mov(dword_ptr(esp, dstoff), eax); if (dstParameterSize > 4) { if (parameterTypes[i].getNativeType() == NativeType.SLONGLONG && long.class != parameterClasses[i]) { // sign extend from int.class -> long long a.sar(eax, imm(31)); } else if (parameterTypes[i].getNativeType() == NativeType.ULONGLONG && long.class != parameterClasses[i]) { // zero extend from int.class -> unsigned long long a.mov(dword_ptr(esp, dstoff + 4), imm(0)); } else { a.mov(eax, dword_ptr(esp, disp + 4)); } a.mov(dword_ptr(esp, dstoff + 4), eax); } dstoff += dstParameterSize; srcoff += srcParameterSize; } // Call to the actual native function a.call(imm(function.getFunctionAddress() & 0xffffffffL)); if (saveErrno) { int save = 0; switch (resultType.getNativeType()) { case FLOAT: a.fstp(dword_ptr(esp, save)); break; case DOUBLE: a.fstp(qword_ptr(esp, save)); break; case SLONGLONG: case ULONGLONG: a.mov(dword_ptr(esp, save), eax); a.mov(dword_ptr(esp, save + 4), edx); break; case VOID: // No need to save for void values break; default: a.mov(dword_ptr(esp, save), eax); } // Save the errno in a thread-local variable a.call(imm(errnoFunctionAddress & 0xffffffffL)); // Retrieve return value and put it back in the appropriate return register switch (resultType.getNativeType()) { case FLOAT: a.fld(dword_ptr(esp, save)); break; case DOUBLE: a.fld(qword_ptr(esp, save)); break; case SCHAR: a.movsx(eax, byte_ptr(esp, save)); break; case UCHAR: a.movzx(eax, byte_ptr(esp, save)); break; case SSHORT: a.movsx(eax, word_ptr(esp, save)); break; case USHORT: a.movzx(eax, word_ptr(esp, save)); break; case SLONGLONG: case ULONGLONG: a.mov(eax, dword_ptr(esp, save)); a.mov(edx, dword_ptr(esp, save + 4)); break; case VOID: // No need to save for void values break; default: a.mov(eax, dword_ptr(esp, save)); } } else { switch (resultType.getNativeType()) { case SCHAR: a.movsx(eax, al); break; case UCHAR: a.movzx(eax, al); break; case SSHORT: a.movsx(eax, ax); break; case USHORT: a.movzx(eax, ax); break; } } if (long.class == resultClass) { // sign or zero extend the result to 64 bits switch (resultType.getNativeType()) { case SCHAR: case SSHORT: case SINT: case SLONG: // sign extend eax to edx:eax a.mov(edx, eax); a.sar(edx, imm(31)); break; case UCHAR: case USHORT: case UINT: case ULONG: case ADDRESS: a.mov(edx, imm(0)); break; } } // Restore esp to the original position and return a.add(esp, imm(stackadj)); a.ret(); stubs.add(new Stub(name, sig(resultClass, parameterClasses), a)); } static int parameterSize(ParameterType parameterType) { switch (parameterType.getNativeType()) { case SCHAR: case UCHAR: case SSHORT: case USHORT: case SINT: case UINT: case SLONG: case ULONG: case ADDRESS: case FLOAT: return 4; case SLONGLONG: case ULONGLONG: case DOUBLE: return 8; default: throw new IllegalArgumentException("invalid parameter type" + parameterType); } } static int parameterSize(Class t) { if (byte.class == t || short.class == t || char.class == t | int.class == t || float.class == t) { return 4; } else if (long.class == t || double.class == t) { return 8; } throw new IllegalArgumentException("invalid parameter type" + t); } static int resultSize(ResultType resultType) { switch (resultType.getNativeType()) { case SCHAR: case UCHAR: case SSHORT: case USHORT: case SINT: case UINT: case SLONG: case ULONG: case ADDRESS: return 4; case SLONGLONG: case ULONGLONG: return 8; case FLOAT: case DOUBLE: return 16; case VOID: return 0; default: throw new IllegalArgumentException("invalid return type " + resultType); } } static Mem ptr(Register base, long disp, NativeType nativeType) { switch (nativeType) { case SCHAR: case UCHAR: return byte_ptr(base, disp); case SSHORT: case USHORT: return word_ptr(base, disp); default: return dword_ptr(base, disp); } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/X86_64StubCompiler.java000066400000000000000000000275471316720554100272630ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi; import com.kenai.jffi.Function; import jnr.ffi.*; import jnr.ffi.provider.ParameterType; import jnr.ffi.provider.ResultType; import jnr.x86asm.Assembler; import jnr.x86asm.REG; import jnr.x86asm.Register; import static jnr.ffi.provider.jffi.CodegenUtils.sig; import static jnr.x86asm.Asm.*; /** * Compilers method trampoline stubs for x86_64 */ final class X86_64StubCompiler extends AbstractX86StubCompiler { X86_64StubCompiler(jnr.ffi.Runtime runtime) { super(runtime); } boolean canCompile(ResultType returnType, ParameterType[] parameterTypes, CallingConvention convention) { // There is only one calling convention; SYSV, so abort if someone tries to use stdcall if (convention != CallingConvention.DEFAULT) { return false; } switch (returnType.getNativeType()) { case VOID: case SCHAR: case UCHAR: case SSHORT: case USHORT: case SINT: case UINT: case SLONG: case ULONG: case SLONGLONG: case ULONGLONG: case FLOAT: case DOUBLE: case ADDRESS: break; default: return false; } int fCount = 0; int iCount = 0; for (ParameterType t : parameterTypes) { switch (t.getNativeType()) { case SCHAR: case UCHAR: case SSHORT: case USHORT: case SINT: case UINT: case SLONG: case ULONG: case SLONGLONG: case ULONGLONG: case ADDRESS: ++iCount; break; case FLOAT: case DOUBLE: ++fCount; break; default: // Fail on anything else return false; } } // We can only safely compile methods with up to 6 integer and 8 floating point parameters return iCount <= 6 && fCount <= 8; } static final Register[] srcRegisters8 = { dl, cl, r8b, r9b }; static final Register[] srcRegisters16 = { dx, cx, r8w, r9w }; static final Register[] srcRegisters32 = { edx, ecx, Register.gpr(REG.REG_R8D), Register.gpr(REG.REG_R9D) }; static final Register[] srcRegisters64 = { rdx, rcx, r8, r9 }; static final Register[] dstRegisters32 = { edi, esi, edx, ecx, Register.gpr(REG.REG_R8D), Register.gpr(REG.REG_R9D) }; static final Register[] dstRegisters64 = { rdi, rsi, rdx, rcx, r8, r9 }; @Override final void compile(Function function, String name, ResultType resultType, ParameterType[] parameterTypes, Class resultClass, Class[] parameterClasses, CallingConvention convention, boolean saveErrno) { Assembler a = new Assembler(X86_64); int iCount = iCount(parameterTypes); int fCount = fCount(parameterTypes); boolean canJumpToTarget = !saveErrno & iCount <= 6 & fCount <= 8; switch (resultType.getNativeType()) { case SINT: case UINT: canJumpToTarget &= int.class == resultClass; break; case SLONGLONG: case ULONGLONG: canJumpToTarget &= long.class == resultClass; break; case FLOAT: canJumpToTarget &= float.class == resultClass; break; case DOUBLE: canJumpToTarget &= double.class == resultClass; break; case VOID: break; default: canJumpToTarget = false; break; } // JNI functions all look like: // foo(JNIEnv* env, jobject self, arg...) // on AMD64, those sit in %rdi, %rsi, %rdx, %rcx, %r8 and %r9 // So we need to shuffle all the integer args up to over-write the // env and self arguments // for (int i = 0; i < Math.min(iCount, 4); i++) { switch (parameterTypes[i].getNativeType()) { case SCHAR: a.movsx(dstRegisters64[i], srcRegisters8[i]); break; case UCHAR: a.movzx(dstRegisters64[i], srcRegisters8[i]); break; case SSHORT: a.movsx(dstRegisters64[i], srcRegisters16[i]); break; case USHORT: a.movzx(dstRegisters64[i], srcRegisters16[i]); break; case SINT: a.movsxd(dstRegisters64[i], srcRegisters32[i]); break; case UINT: // mov with a 32bit dst reg zero extends to 64bit a.mov(dstRegisters32[i], srcRegisters32[i]); break; default: a.mov(dstRegisters64[i], srcRegisters64[i]); break; } } if (iCount > 6) { throw new IllegalArgumentException("integer argument count > 6"); } // For args 5 & 6 of the function, they would have been pushed on the stack for (int i = 4; i < iCount; i++) { int disp = 8 + ((4 - i) * 8); switch (parameterTypes[i].getNativeType()) { case SCHAR: a.movsx(dstRegisters64[i], byte_ptr(rsp, disp)); break; case UCHAR: a.movzx(dstRegisters64[i], byte_ptr(rsp, disp)); break; case SSHORT: a.movsx(dstRegisters64[i], word_ptr(rsp, disp)); break; case USHORT: a.movzx(dstRegisters64[i], word_ptr(rsp, disp)); break; case SINT: a.movsxd(dstRegisters64[i], dword_ptr(rsp, disp)); break; case UINT: // mov with a 32bit dst reg zero extends to 64bit a.mov(dstRegisters32[i], dword_ptr(rsp, disp)); break; default: a.mov(dstRegisters64[i], qword_ptr(rsp, disp)); break; } } // All the integer registers are loaded; there nothing to do for the floating // registers, as the first 8 args are already in xmm0..xmm7, so just sanity check if (fCount > 8) { throw new IllegalArgumentException("float argument count > 8"); } if (canJumpToTarget) { a.jmp(imm(function.getFunctionAddress())); stubs.add(new Stub(name, sig(resultClass, parameterClasses), a)); return; } // Need to align the stack to 16 bytes for function call. // It already has 8 bytes pushed (the return address), so making space // to save the return value from the function neatly aligns it to 16 bytes int space = resultClass == float.class || resultClass == double.class ? 24 : 8; a.sub(rsp, imm(space)); // Clear %rax, since it is used by varargs functions to determine the number of float registers to be saved a.mov(rax, imm(0)); // Call to the actual native function a.call(imm(function.getFunctionAddress())); if (saveErrno) { // Save the return on the stack switch (resultType.getNativeType()) { case VOID: // No need to save/reload return value registers break; case FLOAT: a.movss(dword_ptr(rsp, 0), xmm0); break; case DOUBLE: a.movsd(qword_ptr(rsp, 0), xmm0); break; default: a.mov(qword_ptr(rsp, 0), rax); } // Save the errno in a thread-local variable a.call(imm(errnoFunctionAddress)); // Retrieve return value and put it back in the appropriate return register switch (resultType.getNativeType()) { case VOID: // No need to save/reload return value registers break; case SCHAR: a.movsx(rax, byte_ptr(rsp, 0)); break; case UCHAR: a.movzx(rax, byte_ptr(rsp, 0)); break; case SSHORT: a.movsx(rax, word_ptr(rsp, 0)); break; case USHORT: a.movzx(rax, word_ptr(rsp, 0)); break; case SINT: a.movsxd(rax, dword_ptr(rsp, 0)); break; case UINT: // storing a value in eax zeroes out the upper 32 bits of rax a.mov(eax, dword_ptr(rsp, 0)); break; case FLOAT: a.movss(xmm0, dword_ptr(rsp, 0)); break; case DOUBLE: a.movsd(xmm0, qword_ptr(rsp, 0)); break; default: a.mov(rax, qword_ptr(rsp, 0)); break; } } else { // sign/zero extend the result switch (resultType.getNativeType()) { case SCHAR: a.movsx(rax, al); break; case UCHAR: a.movzx(rax, al); break; case SSHORT: a.movsx(rax, ax); break; case USHORT: a.movzx(rax, ax); break; case SINT: if (long.class == resultClass) a.movsxd(rax, eax); break; case UINT: if (long.class == resultClass) a.mov(eax, eax); break; } } // Restore rsp to original position a.add(rsp, imm(space)); a.ret(); stubs.add(new Stub(name, sig(resultClass, parameterClasses), a)); } static int fCount(ParameterType[] parameterTypes) { int fCount = 0; for (ParameterType t : parameterTypes) { switch (t.getNativeType()) { case FLOAT: case DOUBLE: ++fCount; break; } } return fCount; } static int iCount(ParameterType[] parameterTypes) { int iCount = 0; for (ParameterType t : parameterTypes) { switch (t.getNativeType()) { case SCHAR: case UCHAR: case SSHORT: case USHORT: case SINT: case UINT: case SLONG: case ULONG: case SLONGLONG: case ULONGLONG: case ADDRESS: ++iCount; break; } } return iCount; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/000077500000000000000000000000001316720554100247765ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/aarch64/000077500000000000000000000000001316720554100262265ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/aarch64/linux/000077500000000000000000000000001316720554100273655ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/aarch64/linux/TypeAliases.java000066400000000000000000000056761316720554100324710ustar00rootroot00000000000000/* * Copyright (C) 2016 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi.platform.aarch64.linux; import jnr.ffi.NativeType; import jnr.ffi.TypeAlias; import java.util.EnumMap; import java.util.Map; public final class TypeAliases { public static final Map ALIASES = buildTypeMap(); private static Map buildTypeMap() { Map m = new EnumMap(TypeAlias.class); m.put(TypeAlias.int8_t, NativeType.SCHAR); m.put(TypeAlias.u_int8_t, NativeType.UCHAR); m.put(TypeAlias.int16_t, NativeType.SSHORT); m.put(TypeAlias.u_int16_t, NativeType.USHORT); m.put(TypeAlias.int32_t, NativeType.SINT); m.put(TypeAlias.u_int32_t, NativeType.UINT); m.put(TypeAlias.int64_t, NativeType.ADDRESS); m.put(TypeAlias.u_int64_t, NativeType.ADDRESS); m.put(TypeAlias.intptr_t, NativeType.SLONG); m.put(TypeAlias.uintptr_t, NativeType.ULONG); m.put(TypeAlias.caddr_t, NativeType.ADDRESS); m.put(TypeAlias.dev_t, NativeType.ULONG); m.put(TypeAlias.blkcnt_t, NativeType.SLONG); m.put(TypeAlias.blksize_t, NativeType.SLONG); m.put(TypeAlias.gid_t, NativeType.UINT); m.put(TypeAlias.in_addr_t, NativeType.UINT); m.put(TypeAlias.in_port_t, NativeType.USHORT); m.put(TypeAlias.ino_t, NativeType.ULONG); m.put(TypeAlias.ino64_t, NativeType.ULONG); m.put(TypeAlias.key_t, NativeType.SINT); m.put(TypeAlias.mode_t, NativeType.UINT); m.put(TypeAlias.nlink_t, NativeType.ULONG); m.put(TypeAlias.id_t, NativeType.UINT); m.put(TypeAlias.pid_t, NativeType.SINT); m.put(TypeAlias.off_t, NativeType.SLONG); m.put(TypeAlias.swblk_t, NativeType.SLONG); m.put(TypeAlias.uid_t, NativeType.UINT); m.put(TypeAlias.clock_t, NativeType.SLONG); m.put(TypeAlias.size_t, NativeType.ULONG); m.put(TypeAlias.ssize_t, NativeType.SLONG); m.put(TypeAlias.time_t, NativeType.SLONG); m.put(TypeAlias.fsblkcnt_t, NativeType.ULONG); m.put(TypeAlias.fsfilcnt_t, NativeType.ULONG); m.put(TypeAlias.sa_family_t, NativeType.USHORT); m.put(TypeAlias.socklen_t, NativeType.UINT); m.put(TypeAlias.rlim_t, NativeType.ULONG); return m; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/arm/000077500000000000000000000000001316720554100255555ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/arm/linux/000077500000000000000000000000001316720554100267145ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/arm/linux/TypeAliases.java000066400000000000000000000057321316720554100320110ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi.platform.arm.linux; import jnr.ffi.NativeType; import jnr.ffi.TypeAlias; import java.util.EnumMap; import java.util.Map; public final class TypeAliases { public static final Map ALIASES = buildTypeMap(); private static Map buildTypeMap() { Map m = new EnumMap(TypeAlias.class); m.put(TypeAlias.int8_t, NativeType.SCHAR); m.put(TypeAlias.u_int8_t, NativeType.UCHAR); m.put(TypeAlias.int16_t, NativeType.SSHORT); m.put(TypeAlias.u_int16_t, NativeType.USHORT); m.put(TypeAlias.int32_t, NativeType.SINT); m.put(TypeAlias.u_int32_t, NativeType.UINT); m.put(TypeAlias.int64_t, NativeType.SLONGLONG); m.put(TypeAlias.u_int64_t, NativeType.ULONGLONG); m.put(TypeAlias.intptr_t, NativeType.SINT); m.put(TypeAlias.uintptr_t, NativeType.ULONG); m.put(TypeAlias.caddr_t, NativeType.ADDRESS); m.put(TypeAlias.dev_t, NativeType.ULONGLONG); m.put(TypeAlias.blkcnt_t, NativeType.SLONGLONG); m.put(TypeAlias.blksize_t, NativeType.SLONG); m.put(TypeAlias.gid_t, NativeType.UINT); m.put(TypeAlias.in_addr_t, NativeType.UINT); m.put(TypeAlias.in_port_t, NativeType.USHORT); m.put(TypeAlias.ino_t, NativeType.ULONGLONG); m.put(TypeAlias.ino64_t, NativeType.ULONGLONG); m.put(TypeAlias.key_t, NativeType.SINT); m.put(TypeAlias.mode_t, NativeType.UINT); m.put(TypeAlias.nlink_t, NativeType.UINT); m.put(TypeAlias.id_t, NativeType.UINT); m.put(TypeAlias.pid_t, NativeType.SINT); m.put(TypeAlias.off_t, NativeType.SLONGLONG); m.put(TypeAlias.swblk_t, NativeType.SLONG); m.put(TypeAlias.uid_t, NativeType.UINT); m.put(TypeAlias.clock_t, NativeType.SLONG); m.put(TypeAlias.size_t, NativeType.UINT); m.put(TypeAlias.ssize_t, NativeType.SINT); m.put(TypeAlias.time_t, NativeType.SLONG); m.put(TypeAlias.fsblkcnt_t, NativeType.ULONGLONG); m.put(TypeAlias.fsfilcnt_t, NativeType.ULONGLONG); m.put(TypeAlias.sa_family_t, NativeType.USHORT); m.put(TypeAlias.socklen_t, NativeType.UINT); m.put(TypeAlias.rlim_t, NativeType.ULONGLONG); return m; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/i386/000077500000000000000000000000001316720554100254675ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/i386/darwin/000077500000000000000000000000001316720554100267535ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/i386/darwin/TypeAliases.java000066400000000000000000000057211316720554100320460ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi.platform.i386.darwin; import jnr.ffi.NativeType; import jnr.ffi.TypeAlias; import java.util.EnumMap; import java.util.Map; public final class TypeAliases { public static final Map ALIASES = buildTypeMap(); private static Map buildTypeMap() { Map m = new EnumMap(TypeAlias.class); m.put(TypeAlias.int8_t, NativeType.SCHAR); m.put(TypeAlias.u_int8_t, NativeType.UCHAR); m.put(TypeAlias.int16_t, NativeType.SSHORT); m.put(TypeAlias.u_int16_t, NativeType.USHORT); m.put(TypeAlias.int32_t, NativeType.SINT); m.put(TypeAlias.u_int32_t, NativeType.UINT); m.put(TypeAlias.int64_t, NativeType.SLONGLONG); m.put(TypeAlias.u_int64_t, NativeType.ULONGLONG); m.put(TypeAlias.intptr_t, NativeType.SLONG); m.put(TypeAlias.uintptr_t, NativeType.ULONG); m.put(TypeAlias.caddr_t, NativeType.ADDRESS); m.put(TypeAlias.dev_t, NativeType.SINT); m.put(TypeAlias.blkcnt_t, NativeType.SLONGLONG); m.put(TypeAlias.blksize_t, NativeType.SINT); m.put(TypeAlias.gid_t, NativeType.UINT); m.put(TypeAlias.in_addr_t, NativeType.UINT); m.put(TypeAlias.in_port_t, NativeType.USHORT); m.put(TypeAlias.ino_t, NativeType.ULONGLONG); m.put(TypeAlias.ino64_t, NativeType.ULONGLONG); m.put(TypeAlias.key_t, NativeType.SINT); m.put(TypeAlias.mode_t, NativeType.USHORT); m.put(TypeAlias.nlink_t, NativeType.USHORT); m.put(TypeAlias.id_t, NativeType.UINT); m.put(TypeAlias.pid_t, NativeType.SINT); m.put(TypeAlias.off_t, NativeType.SLONGLONG); m.put(TypeAlias.swblk_t, NativeType.SINT); m.put(TypeAlias.uid_t, NativeType.UINT); m.put(TypeAlias.clock_t, NativeType.ULONG); m.put(TypeAlias.size_t, NativeType.ULONG); m.put(TypeAlias.ssize_t, NativeType.SLONG); m.put(TypeAlias.time_t, NativeType.SLONG); m.put(TypeAlias.fsblkcnt_t, NativeType.UINT); m.put(TypeAlias.fsfilcnt_t, NativeType.UINT); m.put(TypeAlias.sa_family_t, NativeType.UCHAR); m.put(TypeAlias.socklen_t, NativeType.UINT); m.put(TypeAlias.rlim_t, NativeType.ULONGLONG); return m; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/i386/freebsd/000077500000000000000000000000001316720554100271015ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/i386/freebsd/TypeAliases.java000066400000000000000000000057271316720554100322020ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi.platform.i386.freebsd; import jnr.ffi.TypeAlias; import jnr.ffi.NativeType; import java.util.EnumMap; import java.util.Map; public final class TypeAliases { public static final Map ALIASES = buildTypeMap(); private static Map buildTypeMap() { Map m = new EnumMap(TypeAlias.class); m.put(TypeAlias.int8_t, NativeType.SCHAR); m.put(TypeAlias.u_int8_t, NativeType.UCHAR); m.put(TypeAlias.int16_t, NativeType.SSHORT); m.put(TypeAlias.u_int16_t, NativeType.USHORT); m.put(TypeAlias.int32_t, NativeType.SINT); m.put(TypeAlias.u_int32_t, NativeType.UINT); m.put(TypeAlias.int64_t, NativeType.SLONGLONG); m.put(TypeAlias.u_int64_t, NativeType.ULONGLONG); m.put(TypeAlias.intptr_t, NativeType.SINT); m.put(TypeAlias.uintptr_t, NativeType.UINT); m.put(TypeAlias.caddr_t, NativeType.ADDRESS); m.put(TypeAlias.dev_t, NativeType.UINT); m.put(TypeAlias.blkcnt_t, NativeType.SLONGLONG); m.put(TypeAlias.blksize_t, NativeType.UINT); m.put(TypeAlias.gid_t, NativeType.UINT); m.put(TypeAlias.in_addr_t, NativeType.UINT); m.put(TypeAlias.in_port_t, NativeType.USHORT); m.put(TypeAlias.ino_t, NativeType.UINT); m.put(TypeAlias.ino64_t, NativeType.ULONGLONG); m.put(TypeAlias.key_t, NativeType.SLONG); m.put(TypeAlias.mode_t, NativeType.USHORT); m.put(TypeAlias.nlink_t, NativeType.USHORT); m.put(TypeAlias.id_t, NativeType.SLONGLONG); m.put(TypeAlias.pid_t, NativeType.SINT); m.put(TypeAlias.off_t, NativeType.SLONGLONG); m.put(TypeAlias.swblk_t, NativeType.SLONG); m.put(TypeAlias.uid_t, NativeType.UINT); m.put(TypeAlias.clock_t, NativeType.ULONG); m.put(TypeAlias.size_t, NativeType.UINT); m.put(TypeAlias.ssize_t, NativeType.SINT); m.put(TypeAlias.time_t, NativeType.SINT); m.put(TypeAlias.fsblkcnt_t, NativeType.ULONGLONG); m.put(TypeAlias.fsfilcnt_t, NativeType.ULONGLONG); m.put(TypeAlias.sa_family_t, NativeType.UCHAR); m.put(TypeAlias.socklen_t, NativeType.UINT); m.put(TypeAlias.rlim_t, NativeType.SLONGLONG); return m; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/i386/linux/000077500000000000000000000000001316720554100266265ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/i386/linux/TypeAliases.java000066400000000000000000000057331316720554100317240ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi.platform.i386.linux; import jnr.ffi.NativeType; import jnr.ffi.TypeAlias; import java.util.EnumMap; import java.util.Map; public final class TypeAliases { public static final Map ALIASES = buildTypeMap(); private static Map buildTypeMap() { Map m = new EnumMap(TypeAlias.class); m.put(TypeAlias.int8_t, NativeType.SCHAR); m.put(TypeAlias.u_int8_t, NativeType.UCHAR); m.put(TypeAlias.int16_t, NativeType.SSHORT); m.put(TypeAlias.u_int16_t, NativeType.USHORT); m.put(TypeAlias.int32_t, NativeType.SINT); m.put(TypeAlias.u_int32_t, NativeType.UINT); m.put(TypeAlias.int64_t, NativeType.SLONGLONG); m.put(TypeAlias.u_int64_t, NativeType.ULONGLONG); m.put(TypeAlias.intptr_t, NativeType.SINT); m.put(TypeAlias.uintptr_t, NativeType.ULONG); m.put(TypeAlias.caddr_t, NativeType.ADDRESS); m.put(TypeAlias.dev_t, NativeType.ULONGLONG); m.put(TypeAlias.blkcnt_t, NativeType.SLONGLONG); m.put(TypeAlias.blksize_t, NativeType.SLONG); m.put(TypeAlias.gid_t, NativeType.UINT); m.put(TypeAlias.in_addr_t, NativeType.UINT); m.put(TypeAlias.in_port_t, NativeType.USHORT); m.put(TypeAlias.ino_t, NativeType.ULONGLONG); m.put(TypeAlias.ino64_t, NativeType.ULONGLONG); m.put(TypeAlias.key_t, NativeType.SINT); m.put(TypeAlias.mode_t, NativeType.UINT); m.put(TypeAlias.nlink_t, NativeType.UINT); m.put(TypeAlias.id_t, NativeType.UINT); m.put(TypeAlias.pid_t, NativeType.SINT); m.put(TypeAlias.off_t, NativeType.SLONGLONG); m.put(TypeAlias.swblk_t, NativeType.SLONG); m.put(TypeAlias.uid_t, NativeType.UINT); m.put(TypeAlias.clock_t, NativeType.SLONG); m.put(TypeAlias.size_t, NativeType.UINT); m.put(TypeAlias.ssize_t, NativeType.SINT); m.put(TypeAlias.time_t, NativeType.SLONG); m.put(TypeAlias.fsblkcnt_t, NativeType.ULONGLONG); m.put(TypeAlias.fsfilcnt_t, NativeType.ULONGLONG); m.put(TypeAlias.sa_family_t, NativeType.USHORT); m.put(TypeAlias.socklen_t, NativeType.UINT); m.put(TypeAlias.rlim_t, NativeType.ULONGLONG); return m; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/i386/openbsd/000077500000000000000000000000001316720554100271215ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/i386/openbsd/TypeAliases.java000066400000000000000000000057071316720554100322200ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi.platform.i386.openbsd; import jnr.ffi.NativeType; import jnr.ffi.TypeAlias; import java.util.EnumMap; import java.util.Map; public final class TypeAliases { public static final Map ALIASES = buildTypeMap(); private static Map buildTypeMap() { Map m = new EnumMap(TypeAlias.class); m.put(TypeAlias.int8_t, NativeType.SCHAR); m.put(TypeAlias.u_int8_t, NativeType.UCHAR); m.put(TypeAlias.int16_t, NativeType.SSHORT); m.put(TypeAlias.u_int16_t, NativeType.USHORT); m.put(TypeAlias.int32_t, NativeType.SINT); m.put(TypeAlias.u_int32_t, NativeType.UINT); m.put(TypeAlias.int64_t, NativeType.SLONGLONG); m.put(TypeAlias.u_int64_t, NativeType.ULONGLONG); m.put(TypeAlias.intptr_t, NativeType.SLONG); m.put(TypeAlias.uintptr_t, NativeType.ULONG); m.put(TypeAlias.caddr_t, NativeType.ADDRESS); m.put(TypeAlias.dev_t, NativeType.SINT); m.put(TypeAlias.blkcnt_t, NativeType.SLONG); m.put(TypeAlias.blksize_t, NativeType.SLONG); m.put(TypeAlias.gid_t, NativeType.UINT); m.put(TypeAlias.in_addr_t, NativeType.UINT); m.put(TypeAlias.in_port_t, NativeType.USHORT); m.put(TypeAlias.ino_t, NativeType.UINT); m.put(TypeAlias.ino64_t, NativeType.ULONGLONG); m.put(TypeAlias.key_t, NativeType.SLONG); m.put(TypeAlias.mode_t, NativeType.UINT); m.put(TypeAlias.nlink_t, NativeType.UINT); m.put(TypeAlias.id_t, NativeType.UINT); m.put(TypeAlias.pid_t, NativeType.SINT); m.put(TypeAlias.off_t, NativeType.SLONGLONG); m.put(TypeAlias.swblk_t, NativeType.SINT); m.put(TypeAlias.uid_t, NativeType.UINT); m.put(TypeAlias.clock_t, NativeType.SINT); m.put(TypeAlias.size_t, NativeType.ULONG); m.put(TypeAlias.ssize_t, NativeType.SLONG); m.put(TypeAlias.time_t, NativeType.SINT); m.put(TypeAlias.fsblkcnt_t, NativeType.ULONG); m.put(TypeAlias.fsfilcnt_t, NativeType.ULONG); m.put(TypeAlias.sa_family_t, NativeType.UCHAR); m.put(TypeAlias.socklen_t, NativeType.UINT); m.put(TypeAlias.rlim_t, NativeType.ULONGLONG); return m; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/i386/solaris/000077500000000000000000000000001316720554100271435ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/i386/solaris/TypeAliases.java000066400000000000000000000057341316720554100322420ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi.platform.i386.solaris; import jnr.ffi.NativeType; import jnr.ffi.TypeAlias; import java.util.EnumMap; import java.util.Map; public final class TypeAliases { public static final Map ALIASES = buildTypeMap(); private static Map buildTypeMap() { Map m = new EnumMap(TypeAlias.class); m.put(TypeAlias.int8_t, NativeType.SCHAR); m.put(TypeAlias.u_int8_t, NativeType.UCHAR); m.put(TypeAlias.int16_t, NativeType.SSHORT); m.put(TypeAlias.u_int16_t, NativeType.USHORT); m.put(TypeAlias.int32_t, NativeType.SINT); m.put(TypeAlias.u_int32_t, NativeType.UINT); m.put(TypeAlias.int64_t, NativeType.SLONGLONG); m.put(TypeAlias.u_int64_t, NativeType.ULONGLONG); m.put(TypeAlias.intptr_t, NativeType.SINT); m.put(TypeAlias.uintptr_t, NativeType.UINT); m.put(TypeAlias.caddr_t, NativeType.ADDRESS); m.put(TypeAlias.dev_t, NativeType.ULONG); m.put(TypeAlias.blkcnt_t, NativeType.SLONGLONG); m.put(TypeAlias.blksize_t, NativeType.SLONG); m.put(TypeAlias.gid_t, NativeType.UINT); m.put(TypeAlias.in_addr_t, NativeType.UINT); m.put(TypeAlias.in_port_t, NativeType.USHORT); m.put(TypeAlias.ino_t, NativeType.ULONGLONG); m.put(TypeAlias.ino64_t, NativeType.ULONGLONG); m.put(TypeAlias.key_t, NativeType.SINT); m.put(TypeAlias.mode_t, NativeType.ULONG); m.put(TypeAlias.nlink_t, NativeType.ULONG); m.put(TypeAlias.id_t, NativeType.SLONG); m.put(TypeAlias.pid_t, NativeType.SLONG); m.put(TypeAlias.off_t, NativeType.SLONGLONG); m.put(TypeAlias.swblk_t, NativeType.SLONG); m.put(TypeAlias.uid_t, NativeType.UINT); m.put(TypeAlias.clock_t, NativeType.SLONG); m.put(TypeAlias.size_t, NativeType.UINT); m.put(TypeAlias.ssize_t, NativeType.SINT); m.put(TypeAlias.time_t, NativeType.SLONG); m.put(TypeAlias.fsblkcnt_t, NativeType.ULONGLONG); m.put(TypeAlias.fsfilcnt_t, NativeType.ULONGLONG); m.put(TypeAlias.sa_family_t, NativeType.USHORT); m.put(TypeAlias.socklen_t, NativeType.UINT); m.put(TypeAlias.rlim_t, NativeType.ULONGLONG); return m; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/i386/windows/000077500000000000000000000000001316720554100271615ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/i386/windows/TypeAliases.java000066400000000000000000000057331316720554100322570ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi.platform.i386.windows; import jnr.ffi.NativeType; import jnr.ffi.TypeAlias; import java.util.EnumMap; import java.util.Map; public final class TypeAliases { public static final Map ALIASES = buildTypeMap(); private static Map buildTypeMap() { Map m = new EnumMap(TypeAlias.class); m.put(TypeAlias.int8_t, NativeType.SCHAR); m.put(TypeAlias.u_int8_t, NativeType.UCHAR); m.put(TypeAlias.int16_t, NativeType.SSHORT); m.put(TypeAlias.u_int16_t, NativeType.USHORT); m.put(TypeAlias.int32_t, NativeType.SLONG); m.put(TypeAlias.u_int32_t, NativeType.UINT); m.put(TypeAlias.int64_t, NativeType.SLONGLONG); m.put(TypeAlias.u_int64_t, NativeType.ULONGLONG); m.put(TypeAlias.intptr_t, NativeType.SLONG); m.put(TypeAlias.uintptr_t, NativeType.ULONG); m.put(TypeAlias.caddr_t, NativeType.ADDRESS); m.put(TypeAlias.dev_t, NativeType.ULONG); m.put(TypeAlias.blkcnt_t, NativeType.SLONGLONG); m.put(TypeAlias.blksize_t, NativeType.SLONG); m.put(TypeAlias.gid_t, NativeType.ULONG); m.put(TypeAlias.in_addr_t, NativeType.UINT); m.put(TypeAlias.in_port_t, NativeType.USHORT); m.put(TypeAlias.ino_t, NativeType.ULONGLONG); m.put(TypeAlias.ino64_t, NativeType.ULONGLONG); m.put(TypeAlias.key_t, NativeType.SLONGLONG); m.put(TypeAlias.mode_t, NativeType.USHORT); m.put(TypeAlias.nlink_t, NativeType.USHORT); m.put(TypeAlias.id_t, NativeType.ULONG); m.put(TypeAlias.pid_t, NativeType.SINT); m.put(TypeAlias.off_t, NativeType.SLONGLONG); m.put(TypeAlias.swblk_t, NativeType.SLONG); m.put(TypeAlias.uid_t, NativeType.ULONG); m.put(TypeAlias.clock_t, NativeType.ULONG); m.put(TypeAlias.size_t, NativeType.UINT); m.put(TypeAlias.ssize_t, NativeType.SINT); m.put(TypeAlias.time_t, NativeType.SLONG); m.put(TypeAlias.fsblkcnt_t, NativeType.ULONG); m.put(TypeAlias.fsfilcnt_t, NativeType.ULONG); m.put(TypeAlias.sa_family_t, NativeType.USHORT); m.put(TypeAlias.socklen_t, NativeType.SINT); m.put(TypeAlias.rlim_t, NativeType.ULONG); return m; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/mips/000077500000000000000000000000001316720554100257465ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/mips/linux/000077500000000000000000000000001316720554100271055ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/mips/linux/TypeAliases.java000066400000000000000000000057331316720554100322030ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi.platform.mips.linux; import jnr.ffi.NativeType; import jnr.ffi.TypeAlias; import java.util.EnumMap; import java.util.Map; public final class TypeAliases { public static final Map ALIASES = buildTypeMap(); private static Map buildTypeMap() { Map m = new EnumMap(TypeAlias.class); m.put(TypeAlias.int8_t, NativeType.SCHAR); m.put(TypeAlias.u_int8_t, NativeType.UCHAR); m.put(TypeAlias.int16_t, NativeType.SSHORT); m.put(TypeAlias.u_int16_t, NativeType.USHORT); m.put(TypeAlias.int32_t, NativeType.SINT); m.put(TypeAlias.u_int32_t, NativeType.UINT); m.put(TypeAlias.int64_t, NativeType.SLONGLONG); m.put(TypeAlias.u_int64_t, NativeType.ULONGLONG); m.put(TypeAlias.intptr_t, NativeType.SINT); m.put(TypeAlias.uintptr_t, NativeType.ULONG); m.put(TypeAlias.caddr_t, NativeType.ADDRESS); m.put(TypeAlias.dev_t, NativeType.ULONGLONG); m.put(TypeAlias.blkcnt_t, NativeType.SLONGLONG); m.put(TypeAlias.blksize_t, NativeType.SLONG); m.put(TypeAlias.gid_t, NativeType.UINT); m.put(TypeAlias.in_addr_t, NativeType.UINT); m.put(TypeAlias.in_port_t, NativeType.USHORT); m.put(TypeAlias.ino_t, NativeType.ULONGLONG); m.put(TypeAlias.ino64_t, NativeType.ULONGLONG); m.put(TypeAlias.key_t, NativeType.SINT); m.put(TypeAlias.mode_t, NativeType.UINT); m.put(TypeAlias.nlink_t, NativeType.UINT); m.put(TypeAlias.id_t, NativeType.UINT); m.put(TypeAlias.pid_t, NativeType.SINT); m.put(TypeAlias.off_t, NativeType.SLONGLONG); m.put(TypeAlias.swblk_t, NativeType.SLONG); m.put(TypeAlias.uid_t, NativeType.UINT); m.put(TypeAlias.clock_t, NativeType.SLONG); m.put(TypeAlias.size_t, NativeType.UINT); m.put(TypeAlias.ssize_t, NativeType.SINT); m.put(TypeAlias.time_t, NativeType.SLONG); m.put(TypeAlias.fsblkcnt_t, NativeType.ULONGLONG); m.put(TypeAlias.fsfilcnt_t, NativeType.ULONGLONG); m.put(TypeAlias.sa_family_t, NativeType.USHORT); m.put(TypeAlias.socklen_t, NativeType.UINT); m.put(TypeAlias.rlim_t, NativeType.ULONGLONG); return m; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/mipsel/000077500000000000000000000000001316720554100262675ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/mipsel/linux/000077500000000000000000000000001316720554100274265ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/mipsel/linux/TypeAliases.java000066400000000000000000000057351316720554100325260ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi.platform.mipsel.linux; import jnr.ffi.NativeType; import jnr.ffi.TypeAlias; import java.util.EnumMap; import java.util.Map; public final class TypeAliases { public static final Map ALIASES = buildTypeMap(); private static Map buildTypeMap() { Map m = new EnumMap(TypeAlias.class); m.put(TypeAlias.int8_t, NativeType.SCHAR); m.put(TypeAlias.u_int8_t, NativeType.UCHAR); m.put(TypeAlias.int16_t, NativeType.SSHORT); m.put(TypeAlias.u_int16_t, NativeType.USHORT); m.put(TypeAlias.int32_t, NativeType.SINT); m.put(TypeAlias.u_int32_t, NativeType.UINT); m.put(TypeAlias.int64_t, NativeType.SLONGLONG); m.put(TypeAlias.u_int64_t, NativeType.ULONGLONG); m.put(TypeAlias.intptr_t, NativeType.SINT); m.put(TypeAlias.uintptr_t, NativeType.ULONG); m.put(TypeAlias.caddr_t, NativeType.ADDRESS); m.put(TypeAlias.dev_t, NativeType.ULONGLONG); m.put(TypeAlias.blkcnt_t, NativeType.SLONGLONG); m.put(TypeAlias.blksize_t, NativeType.SLONG); m.put(TypeAlias.gid_t, NativeType.UINT); m.put(TypeAlias.in_addr_t, NativeType.UINT); m.put(TypeAlias.in_port_t, NativeType.USHORT); m.put(TypeAlias.ino_t, NativeType.ULONGLONG); m.put(TypeAlias.ino64_t, NativeType.ULONGLONG); m.put(TypeAlias.key_t, NativeType.SINT); m.put(TypeAlias.mode_t, NativeType.UINT); m.put(TypeAlias.nlink_t, NativeType.UINT); m.put(TypeAlias.id_t, NativeType.UINT); m.put(TypeAlias.pid_t, NativeType.SINT); m.put(TypeAlias.off_t, NativeType.SLONGLONG); m.put(TypeAlias.swblk_t, NativeType.SLONG); m.put(TypeAlias.uid_t, NativeType.UINT); m.put(TypeAlias.clock_t, NativeType.SLONG); m.put(TypeAlias.size_t, NativeType.UINT); m.put(TypeAlias.ssize_t, NativeType.SINT); m.put(TypeAlias.time_t, NativeType.SLONG); m.put(TypeAlias.fsblkcnt_t, NativeType.ULONGLONG); m.put(TypeAlias.fsfilcnt_t, NativeType.ULONGLONG); m.put(TypeAlias.sa_family_t, NativeType.USHORT); m.put(TypeAlias.socklen_t, NativeType.UINT); m.put(TypeAlias.rlim_t, NativeType.ULONGLONG); return m; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/ppc/000077500000000000000000000000001316720554100255605ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/ppc/aix/000077500000000000000000000000001316720554100263415ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/ppc/aix/TypeAliases.java000066400000000000000000000056721316720554100314410ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi.platform.ppc.aix; import jnr.ffi.NativeType; import jnr.ffi.TypeAlias; import java.util.EnumMap; import java.util.Map; public final class TypeAliases { public static final Map ALIASES = buildTypeMap(); private static Map buildTypeMap() { Map m = new EnumMap(TypeAlias.class); m.put(TypeAlias.int8_t, NativeType.SCHAR); m.put(TypeAlias.u_int8_t, NativeType.UCHAR); m.put(TypeAlias.int16_t, NativeType.SSHORT); m.put(TypeAlias.u_int16_t, NativeType.USHORT); m.put(TypeAlias.int32_t, NativeType.SINT); m.put(TypeAlias.u_int32_t, NativeType.UINT); m.put(TypeAlias.int64_t, NativeType.SLONGLONG); m.put(TypeAlias.u_int64_t, NativeType.ULONGLONG); m.put(TypeAlias.intptr_t, NativeType.SLONG); m.put(TypeAlias.uintptr_t, NativeType.ULONG); m.put(TypeAlias.caddr_t, NativeType.ADDRESS); m.put(TypeAlias.dev_t, NativeType.UINT); m.put(TypeAlias.blkcnt_t, NativeType.SINT); m.put(TypeAlias.blksize_t, NativeType.SINT); m.put(TypeAlias.gid_t, NativeType.UINT); m.put(TypeAlias.in_addr_t, NativeType.UINT); m.put(TypeAlias.in_port_t, NativeType.USHORT); m.put(TypeAlias.ino_t, NativeType.UINT); m.put(TypeAlias.ino64_t, NativeType.ULONGLONG); m.put(TypeAlias.key_t, NativeType.SINT); m.put(TypeAlias.mode_t, NativeType.UINT); m.put(TypeAlias.nlink_t, NativeType.SSHORT); m.put(TypeAlias.id_t, NativeType.UINT); m.put(TypeAlias.pid_t, NativeType.SINT); m.put(TypeAlias.off_t, NativeType.SLONG); m.put(TypeAlias.swblk_t, NativeType.SINT); m.put(TypeAlias.uid_t, NativeType.UINT); m.put(TypeAlias.clock_t, NativeType.SINT); m.put(TypeAlias.size_t, NativeType.ULONG); m.put(TypeAlias.ssize_t, NativeType.SLONG); m.put(TypeAlias.time_t, NativeType.SINT); m.put(TypeAlias.fsblkcnt_t, NativeType.ULONG); m.put(TypeAlias.fsfilcnt_t, NativeType.ULONG); m.put(TypeAlias.sa_family_t, NativeType.UCHAR); m.put(TypeAlias.socklen_t, NativeType.ULONG); m.put(TypeAlias.rlim_t, NativeType.ULONG); return m; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/ppc/darwin/000077500000000000000000000000001316720554100270445ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/ppc/darwin/TypeAliases.java000066400000000000000000000057201316720554100321360ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi.platform.ppc.darwin; import jnr.ffi.NativeType; import jnr.ffi.TypeAlias; import java.util.EnumMap; import java.util.Map; public final class TypeAliases { public static final Map ALIASES = buildTypeMap(); private static Map buildTypeMap() { Map m = new EnumMap(TypeAlias.class); m.put(TypeAlias.int8_t, NativeType.SCHAR); m.put(TypeAlias.u_int8_t, NativeType.UCHAR); m.put(TypeAlias.int16_t, NativeType.SSHORT); m.put(TypeAlias.u_int16_t, NativeType.USHORT); m.put(TypeAlias.int32_t, NativeType.SINT); m.put(TypeAlias.u_int32_t, NativeType.UINT); m.put(TypeAlias.int64_t, NativeType.SLONGLONG); m.put(TypeAlias.u_int64_t, NativeType.ULONGLONG); m.put(TypeAlias.intptr_t, NativeType.SLONG); m.put(TypeAlias.uintptr_t, NativeType.ULONG); m.put(TypeAlias.caddr_t, NativeType.ADDRESS); m.put(TypeAlias.dev_t, NativeType.SINT); m.put(TypeAlias.blkcnt_t, NativeType.SLONGLONG); m.put(TypeAlias.blksize_t, NativeType.SINT); m.put(TypeAlias.gid_t, NativeType.UINT); m.put(TypeAlias.in_addr_t, NativeType.UINT); m.put(TypeAlias.in_port_t, NativeType.USHORT); m.put(TypeAlias.ino_t, NativeType.ULONGLONG); m.put(TypeAlias.ino64_t, NativeType.ULONGLONG); m.put(TypeAlias.key_t, NativeType.SINT); m.put(TypeAlias.mode_t, NativeType.USHORT); m.put(TypeAlias.nlink_t, NativeType.USHORT); m.put(TypeAlias.id_t, NativeType.UINT); m.put(TypeAlias.pid_t, NativeType.SINT); m.put(TypeAlias.off_t, NativeType.SLONGLONG); m.put(TypeAlias.swblk_t, NativeType.SINT); m.put(TypeAlias.uid_t, NativeType.UINT); m.put(TypeAlias.clock_t, NativeType.ULONG); m.put(TypeAlias.size_t, NativeType.ULONG); m.put(TypeAlias.ssize_t, NativeType.SLONG); m.put(TypeAlias.time_t, NativeType.SLONG); m.put(TypeAlias.fsblkcnt_t, NativeType.UINT); m.put(TypeAlias.fsfilcnt_t, NativeType.UINT); m.put(TypeAlias.sa_family_t, NativeType.UCHAR); m.put(TypeAlias.socklen_t, NativeType.UINT); m.put(TypeAlias.rlim_t, NativeType.ULONGLONG); return m; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/ppc/linux/000077500000000000000000000000001316720554100267175ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/ppc/linux/TypeAliases.java000066400000000000000000000057321316720554100320140ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi.platform.ppc.linux; import jnr.ffi.NativeType; import jnr.ffi.TypeAlias; import java.util.EnumMap; import java.util.Map; public final class TypeAliases { public static final Map ALIASES = buildTypeMap(); private static Map buildTypeMap() { Map m = new EnumMap(TypeAlias.class); m.put(TypeAlias.int8_t, NativeType.SCHAR); m.put(TypeAlias.u_int8_t, NativeType.UCHAR); m.put(TypeAlias.int16_t, NativeType.SSHORT); m.put(TypeAlias.u_int16_t, NativeType.USHORT); m.put(TypeAlias.int32_t, NativeType.SINT); m.put(TypeAlias.u_int32_t, NativeType.UINT); m.put(TypeAlias.int64_t, NativeType.SLONGLONG); m.put(TypeAlias.u_int64_t, NativeType.ULONGLONG); m.put(TypeAlias.intptr_t, NativeType.SINT); m.put(TypeAlias.uintptr_t, NativeType.ULONG); m.put(TypeAlias.caddr_t, NativeType.ADDRESS); m.put(TypeAlias.dev_t, NativeType.ULONGLONG); m.put(TypeAlias.blkcnt_t, NativeType.SLONGLONG); m.put(TypeAlias.blksize_t, NativeType.SLONG); m.put(TypeAlias.gid_t, NativeType.UINT); m.put(TypeAlias.in_addr_t, NativeType.UINT); m.put(TypeAlias.in_port_t, NativeType.USHORT); m.put(TypeAlias.ino_t, NativeType.ULONGLONG); m.put(TypeAlias.ino64_t, NativeType.ULONGLONG); m.put(TypeAlias.key_t, NativeType.SINT); m.put(TypeAlias.mode_t, NativeType.UINT); m.put(TypeAlias.nlink_t, NativeType.UINT); m.put(TypeAlias.id_t, NativeType.UINT); m.put(TypeAlias.pid_t, NativeType.SINT); m.put(TypeAlias.off_t, NativeType.SLONGLONG); m.put(TypeAlias.swblk_t, NativeType.SLONG); m.put(TypeAlias.uid_t, NativeType.UINT); m.put(TypeAlias.clock_t, NativeType.SLONG); m.put(TypeAlias.size_t, NativeType.UINT); m.put(TypeAlias.ssize_t, NativeType.SINT); m.put(TypeAlias.time_t, NativeType.SLONG); m.put(TypeAlias.fsblkcnt_t, NativeType.ULONGLONG); m.put(TypeAlias.fsfilcnt_t, NativeType.ULONGLONG); m.put(TypeAlias.sa_family_t, NativeType.USHORT); m.put(TypeAlias.socklen_t, NativeType.UINT); m.put(TypeAlias.rlim_t, NativeType.ULONGLONG); return m; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/ppc64/000077500000000000000000000000001316720554100257325ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/ppc64/linux/000077500000000000000000000000001316720554100270715ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/ppc64/linux/TypeAliases.java000066400000000000000000000056741316720554100321730ustar00rootroot00000000000000/* * Copyright (C) 2014 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi.platform.ppc64.linux; import jnr.ffi.NativeType; import jnr.ffi.TypeAlias; import java.util.EnumMap; import java.util.Map; public final class TypeAliases { public static final Map ALIASES = buildTypeMap(); private static Map buildTypeMap() { Map m = new EnumMap(TypeAlias.class); m.put(TypeAlias.int8_t, NativeType.SCHAR); m.put(TypeAlias.u_int8_t, NativeType.UCHAR); m.put(TypeAlias.int16_t, NativeType.SSHORT); m.put(TypeAlias.u_int16_t, NativeType.USHORT); m.put(TypeAlias.int32_t, NativeType.SINT); m.put(TypeAlias.u_int32_t, NativeType.UINT); m.put(TypeAlias.int64_t, NativeType.ADDRESS); m.put(TypeAlias.u_int64_t, NativeType.ADDRESS); m.put(TypeAlias.intptr_t, NativeType.SLONG); m.put(TypeAlias.uintptr_t, NativeType.ULONG); m.put(TypeAlias.caddr_t, NativeType.ADDRESS); m.put(TypeAlias.dev_t, NativeType.ULONG); m.put(TypeAlias.blkcnt_t, NativeType.SLONG); m.put(TypeAlias.blksize_t, NativeType.SLONG); m.put(TypeAlias.gid_t, NativeType.UINT); m.put(TypeAlias.in_addr_t, NativeType.UINT); m.put(TypeAlias.in_port_t, NativeType.USHORT); m.put(TypeAlias.ino_t, NativeType.ULONG); m.put(TypeAlias.ino64_t, NativeType.ULONG); m.put(TypeAlias.key_t, NativeType.SINT); m.put(TypeAlias.mode_t, NativeType.UINT); m.put(TypeAlias.nlink_t, NativeType.ULONG); m.put(TypeAlias.id_t, NativeType.UINT); m.put(TypeAlias.pid_t, NativeType.SINT); m.put(TypeAlias.off_t, NativeType.SLONG); m.put(TypeAlias.swblk_t, NativeType.SLONG); m.put(TypeAlias.uid_t, NativeType.UINT); m.put(TypeAlias.clock_t, NativeType.SLONG); m.put(TypeAlias.size_t, NativeType.ULONG); m.put(TypeAlias.ssize_t, NativeType.SLONG); m.put(TypeAlias.time_t, NativeType.SLONG); m.put(TypeAlias.fsblkcnt_t, NativeType.ULONG); m.put(TypeAlias.fsfilcnt_t, NativeType.ULONG); m.put(TypeAlias.sa_family_t, NativeType.USHORT); m.put(TypeAlias.socklen_t, NativeType.UINT); m.put(TypeAlias.rlim_t, NativeType.ULONG); return m; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/ppc64le/000077500000000000000000000000001316720554100262535ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/ppc64le/linux/000077500000000000000000000000001316720554100274125ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/ppc64le/linux/TypeAliases.java000066400000000000000000000056761316720554100325160ustar00rootroot00000000000000/* * Copyright (C) 2014 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi.platform.ppc64le.linux; import jnr.ffi.NativeType; import jnr.ffi.TypeAlias; import java.util.EnumMap; import java.util.Map; public final class TypeAliases { public static final Map ALIASES = buildTypeMap(); private static Map buildTypeMap() { Map m = new EnumMap(TypeAlias.class); m.put(TypeAlias.int8_t, NativeType.SCHAR); m.put(TypeAlias.u_int8_t, NativeType.UCHAR); m.put(TypeAlias.int16_t, NativeType.SSHORT); m.put(TypeAlias.u_int16_t, NativeType.USHORT); m.put(TypeAlias.int32_t, NativeType.SINT); m.put(TypeAlias.u_int32_t, NativeType.UINT); m.put(TypeAlias.int64_t, NativeType.ADDRESS); m.put(TypeAlias.u_int64_t, NativeType.ADDRESS); m.put(TypeAlias.intptr_t, NativeType.SLONG); m.put(TypeAlias.uintptr_t, NativeType.ULONG); m.put(TypeAlias.caddr_t, NativeType.ADDRESS); m.put(TypeAlias.dev_t, NativeType.ULONG); m.put(TypeAlias.blkcnt_t, NativeType.SLONG); m.put(TypeAlias.blksize_t, NativeType.SLONG); m.put(TypeAlias.gid_t, NativeType.UINT); m.put(TypeAlias.in_addr_t, NativeType.UINT); m.put(TypeAlias.in_port_t, NativeType.USHORT); m.put(TypeAlias.ino_t, NativeType.ULONG); m.put(TypeAlias.ino64_t, NativeType.ULONG); m.put(TypeAlias.key_t, NativeType.SINT); m.put(TypeAlias.mode_t, NativeType.UINT); m.put(TypeAlias.nlink_t, NativeType.ULONG); m.put(TypeAlias.id_t, NativeType.UINT); m.put(TypeAlias.pid_t, NativeType.SINT); m.put(TypeAlias.off_t, NativeType.SLONG); m.put(TypeAlias.swblk_t, NativeType.SLONG); m.put(TypeAlias.uid_t, NativeType.UINT); m.put(TypeAlias.clock_t, NativeType.SLONG); m.put(TypeAlias.size_t, NativeType.ULONG); m.put(TypeAlias.ssize_t, NativeType.SLONG); m.put(TypeAlias.time_t, NativeType.SLONG); m.put(TypeAlias.fsblkcnt_t, NativeType.ULONG); m.put(TypeAlias.fsfilcnt_t, NativeType.ULONG); m.put(TypeAlias.sa_family_t, NativeType.USHORT); m.put(TypeAlias.socklen_t, NativeType.UINT); m.put(TypeAlias.rlim_t, NativeType.ULONG); return m; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/s390/000077500000000000000000000000001316720554100254745ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/s390/linux/000077500000000000000000000000001316720554100266335ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/s390/linux/TypeAliases.java000066400000000000000000000057351316720554100317330ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi.platform.s390.linux; import jnr.ffi.NativeType; import jnr.ffi.TypeAlias; import java.util.EnumMap; import java.util.Map; public final class TypeAliases { public static final Map ALIASES = buildTypeMap(); private static Map buildTypeMap() { Map m = new EnumMap(TypeAlias.class); m.put(TypeAlias.int8_t, NativeType.SCHAR); m.put(TypeAlias.u_int8_t, NativeType.UCHAR); m.put(TypeAlias.int16_t, NativeType.SSHORT); m.put(TypeAlias.u_int16_t, NativeType.USHORT); m.put(TypeAlias.int32_t, NativeType.SINT); m.put(TypeAlias.u_int32_t, NativeType.UINT); m.put(TypeAlias.int64_t, NativeType.SLONGLONG); m.put(TypeAlias.u_int64_t, NativeType.ULONGLONG); m.put(TypeAlias.intptr_t, NativeType.SINT); m.put(TypeAlias.uintptr_t, NativeType.ULONG); m.put(TypeAlias.caddr_t, NativeType.ADDRESS); m.put(TypeAlias.dev_t, NativeType.ULONGLONG); m.put(TypeAlias.blkcnt_t, NativeType.SLONGLONG); m.put(TypeAlias.blksize_t, NativeType.SLONG); m.put(TypeAlias.gid_t, NativeType.UINT); m.put(TypeAlias.in_addr_t, NativeType.UINT); m.put(TypeAlias.in_port_t, NativeType.USHORT); m.put(TypeAlias.ino_t, NativeType.ULONGLONG); m.put(TypeAlias.ino64_t, NativeType.ULONGLONG); m.put(TypeAlias.key_t, NativeType.SINT); m.put(TypeAlias.mode_t, NativeType.UINT); m.put(TypeAlias.nlink_t, NativeType.UINT); m.put(TypeAlias.id_t, NativeType.UINT); m.put(TypeAlias.pid_t, NativeType.SINT); m.put(TypeAlias.off_t, NativeType.SLONGLONG); m.put(TypeAlias.swblk_t, NativeType.SLONG); m.put(TypeAlias.uid_t, NativeType.UINT); m.put(TypeAlias.clock_t, NativeType.SLONG); m.put(TypeAlias.size_t, NativeType.ULONG); m.put(TypeAlias.ssize_t, NativeType.SLONG); m.put(TypeAlias.time_t, NativeType.SLONG); m.put(TypeAlias.fsblkcnt_t, NativeType.ULONGLONG); m.put(TypeAlias.fsfilcnt_t, NativeType.ULONGLONG); m.put(TypeAlias.sa_family_t, NativeType.USHORT); m.put(TypeAlias.socklen_t, NativeType.UINT); m.put(TypeAlias.rlim_t, NativeType.ULONGLONG); return m; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/s390x/000077500000000000000000000000001316720554100256645ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/s390x/linux/000077500000000000000000000000001316720554100270235ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/s390x/linux/TypeAliases.java000066400000000000000000000057001316720554100321130ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi.platform.s390x.linux; import jnr.ffi.NativeType; import jnr.ffi.TypeAlias; import java.util.EnumMap; import java.util.Map; public final class TypeAliases { public static final Map ALIASES = buildTypeMap(); private static Map buildTypeMap() { Map m = new EnumMap(TypeAlias.class); m.put(TypeAlias.int8_t, NativeType.SCHAR); m.put(TypeAlias.u_int8_t, NativeType.UCHAR); m.put(TypeAlias.int16_t, NativeType.SSHORT); m.put(TypeAlias.u_int16_t, NativeType.USHORT); m.put(TypeAlias.int32_t, NativeType.SINT); m.put(TypeAlias.u_int32_t, NativeType.UINT); m.put(TypeAlias.int64_t, NativeType.SLONGLONG); m.put(TypeAlias.u_int64_t, NativeType.ULONGLONG); m.put(TypeAlias.intptr_t, NativeType.SLONG); m.put(TypeAlias.uintptr_t, NativeType.ULONG); m.put(TypeAlias.caddr_t, NativeType.ADDRESS); m.put(TypeAlias.dev_t, NativeType.ULONG); m.put(TypeAlias.blkcnt_t, NativeType.SLONG); m.put(TypeAlias.blksize_t, NativeType.SLONG); m.put(TypeAlias.gid_t, NativeType.UINT); m.put(TypeAlias.in_addr_t, NativeType.UINT); m.put(TypeAlias.in_port_t, NativeType.USHORT); m.put(TypeAlias.ino_t, NativeType.ULONG); m.put(TypeAlias.ino64_t, NativeType.ULONG); m.put(TypeAlias.key_t, NativeType.SINT); m.put(TypeAlias.mode_t, NativeType.UINT); m.put(TypeAlias.nlink_t, NativeType.ULONG); m.put(TypeAlias.id_t, NativeType.UINT); m.put(TypeAlias.pid_t, NativeType.SINT); m.put(TypeAlias.off_t, NativeType.SLONG); m.put(TypeAlias.swblk_t, NativeType.SLONG); m.put(TypeAlias.uid_t, NativeType.UINT); m.put(TypeAlias.clock_t, NativeType.SLONG); m.put(TypeAlias.size_t, NativeType.ULONG); m.put(TypeAlias.ssize_t, NativeType.SLONG); m.put(TypeAlias.time_t, NativeType.SLONG); m.put(TypeAlias.fsblkcnt_t, NativeType.ULONG); m.put(TypeAlias.fsfilcnt_t, NativeType.ULONG); m.put(TypeAlias.sa_family_t, NativeType.USHORT); m.put(TypeAlias.socklen_t, NativeType.UINT); m.put(TypeAlias.rlim_t, NativeType.ULONG); return m; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/sparc/000077500000000000000000000000001316720554100261065ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/sparc/solaris/000077500000000000000000000000001316720554100275625ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/sparc/solaris/TypeAliases.java000066400000000000000000000057351316720554100326620ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi.platform.sparc.solaris; import jnr.ffi.NativeType; import jnr.ffi.TypeAlias; import java.util.EnumMap; import java.util.Map; public final class TypeAliases { public static final Map ALIASES = buildTypeMap(); private static Map buildTypeMap() { Map m = new EnumMap(TypeAlias.class); m.put(TypeAlias.int8_t, NativeType.SCHAR); m.put(TypeAlias.u_int8_t, NativeType.UCHAR); m.put(TypeAlias.int16_t, NativeType.SSHORT); m.put(TypeAlias.u_int16_t, NativeType.USHORT); m.put(TypeAlias.int32_t, NativeType.SINT); m.put(TypeAlias.u_int32_t, NativeType.UINT); m.put(TypeAlias.int64_t, NativeType.SLONGLONG); m.put(TypeAlias.u_int64_t, NativeType.ULONGLONG); m.put(TypeAlias.intptr_t, NativeType.SINT); m.put(TypeAlias.uintptr_t, NativeType.UINT); m.put(TypeAlias.caddr_t, NativeType.ADDRESS); m.put(TypeAlias.dev_t, NativeType.ULONG); m.put(TypeAlias.blkcnt_t, NativeType.SLONGLONG); m.put(TypeAlias.blksize_t, NativeType.SLONG); m.put(TypeAlias.gid_t, NativeType.UINT); m.put(TypeAlias.in_addr_t, NativeType.UINT); m.put(TypeAlias.in_port_t, NativeType.USHORT); m.put(TypeAlias.ino_t, NativeType.ULONGLONG); m.put(TypeAlias.ino64_t, NativeType.ULONGLONG); m.put(TypeAlias.key_t, NativeType.SINT); m.put(TypeAlias.mode_t, NativeType.ULONG); m.put(TypeAlias.nlink_t, NativeType.ULONG); m.put(TypeAlias.id_t, NativeType.SLONG); m.put(TypeAlias.pid_t, NativeType.SLONG); m.put(TypeAlias.off_t, NativeType.SLONGLONG); m.put(TypeAlias.swblk_t, NativeType.SLONG); m.put(TypeAlias.uid_t, NativeType.UINT); m.put(TypeAlias.clock_t, NativeType.SLONG); m.put(TypeAlias.size_t, NativeType.UINT); m.put(TypeAlias.ssize_t, NativeType.SINT); m.put(TypeAlias.time_t, NativeType.SLONG); m.put(TypeAlias.fsblkcnt_t, NativeType.ULONGLONG); m.put(TypeAlias.fsfilcnt_t, NativeType.ULONGLONG); m.put(TypeAlias.sa_family_t, NativeType.USHORT); m.put(TypeAlias.socklen_t, NativeType.UINT); m.put(TypeAlias.rlim_t, NativeType.ULONGLONG); return m; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/sparcv9/000077500000000000000000000000001316720554100263655ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/sparcv9/linux/000077500000000000000000000000001316720554100275245ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/sparcv9/linux/TypeAliases.java000066400000000000000000000057001316720554100326140ustar00rootroot00000000000000/* * Copyright (C) 2017 Oracle and/or its affiliates. * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi.platform.sparcv9.linux; import jnr.ffi.NativeType; import jnr.ffi.TypeAlias; import java.util.EnumMap; import java.util.Map; public final class TypeAliases { public static final Map ALIASES = buildTypeMap(); private static Map buildTypeMap() { Map m = new EnumMap(TypeAlias.class); m.put(TypeAlias.int8_t, NativeType.SCHAR); m.put(TypeAlias.u_int8_t, NativeType.UCHAR); m.put(TypeAlias.int16_t, NativeType.SSHORT); m.put(TypeAlias.u_int16_t, NativeType.USHORT); m.put(TypeAlias.int32_t, NativeType.SINT); m.put(TypeAlias.u_int32_t, NativeType.UINT); m.put(TypeAlias.int64_t, NativeType.SLONGLONG); m.put(TypeAlias.u_int64_t, NativeType.ULONGLONG); m.put(TypeAlias.intptr_t, NativeType.SLONG); m.put(TypeAlias.uintptr_t, NativeType.ULONG); m.put(TypeAlias.caddr_t, NativeType.ADDRESS); m.put(TypeAlias.dev_t, NativeType.ULONG); m.put(TypeAlias.blkcnt_t, NativeType.SLONG); m.put(TypeAlias.blksize_t, NativeType.SLONG); m.put(TypeAlias.gid_t, NativeType.UINT); m.put(TypeAlias.in_addr_t, NativeType.UINT); m.put(TypeAlias.in_port_t, NativeType.USHORT); m.put(TypeAlias.ino_t, NativeType.ULONG); m.put(TypeAlias.ino64_t, NativeType.ULONG); m.put(TypeAlias.key_t, NativeType.SINT); m.put(TypeAlias.mode_t, NativeType.UINT); m.put(TypeAlias.nlink_t, NativeType.UINT); m.put(TypeAlias.id_t, NativeType.UINT); m.put(TypeAlias.pid_t, NativeType.SINT); m.put(TypeAlias.off_t, NativeType.SLONG); m.put(TypeAlias.swblk_t, NativeType.SLONG); m.put(TypeAlias.uid_t, NativeType.UINT); m.put(TypeAlias.clock_t, NativeType.SLONG); m.put(TypeAlias.size_t, NativeType.ULONG); m.put(TypeAlias.ssize_t, NativeType.SLONG); m.put(TypeAlias.time_t, NativeType.SLONG); m.put(TypeAlias.fsblkcnt_t, NativeType.ULONG); m.put(TypeAlias.fsfilcnt_t, NativeType.ULONG); m.put(TypeAlias.sa_family_t, NativeType.USHORT); m.put(TypeAlias.socklen_t, NativeType.UINT); m.put(TypeAlias.rlim_t, NativeType.ULONG); return m; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/sparcv9/solaris/000077500000000000000000000000001316720554100300415ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/sparcv9/solaris/TypeAliases.java000066400000000000000000000057361316720554100331420ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi.platform.sparcv9.solaris; import jnr.ffi.NativeType; import jnr.ffi.TypeAlias; import java.util.EnumMap; import java.util.Map; public final class TypeAliases { public static final Map ALIASES = buildTypeMap(); private static Map buildTypeMap() { Map m = new EnumMap(TypeAlias.class); m.put(TypeAlias.int8_t, NativeType.SCHAR); m.put(TypeAlias.u_int8_t, NativeType.UCHAR); m.put(TypeAlias.int16_t, NativeType.SSHORT); m.put(TypeAlias.u_int16_t, NativeType.USHORT); m.put(TypeAlias.int32_t, NativeType.SINT); m.put(TypeAlias.u_int32_t, NativeType.UINT); m.put(TypeAlias.int64_t, NativeType.SLONGLONG); m.put(TypeAlias.u_int64_t, NativeType.ULONGLONG); m.put(TypeAlias.intptr_t, NativeType.SINT); m.put(TypeAlias.uintptr_t, NativeType.UINT); m.put(TypeAlias.caddr_t, NativeType.ADDRESS); m.put(TypeAlias.dev_t, NativeType.ULONG); m.put(TypeAlias.blkcnt_t, NativeType.SLONGLONG); m.put(TypeAlias.blksize_t, NativeType.SLONG); m.put(TypeAlias.gid_t, NativeType.UINT); m.put(TypeAlias.in_addr_t, NativeType.UINT); m.put(TypeAlias.in_port_t, NativeType.USHORT); m.put(TypeAlias.ino_t, NativeType.ULONGLONG); m.put(TypeAlias.ino64_t, NativeType.ULONGLONG); m.put(TypeAlias.key_t, NativeType.SINT); m.put(TypeAlias.mode_t, NativeType.UINT); m.put(TypeAlias.nlink_t, NativeType.ULONG); m.put(TypeAlias.id_t, NativeType.SLONG); m.put(TypeAlias.pid_t, NativeType.SLONG); m.put(TypeAlias.off_t, NativeType.SLONGLONG); m.put(TypeAlias.swblk_t, NativeType.SLONG); m.put(TypeAlias.uid_t, NativeType.UINT); m.put(TypeAlias.clock_t, NativeType.SLONG); m.put(TypeAlias.size_t, NativeType.UINT); m.put(TypeAlias.ssize_t, NativeType.SINT); m.put(TypeAlias.time_t, NativeType.SLONG); m.put(TypeAlias.fsblkcnt_t, NativeType.ULONGLONG); m.put(TypeAlias.fsfilcnt_t, NativeType.ULONGLONG); m.put(TypeAlias.sa_family_t, NativeType.USHORT); m.put(TypeAlias.socklen_t, NativeType.UINT); m.put(TypeAlias.rlim_t, NativeType.ULONGLONG); return m; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/x86_64/000077500000000000000000000000001316720554100257345ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/x86_64/darwin/000077500000000000000000000000001316720554100272205ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/x86_64/darwin/TypeAliases.java000066400000000000000000000057231316720554100323150ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi.platform.x86_64.darwin; import jnr.ffi.NativeType; import jnr.ffi.TypeAlias; import java.util.EnumMap; import java.util.Map; public final class TypeAliases { public static final Map ALIASES = buildTypeMap(); private static Map buildTypeMap() { Map m = new EnumMap(TypeAlias.class); m.put(TypeAlias.int8_t, NativeType.SCHAR); m.put(TypeAlias.u_int8_t, NativeType.UCHAR); m.put(TypeAlias.int16_t, NativeType.SSHORT); m.put(TypeAlias.u_int16_t, NativeType.USHORT); m.put(TypeAlias.int32_t, NativeType.SINT); m.put(TypeAlias.u_int32_t, NativeType.UINT); m.put(TypeAlias.int64_t, NativeType.SLONGLONG); m.put(TypeAlias.u_int64_t, NativeType.ULONGLONG); m.put(TypeAlias.intptr_t, NativeType.SLONG); m.put(TypeAlias.uintptr_t, NativeType.ULONG); m.put(TypeAlias.caddr_t, NativeType.ADDRESS); m.put(TypeAlias.dev_t, NativeType.SINT); m.put(TypeAlias.blkcnt_t, NativeType.SLONGLONG); m.put(TypeAlias.blksize_t, NativeType.SINT); m.put(TypeAlias.gid_t, NativeType.UINT); m.put(TypeAlias.in_addr_t, NativeType.UINT); m.put(TypeAlias.in_port_t, NativeType.USHORT); m.put(TypeAlias.ino_t, NativeType.ULONGLONG); m.put(TypeAlias.ino64_t, NativeType.ULONGLONG); m.put(TypeAlias.key_t, NativeType.SINT); m.put(TypeAlias.mode_t, NativeType.USHORT); m.put(TypeAlias.nlink_t, NativeType.USHORT); m.put(TypeAlias.id_t, NativeType.UINT); m.put(TypeAlias.pid_t, NativeType.SINT); m.put(TypeAlias.off_t, NativeType.SLONGLONG); m.put(TypeAlias.swblk_t, NativeType.SINT); m.put(TypeAlias.uid_t, NativeType.UINT); m.put(TypeAlias.clock_t, NativeType.ULONG); m.put(TypeAlias.size_t, NativeType.ULONG); m.put(TypeAlias.ssize_t, NativeType.SLONG); m.put(TypeAlias.time_t, NativeType.SLONG); m.put(TypeAlias.fsblkcnt_t, NativeType.UINT); m.put(TypeAlias.fsfilcnt_t, NativeType.UINT); m.put(TypeAlias.sa_family_t, NativeType.UCHAR); m.put(TypeAlias.socklen_t, NativeType.UINT); m.put(TypeAlias.rlim_t, NativeType.ULONGLONG); return m; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/x86_64/freebsd/000077500000000000000000000000001316720554100273465ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/x86_64/freebsd/TypeAliases.java000066400000000000000000000057071316720554100324450ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi.platform.x86_64.freebsd; import jnr.ffi.TypeAlias; import jnr.ffi.NativeType; import java.util.EnumMap; import java.util.Map; public final class TypeAliases { public static final Map ALIASES = buildTypeMap(); private static Map buildTypeMap() { Map m = new EnumMap(TypeAlias.class); m.put(TypeAlias.int8_t, NativeType.SCHAR); m.put(TypeAlias.u_int8_t, NativeType.UCHAR); m.put(TypeAlias.int16_t, NativeType.SSHORT); m.put(TypeAlias.u_int16_t, NativeType.USHORT); m.put(TypeAlias.int32_t, NativeType.SINT); m.put(TypeAlias.u_int32_t, NativeType.UINT); m.put(TypeAlias.int64_t, NativeType.SLONGLONG); m.put(TypeAlias.u_int64_t, NativeType.ULONGLONG); m.put(TypeAlias.intptr_t, NativeType.SLONG); m.put(TypeAlias.uintptr_t, NativeType.ULONG); m.put(TypeAlias.caddr_t, NativeType.ADDRESS); m.put(TypeAlias.dev_t, NativeType.SINT); m.put(TypeAlias.blkcnt_t, NativeType.SLONG); m.put(TypeAlias.blksize_t, NativeType.SLONG); m.put(TypeAlias.gid_t, NativeType.UINT); m.put(TypeAlias.in_addr_t, NativeType.UINT); m.put(TypeAlias.in_port_t, NativeType.USHORT); m.put(TypeAlias.ino_t, NativeType.UINT); m.put(TypeAlias.ino64_t, NativeType.ULONGLONG); m.put(TypeAlias.key_t, NativeType.SLONG); m.put(TypeAlias.mode_t, NativeType.UINT); m.put(TypeAlias.nlink_t, NativeType.UINT); m.put(TypeAlias.id_t, NativeType.UINT); m.put(TypeAlias.pid_t, NativeType.SINT); m.put(TypeAlias.off_t, NativeType.SLONGLONG); m.put(TypeAlias.swblk_t, NativeType.SINT); m.put(TypeAlias.uid_t, NativeType.UINT); m.put(TypeAlias.clock_t, NativeType.SINT); m.put(TypeAlias.size_t, NativeType.ULONG); m.put(TypeAlias.ssize_t, NativeType.SLONG); m.put(TypeAlias.time_t, NativeType.SINT); m.put(TypeAlias.fsblkcnt_t, NativeType.ULONG); m.put(TypeAlias.fsfilcnt_t, NativeType.ULONG); m.put(TypeAlias.sa_family_t, NativeType.UCHAR); m.put(TypeAlias.socklen_t, NativeType.UINT); m.put(TypeAlias.rlim_t, NativeType.ULONGLONG); return m; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/x86_64/linux/000077500000000000000000000000001316720554100270735ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/x86_64/linux/TypeAliases.java000066400000000000000000000057011316720554100321640ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi.platform.x86_64.linux; import jnr.ffi.NativeType; import jnr.ffi.TypeAlias; import java.util.EnumMap; import java.util.Map; public final class TypeAliases { public static final Map ALIASES = buildTypeMap(); private static Map buildTypeMap() { Map m = new EnumMap(TypeAlias.class); m.put(TypeAlias.int8_t, NativeType.SCHAR); m.put(TypeAlias.u_int8_t, NativeType.UCHAR); m.put(TypeAlias.int16_t, NativeType.SSHORT); m.put(TypeAlias.u_int16_t, NativeType.USHORT); m.put(TypeAlias.int32_t, NativeType.SINT); m.put(TypeAlias.u_int32_t, NativeType.UINT); m.put(TypeAlias.int64_t, NativeType.SLONGLONG); m.put(TypeAlias.u_int64_t, NativeType.ULONGLONG); m.put(TypeAlias.intptr_t, NativeType.SLONG); m.put(TypeAlias.uintptr_t, NativeType.ULONG); m.put(TypeAlias.caddr_t, NativeType.ADDRESS); m.put(TypeAlias.dev_t, NativeType.ULONG); m.put(TypeAlias.blkcnt_t, NativeType.SLONG); m.put(TypeAlias.blksize_t, NativeType.SLONG); m.put(TypeAlias.gid_t, NativeType.UINT); m.put(TypeAlias.in_addr_t, NativeType.UINT); m.put(TypeAlias.in_port_t, NativeType.USHORT); m.put(TypeAlias.ino_t, NativeType.ULONG); m.put(TypeAlias.ino64_t, NativeType.ULONG); m.put(TypeAlias.key_t, NativeType.SINT); m.put(TypeAlias.mode_t, NativeType.UINT); m.put(TypeAlias.nlink_t, NativeType.ULONG); m.put(TypeAlias.id_t, NativeType.UINT); m.put(TypeAlias.pid_t, NativeType.SINT); m.put(TypeAlias.off_t, NativeType.SLONG); m.put(TypeAlias.swblk_t, NativeType.SLONG); m.put(TypeAlias.uid_t, NativeType.UINT); m.put(TypeAlias.clock_t, NativeType.SLONG); m.put(TypeAlias.size_t, NativeType.ULONG); m.put(TypeAlias.ssize_t, NativeType.SLONG); m.put(TypeAlias.time_t, NativeType.SLONG); m.put(TypeAlias.fsblkcnt_t, NativeType.ULONG); m.put(TypeAlias.fsfilcnt_t, NativeType.ULONG); m.put(TypeAlias.sa_family_t, NativeType.USHORT); m.put(TypeAlias.socklen_t, NativeType.UINT); m.put(TypeAlias.rlim_t, NativeType.ULONG); return m; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/x86_64/openbsd/000077500000000000000000000000001316720554100273665ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/x86_64/openbsd/TypeAliases.java000066400000000000000000000057111316720554100324600ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi.platform.x86_64.openbsd; import jnr.ffi.NativeType; import jnr.ffi.TypeAlias; import java.util.EnumMap; import java.util.Map; public final class TypeAliases { public static final Map ALIASES = buildTypeMap(); private static Map buildTypeMap() { Map m = new EnumMap(TypeAlias.class); m.put(TypeAlias.int8_t, NativeType.SCHAR); m.put(TypeAlias.u_int8_t, NativeType.UCHAR); m.put(TypeAlias.int16_t, NativeType.SSHORT); m.put(TypeAlias.u_int16_t, NativeType.USHORT); m.put(TypeAlias.int32_t, NativeType.SINT); m.put(TypeAlias.u_int32_t, NativeType.UINT); m.put(TypeAlias.int64_t, NativeType.SLONGLONG); m.put(TypeAlias.u_int64_t, NativeType.ULONGLONG); m.put(TypeAlias.intptr_t, NativeType.SLONG); m.put(TypeAlias.uintptr_t, NativeType.ULONG); m.put(TypeAlias.caddr_t, NativeType.ADDRESS); m.put(TypeAlias.dev_t, NativeType.SINT); m.put(TypeAlias.blkcnt_t, NativeType.SLONG); m.put(TypeAlias.blksize_t, NativeType.SLONG); m.put(TypeAlias.gid_t, NativeType.UINT); m.put(TypeAlias.in_addr_t, NativeType.UINT); m.put(TypeAlias.in_port_t, NativeType.USHORT); m.put(TypeAlias.ino_t, NativeType.UINT); m.put(TypeAlias.ino64_t, NativeType.ULONGLONG); m.put(TypeAlias.key_t, NativeType.SLONG); m.put(TypeAlias.mode_t, NativeType.UINT); m.put(TypeAlias.nlink_t, NativeType.UINT); m.put(TypeAlias.id_t, NativeType.UINT); m.put(TypeAlias.pid_t, NativeType.SINT); m.put(TypeAlias.off_t, NativeType.SLONGLONG); m.put(TypeAlias.swblk_t, NativeType.SINT); m.put(TypeAlias.uid_t, NativeType.UINT); m.put(TypeAlias.clock_t, NativeType.SINT); m.put(TypeAlias.size_t, NativeType.ULONG); m.put(TypeAlias.ssize_t, NativeType.SLONG); m.put(TypeAlias.time_t, NativeType.SINT); m.put(TypeAlias.fsblkcnt_t, NativeType.ULONG); m.put(TypeAlias.fsfilcnt_t, NativeType.ULONG); m.put(TypeAlias.sa_family_t, NativeType.UCHAR); m.put(TypeAlias.socklen_t, NativeType.UINT); m.put(TypeAlias.rlim_t, NativeType.ULONGLONG); return m; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/x86_64/solaris/000077500000000000000000000000001316720554100274105ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/x86_64/solaris/TypeAliases.java000066400000000000000000000056751316720554100325130ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi.platform.x86_64.solaris; import jnr.ffi.NativeType; import jnr.ffi.TypeAlias; import java.util.EnumMap; import java.util.Map; public final class TypeAliases { public static final Map ALIASES = buildTypeMap(); private static Map buildTypeMap() { Map m = new EnumMap(TypeAlias.class); m.put(TypeAlias.int8_t, NativeType.SCHAR); m.put(TypeAlias.u_int8_t, NativeType.UCHAR); m.put(TypeAlias.int16_t, NativeType.SSHORT); m.put(TypeAlias.u_int16_t, NativeType.USHORT); m.put(TypeAlias.int32_t, NativeType.SINT); m.put(TypeAlias.u_int32_t, NativeType.UINT); m.put(TypeAlias.int64_t, NativeType.SLONG); m.put(TypeAlias.u_int64_t, NativeType.ULONGLONG); m.put(TypeAlias.intptr_t, NativeType.SLONG); m.put(TypeAlias.uintptr_t, NativeType.ULONG); m.put(TypeAlias.caddr_t, NativeType.ADDRESS); m.put(TypeAlias.dev_t, NativeType.ULONG); m.put(TypeAlias.blkcnt_t, NativeType.SLONG); m.put(TypeAlias.blksize_t, NativeType.SINT); m.put(TypeAlias.gid_t, NativeType.UINT); m.put(TypeAlias.in_addr_t, NativeType.UINT); m.put(TypeAlias.in_port_t, NativeType.USHORT); m.put(TypeAlias.ino_t, NativeType.ULONG); m.put(TypeAlias.ino64_t, NativeType.ULONG); m.put(TypeAlias.key_t, NativeType.SINT); m.put(TypeAlias.mode_t, NativeType.UINT); m.put(TypeAlias.nlink_t, NativeType.UINT); m.put(TypeAlias.id_t, NativeType.SINT); m.put(TypeAlias.pid_t, NativeType.SINT); m.put(TypeAlias.off_t, NativeType.SLONG); m.put(TypeAlias.swblk_t, NativeType.SLONG); m.put(TypeAlias.uid_t, NativeType.UINT); m.put(TypeAlias.clock_t, NativeType.SLONG); m.put(TypeAlias.size_t, NativeType.ULONG); m.put(TypeAlias.ssize_t, NativeType.SLONG); m.put(TypeAlias.time_t, NativeType.SLONG); m.put(TypeAlias.fsblkcnt_t, NativeType.ULONG); m.put(TypeAlias.fsfilcnt_t, NativeType.ULONG); m.put(TypeAlias.sa_family_t, NativeType.USHORT); m.put(TypeAlias.socklen_t, NativeType.UINT); m.put(TypeAlias.rlim_t, NativeType.ULONG); return m; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/x86_64/windows/000077500000000000000000000000001316720554100274265ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/provider/jffi/platform/x86_64/windows/TypeAliases.java000066400000000000000000000057431316720554100325250ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.provider.jffi.platform.x86_64.windows; import jnr.ffi.NativeType; import jnr.ffi.TypeAlias; import java.util.EnumMap; import java.util.Map; public final class TypeAliases { public static final Map ALIASES = buildTypeMap(); private static Map buildTypeMap() { Map m = new EnumMap(TypeAlias.class); m.put(TypeAlias.int8_t, NativeType.SCHAR); m.put(TypeAlias.u_int8_t, NativeType.UCHAR); m.put(TypeAlias.int16_t, NativeType.SSHORT); m.put(TypeAlias.u_int16_t, NativeType.USHORT); m.put(TypeAlias.int32_t, NativeType.SINT); m.put(TypeAlias.u_int32_t, NativeType.UINT); m.put(TypeAlias.int64_t, NativeType.SLONGLONG); m.put(TypeAlias.u_int64_t, NativeType.ULONGLONG); m.put(TypeAlias.intptr_t, NativeType.SLONGLONG); m.put(TypeAlias.uintptr_t, NativeType.ULONGLONG); m.put(TypeAlias.caddr_t, NativeType.ADDRESS); m.put(TypeAlias.dev_t, NativeType.UINT); m.put(TypeAlias.blkcnt_t, NativeType.SLONG); m.put(TypeAlias.blksize_t, NativeType.SLONG); m.put(TypeAlias.gid_t, NativeType.SINT); m.put(TypeAlias.in_addr_t, NativeType.UINT); m.put(TypeAlias.in_port_t, NativeType.USHORT); m.put(TypeAlias.ino_t, NativeType.USHORT); m.put(TypeAlias.ino64_t, NativeType.ULONGLONG); m.put(TypeAlias.key_t, NativeType.SINT); m.put(TypeAlias.mode_t, NativeType.USHORT); m.put(TypeAlias.nlink_t, NativeType.SINT); m.put(TypeAlias.id_t, NativeType.SINT); m.put(TypeAlias.pid_t, NativeType.SLONGLONG); m.put(TypeAlias.off_t, NativeType.SLONGLONG); m.put(TypeAlias.swblk_t, NativeType.SLONG); m.put(TypeAlias.uid_t, NativeType.SINT); m.put(TypeAlias.clock_t, NativeType.SINT); m.put(TypeAlias.size_t, NativeType.ULONGLONG); m.put(TypeAlias.ssize_t, NativeType.SLONGLONG); m.put(TypeAlias.time_t, NativeType.SLONGLONG); m.put(TypeAlias.fsblkcnt_t, NativeType.ULONG); m.put(TypeAlias.fsfilcnt_t, NativeType.ULONG); m.put(TypeAlias.sa_family_t, NativeType.USHORT); m.put(TypeAlias.socklen_t, NativeType.SINT); m.put(TypeAlias.rlim_t, NativeType.SINT); return m; } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/000077500000000000000000000000001316720554100215465ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/blkcnt_t.java000066400000000000000000000020671316720554100242160ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.blkcnt_t) public @interface blkcnt_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/blksize_t.java000066400000000000000000000020711316720554100243770ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.blksize_t) public @interface blksize_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/caddr_t.java000066400000000000000000000020651316720554100240140ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.caddr_t) public @interface caddr_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/clock_t.java000066400000000000000000000020651316720554100240320ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.clock_t) public @interface clock_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/dev_t.java000066400000000000000000000020611316720554100235110ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.dev_t) public @interface dev_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/fsblkcnt_t.java000066400000000000000000000020731316720554100245440ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.fsblkcnt_t) public @interface fsblkcnt_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/fsfilcnt_t.java000066400000000000000000000020731316720554100245460ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.fsfilcnt_t) public @interface fsfilcnt_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/gid_t.java000066400000000000000000000020611316720554100234760ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.gid_t) public @interface gid_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/id_t.java000066400000000000000000000020571316720554100233340ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.id_t) public @interface id_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/in_addr_t.java000066400000000000000000000020711316720554100243340ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.in_addr_t) public @interface in_addr_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/in_port_t.java000066400000000000000000000020711316720554100244060ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.in_port_t) public @interface in_port_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/ino64_t.java000066400000000000000000000020651316720554100236760ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.ino64_t) public @interface ino64_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/ino_t.java000066400000000000000000000020611316720554100235200ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.ino_t) public @interface ino_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/int16_t.java000066400000000000000000000020651316720554100237000ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.int16_t) public @interface int16_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/int32_t.java000066400000000000000000000020651316720554100236760ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.int32_t) public @interface int32_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/int64_t.java000066400000000000000000000020651316720554100237030ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.int64_t) public @interface int64_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/int8_t.java000066400000000000000000000020631316720554100236170ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.int8_t) public @interface int8_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/intptr_t.java000066400000000000000000000020671316720554100242610ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.intptr_t) public @interface intptr_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/key_t.java000066400000000000000000000020611316720554100235230ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.key_t) public @interface key_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/mode_t.java000066400000000000000000000020631316720554100236610ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.mode_t) public @interface mode_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/nlink_t.java000066400000000000000000000020651316720554100240520ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.nlink_t) public @interface nlink_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/off_t.java000066400000000000000000000020611316720554100235050ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.off_t) public @interface off_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/pid_t.java000066400000000000000000000020611316720554100235070ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.pid_t) public @interface pid_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/rlim_t.java000066400000000000000000000020631316720554100237000ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.rlim_t) public @interface rlim_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/sa_family_t.java000066400000000000000000000020751316720554100247040ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.sa_family_t) public @interface sa_family_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/size_t.java000066400000000000000000000020631316720554100237070ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.size_t) public @interface size_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/socklen_t.java000066400000000000000000000020711316720554100243720ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.socklen_t) public @interface socklen_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/ssize_t.java000066400000000000000000000020651316720554100240740ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.ssize_t) public @interface ssize_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/swblk_t.java000066400000000000000000000020651316720554100240610ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.swblk_t) public @interface swblk_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/time_t.java000066400000000000000000000020631316720554100236730ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.time_t) public @interface time_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/u_int16_t.java000066400000000000000000000020711316720554100242210ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.u_int16_t) public @interface u_int16_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/u_int32_t.java000066400000000000000000000020711316720554100242170ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.u_int32_t) public @interface u_int32_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/u_int64_t.java000066400000000000000000000020711316720554100242240ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.u_int64_t) public @interface u_int64_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/u_int8_t.java000066400000000000000000000020671316720554100241470ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.u_int8_t) public @interface u_int8_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/uid_t.java000066400000000000000000000020611316720554100235140ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.uid_t) public @interface uid_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/types/uintptr_t.java000066400000000000000000000020711316720554100244410ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.types; import jnr.ffi.TypeAlias; import jnr.ffi.annotations.TypeDefinition; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target(value = { ElementType.PARAMETER, ElementType.METHOD }) @TypeDefinition(alias = TypeAlias.uintptr_t) public @interface uintptr_t { } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/util/000077500000000000000000000000001316720554100213575ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/util/AnnotationNameComparator.java000066400000000000000000000024241316720554100271670ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.util; import java.lang.annotation.Annotation; import java.util.Comparator; /** * Sorts annotations according to name */ final class AnnotationNameComparator implements Comparator { static final Comparator INSTANCE = new AnnotationNameComparator(); public static Comparator getInstance() { return INSTANCE; } public int compare(Annotation o1, Annotation o2) { return o1.annotationType().getName().compareTo(o2.annotationType().getName()); } public boolean equals(Object other) { return other != null && getClass().equals(other.getClass()); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/util/AnnotationProperty.java000066400000000000000000000211771316720554100261110ustar00rootroot00000000000000package jnr.ffi.util; /* * Copyright 2010 The Miyamoto Team * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import java.util.Arrays; /** * Describes an annotation property. * * @version $Id$ */ final class AnnotationProperty { /** * The property name. */ private final String name; /** * The property type. */ private final Class type; /** * The property value. This field can be mutable. */ private Object value; /** * Creates a new annotation property instance. * * @param name the property name. * @param type the property type. */ public AnnotationProperty(String name, Class type) { this.name = name; this.type = type; } /** * Returns the property name. * * @return the property name. */ public String getName() { return this.name; } /** * Returns the property type. * * @return the property type. */ public Class getType() { return this.type; } /** * Returns the property value. * * @return the property value. */ public Object getValue() { return this.value; } /** * Sets the property value. * * @param value the property value. */ public void setValue(Object value) { if (value != null && !(this.type.isAssignableFrom(value.getClass()) || (this.type == Boolean.TYPE && value.getClass() == Boolean.class) || (this.type == Byte.TYPE && value.getClass() == Byte.class) || (this.type == Character.TYPE && value.getClass() == Character.class) || (this.type == Double.TYPE && value.getClass() == Double.class) || (this.type == Float.TYPE && value.getClass() == Float.class) || (this.type == Integer.TYPE && value.getClass() == Integer.class) || (this.type == Long.TYPE && value.getClass() == Long.class) || (this.type == Short.TYPE && value.getClass() == Short.class))) { throw new IllegalArgumentException("Cannot assign value of type '" + value.getClass().getName() + "' to property '" + this.name + "' of type '" + this.type.getName() + "'"); } this.value = value; } /** * {@inheritDoc} */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + this.name.hashCode(); result = prime * result + this.type.hashCode(); result = prime * result + this.getValueHashCode(); return result; } /** * Calculates this annotation value hash code. * * @return this annotation value hash code. */ protected int getValueHashCode() { if (this.value == null) { return 0; } if (!this.type.isArray()) { return this.value.hashCode(); } if (this.type == byte[].class) { return Arrays.hashCode((byte[]) this.value); } if (this.type == char[].class) { return Arrays.hashCode((char[]) this.value); } if (this.type == double[].class) { return Arrays.hashCode((double[]) this.value); } if (this.type == float[].class) { return Arrays.hashCode((float[]) this.value); } if (this.type == int[].class) { return Arrays.hashCode((int[]) this.value); } if (this.type == long[].class) { return Arrays.hashCode((long[]) this.value); } if (this.type == short[].class) { return Arrays.hashCode((short[]) this.value); } if (this.type == boolean[].class) { return Arrays.hashCode((boolean[]) this.value); } return Arrays.hashCode((Object[]) this.value); } /** * {@inheritDoc} */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (this.getClass() != obj.getClass()) { return false; } AnnotationProperty other = (AnnotationProperty) obj; if (this.name == null) { if (other.getName() != null) { return false; } } else if (!this.name.equals(other.getName())) { return false; } if (this.type == null) { if (other.getType() != null) { return false; } } else if (!this.type.equals(other.getType())) { return false; } if (this.value == null) { if (other.getValue() != null) { return false; } } else { // Check for primitive, string, class, enum const, annotation if (!this.type.isArray()) { return this.value.equals(other.getValue()); } // Check for array of string, class, enum const, annotation if (this.value instanceof Object[] && other.getValue() instanceof Object[]) { Arrays.equals((Object[]) this.value, (Object[]) other.getValue()); } // Deal with array of primitives if (this.type == byte[].class) { return Arrays.equals((byte[]) this.value, (byte[]) other.getValue()); } if (this.type == char[].class) { return Arrays.equals((char[]) this.value, (char[]) other.getValue()); } if (this.type == double[].class) { return Arrays.equals((double[]) this.value, (double[]) other.getValue()); } if (this.type == float[].class) { return Arrays.equals((float[]) this.value, (float[]) other.getValue()); } if (this.type == int[].class) { return Arrays.equals((int[]) this.value, (int[]) other.getValue()); } if (this.type == long[].class) { return Arrays.equals((long[]) this.value, (long[]) other.getValue()); } if (this.type == short[].class) { return Arrays.equals((short[]) this.value, (short[]) other.getValue()); } if (this.type == boolean[].class) { return Arrays.equals((boolean[]) this.value, (boolean[]) other.getValue()); } } return false; } /** * {@inheritDoc} */ @Override public String toString() { return "(name=" + this.name + ", type=" + (this.type.isArray() ? (this.type.getComponentType().getName() + "[]") : this.type.getName()) + ", value=" + this.valueToString() + ")"; } /** * Calculates the {@code toString} of the property value. * * @return the {@code toString} of the property value. */ protected String valueToString() { if (!this.type.isArray()) { return String.valueOf(this.value); } Class arrayType = this.type.getComponentType(); if (arrayType == Boolean.TYPE) { return Arrays.toString((boolean[]) this.value); } else if (arrayType == Byte.TYPE) { return Arrays.toString((byte[]) this.value); } else if (arrayType == Character.TYPE) { return Arrays.toString((char[]) this.value); } else if (arrayType == Double.TYPE) { return Arrays.toString((double[]) this.value); } else if (arrayType == Float.TYPE) { return Arrays.toString((float[]) this.value); } else if (arrayType == Integer.TYPE) { return Arrays.toString((int[]) this.value); } else if (arrayType == Long.TYPE) { return Arrays.toString((long[]) this.value); } else if (arrayType == Short.TYPE) { return Arrays.toString((short[]) this.value); } return Arrays.toString((Object[]) this.value); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/util/AnnotationProxy.java000066400000000000000000000214151316720554100254010ustar00rootroot00000000000000package jnr.ffi.util; /* * Copyright 2010 The Miyamoto Team * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import java.lang.annotation.Annotation; import java.lang.reflect.AccessibleObject; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.LinkedHashMap; import java.util.Map; import java.util.Map.Entry; /** * * * @param The annotation type has to be proxed. * @version $Id$ */ public final class AnnotationProxy implements Annotation, InvocationHandler { /** * The multiplicator required in the hash code calculation. */ private static final int MEMBER_NAME_MULTIPLICATOR = 127; /** * Creates a new annotation proxy. * * @param the annotation type has to be proxed. * @param annotationType the annotation type class has to be proxed. * @return a new annotation proxy. */ public static AnnotationProxy newProxy(Class annotationType) { if (annotationType == null) { throw new IllegalArgumentException("Parameter 'annotationType' must be not null"); } return new AnnotationProxy(annotationType); } /** * Retrieves the annotation proxy, if any, given the annotation. * * @param obj the annotation. * @return the annotation proxy, if any, given the annotation. */ private static AnnotationProxy getAnnotationProxy(Object obj) { if (Proxy.isProxyClass(obj.getClass())) { InvocationHandler handler = Proxy.getInvocationHandler(obj); if (handler instanceof AnnotationProxy) { return (AnnotationProxy) handler; } } return null; } /** * Access to the declared methods of an annotation, given the type. * * @param the annotation type. * @param annotationType the annotation type class. * @return the declared methods of an annotation, given the type. */ private static Method[] getDeclaredMethods(final Class annotationType) { return AccessController.doPrivileged( new PrivilegedAction() { public Method[] run() { final Method[] declaredMethods = annotationType.getDeclaredMethods(); AccessibleObject.setAccessible(declaredMethods, true); return declaredMethods; } }); } /** * The annotation type class has to be proxed. */ private final Class annotationType; /** * The annotation properties registry. */ private final Map properties = new LinkedHashMap(); /** * The proxed annotation. */ private final A proxedAnnotation; /** * Build a new proxy annotation given the annotation type. * * @param annotationType the annotation type class has to be proxed. */ private AnnotationProxy(Class annotationType) { this.annotationType = annotationType; String propertyName; Class returnType; Object defaultValue; for (Method method : getDeclaredMethods(annotationType)) { propertyName = method.getName(); returnType = method.getReturnType(); defaultValue = method.getDefaultValue(); AnnotationProperty property = new AnnotationProperty(propertyName, returnType); property.setValue(defaultValue); this.properties.put(propertyName, property); } this.proxedAnnotation = annotationType.cast(Proxy.newProxyInstance(annotationType.getClassLoader(), new Class[]{ annotationType }, this)); } /** * Set a property value. * * @param name the property name. * @param value the property value. */ public void setProperty(String name, Object value) { if (name == null) { throw new IllegalArgumentException("Parameter 'name' must be not null"); } if (value == null) { throw new IllegalArgumentException("Parameter 'value' must be not null"); } if (!this.properties.containsKey(name)) { throw new IllegalArgumentException("Annotation '" + this.annotationType.getName() + "' does not contain a property named '" + name + "'"); } this.properties.get(name).setValue(value); } /** * Returns the property value, given the name, if present. * * @param name the property name. * @return the property value, given the name, if present. */ public Object getProperty(String name) { if (name == null) { throw new IllegalArgumentException("Parameter 'name' must be not null"); } return this.properties.get(name).getValue(); } /** * {@inheritDoc} */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String name = method.getName(); if (this.properties.containsKey(name)) { return this.properties.get(name).getValue(); } return method.invoke(this, args); } /** * {@inheritDoc} */ public Class annotationType() { return this.annotationType; } /** * Returns the proxed annotation. * * @return the proxed annotation. */ public A getProxedAnnotation() { return this.proxedAnnotation; } /** * {@inheritDoc} */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (!this.annotationType.isInstance(obj)) { return false; } String propertyName; AnnotationProperty expected; for (Method method : getDeclaredMethods(this.annotationType())) { propertyName = method.getName(); if (!this.properties.containsKey(propertyName)) { return false; } expected = this.properties.get(propertyName); AnnotationProperty actual = new AnnotationProperty(propertyName, method.getReturnType()); AnnotationProxy proxy = getAnnotationProxy(obj); if (proxy != null) { actual.setValue(proxy.getProperty(propertyName)); } else { try { actual.setValue(method.invoke(obj)); } catch (IllegalArgumentException e) { return false; } catch (IllegalAccessException e) { throw new AssertionError(e); } catch (InvocationTargetException e) { return false; } } if (!expected.equals(actual)) { return false; } } return true; } /** * {@inheritDoc} */ @Override public int hashCode() { int hashCode = 0; for (Entry property : this.properties.entrySet()) { hashCode += (MEMBER_NAME_MULTIPLICATOR * property.getKey().hashCode() ^ property.getValue().getValueHashCode()); } return hashCode; } /** * {@inheritDoc} */ @Override public String toString() { StringBuilder stringBuilder = new StringBuilder("@") .append(this.annotationType.getName()) .append('('); int counter = 0; for (Entry property : this.properties.entrySet()) { if (counter > 0) { stringBuilder.append(", "); } stringBuilder.append(property.getKey()) .append('=') .append(property.getValue().valueToString()); counter++; } return stringBuilder.append(')').toString(); } }jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/util/Annotations.java000066400000000000000000000055421316720554100245250ustar00rootroot00000000000000/* * Copyright (C) 2012 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.util; import java.lang.annotation.Annotation; import java.util.*; /** * Utilities for collections of annotations */ public final class Annotations { public static final Collection EMPTY_ANNOTATIONS = Collections.emptyList(); private Annotations() {} public static Collection sortedAnnotationCollection(Annotation[] annotations) { if (annotations.length > 1) { return sortedAnnotationCollection(Arrays.asList(annotations)); } else if (annotations.length > 0) { return Collections.singletonList(annotations[0]); } else { return Collections.emptyList(); } } public static Collection sortedAnnotationCollection(Collection annotations) { // If already sorted, or empty, or only one element, no need to sort again if (annotations.size() < 2 || (annotations instanceof SortedSet && ((SortedSet) annotations).comparator() instanceof AnnotationNameComparator)) { return annotations; } SortedSet sorted = new TreeSet(AnnotationNameComparator.getInstance()); sorted.addAll(annotations); return Collections.unmodifiableSortedSet(sorted); } public static final Collection mergeAnnotations(Collection a, Collection b) { if (a.isEmpty() && b.isEmpty()) { return EMPTY_ANNOTATIONS; } else if (!a.isEmpty() && b.isEmpty()) { return a; } else if (a.isEmpty() && !b.isEmpty()) { return b; } else { List all = new ArrayList(a); all.addAll(b); return sortedAnnotationCollection(all); } } public static final Collection mergeAnnotations(Collection... collections) { int totalLength = 0; for (Collection c : collections) { totalLength += c.size(); } List all = new ArrayList(totalLength); for (Collection c : collections) { all.addAll(c); } return sortedAnnotationCollection(all); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/util/BufferUtil.java000066400000000000000000000137111316720554100242740ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.util; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.*; /** * */ public final class BufferUtil { private BufferUtil() {} public static void putString(ByteBuffer buf, Charset charset, String value) { putCharSequence(buf, charset, value); } public static String getString(ByteBuffer buf, Charset charset) { return getCharSequence(buf, charset).toString(); } public static void putCharSequence(ByteBuffer buf, Charset charset, CharSequence value) { putCharSequence(buf, charset.newEncoder(), value); } public static void putCharSequence(ByteBuffer buf, CharsetEncoder encoder, CharSequence value) { // // Convert any CharSequence implementor (String, etc) into a native // C string. // encoder.reset().onMalformedInput(CodingErrorAction.REPLACE) .onUnmappableCharacter(CodingErrorAction.REPLACE) .encode(CharBuffer.wrap(value), buf, true); encoder.flush(buf); final int nulSize = Math.round(encoder.maxBytesPerChar()); // NUL terminate the string if (nulSize == 4) { buf.putInt(0); } else if (nulSize == 2) { buf.putShort((short) 0); } else if (nulSize == 1) { buf.put((byte) 0); } } public static CharSequence getCharSequence(ByteBuffer buf, Charset charset) { final ByteBuffer buffer = buf.slice(); // Find the NUL terminator and limit to that, so the // StringBuffer/StringBuilder does not have superfluous NUL chars int end = indexOf(buffer, (byte) 0); if (end < 0) { end = buffer.limit(); } buffer.position(0).limit(end); return charset.decode(buffer); } public static CharSequence getCharSequence(final ByteBuffer buf, final CharsetDecoder decoder) { final ByteBuffer buffer = buf.slice(); // Find the NUL terminator and limit to that, so the // StringBuffer/StringBuilder does not have superfluous NUL chars int end = indexOf(buffer, (byte) 0); if (end < 0) { end = buffer.limit(); } buffer.position(0).limit(end); try { return decoder.reset().onMalformedInput(CodingErrorAction.REPLACE) .onUnmappableCharacter(CodingErrorAction.REPLACE).decode(buffer); } catch (CharacterCodingException ex) { throw new Error("Illegal character data in native string", ex); } } /** * Finds the position of a byte relative to the start of the buffer. * * @param buf The ByteBuffer to find the value in * @param value The value to locate * @return The position within the buffer that value is found, or -1 if not * found. */ public static int positionOf(ByteBuffer buf, byte value) { if (buf.hasArray()) { final byte[] array = buf.array(); final int offset = buf.arrayOffset(); final int limit = buf.limit(); for (int pos = buf.position(); pos < limit; ++pos) { if (array[offset + pos] == value) { return pos; } } } else { final int limit = buf.limit(); for (int pos = buf.position(); pos < limit; ++pos) { if (buf.get(pos) == value) { return pos; } } } return -1; } public static int indexOf(ByteBuffer buf, byte value) { if (buf.hasArray()) { byte[] array = buf.array(); int begin = buf.arrayOffset() + buf.position(); int end = buf.arrayOffset() + buf.limit(); for (int offset = 0; offset < end && offset > -1; ++offset) { if (array[begin + offset] == value) { return offset; } } } else { int begin = buf.position(); for (int offset = 0; offset < buf.limit(); ++offset) { if (buf.get(begin + offset) == value) { return offset; } } } return -1; } public static int indexOf(ByteBuffer buf, int offset, byte value) { if (buf.hasArray()) { byte[] array = buf.array(); int begin = buf.arrayOffset() + buf.position() + offset; int end = buf.arrayOffset() + buf.limit(); for (int idx = 0; idx < end && idx > -1; ++idx) { if (array[begin + idx] == value) { return idx; } } } else { int begin = buf.position(); for (int idx = 0; idx < buf.limit(); ++idx) { if (buf.get(begin + idx) == value) { return idx; } } } return -1; } public static ByteBuffer slice(final ByteBuffer buffer, final int position) { final ByteBuffer tmp = buffer.duplicate(); tmp.position(position); return tmp.slice(); } public static ByteBuffer slice(final ByteBuffer buffer, final int position, final int size) { final ByteBuffer tmp = buffer.duplicate(); tmp.position(position).limit(position + size); return tmp.slice(); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/util/EnumMapper.java000066400000000000000000000121201316720554100242670ustar00rootroot00000000000000/* * Copyright (C) 2008-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.util; import jnr.ffi.mapper.*; import java.lang.reflect.Method; import java.util.*; /** * Provides mapping from Enum values to native integers and vice-versa */ @ToNativeConverter.NoContext @FromNativeConverter.NoContext public final class EnumMapper { private static final class StaticDataHolder { private static volatile Map, EnumMapper> MAPPERS = Collections.emptyMap(); } private final Class enumClass; private final Integer[] intValues; private final Long[] longValues; private final Map reverseLookupMap = new HashMap(); private EnumMapper(Class enumClass) { this.enumClass = enumClass; EnumSet enums = EnumSet.allOf(enumClass); this.intValues = new Integer[enums.size()]; this.longValues = new Long[enums.size()]; Method intValueMethod = getNumberValueMethod(enumClass, int.class); Method longValueMethod = getNumberValueMethod(enumClass, long.class); for (Enum e : enums) { Number value; if (longValueMethod != null) { value = reflectedNumberValue(e, longValueMethod); } else if (intValueMethod != null) { value = reflectedNumberValue(e, intValueMethod); } else { value = e.ordinal(); } intValues[e.ordinal()] = value.intValue(); longValues[e.ordinal()] = value.longValue(); reverseLookupMap.put(value, e); } } public static interface IntegerEnum { public int intValue(); } public static EnumMapper getInstance(Class enumClass) { EnumMapper mapper = StaticDataHolder.MAPPERS.get(enumClass); if (mapper != null) { return mapper; } return addMapper(enumClass); } private static synchronized EnumMapper addMapper(Class enumClass) { EnumMapper mapper = new EnumMapper(enumClass); Map, EnumMapper> tmp = new IdentityHashMap, EnumMapper>(StaticDataHolder.MAPPERS); tmp.put(enumClass, mapper); StaticDataHolder.MAPPERS = tmp; return mapper; } private static Method getNumberValueMethod(Class c, Class numberClass) { try { Method m = c.getDeclaredMethod(numberClass.getSimpleName() + "Value"); return m != null && numberClass == m.getReturnType() ? m : null; } catch (Throwable t) { return null; } } private static Number reflectedNumberValue(Enum e, Method m) { try { return (Number) m.invoke(e); } catch (Throwable ex) { throw new RuntimeException(ex); } } public final Integer integerValue(Enum value) { if (value.getClass() != enumClass) { throw new IllegalArgumentException("enum class mismatch, " + value.getClass()); } return intValues[value.ordinal()]; } public final int intValue(Enum value) { return integerValue(value); } public final Long longValue(Enum value) { if (value.getClass() != enumClass) { throw new IllegalArgumentException("enum class mismatch, " + value.getClass()); } return longValues[value.ordinal()]; } public Enum valueOf(int value) { return reverseLookup(value); } public Enum valueOf(long value) { return reverseLookup(value); } public Enum valueOf(Number value) { return reverseLookup(value); } private Enum reverseLookup(Number value) { Enum e = reverseLookupMap.get(value); return e != null ? e : badValue(value); } private Enum badValue(Number value) { // // No value found - try to find the default value for unknown values. // This is useful for enums that aren't fixed in stone and/or where you // don't want to throw an Exception for an unknown value. // try { return Enum.valueOf(enumClass, "__UNKNOWN_NATIVE_VALUE"); } catch (IllegalArgumentException ex) { // // No default, so just give up and throw an exception // throw new IllegalArgumentException("No known Enum mapping for value " + value + " of type " + enumClass.getName()); } } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/util/ref/000077500000000000000000000000001316720554100221335ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/util/ref/FinalizablePhantomReference.java000066400000000000000000000027451316720554100303740ustar00rootroot00000000000000/* * Copyright (C) 2007 The Guava Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.util.ref; import java.lang.ref.PhantomReference; /** * Phantom reference with a {@code finalizeReferent()} method which a background thread invokes * after the garbage collector reclaims the referent. This is a simpler alternative to using a * {@link java.lang.ref.ReferenceQueue}. * *

Unlike a normal phantom reference, this reference will be cleared automatically. * * @author Bob Lee * @since 2.0 (imported from Google Collections Library) */ public abstract class FinalizablePhantomReference extends PhantomReference implements FinalizableReference { /** * Constructs a new finalizable phantom reference. * * @param referent to phantom reference * @param queue that should finalize the referent */ protected FinalizablePhantomReference(T referent, FinalizableReferenceQueue queue) { super(referent, queue.queue); queue.cleanUp(); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/util/ref/FinalizableReference.java000066400000000000000000000022061316720554100270350ustar00rootroot00000000000000/* * Copyright (C) 2007 The Guava Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.util.ref; /** * Implemented by references that have code to run after garbage collection of their referents. * * @see FinalizableReferenceQueue * @author Bob Lee * @since 2.0 (imported from Google Collections Library) */ public interface FinalizableReference { /** * Invoked on a background thread after the referent has been garbage collected unless security * restrictions prevented starting a background thread, in which case this method is invoked when * new references are created. */ void finalizeReferent(); } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/util/ref/FinalizableReferenceQueue.java000066400000000000000000000256111316720554100300470ustar00rootroot00000000000000/* * Copyright (C) 2007 The Guava Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.util.ref; import java.io.FileNotFoundException; import java.io.IOException; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.WeakHashMap; import java.util.logging.Level; import java.util.logging.Logger; /** * A reference queue with an associated background thread that dequeues references and invokes * {@link FinalizableReference#finalizeReferent()} on them. * *

Keep a strong reference to this object until all of the associated referents have been * finalized. If this object is garbage collected earlier, the backing thread will not invoke {@code * finalizeReferent()} on the remaining references. * * @author Bob Lee * @since 2.0 (imported from Google Collections Library) */ public class FinalizableReferenceQueue { /* * The Finalizer thread keeps a phantom reference to this object. When the client (for example, a * map built by MapMaker) no longer has a strong reference to this object, the garbage collector * will reclaim it and enqueue the phantom reference. The enqueued reference will trigger the * Finalizer to stop. * * If this library is loaded in the system class loader, FinalizableReferenceQueue can load * Finalizer directly with no problems. * * If this library is loaded in an application class loader, it's important that Finalizer not * have a strong reference back to the class loader. Otherwise, you could have a graph like this: * * Finalizer Thread runs instance of -> Finalizer.class loaded by -> Application class loader * which loaded -> ReferenceMap.class which has a static -> FinalizableReferenceQueue instance * * Even if no other references to classes from the application class loader remain, the Finalizer * thread keeps an indirect strong reference to the queue in ReferenceMap, which keeps the * Finalizer running, and as a result, the application class loader can never be reclaimed. * * This means that dynamically loaded web applications and OSGi bundles can't be unloaded. * * If the library is loaded in an application class loader, we try to break the cycle by loading * Finalizer in its own independent class loader: * * System class loader -> Application class loader -> ReferenceMap -> FinalizableReferenceQueue * -> etc. -> Decoupled class loader -> Finalizer * * Now, Finalizer no longer keeps an indirect strong reference to the static * FinalizableReferenceQueue field in ReferenceMap. The application class loader can be reclaimed * at which point the Finalizer thread will stop and its decoupled class loader can also be * reclaimed. * * If any of this fails along the way, we fall back to loading Finalizer directly in the * application class loader. */ private static final Logger logger = Logger.getLogger(FinalizableReferenceQueue.class.getName()); private static final String FINALIZER_CLASS_NAME = "jnr.ffi.util.ref.internal.Finalizer"; /** Reference to Finalizer.startFinalizer(). */ private static final Method startFinalizer; static { Class finalizer = loadFinalizer( new SystemLoader(), new DecoupledLoader(), new DirectLoader()); startFinalizer = getStartFinalizer(finalizer); } private static final Map finalizerQueues = Collections.synchronizedMap(new WeakHashMap()); /** * The actual reference queue that our background thread will poll. */ final ReferenceQueue queue; /** * Whether or not the background thread started successfully. */ final boolean threadStarted; /** * Constructs a new queue. */ @SuppressWarnings("unchecked") public FinalizableReferenceQueue() { // We could start the finalizer lazily, but I'd rather it blow up early. ReferenceQueue queue; boolean threadStarted = false; try { queue = (ReferenceQueue) startFinalizer.invoke(null, FinalizableReference.class, this); threadStarted = true; } catch (IllegalAccessException impossible) { throw new AssertionError(impossible); // startFinalizer() is public } catch (Throwable t) { logger.log(Level.INFO, "Failed to start reference finalizer thread." + " Reference cleanup will only occur when new references are created.", t); queue = new ReferenceQueue(); } this.queue = queue; this.threadStarted = threadStarted; finalizerQueues.put(this, Boolean.TRUE); } /** * Repeatedly dequeues references from the queue and invokes {@link * FinalizableReference#finalizeReferent()} on them until the queue is empty. This method is a * no-op if the background thread was created successfully. */ void cleanUp() { if (!threadStarted) { pollReferenceQueue(); } } private void pollReferenceQueue() { Reference reference; while ((reference = queue.poll()) != null) { /* * This is for the benefit of phantom references. Weak and soft references will have already * been cleared by this point. */ reference.clear(); try { ((FinalizableReference) reference).finalizeReferent(); } catch (Throwable t) { logger.log(Level.SEVERE, "Error cleaning up after reference.", t); } } } /** * Iterates through the given loaders until it finds one that can load Finalizer. * * @return Finalizer.class */ private static Class loadFinalizer(FinalizerLoader... loaders) { for (FinalizerLoader loader : loaders) { Class finalizer = loader.loadFinalizer(); if (finalizer != null) { return finalizer; } } throw new AssertionError(); } /** * Loads Finalizer.class. */ interface FinalizerLoader { /** * Returns Finalizer.class or null if this loader shouldn't or can't load it. * * @throws SecurityException if we don't have the appropriate privileges */ Class loadFinalizer(); } /** * Tries to load Finalizer from the system class loader. If Finalizer is in the system class path, * we needn't create a separate loader. */ static class SystemLoader implements FinalizerLoader { @Override public Class loadFinalizer() { ClassLoader systemLoader; try { systemLoader = ClassLoader.getSystemClassLoader(); } catch (SecurityException e) { logger.info("Not allowed to access system class loader."); return null; } if (systemLoader != null) { try { return systemLoader.loadClass(FINALIZER_CLASS_NAME); } catch (ClassNotFoundException e) { // Ignore. Finalizer is simply in a child class loader. return null; } } else { return null; } } } /** * Try to load Finalizer in its own class loader. If Finalizer's thread had a direct reference to * our class loader (which could be that of a dynamically loaded web application or OSGi bundle), * it would prevent our class loader from getting garbage collected. */ static class DecoupledLoader implements FinalizerLoader { private static final String LOADING_ERROR = "Could not load Finalizer in its own class loader." + "Loading Finalizer in the current class loader instead. As a result, you will not be able" + "to garbage collect this class loader. To support reclaiming this class loader, either" + "resolve the underlying issue, or move Google Collections to your system class path."; @Override public Class loadFinalizer() { try { /* * We use URLClassLoader because it's the only concrete class loader implementation in the * JDK. If we used our own ClassLoader subclass, Finalizer would indirectly reference this * class loader: * * Finalizer.class -> CustomClassLoader -> CustomClassLoader.class -> This class loader * * System class loader will (and must) be the parent. */ ClassLoader finalizerLoader = newLoader(getBaseUrl()); return finalizerLoader.loadClass(FINALIZER_CLASS_NAME); } catch (Exception e) { logger.log(Level.WARNING, LOADING_ERROR, e); return null; } } /** * Gets URL for base of path containing Finalizer.class. */ URL getBaseUrl() throws IOException { // Find URL pointing to Finalizer.class file. String finalizerPath = FINALIZER_CLASS_NAME.replace('.', '/') + ".class"; URL finalizerUrl = getClass().getClassLoader().getResource(finalizerPath); if (finalizerUrl == null) { throw new FileNotFoundException(finalizerPath); } // Find URL pointing to base of class path. String urlString = finalizerUrl.toString(); if (!urlString.endsWith(finalizerPath)) { throw new IOException("Unsupported path style: " + urlString); } urlString = urlString.substring(0, urlString.length() - finalizerPath.length()); return new URL(finalizerUrl, urlString); } /** Creates a class loader with the given base URL as its classpath. */ URLClassLoader newLoader(URL base) { return new URLClassLoader(new URL[] {base}); } } /** * Loads Finalizer directly using the current class loader. We won't be able to garbage collect * this class loader, but at least the world doesn't end. */ static class DirectLoader implements FinalizerLoader { @Override public Class loadFinalizer() { try { return Class.forName(FINALIZER_CLASS_NAME); } catch (ClassNotFoundException e) { throw new AssertionError(e); } } } /** * Looks up Finalizer.startFinalizer(). */ static Method getStartFinalizer(Class finalizer) { try { return finalizer.getMethod("startFinalizer", Class.class, Object.class); } catch (NoSuchMethodException e) { throw new AssertionError(e); } } public static void cleanUpAll() { try { // Iterate over a new array containing all the queues, so we don't risk a concurrent modification exception for (Object frq : finalizerQueues.keySet().toArray()) { ((FinalizableReferenceQueue) frq).cleanUp(); } } catch (Throwable t) {} } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/util/ref/FinalizableSoftReference.java000066400000000000000000000025701316720554100276750ustar00rootroot00000000000000/* * Copyright (C) 2007 The Guava Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.util.ref; import java.lang.ref.SoftReference; /** * Soft reference with a {@code finalizeReferent()} method which a background thread invokes after * the garbage collector reclaims the referent. This is a simpler alternative to using a {@link * java.lang.ref.ReferenceQueue}. * * @author Bob Lee * @since 2.0 (imported from Google Collections Library) */ public abstract class FinalizableSoftReference extends SoftReference implements FinalizableReference { /** * Constructs a new finalizable soft reference. * * @param referent to softly reference * @param queue that should finalize the referent */ protected FinalizableSoftReference(T referent, FinalizableReferenceQueue queue) { super(referent, queue.queue); queue.cleanUp(); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/util/ref/FinalizableWeakReference.java000066400000000000000000000025701316720554100276510ustar00rootroot00000000000000/* * Copyright (C) 2007 The Guava Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.util.ref; import java.lang.ref.WeakReference; /** * Weak reference with a {@code finalizeReferent()} method which a background thread invokes after * the garbage collector reclaims the referent. This is a simpler alternative to using a {@link * java.lang.ref.ReferenceQueue}. * * @author Bob Lee * @since 2.0 (imported from Google Collections Library) */ public abstract class FinalizableWeakReference extends WeakReference implements FinalizableReference { /** * Constructs a new finalizable weak reference. * * @param referent to weakly reference * @param queue that should finalize the referent */ protected FinalizableWeakReference(T referent, FinalizableReferenceQueue queue) { super(referent, queue.queue); queue.cleanUp(); } } jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/util/ref/internal/000077500000000000000000000000001316720554100237475ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/main/java/jnr/ffi/util/ref/internal/Finalizer.java000066400000000000000000000227661316720554100265520ustar00rootroot00000000000000/* * Copyright (C) 2008 The Guava Authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.util.ref.internal; import java.lang.ref.PhantomReference; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.logging.Level; import java.util.logging.Logger; /** * Thread that finalizes referents. All references should implement * {@code com.google.common.base.FinalizableReference}. *

*

While this class is public, we consider it to be *internal* and not part * of our published API. It is public so we can access it reflectively across * class loaders in secure environments. *

*

This class can't depend on other Google Collections code. If we were * to load this class in the same class loader as the rest of * Google Collections, this thread would keep an indirect strong reference * to the class loader and prevent it from being garbage collected. This * poses a problem for environments where you want to throw away the class * loader. For example, dynamically reloading a web application or unloading * an OSGi bundle. *

*

{@code com.google.common.base.FinalizableReferenceQueue} loads this class * in its own class loader. That way, this class doesn't prevent the main * class loader from getting garbage collected, and this class can detect when * the main class loader has been garbage collected and stop itself. */ public class Finalizer implements Runnable { private static final Logger logger = Logger.getLogger(Finalizer.class.getName()); /** * Name of FinalizableReference.class. */ private static final String FINALIZABLE_REFERENCE = "jnr.ffi.util.ref.FinalizableReference"; private Thread thread; /** * Starts the Finalizer thread. FinalizableReferenceQueue calls this method * reflectively. * * @param finalizableReferenceClass FinalizableReference.class * @param frq reference to instance of FinalizableReferenceQueue that started * this thread * @return ReferenceQueue which Finalizer will poll */ public static ReferenceQueue startFinalizer( Class finalizableReferenceClass, Object frq) { /* * We use FinalizableReference.class for two things: * * 1) To invoke FinalizableReference.finalizeReferent() * * 2) To detect when FinalizableReference's class loader has to be garbage * collected, at which point, Finalizer can stop running */ if (!finalizableReferenceClass.getName().equals(FINALIZABLE_REFERENCE)) { throw new IllegalArgumentException( "Expected " + FINALIZABLE_REFERENCE + "."); } Finalizer finalizer = new Finalizer(finalizableReferenceClass, frq); finalizer.start(); return finalizer.queue; } private final WeakReference> finalizableReferenceClassReference; private final PhantomReference frqReference; private final ReferenceQueue queue = new ReferenceQueue(); private static final Field inheritableThreadLocals; private static final Constructor inheritableThreadlocalsConstructor; static { // Try the constructor first because it is cleaner and doesn't produce warnings on Java 9. Constructor itlc = null; try { itlc = getInheritableThreadLocalsConstructor(); } catch (Throwable t) { } Field itl = null; if (itlc == null) { try { itl = getInheritableThreadLocalsField(); } catch (Throwable t) { } } inheritableThreadLocals = itl; inheritableThreadlocalsConstructor = itlc; if (itl == null && itlc == null) { logger.log(Level.INFO, "Couldn't access Thread.inheritableThreadLocals or appropriate constructor." + " Reference finalizer threads will inherit thread local values."); } } /** * Constructs a new finalizer thread. */ private Finalizer(Class finalizableReferenceClass, Object frq) { this.finalizableReferenceClassReference = new WeakReference>(finalizableReferenceClass); // Keep track of the FRQ that started us so we know when to stop. this.frqReference = new PhantomReference(frq, queue); } public void start() { if (inheritableThreadlocalsConstructor != null) { try { this.thread = inheritableThreadlocalsConstructor.newInstance( Thread.currentThread().getThreadGroup(), this, Finalizer.class.getName(), 0, false ); } catch (Throwable t) { logger.log(Level.INFO, "Failed to disable thread local values inherited" + " by reference finalizer thread.", t); // fall through and try field tweak } } if (this.thread == null) { this.thread = new Thread(this, Finalizer.class.getName()); if (inheritableThreadLocals != null) { try { inheritableThreadLocals.set(this.thread, null); } catch (Throwable t) { logger.log(Level.INFO, "Failed to clear thread local values inherited" + " by reference finalizer thread.", t); } } } thread.setDaemon(true); thread.setPriority(Thread.MAX_PRIORITY); // Set the context class loader to null in order to avoid // keeping a strong reference to an application classloader. thread.setContextClassLoader(null); thread.start(); } /** * Loops continuously, pulling references off the queue and cleaning them up. */ @SuppressWarnings("InfiniteLoopStatement") @Override public void run() { while (true) { try { if (!cleanUp(queue.remove())) { break; } } catch (InterruptedException e) { /* ignore */ } } } /** * Cleans up a single reference. Catches and logs all throwables. */ private boolean cleanUp(Reference reference) { Method finalizeReferentMethod = getFinalizeReferentMethod(); if (finalizeReferentMethod == null) { return false; } do { /* * This is for the benefit of phantom references. Weak and soft * references will have already been cleared by this point. */ reference.clear(); if (reference == frqReference) { /* * The client no longer has a reference to the * FinalizableReferenceQueue. We can stop. */ return false; } try { finalizeReferentMethod.invoke(reference); } catch (Throwable t) { logger.log(Level.SEVERE, "Error cleaning up after reference.", t); } /* * Loop as long as we have references available so as not to waste * CPU looking up the Method over and over again. */ } while ((reference = queue.poll()) != null); return true; } /** * Looks up FinalizableReference.finalizeReferent() method. */ private Method getFinalizeReferentMethod() { Class finalizableReferenceClass = finalizableReferenceClassReference.get(); if (finalizableReferenceClass == null) { /* * FinalizableReference's class loader was reclaimed. While there's a * chance that other finalizable references could be enqueued * subsequently (at which point the class loader would be resurrected * by virtue of us having a strong reference to it), we should pretty * much just shut down and make sure we don't keep it alive any longer * than necessary. */ return null; } try { return finalizableReferenceClass.getMethod("finalizeReferent"); } catch (NoSuchMethodException e) { throw new AssertionError(e); } } public static Field getInheritableThreadLocalsField() { try { Field inheritableThreadLocals = Thread.class.getDeclaredField("inheritableThreadLocals"); inheritableThreadLocals.setAccessible(true); return inheritableThreadLocals; } catch (Throwable t) { return null; } } public static Constructor getInheritableThreadLocalsConstructor() { try { return Thread.class.getConstructor(ThreadGroup.class, Runnable.class, String.class, long.class, boolean.class); } catch (Throwable t) { return null; } } } jnr-ffi-jnr-ffi-2.1.7/src/test/000077500000000000000000000000001316720554100161575ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/test/java/000077500000000000000000000000001316720554100171005ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/000077500000000000000000000000001316720554100176715ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/000077500000000000000000000000001316720554100204355ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/ArrayTest.java000066400000000000000000000221241316720554100232170ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; import jnr.ffi.annotations.LongLong; import jnr.ffi.annotations.In; import jnr.ffi.annotations.Out; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import java.lang.*; import static org.junit.Assert.*; public class ArrayTest { public static interface TestLib { // Pointer ptr_return_array_element(Pointer[] array, int index); // void ptr_set_array_element(Pointer[] array, int index, Pointer value); byte ptr_ret_int8_t(byte[] p, int offset); short ptr_ret_int16_t(short[] p, int offset); int ptr_ret_int32_t(int[] p, int offset); @LongLong long ptr_ret_int64_t(@LongLong long[] p, int offset); long ptr_ret_int32_t(long[] p, int offset); float ptr_ret_float(float[] p, int offset); // Pointer ptr_ret_pointer(Pointer[] p, int offset); double ptr_ret_double(double[] p, int offset); void ptr_set_int8_t(byte[] p, int offset, byte value); void ptr_set_int16_t(short[] p, int offset, short value); void ptr_set_int32_t(int[] p, int offset, int value); void ptr_set_int64_t(@LongLong long[] p, int offset, @LongLong long value); void ptr_set_int32_t(long[] p, int offset, long value); void ptr_set_float(float[] p, int offset, float value); void ptr_set_double(double[] p, int offset, double value); // void ptr_set_pointer(Pointer[] p, int offset, Pointer value); Pointer ptr_malloc(int size); void ptr_free(Pointer ptr); } public static interface TestLibInOnly { byte ptr_ret_int8_t(@In byte[] p, int offset); short ptr_ret_int16_t(@In short[] p, int offset); int ptr_ret_int32_t(@In int[] p, int offset); @LongLong long ptr_ret_int64_t(@In @LongLong long[] p, int offset); long ptr_ret_int32_t(@In long[] p, int offset); float ptr_ret_float(@In float[] p, int offset); void ptr_set_int8_t(@In byte[] p, int offset, byte value); void ptr_set_int16_t(@In short[] p, int offset, short value); void ptr_set_int32_t(@In int[] p, int offset, int value); void ptr_set_int64_t(@In @LongLong long[] p, int offset, @LongLong long value); void ptr_set_int32_t(@In long[] p, int offset, long value); void ptr_set_float(@In float[] p, int offset, float value); void ptr_set_double(@In double[] p, int offset, double value); // void ptr_set_pointer(@In Pointer[] p, int offset, Pointer value); } public static interface TestLibOutOnly { byte ptr_ret_int8_t(@Out byte[] p, int offset); short ptr_ret_int16_t(@Out short[] p, int offset); int ptr_ret_int32_t(@Out int[] p, int offset); @LongLong long ptr_ret_int64_t(@Out @LongLong long[] p, int offset); long ptr_ret_int32_t(@Out long[] p, int offset); float ptr_ret_float(@Out float[] p, int offset); void ptr_set_int8_t(@Out byte[] p, int offset, byte value); void ptr_set_int16_t(@Out short[] p, int offset, short value); void ptr_set_int32_t(@Out int[] p, int offset, int value); void ptr_set_int64_t(@Out @LongLong long[] p, int offset, @LongLong long value); void ptr_set_int32_t(@Out long[] p, int offset, long value); void ptr_set_float(@Out float[] p, int offset, float value); void ptr_set_double(@Out double[] p, int offset, double value); // void ptr_set_pointer(@Out Pointer[] p, int offset, Pointer value); } static TestLib testlib; public ArrayTest() { } @BeforeClass public static void setUpClass() throws Exception { testlib = TstUtil.loadTestLib(TestLib.class); } @AfterClass public static void tearDownClass() throws Exception { } @Before public void setUp() { } @After public void tearDown() { } @Test public void byteByReference() { final byte MAGIC = (byte) 0xfe; byte[] ref = { MAGIC }; assertEquals("byte reference not read correctly", MAGIC, testlib.ptr_ret_int8_t(ref, 0)); final byte MAGIC2 = (byte) 0xca; testlib.ptr_set_int8_t(ref, 0, MAGIC2); assertEquals("byte reference not written correctly", MAGIC2, ref[0]); } @Test public void shortByReference() { final short MAGIC = (short) 0xfee1; short[] ref = { MAGIC }; assertEquals("short reference not read correctly", MAGIC, testlib.ptr_ret_int16_t(ref, 0)); final short MAGIC2 = (short) 0xcafe; testlib.ptr_set_int16_t(ref, 0, MAGIC2); assertEquals("short reference not written correctly", MAGIC2, ref[0]); } @Test public void intByReference() { final int MAGIC = (int) 0xfee1dead; int[] ref = { MAGIC }; assertEquals("int reference not read correctly", MAGIC, testlib.ptr_ret_int32_t(ref, 0)); final int MAGIC2 = (int) 0xcafebabe; testlib.ptr_set_int32_t(ref, 0, MAGIC2); assertEquals("int reference not written correctly", MAGIC2, ref[0]); } @Test public void getLongByReference() { final long MAGIC = 0x1234fee1dead6789L; long[] ref = { MAGIC }; assertEquals("long reference not read correctly", MAGIC, testlib.ptr_ret_int64_t(ref, 0)); } @Test public void setLongByReference() { final long MAGIC = 0xcafebabe12345678L; long[] ref = { 0L }; testlib.ptr_set_int64_t(ref, 0, MAGIC); assertEquals("long reference not written correctly", MAGIC, ref[0]); } @Test public void setLong32ByReference() { if (Runtime.getRuntime(testlib).longSize() == 4) { final long MAGIC = 0x12345678L; long[] ref = {0L}; testlib.ptr_set_int32_t(ref, 0, MAGIC); assertEquals("long reference not written correctly", MAGIC, ref[0]); } } // @Test // public void pointerByReference() { // final Pointer MAGIC = new Pointer(0xfee1dead); // Pointer[] ref = { MAGIC }; // assertEquals("Pointer reference not read correctly", MAGIC, testlib.ptr_ret_pointer(ref, 0)); // final Pointer MAGIC2 = new Pointer(0xcafebabe); // testlib.ptr_set_pointer(ref, 0, MAGIC2); // assertEquals("Pointer reference not written correctly", MAGIC2, ref[0]); // } @Test public void floatByReference() { final float MAGIC = (float) 0xfee1dead; float[] ref = { MAGIC }; assertEquals("float reference not read correctly", MAGIC, testlib.ptr_ret_float(ref, 0), 0.00001); final float MAGIC2 = (float) 0xcafebabe; testlib.ptr_set_float(ref, 0, MAGIC2); assertEquals("float reference not written correctly", MAGIC2, ref[0], 0.00001); } @Test public void doubleByReference() { final double MAGIC = 0x1234fee1dead6789L; double[] ref = { MAGIC }; assertEquals("double reference not read correctly", MAGIC, testlib.ptr_ret_double(ref, 0), 0.00001); final double MAGIC2 = (double) 0xcafebabe12345678L; testlib.ptr_set_double(ref, 0, MAGIC2); assertEquals("double reference not written correctly", MAGIC2, ref[0], 0d); } //@Test public void inOnlyByteByReference() { TestLibInOnly lib = TstUtil.loadTestLib(TestLibInOnly.class); final byte MAGIC = (byte) 0xfe; byte[] ref = { MAGIC }; assertEquals("byte reference not read correctly", MAGIC, lib.ptr_ret_int8_t(ref, 0)); final byte MAGIC2 = (byte) 0xca; lib.ptr_set_int8_t(ref, 0, MAGIC2); assertEquals("byte array read from native memory when it should not be", MAGIC, ref[0]); } //@Test public void inOnlyByteArray() { TestLibInOnly lib = TstUtil.loadTestLib(TestLibInOnly.class); final byte MAGIC = (byte) 0xfe; byte[] ref = new byte[1024]; ref[0] = MAGIC; assertEquals("byte array not read correctly", MAGIC, lib.ptr_ret_int8_t(ref, 0)); final byte MAGIC2 = (byte) 0xca; lib.ptr_set_int8_t(ref, 0, MAGIC2); assertEquals("byte array read from native memory when it should not be", MAGIC, ref[0]); } //@Test public void outOnlyByteByReference() { TestLibOutOnly lib = TstUtil.loadTestLib(TestLibOutOnly.class); final byte MAGIC = (byte) 0xfe; byte[] ref = { MAGIC }; final byte MAGIC2 = (byte) 0xca; lib.ptr_set_int8_t(ref, 0, MAGIC2); assertEquals("byte reference not copied from native memory", MAGIC2, ref[0]); } }jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/BufferTest.java000066400000000000000000000372771316720554100233710ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; import jnr.ffi.annotations.LongLong; import jnr.ffi.annotations.In; import jnr.ffi.annotations.Out; import java.nio.*; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; import static org.junit.Assert.assertEquals; /** * * @author wayne */ public class BufferTest { public BufferTest() { } public static interface TestLib { void fillByteBuffer(@Out ByteBuffer buf, byte value, int size); void fillByteBuffer(@Out Buffer buf, byte value, int size); // void fillCharBuffer(@Out CharBuffer buf, char value, int size); void fillShortBuffer(@Out ShortBuffer buf, short value, int size); void fillShortBuffer(@Out Buffer buf, short value, int size); void fillIntBuffer(@Out IntBuffer buf, int value, int size); void fillIntBuffer(@Out Buffer buf, int value, int size); void fillLongBuffer(@Out LongBuffer buf, @LongLong long value, int size); void fillLongBuffer(@Out Buffer buf, @LongLong long value, int size); void fillFloatBuffer(@Out FloatBuffer buf, float value, int size); void fillDoubleBuffer(@Out DoubleBuffer buf, double value, int size); void fillByteBuffer(@Out byte[] buf, byte value, int size); // void fillCharBuffer(@Out char[] buf, char value, int size); void fillShortBuffer(@Out short[] buf, short value, int size); void fillIntBuffer(@Out int[] buf, int value, int size); void fillLongBuffer(@Out @LongLong long[] buf, @LongLong long value, int size); void fillFloatBuffer(@Out float[] buf, float value, int size); void fillDoubleBuffer(@Out double[] buf, double value, int size); void copyByteBuffer(@Out ByteBuffer dst, @In ByteBuffer src, int size); void copyByteBuffer(@Out ByteBuffer dst, @In byte[] src, int size); void copyByteBuffer(@Out byte[] dst, @In ByteBuffer src, int size); void copyByteBuffer(@Out byte[] dst, @In byte[] src, int size); void copyShortBuffer(@Out ShortBuffer dst, @In ShortBuffer src, int size); void copyShortBuffer(@Out ShortBuffer dst, @In short[] src, int size); void copyShortBuffer(@Out short[] dst, @In ShortBuffer src, int size); void copyShortBuffer(@Out short[] dst, @In short[] src, int size); void copyIntBuffer(@Out IntBuffer dst, @In IntBuffer src, int size); void copyIntBuffer(@Out IntBuffer dst, @In int[] src, int size); void copyIntBuffer(@Out int[] dst, @In IntBuffer src, int size); void copyIntBuffer(@Out int[] dst, @In int[] src, int size); } static TestLib lib; static Runtime runtime; @BeforeClass public static void setUpClass() throws Exception { lib = TstUtil.loadTestLib(TestLib.class); runtime = Runtime.getRuntime(lib); } @AfterClass public static void tearDownClass() throws Exception { lib = null; } @Before public void setUp() { } @After public void tearDown() { } // SMALL sized heap buffers can be done using direct buffers private static final int SMALL = 64; // LARGE sized heap buffers are handled via the native code private static final int LARGE = 2048; public void testByteBufferArgument(int size) { ByteBuffer buf = ByteBuffer.allocate(size).order(runtime.byteOrder()); final byte MAGIC = (byte)0xED; lib.fillByteBuffer(buf, MAGIC, buf.remaining()); for (int i=0;i < buf.capacity();i++) { assertEquals("Bad value at index " + i, MAGIC, buf.get(i)); } } @Test public void fillSmallByteBufferArgument() { testByteBufferArgument(SMALL); } @Test public void fillLargeByteBufferArgument() { testByteBufferArgument(LARGE); } @Test public void fillByteBufferWithOffsetArgument() { ByteBuffer buf = ByteBuffer.allocate(SMALL).order(runtime.byteOrder()); final byte MAGIC = (byte)0xED; buf.put((byte)0xDE); lib.fillByteBuffer(buf.slice(), MAGIC, SMALL - 1); assertEquals("Value at position 0 overwritten", (byte)0xde, buf.get(0)); for (int i=buf.position();i < buf.capacity();i++) { assertEquals("Bad value at index " + i, MAGIC, buf.get(i)); } } @Test public void fillByteBufferSlice() { final int SIZE = SMALL; ByteBuffer buf = ByteBuffer.allocate(SIZE).order(runtime.byteOrder()); final byte MAGIC = (byte)0xED; buf.put(0, (byte)0xDE); buf.put(buf.limit() - 1, (byte) 0xDE); ByteBuffer dup = buf.duplicate(); dup.position(1).limit(buf.limit() - 1); ByteBuffer slice = dup.slice(); lib.fillByteBuffer(slice, MAGIC, slice.capacity()); assertEquals("Value at position 0 overwritten", (byte)0xde, buf.get(0)); assertEquals("Value at position " + (SIZE - 1) + " overwritten", (byte)0xde, buf.get(SIZE - 1)); for (int i = 1; i < buf.capacity() - 1; i++) { assertEquals("Bad value at index " + i, MAGIC, buf.get(i)); } } public void testShortBufferArgument(int size) { ShortBuffer buf = ShortBuffer.allocate(size); final short MAGIC = (short)0xABED; lib.fillShortBuffer(buf, MAGIC, size); for (int i=0;i < buf.capacity();i++) { assertEquals("Bad value at index " + i, MAGIC, buf.get(i)); } } @Test public void fillSmallShortBufferArgument() { testShortBufferArgument(SMALL); } @Test public void fillLargeShortBufferArgument() { testShortBufferArgument(LARGE); } @Test public void fillShortBufferWithOffsetArgument() { ShortBuffer buf = ShortBuffer.allocate(SMALL); final short MAGIC = (short)0xABED; buf.put((short)0xDEAD); lib.fillShortBuffer(buf.slice(), MAGIC, SMALL - 1); assertEquals("Value at position 0 overwritten", (short)0xdead, buf.get(0)); for (int i=1;i < buf.capacity();i++) { assertEquals("Bad value at index " + i, MAGIC, buf.get(i)); } } @Test public void fillShortBufferSlice() { ShortBuffer buf = ShortBuffer.allocate(SMALL); final short FILL = (short) 0x1234; final short GUARD = (short) 0xdead; buf.put(0, GUARD).put(buf.limit() - 1, GUARD); ShortBuffer dup = buf.duplicate(); dup.position(1).limit(buf.limit() - 1); ShortBuffer slice = dup.slice(); lib.fillShortBuffer(slice, FILL, slice.capacity()); assertEquals("Value at position 0 overwritten", GUARD, buf.get(0)); assertEquals("Value at position " + (buf.limit() - 1) + " overwritten", GUARD, buf.get(buf.limit() - 1)); for (int i = 1; i < buf.limit() - 1; i++) { assertEquals("Bad value at index " + i, FILL, buf.get(i)); } } public void testIntBufferArgument(int size) { IntBuffer buf = IntBuffer.allocate(size); final int MAGIC = 0xABEDCF23; lib.fillIntBuffer(buf, MAGIC, size); for (int i=0;i < buf.capacity();i++) { assertEquals("Bad value at index " + i, MAGIC, buf.get(i)); } } @Test public void fillSmallIntBufferArgument() { testIntBufferArgument(SMALL); } @Test public void fillLargeIntBufferArgument() { testIntBufferArgument(SMALL); } @Test public void fillIntBufferWithOffsetArgument() { IntBuffer buf = IntBuffer.allocate(SMALL); final int MAGIC = 0xABEDCF23; buf.put(0xdeadbeef); lib.fillIntBuffer(buf.slice(), MAGIC, SMALL - 1); assertEquals("Value at position 0 overwritten", 0xdeadbeef, buf.get(0)); for (int i=1;i < buf.capacity();i++) { assertEquals("Bad value at index " + i, MAGIC, buf.get(i)); } } @Test public void fillIntBufferSlice() { IntBuffer buf = IntBuffer.allocate(SMALL); final int FILL = 0x12345678; final int GUARD = 0xdeadbeef; buf.put(0, GUARD).put(buf.limit() - 1, GUARD); IntBuffer dup = buf.duplicate(); dup.position(1).limit(buf.limit() - 1); IntBuffer slice = dup.slice(); lib.fillIntBuffer(slice, FILL, slice.capacity()); assertEquals("Value at position 0 overwritten", GUARD, buf.get(0)); assertEquals("Value at position " + (buf.limit() - 1) + " overwritten", GUARD, buf.get(buf.limit() - 1)); for (int i = 1; i < buf.limit() - 1; i++) { assertEquals("Bad value at index " + i, FILL, buf.get(i)); } } @Test public void fillLongBufferArgument() { LongBuffer buf = LongBuffer.allocate(SMALL); final long MAGIC = 0x1234567887654321L; lib.fillLongBuffer(buf, MAGIC, SMALL); for (int i=0;i < buf.capacity();i++) { assertEquals("Bad value at index " + i, MAGIC, buf.get(i)); } } @Test public void fillLongBufferWithOffsetArgument() { LongBuffer buf = LongBuffer.allocate(SMALL); final long MAGIC = 0x1234567887654321L; buf.put(0xdeadbeefL); lib.fillLongBuffer(buf.slice(), MAGIC, SMALL - 1); assertEquals("Value at position 0 overwritten", 0xdeadbeefL, buf.get(0)); for (int i=1;i < buf.capacity();i++) { assertEquals("Bad value at index " + i, MAGIC, buf.get(i)); } } @Test public void fillLongBufferSlice() { LongBuffer buf = LongBuffer.allocate(SMALL); final long GUARD = 0xdeadbeefL; final long FILL = 0x1234567887654321L; buf.put(0, GUARD).put(buf.limit() - 1, GUARD); LongBuffer dup = buf.duplicate(); dup.position(1).limit(buf.limit() - 1); LongBuffer slice = dup.slice(); lib.fillLongBuffer(dup.slice(), FILL, slice.capacity()); assertEquals("Value at position 0 overwritten", GUARD, buf.get(0)); assertEquals("Value at position " + (buf.limit() - 1) + " overwritten", GUARD, buf.get(buf.limit() - 1)); for (int i = 1; i < buf.limit() - 1; i++) { assertEquals("Bad value at index " + i, FILL, buf.get(i)); } } @Test public void fillDirectByteBufferArgument() { ByteBuffer buf = ByteBuffer.allocateDirect(SMALL).order(runtime.byteOrder()); final byte MAGIC = (byte)0xED; lib.fillByteBuffer(buf, MAGIC, SMALL); for (int i=0;i < buf.capacity();i++) { assertEquals("Bad value at index " + i, MAGIC, buf.get(i)); } } @Test public void fillDirectShortBufferArgument() { ByteBuffer buf = ByteBuffer.allocateDirect(SMALL*2).order(runtime.byteOrder()); ShortBuffer shortBuf = buf.asShortBuffer(); final short MAGIC = (short)0xABED; lib.fillShortBuffer(shortBuf, MAGIC, SMALL); for (int i=0;i < shortBuf.capacity();i++) { assertEquals("Bad value at index " + i, MAGIC, shortBuf.get(i)); } } @Test public void fillDirectShortBufferSlice() { ByteBuffer buf = ByteBuffer.allocateDirect(SMALL*2).order(runtime.byteOrder()); ShortBuffer shortBuf = buf.asShortBuffer(); buf.position(2); ShortBuffer sliced = buf.slice().asShortBuffer(); final short MAGIC = (short)0xABED; lib.fillShortBuffer(sliced, MAGIC, SMALL - 1); assertEquals("Bad value at index " + 0, 0, shortBuf.get(0)); for (int i=1; i < shortBuf.capacity() - 1; i++) { assertEquals("Bad value at index " + i, MAGIC, shortBuf.get(i)); } } @Test public void fillDirectShortBufferSliceAsBuffer() { ByteBuffer buf = ByteBuffer.allocateDirect(SMALL*2).order(runtime.byteOrder()); ShortBuffer shortBuf = buf.asShortBuffer(); buf.position(2); Buffer sliced = buf.slice().asShortBuffer(); final short MAGIC = (short)0xABED; lib.fillShortBuffer(sliced, MAGIC, SMALL - 1); assertEquals("Bad value at index " + 0, 0, shortBuf.get(0)); for (int i=1; i < shortBuf.capacity() - 1; i++) { assertEquals("Bad value at index " + i, MAGIC, shortBuf.get(i)); } } @Test public void fillDirectIntBufferArgument() { ByteBuffer buf = ByteBuffer.allocateDirect(SMALL*4).order(runtime.byteOrder()); IntBuffer intBuf = buf.asIntBuffer(); final int MAGIC = 0xABEDCF23; lib.fillIntBuffer(intBuf, MAGIC, SMALL); for (int i=0;i < intBuf.capacity();i++) { assertEquals("Bad value at index " + i, MAGIC, intBuf.get(i)); } } @Test public void fillDirectLongBufferArgument() { ByteBuffer buf = ByteBuffer.allocateDirect(SMALL*8).order(runtime.byteOrder()); LongBuffer longBuf = buf.asLongBuffer(); final long MAGIC = 0x1234567887654321L; lib.fillLongBuffer(longBuf, MAGIC, SMALL); for (int i=0;i < longBuf.capacity();i++) { assertEquals("Bad value at index " + i, MAGIC, longBuf.get(i)); } } @Test public void copySmallDirectByteBufferToArray() { testCopyByteBufferToArray(ByteBuffer.allocateDirect(SMALL)); } @Test public void copyLargeDirectByteBufferToArray() { testCopyByteBufferToArray(ByteBuffer.allocateDirect(LARGE)); } @Test public void copySmallHeapByteBufferToArray() { testCopyByteBufferToArray(ByteBuffer.allocate(SMALL)); } @Test public void copyLargeHeapByteBufferToArray() { testCopyByteBufferToArray(ByteBuffer.allocate(LARGE)); } public void testCopyByteBufferToArray(ByteBuffer src) { final int size = src.capacity(); for (int i = 0; i < size; ++i) { src.put(i, (byte) i); } byte[] dst = new byte[size]; lib.copyByteBuffer(dst, src, size); for (int i = 0; i < size; ++i) { assertEquals("Bad value at index " + i, (byte) i, dst[i]); } } // FIXME: re-enable when read-only buffers are supported // @Test public void copyReadOnlyHeapByteBufferToArray() { final int size = SMALL; ByteBuffer src = ByteBuffer.allocate(size); for (int i = 0; i < size; ++i) { src.put(i, (byte) i); } byte[] dst = new byte[size]; lib.copyByteBuffer(dst, src.asReadOnlyBuffer(), size); for (int i = 0; i < size; ++i) { assertEquals("Bad value at index " + i, (byte) i, dst[i]); } } // @Test // public void pinnedByteBuffer() { // ByteBuffer buf = ByteBuffer.allocate(LARGE); // Function fillByteBuffer = NativeLibrary.getInstance("jffitest").getFunction("fillByteBuffer"); // NativeInvoker nativeInvoker = FFINativeInvoker.getInvoker(fillByteBuffer, NativeInvoker.VOID); // CallBuilder cb = CallBuilder.create(nativeInvoker); // final byte MAGIC = (byte)0xED; // cb.addPinned(buf).addInt8(MAGIC).addInt32(buf.remaining()).invokeVoid(); // for (int i=0;i < buf.capacity();i++) { // assertEquals("Bad value at index " + i, MAGIC, buf.get(i)); // } // } }jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/DelegateTest.java000066400000000000000000000664571316720554100236740ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; import jnr.ffi.annotations.Delegate; import jnr.ffi.annotations.LongLong; import jnr.ffi.types.u_int32_t; import org.junit.*; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; /** * */ public class DelegateTest { public DelegateTest() { } private static TestLib lib; @BeforeClass public static void setUpClass() throws Exception { lib = TstUtil.loadTestLib(TestLib.class); } @AfterClass public static void tearDownClass() throws Exception { } @Before public void setUp() { } @After public void tearDown() { } public static interface TestLib { public static interface CallableNull { @Delegate public int call(); } int testClosureNull(CallableNull closure, int defaultValue); public static interface CallableVrV { @Delegate public void call(); } void testClosureVrV(CallableVrV closure); public static interface CallableVrB { @Delegate public byte call(); } byte testClosureVrB(CallableVrB closure); public static interface CallableVrS { @Delegate public short call(); } short testClosureVrS(CallableVrS closure); public static interface CallableVrI { @Delegate public int call(); } int testClosureVrI(CallableVrI closure); public static interface CallableVrL { @Delegate public @LongLong long call(); } @LongLong long testClosureVrL(CallableVrL closure); public interface CallableVrF { @Delegate public float call(); } float testClosureVrF(CallableVrF closure); public interface CallableVrD { @Delegate public double call(); } double testClosureVrD(CallableVrD closure); public interface CallableBrV { @Delegate public void call(byte a1); } void testClosureBrV(CallableBrV closure, byte a1); public interface CallableSrV { @Delegate public void call(short a1); } void testClosureSrV(CallableSrV closure, short a1); public interface CallableIrV { @Delegate public void call(int a1); } void testClosureIrV(CallableIrV closure, int a1); public interface CallableIrVBoxed { @Delegate public void call(@u_int32_t Long a1); } void testClosureIrV(CallableIrVBoxed closure, @u_int32_t long a1); public interface CallableErV { @Delegate public void call(@u_int32_t EnumTest.TestEnum a1); } void testClosureIrV(CallableErV closure, @u_int32_t EnumTest.TestEnum a1); public static interface CallableVrE { @Delegate public EnumTest.TestEnum call(); } int testClosureVrI(CallableVrE closure); public class ClosureStruct extends Struct { public final Function function = function(CallableIrV.class); public ClosureStruct(Runtime runtime) { super(runtime); } } void testStructClosureIrV(ClosureStruct closure, int a1); // void testClosureBrV(Callable closure, byte a1); // void testClosureSrV(Callable closure, short a1); // void testClosureLrV(Callable closure, long a1); // void testClosureFrV(Callable closure, float a1); // void testClosureDrV(Callable closure, double a1); // // // closures with small-big-small arguments // void testClosureBSBrV(Callable closure, byte a1, short a2, byte a3); // void testClosureBIBrV(Callable closure, byte a1, int a2, byte a3); // void testClosureBLBrV(Callable closure, byte a1, long a2, byte a3); // void testClosureBFBrV(Callable closure, byte a1, float a2, byte a3); // void testClosureBDBrV(Callable closure, byte a1, double a2, byte a3); // // void testClosureSBSrV(Callable closure, short a1, byte a2, short a3); // void testClosureSISrV(Callable closure, short a1, int a2, short a3); // void testClosureSLSrV(Callable closure, short a1, long a2, short a3); // void testClosureSFSrV(Callable closure, short a1, float a2, short a3); // void testClosureSDSrV(Callable closure, short a1, double a2, short a3); // // // Now big-smaller-smaller // void testClosureLSBrV(Callable closure, long a1, short a2, byte a3); // // big-smaller-small // void testClosureLBSrV(Callable closure, long a1, byte a2, short a3); public interface ReusableCallable { @Delegate public void call(int a1); } Pointer ret_pointer(ReusableCallable callable); public CallableVrV ret_pointer(CallableVrV callable); public CallableIrV ret_pointer(CallableIrV callable); } @Test public void closureNullWithValue() { final boolean[] called = { false }; final TestLib.CallableNull closure = new TestLib.CallableNull() { public int call() { called[0] = true; return 42; } }; int retValue = lib.testClosureNull(closure, 41); assertTrue("Callable not called", called[0]); assertEquals("Incorrect return value from callable", 42, retValue); } @Test public void closureNullWithNull() { final TestLib.CallableNull closure = null; int retValue = lib.testClosureNull(closure, 41); assertEquals("Incorrect return value from callable", 41, retValue); } @Test public void closureVrV() { final boolean[] called = { false }; final TestLib.CallableVrV closure = new TestLib.CallableVrV() { public void call() { called[0] = true; } }; lib.testClosureVrV(closure); assertTrue("Callable not called", called[0]); } @Test public void closureVrB() { final boolean[] called = { false }; final byte MAGIC = (byte) 0xfe; TestLib.CallableVrB closure = new TestLib.CallableVrB() { public byte call() { called[0] = true; return MAGIC; } }; byte retVal = lib.testClosureVrB(closure); assertTrue("Callable not called", called[0]); assertEquals("Incorrect return value from closure", MAGIC, retVal); } @Test public void closureVrS() { final boolean[] called = { false }; final short MAGIC = (short) 0xfee1; TestLib.CallableVrS closure = new TestLib.CallableVrS() { public short call() { called[0] = true; return MAGIC; } }; short retVal = lib.testClosureVrS(closure); assertTrue("Callable not called", called[0]); assertEquals("Incorrect return value from closure", MAGIC, retVal); } @Test public void closureVrI() { final boolean[] called = { false }; final int MAGIC = (int) 0xfee1dead; TestLib.CallableVrI closure = new TestLib.CallableVrI() { public int call() { called[0] = true; return MAGIC; } }; int retVal = lib.testClosureVrI(closure); assertTrue("Callable not called", called[0]); assertEquals("Incorrect return value from closure", MAGIC, retVal); } @Test public void closureVrL() { final boolean[] called = { false }; final long MAGIC = 0xfee1deadcafebabeL; TestLib.CallableVrL closure = new TestLib.CallableVrL() { public long call() { called[0] = true; return MAGIC; } }; long retVal = lib.testClosureVrL(closure); assertTrue("Callable not called", called[0]); assertEquals("Incorrect return value from closure", MAGIC, retVal); } @Test public void closureVrF() { final boolean[] called = { false }; final float MAGIC = (float) 0xfee1dead; TestLib.CallableVrF closure = new TestLib.CallableVrF() { public float call() { called[0] = true; return MAGIC; } }; float retVal = lib.testClosureVrF(closure); assertTrue("Callable not called", called[0]); assertEquals("Incorrect return value from closure", MAGIC, retVal, 0f); } @Test public void closureVrD() { final boolean[] called = { false }; final double MAGIC = (double) 0xfee1dead; TestLib.CallableVrD closure = new TestLib.CallableVrD() { public double call() { called[0] = true; return MAGIC; } }; double retVal = lib.testClosureVrD(closure); assertTrue("Callable not called", called[0]); assertEquals("Incorrect return value from closure", MAGIC, retVal, 0d); } @Test public void closureBrV() { final boolean[] called = { false }; final byte[] val = { 0 }; final byte MAGIC = (byte) 0xde; TestLib.CallableBrV closure = new TestLib.CallableBrV() { public void call(byte a1) { called[0] = true; val[0] = a1; } }; lib.testClosureBrV(closure, MAGIC); assertTrue("Callable not called", called[0]); assertEquals("Wrong value passed to closure", MAGIC, val[0]); } @Test public void closureSrV() { final boolean[] called = { false }; final short[] val = { 0 }; final short MAGIC = (short) 0xdead; TestLib.CallableSrV closure = new TestLib.CallableSrV() { public void call(short a1) { called[0] = true; val[0] = a1; } }; lib.testClosureSrV(closure, MAGIC); assertTrue("Callable not called", called[0]); assertEquals("Wrong value passed to closure", MAGIC, val[0]); } @Test public void closureIrV() { final boolean[] called = { false }; final int[] val = { 0 }; final int MAGIC = 0xdeadbeef; TestLib.CallableIrV closure = new TestLib.CallableIrV() { public void call(int a1) { called[0] = true; val[0] = a1; } }; lib.testClosureIrV(closure, MAGIC); assertTrue("Callable not called", called[0]); assertEquals("Wrong value passed to closure", MAGIC, val[0]); } @Test public void closureStructIrV() { final boolean[] called = { false }; final int[] val = { 0 }; final int MAGIC = 0xdeadbeef; TestLib.CallableIrV closure = new TestLib.CallableIrV() { public void call(int a1) { called[0] = true; val[0] = a1; } }; TestLib.ClosureStruct s = new TestLib.ClosureStruct(Runtime.getRuntime(lib)); s.function.set(closure); lib.testStructClosureIrV(s, MAGIC); assertTrue("Callable not called", called[0]); assertEquals("Wrong value passed to closure", MAGIC, val[0]); } @Test public void closureIrVBoxed() { final boolean[] called = { false }; final int[] val = { 0 }; final int MAGIC = 0xdeadbeef; TestLib.CallableIrVBoxed closure = new TestLib.CallableIrVBoxed() { public void call(Long a1) { called[0] = true; val[0] = a1.intValue(); } }; lib.testClosureIrV(closure, MAGIC); assertTrue("Callable not called", called[0]); assertEquals("Wrong value passed to closure", MAGIC, val[0]); } @Test public void closureErV() { final boolean[] called = { false }; final EnumTest.TestEnum[] val = { null }; final EnumTest.TestEnum MAGIC = EnumTest.TestEnum.C; TestLib.CallableErV closure = new TestLib.CallableErV() { public void call(EnumTest.TestEnum a1) { called[0] = true; val[0] = a1; } }; lib.testClosureIrV(closure, MAGIC); assertTrue("Callable not called", called[0]); assertEquals("Wrong value passed to closure", MAGIC, val[0]); } @Test public void closureVrE() { final boolean[] called = { false }; final EnumTest.TestEnum MAGIC = EnumTest.TestEnum.C; TestLib.CallableVrE closure = new TestLib.CallableVrE() { public EnumTest.TestEnum call() { called[0] = true; return MAGIC; } }; int retVal = lib.testClosureVrI(closure); assertTrue("Callable not called", called[0]); assertEquals("Incorrect return value from closure", MAGIC.intValue(), retVal); } @Test public void reuseClosure() { TestLib.ReusableCallable closure = new TestLib.ReusableCallable() { public void call(int a1) {} }; Pointer p1 = lib.ret_pointer(closure); Pointer p2 = lib.ret_pointer(closure); assertEquals("not same native address for Callable instance", p1, p2); } @Test public void allocateMany() { for (int i = 0; i < 100000; i++) { lib.ret_pointer(new TestLib.ReusableCallable() { public void call(int a1) {} }); } // assertEquals("not same native address for Callable instance", p1, p2); } @Test public void callFunctionPointerVrV() { final boolean[] called = { false }; TestLib.CallableVrV javaClosure = new TestLib.CallableVrV() { @Override public void call() { called[0] = true; } }; TestLib.CallableVrV callable = lib.ret_pointer(javaClosure); callable.call(); assertTrue(called[0]); } @Test public void callFunctionPointerIrV() { final boolean[] called = { false }; final int[] values = { 0 }; final int MAGIC = 0xdeadbeef; TestLib.CallableIrV javaClosure = new TestLib.CallableIrV() { @Override public void call(int i) { called[0] = true; values[0] = i; } }; TestLib.CallableIrV callable = lib.ret_pointer(javaClosure); callable.call(MAGIC); assertEquals(MAGIC, values[0]); assertTrue(called[0]); } // @Test // public void closureLrV() { // final boolean[] called = { false }; // final long[] val = { 0 }; // final long MAGIC = 0xfee1deadcafebabeL; // Callable closure = new Callable() { // // public void invoke(long a1) { // called[0] = true; // val[0] = a1; // } // }; // lib.testClosureLrV(closure, MAGIC); // assertTrue("Callable not called", called[0]); // assertEquals("Wrong value passed to closure", MAGIC, val[0]); // } // @Test // public void closureFrV() { // final boolean[] called = { false }; // final float[] val = { 0 }; // final float MAGIC = (float) 0xdeadbeef; // Callable closure = new Callable() { // // public void invoke(float a1) { // called[0] = true; // val[0] = a1; // } // }; // lib.testClosureFrV(closure, MAGIC); // assertTrue("Callable not called", called[0]); // assertEquals("Wrong value passed to closure", MAGIC, val[0], 0f); // } // @Test // public void closureDrV() { // final boolean[] called = { false }; // final double[] val = { 0 }; // final double MAGIC = (double) 0xfee1deadcafebabeL; // Callable closure = new Callable() { // // public void invoke(double a1) { // called[0] = true; // val[0] = a1; // } // }; // lib.testClosureDrV(closure, MAGIC); // assertTrue("Callable not called", called[0]); // assertEquals("Wrong value passed to closure", MAGIC, val[0], 0d); // } // @Test // public void closureBSBrV() { // final boolean[] called = { false }; // final byte[] v1 = { 0 }; // final short[] v2 = { 0 }; // final byte[] v3 = { 0 }; // final byte A1 = (byte) 0x11; // final short A2 = (short) 0xfee1; // final byte A3 = (byte) 0x22; // Callable closure = new Callable() { // // public void invoke(byte a1, short a2, byte a3) { // called[0] = true; // v1[0] = a1; // v2[0] = a2; // v3[0] = a3; // } // }; // lib.testClosureBSBrV(closure, A1, A2, A3); // assertTrue("Callable not called", called[0]); // assertEquals("Wrong value passed to closure", A1, v1[0]); // assertEquals("Wrong value passed to closure", A2, v2[0]); // assertEquals("Wrong value passed to closure", A3, v3[0]); // } // @Test // public void closureBIBrV() { // final boolean[] called = { false }; // final byte[] v1 = { 0 }; // final int[] v2 = { 0 }; // final byte[] v3 = { 0 }; // final byte A1 = (byte) 0x11; // final int A2 = (int) 0xfee1dead; // final byte A3 = (byte) 0x22; // Callable closure = new Callable() { // // public void invoke(byte a1, int a2, byte a3) { // called[0] = true; // v1[0] = a1; // v2[0] = a2; // v3[0] = a3; // } // }; // lib.testClosureBIBrV(closure, A1, A2, A3); // assertTrue("Callable not called", called[0]); // assertEquals("Wrong value passed to closure", A1, v1[0]); // assertEquals("Wrong value passed to closure", A2, v2[0]); // assertEquals("Wrong value passed to closure", A3, v3[0]); // } // @Test // public void closureBLBrV() { // final boolean[] called = { false }; // final byte[] v1 = { 0 }; // final long[] v2 = { 0 }; // final byte[] v3 = { 0 }; // final byte A1 = (byte) 0x11; // final long A2 = (long) 0xfee1deadcafebabeL; // final byte A3 = (byte) 0x22; // Callable closure = new Callable() { // // public void invoke(byte a1, long a2, byte a3) { // called[0] = true; // v1[0] = a1; // v2[0] = a2; // v3[0] = a3; // } // }; // lib.testClosureBLBrV(closure, A1, A2, A3); // assertTrue("Callable not called", called[0]); // assertEquals("Wrong value passed to closure", A1, v1[0]); // assertEquals("Wrong value passed to closure", A2, v2[0]); // assertEquals("Wrong value passed to closure", A3, v3[0]); // } // @Test // public void closureBFBrV() { // final boolean[] called = { false }; // final byte[] v1 = { 0 }; // final float[] v2 = { 0 }; // final byte[] v3 = { 0 }; // final byte A1 = (byte) 0x11; // final float A2 = (float) 0xfee1dead; // final byte A3 = (byte) 0x22; // Callable closure = new Callable() { // // public void invoke(byte a1, float a2, byte a3) { // called[0] = true; // v1[0] = a1; // v2[0] = a2; // v3[0] = a3; // } // }; // lib.testClosureBFBrV(closure, A1, A2, A3); // assertTrue("Callable not called", called[0]); // assertEquals("Wrong value passed to closure", A1, v1[0]); // assertEquals("Wrong value passed to closure", A2, v2[0], 0f); // assertEquals("Wrong value passed to closure", A3, v3[0]); // } // @Test // public void closureBDBrV() { // final boolean[] called = { false }; // final byte[] v1 = { 0 }; // final double[] v2 = { 0 }; // final byte[] v3 = { 0 }; // final byte A1 = (byte) 0x11; // final double A2 = (double) 0xfee1deadcafebabeL; // final byte A3 = (byte) 0x22; // Callable closure = new Callable() { // // public void invoke(byte a1, double a2, byte a3) { // called[0] = true; // v1[0] = a1; // v2[0] = a2; // v3[0] = a3; // } // }; // lib.testClosureBDBrV(closure, A1, A2, A3); // assertTrue("Callable not called", called[0]); // assertEquals("Wrong value passed to closure", A1, v1[0]); // assertEquals("Wrong value passed to closure", A2, v2[0], 0d); // assertEquals("Wrong value passed to closure", A3, v3[0]); // } // @Test // public void closureSBSrV() { // final boolean[] called = { false }; // final short[] v1 = { 0 }; // final byte[] v2 = { 0 }; // final short[] v3 = { 0 }; // final short A1 = (short) 0x1111; // final byte A2 = (byte) 0xfe; // final short A3 = (short) 0x2222; // Callable closure = new Callable() { // // public void invoke(short a1, byte a2, short a3) { // called[0] = true; // v1[0] = a1; // v2[0] = a2; // v3[0] = a3; // } // }; // lib.testClosureSBSrV(closure, A1, A2, A3); // assertTrue("Callable not called", called[0]); // assertEquals("Wrong value passed to closure", A1, v1[0]); // assertEquals("Wrong value passed to closure", A2, v2[0]); // assertEquals("Wrong value passed to closure", A3, v3[0]); // } // @Test // public void closureSISrV() { // final boolean[] called = { false }; // final short[] v1 = { 0 }; // final int[] v2 = { 0 }; // final short[] v3 = { 0 }; // final short A1 = (short) 0x1111; // final int A2 = (int) 0xfee1dead; // final short A3 = (short) 0x2222; // Callable closure = new Callable() { // // public void invoke(short a1, int a2, short a3) { // called[0] = true; // v1[0] = a1; // v2[0] = a2; // v3[0] = a3; // } // }; // lib.testClosureSISrV(closure, A1, A2, A3); // assertTrue("Callable not called", called[0]); // assertEquals("Wrong value passed to closure", A1, v1[0]); // assertEquals("Wrong value passed to closure", A2, v2[0]); // assertEquals("Wrong value passed to closure", A3, v3[0]); // } // // @Test // public void closureSLSrV() { // final boolean[] called = { false }; // final short[] v1 = { 0 }; // final long[] v2 = { 0 }; // final short[] v3 = { 0 }; // final short A1 = (short) 0x1111; // final long A2 = (long) 0xfee1deadcafebabeL; // final short A3 = (short) 0x2222; // Callable closure = new Callable() { // // public void invoke(short a1, long a2, short a3) { // called[0] = true; // v1[0] = a1; // v2[0] = a2; // v3[0] = a3; // } // }; // lib.testClosureSLSrV(closure, A1, A2, A3); // assertTrue("Callable not called", called[0]); // assertEquals("Wrong value passed to closure", A1, v1[0]); // assertEquals("Wrong value passed to closure", A2, v2[0]); // assertEquals("Wrong value passed to closure", A3, v3[0]); // } // @Test // public void closureSFSrV() { // final boolean[] called = { false }; // final short[] v1 = { 0 }; // final float[] v2 = { 0 }; // final short[] v3 = { 0 }; // final short A1 = (short) 0x1111; // final float A2 = (float) 0xfee1dead; // final short A3 = (short) 0x2222; // Callable closure = new Callable() { // // public void invoke(short a1, float a2, short a3) { // called[0] = true; // v1[0] = a1; // v2[0] = a2; // v3[0] = a3; // } // }; // lib.testClosureSFSrV(closure, A1, A2, A3); // assertTrue("Callable not called", called[0]); // assertEquals("Wrong value passed to closure", A1, v1[0]); // assertEquals("Wrong value passed to closure", A2, v2[0], 0f); // assertEquals("Wrong value passed to closure", A3, v3[0]); // } // @Test // public void closureSDSrV() { // final boolean[] called = { false }; // final short[] v1 = { 0 }; // final double[] v2 = { 0 }; // final short[] v3 = { 0 }; // final short A1 = (short) 0x1111; // final double A2 = (double) 0xfee1deadcafebabeL; // final short A3 = (short) 0x2222; // Callable closure = new Callable() { // // public void invoke(short a1, double a2, short a3) { // called[0] = true; // v1[0] = a1; // v2[0] = a2; // v3[0] = a3; // } // }; // lib.testClosureSDSrV(closure, A1, A2, A3); // assertTrue("Callable not called", called[0]); // assertEquals("Wrong value passed to closure", A1, v1[0]); // assertEquals("Wrong value passed to closure", A2, v2[0], 0d); // assertEquals("Wrong value passed to closure", A3, v3[0]); // } // @Test // public void closureLSBrV() { // final boolean[] called = { false }; // final long[] v1 = { 0 }; // final short[] v2 = { 0 }; // final byte[] v3 = { 0 }; // final long A1 = (long) 0xfee1deadcafebabeL; // final short A2 = (short) 0x1111; // final byte A3 = (byte) 0x22; // Callable closure = new Callable() { // // public void invoke(long a1, short a2, byte a3) { // called[0] = true; // v1[0] = a1; // v2[0] = a2; // v3[0] = a3; // } // }; // lib.testClosureLSBrV(closure, A1, A2, A3); // assertTrue("Callable not called", called[0]); // assertEquals("Wrong value passed to closure", A1, v1[0]); // assertEquals("Wrong value passed to closure", A2, v2[0]); // assertEquals("Wrong value passed to closure", A3, v3[0]); // } // @Test // public void closureLBSrV() { // final boolean[] called = { false }; // final long[] v1 = { 0 }; // final byte[] v2 = { 0 }; // final short[] v3 = { 0 }; // final long A1 = (long) 0xfee1deadcafebabeL; // final byte A2 = (byte) 0x11; // final short A3 = (short) 0x2222; // Callable closure = new Callable() { // // public void invoke(long a1, byte a2, short a3) { // called[0] = true; // v1[0] = a1; // v2[0] = a2; // v3[0] = a3; // } // }; // lib.testClosureLBSrV(closure, A1, A2, A3); // assertTrue("Callable not called", called[0]); // assertEquals("Wrong value passed to closure", A1, v1[0]); // assertEquals("Wrong value passed to closure", A2, v2[0]); // assertEquals("Wrong value passed to closure", A3, v3[0]); // } } jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/EnumTest.java000066400000000000000000000070261316720554100230510ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; import jnr.ffi.util.EnumMapper; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import java.util.EnumSet; import java.util.Set; import static org.junit.Assert.*; /** * * @author wayne */ public class EnumTest { public EnumTest() { } public static enum TestEnum implements EnumMapper.IntegerEnum { A(1), B(2), C(3), Z(100); TestEnum(int value) { this.value = value; } public int intValue() { return value; } private final int value; } public static enum BitField { A(0x1), B(0x2), C(0x4), D(0x8); BitField(int value) { this.value = value; } public int intValue() { return value; } private final int value; } public static interface TestLib { public int ret_int32_t(TestEnum e); public int add_int32_t(TestEnum i1, TestEnum i2); public int ret_int32_t(Set enumSet); } public static interface ReturnEnumLib { public TestEnum ret_int32_t(int e); public Set ret_int32_t(Set bitfield); public TestEnum ret_int32_t(TestEnum e); public TestEnum add_int32_t(int i1, int i2); public TestEnum add_int32_t(TestEnum i1, TestEnum i2); } static TestLib testlib; static ReturnEnumLib retenum; @BeforeClass public static void setUpClass() throws Exception { testlib = TstUtil.loadTestLib(TestLib.class); retenum = TstUtil.loadTestLib(ReturnEnumLib.class); } @AfterClass public static void tearDownClass() throws Exception { } @Before public void setUp() { } @After public void tearDown() { } // TODO add test methods here. // The methods must be annotated with annotation @Test. For example: // // @Test // public void hello() {} @Test public void enumArgument() { assertEquals("Wrong value returned for enum", TestEnum.Z.intValue(), testlib.ret_int32_t(TestEnum.Z)); assertEquals("Wrong value returned for enum", TestEnum.C.intValue(), testlib.add_int32_t(TestEnum.A, TestEnum.B)); } @Test public void returnEnum() { assertEquals("Wrong value returned for enum", TestEnum.Z, retenum.ret_int32_t(TestEnum.Z.intValue())); assertEquals("Wrong value returned for enum", TestEnum.C, retenum.add_int32_t(1, 2)); } @Test public void enumSetParameter() { assertEquals(TestEnum.A.intValue() | TestEnum.B.intValue(), testlib.ret_int32_t(EnumSet.of(TestEnum.A, TestEnum.B))); } @Test public void enumSetResult() { EnumSet MAGIC = EnumSet.of(BitField.A, BitField.B); assertEquals(MAGIC, retenum.ret_int32_t(MAGIC)); } }jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/GlobalVariableTest.java000066400000000000000000000053001316720554100250040ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; import jnr.ffi.annotations.Delegate; import jnr.ffi.types.u_int32_t; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; public class GlobalVariableTest { public static interface ClosureIrV { @Delegate void call(int value); } public static interface TestLib { @u_int32_t Variable gvar_s32(); int gvar_s32_get(); void gvar_s32_set(int value); Variable gvar_pointer(); Pointer gvar_pointer_get(); } @Test public void testIntegerVariableSet() { TestLib lib = TstUtil.loadTestLib(TestLib.class); Variable var = lib.gvar_s32(); final long MAGIC = 0xdeadbeef; var.set(MAGIC); assertEquals(MAGIC, lib.gvar_s32_get()); } @Test public void testIntegerVariableGet() { TestLib lib = TstUtil.loadTestLib(TestLib.class); Variable var = lib.gvar_s32(); final int MAGIC = 0xdeadbeef; lib.gvar_s32_set(MAGIC); assertEquals(MAGIC, var.get().intValue()); } @Test public void testCallbackVariableSet() { TestLib lib = TstUtil.loadTestLib(TestLib.class); Variable var = lib.gvar_pointer(); var.set(new ClosureIrV() { public void call(int value) { } }); assertNotNull(lib.gvar_pointer_get()); } // @Test public void testCallbackVariableGet() { // TestLib lib = TstUtil.loadTestLib(TestLib.class); // Variable var = lib.gvar_pointer(); // final boolean[] called = { false }; // final int[] values = { 0 }; // // var.set(new ClosureIrV() { // public void call(int value) { // called[0] = true; // values[0] = value; // } // }); // assertNotNull(lib.gvar_pointer_get()); // assertNotNull(var.get()); // var.get().call(0xdeadbeef); // assertTrue(called[0]); // assertEquals(0xdeadbeef, values[0]); // } } jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/InvocationTest.java000066400000000000000000000023021316720554100242460ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.assertEquals; /** * */ public class InvocationTest { public static interface TestLib { int ret_int32_t(int i); } static TestLib testlib; @BeforeClass public static void setUpClass() throws Exception { testlib = TstUtil.loadTestLib(TestLib.class); } @Test public void hammer() throws Throwable { for (int i = 0; i < 1000000; i++) { assertEquals(i, testlib.ret_int32_t(i)); } } } jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/LastErrorTest.java000066400000000000000000000077371316720554100240730ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; import jnr.ffi.annotations.IgnoreError; import jnr.ffi.annotations.SaveError; import org.junit.Test; import java.util.Collections; import java.util.HashMap; import java.util.Map; import static org.junit.Assert.*; /** * */ public class LastErrorTest { public interface ErrorSavingUnspecified { int setLastError(int error); } public interface MethodSaveError extends ErrorSavingUnspecified { @SaveError int setLastError(int error); } public interface MethodIgnoreError extends ErrorSavingUnspecified { @IgnoreError int setLastError(int error); } public interface MethodIgnoreAndSaveError extends ErrorSavingUnspecified { @IgnoreError @SaveError int setLastError(int error); } @Test public void testLastError() { assertSavesError(true, ErrorSavingUnspecified.class); assertSavesError(true, MethodSaveError.class); assertSavesError(false, MethodIgnoreError.class); assertSavesError(true, MethodIgnoreAndSaveError.class); assertSavesError(false, ErrorSavingUnspecified.class, LibraryOption.IgnoreError); assertSavesError(true, MethodSaveError.class, LibraryOption.IgnoreError); assertSavesError(false, MethodIgnoreError.class, LibraryOption.IgnoreError); assertSavesError(true, MethodIgnoreAndSaveError.class, LibraryOption.IgnoreError); assertSavesError(true, ErrorSavingUnspecified.class, LibraryOption.SaveError); assertSavesError(true, MethodSaveError.class, LibraryOption.SaveError); assertSavesError(false, MethodIgnoreError.class, LibraryOption.SaveError); assertSavesError(true, MethodIgnoreAndSaveError.class, LibraryOption.SaveError); assertSavesError(true, ErrorSavingUnspecified.class, LibraryOption.IgnoreError, LibraryOption.SaveError); assertSavesError(true, MethodSaveError.class, LibraryOption.IgnoreError, LibraryOption.SaveError); assertSavesError(false, MethodIgnoreError.class, LibraryOption.IgnoreError, LibraryOption.SaveError); assertSavesError(true, MethodIgnoreAndSaveError.class, LibraryOption.IgnoreError, LibraryOption.SaveError); } void assertSavesError(boolean expected, Class cls) { assertSavesError(expected, cls, Collections.emptyMap()); } void assertSavesError(boolean expected, Class cls, LibraryOption... options) { Map optionsMap = new HashMap(); for (LibraryOption option : options) optionsMap.put(option, option); assertSavesError(expected, cls, optionsMap); } void assertSavesError(boolean expected, Class cls, Map options) { ErrorSavingUnspecified methodSaveError = TstUtil.loadTestLib(cls, options); Runtime runtime = Runtime.getRuntime(methodSaveError); // clear errno runtime.setLastError(0); final int MAGIC = 0xdeadbeef; methodSaveError.setLastError(MAGIC); if (expected) { assertEquals("Errno value was not saved for " + cls, MAGIC, runtime.getLastError()); } else { assertNotEquals("Errno value was saved for " + cls, MAGIC, runtime.getLastError()); } } }jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/LibraryLoaderTest.java000066400000000000000000000122261316720554100246760ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.fail; import static org.junit.Assert.assertEquals; import jnr.ffi.mapper.FunctionMapper; import jnr.ffi.provider.FFIProvider; import org.junit.Test; public class LibraryLoaderTest { public static interface TestLib { int setLastError(int error); } @Test public void loadShouldNotThrowExceptions() { try { LibraryLoader.create(TestLib.class).load("non-existent-library"); } catch (Throwable t) { fail("load raised exception " + t); } } @Test(expected = UnsatisfiedLinkError.class) public void failImmediatelyShouldThrowULE() { LibraryLoader.create(TestLib.class).failImmediately().load("non-existent-library"); } @Test(expected = UnsatisfiedLinkError.class) public void invocationOnFailedLoadShouldThrowULE() { TestLib lib = LibraryLoader.create(TestLib.class).failImmediately().load("non-existent-library"); lib.setLastError(0); } // Loadable library interface to test function mapping public static interface TestLibMapped { int set(int error); } @Test public void optionWithFunctionMapper() { LibraryLoader loader = FFIProvider.getSystemProvider() .createLibraryLoader(TestLibMapped.class); loader.library("test"); // Define function mappings by a FunctionMapper entry in options FunctionMapper.Builder shortNames = new FunctionMapper.Builder(); shortNames.map("set", "setLastError"); loader.option(LibraryOption.FunctionMapper, shortNames.build()); // Load and call the mapped function TestLibMapped lib = loader.load(); lib.set(1); } @Test public void mapperWithFuctionMapper() { LibraryLoader loader = FFIProvider.getSystemProvider() .createLibraryLoader(TestLibMapped.class); loader.library("test"); // Define function mappings via the type-safe API FunctionMapper.Builder shortNames = new FunctionMapper.Builder(); shortNames.map("set", "setLastError"); loader.mapper(shortNames.build()); // Load and call the mapped function TestLibMapped lib = loader.load(); lib.set(2); } @Test public void mapMethod() { LibraryLoader loader = FFIProvider.getSystemProvider() .createLibraryLoader(TestLibMapped.class); loader.library("test"); // Define function mappings via the String API loader.map("set", "setLastError"); // Load and call the mapped function TestLibMapped lib = loader.load(); lib.set(3); } // Loadable library interface to test complicated function mapping public static interface TestLibMath { public int add(int i1, int i2); // = add_int32_t public int sub(int i1, int i2); // = sub_int32_t public int mul(int i1, int i2); // = mul_int32_t public int div(int i1, int i2); // = div_int32_t public double addd(double f1, double f2); // = add_double public double subd(double f1, double f2); // = add_double } @Test public void functionMappersCombine() { LibraryLoader loader = FFIProvider.getSystemProvider() .createLibraryLoader(TestLibMath.class); loader.library("test"); // Define function mappings by a FunctionMapper entry in options FunctionMapper.Builder shortNames = new FunctionMapper.Builder(); shortNames.map("add", "add_int32_t"); shortNames.map("sub", "sub_int32_t"); loader.option(LibraryOption.FunctionMapper, shortNames.build()); // Define function mappings via the type-safe API shortNames = new FunctionMapper.Builder(); shortNames.map("mul", "mul_int32_t"); shortNames.map("div", "div_int32_t"); loader.mapper(shortNames.build()); // Define function mappings via the String API loader.map("addd", "add_double"); loader.map("subd", "sub_double"); TestLibMath lib = loader.load(); assertNotNull("Could not load libtest", lib); // Do some arithmetic with the library to prove methods exist int sum = lib.sub(lib.add(10, 5), 3); // 10+5-3 = 12 int prod = lib.mul(sum, 7); int answer = lib.div(prod, 2); assertEquals(answer, 42); double a = lib.subd(lib.addd(30.0, 20.0), 8.0); assertEquals(a, 42.0, 1e-4); } } jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/LibraryTest.java000066400000000000000000000035071316720554100235510ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; /** * Test library locating/loading */ public class LibraryTest { public LibraryTest() { } @BeforeClass public static void setUpClass() throws Exception { } @AfterClass public static void tearDownClass() throws Exception { } @Before public void setUp() { } @After public void tearDown() { } // TODO add test methods here. // The methods must be annotated with annotation @Test. For example: // // @Test // public void hello() {} public static interface TestLib { int setLastError(int error); } @Test public void loadTestLib() { TestLib lib = TstUtil.loadTestLib(TestLib.class); assertNotNull("Could not load libtest", lib); // This just forces the library to really load and call a function lib.setLastError(0); } @Test(expected = UnsatisfiedLinkError.class) public void badLibrarynameShouldThrowULE() { Library.loadLibrary(TestLib.class, "non-existant-library"); } }jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/MemoryIOTest.java000066400000000000000000000321711316720554100236440ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; import java.nio.ByteBuffer; import jnr.ffi.annotations.LongLong; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; /** * * @author wayne */ public class MemoryIOTest { public static interface TestLib { byte ptr_ret_int8_t(Pointer p, int offset); short ptr_ret_int16_t(Pointer p, int offset); int ptr_ret_int32_t(Pointer p, int offset); @LongLong long ptr_ret_int64_t(Pointer p, int offset); float ptr_ret_float(Pointer p, int offset); double ptr_ret_double(Pointer p, int offset); void ptr_set_int8_t(Pointer p, int offset, byte value); void ptr_set_int16_t(Pointer p, int offset, short value); void ptr_set_int32_t(Pointer p, int offset, int value); void ptr_set_int64_t(Pointer p, int offset, @LongLong long value); void ptr_set_float(Pointer p, int offset, float value); void ptr_set_double(Pointer p, int offset, double value); } static TestLib testlib; static Runtime runtime; private static final int FLOAT_BYTE_SIZE = Float.SIZE / 8; private static final int DOUBLE_BYTE_SIZE = Double.SIZE / 8; public MemoryIOTest() { } @BeforeClass public static void setUpClass() throws Exception { testlib = TstUtil.loadTestLib(TestLib.class); runtime = Runtime.getRuntime(testlib); } @AfterClass public static void tearDownClass() throws Exception { } @Before public void setUp() { } @After public void tearDown() { } private Pointer direct(int size) { return Memory.allocateDirect(runtime, size); } private Pointer heap(int size) { return Memory.allocate(runtime, size); } private Pointer buffer(int size) { return wrap(ByteBuffer.allocate(size).order(runtime.byteOrder())); } private static Pointer wrap(ByteBuffer buffer) { return Pointer.wrap(runtime, buffer); } private static Pointer allocateDirect(int size) { return Memory.allocateDirect(runtime, size); } private void testPutByte(Pointer io, int size) { for (int i = 0; i < size; ++i) { io.putByte(i, (byte) (i + 5)); assertEquals("Incorrect value at offset " + i, (byte) (i + 5), testlib.ptr_ret_int8_t(io, i)); } } private void testGetByte(Pointer io, int size) { for (int i = 0; i < size; ++i) { testlib.ptr_set_int8_t(io, i, (byte) (i + 5)); assertEquals("Incorrect value at offset " + i, (byte) (i + 5), io.getByte(i)); } } private void testPutShort(Pointer io, int size) { for (int i = 0; i <= size - 2; i += 2) { io.putShort(i, (short) i); assertEquals("Incorrect value at offset " + i, (short) i, testlib.ptr_ret_int16_t(io, i)); } } private void testGetShort(Pointer io, int size) { for (int i = 0; i <= size - 2; i += 2) { testlib.ptr_set_int16_t(io, i, (short) i); assertEquals("Incorrect value at offset " + i, (short) i, io.getShort(i)); } } private void testPutInt(Pointer io, int size) { for (int i = 0; i <= size - 4; i += 4) { io.putInt(i, i); assertEquals("Incorrect value at offset " + i, i, testlib.ptr_ret_int32_t(io, i)); } } private void testGetInt(Pointer io, int size) { for (int i = 0; i <= size - 4; i += 4) { testlib.ptr_set_int32_t(io, i, i); assertEquals("Incorrect value at offset " + i, i, io.getInt(i)); } } private void testPutLongLong(Pointer io, int size) { for (int i = 0; i <= size - 8; i += 8) { io.putLongLong(i, i); assertEquals("Incorrect value at offset " + i, (long) i, testlib.ptr_ret_int64_t(io, i)); } } private void testGetLongLong(Pointer io, int size) { for (int i = 0; i <= size - 8; i += 8) { testlib.ptr_set_int64_t(io, i, i); assertEquals("Incorrect value at offset " + i, (long) i, io.getLongLong(i)); } } private void testPutFloat(Pointer io, int size) { for (int i = 0; i <= size - FLOAT_BYTE_SIZE; i += FLOAT_BYTE_SIZE) { io.putFloat(i, i); assertEquals("Incorrect value at offset " + i, (float) i, testlib.ptr_ret_float(io, i), 0.00001); } } private void testGetFloat(Pointer io, int size) { for (int i = 0; i <= size - FLOAT_BYTE_SIZE; i += FLOAT_BYTE_SIZE) { testlib.ptr_set_float(io, i, (float) i); assertEquals("Incorrect value at offset " + i, (float) i, io.getFloat(i), 0.00001); } } private void testPutDouble(Pointer io, int size) { for (int i = 0; i <= size - DOUBLE_BYTE_SIZE; i += DOUBLE_BYTE_SIZE) { io.putDouble(i, (double) i); assertEquals("Incorrect value at offset " + i, (double) i, testlib.ptr_ret_double(io, i), 0d); } } private void testGetDouble(Pointer io, int size) { for (int i = 0; i <= size - DOUBLE_BYTE_SIZE; i += DOUBLE_BYTE_SIZE) { testlib.ptr_set_double(io, i, (double) i); assertEquals("Incorrect value at offset " + i, (double) i, io.getDouble(i), 0d); } } @Test public void testHeapMemoryIOPutByte() { final int SIZE = 16; testPutByte(heap(SIZE), SIZE); } @Test public void testHeapMemoryIOGetByte() { final int SIZE = 16; testGetByte(heap(SIZE), SIZE); } @Test public void testHeapMemoryIOPutShort() { final int SIZE = 16; testPutShort(heap(SIZE), SIZE); } @Test public void testHeapMemoryIOGetShort() { final int SIZE = 16; testGetShort(heap(SIZE), SIZE); } @Test public void testHeapMemoryIOPutInt() { final int SIZE = 16; testPutInt(heap(SIZE), SIZE); } @Test public void testHeapMemoryIOGetInt() { final int SIZE = 16; testGetInt(heap(SIZE), SIZE); } @Test public void testHeapMemoryIOPutLong() { final int SIZE = 16; Pointer memory = heap(SIZE); testPutLongLong(memory, SIZE); } @Test public void testHeapMemoryIOGetLongLong() { final int SIZE = 16; testGetLongLong(heap(SIZE), SIZE); } @Test public void testHeapMemoryIOPutFloat() { final int SIZE = 16; Pointer memory = heap(SIZE); testPutFloat(memory, SIZE); } @Test public void testHeapMemoryIOGetFloat() { final int SIZE = 16; testGetFloat(heap(SIZE), SIZE); } @Test public void testHeapMemoryIOPutDouble() { final int SIZE = 16; Pointer memory = heap(SIZE); testPutDouble(memory, SIZE); } @Test public void testHeapMemoryIOGetDouble() { final int SIZE = 16; testGetDouble(heap(SIZE), SIZE); } @Test public void testNegativeBoundedIO() { final int SIZE = 16; Pointer memio = allocateDirect(SIZE); try { memio.putByte(-1, (byte) 0); fail("Should have thrown IndexOutOfBoundsException"); } catch (IndexOutOfBoundsException ex) { } } @Test public void testOverflowBoundedIO() { final int SIZE = 16; Pointer memio = allocateDirect(SIZE); try { memio.putByte(16, (byte) 0); fail("Should have thrown IndexOutOfBoundsException"); } catch (IndexOutOfBoundsException ex) { } } @Test public void testDirectMemoryIOPutByte() { final int SIZE = 16; testPutByte(direct(SIZE), SIZE); } @Test public void testDirectMemoryIOGetByte() { final int SIZE = 16; testGetByte(direct(SIZE), SIZE); } @Test public void testDirectMemoryIOPutShort() { final int SIZE = 16; testPutShort(direct(SIZE), SIZE); } @Test public void testDirectMemoryIOGetShort() { final int SIZE = 16; testGetShort(direct(SIZE), SIZE); } @Test public void testDirectMemoryIOPutInt() { final int SIZE = 16; testPutInt(direct(SIZE), SIZE); } @Test public void testDirectMemoryIOGetInt() { final int SIZE = 16; testGetInt(direct(SIZE), SIZE); } @Test public void testDirectMemoryIOPutLongLong() { final int SIZE = 16; testPutLongLong(direct(SIZE), SIZE); } @Test public void testDirectMemoryIOGetLongLong() { final int SIZE = 16; testGetLongLong(direct(SIZE), SIZE); } @Test public void testDirectMemoryIOPutFloat() { final int SIZE = 16; testPutFloat(direct(SIZE), SIZE); } @Test public void testDirectMemoryIOGetFloat() { final int SIZE = 16; testGetFloat(direct(SIZE), SIZE); } @Test public void testDirectMemoryIOPutDouble() { final int SIZE = 16; testPutDouble(direct(SIZE), SIZE); } @Test public void testDirectMemoryIOGetDouble() { final int SIZE = 16; testGetDouble(direct(SIZE), SIZE); } @Test public void testBufferIOPutByte() { final int SIZE = 16; testPutByte(buffer(SIZE), SIZE); } @Test public void testBufferIOGetByte() { final int SIZE = 16; testGetByte(buffer(SIZE), SIZE); } @Test public void testBufferIOPutShort() { final int SIZE = 16; testPutShort(buffer(SIZE), SIZE); } @Test public void testBufferIOGetShort() { final int SIZE = 16; testGetShort(buffer(SIZE), SIZE); } @Test public void testBufferIOPutInt() { final int SIZE = 16; testPutInt(buffer(SIZE), SIZE); } @Test public void testBufferIOGetInt() { final int SIZE = 16; testGetInt(buffer(SIZE), SIZE); } @Test public void testBufferIOPutLongLong() { final int SIZE = 16; testPutLongLong(buffer(SIZE), SIZE); } @Test public void testBufferIOGetLongLong() { final int SIZE = 16; testGetLongLong(buffer(SIZE), SIZE); } @Test public void testBufferIOPutFloat() { final int SIZE = 16; testPutFloat(buffer(SIZE), SIZE); } @Test public void testBufferIOGetFloat() { final int SIZE = 16; testGetFloat(buffer(SIZE), SIZE); } @Test public void testBufferIOPutDouble() { final int SIZE = 16; testPutDouble(buffer(SIZE), SIZE); } @Test public void testBufferIOGetDouble() { final int SIZE = 16; testGetDouble(buffer(SIZE), SIZE); } @Test public void testNegativeBufferIO() { final int SIZE = 16; Pointer memio = wrap(ByteBuffer.allocate(SIZE)); try { memio.putByte(-1, (byte) 0); fail("Should have thrown IndexOutOfBoundsException"); } catch (IndexOutOfBoundsException ex) { } } @Test public void testOverflowBufferIO() { final int SIZE = 16; Pointer memio = wrap(ByteBuffer.allocate(SIZE)); try { memio.putByte(16, (byte) 0); fail("Should have thrown IndexOutOfBoundsException"); } catch (IndexOutOfBoundsException ex) { } } @Test public void transferDirectToHeap() throws Exception { ByteBuffer buf = ByteBuffer.allocate(1024); Pointer dst = Pointer.wrap(runtime, buf); Pointer src = Memory.allocateDirect(runtime, 1024); byte[] MAGIC = "MAGIC".getBytes(); src.put(0, MAGIC, 0, MAGIC.length); src.transferTo(0, dst, 0, MAGIC.length); for (int i = 0; i < MAGIC.length; ++i) { assertEquals("Wrong byte at index " + i, MAGIC[i], dst.getByte(i)); } for (int i = 0; i < MAGIC.length; ++i) { assertEquals("Wrong byte at index " + i, MAGIC[i], buf.get(i)); } } @Test public void transferDirectToDirect() throws Exception { Pointer dst = Memory.allocateDirect(runtime, 1024); Pointer src = Memory.allocateDirect(runtime, 1024); final byte[] MAGIC = "MAGIC".getBytes(); final int SRCOFF = 100; final int DSTOFF = 123; src.put(SRCOFF, MAGIC, 0, MAGIC.length); src.transferTo(SRCOFF, dst, DSTOFF, MAGIC.length); for (int i = 0; i < MAGIC.length; ++i) { assertEquals("Wrong byte at index " + i, MAGIC[i], dst.getByte(DSTOFF + i)); } } @Test public void manyTransientAllocations() { for (int i = 0; i < 100000; i++) { Memory.allocate(runtime, 4); } } } jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/NumberTest.java000066400000000000000000000261171316720554100233770ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; import java.util.Random; import jnr.ffi.annotations.LongLong; import jnr.ffi.types.*; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; /** * * @author wayne */ public class NumberTest { public NumberTest() { } public static interface TestLib { public byte add_int8_t(byte i1, byte i2); public short add_int16_t(short i1, short i2); public short add_int16_t(Short i1, short i2); public int add_int32_t(int i1, int i2); public @LongLong long add_int64_t(@LongLong long i1, @LongLong long i2); public long add_long(long i1, long i2); public Long add_long(Long i1, Long i2); public NativeLong add_long(NativeLong i1, NativeLong i2); public NativeLong sub_long(NativeLong i1, NativeLong i2); public NativeLong mul_long(NativeLong i1, NativeLong i2); public NativeLong div_long(NativeLong i1, NativeLong i2); public float add_float(float f1, float f2); public float sub_float(float f1, float f2); public float mul_float(float f1, float f2); public float div_float(float f1, float f2); public double add_double(double f1, double f2); public double sub_double(double f1, double f2); public double mul_double(double f1, double f2); public double div_double(double f1, double f2); public @int32_t long ret_int32_t(@int32_t long l); public @u_int32_t long ret_uint32_t(@u_int32_t long l); public @pid_t int ret_int32_t(@pid_t int l); } static TestLib testlib; public static interface TestBoolean { public boolean ret_int32_t(int l); } static TestBoolean testboolean; @BeforeClass public static void setUpClass() throws Exception { testlib = TstUtil.loadTestLib(TestLib.class); testboolean = TstUtil.loadTestLib(TestBoolean.class); } @AfterClass public static void tearDownClass() throws Exception { } @Before public void setUp() throws Exception { } @After public void tearDown() throws Exception { } @Test public void testByteAddition() throws Exception { for (int i = 0; i <= 255; ++i) { byte i1 = (byte) i; byte i2 = (byte) 0xde; assertEquals("byte addition failed", (byte) (i1 + i2), testlib.add_int8_t(i1, i2)); } } @Test public void testShortAddition() throws Exception { for (int i = 0; i <= 0xffff; ++i) { short i1 = (short) i; short i2 = (short) 0xdead; assertEquals("byte addition failed", (short) (i1 + i2), testlib.add_int16_t(i1, i2)); } } static interface FloatOp { public float j(float f1, float f2); public float n(float f1, float f2); } private void testFloat(FloatOp op) throws Exception { float f1 = 1.0f; float f2 = (float) 0xdeadbeef; assertEquals("float " + op + " failed", op.j(f1, f2), op.n(f1, f2), 0.001); for (int i = 0; i < 0xffff; ++i) { f1 = (float) i; assertEquals("float + " + op + " failed", op.j(f1, f2), op.n(f1, f2), 0.001); } Random random = new Random(); for (int i = 0; i < 0xffff; ++i) { f1 = random.nextFloat(); f2 = random.nextFloat(); float expected = op.j(f1, f2); float result = op.n(f1, f2); if (expected != result) { fail(String.format("float " + op + "(%f, %f) failed - expected: %f, received: %f", f1, f2, expected, result)); } } } @Test public void testFloatAddition() throws Exception { testFloat(new FloatOp() { public float j(float f1, float f2) { return f1 + f2; } public float n(float f1, float f2) { return testlib.add_float(f1, f2); } @Override public String toString() { return "add"; } }); } @Test public void testFloatSubtraction() throws Exception { testFloat(new FloatOp() { public float j(float f1, float f2) { return f1 - f2; } public float n(float f1, float f2) { return testlib.sub_float(f1, f2); } @Override public String toString() { return "subtract"; } }); } @Test public void testFloatMultiplication() throws Exception { testFloat(new FloatOp() { public float j(float f1, float f2) { return f1 * f2; } public float n(float f1, float f2) { return testlib.mul_float(f1, f2); } public String toString() { return "multiply"; } }); } @Test public void testFloatDivision() throws Exception { testFloat(new FloatOp() { public float j(float f1, float f2) { return f1 / f2; } public float n(float f1, float f2) { return testlib.div_float(f1, f2); } @Override public String toString() { return "divide"; } }); } static interface DoubleOp { public double j(double f1, double f2); public double n(double f1, double f2); } private void testDouble(DoubleOp op) throws Exception { double f1 = 1.0f; double f2 = (double) 0xdeadbeef; assertEquals("double " + op + " failed", op.j(f1, f2), op.n(f1, f2), 0.001); for (int i = 0; i < 0xffff; ++i) { f1 = (float) i; assertEquals("double + " + op + " failed", op.j(f1, f2), op.n(f1, f2), 0.001); } Random random = new Random(); for (int i = 0; i < 0xffff; ++i) { f1 = random.nextFloat(); f2 = random.nextFloat(); double expected = op.j(f1, f2); double result = op.n(f1, f2); if (expected != result) { fail(String.format("double " + op + "(%f, %f) failed - expected: %f, received: %f", f1, f2, expected, result)); } } } @Test public void testDoubleAddition() throws Exception { testDouble(new DoubleOp() { public double j(double f1, double f2) { return f1 + f2; } public double n(double f1, double f2) { return testlib.add_double(f1, f2); } @Override public String toString() { return "add"; } }); } @Test public void testDoubleSubtraction() throws Exception { testDouble(new DoubleOp() { public double j(double f1, double f2) { return f1 - f2; } public double n(double f1, double f2) { return testlib.sub_double(f1, f2); } @Override public String toString() { return "subtract"; } }); } @Test public void testDoubleMultiplication() throws Exception { testDouble(new DoubleOp() { public double j(double f1, double f2) { return f1 * f2; } public double n(double f1, double f2) { return testlib.mul_double(f1, f2); } @Override public String toString() { return "multiply"; } }); } @Test public void testDoubleDivision() throws Exception { testDouble(new DoubleOp() { public double j(double f1, double f2) { return f1 / f2; } public double n(double f1, double f2) { return testlib.div_double(f1, f2); } @Override public String toString() { return "divide"; } }); } static interface NativeLongOp { public long j(long f1, long f2); public long n(long f1, long f2); } private void testNativeLong(NativeLongOp op) throws Exception { long i1 = 1; long i2 = 2; assertEquals("NativeLong " + op + " failed", op.j(i1, i2), op.n(i1, i2)); for (int i = 0; i < 0xffff; ++i) { assertEquals("NativeLong + " + op + " failed", op.j(i, i2), op.n(i, i2)); } } @Test public void NativeLong_valueOf() { for (int i = -1000; i < 1000; ++i) { assertEquals("Incorrect value from valueOf(" + i+ ")", i, NativeLong.valueOf(i).intValue()); } for (long i = -1000; i < 1000; ++i) { assertEquals("Incorrect value from valueOf(" + i+ ")", i, NativeLong.valueOf(i).longValue()); } } @Test public void testNativeLongAddition() throws Exception { testNativeLong(new NativeLongOp() { public long j(long i1, long i2) { return i1 + i2; } public long n(long i1, long i2) { return testlib.add_long(NativeLong.valueOf(i1), NativeLong.valueOf(i2)).longValue(); } }); } @Test public void testPrimitiveLongAddition() throws Exception { testNativeLong(new NativeLongOp() { public long j(long i1, long i2) { return i1 + i2; } public long n(long i1, long i2) { return testlib.add_long(i1, i2); } }); } @Test public void testBoxedLongAddition() throws Exception { testNativeLong(new NativeLongOp() { public long j(long i1, long i2) { return i1 + i2; } public long n(long i1, long i2) { return testlib.add_long(new Long(i1), new Long(i2)); } }); } @Test public void testSignExtension() throws Exception { assertEquals("upper 32 bits not set to 1", 0xffffffffdeadbeefL, testlib.ret_int32_t(0x1eefdeadbeefL)); } @Test public void testZeroExtension() throws Exception { assertEquals("upper 32 bits not set to zero", 0xdeadbeefL, testlib.ret_uint32_t(0xfee1deadbeefL)); } @Test public void testBooleanFromInt() throws Exception { assertEquals(false, testboolean.ret_int32_t(0)); assertEquals(true, testboolean.ret_int32_t(-1)); assertEquals(true, testboolean.ret_int32_t(1)); assertEquals(true, testboolean.ret_int32_t(2)); } } jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/ObjectReferenceManagerTest.java000066400000000000000000000043641316720554100264670ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; import org.junit.Test; import static org.junit.Assert.*; public class ObjectReferenceManagerTest { @Test public void sameObjectReturned() { ObjectReferenceManager referenceManager = ObjectReferenceManager.newInstance(Runtime.getSystemRuntime()); String bar = "bar"; Pointer ptr = referenceManager.add(bar); assertSame(bar, referenceManager.get(ptr)); } @Test public void differentPointerReturnedForSameObject() { ObjectReferenceManager referenceManager = ObjectReferenceManager.newInstance(Runtime.getSystemRuntime()); String bar = "bar"; Pointer ptr = referenceManager.add(bar); Pointer ptr2 = referenceManager.add(bar); assertSame(bar, referenceManager.get(ptr)); assertSame(bar, referenceManager.get(ptr2)); assertNotSame(ptr, ptr2); } @Test public void remove() { ObjectReferenceManager referenceManager = ObjectReferenceManager.newInstance(Runtime.getSystemRuntime()); assertTrue(referenceManager.remove(referenceManager.add("bar"))); } @Test public void referenceEqualityOnly() { ObjectReferenceManager referenceManager = ObjectReferenceManager.newInstance(Runtime.getSystemRuntime()); String bar = "bar"; String bar2 = new String("bar"); Pointer ptr = referenceManager.add(bar); Pointer ptr2 = referenceManager.add(bar2); assertNotSame(ptr, ptr2); assertNotEquals(ptr, ptr2); assertSame(bar, referenceManager.get(ptr)); assertSame(bar2, referenceManager.get(ptr2)); } } jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/PlatformTest.java000066400000000000000000000054371316720554100237350ustar00rootroot00000000000000package jnr.ffi; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import java.io.File; import java.io.IOException; import java.util.Collections; public class PlatformTest { private File tmpDir; @Before public void createTempDir() throws IOException { tmpDir = mkTmpDir(); } @After public void deleteTempDir() throws IOException { rmDir(tmpDir); } private void rmDir(File dir) throws IOException { File[] children = dir.listFiles(); if (children != null) { for (File child : children) { if (child.isDirectory()) { rmDir(child); } else { rm(child); } } } rm(dir); } private void rm(File file) throws IOException { if (!file.delete()) { throw new IOException("Could not delete " + file); } } private File mkTmpDir() throws IOException { File tmp = new File(System.getProperty("java.io.tmpdir")); String suffix = System.currentTimeMillis() + "-"; for (int counter = 0; counter < 100; counter++) { File tempDir = new File(tmp, suffix + counter); if (tempDir.mkdir()) { return tempDir; } } throw new IOException("Could not create temp dir"); } private void testVersionComparison(String expected, String... versions) throws Exception { Platform.Linux linux = new Platform.Linux(); String libName = "test"; String mappedLibName = "lib" + libName + ".so"; for (String version : versions) { String name = versionedLibName(mappedLibName, version); if (!new File(tmpDir, name).createNewFile()) { throw new IOException("Could not create file " + name); } } String locatedLibrary = linux.locateLibrary(libName, Collections.singletonList(tmpDir.getAbsolutePath())); Assert.assertEquals(new File(tmpDir, versionedLibName(mappedLibName, expected)).getAbsolutePath(), locatedLibrary); } private String versionedLibName(String mappedLibName, String version) { String name = mappedLibName; if (!version.isEmpty()) { name += "." + version; } return name; } @Test public void testNoVersionComparison() throws Exception { testVersionComparison("", ""); } @Test public void testSingleComponentVersionComparison() throws Exception { testVersionComparison("42", "", "5", "6", "42"); } @Test public void testMultiComponentVersionComparison() throws Exception { testVersionComparison("42.1.3.4", "", "5", "6.1", "42", "42.1", "42.0.5", "42.1.3.4"); } } jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/PointerTest.java000066400000000000000000000361521316720554100235670ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; import jnr.ffi.annotations.*; import jnr.ffi.types.int32_t; import jnr.ffi.types.int8_t; import jnr.ffi.types.size_t; import org.junit.*; import java.nio.ByteOrder; import java.nio.charset.Charset; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; /** * */ public class PointerTest { public PointerTest() { } public static interface TestLib { Pointer ptr_return_array_element(@In Pointer[] array, int index); void ptr_set_array_element(@Out Pointer[] array, int index, Pointer value); byte ptr_ret_int8_t(Pointer p, int offset); byte ptr_ret_int8_t(Address p, int offset); short ptr_ret_int16_t(Pointer p, int offset); int ptr_ret_int32_t(Pointer p, int offset); @LongLong long ptr_ret_int64_t(Pointer p, int offset); float ptr_ret_float(Pointer p, int offset); double ptr_ret_double(Pointer p, int offset); void ptr_set_int8_t(Pointer p, int offset, @int8_t byte value); void ptr_set_int16_t(Pointer p, int offset, short value); void ptr_set_int32_t(Pointer p, int offset, @int32_t int value); void ptr_set_int32_t(Pointer p, int offset, @int32_t long value); void ptr_set_int64_t(Pointer p, int offset, @LongLong long value); void ptr_set_float(Pointer p, int offset, float value); void ptr_set_double(Pointer p, int offset, double value); void ptr_reverse_l5(Pointer p1, Pointer p2, Pointer p3, Pointer p4, Pointer p5); void ptr_reverse_l6(Pointer p1, Pointer p2, Pointer p3, Pointer p4, Pointer p5, Pointer p6); public static final class Foo extends Struct { public final UnsignedLong l1 = new UnsignedLong(); public final UnsignedLong l2 = new UnsignedLong(); public final UnsignedLong l3 = new UnsignedLong(); public Foo(Runtime runtime) { super(runtime); } } int fill_struct_from_longs(@size_t long l1, @size_t long l2, @Out Foo[] foo, @size_t long l3); Pointer ptr_malloc(@size_t int size); void ptr_free(Pointer ptr); } static TestLib testlib; static Runtime runtime; public static interface Libc { Pointer calloc(int nmemb, int size); Pointer malloc(int size); void free(Pointer ptr); void cfree(Pointer ptr); } @BeforeClass public static void setUpClass() throws Exception { testlib = TstUtil.loadTestLib(TestLib.class); runtime = Runtime.getRuntime(testlib); // libc = Library.loadLibrary("c", Libc.class); } @AfterClass public static void tearDownClass() throws Exception { } @Before public void setUp() { } @After public void tearDown() { } // @Test // public void testGetPointerArrayArgument() throws Exception { // // Pointer MAGIC0 = new Pointer(0xdeadbeef); // Pointer MAGIC1 = new Pointer(0xcafebabe); // Pointer[] array = { MAGIC0, MAGIC1 }; // // assertEquals("Incorrect Pointer at index 0", MAGIC0, // testlib.ptr_return_array_element(array, 0)); // assertEquals("Incorrect Pointer at index 1", MAGIC1, // testlib.ptr_return_array_element(array, 1)); // } // @Test // public void testSetPointerArrayArgument() throws Exception { // // Pointer MAGIC0 = new Pointer(0xdeadbeef); // Pointer MAGIC1 = new Pointer(0xcafebabe); // Pointer[] array = { MAGIC0, MAGIC1 }; // // testlib.ptr_set_array_element(array, 0, MAGIC1); // testlib.ptr_set_array_element(array, 1, MAGIC0); // assertEquals("Pointer at index 0 not set", MAGIC1, array[0]); // assertEquals("Pointer at index 1 not set", MAGIC0, array[1]); // } // // @Test // public void testLongPointerValue() throws Exception { // long MAGIC0 = 0xdeadbeefL | (Address.SIZE == 64 ? (0xfee1deadL << 32) : 0L); // assertEquals("Pointer value not equal", MAGIC0, new Pointer(MAGIC0).nativeAddress()); // } static final int SIZE = 128; @Test public void testPointerSetByte() { Pointer p = testlib.ptr_malloc(SIZE); byte MAGIC = (byte) 0xFE; for (int i = 0; i < SIZE; ++i) { p.putByte(i, MAGIC); assertEquals("Byte not set at offset " + i, MAGIC, testlib.ptr_ret_int8_t(p, i)); } } @Test public void testPointerSetShort() { Pointer p = testlib.ptr_malloc(SIZE); short MAGIC = (short) 0xFEE1; for (int i = 0; i < (SIZE - 1); i += 2) { p.putShort(i, MAGIC); assertEquals("Short not set at offset " + i, MAGIC, testlib.ptr_ret_int16_t(p, i)); } } @Test public void testPointerSetInt() { Pointer p = testlib.ptr_malloc(SIZE); int MAGIC = (int) 0xFEE1DEAD; for (int i = 0; i < (SIZE - 3); i += 4) { p.putInt(i, MAGIC); assertEquals("Integer not set at offset " + i, MAGIC, testlib.ptr_ret_int32_t(p, i)); } } @Test public void testPointerSetLongLong() { Pointer p = testlib.ptr_malloc(SIZE); long MAGIC = 0xFEE1DEADABCDEF12L; final long l = MAGIC; byte[] bytes = runtime.byteOrder().equals(ByteOrder.BIG_ENDIAN) ? new byte[]{ (byte) (l >>> 56), (byte) (l >>> 48), (byte) (l >>> 40), (byte) (l >>> 32), (byte) (l >>> 24), (byte) (l >>> 16), (byte) (l >>> 8), (byte) (l >>> 0) } : new byte[]{ (byte) (l >>> 0), (byte) (l >>> 8), (byte) (l >>> 16), (byte) (l >>> 24), (byte) (l >>> 32), (byte) (l >>> 40), (byte) (l >>> 48), (byte) (l >>> 56) }; for (int i = 0; i < (SIZE - 7); i += 8) { p.putLongLong(i, MAGIC); for (int idx = 0; idx < 8; ++idx) { assertEquals("incorrect byte value at offset= " + i + " idx=" + idx, bytes[idx], p.getByte(i + idx)); } assertEquals("Long not set at offset " + i, MAGIC, testlib.ptr_ret_int64_t(p, i)); } } @Test public void testPointerSetFloat() { Pointer p = testlib.ptr_malloc(SIZE); float MAGIC = (float) 0xFEE1DEADABCDEF12L; for (int i = 0; i < (SIZE - 3); i += 4) { p.putFloat(i, MAGIC); assertEquals("Float not set at offset " + i, MAGIC, testlib.ptr_ret_float(p, i), 0.00001); } } @Test public void testPointerSetDouble() { Pointer p = testlib.ptr_malloc(SIZE); double MAGIC = (double) 0xFEE1DEADABCDEF12L; long l = Double.doubleToRawLongBits(MAGIC); byte[] bytes = runtime.byteOrder().equals(ByteOrder.BIG_ENDIAN) ? new byte[]{ (byte) (l >>> 56), (byte) (l >>> 48), (byte) (l >>> 40), (byte) (l >>> 32), (byte) (l >>> 24), (byte) (l >>> 16), (byte) (l >>> 8), (byte) (l >>> 0) } : new byte[]{ (byte) (l >>> 0), (byte) (l >>> 8), (byte) (l >>> 16), (byte) (l >>> 24), (byte) (l >>> 32), (byte) (l >>> 40), (byte) (l >>> 48), (byte) (l >>> 56) }; p.putDouble(0, MAGIC); for (int i = 0; i < 8; ++i) { assertEquals("incorrect byte value at idx=" + i, bytes[i], p.getByte(i)); } for (int i = 0; i < (SIZE - 7); i += 8) { p.putDouble(i, MAGIC); assertEquals("Double not set at offset " + i, MAGIC, testlib.ptr_ret_double(p, i), 0.0001E16); } } @Test public void testPointerGetByte() { Pointer p = testlib.ptr_malloc(SIZE); byte MAGIC = (byte) 0xFE; for (int i = 0; i < SIZE; ++i) { testlib.ptr_set_int8_t(p, i, MAGIC); assertEquals("Byte not set at offset " + i, MAGIC, p.getByte(i)); } } @Test public void testPointerGetShort() { Pointer p = testlib.ptr_malloc(SIZE); short MAGIC = (short) 0xFEE1; for (int i = 0; i < SIZE - 1; i += 2) { testlib.ptr_set_int16_t(p, i, MAGIC); assertEquals("Short not set at offset " + i, MAGIC, p.getShort(i)); } } @Test public void testPointerGetInt() { Pointer p = testlib.ptr_malloc(SIZE); int MAGIC = (int) 0xFEE1DEAD; for (int i = 0; i < SIZE - 3; i += 4) { testlib.ptr_set_int32_t(p, i, MAGIC); assertEquals("Integer not set at offset " + i, MAGIC, p.getInt(i)); } } @Test public void testPointerGetLongLong() { Pointer p = testlib.ptr_malloc(SIZE); long MAGIC = 0xFEE1DEADABCDEF12L; for (int i = 0; i < SIZE - 7; i += 8) { testlib.ptr_set_int64_t(p, i, MAGIC); assertEquals("Long not set at offset " + i, MAGIC, p.getLongLong(i)); } } @Test public void testPointerGetFloat() { Pointer p = testlib.ptr_malloc(SIZE); float MAGIC = (float) 0xFEE1DEADABCDEF12L; for (int i = 0; i < (SIZE - 3); i += 4) { testlib.ptr_set_float(p, i, MAGIC); assertEquals("Float not set at offset " + i, MAGIC, p.getFloat(i), 0.0001); } } @Test public void testPointerGetDouble() { Pointer p = testlib.ptr_malloc(SIZE); double MAGIC = (double) 0xFEE1DEADABCDEF12L; for (int i = 0; i < (SIZE - 7); i += 8) { testlib.ptr_set_double(p, i, MAGIC); assertEquals("Double not set at offset " + i, MAGIC, p.getDouble(i), 0.00001); } } @Test public void testMalloc() { Pointer[] pointers = new Pointer[1024]; for (int i = 0; i < pointers.length; ++i) { pointers[i] = testlib.ptr_malloc(SIZE); } for (int i = 0; i < pointers.length; ++i) { testlib.ptr_free(pointers[i]); } } @Test public void testP5() { Pointer[] p = new Pointer[5]; long[] v = { 1, 2, 3, 4, 5 }; for (int i = 0; i < p.length; ++i) { if ((i % 2) == 0) { p[i] = Memory.allocate(Runtime.getRuntime(testlib), 8); } else { p[i] = Memory.allocateDirect(Runtime.getRuntime(testlib), 8); } p[i].putLongLong(0, v[i]); } testlib.ptr_reverse_l5(p[0], p[1], p[2], p[3], p[4]); for (int i = 0; i < p.length; ++i) { assertEquals("not same value for pointer " + (i + 1), v[v.length - i - 1], p[i].getLongLong(0)); } } @Test public void testP6() { Pointer[] p = new Pointer[6]; long[] v = { 1, 2, 3, 4, 5, 6}; for (int i = 0; i < p.length; ++i) { if ((i % 2) == 0) { p[i] = Memory.allocate(Runtime.getRuntime(testlib), 8); } else { p[i] = Memory.allocateDirect(Runtime.getRuntime(testlib), 8); } p[i].putLongLong(0, v[i]); } testlib.ptr_reverse_l6(p[0], p[1], p[2], p[3], p[4], p[5]); for (int i = 0; i < p.length; ++i) { assertEquals("not same value for pointer " + (i + 1), v[v.length - i - 1], p[i].getLongLong(0)); } } @Test public void nullTerminatedStringArray() { Runtime runtime = Runtime.getRuntime(testlib); Pointer[] array = new Pointer[10]; String[] in = new String[array.length]; for (int i = 0; i < array.length; i++) { array[i] = Memory.allocateDirect(runtime, 128); array[i].putString(0, in[i] = Integer.toString(i), 128, Charset.defaultCharset()); } Pointer memory = Memory.allocateDirect(runtime, (2 * array.length + 1) * runtime.addressSize(), true); memory.put(array.length * runtime.addressSize(), array, 0, array.length); String[] out = memory.getNullTerminatedStringArray(array.length * runtime.addressSize()); assertArrayEquals(in, out); } @Test public void nullTerminatedPointerArray() { Runtime runtime = Runtime.getRuntime(testlib); Pointer[] array = new Pointer[10]; String[] in = new String[array.length]; for (int i = 0; i < array.length; i++) { array[i] = Memory.allocateDirect(runtime, 128); array[i].putString(0, in[i] = Integer.toString(i), 128, Charset.defaultCharset()); } Pointer memory = Memory.allocateDirect(runtime, (2 * array.length + 1) * runtime.addressSize(), true); memory.put(array.length * runtime.addressSize(), array, 0, array.length); Pointer[] out = memory.getNullTerminatedPointerArray(array.length * runtime.addressSize()); assertArrayEquals(array, out); } @Test public void testAddressSetByte() { Pointer p = testlib.ptr_malloc(SIZE); byte MAGIC = (byte) 0xFE; for (int i = 0; i < SIZE; ++i) { p.putByte(i, MAGIC); assertEquals("Byte not set at offset " + i, MAGIC, testlib.ptr_ret_int8_t(Address.valueOf(p.address()), i)); } } @Test public void pointerArrayGetElement() { Pointer[] ary = new Pointer[10]; Pointer p1 = ary[0] = runtime.getMemoryManager().newPointer(0xdeadbeef & runtime.addressMask()); Pointer p2 = ary[9] = runtime.getMemoryManager().newPointer(0xfee1dead & runtime.addressMask()); assertEquals(p1, testlib.ptr_return_array_element(ary, 0)); assertEquals(p2, testlib.ptr_return_array_element(ary, 9)); } @Test public void pointerArraySetElement() { Pointer[] ary = new Pointer[10]; Pointer p1 = runtime.getMemoryManager().newPointer(0xdeadbeef & runtime.addressMask()); Pointer p2 = runtime.getMemoryManager().newPointer(0xfee1dead & runtime.addressMask()); testlib.ptr_set_array_element(ary, 0, p1); assertEquals(p1, ary[0]); testlib.ptr_set_array_element(ary, 9, p2); assertEquals(p2, ary[9]); } @Test public void mixObjectsAndPrimitives() { TestLib.Foo[] structs = Struct.arrayOf(runtime, TestLib.Foo.class, 1); TestLib.Foo foo = structs[0]; testlib.fill_struct_from_longs(0xdeadL, 0xbeefL, structs, 0x1eefcafe); assertEquals(0xdeadL, foo.l1.get()); assertEquals(0xbeefL, foo.l2.get()); assertEquals(0x1eefcafeL, foo.l3.get()); } // @Test // public void testLibcMalloc() { // Pointer p = libc.malloc(SIZE); // libc.free(p); // } } jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/ResultConverterTest.java000077500000000000000000000117571316720554100253240ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; import jnr.ffi.mapper.*; import java.lang.annotation.Annotation; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.HashMap; import java.util.Map; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; /** * * @author wayne */ public class ResultConverterTest { public static final class TestType { public final String str; public TestType(String str) { this.str = str; } } public static interface TestLib { TestType string_duplicate(CharSequence cs); void cfree(Pointer ptr); } public static interface Libc { Pointer calloc(int nmemb, int size); Pointer malloc(int size); void free(Pointer ptr); void cfree(Pointer ptr); } public static final class TestTypeResultConverter implements FromNativeConverter { public Class nativeType() { return Pointer.class; } public TestType fromNative(Pointer nativeValue, FromNativeContext context) { return new TestType(nativeValue.getString(0)); } } static final TypeMapper mapper = new TypeMapper() { public FromNativeConverter getFromNativeConverter(Class type) { if (TestType.class == type) { return new TestTypeResultConverter(); } return null; } public ToNativeConverter getToNativeConverter(Class type) { return null; } }; static TestLib testlib; static Runtime runtime; public ResultConverterTest() { } @BeforeClass public static void setUpClass() throws Exception { Map options = new HashMap(); options.put(LibraryOption.TypeMapper, mapper); System.setProperty("jaffl.compiler.dump", "true"); testlib = TstUtil.loadTestLib(TestLib.class, options); runtime = Runtime.getRuntime(testlib); } @AfterClass public static void tearDownClass() throws Exception { } @Before public void setUp() { } @After public void tearDown() { } // TODO add test methods here. // The methods must be annotated with annotation @Test. For example: // // @Test // public void hello() {} @Test public void testCustomResult() { final String MAGIC = "test"; TestType t = testlib.string_duplicate(MAGIC); assertNotNull(t); assertEquals("contents not set", MAGIC, t.str); } @Retention(RetentionPolicy.RUNTIME) public @interface PosixError { } @FromNativeConverter.NoContext public static final class PosixErrorConverter implements FromNativeConverter { public final Integer fromNative(Integer nativeValue, FromNativeContext context) { if (nativeValue < 0) { throw new RuntimeException("posix error!"); } return nativeValue; } public Class nativeType() { return Integer.class; } } static final SignatureTypeMapper posixTypeMapper = new AbstractSignatureTypeMapper() { public FromNativeConverter getFromNativeConverter(SignatureType type, FromNativeContext context) { if (int.class == type.getDeclaredType()) { for (Annotation a : context.getAnnotations()) { if (a instanceof PosixError) { return new PosixErrorConverter(); } } } return null; } public ToNativeConverter getToNativeConverter(SignatureType type, ToNativeContext context) { return null; } }; public static interface Posix { @PosixError int ret_int32_t(int v); } @Test public void testPosixError() { Map options = new HashMap(); options.put(LibraryOption.TypeMapper, posixTypeMapper); Posix posix = TstUtil.loadTestLib(Posix.class, options); assertEquals(1, posix.ret_int32_t(1)); try { posix.ret_int32_t(-1); } catch (RuntimeException re) { System.out.println(re); } } } jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/StringArrayTest.java000066400000000000000000000066331316720554100244150ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; import jnr.ffi.annotations.In; import jnr.ffi.annotations.Out; import java.nio.charset.Charset; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; /** * * @author wayne */ public class StringArrayTest { public StringArrayTest() { } public static interface TestLib { String ptr_return_array_element(@In String[] array, int index); void ptr_set_array_element(@Out String[] array, int index, Pointer value); String ptr_return_array_element(@In CharSequence[] array, int index); } static TestLib testlib; static Runtime runtime; @BeforeClass public static void setUpClass() throws Exception { testlib = TstUtil.loadTestLib(TestLib.class); runtime = Runtime.getRuntime(testlib); } @AfterClass public static void tearDownClass() throws Exception { } @Before public void setUp() { } @After public void tearDown() { } // TODO add test methods here. // The methods must be annotated with annotation @Test. For example: // // @Test // public void hello() {} @Test public void lastElementOfStringArrayShouldBeNull() { String[] strings = { "test" }; String result = testlib.ptr_return_array_element(strings, 1); assertNull("last element of string array was not null", result); } @Test public void lastElementOfCharSequenceArrayShouldBeNull() { CharSequence[] strings = { "test" }; String result = testlib.ptr_return_array_element(strings, 1); assertNull("last element of string array was not null", result); } @Test public void firstElementOfStringArrayShouldNotBeNull() { final String MAGIC = "test"; String[] strings = { MAGIC }; assertNotNull(testlib.ptr_return_array_element(strings, 0)); } @Test public void firstElementOfStringArrayShouldEqualOriginalValue() { final String MAGIC = "test"; String[] strings = { MAGIC }; assertEquals(MAGIC, testlib.ptr_return_array_element(strings, 0)); } @Test public void elementsSetByNativeCodeShouldBeReloaded() { final String MAGIC = "test"; String[] strings = new String[1]; Pointer ptr = Memory.allocateDirect(runtime, 1024); ptr.putString(0, MAGIC, 1024, Charset.defaultCharset()); testlib.ptr_set_array_element(strings, 0, ptr); assertEquals(MAGIC, strings[0]); } @Test public void lastIndexOfSparseStringArrayShouldNotBeNull() { String[] strings = { null, "test" }; String result = testlib.ptr_return_array_element(strings, 1); assertNotNull("last element of string array was null", result); } }jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/StringTest.java000066400000000000000000000075001316720554100234100ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; import jnr.ffi.annotations.In; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; /** * * @author wayne */ public class StringTest { public StringTest() { } public static interface TestLib { boolean string_equals(String s1, String s2); boolean string_equals(CharSequence s1, byte[] s2); void string_set(StringBuffer dst, CharSequence src); void string_set(StringBuilder dst, CharSequence src); void string_concat(StringBuilder dst, CharSequence src); void string_concat(StringBuffer dst, CharSequence src); String ptr_return_array_element(@In String[] array, int index); } static TestLib testlib; @BeforeClass public static void setUpClass() throws Exception { testlib = TstUtil.loadTestLib(TestLib.class); } @AfterClass public static void tearDownClass() throws Exception { } @Before public void setUp() { } @After public void tearDown() { } @Test public void testReadOnlyString() { String MAGIC = "deadbeef\u0000"; assertTrue("String did not equal byte array", testlib.string_equals(MAGIC, MAGIC.getBytes())); assertTrue("StringBuffer did not equal byte array", testlib.string_equals(new StringBuffer(MAGIC), MAGIC.getBytes())); assertTrue("StringBuilder did not equal byte array", testlib.string_equals(new StringBuilder(MAGIC), MAGIC.getBytes())); } @Test public void testSetStringBuffer() { String MAGIC = "deadbeef"; StringBuffer buffer = new StringBuffer(1024); testlib.string_set(buffer, MAGIC); assertEquals("StringBuffer was not set", MAGIC, buffer.toString()); } @Test public void testSetStringBuilder() { String MAGIC = "deadbeef"; StringBuilder buffer = new StringBuilder(1024); testlib.string_set(buffer, MAGIC); assertEquals("StringBuilder was not set", MAGIC, buffer.toString()); } @Test public void testStringBufferAppend() { String ORIG = "test "; String MAGIC = "deadbeef"; StringBuffer buffer = new StringBuffer(1024); buffer.append(ORIG); testlib.string_concat(buffer, MAGIC); assertEquals("StringBuilder was not set", ORIG + MAGIC, buffer.toString()); } @Test public void testStringBuilderAppend() { String ORIG = "test "; String MAGIC = "deadbeef"; StringBuilder buffer = new StringBuilder(1024); buffer.append(ORIG); testlib.string_concat(buffer, MAGIC); assertEquals("StringBuilder was not set", ORIG + MAGIC, buffer.toString()); } @Test public void testStringParams() { assertTrue("strings should be equal", testlib.string_equals("test", "test")); assertFalse("strings should not be equal", testlib.string_equals("test", "deadbeef")); } @Test public void stringResult() { final String MAGIC = "deadbeef"; assertEquals(MAGIC, testlib.ptr_return_array_element(new String[] { MAGIC }, 0)); } } jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/TstUtil.java000066400000000000000000000037231316720554100227150ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; import jnr.ffi.provider.FFIProvider; import java.nio.ByteBuffer; import java.util.Collections; import java.util.Map; public final class TstUtil { private TstUtil() {} private static FFIProvider provider; private static String libname = "test"; public static void setProvider(FFIProvider provider) { TstUtil.provider = provider; } public static void setPath(String path) { TstUtil.libname = path; } public static interface HelperLib { Pointer ptr_from_buffer(ByteBuffer buf); } public static T loadTestLib(Class interfaceClass) { final Map options = Collections.emptyMap(); return loadTestLib(interfaceClass, options); } public static T loadTestLib(Class interfaceClass, Map options) { LibraryLoader loader = (provider != null ? provider : FFIProvider.getSystemProvider()).createLibraryLoader(interfaceClass); loader.library(libname); for (Map.Entry option : options.entrySet()) { loader.option(option.getKey(), option.getValue()); } return loader.load(); } public static Pointer getDirectBufferPointer(ByteBuffer buf) { return TstUtil.loadTestLib(HelperLib.class).ptr_from_buffer(buf); } } jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/TypeDefinitionTest.java000066400000000000000000000044061316720554100250760ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi; import jnr.ffi.annotations.LongLong; import jnr.ffi.types.*; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; /** * */ public class TypeDefinitionTest { public TypeDefinitionTest() { } public static interface TestLib { public @int8_t int add_int8_t(@int8_t int i1, @int8_t int i2); public @int8_t int add_int8_t(@int8_t Integer i1, @int8_t int i2); public @int8_t Long add_int8_t(@int8_t Long i1, @int8_t Integer i2); public int add_uint8_t(@u_int8_t int i1, @u_int8_t int i2); public int ret_uint8_t(@u_int8_t int i1); public @u_int32_t long ret_uint32_t(@u_int32_t long i1); public @u_int32_t short ret_uint32_t(@u_int32_t byte i1); public void ret_long(@size_t int i1); } static TestLib testlib; @BeforeClass public static void setUpClass() throws Exception { testlib = TstUtil.loadTestLib(TestLib.class); } @AfterClass public static void tearDownClass() throws Exception { testlib = null; } @Test public void doNothing() { } @Test public void returnUnsigned8() { int i1 = 0xdead0001; // when passed to the native function, only the lowest 8 bits are passed assertEquals("incorrect value returned", 1, testlib.ret_uint8_t(i1)); } @Test public void addUnsigned8() { int i1 = 0xdead0001; int i2 = 0xbeef0002; // when passed to the native function, only the lowest 8 bits are passed assertEquals("did not add correctly", 3, testlib.add_uint8_t(i1, i2)); } } jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/VarargsTest.java000066400000000000000000000044741316720554100235560ustar00rootroot00000000000000package jnr.ffi; import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import jnr.ffi.annotations.Encoding; import jnr.ffi.annotations.Meta; import jnr.ffi.provider.FFIProvider; import jnr.ffi.types.size_t; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; public class VarargsTest { public static interface C { public int snprintf(Pointer buffer, @size_t long bufferSize, String format, Object... varargs); } static C c; @BeforeClass public static void setUpClass() throws Exception { LibraryLoader loader = FFIProvider.getSystemProvider().createLibraryLoader(C.class); c = loader.load(Platform.getNativePlatform().getStandardCLibraryName()); } @AfterClass public static void tearDownClass() throws Exception { c = null; } @Test public void testSizeT() { Pointer ptr = Runtime.getRuntime(c).getMemoryManager().allocate(5000); int size = c.snprintf(ptr, 5000, "%zu", size_t.class, 12345); Assert.assertEquals(5, size); String result = ptr.getString(0, size, Charset.defaultCharset()); Assert.assertEquals("12345", result); } @Test public void testMetaAscii() throws UnsupportedEncodingException { Pointer ptr = Runtime.getRuntime(c).getMemoryManager().allocate(5000); int size = c.snprintf(ptr, 5000, "%s", AsciiEncoding.class, "\u7684"); Assert.assertEquals(1, size); String result = ptr.getString(0, size, Charset.forName("ASCII")); String expected = new String("\u7684".getBytes("ASCII"), "ASCII"); Assert.assertEquals(expected, result); } @Test public void testMetaUtf8() throws UnsupportedEncodingException { Pointer ptr = Runtime.getRuntime(c).getMemoryManager().allocate(5000); int size = c.snprintf(ptr, 5000, "%s", UTF8Encoding.class, "\u7684"); Assert.assertEquals(3, size); String result = ptr.getString(0, size, Charset.forName("UTF-8")); String expected = new String("\u7684".getBytes("UTF-8"), "UTF-8"); Assert.assertEquals(expected, result); } @Meta @Encoding(value="ASCII") public static @interface AsciiEncoding { } @Meta @Encoding(value="UTF-8") public static @interface UTF8Encoding { } } jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/byref/000077500000000000000000000000001316720554100215445ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/byref/AddressByReferenceTest.java000066400000000000000000000065261316720554100267570ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.byref; import jnr.ffi.TstUtil; import jnr.ffi.Address; import jnr.ffi.annotations.In; import jnr.ffi.annotations.Out; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; /** * * @author wayne */ public class AddressByReferenceTest { public AddressByReferenceTest() { } @BeforeClass public static void setUpClass() throws Exception { } @AfterClass public static void tearDownClass() throws Exception { } @Before public void setUp() { } @After public void tearDown() { } public static interface TestLib { Address ptr_ret_pointer(AddressByReference p, int offset); void ptr_set_pointer(AddressByReference p, int offset, Address value); } public static interface TestLibInOnly { Address ptr_ret_pointer(@In AddressByReference p, int offset); void ptr_set_pointer(@In AddressByReference p, int offset, Address value); } public static interface TestLibOutOnly { Address ptr_ret_pointer(@Out AddressByReference p, int offset); void ptr_set_pointer(@Out AddressByReference p, int offset, Address value); } @Test public void inOnlyReferenceSet() { TestLibInOnly lib = TstUtil.loadTestLib(TestLibInOnly.class); final Address MAGIC = Address.valueOf(0xdeadbeef); AddressByReference ref = new AddressByReference(MAGIC); assertEquals("Wrong value passed", MAGIC, lib.ptr_ret_pointer(ref, 0)); } @Test public void inOnlyIntReferenceNotWritten() { TestLibInOnly lib = TstUtil.loadTestLib(TestLibInOnly.class); final Address MAGIC = Address.valueOf(0xdeadbeefL); AddressByReference ref = new AddressByReference(MAGIC); lib.ptr_set_pointer(ref, 0, Address.valueOf(0)); assertEquals("Int reference written when it should not be", MAGIC, ref.getValue()); } @Test public void outOnlyIntReferenceNotRead() { TestLibOutOnly lib = TstUtil.loadTestLib(TestLibOutOnly.class); final Address MAGIC = Address.valueOf(0xdeadbeef); AddressByReference ref = new AddressByReference(MAGIC); assertTrue("Reference value passed to native code when it should not be", !MAGIC.equals(lib.ptr_ret_pointer(ref, 0))); } @Test public void outOnlyIntReferenceGet() { TestLibOutOnly lib = TstUtil.loadTestLib(TestLibOutOnly.class); final Address MAGIC = Address.valueOf(0xdeadbeef); AddressByReference ref = new AddressByReference(Address.valueOf(0)); lib.ptr_set_pointer(ref, 0, MAGIC); assertEquals("Reference value not set", MAGIC, ref.getValue()); } } jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/byref/ByteByReferenceTest.java000066400000000000000000000062411316720554100262670ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.byref; import jnr.ffi.TstUtil; import jnr.ffi.annotations.In; import jnr.ffi.annotations.Out; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; /** * */ public class ByteByReferenceTest { public ByteByReferenceTest() { } @BeforeClass public static void setUpClass() throws Exception { } @AfterClass public static void tearDownClass() throws Exception { } @Before public void setUp() { } @After public void tearDown() { } public static interface TestLib { byte ptr_ret_int8_t(ByteByReference p, int offset); void ptr_set_int_t(ByteByReference p, int offset, byte value); } public static interface TestLibInOnly { byte ptr_ret_int8_t(@In ByteByReference p, int offset); void ptr_set_int8_t(@In ByteByReference p, int offset, byte value); } public static interface TestLibOutOnly { byte ptr_ret_int8_t(@Out ByteByReference p, int offset); void ptr_set_int8_t(@Out ByteByReference p, int offset, byte value); } @Test public void inOnlyReferenceSet() { TestLibInOnly lib = TstUtil.loadTestLib(TestLibInOnly.class); final byte MAGIC = (byte) 0xef; ByteByReference ref = new ByteByReference(MAGIC); assertEquals("Wrong value passed", MAGIC, lib.ptr_ret_int8_t(ref, 0)); } @Test public void inOnlyByteReferenceNotWritten() { TestLibInOnly lib = TstUtil.loadTestLib(TestLibInOnly.class); final byte MAGIC = (byte) 0xef; ByteByReference ref = new ByteByReference(MAGIC); lib.ptr_set_int8_t(ref, 0, (byte) 0); assertEquals("Int reference written when it should not be", Byte.valueOf(MAGIC), ref.getValue()); } @Test public void outOnlyByteReferenceNotRead() { TestLibOutOnly lib = TstUtil.loadTestLib(TestLibOutOnly.class); final byte MAGIC = (byte) 0xef; ByteByReference ref = new ByteByReference(MAGIC); assertTrue("Reference value passed to native code when it should not be", MAGIC != lib.ptr_ret_int8_t(ref, 0)); } @Test public void outOnlyByteReferenceGet() { TestLibOutOnly lib = TstUtil.loadTestLib(TestLibOutOnly.class); final byte MAGIC = (byte) 0xef; ByteByReference ref = new ByteByReference((byte) 0); lib.ptr_set_int8_t(ref, 0, MAGIC); assertEquals("Reference value not set", Byte.valueOf(MAGIC), ref.getValue()); } }jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/byref/IntByReferenceTest.java000066400000000000000000000061701316720554100261170ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.byref; import jnr.ffi.TstUtil; import jnr.ffi.annotations.In; import jnr.ffi.annotations.Out; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; /** * */ public class IntByReferenceTest { public IntByReferenceTest() { } @BeforeClass public static void setUpClass() throws Exception { } @AfterClass public static void tearDownClass() throws Exception { } @Before public void setUp() { } @After public void tearDown() { } public static interface TestLib { int ptr_ret_int32_t(IntByReference p, int offset); void ptr_set_int32_t(IntByReference p, int offset, int value); } public static interface TestLibInOnly { int ptr_ret_int32_t(@In IntByReference p, int offset); void ptr_set_int32_t(@In IntByReference p, int offset, int value); } public static interface TestLibOutOnly { int ptr_ret_int32_t(@Out IntByReference p, int offset); void ptr_set_int32_t(@Out IntByReference p, int offset, int value); } @Test public void inOnlyIntReferenceSet() { TestLibInOnly lib = TstUtil.loadTestLib(TestLibInOnly.class); final int MAGIC = 0xdeadbeef; IntByReference ref = new IntByReference(MAGIC); assertEquals("Wrong value passed", MAGIC, lib.ptr_ret_int32_t(ref, 0)); } @Test public void inOnlyIntReferenceNotWritten() { TestLibInOnly lib = TstUtil.loadTestLib(TestLibInOnly.class); final int MAGIC = 0xdeadbeef; IntByReference ref = new IntByReference(MAGIC); lib.ptr_set_int32_t(ref, 0, 0); assertEquals("Int reference written when it should not be", Integer.valueOf(MAGIC), ref.getValue()); } @Test public void outOnlyIntReferenceNotRead() { TestLibOutOnly lib = TstUtil.loadTestLib(TestLibOutOnly.class); final int MAGIC = 0xdeadbeef; IntByReference ref = new IntByReference(MAGIC); assertTrue("Reference value passed to native code when it should not be", MAGIC != lib.ptr_ret_int32_t(ref, 0)); } @Test public void outOnlyIntReferenceGet() { TestLibOutOnly lib = TstUtil.loadTestLib(TestLibOutOnly.class); final int MAGIC = 0xdeadbeef; IntByReference ref = new IntByReference(0); lib.ptr_set_int32_t(ref, 0, MAGIC); assertEquals("Reference value not set", Integer.valueOf(MAGIC), ref.getValue()); } }jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/byref/PointerByReferenceTest.java000066400000000000000000000072101316720554100270010ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.byref; import jnr.ffi.Library; import jnr.ffi.Memory; import jnr.ffi.Pointer; import jnr.ffi.Runtime; import jnr.ffi.TstUtil; import jnr.ffi.annotations.In; import jnr.ffi.annotations.Out; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; /** * */ public class PointerByReferenceTest { public PointerByReferenceTest() { } @BeforeClass public static void setUpClass() throws Exception { } @AfterClass public static void tearDownClass() throws Exception { } @Before public void setUp() { } @After public void tearDown() { } public static interface TestLib { Pointer ptr_ret_pointer(PointerByReference p, int offset); void ptr_set_pointer(PointerByReference p, int offset, Pointer value); } public static interface TestLibInOnly { Pointer ptr_ret_pointer(@In PointerByReference p, int offset); void ptr_set_pointer(@In PointerByReference p, int offset, Pointer value); } public static interface TestLibOutOnly { Pointer ptr_ret_pointer(@Out PointerByReference p, int offset); void ptr_set_pointer(@Out PointerByReference p, int offset, Pointer value); } @Test public void inOnlyReferenceSet() { TestLibInOnly lib = TstUtil.loadTestLib(TestLibInOnly.class); Runtime runtime = Runtime.getRuntime(lib); final Pointer MAGIC = Memory.allocateDirect(runtime, 123); PointerByReference ref = new PointerByReference(MAGIC); assertEquals("Wrong value passed", MAGIC, lib.ptr_ret_pointer(ref, 0)); } @Test public void inOnlyIntReferenceNotWritten() { TestLibInOnly lib = TstUtil.loadTestLib(TestLibInOnly.class); Runtime runtime = Runtime.getRuntime(lib); final Pointer MAGIC = Memory.allocateDirect(runtime, 123); PointerByReference ref = new PointerByReference(MAGIC); lib.ptr_set_pointer(ref, 0, null); assertEquals("Int reference written when it should not be", MAGIC, ref.getValue()); } @Test public void outOnlyIntReferenceNotRead() { TestLibOutOnly lib = TstUtil.loadTestLib(TestLibOutOnly.class); Runtime runtime = Runtime.getRuntime(lib); final Pointer MAGIC = Memory.allocateDirect(runtime, 123); PointerByReference ref = new PointerByReference(MAGIC); assertNotSame("Reference value passed to native code when it should not be", MAGIC, lib.ptr_ret_pointer(ref, 0)); } @Test public void outOnlyIntReferenceGet() { TestLibOutOnly lib = TstUtil.loadTestLib(TestLibOutOnly.class); Runtime runtime = Runtime.getRuntime(lib); final Pointer MAGIC = Memory.allocateDirect(runtime, 123); PointerByReference ref = new PointerByReference(Memory.allocateDirect(runtime, 1)); lib.ptr_set_pointer(ref, 0, MAGIC); assertEquals("Reference value not set", MAGIC, ref.getValue()); } }jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/mapper/000077500000000000000000000000001316720554100217215ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/mapper/AnnotatedMappedTypeTest.java000066400000000000000000000044501316720554100273350ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.mapper; import jnr.ffi.*; import jnr.ffi.Runtime; import jnr.ffi.annotations.In; import jnr.ffi.annotations.LongLong; import jnr.ffi.annotations.Out; import jnr.ffi.provider.converters.EnumSetConverter; import jnr.ffi.types.size_t; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import static junit.framework.TestCase.*; public class AnnotatedMappedTypeTest { public static final class CustomPointer { private final Pointer pointer; public CustomPointer(Pointer pointer) { this.pointer = pointer; } @ToNativeConverter.ToNative(nativeType = jnr.ffi.Pointer.class) public static Pointer toNative(CustomPointer value, ToNativeContext context) { return value != null ? value.pointer : null; } @FromNativeConverter.FromNative(nativeType = jnr.ffi.Pointer.class) public static CustomPointer fromNative(Pointer value, FromNativeContext context) { return value != null ? new CustomPointer(value) : null; } } public static interface TestLib { CustomPointer ptr_malloc(@size_t int size); void ptr_free(CustomPointer ptr); } static TestLib testlib; static Runtime runtime; @BeforeClass public static void setUpClass() throws Exception { testlib = TstUtil.loadTestLib(TestLib.class); runtime = Runtime.getRuntime(testlib); } @Test public void returnsInstanceOfCorrectClass() { assertSame(CustomPointer.class, testlib.ptr_malloc(1).getClass()); } @Test public void toNative() { testlib.ptr_free(testlib.ptr_malloc(1)); } } jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/mapper/CachingTypeMapperTest.java000066400000000000000000000237301316720554100267740ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.mapper; import jnr.ffi.*; import jnr.ffi.Runtime; import jnr.ffi.annotations.In; import jnr.ffi.annotations.Out; import jnr.ffi.provider.converters.EnumSetConverter; import org.junit.Before; import org.junit.Test; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import java.util.Set; import static org.junit.Assert.*; public class CachingTypeMapperTest { public static interface Lib { public static enum Enum1 { A, B; } public static enum Enum2 { A, B; } public int ret_int(); public Set ret_enumset1a(); public Set ret_enumset1b(); public Set ret_enumset2a(); public Set ret_enumset2b(); public Set ret_intset(); public void enumset_param(Set enums); public void annotated_params(@In long[] in, @Out long[] out); public void int_array_params(int[] in, int[] out); public void intset_param(Set bitfield); } private static Method getLibMethod(String name, Class... parameterTypes) { try { return Lib.class.getMethod(name, parameterTypes); } catch (Throwable t) { throw new RuntimeException(t); } } @ToNativeConverter.Cacheable private static final class LongArrayParameterConverter implements ToNativeConverter { @Override public Pointer toNative(long[] value, ToNativeContext context) { return null; } @Override public Class nativeType() { return Pointer.class; } } // Do not mark as cacheable private static final class IntArrayParameterConverter implements ToNativeConverter { @Override public Pointer toNative(int[] value, ToNativeContext context) { return null; } @Override public Class nativeType() { return Pointer.class; } } private static final class TestTypeMapper implements SignatureTypeMapper { public FromNativeConverter getFromNativeConverter(SignatureType type, FromNativeContext context) { FromNativeConverter converter; if (type.getDeclaredType() == Set.class && (converter = EnumSetConverter.getFromNativeConverter(type, context)) != null) { return converter; } else { return null; } } public ToNativeConverter getToNativeConverter(SignatureType type, ToNativeContext context) { ToNativeConverter converter; if (type.getDeclaredType() == Set.class && (converter = EnumSetConverter.getToNativeConverter(type, context)) != null) { return converter; } else if (long[].class == type.getDeclaredType()) { return new LongArrayParameterConverter(); } else if (int[].class == type.getDeclaredType()) { return new IntArrayParameterConverter(); } else { return null; } } @Override public FromNativeType getFromNativeType(SignatureType type, FromNativeContext context) { return FromNativeTypes.create(getFromNativeConverter(type, context)); } @Override public ToNativeType getToNativeType(SignatureType type, ToNativeContext context) { return ToNativeTypes.create(getToNativeConverter(type, context)); } } private static final class CountingTypeMapper implements SignatureTypeMapper { private final Map fromConverterStats = new HashMap(); private final Map toConverterStats = new HashMap(); private final SignatureTypeMapper typeMapper; CountingTypeMapper(SignatureTypeMapper typeMapper) { this.typeMapper = typeMapper; } private void incrementCount(Map stats, Class type) { Integer count = stats.get(type); stats.put(type, count != null ? count + 1 : 1); } @Override public FromNativeType getFromNativeType(SignatureType type, FromNativeContext context) { incrementCount(fromConverterStats, type.getDeclaredType()); return typeMapper.getFromNativeType(type, context); } @Override public ToNativeType getToNativeType(SignatureType type, ToNativeContext context) { incrementCount(toConverterStats, type.getDeclaredType()); return typeMapper.getToNativeType(type, context); } public int getFromNativeCount(Class type) { Integer count = fromConverterStats.get(type); return count != null ? count : 0; } public int getToNativeCount(Class type) { Integer count = toConverterStats.get(type); return count != null ? count : 0; } } private SignatureTypeMapper defaultTypeMapper; @Before public void setUp() { defaultTypeMapper = new CachingTypeMapper(new TestTypeMapper()); } private ToNativeConverter getToNativeConverter(SignatureTypeMapper typeMapper, Method m, int parameterIndex) { ToNativeContext toNativeContext = new MethodParameterContext(Runtime.getSystemRuntime(), m, parameterIndex); SignatureType signatureType = DefaultSignatureType.create(m.getParameterTypes()[parameterIndex], toNativeContext); ToNativeType toNativeType = typeMapper.getToNativeType(signatureType, toNativeContext); return toNativeType != null ? toNativeType.getToNativeConverter() : null; } private FromNativeConverter getFromNativeConverter(SignatureTypeMapper typeMapper, Method m) { FromNativeContext fromNativeContext = new MethodResultContext(Runtime.getSystemRuntime(), m); SignatureType signatureType = DefaultSignatureType.create(m.getReturnType(), fromNativeContext); FromNativeType fromNativeType = typeMapper.getFromNativeType(signatureType, fromNativeContext); return fromNativeType != null ? fromNativeType.getFromNativeConverter() : null; } @Test public void intReturnHasNoConverter() { assertNull(getFromNativeConverter(defaultTypeMapper, getLibMethod("ret_int"))); } @Test public void sameResultTypeHasSameConverter() { FromNativeConverter converter; assertNotNull(converter = getFromNativeConverter(defaultTypeMapper, getLibMethod("ret_enumset1a"))); assertSame(converter, getFromNativeConverter(defaultTypeMapper, getLibMethod("ret_enumset1b"))); } @Test public void differentEnumSet() { FromNativeConverter converter1; assertNotNull(converter1 = getFromNativeConverter(defaultTypeMapper, getLibMethod("ret_enumset1a"))); assertSame(converter1, getFromNativeConverter(defaultTypeMapper, getLibMethod("ret_enumset1b"))); FromNativeConverter converter2; assertNotNull(converter2 = getFromNativeConverter(defaultTypeMapper, getLibMethod("ret_enumset2a"))); assertSame(converter2, getFromNativeConverter(defaultTypeMapper, getLibMethod("ret_enumset2b"))); assertNotSame(converter1, converter2); } @Test public void integerSet() { assertNull(getFromNativeConverter(defaultTypeMapper, getLibMethod("ret_intset"))); } @Test public void differentAnnotations() { ToNativeConverter converter1, converter2; Method m = getLibMethod("annotated_params", long[].class, long[].class); assertNotNull(converter1 = getToNativeConverter(defaultTypeMapper, m, 0)); assertNotNull(converter2 = getToNativeConverter(defaultTypeMapper, m, 1)); assertNotSame(converter1, converter2); } @Test public void uncacheableConverter() { CountingTypeMapper counter; SignatureTypeMapper typeMapper = new CachingTypeMapper(counter = new CountingTypeMapper(new TestTypeMapper())); ToNativeConverter converter1, converter2; Method m = getLibMethod("int_array_params", int[].class, int[].class); assertNotNull(converter1 = getToNativeConverter(typeMapper, m, 0)); assertEquals(1, counter.getToNativeCount(int[].class)); assertNotNull(converter2 = getToNativeConverter(typeMapper, m, 1)); assertEquals(2, counter.getToNativeCount(int[].class)); assertNotSame(converter1, converter2); } @Test public void converterIsCached() { CountingTypeMapper counter; SignatureTypeMapper typeMapper = new CachingTypeMapper(counter = new CountingTypeMapper(new TestTypeMapper())); FromNativeConverter converter1; assertNotNull(converter1 = getFromNativeConverter(typeMapper, getLibMethod("ret_enumset1a"))); assertEquals(1, counter.getFromNativeCount(Set.class)); assertSame(converter1, getFromNativeConverter(typeMapper, getLibMethod("ret_enumset1b"))); assertEquals(1, counter.getFromNativeCount(Set.class)); FromNativeConverter converter2; assertNotNull(converter2 = getFromNativeConverter(typeMapper, getLibMethod("ret_enumset2a"))); assertEquals(2, counter.getFromNativeCount(Set.class)); assertSame(converter2, getFromNativeConverter(typeMapper, getLibMethod("ret_enumset2b"))); assertNotSame(converter1, converter2); assertEquals(2, counter.getFromNativeCount(Set.class)); } } jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/provider/000077500000000000000000000000001316720554100222675ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/provider/InterfaceScannerTest.java000066400000000000000000000017671316720554100272170ustar00rootroot00000000000000package jnr.ffi.provider; import jnr.ffi.TstUtil; import org.junit.Assert; import org.junit.Assume; import org.junit.Test; import java.lang.reflect.Method; import java.util.Collection; public class InterfaceScannerTest { private static final Method SPLITERATOR; static { Method s = null; try { Collection.class.getMethod("spliterator"); } catch (Exception e) { // leave null, tests will be skipped } SPLITERATOR = s; } @Test public void loadTestLib() throws Exception { // If we're on Java 8+, proceed Assume.assumeNotNull(SPLITERATOR); Collection lib = TstUtil.loadTestLib(Collection.class); // spliterator function does not exist in the test lib, so this only works if we're skipping default methods Object spliterator = SPLITERATOR.invoke(lib); Assert.assertNotNull(spliterator); Assert.assertEquals("java.util.Spliterator", spliterator.getClass().getName()); } } jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/struct/000077500000000000000000000000001316720554100217615ustar00rootroot00000000000000jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/struct/AlignmentTest.java000077500000000000000000000453031316720554100254120ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.struct; import jnr.ffi.*; import jnr.ffi.Runtime; import jnr.ffi.struct.AlignmentTest.TestLib.PointerStruct; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; /** * */ public class AlignmentTest { public static interface TestLib { public class PointerStruct extends Struct { public final Signed8 s8 = new Signed8(); public final Pointer p = new Pointer(); public PointerStruct() { super(runtime); } } public class StructAlignment extends Struct { public final u_int8_t f0 = new u_int8_t(); public final u_int16_t f1 = new u_int16_t(); public final u_int32_t f2 = new u_int32_t(); public final u_int64_t f3 = new u_int64_t(); public final Pointer f4 = new Pointer(); public StructAlignment(Alignment alignment) { super(runtime, alignment); } } public int struct_alignment_size_1(); public int struct_alignment_field_offset_1(int field); public int struct_alignment_size_2(); public int struct_alignment_field_offset_2(int field); public int struct_alignment_size_4(); public int struct_alignment_field_offset_4(int field); public int struct_alignment_size_8(); public int struct_alignment_field_offset_8(int field); public int struct_alignment_size_16(); public int struct_alignment_field_offset_16(int field); class InnerStructAlignment1 extends Struct { class InnerStructAlignment2 extends Struct { class InnerStructAlignment3 extends Struct { public final u_int8_t f0 = new u_int8_t(); public final u_int16_t f1 = new u_int16_t(); public final u_int32_t f2 = new u_int32_t(); public final u_int64_t f3 = new u_int64_t(); public final Pointer f4 = new Pointer(); public InnerStructAlignment3(Struct enclosing) { super(runtime, enclosing); } } public final u_int8_t f0 = new u_int8_t(); public final u_int16_t f1 = new u_int16_t(); public final u_int32_t f2 = new u_int32_t(); public final u_int64_t f3 = new u_int64_t(); public final Pointer f4 = new Pointer(); public final InnerStructAlignment3 f5 = inner(new InnerStructAlignment3(this)); public InnerStructAlignment2(Struct enclosing) { super(runtime, enclosing); } } public final u_int8_t f0 = new u_int8_t(); public final u_int16_t f1 = new u_int16_t(); public final u_int32_t f2 = new u_int32_t(); public final u_int64_t f3 = new u_int64_t(); public final Pointer f4 = new Pointer(); public final InnerStructAlignment2 f5 = inner(new InnerStructAlignment2(this)); public InnerStructAlignment1(Alignment alignment) { super(runtime, alignment); } } int inner_struct_alignment_size_1(); int inner_struct_alignment_field_offset_1(int level, int field); int inner_struct_alignment_size_2(); int inner_struct_alignment_field_offset_2(int level, int field); int inner_struct_alignment_size_4(); int inner_struct_alignment_field_offset_4(int level, int field); int inner_struct_alignment_size_8(); int inner_struct_alignment_field_offset_8(int level, int field); int inner_struct_alignment_size_16(); int inner_struct_alignment_field_offset_16(int level, int field); } static TestLib testlib; static Runtime runtime; public AlignmentTest() { } @BeforeClass public static void setUpClass() throws Exception { testlib = TstUtil.loadTestLib(TestLib.class); runtime = Runtime.getRuntime(testlib); } @AfterClass public static void tearDownClass() throws Exception { } @Before public void setUp() { } @After public void tearDown() { } // TODO add test methods here. // The methods must be annotated with annotation @Test. For example: // // @Test // public void hello() {} @Test public void alignPointer() throws Throwable { PointerStruct s = new PointerStruct(); final int SIZE = runtime.addressSize() == 4 ? 8 : 16; assertEquals("Incorrect pointer field alignment", SIZE, Struct.size(s)); } @Test public void alignsStructWhenTheAlignmentValueIs1() { TestLib.StructAlignment s = new TestLib.StructAlignment(new Struct.Alignment(1)); assertEquals("StructAlignment1 size", testlib.struct_alignment_size_1(), Struct.size(s)); assertEquals("f0 offset", testlib.struct_alignment_field_offset_1(0), s.f0.offset()); assertEquals("f1 offset", testlib.struct_alignment_field_offset_1(1), s.f1.offset()); assertEquals("f2 offset", testlib.struct_alignment_field_offset_1(2), s.f2.offset()); assertEquals("f3 offset", testlib.struct_alignment_field_offset_1(3), s.f3.offset()); assertEquals("f4 offset", testlib.struct_alignment_field_offset_1(4), s.f4.offset()); } @Test public void alignsStructWhenTheAlignmentValueIs2() { TestLib.StructAlignment s = new TestLib.StructAlignment(new Struct.Alignment(2)); assertEquals("StructAlignment2 size", testlib.struct_alignment_size_2(), Struct.size(s)); assertEquals("f0 offset", testlib.struct_alignment_field_offset_2(0), s.f0.offset()); assertEquals("f1 offset", testlib.struct_alignment_field_offset_2(1), s.f1.offset()); assertEquals("f2 offset", testlib.struct_alignment_field_offset_2(2), s.f2.offset()); assertEquals("f3 offset", testlib.struct_alignment_field_offset_2(3), s.f3.offset()); assertEquals("f4 offset", testlib.struct_alignment_field_offset_2(4), s.f4.offset()); } @Test public void alignsStructWhenTheAlignmentValueIs4() { TestLib.StructAlignment s = new TestLib.StructAlignment(new Struct.Alignment(4)); assertEquals("StructAlignment4 size", testlib.struct_alignment_size_4(), Struct.size(s)); assertEquals("f0 offset", testlib.struct_alignment_field_offset_4(0), s.f0.offset()); assertEquals("f1 offset", testlib.struct_alignment_field_offset_4(1), s.f1.offset()); assertEquals("f2 offset", testlib.struct_alignment_field_offset_4(2), s.f2.offset()); assertEquals("f3 offset", testlib.struct_alignment_field_offset_4(3), s.f3.offset()); assertEquals("f4 offset", testlib.struct_alignment_field_offset_4(4), s.f4.offset()); } @Test public void alignsStructWhenTheAlignmentValueIs8() { TestLib.StructAlignment s = new TestLib.StructAlignment(new Struct.Alignment(8)); assertEquals("StructAlignment8 size", testlib.struct_alignment_size_8(), Struct.size(s)); assertEquals("f0 offset", testlib.struct_alignment_field_offset_8(0), s.f0.offset()); assertEquals("f1 offset", testlib.struct_alignment_field_offset_8(1), s.f1.offset()); assertEquals("f2 offset", testlib.struct_alignment_field_offset_8(2), s.f2.offset()); assertEquals("f3 offset", testlib.struct_alignment_field_offset_8(3), s.f3.offset()); assertEquals("f4 offset", testlib.struct_alignment_field_offset_8(4), s.f4.offset()); } @Test public void alignsStructWhenTheAlignmentValueIs16() { TestLib.StructAlignment s = new TestLib.StructAlignment(new Struct.Alignment(16)); assertEquals("StructAlignment16 size", testlib.struct_alignment_size_16(), Struct.size(s)); assertEquals("f0 offset", testlib.struct_alignment_field_offset_16(0), s.f0.offset()); assertEquals("f1 offset", testlib.struct_alignment_field_offset_16(1), s.f1.offset()); assertEquals("f2 offset", testlib.struct_alignment_field_offset_16(2), s.f2.offset()); assertEquals("f3 offset", testlib.struct_alignment_field_offset_16(3), s.f3.offset()); assertEquals("f4 offset", testlib.struct_alignment_field_offset_16(4), s.f4.offset()); } @Test public void alignsInnerStructWhenTheAlignmentValueIs1() { TestLib.InnerStructAlignment1 s = new TestLib.InnerStructAlignment1(new Struct.Alignment(1)); assertEquals("InnerStructAlignment1 size", testlib.inner_struct_alignment_size_1(), Struct.size(s)); assertEquals("f0 offset" , testlib.inner_struct_alignment_field_offset_1(0, 0), s.f0.offset()); assertEquals("f1 offset" , testlib.inner_struct_alignment_field_offset_1(0, 1), s.f1.offset()); assertEquals("f2 offset" , testlib.inner_struct_alignment_field_offset_1(0, 2), s.f2.offset()); assertEquals("f3 offset" , testlib.inner_struct_alignment_field_offset_1(0, 3), s.f3.offset()); assertEquals("f4 offset" , testlib.inner_struct_alignment_field_offset_1(0, 4), s.f4.offset()); assertEquals("f5.f0 offset" , testlib.inner_struct_alignment_field_offset_1(1, 0), s.f5.f0.offset()); assertEquals("f5.f1 offset" , testlib.inner_struct_alignment_field_offset_1(1, 1), s.f5.f1.offset()); assertEquals("f5.f2 offset" , testlib.inner_struct_alignment_field_offset_1(1, 2), s.f5.f2.offset()); assertEquals("f5.f3 offset" , testlib.inner_struct_alignment_field_offset_1(1, 3), s.f5.f3.offset()); assertEquals("f5.f4 offset" , testlib.inner_struct_alignment_field_offset_1(1, 4), s.f5.f4.offset()); assertEquals("f5.f5.f0 offset", testlib.inner_struct_alignment_field_offset_1(2, 0), s.f5.f5.f0.offset()); assertEquals("f5.f5.f1 offset", testlib.inner_struct_alignment_field_offset_1(2, 1), s.f5.f5.f1.offset()); assertEquals("f5.f5.f2 offset", testlib.inner_struct_alignment_field_offset_1(2, 2), s.f5.f5.f2.offset()); assertEquals("f5.f5.f3 offset", testlib.inner_struct_alignment_field_offset_1(2, 3), s.f5.f5.f3.offset()); assertEquals("f5.f5.f4 offset", testlib.inner_struct_alignment_field_offset_1(2, 4), s.f5.f5.f4.offset()); } @Test public void alignsInnerStructWhenTheAlignmentValueIs2() { TestLib.InnerStructAlignment1 s = new TestLib.InnerStructAlignment1(new Struct.Alignment(2)); assertEquals("InnerStructAlignment2 size", testlib.inner_struct_alignment_size_2(), Struct.size(s)); assertEquals("f0 offset" , testlib.inner_struct_alignment_field_offset_2(0, 0), s.f0.offset()); assertEquals("f1 offset" , testlib.inner_struct_alignment_field_offset_2(0, 1), s.f1.offset()); assertEquals("f2 offset" , testlib.inner_struct_alignment_field_offset_2(0, 2), s.f2.offset()); assertEquals("f3 offset" , testlib.inner_struct_alignment_field_offset_2(0, 3), s.f3.offset()); assertEquals("f4 offset" , testlib.inner_struct_alignment_field_offset_2(0, 4), s.f4.offset()); assertEquals("f5.f0 offset" , testlib.inner_struct_alignment_field_offset_2(1, 0), s.f5.f0.offset()); assertEquals("f5.f1 offset" , testlib.inner_struct_alignment_field_offset_2(1, 1), s.f5.f1.offset()); assertEquals("f5.f2 offset" , testlib.inner_struct_alignment_field_offset_2(1, 2), s.f5.f2.offset()); assertEquals("f5.f3 offset" , testlib.inner_struct_alignment_field_offset_2(1, 3), s.f5.f3.offset()); assertEquals("f5.f4 offset" , testlib.inner_struct_alignment_field_offset_2(1, 4), s.f5.f4.offset()); assertEquals("f5.f5.f0 offset", testlib.inner_struct_alignment_field_offset_2(2, 0), s.f5.f5.f0.offset()); assertEquals("f5.f5.f1 offset", testlib.inner_struct_alignment_field_offset_2(2, 1), s.f5.f5.f1.offset()); assertEquals("f5.f5.f2 offset", testlib.inner_struct_alignment_field_offset_2(2, 2), s.f5.f5.f2.offset()); assertEquals("f5.f5.f3 offset", testlib.inner_struct_alignment_field_offset_2(2, 3), s.f5.f5.f3.offset()); assertEquals("f5.f5.f4 offset", testlib.inner_struct_alignment_field_offset_2(2, 4), s.f5.f5.f4.offset()); } @Test public void alignsInnerStructWhenTheAlignmentValueIs4() { TestLib.InnerStructAlignment1 s = new TestLib.InnerStructAlignment1(new Struct.Alignment(4)); assertEquals("InnerStructAlignment4 size", testlib.inner_struct_alignment_size_4(), Struct.size(s)); assertEquals("f1 offset" , testlib.inner_struct_alignment_field_offset_4(0, 1), s.f1.offset()); assertEquals("f0 offset" , testlib.inner_struct_alignment_field_offset_4(0, 0), s.f0.offset()); assertEquals("f2 offset" , testlib.inner_struct_alignment_field_offset_4(0, 2), s.f2.offset()); assertEquals("f3 offset" , testlib.inner_struct_alignment_field_offset_4(0, 3), s.f3.offset()); assertEquals("f4 offset" , testlib.inner_struct_alignment_field_offset_4(0, 4), s.f4.offset()); assertEquals("f5.f0 offset" , testlib.inner_struct_alignment_field_offset_4(1, 0), s.f5.f0.offset()); assertEquals("f5.f1 offset" , testlib.inner_struct_alignment_field_offset_4(1, 1), s.f5.f1.offset()); assertEquals("f5.f2 offset" , testlib.inner_struct_alignment_field_offset_4(1, 2), s.f5.f2.offset()); assertEquals("f5.f3 offset" , testlib.inner_struct_alignment_field_offset_4(1, 3), s.f5.f3.offset()); assertEquals("f5.f4 offset" , testlib.inner_struct_alignment_field_offset_4(1, 4), s.f5.f4.offset()); assertEquals("f5.f5.f0 offset", testlib.inner_struct_alignment_field_offset_4(2, 0), s.f5.f5.f0.offset()); assertEquals("f5.f5.f1 offset", testlib.inner_struct_alignment_field_offset_4(2, 1), s.f5.f5.f1.offset()); assertEquals("f5.f5.f2 offset", testlib.inner_struct_alignment_field_offset_4(2, 2), s.f5.f5.f2.offset()); assertEquals("f5.f5.f3 offset", testlib.inner_struct_alignment_field_offset_4(2, 3), s.f5.f5.f3.offset()); assertEquals("f5.f5.f4 offset", testlib.inner_struct_alignment_field_offset_4(2, 4), s.f5.f5.f4.offset()); } @Test public void alignsInnerStructWhenTheAlignmentValueIs8() { TestLib.InnerStructAlignment1 s = new TestLib.InnerStructAlignment1(new Struct.Alignment(8)); assertEquals("InnerStructAlignment8 size", testlib.inner_struct_alignment_size_8(), Struct.size(s)); assertEquals("f1 offset" , testlib.inner_struct_alignment_field_offset_8(0, 1), s.f1.offset()); assertEquals("f0 offset" , testlib.inner_struct_alignment_field_offset_8(0, 0), s.f0.offset()); assertEquals("f2 offset" , testlib.inner_struct_alignment_field_offset_8(0, 2), s.f2.offset()); assertEquals("f3 offset" , testlib.inner_struct_alignment_field_offset_8(0, 3), s.f3.offset()); assertEquals("f4 offset" , testlib.inner_struct_alignment_field_offset_8(0, 4), s.f4.offset()); assertEquals("f5.f0 offset" , testlib.inner_struct_alignment_field_offset_8(1, 0), s.f5.f0.offset()); assertEquals("f5.f1 offset" , testlib.inner_struct_alignment_field_offset_8(1, 1), s.f5.f1.offset()); assertEquals("f5.f2 offset" , testlib.inner_struct_alignment_field_offset_8(1, 2), s.f5.f2.offset()); assertEquals("f5.f3 offset" , testlib.inner_struct_alignment_field_offset_8(1, 3), s.f5.f3.offset()); assertEquals("f5.f4 offset" , testlib.inner_struct_alignment_field_offset_8(1, 4), s.f5.f4.offset()); assertEquals("f5.f5.f0 offset", testlib.inner_struct_alignment_field_offset_8(2, 0), s.f5.f5.f0.offset()); assertEquals("f5.f5.f1 offset", testlib.inner_struct_alignment_field_offset_8(2, 1), s.f5.f5.f1.offset()); assertEquals("f5.f5.f2 offset", testlib.inner_struct_alignment_field_offset_8(2, 2), s.f5.f5.f2.offset()); assertEquals("f5.f5.f3 offset", testlib.inner_struct_alignment_field_offset_8(2, 3), s.f5.f5.f3.offset()); assertEquals("f5.f5.f4 offset", testlib.inner_struct_alignment_field_offset_8(2, 4), s.f5.f5.f4.offset()); } @Test public void alignsInnerStructWhenTheAlignmentValueIs16() { TestLib.InnerStructAlignment1 s = new TestLib.InnerStructAlignment1(new Struct.Alignment(16)); assertEquals("InnerStructAlignment16 size", testlib.inner_struct_alignment_size_16(), Struct.size(s)); assertEquals("f1 offset" , testlib.inner_struct_alignment_field_offset_16(0, 1), s.f1.offset()); assertEquals("f0 offset" , testlib.inner_struct_alignment_field_offset_16(0, 0), s.f0.offset()); assertEquals("f2 offset" , testlib.inner_struct_alignment_field_offset_16(0, 2), s.f2.offset()); assertEquals("f3 offset" , testlib.inner_struct_alignment_field_offset_16(0, 3), s.f3.offset()); assertEquals("f4 offset" , testlib.inner_struct_alignment_field_offset_16(0, 4), s.f4.offset()); assertEquals("f5.f0 offset" , testlib.inner_struct_alignment_field_offset_16(1, 0), s.f5.f0.offset()); assertEquals("f5.f1 offset" , testlib.inner_struct_alignment_field_offset_16(1, 1), s.f5.f1.offset()); assertEquals("f5.f2 offset" , testlib.inner_struct_alignment_field_offset_16(1, 2), s.f5.f2.offset()); assertEquals("f5.f3 offset" , testlib.inner_struct_alignment_field_offset_16(1, 3), s.f5.f3.offset()); assertEquals("f5.f4 offset" , testlib.inner_struct_alignment_field_offset_16(1, 4), s.f5.f4.offset()); assertEquals("f5.f5.f0 offset", testlib.inner_struct_alignment_field_offset_16(2, 0), s.f5.f5.f0.offset()); assertEquals("f5.f5.f1 offset", testlib.inner_struct_alignment_field_offset_16(2, 1), s.f5.f5.f1.offset()); assertEquals("f5.f5.f2 offset", testlib.inner_struct_alignment_field_offset_16(2, 2), s.f5.f5.f2.offset()); assertEquals("f5.f5.f3 offset", testlib.inner_struct_alignment_field_offset_16(2, 3), s.f5.f5.f3.offset()); assertEquals("f5.f5.f4 offset", testlib.inner_struct_alignment_field_offset_16(2, 4), s.f5.f5.f4.offset()); } } jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/struct/ArrayTest.java000066400000000000000000000065441316720554100245530ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.struct; import jnr.ffi.*; import jnr.ffi.Runtime; import jnr.ffi.annotations.In; import jnr.ffi.provider.AbstractArrayMemoryIO; import jnr.ffi.provider.DelegatingMemoryIO; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; public class ArrayTest { public static interface TestLib { byte ptr_ret_int8_t(@In s8[] s, int index); class PointerStruct extends Struct { public final Signed8 s8 = new Signed8(); public final Pointer p = new Pointer(); public PointerStruct(Runtime runtime) { super(runtime); } } } static TestLib testlib; static Runtime runtime; public ArrayTest() { } @BeforeClass public static void setUpClass() throws Exception { testlib = TstUtil.loadTestLib(TestLib.class); runtime = Runtime.getRuntime(testlib); } @AfterClass public static void tearDownClass() throws Exception { } @Before public void setUp() { } @After public void tearDown() { } public static final class s8 extends Struct { public final Signed8 s8 = new Signed8(); public s8(Runtime runtime) { super(runtime); } } public static final class s32 extends Struct { public final Signed8 s8 = new Signed8(); public s32(Runtime runtime) { super(runtime); } } // TODO add test methods here. // The methods must be annotated with annotation @Test. For example: // // @Test // public void hello() {} @Test public void s8Array() { s8[] array = Struct.arrayOf(runtime, s8.class, 10); assertEquals("Array length incorrect", 10, array.length); for (int i = 0; i < array.length; ++i) { assertNotNull("Memory not allocated for array member", Struct.getMemory(array[i])); } Pointer ptr = ((DelegatingMemoryIO) Struct.getMemory(array[0])).getDelegatedMemoryIO(); for (int i = 0; i < array.length; ++i) { assertSame("Different backing memory", ptr, ((DelegatingMemoryIO) Struct.getMemory(array[i])).getDelegatedMemoryIO()); } if (ptr instanceof AbstractArrayMemoryIO) { assertEquals("Incorrect size", array.length, ((AbstractArrayMemoryIO)ptr).length()); } for (int i = 0; i < array.length; ++i) { array[i].s8.set((byte) i); } for (int i = 0; i < array.length; ++i) { assertEquals("Incorrect value written to native memory at index " + i, (byte) i, testlib.ptr_ret_int8_t(array, i)); } } }jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/struct/AsciiStringFieldTest.java000066400000000000000000000053341316720554100266540ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.struct; import jnr.ffi.Library; import jnr.ffi.Struct; import jnr.ffi.annotations.In; import jnr.ffi.annotations.Out; import jnr.ffi.annotations.Pinned; import jnr.ffi.annotations.Transient; import jnr.ffi.Runtime; import jnr.ffi.TstUtil; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; /** * * @author wayne */ public class AsciiStringFieldTest { public AsciiStringFieldTest() { } public class StringFieldStruct extends Struct { public final String string = new AsciiString(32); public StringFieldStruct() { super(runtime); } public StringFieldStruct(Runtime runtime) { super(runtime); } } public static interface TestLib { // This makes use of the string being the first field in the struct int string_equals(@Pinned @In @Transient StringFieldStruct s1, String s2); int copyByteBuffer(@Pinned @Out StringFieldStruct dst, @In byte[] src, int len); int copyByteBuffer(@Pinned @Out byte[] dst, @Pinned @In @Transient StringFieldStruct src, int len); int copyByteBuffer(@Pinned @Out StringBuilder dst, @Pinned @In @Transient StringFieldStruct src, int len); } static TestLib testlib; static Runtime runtime; @BeforeClass public static void setUpClass() throws Exception { testlib = TstUtil.loadTestLib(TestLib.class); runtime = Runtime.getRuntime(testlib); } @AfterClass public static void tearDownClass() throws Exception { } @Before public void setUp() { } @After public void tearDown() { } @Test public void stringFieldFirstInStruct() { StringFieldStruct s = new StringFieldStruct(); final String MAGIC = "test"; s.string.set(MAGIC); StringBuilder tmp = new StringBuilder(s.string.length()); testlib.copyByteBuffer(tmp, s, s.string.length()); assertEquals("String not put into struct correctly", MAGIC, tmp.toString()); } }jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/struct/EnumTest.java000066400000000000000000000164241316720554100243770ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.struct; import jnr.ffi.*; import jnr.ffi.Runtime; import jnr.ffi.util.EnumMapper; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; /** * * @author wayne */ public class EnumTest { public EnumTest() { } public enum TestEnum { ZERO, B, MAGIC } public class struct1 extends Struct { public final Enum8 b = new Enum8(TestEnum.class); public final Enum16 s = new Enum16(TestEnum.class); public final Enum32 i = new Enum32(TestEnum.class); public final Enum64 i64 = new Enum64(TestEnum.class); public final EnumLong l = new EnumLong(TestEnum.class); public struct1() { super(runtime); } } public static interface TestLib { byte struct_field_Signed8(struct1 s); short struct_field_Signed16(struct1 s); int struct_field_Signed32(struct1 s); long struct_field_Signed64(struct1 s); float struct_field_Float32(struct1 s); double struct_field_Float64(struct1 s); short struct_align_Signed16(Int16Align s); int struct_align_Signed32(Int32Align s); long struct_align_Signed64(Int64Align s); NativeLong struct_align_SignedLong(LongAlign s); // float struct_align_Float32(Float32Align s); // double struct_align_Float64(Float64Align s); // void struct_set_string(struct1 s, String string); } static TestLib testlib; static Runtime runtime; @BeforeClass public static void setUpClass() throws Exception { testlib = TstUtil.loadTestLib(TestLib.class); runtime = Runtime.getRuntime(testlib); } @AfterClass public static void tearDownClass() throws Exception { } @Before public void setUp() { } @After public void tearDown() { } // TODO add test methods here. // The methods must be annotated with annotation @Test. For example: // // @Test // public void hello() {} public static class Int16Align extends Struct { public final Enum8 first = new Enum8(TestEnum.class); public final Enum16 s = new Enum16(TestEnum.class); public Int16Align() { super(runtime); } } public static class Int32Align extends Struct { public final Enum8 first = new Enum8(TestEnum.class); public final Enum32 i = new Enum32(TestEnum.class); public Int32Align() { super(runtime); } } public static class Int64Align extends Struct { public final Enum8 first = new Enum8(TestEnum.class); public final Enum64 l = new Enum64(TestEnum.class); public Int64Align() { super(runtime); } } public static class LongAlign extends Struct { public final Enum8 first = new Enum8(TestEnum.class); public final EnumLong l = new EnumLong(TestEnum.class); public LongAlign() { super(runtime); } } @Test public void testInt8InitialValue() { struct1 s = new struct1(); assertEquals("default value not zero", TestEnum.ZERO, s.b.get()); } @Test public void testInt8Set() { struct1 s = new struct1(); final TestEnum MAGIC = TestEnum.MAGIC; s.b.set(MAGIC); assertEquals("Byte value not set correctly", MAGIC, s.b.get()); } @Test public void byteField() { final byte MAGIC = (byte) EnumMapper.getInstance(TestEnum.class).intValue(TestEnum.MAGIC); struct1 s = new struct1(); s.b.set(TestEnum.MAGIC); assertEquals("byte field not set", MAGIC, testlib.struct_field_Signed8(s)); s.b.set(TestEnum.ZERO); assertEquals("byte field not cleared", (byte) 0, testlib.struct_field_Signed8(s)); } @Test public void shortField() { final short MAGIC = (short) EnumMapper.getInstance(TestEnum.class).intValue(TestEnum.MAGIC); struct1 s = new struct1(); s.s.set(TestEnum.MAGIC); assertEquals("short field not set", MAGIC, testlib.struct_field_Signed16(s)); s.s.set(TestEnum.ZERO); assertEquals("short field not cleared", (short) 0, testlib.struct_field_Signed16(s)); } @Test public void intField() { final int MAGIC = EnumMapper.getInstance(TestEnum.class).intValue(TestEnum.MAGIC); struct1 s = new struct1(); s.i.set(TestEnum.MAGIC); assertEquals("int field not set", MAGIC, testlib.struct_field_Signed32(s)); s.i.set(TestEnum.ZERO); assertEquals("int field not cleared", 0, testlib.struct_field_Signed32(s)); } @Test public void int64Field() { final long MAGIC = EnumMapper.getInstance(TestEnum.class).intValue(TestEnum.MAGIC); struct1 s = new struct1(); s.i64.set(TestEnum.MAGIC); assertEquals("long field not set", MAGIC, testlib.struct_field_Signed64(s)); s.i64.set(TestEnum.ZERO); assertEquals("long field not cleared", 0L, testlib.struct_field_Signed64(s)); } @Test public void alignInt16Field() { final short MAGIC = (short) EnumMapper.getInstance(TestEnum.class).intValue(TestEnum.MAGIC); Int16Align s = new Int16Align(); s.s.set(TestEnum.MAGIC); assertEquals("short field not aligned", MAGIC, testlib.struct_align_Signed16(s)); } @Test public void alignSigned32Field() { final int MAGIC = (int) EnumMapper.getInstance(TestEnum.class).intValue(TestEnum.MAGIC); Int32Align s = new Int32Align(); s.i.set(TestEnum.MAGIC); assertEquals("int field not aligned", MAGIC, testlib.struct_align_Signed32(s)); } @Test public void alignSigned64Field() { final long MAGIC = EnumMapper.getInstance(TestEnum.class).intValue(TestEnum.MAGIC); Int64Align s = new Int64Align(); s.l.set(TestEnum.MAGIC); assertEquals("long field not aligned", MAGIC, testlib.struct_align_Signed64(s)); } @Test public void alignSignedLongField() { final NativeLong MAGIC = new NativeLong(EnumMapper.getInstance(TestEnum.class).intValue(TestEnum.MAGIC)); LongAlign s = new LongAlign(); s.l.set(TestEnum.MAGIC); assertEquals("native long field not aligned", MAGIC, testlib.struct_align_SignedLong(s)); } } jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/struct/PaddingTest.java000066400000000000000000000037231316720554100250370ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.struct; import jnr.ffi.*; import jnr.ffi.Runtime; import jnr.ffi.struct.PaddingTest.TestLib.LongPadding; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; public class PaddingTest { static TestLib testlib; static Runtime runtime; public static interface TestLib { static final class LongPadding extends Struct { public final Signed8 s8 = new Signed8(); public final Padding pad = new Padding(NativeType.SLONG, 3); public LongPadding() { super(runtime); } } } public PaddingTest() { } @BeforeClass public static void setUpClass() throws Exception { testlib = TstUtil.loadTestLib(TestLib.class); runtime = Runtime.getRuntime(testlib); } @AfterClass public static void tearDownClass() throws Exception { } @Before public void setUp() { } @After public void tearDown() { } @Test public void longPadding() throws Throwable { Type longType = runtime.findType(NativeType.SLONG); final int SIZE = longType.alignment() + (longType.size() * 3); assertEquals("incorrect size", SIZE, Struct.size(new LongPadding())); } }jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/struct/StructLayoutTest.java000066400000000000000000000314231316720554100261510ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.struct; import jnr.ffi.*; import jnr.ffi.Runtime; import jnr.ffi.annotations.LongLong; import org.junit.*; import static org.junit.Assert.assertEquals; /** * */ public class StructLayoutTest { public StructLayoutTest() { } public static interface TestLib { byte struct_field_Signed8(Pointer s); short struct_field_Signed16(Pointer s); int struct_field_Signed32(Pointer s); @LongLong long struct_field_Signed64(Pointer s); float struct_field_Float32(Pointer s); double struct_field_Float64(Pointer s); short struct_align_Signed16(Pointer s); int struct_align_Signed32(Pointer s); @LongLong long struct_align_Signed64(Pointer s); NativeLong struct_align_SignedLong(Pointer s); Pointer struct_make_struct(byte b, short s, int i, @LongLong long ll, float f, double d); // float struct_align_Float32(Float32Align s); // double struct_align_Float64(Float64Align s); // void struct_set_string(struct1 s, String string); } static TestLib testlib; static Runtime runtime; @BeforeClass public static void setUpClass() throws Exception { testlib = TstUtil.loadTestLib(TestLib.class); runtime = Runtime.getRuntime(testlib); } @AfterClass public static void tearDownClass() throws Exception { } @Before public void setUp() { } @After public void tearDown() { } public static class struct1 extends StructLayout { public final Signed8 b = new Signed8(); public final Signed16 s = new Signed16(); public final Signed32 i = new Signed32(); public final Signed64 i64 = new Signed64(); public final SignedLong l = new SignedLong(); public final Float f = new Float(); public final Double d = new Double(); public struct1() { super(runtime); } } public static class Int16Align extends StructLayout { public final Signed8 first = new Signed8(); public final Signed16 s = new Signed16(); public Int16Align() { super(runtime); } } public static class Int32Align extends StructLayout { public final Signed8 first = new Signed8(); public final Signed32 i = new Signed32(); public Int32Align() { super(runtime); } } public static class Int64Align extends StructLayout { public final Signed8 first = new Signed8(); public final Signed64 l = new Signed64(); public Int64Align() { super(runtime); } } public static class LongAlign extends StructLayout { public final Signed8 first = new Signed8(); public final SignedLong l = new SignedLong(); public LongAlign() { super(runtime); } } @Test public void testInt8InitialValue() { struct1 s = new struct1(); Pointer ptr = Memory.allocate(runtime, s.size()); assertEquals("default value not zero", (byte) 0, s.b.get(ptr)); } @Test public void testInt8Set() { struct1 s = new struct1(); Pointer ptr = Memory.allocate(runtime, s.size()); final byte MAGIC = (byte) 0xfe; s.b.set(ptr, MAGIC); assertEquals("Byte value not set correctly", MAGIC, s.b.get(ptr)); } @Test public void byteField() { final byte MAGIC = (byte) 0xbe; struct1 s = new struct1(); Pointer ptr = Memory.allocate(runtime, s.size()); s.b.set(ptr, MAGIC); assertEquals("byte field not set", MAGIC, testlib.struct_field_Signed8(ptr)); s.b.set(ptr, (byte) 0); assertEquals("byte field not cleared", (byte) 0, testlib.struct_field_Signed8(ptr)); } @Test public void shortField() { final short MAGIC = (short) 0xbeef; struct1 s = new struct1(); Pointer ptr = Memory.allocate(runtime, s.size()); s.s.set(ptr, MAGIC); assertEquals("short field not set", MAGIC, testlib.struct_field_Signed16(ptr)); s.s.set(ptr, (short) 0); assertEquals("short field not cleared", (short) 0, testlib.struct_field_Signed16(ptr)); } @Test public void intField() { final int MAGIC = 0xdeadbeef; struct1 s = new struct1(); Pointer ptr = Memory.allocate(runtime, s.size()); s.i.set(ptr, MAGIC); assertEquals("int field not set", MAGIC, testlib.struct_field_Signed32(ptr)); s.i.set(ptr, 0); assertEquals("int field not cleared", 0, testlib.struct_field_Signed32(ptr)); } @Test public void int64Field() { final long MAGIC = 0x1234deadbeef5678L; struct1 s = new struct1(); Pointer ptr = Memory.allocate(runtime, s.size()); s.i64.set(ptr, MAGIC); assertEquals("long field not set", MAGIC, testlib.struct_field_Signed64(ptr)); s.i64.set(ptr, 0); assertEquals("long field not cleared", 0L, testlib.struct_field_Signed64(ptr)); } @Test public void alignInt16Field() { final short MAGIC = (short) 0xbeef; Int16Align s = new Int16Align(); Pointer ptr = Memory.allocate(runtime, s.size()); s.s.set(ptr, MAGIC); assertEquals("short field not aligned", MAGIC, testlib.struct_align_Signed16(ptr)); } @Test public void alignSigned32Field() { final int MAGIC = (int) 0xdeadbeef; Int32Align s = new Int32Align(); Pointer ptr = Memory.allocate(runtime, s.size()); s.i.set(ptr, MAGIC); assertEquals("int field not aligned", MAGIC, testlib.struct_align_Signed32(ptr)); } @Test public void alignSigned64Field() { final long MAGIC = 0x1234deadbeef5678L; Int64Align s = new Int64Align(); Pointer ptr = Memory.allocate(runtime, s.size()); s.l.set(ptr, MAGIC); assertEquals("long field not aligned", MAGIC, testlib.struct_align_Signed64(ptr)); } @Test public void alignSignedLongField() { final NativeLong MAGIC = new NativeLong(0xdeadbeef); LongAlign s = new LongAlign(); Pointer ptr = Memory.allocate(runtime, s.size()); s.l.set(ptr, MAGIC); assertEquals("native long field not aligned", MAGIC, testlib.struct_align_SignedLong(ptr)); } @Test public void returnStructAddress() throws Throwable { final byte B = 0x11; final short S = 0x2222; final int I = 0x33333333; final long L = 0x4444444444444444L; final float F = (float) 0x55555555; final double D = (double) 0x6666666666666666L; struct1 s = new struct1(); Pointer ptr = testlib.struct_make_struct(B, S, I, L, F, D); assertEquals("Incorrect byte value in struct", B, s.b.get(ptr)); assertEquals("Incorrect short value in struct", S, s.s.get(ptr)); assertEquals("Incorrect int value in struct", I, s.i.get(ptr)); assertEquals("Incorrect int64 value in struct", L, s.i64.get(ptr)); assertEquals("Incorrect float value in struct", F, s.f.get(ptr), 0.0001); assertEquals("Incorrect double value in struct", D, s.d.get(ptr), 0.0001); } private static final class ArrayTest extends StructLayout { public final Signed8[] byteArray = array(new Signed8[8]); public ArrayTest() { super(runtime); } } @Test public void arrayMember() { ArrayTest s = new ArrayTest(); assertEquals("First element not at correct offset", 0L, s.byteArray[0].offset()); assertEquals("Second element not at correct offset", 1L, s.byteArray[1].offset()); assertEquals("Last element not at correct offset", 7L, s.byteArray[7].offset()); } private static final class Unsigned8Test extends StructLayout { public final Unsigned8 u8 = new Unsigned8(); public Unsigned8Test() { super(runtime); } } @Test public void unsigned8() { Unsigned8Test s = new Unsigned8Test(); Pointer ptr = Memory.allocate(runtime, s.size()); final short MAGIC = (short) Byte.MAX_VALUE + 1; s.u8.set(ptr, MAGIC); assertEquals("Incorrect unsigned byte value", MAGIC, s.u8.shortValue(ptr)); } private static final class Unsigned16Test extends Struct { public final Unsigned16 u16 = new Unsigned16(); public Unsigned16Test() { super(runtime); } } @Test public void unsigned16() { Unsigned16Test s = new Unsigned16Test(); final int MAGIC = (int) Short.MAX_VALUE + 1; s.u16.set(MAGIC); assertEquals("Incorrect unsigned short value", MAGIC, s.u16.intValue()); } private static final class Unsigned32Test extends Struct { public final Unsigned32 u32 = new Unsigned32(); public Unsigned32Test() { super(runtime); } } @Test public void unsigned32() { Unsigned32Test s = new Unsigned32Test(); final long MAGIC = (long) Integer.MAX_VALUE + 1; s.u32.set(MAGIC); assertEquals("Incorrect unsigned int value", MAGIC, s.u32.longValue()); } private static final class Unsigned64Test extends StructLayout { public final Unsigned64 u64 = new Unsigned64(); public Unsigned64Test() { super(runtime); } } @Test public void unsigned64() { Unsigned64Test s = new Unsigned64Test(); Pointer ptr = Memory.allocate(runtime, s.size()); final long MAGIC = Long.MAX_VALUE; s.u64.set(ptr, MAGIC); assertEquals("Incorrect unsigned long long value", MAGIC, s.u64.longValue(ptr)); // Just make sure that an Unsigned64 doesn't do anything weird with negative values s.u64.set(ptr, Long.MIN_VALUE); assertEquals("Incorrect unsigned long long value", Long.MIN_VALUE, s.u64.longValue(ptr)); } private static final class UnsignedLongTest extends StructLayout { public final UnsignedLong ul = new UnsignedLong(); public UnsignedLongTest() { super(runtime); } } @Test public void unsignedLong() { UnsignedLongTest s = new UnsignedLongTest(); Pointer ptr = Memory.allocate(runtime, s.size()); final long MAGIC = (long) Integer.MAX_VALUE; s.ul.set(ptr, MAGIC); assertEquals("Incorrect unsigned long value", MAGIC, s.ul.longValue(ptr)); } private class InnerStruct extends StructLayout { public final Signed8 s8 = new Signed8(); public InnerStruct() { super(runtime); } } private class InnerTest extends StructLayout { public final Signed32 i32 = new Signed32(); public final InnerStruct s = inner(new InnerStruct()); public InnerTest() { super(runtime); } } @Test public void innerStruct() { InnerTest t = new InnerTest(); Pointer ptr = Memory.allocate(runtime, t.size()); ptr.putInt(0, 0xdeadbeef); ptr.putByte(4, (byte) 0x12); assertEquals("incorrect inner struct field value", (byte) 0x12, t.s.s8.get(ptr)); } static final class LongPadding extends StructLayout { public final Signed8 s8 = new Signed8(); public final Padding pad = new Padding(NativeType.SLONG, 3); public LongPadding() { super(runtime); } } @Test public void longPadding() throws Throwable { Type longType = runtime.findType(NativeType.SLONG); final int SIZE = longType.alignment() + (longType.size() * 3); assertEquals("incorrect size", SIZE, new LongPadding().size()); } static final class TailPadding extends StructLayout { public final SignedLong sl = new SignedLong(); public final Signed8 s8 = new Signed8(); public TailPadding() { super(runtime); } } @Test public void tailPadding() throws Throwable { Type longType = runtime.findType(NativeType.SLONG); assertEquals("incorrect size", longType.size() * 2, new TailPadding().size()); assertEquals("incorrect alignment", longType.alignment(), new TailPadding().alignment()); } } jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/struct/StructureTest.java000066400000000000000000000362401316720554100254710ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.struct; import jnr.ffi.*; import jnr.ffi.Runtime; import jnr.ffi.annotations.LongLong; import jnr.ffi.TstUtil; import jnr.ffi.types.*; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; import static jnr.ffi.TypeAlias.*; /** * */ public class StructureTest { public StructureTest() { } public static interface TestLib { byte struct_field_Signed8(struct1 s); short struct_field_Signed16(struct1 s); int struct_field_Signed32(struct1 s); @LongLong long struct_field_Signed64(struct1 s); float struct_field_Float32(struct1 s); double struct_field_Float64(struct1 s); short struct_align_Signed16(Int16Align s); int struct_align_Signed32(Int32Align s); @LongLong long struct_align_Signed64(Int64Align s); NativeLong struct_align_SignedLong(LongAlign s); struct1 struct_make_struct(byte b, short s, int i, @LongLong long ll, float f, double d); // float struct_align_Float32(Float32Align s); // double struct_align_Float64(Float64Align s); // void struct_set_string(struct1 s, String string); } static TestLib testlib; static Runtime runtime; @BeforeClass public static void setUpClass() throws Exception { testlib = TstUtil.loadTestLib(TestLib.class); runtime = Runtime.getRuntime(testlib); } @AfterClass public static void tearDownClass() throws Exception { } @Before public void setUp() { } @After public void tearDown() { } public static class struct1 extends Struct { public final Signed8 b = new Signed8(); public final Signed16 s = new Signed16(); public final Signed32 i = new Signed32(); public final Signed64 i64 = new Signed64(); public final SignedLong l = new SignedLong(); public final Float f = new Float(); public final Double d = new Double(); public struct1(jnr.ffi.Runtime runtime) { super(runtime); } } public static class structWithStructRef extends Struct { public final StructRef mStructRef = new StructRef(struct1.class); public structWithStructRef(jnr.ffi.Runtime runtime) { super(runtime); } } public static class Int16Align extends Struct { public final Signed8 first = new Signed8(); public final Signed16 s = new Signed16(); public Int16Align(jnr.ffi.Runtime runtime) { super(runtime); } } public static class Int32Align extends Struct { public final Signed8 first = new Signed8(); public final Signed32 i = new Signed32(); public Int32Align(jnr.ffi.Runtime runtime) { super(runtime); } } public static class Int64Align extends Struct { public final Signed8 first = new Signed8(); public final Signed64 l = new Signed64(); public Int64Align(jnr.ffi.Runtime runtime) { super(runtime); } } public static class LongAlign extends Struct { public final Signed8 first = new Signed8(); public final SignedLong l = new SignedLong(); public LongAlign(jnr.ffi.Runtime runtime) { super(runtime); } } @Test public void testInt8InitialValue() { struct1 s = new struct1(runtime); assertEquals("default value not zero", (byte) 0, s.b.get()); } @Test public void testInt8Set() { struct1 s = new struct1(runtime); final byte MAGIC = (byte) 0xfe; s.b.set(MAGIC); assertEquals("Byte value not set correctly", MAGIC, s.b.get()); } @Test public void byteField() { final byte MAGIC = (byte) 0xbe; struct1 s = new struct1(runtime); s.b.set(MAGIC); assertEquals("byte field not set", MAGIC, testlib.struct_field_Signed8(s)); s.b.set((byte) 0); assertEquals("byte field not cleared", (byte) 0, testlib.struct_field_Signed8(s)); } @Test public void shortField() { final short MAGIC = (short) 0xbeef; struct1 s = new struct1(runtime); s.s.set(MAGIC); assertEquals("short field not set", MAGIC, testlib.struct_field_Signed16(s)); s.s.set((short) 0); assertEquals("short field not cleared", (short) 0, testlib.struct_field_Signed16(s)); } @Test public void intField() { final int MAGIC = 0xdeadbeef; struct1 s = new struct1(runtime); s.i.set(MAGIC); assertEquals("int field not set", MAGIC, testlib.struct_field_Signed32(s)); s.i.set(0); assertEquals("int field not cleared", 0, testlib.struct_field_Signed32(s)); } @Test public void int64Field() { final long MAGIC = 0x1234deadbeef5678L; struct1 s = new struct1(runtime); s.i64.set(MAGIC); assertEquals("long field not set", MAGIC, testlib.struct_field_Signed64(s)); s.i64.set(0); assertEquals("long field not cleared", 0L, testlib.struct_field_Signed64(s)); } @Test public void alignInt16Field() { final short MAGIC = (short) 0xbeef; Int16Align s = new Int16Align(runtime); s.s.set(MAGIC); assertEquals("short field not aligned", MAGIC, testlib.struct_align_Signed16(s)); } @Test public void alignSigned32Field() { final int MAGIC = (int) 0xdeadbeef; Int32Align s = new Int32Align(runtime); s.i.set(MAGIC); assertEquals("int field not aligned", MAGIC, testlib.struct_align_Signed32(s)); } @Test public void alignSigned64Field() { final long MAGIC = 0x1234deadbeef5678L; Int64Align s = new Int64Align(runtime); s.l.set(MAGIC); assertEquals("long field not aligned", MAGIC, testlib.struct_align_Signed64(s)); } @Test public void alignSignedLongField() { final NativeLong MAGIC = new NativeLong(0xdeadbeef); LongAlign s = new LongAlign(runtime); s.l.set(MAGIC); assertEquals("native long field not aligned", MAGIC, testlib.struct_align_SignedLong(s)); } @Test public void returnStructAddress() throws Throwable { final byte B = 0x11; final short S = 0x2222; final int I = 0x33333333; final long L = 0x4444444444444444L; final float F = (float) 0x55555555; final double D = (double) 0x6666666666666666L; struct1 s = testlib.struct_make_struct(B, S, I, L, F, D); assertEquals("Incorrect byte value in struct", B, s.b.get()); assertEquals("Incorrect short value in struct", S, s.s.get()); assertEquals("Incorrect int value in struct", I, s.i.get()); assertEquals("Incorrect int64 value in struct", L, s.i64.get()); assertEquals("Incorrect float value in struct", F, s.f.get(), 0.0001); assertEquals("Incorrect double value in struct", D, s.d.get(), 0.0001); } private static final class ArrayTest extends Struct { public final Signed8[] byteArray = array(new Signed8[8]); public ArrayTest() { super(runtime); } } @Test public void arrayMember() { ArrayTest s = new ArrayTest(); assertEquals("First element not at correct offset", 0L, s.byteArray[0].offset()); assertEquals("Second element not at correct offset", 1L, s.byteArray[1].offset()); assertEquals("Last element not at correct offset", 7L, s.byteArray[7].offset()); } private static final class Unsigned8Test extends Struct { public final Unsigned8 u8 = new Unsigned8(); public Unsigned8Test() { super(runtime); } } @Test public void structRef() { structWithStructRef structWithStructRef = new structWithStructRef(runtime); struct1 s = new struct1(runtime); s.i.set(12); structWithStructRef.mStructRef.set(s); assertEquals("Struct field not equals", s.i.get(), structWithStructRef.mStructRef.get().i.get()); structWithStructRef.mStructRef.set(new struct1[]{s}); assertEquals("Struct field not equals", s.i.get(), structWithStructRef.mStructRef.get(1)[0].i.get()); } @Test public void unsigned8() { Unsigned8Test s = new Unsigned8Test(); final short MAGIC = (short) Byte.MAX_VALUE + 1; s.u8.set(MAGIC); assertEquals("Incorrect unsigned byte value", MAGIC, s.u8.shortValue()); } private static final class Unsigned16Test extends Struct { public final Unsigned16 u16 = new Unsigned16(); public Unsigned16Test() { super(runtime); } } @Test public void unsigned16() { Unsigned16Test s = new Unsigned16Test(); final int MAGIC = (int) Short.MAX_VALUE + 1; s.u16.set(MAGIC); assertEquals("Incorrect unsigned short value", MAGIC, s.u16.intValue()); } private static final class Unsigned32Test extends Struct { public final Unsigned32 u32 = new Unsigned32(); public Unsigned32Test() { super(runtime); } } @Test public void unsigned32() { Unsigned32Test s = new Unsigned32Test(); final long MAGIC = (long) Integer.MAX_VALUE + 1; s.u32.set(MAGIC); assertEquals("Incorrect unsigned int value", MAGIC, s.u32.longValue()); } private static final class Unsigned64Test extends Struct { public final Unsigned64 u64 = new Unsigned64(); public Unsigned64Test() { super(runtime); } } @Test public void unsigned64() { Unsigned64Test s = new Unsigned64Test(); final long MAGIC = Long.MAX_VALUE; s.u64.set(MAGIC); assertEquals("Incorrect unsigned long long value", MAGIC, s.u64.longValue()); // Just make sure that an Unsigned64 doesn't do anything weird with negative values s.u64.set(Long.MIN_VALUE); assertEquals("Incorrect unsigned long long value", Long.MIN_VALUE, s.u64.longValue()); } private static final class UnsignedLongTest extends Struct { public final UnsignedLong ul = new UnsignedLong(); public UnsignedLongTest() { super(runtime); } } @Test public void unsignedLong() { UnsignedLongTest s = new UnsignedLongTest(); final long MAGIC = (long) Integer.MAX_VALUE; s.ul.set(MAGIC); assertEquals("Incorrect unsigned long value", MAGIC, s.ul.longValue()); } private class InnerStruct extends Struct { public final Signed8 s8 = new Signed8(); public InnerStruct() { super(runtime); } } private class InnerTest extends Struct { public final Signed32 i32 = new Signed32(); public final InnerStruct s = inner(new InnerStruct()); public InnerTest() { super(runtime); } } private class DoubleInnerTest extends Struct { public final Signed32 s32 = new Signed32(); public final InnerTest innerTestStruct = inner(new InnerTest()); public DoubleInnerTest() { super(runtime); } } @Test public void innerStruct() { InnerTest t = new InnerTest(); Pointer io = Struct.getMemory(t); io.putInt(0, 0xdeadbeef); io.putByte(4, (byte) 0x12); assertEquals("incorrect inner struct field value", (byte) 0x12, t.s.s8.get()); } @Test public void doubleInnerStruct() { DoubleInnerTest t = new DoubleInnerTest(); Pointer io = Struct.getMemory(t); io.putInt(0, 0xffffffff); io.putInt(4, 0xffffffff); assertEquals(0, t.innerTestStruct.s.s8.get()); } public static class structWithPointer extends Struct { public final Pointer pointer = new Pointer(); public structWithPointer(jnr.ffi.Runtime runtime) { super(runtime); } } @Test public void abstractPointer() { structWithPointer s = new structWithPointer(runtime); Pointer p = Memory.allocate(s.getRuntime(), NativeType.UCHAR); p.putByte(0, (byte) 0xff); s.pointer.set(p); assertNotNull("Abstract pointer was not copied", s.pointer.get()); assertEquals("Abstract pointer value does not match", p.getByte(0), s.pointer.get().getByte(0)); } @Test public void tempPointer() { structWithPointer s = new structWithPointer(runtime); Pointer p = Memory.allocateTemporary(s.getRuntime(), NativeType.UCHAR); p.putByte(0, (byte) 0xff); s.pointer.set(p); assertNotNull("Temp pointer was not copied", s.pointer.get()); assertEquals("Temp pointer value does not match", p.getByte(0), s.pointer.get().getByte(0)); } @Test public void directPointer() { structWithPointer s = new structWithPointer(runtime); Pointer p = Memory.allocateDirect(s.getRuntime(), NativeType.UCHAR); p.putByte(0, (byte) 0xff); s.pointer.set(p); assertNotNull("Direct pointer was not copied", s.pointer.get()); assertEquals("Direct pointer value does not match", p.getByte(0), s.pointer.get().getByte(0)); } private class TypeTest extends Struct { class Fixnum extends NumberField { Fixnum(TypeAlias type) { super(NativeType.SINT); } @Override public void set(Number value) { //To change body of implemented methods use File | Settings | File Templates. } @Override public int intValue() { return 0; //To change body of implemented methods use File | Settings | File Templates. } } class Fubar extends NumberField { Fubar(Class type) { super(NativeType.SINT); } @Override public void set(Number value) { //To change body of implemented methods use File | Settings | File Templates. } @Override public int intValue() { return 0; //To change body of implemented methods use File | Settings | File Templates. } } public final Fixnum i = new Fixnum(ssize_t); public final Fubar fubar = new Fubar(ssize_t.class); private TypeTest(Runtime runtime) { super(runtime); } } public static interface TestLib2 { @ssize_t long write(int fd, Pointer buf, @size_t long len); } } jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/struct/UTF8StringFieldTest.java000066400000000000000000000067501316720554100263550ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.struct; import jnr.ffi.Struct; import jnr.ffi.TstUtil; import jnr.ffi.Library; import jnr.ffi.Runtime; import jnr.ffi.annotations.In; import jnr.ffi.annotations.Out; import jnr.ffi.annotations.Pinned; import jnr.ffi.annotations.Transient; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; /** * * @author wayne */ public class UTF8StringFieldTest { public UTF8StringFieldTest() { } public static class StringFieldStruct extends Struct { public final UTF8String string = new UTF8String(32); public StringFieldStruct() { super(runtime); } } public static interface TestLib { // This makes use of the string being the first field in the struct int string_equals(@Pinned @In @Transient StringFieldStruct s1, String s2); int copyByteBuffer(@Pinned @Out StringFieldStruct dst, @In byte[] src, int len); int copyByteBuffer(@Pinned @Out byte[] dst, @Pinned @In @Transient StringFieldStruct src, int len); int copyByteBuffer(@Pinned @Out StringBuilder dst, @Pinned @In @Transient StringFieldStruct src, int len); } static TestLib testlib; static Runtime runtime; @BeforeClass public static void setUpClass() throws Exception { testlib = TstUtil.loadTestLib(TestLib.class); runtime = Runtime.getRuntime(testlib); } @AfterClass public static void tearDownClass() throws Exception { } @Before public void setUp() { } @After public void tearDown() { } @Test public void stringFieldFirstInStruct() { StringFieldStruct s = new StringFieldStruct(); final String MAGIC = "test"; s.string.set(MAGIC); StringBuilder tmp = new StringBuilder(s.string.length()); testlib.copyByteBuffer(tmp, s, s.string.length()); assertEquals("String not put into struct correctly", MAGIC, tmp.toString()); } public static final class SockaddrUnix extends Struct { private final Signed8 sun_len = new Signed8(); private final Signed8 sun_family = new Signed8(); private final UTF8String sun_path = new UTF8String(100); public SockaddrUnix() { super(runtime); } } @Test public void testSockaddrUnix() { final int SUN_LEN = 1; final int SUN_FAM = 2; final String SUN_PATH = "test"; SockaddrUnix s = new SockaddrUnix(); s.sun_len.set(SUN_LEN); s.sun_family.set(SUN_FAM); s.sun_path.set(SUN_PATH); assertEquals("Incorrect sun_len value", SUN_LEN, s.sun_len.intValue()); assertEquals("Incorrect sun_fam value", SUN_FAM, s.sun_family.intValue()); assertEquals("Incorrect sun_path value", SUN_PATH, s.sun_path.toString()); } }jnr-ffi-jnr-ffi-2.1.7/src/test/java/jnr/ffi/struct/UnionTest.java000066400000000000000000000116171316720554100245620ustar00rootroot00000000000000/* * Copyright (C) 2007-2010 Wayne Meissner * * This file is part of the JNR project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jnr.ffi.struct; import java.nio.ByteOrder; import jnr.ffi.Runtime; import jnr.ffi.Struct; import jnr.ffi.TstUtil; import jnr.ffi.Union; import org.junit.After; import org.junit.AfterClass; import org.junit.Before; import org.junit.BeforeClass; import org.junit.Test; import static org.junit.Assert.*; /** * */ public class UnionTest { public static interface TestLib { } public UnionTest() { } static TestLib testlib; static Runtime runtime; @BeforeClass public static void setUpClass() throws Exception { testlib = TstUtil.loadTestLib(TestLib.class); runtime = Runtime.getRuntime(testlib); } @AfterClass public static void tearDownClass() throws Exception { } @Before public void setUp() { } @After public void tearDown() { } public static final class union extends Union { public final Signed8 s8 = new Signed8(); public final Unsigned8 u8 = new Unsigned8(); public final Signed16 s16 = new Signed16(); public final Unsigned16 u16 = new Unsigned16(); public final Signed32 s32 = new Signed32(); public final Unsigned32 u32 = new Unsigned32(); public final Signed64 s64 = new Signed64(); public final Unsigned64 u64 = new Unsigned64(); public union() { super(runtime); } } public static final class innerStruct extends Struct { public final Unsigned8 firstByte = new Unsigned8(); public final Unsigned8 secondByte = new Unsigned8(); public innerStruct() { super(runtime); } } public static final class unionWithStruct extends Union { public final Unsigned16 u16 = new Unsigned16(); public final innerStruct inner = inner(new innerStruct()); public unionWithStruct() { super(runtime); } } @Test public void offsetTest() { union u = new union(); assertEquals("Not at offset 0", 0L, u.s8.offset()); assertEquals("Not at offset 0", 0L, u.u8.offset()); assertEquals("Not at offset 0", 0L, u.s16.offset()); assertEquals("Not at offset 0", 0L, u.u16.offset()); assertEquals("Not at offset 0", 0L, u.s32.offset()); assertEquals("Not at offset 0", 0L, u.s32.offset()); assertEquals("Not at offset 0", 0L, u.s64.offset()); assertEquals("Not at offset 0", 0L, u.u64.offset()); } @Test public void s8s16() { union u = new union(); final int MAGIC = runtime.byteOrder().equals(ByteOrder.BIG_ENDIAN) ? 0xef00 : 0x00ef; u.s16.set((short) MAGIC); assertEquals("Wrong value", (byte) 0xef, u.s8.get()); } @Test public void s8s32() { union u = new union(); final int MAGIC = runtime.byteOrder().equals(ByteOrder.BIG_ENDIAN) ? 0xef000000 : 0x000000ef; u.s32.set(MAGIC); assertEquals("Wrong value", (byte) 0xef, u.s8.get()); } @Test public void s16s32() { union u = new union(); final int MAGIC = runtime.byteOrder().equals(ByteOrder.BIG_ENDIAN) ? 0xdead0000 : 0x0000dead; u.s32.set(MAGIC); assertEquals("Wrong value", (short) 0xdead, u.s16.get()); } @Test public void s8s64() { union u = new union(); final long MAGIC = runtime.byteOrder().equals(ByteOrder.BIG_ENDIAN) ? 0xef00000000000000L : 0xefL; u.s64.set(MAGIC); assertEquals("Wrong value", (byte) 0xef, u.s8.get()); } @Test public void s16s64() { union u = new union(); final long MAGIC = runtime.byteOrder().equals(ByteOrder.BIG_ENDIAN) ? 0xbeef000000000000L : 0xbeefL; u.s64.set(MAGIC); assertEquals("Wrong value", (short) 0xbeef, u.s16.get()); } @Test public void s32s64() { union u = new union(); final long MAGIC = runtime.byteOrder().equals(ByteOrder.BIG_ENDIAN) ? 0xdeadbeef00000000L : 0xdeadbeefL; u.s64.set(MAGIC); assertEquals("Wrong value", 0xdeadbeef, u.s32.get()); } @Test public void innerStructSize() { unionWithStruct unionWithStruct = new unionWithStruct(); assertEquals(2, Struct.size(unionWithStruct)); } }