BridgeWorks -> TIG

Liste des GroupesRevenir à co vms 
Sujet : BridgeWorks -> TIG
De : arne (at) *nospam* vajhoej.dk (Arne Vajhøj)
Groupes : comp.os.vms
Date : 01. Aug 2024, 13:20:28
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <v8fuib$256sq$1@dont-email.me>
User-Agent : Mozilla Thunderbird
I could not get BridgeWorks to work. And the VMS side was
VMS Alpha only. And the non-Java option for client side
was COM.
But I do like the concept. So I tried creating something
similar that works with newer stuff. TIG (Transparent
Interface Generation).
VMS code:
data.inc:
       structure /mydata/
         integer*4 iv
         character*256 sv
       end structure
demof.for:
       integer*4 function add(a, b, res)
       implicit none
       integer*4 a, b, res
       res = a + b
       add = 1
       end
c
       integer*4 function conc(a, b, res)
       implicit none
       character*(*) a, b, res
       res = a // b
       conc = 1
       end
c
       integer*4 function modify(o)
       implicit none
       include 'data.inc'
       record /mydata/o
       o.iv = o.iv + 1
       o.sv = trim(o.sv) // 'X'
       modify = 1
       end
c
       integer*4 function getid(id)
       implicit none
       character*(*) id
       id = 'Fortran on VMS'
       getid = 1
       end
(trivial I know, but ...)
So to make it all work I describe the functions in an XML file.
demof.xml:
<config>
     <image>demof</image>
     <port>12346</port>
     <mt>false</mt>
     <server>
         <language>dk.vajhoej.vms.tig.server.JavaServerGen</language>
     </server>
     <client>
         <language>dk.vajhoej.vms.tig.client.JavaClientGen</language>
         <language>dk.vajhoej.vms.tig.client.CSharpClientGen</language>
         <language>dk.vajhoej.vms.tig.client.CClientGen</language>
     </client>
     <methods>
         <method>
             <name>add</name>
             <args>
                 <arg>
                     <name>a</name>
                     <type>LongWord</type>
                     <pass>Reference</pass>
                     <use>In</use>
                 </arg>
                 <arg>
                     <name>b</name>
                     <type>LongWord</type>
                     <pass>Reference</pass>
                     <use>In</use>
                 </arg>
                 <arg>
                     <name>res</name>
                     <type>LongWord</type>
                     <pass>Reference</pass>
                     <use>Out</use>
                 </arg>
             </args>
         </method>
         <method>
             <name>conc</name>
             <args>
                 <arg>
                     <name>a</name>
                     <type>FixedCharacterString</type>
                     <pass>Descriptor</pass>
                     <use>In</use>
                 </arg>
                 <arg>
                     <name>b</name>
                     <type>FixedCharacterString</type>
                     <pass>Descriptor</pass>
                     <use>In</use>
                 </arg>
                 <arg>
                     <name>res</name>
                     <type>FixedCharacterString</type>
                     <pass>Descriptor</pass>
                     <use>Out</use>
                 </arg>
             </args>
         </method>
         <method>
             <name>modify</name>
             <args>
                 <arg>
                     <name>o</name>
                     <type>Block</type>
                     <pass>Reference</pass>
                     <use>InOut</use>
                     <impl>Dataf</impl>
                 </arg>
             </args>
         </method>
         <method>
             <name>getid</name>
             <args>
                 <arg>
                     <name>res</name>
                     <type>FixedCharacterString</type>
                     <pass>Descriptor</pass>
                     <use>Out</use>
                 </arg>
             </args>
         </method>
     </methods>
