# HG changeset patch
# User jfp <jf.pieronne@laposte.net>
# Date 1716451717 -7200
#      Thu May 23 10:08:37 2024 +0200
# Node ID a3e428f4938bc17344be0358c9b1cf30f0d8a7c8
# Parent  f04f54a524c6fcdbeb547b59f25545d636e9acd5
rms.search return file fid, use it. Add FILEQIO.create class method

diff --git a/python/local/ovms_module/ovms/fileqio.py b/python/local/ovms_module/ovms/fileqio.py
--- a/python/local/ovms_module/ovms/fileqio.py
+++ b/python/local/ovms_module/ovms/fileqio.py
@@ -1,4 +1,7 @@
 import ctypes
+from ovms import ast
+from ovms import crtl
+from ovms import descrip
 from ovms import iodef
 from ovms import efndef
 from ovms import iosbdef
@@ -8,7 +11,6 @@
 from ovms import atrdef
 from ovms import starlet
 from ovms import stsdef
-from ovms import ast
 from typing import Tuple
 
 
@@ -27,9 +29,10 @@
         self.fibdesc = None
 
     def _open_p1(self) -> Tuple[int, fibdef.FIBDEF]:
-        dev = rms.search(self.filename)[1]
+        rs = rms.search(self.filename, fid=True)
+        dev = rs[1]
+        ifid = rs[-1]
 
-        ifid = rms.getrmsattr(self.filename, rms.RMSATTR_K_FID)
         fid = fibdef.FIDDEF()
         fid.fid_w_num = ifid[0] & 0x0000FFFF
         fid.fid_w_seq = ifid[1] & 0x0000FFFF
@@ -333,3 +336,94 @@
         await ast.wait_completion(astctxt)
         if not stsdef.vms_status_success(iosb.iosb_w_status):
             raise IOError(iosb.iosb_w_status, "IOSB awriteblk error")
+
+    @classmethod
+    def _create(
+        cls,
+        filename: str,
+        exsz: int,
+        fat: fatdef.FAT,
+        astctxt: ast.AstContext | None = None,
+    ) -> iosbdef.IOSB_r_io_64:
+        qio_call = starlet.vms_qiow if astctxt is None else starlet.vms_qio
+        r = rms.parse(filename)
+        chan = starlet.assign(r[1])[1]
+
+        r = b"".join(r[1:3])
+        r = crtl.from_vms(r)
+        r = crtl.to_vms(r, 0, 1) + ".DIR"  # type: ignore
+        r = rms.getrmsattr(r, rms.RMSATTR_K_FID)
+
+        fib = fibdef.FIBDEF()
+        fib.fib_w_nmctl = fibdef.FIB_M_NEWVER
+
+        fib.fib_r_did_fields.fid_w_num = r[0] & 0x0000FFFF
+        fib.fib_r_did_fields.fid_w_seq = r[1] & 0x0000FFFF
+        fib.fib_r_did_fields.fid_b_rvn = (r[0] & 0x00FF0000) >> 16
+        fib.fib_r_did_fields.fid_b_nmx = r[2] & 0xFF
+        fib.fib_w_exctl = fibdef.FIB_M_EXTEND  # | fibdef.FIB_M_ALDEF
+        fib.fib_l_exsz = exsz
+        fib.fib_l_acctl = fibdef.FIB_M_NOWRITE | fibdef.FIB_M_WRITE
+
+        fibdesc = fibdef.FIBDESC()
+        fibdesc.length = ctypes.sizeof(fib)
+        fibdesc.a_fibdef = ctypes.pointer(fib)
+
+        efn = ctypes.c_uint32(efndef.EFN_C_ENF)
+        ichan = ctypes.c_uint16(chan)
+        zero64 = ctypes.c_uint64(0)
+        func = ctypes.c_uint32(iodef.IO__CREATE | iodef.IO_M_CREATE)
+        iosb = iosbdef.IOSB_r_io_64()
+        if astctxt is None:
+            c_ast_completion = None
+            c_ast_param = zero64
+        else:
+            c_ast_completion = ctypes.c_uint64(ast.vms_ast_completion)
+            c_ast_param = ctypes.c_uint64(id(astctxt))
+
+        atr1 = atrdef.ATR()
+        atrdef.set_atr_item(
+            atr1,
+            atrdef.ATR_S_RECATTR,
+            atrdef.ATR_C_RECATTR,
+            ctypes.pointer(fat),
+        )
+        atr2 = atrdef.ATR()  # default fill with zeros
+        atrs = (atrdef.ATR * 2)(atr1, atr2)
+
+        status = qio_call(
+            efn,
+            ichan,
+            func,
+            ctypes.byref(iosb),
+            c_ast_completion,
+            c_ast_param,
+            ctypes.byref(fibdesc),
+            descrip.bydesc(filename.encode()),
+            zero64,
+            zero64,
+            ctypes.byref(atrs),
+            zero64,
+        )
+
+        if not stsdef.vms_status_success(status):
+            starlet.dassgn(chan)
+            raise IOError(status, "qio _create CREATE error")
+
+        return iosb
+
+    @classmethod
+    def create(cls, filename: str, exsz: int, fifat: fatdef.FAT | None = None):
+
+        fat = fatdef.FAT()
+        if fifat is not None:
+            ctypes.memmove(ctypes.byref(fat), ctypes.byref(fifat), ctypes.sizeof(fat))
+        # set eof
+        fat.fat_w_efblkh = 0
+        fat.fat_l_efblkl = 1
+        fat.fat_w_ffbyte = 0
+        iosb = FILEQIO._create(filename, exsz, fat, None)
+        if not stsdef.vms_status_success(iosb.iosb_w_status):
+            raise IOError(iosb.iosb_w_status, "IOSB create error")
+
+        return