Changed category for memo tests

Changed category for memo tests

//
// Copyright (c) XSharp B.V.  All Rights Reserved.
// Licensed under the Apache License, Version 2.0.
// See License.txt in the project root for license information.
//

USING System
USING System.Collections.Generic
USING System.Linq
USING System.Text
using XUnit

BEGIN NAMESPACE XSharp.Core.Tests
	CLASS StringTests
	[Fact, Trait("Category", "String")];
	METHOD AdjustFNameTest() as void
		Assert.Equal("    xyz   ddss.dbf",AdjustFName("    xyz   ddss    .dbf"))
		Assert.Equal(null,AdjustFName(null))
		Assert.Equal(" abc ced",AdjustFName(" abc ced   "))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD AllTrimTest() as void

		local s := e" Hello World  " as string

		Assert.Equal("Hello World",AllTrim(s))
		Assert.Equal(null,AllTrim(null))

		s:= "Hello World    "
		Assert.Equal("Hello World",AllTrim(s))

	RETURN

	[Fact, Trait("Category", "String")];
	METHOD AscTest() as void
		local value := " 123" as string
		Assert.Equal((DWORD)32,Asc(VALUE))
		local nOld as LONG
		nOld := RuntimeState.DosCodePage
		RuntimeState.DosCodePage := 737 // Greek
		Assert.Equal((DWORD)150,Asc("Ψ"))
		RuntimeState.DosCodePage := 437 // US
		Assert.Equal((DWORD)63,Asc("Ψ"))  // ? because not defined for the codepage
		RuntimeState.DosCodePage := nOld
		Assert.Equal((dword)32,Asc(" "))
		Assert.Equal((dword)63,Asc(((char) 512):ToString())) // ?
		Assert.Equal((dword)0,Asc(null))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD AscWTest() as void
		local value := " 123" as string
		Assert.Equal((dword)32,AscW(value))
		Assert.Equal((DWORD)955,AscW("λ"))
		Assert.Equal((DWORD)936,AscW("Ψ"))
		Assert.Equal((dword)32,AscW(" "))
		Assert.Equal((dword)512,AscW(((char) 512):ToString()))
		Assert.Equal((dword)0,AscW(null))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD AscATest() as void
		local value := " 123" as string
		Assert.Equal((dword)32,AscA(value))
		Assert.Equal((dword)32,AscA(" "))
		local nOld as LONG
		nOld := RuntimeState.WinCodePage
		RuntimeState.WinCodePage := 1253 // Greek
		Assert.Equal((DWORD)235,AscA("λ"))
		RuntimeState.WinCodePage  := 1252 // Western Europea
		Assert.Equal((dword)63,Asc("λ"))	// ? because not defined for the codepage
		RuntimeState.WinCodePage  := nOld
		Assert.Equal((dword)0,AscA(null))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD AtTest() as void
		var time := "16:55:23"
		Assert.Equal((dword)4,At("55",time))
		Assert.Equal((dword)0,At("55",null))
		Assert.Equal((dword)0,At(null,time))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD At2Test() as void
		var time := "16:55:23"
		Assert.Equal((dword)4,At2("55",time))
		Assert.Equal((dword)0,At2("55",null))
		Assert.Equal((dword)0,At2(null,time))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD AtCTest() as void
		Assert.Equal((dword)7,AtC("World","Hello World"))
		Assert.Equal((dword)7,AtC("world","Hello World"))
		Assert.Equal((dword)0,At("world","Hello World"))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD AtC2Test() as void
		Assert.Equal((dword)7,AtC2("World","Hello World"))
		Assert.Equal((dword)7,AtC2("world","Hello World"))
		Assert.Equal((dword)0,At2("world","Hello World"))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD At3Test() as void
		var time := "16:25:23"
		Assert.Equal((dword)7,At3("2",time,5))
		Assert.Equal((dword)0,At3("2",time,12))

	RETURN

	[Fact, Trait("Category", "String")];
	METHOD CharEvenTest() as void
		Assert.Equal("1234",CharEven("A1B2C3D4"))
		Assert.Equal("1234",CharEven("A1B2C3D4E"))
		Assert.Equal(null,CharEven(null))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD CharOddTest() as void
		Assert.Equal("ABCD",CharOdd("A1B2C3D4"))
		Assert.Equal("ABCDE",CharOdd("A1B2C3D4E"))
		Assert.Equal(null,CharOdd(null))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD CharPosTest() as void
		Assert.Equal("o",CharPos("Hello World",5))
		Assert.Equal(String.Empty,CharPos("A1B2C3D4E",33))
	RETURN

	[Fact, Trait("Category", "String")];
	method HardCRTest() as void
		local s as string
		s := "aaa" + ((char) 141):ToString() +chr(10)+ "bbb"
		Assert.Equal(1U, MlCount1(s))
		Assert.Equal(2U, MlCount1(HardCR(s)))

	[Fact, Trait("Category", "String")];
	METHOD InStrTest() as void
		Assert.Equal(true,Instr("o W","Hello World"))
		Assert.Equal(false,Instr("o w","Hello World"))
		Assert.Equal(false,Instr(null,null))
		Assert.Equal(false,Instr("w",null))
		Assert.Equal(false,Instr(null,"w"))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD StringIsTest() as void
	//

	Assert.Equal(true,IsAlpha("A"))
	Assert.Equal(true,IsAlNum("A"))
	Assert.Equal(false,IsAlpha("9"))
	Assert.Equal(true,IsDigit("9"))
	Assert.Equal(true,IsXDigit("9"))
	Assert.Equal(true,IsBDigit("0"))
	Assert.Equal(true,IsBDigit("1"))
	Assert.Equal(false,IsBDigit("2"))
	Assert.Equal(false,IsUpper("2"))
	Assert.Equal(false,IsUpper("a"))
	Assert.Equal(true,IsUpper("A"))
	Assert.Equal(false,IsLower("2"))
	Assert.Equal(false,IsLower("A"))
	Assert.Equal(true,IsLower("a"))
	Assert.Equal(true,IsSpace(" "))
	Assert.Equal(true,IsSpace(e"\t"))
	Assert.Equal(true,IsSpace(e"\r"))
	Assert.Equal(true,IsSpace(e"\v"))
	Assert.Equal(true,IsSpace(e"\n"))
	Assert.Equal(false,IsSpace("A"))

	[Fact, Trait("Category", "String")];
	METHOD LeftTest() as void

		local s := "Hello World" as string
		local unassigned		 as string

		Assert.Equal("",left(s,0))
		Assert.Equal("H",left(s,1))
		Assert.Equal("Hello World",left(s,99))

		Assert.Equal(null,left(unassigned,0))
		Assert.Equal(null,left(unassigned,1))
		Assert.Equal(null,left(unassigned,99))

	RETURN

	[Fact, Trait("Category", "String")];
	METHOD LowerTest() as void
		Assert.Equal("hello world",Lower("Hello World"))
		Assert.Equal(null,Lower(null))
		var s := "Hello World"
		lowerA(s)
		Assert.Equal("hello world",s)
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD LenTest() as void
		Assert.Equal(0U, SLen(""))
		Assert.Equal(0U, SLen(null))
		Assert.Equal(1U, SLen("x"))
		Assert.Equal(5U, SLen("12345"))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD LTrimTest() as void
		Assert.Equal("Hello World",LTrim("    Hello World"))
		Assert.Equal(null,Lower(null))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD OccursTest() as void
		Assert.Equal((dword)2,Occurs("or","the world according to me"))
		Assert.Equal((dword)0,Occurs(null,null))
		Assert.Equal((dword)0,Occurs("x",null))
		Assert.Equal((dword)0,Occurs(null,"xx"))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD Occurs3Test() as void
		Assert.Equal((dword)1,Occurs3("or","the world according to me",7))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD ProperTest() as void
		Assert.Equal("Hello World",Proper("hello world"))
		Assert.Equal(null,Proper(null))
		Assert.Equal(Proper("1st characters are in uppercase"), "1st Characters Are In Uppercase")

	RETURN

	[Fact, Trait("Category", "String")];
	METHOD RAtTest() as void
		Assert.Equal((dword)14,RAt("or","the world according to me"))
		Assert.Equal((dword)0,Rat(null,null))
		Assert.Equal((dword)0,Rat("or",null))
		Assert.Equal((dword)0,Rat(null,"the world"))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD RAtLineTest() as void
	  LOCAL cSource AS STRING

	  cSource := e"This is the first line\r\nThis is the second line\r\nThis is the third line"

	  Assert.Equal(3U, RAtLine("line", cSource) )
	  Assert.Equal(2U, RAtLine("second line", cSource) )

	  Assert.Equal(3U, RAtLine2("line", cSource) )
	  Assert.Equal(2U, RAtLine2("second line", cSource) )
	  RETURN

	[Fact, Trait("Category", "String")];
	METHOD RAt2Test() as void
		Assert.Equal((dword)14,RAt2("or","the world according to me"))
		Assert.Equal((dword)0,Rat2(null,null))
		Assert.Equal((dword)0,Rat2("or",null))
		Assert.Equal((dword)0,Rat2(null,"the world"))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD RAt3Test() as void
		Assert.Equal((dword)14,RAt3("or","the world according to me",9))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD ReplicateTest() as void
		Assert.Equal("dudadudaduda",Replicate("duda",3))
		Assert.Equal("dudadudaduda",Repl("duda",3))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD RTrimTest() as void
		Assert.Equal("    Hello World",RTrim("    Hello World     "))
		Assert.Equal(null,RTrim(null))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD RightTest() as void
		Assert.Equal("World",Right("Hello World",5))
		Assert.Equal(null,Right(null,0))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD SCloneTest() as void
		local s:="Hello World" as string
		Assert.Equal(s,SClone(s))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD SLenTest() as void
		local s:="Hello World" as string
		var l := SLen(s)
		Assert.Equal((dword)11,SLen(s))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD SLenExceptionTest() as void
		local s as string
		s:=string.Empty
		//XUnit.Assert.Throws<InvalidOperationException>( () => SLen(s))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD StuffTest() as void
		local s:="Hello World" as string
		Assert.Equal("Hello Kiel",Stuff(s,7,5,"Kiel"))
		Assert.Equal("Kiel",Stuff(null,7,5,"Kiel"))
		Assert.Equal("Hello ",Stuff(s,7,5,""))
		Assert.Equal("Hello WorldKiel",Stuff(s,12,5,"Kiel"))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD SubStr2Test() as void
		local s:="Hello World" as string
		Assert.Equal("World",SubStr2(s,7))
		Assert.Equal("",SubStr2(s,20))
		Assert.Equal(null,SubStr2(null,5))
	RETURN
	[Fact, Trait("Category", "String")];
	METHOD SubStr3Test() as void
		local s:="Hello World" as string
		Assert.Equal("World",SubStr3(s,7,5))
		Assert.Equal("",SubStr3(s,20,5))
		Assert.Equal(null,SubStr3(null,5,2))
	RETURN
	[Fact, Trait("Category", "String")];
	METHOD TrimTest() as void
		local s:="Hello World   " as string
		Assert.Equal("Hello World",Trim(s))
		Assert.Equal(null,Trim(null))
	RETURN
	[Fact, Trait("Category", "String")];
	METHOD UpperTest() as void
		local s:="Hello World" as string
		Assert.Equal("HELLO WORLD",Upper(s))
		Assert.Equal(null,Upper(null))
		upperA(s)
		Assert.Equal("HELLO WORLD",s)
	return

   [Fact, Trait("Category", "String")];
   METHOD SoundExTest() AS VOID
	  Assert.Equal("F631", SoundEx("Fred Bloggs")  )
	  Assert.Equal("S530", SoundEx("Smith")  )
	  Assert.Equal("S530", SoundEx("Smythe") )

	  return

   [Fact, Trait("Category", "String")];
   METHOD CharMixTest() AS VOID
	  Assert.Equal("1234567890", CHarMix("13579","24680"))
	  Assert.Equal("", CHarMix("","24680"))
	  Assert.Equal("12", CHarMix("1","24680"))
	  Assert.Equal("", CHarMix("13579",""))
	  Assert.Equal("1232527292", CHarMix("13579","2"))

	  return
   [Fact, Trait("Category", "Memo")];
   method AtLineTest() as void
	  local test as string
	  test := e"first line\r\nsecond line\r\nthird line"
	  Assert.Equal(1U, AtLine("first", test))
	  Assert.Equal(2U, AtLine("second", test))
	  Assert.Equal(3U, AtLine("third", test))
	  Assert.Equal(0U, AtLine("fourth", test))
	  Assert.Equal(1U, AtCLine("First", test))
	  Assert.Equal(2U, AtCLine("Second", test))
	  Assert.Equal(3U, AtCLine("Third", test))
	  Assert.Equal(0U, AtCLine("Fourth", test))

	  return

   [Fact, Trait("Category", "Memo")];
   method MemLinesTest() as void
	  local test as string
	  test := e"first line\r\nsecond line\r\nthird line"
	  Assert.Equal(3U, MemLines(test))
	  Assert.Equal(3U, MlCount1(test))
	  Assert.Equal(0U, MemLines(""))
	  Assert.Equal(1U, MemLines(" "))
	  Assert.Equal(0U, MlCount1(""))
	  Assert.Equal(1U, MlCount1(" "))
	  Assert.Equal(0U, MemLines(null))
	  Assert.Equal(0U, MlCount1(NULL))
	  return

   [Fact, Trait("Category", "Memo")];
	method MemoTest() as void
		local sToWrite := "test" as string
		MemoWrit("test.txt", sToWrite)
		var sText := System.IO.File.ReadAllText("test.txt")
		Assert.Equal(sToWrite, sText)
		sText := MemORead("test.txt")
		Assert.Equal(sToWrite, sText)
		end class

