unit jniAddressList; { AddressList replacement to be used by the java version. It only contains data and not responsible for gui updates } {$mode delphi}{$H+} interface uses Classes, SysUtils, jni; procedure InitializeJniAddressList(env: PJNIEnv); implementation uses MemoryRecordUnit, unixporthelper, commonTypeDefs, syncobjs, math; type TAddressListFreezer=class(TThread) private public procedure execute; override; end; var addresslist: TList=nil; //list of MemoryRecord's addresslistcs: TCriticalsection; //used to protect the list from the freezer thread. Changing memory records is not part of this. AddressListEntry_class: jclass; //global ref AddressListEntry_init_method: jmethodID; description_fieldid: JFieldID; vartype_fieldid: JFieldID; addressString_fieldid: JFieldID; address_fieldid: JFieldID; offsets_fieldid: JFieldID; index_fieldid: JFieldID; active_fieldid: jfieldID; isUnicode_fieldid: jfieldID; size_fieldid: jFieldid; freezeInterval: integer; freezerthread: TAddressListFreezer; procedure TAddressListFreezer.execute; { 'timer' that freezes the addresslist } var i: integer; r: TMemoryrecord; begin while not terminated do begin addresslistcs.enter; try for i:=0 to addresslist.count-1 do begin r:=TMemoryrecord(addresslist[i]); if (r.Active) then r.ApplyFreeze; end; finally addresslistcs.Leave; end; sleep(freezeInterval); end; end; function addresslist_getCount(PEnv: PJNIEnv; Obj: JObject): jint; cdecl; begin // log('addresslist_getCount'); if (addresslist<>nil) then result:=addresslist.Count else begin result:=0; log('addresslist=nil'); end; end; function addresslist_setActive(PEnv: PJNIEnv; Obj: JObject; index: jint; state: jboolean): jboolean; cdecl; var r: TMemoryRecord; begin log('addresslist_setActive'); if (index>=0) and (index=0) and (index=0) and (index=0) and (index=addresslist.count) then begin log('index ('+inttostr(index)+') is outside bounds'); exit; end; r:=TMemoryRecord(addresslist[index]); // log('accessing provided entry'); descriptionstring:=penv^.GetObjectField(penv, entry, description_fieldid); if (descriptionstring<>nil) then begin // log('got the description'); r.Description:=jniGetString(penv, descriptionstring); // log('description='+r.Description); end else log('description=null'); // log('getting vartype'); i:=penv^.GetIntField(penv, entry, vartype_fieldid); // log('vartype='+inttostr(i)); r.VarType:=TVariableType(i); // log('Getting addressString'); addressString:=penv^.GetObjectField(penv, entry, addressString_fieldid); if (addressString<>nil) then begin // log('got the addressString'); r.interpretableaddress:=jniGetString(penv, addressString); end else log('addressString=null'); offsets:=penv^.GetObjectField(penv, entry, offsets_fieldid); if (offsets<>nil) then begin // log('offsets is not null'); l:=penv^.GetArrayLength(penv, offsets); // log('the offsets array length='+inttostr(l)); iscopy:=0; offsetlist:=PJintArray(penv^.GetIntArrayElements(penv,offsets, iscopy)); if offsetlist<>nil then begin r.offsetCount:=l; for i:=0 to l-1 do r.offsets[i].offset:=offsetlist[i]; penv^.ReleaseIntArrayElements(penv, offsets, PJint(offsetlist),JNI_ABORT); end else log('offsetlist=nil'); end; if r.vartype=vtString then begin Log('set address: string'); r.extra.stringData.length:=penv^.GetIntField(penv, entry, size_fieldid); r.Extra.stringData.unicode:=penv^.GetBooleanField(penv, entry, isUnicode_fieldid)<>0; Log('Length='+inttostr(r.extra.stringData.length)); Log('isUnicode='+BoolToStr(r.extra.stringData.unicode)); end; if r.vartype=vtByteArray then r.Extra.byteData.bytelength:=penv^.GetIntField(penv, entry, size_fieldid); r.ReinterpretAddress; end; function addresslist_addEntry(PEnv: PJNIEnv; Obj: JObject; entry: JObject): jint; cdecl; var r: TMemoryrecord; begin //log('creating memory record'); r:=TMemoryrecord.Create(nil); addresslistcs.enter; try addresslist.Add(r); result:=addresslist.count; // log('Initializing memory record. (result='+inttostr(result)+')'); addresslist_setEntry(penv, obj, result-1, entry); finally addresslistcs.leave; end; end; procedure addresslist_deleteEntry(PEnv: PJNIEnv; Obj: JObject; index: jint); cdecl; begin log('Delete entry'); if (index>=0) and (index', '()V'); description_fieldid:=env^.GetFieldID(env, AddressListEntry_class, 'description','Ljava/lang/String;'); vartype_fieldid:=env^.GetFieldID(env, AddressListEntry_class, 'vartype','I'); addressString_fieldid:=env^.GetFieldID(env, AddressListEntry_class, 'addressString','Ljava/lang/String;'); address_fieldid:=env^.GetFieldID(env, AddressListEntry_class, 'address','J'); offsets_fieldid:=env^.GetFieldID(env, AddressListEntry_class, 'offsets','[I'); active_fieldid:=env^.GetFieldID(env, AddressListEntry_class, 'active','Z'); index_fieldid:=env^.GetFieldID(env, AddressListEntry_class, 'index','I'); isUnicode_fieldid:=env^.GetFieldID(env, AddressListEntry_class, 'isUnicode','Z'); size_fieldid:=env^.GetFieldID(env, AddressListEntry_class, 'size','I'); log('description_fieldid='+inttohex(ptruint(description_fieldid),8)); log('vartype_fieldid='+inttohex(ptruint(vartype_fieldid),8)); end; end.