Updated comments

Updated comments

//
// 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.IO
USING System.Collections.Generic
USING System.Linq
USING XSharp.RDD
USING XSharp.RDD.Support
USING XSharp.RDD.Enums

BEGIN NAMESPACE XSharp.ADS
    /// Class for Ads Column reading / writing
    CLASS AdsColumn INHERIT RDDFieldInfo
        INTERNAL RDD        AS XSharp.ADS.AdsRDD
        INTERNAL AdsType    as AdsFieldType
        INTERNAL FieldPos   as DWORD
        PROPERTY _Table as IntPtr GET RDD:_Table

        STATIC METHOD Create(oInfo AS RDDFieldInfo, oRDD AS XSharp.ADS.AdsRDD,type as AdsFieldType, nPos as DWORD) AS AdsColumn
            // Commented out types are Harbour specific
            SWITCH type
            // char types
            CASE AdsFieldType.TIMESTAMP
            CASE AdsFieldType.MODTIME
            CASE AdsFieldType.TIME
            CASE AdsFieldType.MONEY
            CASE AdsFieldType.ROWVERSION
		    CASE AdsFieldType.STRING
		    CASE AdsFieldType.VARCHAR
		    CASE AdsFieldType.CISTRING
		    CASE AdsFieldType.VARCHAR_FOX
		    CASE AdsFieldType.NCHAR
		    CASE AdsFieldType.NVARCHAR
                return AdsCharacterColumn{oInfo, oRDD, type,nPos}

		    CASE AdsFieldType.MEMO
		    CASE AdsFieldType.BINARY
		    CASE AdsFieldType.IMAGE
		    CASE AdsFieldType.NMEMO
		    CASE AdsFieldType.RAW
		    CASE AdsFieldType.VARBINARY_FOX
                return AdsMemoColumn{oInfo, oRDD, type,nPos}

		    CASE AdsFieldType.SHORTINT
		    CASE AdsFieldType.AUTOINC
		    CASE AdsFieldType.INTEGER
		    CASE AdsFieldType.NUMERIC
		    CASE AdsFieldType.DOUBLE
		    CASE AdsFieldType.CURDOUBLE
                return AdsNumericColumn{oInfo, oRDD, type,nPos}

		    CASE AdsFieldType.LOGICAL
                return AdsLogicColumn{oInfo, oRDD, type,nPos}

		    CASE AdsFieldType.DATE
		    CASE AdsFieldType.COMPACTDATE
                return AdsDateColumn{oInfo, oRDD, type,nPos}
            OTHERWISE
                oRDD:ADSERROR(ERDD_DATATYPE, EG_DataType, __ENTITY__,"Unexpected fieldtype: "+ ((int) type):ToString())
            END SWITCH
            RETURN NULL

        PROTECTED CONSTRUCTOR(oInfo AS RddFieldInfo,oRDD AS XSharp.ADS.AdsRDD, type as AdsFieldType, nPos as DWORD)
            SUPER(oInfo)
            SELF:RDD        := oRDD
            SELF:AdsType    := type
            SELF:FieldPos   := nPos
            RETURN

        VIRTUAL METHOD GetValue() AS OBJECT
            RETURN NIL

        VIRTUAL METHOD PutValue(oValue AS OBJECT) AS LOGIC
            RETURN FALSE

   OVERRIDE METHOD ToString() AS STRING
        RETURN SELF:Name+" ('"+SELF:FieldTypeStr+"',"+SELF:Length:ToString()+","+SELF:Decimals:ToString()+","+SELF:Adstype:ToString()+")"

    END CLASS

    /// Class for reading / writing String Columns
    CLASS AdsCharacterColumn INHERIT AdsColumn

         CONSTRUCTOR(oInfo AS RddFieldInfo,oRDD AS XSharp.ADS.AdsRDD, type as AdsFieldType,nPos AS DWORD)
            SUPER(oInfo, oRDD,type,nPos)
            IF SELF:Decimals != 0
                SELF:Length         += SELF:Decimals * 256
			    SELF:Decimals       := 0
            ENDIF
            RETURN

       OVERRIDE METHOD PutValue(oValue AS OBJECT) AS LOGIC
	        LOCAL result := 0 AS DWORD
		    LOCAL slength AS DWORD
		    LOCAL strValue AS STRING
    		VAR tc := Type.GetTypeCode(oValue:GetType())
            SWITCH SELF:AdsType
		    CASE AdsFieldType.STRING
		    CASE AdsFieldType.VARCHAR
            CASE AdsFieldType.VARCHAR_FOX
		    CASE AdsFieldType.CISTRING
		    CASE AdsFieldType.NCHAR
		    CASE AdsFieldType.NVARCHAR
			    IF tc != TypeCode.String
				    SELF:RDD:ADSERROR(ERDD_DATATYPE, EG_DataType, __ENTITY__,"String expected")
			    ENDIF
			    strValue := (STRING) oValue
			    slength  := (DWORD) strValue:Length
                slength := Math.Min(slength, SELF:Length)
			    IF slength == 0
				    result := ACE.AdsSetEmpty(SELF:_Table, SELF:FieldPos)
			    ELSE
                    IF SELF:AdsType == AdsFieldType.NCHAR .or. SELF:AdsType == AdsFieldType.NVARCHAR
                        result := ACE.AdsSetStringW(SELF:_Table, SELF:FieldPos, strValue, slength)
                    ELSE
                        result := ACE.AdsSetString(SELF:_Table, SELF:FieldPos, strValue, slength)
                    ENDIF
			    ENDIF
		    CASE AdsFieldType.TIME
		    CASE AdsFieldType.TIMESTAMP
		    CASE AdsFieldType.MONEY
		    CASE AdsFieldType.ROWVERSION
		    CASE AdsFieldType.MODTIME
			    IF tc != TypeCode.String
				    SELF:RDD:ADSERROR(ERDD_DATATYPE, EG_DataType, __ENTITY__,"String expected")
			    ENDIF
			    strValue := (STRING) oValue
			    slength  := (DWORD) strValue:Length
			    result := ACE.AdsSetField(SELF:_Table, SELF:FieldPos, strValue, slength)
		    OTHERWISE
                // Should never happen. We filter on the type when creating the column object
			    SELF:RDD:ADSError(ERDD_DATATYPE, EG_DataType, __ENTITY__,"Unexpected fieldtype: "+SELF:AdsType:ToString())
		    END SWITCH
            IF result != 0 .AND. result != ACE.AE_DATA_TRUNCATED
			    SELF:RDD:ADSERROR(result, EG_WRITE, __ENTITY__)
		    ENDIF
            RETURN TRUE

        OVERRIDE METHOD Validate() AS LOGIC
            IF SELF:Length == 0  .OR. SELF:Decimals > 0  .OR. SELF:Length > System.UInt16.MaxValue
                RETURN FALSE
            ENDIF
            RETURN TRUE

        OVERRIDE METHOD GetValue() AS OBJECT
            LOCAL result    := 0 as DWORD
            LOCAL slength    := SELF:Length+1 AS DWORD
			LOCAL chars := CHAR[] {slength} as CHAR[]
		    SWITCH SELF:AdsType
		    CASE AdsFieldType.TIME
		    CASE AdsFieldType.TIMESTAMP
		    CASE AdsFieldType.MONEY
		    CASE AdsFieldType.ROWVERSION
		    CASE AdsFieldType.MODTIME
                LOCAL isEmpty   := 0 AS WORD
			    RDD:_CheckError(ACE.AdsIsEmpty(SELF:_Table,  SELF:FieldPos , OUT isEmpty),EG_READ)
			    IF isEmpty == 1
				    RETURN NULL
			    ENDIF
			    chars := CHAR[] {slength}
			    result := ACE.AdsGetField(SELF:_Table, SELF:FieldPos, chars, REF slength ,0)
		    CASE AdsFieldType.STRING
		    CASE AdsFieldType.VARCHAR
		    CASE AdsFieldType.CISTRING
		    CASE AdsFieldType.VARCHAR_FOX
		    CASE AdsFieldType.NCHAR
		    CASE AdsFieldType.NVARCHAR
			    chars := CHAR[] {slength}
                IF SELF:AdsType == AdsFieldType.NCHAR .or. SELF:AdsType == AdsFieldType.NVARCHAR
			        result := ACE.AdsGetStringW(SELF:_Table, SELF:FieldPos, chars, REF slength ,0)
                ELSE
			        result := ACE.AdsGetString(SELF:_Table, SELF:FieldPos, chars, REF slength ,0)
                ENDIF
		    OTHERWISE
                // Should never happen. We filter on the type when creating the column object
			    SELF:RDD:ADSError(ERDD_DATATYPE, EG_DataType, __ENTITY__,"Unexpected fieldtype: "+SELF:AdsType:ToString())
		    END SWITCH
		    SWITCH result
		    CASE 0
			    IF SELF:AdsType == AdsFieldType.NCHAR .or. SELF:AdsType == AdsFieldType.NVARCHAR
                    RETURN STRING{chars, 0, (INT) SELF:length}
			    ELSE
				    RETURN SELF:RDD:_Ansi2Unicode(chars, (INT) SELF:length)
			    ENDIF
		    CASE ACE.AE_NO_CURRENT_RECORD
			    RETURN STRING{' ', (INT) SELF:length}
		    OTHERWISE
			    SELF:RDD:_CheckError(result,EG_READ)
		    END SWITCH
            RETURN String.Empty

    END CLASS
    /// Class for reading / writing Date Columns
    CLASS AdsDateColumn INHERIT AdsColumn

         CONSTRUCTOR(oInfo AS RddFieldInfo,oRDD AS XSharp.ADS.AdsRDD, type as AdsFieldType,nPos AS DWORD)
            SUPER(oInfo, oRDD,type,nPos)
            RETURN

        OVERRIDE METHOD GetValue() AS OBJECT
		    LOCAL lJulian AS LONG
            VAR result := ACE.AdsGetJulian(SELF:_Table, SELF:FieldPos, OUT lJulian)
		    IF result == ACE.AE_NO_CURRENT_RECORD
			    RETURN DbDate{0,0,0}
		    ELSEIF result != 0
			    SELF:RDD:_CheckError(result,EG_READ)
		    ENDIF
		    TRY
			    IF lJulian == 0
				    RETURN DbDate{0,0,0}
			    ELSE
                    // there is a function to convert julian to string but it does not always work correctly
                    // this seems to always do the job
				    LOCAL wLength := ACE.ADS_MAX_DATEMASK+1 AS DWORD
                    LOCAL chars := CHAR[] {SELF:length} as CHAR[]
				    result := ACE.AdsGetString(SELF:_Table, SELF:FieldPos, chars, REF wLength, 0)
				    VAR cDate := STRING{chars, 0, 8}
				    IF String.IsNullOrWhiteSpace(cDate)
					    RETURN DbDate{0,0,0}
				    ELSE
					    VAR dt := DateTime.ParseExact(cDate, "yyyyMMdd",NULL)
					    RETURN DbDate{dt:Year, dt:Month, dt:Day}
				    ENDIF
			    ENDIF
		    CATCH

		    END TRY
		    RETURN DbDate{0,0,0}

        OVERRIDE METHOD PutValue(oValue AS OBJECT) AS LOGIC
            // Note that the XSharp.__Date type also returns a typecode of DateTime
            VAR tc := Type.GetTypeCode(oValue:GetType())
	        IF oValue IS IDate VAR oDate
                tc := TypeCode.DateTime
		        IF oDate:IsEmpty
			        oValue := DateTime.MinValue
		        ELSE
			        oValue := DateTime{oDate:Year, oDate:Month, oDate:Day}
		        ENDIF
            ELSEIF oValue IS DateTime
                tc := TypeCode.DateTime
	        ENDIF
		    IF tc != TypeCode.DateTime
			    SELF:RDD:ADSERROR(ERDD_DATATYPE, EG_DataType, __ENTITY__,"Date or DateTime value expected")
		    ENDIF

		    LOCAL dt := (DateTime) oValue AS DateTime
            if (dt == DateTime.MinValue)
                SELF:RDD:_CheckError(ACE.AdsSetEmpty(SELF:_Table, SELF:FieldPos),EG_WRITE)
            ELSE
		        LOCAL text := dt:ToString("yyyyMMdd") AS STRING
		        LOCAL r8Julian AS REAL8
		        SELF:RDD:_CheckError(AceUnPub.AdsConvertStringToJulian(text, (WORD) text:Length, OUT r8Julian),EG_WRITE)
		        SELF:RDD:_CheckError(ACE.AdsSetJulian(SELF:_Table, SELF:FieldPos, (LONG) r8Julian),EG_WRITE)
            ENDIF
            RETURN TRUE

        OVERRIDE METHOD Validate() AS LOGIC
            RETURN SELF:Length == 8  .AND.  SELF:Decimals == 0

    END CLASS

    /// Class for reading / writing Logic Columns
    CLASS AdsLogicColumn INHERIT AdsColumn

        CONSTRUCTOR(oInfo AS RddFieldInfo,oRDD AS XSharp.ADS.AdsRDD, type as AdsFieldType,nPos AS DWORD)
            SUPER(oInfo,oRDD,type,nPos)
            RETURN

        OVERRIDE METHOD GetValue() AS OBJECT
	        LOCAL wValue AS WORD
		    var result := ACE.AdsGetLogical(SELF:_Table, SELF:FieldPos, OUT wValue)
		    IF result ==  ACE.AE_NO_CURRENT_RECORD
			    wValue := 0
		    ELSEIF ! SELF:RDD:_CheckError(result,EG_READ)
              // Exception
		    ENDIF
		    RETURN wValue != 0

       OVERRIDE METHOD PutValue(oValue AS OBJECT) AS LOGIC
            VAR tc := Type.GetTypeCode(oValue:GetType())
		    IF tc != TypeCode.Boolean
			    SELF:RDD:ADSERROR(ERDD_DATATYPE, EG_DataType, __ENTITY__,"Logic value expected")
		    ENDIF
		    SELF:RDD:_CheckError(ACE.AdsSetLogical(SELF:_Table, SELF:FieldPos, (WORD)  IIF( (LOGIC) oValue, 1, 0)),EG_WRITE)
            RETURN TRUE

       OVERRIDE METHOD Validate() AS LOGIC
            RETURN SELF:Length == 1  .AND.  SELF:Decimals == 0
    END CLASS

    /// Class for reading / writing Numeric Columns
    CLASS AdsNumericColumn INHERIT AdsColumn

    CONSTRUCTOR(oInfo AS RddFieldInfo,oRDD AS XSharp.ADS.AdsRDD, type as AdsFieldType,nPos AS DWORD)
            SUPER(oInfo,oRDD,type,nPos)
            RETURN

        OVERRIDE METHOD GetValue() AS OBJECT
            LOCAL result    := 0 as DWORD
		    SWITCH SELF:AdsType
		    CASE AdsFieldType.NUMERIC
		    CASE AdsFieldType.DOUBLE
		    CASE AdsFieldType.INTEGER
		    CASE AdsFieldType.SHORTINT
		    CASE AdsFieldType.AUTOINC
		    CASE AdsFieldType.CURDOUBLE
			    LOCAL r8 AS REAL8
			    result := ACE.AdsGetDouble(SELF:_Table, SELF:FieldPos, OUT r8)
			    IF result == ACE.AE_NO_CURRENT_RECORD
				    r8 := 0.0
			    ENDIF
			    IF SELF:AdsType:IsDouble()
				    VAR value := r8:ToString()
				    VAR pos := VALUE:IndexOf('.')
				    RETURN DbFloat{r8, SELF:Length, IIF(pos > 0, SELF:Length - pos -1, 0)}
			    ELSE
				    RETURN DbFloat{r8, SELF:Length, SELF:Decimals}
			    ENDIF
		    OTHERWISE
                // Should never happen. We filter on the type when creating the column object
			    SELF:RDD:ADSError(ERDD_DATATYPE, EG_DataType, __ENTITY__,"Unexpected fieldtype: "+SELF:AdsType:ToString())
		    END SWITCH
            RETURN NULL

      OVERRIDE METHOD PutValue(oValue AS OBJECT) AS LOGIC
        VAR tc := Type.GetTypeCode(oValue:GetType())
      	IF oValue IS IFloat VAR floatValue
		    tc := TypeCode.Double
		    oValue := floatValue:Value
        ENDIF
        LOCAL wType AS WORD
        LOCAL result := 0 AS DWORD
        SELF:RDD:_CheckError(ACE.AdsGetFieldType(SELF:_Table, SELF:FieldPos, OUT wType),EG_READ)
        IF wType != ACE.ADS_AUTOINC
	        TRY
	            LOCAL r8 AS REAL8
		        r8 := Convert.ToDouble(oValue)
		        SELF:RDD:_CheckError(ACE.AdsSetDouble(SELF:_Table, SELF:FieldPos, r8),EG_WRITE)

            CATCH
		        SELF:RDD:ADSERROR(ERDD_DATATYPE, EG_DataType, __ENTITY__,"Numeric value expected")
                RETURN FALSE
	        END TRY
        ELSE
	        NOP // Do not allow to write to AUTO INC field
        ENDIF
        RETURN TRUE

       OVERRIDE METHOD Validate() AS LOGIC
           IF SELF:Length >= 1  .AND.  SELF:Length <= 255
                IF SELF:Decimals > 0
                    // We must check that we have enough space for DOT and decimal
                    IF SELF:Length <= 2  .OR.  SELF:Decimals >= SELF:Length -1
                        RETURN FALSE
                    ENDIF
                ENDIF
            ELSE
                RETURN FALSE
            ENDIF
            RETURN TRUE

    END CLASS

    /// Class for reading / writing Memo Columns.
    CLASS AdsMemoColumn INHERIT AdsColumn
        // AdsFieldType.MEMO
        // AdsFieldType.NMEMO
        // AdsFieldType.BINARY
        // AdsFieldType.IMAGE
        // AdsFieldType.RAW
        // AdsFieldType.VARBINARY_FOX

        CONSTRUCTOR(oInfo AS RddFieldInfo,oRDD AS XSharp.ADS.AdsRDD, type as AdsFieldType,nPos AS DWORD)
            SUPER(oInfo,oRDD,type,nPos)
            RETURN

        OVERRIDE METHOD GetValue() AS OBJECT
            LOCAL isEmpty   := 0 AS WORD
            LOCAL result    := 0 as DWORD
            LOCAL mlength    := 0 AS DWORD
            LOCAL bytes     := NULL AS BYTE[]
			LOCAL chars := CHAR[] {length} as CHAR[]
            SWITCH SELF:AdsType
		    CASE AdsFieldType.MEMO
		    CASE AdsFieldType.NMEMO
		    CASE AdsFieldType.BINARY
		    CASE AdsFieldType.IMAGE
			    result := ACE.AdsGetMemoLength(SELF:_Table, SELF:FieldPos, OUT mlength )
			    SWITCH result
			    CASE 0
				    IF length == 0
					    RETURN string.Empty
				    ENDIF
			    CASE ACE.AE_NO_CURRENT_RECORD
				    IF SELF:AdsType == AdsFieldType.MEMO .or. SELF:AdsType == AdsFieldType.NMEMO
					    RETURN string.Empty
				    ELSE    // image and binary
					    RETURN NULL
				    ENDIF
			    OTHERWISE
				    SELF:RDD:_CheckError(result,EG_READ)
			    END SWITCH
			    SWITCH SELF:AdsType
			    CASE AdsFieldType.MEMO
				    chars := CHAR[] {mlength+1}
				    SELF:RDD:_CheckError(ACE.AdsGetString(SELF:_Table, SELF:FieldPos, chars, REF mlength ,0),EG_READ)
				    RETURN SELF:RDD:_Ansi2Unicode(chars, (INT) length)
			    CASE AdsFieldType.NMEMO
				    chars := CHAR[] {++length}
				    SELF:RDD:_CheckError(ACE.AdsGetStringW(SELF:_Table, SELF:FieldPos, chars, REF mlength ,0),EG_READ)
			    CASE AdsFieldType.BINARY
			    CASE AdsFieldType.IMAGE
				    bytes := BYTE[] {mlength}
				    SELF:RDD:_CheckError(ACE.AdsGetBinary(SELF:_Table, SELF:FieldPos, 0, bytes, REF mlength ),EG_READ)
				    RETURN bytes
			    END SWITCH

		    CASE AdsFieldType.RAW
		    CASE AdsFieldType.VARBINARY_FOX
			    result := ACE.AdsIsEmpty(SELF:_Table, SELF:FieldPos, OUT isEmpty)
			    IF result == 0
				    IF isEmpty == 1
					    RETURN NULL
				    ENDIF
			    ELSE
				    SELF:RDD:_CheckError(result,EG_READ)
			    ENDIF
			    mlength := SELF:Length
			    bytes := BYTE[] {mlength}
			    SELF:RDD:_CheckError(ACE.AdsGetBinary(SELF:_Table, SELF:FieldPos, 0, bytes, REF mlength ),EG_READ)
			    RETURN bytes
            OTHERWISE
                // Should never happen. We filter on the type when creating the column object
			    SELF:RDD:ADSError(ERDD_DATATYPE, EG_DataType, __ENTITY__,"Unexpected fieldtype: "+SELF:AdsType:ToString())
		    END SWITCH
            RETURN NULL

        OVERRIDE METHOD PutValue(oValue AS OBJECT) AS LOGIC
	        LOCAL result := 0 AS DWORD
		    LOCAL slength AS DWORD
		    LOCAL strValue AS STRING
    		VAR tc := Type.GetTypeCode(oValue:GetType())
            SWITCH SELF:AdsType
		    CASE AdsFieldType.MEMO
		    CASE AdsFieldType.NMEMO
			    IF tc != TypeCode.String
				    SELF:RDD:ADSERROR(ERDD_DATATYPE, EG_DataType, __ENTITY__,"String expected")
			    ENDIF
			    strValue := (STRING) oValue
			    slength  := (DWORD) strValue:Length
			    IF slength == 0
				    result := ACE.AdsSetEmpty(SELF:_Table, SELF:FieldPos)
			    ELSE
                    IF SELF:AdsType == AdsFieldType.NMEMO
                        result := ACE.AdsSetStringW(SELF:_Table, SELF:FieldPos, strValue, slength)
                    ELSE
                        result := ACE.AdsSetString(SELF:_Table, SELF:FieldPos, strValue, slength)
                    ENDIF
			    ENDIF
		    CASE AdsFieldType.BINARY
		    CASE AdsFieldType.IMAGE
		    CASE AdsFieldType.RAW
		    CASE AdsFieldType.VARBINARY_FOX
			    IF tc != TypeCode.String .AND. tc != TypeCode.Object
				    SELF:RDD:ADSERROR(ERDD_DATATYPE, EG_DataType, __ENTITY__,"String or Object expected")
			    ENDIF
			    IF tc != TypeCode.String
				    strValue := (STRING) oValue
				    slength := (DWORD) strValue:Length
				    result := ACE.AdsSetString(SELF:_Table, SELF:FieldPos, strValue, slength)
			    ELSE
				    LOCAL bytes AS BYTE[]
				    bytes   := (BYTE[]) oValue
				    slength  := (DWORD) bytes:Length
				    IF SELF:AdsType == AdsFieldType.RAW .OR. SELF:AdsType == AdsFieldType.VARBINARY_FOX
					    result := ACE.AdsSetField(SELF:_Table, SELF:FieldPos, bytes, slength)
				    ELSE
					    result := ACE.AdsSetBinary(SELF:_Table, SELF:FieldPos, SELF:AdsType, slength, 0, bytes, slength)
				    ENDIF
			    ENDIF
		    OTHERWISE
                // Should never happen. We filter on the type when creating the column object
			    SELF:RDD:ADSError(ERDD_DATATYPE, EG_DataType, __ENTITY__,"Unexpected fieldtype: "+SELF:AdsType:ToString())
		    END SWITCH
            IF result != 0 .AND. result != ACE.AE_DATA_TRUNCATED
			    SELF:RDD:ADSERROR(result, EG_WRITE, __ENTITY__)
		    ENDIF
            RETURN TRUE

       OVERRIDE METHOD Validate() AS LOGIC
            RETURN SELF:Length == 10 .AND.  SELF:Decimals == 0

    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.IO
