From 08890eabe13e975511e43c73be9f6dfa50f32600 Mon Sep 17 00:00:00 2001 From: Eka Puji Widiyanto Date: Tue, 22 May 2018 08:18:41 +0700 Subject: [PATCH] Upload superobject demo Delphi 7 --- Project1.cfg | 35 + Project1.dof | 125 + Project1.dpr | 17 + Project1.exe | Bin 0 -> 430080 bytes Project1.res | Bin 0 -> 876 bytes Unit1.dcu | Bin 0 -> 4778 bytes Unit1.dfm | 25 + Unit1.pas | 49 + superdate.dcu | Bin 0 -> 16035 bytes superdate.pas | 1035 +++++++ superobject.dcu | Bin 0 -> 112536 bytes superobject.pas | 6609 ++++++++++++++++++++++++++++++++++++++++++++ supertypes.dcu | Bin 0 -> 573 bytes supertypes.pas | 38 + superxmlparser.dcu | Bin 0 -> 23166 bytes superxmlparser.pas | 1474 ++++++++++ 16 files changed, 9407 insertions(+) create mode 100644 Project1.cfg create mode 100644 Project1.dof create mode 100644 Project1.dpr create mode 100644 Project1.exe create mode 100644 Project1.res create mode 100644 Unit1.dcu create mode 100644 Unit1.dfm create mode 100644 Unit1.pas create mode 100644 superdate.dcu create mode 100644 superdate.pas create mode 100644 superobject.dcu create mode 100644 superobject.pas create mode 100644 supertypes.dcu create mode 100644 supertypes.pas create mode 100644 superxmlparser.dcu create mode 100644 superxmlparser.pas diff --git a/Project1.cfg b/Project1.cfg new file mode 100644 index 0000000..d7e0bf8 --- /dev/null +++ b/Project1.cfg @@ -0,0 +1,35 @@ +-$A8 +-$B- +-$C+ +-$D+ +-$E- +-$F- +-$G+ +-$H+ +-$I+ +-$J- +-$K- +-$L+ +-$M- +-$N+ +-$O+ +-$P+ +-$Q- +-$R- +-$S- +-$T- +-$U- +-$V+ +-$W- +-$X+ +-$YD +-$Z1 +-cg +-AWinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; +-H+ +-W+ +-M +-$M16384,1048576 +-K$00400000 +-LE"c:\program files (x86)\borland\delphi7\Projects\Bpl" +-LN"c:\program files (x86)\borland\delphi7\Projects\Bpl" diff --git a/Project1.dof b/Project1.dof new file mode 100644 index 0000000..c24444a --- /dev/null +++ b/Project1.dof @@ -0,0 +1,125 @@ +[FileVersion] +Version=7.0 +[Compiler] +A=8 +B=0 +C=1 +D=1 +E=0 +F=0 +G=1 +H=1 +I=1 +J=0 +K=0 +L=1 +M=0 +N=1 +O=1 +P=1 +Q=0 +R=0 +S=0 +T=0 +U=0 +V=1 +W=0 +X=1 +Y=1 +Z=1 +ShowHints=1 +ShowWarnings=1 +UnitAliases=WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;DbiErrs=BDE; +NamespacePrefix= +SymbolDeprecated=1 +SymbolLibrary=1 +SymbolPlatform=1 +UnitLibrary=1 +UnitPlatform=1 +UnitDeprecated=1 +HResultCompat=1 +HidingMember=1 +HiddenVirtual=1 +Garbage=1 +BoundsError=1 +ZeroNilCompat=1 +StringConstTruncated=1 +ForLoopVarVarPar=1 +TypedConstVarPar=1 +AsgToTypedConst=1 +CaseLabelRange=1 +ForVariable=1 +ConstructingAbstract=1 +ComparisonFalse=1 +ComparisonTrue=1 +ComparingSignedUnsigned=1 +CombiningSignedUnsigned=1 +UnsupportedConstruct=1 +FileOpen=1 +FileOpenUnitSrc=1 +BadGlobalSymbol=1 +DuplicateConstructorDestructor=1 +InvalidDirective=1 +PackageNoLink=1 +PackageThreadVar=1 +ImplicitImport=1 +HPPEMITIgnored=1 +NoRetVal=1 +UseBeforeDef=1 +ForLoopVarUndef=1 +UnitNameMismatch=1 +NoCFGFileFound=1 +MessageDirective=1 +ImplicitVariants=1 +UnicodeToLocale=1 +LocaleToUnicode=1 +ImagebaseMultiple=1 +SuspiciousTypecast=1 +PrivatePropAccessor=1 +UnsafeType=1 +UnsafeCode=1 +UnsafeCast=1 +[Linker] +MapFile=0 +OutputObjs=0 +ConsoleApp=1 +DebugInfo=0 +RemoteSymbols=0 +MinStackSize=16384 +MaxStackSize=1048576 +ImageBase=4194304 +ExeDescription= +[Directories] +OutputDir= +UnitOutputDir= +PackageDLLOutputDir= +PackageDCPOutputDir= +SearchPath= +Packages=vcl;rtl;dbrtl;inet;inetdb;dsnap;bdertl;vclx;vcldb;vcldbx;visualclx;visualdbclx;vclactnband;vclshlctrls;vclie;xmlrtl;inetdbbde;inetdbxpress;webdsnap;soaprtl;websnap;adortl;dbexpress;dsnapcon;dbxcds;ibxpress;teeui;teedb;tee;dss;VclSmp;qrpt;teeqr;Rave50CLX;Rave50VCL;IntrawebDB_50_70;Intraweb_50_70;VclNewlyext;SUIPackD7;OpenWirePkgD7;SignalLabBasicPkgD7;SignalLabAdditionalPkgD7;UserLabBasicPkgD7;InstrumentLabPkgD7;BMThreadDsnD7;BMThreadPkgD7;CPortLib7 +Conditionals= +DebugSourceDirs= +UsePackages=0 +[Parameters] +RunParams= +HostApplication= +Launcher= +UseLauncher=0 +DebugCWD= +[Language] +ActiveLang= +ProjectLang= +RootDir=C:\Program Files (x86)\Borland\Delphi7\Bin\ +[Version Info] +IncludeVerInfo=0 +AutoIncBuild=0 +MajorVer=1 +MinorVer=0 +Release=0 +Build=0 +Debug=0 +PreRelease=0 +Special=0 +Private=0 +DLL=0 +Locale=1057 +CodePage=1252 diff --git a/Project1.dpr b/Project1.dpr new file mode 100644 index 0000000..7b09157 --- /dev/null +++ b/Project1.dpr @@ -0,0 +1,17 @@ +program Project1; + +uses + Forms, + Unit1 in 'Unit1.pas' {Form1}, + superdate in 'superdate.pas', + superobject in 'superobject.pas', + supertypes in 'supertypes.pas', + superxmlparser in 'superxmlparser.pas'; + +{$R *.res} + +begin + Application.Initialize; + Application.CreateForm(TForm1, Form1); + Application.Run; +end. diff --git a/Project1.exe b/Project1.exe new file mode 100644 index 0000000000000000000000000000000000000000..da432401a0035c291bceb4692478ad2d1e2e19b5 GIT binary patch literal 430080 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