END NAMESPACE

//
// Copyright (c) XSharp B.V.  All Rights Reserved.
// Licensed under the Apache License, Version 2.0.
// See License.txt in the project root for license information.
//

USING System
USING System.Collections.Generic
USING System.Linq
USING System.Text
using XUnit

BEGIN NAMESPACE XSharp.Core.Tests
	CLASS StringTests
	[Fact, Trait("Category", "String")];
	METHOD AdjustFNameTest() as void
		Assert.Equal("    xyz   ddss.dbf",AdjustFName("    xyz   ddss    .dbf"))
		Assert.Equal(null,AdjustFName(null))
		Assert.Equal(" abc ced",AdjustFName(" abc ced   "))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD AllTrimTest() as void

		local s := e" Hello World  " as string

		Assert.Equal("Hello World",AllTrim(s))
		Assert.Equal(null,AllTrim(null))

		s:= "Hello World    "
		Assert.Equal("Hello World",AllTrim(s))

	RETURN

	[Fact, Trait("Category", "String")];
	METHOD AscTest() as void
		local value := " 123" as string
		Assert.Equal((DWORD)32,Asc(VALUE))
		local nOld as LONG
		nOld := RuntimeState.DosCodePage
		RuntimeState.DosCodePage := 737 // Greek
		Assert.Equal((DWORD)150,Asc("Ψ"))
		RuntimeState.DosCodePage := 437 // US
		Assert.Equal((DWORD)63,Asc("Ψ"))  // ? because not defined for the codepage
		RuntimeState.DosCodePage := nOld
		Assert.Equal((dword)32,Asc(" "))
		Assert.Equal((dword)63,Asc(((char) 512):ToString())) // ?
		Assert.Equal((dword)0,Asc(null))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD AscWTest() as void
		local value := " 123" as string
		Assert.Equal((dword)32,AscW(value))
		Assert.Equal((DWORD)955,AscW("λ"))
		Assert.Equal((DWORD)936,AscW("Ψ"))
		Assert.Equal((dword)32,AscW(" "))
		Assert.Equal((dword)512,AscW(((char) 512):ToString()))
		Assert.Equal((dword)0,AscW(null))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD AscATest() as void
		local value := " 123" as string
		Assert.Equal((dword)32,AscA(value))
		Assert.Equal((dword)32,AscA(" "))
		local nOld as LONG
		nOld := RuntimeState.WinCodePage
		RuntimeState.WinCodePage := 1253 // Greek
		Assert.Equal((DWORD)235,AscA("λ"))
		RuntimeState.WinCodePage  := 1252 // Western Europea
		Assert.Equal((dword)63,Asc("λ"))	// ? because not defined for the codepage
		RuntimeState.WinCodePage  := nOld
		Assert.Equal((dword)0,AscA(null))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD AtTest() as void
		var time := "16:55:23"
		Assert.Equal((dword)4,At("55",time))
		Assert.Equal((dword)0,At("55",null))
		Assert.Equal((dword)0,At(null,time))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD At2Test() as void
		var time := "16:55:23"
		Assert.Equal((dword)4,At2("55",time))
		Assert.Equal((dword)0,At2("55",null))
		Assert.Equal((dword)0,At2(null,time))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD AtCTest() as void
		Assert.Equal((dword)7,AtC("World","Hello World"))
		Assert.Equal((dword)7,AtC("world","Hello World"))
		Assert.Equal((dword)0,At("world","Hello World"))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD AtC2Test() as void
		Assert.Equal((dword)7,AtC2("World","Hello World"))
		Assert.Equal((dword)7,AtC2("world","Hello World"))
		Assert.Equal((dword)0,At2("world","Hello World"))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD At3Test() as void
		var time := "16:25:23"
		Assert.Equal((dword)7,At3("2",time,5))
		Assert.Equal((dword)0,At3("2",time,12))

	RETURN

	[Fact, Trait("Category", "String")];
	METHOD CharEvenTest() as void
		Assert.Equal("1234",CharEven("A1B2C3D4"))
		Assert.Equal("1234",CharEven("A1B2C3D4E"))
		Assert.Equal(null,CharEven(null))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD CharOddTest() as void
		Assert.Equal("ABCD",CharOdd("A1B2C3D4"))
		Assert.Equal("ABCDE",CharOdd("A1B2C3D4E"))
		Assert.Equal(null,CharOdd(null))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD CharPosTest() as void
		Assert.Equal("o",CharPos("Hello World",5))
		Assert.Equal(String.Empty,CharPos("A1B2C3D4E",33))
	RETURN

	[Fact, Trait("Category", "String")];
	method HardCRTest() as void
		local s as string
		s := "aaa" + ((char) 141):ToString() +chr(10)+ "bbb"
		Assert.Equal(1U, MlCount1(s))
		Assert.Equal(2U, MlCount1(HardCR(s)))

	[Fact, Trait("Category", "String")];
	METHOD InStrTest() as void
		Assert.Equal(true,Instr("o W","Hello World"))
		Assert.Equal(false,Instr("o w","Hello World"))
		Assert.Equal(false,Instr(null,null))
		Assert.Equal(false,Instr("w",null))
		Assert.Equal(false,Instr(null,"w"))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD StringIsTest() as void
	//

	Assert.Equal(true,IsAlpha("A"))
	Assert.Equal(true,IsAlNum("A"))
	Assert.Equal(false,IsAlpha("9"))
	Assert.Equal(true,IsDigit("9"))
	Assert.Equal(true,IsXDigit("9"))
	Assert.Equal(true,IsBDigit("0"))
	Assert.Equal(true,IsBDigit("1"))
	Assert.Equal(false,IsBDigit("2"))
	Assert.Equal(false,IsUpper("2"))
	Assert.Equal(false,IsUpper("a"))
	Assert.Equal(true,IsUpper("A"))
	Assert.Equal(false,IsLower("2"))
	Assert.Equal(false,IsLower("A"))
	Assert.Equal(true,IsLower("a"))
	Assert.Equal(true,IsSpace(" "))
	Assert.Equal(true,IsSpace(e"\t"))
	Assert.Equal(true,IsSpace(e"\r"))
	Assert.Equal(true,IsSpace(e"\v"))
	Assert.Equal(true,IsSpace(e"\n"))
	Assert.Equal(false,IsSpace("A"))

	[Fact, Trait("Category", "String")];
	METHOD LeftTest() as void

		local s := "Hello World" as string
		local unassigned		 as string

		Assert.Equal("",left(s,0))
		Assert.Equal("H",left(s,1))
		Assert.Equal("Hello World",left(s,99))

		Assert.Equal(null,left(unassigned,0))
		Assert.Equal(null,left(unassigned,1))
		Assert.Equal(null,left(unassigned,99))

	RETURN

	[Fact, Trait("Category", "String")];
	METHOD LowerTest() as void
		Assert.Equal("hello world",Lower("Hello World"))
		Assert.Equal(null,Lower(null))
		var s := "Hello World"
		lowerA(s)
		Assert.Equal("hello world",s)
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD LenTest() as void
		Assert.Equal(0U, SLen(""))
		Assert.Equal(0U, SLen(null))
		Assert.Equal(1U, SLen("x"))
		Assert.Equal(5U, SLen("12345"))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD LTrimTest() as void
		Assert.Equal("Hello World",LTrim("    Hello World"))
		Assert.Equal(null,Lower(null))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD OccursTest() as void
		Assert.Equal((dword)2,Occurs("or","the world according to me"))
		Assert.Equal((dword)0,Occurs(null,null))
		Assert.Equal((dword)0,Occurs("x",null))
		Assert.Equal((dword)0,Occurs(null,"xx"))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD Occurs3Test() as void
		Assert.Equal((dword)1,Occurs3("or","the world according to me",7))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD ProperTest() as void
		Assert.Equal("Hello World",Proper("hello world"))
		Assert.Equal(null,Proper(null))
		Assert.Equal(Proper("1st characters are in uppercase"), "1st Characters Are In Uppercase")

	RETURN

	[Fact, Trait("Category", "String")];
	METHOD RAtTest() as void
		Assert.Equal((dword)14,RAt("or","the world according to me"))
		Assert.Equal((dword)0,Rat(null,null))
		Assert.Equal((dword)0,Rat("or",null))
		Assert.Equal((dword)0,Rat(null,"the world"))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD RAtLineTest() as void
	  LOCAL cSource AS STRING

	  cSource := e"This is the first line\r\nThis is the second line\r\nThis is the third line"

	  Assert.Equal(3U, RAtLine("line", cSource) )
	  Assert.Equal(2U, RAtLine("second line", cSource) )

	  Assert.Equal(3U, RAtLine2("line", cSource) )
	  Assert.Equal(2U, RAtLine2("second line", cSource) )
	  RETURN

	[Fact, Trait("Category", "String")];
	METHOD RAt2Test() as void
		Assert.Equal((dword)14,RAt2("or","the world according to me"))
		Assert.Equal((dword)0,Rat2(null,null))
		Assert.Equal((dword)0,Rat2("or",null))
		Assert.Equal((dword)0,Rat2(null,"the world"))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD RAt3Test() as void
		Assert.Equal((dword)14,RAt3("or","the world according to me",9))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD ReplicateTest() as void
		Assert.Equal("dudadudaduda",Replicate("duda",3))
		Assert.Equal("dudadudaduda",Repl("duda",3))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD RTrimTest() as void
		Assert.Equal("    Hello World",RTrim("    Hello World     "))
		Assert.Equal(null,RTrim(null))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD RightTest() as void
		Assert.Equal("World",Right("Hello World",5))
		Assert.Equal(null,Right(null,0))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD SCloneTest() as void
		local s:="Hello World" as string
		Assert.Equal(s,SClone(s))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD SLenTest() as void
		local s:="Hello World" as string
		var l := SLen(s)
		Assert.Equal((dword)11,SLen(s))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD SLenExceptionTest() as void
		local s as string
		s:=string.Empty
		//XUnit.Assert.Throws<InvalidOperationException>( () => SLen(s))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD StuffTest() as void
		local s:="Hello World" as string
		Assert.Equal("Hello Kiel",Stuff(s,7,5,"Kiel"))
		Assert.Equal("Kiel",Stuff(null,7,5,"Kiel"))
		Assert.Equal("Hello ",Stuff(s,7,5,""))
		Assert.Equal("Hello WorldKiel",Stuff(s,12,5,"Kiel"))
	RETURN

	[Fact, Trait("Category", "String")];
	METHOD SubStr2Test() as void
		local s:="Hello World" as string
		Assert.Equal("World",SubStr2(s,7))
		Assert.Equal("",SubStr2(s,20))
		Assert.Equal(null,SubStr2(null,5))
	RETURN
	[Fact, Trait("Category", "String")];
	METHOD SubStr3Test() as void
		local s:="Hello World" as string
		Assert.Equal("World",SubStr3(s,7,5))
		Assert.Equal("",SubStr3(s,20,5))
		Assert.Equal(null,SubStr3(null,5,2))
	RETURN
	[Fact, Trait("Category", "String")];
	METHOD TrimTest() as void
		local s:="Hello World   " as string
		Assert.Equal("Hello World",Trim(s))
		Assert.Equal(null,Trim(null))
	RETURN
	[Fact, Trait("Category", "String")];
	METHOD UpperTest() as void
		local s:="Hello World" as string
		Assert.Equal("HELLO WORLD",Upper(s))
		Assert.Equal(null,Upper(null))
		upperA(s)
		Assert.Equal("HELLO WORLD",s)
	return

   [Fact, Trait("Category", "String")];
   METHOD SoundExTest() AS VOID
	  Assert.Equal("F631", SoundEx("Fred Bloggs")  )
	  Assert.Equal("S530", SoundEx("Smith")  )
	  Assert.Equal("S530", SoundEx("Smythe") )

	  return

   [Fact, Trait("Category", "String")];
   METHOD CharMixTest() AS VOID
	  Assert.Equal("1234567890", CHarMix("13579","24680"))
	  Assert.Equal("", CHarMix("","24680"))
	  Assert.Equal("12", CHarMix("1","24680"))
	  Assert.Equal("", CHarMix("13579",""))
	  Assert.Equal("1232527292", CHarMix("13579","2"))

	  return
   [Fact, Trait("Category", "String")];
   method AtLineTest() as void
	  local test as string
	  test := e"first line\r\nsecond line\r\nthird line"
	  Assert.Equal(1U, AtLine("first", test))
	  Assert.Equal(2U, AtLine("second", test))
	  Assert.Equal(3U, AtLine("third", test))
	  Assert.Equal(0U, AtLine("fourth", test))
	  Assert.Equal(1U, AtCLine("First", test))
	  Assert.Equal(2U, AtCLine("Second", test))
	  Assert.Equal(3U, AtCLine("Third", test))
	  Assert.Equal(0U, AtCLine("Fourth", test))

	  return

   [Fact, Trait("Category", "String")];
   method MemLinesTest() as void
	  local test as string
	  test := e"first line\r\nsecond line\r\nthird line"
	  Assert.Equal(3U, MemLines(test))
	  Assert.Equal(3U, MlCount1(test))
	  Assert.Equal(0U, MemLines(""))
	  Assert.Equal(1U, MemLines(" "))
	  Assert.Equal(0U, MlCount1(""))
	  Assert.Equal(1U, MlCount1(" "))
	  Assert.Equal(0U, MemLines(null))
	  Assert.Equal(0U, MlCount1(NULL))
	  return

   [Fact, Trait("Category", "String")];
	method MemoTest() as void
		local sToWrite := "test" as string
		MemoWrit("test.txt", sToWrite)
		var sText := System.IO.File.ReadAllText("test.txt")
		Assert.Equal(sToWrite, sText)
		sText := MemORead("test.txt")
		Assert.Equal(sToWrite, sText)
		end class