</config>
(I prefer XML config file over GUI!)
Generate some code for both VMS side and client side.
Java test client:
Dataf.java:
import dk.vajhoej.record.FieldType;
import dk.vajhoej.record.Struct;
import dk.vajhoej.record.StructField;
@Struct
public class Dataf {
     @StructField(n=0, type=FieldType.INT4)
     private int iv;
     @StructField(n=1, type=FieldType.FIXSTR, length=256, pad=true, padchar=' ')
     private String sv;
     public Dataf() {
         this(0, "");
     }
     public Dataf(int iv, String sv) {
         this.iv = iv;
         this.sv = sv;
     }
     public int getIv() {
         return iv;
     }
     public void setIv(int iv) {
         this.iv = iv;
     }
     public String getSv() {
         return sv;
     }
     public void setSv(String sv) {
         this.sv = sv;
     }
     @Override
     public String toString() {
         return String.format("{iv: %d, sv: %s}", iv, sv);
     }
}
Testf.java:
import java.io.IOException;
import dk.vajhoej.record.RecordException;
public class Testf {
     public static void main(String[] args) throws IOException, RecordException {
         int stat;
         DemofClient cli = new DemofClient("192.168.68.40");
         int v1 = 123;
         int v2 = 456;
         int[] v3 = new int[1];
         stat = cli.add(v1, v2, v3);
         System.out.printf("stat = %d\n", stat);
         System.out.printf("%d + %d = %d\n", v1, v2, v3[0]);
         String s1 = "ABC";
         String s2 = "DEF";
         String[] s3 = new String[1];
         stat = cli.conc(s1, s2, s3);
         System.out.printf("stat = %d\n", stat);
         System.out.printf("|%s| + |%s| = |%s|\n", s1, s2, s3[0]);
         Dataf[] o = new Dataf[1];
         o[0] = new Dataf(123, "ABC");
         stat = cli.modify(o);
         System.out.printf("stat = %d\n", stat);
         System.out.printf("o = %s\n", o[0]);
         String[] id = new String[1];
         stat = cli.getid(id);
         System.out.printf("stat = %d\n", stat);
         System.out.printf("id = %s\n", id[0]);
     }
}
C# test client:
Dataf.cs:
using Vajhoej.Record;
[Struct]
public class Dataf
{
[StructField(N=0, Type=FieldType.INT4)]
private int iv;
[StructField(N=1, Type=FieldType.FIXSTR, Length=256, Pad=true, PadChar=' ')]
private string sv;
public int Iv
{
get { return iv; }
set { iv = value; }
}
public string Sv
{
get { return sv; }
set { sv = value; }
}
     public override string ToString()
     {
         return string.Format("{{iv: {0}, sv: {1}}}", iv, sv);
     }
}
Testf.cs:
using System;
public class Testf
{
     public static void Main(string[] args)
     {
         int stat;
         DemofClient cli = new DemofClient("192.168.68.40");
         int v1 = 123;
         int v2 = 456;
         int v3 = 0;
         stat = cli.Add(v1, v2, ref v3);
         Console.WriteLine("stat = {0}", stat);
         Console.WriteLine("{0} + {1} = {2}", v1, v2, v3);
         string s1 = "ABC";
         string s2 = "DEF";
         string s3 = "";
         stat = cli.Conc(s1, s2, ref s3);
         Console.WriteLine("stat = {0}", stat);
         Console.WriteLine("|{0}| + |{1}| = |{2}|", s1, s2, s3);
         Dataf o = new Dataf { Iv = 123, Sv = "ABC" };
         stat = cli.Modify(ref o);
         Console.WriteLine("stat = {0}", stat);
         Console.WriteLine("o = {0}", o);
         String id = "";
         stat = cli.Getid(ref id);
         Console.WriteLine("stat = {0}", stat);
         Console.WriteLine("id = {0}", id);
     }
}
C test client:
dataf.h:
struct dataf_t
{
     int iv;
     char sv[256];
};
typedef struct dataf_t *dataf;
testf.c:
#include <stdio.h>
#include <stdint.h>
#ifdef WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#endif
#include "demof_client.h"
int main()
{
#ifdef WIN32
     WSADATA WSAData;
     WSAStartup(0x0101, &WSAData);
#endif
     int32_t stat;
     struct tig_t cli;
     demof_client_init(&cli, "192.168.68.40");
     int v1 = 123;
     int v2 = 456;
     int v3 = 0;
     stat = demof_client_add(&cli, v1, v2, &v3);
     printf("stat = %d\n", stat);
     printf("%d + %d = %d\n", v1, v2, v3);
     char *s1 = "ABC";
     char *s2 = "DEF";
     char *s3 = NULL;
     stat = demof_client_conc(&cli, s1, s2, &s3);
     printf("stat = %d\n", stat);
     printf("|%s| + |%s| = |%s|\n", s1, s2, s3);
     dataf o = malloc(sizeof(struct dataf_t));
     o->iv = 123;
     strcpy(o->sv, "ABC");
     stat = demof_client_modify(&cli, &o);
     printf("stat = %d\n", stat);
     printf("{iv: %d, sv: %s}\n", o->iv, o->sv);
     char *id = NULL;
     stat = demof_client_getid(&cli, &id);
     printf("stat = %d\n", stat);
     printf("id = %s\n", id);
#ifdef WIN32
     WSACleanup();
#endif
     return 0;
}
Clients tested on Windows, but they should work fine on Linux as well -
standard Java/C#/C.
I think the client code looks very reasonable.
Question is whether it is worth continuing working on.
Lots of outstanding work:
* comment code
* document wire protocol
* add support for more data types including VAX float
* add support for arrays outside of structs
* add Python client generation
* add C++ client generation
* add C server generation (there is not really any reason for
   server to be in Java except that it is easier to write a
   multi-threaded server in Java than in C)
Thoughts?
Arne

Date Sujet#  Auteur
1 Aug 24 * BridgeWorks -> TIG8Arne Vajhøj
1 Aug 24 +* Re: BridgeWorks -> TIG3Arne Vajhøj
2 Aug 24 i`* Re: BridgeWorks -> TIG2Simon Clubley
4 Aug 24 i `- Re: BridgeWorks -> TIG1Arne Vajhøj
4 Aug 24 +- Re: BridgeWorks -> TIG1Lawrence D'Oliveiro
12 Aug 24 `* Re: BridgeWorks -> TIG3Arne Vajhøj
14 Aug 24  +- Re: BridgeWorks -> TIG1Arne Vajhøj
11 Nov 24  `- Re: BridgeWorks -> TIG1Arne Vajhøj

Haut de la page

Les messages affichés proviennent d'usenet.

NewsPortal