/*

CLASS {NATIVE_File_stream|_Cpp}, NATIVE :

*/
#ifdef SEPARATE_UNITS
#include "NATIVE_File_stream.h"
#endif

std::vector<FILE*> AL4_Filestream::All_streams;

/*
CONST STR :
    NATIVE_File_stream_import = @
    "#ifdef SEPARATE_UNITS"
    "       #include " #QU "NATIVE_File_stream.h" #QU
    "#endif"
    "#include <stdio.h>"
    "#include <stdlib.h>"
    "#ifdef MSWINDOWS"
    "   #include <io.h>"
    "	#include <time.h>"
    "#else"
    "   #include <sys/io.h>"
    "#endif"
    
	NATIVE_All_streams = ""
    
    NATIVE_File_stream_open = @
    "    if (AL4_Filestream::All_streams.size() == 0)"
    "       AL4_Filestream::All_streams.push_back(nullptr);"
    "    int h = -1;"
    "    for (int i = AL4_Filestream::All_streams.size()-1; i>0; i--)"
    "        if (AL4_Filestream::All_streams[i] == nullptr)"
    "        {"
    "           h = i; break;"
    "        }"
    "    if (h <= 0)"
    "    {"
    "       h = AL4_Filestream::All_streams.size();"
    "       AL4_Filestream::All_streams.push_back(nullptr);"
    "    }"
    "#ifdef MSWINDOWS"
    ""
    ''	 std::wstring fm = L"rb";''
    "    switch (X_Mode)"
    "    {"
    "	 case 1:"
    "		fm = L"#QU"wb"#QU";"
    "       break;"
    "	 case 2:"
    "		fm = L"#QU"r+b"#QU";"
    "       break;"
    "    }"
    "#else"
    ""
    ''	 std::string fm = std::string("rb");''
    "    switch (X_Mode)"
    "    {"
    "	 case 1:"
    "		fm = std::string("#QU"wb"#QU");"
    "       break;"
    "	 case 2:"
    "		fm = "#QU"r+b"#QU";"
    "       break;"
    "    }"
	"#endif"
    "    try {"
    "#ifdef MSWINDOWS"
    "    int siz = MultiByteToWideChar(CP_UTF8, 0, "
    "        X_Path.c_str(), X_Path.length(), NULL, 0);"
    "    std::wstring w;"
    "	 w.reserve(siz);"
    "	 for (int i = 0; i < siz; i++) w += '_';"
    "    MultiByteToWideChar(CP_UTF8, 0, X_Path.c_str(), "
    "           X_Path.length(), &w[0], siz);"
    "        AL4_Filestream::All_streams[h] = _wfopen("
    "            w.c_str(), fm.c_str());"
    ''       if (AL4_Filestream::All_streams[h] == 0 && fm == L"r+b")''
    "            AL4_Filestream::All_streams[h] = _wfopen("
    ''                   w.c_str(), L"w+b");''
    "#else"
    "        AL4_Filestream::All_streams[h] = fopen("
    "            X_Path.c_str(), fm.c_str());"
    ''       if (AL4_Filestream::All_streams[h] == 0 && fm == "r+b")''
    "            AL4_Filestream::All_streams[h] = fopen("
    ''                   X_Path.c_str(), "w+b");''
	"#endif"
    "    }"
    "    catch (std::exception& E) {"
    "       AL4_system::Any_exception(E);"
    "    }"
    "    RESULT = h;"
    
    NATIVE_File_stream_destroy = @
    "if (X_Handle < 1 || X_Handle >= (int)AL4_Filestream::All_streams.size()"
    "	|| AL4_Filestream::All_streams[X_Handle] == nullptr)"
    "   return;"
    "FILE* f = AL4_Filestream::All_streams[X_Handle];"
    "fclose(f);"
    "AL4_Filestream::All_streams[X_Handle] = nullptr;"
    
    NATIVE_File_stream_size = @
    "if (X_Handle < 1 || X_Handle >= (int)AL4_Filestream::All_streams.size()"
    " 	|| AL4_Filestream::All_streams[X_Handle] == nullptr) return 0;"
    "FILE* f = AL4_Filestream::All_streams[X_Handle];"
    "long int cur_pos = ftell(f);"
    "fseek(f, 0, SEEK_END);"
    "RESULT = ftell(f);"
    "fseek(f, cur_pos, SEEK_SET);"
    
    NATIVE_File_stream_position = @
    "if (X_Handle < 1 || X_Handle >= (int)AL4_Filestream::All_streams.size()"
    " 	|| AL4_Filestream::All_streams[X_Handle] == nullptr) return 0;"
    "FILE* f = AL4_Filestream::All_streams[X_Handle];"
    "RESULT = ftell(f);"
    
    NATIVE_File_stream_set_pos = @
    "if (X_Handle < 1 || X_Handle >= (int)AL4_Filestream::All_streams.size()"
    " 	|| AL4_Filestream::All_streams[X_Handle] == nullptr) return;"
    "FILE* f = AL4_Filestream::All_streams[X_Handle];"
    "long To = (long)X_New;"
    "switch (X_Disp)"
    "{"
    "case 0: fseek(f, To, SEEK_SET); break;"
    "case 1: fseek(f, To, SEEK_CUR); break;"
    "case 2: fseek(f, To, SEEK_END); break;"
    "}"
    
    NATIVE_File_stream_close = @
    "if (X_Handle < 1 || X_Handle >= (int)AL4_Filestream::All_streams.size()"
    " 	|| AL4_Filestream::All_streams[X_Handle] == nullptr) return;"
    "FILE* f = AL4_Filestream::All_streams[X_Handle];"
    "fclose(f);"
    "AL4_Filestream::All_streams[X_Handle] = NULL;"
    
    NATIVE_File_stream_read_bytes = @
    "if (X_Handle < 1 || X_Handle >= (int)AL4_Filestream::All_streams.size()"
    " 	|| AL4_Filestream::All_streams[X_Handle] == nullptr) return 0;"
    "FILE* f = AL4_Filestream::All_streams[X_Handle];"
    "char* read_buf = new char[X_Dest->Count()];"
    "int count = X_Dest->Count();"
    "try {"
    "    RESULT = fread(read_buf, 1, count, f);"
    "}"
    "catch (std::exception& E) {"
    "    AL4_system::Any_exception(E);"
    "}"
    "if ((long int)RESULT > count) RESULT = (int)count;"
    "for (int i = 0; i < RESULT; i++)"
    "     X_Dest->set(i, (byte)read_buf[i]);"
    "delete[] read_buf;"
    
    NATIVE_File_stream_write_bytes = @
    "if (X_Handle < 1 || X_Handle >= (int)AL4_Filestream::All_streams.size()"
    " 	|| AL4_Filestream::All_streams[X_Handle] == nullptr) return 0;"
    "FILE* f = AL4_Filestream::All_streams[X_Handle];"
    "try {"
    "    long int was_pos = ftell(f);"
    "    if (X_Source->Count() > 0) {"
    "        RESULT = fwrite("
    "        (char*)X_Source->FirstByte(), 1,"
    "        X_Source->Count(), f);"
    "        fseek(f, was_pos + RESULT, SEEK_SET);"
    "    }"
    "}"
    "catch (std::exception& E) {"
    "    AL4_system::Any_exception(E);"
    "}"
    
    .
    
    
        
END
*/