END NAMESPACE


QtQml: module updated

QtQml: module updated

Modified:
source/QtQml/QQmlApplicationEngine.prg

/*

  Qt5xHb - Bindings libraries for Harbour/xHarbour and Qt Framework 5

  Copyright (C) 2018 Marcos Antonio Gambeta <marcosgambeta AT outlook DOT com>

*/

/*
  DO NOT EDIT THIS FILE - the content was created using a source code generator
*/

#include "hbclass.ch"

#ifndef QT5XHB_NO_REQUESTS
REQUEST QOBJECT
#endif

CLASS QQmlApplicationEngine INHERIT QQmlEngine

   METHOD new
   METHOD delete
   METHOD rootObjects
   METHOD load
   METHOD loadData

   METHOD onObjectCreated

   DESTRUCTOR destroyObject

END CLASS

PROCEDURE destroyObject () CLASS QQmlApplicationEngine
   IF ::self_destruction
      ::delete()
   ENDIF
RETURN

#pragma BEGINDUMP

#include <Qt>

#ifndef __XHARBOUR__
#if (QT_VERSION >= QT_VERSION_CHECK(5,1,0))
#include <QQmlApplicationEngine>
#endif
#endif

#include "qt5xhb_common.h"
#include "qt5xhb_macros.h"
#include "qt5xhb_utils.h"

