unit NATIVE_String_functions;
interface

uses AL4 {$IFnDEF linux} , Windows {$ENDIF} {$IFDEF FPC} , Classes {$ENDIF};

function Do_Oem_to_string(const X_Oem: String): String;
function Do_Ansi_to_utf8(const X_Ansi: AnsiString): String;
function Do_Ansi_bytes_to_utf8(X_Ansi: DynAByte): String;


implementation

function Do_Oem_to_string(const X_Oem: AnsiString): String;
{$IFDEF FPC}
	{$IFnDEF linux}
var buf: PWideChar;
	W: WideString;
	{$ENDIF}
{$ELSE}
var buf: PChar;
{$ENDIF}
begin
	{$IFDEF linux}
	Result := X_Oem;
	{$ELSE}
	     GetMem(buf, (Length(X_Oem)+1) {$IFDEF FPC} * Sizeof(WideChar) {$ENDIF} );
	     buf[Length(X_Oem)] := #0;
	     {$IFDEF FPC}
		     OemToCharBuffW(PChar(X_Oem), buf, Length(X_Oem));
		     W := buf;
		     Result := W;
	     {$ELSE}
		     OemToCharBuffA(PChar(X_Oem), buf, Length(X_Oem));
		     RESULT := buf;
	     {$ENDIF}
	     FreeMem(buf);
	{$ENDIF}
end;

function Do_Ansi_to_utf8(const X_Ansi: AnsiString): String;
begin
	{$IFDEF FPC}
	Result := AnsiToUtf8(X_Ansi);
	{$ELSE}
	RESULT := X_Ansi;
	{$ENDIF}
end;

function Do_Ansi_bytes_to_utf8(X_Ansi: DynAByte): String;
{$IFDEF FPC}
var //p: PChar;
	L: TList;
	len_r: Integer;
	r: RawByteString;
	i: Integer;
{$ENDIF}
begin
	{$IFDEF FPC}
	L := X_Ansi.List;
	len_r := X_Ansi.Count();
	SetLength(r, len_r);
	for i := 0 to len_r-1 do
	    r[i+1] := AnsiChar(X_Ansi.GetBytes(i)) ;
	//p := PChar( @L.List[0]);
	SetCodePage(r, 1251, false);
	//SetCodePage(r, CP_UTF8, true);
	Result := AnsiToUtf8(r);
	{$ELSE}
	RESULT := '';
	{$ENDIF}
end;