USING System.Collections.Generic
USING System.Linq
USING XSharp.RDD
USING XSharp.RDD.Support
USING XSharp.RDD.Enums

BEGIN NAMESPACE XSharp.ADS
    /// Class for DBF Column reading / writing
    CLASS AdsColumn INHERIT RDDFieldInfo
        INTERNAL RDD        AS XSharp.ADS.AdsRDD
        INTERNAL AdsType    as AdsFieldType
        INTERNAL FieldPos   as DWORD
        PROPERTY _Table as IntPtr GET RDD:_Table

        STATIC METHOD Create(oInfo AS RDDFieldInfo, oRDD AS XSharp.ADS.AdsRDD,type as AdsFieldType, nPos as DWORD) AS AdsColumn
            // Commented out types are Harbour specific
            SWITCH type
            // char types
            CASE AdsFieldType.TIMESTAMP
            CASE AdsFieldType.MODTIME
            CASE AdsFieldType.TIME
            CASE AdsFieldType.MONEY
            CASE AdsFieldType.ROWVERSION
		    CASE AdsFieldType.STRING
		    CASE AdsFieldType.VARCHAR
		    CASE AdsFieldType.CISTRING
		    CASE AdsFieldType.VARCHAR_FOX
		    CASE AdsFieldType.NCHAR
		    CASE AdsFieldType.NVARCHAR
                return AdsCharacterColumn{oInfo, oRDD, type,nPos}

		    CASE AdsFieldType.MEMO
		    CASE AdsFieldType.BINARY
		    CASE AdsFieldType.IMAGE
		    CASE AdsFieldType.NMEMO
		    CASE AdsFieldType.RAW
		    CASE AdsFieldType.VARBINARY_FOX
                return AdsMemoColumn{oInfo, oRDD, type,nPos}

		    CASE AdsFieldType.SHORTINT
		    CASE AdsFieldType.AUTOINC
		    CASE AdsFieldType.INTEGER
		    CASE AdsFieldType.NUMERIC
		    CASE AdsFieldType.DOUBLE
		    CASE AdsFieldType.CURDOUBLE
                return AdsNumericColumn{oInfo, oRDD, type,nPos}

		    CASE AdsFieldType.LOGICAL
                return AdsLogicColumn{oInfo, oRDD, type,nPos}

		    CASE AdsFieldType.DATE
		    CASE AdsFieldType.COMPACTDATE
                return AdsDateColumn{oInfo, oRDD, type,nPos}
            OTHERWISE
                oRDD:ADSERROR(ERDD_DATATYPE, EG_DataType, __ENTITY__,"Unexpected fieldtype: "+ ((int) type):ToString())
            END SWITCH
            RETURN NULL

        PROTECTED CONSTRUCTOR(oInfo AS RddFieldInfo,oRDD AS XSharp.ADS.AdsRDD, type as AdsFieldType, nPos as DWORD)
            SUPER(oInfo)
            SELF:RDD        := oRDD
            SELF:AdsType    := type
            SELF:FieldPos   := nPos
            RETURN

        VIRTUAL METHOD GetValue() AS OBJECT
            RETURN NIL

        VIRTUAL METHOD PutValue(oValue AS OBJECT) AS LOGIC
            RETURN FALSE

   OVERRIDE METHOD ToString() AS STRING
        RETURN SELF:Name+" ('"+SELF:FieldTypeStr+"',"+SELF:Length:ToString()+","+SELF:Decimals:ToString()+","+SELF:Adstype:ToString()+")"

    END CLASS

    /// Class for reading / writing String Columns
    CLASS AdsCharacterColumn INHERIT AdsColumn

         CONSTRUCTOR(oInfo AS RddFieldInfo,oRDD AS XSharp.ADS.AdsRDD, type as AdsFieldType,nPos AS DWORD)
            SUPER(oInfo, oRDD,type,nPos)
            IF SELF:Decimals != 0
                SELF:Length         += SELF:Decimals * 256
			    SELF:Decimals       := 0
            ENDIF
            RETURN

       OVERRIDE METHOD PutValue(oValue AS OBJECT) AS LOGIC
	        LOCAL result := 0 AS DWORD
		    LOCAL slength AS DWORD
		    LOCAL strValue AS STRING
    		VAR tc := Type.GetTypeCode(oValue:GetType())
            SWITCH SELF:AdsType
		    CASE AdsFieldType.STRING
		    CASE AdsFieldType.VARCHAR
            CASE AdsFieldType.VARCHAR_FOX
		    CASE AdsFieldType.CISTRING
		    CASE AdsFieldType.NCHAR
		    CASE AdsFieldType.NVARCHAR
			    IF tc != TypeCode.String
				    SELF:RDD:ADSERROR(ERDD_DATATYPE, EG_DataType, __ENTITY__,"String expected")
			    ENDIF
			    strValue := (STRING) oValue
			    slength  := (DWORD) strValue:Length
                slength := Math.Min(slength, SELF:Length)
			    IF slength == 0
				    result := ACE.AdsSetEmpty(SELF:_Table, SELF:FieldPos)
			    ELSE
                    IF SELF:AdsType == AdsFieldType.NCHAR .or. SELF:AdsType == AdsFieldType.NVARCHAR
                        result := ACE.AdsSetStringW(SELF:_Table, SELF:FieldPos, strValue, slength)
                    ELSE
                        result := ACE.AdsSetString(SELF:_Table, SELF:FieldPos, strValue, slength)
                    ENDIF
			    ENDIF
		    CASE AdsFieldType.TIME
		    CASE AdsFieldType.TIMESTAMP
		    CASE AdsFieldType.MONEY
		    CASE AdsFieldType.ROWVERSION
		    CASE AdsFieldType.MODTIME
			    IF tc != TypeCode.String
				    SELF:RDD:ADSERROR(ERDD_DATATYPE, EG_DataType, __ENTITY__,"String expected")
			    ENDIF
			    strValue := (STRING) oValue
			    slength  := (DWORD) strValue:Length
			    result := ACE.AdsSetField(SELF:_Table, SELF:FieldPos, strValue, slength)
		    OTHERWISE
                // Should never happen. We filter on the type when creating the column object
			    SELF:RDD:ADSError(ERDD_DATATYPE, EG_DataType, __ENTITY__,"Unexpected fieldtype: "+SELF:AdsType:ToString())
		    END SWITCH
            IF result != 0 .AND. result != ACE.AE_DATA_TRUNCATED
			    SELF:RDD:ADSERROR(result, EG_WRITE, __ENTITY__)
		    ENDIF
            RETURN TRUE

        OVERRIDE METHOD Validate() AS LOGIC
            IF SELF:Length == 0  .OR. SELF:Decimals > 0  .OR. SELF:Length > System.UInt16.MaxValue
                RETURN FALSE
            ENDIF
            RETURN TRUE

        OVERRIDE METHOD GetValue() AS OBJECT
            LOCAL result    := 0 as DWORD
            LOCAL slength    := SELF:Length+1 AS DWORD
			LOCAL chars := CHAR[] {slength} as CHAR[]
		    SWITCH SELF:AdsType
		    CASE AdsFieldType.TIME
		    CASE AdsFieldType.TIMESTAMP
		    CASE AdsFieldType.MONEY
		    CASE AdsFieldType.ROWVERSION
		    CASE AdsFieldType.MODTIME
                LOCAL isEmpty   := 0 AS WORD
			    RDD:_CheckError(ACE.AdsIsEmpty(SELF:_Table,  SELF:FieldPos , OUT isEmpty),EG_READ)
			    IF isEmpty == 1
				    RETURN NULL
			    ENDIF
			    chars := CHAR[] {slength}
			    result := ACE.AdsGetField(SELF:_Table, SELF:FieldPos, chars, REF slength ,0)
		    CASE AdsFieldType.STRING
		    CASE AdsFieldType.VARCHAR
		    CASE AdsFieldType.CISTRING
		    CASE AdsFieldType.VARCHAR_FOX
		    CASE AdsFieldType.NCHAR
		    CASE AdsFieldType.NVARCHAR
			    chars := CHAR[] {slength}
                IF SELF:AdsType == AdsFieldType.NCHAR .or. SELF:AdsType == AdsFieldType.NVARCHAR
			        result := ACE.AdsGetStringW(SELF:_Table, SELF:FieldPos, chars, REF slength ,0)
                ELSE
			        result := ACE.AdsGetString(SELF:_Table, SELF:FieldPos, chars, REF slength ,0)
                ENDIF
		    OTHERWISE
                // Should never happen. We filter on the type when creating the column object
			    SELF:RDD:ADSError(ERDD_DATATYPE, EG_DataType, __ENTITY__,"Unexpected fieldtype: "+SELF:AdsType:ToString())
		    END SWITCH
		    SWITCH result
		    CASE 0
			    IF SELF:AdsType == AdsFieldType.NCHAR .or. SELF:AdsType == AdsFieldType.NVARCHAR
                    RETURN STRING{chars, 0, (INT) SELF:length}
			    ELSE
				    RETURN SELF:RDD:_Ansi2Unicode(chars, (INT) SELF:length)
			    ENDIF
		    CASE ACE.AE_NO_CURRENT_RECORD
			    RETURN STRING{' ', (INT) SELF:length}
		    OTHERWISE
			    SELF:RDD:_CheckError(result,EG_READ)
		    END SWITCH
            RETURN String.Empty

    END CLASS
    /// Class for reading / writing Date Columns
    CLASS AdsDateColumn INHERIT AdsColumn

         CONSTRUCTOR(oInfo AS RddFieldInfo,oRDD AS XSharp.ADS.AdsRDD, type as AdsFieldType,nPos AS DWORD)
            SUPER(oInfo, oRDD,type,nPos)
            RETURN

        OVERRIDE METHOD GetValue() AS OBJECT
		    LOCAL lJulian AS LONG
            VAR result := ACE.AdsGetJulian(SELF:_Table, SELF:FieldPos, OUT lJulian)
		    IF result == ACE.AE_NO_CURRENT_RECORD
			    RETURN DbDate{0,0,0}
		    ELSEIF result != 0
			    SELF:RDD:_CheckError(result,EG_READ)
		    ENDIF
		    TRY
			    IF lJulian == 0
				    RETURN DbDate{0,0,0}
			    ELSE
                    // there is a function to convert julian to string but it does not always work correctly
                    // this seems to always do the job
				    LOCAL wLength := ACE.ADS_MAX_DATEMASK+1 AS DWORD
                    LOCAL chars := CHAR[] {SELF:length} as CHAR[]
				    result := ACE.AdsGetString(SELF:_Table, SELF:FieldPos, chars, REF wLength, 0)
				    VAR cDate := STRING{chars, 0, 8}
				    IF String.IsNullOrWhiteSpace(cDate)
					    RETURN DbDate{0,0,0}
				    ELSE
					    VAR dt := DateTime.ParseExact(cDate, "yyyyMMdd",NULL)
					    RETURN DbDate{dt:Year, dt:Month, dt:Day}
				    ENDIF
			    ENDIF
		    CATCH

		    END TRY
		    RETURN DbDate{0,0,0}

        OVERRIDE METHOD PutValue(oValue AS OBJECT) AS LOGIC
            // Note that the XSharp.__Date type also returns a typecode of DateTime
            VAR tc := Type.GetTypeCode(oValue:GetType())
	        IF oValue IS IDate VAR oDate
                tc := TypeCode.DateTime
		        IF oDate:IsEmpty
			        oValue := DateTime.MinValue
		        ELSE
			        oValue := DateTime{oDate:Year, oDate:Month, oDate:Day}
		        ENDIF
            ELSEIF oValue IS DateTime
                tc := TypeCode.DateTime
	        ENDIF
		    IF tc != TypeCode.DateTime
			    SELF:RDD:ADSERROR(ERDD_DATATYPE, EG_DataType, __ENTITY__,"Date or DateTime value expected")
		    ENDIF

		    LOCAL dt := (DateTime) oValue AS DateTime
            if (dt == DateTime.MinValue)
                SELF:RDD:_CheckError(ACE.AdsSetEmpty(SELF:_Table, SELF:FieldPos),EG_WRITE)
            ELSE
		        LOCAL text := dt:ToString("yyyyMMdd") AS STRING
		        LOCAL r8Julian AS REAL8
		        SELF:RDD:_CheckError(AceUnPub.AdsConvertStringToJulian(text, (WORD) text:Length, OUT r8Julian),EG_WRITE)
		        SELF:RDD:_CheckError(ACE.AdsSetJulian(SELF:_Table, SELF:FieldPos, (LONG) r8Julian),EG_WRITE)
            ENDIF
            RETURN TRUE

        OVERRIDE METHOD Validate() AS LOGIC
            RETURN SELF:Length == 8  .AND.  SELF:Decimals == 0

    END CLASS

    /// Class for reading / writing Logic Columns
    CLASS AdsLogicColumn INHERIT AdsColumn

        CONSTRUCTOR(oInfo AS RddFieldInfo,oRDD AS XSharp.ADS.AdsRDD, type as AdsFieldType,nPos AS DWORD)
            SUPER(oInfo,oRDD,type,nPos)
            RETURN

        OVERRIDE METHOD GetValue() AS OBJECT
	        LOCAL wValue AS WORD
		    var result := ACE.AdsGetLogical(SELF:_Table, SELF:FieldPos, OUT wValue)
		    IF result ==  ACE.AE_NO_CURRENT_RECORD
			    wValue := 0
		    ELSEIF ! SELF:RDD:_CheckError(result,EG_READ)
              // Exception
		    ENDIF
		    RETURN wValue != 0

       OVERRIDE METHOD PutValue(oValue AS OBJECT) AS LOGIC
            VAR tc := Type.GetTypeCode(oValue:GetType())
		    IF tc != TypeCode.Boolean
			    SELF:RDD:ADSERROR(ERDD_DATATYPE, EG_DataType, __ENTITY__,"Logic value expected")
		    ENDIF
		    SELF:RDD:_CheckError(ACE.AdsSetLogical(SELF:_Table, SELF:FieldPos, (WORD)  IIF( (LOGIC) oValue, 1, 0)),EG_WRITE)
            RETURN TRUE

       OVERRIDE METHOD Validate() AS LOGIC
            RETURN SELF:Length == 1  .AND.  SELF:Decimals == 0
    END CLASS

    /// Class for reading / writing Numeric Columns
    CLASS AdsNumericColumn INHERIT AdsColumn

    CONSTRUCTOR(oInfo AS RddFieldInfo,oRDD AS XSharp.ADS.AdsRDD, type as AdsFieldType,nPos AS DWORD)
            SUPER(oInfo,oRDD,type,nPos)
            RETURN

        OVERRIDE METHOD GetValue() AS OBJECT
            LOCAL result    := 0 as DWORD
		    SWITCH SELF:AdsType
		    CASE AdsFieldType.NUMERIC
		    CASE AdsFieldType.DOUBLE
		    CASE AdsFieldType.INTEGER
		    CASE AdsFieldType.SHORTINT
		    CASE AdsFieldType.AUTOINC
		    CASE AdsFieldType.CURDOUBLE
			    LOCAL r8 AS REAL8
			    result := ACE.AdsGetDouble(SELF:_Table, SELF:FieldPos, OUT r8)
			    IF result == ACE.AE_NO_CURRENT_RECORD
				    r8 := 0.0
			    ENDIF
			    IF SELF:AdsType:IsDouble()
				    VAR value := r8:ToString()
				    VAR pos := VALUE:IndexOf('.')
				    RETURN DbFloat{r8, SELF:Length, IIF(pos > 0, SELF:Length - pos -1, 0)}
			    ELSE
				    RETURN DbFloat{r8, SELF:Length, SELF:Decimals}
			    ENDIF
		    OTHERWISE
                // Should never happen. We filter on the type when creating the column object
			    SELF:RDD:ADSError(ERDD_DATATYPE, EG_DataType, __ENTITY__,"Unexpected fieldtype: "+SELF:AdsType:ToString())
		    END SWITCH
            RETURN NULL

      OVERRIDE METHOD PutValue(oValue AS OBJECT) AS LOGIC
        VAR tc := Type.GetTypeCode(oValue:GetType())
      	IF oValue IS IFloat VAR floatValue
		    tc := TypeCode.Double
		    oValue := floatValue:Value
        ENDIF
        LOCAL wType AS WORD
        LOCAL result := 0 AS DWORD
        SELF:RDD:_CheckError(ACE.AdsGetFieldType(SELF:_Table, SELF:FieldPos, OUT wType),EG_READ)
        IF wType != ACE.ADS_AUTOINC
	        TRY
	            LOCAL r8 AS REAL8
		        r8 := Convert.ToDouble(oValue)
		        SELF:RDD:_CheckError(ACE.AdsSetDouble(SELF:_Table, SELF:FieldPos, r8),EG_WRITE)

            CATCH
		        SELF:RDD:ADSERROR(ERDD_DATATYPE, EG_DataType, __ENTITY__,"Numeric value expected")
                RETURN FALSE
	        END TRY
        ELSE
	        NOP // Do not allow to write to AUTO INC field
        ENDIF
        RETURN TRUE

       OVERRIDE METHOD Validate() AS LOGIC
           IF SELF:Length >= 1  .AND.  SELF:Length <= 255
                IF SELF:Decimals > 0
                    // We must check that we have enough space for DOT and decimal
                    IF SELF:Length <= 2  .OR.  SELF:Decimals >= SELF:Length -1
                        RETURN FALSE
                    ENDIF
                ENDIF
            ELSE
                RETURN FALSE
            ENDIF
            RETURN TRUE

    END CLASS

    /// Class for reading / writing Memo Columns. This class returns and writes the block numbers.
    CLASS AdsMemoColumn INHERIT AdsColumn
        // AdsFieldType.MEMO
        // AdsFieldType.NMEMO
        // AdsFieldType.BINARY
        // AdsFieldType.IMAGE
        // AdsFieldType.RAW
        // AdsFieldType.VARBINARY_FOX

        CONSTRUCTOR(oInfo AS RddFieldInfo,oRDD AS XSharp.ADS.AdsRDD, type as AdsFieldType,nPos AS DWORD)
            SUPER(oInfo,oRDD,type,nPos)
            RETURN

        OVERRIDE METHOD GetValue() AS OBJECT
            LOCAL isEmpty   := 0 AS WORD
            LOCAL result    := 0 as DWORD
            LOCAL mlength    := 0 AS DWORD
            LOCAL bytes     := NULL AS BYTE[]
			LOCAL chars := CHAR[] {length} as CHAR[]
            SWITCH SELF:AdsType
		    CASE AdsFieldType.MEMO
		    CASE AdsFieldType.NMEMO
		    CASE AdsFieldType.BINARY
		    CASE AdsFieldType.IMAGE
			    result := ACE.AdsGetMemoLength(SELF:_Table, SELF:FieldPos, OUT mlength )
			    SWITCH result
			    CASE 0
				    IF length == 0
					    RETURN string.Empty
				    ENDIF
			    CASE ACE.AE_NO_CURRENT_RECORD
				    IF SELF:AdsType == AdsFieldType.MEMO .or. SELF:AdsType == AdsFieldType.NMEMO
					    RETURN string.Empty
				    ELSE    // image and binary
					    RETURN NULL
				    ENDIF
			    OTHERWISE
				    SELF:RDD:_CheckError(result,EG_READ)
			    END SWITCH
			    SWITCH SELF:AdsType
			    CASE AdsFieldType.MEMO
				    chars := CHAR[] {mlength+1}
				    SELF:RDD:_CheckError(ACE.AdsGetString(SELF:_Table, SELF:FieldPos, chars, REF mlength ,0),EG_READ)
				    RETURN SELF:RDD:_Ansi2Unicode(chars, (INT) length)
			    CASE AdsFieldType.NMEMO
				    chars := CHAR[] {++length}
				    SELF:RDD:_CheckError(ACE.AdsGetStringW(SELF:_Table, SELF:FieldPos, chars, REF mlength ,0),EG_READ)
			    CASE AdsFieldType.BINARY
			    CASE AdsFieldType.IMAGE
				    bytes := BYTE[] {mlength}
				    SELF:RDD:_CheckError(ACE.AdsGetBinary(SELF:_Table, SELF:FieldPos, 0, bytes, REF mlength ),EG_READ)
				    RETURN bytes
			    END SWITCH

		    CASE AdsFieldType.RAW
		    CASE AdsFieldType.VARBINARY_FOX
			    result := ACE.AdsIsEmpty(SELF:_Table, SELF:FieldPos, OUT isEmpty)
			    IF result == 0
				    IF isEmpty == 1
					    RETURN NULL
				    ENDIF
			    ELSE
				    SELF:RDD:_CheckError(result,EG_READ)
			    ENDIF
			    mlength := SELF:Length
			    bytes := BYTE[] {mlength}
			    SELF:RDD:_CheckError(ACE.AdsGetBinary(SELF:_Table, SELF:FieldPos, 0, bytes, REF mlength ),EG_READ)
			    RETURN bytes
            OTHERWISE
                // Should never happen. We filter on the type when creating the column object
			    SELF:RDD:ADSError(ERDD_DATATYPE, EG_DataType, __ENTITY__,"Unexpected fieldtype: "+SELF:AdsType:ToString())
		    END SWITCH
            RETURN NULL

        OVERRIDE METHOD PutValue(oValue AS OBJECT) AS LOGIC
	        LOCAL result := 0 AS DWORD
		    LOCAL slength AS DWORD
		    LOCAL strValue AS STRING
    		VAR tc := Type.GetTypeCode(oValue:GetType())
            SWITCH SELF:AdsType
		    CASE AdsFieldType.MEMO
		    CASE AdsFieldType.NMEMO
			    IF tc != TypeCode.String
				    SELF:RDD:ADSERROR(ERDD_DATATYPE, EG_DataType, __ENTITY__,"String expected")
			    ENDIF
			    strValue := (STRING) oValue
			    slength  := (DWORD) strValue:Length
			    IF slength == 0
				    result := ACE.AdsSetEmpty(SELF:_Table, SELF:FieldPos)
			    ELSE
                    IF SELF:AdsType == AdsFieldType.NMEMO
                        result := ACE.AdsSetStringW(SELF:_Table, SELF:FieldPos, strValue, slength)
                    ELSE
                        result := ACE.AdsSetString(SELF:_Table, SELF:FieldPos, strValue, slength)
                    ENDIF
			    ENDIF
		    CASE AdsFieldType.BINARY
		    CASE AdsFieldType.IMAGE
		    CASE AdsFieldType.RAW
		    CASE AdsFieldType.VARBINARY_FOX
			    IF tc != TypeCode.String .AND. tc != TypeCode.Object
				    SELF:RDD:ADSERROR(ERDD_DATATYPE, EG_DataType, __ENTITY__,"String or Object expected")
			    ENDIF
			    IF tc != TypeCode.String
				    strValue := (STRING) oValue
				    slength := (DWORD) strValue:Length
				    result := ACE.AdsSetString(SELF:_Table, SELF:FieldPos, strValue, slength)
			    ELSE
				    LOCAL bytes AS BYTE[]
				    bytes   := (BYTE[]) oValue
				    slength  := (DWORD) bytes:Length
				    IF SELF:AdsType == AdsFieldType.RAW .OR. SELF:AdsType == AdsFieldType.VARBINARY_FOX
					    result := ACE.AdsSetField(SELF:_Table, SELF:FieldPos, bytes, slength)
				    ELSE
					    result := ACE.AdsSetBinary(SELF:_Table, SELF:FieldPos, SELF:AdsType, slength, 0, bytes, slength)
				    ENDIF
			    ENDIF
		    OTHERWISE
                // Should never happen. We filter on the type when creating the column object
			    SELF:RDD:ADSError(ERDD_DATATYPE, EG_DataType, __ENTITY__,"Unexpected fieldtype: "+SELF:AdsType:ToString())
		    END SWITCH
            IF result != 0 .AND. result != ACE.AE_DATA_TRUNCATED
			    SELF:RDD:ADSERROR(result, EG_WRITE, __ENTITY__)
		    ENDIF
            RETURN TRUE

       OVERRIDE METHOD Validate() AS LOGIC
            RETURN SELF:Length == 10 .AND.  SELF:Decimals == 0

    END CLASS