#ifdef __XHARBOUR__
#if (QT_VERSION >= QT_VERSION_CHECK(5,1,0))
#include <QQmlApplicationEngine>
#endif
#endif

/*
QQmlApplicationEngine(QObject *parent=0)
*/
void QQmlApplicationEngine_new1 ()
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,1,0))
  QQmlApplicationEngine * o = new QQmlApplicationEngine ( OPQOBJECT(1,0) );
  _qt5xhb_returnNewObject( o, false );
#endif
}

/*
QQmlApplicationEngine(const QUrl &url, QObject *parent=0)
*/
void QQmlApplicationEngine_new2 ()
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,1,0))
  QQmlApplicationEngine * o = new QQmlApplicationEngine ( *PQURL(1), OPQOBJECT(2,0) );
  _qt5xhb_returnNewObject( o, false );
#endif
}

/*
QQmlApplicationEngine(const QString &filePath, QObject *parent=0)
*/
void QQmlApplicationEngine_new3 ()
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,1,0))
  QQmlApplicationEngine * o = new QQmlApplicationEngine ( PQSTRING(1), OPQOBJECT(2,0) );
  _qt5xhb_returnNewObject( o, false );
#endif
}

//[1]QQmlApplicationEngine(QObject *parent=0)
//[2]QQmlApplicationEngine(const QUrl &url, QObject *parent=0)
//[3]QQmlApplicationEngine(const QString &filePath, QObject *parent=0)

HB_FUNC_STATIC( QQMLAPPLICATIONENGINE_NEW )
{
  if( ISBETWEEN(0,1) && (ISQOBJECT(1)||ISNIL(1)) )
  {
    QQmlApplicationEngine_new1();
  }
  else if( ISBETWEEN(1,2) && ISQURL(1) && (ISQOBJECT(2)||ISNIL(2)) )
  {
    QQmlApplicationEngine_new2();
  }
  else if( ISBETWEEN(1,2) && ISCHAR(1) && (ISQOBJECT(2)||ISNIL(2)) )
  {
    QQmlApplicationEngine_new3();
  }
  else
  {
    hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
  }
}

HB_FUNC_STATIC( QQMLAPPLICATIONENGINE_DELETE )
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,1,0))
  QQmlApplicationEngine * obj = (QQmlApplicationEngine *) _qt5xhb_itemGetPtrStackSelfItem();

  if( obj )
  {
    delete obj;
    obj = NULL;
    PHB_ITEM self = hb_stackSelfItem();
    PHB_ITEM ptr = hb_itemPutPtr( NULL, NULL );
    hb_objSendMsg( self, "_pointer", 1, ptr );
    hb_itemRelease( ptr );
  }

  hb_itemReturn( hb_stackSelfItem() );
#endif
}

/*
QList<QObject*> rootObjects()
*/
HB_FUNC_STATIC( QQMLAPPLICATIONENGINE_ROOTOBJECTS )
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,1,0))
  QQmlApplicationEngine * obj = (QQmlApplicationEngine *) _qt5xhb_itemGetPtrStackSelfItem();

  if( obj )
  {
    if( ISNUMPAR(0) )
    {
      QList<QObject *> list = obj->rootObjects ();
      PHB_DYNS pDynSym = hb_dynsymFindName( "QOBJECT" );
      PHB_ITEM pArray = hb_itemArrayNew(0);
      int i;
      for(i=0;i<list.count();i++)
      {
        if( pDynSym )
        {
          hb_vmPushDynSym( pDynSym );
          hb_vmPushNil();
          hb_vmDo( 0 );
          PHB_ITEM pObject = hb_itemNew( NULL );
          hb_itemCopy( pObject, hb_stackReturnItem() );
          PHB_ITEM pItem = hb_itemNew( NULL );
          hb_itemPutPtr( pItem, (QObject *) list[i] );
          hb_objSendMsg( pObject, "_POINTER", 1, pItem );
          hb_itemRelease( pItem );
          hb_arrayAddForward( pArray, pObject );
          hb_itemRelease( pObject );
        }
        else
        {
          hb_errRT_BASE( EG_NOFUNC, 1001, NULL, "QOBJECT", HB_ERR_ARGS_BASEPARAMS );
        }
      }
      hb_itemReturnRelease(pArray);
    }
    else
    {
      hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
    }
  }
#endif
}

/*
void load(const QUrl &url)
*/
void QQmlApplicationEngine_load1 ()
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,1,0))
  QQmlApplicationEngine * obj = (QQmlApplicationEngine *) _qt5xhb_itemGetPtrStackSelfItem();

  if( obj )
  {
      obj->load ( *PQURL(1) );
  }

  hb_itemReturn( hb_stackSelfItem() );