#quF)oHFj9@gr^&TZbqfP`GVze-eZvwxu%9-?F= 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ξ@STg@DM%~X3$D&G#a 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 literal 0 HcmV?d00001 diff --git a/Unit1.dcu b/Unit1.dcu new file mode 100644 index 0000000000000000000000000000000000000000..1893622aea582805fe827d95aa22ad0a6828e677 GIT binary patch literal 4778 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 literal 0 HcmV?d00001 diff --git a/superdate.pas b/superdate.pas new file mode 100644 index 0000000..66ba49b --- /dev/null +++ b/superdate.pas @@ -0,0 +1,1035 @@ +unit superdate; + +{$IFDEF FPC} + {$MODE OBJFPC}{$H+} +{$ENDIF} + +interface + +uses + Windows, supertypes; + +function JavaToDelphiDateTime(const dt: Int64): TDateTime; +function DelphiToJavaDateTime(const dt: TDateTime): Int64; + +function DelphiDateTimeToISO8601Date(dt: TDateTime): SOString; +function DelphiDateTimeToISO8601DateWithTimeZone(dt: TDateTime; tzi: PTimeZoneInformation): SOString; + +function ISO8601DateToJavaDateTime(const str: SOString; var ms: Int64): Boolean; +function ISO8601DateToDelphiDateTime(const str: SOString; var dt: TDateTime): Boolean; + +implementation + +uses + Registry, SysUtils, DateUtils, Math; + +function GetTimeZoneInformationForYear(Year: Word; Dummy: Pointer; var TimeZoneInformation: TTimeZoneInformation): Boolean; +type + TRegistryTZI = packed record + Bias: LongInt; + StandardBias: LongInt; + DaylightBias: LongInt; + StandardChangeTime: TSystemTime; + DaylightChangeTime: TSystemTime; + end; +var + tzi: TRegistryTZI; + ChangeYear: Word; + LocalTimeZone: string; + KeyName: string; +const + TZ_TZI_KEY = '\SYSTEM\CurrentControlSet\Control\TimeZoneInformation'; { Vista and + } + TZ_KEY = '\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\'; + TZ_KEYNAME = 'TimeZoneKeyName'; +begin + FillChar(TimeZoneInformation, SizeOf(TimeZoneInformation), 0); + with TRegistry.Create do + try + RootKey := HKEY_LOCAL_MACHINE; + + if OpenKeyReadOnly(TZ_TZI_KEY) and ValueExists(TZ_KEYNAME) then + LocalTimeZone := Trim(ReadString(TZ_KEYNAME)) + else + begin + { Windows XP } + CloseKey; + RootKey := HKEY_CURRENT_USER; + if OpenKeyReadOnly(TZ_KEY) and ValueExists(TZ_KEYNAME) then + begin + LocalTimeZone := Trim(ReadString(TZ_KEYNAME)); + CloseKey; + RootKey := HKEY_LOCAL_MACHINE; + end + else + begin + Result := False; + Exit; + end; + end; + + if KeyExists(TZ_KEY + LocalTimeZone) then + KeyName := TZ_KEY + LocalTimeZone + else + begin + Result := False; + Exit; + end; + + ChangeYear := 0; + if OpenKeyReadOnly(KeyName + '\Dynamic DST') then + try + ChangeYear := Year; + if Year < ReadInteger('FirstEntry') then + ChangeYear := ReadInteger('FirstEntry') + else if Year > ReadInteger('LastEntry') then + ChangeYear := ReadInteger('LastEntry'); + + while (not ValueExists(IntToStr(ChangeYear))) and (ChangeYear > 0) do + Dec(ChangeYear); + + if ChangeYear > 0 then + ReadBinaryData(IntToStr(ChangeYear), tzi, SizeOf(TRegistryTZI)); + finally + CloseKey; + end; + + if (ChangeYear = 0) and OpenKeyReadOnly(KeyName) then + try + ReadBinaryData('TZI', tzi, SizeOf(TRegistryTZI)); + finally + CloseKey; + end; + + TimeZoneInformation.Bias := tzi.Bias; + TimeZoneInformation.StandardDate := tzi.StandardChangeTime; + TimeZoneInformation.StandardBias := tzi.StandardBias; + TimeZoneInformation.DaylightDate := tzi.DaylightChangeTime; + TimeZoneInformation.DaylightBias := tzi.DaylightBias; + + Result := True; + finally + Free; + end; +end; + +function DayLightCompareDate(const date: PSystemTime; + const compareDate: PSystemTime): Integer; +var + limit_day, dayinsecs, weekofmonth: Integer; + First: Word; +begin + if (date^.wMonth < compareDate^.wMonth) then + begin + Result := -1; (* We are in a month before the date limit. *) + Exit; + end; + + if (date^.wMonth > compareDate^.wMonth) then + begin + Result := 1; (* We are in a month after the date limit. *) + Exit; + end; + + (* if year is 0 then date is in day-of-week format, otherwise + * it's absolute date. + *) + if (compareDate^.wYear = 0) then + begin + (* compareDate.wDay is interpreted as number of the week in the month + * 5 means: the last week in the month *) + weekofmonth := compareDate^.wDay; + (* calculate the day of the first DayOfWeek in the month *) + First := (6 + compareDate^.wDayOfWeek - date^.wDayOfWeek + date^.wDay) mod 7 + 1; + limit_day := First + 7 * (weekofmonth - 1); + (* check needed for the 5th weekday of the month *) + if (limit_day > MonthDays[(date^.wMonth=2) and IsLeapYear(date^.wYear)][date^.wMonth]) then + dec(limit_day, 7); + end + else + limit_day := compareDate^.wDay; + + (* convert to seconds *) + limit_day := ((limit_day * 24 + compareDate^.wHour) * 60 + compareDate^.wMinute ) * 60; + dayinsecs := ((date^.wDay * 24 + date^.wHour) * 60 + date^.wMinute ) * 60 + date^.wSecond; + (* and compare *) + + if dayinsecs < limit_day then + Result := -1 else + if dayinsecs > limit_day then + Result := 1 else + Result := 0; (* date is equal to the date limit. *) +end; + +function CompTimeZoneID(const pTZinfo: PTimeZoneInformation; + lpFileTime: PFileTime; islocal: Boolean): LongWord; +var + ret: Integer; + beforeStandardDate, afterDaylightDate: Boolean; + llTime: Int64; + SysTime: TSystemTime; + ftTemp: TFileTime; +begin + llTime := 0; + + if (pTZinfo^.DaylightDate.wMonth <> 0) then + begin + (* if year is 0 then date is in day-of-week format, otherwise + * it's absolute date. + *) + if ((pTZinfo^.StandardDate.wMonth = 0) or + ((pTZinfo^.StandardDate.wYear = 0) and + ((pTZinfo^.StandardDate.wDay < 1) or + (pTZinfo^.StandardDate.wDay > 5) or + (pTZinfo^.DaylightDate.wDay < 1) or + (pTZinfo^.DaylightDate.wDay > 5)))) then + begin + SetLastError(ERROR_INVALID_PARAMETER); + Result := TIME_ZONE_ID_INVALID; + Exit; + end; + + if (not islocal) then + begin + llTime := PInt64(lpFileTime)^; + dec(llTime, Int64(pTZinfo^.Bias + pTZinfo^.DaylightBias) * 600000000); + PInt64(@ftTemp)^ := llTime; + lpFileTime := @ftTemp; + end; + + FileTimeToSystemTime(lpFileTime^, SysTime); + + (* check for daylight savings *) + ret := DayLightCompareDate(@SysTime, @pTZinfo^.StandardDate); + if (ret = -2) then + begin + Result := TIME_ZONE_ID_INVALID; + Exit; + end; + + beforeStandardDate := ret < 0; + + if (not islocal) then + begin + dec(llTime, Int64(pTZinfo^.StandardBias - pTZinfo^.DaylightBias) * 600000000); + PInt64(@ftTemp)^ := llTime; + FileTimeToSystemTime(lpFileTime^, SysTime); + end; + + ret := DayLightCompareDate(@SysTime, @pTZinfo^.DaylightDate); + if (ret = -2) then + begin + Result := TIME_ZONE_ID_INVALID; + Exit; + end; + + afterDaylightDate := ret >= 0; + + Result := TIME_ZONE_ID_STANDARD; + if( pTZinfo^.DaylightDate.wMonth < pTZinfo^.StandardDate.wMonth ) then + begin + (* Northern hemisphere *) + if( beforeStandardDate and afterDaylightDate) then + Result := TIME_ZONE_ID_DAYLIGHT; + end else (* Down south *) + if( beforeStandardDate or afterDaylightDate) then + Result := TIME_ZONE_ID_DAYLIGHT; + end else + (* No transition date *) + Result := TIME_ZONE_ID_UNKNOWN; +end; + +function GetTimezoneBias(const pTZinfo: PTimeZoneInformation; + lpFileTime: PFileTime; islocal: Boolean; pBias: PLongint): Boolean; +var + bias: LongInt; + tzid: LongWord; +begin + bias := pTZinfo^.Bias; + tzid := CompTimeZoneID(pTZinfo, lpFileTime, islocal); + + if( tzid = TIME_ZONE_ID_INVALID) then + begin + Result := False; + Exit; + end; + if (tzid = TIME_ZONE_ID_DAYLIGHT) then + inc(bias, pTZinfo^.DaylightBias) + else if (tzid = TIME_ZONE_ID_STANDARD) then + inc(bias, pTZinfo^.StandardBias); + pBias^ := bias; + Result := True; +end; + +function SystemTimeToTzSpecificLocalTime( + lpTimeZoneInformation: PTimeZoneInformation; + lpUniversalTime, lpLocalTime: PSystemTime): BOOL; +var + ft: TFileTime; + lBias: LongInt; + llTime: Int64; + tzinfo: TTimeZoneInformation; +begin + if (lpTimeZoneInformation <> nil) then + tzinfo := lpTimeZoneInformation^ else + if not GetTimeZoneInformationForYear(lpUniversalTime^.wYear, nil, tzinfo) then + begin + Result := False; + Exit; + end; + + if (not SystemTimeToFileTime(lpUniversalTime^, ft)) then + begin + Result := False; + Exit; + end; + llTime := PInt64(@ft)^; + if (not GetTimezoneBias(@tzinfo, @ft, False, @lBias)) then + begin + Result := False; + Exit; + end; + (* convert minutes to 100-nanoseconds-ticks *) + dec(llTime, Int64(lBias) * 600000000); + PInt64(@ft)^ := llTime; + Result := FileTimeToSystemTime(ft, lpLocalTime^); +end; + +function TzSpecificLocalTimeToSystemTime( + const lpTimeZoneInformation: PTimeZoneInformation; + const lpLocalTime: PSystemTime; lpUniversalTime: PSystemTime): BOOL; +var + ft: TFileTime; + lBias: LongInt; + t: Int64; + tzinfo: TTimeZoneInformation; +begin + if (lpTimeZoneInformation <> nil) then + tzinfo := lpTimeZoneInformation^ + else + if not GetTimeZoneInformationForYear(lpLocalTime^.wYear, nil, tzinfo) then + begin + Result := False; + Exit; + end; + + if (not SystemTimeToFileTime(lpLocalTime^, ft)) then + begin + Result := False; + Exit; + end; + t := PInt64(@ft)^; + if (not GetTimezoneBias(@tzinfo, @ft, True, @lBias)) then + begin + Result := False; + Exit; + end; + (* convert minutes to 100-nanoseconds-ticks *) + inc(t, Int64(lBias) * 600000000); + PInt64(@ft)^ := t; + Result := FileTimeToSystemTime(ft, lpUniversalTime^); +end; + +function JavaToDelphiDateTime(const dt: Int64): TDateTime; +var + utc, local: TSystemTime; + tzi: TTimeZoneInformation; +begin + DateTimeToSystemTime(25569 + (dt / 86400000), utc); + if GetTimeZoneInformationForYear(utc.wYear, nil, tzi) and + SystemTimeToTzSpecificLocalTime(@tzi, @utc, @local) then + Result := SystemTimeToDateTime(local) + else + Result := SystemTimeToDateTime(utc); +end; + +function DelphiToJavaDateTime(const dt: TDateTime): Int64; +var + local, utc, st: TSystemTime; + tzi: TTimeZoneInformation; +begin + DateTimeToSystemTime(dt, local); + if GetTimeZoneInformationForYear(local.wYear, nil, tzi) and + TzSpecificLocalTimeToSystemTime(@tzi, @local, @utc) then + st := utc + else + st := local; + Result := Round((SystemTimeToDateTime(st) - 25569) * 86400000); +end; + +function DelphiDateTimeToISO8601Date(dt: TDateTime): SOString; +begin + Result := DelphiDateTimeToISO8601DateWithTimeZone(dt, nil); +end; + +function DelphiDateTimeToISO8601DateWithTimeZone(dt: TDateTime; tzi: PTimeZoneInformation): SOString; +const + ISO_Fmt = '%.4d-%.2d-%.2dT%.2d:%.2d:%.2d.%d'; + TZ_Fmt = '%s%.2d:%.2d'; +var + local, utc: TSystemTime; + ttzi: TTimeZoneInformation; + bias: TDateTime; + h, m, d: Word; + iso: string; +begin + DateTimeToSystemTime(dt, local); + iso := Format(ISO_Fmt, [ + local.wYear, local.wMonth, local.wDay, + local.wHour, local.wMinute, local.wSecond, local.wMilliseconds + ]); + if (tzi = nil) and GetTimeZoneInformationForYear(local.wYear, nil, ttzi) then + tzi := @ttzi; + if (tzi <> nil) and TzSpecificLocalTimeToSystemTime(tzi, @local, @utc) then + begin + bias := SystemTimeToDateTime(local) - SystemTimeToDateTime(utc); + DecodeTime(bias, h, m, d, d); + case Sign(bias) of + -1: Result := iso + Format(TZ_Fmt, [ '-', h, m ]); + 0: Result := iso + 'Z'; + +1: Result := iso + Format(TZ_Fmt, [ '+', h, m ]); + end; + end + else + Result := iso; +end; + + +{ iso -> java } + +function ISO8601DateToJavaDateTime(const str: SOString; var ms: Int64): Boolean; +type + TState = ( + stStart, stYear, stMonth, stWeek, stWeekDay, stDay, stDayOfYear, + stHour, stMin, stSec, stMs, stUTC, stGMTH, stGMTM, + stGMTend, stEnd); + TPerhaps = (yes, no, perhaps); +var + p: PSOChar; + state: TState; + pos, v: Word; + sep: TPerhaps; + inctz, havetz, havedate: Boolean; + st: TSystemTime; + dayofyear: Integer; + week: Word; + bias: Integer; + DayTable: PDayTable; + tzi: TTimeZoneInformation; + utc: TSystemTime; + + function get(var v: Word; c: SOChar): Boolean; {$IFDEF HAVE_INLINE} inline;{$ENDIF} + begin + if (c < #256) and (AnsiChar(c) in ['0'..'9']) then + begin + Result := True; + v := v * 10 + Ord(c) - Ord('0'); + end else + Result := False; + end; + +label + error; +begin + p := PSOChar(str); + sep := perhaps; + state := stStart; + pos := 0; + FillChar(st, SizeOf(st), 0); + dayofyear := 0; + bias := 0; + week := 0; + havedate := True; + inctz := False; + havetz := False; + + while true do + case state of + stStart: + case p^ of + '0'..'9': state := stYear; + 'T', 't': + begin + state := stHour; + pos := 0; + inc(p); + havedate := False; + end; + else + goto error; + end; + stYear: + case pos of + 0..1,3: + if get(st.wYear, p^) then + begin + Inc(pos); + Inc(p); + end else + goto error; + 2: case p^ of + '0'..'9': + begin + st.wYear := st.wYear * 10 + ord(p^) - ord('0'); + Inc(pos); + Inc(p); + end; + ':': + begin + havedate := false; + st.wHour := st.wYear; + st.wYear := 0; + inc(p); + pos := 0; + state := stMin; + sep := yes; + end; + else + goto error; + end; + 4: case p^ of + '-': begin + pos := 0; + Inc(p); + sep := yes; + state := stMonth; + end; + '0'..'9': + begin + sep := no; + pos := 0; + state := stMonth; + end; + 'W', 'w' : + begin + pos := 0; + Inc(p); + state := stWeek; + end; + 'T', 't', ' ': + begin + state := stHour; + pos := 0; + inc(p); + st.wMonth := 1; + st.wDay := 1; + end; + #0: + begin + st.wMonth := 1; + st.wDay := 1; + state := stEnd; + end; + else + goto error; + end; + end; + stMonth: + case pos of + 0: case p^ of + '0'..'9': + begin + st.wMonth := ord(p^) - ord('0'); + Inc(pos); + Inc(p); + end; + 'W', 'w': + begin + pos := 0; + Inc(p); + state := stWeek; + end; + else + goto error; + end; + 1: if get(st.wMonth, p^) then + begin + Inc(pos); + Inc(p); + end else + goto error; + 2: case p^ of + '-': + if (sep in [yes, perhaps]) then + begin + pos := 0; + Inc(p); + state := stDay; + sep := yes; + end else + goto error; + '0'..'9': + if sep in [no, perhaps] then + begin + pos := 0; + state := stDay; + sep := no; + end else + begin + dayofyear := st.wMonth * 10 + Ord(p^) - Ord('0'); + st.wMonth := 0; + inc(p); + pos := 3; + state := stDayOfYear; + end; + 'T', 't', ' ': + begin + state := stHour; + pos := 0; + inc(p); + st.wDay := 1; + end; + #0: + begin + st.wDay := 1; + state := stEnd; + end; + else + goto error; + end; + end; + stDay: + case pos of + 0: if get(st.wDay, p^) then + begin + Inc(pos); + Inc(p); + end else + goto error; + 1: if get(st.wDay, p^) then + begin + Inc(pos); + Inc(p); + end else + if sep in [no, perhaps] then + begin + dayofyear := st.wMonth * 10 + st.wDay; + st.wDay := 0; + st.wMonth := 0; + state := stDayOfYear; + end else + goto error; + + 2: case p^ of + 'T', 't', ' ': + begin + pos := 0; + Inc(p); + state := stHour; + end; + #0: state := stEnd; + else + goto error; + end; + end; + stDayOfYear: + begin + if (dayofyear <= 0) then goto error; + case p^ of + 'T', 't', ' ': + begin + pos := 0; + Inc(p); + state := stHour; + end; + #0: state := stEnd; + else + goto error; + end; + end; + stWeek: + begin + case pos of + 0..1: if get(week, p^) then + begin + inc(pos); + inc(p); + end else + goto error; + 2: case p^ of + '-': if (sep in [yes, perhaps]) then + begin + Inc(p); + state := stWeekDay; + sep := yes; + end else + goto error; + '1'..'7': + if sep in [no, perhaps] then + begin + state := stWeekDay; + sep := no; + end else + goto error; + else + goto error; + end; + end; + end; + stWeekDay: + begin + if (week > 0) and get(st.wDayOfWeek, p^) then + begin + inc(p); + v := st.wYear - 1; + v := ((v * 365) + (v div 4) - (v div 100) + (v div 400)) mod 7 + 1; + dayofyear := (st.wDayOfWeek - v) + ((week) * 7) + 1; + if v <= 4 then dec(dayofyear, 7); + case p^ of + 'T', 't', ' ': + begin + pos := 0; + Inc(p); + state := stHour; + end; + #0: state := stEnd; + else + goto error; + end; + end else + goto error; + end; + stHour: + case pos of + 0: case p^ of + '0'..'9': + if get(st.wHour, p^) then + begin + inc(pos); + inc(p); + end else + goto error; + '-': + begin + inc(p); + state := stMin; + end; + else + goto error; + end; + 1: if get(st.wHour, p^) then + begin + inc(pos); + inc(p); + end else + goto error; + 2: case p^ of + ':': if sep in [yes, perhaps] then + begin + sep := yes; + pos := 0; + Inc(p); + state := stMin; + end else + goto error; + ',', '.': + begin + Inc(p); + state := stMs; + end; + '+': + if havedate then + begin + state := stGMTH; + pos := 0; + v := 0; + inc(p); + end else + goto error; + '-': + if havedate then + begin + state := stGMTH; + pos := 0; + v := 0; + inc(p); + inctz := True; + end else + goto error; + 'Z', 'z': + if havedate then + state := stUTC else + goto error; + '0'..'9': + if sep in [no, perhaps] then + begin + pos := 0; + state := stMin; + sep := no; + end else + goto error; + #0: state := stEnd; + else + goto error; + end; + end; + stMin: + case pos of + 0: case p^ of + '0'..'9': + if get(st.wMinute, p^) then + begin + inc(pos); + inc(p); + end else + goto error; + '-': + begin + inc(p); + state := stSec; + end; + else + goto error; + end; + 1: if get(st.wMinute, p^) then + begin + inc(pos); + inc(p); + end else + goto error; + 2: case p^ of + ':': if sep in [yes, perhaps] then + begin + pos := 0; + Inc(p); + state := stSec; + sep := yes; + end else + goto error; + ',', '.': + begin + Inc(p); + state := stMs; + end; + '+': + if havedate then + begin + state := stGMTH; + pos := 0; + v := 0; + inc(p); + end else + goto error; + '-': + if havedate then + begin + state := stGMTH; + pos := 0; + v := 0; + inc(p); + inctz := True; + end else + goto error; + 'Z', 'z': + if havedate then + state := stUTC else + goto error; + '0'..'9': + if sep in [no, perhaps] then + begin + pos := 0; + state := stSec; + end else + goto error; + #0: state := stEnd; + else + goto error; + end; + end; + stSec: + case pos of + 0..1: if get(st.wSecond, p^) then + begin + inc(pos); + inc(p); + end else + goto error; + 2: case p^ of + ',', '.': + begin + Inc(p); + state := stMs; + end; + '+': + if havedate then + begin + state := stGMTH; + pos := 0; + v := 0; + inc(p); + end else + goto error; + '-': + if havedate then + begin + state := stGMTH; + pos := 0; + v := 0; + inc(p); + inctz := True; + end else + goto error; + 'Z', 'z': + if havedate then + state := stUTC else + goto error; + #0: state := stEnd; + else + goto error; + end; + end; + stMs: + case p^ of + '0'..'9': + begin + st.wMilliseconds := st.wMilliseconds * 10 + ord(p^) - ord('0'); + inc(p); + end; + '+': + if havedate then + begin + state := stGMTH; + pos := 0; + v := 0; + inc(p); + end else + goto error; + '-': + if havedate then + begin + state := stGMTH; + pos := 0; + v := 0; + inc(p); + inctz := True; + end else + goto error; + 'Z', 'z': + if havedate then + state := stUTC else + goto error; + #0: state := stEnd; + else + goto error; + end; + stUTC: // = GMT 0 + begin + havetz := True; + inc(p); + if p^ = #0 then + Break else + goto error; + end; + stGMTH: + begin + havetz := True; + case pos of + 0..1: if get(v, p^) then + begin + inc(p); + inc(pos); + end else + goto error; + 2: + begin + bias := v * 60; + case p^ of + ':': //if sep in [yes, perhaps] then + begin + state := stGMTM; + inc(p); + pos := 0; + v := 0; + sep := yes; + end; // else goto error; + '0'..'9': + //if sep in [no, perhaps] then + begin + state := stGMTM; + pos := 1; + sep := no; + inc(p); + v := ord(p^) - ord('0'); + end; // else goto error; + #0: state := stGMTend; + else + goto error; + end; + + end; + end; + end; + stGMTM: + case pos of + 0..1: if get(v, p^) then + begin + inc(p); + inc(pos); + end else + goto error; + 2: case p^ of + #0: + begin + state := stGMTend; + inc(bias, v); + end; + else + goto error; + end; + end; + stGMTend: + begin + if not inctz then + bias := -bias; + Break; + end; + stEnd: + begin + + Break; + end; + end; + + if (st.wHour >= 24) or (st.wMinute >= 60) or (st.wSecond >= 60) or (st.wMilliseconds >= 1000) or (week > 53) + then goto error; + + if not havetz then + begin + if GetTimeZoneInformationForYear(st.wYear, nil, tzi) and + TzSpecificLocalTimeToSystemTime(@tzi, @st, @utc) then + bias := Trunc((SystemTimeToDateTime(st) - SystemTimeToDateTime(utc)) * MinsPerDay); + end; + + ms := st.wMilliseconds + st.wSecond * 1000 + (st.wMinute + bias) * 60000 + st.wHour * 3600000; + if havedate then + begin + DayTable := @MonthDays[IsLeapYear(st.wYear)]; + if st.wMonth <> 0 then + begin + if not (st.wMonth in [1..12]) or (DayTable^[st.wMonth] < st.wDay) then + goto error; + + for v := 1 to st.wMonth - 1 do + Inc(ms, Int64(DayTable^[v]) * 86400000); + end; + dec(st.wYear); + + Inc(ms, (Int64((st.wYear * 365) + (st.wYear div 4) - (st.wYear div 100) + (st.wYear div 400) + + st.wDay + dayofyear - 719163) * 86400000)); + end; + + Result := True; + Exit; +error: + Result := False; +end; + +function ISO8601DateToDelphiDateTime(const str: SOString; var dt: TDateTime): Boolean; +var + ms: Int64; +begin + Result := ISO8601DateToJavaDateTime(str, ms); + if Result then + dt := JavaToDelphiDateTime(ms) +end; + +end. diff --git a/superobject.dcu b/superobject.dcu new file mode 100644 index 0000000000000000000000000000000000000000..b5fd6fb109374f14e539b9873b0bd8a1df3a8992 GIT binary patch literal 112536 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 a2@c#BJFwk>--*`1MFsCjoT1|{^Zx-4|I+XP literal 0 HcmV?d00001 diff --git a/superobject.pas b/superobject.pas new file mode 100644 index 0000000..8e51858 --- /dev/null +++ b/superobject.pas @@ -0,0 +1,6609 @@ +(* + * Super Object Toolkit + * + * Usage allowed under the restrictions of the Lesser GNU General Public License + * or alternatively the restrictions of the Mozilla Public License 1.1 + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for + * the specific language governing rights and limitations under the License. + * + * Embarcadero Technologies Inc is not permitted to use or redistribute + * this source code without explicit permission. + * + * Unit owner : Henri Gourvest + * Web site : http://www.progdigy.com + * + * This unit is inspired from the json c lib: + * Michael Clark + * http://oss.metaparadigm.com/json-c/ + * + * CHANGES: + * v1.2 + * + support of currency data type + * + right trim unquoted string + * + read Unicode Files and streams (Litle Endian with BOM) + * + Fix bug on javadate functions + windows nt compatibility + * + Now you can force to parse only the canonical syntax of JSON using the stric parameter + * + Delphi 2010 RTTI marshalling + * v1.1 + * + Double licence MPL or LGPL. + * + Delphi 2009 compatibility & Unicode support. + * + AsString return a string instead of PChar. + * + Escaped and Unascaped JSON serialiser. + * + Missed FormFeed added \f + * - Removed @ trick, uses forcepath() method instead. + * + Fixed parse error with uppercase E symbol in numbers. + * + Fixed possible buffer overflow when enlarging array. + * + Added "delete", "pack", "insert" methods for arrays and/or objects + * + Multi parametters when calling methods + * + Delphi Enumerator (for obj1 in obj2 do ...) + * + Format method ex: obj.format('<%name%>%tab[1]%') + * + ParseFile and ParseStream methods + * + Parser now understand hexdecimal c syntax ex: \xFF + * + Null Object Design Patern (ex: for obj in values.N['path'] do ...) + * v1.0 + * + renamed class + * + interfaced object + * + added a new data type: the method + * + parser can now evaluate properties and call methods + * - removed obselet rpc class + * - removed "find" method, now you can use "parse" method instead + * v0.6 + * + refactoring + * v0.5 + * + new find method to get or set value using a path syntax + * ex: obj.s['obj.prop[1]'] := 'string value'; + * obj.a['@obj.array'].b[n] := true; // @ -> create property if necessary + * v0.4 + * + bug corrected: AVL tree badly balanced. + * v0.3 + * + New validator partially based on the Kwalify syntax. + * + extended syntax to parse unquoted fields. + * + Freepascal compatibility win32/64 Linux32/64. + * + JavaToDelphiDateTime and DelphiToJavaDateTime improved for UTC. + * + new TJsonObject.Compare function. + * v0.2 + * + Hashed string list replaced with a faster AVL tree + * + JsonInt data type can be changed to int64 + * + JavaToDelphiDateTime and DelphiToJavaDateTime helper fonctions + * + from json-c v0.7 + * + Add escaping of backslash to json output + * + Add escaping of foward slash on tokenizing and output + * + Changes to internal tokenizer from using recursion to + * using a depth state structure to allow incremental parsing + * v0.1 + * + first release + *) + +{$IFDEF FPC} + {$MODE OBJFPC}{$H+} +{$ENDIF} + +{$DEFINE SUPER_METHOD} +{.$DEFINE DEBUG} // track memory leack + + +{$if defined(FPC) or defined(VER170) or defined(VER180) or defined(VER190) + or defined(VER200) or defined(VER210) or defined(VER220) or defined(VER230) + or defined(VER240) or defined(VER250) or defined(VER260)} + {$DEFINE HAVE_INLINE} +{$ifend} + +{$if defined(VER210) or defined(VER220) or defined(VER230) or defined(VER240) + or defined(VER250) or defined(VER260)} + {$define HAVE_RTTI} +{$ifend} + +{$if defined(VER230) or defined(VER240) or defined(VER250) or defined(VER260)} + {$define NEED_FORMATSETTINGS} +{$ifend} + +{$if defined(FPC) and defined(VER2_6)} + {$define NEED_FORMATSETTINGS} +{$ifend} + +{$OVERFLOWCHECKS OFF} +{$RANGECHECKS OFF} + +unit superobject; + +interface +uses + Classes, supertypes +{$IFDEF HAVE_RTTI} + ,Generics.Collections, RTTI, TypInfo +{$ENDIF} + ; + +const + SUPER_ARRAY_LIST_DEFAULT_SIZE = 32; + SUPER_TOKENER_MAX_DEPTH = 32; + + SUPER_AVL_MAX_DEPTH = sizeof(longint) * 8; + SUPER_AVL_MASK_HIGH_BIT = not ((not longword(0)) shr 1); + +type + // forward declarations + TSuperObject = class; + ISuperObject = interface; + TSuperArray = class; + +(* AVL Tree + * This is a "special" autobalanced AVL tree + * It use a hash value for fast compare + *) + +{$IFDEF SUPER_METHOD} + TSuperMethod = procedure(const This, Params: ISuperObject; var Result: ISuperObject); +{$ENDIF} + + + TSuperAvlBitArray = set of 0..SUPER_AVL_MAX_DEPTH - 1; + + TSuperAvlSearchType = (stEQual, stLess, stGreater); + TSuperAvlSearchTypes = set of TSuperAvlSearchType; + TSuperAvlIterator = class; + + TSuperAvlEntry = class + private + FGt, FLt: TSuperAvlEntry; + FBf: integer; + FHash: Cardinal; + FName: SOString; + FPtr: Pointer; + function GetValue: ISuperObject; + procedure SetValue(const val: ISuperObject); + public + class function Hash(const k: SOString): Cardinal; virtual; + constructor Create(const AName: SOString; Obj: Pointer); virtual; + property Name: SOString read FName; + property Ptr: Pointer read FPtr; + property Value: ISuperObject read GetValue write SetValue; + end; + + TSuperAvlTree = class + private + FRoot: TSuperAvlEntry; + FCount: Integer; + function balance(bal: TSuperAvlEntry): TSuperAvlEntry; + protected + procedure doDeleteEntry(Entry: TSuperAvlEntry; all: boolean); virtual; + function CompareNodeNode(node1, node2: TSuperAvlEntry): integer; virtual; + function CompareKeyNode(const k: SOString; h: TSuperAvlEntry): integer; virtual; + function Insert(h: TSuperAvlEntry): TSuperAvlEntry; virtual; + function Search(const k: SOString; st: TSuperAvlSearchTypes = [stEqual]): TSuperAvlEntry; virtual; + public + constructor Create; virtual; + destructor Destroy; override; + function IsEmpty: boolean; + procedure Clear(all: boolean = false); virtual; + procedure Pack(all: boolean); + function Delete(const k: SOString): ISuperObject; + function GetEnumerator: TSuperAvlIterator; + property count: Integer read FCount; + end; + + TSuperTableString = class(TSuperAvlTree) + protected + procedure doDeleteEntry(Entry: TSuperAvlEntry; all: boolean); override; + procedure PutO(const k: SOString; const value: ISuperObject); + function GetO(const k: SOString): ISuperObject; + procedure PutS(const k: SOString; const value: SOString); + function GetS(const k: SOString): SOString; + procedure PutI(const k: SOString; value: SuperInt); + function GetI(const k: SOString): SuperInt; + procedure PutD(const k: SOString; value: Double); + function GetD(const k: SOString): Double; + procedure PutB(const k: SOString; value: Boolean); + function GetB(const k: SOString): Boolean; +{$IFDEF SUPER_METHOD} + procedure PutM(const k: SOString; value: TSuperMethod); + function GetM(const k: SOString): TSuperMethod; +{$ENDIF} + procedure PutN(const k: SOString; const value: ISuperObject); + function GetN(const k: SOString): ISuperObject; + procedure PutC(const k: SOString; value: Currency); + function GetC(const k: SOString): Currency; + public + property O[const k: SOString]: ISuperObject read GetO write PutO; default; + property S[const k: SOString]: SOString read GetS write PutS; + property I[const k: SOString]: SuperInt read GetI write PutI; + property D[const k: SOString]: Double read GetD write PutD; + property B[const k: SOString]: Boolean read GetB write PutB; +{$IFDEF SUPER_METHOD} + property M[const k: SOString]: TSuperMethod read GetM write PutM; +{$ENDIF} + property N[const k: SOString]: ISuperObject read GetN write PutN; + property C[const k: SOString]: Currency read GetC write PutC; + + function GetValues: ISuperObject; + function GetNames: ISuperObject; + function Find(const k: SOString; var value: ISuperObject): Boolean; + function Exists(const k: SOString): Boolean; + end; + + TSuperAvlIterator = class + private + FTree: TSuperAvlTree; + FBranch: TSuperAvlBitArray; + FDepth: LongInt; + FPath: array[0..SUPER_AVL_MAX_DEPTH - 2] of TSuperAvlEntry; + public + constructor Create(tree: TSuperAvlTree); virtual; + procedure Search(const k: SOString; st: TSuperAvlSearchTypes = [stEQual]); + procedure First; + procedure Last; + function GetIter: TSuperAvlEntry; + procedure Next; + procedure Prior; + // delphi enumerator + function MoveNext: Boolean; + property Current: TSuperAvlEntry read GetIter; + end; + + TSuperObjectArray = array[0..(high(Integer) div sizeof(TSuperObject))-1] of ISuperObject; + PSuperObjectArray = ^TSuperObjectArray; + + TSuperArray = class + private + FArray: PSuperObjectArray; + FLength: Integer; + FSize: Integer; + procedure Expand(max: Integer); + protected + function GetO(const index: integer): ISuperObject; + procedure PutO(const index: integer; const Value: ISuperObject); + function GetB(const index: integer): Boolean; + procedure PutB(const index: integer; Value: Boolean); + function GetI(const index: integer): SuperInt; + procedure PutI(const index: integer; Value: SuperInt); + function GetD(const index: integer): Double; + procedure PutD(const index: integer; Value: Double); + function GetC(const index: integer): Currency; + procedure PutC(const index: integer; Value: Currency); + function GetS(const index: integer): SOString; + procedure PutS(const index: integer; const Value: SOString); +{$IFDEF SUPER_METHOD} + function GetM(const index: integer): TSuperMethod; + procedure PutM(const index: integer; Value: TSuperMethod); +{$ENDIF} + function GetN(const index: integer): ISuperObject; + procedure PutN(const index: integer; const Value: ISuperObject); + public + constructor Create; virtual; + destructor Destroy; override; + function Add(const Data: ISuperObject): Integer; overload; + function Add(Data: SuperInt): Integer; overload; + function Add(const Data: SOString): Integer; overload; + function Add(Data: Boolean): Integer; overload; + function Add(Data: Double): Integer; overload; + function AddC(const Data: Currency): Integer; + function Delete(index: Integer): ISuperObject; + procedure Insert(index: Integer; const value: ISuperObject); + procedure Clear(all: boolean = false); + procedure Pack(all: boolean); + property Length: Integer read FLength; + + property N[const index: integer]: ISuperObject read GetN write PutN; + property O[const index: integer]: ISuperObject read GetO write PutO; default; + property B[const index: integer]: boolean read GetB write PutB; + property I[const index: integer]: SuperInt read GetI write PutI; + property D[const index: integer]: Double read GetD write PutD; + property C[const index: integer]: Currency read GetC write PutC; + property S[const index: integer]: SOString read GetS write PutS; +{$IFDEF SUPER_METHOD} + property M[const index: integer]: TSuperMethod read GetM write PutM; +{$ENDIF} + end; + + TSuperWriter = class + public + // abstact methods to overide + function Append(buf: PSOChar; Size: Integer): Integer; overload; virtual; abstract; + function Append(buf: PSOChar): Integer; overload; virtual; abstract; + procedure Reset; virtual; abstract; + end; + + TSuperWriterString = class(TSuperWriter) + private + FBuf: PSOChar; + FBPos: integer; + FSize: integer; + public + function Append(buf: PSOChar; Size: Integer): Integer; overload; override; + function Append(buf: PSOChar): Integer; overload; override; + procedure Reset; override; + procedure TrimRight; + constructor Create; virtual; + destructor Destroy; override; + function GetString: SOString; + property Data: PSOChar read FBuf; + property Size: Integer read FSize; + property Position: integer read FBPos; + end; + + TSuperWriterStream = class(TSuperWriter) + private + FStream: TStream; + public + function Append(buf: PSOChar): Integer; override; + procedure Reset; override; + constructor Create(AStream: TStream); reintroduce; virtual; + end; + + TSuperAnsiWriterStream = class(TSuperWriterStream) + public + function Append(buf: PSOChar; Size: Integer): Integer; override; + end; + + TSuperUnicodeWriterStream = class(TSuperWriterStream) + public + function Append(buf: PSOChar; Size: Integer): Integer; override; + end; + + TSuperWriterFake = class(TSuperWriter) + private + FSize: Integer; + public + function Append(buf: PSOChar; Size: Integer): Integer; override; + function Append(buf: PSOChar): Integer; override; + procedure Reset; override; + constructor Create; reintroduce; virtual; + property size: integer read FSize; + end; + + TSuperWriterSock = class(TSuperWriter) + private + FSocket: longint; + FSize: Integer; + public + function Append(buf: PSOChar; Size: Integer): Integer; override; + function Append(buf: PSOChar): Integer; override; + procedure Reset; override; + constructor Create(ASocket: longint); reintroduce; virtual; + property Socket: longint read FSocket; + property Size: Integer read FSize; + end; + + TSuperTokenizerError = ( + teSuccess, + teContinue, + teDepth, + teParseEof, + teParseUnexpected, + teParseNull, + teParseBoolean, + teParseNumber, + teParseArray, + teParseObjectKeyName, + teParseObjectKeySep, + teParseObjectValueSep, + teParseString, + teParseComment, + teEvalObject, + teEvalArray, + teEvalMethod, + teEvalInt + ); + + TSuperTokenerState = ( + tsEatws, + tsStart, + tsFinish, + tsNull, + tsCommentStart, + tsComment, + tsCommentEol, + tsCommentEnd, + tsString, + tsStringEscape, + tsIdentifier, + tsEscapeUnicode, + tsEscapeHexadecimal, + tsBoolean, + tsNumber, + tsArray, + tsArrayAdd, + tsArraySep, + tsObjectFieldStart, + tsObjectField, + tsObjectUnquotedField, + tsObjectFieldEnd, + tsObjectValue, + tsObjectValueAdd, + tsObjectSep, + tsEvalProperty, + tsEvalArray, + tsEvalMethod, + tsParamValue, + tsParamPut, + tsMethodValue, + tsMethodPut + ); + + PSuperTokenerSrec = ^TSuperTokenerSrec; + TSuperTokenerSrec = record + state, saved_state: TSuperTokenerState; + obj: ISuperObject; + current: ISuperObject; + field_name: SOString; + parent: ISuperObject; + gparent: ISuperObject; + end; + + TSuperTokenizer = class + public + str: PSOChar; + pb: TSuperWriterString; + depth, is_double, floatcount, st_pos, char_offset: Integer; + err: TSuperTokenizerError; + ucs_char: Word; + quote_char: SOChar; + stack: array[0..SUPER_TOKENER_MAX_DEPTH-1] of TSuperTokenerSrec; + line, col: Integer; + public + constructor Create; virtual; + destructor Destroy; override; + procedure ResetLevel(adepth: integer); + procedure Reset; + end; + + // supported object types + TSuperType = ( + stNull, + stBoolean, + stDouble, + stCurrency, + stInt, + stObject, + stArray, + stString +{$IFDEF SUPER_METHOD} + ,stMethod +{$ENDIF} + ); + + TSuperValidateError = ( + veRuleMalformated, + veFieldIsRequired, + veInvalidDataType, + veFieldNotFound, + veUnexpectedField, + veDuplicateEntry, + veValueNotInEnum, + veInvalidLength, + veInvalidRange + ); + + TSuperFindOption = ( + foCreatePath, + foPutValue, + foDelete +{$IFDEF SUPER_METHOD} + ,foCallMethod +{$ENDIF} + ); + + TSuperFindOptions = set of TSuperFindOption; + TSuperCompareResult = (cpLess, cpEqu, cpGreat, cpError); + TSuperOnValidateError = procedure(sender: Pointer; error: TSuperValidateError; const objpath: SOString); + + TSuperEnumerator = class + private + FObj: ISuperObject; + FObjEnum: TSuperAvlIterator; + FCount: Integer; + public + constructor Create(const obj: ISuperObject); virtual; + destructor Destroy; override; + function MoveNext: Boolean; + function GetCurrent: ISuperObject; + property Current: ISuperObject read GetCurrent; + end; + + ISuperObject = interface + ['{4B86A9E3-E094-4E5A-954A-69048B7B6327}'] + function GetEnumerator: TSuperEnumerator; + function GetDataType: TSuperType; + function GetProcessing: boolean; + procedure SetProcessing(value: boolean); + function ForcePath(const path: SOString; dataType: TSuperType = stObject): ISuperObject; + function Format(const str: SOString; BeginSep: SOChar = '%'; EndSep: SOChar = '%'): SOString; + + function GetO(const path: SOString): ISuperObject; + procedure PutO(const path: SOString; const Value: ISuperObject); + function GetB(const path: SOString): Boolean; + procedure PutB(const path: SOString; Value: Boolean); + function GetI(const path: SOString): SuperInt; + procedure PutI(const path: SOString; Value: SuperInt); + function GetD(const path: SOString): Double; + procedure PutC(const path: SOString; Value: Currency); + function GetC(const path: SOString): Currency; + procedure PutD(const path: SOString; Value: Double); + function GetS(const path: SOString): SOString; + procedure PutS(const path: SOString; const Value: SOString); +{$IFDEF SUPER_METHOD} + function GetM(const path: SOString): TSuperMethod; + procedure PutM(const path: SOString; Value: TSuperMethod); +{$ENDIF} + function GetA(const path: SOString): TSuperArray; + + // Null Object Design patern + function GetN(const path: SOString): ISuperObject; + procedure PutN(const path: SOString; const Value: ISuperObject); + + // Writers + function Write(writer: TSuperWriter; indent: boolean; escape: boolean; level: integer): Integer; + function SaveTo(stream: TStream; indent: boolean = false; escape: boolean = true): integer; overload; + function SaveTo(const FileName: string; indent: boolean = false; escape: boolean = true): integer; overload; + function SaveTo(socket: longint; indent: boolean = false; escape: boolean = true): integer; overload; + function CalcSize(indent: boolean = false; escape: boolean = true): integer; + + // convert + function AsBoolean: Boolean; + function AsInteger: SuperInt; + function AsDouble: Double; + function AsCurrency: Currency; + function AsString: SOString; + function AsArray: TSuperArray; + function AsObject: TSuperTableString; +{$IFDEF SUPER_METHOD} + function AsMethod: TSuperMethod; +{$ENDIF} + function AsJSon(indent: boolean = false; escape: boolean = true): SOString; + + procedure Clear(all: boolean = false); + procedure Pack(all: boolean = false); + + property N[const path: SOString]: ISuperObject read GetN write PutN; + property O[const path: SOString]: ISuperObject read GetO write PutO; default; + property B[const path: SOString]: boolean read GetB write PutB; + property I[const path: SOString]: SuperInt read GetI write PutI; + property D[const path: SOString]: Double read GetD write PutD; + property C[const path: SOString]: Currency read GetC write PutC; + property S[const path: SOString]: SOString read GetS write PutS; +{$IFDEF SUPER_METHOD} + property M[const path: SOString]: TSuperMethod read GetM write PutM; +{$ENDIF} + property A[const path: SOString]: TSuperArray read GetA; + +{$IFDEF SUPER_METHOD} + function call(const path: SOString; const param: ISuperObject = nil): ISuperObject; overload; + function call(const path, param: SOString): ISuperObject; overload; +{$ENDIF} + + // clone a node + function Clone: ISuperObject; + function Delete(const path: SOString): ISuperObject; + // merges tow objects of same type, if reference is true then nodes are not cloned + procedure Merge(const obj: ISuperObject; reference: boolean = false); overload; + procedure Merge(const str: SOString); overload; + + // validate methods + function Validate(const rules: SOString; const defs: SOString = ''; callback: TSuperOnValidateError = nil; sender: Pointer = nil): boolean; overload; + function Validate(const rules: ISuperObject; const defs: ISuperObject = nil; callback: TSuperOnValidateError = nil; sender: Pointer = nil): boolean; overload; + + // compare + function Compare(const obj: ISuperObject): TSuperCompareResult; overload; + function Compare(const str: SOString): TSuperCompareResult; overload; + + // the data type + function IsType(AType: TSuperType): boolean; + property DataType: TSuperType read GetDataType; + property Processing: boolean read GetProcessing write SetProcessing; + + function GetDataPtr: Pointer; + procedure SetDataPtr(const Value: Pointer); + property DataPtr: Pointer read GetDataPtr write SetDataPtr; + end; + + TSuperObject = class(TObject, ISuperObject) + private + FRefCount: Integer; + FProcessing: boolean; + FDataType: TSuperType; + FDataPtr: Pointer; +{.$if true} + FO: record + case TSuperType of + stBoolean: (c_boolean: boolean); + stDouble: (c_double: double); + stCurrency: (c_currency: Currency); + stInt: (c_int: SuperInt); + stObject: (c_object: TSuperTableString); + stArray: (c_array: TSuperArray); +{$IFDEF SUPER_METHOD} + stMethod: (c_method: TSuperMethod); +{$ENDIF} + end; +{.$ifend} + FOString: SOString; + function GetDataType: TSuperType; + function GetDataPtr: Pointer; + procedure SetDataPtr(const Value: Pointer); + protected +{$IFDEF FPC} + function QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} iid: tguid; out obj): longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; +{$ELSE} + function QueryInterface(const IID: TGUID; out Obj): HResult; virtual; stdcall; +{$ENDIF} + function _AddRef: Integer; virtual; stdcall; + function _Release: Integer; virtual; stdcall; + + function GetO(const path: SOString): ISuperObject; + procedure PutO(const path: SOString; const Value: ISuperObject); + function GetB(const path: SOString): Boolean; + procedure PutB(const path: SOString; Value: Boolean); + function GetI(const path: SOString): SuperInt; + procedure PutI(const path: SOString; Value: SuperInt); + function GetD(const path: SOString): Double; + procedure PutD(const path: SOString; Value: Double); + procedure PutC(const path: SOString; Value: Currency); + function GetC(const path: SOString): Currency; + function GetS(const path: SOString): SOString; + procedure PutS(const path: SOString; const Value: SOString); +{$IFDEF SUPER_METHOD} + function GetM(const path: SOString): TSuperMethod; + procedure PutM(const path: SOString; Value: TSuperMethod); +{$ENDIF} + function GetA(const path: SOString): TSuperArray; + function Write(writer: TSuperWriter; indent: boolean; escape: boolean; level: integer): Integer; virtual; + public + function GetEnumerator: TSuperEnumerator; + procedure AfterConstruction; override; + procedure BeforeDestruction; override; + class function NewInstance: TObject; override; + property RefCount: Integer read FRefCount; + + function GetProcessing: boolean; + procedure SetProcessing(value: boolean); + + // Writers + function SaveTo(stream: TStream; indent: boolean = false; escape: boolean = true): integer; overload; + function SaveTo(const FileName: string; indent: boolean = false; escape: boolean = true): integer; overload; + function SaveTo(socket: longint; indent: boolean = false; escape: boolean = true): integer; overload; + function CalcSize(indent: boolean = false; escape: boolean = true): integer; + function AsJSon(indent: boolean = false; escape: boolean = true): SOString; + + // parser ... owned! + class function ParseString(s: PSOChar; strict: Boolean; partial: boolean = true; const this: ISuperObject = nil; options: TSuperFindOptions = []; + const put: ISuperObject = nil; dt: TSuperType = stNull): ISuperObject; + class function ParseStream(stream: TStream; strict: Boolean; partial: boolean = true; const this: ISuperObject = nil; options: TSuperFindOptions = []; + const put: ISuperObject = nil; dt: TSuperType = stNull): ISuperObject; + class function ParseFile(const FileName: string; strict: Boolean; partial: boolean = true; const this: ISuperObject = nil; options: TSuperFindOptions = []; + const put: ISuperObject = nil; dt: TSuperType = stNull): ISuperObject; + class function ParseEx(tok: TSuperTokenizer; str: PSOChar; len: integer; strict: Boolean; const this: ISuperObject = nil; + options: TSuperFindOptions = []; const put: ISuperObject = nil; dt: TSuperType = stNull): ISuperObject; + + // constructors / destructor + constructor Create(jt: TSuperType = stObject); overload; virtual; + constructor Create(b: boolean); overload; virtual; + constructor Create(i: SuperInt); overload; virtual; + constructor Create(d: double); overload; virtual; + constructor CreateCurrency(c: Currency); overload; virtual; + constructor Create(const s: SOString); overload; virtual; +{$IFDEF SUPER_METHOD} + constructor Create(m: TSuperMethod); overload; virtual; +{$ENDIF} + destructor Destroy; override; + + // convert + function AsBoolean: Boolean; virtual; + function AsInteger: SuperInt; virtual; + function AsDouble: Double; virtual; + function AsCurrency: Currency; virtual; + function AsString: SOString; virtual; + function AsArray: TSuperArray; virtual; + function AsObject: TSuperTableString; virtual; +{$IFDEF SUPER_METHOD} + function AsMethod: TSuperMethod; virtual; +{$ENDIF} + procedure Clear(all: boolean = false); virtual; + procedure Pack(all: boolean = false); virtual; + function GetN(const path: SOString): ISuperObject; + procedure PutN(const path: SOString; const Value: ISuperObject); + function ForcePath(const path: SOString; dataType: TSuperType = stObject): ISuperObject; + function Format(const str: SOString; BeginSep: SOChar = '%'; EndSep: SOChar = '%'): SOString; + + property N[const path: SOString]: ISuperObject read GetN write PutN; + property O[const path: SOString]: ISuperObject read GetO write PutO; default; + property B[const path: SOString]: boolean read GetB write PutB; + property I[const path: SOString]: SuperInt read GetI write PutI; + property D[const path: SOString]: Double read GetD write PutD; + property C[const path: SOString]: Currency read GetC write PutC; + property S[const path: SOString]: SOString read GetS write PutS; +{$IFDEF SUPER_METHOD} + property M[const path: SOString]: TSuperMethod read GetM write PutM; +{$ENDIF} + property A[const path: SOString]: TSuperArray read GetA; + + {$IFDEF SUPER_METHOD} + function call(const path: SOString; const param: ISuperObject = nil): ISuperObject; overload; virtual; + function call(const path, param: SOString): ISuperObject; overload; virtual; +{$ENDIF} + // clone a node + function Clone: ISuperObject; virtual; + function Delete(const path: SOString): ISuperObject; + // merges tow objects of same type, if reference is true then nodes are not cloned + procedure Merge(const obj: ISuperObject; reference: boolean = false); overload; + procedure Merge(const str: SOString); overload; + + // validate methods + function Validate(const rules: SOString; const defs: SOString = ''; callback: TSuperOnValidateError = nil; sender: Pointer = nil): boolean; overload; + function Validate(const rules: ISuperObject; const defs: ISuperObject = nil; callback: TSuperOnValidateError = nil; sender: Pointer = nil): boolean; overload; + + // compare + function Compare(const obj: ISuperObject): TSuperCompareResult; overload; + function Compare(const str: SOString): TSuperCompareResult; overload; + + // the data type + function IsType(AType: TSuperType): boolean; + property DataType: TSuperType read GetDataType; + // a data pointer to link to something ele, a treeview for example + property DataPtr: Pointer read GetDataPtr write SetDataPtr; + property Processing: boolean read GetProcessing; + end; + +{$IFDEF HAVE_RTTI} + TSuperRttiContext = class; + + TSerialFromJson = function(ctx: TSuperRttiContext; const obj: ISuperObject; var Value: TValue): Boolean; + TSerialToJson = function(ctx: TSuperRttiContext; var value: TValue; const index: ISuperObject): ISuperObject; + + TSuperAttribute = class(TCustomAttribute) + private + FName: string; + public + constructor Create(const AName: string); + property Name: string read FName; + end; + + SOName = class(TSuperAttribute); + SODefault = class(TSuperAttribute); + + + TSuperRttiContext = class + private + class function GetFieldName(r: TRttiField): string; + class function GetFieldDefault(r: TRttiField; const obj: ISuperObject): ISuperObject; + public + Context: TRttiContext; + SerialFromJson: TDictionary; + SerialToJson: TDictionary; + constructor Create; virtual; + destructor Destroy; override; + function FromJson(TypeInfo: PTypeInfo; const obj: ISuperObject; var Value: TValue): Boolean; virtual; + function ToJson(var value: TValue; const index: ISuperObject): ISuperObject; virtual; + function AsType(const obj: ISuperObject): T; + function AsJson(const obj: T; const index: ISuperObject = nil): ISuperObject; + end; + + TSuperObjectHelper = class helper for TObject + public + function ToJson(ctx: TSuperRttiContext = nil): ISuperObject; + constructor FromJson(const obj: ISuperObject; ctx: TSuperRttiContext = nil); overload; + constructor FromJson(const str: string; ctx: TSuperRttiContext = nil); overload; + end; +{$ENDIF} + + TSuperObjectIter = record + key: SOString; + val: ISuperObject; + Ite: TSuperAvlIterator; + end; + +function ObjectIsError(obj: TSuperObject): boolean; +function ObjectIsType(const obj: ISuperObject; typ: TSuperType): boolean; +function ObjectGetType(const obj: ISuperObject): TSuperType; +function ObjectIsNull(const obj: ISuperObject): Boolean; + +function ObjectFindFirst(const obj: ISuperObject; var F: TSuperObjectIter): boolean; +function ObjectFindNext(var F: TSuperObjectIter): boolean; +procedure ObjectFindClose(var F: TSuperObjectIter); + +function SO(const s: SOString = '{}'): ISuperObject; overload; +function SO(const value: Variant): ISuperObject; overload; +function SO(const Args: array of const): ISuperObject; overload; + +function SA(const Args: array of const): ISuperObject; overload; + +function TryObjectToDate(const obj: ISuperObject; var dt: TDateTime): Boolean; +function UUIDToString(const g: TGUID): SOString; +function StringToUUID(const str: SOString; var g: TGUID): Boolean; + +{$IFDEF HAVE_RTTI} + +type + TSuperInvokeResult = ( + irSuccess, + irMethothodError, // method don't exist + irParamError, // invalid parametters + irError // other error + ); + +function TrySOInvoke(var ctx: TSuperRttiContext; const obj: TValue; const method: string; const params: ISuperObject; var Return: ISuperObject): TSuperInvokeResult; overload; +function SOInvoke(const obj: TValue; const method: string; const params: ISuperObject; ctx: TSuperRttiContext = nil): ISuperObject; overload; +function SOInvoke(const obj: TValue; const method: string; const params: string; ctx: TSuperRttiContext = nil): ISuperObject; overload; +{$ENDIF} + +implementation +uses + sysutils, Windows, superdate +{$IFDEF FPC} + ,sockets +{$ELSE} + ,WinSock +{$ENDIF} + ; + +{$IFDEF DEBUG} +var + debugcount: integer = 0; +{$ENDIF} + +const + super_number_chars_set = ['0'..'9','.','+','-','e','E']; + super_hex_chars: PSOChar = '0123456789abcdef'; + super_hex_chars_set = ['0'..'9','a'..'f','A'..'F']; + + ESC_BS: PSOChar = '\b'; + ESC_LF: PSOChar = '\n'; + ESC_CR: PSOChar = '\r'; + ESC_TAB: PSOChar = '\t'; + ESC_FF: PSOChar = '\f'; + ESC_QUOT: PSOChar = '\"'; + ESC_SL: PSOChar = '\\'; + ESC_SR: PSOChar = '\/'; + ESC_ZERO: PSOChar = '\u0000'; + + TOK_CRLF: PSOChar = #13#10; + TOK_SP: PSOChar = #32; + TOK_BS: PSOChar = #8; + TOK_TAB: PSOChar = #9; + TOK_LF: PSOChar = #10; + TOK_FF: PSOChar = #12; + TOK_CR: PSOChar = #13; +// TOK_SL: PSOChar = '\'; +// TOK_SR: PSOChar = '/'; + TOK_NULL: PSOChar = 'null'; + TOK_CBL: PSOChar = '{'; // curly bracket left + TOK_CBR: PSOChar = '}'; // curly bracket right + TOK_ARL: PSOChar = '['; + TOK_ARR: PSOChar = ']'; + TOK_ARRAY: PSOChar = '[]'; + TOK_OBJ: PSOChar = '{}'; // empty object + TOK_COM: PSOChar = ','; // Comma + TOK_DQT: PSOChar = '"'; // Double Quote + TOK_TRUE: PSOChar = 'true'; + TOK_FALSE: PSOChar = 'false'; + +{$if (sizeof(Char) = 1)} +function StrLComp(const Str1, Str2: PSOChar; MaxLen: Cardinal): Integer; +var + P1, P2: PWideChar; + I: Cardinal; + C1, C2: WideChar; +begin + P1 := Str1; + P2 := Str2; + I := 0; + while I < MaxLen do + begin + C1 := P1^; + C2 := P2^; + + if (C1 <> C2) or (C1 = #0) then + begin + Result := Ord(C1) - Ord(C2); + Exit; + end; + + Inc(P1); + Inc(P2); + Inc(I); + end; + Result := 0; +end; + +function StrComp(const Str1, Str2: PSOChar): Integer; +var + P1, P2: PWideChar; + C1, C2: WideChar; +begin + P1 := Str1; + P2 := Str2; + while True do + begin + C1 := P1^; + C2 := P2^; + + if (C1 <> C2) or (C1 = #0) then + begin + Result := Ord(C1) - Ord(C2); + Exit; + end; + + Inc(P1); + Inc(P2); + end; +end; + +function StrLen(const Str: PSOChar): Cardinal; +var + p: PSOChar; +begin + Result := 0; + if Str <> nil then + begin + p := Str; + while p^ <> #0 do inc(p); + Result := (p - Str); + end; +end; +{$ifend} + +function FloatToJson(const value: Double): SOString; +var + p: PSOChar; +begin + Result := FloatToStr(value); + if {$if defined(NEED_FORMATSETTINGS)}FormatSettings.{$ifend}DecimalSeparator <> '.' then + begin + p := PSOChar(Result); + while p^ <> #0 do + if p^ <> SOChar({$if defined(NEED_FORMATSETTINGS)}FormatSettings.{$ifend}DecimalSeparator) then + inc(p) else + begin + p^ := '.'; + Exit; + end; + end; +end; + +function CurrToJson(const value: Currency): SOString; +var + p: PSOChar; +begin + Result := CurrToStr(value); + if {$if defined(NEED_FORMATSETTINGS)}FormatSettings.{$ifend}DecimalSeparator <> '.' then + begin + p := PSOChar(Result); + while p^ <> #0 do + if p^ <> SOChar({$if defined(NEED_FORMATSETTINGS)}FormatSettings.{$ifend}DecimalSeparator) then + inc(p) else + begin + p^ := '.'; + Exit; + end; + end; +end; + +function TryObjectToDate(const obj: ISuperObject; var dt: TDateTime): Boolean; +var + i: Int64; +begin + case ObjectGetType(obj) of + stInt: + begin + dt := JavaToDelphiDateTime(obj.AsInteger); + Result := True; + end; + stString: + begin + if ISO8601DateToJavaDateTime(obj.AsString, i) then + begin + dt := JavaToDelphiDateTime(i); + Result := True; + end else + Result := TryStrToDateTime(obj.AsString, dt); + end; + else + Result := False; + end; +end; + +function SO(const s: SOString): ISuperObject; overload; +begin + Result := TSuperObject.ParseString(PSOChar(s), False); +end; + +function SA(const Args: array of const): ISuperObject; overload; +type + TByteArray = array[0..sizeof(integer) - 1] of byte; + PByteArray = ^TByteArray; +var + j: Integer; + intf: IInterface; +begin + Result := TSuperObject.Create(stArray); + for j := 0 to length(Args) - 1 do + with Result.AsArray do + case TVarRec(Args[j]).VType of + vtInteger : Add(TSuperObject.Create(TVarRec(Args[j]).VInteger)); + vtInt64 : Add(TSuperObject.Create(TVarRec(Args[j]).VInt64^)); + vtBoolean : Add(TSuperObject.Create(TVarRec(Args[j]).VBoolean)); + vtChar : Add(TSuperObject.Create(SOString(TVarRec(Args[j]).VChar))); + vtWideChar: Add(TSuperObject.Create(SOChar(TVarRec(Args[j]).VWideChar))); + vtExtended: Add(TSuperObject.Create(TVarRec(Args[j]).VExtended^)); + vtCurrency: Add(TSuperObject.CreateCurrency(TVarRec(Args[j]).VCurrency^)); + vtString : Add(TSuperObject.Create(SOString(TVarRec(Args[j]).VString^))); + vtPChar : Add(TSuperObject.Create(SOString(TVarRec(Args[j]).VPChar^))); + vtAnsiString: Add(TSuperObject.Create(SOString(AnsiString(TVarRec(Args[j]).VAnsiString)))); + vtWideString: Add(TSuperObject.Create(SOString(PWideChar(TVarRec(Args[j]).VWideString)))); + vtInterface: + if TVarRec(Args[j]).VInterface = nil then + Add(nil) else + if IInterface(TVarRec(Args[j]).VInterface).QueryInterface(ISuperObject, intf) = 0 then + Add(ISuperObject(intf)) else + Add(nil); + vtPointer : + if TVarRec(Args[j]).VPointer = nil then + Add(nil) else + Add(TSuperObject.Create(PtrInt(TVarRec(Args[j]).VPointer))); + vtVariant: + Add(SO(TVarRec(Args[j]).VVariant^)); + vtObject: + if TVarRec(Args[j]).VPointer = nil then + Add(nil) else + Add(TSuperObject.Create(PtrInt(TVarRec(Args[j]).VPointer))); + vtClass: + if TVarRec(Args[j]).VPointer = nil then + Add(nil) else + Add(TSuperObject.Create(PtrInt(TVarRec(Args[j]).VPointer))); +{$if declared(vtUnicodeString)} + vtUnicodeString: + Add(TSuperObject.Create(SOString(string(TVarRec(Args[j]).VUnicodeString)))); +{$ifend} + else + assert(false); + end; +end; + +function SO(const Args: array of const): ISuperObject; overload; +var + j: Integer; + arr: ISuperObject; +begin + Result := TSuperObject.Create(stObject); + arr := SA(Args); + with arr.AsArray do + for j := 0 to (Length div 2) - 1 do + Result.AsObject.PutO(O[j*2].AsString, O[(j*2) + 1]); +end; + +function SO(const value: Variant): ISuperObject; overload; +begin + with TVarData(value) do + case VType of + varNull: Result := nil; + varEmpty: Result := nil; + varSmallInt: Result := TSuperObject.Create(VSmallInt); + varInteger: Result := TSuperObject.Create(VInteger); + varSingle: Result := TSuperObject.Create(VSingle); + varDouble: Result := TSuperObject.Create(VDouble); + varCurrency: Result := TSuperObject.CreateCurrency(VCurrency); + varDate: Result := TSuperObject.Create(DelphiToJavaDateTime(vDate)); + varOleStr: Result := TSuperObject.Create(SOString(VOleStr)); + varBoolean: Result := TSuperObject.Create(VBoolean); + varShortInt: Result := TSuperObject.Create(VShortInt); + varByte: Result := TSuperObject.Create(VByte); + varWord: Result := TSuperObject.Create(VWord); + varLongWord: Result := TSuperObject.Create(VLongWord); + varInt64: Result := TSuperObject.Create(VInt64); + varString: Result := TSuperObject.Create(SOString(AnsiString(VString))); +{$if declared(varUString)} + {$IFDEF FPC} + varUString: Result := TSuperObject.Create(SOString(UnicodeString(VString))); + {$ELSE} + varUString: Result := TSuperObject.Create(SOString(string(VUString))); + {$ENDIF} +{$ifend} + else + raise Exception.CreateFmt('Unsuported variant data type: %d', [VType]); + end; +end; + +function ObjectIsError(obj: TSuperObject): boolean; +begin + Result := PtrUInt(obj) > PtrUInt(-4000); +end; + +function ObjectIsType(const obj: ISuperObject; typ: TSuperType): boolean; +begin + if obj <> nil then + Result := typ = obj.DataType else + Result := typ = stNull; +end; + +function ObjectGetType(const obj: ISuperObject): TSuperType; +begin + if obj <> nil then + Result := obj.DataType else + Result := stNull; +end; + +function ObjectIsNull(const obj: ISuperObject): Boolean; +begin + Result := ObjectIsType(obj, stNull); +end; + +function ObjectFindFirst(const obj: ISuperObject; var F: TSuperObjectIter): boolean; +var + i: TSuperAvlEntry; +begin + if ObjectIsType(obj, stObject) then + begin + F.Ite := TSuperAvlIterator.Create(obj.AsObject); + F.Ite.First; + i := F.Ite.GetIter; + if i <> nil then + begin + f.key := i.Name; + f.val := i.Value; + Result := true; + end else + Result := False; + end else + Result := False; +end; + +function ObjectFindNext(var F: TSuperObjectIter): boolean; +var + i: TSuperAvlEntry; +begin + F.Ite.Next; + i := F.Ite.GetIter; + if i <> nil then + begin + f.key := i.FName; + f.val := i.Value; + Result := true; + end else + Result := False; +end; + +procedure ObjectFindClose(var F: TSuperObjectIter); +begin + F.Ite.Free; + F.val := nil; +end; + +function UuidFromString(p: PSOChar; Uuid: PGUID): Boolean; +const + hex2bin: array[48..102] of Byte = ( + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, + 0,10,11,12,13,14,15, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0,10,11,12,13,14,15); +type + TState = (stEatSpaces, stStart, stHEX, stBracket, stEnd); + TUUID = record + case byte of + 0: (guid: TGUID); + 1: (bytes: array[0..15] of Byte); + 2: (words: array[0..7] of Word); + 3: (ints: array[0..3] of Cardinal); + 4: (i64s: array[0..1] of UInt64); + end; + + function ishex(const c: SOChar): Boolean; {$IFDEF HAVE_INLINE} inline;{$ENDIF} + begin + result := (c < #256) and (AnsiChar(c) in ['0'..'9', 'a'..'z', 'A'..'Z']) + end; +var + pos: Byte; + state, saved: TState; + bracket, separator: Boolean; +label + redo; +begin + FillChar(Uuid^, SizeOf(TGUID), 0); + saved := stStart; + state := stEatSpaces; + bracket := false; + separator := false; + pos := 0; + while true do +redo: + case state of + stEatSpaces: + begin + while true do + case p^ of + ' ', #13, #10, #9: inc(p); + else + state := saved; + goto redo; + end; + end; + stStart: + case p^ of + '{': + begin + bracket := true; + inc(p); + state := stEatSpaces; + saved := stHEX; + pos := 0; + end; + else + state := stHEX; + end; + stHEX: + case pos of + 0..7: + if ishex(p^) then + begin + Uuid^.D1 := (Uuid^.D1 * 16) + hex2bin[Ord(p^)]; + inc(p); + inc(pos); + end else + begin + Result := False; + Exit; + end; + 8: + if (p^ = '-') then + begin + separator := true; + inc(p); + inc(pos) + end else + inc(pos); + 13,18,23: + if separator then + begin + if p^ <> '-' then + begin + Result := False; + Exit; + end; + inc(p); + inc(pos); + end else + inc(pos); + 9..12: + if ishex(p^) then + begin + TUUID(Uuid^).words[2] := (TUUID(Uuid^).words[2] * 16) + hex2bin[Ord(p^)]; + inc(p); + inc(pos); + end else + begin + Result := False; + Exit; + end; + 14..17: + if ishex(p^) then + begin + TUUID(Uuid^).words[3] := (TUUID(Uuid^).words[3] * 16) + hex2bin[Ord(p^)]; + inc(p); + inc(pos); + end else + begin + Result := False; + Exit; + end; + 19..20: + if ishex(p^) then + begin + TUUID(Uuid^).bytes[8] := (TUUID(Uuid^).bytes[8] * 16) + hex2bin[Ord(p^)]; + inc(p); + inc(pos); + end else + begin + Result := False; + Exit; + end; + 21..22: + if ishex(p^) then + begin + TUUID(Uuid^).bytes[9] := (TUUID(Uuid^).bytes[9] * 16) + hex2bin[Ord(p^)]; + inc(p); + inc(pos); + end else + begin + Result := False; + Exit; + end; + 24..25: + if ishex(p^) then + begin + TUUID(Uuid^).bytes[10] := (TUUID(Uuid^).bytes[10] * 16) + hex2bin[Ord(p^)]; + inc(p); + inc(pos); + end else + begin + Result := False; + Exit; + end; + 26..27: + if ishex(p^) then + begin + TUUID(Uuid^).bytes[11] := (TUUID(Uuid^).bytes[11] * 16) + hex2bin[Ord(p^)]; + inc(p); + inc(pos); + end else + begin + Result := False; + Exit; + end; + 28..29: + if ishex(p^) then + begin + TUUID(Uuid^).bytes[12] := (TUUID(Uuid^).bytes[12] * 16) + hex2bin[Ord(p^)]; + inc(p); + inc(pos); + end else + begin + Result := False; + Exit; + end; + 30..31: + if ishex(p^) then + begin + TUUID(Uuid^).bytes[13] := (TUUID(Uuid^).bytes[13] * 16) + hex2bin[Ord(p^)]; + inc(p); + inc(pos); + end else + begin + Result := False; + Exit; + end; + 32..33: + if ishex(p^) then + begin + TUUID(Uuid^).bytes[14] := (TUUID(Uuid^).bytes[14] * 16) + hex2bin[Ord(p^)]; + inc(p); + inc(pos); + end else + begin + Result := False; + Exit; + end; + 34..35: + if ishex(p^) then + begin + TUUID(Uuid^).bytes[15] := (TUUID(Uuid^).bytes[15] * 16) + hex2bin[Ord(p^)]; + inc(p); + inc(pos); + end else + begin + Result := False; + Exit; + end; + 36: if bracket then + begin + state := stEatSpaces; + saved := stBracket; + end else + begin + state := stEatSpaces; + saved := stEnd; + end; + end; + stBracket: + begin + if p^ <> '}' then + begin + Result := False; + Exit; + end; + inc(p); + state := stEatSpaces; + saved := stEnd; + end; + stEnd: + begin + if p^ <> #0 then + begin + Result := False; + Exit; + end; + Break; + end; + end; + Result := True; +end; + +function UUIDToString(const g: TGUID): SOString; +begin + Result := format('%.8x%.4x%.4x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x', + [g.D1, g.D2, g.D3, + g.D4[0], g.D4[1], g.D4[2], + g.D4[3], g.D4[4], g.D4[5], + g.D4[6], g.D4[7]]); +end; + +function StringToUUID(const str: SOString; var g: TGUID): Boolean; +begin + Result := UuidFromString(PSOChar(str), @g); +end; + +{$IFDEF HAVE_RTTI} + +function serialtoboolean(ctx: TSuperRttiContext; var value: TValue; const index: ISuperObject): ISuperObject; +begin + Result := TSuperObject.Create(TValueData(value).FAsSLong <> 0); +end; + +function serialtodatetime(ctx: TSuperRttiContext; var value: TValue; const index: ISuperObject): ISuperObject; +begin + Result := TSuperObject.Create(DelphiToJavaDateTime(TValueData(value).FAsDouble)); +end; + +function serialtoguid(ctx: TSuperRttiContext; var value: TValue; const index: ISuperObject): ISuperObject; +var + g: TGUID; +begin + value.ExtractRawData(@g); + Result := TSuperObject.Create( + format('%.8x-%.4x-%.4x-%.2x%.2x-%.2x%.2x%.2x%.2x%.2x%.2x', + [g.D1, g.D2, g.D3, + g.D4[0], g.D4[1], g.D4[2], + g.D4[3], g.D4[4], g.D4[5], + g.D4[6], g.D4[7]]) + ); +end; + +function serialfromboolean(ctx: TSuperRttiContext; const obj: ISuperObject; var Value: TValue): Boolean; +var + o: ISuperObject; +begin + case ObjectGetType(obj) of + stBoolean: + begin + TValueData(Value).FAsSLong := obj.AsInteger; + Result := True; + end; + stInt: + begin + TValueData(Value).FAsSLong := ord(obj.AsInteger <> 0); + Result := True; + end; + stString: + begin + o := SO(obj.AsString); + if not ObjectIsType(o, stString) then + Result := serialfromboolean(ctx, SO(obj.AsString), Value) else + Result := False; + end; + else + Result := False; + end; +end; + +function serialfromdatetime(ctx: TSuperRttiContext; const obj: ISuperObject; var Value: TValue): Boolean; +var + dt: TDateTime; + i: Int64; +begin + case ObjectGetType(obj) of + stInt: + begin + TValueData(Value).FAsDouble := JavaToDelphiDateTime(obj.AsInteger); + Result := True; + end; + stString: + begin + if ISO8601DateToJavaDateTime(obj.AsString, i) then + begin + TValueData(Value).FAsDouble := JavaToDelphiDateTime(i); + Result := True; + end else + if TryStrToDateTime(obj.AsString, dt) then + begin + TValueData(Value).FAsDouble := dt; + Result := True; + end else + Result := False; + end; + else + Result := False; + end; +end; + +function serialfromguid(ctx: TSuperRttiContext; const obj: ISuperObject; var Value: TValue): Boolean; +begin + case ObjectGetType(obj) of + stNull: + begin + FillChar(Value.GetReferenceToRawData^, SizeOf(TGUID), 0); + Result := True; + end; + stString: Result := UuidFromString(PSOChar(obj.AsString), Value.GetReferenceToRawData); + else + Result := False; + end; +end; + +function SOInvoke(const obj: TValue; const method: string; const params: ISuperObject; ctx: TSuperRttiContext): ISuperObject; overload; +var + owned: Boolean; +begin + if ctx = nil then + begin + ctx := TSuperRttiContext.Create; + owned := True; + end else + owned := False; + try + if TrySOInvoke(ctx, obj, method, params, Result) <> irSuccess then + raise Exception.Create('Invalid method call'); + finally + if owned then + ctx.Free; + end; +end; + +function SOInvoke(const obj: TValue; const method: string; const params: string; ctx: TSuperRttiContext): ISuperObject; overload; +begin + Result := SOInvoke(obj, method, so(params), ctx) +end; + +function TrySOInvoke(var ctx: TSuperRttiContext; const obj: TValue; + const method: string; const params: ISuperObject; + var Return: ISuperObject): TSuperInvokeResult; +var + t: TRttiInstanceType; + m: TRttiMethod; + a: TArray; + ps: TArray; + v: TValue; + index: ISuperObject; + + function GetParams: Boolean; + var + i: Integer; + begin + case ObjectGetType(params) of + stArray: + for i := 0 to Length(ps) - 1 do + if (pfOut in ps[i].Flags) then + TValue.Make(nil, ps[i].ParamType.Handle, a[i]) else + if not ctx.FromJson(ps[i].ParamType.Handle, params.AsArray[i], a[i]) then + Exit(False); + stObject: + for i := 0 to Length(ps) - 1 do + if (pfOut in ps[i].Flags) then + TValue.Make(nil, ps[i].ParamType.Handle, a[i]) else + if not ctx.FromJson(ps[i].ParamType.Handle, params.AsObject[ps[i].Name], a[i]) then + Exit(False); + stNull: ; + else + Exit(False); + end; + Result := True; + end; + + procedure SetParams; + var + i: Integer; + begin + case ObjectGetType(params) of + stArray: + for i := 0 to Length(ps) - 1 do + if (ps[i].Flags * [pfVar, pfOut]) <> [] then + params.AsArray[i] := ctx.ToJson(a[i], index); + stObject: + for i := 0 to Length(ps) - 1 do + if (ps[i].Flags * [pfVar, pfOut]) <> [] then + params.AsObject[ps[i].Name] := ctx.ToJson(a[i], index); + end; + end; + +begin + Result := irSuccess; + index := SO; + case obj.Kind of + tkClass: + begin + t := TRttiInstanceType(ctx.Context.GetType(obj.AsObject.ClassType)); + m := t.GetMethod(method); + if m = nil then Exit(irMethothodError); + ps := m.GetParameters; + SetLength(a, Length(ps)); + if not GetParams then Exit(irParamError); + if m.IsClassMethod then + begin + v := m.Invoke(obj.AsObject.ClassType, a); + Return := ctx.ToJson(v, index); + SetParams; + end else + begin + v := m.Invoke(obj, a); + Return := ctx.ToJson(v, index); + SetParams; + end; + end; + tkClassRef: + begin + t := TRttiInstanceType(ctx.Context.GetType(obj.AsClass)); + m := t.GetMethod(method); + if m = nil then Exit(irMethothodError); + ps := m.GetParameters; + SetLength(a, Length(ps)); + + if not GetParams then Exit(irParamError); + if m.IsClassMethod then + begin + v := m.Invoke(obj, a); + Return := ctx.ToJson(v, index); + SetParams; + end else + Exit(irError); + end; + else + Exit(irError); + end; +end; + +{$ENDIF} + +{ TSuperEnumerator } + +constructor TSuperEnumerator.Create(const obj: ISuperObject); +begin + FObj := obj; + FCount := -1; + if ObjectIsType(FObj, stObject) then + FObjEnum := FObj.AsObject.GetEnumerator else + FObjEnum := nil; +end; + +destructor TSuperEnumerator.Destroy; +begin + if FObjEnum <> nil then + FObjEnum.Free; +end; + +function TSuperEnumerator.MoveNext: Boolean; +begin + case ObjectGetType(FObj) of + stObject: Result := FObjEnum.MoveNext; + stArray: + begin + inc(FCount); + if FCount < FObj.AsArray.Length then + Result := True else + Result := False; + end; + else + Result := false; + end; +end; + +function TSuperEnumerator.GetCurrent: ISuperObject; +begin + case ObjectGetType(FObj) of + stObject: Result := FObjEnum.Current.Value; + stArray: Result := FObj.AsArray.GetO(FCount); + else + Result := FObj; + end; +end; + +{ TSuperObject } + +constructor TSuperObject.Create(jt: TSuperType); +begin + inherited Create; +{$IFDEF DEBUG} + InterlockedIncrement(debugcount); +{$ENDIF} + + FProcessing := false; + FDataPtr := nil; + FDataType := jt; + case FDataType of + stObject: FO.c_object := TSuperTableString.Create; + stArray: FO.c_array := TSuperArray.Create; + stString: FOString := ''; + else + FO.c_object := nil; + end; +end; + +constructor TSuperObject.Create(b: boolean); +begin + Create(stBoolean); + FO.c_boolean := b; +end; + +constructor TSuperObject.Create(i: SuperInt); +begin + Create(stInt); + FO.c_int := i; +end; + +constructor TSuperObject.Create(d: double); +begin + Create(stDouble); + FO.c_double := d; +end; + +constructor TSuperObject.CreateCurrency(c: Currency); +begin + Create(stCurrency); + FO.c_currency := c; +end; + +destructor TSuperObject.Destroy; +begin +{$IFDEF DEBUG} + InterlockedDecrement(debugcount); +{$ENDIF} + case FDataType of + stObject: FO.c_object.Free; + stArray: FO.c_array.Free; + end; + inherited; +end; + +function TSuperObject.Write(writer: TSuperWriter; indent: boolean; escape: boolean; level: integer): Integer; +function DoEscape(str: PSOChar; len: Integer): Integer; +var + pos, start_offset: Integer; + c: SOChar; + buf: array[0..5] of SOChar; +type + TByteChar = record + case integer of + 0: (a, b: Byte); + 1: (c: WideChar); + end; + begin + if str = nil then + begin + Result := 0; + exit; + end; + pos := 0; start_offset := 0; + with writer do + while pos < len do + begin + c := str[pos]; + case c of + #8,#9,#10,#12,#13,'"','\','/': + begin + if(pos - start_offset > 0) then + Append(str + start_offset, pos - start_offset); + + if(c = #8) then Append(ESC_BS, 2) + else if (c = #9) then Append(ESC_TAB, 2) + else if (c = #10) then Append(ESC_LF, 2) + else if (c = #12) then Append(ESC_FF, 2) + else if (c = #13) then Append(ESC_CR, 2) + else if (c = '"') then Append(ESC_QUOT, 2) + else if (c = '\') then Append(ESC_SL, 2) + else if (c = '/') then Append(ESC_SR, 2); + inc(pos); + start_offset := pos; + end; + else + if (SOIChar(c) > 255) then + begin + if(pos - start_offset > 0) then + Append(str + start_offset, pos - start_offset); + buf[0] := '\'; + buf[1] := 'u'; + buf[2] := super_hex_chars[TByteChar(c).b shr 4]; + buf[3] := super_hex_chars[TByteChar(c).b and $f]; + buf[4] := super_hex_chars[TByteChar(c).a shr 4]; + buf[5] := super_hex_chars[TByteChar(c).a and $f]; + Append(@buf, 6); + inc(pos); + start_offset := pos; + end else + if (c < #32) or (c > #127) then + begin + if(pos - start_offset > 0) then + Append(str + start_offset, pos - start_offset); + buf[0] := '\'; + buf[1] := 'u'; + buf[2] := '0'; + buf[3] := '0'; + buf[4] := super_hex_chars[ord(c) shr 4]; + buf[5] := super_hex_chars[ord(c) and $f]; + Append(buf, 6); + inc(pos); + start_offset := pos; + end else + inc(pos); + end; + end; + if(pos - start_offset > 0) then + writer.Append(str + start_offset, pos - start_offset); + Result := 0; + end; + +function DoMinimalEscape(str: PSOChar; len: Integer): Integer; +var + pos, start_offset: Integer; + c: SOChar; +type + TByteChar = record + case integer of + 0: (a, b: Byte); + 1: (c: WideChar); + end; + begin + if str = nil then + begin + Result := 0; + exit; + end; + pos := 0; start_offset := 0; + with writer do + while pos < len do + begin + c := str[pos]; + case c of + #0: + begin + if(pos - start_offset > 0) then + Append(str + start_offset, pos - start_offset); + Append(ESC_ZERO, 6); + inc(pos); + start_offset := pos; + end; + '"': + begin + if(pos - start_offset > 0) then + Append(str + start_offset, pos - start_offset); + Append(ESC_QUOT, 2); + inc(pos); + start_offset := pos; + end; + '\': + begin + if(pos - start_offset > 0) then + Append(str + start_offset, pos - start_offset); + Append(ESC_SL, 2); + inc(pos); + start_offset := pos; + end; + else + inc(pos); + end; + end; + if(pos - start_offset > 0) then + writer.Append(str + start_offset, pos - start_offset); + Result := 0; + end; + + + procedure _indent(i: shortint; r: boolean); + begin + inc(level, i); + if r then + with writer do + begin +{$IFDEF MSWINDOWS} + Append(TOK_CRLF, 2); +{$ELSE} + Append(TOK_LF, 1); +{$ENDIF} + for i := 0 to level - 1 do + Append(TOK_SP, 1); + end; + end; +var + k,j: Integer; + iter: TSuperObjectIter; + st: AnsiString; + val: ISuperObject; +const + ENDSTR_A: PSOChar = '": '; + ENDSTR_B: PSOChar = '":'; +begin + + if FProcessing then + begin + Result := writer.Append(TOK_NULL, 4); + Exit; + end; + + FProcessing := true; + with writer do + try + case FDataType of + stObject: + if FO.c_object.FCount > 0 then + begin + k := 0; + Append(TOK_CBL, 1); + if indent then _indent(1, false); + if ObjectFindFirst(Self, iter) then + repeat + {$IFDEF SUPER_METHOD} + if (iter.val = nil) or not ObjectIsType(iter.val, stMethod) then + begin + {$ENDIF} + if (iter.val = nil) or (not iter.val.Processing) then + begin + if(k <> 0) then + Append(TOK_COM, 1); + if indent then _indent(0, true); + Append(TOK_DQT, 1); + if escape then + doEscape(PSOChar(iter.key), Length(iter.key)) else + DoMinimalEscape(PSOChar(iter.key), Length(iter.key)); + if indent then + Append(ENDSTR_A, 3) else + Append(ENDSTR_B, 2); + if(iter.val = nil) then + Append(TOK_NULL, 4) else + iter.val.write(writer, indent, escape, level); + inc(k); + end; + {$IFDEF SUPER_METHOD} + end; + {$ENDIF} + until not ObjectFindNext(iter); + ObjectFindClose(iter); + if indent then _indent(-1, true); + Result := Append(TOK_CBR, 1); + end else + Result := Append(TOK_OBJ, 2); + stBoolean: + begin + if (FO.c_boolean) then + Result := Append(TOK_TRUE, 4) else + Result := Append(TOK_FALSE, 5); + end; + stInt: + begin + str(FO.c_int, st); + Result := Append(PSOChar(SOString(st))); + end; + stDouble: + Result := Append(PSOChar(FloatToJson(FO.c_double))); + stCurrency: + begin + Result := Append(PSOChar(CurrToJson(FO.c_currency))); + end; + stString: + begin + Append(TOK_DQT, 1); + if escape then + doEscape(PSOChar(FOString), Length(FOString)) else + DoMinimalEscape(PSOChar(FOString), Length(FOString)); + Append(TOK_DQT, 1); + Result := 0; + end; + stArray: + if FO.c_array.FLength > 0 then + begin + Append(TOK_ARL, 1); + if indent then _indent(1, true); + k := 0; + j := 0; + while k < FO.c_array.FLength do + begin + + val := FO.c_array.GetO(k); + {$IFDEF SUPER_METHOD} + if not ObjectIsType(val, stMethod) then + begin + {$ENDIF} + if (val = nil) or (not val.Processing) then + begin + if (j <> 0) then + Append(TOK_COM, 1); + if(val = nil) then + Append(TOK_NULL, 4) else + val.write(writer, indent, escape, level); + inc(j); + end; + {$IFDEF SUPER_METHOD} + end; + {$ENDIF} + inc(k); + end; + if indent then _indent(-1, false); + Result := Append(TOK_ARR, 1); + end else + Result := Append(TOK_ARRAY, 2); + stNull: + Result := Append(TOK_NULL, 4); + else + Result := 0; + end; + finally + FProcessing := false; + end; +end; + +function TSuperObject.IsType(AType: TSuperType): boolean; +begin + Result := AType = FDataType; +end; + +function TSuperObject.AsBoolean: boolean; +begin + case FDataType of + stBoolean: Result := FO.c_boolean; + stInt: Result := (FO.c_int <> 0); + stDouble: Result := (FO.c_double <> 0); + stCurrency: Result := (FO.c_currency <> 0); + stString: Result := (Length(FOString) <> 0); + stNull: Result := False; + else + Result := True; + end; +end; + +function TSuperObject.AsInteger: SuperInt; +var + code: integer; + cint: SuperInt; +begin + case FDataType of + stInt: Result := FO.c_int; + stDouble: Result := round(FO.c_double); + stCurrency: Result := round(FO.c_currency); + stBoolean: Result := ord(FO.c_boolean); + stString: + begin + Val(FOString, cint, code); + if code = 0 then + Result := cint else + Result := 0; + end; + else + Result := 0; + end; +end; + +function TSuperObject.AsDouble: Double; +var + code: integer; + cdouble: double; +begin + case FDataType of + stDouble: Result := FO.c_double; + stCurrency: Result := FO.c_currency; + stInt: Result := FO.c_int; + stBoolean: Result := ord(FO.c_boolean); + stString: + begin + Val(FOString, cdouble, code); + if code = 0 then + Result := cdouble else + Result := 0.0; + end; + else + Result := 0.0; + end; +end; + +function TSuperObject.AsCurrency: Currency; +var + code: integer; + cdouble: double; +begin + case FDataType of + stDouble: Result := FO.c_double; + stCurrency: Result := FO.c_currency; + stInt: Result := FO.c_int; + stBoolean: Result := ord(FO.c_boolean); + stString: + begin + Val(FOString, cdouble, code); + if code = 0 then + Result := cdouble else + Result := 0.0; + end; + else + Result := 0.0; + end; +end; + +function TSuperObject.AsString: SOString; +begin + case FDataType of + stString: Result := FOString; + stNull: Result := ''; + else + Result := AsJSon(false, false); + end; +end; + +function TSuperObject.GetEnumerator: TSuperEnumerator; +begin + Result := TSuperEnumerator.Create(Self); +end; + +procedure TSuperObject.AfterConstruction; +begin + InterlockedDecrement(FRefCount); +end; + +procedure TSuperObject.BeforeDestruction; +begin + if RefCount <> 0 then + raise Exception.Create('Invalid pointer'); +end; + +function TSuperObject.AsArray: TSuperArray; +begin + if FDataType = stArray then + Result := FO.c_array else + Result := nil; +end; + +function TSuperObject.AsObject: TSuperTableString; +begin + if FDataType = stObject then + Result := FO.c_object else + Result := nil; +end; + +function TSuperObject.AsJSon(indent, escape: boolean): SOString; +var + pb: TSuperWriterString; +begin + pb := TSuperWriterString.Create; + try + if(Write(pb, indent, escape, 0) < 0) then + begin + Result := ''; + Exit; + end; + if pb.FBPos > 0 then + Result := pb.FBuf else + Result := ''; + finally + pb.Free; + end; +end; + +class function TSuperObject.ParseString(s: PSOChar; strict: Boolean; partial: boolean; const this: ISuperObject; + options: TSuperFindOptions; const put: ISuperObject; dt: TSuperType): ISuperObject; +var + tok: TSuperTokenizer; + obj: ISuperObject; +begin + tok := TSuperTokenizer.Create; + obj := ParseEx(tok, s, -1, strict, this, options, put, dt); + if(tok.err <> teSuccess) or (not partial and (s[tok.char_offset] <> #0)) then + Result := nil else + Result := obj; + tok.Free; +end; + +class function TSuperObject.ParseStream(stream: TStream; strict: Boolean; + partial: boolean; const this: ISuperObject; options: TSuperFindOptions; + const put: ISuperObject; dt: TSuperType): ISuperObject; +const + BUFFER_SIZE = 1024; +var + tok: TSuperTokenizer; + buffera: array[0..BUFFER_SIZE-1] of AnsiChar; + bufferw: array[0..BUFFER_SIZE-1] of SOChar; + bom: array[0..1] of byte; + unicode: boolean; + j, size: Integer; + st: string; +begin + st := ''; + tok := TSuperTokenizer.Create; + + if (stream.Read(bom, sizeof(bom)) = 2) and (bom[0] = $FF) and (bom[1] = $FE) then + begin + unicode := true; + size := stream.Read(bufferw, BUFFER_SIZE * SizeOf(SoChar)) div SizeOf(SoChar); + end else + begin + unicode := false; + stream.Seek(0, soFromBeginning); + size := stream.Read(buffera, BUFFER_SIZE); + end; + + while size > 0 do + begin + if not unicode then + for j := 0 to size - 1 do + bufferw[j] := SOChar(buffera[j]); + ParseEx(tok, bufferw, size, strict, this, options, put, dt); + + if tok.err = teContinue then + begin + if not unicode then + size := stream.Read(buffera, BUFFER_SIZE) else + size := stream.Read(bufferw, BUFFER_SIZE * SizeOf(SoChar)) div SizeOf(SoChar); + end else + Break; + end; + if(tok.err <> teSuccess) or (not partial and (st[tok.char_offset] <> #0)) then + Result := nil else + Result := tok.stack[tok.depth].current; + tok.Free; +end; + +class function TSuperObject.ParseFile(const FileName: string; strict: Boolean; + partial: boolean; const this: ISuperObject; options: TSuperFindOptions; + const put: ISuperObject; dt: TSuperType): ISuperObject; +var + stream: TFileStream; +begin + stream := TFileStream.Create(FileName, fmOpenRead, fmShareDenyWrite); + try + Result := ParseStream(stream, strict, partial, this, options, put, dt); + finally + stream.Free; + end; +end; + +class function TSuperObject.ParseEx(tok: TSuperTokenizer; str: PSOChar; len: integer; + strict: Boolean; const this: ISuperObject; options: TSuperFindOptions; const put: ISuperObject; dt: TSuperType): ISuperObject; + +const + spaces = [#32,#8,#9,#10,#12,#13]; + delimiters = ['"', '.', '[', ']', '{', '}', '(', ')', ',', ':', #0]; + reserved = delimiters + spaces; + path = ['a'..'z', 'A'..'Z', '.', '_']; + + function hexdigit(x: SOChar): byte; {$IFDEF HAVE_INLINE} inline;{$ENDIF} + begin + if x <= '9' then + Result := byte(x) - byte('0') else + Result := (byte(x) and 7) + 9; + end; + function min(v1, v2: integer): integer;{$IFDEF HAVE_INLINE} inline;{$ENDIF} + begin if v1 < v2 then result := v1 else result := v2 end; + +var + obj: ISuperObject; + v: SOChar; +{$IFDEF SUPER_METHOD} + sm: TSuperMethod; +{$ENDIF} + numi: SuperInt; + numd: Double; + code: integer; + TokRec: PSuperTokenerSrec; + evalstack: integer; + p: PSOChar; + + function IsEndDelimiter(v: AnsiChar): Boolean; + begin + if tok.depth > 0 then + case tok.stack[tok.depth - 1].state of + tsArrayAdd: Result := v in [',', ']', #0]; + tsObjectValueAdd: Result := v in [',', '}', #0]; + else + Result := v = #0; + end else + Result := v = #0; + end; + +label out, redo_char; +begin + evalstack := 0; + obj := nil; + Result := nil; + TokRec := @tok.stack[tok.depth]; + + tok.char_offset := 0; + tok.err := teSuccess; + + repeat + if (tok.char_offset = len) then + begin + if (tok.depth = 0) and (TokRec^.state = tsEatws) and + (TokRec^.saved_state = tsFinish) then + tok.err := teSuccess else + tok.err := teContinue; + goto out; + end; + + v := str^; + + case v of + #10: + begin + inc(tok.line); + tok.col := 0; + end; + #9: inc(tok.col, 4); + else + inc(tok.col); + end; + +redo_char: + case TokRec^.state of + tsEatws: + begin + if (SOIChar(v) < 256) and (AnsiChar(v) in spaces) then {nop} else + if (v = '/') then + begin + tok.pb.Reset; + tok.pb.Append(@v, 1); + TokRec^.state := tsCommentStart; + end else begin + TokRec^.state := TokRec^.saved_state; + goto redo_char; + end + end; + + tsStart: + case v of + '"', + '''': + begin + TokRec^.state := tsString; + tok.pb.Reset; + tok.quote_char := v; + end; + '-': + begin + TokRec^.state := tsNumber; + tok.pb.Reset; + tok.is_double := 0; + tok.floatcount := -1; + goto redo_char; + end; + + '0'..'9': + begin + if (tok.depth = 0) then + case ObjectGetType(this) of + stObject: + begin + TokRec^.state := tsIdentifier; + TokRec^.current := this; + goto redo_char; + end; + end; + TokRec^.state := tsNumber; + tok.pb.Reset; + tok.is_double := 0; + tok.floatcount := -1; + goto redo_char; + end; + '{': + begin + TokRec^.state := tsEatws; + TokRec^.saved_state := tsObjectFieldStart; + TokRec^.current := TSuperObject.Create(stObject); + end; + '[': + begin + TokRec^.state := tsEatws; + TokRec^.saved_state := tsArray; + TokRec^.current := TSuperObject.Create(stArray); + end; +{$IFDEF SUPER_METHOD} + '(': + begin + if (tok.depth = 0) and ObjectIsType(this, stMethod) then + begin + TokRec^.current := this; + TokRec^.state := tsParamValue; + end; + end; +{$ENDIF} + 'N', + 'n': + begin + TokRec^.state := tsNull; + tok.pb.Reset; + tok.st_pos := 0; + goto redo_char; + end; + 'T', + 't', + 'F', + 'f': + begin + TokRec^.state := tsBoolean; + tok.pb.Reset; + tok.st_pos := 0; + goto redo_char; + end; + else + TokRec^.state := tsIdentifier; + tok.pb.Reset; + goto redo_char; + end; + + tsFinish: + begin + if(tok.depth = 0) then goto out; + obj := TokRec^.current; + tok.ResetLevel(tok.depth); + dec(tok.depth); + TokRec := @tok.stack[tok.depth]; + goto redo_char; + end; + + tsNull: + begin + tok.pb.Append(@v, 1); + if (StrLComp(TOK_NULL, PSOChar(tok.pb.FBuf), min(tok.st_pos + 1, 4)) = 0) then + begin + if (tok.st_pos = 4) then + if (((SOIChar(v) < 256) and (AnsiChar(v) in path)) or (SOIChar(v) >= 256)) then + TokRec^.state := tsIdentifier else + begin + TokRec^.current := TSuperObject.Create(stNull); + TokRec^.saved_state := tsFinish; + TokRec^.state := tsEatws; + goto redo_char; + end; + end else + begin + TokRec^.state := tsIdentifier; + tok.pb.FBuf[tok.st_pos] := #0; + dec(tok.pb.FBPos); + goto redo_char; + end; + inc(tok.st_pos); + end; + + tsCommentStart: + begin + if(v = '*') then + begin + TokRec^.state := tsComment; + end else + if (v = '/') then + begin + TokRec^.state := tsCommentEol; + end else + begin + tok.err := teParseComment; + goto out; + end; + tok.pb.Append(@v, 1); + end; + + tsComment: + begin + if(v = '*') then + TokRec^.state := tsCommentEnd; + tok.pb.Append(@v, 1); + end; + + tsCommentEol: + begin + if (v = #10) then + TokRec^.state := tsEatws else + tok.pb.Append(@v, 1); + end; + + tsCommentEnd: + begin + tok.pb.Append(@v, 1); + if (v = '/') then + TokRec^.state := tsEatws else + TokRec^.state := tsComment; + end; + + tsString: + begin + if (v = tok.quote_char) then + begin + TokRec^.current := TSuperObject.Create(SOString(tok.pb.GetString)); + TokRec^.saved_state := tsFinish; + TokRec^.state := tsEatws; + end else + if (v = '\') then + begin + TokRec^.saved_state := tsString; + TokRec^.state := tsStringEscape; + end else + begin + tok.pb.Append(@v, 1); + end + end; + + tsEvalProperty: + begin + if (TokRec^.current = nil) and (foCreatePath in options) then + begin + TokRec^.current := TSuperObject.Create(stObject); + TokRec^.parent.AsObject.PutO(tok.pb.Fbuf, TokRec^.current) + end else + if not ObjectIsType(TokRec^.current, stObject) then + begin + tok.err := teEvalObject; + goto out; + end; + tok.pb.Reset; + TokRec^.state := tsIdentifier; + goto redo_char; + end; + + tsEvalArray: + begin + if (TokRec^.current = nil) and (foCreatePath in options) then + begin + TokRec^.current := TSuperObject.Create(stArray); + TokRec^.parent.AsObject.PutO(tok.pb.Fbuf, TokRec^.current) + end else + if not ObjectIsType(TokRec^.current, stArray) then + begin + tok.err := teEvalArray; + goto out; + end; + tok.pb.Reset; + TokRec^.state := tsParamValue; + goto redo_char; + end; +{$IFDEF SUPER_METHOD} + tsEvalMethod: + begin + if ObjectIsType(TokRec^.current, stMethod) and assigned(TokRec^.current.AsMethod) then + begin + tok.pb.Reset; + TokRec^.obj := TSuperObject.Create(stArray); + TokRec^.state := tsMethodValue; + goto redo_char; + end else + begin + tok.err := teEvalMethod; + goto out; + end; + end; + + tsMethodValue: + begin + case v of + ')': + TokRec^.state := tsIdentifier; + else + if (tok.depth >= SUPER_TOKENER_MAX_DEPTH-1) then + begin + tok.err := teDepth; + goto out; + end; + inc(evalstack); + TokRec^.state := tsMethodPut; + inc(tok.depth); + tok.ResetLevel(tok.depth); + TokRec := @tok.stack[tok.depth]; + goto redo_char; + end; + end; + + tsMethodPut: + begin + TokRec^.obj.AsArray.Add(obj); + case v of + ',': + begin + tok.pb.Reset; + TokRec^.saved_state := tsMethodValue; + TokRec^.state := tsEatws; + end; + ')': + begin + if TokRec^.obj.AsArray.Length = 1 then + TokRec^.obj := TokRec^.obj.AsArray.GetO(0); + dec(evalstack); + tok.pb.Reset; + TokRec^.saved_state := tsIdentifier; + TokRec^.state := tsEatws; + end; + else + tok.err := teEvalMethod; + goto out; + end; + end; +{$ENDIF} + tsParamValue: + begin + case v of + ']': + TokRec^.state := tsIdentifier; + else + if (tok.depth >= SUPER_TOKENER_MAX_DEPTH-1) then + begin + tok.err := teDepth; + goto out; + end; + inc(evalstack); + TokRec^.state := tsParamPut; + inc(tok.depth); + tok.ResetLevel(tok.depth); + TokRec := @tok.stack[tok.depth]; + goto redo_char; + end; + end; + + tsParamPut: + begin + dec(evalstack); + TokRec^.obj := obj; + tok.pb.Reset; + TokRec^.saved_state := tsIdentifier; + TokRec^.state := tsEatws; + if v <> ']' then + begin + tok.err := teEvalArray; + goto out; + end; + end; + + tsIdentifier: + begin + if (this = nil) then + begin + if (SOIChar(v) < 256) and IsEndDelimiter(AnsiChar(v)) then + begin + if not strict then + begin + tok.pb.TrimRight; + TokRec^.current := TSuperObject.Create(tok.pb.Fbuf); + TokRec^.saved_state := tsFinish; + TokRec^.state := tsEatws; + goto redo_char; + end else + begin + tok.err := teParseString; + goto out; + end; + end else + if (v = '\') then + begin + TokRec^.saved_state := tsIdentifier; + TokRec^.state := tsStringEscape; + end else + tok.pb.Append(@v, 1); + end else + begin + if (SOIChar(v) < 256) and (AnsiChar(v) in reserved) then + begin + TokRec^.gparent := TokRec^.parent; + if TokRec^.current = nil then + TokRec^.parent := this else + TokRec^.parent := TokRec^.current; + + case ObjectGetType(TokRec^.parent) of + stObject: + case v of + '.': + begin + TokRec^.state := tsEvalProperty; + if tok.pb.FBPos > 0 then + TokRec^.current := TokRec^.parent.AsObject.GetO(tok.pb.Fbuf); + end; + '[': + begin + TokRec^.state := tsEvalArray; + if tok.pb.FBPos > 0 then + TokRec^.current := TokRec^.parent.AsObject.GetO(tok.pb.Fbuf); + end; + '(': + begin + TokRec^.state := tsEvalMethod; + if tok.pb.FBPos > 0 then + TokRec^.current := TokRec^.parent.AsObject.GetO(tok.pb.Fbuf); + end; + else + if tok.pb.FBPos > 0 then + TokRec^.current := TokRec^.parent.AsObject.GetO(tok.pb.Fbuf); + if (foPutValue in options) and (evalstack = 0) then + begin + TokRec^.parent.AsObject.PutO(tok.pb.Fbuf, put); + TokRec^.current := put + end else + if (foDelete in options) and (evalstack = 0) then + begin + TokRec^.current := TokRec^.parent.AsObject.Delete(tok.pb.Fbuf); + end else + if (TokRec^.current = nil) and (foCreatePath in options) then + begin + TokRec^.current := TSuperObject.Create(dt); + TokRec^.parent.AsObject.PutO(tok.pb.Fbuf, TokRec^.current); + end; + if not (foDelete in options) then + TokRec^.current := TokRec^.parent.AsObject.GetO(tok.pb.Fbuf); + TokRec^.state := tsFinish; + goto redo_char; + end; + stArray: + begin + if TokRec^.obj <> nil then + begin + if not ObjectIsType(TokRec^.obj, stInt) or (TokRec^.obj.AsInteger < 0) then + begin + tok.err := teEvalInt; + TokRec^.obj := nil; + goto out; + end; + numi := TokRec^.obj.AsInteger; + TokRec^.obj := nil; + + TokRec^.current := TokRec^.parent.AsArray.GetO(numi); + case v of + '.': + if (TokRec^.current = nil) and (foCreatePath in options) then + begin + TokRec^.current := TSuperObject.Create(stObject); + TokRec^.parent.AsArray.PutO(numi, TokRec^.current); + end else + if (TokRec^.current = nil) then + begin + tok.err := teEvalObject; + goto out; + end; + '[': + begin + if (TokRec^.current = nil) and (foCreatePath in options) then + begin + TokRec^.current := TSuperObject.Create(stArray); + TokRec^.parent.AsArray.Add(TokRec^.current); + end else + if (TokRec^.current = nil) then + begin + tok.err := teEvalArray; + goto out; + end; + TokRec^.state := tsEvalArray; + end; + '(': TokRec^.state := tsEvalMethod; + else + if (foPutValue in options) and (evalstack = 0) then + begin + TokRec^.parent.AsArray.PutO(numi, put); + TokRec^.current := put; + end else + if (foDelete in options) and (evalstack = 0) then + begin + TokRec^.current := TokRec^.parent.AsArray.Delete(numi); + end else + TokRec^.current := TokRec^.parent.AsArray.GetO(numi); + TokRec^.state := tsFinish; + goto redo_char + end; + end else + begin + case v of + '.': + begin + if (foPutValue in options) then + begin + TokRec^.current := TSuperObject.Create(stObject); + TokRec^.parent.AsArray.Add(TokRec^.current); + end else + TokRec^.current := TokRec^.parent.AsArray.GetO(TokRec^.parent.AsArray.FLength - 1); + end; + '[': + begin + if (foPutValue in options) then + begin + TokRec^.current := TSuperObject.Create(stArray); + TokRec^.parent.AsArray.Add(TokRec^.current); + end else + TokRec^.current := TokRec^.parent.AsArray.GetO(TokRec^.parent.AsArray.FLength - 1); + TokRec^.state := tsEvalArray; + end; + '(': + begin + if not (foPutValue in options) then + TokRec^.current := TokRec^.parent.AsArray.GetO(TokRec^.parent.AsArray.FLength - 1) else + TokRec^.current := nil; + + TokRec^.state := tsEvalMethod; + end; + else + if (foPutValue in options) and (evalstack = 0) then + begin + TokRec^.parent.AsArray.Add(put); + TokRec^.current := put; + end else + if tok.pb.FBPos = 0 then + TokRec^.current := TokRec^.parent.AsArray.GetO(TokRec^.parent.AsArray.FLength - 1); + TokRec^.state := tsFinish; + goto redo_char + end; + end; + end; +{$IFDEF SUPER_METHOD} + stMethod: + case v of + '.': + begin + TokRec^.current := nil; + sm := TokRec^.parent.AsMethod; + sm(TokRec^.gparent, TokRec^.obj, TokRec^.current); + TokRec^.obj := nil; + end; + '[': + begin + TokRec^.current := nil; + sm := TokRec^.parent.AsMethod; + sm(TokRec^.gparent, TokRec^.obj, TokRec^.current); + TokRec^.state := tsEvalArray; + TokRec^.obj := nil; + end; + '(': + begin + TokRec^.current := nil; + sm := TokRec^.parent.AsMethod; + sm(TokRec^.gparent, TokRec^.obj, TokRec^.current); + TokRec^.state := tsEvalMethod; + TokRec^.obj := nil; + end; + else + if not (foPutValue in options) or (evalstack > 0) then + begin + TokRec^.current := nil; + sm := TokRec^.parent.AsMethod; + sm(TokRec^.gparent, TokRec^.obj, TokRec^.current); + TokRec^.obj := nil; + TokRec^.state := tsFinish; + goto redo_char + end else + begin + tok.err := teEvalMethod; + TokRec^.obj := nil; + goto out; + end; + end; +{$ENDIF} + end; + end else + tok.pb.Append(@v, 1); + end; + end; + + tsStringEscape: + case v of + 'b', + 'n', + 'r', + 't', + 'f': + begin + if(v = 'b') then tok.pb.Append(TOK_BS, 1) + else if(v = 'n') then tok.pb.Append(TOK_LF, 1) + else if(v = 'r') then tok.pb.Append(TOK_CR, 1) + else if(v = 't') then tok.pb.Append(TOK_TAB, 1) + else if(v = 'f') then tok.pb.Append(TOK_FF, 1); + TokRec^.state := TokRec^.saved_state; + end; + 'u': + begin + tok.ucs_char := 0; + tok.st_pos := 0; + TokRec^.state := tsEscapeUnicode; + end; + 'x': + begin + tok.ucs_char := 0; + tok.st_pos := 0; + TokRec^.state := tsEscapeHexadecimal; + end + else + tok.pb.Append(@v, 1); + TokRec^.state := TokRec^.saved_state; + end; + + tsEscapeUnicode: + begin + if ((SOIChar(v) < 256) and (AnsiChar(v) in super_hex_chars_set)) then + begin + inc(tok.ucs_char, (Word(hexdigit(v)) shl ((3-tok.st_pos)*4))); + inc(tok.st_pos); + if (tok.st_pos = 4) then + begin + tok.pb.Append(@tok.ucs_char, 1); + TokRec^.state := TokRec^.saved_state; + end + end else + begin + tok.err := teParseString; + goto out; + end + end; + tsEscapeHexadecimal: + begin + if ((SOIChar(v) < 256) and (AnsiChar(v) in super_hex_chars_set)) then + begin + inc(tok.ucs_char, (Word(hexdigit(v)) shl ((1-tok.st_pos)*4))); + inc(tok.st_pos); + if (tok.st_pos = 2) then + begin + tok.pb.Append(@tok.ucs_char, 1); + TokRec^.state := TokRec^.saved_state; + end + end else + begin + tok.err := teParseString; + goto out; + end + end; + tsBoolean: + begin + tok.pb.Append(@v, 1); + if (StrLComp('true', PSOChar(tok.pb.FBuf), min(tok.st_pos + 1, 4)) = 0) then + begin + if (tok.st_pos = 4) then + if (((SOIChar(v) < 256) and (AnsiChar(v) in path)) or (SOIChar(v) >= 256)) then + TokRec^.state := tsIdentifier else + begin + TokRec^.current := TSuperObject.Create(true); + TokRec^.saved_state := tsFinish; + TokRec^.state := tsEatws; + goto redo_char; + end + end else + if (StrLComp('false', PSOChar(tok.pb.FBuf), min(tok.st_pos + 1, 5)) = 0) then + begin + if (tok.st_pos = 5) then + if (((SOIChar(v) < 256) and (AnsiChar(v) in path)) or (SOIChar(v) >= 256)) then + TokRec^.state := tsIdentifier else + begin + TokRec^.current := TSuperObject.Create(false); + TokRec^.saved_state := tsFinish; + TokRec^.state := tsEatws; + goto redo_char; + end + end else + begin + TokRec^.state := tsIdentifier; + tok.pb.FBuf[tok.st_pos] := #0; + dec(tok.pb.FBPos); + goto redo_char; + end; + inc(tok.st_pos); + end; + + tsNumber: + begin + if (SOIChar(v) < 256) and (AnsiChar(v) in super_number_chars_set) then + begin + tok.pb.Append(@v, 1); + if (SOIChar(v) < 256) then + case v of + '.': begin + tok.is_double := 1; + tok.floatcount := 0; + end; + 'e','E': + begin + tok.is_double := 1; + tok.floatcount := -1; + end; + '0'..'9': + begin + + if (tok.is_double = 1) and (tok.floatcount >= 0) then + begin + inc(tok.floatcount); + if tok.floatcount > 4 then + tok.floatcount := -1; + end; + end; + end; + end else + begin + if (tok.is_double = 0) then + begin + val(tok.pb.FBuf, numi, code); + if ObjectIsType(this, stArray) then + begin + if (foPutValue in options) and (evalstack = 0) then + begin + this.AsArray.PutO(numi, put); + TokRec^.current := put; + end else + if (foDelete in options) and (evalstack = 0) then + TokRec^.current := this.AsArray.Delete(numi) else + TokRec^.current := this.AsArray.GetO(numi); + end else + TokRec^.current := TSuperObject.Create(numi); + + end else + if (tok.is_double <> 0) then + begin + if tok.floatcount >= 0 then + begin + p := tok.pb.FBuf; + while p^ <> '.' do inc(p); + for code := 0 to tok.floatcount - 1 do + begin + p^ := p[1]; + inc(p); + end; + p^ := #0; + val(tok.pb.FBuf, numi, code); + case tok.floatcount of + 0: numi := numi * 10000; + 1: numi := numi * 1000; + 2: numi := numi * 100; + 3: numi := numi * 10; + end; + TokRec^.current := TSuperObject.CreateCurrency(PCurrency(@numi)^); + end else + begin + val(tok.pb.FBuf, numd, code); + TokRec^.current := TSuperObject.Create(numd); + end; + end else + begin + tok.err := teParseNumber; + goto out; + end; + TokRec^.saved_state := tsFinish; + TokRec^.state := tsEatws; + goto redo_char; + end + end; + + tsArray: + begin + if (v = ']') then + begin + TokRec^.saved_state := tsFinish; + TokRec^.state := tsEatws; + end else + begin + if(tok.depth >= SUPER_TOKENER_MAX_DEPTH-1) then + begin + tok.err := teDepth; + goto out; + end; + TokRec^.state := tsArrayAdd; + inc(tok.depth); + tok.ResetLevel(tok.depth); + TokRec := @tok.stack[tok.depth]; + goto redo_char; + end + end; + + tsArrayAdd: + begin + TokRec^.current.AsArray.Add(obj); + TokRec^.saved_state := tsArraySep; + TokRec^.state := tsEatws; + goto redo_char; + end; + + tsArraySep: + begin + if (v = ']') then + begin + TokRec^.saved_state := tsFinish; + TokRec^.state := tsEatws; + end else + if (v = ',') then + begin + TokRec^.saved_state := tsArray; + TokRec^.state := tsEatws; + end else + begin + tok.err := teParseArray; + goto out; + end + end; + + tsObjectFieldStart: + begin + if (v = '}') then + begin + TokRec^.saved_state := tsFinish; + TokRec^.state := tsEatws; + end else + if (SOIChar(v) < 256) and (AnsiChar(v) in ['"', '''']) then + begin + tok.quote_char := v; + tok.pb.Reset; + TokRec^.state := tsObjectField; + end else + if not((SOIChar(v) < 256) and ((AnsiChar(v) in reserved) or strict)) then + begin + TokRec^.state := tsObjectUnquotedField; + tok.pb.Reset; + goto redo_char; + end else + begin + tok.err := teParseObjectKeyName; + goto out; + end + end; + + tsObjectField: + begin + if (v = tok.quote_char) then + begin + TokRec^.field_name := tok.pb.FBuf; + TokRec^.saved_state := tsObjectFieldEnd; + TokRec^.state := tsEatws; + end else + if (v = '\') then + begin + TokRec^.saved_state := tsObjectField; + TokRec^.state := tsStringEscape; + end else + begin + tok.pb.Append(@v, 1); + end + end; + + tsObjectUnquotedField: + begin + if (SOIChar(v) < 256) and (AnsiChar(v) in [':', #0]) then + begin + TokRec^.field_name := tok.pb.FBuf; + TokRec^.saved_state := tsObjectFieldEnd; + TokRec^.state := tsEatws; + goto redo_char; + end else + if (v = '\') then + begin + TokRec^.saved_state := tsObjectUnquotedField; + TokRec^.state := tsStringEscape; + end else + tok.pb.Append(@v, 1); + end; + + tsObjectFieldEnd: + begin + if (v = ':') then + begin + TokRec^.saved_state := tsObjectValue; + TokRec^.state := tsEatws; + end else + begin + tok.err := teParseObjectKeySep; + goto out; + end + end; + + tsObjectValue: + begin + if (tok.depth >= SUPER_TOKENER_MAX_DEPTH-1) then + begin + tok.err := teDepth; + goto out; + end; + TokRec^.state := tsObjectValueAdd; + inc(tok.depth); + tok.ResetLevel(tok.depth); + TokRec := @tok.stack[tok.depth]; + goto redo_char; + end; + + tsObjectValueAdd: + begin + TokRec^.current.AsObject.PutO(TokRec^.field_name, obj); + TokRec^.field_name := ''; + TokRec^.saved_state := tsObjectSep; + TokRec^.state := tsEatws; + goto redo_char; + end; + + tsObjectSep: + begin + if (v = '}') then + begin + TokRec^.saved_state := tsFinish; + TokRec^.state := tsEatws; + end else + if (v = ',') then + begin + TokRec^.saved_state := tsObjectFieldStart; + TokRec^.state := tsEatws; + end else + begin + tok.err := teParseObjectValueSep; + goto out; + end + end; + end; + inc(str); + inc(tok.char_offset); + until v = #0; + + if(TokRec^.state <> tsFinish) and + (TokRec^.saved_state <> tsFinish) then + tok.err := teParseEof; + + out: + if(tok.err in [teSuccess]) then + begin +{$IFDEF SUPER_METHOD} + if (foCallMethod in options) and ObjectIsType(TokRec^.current, stMethod) and assigned(TokRec^.current.AsMethod) then + begin + sm := TokRec^.current.AsMethod; + sm(TokRec^.parent, put, Result); + end else +{$ENDIF} + Result := TokRec^.current; + end else + Result := nil; +end; + +procedure TSuperObject.PutO(const path: SOString; const Value: ISuperObject); +begin + ParseString(PSOChar(path), true, False, self, [foCreatePath, foPutValue], Value); +end; + +procedure TSuperObject.PutB(const path: SOString; Value: Boolean); +begin + ParseString(PSOChar(path), true, False, self, [foCreatePath, foPutValue], TSuperObject.Create(Value)); +end; + +procedure TSuperObject.PutD(const path: SOString; Value: Double); +begin + ParseString(PSOChar(path), true, False, self, [foCreatePath, foPutValue], TSuperObject.Create(Value)); +end; + +procedure TSuperObject.PutC(const path: SOString; Value: Currency); +begin + ParseString(PSOChar(path), true, False, self, [foCreatePath, foPutValue], TSuperObject.CreateCurrency(Value)); +end; + +procedure TSuperObject.PutI(const path: SOString; Value: SuperInt); +begin + ParseString(PSOChar(path), true, False, self, [foCreatePath, foPutValue], TSuperObject.Create(Value)); +end; + +procedure TSuperObject.PutS(const path: SOString; const Value: SOString); +begin + ParseString(PSOChar(path), true, False, self, [foCreatePath, foPutValue], TSuperObject.Create(Value)); +end; + + +{$IFDEF FPC} +function TSuperObject.QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} iid: tguid; out obj): longint;{$IFNDEF WINDOWS}cdecl{$ELSE}stdcall{$ENDIF}; +{$ELSE} +function TSuperObject.QueryInterface(const IID: TGUID; out Obj): HResult; stdcall; +{$ENDIF} +begin + if GetInterface(IID, Obj) then + Result := 0 + else + Result := E_NOINTERFACE; +end; + +function TSuperObject.SaveTo(stream: TStream; indent, escape: boolean): integer; +var + pb: TSuperWriterStream; +begin + if escape then + pb := TSuperAnsiWriterStream.Create(stream) else + pb := TSuperUnicodeWriterStream.Create(stream); + + if(Write(pb, indent, escape, 0) < 0) then + begin + pb.Reset; + pb.Free; + Result := 0; + Exit; + end; + Result := stream.Size; + pb.Free; +end; + +function TSuperObject.CalcSize(indent, escape: boolean): integer; +var + pb: TSuperWriterFake; +begin + pb := TSuperWriterFake.Create; + if(Write(pb, indent, escape, 0) < 0) then + begin + pb.Free; + Result := 0; + Exit; + end; + Result := pb.FSize; + pb.Free; +end; + +function TSuperObject.SaveTo(socket: Integer; indent, escape: boolean): integer; +var + pb: TSuperWriterSock; +begin + pb := TSuperWriterSock.Create(socket); + if(Write(pb, indent, escape, 0) < 0) then + begin + pb.Free; + Result := 0; + Exit; + end; + Result := pb.FSize; + pb.Free; +end; + +constructor TSuperObject.Create(const s: SOString); +begin + Create(stString); + FOString := s; +end; + +procedure TSuperObject.Clear(all: boolean); +begin + if FProcessing then exit; + FProcessing := true; + try + case FDataType of + stBoolean: FO.c_boolean := false; + stDouble: FO.c_double := 0.0; + stCurrency: FO.c_currency := 0.0; + stInt: FO.c_int := 0; + stObject: FO.c_object.Clear(all); + stArray: FO.c_array.Clear(all); + stString: FOString := ''; +{$IFDEF SUPER_METHOD} + stMethod: FO.c_method := nil; +{$ENDIF} + end; + finally + FProcessing := false; + end; +end; + +procedure TSuperObject.Pack(all: boolean = false); +begin + if FProcessing then exit; + FProcessing := true; + try + case FDataType of + stObject: FO.c_object.Pack(all); + stArray: FO.c_array.Pack(all); + end; + finally + FProcessing := false; + end; +end; + +function TSuperObject.GetN(const path: SOString): ISuperObject; +begin + Result := ParseString(PSOChar(path), False, true, self); + if Result = nil then + Result := TSuperObject.Create(stNull); +end; + +procedure TSuperObject.PutN(const path: SOString; const Value: ISuperObject); +begin + if Value = nil then + ParseString(PSOChar(path), False, True, self, [foCreatePath, foPutValue], TSuperObject.Create(stNull)) else + ParseString(PSOChar(path), False, True, self, [foCreatePath, foPutValue], Value); +end; + +function TSuperObject.Delete(const path: SOString): ISuperObject; +begin + Result := ParseString(PSOChar(path), False, true, self, [foDelete]); +end; + +function TSuperObject.Clone: ISuperObject; +var + ite: TSuperObjectIter; + arr: TSuperArray; + j: integer; +begin + case FDataType of + stBoolean: Result := TSuperObject.Create(FO.c_boolean); + stDouble: Result := TSuperObject.Create(FO.c_double); + stCurrency: Result := TSuperObject.CreateCurrency(FO.c_currency); + stInt: Result := TSuperObject.Create(FO.c_int); + stString: Result := TSuperObject.Create(FOString); +{$IFDEF SUPER_METHOD} + stMethod: Result := TSuperObject.Create(FO.c_method); +{$ENDIF} + stObject: + begin + Result := TSuperObject.Create(stObject); + if ObjectFindFirst(self, ite) then + with Result.AsObject do + repeat + PutO(ite.key, ite.val.Clone); + until not ObjectFindNext(ite); + ObjectFindClose(ite); + end; + stArray: + begin + Result := TSuperObject.Create(stArray); + arr := AsArray; + with Result.AsArray do + for j := 0 to arr.Length - 1 do + Add(arr.GetO(j).Clone); + end; + stNull: + Result := TSuperObject.Create(stNull); + else + Result := nil; + end; +end; + +procedure TSuperObject.Merge(const obj: ISuperObject; reference: boolean); +var + prop1, prop2: ISuperObject; + ite: TSuperObjectIter; + arr: TSuperArray; + j: integer; +begin + if ObjectIsType(obj, FDataType) then + case FDataType of + stBoolean: FO.c_boolean := obj.AsBoolean; + stDouble: FO.c_double := obj.AsDouble; + stCurrency: FO.c_currency := obj.AsCurrency; + stInt: FO.c_int := obj.AsInteger; + stString: FOString := obj.AsString; +{$IFDEF SUPER_METHOD} + stMethod: FO.c_method := obj.AsMethod; +{$ENDIF} + stObject: + begin + if ObjectFindFirst(obj, ite) then + with FO.c_object do + repeat + prop1 := FO.c_object.GetO(ite.key); + if (prop1 <> nil) and (ite.val <> nil) and (prop1.DataType = ite.val.DataType) then + prop1.Merge(ite.val) else + if reference then + PutO(ite.key, ite.val) else + if ite.val <> nil then + PutO(ite.key, ite.val.Clone) else + PutO(ite.key, nil) + + until not ObjectFindNext(ite); + ObjectFindClose(ite); + end; + stArray: + begin + arr := obj.AsArray; + with FO.c_array do + for j := 0 to arr.Length - 1 do + begin + prop1 := GetO(j); + prop2 := arr.GetO(j); + if (prop1 <> nil) and (prop2 <> nil) and (prop1.DataType = prop2.DataType) then + prop1.Merge(prop2) else + if reference then + PutO(j, prop2) else + if prop2 <> nil then + PutO(j, prop2.Clone) else + PutO(j, nil); + end; + end; + end; +end; + +procedure TSuperObject.Merge(const str: SOString); +begin + Merge(TSuperObject.ParseString(PSOChar(str), False), true); +end; + +class function TSuperObject.NewInstance: TObject; +begin + Result := inherited NewInstance; + TSuperObject(Result).FRefCount := 1; +end; + +function TSuperObject.ForcePath(const path: SOString; dataType: TSuperType = stObject): ISuperObject; +begin + Result := ParseString(PSOChar(path), False, True, Self, [foCreatePath], nil, dataType); +end; + +function TSuperObject.Format(const str: SOString; BeginSep: SOChar; EndSep: SOChar): SOString; +var + p1, p2: PSOChar; +begin + Result := ''; + p2 := PSOChar(str); + p1 := p2; + while true do + if p2^ = BeginSep then + begin + if p2 > p1 then + Result := Result + Copy(p1, 0, p2-p1); + inc(p2); + p1 := p2; + while true do + if p2^ = EndSep then Break else + if p2^ = #0 then Exit else + inc(p2); + Result := Result + GetS(copy(p1, 0, p2-p1)); + inc(p2); + p1 := p2; + end + else if p2^ = #0 then + begin + if p2 > p1 then + Result := Result + Copy(p1, 0, p2-p1); + Break; + end else + inc(p2); +end; + +function TSuperObject.GetO(const path: SOString): ISuperObject; +begin + Result := ParseString(PSOChar(path), False, True, Self); +end; + +function TSuperObject.GetA(const path: SOString): TSuperArray; +var + obj: ISuperObject; +begin + obj := ParseString(PSOChar(path), False, True, Self); + if obj <> nil then + Result := obj.AsArray else + Result := nil; +end; + +function TSuperObject.GetB(const path: SOString): Boolean; +var + obj: ISuperObject; +begin + obj := GetO(path); + if obj <> nil then + Result := obj.AsBoolean else + Result := false; +end; + +function TSuperObject.GetD(const path: SOString): Double; +var + obj: ISuperObject; +begin + obj := GetO(path); + if obj <> nil then + Result := obj.AsDouble else + Result := 0.0; +end; + +function TSuperObject.GetC(const path: SOString): Currency; +var + obj: ISuperObject; +begin + obj := GetO(path); + if obj <> nil then + Result := obj.AsCurrency else + Result := 0.0; +end; + +function TSuperObject.GetI(const path: SOString): SuperInt; +var + obj: ISuperObject; +begin + obj := GetO(path); + if obj <> nil then + Result := obj.AsInteger else + Result := 0; +end; + +function TSuperObject.GetDataPtr: Pointer; +begin + Result := FDataPtr; +end; + +function TSuperObject.GetDataType: TSuperType; +begin + Result := FDataType +end; + +function TSuperObject.GetS(const path: SOString): SOString; +var + obj: ISuperObject; +begin + obj := GetO(path); + if obj <> nil then + Result := obj.AsString else + Result := ''; +end; + +function TSuperObject.SaveTo(const FileName: string; indent, escape: boolean): integer; +var + stream: TFileStream; +begin + stream := TFileStream.Create(FileName, fmCreate); + try + Result := SaveTo(stream, indent, escape); + finally + stream.Free; + end; +end; + +function TSuperObject.Validate(const rules: SOString; const defs: SOString = ''; callback: TSuperOnValidateError = nil; sender: Pointer = nil): boolean; +begin + Result := Validate(TSuperObject.ParseString(PSOChar(rules), False), TSuperObject.ParseString(PSOChar(defs), False), callback, sender); +end; + +function TSuperObject.Validate(const rules: ISuperObject; const defs: ISuperObject = nil; callback: TSuperOnValidateError = nil; sender: Pointer = nil): boolean; +type + TDataType = (dtUnknown, dtStr, dtInt, dtFloat, dtNumber, dtText, dtBool, + dtMap, dtSeq, dtScalar, dtAny); +var + datatypes: ISuperObject; + names: ISuperObject; + + function FindInheritedProperty(const prop: PSOChar; p: ISuperObject): ISuperObject; + var + o: ISuperObject; + e: TSuperAvlEntry; + begin + o := p[prop]; + if o <> nil then + result := o else + begin + o := p['inherit']; + if (o <> nil) and ObjectIsType(o, stString) then + begin + e := names.AsObject.Search(o.AsString); + if (e <> nil) then + Result := FindInheritedProperty(prop, e.Value) else + Result := nil; + end else + Result := nil; + end; + end; + + function FindDataType(o: ISuperObject): TDataType; + var + e: TSuperAvlEntry; + obj: ISuperObject; + begin + obj := FindInheritedProperty('type', o); + if obj <> nil then + begin + e := datatypes.AsObject.Search(obj.AsString); + if e <> nil then + Result := TDataType(e.Value.AsInteger) else + Result := dtUnknown; + end else + Result := dtUnknown; + end; + + procedure GetNames(o: ISuperObject); + var + obj: ISuperObject; + f: TSuperObjectIter; + begin + obj := o['name']; + if ObjectIsType(obj, stString) then + names[obj.AsString] := o; + + case FindDataType(o) of + dtMap: + begin + obj := o['mapping']; + if ObjectIsType(obj, stObject) then + begin + if ObjectFindFirst(obj, f) then + repeat + if ObjectIsType(f.val, stObject) then + GetNames(f.val); + until not ObjectFindNext(f); + ObjectFindClose(f); + end; + end; + dtSeq: + begin + obj := o['sequence']; + if ObjectIsType(obj, stObject) then + GetNames(obj); + end; + end; + end; + + function FindInheritedField(const prop: SOString; p: ISuperObject): ISuperObject; + var + o: ISuperObject; + e: TSuperAvlEntry; + begin + o := p['mapping']; + if ObjectIsType(o, stObject) then + begin + o := o.AsObject.GetO(prop); + if o <> nil then + begin + Result := o; + Exit; + end; + end; + + o := p['inherit']; + if ObjectIsType(o, stString) then + begin + e := names.AsObject.Search(o.AsString); + if (e <> nil) then + Result := FindInheritedField(prop, e.Value) else + Result := nil; + end else + Result := nil; + end; + + function InheritedFieldExist(const obj: ISuperObject; p: ISuperObject; const name: SOString = ''): boolean; + var + o: ISuperObject; + e: TSuperAvlEntry; + j: TSuperAvlIterator; + begin + Result := true; + o := p['mapping']; + if ObjectIsType(o, stObject) then + begin + j := TSuperAvlIterator.Create(o.AsObject); + try + j.First; + e := j.GetIter; + while e <> nil do + begin + if obj.AsObject.Search(e.Name) = nil then + begin + Result := False; + if assigned(callback) then + callback(sender, veFieldNotFound, name + '.' + e.Name); + end; + j.Next; + e := j.GetIter; + end; + + finally + j.Free; + end; + end; + + o := p['inherit']; + if ObjectIsType(o, stString) then + begin + e := names.AsObject.Search(o.AsString); + if (e <> nil) then + Result := InheritedFieldExist(obj, e.Value, name) and Result; + end; + end; + + function getInheritedBool(f: PSOChar; p: ISuperObject; default: boolean = false): boolean; + var + o: ISuperObject; + begin + o := FindInheritedProperty(f, p); + case ObjectGetType(o) of + stBoolean: Result := o.AsBoolean; + stNull: Result := Default; + else + Result := default; + if assigned(callback) then + callback(sender, veRuleMalformated, f); + end; + end; + + procedure GetInheritedFieldList(list: ISuperObject; p: ISuperObject); + var + o: ISuperObject; + e: TSuperAvlEntry; + i: TSuperAvlIterator; + begin + Result := true; + o := p['mapping']; + if ObjectIsType(o, stObject) then + begin + i := TSuperAvlIterator.Create(o.AsObject); + try + i.First; + e := i.GetIter; + while e <> nil do + begin + if list.AsObject.Search(e.Name) = nil then + list[e.Name] := e.Value; + i.Next; + e := i.GetIter; + end; + + finally + i.Free; + end; + end; + + o := p['inherit']; + if ObjectIsType(o, stString) then + begin + e := names.AsObject.Search(o.AsString); + if (e <> nil) then + GetInheritedFieldList(list, e.Value); + end; + end; + + function CheckEnum(o: ISuperObject; p: ISuperObject; name: SOString = ''): boolean; + var + enum: ISuperObject; + i: integer; + begin + Result := false; + enum := FindInheritedProperty('enum', p); + case ObjectGetType(enum) of + stArray: + for i := 0 to enum.AsArray.Length - 1 do + if (o.AsString = enum.AsArray[i].AsString) then + begin + Result := true; + exit; + end; + stNull: Result := true; + else + Result := false; + if assigned(callback) then + callback(sender, veRuleMalformated, ''); + Exit; + end; + + if (not Result) and assigned(callback) then + callback(sender, veValueNotInEnum, name); + end; + + function CheckLength(len: integer; p: ISuperObject; const objpath: SOString): boolean; + var + length, o: ISuperObject; + begin + result := true; + length := FindInheritedProperty('length', p); + case ObjectGetType(length) of + stObject: + begin + o := length.AsObject.GetO('min'); + if (o <> nil) and (o.AsInteger > len) then + begin + Result := false; + if assigned(callback) then + callback(sender, veInvalidLength, objpath); + end; + o := length.AsObject.GetO('max'); + if (o <> nil) and (o.AsInteger < len) then + begin + Result := false; + if assigned(callback) then + callback(sender, veInvalidLength, objpath); + end; + o := length.AsObject.GetO('minex'); + if (o <> nil) and (o.AsInteger >= len) then + begin + Result := false; + if assigned(callback) then + callback(sender, veInvalidLength, objpath); + end; + o := length.AsObject.GetO('maxex'); + if (o <> nil) and (o.AsInteger <= len) then + begin + Result := false; + if assigned(callback) then + callback(sender, veInvalidLength, objpath); + end; + end; + stNull: ; + else + Result := false; + if assigned(callback) then + callback(sender, veRuleMalformated, ''); + end; + end; + + function CheckRange(obj: ISuperObject; p: ISuperObject; const objpath: SOString): boolean; + var + length, o: ISuperObject; + begin + result := true; + length := FindInheritedProperty('range', p); + case ObjectGetType(length) of + stObject: + begin + o := length.AsObject.GetO('min'); + if (o <> nil) and (o.Compare(obj) = cpGreat) then + begin + Result := false; + if assigned(callback) then + callback(sender, veInvalidRange, objpath); + end; + o := length.AsObject.GetO('max'); + if (o <> nil) and (o.Compare(obj) = cpLess) then + begin + Result := false; + if assigned(callback) then + callback(sender, veInvalidRange, objpath); + end; + o := length.AsObject.GetO('minex'); + if (o <> nil) and (o.Compare(obj) in [cpGreat, cpEqu]) then + begin + Result := false; + if assigned(callback) then + callback(sender, veInvalidRange, objpath); + end; + o := length.AsObject.GetO('maxex'); + if (o <> nil) and (o.Compare(obj) in [cpLess, cpEqu]) then + begin + Result := false; + if assigned(callback) then + callback(sender, veInvalidRange, objpath); + end; + end; + stNull: ; + else + Result := false; + if assigned(callback) then + callback(sender, veRuleMalformated, ''); + end; + end; + + + function process(o: ISuperObject; p: ISuperObject; objpath: SOString = ''): boolean; + var + ite: TSuperAvlIterator; + ent: TSuperAvlEntry; + p2, o2, sequence: ISuperObject; + s: SOString; + i: integer; + uniquelist, fieldlist: ISuperObject; + begin + Result := true; + if (o = nil) then + begin + if getInheritedBool('required', p) then + begin + if assigned(callback) then + callback(sender, veFieldIsRequired, objpath); + result := false; + end; + end else + case FindDataType(p) of + dtStr: + case ObjectGetType(o) of + stString: + begin + Result := Result and CheckLength(Length(o.AsString), p, objpath); + Result := Result and CheckRange(o, p, objpath); + end; + else + if assigned(callback) then + callback(sender, veInvalidDataType, objpath); + result := false; + end; + dtBool: + case ObjectGetType(o) of + stBoolean: + begin + Result := Result and CheckRange(o, p, objpath); + end; + else + if assigned(callback) then + callback(sender, veInvalidDataType, objpath); + result := false; + end; + dtInt: + case ObjectGetType(o) of + stInt: + begin + Result := Result and CheckRange(o, p, objpath); + end; + else + if assigned(callback) then + callback(sender, veInvalidDataType, objpath); + result := false; + end; + dtFloat: + case ObjectGetType(o) of + stDouble, stCurrency: + begin + Result := Result and CheckRange(o, p, objpath); + end; + else + if assigned(callback) then + callback(sender, veInvalidDataType, objpath); + result := false; + end; + dtMap: + case ObjectGetType(o) of + stObject: + begin + // all objects have and match a rule ? + ite := TSuperAvlIterator.Create(o.AsObject); + try + ite.First; + ent := ite.GetIter; + while ent <> nil do + begin + p2 := FindInheritedField(ent.Name, p); + if ObjectIsType(p2, stObject) then + result := process(ent.Value, p2, objpath + '.' + ent.Name) and result else + begin + if assigned(callback) then + callback(sender, veUnexpectedField, objpath + '.' + ent.Name); + result := false; // field have no rule + end; + ite.Next; + ent := ite.GetIter; + end; + finally + ite.Free; + end; + + // all expected field exists ? + Result := InheritedFieldExist(o, p, objpath) and Result; + end; + stNull: {nop}; + else + result := false; + if assigned(callback) then + callback(sender, veRuleMalformated, objpath); + end; + dtSeq: + case ObjectGetType(o) of + stArray: + begin + sequence := FindInheritedProperty('sequence', p); + if sequence <> nil then + case ObjectGetType(sequence) of + stObject: + begin + for i := 0 to o.AsArray.Length - 1 do + result := process(o.AsArray.GetO(i), sequence, objpath + '[' + IntToStr(i) + ']') and result; + if getInheritedBool('unique', sequence) then + begin + // type is unique ? + uniquelist := TSuperObject.Create(stObject); + try + for i := 0 to o.AsArray.Length - 1 do + begin + s := o.AsArray.GetO(i).AsString; + if (s <> '') then + begin + if uniquelist.AsObject.Search(s) = nil then + uniquelist[s] := nil else + begin + Result := False; + if Assigned(callback) then + callback(sender, veDuplicateEntry, objpath + '[' + IntToStr(i) + ']'); + end; + end; + end; + finally + uniquelist := nil; + end; + end; + + // field is unique ? + if (FindDataType(sequence) = dtMap) then + begin + fieldlist := TSuperObject.Create(stObject); + try + GetInheritedFieldList(fieldlist, sequence); + ite := TSuperAvlIterator.Create(fieldlist.AsObject); + try + ite.First; + ent := ite.GetIter; + while ent <> nil do + begin + if getInheritedBool('unique', ent.Value) then + begin + uniquelist := TSuperObject.Create(stObject); + try + for i := 0 to o.AsArray.Length - 1 do + begin + o2 := o.AsArray.GetO(i); + if o2 <> nil then + begin + s := o2.AsObject.GetO(ent.Name).AsString; + if (s <> '') then + if uniquelist.AsObject.Search(s) = nil then + uniquelist[s] := nil else + begin + Result := False; + if Assigned(callback) then + callback(sender, veDuplicateEntry, objpath + '[' + IntToStr(i) + '].' + ent.name); + end; + end; + end; + finally + uniquelist := nil; + end; + end; + ite.Next; + ent := ite.GetIter; + end; + finally + ite.Free; + end; + finally + fieldlist := nil; + end; + end; + + + end; + stNull: {nop}; + else + result := false; + if assigned(callback) then + callback(sender, veRuleMalformated, objpath); + end; + Result := Result and CheckLength(o.AsArray.Length, p, objpath); + + end; + else + result := false; + if assigned(callback) then + callback(sender, veRuleMalformated, objpath); + end; + dtNumber: + case ObjectGetType(o) of + stInt, + stDouble, stCurrency: + begin + Result := Result and CheckRange(o, p, objpath); + end; + else + if assigned(callback) then + callback(sender, veInvalidDataType, objpath); + result := false; + end; + dtText: + case ObjectGetType(o) of + stInt, + stDouble, + stCurrency, + stString: + begin + result := result and CheckLength(Length(o.AsString), p, objpath); + Result := Result and CheckRange(o, p, objpath); + end; + else + if assigned(callback) then + callback(sender, veInvalidDataType, objpath); + result := false; + end; + dtScalar: + case ObjectGetType(o) of + stBoolean, + stDouble, + stCurrency, + stInt, + stString: + begin + result := result and CheckLength(Length(o.AsString), p, objpath); + Result := Result and CheckRange(o, p, objpath); + end; + else + if assigned(callback) then + callback(sender, veInvalidDataType, objpath); + result := false; + end; + dtAny:; + else + if assigned(callback) then + callback(sender, veRuleMalformated, objpath); + result := false; + end; + Result := Result and CheckEnum(o, p, objpath) + + end; +var + j: integer; + +begin + Result := False; + datatypes := TSuperObject.Create(stObject); + names := TSuperObject.Create; + try + datatypes.I['str'] := ord(dtStr); + datatypes.I['int'] := ord(dtInt); + datatypes.I['float'] := ord(dtFloat); + datatypes.I['number'] := ord(dtNumber); + datatypes.I['text'] := ord(dtText); + datatypes.I['bool'] := ord(dtBool); + datatypes.I['map'] := ord(dtMap); + datatypes.I['seq'] := ord(dtSeq); + datatypes.I['scalar'] := ord(dtScalar); + datatypes.I['any'] := ord(dtAny); + + if ObjectIsType(defs, stArray) then + for j := 0 to defs.AsArray.Length - 1 do + if ObjectIsType(defs.AsArray[j], stObject) then + GetNames(defs.AsArray[j]) else + begin + if assigned(callback) then + callback(sender, veRuleMalformated, ''); + Exit; + end; + + + if ObjectIsType(rules, stObject) then + GetNames(rules) else + begin + if assigned(callback) then + callback(sender, veRuleMalformated, ''); + Exit; + end; + + Result := process(self, rules); + + finally + datatypes := nil; + names := nil; + end; +end; + +function TSuperObject._AddRef: Integer; stdcall; +begin + Result := InterlockedIncrement(FRefCount); +end; + +function TSuperObject._Release: Integer; stdcall; +begin + Result := InterlockedDecrement(FRefCount); + if Result = 0 then + Destroy; +end; + +function TSuperObject.Compare(const str: SOString): TSuperCompareResult; +begin + Result := Compare(TSuperObject.ParseString(PSOChar(str), False)); +end; + +function TSuperObject.Compare(const obj: ISuperObject): TSuperCompareResult; + function GetIntCompResult(const i: int64): TSuperCompareResult; + begin + if i < 0 then result := cpLess else + if i = 0 then result := cpEqu else + Result := cpGreat; + end; + + function GetDblCompResult(const d: double): TSuperCompareResult; + begin + if d < 0 then result := cpLess else + if d = 0 then result := cpEqu else + Result := cpGreat; + end; + +begin + case DataType of + stBoolean: + case ObjectGetType(obj) of + stBoolean: Result := GetIntCompResult(ord(FO.c_boolean) - ord(obj.AsBoolean)); + stDouble: Result := GetDblCompResult(ord(FO.c_boolean) - obj.AsDouble); + stCurrency:Result := GetDblCompResult(ord(FO.c_boolean) - obj.AsCurrency); + stInt: Result := GetIntCompResult(ord(FO.c_boolean) - obj.AsInteger); + stString: Result := GetIntCompResult(StrComp(PSOChar(AsString), PSOChar(obj.AsString))); + else + Result := cpError; + end; + stDouble: + case ObjectGetType(obj) of + stBoolean: Result := GetDblCompResult(FO.c_double - ord(obj.AsBoolean)); + stDouble: Result := GetDblCompResult(FO.c_double - obj.AsDouble); + stCurrency:Result := GetDblCompResult(FO.c_double - obj.AsCurrency); + stInt: Result := GetDblCompResult(FO.c_double - obj.AsInteger); + stString: Result := GetIntCompResult(StrComp(PSOChar(AsString), PSOChar(obj.AsString))); + else + Result := cpError; + end; + stCurrency: + case ObjectGetType(obj) of + stBoolean: Result := GetDblCompResult(FO.c_currency - ord(obj.AsBoolean)); + stDouble: Result := GetDblCompResult(FO.c_currency - obj.AsDouble); + stCurrency:Result := GetDblCompResult(FO.c_currency - obj.AsCurrency); + stInt: Result := GetDblCompResult(FO.c_currency - obj.AsInteger); + stString: Result := GetIntCompResult(StrComp(PSOChar(AsString), PSOChar(obj.AsString))); + else + Result := cpError; + end; + stInt: + case ObjectGetType(obj) of + stBoolean: Result := GetIntCompResult(FO.c_int - ord(obj.AsBoolean)); + stDouble: Result := GetDblCompResult(FO.c_int - obj.AsDouble); + stCurrency:Result := GetDblCompResult(FO.c_int - obj.AsCurrency); + stInt: Result := GetIntCompResult(FO.c_int - obj.AsInteger); + stString: Result := GetIntCompResult(StrComp(PSOChar(AsString), PSOChar(obj.AsString))); + else + Result := cpError; + end; + stString: + case ObjectGetType(obj) of + stBoolean, + stDouble, + stCurrency, + stInt, + stString: Result := GetIntCompResult(StrComp(PSOChar(AsString), PSOChar(obj.AsString))); + else + Result := cpError; + end; + else + Result := cpError; + end; +end; + +{$IFDEF SUPER_METHOD} +function TSuperObject.AsMethod: TSuperMethod; +begin + if FDataType = stMethod then + Result := FO.c_method else + Result := nil; +end; +{$ENDIF} + +{$IFDEF SUPER_METHOD} +constructor TSuperObject.Create(m: TSuperMethod); +begin + Create(stMethod); + FO.c_method := m; +end; +{$ENDIF} + +{$IFDEF SUPER_METHOD} +function TSuperObject.GetM(const path: SOString): TSuperMethod; +var + v: ISuperObject; +begin + v := ParseString(PSOChar(path), False, True, Self); + if (v <> nil) and (ObjectGetType(v) = stMethod) then + Result := v.AsMethod else + Result := nil; +end; +{$ENDIF} + +{$IFDEF SUPER_METHOD} +procedure TSuperObject.PutM(const path: SOString; Value: TSuperMethod); +begin + ParseString(PSOChar(path), False, True, Self, [foCreatePath, foPutValue], TSuperObject.Create(Value)); +end; +{$ENDIF} + +{$IFDEF SUPER_METHOD} +function TSuperObject.call(const path: SOString; const param: ISuperObject): ISuperObject; +begin + Result := ParseString(PSOChar(path), False, True, Self, [foCallMethod], param); +end; +{$ENDIF} + +{$IFDEF SUPER_METHOD} +function TSuperObject.call(const path, param: SOString): ISuperObject; +begin + Result := ParseString(PSOChar(path), False, True, Self, [foCallMethod], TSuperObject.ParseString(PSOChar(param), False)); +end; +{$ENDIF} + +function TSuperObject.GetProcessing: boolean; +begin + Result := FProcessing; +end; + +procedure TSuperObject.SetDataPtr(const Value: Pointer); +begin + FDataPtr := Value; +end; + +procedure TSuperObject.SetProcessing(value: boolean); +begin + FProcessing := value; +end; + +{ TSuperArray } + +function TSuperArray.Add(const Data: ISuperObject): Integer; +begin + Result := FLength; + PutO(Result, data); +end; + +function TSuperArray.Add(Data: SuperInt): Integer; +begin + Result := Add(TSuperObject.Create(Data)); +end; + +function TSuperArray.Add(const Data: SOString): Integer; +begin + Result := Add(TSuperObject.Create(Data)); +end; + +function TSuperArray.Add(Data: Boolean): Integer; +begin + Result := Add(TSuperObject.Create(Data)); +end; + +function TSuperArray.Add(Data: Double): Integer; +begin + Result := Add(TSuperObject.Create(Data)); +end; + +function TSuperArray.AddC(const Data: Currency): Integer; +begin + Result := Add(TSuperObject.CreateCurrency(Data)); +end; + +function TSuperArray.Delete(index: Integer): ISuperObject; +begin + if (Index >= 0) and (Index < FLength) then + begin + Result := FArray^[index]; + FArray^[index] := nil; + Dec(FLength); + if Index < FLength then + begin + Move(FArray^[index + 1], FArray^[index], + (FLength - index) * SizeOf(Pointer)); + Pointer(FArray^[FLength]) := nil; + end; + end; +end; + +procedure TSuperArray.Insert(index: Integer; const value: ISuperObject); +begin + if (Index >= 0) then + if (index < FLength) then + begin + if FLength = FSize then + Expand(index); + if Index < FLength then + Move(FArray^[index], FArray^[index + 1], + (FLength - index) * SizeOf(Pointer)); + Pointer(FArray^[index]) := nil; + FArray^[index] := value; + Inc(FLength); + end else + PutO(index, value); +end; + +procedure TSuperArray.Clear(all: boolean); +var + j: Integer; +begin + for j := 0 to FLength - 1 do + if FArray^[j] <> nil then + begin + if all then + FArray^[j].Clear(all); + FArray^[j] := nil; + end; + FLength := 0; +end; + +procedure TSuperArray.Pack(all: boolean); +var + PackedCount, StartIndex, EndIndex, j: Integer; +begin + if FLength > 0 then + begin + PackedCount := 0; + StartIndex := 0; + repeat + while (StartIndex < FLength) and (FArray^[StartIndex] = nil) do + Inc(StartIndex); + if StartIndex < FLength then + begin + EndIndex := StartIndex; + while (EndIndex < FLength) and (FArray^[EndIndex] <> nil) do + Inc(EndIndex); + + Dec(EndIndex); + + if StartIndex > PackedCount then + Move(FArray^[StartIndex], FArray^[PackedCount], (EndIndex - StartIndex + 1) * SizeOf(Pointer)); + + Inc(PackedCount, EndIndex - StartIndex + 1); + StartIndex := EndIndex + 1; + end; + until StartIndex >= FLength; + FillChar(FArray^[PackedCount], (FLength - PackedCount) * sizeof(Pointer), 0); + FLength := PackedCount; + if all then + for j := 0 to FLength - 1 do + FArray^[j].Pack(all); + end; +end; + +constructor TSuperArray.Create; +begin + inherited Create; + FSize := SUPER_ARRAY_LIST_DEFAULT_SIZE; + FLength := 0; + GetMem(FArray, sizeof(Pointer) * FSize); + FillChar(FArray^, sizeof(Pointer) * FSize, 0); +end; + +destructor TSuperArray.Destroy; +begin + Clear; + FreeMem(FArray); + inherited; +end; + +procedure TSuperArray.Expand(max: Integer); +var + new_size: Integer; +begin + if (max < FSize) then + Exit; + if max < (FSize shl 1) then + new_size := (FSize shl 1) else + new_size := max + 1; + ReallocMem(FArray, new_size * sizeof(Pointer)); + FillChar(FArray^[FSize], (new_size - FSize) * sizeof(Pointer), 0); + FSize := new_size; +end; + +function TSuperArray.GetO(const index: Integer): ISuperObject; +begin + if(index >= FLength) then + Result := nil else + Result := FArray^[index]; +end; + +function TSuperArray.GetB(const index: integer): Boolean; +var + obj: ISuperObject; +begin + obj := GetO(index); + if obj <> nil then + Result := obj.AsBoolean else + Result := false; +end; + +function TSuperArray.GetD(const index: integer): Double; +var + obj: ISuperObject; +begin + obj := GetO(index); + if obj <> nil then + Result := obj.AsDouble else + Result := 0.0; +end; + +function TSuperArray.GetI(const index: integer): SuperInt; +var + obj: ISuperObject; +begin + obj := GetO(index); + if obj <> nil then + Result := obj.AsInteger else + Result := 0; +end; + +function TSuperArray.GetS(const index: integer): SOString; +var + obj: ISuperObject; +begin + obj := GetO(index); + if obj <> nil then + Result := obj.AsString else + Result := ''; +end; + +procedure TSuperArray.PutO(const index: Integer; const Value: ISuperObject); +begin + Expand(index); + FArray^[index] := value; + if(FLength <= index) then FLength := index + 1; +end; + +function TSuperArray.GetN(const index: integer): ISuperObject; +begin + Result := GetO(index); + if Result = nil then + Result := TSuperObject.Create(stNull); +end; + +procedure TSuperArray.PutN(const index: integer; const Value: ISuperObject); +begin + if Value <> nil then + PutO(index, Value) else + PutO(index, TSuperObject.Create(stNull)); +end; + +procedure TSuperArray.PutB(const index: integer; Value: Boolean); +begin + PutO(index, TSuperObject.Create(Value)); +end; + +procedure TSuperArray.PutD(const index: integer; Value: Double); +begin + PutO(index, TSuperObject.Create(Value)); +end; + +function TSuperArray.GetC(const index: integer): Currency; +var + obj: ISuperObject; +begin + obj := GetO(index); + if obj <> nil then + Result := obj.AsCurrency else + Result := 0.0; +end; + +procedure TSuperArray.PutC(const index: integer; Value: Currency); +begin + PutO(index, TSuperObject.CreateCurrency(Value)); +end; + +procedure TSuperArray.PutI(const index: integer; Value: SuperInt); +begin + PutO(index, TSuperObject.Create(Value)); +end; + +procedure TSuperArray.PutS(const index: integer; const Value: SOString); +begin + PutO(index, TSuperObject.Create(Value)); +end; + +{$IFDEF SUPER_METHOD} +function TSuperArray.GetM(const index: integer): TSuperMethod; +var + v: ISuperObject; +begin + v := GetO(index); + if (ObjectGetType(v) = stMethod) then + Result := v.AsMethod else + Result := nil; +end; +{$ENDIF} + +{$IFDEF SUPER_METHOD} +procedure TSuperArray.PutM(const index: integer; Value: TSuperMethod); +begin + PutO(index, TSuperObject.Create(Value)); +end; +{$ENDIF} + +{ TSuperWriterString } + +function TSuperWriterString.Append(buf: PSOChar; Size: Integer): Integer; + function max(a, b: Integer): integer; begin if a > b then Result := a else Result := b end; +begin + Result := size; + if Size > 0 then + begin + if (FSize - FBPos <= size) then + begin + FSize := max(FSize * 2, FBPos + size + 8); + ReallocMem(FBuf, FSize * SizeOf(SOChar)); + end; + // fast move + case size of + 1: FBuf[FBPos] := buf^; + 2: PInteger(@FBuf[FBPos])^ := PInteger(buf)^; + 4: PInt64(@FBuf[FBPos])^ := PInt64(buf)^; + else + move(buf^, FBuf[FBPos], size * SizeOf(SOChar)); + end; + inc(FBPos, size); + FBuf[FBPos] := #0; + end; +end; + +function TSuperWriterString.Append(buf: PSOChar): Integer; +begin + Result := Append(buf, strlen(buf)); +end; + +constructor TSuperWriterString.Create; +begin + inherited; + FSize := 32; + FBPos := 0; + GetMem(FBuf, FSize * SizeOf(SOChar)); +end; + +destructor TSuperWriterString.Destroy; +begin + inherited; + if FBuf <> nil then + FreeMem(FBuf) +end; + +function TSuperWriterString.GetString: SOString; +begin + SetString(Result, FBuf, FBPos); +end; + +procedure TSuperWriterString.Reset; +begin + FBuf[0] := #0; + FBPos := 0; +end; + +procedure TSuperWriterString.TrimRight; +begin + while (FBPos > 0) and (FBuf[FBPos-1] < #256) and (AnsiChar(FBuf[FBPos-1]) in [#32, #13, #10]) do + begin + dec(FBPos); + FBuf[FBPos] := #0; + end; +end; + +{ TSuperWriterStream } + +function TSuperWriterStream.Append(buf: PSOChar): Integer; +begin + Result := Append(buf, StrLen(buf)); +end; + +constructor TSuperWriterStream.Create(AStream: TStream); +begin + inherited Create; + FStream := AStream; +end; + +procedure TSuperWriterStream.Reset; +begin + FStream.Size := 0; +end; + +{ TSuperWriterStream } + +function TSuperAnsiWriterStream.Append(buf: PSOChar; Size: Integer): Integer; +var + Buffer: array[0..1023] of AnsiChar; + pBuffer: PAnsiChar; + i: Integer; +begin + if Size = 1 then + Result := FStream.Write(buf^, Size) else + begin + if Size > SizeOf(Buffer) then + GetMem(pBuffer, Size) else + pBuffer := @Buffer; + try + for i := 0 to Size - 1 do + pBuffer[i] := AnsiChar(buf[i]); + Result := FStream.Write(pBuffer^, Size); + finally + if pBuffer <> @Buffer then + FreeMem(pBuffer); + end; + end; +end; + +{ TSuperUnicodeWriterStream } + +function TSuperUnicodeWriterStream.Append(buf: PSOChar; Size: Integer): Integer; +begin + Result := FStream.Write(buf^, Size * 2); +end; + +{ TSuperWriterFake } + +function TSuperWriterFake.Append(buf: PSOChar; Size: Integer): Integer; +begin + inc(FSize, Size); + Result := FSize; +end; + +function TSuperWriterFake.Append(buf: PSOChar): Integer; +begin + inc(FSize, Strlen(buf)); + Result := FSize; +end; + +constructor TSuperWriterFake.Create; +begin + inherited Create; + FSize := 0; +end; + +procedure TSuperWriterFake.Reset; +begin + FSize := 0; +end; + +{ TSuperWriterSock } + +function TSuperWriterSock.Append(buf: PSOChar; Size: Integer): Integer; +var + Buffer: array[0..1023] of AnsiChar; + pBuffer: PAnsiChar; + i: Integer; +begin + if Size = 1 then +{$IFDEF FPC} + Result := fpsend(FSocket, buf, size, 0) else +{$ELSE} + Result := send(FSocket, buf^, size, 0) else +{$ENDIF} + begin + if Size > SizeOf(Buffer) then + GetMem(pBuffer, Size) else + pBuffer := @Buffer; + try + for i := 0 to Size - 1 do + pBuffer[i] := AnsiChar(buf[i]); +{$IFDEF FPC} + Result := fpsend(FSocket, pBuffer, size, 0); +{$ELSE} + Result := send(FSocket, pBuffer^, size, 0); +{$ENDIF} + finally + if pBuffer <> @Buffer then + FreeMem(pBuffer); + end; + end; + inc(FSize, Result); +end; + +function TSuperWriterSock.Append(buf: PSOChar): Integer; +begin + Result := Append(buf, StrLen(buf)); +end; + +constructor TSuperWriterSock.Create(ASocket: Integer); +begin + inherited Create; + FSocket := ASocket; + FSize := 0; +end; + +procedure TSuperWriterSock.Reset; +begin + FSize := 0; +end; + +{ TSuperTokenizer } + +constructor TSuperTokenizer.Create; +begin + pb := TSuperWriterString.Create; + line := 1; + col := 0; + Reset; +end; + +destructor TSuperTokenizer.Destroy; +begin + Reset; + pb.Free; + inherited; +end; + +procedure TSuperTokenizer.Reset; +var + i: integer; +begin + for i := depth downto 0 do + ResetLevel(i); + depth := 0; + err := teSuccess; +end; + +procedure TSuperTokenizer.ResetLevel(adepth: integer); +begin + stack[adepth].state := tsEatws; + stack[adepth].saved_state := tsStart; + stack[adepth].current := nil; + stack[adepth].field_name := ''; + stack[adepth].obj := nil; + stack[adepth].parent := nil; + stack[adepth].gparent := nil; +end; + +{ TSuperAvlTree } + +constructor TSuperAvlTree.Create; +begin + FRoot := nil; + FCount := 0; +end; + +destructor TSuperAvlTree.Destroy; +begin + Clear; + inherited; +end; + +function TSuperAvlTree.IsEmpty: boolean; +begin + result := FRoot = nil; +end; + +function TSuperAvlTree.balance(bal: TSuperAvlEntry): TSuperAvlEntry; +var + deep, old: TSuperAvlEntry; + bf: integer; +begin + if (bal.FBf > 0) then + begin + deep := bal.FGt; + if (deep.FBf < 0) then + begin + old := bal; + bal := deep.FLt; + old.FGt := bal.FLt; + deep.FLt := bal.FGt; + bal.FLt := old; + bal.FGt := deep; + bf := bal.FBf; + if (bf <> 0) then + begin + if (bf > 0) then + begin + old.FBf := -1; + deep.FBf := 0; + end else + begin + deep.FBf := 1; + old.FBf := 0; + end; + bal.FBf := 0; + end else + begin + old.FBf := 0; + deep.FBf := 0; + end; + end else + begin + bal.FGt := deep.FLt; + deep.FLt := bal; + if (deep.FBf = 0) then + begin + deep.FBf := -1; + bal.FBf := 1; + end else + begin + deep.FBf := 0; + bal.FBf := 0; + end; + bal := deep; + end; + end else + begin + (* "Less than" subtree is deeper. *) + + deep := bal.FLt; + if (deep.FBf > 0) then + begin + old := bal; + bal := deep.FGt; + old.FLt := bal.FGt; + deep.FGt := bal.FLt; + bal.FGt := old; + bal.FLt := deep; + + bf := bal.FBf; + if (bf <> 0) then + begin + if (bf < 0) then + begin + old.FBf := 1; + deep.FBf := 0; + end else + begin + deep.FBf := -1; + old.FBf := 0; + end; + bal.FBf := 0; + end else + begin + old.FBf := 0; + deep.FBf := 0; + end; + end else + begin + bal.FLt := deep.FGt; + deep.FGt := bal; + if (deep.FBf = 0) then + begin + deep.FBf := 1; + bal.FBf := -1; + end else + begin + deep.FBf := 0; + bal.FBf := 0; + end; + bal := deep; + end; + end; + Result := bal; +end; + +function TSuperAvlTree.Insert(h: TSuperAvlEntry): TSuperAvlEntry; +var + unbal, parentunbal, hh, parent: TSuperAvlEntry; + depth, unbaldepth: longint; + cmp: integer; + unbalbf: integer; + branch: TSuperAvlBitArray; + p: Pointer; +begin + inc(FCount); + h.FLt := nil; + h.FGt := nil; + h.FBf := 0; + branch := []; + + if (FRoot = nil) then + FRoot := h + else + begin + unbal := nil; + parentunbal := nil; + depth := 0; + unbaldepth := 0; + hh := FRoot; + parent := nil; + repeat + if (hh.FBf <> 0) then + begin + unbal := hh; + parentunbal := parent; + unbaldepth := depth; + end; + if hh.FHash <> h.FHash then + begin + if hh.FHash < h.FHash then cmp := -1 else + if hh.FHash > h.FHash then cmp := 1 else + cmp := 0; + end else + cmp := CompareNodeNode(h, hh); + if (cmp = 0) then + begin + Result := hh; + //exchange data + p := hh.Ptr; + hh.FPtr := h.Ptr; + h.FPtr := p; + doDeleteEntry(h, false); + dec(FCount); + exit; + end; + parent := hh; + if (cmp > 0) then + begin + hh := hh.FGt; + include(branch, depth); + end else + begin + hh := hh.FLt; + exclude(branch, depth); + end; + inc(depth); + until (hh = nil); + + if (cmp < 0) then + parent.FLt := h else + parent.FGt := h; + + depth := unbaldepth; + + if (unbal = nil) then + hh := FRoot + else + begin + if depth in branch then + cmp := 1 else + cmp := -1; + inc(depth); + unbalbf := unbal.FBf; + if (cmp < 0) then + dec(unbalbf) else + inc(unbalbf); + if cmp < 0 then + hh := unbal.FLt else + hh := unbal.FGt; + if ((unbalbf <> -2) and (unbalbf <> 2)) then + begin + unbal.FBf := unbalbf; + unbal := nil; + end; + end; + + if (hh <> nil) then + while (h <> hh) do + begin + if depth in branch then + cmp := 1 else + cmp := -1; + inc(depth); + if (cmp < 0) then + begin + hh.FBf := -1; + hh := hh.FLt; + end else (* cmp > 0 *) + begin + hh.FBf := 1; + hh := hh.FGt; + end; + end; + + if (unbal <> nil) then + begin + unbal := balance(unbal); + if (parentunbal = nil) then + FRoot := unbal + else + begin + depth := unbaldepth - 1; + if depth in branch then + cmp := 1 else + cmp := -1; + if (cmp < 0) then + parentunbal.FLt := unbal else + parentunbal.FGt := unbal; + end; + end; + end; + result := h; +end; + +function TSuperAvlTree.Search(const k: SOString; st: TSuperAvlSearchTypes): TSuperAvlEntry; +var + cmp, target_cmp: integer; + match_h, h: TSuperAvlEntry; + ha: Cardinal; +begin + ha := TSuperAvlEntry.Hash(k); + + match_h := nil; + h := FRoot; + + if (stLess in st) then + target_cmp := 1 else + if (stGreater in st) then + target_cmp := -1 else + target_cmp := 0; + + while (h <> nil) do + begin + if h.FHash < ha then cmp := -1 else + if h.FHash > ha then cmp := 1 else + cmp := 0; + + if cmp = 0 then + cmp := CompareKeyNode(PSOChar(k), h); + if (cmp = 0) then + begin + if (stEqual in st) then + begin + match_h := h; + break; + end; + cmp := -target_cmp; + end + else + if (target_cmp <> 0) then + if ((cmp xor target_cmp) and SUPER_AVL_MASK_HIGH_BIT) = 0 then + match_h := h; + if cmp < 0 then + h := h.FLt else + h := h.FGt; + end; + result := match_h; +end; + +function TSuperAvlTree.Delete(const k: SOString): ISuperObject; +var + depth, rm_depth: longint; + branch: TSuperAvlBitArray; + h, parent, child, path, rm, parent_rm: TSuperAvlEntry; + cmp, cmp_shortened_sub_with_path, reduced_depth, bf: integer; + ha: Cardinal; +begin + ha := TSuperAvlEntry.Hash(k); + cmp_shortened_sub_with_path := 0; + branch := []; + + depth := 0; + h := FRoot; + parent := nil; + while true do + begin + if (h = nil) then + exit; + if h.FHash < ha then cmp := -1 else + if h.FHash > ha then cmp := 1 else + cmp := 0; + + if cmp = 0 then + cmp := CompareKeyNode(k, h); + if (cmp = 0) then + break; + parent := h; + if (cmp > 0) then + begin + h := h.FGt; + include(branch, depth) + end else + begin + h := h.FLt; + exclude(branch, depth) + end; + inc(depth); + cmp_shortened_sub_with_path := cmp; + end; + rm := h; + parent_rm := parent; + rm_depth := depth; + + if (h.FBf < 0) then + begin + child := h.FLt; + exclude(branch, depth); + cmp := -1; + end else + begin + child := h.FGt; + include(branch, depth); + cmp := 1; + end; + inc(depth); + + if (child <> nil) then + begin + cmp := -cmp; + repeat + parent := h; + h := child; + if (cmp < 0) then + begin + child := h.FLt; + exclude(branch, depth); + end else + begin + child := h.FGt; + include(branch, depth); + end; + inc(depth); + until (child = nil); + + if (parent = rm) then + cmp_shortened_sub_with_path := -cmp else + cmp_shortened_sub_with_path := cmp; + + if cmp > 0 then + child := h.FLt else + child := h.FGt; + end; + + if (parent = nil) then + FRoot := child else + if (cmp_shortened_sub_with_path < 0) then + parent.FLt := child else + parent.FGt := child; + + if parent = rm then + path := h else + path := parent; + + if (h <> rm) then + begin + h.FLt := rm.FLt; + h.FGt := rm.FGt; + h.FBf := rm.FBf; + if (parent_rm = nil) then + FRoot := h + else + begin + depth := rm_depth - 1; + if (depth in branch) then + parent_rm.FGt := h else + parent_rm.FLt := h; + end; + end; + + if (path <> nil) then + begin + h := FRoot; + parent := nil; + depth := 0; + while (h <> path) do + begin + if (depth in branch) then + begin + child := h.FGt; + h.FGt := parent; + end else + begin + child := h.FLt; + h.FLt := parent; + end; + inc(depth); + parent := h; + h := child; + end; + + reduced_depth := 1; + cmp := cmp_shortened_sub_with_path; + while true do + begin + if (reduced_depth <> 0) then + begin + bf := h.FBf; + if (cmp < 0) then + inc(bf) else + dec(bf); + if ((bf = -2) or (bf = 2)) then + begin + h := balance(h); + bf := h.FBf; + end else + h.FBf := bf; + reduced_depth := integer(bf = 0); + end; + if (parent = nil) then + break; + child := h; + h := parent; + dec(depth); + if depth in branch then + cmp := 1 else + cmp := -1; + if (cmp < 0) then + begin + parent := h.FLt; + h.FLt := child; + end else + begin + parent := h.FGt; + h.FGt := child; + end; + end; + FRoot := h; + end; + if rm <> nil then + begin + Result := rm.GetValue; + doDeleteEntry(rm, false); + dec(FCount); + end; +end; + +procedure TSuperAvlTree.Pack(all: boolean); +var + node1, node2: TSuperAvlEntry; + list: TList; + i: Integer; +begin + node1 := FRoot; + list := TList.Create; + while node1 <> nil do + begin + if (node1.FLt = nil) then + begin + node2 := node1.FGt; + if (node1.FPtr = nil) then + list.Add(node1) else + if all then + node1.Value.Pack(all); + end + else + begin + node2 := node1.FLt; + node1.FLt := node2.FGt; + node2.FGt := node1; + end; + node1 := node2; + end; + for i := 0 to list.Count - 1 do + Delete(TSuperAvlEntry(list[i]).FName); + list.Free; +end; + +procedure TSuperAvlTree.Clear(all: boolean); +var + node1, node2: TSuperAvlEntry; +begin + node1 := FRoot; + while node1 <> nil do + begin + if (node1.FLt = nil) then + begin + node2 := node1.FGt; + doDeleteEntry(node1, all); + end + else + begin + node2 := node1.FLt; + node1.FLt := node2.FGt; + node2.FGt := node1; + end; + node1 := node2; + end; + FRoot := nil; + FCount := 0; +end; + +function TSuperAvlTree.CompareKeyNode(const k: SOString; h: TSuperAvlEntry): integer; +begin + Result := StrComp(PSOChar(k), PSOChar(h.FName)); +end; + +function TSuperAvlTree.CompareNodeNode(node1, node2: TSuperAvlEntry): integer; +begin + Result := StrComp(PSOChar(node1.FName), PSOChar(node2.FName)); +end; + +{ TSuperAvlIterator } + +(* Initialize depth to invalid value, to indicate iterator is +** invalid. (Depth is zero-base.) It's not necessary to initialize +** iterators prior to passing them to the "start" function. +*) + +constructor TSuperAvlIterator.Create(tree: TSuperAvlTree); +begin + FDepth := not 0; + FTree := tree; +end; + +procedure TSuperAvlIterator.Search(const k: SOString; st: TSuperAvlSearchTypes); +var + h: TSuperAvlEntry; + d: longint; + cmp, target_cmp: integer; + ha: Cardinal; +begin + ha := TSuperAvlEntry.Hash(k); + h := FTree.FRoot; + d := 0; + FDepth := not 0; + if (h = nil) then + exit; + + if (stLess in st) then + target_cmp := 1 else + if (stGreater in st) then + target_cmp := -1 else + target_cmp := 0; + + while true do + begin + if h.FHash < ha then cmp := -1 else + if h.FHash > ha then cmp := 1 else + cmp := 0; + + if cmp = 0 then + cmp := FTree.CompareKeyNode(k, h); + if (cmp = 0) then + begin + if (stEqual in st) then + begin + FDepth := d; + break; + end; + cmp := -target_cmp; + end + else + if (target_cmp <> 0) then + if ((cmp xor target_cmp) and SUPER_AVL_MASK_HIGH_BIT) = 0 then + FDepth := d; + if cmp < 0 then + h := h.FLt else + h := h.FGt; + if (h = nil) then + break; + if (cmp > 0) then + include(FBranch, d) else + exclude(FBranch, d); + FPath[d] := h; + inc(d); + end; +end; + +procedure TSuperAvlIterator.First; +var + h: TSuperAvlEntry; +begin + h := FTree.FRoot; + FDepth := not 0; + FBranch := []; + while (h <> nil) do + begin + if (FDepth <> not 0) then + FPath[FDepth] := h; + inc(FDepth); + h := h.FLt; + end; +end; + +procedure TSuperAvlIterator.Last; +var + h: TSuperAvlEntry; +begin + h := FTree.FRoot; + FDepth := not 0; + FBranch := [0..SUPER_AVL_MAX_DEPTH - 1]; + while (h <> nil) do + begin + if (FDepth <> not 0) then + FPath[FDepth] := h; + inc(FDepth); + h := h.FGt; + end; +end; + +function TSuperAvlIterator.MoveNext: boolean; +begin + if FDepth = not 0 then + First else + Next; + Result := GetIter <> nil; +end; + +function TSuperAvlIterator.GetIter: TSuperAvlEntry; +begin + if (FDepth = not 0) then + begin + result := nil; + exit; + end; + if FDepth = 0 then + Result := FTree.FRoot else + Result := FPath[FDepth - 1]; +end; + +procedure TSuperAvlIterator.Next; +var + h: TSuperAvlEntry; +begin + if (FDepth <> not 0) then + begin + if FDepth = 0 then + h := FTree.FRoot.FGt else + h := FPath[FDepth - 1].FGt; + + if (h = nil) then + repeat + if (FDepth = 0) then + begin + FDepth := not 0; + break; + end; + dec(FDepth); + until (not (FDepth in FBranch)) + else + begin + include(FBranch, FDepth); + FPath[FDepth] := h; + inc(FDepth); + while true do + begin + h := h.FLt; + if (h = nil) then + break; + exclude(FBranch, FDepth); + FPath[FDepth] := h; + inc(FDepth); + end; + end; + end; +end; + +procedure TSuperAvlIterator.Prior; +var + h: TSuperAvlEntry; +begin + if (FDepth <> not 0) then + begin + if FDepth = 0 then + h := FTree.FRoot.FLt else + h := FPath[FDepth - 1].FLt; + if (h = nil) then + repeat + if (FDepth = 0) then + begin + FDepth := not 0; + break; + end; + dec(FDepth); + until (FDepth in FBranch) + else + begin + exclude(FBranch, FDepth); + FPath[FDepth] := h; + inc(FDepth); + while true do + begin + h := h.FGt; + if (h = nil) then + break; + include(FBranch, FDepth); + FPath[FDepth] := h; + inc(FDepth); + end; + end; + end; +end; + +procedure TSuperAvlTree.doDeleteEntry(Entry: TSuperAvlEntry; all: boolean); +begin + Entry.Free; +end; + +function TSuperAvlTree.GetEnumerator: TSuperAvlIterator; +begin + Result := TSuperAvlIterator.Create(Self); +end; + +{ TSuperAvlEntry } + +constructor TSuperAvlEntry.Create(const AName: SOString; Obj: Pointer); +begin + FName := AName; + FPtr := Obj; + FHash := Hash(FName); +end; + +function TSuperAvlEntry.GetValue: ISuperObject; +begin + Result := ISuperObject(FPtr) +end; + +class function TSuperAvlEntry.Hash(const k: SOString): Cardinal; +var + h: cardinal; + i: Integer; +begin + h := 0; + for i := 1 to Length(k) do + h := h*129 + ord(k[i]) + $9e370001; + Result := h; +end; + +procedure TSuperAvlEntry.SetValue(const val: ISuperObject); +begin + ISuperObject(FPtr) := val; +end; + +{ TSuperTableString } + +function TSuperTableString.GetValues: ISuperObject; +var + ite: TSuperAvlIterator; + obj: TSuperAvlEntry; +begin + Result := TSuperObject.Create(stArray); + ite := TSuperAvlIterator.Create(Self); + try + ite.First; + obj := ite.GetIter; + while obj <> nil do + begin + Result.AsArray.Add(obj.Value); + ite.Next; + obj := ite.GetIter; + end; + finally + ite.Free; + end; +end; + +function TSuperTableString.GetNames: ISuperObject; +var + ite: TSuperAvlIterator; + obj: TSuperAvlEntry; +begin + Result := TSuperObject.Create(stArray); + ite := TSuperAvlIterator.Create(Self); + try + ite.First; + obj := ite.GetIter; + while obj <> nil do + begin + Result.AsArray.Add(TSuperObject.Create(obj.FName)); + ite.Next; + obj := ite.GetIter; + end; + finally + ite.Free; + end; +end; + +procedure TSuperTableString.doDeleteEntry(Entry: TSuperAvlEntry; all: boolean); +begin + if Entry.Ptr <> nil then + begin + if all then Entry.Value.Clear(true); + Entry.Value := nil; + end; + inherited; +end; + +function TSuperTableString.Find(const k: SOString; var value: ISuperObject): Boolean; +var + e: TSuperAvlEntry; +begin + e := Search(k); + if e <> nil then + begin + value := e.Value; + Result := True; + end else + Result := False; +end; + +function TSuperTableString.Exists(const k: SOString): Boolean; +begin + Result := Search(k) <> nil; +end; + +function TSuperTableString.GetO(const k: SOString): ISuperObject; +var + e: TSuperAvlEntry; +begin + e := Search(k); + if e <> nil then + Result := e.Value else + Result := nil +end; + +procedure TSuperTableString.PutO(const k: SOString; const value: ISuperObject); +var + entry: TSuperAvlEntry; +begin + entry := Insert(TSuperAvlEntry.Create(k, Pointer(value))); + if entry.FPtr <> nil then + ISuperObject(entry.FPtr)._AddRef; +end; + +procedure TSuperTableString.PutS(const k: SOString; const value: SOString); +begin + PutO(k, TSuperObject.Create(Value)); +end; + +function TSuperTableString.GetS(const k: SOString): SOString; +var + obj: ISuperObject; +begin + obj := GetO(k); + if obj <> nil then + Result := obj.AsString else + Result := ''; +end; + +procedure TSuperTableString.PutI(const k: SOString; value: SuperInt); +begin + PutO(k, TSuperObject.Create(Value)); +end; + +function TSuperTableString.GetI(const k: SOString): SuperInt; +var + obj: ISuperObject; +begin + obj := GetO(k); + if obj <> nil then + Result := obj.AsInteger else + Result := 0; +end; + +procedure TSuperTableString.PutD(const k: SOString; value: Double); +begin + PutO(k, TSuperObject.Create(Value)); +end; + +procedure TSuperTableString.PutC(const k: SOString; value: Currency); +begin + PutO(k, TSuperObject.CreateCurrency(Value)); +end; + +function TSuperTableString.GetC(const k: SOString): Currency; +var + obj: ISuperObject; +begin + obj := GetO(k); + if obj <> nil then + Result := obj.AsCurrency else + Result := 0.0; +end; + +function TSuperTableString.GetD(const k: SOString): Double; +var + obj: ISuperObject; +begin + obj := GetO(k); + if obj <> nil then + Result := obj.AsDouble else + Result := 0.0; +end; + +procedure TSuperTableString.PutB(const k: SOString; value: Boolean); +begin + PutO(k, TSuperObject.Create(Value)); +end; + +function TSuperTableString.GetB(const k: SOString): Boolean; +var + obj: ISuperObject; +begin + obj := GetO(k); + if obj <> nil then + Result := obj.AsBoolean else + Result := False; +end; + +{$IFDEF SUPER_METHOD} +procedure TSuperTableString.PutM(const k: SOString; value: TSuperMethod); +begin + PutO(k, TSuperObject.Create(Value)); +end; +{$ENDIF} + +{$IFDEF SUPER_METHOD} +function TSuperTableString.GetM(const k: SOString): TSuperMethod; +var + obj: ISuperObject; +begin + obj := GetO(k); + if obj <> nil then + Result := obj.AsMethod else + Result := nil; +end; +{$ENDIF} + +procedure TSuperTableString.PutN(const k: SOString; const value: ISuperObject); +begin + if value <> nil then + PutO(k, TSuperObject.Create(stNull)) else + PutO(k, value); +end; + +function TSuperTableString.GetN(const k: SOString): ISuperObject; +var + obj: ISuperObject; +begin + obj := GetO(k); + if obj <> nil then + Result := obj else + Result := TSuperObject.Create(stNull); +end; + + +{$IFDEF HAVE_RTTI} + +{ TSuperAttribute } + +constructor TSuperAttribute.Create(const AName: string); +begin + FName := AName; +end; + +{ TSuperRttiContext } + +constructor TSuperRttiContext.Create; +begin + Context := TRttiContext.Create; + SerialFromJson := TDictionary.Create; + SerialToJson := TDictionary.Create; + + SerialFromJson.Add(TypeInfo(Boolean), serialfromboolean); + SerialFromJson.Add(TypeInfo(TDateTime), serialfromdatetime); + SerialFromJson.Add(TypeInfo(TGUID), serialfromguid); + SerialToJson.Add(TypeInfo(Boolean), serialtoboolean); + SerialToJson.Add(TypeInfo(TDateTime), serialtodatetime); + SerialToJson.Add(TypeInfo(TGUID), serialtoguid); +end; + +destructor TSuperRttiContext.Destroy; +begin + SerialFromJson.Free; + SerialToJson.Free; + Context.Free; +end; + +class function TSuperRttiContext.GetFieldName(r: TRttiField): string; +var + o: TCustomAttribute; +begin + for o in r.GetAttributes do + if o is SOName then + Exit(SOName(o).Name); + Result := r.Name; +end; + +class function TSuperRttiContext.GetFieldDefault(r: TRttiField; const obj: ISuperObject): ISuperObject; +var + o: TCustomAttribute; +begin + if not ObjectIsType(obj, stNull) then Exit(obj); + for o in r.GetAttributes do + if o is SODefault then + Exit(SO(SODefault(o).Name)); + Result := obj; +end; + +function TSuperRttiContext.AsType(const obj: ISuperObject): T; +var + ret: TValue; +begin + if FromJson(TypeInfo(T), obj, ret) then + Result := ret.AsType else + raise exception.Create('Marshalling error'); +end; + +function TSuperRttiContext.AsJson(const obj: T; const index: ISuperObject = nil): ISuperObject; +var + v: TValue; +begin + TValue.Make(@obj, TypeInfo(T), v); + if index <> nil then + Result := ToJson(v, index) else + Result := ToJson(v, so); +end; + +function TSuperRttiContext.FromJson(TypeInfo: PTypeInfo; const obj: ISuperObject; + var Value: TValue): Boolean; + + procedure FromChar; + begin + if ObjectIsType(obj, stString) and (Length(obj.AsString) = 1) then + begin + Value := string(AnsiString(obj.AsString)[1]); + Result := True; + end else + Result := False; + end; + + procedure FromWideChar; + begin + if ObjectIsType(obj, stString) and (Length(obj.AsString) = 1) then + begin + Value := obj.AsString[1]; + Result := True; + end else + Result := False; + end; + + procedure FromInt64; + var + i: Int64; + begin + case ObjectGetType(obj) of + stInt: + begin + TValue.Make(nil, TypeInfo, Value); + TValueData(Value).FAsSInt64 := obj.AsInteger; + Result := True; + end; + stString: + begin + if TryStrToInt64(obj.AsString, i) then + begin + TValue.Make(nil, TypeInfo, Value); + TValueData(Value).FAsSInt64 := i; + Result := True; + end else + Result := False; + end; + else + Result := False; + end; + end; + + procedure FromInt(const obj: ISuperObject); + var + TypeData: PTypeData; + i: Integer; + o: ISuperObject; + begin + case ObjectGetType(obj) of + stInt, stBoolean: + begin + i := obj.AsInteger; + TypeData := GetTypeData(TypeInfo); + if TypeData.MaxValue > TypeData.MinValue then + Result := (i >= TypeData.MinValue) and (i <= TypeData.MaxValue) else + Result := (i >= TypeData.MinValue) and (i <= Int64(PCardinal(@TypeData.MaxValue)^)); + if Result then + TValue.Make(@i, TypeInfo, Value); + end; + stString: + begin + o := SO(obj.AsString); + if not ObjectIsType(o, stString) then + FromInt(o) else + Result := False; + end; + else + Result := False; + end; + end; + + procedure fromSet; + var + i: Integer; + begin + case ObjectGetType(obj) of + stInt: + begin + TValue.Make(nil, TypeInfo, Value); + TValueData(Value).FAsSLong := obj.AsInteger; + Result := True; + end; + stString: + begin + if TryStrToInt(obj.AsString, i) then + begin + TValue.Make(nil, TypeInfo, Value); + TValueData(Value).FAsSLong := i; + Result := True; + end else + Result := False; + end; + else + Result := False; + end; + end; + + procedure FromFloat(const obj: ISuperObject); + var + o: ISuperObject; + begin + case ObjectGetType(obj) of + stInt, stDouble, stCurrency: + begin + TValue.Make(nil, TypeInfo, Value); + case GetTypeData(TypeInfo).FloatType of + ftSingle: TValueData(Value).FAsSingle := obj.AsDouble; + ftDouble: TValueData(Value).FAsDouble := obj.AsDouble; + ftExtended: TValueData(Value).FAsExtended := obj.AsDouble; + ftComp: TValueData(Value).FAsSInt64 := obj.AsInteger; + ftCurr: TValueData(Value).FAsCurr := obj.AsCurrency; + end; + Result := True; + end; + stString: + begin + o := SO(obj.AsString); + if not ObjectIsType(o, stString) then + FromFloat(o) else + Result := False; + end + else + Result := False; + end; + end; + + procedure FromString; + begin + case ObjectGetType(obj) of + stObject, stArray: + Result := False; + stnull: + begin + Value := ''; + Result := True; + end; + else + Value := obj.AsString; + Result := True; + end; + end; + + procedure FromClass; + var + f: TRttiField; + v: TValue; + begin + case ObjectGetType(obj) of + stObject: + begin + Result := True; + if Value.Kind <> tkClass then + Value := GetTypeData(TypeInfo).ClassType.Create; + for f in Context.GetType(Value.AsObject.ClassType).GetFields do + if f.FieldType <> nil then + begin + v := TValue.Empty; + Result := FromJson(f.FieldType.Handle, GetFieldDefault(f, obj.AsObject[GetFieldName(f)]), v); + if Result then + f.SetValue(Value.AsObject, v) else + Exit; + end; + end; + stNull: + begin + Value := nil; + Result := True; + end + else + // error + Value := nil; + Result := False; + end; + end; + + procedure FromRecord; + var + f: TRttiField; + p: Pointer; + v: TValue; + begin + Result := True; + TValue.Make(nil, TypeInfo, Value); + for f in Context.GetType(TypeInfo).GetFields do + begin + if ObjectIsType(obj, stObject) and (f.FieldType <> nil) then + begin +{$IFDEF VER210} + p := IValueData(TValueData(Value).FHeapData).GetReferenceToRawData; +{$ELSE} + p := TValueData(Value).FValueData.GetReferenceToRawData; +{$ENDIF} + Result := FromJson(f.FieldType.Handle, GetFieldDefault(f, obj.AsObject[GetFieldName(f)]), v); + if Result then + f.SetValue(p, v) else + begin + //Writeln(f.Name); + Exit; + end; + end else + begin + Result := False; + Exit; + end; + end; + end; + + procedure FromDynArray; + var + i: Integer; + p: Pointer; + pb: PByte; + val: TValue; + typ: PTypeData; + el: PTypeInfo; + begin + case ObjectGetType(obj) of + stArray: + begin + i := obj.AsArray.Length; + p := nil; + DynArraySetLength(p, TypeInfo, 1, @i); + pb := p; + typ := GetTypeData(TypeInfo); + if typ.elType <> nil then + el := typ.elType^ else + el := typ.elType2^; + + Result := True; + for i := 0 to i - 1 do + begin + Result := FromJson(el, obj.AsArray[i], val); + if not Result then + Break; + val.ExtractRawData(pb); + val := TValue.Empty; + Inc(pb, typ.elSize); + end; + if Result then + TValue.MakeWithoutCopy(@p, TypeInfo, Value) else + DynArrayClear(p, TypeInfo); + end; + stNull: + begin + TValue.MakeWithoutCopy(nil, TypeInfo, Value); + Result := True; + end; + else + i := 1; + p := nil; + DynArraySetLength(p, TypeInfo, 1, @i); + pb := p; + typ := GetTypeData(TypeInfo); + if typ.elType <> nil then + el := typ.elType^ else + el := typ.elType2^; + + Result := FromJson(el, obj, val); + val.ExtractRawData(pb); + val := TValue.Empty; + + if Result then + TValue.MakeWithoutCopy(@p, TypeInfo, Value) else + DynArrayClear(p, TypeInfo); + end; + end; + + procedure FromArray; + var + ArrayData: PArrayTypeData; + idx: Integer; + function ProcessDim(dim: Byte; const o: ISuperobject): Boolean; + var + i: Integer; + v: TValue; + a: PTypeData; + begin + if ObjectIsType(o, stArray) and (ArrayData.Dims[dim-1] <> nil) then + begin + a := @GetTypeData(ArrayData.Dims[dim-1]^).ArrayData; + if (a.MaxValue - a.MinValue + 1) <> o.AsArray.Length then + begin + Result := False; + Exit; + end; + Result := True; + if dim = ArrayData.DimCount then + for i := a.MinValue to a.MaxValue do + begin + Result := FromJson(ArrayData.ElType^, o.AsArray[i], v); + if not Result then + Exit; + Value.SetArrayElement(idx, v); + inc(idx); + end + else + for i := a.MinValue to a.MaxValue do + begin + Result := ProcessDim(dim + 1, o.AsArray[i]); + if not Result then + Exit; + end; + end else + Result := False; + end; + var + i: Integer; + v: TValue; + begin + TValue.Make(nil, TypeInfo, Value); + ArrayData := @GetTypeData(TypeInfo).ArrayData; + idx := 0; + if ArrayData.DimCount = 1 then + begin + if ObjectIsType(obj, stArray) and (obj.AsArray.Length = ArrayData.ElCount) then + begin + Result := True; + for i := 0 to ArrayData.ElCount - 1 do + begin + Result := FromJson(ArrayData.ElType^, obj.AsArray[i], v); + if not Result then + Exit; + Value.SetArrayElement(idx, v); + v := TValue.Empty; + inc(idx); + end; + end else + Result := False; + end else + Result := ProcessDim(1, obj); + end; + + procedure FromClassRef; + var + r: TRttiType; + begin + if ObjectIsType(obj, stString) then + begin + r := Context.FindType(obj.AsString); + if r <> nil then + begin + Value := TRttiInstanceType(r).MetaclassType; + Result := True; + end else + Result := False; + end else + Result := False; + end; + + procedure FromUnknown; + begin + case ObjectGetType(obj) of + stBoolean: + begin + Value := obj.AsBoolean; + Result := True; + end; + stDouble: + begin + Value := obj.AsDouble; + Result := True; + end; + stCurrency: + begin + Value := obj.AsCurrency; + Result := True; + end; + stInt: + begin + Value := obj.AsInteger; + Result := True; + end; + stString: + begin + Value := obj.AsString; + Result := True; + end + else + Value := nil; + Result := False; + end; + end; + + procedure FromInterface; + const soguid: TGuid = '{4B86A9E3-E094-4E5A-954A-69048B7B6327}'; + var + o: ISuperObject; + begin + if CompareMem(@GetTypeData(TypeInfo).Guid, @soguid, SizeOf(TGUID)) then + begin + if obj <> nil then + TValue.Make(@obj, TypeInfo, Value) else + begin + o := TSuperObject.Create(stNull); + TValue.Make(@o, TypeInfo, Value); + end; + Result := True; + end else + Result := False; + end; +var + Serial: TSerialFromJson; +begin + + if TypeInfo <> nil then + begin + if not SerialFromJson.TryGetValue(TypeInfo, Serial) then + case TypeInfo.Kind of + tkChar: FromChar; + tkInt64: FromInt64; + tkEnumeration, tkInteger: FromInt(obj); + tkSet: fromSet; + tkFloat: FromFloat(obj); + tkString, tkLString, tkUString, tkWString: FromString; + tkClass: FromClass; + tkMethod: ; + tkWChar: FromWideChar; + tkRecord: FromRecord; + tkPointer: ; + tkInterface: FromInterface; + tkArray: FromArray; + tkDynArray: FromDynArray; + tkClassRef: FromClassRef; + else + FromUnknown + end else + begin + TValue.Make(nil, TypeInfo, Value); + Result := Serial(Self, obj, Value); + end; + end else + Result := False; +end; + +function TSuperRttiContext.ToJson(var value: TValue; const index: ISuperObject): ISuperObject; + procedure ToInt64; + begin + Result := TSuperObject.Create(SuperInt(Value.AsInt64)); + end; + + procedure ToChar; + begin + Result := TSuperObject.Create(string(Value.AsType)); + end; + + procedure ToInteger; + begin + Result := TSuperObject.Create(TValueData(Value).FAsSLong); + end; + + procedure ToFloat; + begin + case Value.TypeData.FloatType of + ftSingle: Result := TSuperObject.Create(TValueData(Value).FAsSingle); + ftDouble: Result := TSuperObject.Create(TValueData(Value).FAsDouble); + ftExtended: Result := TSuperObject.Create(TValueData(Value).FAsExtended); + ftComp: Result := TSuperObject.Create(TValueData(Value).FAsSInt64); + ftCurr: Result := TSuperObject.CreateCurrency(TValueData(Value).FAsCurr); + end; + end; + + procedure ToString; + begin + Result := TSuperObject.Create(string(Value.AsType)); + end; + + procedure ToClass; + var + o: ISuperObject; + f: TRttiField; + v: TValue; + begin + if TValueData(Value).FAsObject <> nil then + begin + o := index[IntToStr(NativeInt(Value.AsObject))]; + if o = nil then + begin + Result := TSuperObject.Create(stObject); + index[IntToStr(NativeInt(Value.AsObject))] := Result; + for f in Context.GetType(Value.AsObject.ClassType).GetFields do + if f.FieldType <> nil then + begin + v := f.GetValue(Value.AsObject); + Result.AsObject[GetFieldName(f)] := ToJson(v, index); + end + end else + Result := o; + end else + Result := nil; + end; + + procedure ToWChar; + begin + Result := TSuperObject.Create(string(Value.AsType)); + end; + + procedure ToVariant; + begin + Result := SO(Value.AsVariant); + end; + + procedure ToRecord; + var + f: TRttiField; + v: TValue; + begin + Result := TSuperObject.Create(stObject); + for f in Context.GetType(Value.TypeInfo).GetFields do + begin +{$IFDEF VER210} + v := f.GetValue(IValueData(TValueData(Value).FHeapData).GetReferenceToRawData); +{$ELSE} + v := f.GetValue(TValueData(Value).FValueData.GetReferenceToRawData); +{$ENDIF} + Result.AsObject[GetFieldName(f)] := ToJson(v, index); + end; + end; + + procedure ToArray; + var + idx: Integer; + ArrayData: PArrayTypeData; + + procedure ProcessDim(dim: Byte; const o: ISuperObject); + var + dt: PTypeData; + i: Integer; + o2: ISuperObject; + v: TValue; + begin + if ArrayData.Dims[dim-1] = nil then Exit; + dt := GetTypeData(ArrayData.Dims[dim-1]^); + if Dim = ArrayData.DimCount then + for i := dt.MinValue to dt.MaxValue do + begin + v := Value.GetArrayElement(idx); + o.AsArray.Add(toJSon(v, index)); + inc(idx); + end + else + for i := dt.MinValue to dt.MaxValue do + begin + o2 := TSuperObject.Create(stArray); + o.AsArray.Add(o2); + ProcessDim(dim + 1, o2); + end; + end; + var + i: Integer; + v: TValue; + begin + Result := TSuperObject.Create(stArray); + ArrayData := @Value.TypeData.ArrayData; + idx := 0; + if ArrayData.DimCount = 1 then + for i := 0 to ArrayData.ElCount - 1 do + begin + v := Value.GetArrayElement(i); + Result.AsArray.Add(toJSon(v, index)) + end + else + ProcessDim(1, Result); + end; + + procedure ToDynArray; + var + i: Integer; + v: TValue; + begin + Result := TSuperObject.Create(stArray); + for i := 0 to Value.GetArrayLength - 1 do + begin + v := Value.GetArrayElement(i); + Result.AsArray.Add(toJSon(v, index)); + end; + end; + + procedure ToClassRef; + begin + if TValueData(Value).FAsClass <> nil then + Result := TSuperObject.Create(string( + TValueData(Value).FAsClass.UnitName + '.' + + TValueData(Value).FAsClass.ClassName)) else + Result := nil; + end; + + procedure ToInterface; +{$IFNDEF VER210} + var + intf: IInterface; +{$ENDIF} + begin +{$IFDEF VER210} + if TValueData(Value).FHeapData <> nil then + TValueData(Value).FHeapData.QueryInterface(ISuperObject, Result) else + Result := nil; +{$ELSE} + if TValueData(Value).FValueData <> nil then + begin + intf := IInterface(PPointer(TValueData(Value).FValueData.GetReferenceToRawData)^); + if intf <> nil then + intf.QueryInterface(ISuperObject, Result) else + Result := nil; + end else + Result := nil; +{$ENDIF} + end; + +var + Serial: TSerialToJson; +begin + if not SerialToJson.TryGetValue(value.TypeInfo, Serial) then + case Value.Kind of + tkInt64: ToInt64; + tkChar: ToChar; + tkSet, tkInteger, tkEnumeration: ToInteger; + tkFloat: ToFloat; + tkString, tkLString, tkUString, tkWString: ToString; + tkClass: ToClass; + tkWChar: ToWChar; + tkVariant: ToVariant; + tkRecord: ToRecord; + tkArray: ToArray; + tkDynArray: ToDynArray; + tkClassRef: ToClassRef; + tkInterface: ToInterface; + else + result := nil; + end else + Result := Serial(Self, value, index); +end; + +{ TSuperObjectHelper } + +constructor TSuperObjectHelper.FromJson(const obj: ISuperObject; ctx: TSuperRttiContext = nil); +var + v: TValue; + ctxowned: Boolean; +begin + if ctx = nil then + begin + ctx := TSuperRttiContext.Create; + ctxowned := True; + end else + ctxowned := False; + try + v := Self; + if not ctx.FromJson(v.TypeInfo, obj, v) then + raise Exception.Create('Invalid object'); + finally + if ctxowned then + ctx.Free; + end; +end; + +constructor TSuperObjectHelper.FromJson(const str: string; ctx: TSuperRttiContext = nil); +begin + FromJson(SO(str), ctx); +end; + +function TSuperObjectHelper.ToJson(ctx: TSuperRttiContext = nil): ISuperObject; +var + v: TValue; + ctxowned: boolean; +begin + if ctx = nil then + begin + ctx := TSuperRttiContext.Create; + ctxowned := True; + end else + ctxowned := False; + try + v := Self; + Result := ctx.ToJson(v, SO); + finally + if ctxowned then + ctx.Free; + end; +end; + +{$ENDIF} + +{$IFDEF DEBUG} +initialization + +finalization + Assert(debugcount = 0, 'Memory leak'); +{$ENDIF} +end. + diff --git a/supertypes.dcu b/supertypes.dcu new file mode 100644 index 0000000000000000000000000000000000000000..0deaab1ec7721faa617da08db0b9d05de8bab278 GIT binary patch literal 573 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%0D&6!Ebkj$rn=yiJ#;9~N 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 + * Web site : http://www.progdigy.com + *) + + unit superxmlparser; +{$IFDEF FPC} + {$MODE OBJFPC}{$H+} +{$ENDIF} + +interface + +uses superobject, classes, supertypes; + +type + TOnProcessingInstruction = procedure(const PI, PIParent: ISuperObject); + +function XMLParseString(const data: SOString; pack: Boolean = false; onpi: TOnProcessingInstruction = nil): ISuperObject; +function XMLParseStream(stream: TStream; pack: Boolean = false; onpi: TOnProcessingInstruction = nil): ISuperObject; +function XMLParseFile(const FileName: string; pack: Boolean = false; onpi: TOnProcessingInstruction = nil): ISuperObject; + +{$IFDEF UNICODE} +type + TXMLWriteMethod = reference to procedure(const data: string); +procedure XMLWrite(const node: ISuperObject; const method: TXMLWriteMethod); +{$ENDIF} + +const + xmlname = '#name'; + xmlattributes = '#attributes'; + xmlchildren = '#children'; + xmltext = '#text'; + + dtdname = '#name'; + dtdPubidLiteral = '#pubidliteral'; + dtdSystemLiteral = '#systemliteral'; + + +implementation +uses sysutils {$IFNDEF UNIX}, windows{$ENDIF}; + +const + XML_SPACE : PSOChar = #32; +// XML_ARL: PSOChar = '['; + XML_ARR: PSOChar = ']'; + XML_BIG: PSOChar = '>'; + XML_LOW: PSOChar = '<'; + XML_AMP: PSOChar = '&'; + XML_SQU: PSOChar = ''''; + XML_DQU: PSOChar = '"'; + +type + TSuperXMLState = ( + xsStart, // | + xsEatSpaces, // + xsElement, // <| + xsElementName, // <[a..z]| + xsAttributes, // ..<| + xsCloseElementName, // ..| + xsElementString, // |azer + xsElementComment, // + xsElementPI, // + xsElementCDATA, // + xsEscape, // &| + xsEscape_lt, // &l|t; + xsEscape_gt, // &g|t; + xsEscape_amp, // &a|mp; + xsEscape_apos, // &a|pos; + xsEscape_quot, // &q|uot; + xsEscape_char, // &#|; + xsEscape_char_num, // |123456; + xsEscape_char_hex, // &#x|000FFff; + xsEnd); + + TSuperXMLError = (xeSuccess, xeContinue, xeProcessInst, xeError); + TSuperXMLElementClass = (xcNone, xcElement, xcComment, xcString, xcCdata, xcDocType, xcProcessInst); + TSuperXMLEncoding = ({$IFNDEF UNIX}xnANSI,{$ENDIF} xnUTF8, xnUnicode); + +{$IFDEF UNICODE} + procedure XMLWrite(const node: ISuperObject; const method: TXMLWriteMethod); + procedure Escape(const str: string); + var + p1, p2: PChar; + procedure push(const data: string); + begin + if p2 > p1 then + method(Copy(p1, 0, p2-p1)); + Inc(p2); + p1 := p2; + if data <> '' then + method(data); + end; + begin + p1 := PChar(str); + p2 := p1; + + while True do + case p2^ of + '<': push('<'); + '>': push('>'); + '&': push('&'); + '"': push('"'); + #0 : + begin + push(''); + Break; + end; + else + inc(p2); + end; + end; + var + o: ISuperObject; + ent: TSuperAvlEntry; + begin + method('<' + node.S[xmlname]); + if ObjectIsType(node[xmlattributes], stObject) then + for ent in node[xmlattributes].AsObject do + begin + method(' ' + ent.Name + '="'); + Escape(ent.Value.AsString); + method('"'); + end; + if ObjectIsType(node[xmlchildren], stArray) then + begin + method('>'); + for o in node[xmlchildren] do + if ObjectIsType(o, stString) then + Escape(o.AsString) else + XMLWrite(o, method); + method(''); + end else + method('/>'); + end; +{$ENDIF} + +type + PSuperXMLStack = ^TSuperXMLStack; + TSuperXMLStack = record + state: TSuperXMLState; + savedstate: TSuperXMLState; + prev: PSuperXMLStack; + next: PSuperXMLStack; + clazz: TSuperXMLElementClass; + obj: ISuperObject; + end; + + TSuperXMLParser = class + private + FStack: PSuperXMLStack; + FDocType: ISuperObject; + FError: TSuperXMLError; + FStr: TSuperWriterString; + FValue: TSuperWriterString; + FPosition: Integer; + FAChar: SOChar; + FPack: Boolean; + procedure StackUp; + procedure StackDown; + procedure Reset; + function ParseBuffer(data: PSOChar; var PI, PIParent: ISuperObject; len: Integer = -1): Integer; + public + constructor Create(pack: Boolean); + destructor Destroy; override; + end; + +{ TXMLContext } + +constructor TSuperXMLParser.Create(pack: Boolean); +begin + FDocType := nil; + FStr := TSuperWriterString.Create; + FValue := TSuperWriterString.Create; + StackUp; + FError := xeSuccess; + FPack := pack; +end; + +destructor TSuperXMLParser.Destroy; +begin + while FStack <> nil do + StackDown; + FStr.Free; + FValue.Free; +end; + +procedure TSuperXMLParser.Reset; +begin + while FStack <> nil do + StackDown; + StackUp; + FError := xeSuccess; +end; + +function TSuperXMLParser.ParseBuffer(data: PSOChar; var PI, PIParent: ISuperObject; len: integer): Integer; +const + spaces = [#32,#9,#10,#13]; + alphas = ['a'..'z', 'A'..'Z', '_', ':', #161..#255]; + nums = ['0'..'9', '.', '-']; + hex = nums + ['a'..'f','A'..'F']; + alphanums = alphas + nums; + publitteral = [#32, #13, #10, 'a'..'z', 'A'..'Z', '0'..'9', '-', '''', '"', '(', ')', + '+', ',', '.', '/', ':', '=', '?', ';', '!', '*', '#', '@', '$', '_', '%']; + + function hexdigit(const x: SOChar): byte; + begin + if x <= '9' then + Result := byte(x) - byte('0') else + Result := (byte(x) and 7) + 9; + end; + + procedure putchildrenstr; + var + anobject: ISuperObject; + begin + anobject := FStack^.obj.AsObject[xmlchildren]; + if anobject = nil then + begin + anobject := TSuperObject.Create(stArray); + FStack^.obj.AsObject[xmlchildren] := anobject; + end; + anobject.AsArray.Add(TSuperObject.Create(FValue.Data)); + end; + + procedure AddProperty(const parent, value: ISuperObject; const name: SOString); + var + anobject: ISuperObject; + arr: ISuperObject; + begin + anobject := parent.AsObject[name]; + if anobject = nil then + parent.AsObject[name] := value else + begin + if (anobject.DataType = stArray) then + anobject.AsArray.Add(value) else + begin + arr := TSuperObject.Create(stArray); + arr.AsArray.Add(anobject); + arr.AsArray.Add(value); + parent.AsObject[name] := arr; + end; + end; + end; + + procedure packend; + var + anobject, anobject2: ISuperObject; + n: Integer; + begin + anobject := FStack^.obj.AsObject[xmlchildren]; + if (anobject <> nil) and (anobject.AsArray.Length = 1) and (anobject.AsArray[0].DataType = stString) then + begin + if FStack^.obj.AsObject.count = 2 then // name + children + begin + if FStack^.prev <> nil then + AddProperty(FStack^.prev^.obj, anobject.AsArray[0], FStack^.obj.AsObject.S[xmlname]) else + begin + AddProperty(FStack^.obj, anobject.AsArray[0], xmltext); + FStack^.obj.AsObject.Delete(xmlchildren); + end; + end + else + begin + AddProperty(FStack^.obj, anobject.AsArray[0], FStack^.obj.AsObject.S[xmlname]); + FStack^.obj.AsObject.Delete(xmlchildren); + if FStack^.prev <> nil then + AddProperty(FStack^.prev^.obj, FStack^.obj, FStack^.obj.AsObject.S[xmlname]) else + FStack^.obj.AsObject.Delete(xmlchildren); + FStack^.obj.AsObject.Delete(xmlname); + end; + end else + begin + if (anobject <> nil) then + begin + for n := 0 to anobject.AsArray.Length - 1 do + begin + anobject2 := anobject.AsArray[n]; + if ObjectIsType(anobject2, stObject) then + begin + AddProperty(FStack^.obj, anobject2, anobject2.AsObject.S[xmlname]); + anobject2.AsObject.Delete(xmlname); + end else + AddProperty(FStack^.obj, anobject2, xmltext); + end; + FStack^.obj.Delete(xmlchildren); + end; + if (FStack^.prev <> nil) and (FStack^.obj.AsObject.count > 1) then + begin + if (FStack^.obj.AsObject.count = 2) and (FStack^.obj.AsObject[xmltext] <> nil) then + AddProperty(FStack^.prev^.obj, FStack^.obj.AsObject[xmltext], FStack^.obj.AsObject.S[xmlname]) else + AddProperty(FStack^.prev^.obj, FStack^.obj, FStack^.obj.AsObject.S[xmlname]); + end; + FStack^.obj.Delete(xmlname); + end; + end; + +var + c: SOChar; + read: Integer; + p: PSOChar; + anobject: ISuperObject; +label + redo, err; +begin + p := data; + read := 0; + //Result := 0; + repeat + + if (read = len) then + begin + if (FStack^.prev = nil) and ((FStack^.state = xsEnd) or ((FStack^.state = xsEatSpaces) and (FStack^.savedstate = xsEnd))) then + begin + if FPack then + packend; + FError := xeSuccess; + end else + FError := xeContinue; + Result := read; + exit; + end; + c := p^; + redo: + case FStack^.state of + + xsEatSpaces: + if {$IFDEF UNICODE}(c < #256) and {$ENDIF} (AnsiChar(c) in spaces) then {nop} else + begin + FStack^.state := FStack^.savedstate; + goto redo; + end; + + xsStart: + case c of + '<': FStack^.state := xsElement; + else + goto err; + end; + xsElement: + begin + case c of + '?': + begin + FStack^.savedstate := xsStart; + FStack^.state := xsEatSpaces; + StackUp; + FStr.Reset; + FStack^.state := xsElementPI; + FStack^.clazz := xcProcessInst; + end; + '!': + begin + FPosition := 0; + FStack^.state := xsElementComment; + FStack^.clazz := xcComment; + end; + else + if ((c < #256) and (AnsiChar(c) in alphas)) or (c >= #256) then + begin + FStr.Reset; + FStack^.state := xsElementName; + FStack^.clazz := xcElement; + goto redo; + end else + goto err; + end; + end; + xsElementPI: + begin + if ((c < #256) and (AnsiChar(c) in alphanums)) or (c >= #256) then + FStr.Append(@c, 1) else + begin + FStack^.obj := TSuperObject.Create(stObject); + FStack^.obj.AsObject.S[xmlname] := FStr.Data; + FStack^.state := xsEatSpaces; + if FStr.Data = 'xml' then + FStack^.savedstate := xsAttributes else + begin + FValue.Reset; + FStack^.savedstate := xsElementDataPI; + end; + goto redo; + end; + end; + xsElementDataPI: + begin + case c of + '?': + begin + FStack^.obj.AsObject.S['data'] := FValue.Data; + FStack^.state := xsCloseElementPI; + end; + else + FValue.Append(@c, 1); + end; + end; + xsCloseElementPI: + begin + if (c <> '>') then goto err; + PI := FStack^.obj; + StackDown; + PIParent := FStack^.obj; + FError := xeProcessInst; + Result := read + 1; + Exit; + end; + xsElementName: + begin + if ((c < #256) and (AnsiChar(c) in alphanums)) or (c >= #256) then + FStr.Append(@c, 1) else + begin + FStack^.obj := TSuperObject.Create(stObject); + FStack^.obj.AsObject.S[xmlname] := FStr.Data; + FStack^.state := xsEatSpaces; + FStack^.savedstate := xsAttributes; + goto redo; + end; + end; + xsChildren: + begin + case c of + '<': FStack^.state := xsTryCloseElement; + else + FValue.Reset; + FStack^.state := xsElementString; + FStack^.clazz := xcString; + goto redo; + end; + end; + xsCloseEmptyElement: + begin + case c of + '>': + begin + FStack^.state := xsEatSpaces; + FStack^.savedstate := xsEnd; + end + else + goto err; + end; + end; + xsTryCloseElement: + begin + case c of + '/': begin + FStack^.state := xsCloseElementName; + FPosition := 0; + FStr.Reset; + FStr.Append(PSoChar(FStack^.obj.AsObject.S[xmlname])); + end; + '!': begin + FPosition := 0; + FStack^.state := xsElementComment; + FStack^.clazz := xcComment; + end; + '?': begin + FStack^.savedstate := xsChildren; + FStack^.state := xsEatSpaces; + StackUp; + FStr.Reset; + FStack^.state := xsElementPI; + FStack^.clazz := xcProcessInst; + end + else + FStack^.state := xsChildren; + StackUp; + if ((c < #256) and (AnsiChar(c) in alphas)) or (c >= #256) then + begin + FStr.Reset; + FStack^.state := xsElementName; + FStack^.clazz := xcElement; + goto redo; + end else + goto err; + end; + end; + xsCloseElementName: + begin + if FStr.Position = FPosition then + begin + FStack^.savedstate := xsCloseEmptyElement; + FStack^.state := xsEatSpaces; + goto redo; + end else + begin + if (c <> FStr.Data[FPosition]) then goto err; + inc(FPosition); + end; + end; + xsAttributes: + begin + case c of + '?': begin + if FStack^.clazz <> xcProcessInst then goto err; + FStack^.state := xsCloseElementPI; + end; + '/': begin + FStack^.state := xsCloseEmptyElement; + end; + '>': begin + FStack^.state := xsEatSpaces; + FStack^.savedstate := xsChildren; + end + else + if ((c < #256) and (AnsiChar(c) in alphas)) or (c >= #256) then + begin + FStr.Reset; + FStr.Append(@c, 1); + FStack^.state := xsAttributeName; + end else + goto err; + end; + end; + xsAttributeName: + begin + if ((c < #256) and (AnsiChar(c) in alphanums)) or (c >= #256) then + FStr.Append(@c, 1) else + begin + // no duplicate attribute + if FPack then + begin + if FStack^.obj.AsObject[FStr.Data] <> nil then + goto err; + end else + begin + anobject := FStack^.obj.AsObject[xmlattributes]; + if (anobject <> nil) and (anobject.AsObject[FStr.Data] <> nil) then + goto err; + end; + FStack^.state := xsEatSpaces; + FStack^.savedstate := xsEqual; + goto redo; + end; + end; + xsEqual: + begin + if c <> '=' then goto err; + FStack^.state := xsEatSpaces; + FStack^.savedstate := xsAttributeValue; + FValue.Reset; + FPosition := 0; + FAChar := #0; + end; + xsAttributeValue: + begin + if FAChar <> #0 then + begin + if (c = FAChar) then + begin + if FPack then + begin + FStack^.obj.AsObject[FStr.Data] := TSuperObject.Create(Fvalue.Data); + end else + begin + anobject := FStack^.obj.AsObject[xmlattributes]; + if anobject = nil then + begin + anobject := TSuperObject.Create(stObject); + FStack^.obj.AsObject[xmlattributes] := anobject; + end; + anobject.AsObject[FStr.Data] := TSuperObject.Create(Fvalue.Data); + end; + FStack^.savedstate := xsAttributes; + FStack^.state := xsEatSpaces; + end else + case c of + '&': + begin + FStack^.state := xsEscape; + FStack^.savedstate := xsAttributeValue; + end; + #13, #10: + begin + FValue.TrimRight; + FValue.Append(XML_SPACE, 1); + FStack^.state := xsEatSpaces; + FStack^.savedstate := xsAttributeValue; + end; + else + FValue.Append(@c, 1); + end; + + end else + begin + if (c < #256) and (AnsiChar(c) in ['"', '''']) then + begin + FAChar := c; + inc(FPosition); + + end else + goto err; + end; + end; + xsElementString: + begin + case c of + '<': begin + FValue.TrimRight; + putchildrenstr; + FStack^.state := xsTryCloseElement; + end; + #13, #10: + begin + FValue.TrimRight; + FValue.Append(XML_SPACE, 1); + FStack^.state := xsEatSpaces; + FStack^.savedstate := xsElementString; + end; + '&': + begin + FStack^.state := xsEscape; + FStack^.savedstate := xsElementString; + end + else + FValue.Append(@c, 1); + end; + end; + xsElementComment: + begin + case FPosition of + 0: + begin + case c of + '-': Inc(FPosition); + '[': + begin + FValue.Reset; + FPosition := 0; + FStack^.state := xsElementCDATA; + FStack^.clazz := xcCdata; + end; + 'D': + begin + if (FStack^.prev = nil) and (FDocType = nil) then + begin + FStack^.state := xsElementDocType; + FPosition := 0; + FStack^.clazz := xcDocType; + end else + goto err; + end; + else + goto err; + end; + end; + 1: + begin + if c <> '-' then goto err; + Inc(FPosition); + end; + else + if c = '-' then + begin + FPosition := 0; + FStack^.state := xsCloseElementComment; + end; + end; + end; + xsCloseElementComment: + begin + case FPosition of + 0: begin + if c <> '-' then + begin + FPosition := 2; + FStack^.state := xsElementComment; + end else + Inc(FPosition); + end; + 1: begin + if c <> '>' then goto err; + FStack^.state := xsEatSpaces; + if FStack^.obj <> nil then + FStack^.savedstate := xsChildren else + FStack^.savedstate := xsStart; + end; + end; + end; + xsElementCDATA: + begin + case FPosition of + 0: if (c = 'C') then inc(FPosition) else goto err; + 1: if (c = 'D') then inc(FPosition) else goto err; + 2: if (c = 'A') then inc(FPosition) else goto err; + 3: if (c = 'T') then inc(FPosition) else goto err; + 4: if (c = 'A') then inc(FPosition) else goto err; + 5: if (c = '[') then inc(FPosition) else goto err; + else + case c of + ']': begin + FPosition := 0; + FStack^.state := xsClodeElementCDATA; + end; + else + FValue.Append(@c, 1); + end; + end; + end; + xsClodeElementCDATA: + begin + case FPosition of + 0: if (c = ']') then + inc(FPosition) else + begin + FValue.Append(XML_ARR, 1); + FValue.Append(@c, 1); + FPosition := 6; + FStack^.state := xsElementCDATA; + end; + 1: case c of + '>': + begin + putchildrenstr; + FStack^.state := xsEatSpaces; + FStack^.savedstate := xsChildren; + end; + ']': + begin + FValue.Append(@c, 1); + end; + else + FValue.Append(@c, 1); + FStack^.state := xsElementCDATA; + end; + end; + end; + xsElementDocType: + begin + case FPosition of + 0: if (c = 'O') then inc(FPosition) else goto err; + 1: if (c = 'C') then inc(FPosition) else goto err; + 2: if (c = 'T') then inc(FPosition) else goto err; + 3: if (c = 'Y') then inc(FPosition) else goto err; + 4: if (c = 'P') then inc(FPosition) else goto err; + 5: if (c = 'E') then inc(FPosition) else goto err; + else + if (c < #256) and (AnsiChar(c) in spaces) then + begin + FStack^.state := xsEatSpaces; + FStack^.savedstate := xsElementDocTypeName; + FStr.Reset; + end else + goto err; + end; + end; + xsElementDocTypeName: + begin + case FStr.Position of + 0: begin + case c of + '>': + begin + FStack^.state := xsEatSpaces; + FStack^.state := xsStart; + FStack^.clazz := xcNone; + end + else + if ((c < #256) and (AnsiChar(c) in alphas)) or (c > #256) then + FStr.Append(@c, 1) else + goto err; + end; + end; + else + if ((c < #256) and (AnsiChar(c) in alphanums)) or (c > #256) then + FStr.Append(@c, 1) else + if (c < #256) and (AnsiChar(c) in spaces) then + begin + FDocType := TSuperObject.Create(stObject); + FDocType.AsObject.S[xmlname] := FStr.Data; + FStack^.state := xsEatSpaces; + FStack^.savedstate := xsElementDocTypeExternId; + end else + goto err; + end; + end; + xsElementDocTypeExternId: + begin + case c of + 'P': + begin + FPosition := 0; + FStack^.state := xsElementDocTypeExternIdPublic; + end; + 'S': + begin + FPosition := 0; + FStack^.state := xsElementDocTypeExternIdSystem; + end; + '[': + begin + FStack^.savedstate := xsElementDocTypeIntSubset; + FStack^.state := xsEatSpaces; + end; + '>': + begin + FStack^.savedstate := xsStart; + FStack^.state := xsEatSpaces + end + else + goto err; + end; + end; + xsElementDocTypeExternIdPublic: + begin + case FPosition of + 0: if (c = 'U') then inc(FPosition) else goto err; + 1: if (c = 'B') then inc(FPosition) else goto err; + 2: if (c = 'L') then inc(FPosition) else goto err; + 3: if (c = 'I') then inc(FPosition) else goto err; + 4: if (c = 'C') then inc(FPosition) else goto err; + else + if (c < #256) and (AnsiChar(c) in spaces) then + begin + FStr.Reset; + FPosition := 0; + FStack^.savedstate := xsElementDocTypePubIdLiteral; + FStack^.state := xsEatSpaces; + end else + goto err; + end; + end; + + xsElementDocTypeExternIdSystem: + begin + case FPosition of + 0: if (c = 'Y') then inc(FPosition) else goto err; + 1: if (c = 'S') then inc(FPosition) else goto err; + 2: if (c = 'T') then inc(FPosition) else goto err; + 3: if (c = 'E') then inc(FPosition) else goto err; + 4: if (c = 'M') then inc(FPosition) else goto err; + else + if (c < #256) and (AnsiChar(c) in spaces) then + begin + FStr.Reset; + FPosition := 0; + FStack^.savedstate := xsElementDocTypeSystemLiteral; + FStack^.state := xsEatSpaces; + end else + goto err; + end; + end; + xsElementDocTypePubIdLiteral: + begin + if FPosition = 0 then + case c of + '"', '''': + begin + FAChar := c; + FPosition := 1; + end + else + goto err; + end else + if c = FAChar then + begin + FDocType.AsObject.S[dtdPubidLiteral] := FStr.Data; + FStr.Reset; + FPosition := 0; + FStack^.state := xsEatSpaces; + FStack^.savedstate := xsElementDocTypeSystemLiteral; + end else + if (c < #256) and (AnsiChar(c) in publitteral) then + FStr.Append(@c, 1); + end; + xsElementDocTypeSystemLiteral: + begin + if FPosition = 0 then + case c of + '"', '''': + begin + FAChar := c; + FPosition := 1; + end + else + goto err; + end else + if c = FAChar then + begin + FDocType.AsObject.S[dtdSystemLiteral] := FStr.Data; + FStack^.state := xsEatSpaces; + FStack^.savedstate := xsElementDocTypeTryIntSubset; + end else + FStr.Append(@c, 1); + end; + + xsElementDocTypeTryIntSubset: + begin + case c of + '>': + begin + FStack^.state := xsEatSpaces; + FStack^.savedstate := xsStart; + FStack^.clazz := xcNone; + end; + '[': + begin + FStack^.state := xsEatSpaces; + FStack^.savedstate := xsElementDocTypeIntSubset; + end; + end; + end; + xsElementDocTypeIntSubset: + begin + case c of + ']': + begin + FStack^.state := xsEatSpaces; + FStack^.savedstate := xsElementDocTypeTryClose; + end; + end; + end; + xsElementDocTypeTryClose: + begin + if c = '>' then + begin + FStack^.state := xsEatSpaces; + FStack^.savedstate := xsStart; + FStack^.clazz := xcNone; + end else + goto err; + end; + xsEscape: + begin + FPosition := 0; + case c of + 'l': FStack^.state := xsEscape_lt; + 'g': FStack^.state := xsEscape_gt; + 'a': FStack^.state := xsEscape_amp; + 'q': FStack^.state := xsEscape_quot; + '#': FStack^.state := xsEscape_char; + else + goto err; + end; + end; + xsEscape_lt: + begin + case FPosition of + 0: begin + if c <> 't' then goto err; + Inc(FPosition); + end; + 1: begin + if c <> ';' then goto err; + FValue.Append(XML_LOW, 1); + FStack^.state := FStack^.savedstate; + end; + end; + end; + xsEscape_gt: + begin + case FPosition of + 0: begin + if c <> 't' then goto err; + Inc(FPosition); + end; + 1: begin + if c <> ';' then goto err; + FValue.Append(XML_BIG, 1); + FStack^.state := FStack^.savedstate; + end; + end; + end; + xsEscape_amp: + begin + case FPosition of + 0: begin + case c of + 'm': Inc(FPosition); + 'p': begin + FStack^.state := xsEscape_apos; + Inc(FPosition); + end; + else + goto err; + end; + end; + 1: begin + if c <> 'p' then goto err; + Inc(FPosition); + end; + 2: begin + if c <> ';' then goto err; + FValue.Append(XML_AMP, 1); + FStack^.state := FStack^.savedstate; + end; + end; + end; + xsEscape_apos: + begin + case FPosition of + 0: begin + case c of + 'p': Inc(FPosition); + 'm': begin + FStack^.state := xsEscape_amp; + Inc(FPosition); + end; + else + goto err; + end; + end; + 1: begin + if c <> 'o' then goto err; + Inc(FPosition); + end; + 2: begin + if c <> 's' then goto err; + Inc(FPosition); + end; + 3: begin + if c <> ';' then goto err; + FValue.Append(XML_SQU, 1); + FStack^.state := FStack^.savedstate; + end; + end; + end; + xsEscape_quot: + begin + case FPosition of + 0: begin + if c <> 'u' then goto err; + Inc(FPosition); + end; + 1: begin + if c <> 'o' then goto err; + Inc(FPosition); + end; + 2: begin + if c <> 't' then goto err; + Inc(FPosition); + end; + 3: begin + if c <> ';' then goto err; + FValue.Append(XML_DQU, 1); + FStack^.state := FStack^.savedstate; + end; + end; + end; + xsEscape_char: + begin + if (SOIChar(c) >= 256) then goto err; + case AnsiChar(c) of + '0'..'9': + begin + FPosition := SOIChar(c) - 48; + FStack^.state := xsEscape_char_num; + end; + 'x': + begin + FStack^.state := xsEscape_char_hex; + end + else + goto err; + end; + end; + xsEscape_char_num: + begin + if (SOIChar(c) >= 256) then goto err; + case AnsiChar(c) of + '0'..'9':FPosition := (FPosition * 10) + (SOIChar(c) - 48); + ';': begin + FValue.Append(@FPosition, 1); + FStack^.state := FStack^.savedstate; + end; + else + goto err; + end; + end; + xsEscape_char_hex: + begin + if (c >= #256) then goto err; + if (AnsiChar(c) in hex) then + begin + FPosition := (FPosition * 16) + SOIChar(hexdigit(c)); + end else + if c = ';' then + begin + FValue.Append(@FPosition, 1); + FStack^.state := FStack^.savedstate; + end else + goto err; + end; + xsEnd: + begin + if(FStack^.prev = nil) then Break; + if FStack^.obj <> nil then + begin + if FPack then + packend else + begin + anobject := FStack^.prev^.obj.AsObject[xmlchildren]; + if anobject = nil then + begin + anobject := TSuperObject.Create(stArray); + FStack^.prev^.obj.AsObject[xmlchildren] := anobject; + end; + anobject.AsArray.Add(FStack^.obj); + end; + end; + StackDown; + goto redo; + end; + end; + inc(p); + inc(read); + until (c = #0); + + if FStack^.state = xsEnd then + begin + if FPack then + packend; + FError := xeSuccess; + end else + FError := xeError; + Result := read; + exit; +err: + FError := xeError; + Result := read; +end; + +function XMLParseFile(const FileName: string; pack: Boolean; onpi: TOnProcessingInstruction): ISuperObject; +var + stream: TFileStream; +begin + stream := TFileStream.Create(FileName, fmOpenRead, fmShareDenyWrite); + try + Result := XMLParseStream(stream, pack, onpi); + finally + stream.Free; + end; +end; + +procedure TSuperXMLParser.StackDown; +var + prev: PSuperXMLStack; +begin + if FStack <> nil then + begin + prev := FStack^.prev; + FStack^.obj := nil; + FreeMem(FStack); + FStack := prev; + if FStack <> nil then + FStack^.next := nil; + end; +end; + +procedure TSuperXMLParser.StackUp; +var + st: PSuperXMLStack; +begin +{$IFDEF FPC} + st := nil; +{$ENDIF} + GetMem(st, SizeOf(st^)); + FillChar(st^, SizeOf(st^), 0); + st^.state := xsEatSpaces; + st^.savedstate := xsStart; + st^.prev := FStack; + if st^.prev <> nil then + st^.prev^.next := st; + st^.next := nil; + st^.obj := nil; + FStack := st; +end; + +function utf8toucs2(src: PAnsiChar; srclen: Integer; dst: PWideChar; unused: PInteger): Integer; +var + ch: Byte; + ret: Word; + min: Cardinal; + rem, com: integer; +label + redo; +begin + Result := 0; + ret := 0; + rem := 0; + min := 0; + + if unused <> nil then + unused^ := 0; + + if(src = nil) or (srclen = 0) then + begin + dst^ := #0; + Exit; + end; + + while srclen > 0 do + begin + ch := Byte(src^); + inc(src); + dec(srclen); + +redo: + if (ch and $80) = 0 then + begin + dst^ := WideChar(ch); + inc(Result); + end else + begin + if((ch and $E0) = $C0) then + begin + min := $80; + rem := 1; + ret := ch and $1F; + end else + if((ch and $F0) = $E0) then + begin + min := $800; + rem := 2; + ret := ch and $0F; + end else + // too large utf8 bloc + // ignore and continue + continue; + + com := rem; + while(rem <> 0) do + begin + dec(rem); + if(srclen = 0) then + begin + if unused <> nil then + unused^ := com; + Exit; + end; + ch := Byte(src^); + inc(src); + dec(srclen); + if((ch and $C0) = $80) then + begin + ret := ret shl 6; + ret := ret or (ch and $3F); + end else + begin + // unterminated utf8 bloc :/ + // try next one + goto redo; + end; + end; + + if (ret >= min) then + begin + dst^ := WideChar(ret); + inc(Result); + end else + // too small utf8 bloc + // ignore and continue + Continue; + end; + inc(dst); + end; +end; + +function XMLParseStream(stream: TStream; pack: Boolean; onpi: TOnProcessingInstruction): ISuperObject; +const + CP_UTF8 = 65001; +var + wbuffer: array[0..1023] of SOChar; + abuffer: array[0..1023] of AnsiChar; + len, read, cursor: Integer; + PI, PIParent: ISuperObject; + bom: array[0..2] of byte; + + encoding: TSuperXMLEncoding; + encodingstr: string; + cp: Integer; + ecp: ISuperObject; + + function getbuffer: Integer; + var + size, unusued: Integer; + begin + + case encoding of +{$IFNDEF UNIX} + xnANSI: + begin + size := stream.Read(abuffer, sizeof(abuffer)); + result := MultiByteToWideChar(cp, 0, @abuffer, size, @wbuffer, sizeof(wbuffer)); + end; +{$ENDIF} + xnUTF8: + begin + size := stream.Read(abuffer, sizeof(abuffer)); + result := utf8toucs2(@abuffer, size, @wbuffer, @unusued); + if unusued > 0 then + stream.Seek(-unusued, soFromCurrent); + end; + xnUnicode: Result := stream.Read(wbuffer, sizeof(wbuffer)) div sizeof(SOChar); + else + Result := 0; + end; + end; +label + redo, retry; +begin + // init knowned code pages + ecp := so('{iso-8859-1: 28591,'+ + 'iso-8859-2: 28592,'+ + 'iso-8859-3: 28593,'+ + 'iso-8859-4: 28594,'+ + 'iso-8859-5: 28595,'+ + 'iso-8859-6: 28596,'+ + 'iso-8859-7: 28597,'+ + 'iso-8859-8: 28598,'+ + 'iso-8859-9: 28599,'+ + 'iso 8859-15: 28605,'+ + 'iso-2022-jp: 50220,'+ + 'shift_jis: 932,'+ + 'euc-jp: 20932,'+ + 'ascii: 20127,'+ + 'windows-1251: 1251,'+ + 'windows-1252: 1252}'); + + // detect bom + stream.Seek(0, soFromBeginning); + len := stream.Read(bom, sizeof(bom)); + if (len >= 2) and (bom[0] = $FF) and (bom[1] = $FE) then + begin + encoding := xnUnicode; + stream.Seek(2, soFromBeginning); + end else + if (len = 3) and (bom[0] = $EF) and (bom[1] = $BB) and (bom[2] = $BF) then + begin + encoding := xnUTF8; + cp := CP_UTF8; + end else + begin + encoding := xnUTF8; + cp := 0; + stream.Seek(0, soFromBeginning); + end; + + with TSuperXMLParser.Create(pack) do + try + len := getbuffer; + while len > 0 do + begin +retry: + read := ParseBuffer(@wbuffer, PI, PIParent, len); + cursor := 0; +redo: + case FError of + xeContinue: len := getbuffer; + xeSuccess, xeError: Break; + xeProcessInst: + begin + if (PIParent = nil) and (PI.AsObject.S[xmlname] = 'xml') then + begin + if pack then + encodingstr := LowerCase(trim(PI.S['encoding'])) else + encodingstr := LowerCase(trim(PI.S[xmlattributes + '.encoding'])); + if (encodingstr <> '') then + case encoding of + xnUTF8: if(cp = CP_UTF8) then + begin + if (encodingstr <> 'utf-8') then + begin + FError := xeError; + Break; + end; + end else + begin + cp := ecp.I[encodingstr]; + if cp > 0 then + begin +{$IFNDEF UNIX} + encoding := xnANSI; + Reset; + stream.Seek(0, soFromBeginning); + len := getbuffer; + goto retry; +{$ELSE} + raise Exception.Create('charset not implemented'); +{$ENDIF} + end; + end; + xnUnicode: + if (encodingstr <> 'utf-16') and (encodingstr <> 'unicode') then + begin + FError := xeError; + Break; + end; + end; + end else + if Assigned(onpi) then + onpi(PI, PIParent); + + inc(cursor, read); + if cursor >= len then + begin + len := getbuffer; + continue; + end; + read := ParseBuffer(@wbuffer[cursor], PI, PIParent, len - cursor); + goto redo; + end; + end; + end; + if FError = xeSuccess then + Result := FStack^.obj else + Result := nil; + finally + Free; + end; +end; + +function XMLParseString(const data: SOString; pack: Boolean; onpi: TOnProcessingInstruction): ISuperObject; +var + PI, PIParent: ISuperObject; + cursor, read: Integer; +label + redo; +begin + with TSuperXMLParser.Create(pack) do + try + cursor := 0; + read := ParseBuffer(PSOChar(data), PI, PIParent); +redo: + case FError of + xeSuccess: Result := FStack^.obj; + xeError: Result := nil; + xeProcessInst: + begin + if Assigned(onpi) then + onpi(PI, PIParent); + inc(cursor, read); + read := ParseBuffer(@data[cursor+1], PI, PIParent); + goto redo; + end; + end; + finally + Free; + end; +end; + +end.