0671 nwnss: add userspace virtual IO template boundary

This commit is contained in:
ChatGPT
2026-06-16 20:01:06 +00:00
committed by Mario Fetka
parent b40b3ed0a6
commit c190586252
2 changed files with 334 additions and 0 deletions

View File

@@ -157,6 +157,7 @@ add_library(nwnss SHARED
comn/common/nameCache.c
comn/common/objectIDStore.c
comn/common/virtualIOShared.c
comn/common/virtualIOUserspace.c
comn/compression/cmCompFile.c
comn/compression/cmRuntime.c
comn/sbs/sbsMFL.c

View File

@@ -0,0 +1,333 @@
/****************************************************************************
| MARS-NWE libnwnss userspace virtual I/O boundary helpers.
+-------------------------------------------------------------------------*/
#include <string.h>
#include <library/omni.h>
#include <public/zError.h>
#include <public/zFsMsg.h>
#include <public/zPublics.h>
#include <include/latch.h>
#include <include/schedule.h>
#include <comnSA/fileHandle.h>
#include <include/virtualIO.h>
#if defined(MARS_NWE_NWNSS_USERSPACE)
BOOL VIRT_PrintDebug = FALSE;
QUAD AdminVolWrites = 0;
QUAD AdminVolReads = 0;
static STATUS virtWriteAll(Key_t key, NINT *filePos, const void *buffer, NINT len)
{
NINT retLen = 0;
STATUS status;
status = zWrite(key, zNILXID, *filePos, len, buffer, &retLen);
if (status != zOK)
{
return status;
}
*filePos += retLen;
return zOK;
}
STATUS VIRT_Write(struct zNSSMsg_s *msg)
{
(void)msg;
return zERR_NOT_SUPPORTED;
}
STATUS VIRT_ChunkyRead(struct zNSSMsg_s *msg)
{
(void)msg;
return zERR_NOT_SUPPORTED;
}
STATUS VIRT_Close(struct zNSSMsg_s *msg)
{
(void)msg;
return zOK;
}
STATUS VIRT_InitVirtualFile(Key_t key, NINT *filePos)
{
const utf8_t initTemplate[] =
"<virtualIO><define/></virtualIO><?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
"<transform>\n";
return virtWriteAll(key, filePos, initTemplate, strlen((const char *)initTemplate));
}
STATUS VIRT_FinishVirtualFile(Key_t key, NINT *filePos)
{
const utf8_t endTemplate[] = "</transform>";
return virtWriteAll(key, filePos, endTemplate, strlen((const char *)endTemplate));
}
static STATUS VIRT_AddDataStream(
utf8_t *dataStreamName,
NINT bufLen,
utf8_t **buffer)
{
const utf8_t templateStart[] = " <datastream";
const utf8_t templateName[] = " name=\"";
const utf8_t templateEnd[] = ">\n";
NINT startLen = strlen((const char *)templateStart);
NINT nameLen = strlen((const char *)templateName);
NINT endLen = strlen((const char *)templateEnd);
NINT dataStreamNameLen = 0;
if (dataStreamName != NULL)
{
dataStreamNameLen = strlen((const char *)dataStreamName);
if ((dataStreamNameLen + startLen + nameLen + endLen + 1) >= bufLen)
{
return zERR_XML_TOO_LONG;
}
}
strcpy((char *)*buffer, (const char *)templateStart);
*buffer += startLen;
if (dataStreamName != NULL)
{
strcpy((char *)*buffer, (const char *)templateName);
*buffer += nameLen;
strcpy((char *)*buffer, (const char *)dataStreamName);
*buffer += dataStreamNameLen;
*((*buffer)++) = '"';
}
strcpy((char *)*buffer, (const char *)templateEnd);
*buffer += endLen;
return zOK;
}
static STATUS VIRT_FinishDataStream(NINT bufLen, utf8_t **buffer)
{
const utf8_t template[] = " </datastream>\n";
NINT templateLen = strlen((const char *)template);
if (templateLen >= bufLen)
{
return zERR_XML_TOO_LONG;
}
strcpy((char *)*buffer, (const char *)template);
*buffer += templateLen;
return zOK;
}
#define VIRT_BUILD_BUFFER_LEN 1024
#define VIRT_BUILD_BUFFER(_data) \
do { \
len = strlen((const char *)(_data)); \
if ((curptr + len - buffer + 1) >= VIRT_BUILD_BUFFER_LEN) \
{ \
status = zERR_XML_TOO_LONG; \
goto errorExit; \
} \
strcpy((char *)curptr, (const char *)(_data)); \
curptr += len; \
} while (0)
STATUS VIRT_MakeReadWriteFuncDataStream(
Key_t key,
utf8_t *dataStreamName,
utf8_t *readRoutine,
utf8_t *readParm,
utf8_t *writeRoutine,
utf8_t *writeParm,
BOOL useCookieRead,
NINT *filePos)
{
utf8_t *curptr;
utf8_t buffer[VIRT_BUILD_BUFFER_LEN];
STATUS status;
NINT len;
const utf8_t *ReadWriteTemplate1 = MSGNot("<function>\n");
const utf8_t *ReadWriteTemplate2 = MSGNot("\"");
const utf8_t *ReadWriteTemplate3 = MSGNot("</readfunc>\n");
const utf8_t *ReadWriteTemplate4 = MSGNot("<writefunc symname=\"");
const utf8_t *ReadWriteTemplate5 = MSGNot("</writefunc>\n");
const utf8_t *ReadWriteTemplate6 = MSGNot("</function>\n");
const utf8_t *ReadWriteTemplate7 = MSGNot(" cookie=\"yes\"");
const utf8_t *ReadWriteTemplate8 = MSGNot(">");
const utf8_t *ReadWriteTemplate9 = MSGNot("<readfunc symname=\"");
curptr = buffer;
if ((status = VIRT_AddDataStream(dataStreamName, VIRT_BUILD_BUFFER_LEN, &curptr)) != zOK)
{
goto errorExit;
}
VIRT_BUILD_BUFFER(ReadWriteTemplate1);
if ((readRoutine != NULL) && (*readRoutine != 0))
{
VIRT_BUILD_BUFFER(ReadWriteTemplate9);
VIRT_BUILD_BUFFER(readRoutine);
VIRT_BUILD_BUFFER(ReadWriteTemplate2);
if (useCookieRead)
{
VIRT_BUILD_BUFFER(ReadWriteTemplate7);
}
VIRT_BUILD_BUFFER(ReadWriteTemplate8);
if (readParm != NULL)
{
VIRT_BUILD_BUFFER(readParm);
}
VIRT_BUILD_BUFFER(ReadWriteTemplate3);
}
if ((writeRoutine != NULL) && (*writeRoutine != 0))
{
VIRT_BUILD_BUFFER(ReadWriteTemplate4);
VIRT_BUILD_BUFFER(writeRoutine);
VIRT_BUILD_BUFFER(ReadWriteTemplate2);
VIRT_BUILD_BUFFER(ReadWriteTemplate8);
if (writeParm != NULL)
{
VIRT_BUILD_BUFFER(writeParm);
}
VIRT_BUILD_BUFFER(ReadWriteTemplate5);
}
VIRT_BUILD_BUFFER(ReadWriteTemplate6);
if ((status = VIRT_FinishDataStream(VIRT_BUILD_BUFFER_LEN, &curptr)) != zOK)
{
goto errorExit;
}
return virtWriteAll(key, filePos, buffer, strlen((const char *)buffer));
errorExit:
return status;
}
STATUS VIRT_MakeUserReadWriteFuncDataStream(
Key_t key,
utf8_t *dataStreamName,
utf8_t *readLibrary,
utf8_t *readRoutine,
utf8_t *readParm,
utf8_t *writeLibrary,
utf8_t *writeRoutine,
utf8_t *writeParm,
BOOL useCookieRead,
NINT *filePos)
{
utf8_t *curptr;
utf8_t buffer[VIRT_BUILD_BUFFER_LEN];
STATUS status;
NINT len;
const utf8_t *ReadWriteTemplate1 = MSGNot("<function>\n");
const utf8_t *ReadWriteTemplate2 = MSGNot("\"");
const utf8_t *ReadWriteTemplate3 = MSGNot("</readfunc>\n");
const utf8_t *ReadWriteTemplate4 = MSGNot("<writefunc symtype=\"user\" symname=\"");
const utf8_t *lineFuncLibrary = MSGNot("\" library=\"");
const utf8_t *ReadWriteTemplate5 = MSGNot("</writefunc>\n");
const utf8_t *ReadWriteTemplate6 = MSGNot("</function>\n");
const utf8_t *ReadWriteTemplate7 = MSGNot(" cookie=\"yes\"");
const utf8_t *ReadWriteTemplate8 = MSGNot(">");
const utf8_t *ReadWriteTemplate9 = MSGNot("<readfunc symtype=\"user\" symname=\"");
curptr = buffer;
if ((status = VIRT_AddDataStream(dataStreamName, VIRT_BUILD_BUFFER_LEN, &curptr)) != zOK)
{
goto errorExit;
}
VIRT_BUILD_BUFFER(ReadWriteTemplate1);
if ((readRoutine != NULL) && (*readRoutine != 0))
{
VIRT_BUILD_BUFFER(ReadWriteTemplate9);
VIRT_BUILD_BUFFER(readRoutine);
VIRT_BUILD_BUFFER(lineFuncLibrary);
VIRT_BUILD_BUFFER(readLibrary);
VIRT_BUILD_BUFFER(ReadWriteTemplate2);
if (useCookieRead)
{
VIRT_BUILD_BUFFER(ReadWriteTemplate7);
}
VIRT_BUILD_BUFFER(ReadWriteTemplate8);
if (readParm != NULL)
{
VIRT_BUILD_BUFFER(readParm);
}
VIRT_BUILD_BUFFER(ReadWriteTemplate3);
}
if ((writeRoutine != NULL) && (*writeRoutine != 0))
{
VIRT_BUILD_BUFFER(ReadWriteTemplate4);
VIRT_BUILD_BUFFER(writeRoutine);
VIRT_BUILD_BUFFER(lineFuncLibrary);
VIRT_BUILD_BUFFER(writeLibrary);
VIRT_BUILD_BUFFER(ReadWriteTemplate2);
VIRT_BUILD_BUFFER(ReadWriteTemplate8);
if (writeParm != NULL)
{
VIRT_BUILD_BUFFER(writeParm);
}
VIRT_BUILD_BUFFER(ReadWriteTemplate5);
}
VIRT_BUILD_BUFFER(ReadWriteTemplate6);
if ((status = VIRT_FinishDataStream(VIRT_BUILD_BUFFER_LEN, &curptr)) != zOK)
{
goto errorExit;
}
return virtWriteAll(key, filePos, buffer, strlen((const char *)buffer));
errorExit:
return status;
}
STATUS VIRT_MakeDataTypeDataStream(
Key_t key,
utf8_t *dataStreamName,
utf8_t *data,
NINT *filePos)
{
utf8_t *curptr;
utf8_t buffer[VIRT_BUILD_BUFFER_LEN];
STATUS status;
NINT len;
const utf8_t *ReadWriteTemplate1 = MSGNot("<data>");
const utf8_t *ReadWriteTemplate2 = MSGNot("</data>");
curptr = buffer;
if ((status = VIRT_AddDataStream(dataStreamName, VIRT_BUILD_BUFFER_LEN, &curptr)) != zOK)
{
goto errorExit;
}
VIRT_BUILD_BUFFER(ReadWriteTemplate1);
if (data != NULL)
{
VIRT_BUILD_BUFFER(data);
}
VIRT_BUILD_BUFFER(ReadWriteTemplate2);
if ((status = VIRT_FinishDataStream(VIRT_BUILD_BUFFER_LEN, &curptr)) != zOK)
{
goto errorExit;
}
return virtWriteAll(key, filePos, buffer, strlen((const char *)buffer));
errorExit:
return status;
}
#undef VIRT_BUILD_BUFFER
#endif /* MARS_NWE_NWNSS_USERSPACE */