#endif
}

/*
void load(const QString &filePath)
*/
void QQmlApplicationEngine_load2 ()
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,1,0))
  QQmlApplicationEngine * obj = (QQmlApplicationEngine *) _qt5xhb_itemGetPtrStackSelfItem();

  if( obj )
  {
      obj->load ( PQSTRING(1) );
  }

  hb_itemReturn( hb_stackSelfItem() );
#endif
}

//[1]void load(const QUrl &url)
//[2]void load(const QString &filePath)

HB_FUNC_STATIC( QQMLAPPLICATIONENGINE_LOAD )
{
  if( ISNUMPAR(1) && ISQURL(1) )
  {
    QQmlApplicationEngine_load1();
  }
  else if( ISNUMPAR(1) && ISCHAR(1) )
  {
    QQmlApplicationEngine_load2();
  }
  else
  {
    hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
  }
}

/*
void loadData(const QByteArray &data, const QUrl &url = QUrl())
*/
HB_FUNC_STATIC( QQMLAPPLICATIONENGINE_LOADDATA )
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,1,0))
  QQmlApplicationEngine * obj = (QQmlApplicationEngine *) _qt5xhb_itemGetPtrStackSelfItem();

  if( obj )
  {
    if( ISBETWEEN(1,2) && ISQBYTEARRAY(1) && (ISQURL(2)||ISNIL(2)) )
    {
      obj->loadData ( *PQBYTEARRAY(1), ISNIL(2)? QUrl() : *(QUrl *) _qt5xhb_itemGetPtr(2) );
    }
    else
    {
      hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
    }
  }

  hb_itemReturn( hb_stackSelfItem() );
#endif
}

#pragma ENDDUMP

/*

  Qt5xHb - Bindings libraries for Harbour/xHarbour and Qt Framework 5

  Copyright (C) 2018 Marcos Antonio Gambeta <marcosgambeta AT outlook DOT com>

*/

/*
  DO NOT EDIT THIS FILE - the content was created using a source code generator
*/

#include "hbclass.ch"

#ifndef QT5XHB_NO_REQUESTS
REQUEST QOBJECT
#endif

CLASS QQmlApplicationEngine INHERIT QQmlEngine

   METHOD new
   METHOD delete
   METHOD rootObjects
   METHOD load
   METHOD loadData

   METHOD onObjectCreated

   DESTRUCTOR destroyObject

END CLASS

PROCEDURE destroyObject () CLASS QQmlApplicationEngine
   IF ::self_destruction
      ::delete()
   ENDIF
RETURN

#pragma BEGINDUMP

#include <Qt>

#ifndef __XHARBOUR__
#if (QT_VERSION >= QT_VERSION_CHECK(5,1,0))
#include <QQmlApplicationEngine>
#endif
#endif

#include "qt5xhb_common.h"
#include "qt5xhb_macros.h"
#include "qt5xhb_utils.h"

#ifdef __XHARBOUR__
#if (QT_VERSION >= QT_VERSION_CHECK(5,1,0))
#include <QQmlApplicationEngine>
#endif
#endif

/*
QQmlApplicationEngine(QObject *parent=0)
*/
void QQmlApplicationEngine_new1 ()
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,1,0))
  QQmlApplicationEngine * o = new QQmlApplicationEngine ( OPQOBJECT(1,0) );
  _qt5xhb_returnNewObject( o, false );
#endif
}

/*
QQmlApplicationEngine(const QUrl &url, QObject *parent=0)
*/
void QQmlApplicationEngine_new2 ()
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,1,0))
  QQmlApplicationEngine * o = new QQmlApplicationEngine ( *PQURL(1), OPQOBJECT(2,0) );
  _qt5xhb_returnNewObject( o, false );
#endif
}

/*
QQmlApplicationEngine(const QString &filePath, QObject *parent=0)
*/
void QQmlApplicationEngine_new3 ()
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,1,0))
  QQmlApplicationEngine * o = new QQmlApplicationEngine ( PQSTRING(1), OPQOBJECT(2,0) );
  _qt5xhb_returnNewObject( o, false );
#endif
}

//[1]QQmlApplicationEngine(QObject *parent=0)
//[2]QQmlApplicationEngine(const QUrl &url, QObject *parent=0)
//[3]QQmlApplicationEngine(const QString &filePath, QObject *parent=0)

HB_FUNC_STATIC( QQMLAPPLICATIONENGINE_NEW )
{
  if( ISBETWEEN(0,1) && (ISQOBJECT(1)||ISNIL(1)) )
  {
    QQmlApplicationEngine_new1();
  }
  else if( ISBETWEEN(1,2) && ISQURL(1) && (ISQOBJECT(2)||ISNIL(2)) )
  {
    QQmlApplicationEngine_new2();
  }
  else if( ISBETWEEN(1,2) && ISCHAR(1) && (ISQOBJECT(2)||ISNIL(2)) )
  {
    QQmlApplicationEngine_new3();
  }
  else
  {
    hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
  }
}

HB_FUNC_STATIC( QQMLAPPLICATIONENGINE_DELETE )
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,1,0))
  QQmlApplicationEngine * obj = (QQmlApplicationEngine *) _qt5xhb_itemGetPtrStackSelfItem();

  if( obj )
  {
    delete obj;
    obj = NULL;
    PHB_ITEM self = hb_stackSelfItem();
    PHB_ITEM ptr = hb_itemPutPtr( NULL, NULL );
    hb_objSendMsg( self, "_pointer", 1, ptr );
    hb_itemRelease( ptr );
  }

  hb_itemReturn( hb_stackSelfItem() );
#endif
}

/*
QList<QObject*> rootObjects()
*/
HB_FUNC_STATIC( QQMLAPPLICATIONENGINE_ROOTOBJECTS )
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,1,0))
  QQmlApplicationEngine * obj = (QQmlApplicationEngine *) _qt5xhb_itemGetPtrStackSelfItem();

  if( obj )
  {
    if( ISNUMPAR(0) )
    {
      QList<QObject *> list = obj->rootObjects ();
      PHB_DYNS pDynSym = hb_dynsymFindName( "QOBJECT " );
      PHB_ITEM pArray = hb_itemArrayNew(0);
      int i;
      for(i=0;i<list.count();i++)
      {
        if( pDynSym )
        {
          hb_vmPushDynSym( pDynSym );
          hb_vmPushNil();
          hb_vmDo( 0 );
          PHB_ITEM pObject = hb_itemNew( NULL );
          hb_itemCopy( pObject, hb_stackReturnItem() );
          PHB_ITEM pItem = hb_itemNew( NULL );
          hb_itemPutPtr( pItem, (QObject  *) list[i] );
          hb_objSendMsg( pObject, "_POINTER", 1, pItem );
          hb_itemRelease( pItem );
          hb_arrayAddForward( pArray, pObject );
          hb_itemRelease( pObject );
        }
      }
      hb_itemReturnRelease(pArray);
    }
    else
    {
      hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
    }
  }
#endif
}

/*
void load(const QUrl &url)
*/
void QQmlApplicationEngine_load1 ()
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,1,0))
  QQmlApplicationEngine * obj = (QQmlApplicationEngine *) _qt5xhb_itemGetPtrStackSelfItem();

  if( obj )
  {
      obj->load ( *PQURL(1) );
  }

  hb_itemReturn( hb_stackSelfItem() );
#endif
}

/*
void load(const QString &filePath)
*/
void QQmlApplicationEngine_load2 ()
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,1,0))
  QQmlApplicationEngine * obj = (QQmlApplicationEngine *) _qt5xhb_itemGetPtrStackSelfItem();

  if( obj )
  {
      obj->load ( PQSTRING(1) );
  }

  hb_itemReturn( hb_stackSelfItem() );
#endif
}

//[1]void load(const QUrl &url)
//[2]void load(const QString &filePath)

HB_FUNC_STATIC( QQMLAPPLICATIONENGINE_LOAD )
{
  if( ISNUMPAR(1) && ISQURL(1) )
  {
    QQmlApplicationEngine_load1();
  }
  else if( ISNUMPAR(1) && ISCHAR(1) )
  {
    QQmlApplicationEngine_load2();
  }
  else
  {
    hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
  }
}