END NAMESPACE


implement fibrateLevels by returning a (Thrist Levels)

-- implement the idea described in
-- https://code.google.com/p/omega/wiki/IcebergTypes
--

import "../src/LangPrelude.prg" (maybeM)

data Thrist :: (l ~> l ~> *) ~> l ~> l ~> * where
  Nil :: Thrist k a a
  Cons :: k a b -> Thrist k b c -> Thrist k a c
 deriving List(t)

data Multiplicity :: *2 where
  Mono :: Multiplicity
  Poly :: Multiplicity

data Lev :: Multiplicity ~> *1 where
  ValueLevel :: Lev Mono
  LevelUp :: Lev m ~> Lev m
  PolyLevel :: Lev Poly -- level n .
 deriving syntax (lev) Nat(ValueLevel, LevelUp)

data Level :: Lev n ~> * where
  ValueLevel :: Level ValueLevel
  LevelUp :: Level l -> Level (LevelUp l)
  PolyLevel :: Level PolyLevel
 deriving syntax (l) Nat(ValueLevel, LevelUp)

data Signature = Sig -- for now

data Iceberg :: * ~> * ~> * where
  Constructor :: Label t -> Level l -> Signature -> Iceberg () ()

data Icename :: Tag ~> Tag ~> * where -- entities with certain name
  NamedConstructor :: Label t -> Level l -> Signature -> Icename t t