(*
/*

CLASS {NATIVE_String_functions|_Delphi_FPC},
	NATIVE, BITWISE, BYTES, UNTESTED,
	ABSTRACT :

IMPORT: {String_functions}, {System_functions} .

NATIVE: "///COPY NATIVE_String_functions.pas" .

FUN Get_inner_encoding
|_of_strings_in_the_environment ==> {String_functions}.{encoding}, NATIVE : @
"	{$IFDEF FPC}"
"		RESULT := 1;"
"	{$ELSE}"
"		RESULT := 0;"
"	{$ENDIF}" .

FUN Is_encoding_supported(
	{encoding} E|ncoding) ==> BOOL, NATIVE : @ 
	"{$IFDEF LINUX}"
    "CASE X_E OF"
    "0, //'DEFAULT'"
    "1, //'ASCII',"
    "2, //'UTF8'"
    "3, //'UTF16'"
    "4, //'UTF16_BIG'"
    "6, //'UTF32'"
    "7: //'UTF32_BIG'"
    "	RESULT := TRUE"
    "end;"
	"{$ELSE}"
    "CASE X_E OF"
    "1, //'ASCII',"
    "2, //'UTF8'"
    "3, //'UTF16'"
    "4, //'UTF16_BIG'"
    "5, //'UTF7'"
    "6, //'UTF32'"
    "7, //'UTF32_BIG'"
    "0: //'DEFAULT'"
    "	RESULT := TRUE"
    "end;"
    "{$ENDIF}" 
    .
    
FUN Get_bytes_from_default(
	BYTE D|est_buffer_bytes[], STR S|ource_ascii ), NATIVE
	: NATIVE NATIVE_Bytes_from_ascii .
	
FUN Trim_string(STR S|tring_to_trim) ==> STR, NATIVE : @
	"{$IFDEF FPC}"
	"	RESULT := Trim(X_S.As_string);"
	"{$ELSE}"     
	"	RESULT := Trim(X_S);"
	"{$ENDIF}"
	.

FUN Trim_left_string(STR S|tring_to_trim) ==> STR, NATIVE : @
	"{$IFDEF FPC}"
	"   RESULT := TrimLeft(X_S.As_string);"
	"{$ELSE}"     
	"   RESULT := TrimLeft(X_S);" 
	"{$ENDIF}"
	.

FUN Trim_right_string(STR S|tring_to_trim) ==> STR, NATIVE :
	"{$IFDEF FPC}"
	"   RESULT := TrimRight(X_S.As_string);"
	"{$ELSE}"     
	"   RESULT := TrimRight(X_S);" 
	"{$ENDIF}"
	.     

FUN Split_string_native(
STR Dest|ination_buffer[], STR S|tring_to_trim, STR By|_separator), NATIVE : @
	"{$IFDEF FPC}"
	"   Do_split_string(X_Dest, X_S.As_string, X_By.As_string);" 
	"{$ELSE}"     
	"   Do_split_string(X_Dest, X_S, X_By);" 
	"{$ENDIF}"
	.

CONST STR: 
	
	NATIVE_import_string_functions = @
	"uses {$IFDEF LINUX}"
	"	  {$ELSE} "
	"			Windows,"
	" 	  {$ENDIF} NATIVE_String_functions ;"

	NATIVE_Path_sep = @
	"{$IFDEF LINUX}"
	"	RESULT := '/';"
	"{$ELSE}"
	"	RESULT := '\';"
	"{$ENDIF}"
	
	NATIVE_Char = @
	"{$IFDEF FPC}"
	"RESULT := UTF16ToUTF8('' + WideChar(X_I));"
	"{$ELSE}"     
	"RESULT := '' + Char(X_I);"
	"{$ENDIF}"     
	
	NATIVE_Ord = @
	"{$IFDEF FPC}"
	"if Compare_strings(X_Ch, '') <> 0 then RESULT := Integer(Str_X_Ch[1]);"
	"{$ELSE}"     
	"if X_Ch <> '' then RESULT := Integer(X_Ch[ 1 ]);"
	"{$ENDIF}"     
	
	NATIVE_Upper = @
	"RESULT := {$IFDEF FPC} X_S.ToUpper {$ELSE} AnsiUpperCase(X_S) {$ENDIF} ;"
	
	NATIVE_Lower = @
	"RESULT := {$IFDEF FPC} X_S.ToLower {$ELSE} AnsiLowerCase(X_S) {$ENDIF} ;"
	
	NATIVE_Repeat = @
	"var i, dest: Integer;"
	"var s: String;"
	"{$IFDEF FPC} s := Str_X_What;"
	"{$ELSE} s := X_What;"
	"{$ENDIF}"     
	"SetLength(RESULT, Length(s) * X_Count);"
	"dest := 1;"     
	"for i := 0 to X_Count-1 do begin"
	"	 Move(s[1], Result[dest], Length(s));"
	"	 inc(dest, Length(s));"
	"end;"     
	
    NATIVE_Bytes_to_ascii = @
    "var i: Integer;"
   	"    SetLength(Result, X_B.Count());"
    "    if X_B.Count() = 0 then Exit;"
    "	 {$IFDEF USE_FirstByte}"
    "    	Move(X_B.FirstByte()^, Result[1], X_B.Count());"
    "		{$IFnDEF SMALLER_CODE}"
    "			i := 0; if i = 0 then;"     
    "		{$ENDIF}"     
    "	 {$ELSE}"
    "		for i := 0 to X_B.Count()-1 do "
    "			Result[i+1] "
    "			:= Char(X_B.GetBytes(i));"
    "	 {$ENDIF}"
	
	NATIVE_Bytes_to_utf8 = @
	"var size: Integer;"
	" {$IFDEF FPC} var UTF8Str:UTF8String;"
	" {$ELSE} WStr: WideString;"
	" {$ENDIF}"
    "var {$IFNDEF USE_FirstByte} buf: array of Byte; {$ELSE}dummy:Byte;{$ENDIF}"
 	"var i: Integer;"
 	"{$IFDEF FPC}"
    "	 SetLength(UTF8Str, X_B.Count());"
    "	 {$IFDEF USE_FirstByte}"
    "	 	move(X_B.FirstByte()^, UTF8Str[1], X_B.Count());"
    "		{$IFnDEF SMALLER_CODE}"
    "			i := 0; if i = 0 then;"     
    "		{$ENDIF}"     
    "	 {$ELSE}"
    "		for i := 0 to X_B.Count()-1 do"
    "			UTF8Str[i+1] := AnsiChar(X_B.GetBytes(i));"
    "	 {$ENDIF}"
    "	 Result := UTF8Str;"
 	"{$ELSE}"
    "    if X_B.Count() = 0 then Exit;"
	"	 	{$IFDEF USE_FirstByte}"
    "           {$IFnDEF SMALLER_CODE}"
    "           	dummy := 0; if dummy = 0 then;"     
    "           {$ENDIF}"     
    "    		size := MultiByteToWideChar(CP_UTF8, 0, Pointer("
    "            	X_B.FirstByte()), X_B.Count(), nil, 0);"
    "    		SetLength(WStr, size);"
    "    		MultiByteToWideChar(CP_UTF8, 0, Pointer("
    "            	X_B.FirstByte()), X_B.Count(), "
    "            	PWideChar(WStr), size);"
    "		    {$IFnDEF SMALLER_CODE}"
    "			    i := 0; if i = 0 then;"     
    "		    {$ENDIF}"     
    "	 	{$ELSE}"
    "			SetLength(buf, X_B.Count());"
    "			for i := 0 to X_B.Count()-1 do"
    "				buf[i] := X_B.GetBytes(i);"
    "			size := MultiByteToWideChar(CP_UTF8, 0, @buf[0],"
    "            	Length(buf), nil, 0);"
    "    		SetLength(WStr, size);"
    "    		MultiByteToWideChar(CP_UTF8, 0, @buf[0],"
    "            	Length(buf), PWideChar(WStr), size);"
    "	 	{$ENDIF}"
    "    	Result := WStr;"
 	"{$ENDIF}"   
	
	NATIVE_Bytes_to_utf7 = @
	"var size: Integer; WStr: WideString;"
    "var {$IFNDEF USE_FirstByte} buf: array of Byte; {$ELSE}dummy:Byte;{$ENDIF}"
 	"var i: Integer;"
    "	 {$IFnDEF LINUX}"
    "    	if X_B.Count() = 0 then Exit;"
    "	 	{$IFDEF USE_FirstByte}"
    "           {$IFnDEF SMALLER_CODE}"
    "           	dummy := 0; if dummy = 0 then;"     
    "           {$ENDIF}"     
    "    		size := MultiByteToWideChar(CP_UTF7, 0, Pointer("
    "            X_B.FirstByte()), X_B.Count(), nil, 0);"
    "    		SetLength(WStr, size);"
    "    		MultiByteToWideChar(CP_UTF7, 0, Pointer("
    "            X_B.FirstByte()), X_B.Count(),"
    "            PWideChar(WStr), size);"
    "           {$IFnDEF SMALLER_CODE}"
    "      	     i := 0; if i = 0 then;"     
    "           {$ENDIF}"     
    "	 	{$ELSE}"
    "			SetLength(buf, X_B.Count());"
    "			for i := 0 to High(buf) do"
    "				buf[i] := X_B.GetBytes(i);"
    "			size := MultiByteToWideChar(CP_UTF7, 0, @buf[0], Length(buf), "
    "				nil, 0);"
    "    		SetLength(WStr, size);"
    "    		MultiByteToWideChar(CP_UTF7, 0, @buf[0], Length(buf),"
    "            PWideChar(WStr), size);"
    "	 	{$ENDIF}"
    "    	Result := WStr;"
    "	 {$ENDIF}"
	
	NATIVE_Bytes_to_utf16 = @
	"var i: Integer; WStr: WideString;"
 	"    Result := '';" 
    "    if X_B.Count() <= 1 then Exit;"
    "    SetLength(WStr, X_B.Count() div 2);"
    "	 {$IFDEF USE_FirstByte}"
    "    	Move(X_B.FirstByte()^, PWideChar(@WStr[1])^, X_B.Count());"
    "		{$IFnDEF SMALLER_CODE}"
    "			i := 0; if i = 0 then;"     
    "		{$ENDIF}"     
    "	 {$ELSE}"
    "		for i := 0 to Length(WStr)-1 do"
    "			WStr[i + 1] "
    "				:= WideChar(X_B.GetBytes(i*2) + X_B.GetBytes(i*2+1) shl 8);"
    "	 {$ENDIF}"
    "    Result := WStr;" 
	
	NATIVE_Bytes_to_utf16_big = @
	"var i: Integer; WStr: WideString;"
    "var BPtr: {$IFDEF FPC} PByte {$ELSE} PByte_array {$ENDIF} ;"
    "var tmp: Byte;"
	"    Result := '';" 
    "    if X_B.Count() <= 1 then Exit;"
    "    SetLength(WStr, X_B.Count() div 2);"
    "	 {$IFDEF USE_FirstByte}"
    "    	Move(X_B.FirstByte()^, PWideChar(@WStr[1])^, X_B.Count());"
    "	 {$ELSE}"
    "		for i := 0 to Length(WStr)-1 do"
    "			WStr[i + 1] "
    "				:= WideChar(X_B.GetBytes(i*2) + X_B.GetBytes(i*2+1) shl 8);"
    "	 {$ENDIF}"
    "    for i := 0 to Length(WStr)-1 do"
    "    begin"
    "        BPtr := Pointer(@WStr[i + 1]);"
    "        tmp := BPtr[0];"
    "        BPtr[0] := BPtr[1];"
    "        BPtr[1] := tmp;"
    "    end;"
    "    Result := WStr;" 
	
	NATIVE_Bytes_to_utf32 = @
	"var i: Integer; WStr: WideString;"
    "var len: Integer;"
    "var WChr: PWideChar;"
    "var u: DWORD;"
	"    Result := '';"
    "    if X_B.Count() <= 3 then Exit;"
    "    len := 0;"
    "    for i := 0 to X_B.Count() div 4 - 1 do"
    "    begin"
    "        u := X_B.GetBytes(i*4) or ("
    "             X_B.GetBytes(i*4 + 1) shl 8) or ("
    "             X_B.GetBytes(i*4 + 2) shl 16) or ("
    "             X_B.GetBytes(i*4 + 3) shl 24);"
    "        if u <= $FFFF then inc(len);"
    "    end;"
    "    if len = 0 then Exit;"
    "    SetLength(WStr, len);"
    "    WChr := PWideChar(@WStr[0 + 1]);"
    "    for i := 0 to X_B.Count() div 4 - 1 do"
    "    begin"
    "        u := X_B.GetBytes(i*4) or ("
    "             X_B.GetBytes(i*4 + 1) shl 8) or ("
    "             X_B.GetBytes(i*4 + 2) shl 16) or ("
    "             X_B.GetBytes(i*4 + 3) shl 24);"
    "        if u <= $FFFF then"
    "        begin"
    "           WChr^ := WideChar(u);"
    "           inc(WChr);"
    "        end;"
    "    end;"
    "    Result := WStr;" 
	
	NATIVE_Bytes_to_utf32_big = @
	"var WStr: WideString;"
    "var len: Integer;"
    "var i: Integer;"
    "var WChr: PWideChar;"
    "var u: DWORD;"
	"    Result := '';"
    "    if X_B.Count() <= 3 then Exit;"
    "    len := 0;"
    "    for i := 0 to X_B.Count() div 4 - 1 do"
    "    begin"
    "        u := X_B.GetBytes(i*4) or ("
    "             X_B.GetBytes(i*4 + 1) shl 8) or ("
    "             X_B.GetBytes(i*4 + 2) shl 16) or ("
    "             X_B.GetBytes(i*4 + 3) shl 24);"
    "        if u and $FFFF = 0 then inc(len);"
    "    end;"
    "    if len = 0 then Exit;"
    "    SetLength(WStr, len);"
    "    WChr := PWideChar(@WStr[0 + 1]);"
    "    for i := 0 to X_B.Count() div 4 - 1 do"
    "    begin"
    "        u := X_B.GetBytes(i * 4) shl 24 or"
    "             X_B.GetBytes(i * 4 + 1) shl 16 or"
    "             X_B.GetBytes(i * 4 + 2) shl 8 or"
    "             X_B.GetBytes(i * 4 + 3);"
    "        if  u <= $FFFF then"
    "        begin"
    "           WChr^ := WideChar(u);"
    "           inc(WChr);"
    "        end;"
    "    end;"
    "    Result := WStr;"
    
    NATIVE_Bytes_from_ascii = @
    "var s: String; {$IFnDEF USE_FirstByte} i: Integer; {$ENDIF} "
    "	 {$IFDEF FPC}"
    "		s := X_S.As_string;"     
    "	 {$ELSE}"
    "		s := X_S;"     
    "	 {$ENDIF}"     
   	"    X_D.Clear;"
    "    if Length(s) = 0 then Exit;"
    "    X_D.Extend(0, Length(s));"
    "	 {$IFDEF USE_FirstByte}"
    "    	Move(s[1], X_D.FirstByte()^, Length(s));"
    "	 {$ELSE}"
    "	    for i := 0 to Length(s)-1 do"
    "		    X_D.SetBytes(i, Ord(s[i+1]));"
    "	 {$ENDIF}"
    
    NATIVE_Bytes_from_utf8 = @
	"var {$IFDef LINUX} Buf: TBytes; {$ELSE} WStr: WideString; {$ENDIF}"
    "var size, i: Integer; {$IFNDEF LINUX} bb: PByte; {$ENDIF}"
    "{$IFDef LINUX}"
    "	 Buf := TEncoding.UTF8.GetBytes("
    "			{$IFDEF FPC} Str_X_S {$ELSE} X_S {$ENDIF});"
    "	 X_D.Extend(0, Length(Buf));"
    "	 {$IFDEF USE_FirstByte}"
    "	 	move(Buf[0], X_D.FirstByte()^, Length(Buf));"
    "	 {$ELSE}"
	"		for i := 0 to Length(Buf)-1 do"
	"			X_D.SetBytes(i, Buf[i]);"
    "	 {$ENDIF}"
    "	 SetLength(Buf, 0);"
    "{$ELSE}"
    "    WStr := {$IFDEF FPC} Str_X_S {$ELSE} X_S {$ENDIF};"
    "    X_D.Clear;"
    "    size := WideCharToMultiByte(CP_UTF8, 0, PWideChar(WStr),"
    "       Length(WStr), nil, 0, nil, nil);"
    "    if size = 0 then Exit;"
    "    X_D.Extend(0, size);"
    "	 {$IFDEF USE_FirstByte}"
    "    	WideCharToMultiByte(CP_UTF8, 0, PWideChar(WStr),"
    "       	Length(WStr), Pointer(X_D.FirstByte()), size, nil, nil);"
    "		{$IFnDEF SMALLER_CODE}"
    "			i := 0; if i = 0 then;"     
    "			bb := nil; if bb = nil then;"     
    "		{$ENDIF}"     
    "	 {$ELSE}"
    "		GetMem(bb, X_D.Count());"
    "		WideCharToMultiByte(CP_UTF8, 0, PWideChar(WStr),"
    "       	Length(WStr), PChar(bb), size, nil, nil);"
    "		for i := 0 to size-1 do"
    "			X_D.SetBytes(i,"
    "				{$IFDEF _D5orHigher} "
    "				PByte(Integer(bb) + i)^ "
    "				{$ELSE} bb[i] {$ENDIF} "
    " 			);"
    "		FreeMem(bb);"     
    "	 {$ENDIF}"
    "{$ENDIF}"
	
 	NATIVE_Bytes_from_utf7 = @
 	"var size: Integer;"
    "var WStr: WideString;"
    "var {$IFNDEF USE_FirstByte} buf: array of Byte; {$ENDIF} i: Integer; "
    "	 {$IFDEF LINUX}"
    "	 {$ELSE}"
    "    WStr := {$IFDEF FPC} Str_X_S {$ELSE} X_S {$ENDIF};"
    "    X_D.Clear;"
    "    size := WideCharToMultiByte(CP_UTF7, 0, PWideChar(WStr),"
    "       Length(WStr), nil, 0, nil, nil);"
    "    if size = 0 then Exit;"
    "    X_D.Extend(0, size);"
    "	 {$IFDEF USE_FirstByte}"
    "    	WideCharToMultiByte(CP_UTF7, 0, PWideChar(WStr),"
    "       	Length(WStr), Pointer(X_D.FirstByte()), size, nil, nil);"
    "		{$IFnDEF SMALLER_CODE}"
    "			i := 0; if i = 0 then;"     
    "		{$ENDIF}"     
    "	 {$ELSE}"
    "		SetLength(buf, size);"
    "		WideCharToMultiByte(CP_UTF7, 0, PWideChar(WStr),"
    "       	Length(WStr), @buf[0], size, nil, nil);"
    "		for i := 0 to size-1 do"
    "			X_D.SetBytes(i, buf[i]);"
    "	 {$ENDIF}"
    "	 {$ENDIF}"
    
    NATIVE_Bytes_from_utf16 = @
    "var WStr: WideString;"
    "var i: Integer;"
    "    WStr := {$IFDEF FPC} Str_X_S {$ELSE} X_S {$ENDIF};"
    "    X_D.Clear;"
    "    if Length(WStr) = 0 then Exit;"
    "    X_D.Extend(0, Length(WStr) * 2);"
    "	 {$IFDEF USE_FirstByte}"
    "    	Move(WStr[1], X_D.FirstByte()^, Length(WStr) * 2);"
    "		{$IFnDEF SMALLER_CODE}"
    "			i := 0; if i = 0 then;"     
    "		{$ENDIF}"     
    "	 {$ELSE}"
    "		for i := 0 to Length(WStr)-1 do"
    "		begin"
    "			X_D.SetBytes(i*2, Byte(WStr[i+1 ]));"
    "			X_D.SetBytes(i*2+1,"
    "					Byte(Word(WStr[i+1 ]) shr 8));"
    "		end;"
    "	 {$ENDIF}" 
    
    NATIVE_Bytes_from_utf16_big_endian = @
	"var WStr: WideString;"
    "var i: Integer;"
    "var W: PWord;"
    "    WStr := {$IFDEF FPC} Str_X_S {$ELSE} X_S {$ENDIF};"
    "    X_D.Clear;"
    "    if Length(WStr) = 0 then Exit;"
    "    X_D.Extend(0, Length(WStr) * 2);"
    "	 {$IFDEF USE_FirstByte}"
    "    	Move(WStr[1], X_D.FirstByte()^, Length(WStr) * 2);"
    "    	W := Pointer(X_D.FirstByte());"
    "    	for i := 1 to Length(WStr) do"
    "    	begin"
    "        	W^ := ((W^ and $FF) shl 8) or ((W^ and $FF00) shr 8);"
    "        	inc(W);"
    "    	end;"
    "	 {$ELSE}"
    "		for i := 0 to Length(WStr)-1 do"
    "		begin"
    "			X_D.SetBytes(i*2,"
    "				Byte(Word(WStr[i+1]) shr 8));"
    "			X_D.SetBytes(i*2+1, "
    "				Byte(WStr[i+1]));"
    "		end;"
    "	 {$ENDIF}"
    
    NATIVE_Bytes_from_utf32 = @
    "var WStr: WideString;"
    "var i: Integer;"
    "var D: PDWORD;"
    "    WStr := {$IFDEF FPC} Str_X_S {$ELSE} X_S {$ENDIF};"
    "    X_D.Clear;"
    "    if Length(WStr) = 0 then Exit;"
    "    X_D.Extend(0, Length(WStr) * 4);"
    "	 {$IFDEF USE_FirstByte}"
    "    	D := Pointer(X_D.FirstByte());"
    "    	for i := 1 to Length(WStr) do" 
    "    	begin"
    "        	D^ := DWORD(WStr[i]);"
    "        	inc(D);"
    "    	end;"
    "	 {$ELSE}"
    "    	for i := 0 to Length(WStr)-1 do" 
    "    	begin"
    "        	X_D.SetBytes(i*4, Byte(WStr[i+1]));"
    "        	X_D.SetBytes(i*4+1,"
    "				Byte(DWORD(WStr[i+1]) shr 8));"
    "        	X_D.SetBytes(i*4+2,"
    "				Byte(DWORD(WStr[i+1]) shr 16));"
    "        	X_D.SetBytes(i*4+3,"
    "				Byte(DWORD(WStr[i+1]) shr 24));"
    "    	end;"
    "	 {$ENDIF}"
    
    NATIVE_Bytes_from_utf32_big_endian =
    "var WStr: WideString;"
    "var i: Integer;"
    "var D: PDWORD;"
    "var tmp: DWORD;"
    "    WStr := {$IFDEF FPC} Str_X_S {$ELSE} X_S {$ENDIF};"
    "    X_D.Clear;"
    "    if Length(WStr) = 0 then Exit;"
    "    X_D.Extend(0, Length(WStr) * 4);"
    "	 {$IFDEF USE_FirstByte}"
    "    	D := Pointer(X_D.FirstByte());"
    "    	for i := 1 to Length(WStr) do" 
    "    	begin"
    "        	tmp := DWORD(WStr[i]);"
    "        	D^ := (tmp shr 24) or ((tmp shr 8) and $FF00) or "
    "           	((tmp shl 8) and $FF0000) or (tmp shl 24);"
    "        	inc(D);"
    "    	end;"
    "	 {$ELSE}"
    "		for i := 0 to Length(WStr)-1 do" 
    "    	begin"
    "        	tmp := DWORD(WStr[i+1]);"
    "			X_D.SetBytes(i*4+3, Byte(tmp));"
    "			X_D.SetBytes(i*4+2, Byte(tmp shr 8));"
    "			X_D.SetBytes(i*4+1, Byte(tmp shr 16));"
    "			X_D.SetBytes(i*4, Byte(tmp shr 24));"
    "    	end;"
    "	 {$ENDIF}"
    
    NATIVE_Unicode16_to_ANSI = @
    ""
    
    NATIVE_Oem_to_string = @
    "X_S.SetStrings(1, Do_Oem_to_string(X_S.GetStrings(0)));"

    NATIVE_Ansi_bytes_to_utf8 = @
    "RESULT := Do_Ansi_bytes_to_utf8(X_B);"     

    . 
    

        
END
*/
*)
end.