/*
void loadData(const QByteArray &data, const QUrl &url = QUrl())
*/
HB_FUNC_STATIC( QQMLAPPLICATIONENGINE_LOADDATA )
{
#if (QT_VERSION >= QT_VERSION_CHECK(5,1,0))
  QQmlApplicationEngine * obj = (QQmlApplicationEngine *) _qt5xhb_itemGetPtrStackSelfItem();

  if( obj )
  {
    if( ISBETWEEN(1,2) && ISQBYTEARRAY(1) && (ISQURL(2)||ISNIL(2)) )
    {
      obj->loadData ( *PQBYTEARRAY(1), ISNIL(2)? QUrl() : *(QUrl *) _qt5xhb_itemGetPtr(2) );
    }
    else
    {
      hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
    }
  }

  hb_itemReturn( hb_stackSelfItem() );
#endif
}

#pragma ENDDUMP


Fixes #1054

Fixes #1054

//
// Copyright (c) XSharp B.V.  All Rights Reserved.
// Licensed under the Apache License, Version 2.0.
// See License.txt in the project root for license information.
//
USING System.Collections.Generic
USING System.Runtime.InteropServices
USING System.Runtime.Serialization
USING System.Diagnostics
USING System.Text
USING System.Reflection
BEGIN NAMESPACE XSharp

	/// <summary>Internal type that implements the XBase Compatible PSZ type.<br/>
	/// This type has many operators and implicit converters that normally are never directly called from user code.
	/// </summary>
    /// <include file="RTComments.xml" path="Comments/PSZ/*" />
	[DebuggerDisplay( "{DebuggerString(),nq}", Type := "PSZ" ) ] ;
    [Serializable];
	STRUCTURE __Psz IMPLEMENTS  IEquatable<__Psz>, ISerializable
		PRIVATE _value AS BYTE PTR
		/// <exclude />
		STATIC PROPERTY _NULL_PSZ AS __Psz GET (__Psz) IntPtr.Zero
		PRIVATE STATIC _pszList AS List< IntPtr>
		INTERNAL STATIC METHOD RegisterPsz(pszToRegister AS PSZ) AS VOID
			IF _pszList == NULL
				_pszList := List<IntPtr>{}
				AppDomain.CurrentDomain:ProcessExit += System.EventHandler{ NULL, @__FreePSZs() }
			ENDIF
			IF !_pszList:Contains(pszToRegister:Address)
				_pszList:Add(pszToRegister:Address)
			ENDIF
			RETURN

		INTERNAL STATIC METHOD CreatePsz( cString AS STRING) AS PSZ
				RETURN PSZ{cString}

		PRIVATE STATIC METHOD __FreePSZs(o AS OBJECT, args AS EventArgs ) AS VOID
			FOREACH VAR pszToFree IN _pszList
				TRY
					MemFree(pszToFree)
				CATCH
					NOP
				END TRY
			NEXT
			_pszList := NULL

		/// <include file="RTComments.xml" path="Comments/Constructor/*" />
		CONSTRUCTOR (s AS STRING)
			// this constructor has a memory leak
			// there is no garbage collection for structures
			// to free the memory we need to call MemFree on the pointer
			_value := String2Mem(s)
			RegisterPsz(_value)
			RETURN

		/// <include file="RTComments.xml" path="Comments/Constructor/*" />
		CONSTRUCTOR (p AS IntPtr)
			_value := p

		/// <exclude/>
        OVERRIDE METHOD ToString() AS STRING
            IF IsValid
                RETURN Mem2String( _value, Length )
            ENDIF
            IF _value == IntPtr.Zero
                RETURN ""
            ENDIF
            RETURN "<Invalid PSZ>("+ IntPtr{_value}:ToString()+")"

		/// <exclude />
		METHOD DebuggerString() AS STRING
			RETURN IIF( _value == NULL_PTR, "NULL_PSZ", e"\""+ SELF:ToString() +  e"\"" )

		/// <exclude />
		METHOD Equals( p AS PSZ ) AS LOGIC

			LOCAL ret := FALSE AS LOGIC
			IF _value == p:_value
				ret := TRUE
			ELSEIF _value != NULL .AND. p:_value != NULL
				ret := __StringCompare( SELF:ToString(), p:ToString() ) == 0
			ENDIF
			RETURN ret

		INTERNAL METHOD LessThan( p AS PSZ ) AS LOGIC
			LOCAL ret := FALSE AS LOGIC
			IF _value == p:_value
				ret := FALSE
			ELSEIF _value != NULL .AND. p:_value != NULL
				ret := __StringCompare( SELF:ToString(), p:ToString() ) < 0
			ENDIF
			RETURN ret

		INTERNAL METHOD GreaterThan( p AS PSZ ) AS LOGIC
			LOCAL ret := FALSE AS LOGIC
			IF _value == p:_value
				ret := FALSE
			ELSEIF _value != NULL .AND. p:_value != NULL
				ret := __StringCompare( SELF:ToString(), p:ToString() ) > 0
			ENDIF
			RETURN ret

			/// <exclude/>
         OVERRIDE METHOD Equals( o AS OBJECT ) AS LOGIC
			LOCAL ret := FALSE AS LOGIC

			IF o IS PSZ
				ret := SELF:Equals( (PSZ) o )
			ENDIF

		RETURN ret

		/// <inheritdoc />
		OVERRIDE METHOD GetHashCode() AS INT
			RETURN (INT) _value

		/// <exclude />
		METHOD Free() AS VOID
			IF _value != NULL_PTR
				MemFree( _value )
				_value := NULL_PTR
			ENDIF
			RETURN

        PRIVATE PROPERTY IsValid AS LOGIC
            GET
                IF _value == IntPtr.Zero
                    RETURN FALSE
                ENDIF
                TRY
                    Marshal.ReadByte(_value)
                    RETURN TRUE
                CATCH
                    RETURN FALSE
                END TRY
            END GET
        END PROPERTY
		/// <exclude />
		PROPERTY Length AS DWORD
			GET
				LOCAL len AS DWORD
				len := 0
                IF !IsValid
                    RETURN len
                ENDIF
				IF _value != NULL_PTR
					DO WHILE _value[len+1] != 0
						len++
					ENDDO
				ENDIF
				RETURN len
			END GET
		END PROPERTY
		/// <exclude />
		PROPERTY IsEmpty AS LOGIC
			GET
				LOCAL empty := TRUE AS LOGIC
                IF IsValid
				    LOCAL b AS BYTE
				    LOCAL x := 1 AS INT
				    IF _value != NULL_PTR
					    b := _value[x]
					    DO WHILE b != 0 .AND. empty
						    SWITCH b
							CASE 32
							CASE 13
							CASE 10
							CASE 9
								NOP
							OTHERWISE
								empty := FALSE
						    END SWITCH
						    x += 1
						    b := _value[x]
					    ENDDO
				    ENDIF
                ENDIF
				RETURN empty

			END GET
		END PROPERTY
		/// <exclude />
		PROPERTY IsNull AS LOGIC GET _value == NULL
		/// <exclude />
		PROPERTY Address AS IntPtr GET _value
		/// <exclude />
        #pragma options ("az", ON)
		PROPERTY SELF[index AS INT] AS BYTE
			GET
                IF !IsValid
                    RETURN 0
                ENDIF
				RETURN _value[index ]
			END GET
			SET
                IF IsValid
				    _value[index ] := value
                ENDIF
			END SET
		END PROPERTY
		#pragma options ("az", default)
		#region OPERATOR methods
			// binary
			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            // Note that this does not allocate a new string but it returns the offset in the original string
            #pragma options ("az", on)
			OPERATOR +( lhs AS PSZ, rhs AS LONG ) AS PSZ
				RETURN PSZ{@lhs:_value[rhs] }

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            // Note that this does not allocate a new string but it returns the offset in the original string
			OPERATOR +( lhs AS PSZ, rhs AS DWORD ) AS PSZ
				RETURN PSZ{@lhs:_value[(LONG) rhs] }

            #pragma options ("az", DEFAULT)
			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR +( lhs AS PSZ, rhs AS PSZ ) AS PSZ
				RETURN PSZ{ lhs:ToString() + rhs:ToString() }

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR +( lhs AS PSZ, rhs AS STRING ) AS PSZ
				RETURN PSZ{ lhs:ToString() + rhs }

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR +( lhs AS STRING, rhs AS PSZ ) AS STRING
				RETURN lhs + rhs:ToString()

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR -( lhs AS PSZ, rhs AS PSZ ) AS PSZ
				LOCAL l   := lhs:ToString() AS STRING
				LOCAL r   := rhs:ToString() AS STRING
				RETURN PSZ{ String.Concat( l:TrimEnd(), r:TrimEnd() ):PadRight( l:Length + r:Length ) }

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR -( lhs AS PSZ, rhs AS STRING ) AS PSZ
				LOCAL l   := lhs:ToString() AS STRING
				RETURN PSZ{ String.Concat( l:TrimEnd(), rhs:TrimEnd() ):PadRight( l:Length + rhs:Length ) }

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR -( lhs AS STRING, rhs AS PSZ ) AS STRING
				LOCAL r   := rhs:ToString() AS STRING
				RETURN String.Concat( lhs:TrimEnd(), r:TrimEnd() ):PadRight( lhs:Length + r:Length )

			// Comparison Operators
			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR ==( lhs AS PSZ, rhs AS PSZ ) AS LOGIC
				RETURN lhs:Equals( rhs )

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR !=( lhs AS PSZ, rhs AS PSZ ) AS LOGIC
				RETURN ! lhs:Equals( rhs )

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR <( lhs AS PSZ, rhs AS PSZ ) AS LOGIC
				RETURN lhs:LessThan( rhs )

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR <=( lhs AS PSZ, rhs AS PSZ ) AS LOGIC
				RETURN ! lhs:GreaterThan( rhs )

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR >( lhs AS PSZ, rhs AS PSZ ) AS LOGIC
				RETURN lhs:GreaterThan( rhs )

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR >=( lhs AS PSZ, rhs AS PSZ ) AS LOGIC
				RETURN ! lhs:LessThan( rhs )

			// Conversion Operators - To PSZ...

			// PTR -> PSZ
			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR IMPLICIT( p AS PTR ) AS PSZ
				RETURN PSZ{ (IntPtr) p }

			// BYTE PTR -> PSZ
			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR IMPLICIT( p AS BYTE PTR ) AS PSZ
				RETURN PSZ{ (IntPtr) p }

			// SByte PTR -> PSZ
			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR IMPLICIT( p AS SByte PTR ) AS PSZ
				RETURN PSZ{ (IntPtr) p }

			// IntPtr -> PSZ
			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR IMPLICIT( p AS IntPtr ) AS PSZ
				RETURN PSZ{ p }

			///////////////////////////////////////////////////////////////////////////
			// Conversion Operators - From PSZ...

			// PSZ -> PTR
			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR IMPLICIT( p AS PSZ ) AS PTR
				RETURN p:_value

			// PSZ -> BYTE PTR
			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR IMPLICIT( p AS PSZ ) AS BYTE PTR
				RETURN p:_value

			// PSZ -> SByte PTR
			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR IMPLICIT( p AS PSZ ) AS SByte PTR
				RETURN (SByte PTR) p:_value

			// PSZ -> IntPtr
			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR IMPLICIT( p AS PSZ ) AS IntPtr
				RETURN p:_value

			// PSZ -> STRING
			OPERATOR IMPLICIT( p AS PSZ ) AS STRING
				RETURN p:ToString()

		#endregion

       #region ISerializable
        /// <inheritdoc/>
        PUBLIC METHOD GetObjectData(info AS SerializationInfo, context AS StreamingContext) AS VOID
            IF info == NULL
                THROW System.ArgumentException{"info"}
            ENDIF
            info:AddValue("Value", SELF:ToString())
            RETURN
        /// <include file="RTComments.xml" path="Comments/SerializeConstructor/*" />
        CONSTRUCTOR (info AS SerializationInfo, context AS StreamingContext)
            IF info == NULL
                THROW System.ArgumentException{"info"}
            ENDIF
            _value := String2Mem(info:GetString("Value"))
            RegisterPsz(_value)
        #endregion
	END STRUCTURE

