ORIGIN 'betaenv'; LIB_DEF 'external' '../lib'; -- CStructLib: attributes--- (* * COPYRIGHT * Copyright Mjolner Informatics, 1992-99 * All rights reserved. * ****** Patterns for external interface ***** * * In CStructLib, the operations on a cStruct are defined. * The pattern ExternalRecord is an interface to e.g. CStruct objects * allocated from C or other external languages. *) GetByte: (# byteno: @int32; enter byteno->chk exit byteNo -> R.%getByte #); PutByte: (# val: @int8; byteno: @int32; enter(byteno,val) do byteno->chk; (val,byteno) ->R.%putbyte #); GetShort: (# byteno: @int32; enter byteno->chk exit (byteno div 2) ->R.%getShort #); PutShort: (# val: @int16; byteno: @int32; enter (byteno,val) do byteno->chk; (val,byteno div 2) -> R.%putShort #); GetSignedShort: (# byteno: @int32; enter byteno->chk exit (byteno div 2) ->R.%getSignedShort #); GetLong: (# byteno: @int32; enter byteno->chk exit (byteno div 4) ->R.%getLong #); PutLong: (# val: @int32; byteno: @int32 enter (byteno,val) do byteno->chk; (val,byteno div 4) ->R.%putLong #); CStructField: (* Used for declaring CStruct fields *) (# pos:< IntegerObject; p: @pos; #); Byte: CStructField (# set: @(# val: @int8 enter val do (val,p) ->R.%putByte #); enter set exit p ->R.%getByte #); Short: CStructField (# set: @(# val: @int16 enter val do (val,p div 2) ->R.%putShort #); enter set exit (p div 2) ->R.%getShort #); SignedShort: CStructField (# set: @(# val: @int16 enter val do (val,p div 2) ->R.%putShort #); enter set exit (p div 2) ->R.%getSignedShort #); Long: CStructField (# set: @(# val: @int32 enter val do (val,p div 4) ->R.%putLong #); enter set exit (p div 4)->R.%getLong #); --LIB: attributes-- (* Various C functions *) malloc: External (# size: @integer; ptr: @integer; enter size exit ptr #); memcpy: external (# s1, s2, nbytes: @int32; enter (s1, s2, nbytes) exit s1 #); ExternalRecord: (* Super-pattern for describing externally allocated record-structures. * A call to e.g. a C routine may often return a pointer to a CStruct. * By assigning such a pointer to the ptr-field of an externalRecord * object it is possible to interface to such an external CStruct. * Notice the difference to the CStruct pattern, which is typically used * to *provide* external code with a structure allocated in BETA. *) (# ptr: @int32; (* pointer to the externally allocated record *) GetByte: (# byteno: @int32; enter byteno exit %getByteAt (ptr+byteno) #); PutByte: (# val: @int8; byteno: @int32; enter(byteno,val) do val %putByteAt (ptr+byteno) #); GetShort: (# byteno: @int32; enter byteno exit %getShortAt (ptr+byteno) #); GetSignedShort: (# byteno: @int32; enter byteno exit %getSignedShortAt (ptr+byteno) #); PutShort: (# val: @int16; byteno: @int32; enter(byteno,val) do val %putShortAt (ptr+byteno) #); GetLong: (# byteno: @int32 enter byteno exit %getLongAt (ptr+byteno) #); PutLong: (# val: @int32; byteno: @int32 enter(byteno,val) do val %putLongAt (ptr+byteno) #); ExternalRecordField: (* For declaring fields in ExternalRecords *) (# pos:< IntegerValue; p: @pos; #); Byte: ExternalRecordField (# set: @(# val: @int8 enter val do val %putByteAt (ptr+p) #) enter set exit %getByteAt (ptr+p) #); Short: ExternalRecordField (# set: @(# val: @int16 enter val do val %putShortAt (ptr+p) #); enter set exit %getShortAt (ptr+p) #); SignedShort: ExternalRecordField (# set: @(# val: @int16 enter val do val %putShortAt (ptr+p) #); enter set exit %getSignedShortAt (ptr+p) #); Long: ExternalRecordField (# val: @int32; set: @(# enter val do val %putLongAt (ptr+p) #); enter set exit %getLongAt (ptr+p) #); DoubleLong: ExternalRecordField (# v1,v2: @int32; set: @(# enter(v1,v2) do v1 %putLongAt (ptr+p); v2 %putLongAt (ptr+p+4); #); enter set exit (%getLongAt (ptr+p), %getLongAt (ptr+p+4)) #); enter ptr do INNER exit ptr #) (* ExternalRecord *); ExternalRepetition: ExternalRecord (# elementSize:<integerValue; init: (# enter new #); new: (# newrange: @int32 enter newrange do free; newrange->range; #); extend: (# extra: @int32; newptr, newrange, size: @int32; enter extra do (* is realloc available on all platforms? *) elementSize->size; (*'EXTEND: elementsize: ' -> puttext; * elementsize -> putint; ', range.r: ' -> puttext; * range.r->putint; newline; *) range.r+extra -> newrange; size*newrange -> malloc -> newptr; (if newPtr=0 then 'ExternalRepetition.extend: malloc failed' -> screen.putline; else (if ptr<>0 then (* 'memcpy ' -> puttext; size*range.r->putint; * ' bytes.'->putline; *) (newptr, ptr, size*range.r) -> memcpy; free; if); newptr->ptr; newrange -> range.r; if); #); range: @ (# r: @int32; enter (# r2: @int32 enter r2 do r2-r->extend #) exit r #); free: (# cfree: External (# ptr: @integer enter ptr do 'free' -> callC; #); do (if ptr<>0 then ptr -> cfree; 0->ptr; if); 0 -> range.r; #); inxPut: (* Only for elementSize in {1,2,4}. Inx zero based. No index check *) (# elm, inx: @int32; enter (elm, inx) do (if elementSize // 1 then elm %putByteAt (ptr+inx) // 2 then elm %putShortAt (ptr+2*inx) // 4 then elm %putLongAt (ptr+4*inx) else 'ExternalRepetition.inxPut: Not for elementSize='->screen.puttext; elementSize->screen.putInt; screen.newline; if); #); inxCopy: (* Copy elementSize bytes from "element" (which is assumed to * point to data of the same type as the external repetition elements) * to index number inx (counting from zero) in the external * repetition. * Can be used for any elementSize. *) (# inx: @int32; element: ^data; n: @integer; enter (inx, element[]) do elementSize -> n; (ptr+inx*n, %getLongAt(@@element), n) -> memcpy #); inxGet: (* Only for elementSize in {1,2,4}. Inx zero based. No index check *) (# elm, inx: @int32; enter (inx) do (if elementSize // 1 then (%getByteAt (ptr+inx)) -> elm // 2 then (%getShortAt (ptr+2*inx)) -> elm; // 4 then (%getLongAt (ptr+4*inx)) -> elm; else 'ExternalRepetition.inxGet: Not for elementSize='->screen.puttext; elementSize->screen.putInt; screen.newline; if); exit elm #); #); makeCBF: External (* Call this external to install a callback and get * an int32 pointer to it. *) (# pat: ##External; cb: @int32; enter pat## exit cb #); freeCBF: External (* Call this external with an int32 pointer to an installed * callback (obtained via MakeCBF) when it is certain that the * callback will NOT be called again. * This will free BETA heap space associated with the callback. *) (# cbf: @int32; enter cbf #)
13.5 External Interface | © 1990-2002 Mjølner Informatics |
[Modified: Tuesday June 13th 2000 at 16:25]
|