data Icelevel :: Lev n ~> Lev n ~> * where -- entities with certain level
  LevelConstructor :: LevelFits l' l => Label t -> Level l -> Signature -> Icelevel l' l'

data TagLev :: Multiplicity ~> *1 where
  TL :: Tag ~> Lev m ~> TagLev m

data Icenamelevel :: TagLev n ~> TagLev n ~> * where -- entities with certain level and name
  NamedLevelConstructor :: LevelFits l' l => Label t -> Level l -> Signature -> Icenamelevel (TL t l') (TL t l')

builtIns :: Thrist Iceberg () ()
builtIns = [ Constructor `Z 0l Sig, Constructor `S 0l Sig, Constructor natPrime 0l Sig
           , Constructor `Z 1l Sig, Constructor `S 1l Sig, Constructor `Nat 2l Sig
           , Constructor starN (LevelUp (LevelUp PolyLevel)) Sig
           , Constructor constraintN (LevelUp (LevelUp PolyLevel)) Sig
           , Constructor `MultValueAndUp PolyLevel Sig]t
  where HideLabel natPrime = newLabel "Nat'"
        HideLabel starN = newLabel "*n"
        HideLabel constraintN = newLabel "#n"

projectName :: Label l -> Thrist Iceberg () () -> Thrist Icename l l
projectName _ []t = []t
projectName l [Constructor l' lev sig; rest]t = case l `sameLabel` l' of
                                                L Eq -> [NamedConstructor l' lev sig; projectName l rest]t
                                                _ -> projectName l rest

projectName' :: Label t -> Thrist Icelevel l l -> Thrist Icenamelevel (TL t l) (TL t l)
projectName' _ []t = []t
projectName' t [LevelConstructor t' lev sig; rest]t = case t `sameLabel` t' of
                                                      L Eq -> [NamedLevelConstructor t' lev sig; projectName' t rest]t
                                                      _ -> projectName' t rest

-- inclusion relation on levels
--
prop LevelFits :: Lev n ~> Lev n' ~> * where
  BothValue :: LevelFits ValueLevel ValueLevel
  BothPoly :: LevelFits PolyLevel PolyLevel
  BothUp :: LevelFits k k' -> LevelFits (LevelUp k) (LevelUp k')
  ValuePoly :: LevelFits ValueLevel PolyLevel
  AbovePoly :: LevelFits (LevelUp k) PolyLevel

-- runtime compute level inclusion
--
fits :: Level l -> Level l' -> Maybe (LevelFits l l')
fits ValueLevel ValueLevel = Just BothValue
fits PolyLevel PolyLevel = Just BothPoly
fits (LevelUp l) (LevelUp l') = do ev <- fits l l'
                                   return $ BothUp ev
                                 where monad maybeM
fits ValueLevel PolyLevel = Just ValuePoly
fits (LevelUp l) PolyLevel = Just AbovePoly
fits _ _ = Nothing

projectLevel :: Level l -> Thrist Iceberg () () -> Thrist Icelevel l l
projectLevel _ []t = []t
projectLevel l [Constructor t l' sig; rest]t = case l `fits` l' of
                                               Just BothValue -> [LevelConstructor t l' sig; projectLevel l rest]t
                                               Just BothPoly -> [LevelConstructor t l' sig; projectLevel l rest]t
                                               Just (BothUp below) -> [LevelConstructor t l' sig; projectLevel l rest]t
                                               Just ValuePoly -> [LevelConstructor t l' sig; projectLevel l rest]t
                                               Just AbovePoly -> [LevelConstructor t l' sig; projectLevel l rest]t
                                               _ -> projectLevel l rest

projectLevel' :: Level l -> Thrist Icename t t -> Thrist Icenamelevel (TL t l) (TL t l)
projectLevel' _ []t = []t
projectLevel' l [NamedConstructor t l' sig; rest]t = case l `fits` l' of
                                                     Just BothValue -> [NamedLevelConstructor t l' sig; projectLevel' l rest]t
                                                     Just BothPoly -> [NamedLevelConstructor t l' sig; projectLevel' l rest]t
                                                     Just (BothUp below) -> [NamedLevelConstructor t l' sig; projectLevel' l rest]t
                                                     Just ValuePoly -> [NamedLevelConstructor t l' sig; projectLevel' l rest]t
                                                     Just AbovePoly -> [NamedLevelConstructor t l' sig; projectLevel' l rest]t
                                                     _ -> projectLevel' l rest

data Levels :: Lev m ~> Lev m ~> * where
  InLevel :: Thrist Icelevel l l -> Levels l (1+l)l

t3 :: Thrist Levels 0l 2l
t3 = [InLevel $ projectLevel 0l builtIns, InLevel $ projectLevel 1l builtIns]t

fibrateLevels :: Level l -> Thrist Iceberg () () -> Thrist Levels l a
fibrateLevels l berg = [InLevel $ projectLevel l berg; lazy (fibrateLevels (1+l)l berg)]t

[t30, t31, t32, t33; t34]t = fibrateLevels 0l builtIns


work in progress

work in progress

data Dir :: *2 ~> *2 where
  Hor :: name ~> Dir name
  Ver :: name ~> Dir name -- tree of names!

data Tree :: Dir named ~> *1 where
  Unit :: Tree (Ver name)
  Ni :: Tree (Hor name)
  Fork :: Tree (Hor name) ~> Tree (Ver t) ~> Tree (Hor name)
 deriving syntax (tr) LeftList(Ni, Fork) Unit(Unit)

data Dir :: *2 ~> *2 where
  Hor :: name ~> Dir name
  Ver :: name ~> Dir name -- tree of names!

data Tree :: Dir named ~> *1 where
  Unit :: Tree (Ver unit)
  Ni :: Tree (Hor name)
  Fork :: Tree (Hor name) ~> Tree (d {-name-}) ~> Tree (Hor name)
 deriving syntax (tr) LeftList(Ni, Fork) Unit(Unit)


[Runtime] Make sure code internal to Binary uses the original byte[]

//
// 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.Text
USING System.Runtime.InteropServices
USING System.Runtime.CompilerServices
USING System.Diagnostics
USING System.Runtime.Serialization
#pragma options ("az", on)
BEGIN NAMESPACE XSharp
    // use explicit layout so we can compact the size into 12 bytes
    // Type is Immutable, so has no settable properties
    /// Internal type that implements the FoxPro Compatible BINARY type.

    /// This type has many operators and implicit converters that normally are never directly called from user code.
    /// The data in this type is stored as an array of Bytes

    /// Conversions from and to String are supported and they use the current active windows codepage.
    ///
    [Serializable];
    PUBLIC STRUCTURE __Binary IMPLEMENTS IFormattable, ;
        IComparable<__Binary>, ;
        IEquatable<__Binary>, ;
        IComparable,           ;
        ISerializable

        [DebuggerBrowsable(DebuggerBrowsableState.Never)];
        PRIVATE INITONLY _value AS BYTE[]

        #region constructors
        /// <include file="RTComments.xml" path="Comments/Constructor/*" />
        /// <param name="b">Byte[] value that has the bytes that define the binary</param>
        [DebuggerStepThroughAttribute] [MethodImpl(MethodImplOptions.AggressiveInlining)];
        CONSTRUCTOR (b as Byte[])
            IF b == NULL
                THROW NullError()
            ENDIF
            SELF:_value    := b

        PRIVATE STATIC METHOD NullError() as Error
            VAR err			 := Error{ArgumentException{}}
            err:Gencode		 := Gencode.EG_ARG
            err:ArgNum		 := 1
            err:FuncSym		 := "Binary.ctor"
            err:Description  := "Argument cannot be null"
            err:Args         := <OBJECT> {NULL}
            return err

        PRIVATE CONSTRUCTOR( lhs as byte[], rhs as byte[])
            var len := lhs:Length + rhs:Length
            var result := byte[]{len}
            System.Array.Copy(lhs, result, lhs:Length)
            System.Array.Copy(rhs, 0, result,lhs:Length, rhs:Length)
            _value := result

        #endregion
        #region Properties
        /// Binary value as array of Bytes
        PROPERTY @@Value    AS Byte[]
            GET
                var len    := _value:Length
                var result := byte[]{len}
                System.Array.Copy(_value, result, len)
                return result
            END GET
        END PROPERTY
        PROPERTY Length     AS LONG GET iif(_value == NULL, 0, _value:Length)
        #endregion

        #region Equality Operators
        /// <inheritdoc />
        OVERRIDE METHOD Equals(rhs AS OBJECT  ) AS LOGIC
            LOCAL result AS LOGIC
            IF rhs != NULL .AND. rhs IS __Binary
                result := SELF:Equals( (__Binary) rhs)
            ELSE
                result := FALSE
            ENDIF
            RETURN result

        /// <inheritdoc />
        METHOD Equals(rhs AS __Binary ) AS LOGIC
            IF SELF:Length != rhs:Length
                RETURN FALSE
            ENDIF
            FOR VAR i := 0 to SELF:Length-1
                IF SELF:_value[i] != rhs:_value[i]
                    RETURN FALSE
                ENDIF
            NEXT
            RETURN TRUE

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

            /// <exclude />
        METHOD GetTypeCode() AS TypeCode
            RETURN TypeCode.Object

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

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

        #region Comparison Operators
        /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR >(lhs AS __Binary, rhs AS __Binary) AS LOGIC
            var len := Math.Min(lhs:Length,rhs:Length)
            var res := RuntimeState.StringCompare(lhs:_value, rhs:_value, len)
            if res > 0
                return TRUE
            elseif res < 0
                return FALSE
            endif
            RETURN lhs:Length > rhs:Length

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR <(lhs AS __Binary, rhs AS __Binary) AS LOGIC
            var len := Math.Min(lhs:Length,rhs:Length)
            var res := RuntimeState.StringCompare(lhs:_value, rhs:_value, len)
            if res < 0
                return TRUE
            elseif res > 0
                return FALSE
            endif
            RETURN lhs:Length < rhs:Length

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR >=(lhs AS __Binary, rhs AS __Binary) AS LOGIC
            var len := Math.Min(lhs:Length,rhs:Length)
            var res := RuntimeState.StringCompare(lhs:_value, rhs:_value, len)
            if res > 0
                return TRUE
            elseif res < 0
                return FALSE
            endif
            RETURN lhs:Length >= rhs:Length

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR <=(lhs AS __Binary, rhs AS __Binary) AS LOGIC
            var len := Math.Min(lhs:Length,rhs:Length)
            var res := RuntimeState.StringCompare(lhs:_value, rhs:_value, len)
            if res < 0
                return TRUE
            elseif res > 0
                return FALSE
            endif
            RETURN lhs:Length <= rhs:Length

            #endregion

        #region Implicit Converters
        /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(b AS BYTE[]) AS __Binary
            RETURN __Binary{b}

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(b AS __Binary) AS BYTE[]
            RETURN b:_value  // this is a copy of the originsl byte[]

        /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(bytes AS __Binary) AS STRING
            RETURN RuntimeState.WinEncoding:GetString(bytes:_value)

        /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(s AS STRING) AS __Binary
            RETURN __Binary{ RuntimeState.WinEncoding:GetBytes(s) }

            #endregion

        #region Numeric Operators

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR+(lhs AS __Binary, rhs AS __Binary) AS __Binary
            return __Binary{lhs:_value, rhs:_value}

        /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR+(lhs AS __Binary, rhs AS STRING) AS __Binary
            return __Binary{lhs:_value, RuntimeState.WinEncoding:GetBytes(rhs)}

        OPERATOR+(lhs AS STRING, rhs AS __Binary) AS STRING
            var sb := StringBuilder{}
            sb:Append(lhs)
            sb:Append(RuntimeState.WinEncoding:GetString(rhs))
            RETURN sb:ToString()

        #endregion
        #region Unary Operators

            #endregion
        #region Add and Subtract
        /// <exclude />
        METHOD Add(rhs AS __Binary) AS __Binary
            RETURN SELF + rhs

        /// <inheritdoc />
        PUBLIC METHOD CompareTo(rhs AS __Binary) AS INT
            var len := Math.Min(SELF:Length,rhs:Length)
            for var i := 0 to len-1
                if SELF:_value[i] > rhs:_value[i]
                    return 1
                ELSEIF SELF:_value[i] < rhs:_value[i]
                    return -1
                ENDIF
            next
            if SELF:Length > rhs:Length
                RETURN 1
            ELSEIF SELF:Length < rhs:Length
                return -1
            ENDIF
            RETURN 0
            /// <inheritdoc />
        PUBLIC METHOD CompareTo(rhs AS OBJECT) AS INT
            RETURN SELF:CompareTo( (__Binary) rhs)
            #endregion

        #region IFormattable
        /// <inheritdoc />
        PUBLIC OVERRIDE METHOD ToString() AS STRING
            RETURN SELF:ToString("")

        /// <inheritdoc cref="System.Double.ToString"/>
        PUBLIC METHOD ToString(sFormat AS STRING) AS STRING
            if sFormat == "G"
                return RuntimeState:WinEncoding:GetString(self:_value)
            endif
            var sb := StringBuilder{}
            sb:Append("0h")
            foreach var b in self:_value
                sb:Append(b:ToString("X2"))
            next
            return sb:ToString()
            /// <inheritdoc />
        PUBLIC METHOD ToString(format AS STRING, provider AS System.IFormatProvider) AS STRING
            RETURN SELF:ToString(format)
            #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 := NULL
            VAR s := info:GetString("Value")
            IF s:ToLower():StartsWith("0h")
                _value := BYTE[]{(s:Length -2)/2} // subtract 2 for 0h
                LOCAL current := 0 AS INT
                FOR VAR i := 2 TO s:Length-1 STEP 2
                    VAR nibble := s:Substring(i,2)
                    _value[current] := Val("0x"+nibble)
                    current += 1
                NEXT
            ENDIF
        #endregion
        /*
        #region IConvertible
			// forward most methods to the DateTime class so there will
			// be a proper (localized) error message
			/// <inheritdoc />
			METHOD IConvertible.ToBoolean(provider AS System.IFormatProvider) AS LOGIC
				THROW NotImplementedException{}

			/// <inheritdoc />
			METHOD IConvertible.ToByte(provider AS System.IFormatProvider) AS BYTE
				THROW NotImplementedException{}

			/// <inheritdoc />
			METHOD IConvertible.ToChar(provider AS System.IFormatProvider) AS CHAR
				THROW NotImplementedException{}

			/// <inheritdoc />
			METHOD IConvertible.ToDateTime(provider AS System.IFormatProvider) AS System.DateTime
				THROW NotImplementedException{}

			/// <inheritdoc />
			METHOD IConvertible.ToDecimal(provider AS System.IFormatProvider) AS DECIMAL
				THROW NotImplementedException{}

			/// <inheritdoc />
			METHOD IConvertible.ToDouble(provider AS System.IFormatProvider) AS REAL8
				THROW NotImplementedException{}

			/// <inheritdoc />
			METHOD IConvertible.ToInt16(provider AS System.IFormatProvider) AS SHORT
				THROW NotImplementedException{}

			/// <inheritdoc />
			METHOD IConvertible.ToInt32(provider AS System.IFormatProvider) AS LONG
				THROW NotImplementedException{}

			/// <inheritdoc />
			METHOD IConvertible.ToInt64(provider AS System.IFormatProvider) AS INT64
				THROW NotImplementedException{}

			/// <inheritdoc />
			METHOD IConvertible.ToSByte(provider AS System.IFormatProvider) AS SByte
				THROW NotImplementedException{}

			/// <inheritdoc />
			METHOD IConvertible.ToSingle(provider AS System.IFormatProvider) AS REAL4
				THROW NotImplementedException{}

			/// <inheritdoc />
			METHOD IConvertible.ToUInt16(provider AS System.IFormatProvider) AS WORD
				THROW NotImplementedException{}

			/// <inheritdoc />
			METHOD IConvertible.ToUInt32(provider AS System.IFormatProvider) AS DWORD
				THROW NotImplementedException{}

			/// <inheritdoc />
			METHOD IConvertible.ToUInt64(provider AS System.IFormatProvider) AS UINT64
				THROW NotImplementedException{}

            METHOD IConvertible.ToType(conversionType AS System.Type, provider AS System.IFormatProvider) AS OBJECT
				IF conversionType == TYPEOF(STRING)
					RETURN SELF:ToString("")
				ENDIF
				THROW NotImplementedException{}

		    METHOD IConvertible.ToString(provider AS System.IFormatProvider) AS STRING
			    RETURN SELF:ToString("")

        #endregion
        */
    END STRUCTURE

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.Text
USING System.Runtime.InteropServices
USING System.Runtime.CompilerServices
USING System.Diagnostics
USING System.Runtime.Serialization
#pragma options ("az", on)
BEGIN NAMESPACE XSharp
    // use explicit layout so we can compact the size into 12 bytes
    // Type is Immutable, so has no settable properties
    /// Internal type that implements the FoxPro Compatible BINARY type.

    /// This type has many operators and implicit converters that normally are never directly called from user code.
    /// The data in this type is stored as an array of Bytes

    /// Conversions from and to String are supported and they use the current active windows codepage.
    ///
    [Serializable];
    PUBLIC STRUCTURE __Binary IMPLEMENTS IFormattable, ;
        IComparable<__Binary>, ;
        IEquatable<__Binary>, ;
        IComparable,           ;
        ISerializable

        [DebuggerBrowsable(DebuggerBrowsableState.Never)];
        PRIVATE INITONLY _value AS BYTE[]

        #region constructors
        /// <include file="RTComments.xml" path="Comments/Constructor/*" />
        /// <param name="b">Byte[] value that has the bytes that define the binary</param>
        [DebuggerStepThroughAttribute] [MethodImpl(MethodImplOptions.AggressiveInlining)];
        CONSTRUCTOR (b as Byte[])
            IF b == NULL
                THROW NullError()
            ENDIF
            SELF:_value    := b

        PRIVATE STATIC METHOD NullError() as Error
            VAR err			 := Error{ArgumentException{}}
            err:Gencode		 := Gencode.EG_ARG
            err:ArgNum		 := 1
            err:FuncSym		 := "Binary.ctor"
            err:Description  := "Argument cannot be null"
            err:Args         := <OBJECT> {NULL}
            return err

        PRIVATE CONSTRUCTOR( lhs as byte[], rhs as byte[])
            var len := lhs:Length + rhs:Length
            var result := byte[]{len}
            System.Array.Copy(lhs, result, lhs:Length)
            System.Array.Copy(rhs, 0, result,lhs:Length, rhs:Length)
            _value := result

        #endregion
        #region Properties
        /// Binary value as array of Bytes
        PROPERTY @@Value    AS Byte[]
            GET
                var len    := _value:Length
                var result := byte[]{len}
                System.Array.Copy(_value, result, len)
                return result
            END GET
        END PROPERTY
        PROPERTY Length     AS LONG GET iif(_value == NULL, 0, _value:Length)
        #endregion

        #region Equality Operators
        /// <inheritdoc />
        OVERRIDE METHOD Equals(rhs AS OBJECT  ) AS LOGIC
            LOCAL result AS LOGIC
            IF rhs != NULL .AND. rhs IS __Binary
                result := SELF:Equals( (__Binary) rhs)
            ELSE
                result := FALSE
            ENDIF
            RETURN result

        /// <inheritdoc />
        METHOD Equals(rhs AS __Binary ) AS LOGIC
            IF SELF:Length != rhs:Length
                RETURN FALSE
            ENDIF
            FOR VAR i := 0 to SELF:Length-1
                IF SELF:Value[i] != rhs:Value[i]
                    RETURN FALSE
                ENDIF
            NEXT
            RETURN TRUE

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

            /// <exclude />
        METHOD GetTypeCode() AS TypeCode
            RETURN TypeCode.Object

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

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

        #region Comparison Operators
        /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR >(lhs AS __Binary, rhs AS __Binary) AS LOGIC
            var len := Math.Min(lhs:Length,rhs:Length)
            var res := RuntimeState.StringCompare(lhs:Value, rhs:Value, len)
            if res > 0
                return TRUE
            elseif res < 0
                return FALSE
            endif
            RETURN lhs:Length > rhs:Length

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR <(lhs AS __Binary, rhs AS __Binary) AS LOGIC
            var len := Math.Min(lhs:Length,rhs:Length)
            var res := RuntimeState.StringCompare(lhs:Value, rhs:Value, len)
            if res < 0
                return TRUE
            elseif res > 0
                return FALSE
            endif
            RETURN lhs:Length < rhs:Length

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR >=(lhs AS __Binary, rhs AS __Binary) AS LOGIC
            var len := Math.Min(lhs:Length,rhs:Length)
            var res := RuntimeState.StringCompare(lhs:Value, rhs:Value, len)
            if res > 0
                return TRUE
            elseif res < 0
                return FALSE
            endif
            RETURN lhs:Length >= rhs:Length

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR <=(lhs AS __Binary, rhs AS __Binary) AS LOGIC
            var len := Math.Min(lhs:Length,rhs:Length)
            var res := RuntimeState.StringCompare(lhs:Value, rhs:Value, len)
            if res < 0
                return TRUE
            elseif res > 0
                return FALSE
            endif
            RETURN lhs:Length <= rhs:Length

            #endregion

        #region Implicit Converters
        /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(b AS BYTE[]) AS __Binary
            RETURN __Binary{b}

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(b AS __Binary) AS BYTE[]
            RETURN b:Value

        /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(bytes AS __Binary) AS STRING
            RETURN RuntimeState.WinEncoding:GetString(bytes:Value)

        /// <include file="RTComments.xml" path="Comments/Operator/*" />
        [DebuggerStepThroughAttribute];
        STATIC OPERATOR IMPLICIT(s AS STRING) AS __Binary
            RETURN __Binary{ RuntimeState.WinEncoding:GetBytes(s) }

            #endregion

        #region Numeric Operators

            /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR+(lhs AS __Binary, rhs AS __Binary) AS __Binary
            return __Binary{lhs:Value, rhs:Value}

        /// <include file="RTComments.xml" path="Comments/Operator/*" />
        OPERATOR+(lhs AS __Binary, rhs AS STRING) AS __Binary
            return __Binary{lhs:Value, RuntimeState.WinEncoding:GetBytes(rhs)}

        OPERATOR+(lhs AS STRING, rhs AS __Binary) AS STRING
            var sb := StringBuilder{}
            sb:Append(lhs)
            sb:Append(RuntimeState.WinEncoding:GetString(rhs))
            RETURN sb:ToString()

        #endregion
        #region Unary Operators

            #endregion
        #region Add and Subtract
        /// <exclude />
        METHOD Add(rhs AS __Binary) AS __Binary
            RETURN SELF + rhs

        /// <inheritdoc />
        PUBLIC METHOD CompareTo(rhs AS __Binary) AS INT
            var len := Math.Min(SELF:Length,rhs:Length)
            for var i := 0 to len-1
                if SELF:Value[i] > rhs:Value[i]
                    return 1
                ELSEIF SELF:Value[i] < rhs:Value[i]
                    return -1
                ENDIF
            next
            if SELF:Length > rhs:Length
                RETURN 1
            ELSEIF SELF:Length < rhs:Length
                return -1
            ENDIF
            RETURN 0
            /// <inheritdoc />
        PUBLIC METHOD CompareTo(rhs AS OBJECT) AS INT
            RETURN SELF:CompareTo( (__Binary) rhs)
            #endregion

        #region IFormattable
        /// <inheritdoc />
        PUBLIC OVERRIDE METHOD ToString() AS STRING
            RETURN SELF:ToString("")

        /// <inheritdoc cref="System.Double.ToString"/>
        PUBLIC METHOD ToString(sFormat AS STRING) AS STRING
            if sFormat == "G"
                return RuntimeState:WinEncoding:GetString(self:Value)
            endif
            var sb := StringBuilder{}
            sb:Append("0h")
            foreach var b in self:Value
                sb:Append(b:ToString("X2"))
            next
            return sb:ToString()
            /// <inheritdoc />
        PUBLIC METHOD ToString(format AS STRING, provider AS System.IFormatProvider) AS STRING
            RETURN SELF:ToString(format)
            #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 := NULL
            VAR s := info:GetString("Value")
            IF s:ToLower():StartsWith("0h")
                _value := BYTE[]{(s:Length -2)/2} // subtract 2 for 0h
                LOCAL current := 0 AS INT
                FOR VAR i := 2 TO s:Length-1 STEP 2
                    VAR nibble := s:Substring(i,2)
                    _value[current] := Val("0x"+nibble)
                    current += 1
                NEXT
            ENDIF
        #endregion
        /*
        #region IConvertible
			// forward most methods to the DateTime class so there will
			// be a proper (localized) error message
			/// <inheritdoc />
			METHOD IConvertible.ToBoolean(provider AS System.IFormatProvider) AS LOGIC
				THROW NotImplementedException{}

			/// <inheritdoc />
			METHOD IConvertible.ToByte(provider AS System.IFormatProvider) AS BYTE
				THROW NotImplementedException{}

			/// <inheritdoc />
			METHOD IConvertible.ToChar(provider AS System.IFormatProvider) AS CHAR
				THROW NotImplementedException{}

			/// <inheritdoc />
			METHOD IConvertible.ToDateTime(provider AS System.IFormatProvider) AS System.DateTime
				THROW NotImplementedException{}

			/// <inheritdoc />
			METHOD IConvertible.ToDecimal(provider AS System.IFormatProvider) AS DECIMAL
				THROW NotImplementedException{}

			/// <inheritdoc />
			METHOD IConvertible.ToDouble(provider AS System.IFormatProvider) AS REAL8
				THROW NotImplementedException{}

			/// <inheritdoc />
			METHOD IConvertible.ToInt16(provider AS System.IFormatProvider) AS SHORT
				THROW NotImplementedException{}

			/// <inheritdoc />
			METHOD IConvertible.ToInt32(provider AS System.IFormatProvider) AS LONG
				THROW NotImplementedException{}

			/// <inheritdoc />
			METHOD IConvertible.ToInt64(provider AS System.IFormatProvider) AS INT64
				THROW NotImplementedException{}

			/// <inheritdoc />
			METHOD IConvertible.ToSByte(provider AS System.IFormatProvider) AS SByte
				THROW NotImplementedException{}

			/// <inheritdoc />
			METHOD IConvertible.ToSingle(provider AS System.IFormatProvider) AS REAL4
				THROW NotImplementedException{}

			/// <inheritdoc />
			METHOD IConvertible.ToUInt16(provider AS System.IFormatProvider) AS WORD
				THROW NotImplementedException{}

			/// <inheritdoc />
			METHOD IConvertible.ToUInt32(provider AS System.IFormatProvider) AS DWORD
				THROW NotImplementedException{}

			/// <inheritdoc />
			METHOD IConvertible.ToUInt64(provider AS System.IFormatProvider) AS UINT64
				THROW NotImplementedException{}

            METHOD IConvertible.ToType(conversionType AS System.Type, provider AS System.IFormatProvider) AS OBJECT
				IF conversionType == TYPEOF(STRING)
					RETURN SELF:ToString("")
				ENDIF
				THROW NotImplementedException{}

		    METHOD IConvertible.ToString(provider AS System.IFormatProvider) AS STRING
			    RETURN SELF:ToString("")

        #endregion
        */
    END STRUCTURE

END NAMESPACE


QtScript: data for code generation updated

Modified:
codegen/QtScript/QScriptEngine.prg

%%
%% Qt4xHb - Bindings libraries for Harbour/xHarbour and Qt Framework 4
%%
%% Copyright (C) 2018 Marcos Antonio Gambeta <marcosgambeta AT outlook DOT com>
%%

$header

#include "hbclass.ch"

#ifndef QT4XHB_NO_REQUESTS
REQUEST QSCRIPTENGINEAGENT
REQUEST QSCRIPTCONTEXT
REQUEST QSCRIPTVALUE
REQUEST QSCRIPTSTRING
REQUEST QSCRIPTSYNTAXCHECKRESULT
#endif

CLASS QScriptEngine INHERIT QObject

   METHOD new
   METHOD delete
   METHOD abortEvaluation
   METHOD agent
   METHOD availableExtensions
   METHOD clearExceptions
   METHOD collectGarbage
   METHOD currentContext
   METHOD defaultPrototype
   METHOD evaluate
   METHOD globalObject
   METHOD hasUncaughtException
   METHOD importExtension
   METHOD importedExtensions
   METHOD installTranslatorFunctions
   METHOD isEvaluating
   METHOD newArray
   METHOD newRegExp
   METHOD newVariant
   METHOD nullValue
   METHOD popContext
   METHOD processEventsInterval
   METHOD pushContext
   METHOD reportAdditionalMemoryCost
   METHOD setAgent
   METHOD setDefaultPrototype
   METHOD setGlobalObject
   METHOD setProcessEventsInterval
   METHOD toObject
   METHOD toStringHandle
   METHOD uncaughtException
   METHOD uncaughtExceptionBacktrace
   METHOD uncaughtExceptionLineNumber
   METHOD undefinedValue
   METHOD checkSyntax

   METHOD onSignalHandlerException

   DESTRUCTOR destroyObject

END CLASS

$destructor

#pragma BEGINDUMP

$includes

#include <QStringList>

$prototype=QScriptEngine ()
$internalConstructor=|new1|

$prototype=QScriptEngine ( QObject * parent )
$internalConstructor=|new2|QObject *

//[1]QScriptEngine ()
//[2]QScriptEngine ( QObject * parent )

HB_FUNC_STATIC( QSCRIPTENGINE_NEW )
{
  if( ISNUMPAR(0) )
  {
    QScriptEngine_new1();
  }
  else if( ISNUMPAR(1) && ISQOBJECT(1) )
  {
    QScriptEngine_new2();
  }
  else
  {
    hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
  }
}

$deleteMethod

$prototype=void abortEvaluation ( const QScriptValue & result = QScriptValue() )
$method=|void|abortEvaluation|const QScriptValue &=QScriptValue()

$prototype=QScriptEngineAgent * agent () const
$method=|QScriptEngineAgent *|agent|

$prototype=QStringList availableExtensions () const
$method=|QStringList|availableExtensions|

$prototype=void clearExceptions ()
$method=|void|clearExceptions|

$prototype=void collectGarbage ()
$method=|void|collectGarbage|

$prototype=QScriptContext * currentContext () const
$method=|QScriptContext *|currentContext|

$prototype=QScriptValue defaultPrototype ( int metaTypeId ) const
$method=|QScriptValue|defaultPrototype|int

$prototype=QScriptValue evaluate ( const QString & program, const QString & fileName = QString(), int lineNumber = 1 )
$internalMethod=|QScriptValue|evaluate,evaluate1|const QString &,const QString &=QString(),int=1

$prototype=QScriptValue evaluate ( const QScriptProgram & program )
$internalMethod=|QScriptValue|evaluate,evaluate2|const QScriptProgram &

//[1]QScriptValue evaluate ( const QString & program, const QString & fileName = QString(), int lineNumber = 1 )
//[2]QScriptValue evaluate ( const QScriptProgram & program )

HB_FUNC_STATIC( QSCRIPTENGINE_EVALUATE )
{
  if( ISBETWEEN(1,3) && ISCHAR(1) && (ISCHAR(2)||ISNIL(2)) && (ISNUM(3)||ISNUM(3)) )
  {
    QScriptEngine_evaluate1();
  }
  else if( ISNUMPAR(1) && ISQSCRIPTPROGRAM(1) )
  {
    QScriptEngine_evaluate2();
  }
  else
  {
    hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
  }
}

$prototype=QScriptValue globalObject () const
$method=|QScriptValue|globalObject|

$prototype=bool hasUncaughtException () const
$method=|bool|hasUncaughtException|

$prototype=QScriptValue importExtension ( const QString & extension )
$method=|QScriptValue|importExtension|const QString &

$prototype=QStringList importedExtensions () const
$method=|QStringList|importedExtensions|

$prototype=void installTranslatorFunctions ( const QScriptValue & object = QScriptValue() )
$method=|void|installTranslatorFunctions|const QScriptValue &=QScriptValue()

$prototype=bool isEvaluating () const
$method=|bool|isEvaluating|

$prototype=QScriptValue newArray ( uint length = 0 )
$method=|QScriptValue|newArray|uint=0

$prototype=QScriptValue newRegExp ( const QRegExp & regexp )
$internalMethod=|QScriptValue|newRegExp,newRegExp1|const QRegExp &

$prototype=QScriptValue newRegExp ( const QString & pattern, const QString & flags )
$internalMethod=|QScriptValue|newRegExp,newRegExp2|const QString &,const QString &

//[1]QScriptValue newRegExp ( const QRegExp & regexp )
//[2]QScriptValue newRegExp ( const QString & pattern, const QString & flags )

HB_FUNC_STATIC( QSCRIPTENGINE_NEWREGEXP )
{
  if( ISNUMPAR(1) && ISQREGEXP(1) )
  {
    QScriptEngine_newRegExp1();
  }
  else if( ISNUMPAR(2) && ISCHAR(1) && ISCHAR(2) )
  {
    QScriptEngine_newRegExp2();
  }
  else
  {
    hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
  }
}

$prototype=QScriptValue newVariant ( const QVariant & value )
$internalMethod=|QScriptValue|newVariant,newVariant1|const QVariant &

$prototype=QScriptValue newVariant ( const QScriptValue & object, const QVariant & value )
$internalMethod=|QScriptValue|newVariant,newVariant2|const QScriptValue &,const QVariant &

//[1]QScriptValue newVariant ( const QVariant & value )
//[2]QScriptValue newVariant ( const QScriptValue & object, const QVariant & value )

HB_FUNC_STATIC( QSCRIPTENGINE_NEWVARIANT )
{
  if( ISNUMPAR(1) && ISQVARIANT(1) )
  {
    QScriptEngine_newVariant1();
  }
  else if( ISNUMPAR(2) && ISQSCRIPTVALUE(1) && ISQVARIANT(2) )
  {
    QScriptEngine_newVariant2();
  }
  else
  {
    hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
  }
}

$prototype=QScriptValue nullValue ()
$method=|QScriptValue|nullValue|

$prototype=void popContext ()
$method=|void|popContext|

$prototype=int processEventsInterval () const
$method=|int|processEventsInterval|

$prototype=QScriptContext * pushContext ()
$method=|QScriptContext *|pushContext|

$prototype=void reportAdditionalMemoryCost ( int size )
$method=|void|reportAdditionalMemoryCost|int

$prototype=void setAgent ( QScriptEngineAgent * agent )
$method=|void|setAgent|QScriptEngineAgent *

$prototype=void setDefaultPrototype ( int metaTypeId, const QScriptValue & prototype )
$method=|void|setDefaultPrototype|int,const QScriptValue &

$prototype=void setGlobalObject ( const QScriptValue & object )
$method=|void|setGlobalObject|const QScriptValue &

$prototype=void setProcessEventsInterval ( int interval )
$method=|void|setProcessEventsInterval|int

$prototype=QScriptValue toObject ( const QScriptValue & value )
$method=|QScriptValue|toObject|const QScriptValue &

$prototype=QScriptString toStringHandle ( const QString & str )
$method=|QScriptString|toStringHandle|const QString &

$prototype=QScriptValue uncaughtException () const
$method=|QScriptValue|uncaughtException|

$prototype=QStringList uncaughtExceptionBacktrace () const
$method=|QStringList|uncaughtExceptionBacktrace|

$prototype=int uncaughtExceptionLineNumber () const
$method=|int|uncaughtExceptionLineNumber|

$prototype=QScriptValue undefinedValue ()
$method=|QScriptValue|undefinedValue|

$prototype=static QScriptSyntaxCheckResult checkSyntax ( const QString & program )
$staticMethod=|QScriptSyntaxCheckResult|checkSyntax|const QString &

$beginSignals
$signal=|signalHandlerException(QScriptValue)
$endSignals

#pragma ENDDUMP

%%
%% Qt4xHb - Bindings libraries for Harbour/xHarbour and Qt Framework 4
%%
%% Copyright (C) 2018 Marcos Antonio Gambeta <marcosgambeta AT outlook DOT com>
%%

$header

#include "hbclass.ch"

#ifndef QT4XHB_NO_REQUESTS
REQUEST QSCRIPTENGINEAGENT
REQUEST QSCRIPTCONTEXT
REQUEST QSCRIPTVALUE
REQUEST QSCRIPTSTRING
REQUEST QSCRIPTSYNTAXCHECKRESULT
#endif

CLASS QScriptEngine INHERIT QObject

   METHOD new
   METHOD delete
   METHOD abortEvaluation
   METHOD agent
   METHOD availableExtensions
   METHOD clearExceptions
   METHOD collectGarbage
   METHOD currentContext
   METHOD defaultPrototype
   METHOD evaluate
   METHOD globalObject
   METHOD hasUncaughtException
   METHOD importExtension
   METHOD importedExtensions
   METHOD installTranslatorFunctions
   METHOD isEvaluating
   METHOD newArray
   METHOD newRegExp
   METHOD newVariant
   METHOD nullValue
   METHOD popContext
   METHOD processEventsInterval
   METHOD pushContext
   METHOD reportAdditionalMemoryCost
   METHOD setAgent
   METHOD setDefaultPrototype
   METHOD setGlobalObject
   METHOD setProcessEventsInterval
   METHOD toObject
   METHOD toStringHandle
   METHOD uncaughtException
   METHOD uncaughtExceptionBacktrace
   METHOD uncaughtExceptionLineNumber
   METHOD undefinedValue
   METHOD checkSyntax

   METHOD onSignalHandlerException

   DESTRUCTOR destroyObject

END CLASS

$destructor

#pragma BEGINDUMP

$includes

#include <QStringList>

$prototype=QScriptEngine ()
$internalConstructor=|new1|

$prototype=QScriptEngine ( QObject * parent )
$internalConstructor=|new2|QObject *

//[1]QScriptEngine ()
//[2]QScriptEngine ( QObject * parent )

HB_FUNC_STATIC( QSCRIPTENGINE_NEW )
{
  if( ISNUMPAR(0) )
  {
    QScriptEngine_new1();
  }
  else if( ISNUMPAR(1) && ISQOBJECT(1) )
  {
    QScriptEngine_new2();
  }
  else
  {
    hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
  }
}

$deleteMethod

$prototype=void abortEvaluation ( const QScriptValue & result = QScriptValue() )
$method=|void|abortEvaluation|const QScriptValue &=QScriptValue()

$prototype=QScriptEngineAgent * agent () const
$method=|QScriptEngineAgent *|agent|

$prototype=QStringList availableExtensions () const
$method=|QStringList|availableExtensions|

$prototype=void clearExceptions ()
$method=|void|clearExceptions|

$prototype=void collectGarbage ()
$method=|void|collectGarbage|

$prototype=QScriptContext * currentContext () const
$method=|QScriptContext *|currentContext|

$prototype=QScriptValue defaultPrototype ( int metaTypeId ) const
$method=|QScriptValue|defaultPrototype|int

$prototype=QScriptValue evaluate ( const QString & program, const QString & fileName = QString(), int lineNumber = 1 )
$internalMethod=|QScriptValue|evaluate,evaluate1|const QString &,const QString &=QString(),int=1

$prototype=QScriptValue evaluate ( const QScriptProgram & program )
$internalMethod=|QScriptValue|evaluate,evaluate2|const QScriptProgram &

//[1]QScriptValue evaluate ( const QString & program, const QString & fileName = QString(), int lineNumber = 1 )
//[2]QScriptValue evaluate ( const QScriptProgram & program )

HB_FUNC_STATIC( QSCRIPTENGINE_EVALUATE )
{
  if( ISBETWEEN(1,3) && ISCHAR(1) && (ISCHAR(2)||ISNIL(2)) && (ISNUM(3)||ISNUM(3)) )
  {
    QScriptEngine_evaluate1();
  }
  else if( ISNUMPAR(1) && ISQSCRIPTPROGRAM(1) )
  {
    QScriptEngine_evaluate2();
  }
  else
  {
    hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
  }
}

$prototype=QScriptValue globalObject () const
$method=|QScriptValue|globalObject|

$prototype=bool hasUncaughtException () const
$method=|bool|hasUncaughtException|

$prototype=QScriptValue importExtension ( const QString & extension )
$method=|QScriptValue|importExtension|const QString &

$prototype=QStringList importedExtensions () const
$method=|QStringList|importedExtensions|

$prototype=void installTranslatorFunctions ( const QScriptValue & object = QScriptValue() )
$method=|void|installTranslatorFunctions|const QScriptValue &=QScriptValue()

$prototype=bool isEvaluating () const
$method=|bool|isEvaluating|

$prototype=QScriptValue newArray ( uint length = 0 )
$method=|QScriptValue|newArray|uint=0

$prototype=QScriptValue newRegExp ( const QRegExp & regexp )
$internalMethod=|QScriptValue|newRegExp,newRegExp1|const QRegExp &

$prototype=QScriptValue newRegExp ( const QString & pattern, const QString & flags )
$internalMethod=|QScriptValue|newRegExp,newRegExp2|const QString &,const QString &

//[1]QScriptValue newRegExp ( const QRegExp & regexp )
//[2]QScriptValue newRegExp ( const QString & pattern, const QString & flags )

HB_FUNC_STATIC( QSCRIPTENGINE_NEWREGEXP )
{
  if( ISNUMPAR(1) && ISQREGEXP(1) )
  {
    QScriptEngine_newRegExp1();
  }
  else if( ISNUMPAR(2) && ISCHAR(1) && ISCHAR(2) )
  {
    QScriptEngine_newRegExp2();
  }
  else
  {
    hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
  }
}

$prototype=QScriptValue newVariant ( const QVariant & value )
$internalMethod=|QScriptValue|newVariant,newVariant1|const QVariant &

$prototype=QScriptValue newVariant ( const QScriptValue & object, const QVariant & value )
$internalMethod=|QScriptValue|newVariant,newVariant2|const QScriptValue &,const QVariant &

//[1]QScriptValue newVariant ( const QVariant & value )
//[2]QScriptValue newVariant ( const QScriptValue & object, const QVariant & value )

HB_FUNC_STATIC( QSCRIPTENGINE_NEWVARIANT )
{
  if( ISNUMPAR(1) && ISQVARIANT(1) )
  {
    QScriptEngine_newVariant1();
  }
  else if( ISNUMPAR(2) && ISQSCRIPTVALUE(1) && ISQVARIANT(2) )
  {
    QScriptEngine_newVariant2();
  }
  else
  {
    hb_errRT_BASE( EG_ARG, 3012, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );
  }
}

$prototype=QScriptValue nullValue ()
$method=|QScriptValue|nullValue|

$prototype=void popContext ()
$method=|void|popContext|

$prototype=int processEventsInterval () const
$method=|int|processEventsInterval|

$prototype=QScriptContext * pushContext ()
$method=|QScriptContext *|pushContext|

$prototype=void reportAdditionalMemoryCost ( int size )
$method=|void|reportAdditionalMemoryCost|int

$prototype=void setAgent ( QScriptEngineAgent * agent )
$method=|void|setAgent|QScriptEngineAgent *

$prototype=void setDefaultPrototype ( int metaTypeId, const QScriptValue & prototype )
$method=|void|setDefaultPrototype|int,const QScriptValue &

$prototype=void setGlobalObject ( const QScriptValue & object )
$method=|void|setGlobalObject|const QScriptValue &

$prototype=void setProcessEventsInterval ( int interval )
$method=|void|setProcessEventsInterval|int

$prototype=QScriptValue toObject ( const QScriptValue & value )
$method=|QScriptValue|toObject|const QScriptValue &

$prototype=QScriptString toStringHandle ( const QString & str )
$method=|QScriptString|toStringHandle|const QString &

$prototype=QScriptValue uncaughtException () const
$method=|QScriptValue|uncaughtException|

$prototype=QStringList uncaughtExceptionBacktrace () const
$method=|QStringList|uncaughtExceptionBacktrace|

$prototype=int uncaughtExceptionLineNumber () const
$method=|int|uncaughtExceptionLineNumber|

$prototype=QScriptValue undefinedValue ()
$method=|QScriptValue|undefinedValue|

$prototype=static QScriptSyntaxCheckResult checkSyntax ( const QString & program )
$staticMethod=|QScriptSyntaxCheckResult|checkSyntax|const QString &

$beginSignals
$signalMethod=|signalHandlerException(QScriptValue)
$endSignals

#pragma ENDDUMP