END NAMESPACE

// This function is handled by the compiler. The runtime function should never be called
/// <exclude />
FUNCTION Cast2Psz(cSource AS STRING) AS PSZ
	THROW NotImplementedException{}

// This function is handled by the compiler. The runtime function should never be called
/// <exclude />
FUNCTION String2Psz(cSource AS STRING) AS PSZ
	THROW NotImplementedException{}

//
// Copyright (c) XSharp B.V.  All Rights Reserved.
// Licensed under the Apache License, Version 2.0.
// See License.txt in the project root for license information.
//
USING System.Collections.Generic
USING System.Runtime.InteropServices
USING System.Runtime.Serialization
USING System.Diagnostics
USING System.Text
USING System.Reflection
BEGIN NAMESPACE XSharp

	/// <summary>Internal type that implements the XBase Compatible PSZ type.<br/>
	/// This type has many operators and implicit converters that normally are never directly called from user code.
	/// </summary>
    /// <include file="RTComments.xml" path="Comments/PSZ/*" />
	[DebuggerDisplay( "{DebuggerString(),nq}", Type := "PSZ" ) ] ;
    [Serializable];
	STRUCTURE __Psz IMPLEMENTS  IEquatable<__Psz>, ISerializable
		PRIVATE _value AS BYTE PTR
		/// <exclude />
		STATIC PROPERTY _NULL_PSZ AS __Psz GET (__Psz) IntPtr.Zero
		PRIVATE STATIC _pszList AS List< IntPtr>
		INTERNAL STATIC METHOD RegisterPsz(pszToRegister AS PSZ) AS VOID
			IF _pszList == NULL
				_pszList := List<IntPtr>{}
				AppDomain.CurrentDomain:ProcessExit += System.EventHandler{ NULL, @__FreePSZs() }
			ENDIF
			IF !_pszList:Contains(pszToRegister:Address)
				_pszList:Add(pszToRegister:Address)
			ENDIF
			RETURN

		INTERNAL STATIC METHOD CreatePsz( cString AS STRING) AS PSZ
				RETURN PSZ{cString}

		PRIVATE STATIC METHOD __FreePSZs(o AS OBJECT, args AS EventArgs ) AS VOID
			FOREACH VAR pszToFree IN _pszList
				TRY
					MemFree(pszToFree)
				CATCH
					NOP
				END TRY
			NEXT
			_pszList := NULL

		/// <include file="RTComments.xml" path="Comments/Constructor/*" />
		CONSTRUCTOR (s AS STRING)
			// this constructor has a memory leak
			// there is no garbage collection for structures
			// to free the memory we need to call MemFree on the pointer
			_value := String2Mem(s)
			RegisterPsz(_value)
			RETURN

		/// <include file="RTComments.xml" path="Comments/Constructor/*" />
		CONSTRUCTOR (p AS IntPtr)
			_value := p

		/// <exclude/>
        OVERRIDE METHOD ToString() AS STRING
            IF IsValid
                RETURN Mem2String( _value, Length )
            ENDIF
            IF _value == IntPtr.Zero
                RETURN ""
            ENDIF
            RETURN "<Invalid PSZ>("+ IntPtr{_value}:ToString()+")"

		/// <exclude />
		METHOD DebuggerString() AS STRING
			RETURN IIF( _value == NULL_PTR, "NULL_PSZ", e"\""+ SELF:ToString() +  e"\"" )

		/// <exclude />
		METHOD Equals( p AS PSZ ) AS LOGIC

			LOCAL ret := FALSE AS LOGIC
			IF _value == p:_value
				ret := TRUE
			ELSEIF _value != NULL .AND. p:_value != NULL
				ret := __StringCompare( SELF:ToString(), p:ToString() ) == 0
			ENDIF
			RETURN ret

		INTERNAL METHOD LessThan( p AS PSZ ) AS LOGIC
			LOCAL ret := FALSE AS LOGIC
			IF _value == p:_value
				ret := FALSE
			ELSEIF _value != NULL .AND. p:_value != NULL
				ret := __StringCompare( SELF:ToString(), p:ToString() ) < 0
			ENDIF
			RETURN ret

		INTERNAL METHOD GreaterThan( p AS PSZ ) AS LOGIC
			LOCAL ret := FALSE AS LOGIC
			IF _value == p:_value
				ret := FALSE
			ELSEIF _value != NULL .AND. p:_value != NULL
				ret := __StringCompare( SELF:ToString(), p:ToString() ) > 0
			ENDIF
			RETURN ret

			/// <exclude/>
         OVERRIDE METHOD Equals( o AS OBJECT ) AS LOGIC
			LOCAL ret := FALSE AS LOGIC

			IF o IS PSZ
				ret := SELF:Equals( (PSZ) o )
			ENDIF

		RETURN ret

		/// <inheritdoc />
		OVERRIDE METHOD GetHashCode() AS INT
			RETURN (INT) _value

		/// <exclude />
		METHOD Free() AS VOID
			IF _value != NULL_PTR
				MemFree( _value )
				_value := NULL_PTR
			ENDIF
			RETURN

        PRIVATE PROPERTY IsValid AS LOGIC
            GET
                IF _value == IntPtr.Zero
                    RETURN FALSE
                ENDIF
                TRY
                    Marshal.ReadByte(_value)
                    RETURN TRUE
                CATCH
                    RETURN FALSE
                END TRY
            END GET
        END PROPERTY
		/// <exclude />
		PROPERTY Length AS DWORD
			GET
				LOCAL len AS DWORD
				len := 0
                IF !IsValid
                    RETURN len
                ENDIF
				IF _value != NULL_PTR
					DO WHILE _value[len+1] != 0
						len++
					ENDDO
				ENDIF
				RETURN len
			END GET
		END PROPERTY
		/// <exclude />
		PROPERTY IsEmpty AS LOGIC
			GET
				LOCAL empty := TRUE AS LOGIC
                IF IsValid
				    LOCAL b AS BYTE
				    LOCAL x := 1 AS INT
				    IF _value != NULL_PTR
					    b := _value[x]
					    DO WHILE b != 0 .AND. empty
						    SWITCH b
							CASE 32
							CASE 13
							CASE 10
							CASE 9
								NOP
							OTHERWISE
								empty := FALSE
						    END SWITCH
						    x += 1
						    b := _value[x]
					    ENDDO
				    ENDIF
                ENDIF
				RETURN empty

			END GET
		END PROPERTY
		/// <exclude />
		PROPERTY IsNull AS LOGIC GET _value == NULL
		/// <exclude />
		PROPERTY Address AS IntPtr GET _value
		/// <exclude />
        #pragma options ("az", ON)
		PROPERTY SELF[index AS INT] AS BYTE
			GET
                IF !IsValid
                    RETURN 0
                ENDIF
				RETURN _value[index ]
			END GET
			SET
                IF IsValid
				    _value[index ] := value
                ENDIF
			END SET
		END PROPERTY
		#pragma options ("az", default)
		#region OPERATOR methods
			// binary
			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            // Note that this does not allocate a new string but it returns the offset in the original string
            #pragma options ("az", on)
			OPERATOR +( lhs AS PSZ, rhs AS LONG ) AS PSZ
				RETURN PSZ{@lhs:_value[rhs] }

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
            // Note that this does not allocate a new string but it returns the offset in the original string
			OPERATOR +( lhs AS PSZ, rhs AS DWORD ) AS PSZ
				RETURN PSZ{@lhs:_value[(LONG) rhs] }

            #pragma options ("az", DEFAULT)
			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR +( lhs AS PSZ, rhs AS PSZ ) AS PSZ
				RETURN PSZ{ lhs:ToString() + rhs:ToString() }

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR +( lhs AS PSZ, rhs AS STRING ) AS PSZ
				RETURN PSZ{ lhs:ToString() + rhs }

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR +( lhs AS STRING, rhs AS PSZ ) AS STRING
				RETURN lhs + rhs:ToString()

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR -( lhs AS PSZ, rhs AS PSZ ) AS PSZ
				LOCAL l   := lhs:ToString() AS STRING
				LOCAL r   := rhs:ToString() AS STRING
				RETURN PSZ{ String.Concat( l:TrimEnd(), r:TrimEnd() ):PadRight( l:Length + r:Length ) }

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR -( lhs AS PSZ, rhs AS STRING ) AS PSZ
				LOCAL l   := lhs:ToString() AS STRING
				RETURN PSZ{ String.Concat( l:TrimEnd(), rhs:TrimEnd() ):PadRight( l:Length + rhs:Length ) }

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR -( lhs AS STRING, rhs AS PSZ ) AS STRING
				LOCAL r   := rhs:ToString() AS STRING
				RETURN String.Concat( lhs:TrimEnd(), r:TrimEnd() ):PadRight( lhs:Length + r:Length )

			// Comparison Operators
			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR ==( lhs AS PSZ, rhs AS PSZ ) AS LOGIC
				RETURN lhs:Equals( rhs )

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR !=( lhs AS PSZ, rhs AS PSZ ) AS LOGIC
				RETURN ! lhs:Equals( rhs )

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR <( lhs AS PSZ, rhs AS PSZ ) AS LOGIC
				RETURN lhs:LessThan( rhs )

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR <=( lhs AS PSZ, rhs AS PSZ ) AS LOGIC
				RETURN ! lhs:GreaterThan( rhs )

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR >( lhs AS PSZ, rhs AS PSZ ) AS LOGIC
				RETURN lhs:GreaterThan( rhs )

			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR >=( lhs AS PSZ, rhs AS PSZ ) AS LOGIC
				RETURN ! lhs:LessThan( rhs )

			// Conversion Operators - To PSZ...

			// PTR -> PSZ
			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR IMPLICIT( p AS PTR ) AS PSZ
				RETURN PSZ{ (IntPtr) p }

			// BYTE PTR -> PSZ
			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR IMPLICIT( p AS BYTE PTR ) AS PSZ
				RETURN PSZ{ (IntPtr) p }

			// SByte PTR -> PSZ
			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR IMPLICIT( p AS SByte PTR ) AS PSZ
				RETURN PSZ{ (IntPtr) p }

			// IntPtr -> PSZ
			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR IMPLICIT( p AS IntPtr ) AS PSZ
				RETURN PSZ{ p }

			// INT -> PSZ
			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR IMPLICIT( i AS INT ) AS PSZ
				RETURN PSZ{ IntPtr{ i } }

			// DWORD -> PSZ
			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR IMPLICIT( d AS DWORD ) AS PSZ
				RETURN PSZ{ IntPtr{ (INT64) d} }

			///////////////////////////////////////////////////////////////////////////
			// Conversion Operators - From PSZ...

			// PSZ -> PTR
			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR IMPLICIT( p AS PSZ ) AS PTR
				RETURN p:_value

			// PSZ -> BYTE PTR
			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR IMPLICIT( p AS PSZ ) AS BYTE PTR
				RETURN p:_value

			// PSZ -> SByte PTR
			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR IMPLICIT( p AS PSZ ) AS SByte PTR
				RETURN (SByte PTR) p:_value

			// PSZ -> IntPtr
			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR IMPLICIT( p AS PSZ ) AS IntPtr
				RETURN p:_value

			// PSZ -> STRING
			OPERATOR IMPLICIT( p AS PSZ ) AS STRING
				RETURN p:ToString()

			// PSZ -> INT
			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR IMPLICIT( p AS PSZ ) AS INT
				RETURN (INT) p:_value

			// PSZ -> INT64
			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR IMPLICIT( p AS PSZ ) AS INT64
				RETURN (INT64) p:_value

			// PSZ -> DWORD
			/// <include file="RTComments.xml" path="Comments/Operator/*" />
			OPERATOR IMPLICIT( p AS PSZ ) AS DWORD
				RETURN (DWORD) p:_value
		#endregion

       #region ISerializable
        /// <inheritdoc/>
        PUBLIC METHOD GetObjectData(info AS SerializationInfo, context AS StreamingContext) AS VOID
            IF info == NULL
                THROW System.ArgumentException{"info"}
            ENDIF
            info:AddValue("Value", SELF:ToString())
            RETURN
        /// <include file="RTComments.xml" path="Comments/SerializeConstructor/*" />
        CONSTRUCTOR (info AS SerializationInfo, context AS StreamingContext)
            IF info == NULL
                THROW System.ArgumentException{"info"}
            ENDIF
            _value := String2Mem(info:GetString("Value"))
            RegisterPsz(_value)
        #endregion
	END STRUCTURE

END NAMESPACE

// This function is handled by the compiler. The runtime function should never be called
/// <exclude />
FUNCTION Cast2Psz(cSource AS STRING) AS PSZ
	THROW NotImplementedException{}

// This function is handled by the compiler. The runtime function should never be called
/// <exclude />
FUNCTION String2Psz(cSource AS STRING) AS PSZ
	THROW NotImplementedException{}