blob: f970dd61c2e5b6d333a15e48cfcd2c7c5af4b436 [file] [log] [blame]
/* do not edit automatically generated by mc from mcStream. */
/* mcStream.mod provides an interface to create a file from fragments.
Copyright (C) 2015-2025 Free Software Foundation, Inc.
Contributed by Gaius Mulley <gaius@glam.ac.uk>.
This file is part of GNU Modula-2.
GNU Modula-2 is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GNU Modula-2 is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with GNU Modula-2; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
#include <stdbool.h>
# if !defined (PROC_D)
# define PROC_D
typedef void (*PROC_t) (void);
typedef struct { PROC_t proc; } PROC;
# endif
# if !defined (TRUE)
# define TRUE (1==1)
# endif
# if !defined (FALSE)
# define FALSE (1==0)
# endif
# include "GStorage.h"
#if defined(__cplusplus)
# undef NULL
# define NULL 0
#endif
#define _mcStream_C
#include "GmcStream.h"
# include "GFIO.h"
# include "Glibc.h"
# include "GIndexing.h"
# include "GDynamicStrings.h"
# include "GFormatStrings.h"
# include "GSYSTEM.h"
# include "GStorage.h"
# include "Galists.h"
# include "GSFIO.h"
# include "GM2RTS.h"
typedef FIO_File *mcStream_ptrToFile;
# define maxBuffer 4096
static alists_alist listOfFiles;
static Indexing_Index frag;
static FIO_File destFile;
static bool seenDest;
/*
openFrag - create and open fragment, id, and return the file.
The file should not be closed by the user.
*/
extern "C" FIO_File mcStream_openFrag (unsigned int id);
/*
setDest - informs the stream module and all fragments must be copied
info, f.
*/
extern "C" void mcStream_setDest (FIO_File f);
/*
combine - closes all fragments and then writes them in
order to the destination file. The dest file
is returned.
*/
extern "C" FIO_File mcStream_combine (void);
/*
removeFiles - remove any fragment.
*/
extern "C" void mcStream_removeFiles (void);
/*
removeLater -
*/
static DynamicStrings_String removeLater (DynamicStrings_String filename);
/*
removeNow - removes a single file, s.
*/
static void removeNow (DynamicStrings_String s);
/*
createTemporaryFile -
*/
static FIO_File createTemporaryFile (unsigned int id);
/*
copy - copies contents of f to the destination file.
*/
static void copy (mcStream_ptrToFile p);
/*
removeLater -
*/
static DynamicStrings_String removeLater (DynamicStrings_String filename)
{
alists_includeItemIntoList (listOfFiles, reinterpret_cast <void *> (filename));
return filename;
/* static analysis guarentees a RETURN statement will be used before here. */
__builtin_unreachable ();
}
/*
removeNow - removes a single file, s.
*/
static void removeNow (DynamicStrings_String s)
{
if ((libc_unlink (DynamicStrings_string (s))) != 0)
{} /* empty. */
}
/*
createTemporaryFile -
*/
static FIO_File createTemporaryFile (unsigned int id)
{
DynamicStrings_String s;
FIO_File f;
int p;
s = DynamicStrings_InitString ((const char *) "/tmp/frag-%d-%d.frag", 20);
p = libc_getpid ();
s = removeLater (FormatStrings_Sprintf2 (s, (const unsigned char *) &p, (sizeof (p)-1), (const unsigned char *) &id, (sizeof (id)-1)));
f = SFIO_OpenToWrite (s);
return f;
/* static analysis guarentees a RETURN statement will be used before here. */
__builtin_unreachable ();
}
/*
copy - copies contents of f to the destination file.
*/
static void copy (mcStream_ptrToFile p)
{
typedef struct copy__T1_a copy__T1;
struct copy__T1_a { char array[maxBuffer+1]; };
copy__T1 buffer;
unsigned int b;
DynamicStrings_String s;
FIO_File f;
if (p != NULL)
{
f = (*p);
s = DynamicStrings_InitStringCharStar (FIO_getFileName (f));
FIO_Close (f);
f = SFIO_OpenToRead (s);
while ((! (FIO_EOF (f))) && (FIO_IsNoError (f)))
{
b = FIO_ReadNBytes (f, maxBuffer, &buffer);
if (FIO_IsNoError (f))
{
b = FIO_WriteNBytes (destFile, b, &buffer);
}
else if (! (FIO_EOF (f)))
{
/* avoid dangling else. */
libc_printf ((const char *) "mcStream.mod:copy: error seen when reading file fragment: %s\\n", 62, DynamicStrings_string (s));
libc_exit (1);
}
}
FIO_Close (f);
}
}
/*
openFrag - create and open fragment, id, and return the file.
The file should not be closed by the user.
*/
extern "C" FIO_File mcStream_openFrag (unsigned int id)
{
FIO_File f;
mcStream_ptrToFile p;
f = createTemporaryFile (id);
Storage_ALLOCATE ((void **) &p, sizeof (FIO_File));
(*p) = f;
Indexing_PutIndice (frag, id, reinterpret_cast <void *> (p));
return f;
/* static analysis guarentees a RETURN statement will be used before here. */
__builtin_unreachable ();
}
/*
setDest - informs the stream module and all fragments must be copied
info, f.
*/
extern "C" void mcStream_setDest (FIO_File f)
{
seenDest = true;
destFile = f;
}
/*
combine - closes all fragments and then writes them in
order to the destination file. The dest file
is returned.
*/
extern "C" FIO_File mcStream_combine (void)
{
if (! seenDest)
{
M2RTS_HALT (-1);
__builtin_unreachable ();
}
Indexing_ForeachIndiceInIndexDo (frag, (Indexing_IndexProcedure) {(Indexing_IndexProcedure_t) copy});
mcStream_removeFiles ();
return destFile;
/* static analysis guarentees a RETURN statement will be used before here. */
__builtin_unreachable ();
}
/*
removeFiles - remove any fragment.
*/
extern "C" void mcStream_removeFiles (void)
{
alists_foreachItemInListDo (listOfFiles, (alists_performOperation) {(alists_performOperation_t) removeNow});
alists_killList (&listOfFiles);
listOfFiles = alists_initList ();
}
extern "C" void _M2_mcStream_init (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
{
listOfFiles = alists_initList ();
seenDest = false;
frag = Indexing_InitIndex (1);
}
extern "C" void _M2_mcStream_fini (__attribute__((unused)) int argc, __attribute__((unused)) char *argv[], __attribute__((unused)) char *envp[])
{
}