• BridgeWorks -> TIG

    From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Thu Aug 1 08:20:28 2024
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Thu Aug 1 09:24:13 2024
    On 8/1/2024 8:20 AM, Arne Vajhøj wrote:
    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).

    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?

    * look at endianess for C# and C - the Java client is endian
    neutral, but the C# and C clients assume running on little
    endian
    * add buffer size arguments to C client API - it is the 21st century

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Simon Clubley@21:1/5 to arne@vajhoej.dk on Fri Aug 2 12:04:46 2024
    On 2024-08-01, Arne Vajhøj <arne@vajhoej.dk> wrote:

    * look at endianess for C# and C - the Java client is endian
    neutral, but the C# and C clients assume running on little
    endian
    * add buffer size arguments to C client API - it is the 21st century


    * Switch to JSON instead of using XML - it is the year 2024. :-)

    Simon.

    --
    Simon Clubley, clubley@remove_me.eisner.decus.org-Earth.UFP
    Walking destinations on a map are further away than they appear.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to Simon Clubley on Sat Aug 3 21:11:38 2024
    On 8/2/2024 8:04 AM, Simon Clubley wrote:
    * Switch to JSON instead of using XML - it is the year 2024. :-)

    I could.

    But I think this is a case where XML is more readable than JSON.

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to All on Sun Aug 4 01:25:38 2024
    On Thu, 1 Aug 2024 08:20:28 -0400, Arne Vajhøj wrote:

    ...
    <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>
    ...

    This looks so much like the D-Bus introspection format <https://www.freedesktop.org/wiki/Software/dbus/>, <https://dbus.freedesktop.org/doc/dbus-specification.html#introspection-format>

    See also Varlink <https://varlink.org/>, which uses a JSON-based
    channel data format.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Sun Aug 11 19:03:25 2024
    On 8/1/2024 8:20 AM, Arne Vajhøj wrote:
    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).

    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?

    Not much feedback, but I did some of the outstanding tasks and
    packed it up.

    Start here:

    https://www.vajhoej.dk/arne/opensource/vms/doc/tig/doc/

    Download links:

    https://www.vajhoej.dk/arne/opensource/vms/vmstig-bin-v0_1.zip https://www.vajhoej.dk/arne/opensource/vms/vmstig-client-v0_1.zip https://www.vajhoej.dk/arne/opensource/vms/vmstig-src-v0_1.zip

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Wed Aug 14 10:27:25 2024
    On 8/11/2024 7:03 PM, Arne Vajhøj wrote:
    Not much feedback, but I did some of the outstanding tasks and
    packed it up.

    Start here:

    https://www.vajhoej.dk/arne/opensource/vms/doc/tig/doc/

    Download links:

    https://www.vajhoej.dk/arne/opensource/vms/vmstig-bin-v0_1.zip https://www.vajhoej.dk/arne/opensource/vms/vmstig-client-v0_1.zip https://www.vajhoej.dk/arne/opensource/vms/vmstig-src-v0_1.zip

    I have updated.

    Despite the native languages on VMS being non-OO then it
    bothered me that the client side API was really non-OO
    (classes were used but without any data in the class
    it is not much OO).

    So I came up with a hack.

    VMS code (C in this case):

    struct ooctx
    {
    int counter;
    };

    static int counter = 0;

    long increment(struct ooctx *ctx)
    {
    counter++;
    ctx->counter++;
    return 1;
    }

    long get(struct ooctx *ctx, long *c1, long *c2)
    {
    *c1 = counter;
    *c2 = ctx->counter;
    return 1;
    }

    Silly example, but it should illustrate the difference
    between a global variable and a client specific context.

    XML to describe API:

    <config>
    <image>demoo</image>
    <port>12350</port>
    <mt>false</mt>
    <oocontext>o</oocontext> <!-- <=============== this is the trick -->
    <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.PyClientGen</language>
    <language>dk.vajhoej.vms.tig.client.CppClientGen</language>
    </client>
    <methods>
    <method>
    <name>increment</name>
    <args/>
    </method>
    <method>
    <name>get</name>
    <args>
    <arg>
    <name>c1</name>
    <type>LongWord</type>
    <pass>Reference</pass>
    <use>Out</use>
    </arg>
    <arg>
    <name>c2</name>
    <type>LongWord</type>
    <pass>Reference</pass>
    <use>Out</use>
    </arg>
    </args>
    </method>
    </methods>
    </config>

    And let us take client in Python.

    First O.py for client access to context:

    import struct

    class O:
    def __init__(self, counter = 0):
    self.counter = counter
    def pack(self):
    return struct.pack('<l', self.counter)
    def unpack(self, blk):
    self.counter = struct.unpack('<l', blk)[0]

    Test:

    from sys import argv

    from DemooClient import *

    for i in range(3):
    cli = DemooClient(argv[1])
    for j in range(3):
    stat = cli.increment()
    stat, c1, c2 = cli.get()
    print('%d %d (%d)' % (c1, c2, cli.oocontext().counter))

    Output:

    C:\Code\VMS\tig\examples>python testo.py 192.168.68.40
    1 1 (1)
    2 2 (2)
    3 3 (3)
    4 1 (1)
    5 2 (2)
    6 3 (3)
    7 1 (1)
    8 2 (2)
    9 3 (3)

    If one is not interested in the context client side (private context
    in OO world), then one can just specify the size of the context instead
    of the type.

    <oocontext>o</oocontext>



    <oocontext>4</oocontext>

    and drop O.py implementation and do not try to access context
    from client.

    Python client:

    from sys import argv

    from DemoqClient import *

    for i in range(3):
    cli = DemoqClient(argv[1])
    for j in range(3):
    stat = cli.increment()
    stat, c1, c2 = cli.get()
    print('%d %d' % (c1, c2))

    https://www.vajhoej.dk/arne/opensource/vms/vmstig-bin-v0_2.zip https://www.vajhoej.dk/arne/opensource/vms/vmstig-client-v0_2.zip https://www.vajhoej.dk/arne/opensource/vms/vmstig-src-v0_2.zip

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From =?UTF-8?Q?Arne_Vajh=C3=B8j?=@21:1/5 to All on Mon Nov 11 15:39:39 2024
    On 8/11/2024 7:03 PM, Arne Vajhøj wrote:
    On 8/1/2024 8:20 AM, Arne Vajhøj wrote:
    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).

    Start here:

    https://www.vajhoej.dk/arne/opensource/vms/doc/tig/doc/

    I have updated again.

    Support for PHP and VB.NET client side.

    Support for inheriting OO context.

    Download links:

    https://www.vajhoej.dk/arne/opensource/vms/vmstig-bin-v0_3.zip https://www.vajhoej.dk/arne/opensource/vms/vmstig-client-v0_3.zip https://www.vajhoej.dk/arne/opensource/vms/vmstig-src-v0_3.zip

    Arne

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)