diff --git a/wst/trunk/base_xmlrpc_formatter.pas b/wst/trunk/base_xmlrpc_formatter.pas new file mode 100644 index 000000000..0812d637f --- /dev/null +++ b/wst/trunk/base_xmlrpc_formatter.pas @@ -0,0 +1,1382 @@ +{ + This file is part of the Web Service Toolkit + Copyright (c) 2006 by Inoussa OUEDRAOGO + + This file is provide under modified LGPL licence + ( the files COPYING.modifiedLGPL and COPYING.LGPL). + + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +} +unit base_xmlrpc_formatter; + +{$mode objfpc}{$H+} +{$IF (FPC_VERSION = 2) and (FPC_RELEASE > 0)} + {$define FPC_211} +{$ENDIF} + +interface + +uses + Classes, SysUtils, TypInfo, Contnrs, + DOM, + base_service_intf; + +const + sPROTOCOL_NAME = 'XMLRPC'; + + + sCONTENT_TYPE = 'contenttype'; + sXMLRPC_CONTENT_TYPE = 'text/xml'; + +type + + TEnumIntType = Int64; + + TXmlRpcDataType = ( + xdtString, xdtInt, xdtBoolean, xdtdouble, xdtDateTime, xdtBase64, + xdtStruct, xdtArray + ); + +const + XmlRpcDataTypeNames : array[TXmlRpcDataType] of string = ( + 'string', 'int', 'boolean', 'double', 'dateTime.iso8601', 'base64', + 'struct', 'array' + ); + +type + { ESOAPException } + + EXmlRpcException = class(EBaseRemoteException) + end; + + { TStackItem } + + TStackItem = class + private + FScopeObject: TDOMNode; + FScopeType: TScopeType; + protected + function GetItemsCount() : Integer;virtual; + public + constructor Create(AScopeObject : TDOMNode;AScopeType : TScopeType); + function FindNode(var ANodeName : string):TDOMNode;virtual;abstract; + function CreateBuffer( + Const AName : string; + const ADataType : TXmlRpcDataType + ):TDOMNode;virtual;abstract; + property ScopeObject : TDOMNode Read FScopeObject; + property ScopeType : TScopeType Read FScopeType; + property ItemsCount : Integer read GetItemsCount; + end; + + { TObjectStackItem } + + TObjectStackItem = class(TStackItem) + public + function FindNode(var ANodeName : string):TDOMNode;override; + function CreateBuffer( + Const AName : string; + const ADataType : TXmlRpcDataType + ):TDOMNode;override; + end; + + { TArrayStackItem } + + TArrayStackItem = class(TStackItem) + private + FItemList : TDOMNodeList; + FIndex : Integer; + FDataScope : TDOMNode; + protected + procedure EnsureListCreated(); + function GetItemsCount() : Integer;override; + function CreateList():TDOMNodeList; + public + destructor Destroy();override; + function FindNode(var ANodeName : string):TDOMNode;override; + function CreateBuffer( + Const AName : string; + const ADataType : TXmlRpcDataType + ):TDOMNode;override; + end; + + { TParamsArrayStackItem } + + TParamsArrayStackItem = class(TStackItem) + private + FItemList : TDOMNodeList; + FIndex : Integer; + protected + procedure EnsureListCreated(); + function GetItemsCount() : Integer;override; + function CreateList():TDOMNodeList; + public + destructor Destroy();override; + function FindNode(var ANodeName : string):TDOMNode;override; + function CreateBuffer( + Const AName : string; + const ADataType : TXmlRpcDataType + ):TDOMNode;override; + end; + +{$M+} + + { TXmlRpcBaseFormatter } + + TXmlRpcBaseFormatter = class(TSimpleFactoryItem,IFormatterBase) + private + FContentType: string; + FDoc : TXMLDocument; + FStack : TObjectStack; + FSerializationStyle: TSerializationStyle; + private + procedure InternalClear(const ACreateDoc : Boolean); + + function HasScope():Boolean;//inline; + + procedure CheckScope();//inline; + function InternalPutData( + const AName : string; + const AType : TXmlRpcDataType; + const AData : string + ):TDOMNode; + function PutEnum( + Const AName : String; + Const ATypeInfo : PTypeInfo; + Const AData : TEnumIntType + ):TDOMNode; + function PutBool( + Const AName : String; + Const ATypeInfo : PTypeInfo; + Const AData : Boolean + ):TDOMNode; + function PutInt64( + Const AName : String; + Const ATypeInfo : PTypeInfo; + Const AData : Int64 + ):TDOMNode; + function PutStr( + Const AName : String; + Const ATypeInfo : PTypeInfo; + Const AData : String + ):TDOMNode; + function PutFloat( + Const AName : String; + Const ATypeInfo : PTypeInfo; + Const AData : Extended + ):TDOMNode; + procedure PutObj( + Const AName : String; + Const ATypeInfo : PTypeInfo; + Const AData : TObject + ); + + function GetNodeValue(var AName : String):DOMString; + procedure GetEnum( + Const ATypeInfo : PTypeInfo; + Var AName : String; + Var AData : TEnumIntType + ); + procedure GetBool( + Const ATypeInfo : PTypeInfo; + Var AName : String; + Var AData : Boolean + ); + procedure GetInt( + Const ATypeInfo : PTypeInfo; + Var AName : String; + Var AData : Integer + ); + procedure GetInt64( + Const ATypeInfo : PTypeInfo; + Var AName : String; + Var AData : Int64 + ); + procedure GetFloat( + Const ATypeInfo : PTypeInfo; + Var AName : String; + Var AData : Extended + ); + procedure GetStr( + Const ATypeInfo : PTypeInfo; + Var AName : String; + Var AData : String + ); + procedure GetObj( + Const ATypeInfo : PTypeInfo; + Var AName : String; + Var AData : TObject + ); + protected + function GetXmlDoc():TXMLDocument; + function PushStack(AScopeObject : TDOMNode):TStackItem;overload; + function PushStack( + AScopeObject : TDOMNode; + const AStyle : TArrayStyle; + const AItemName : string + ):TStackItem;overload; + function FindAttributeByValueInNode( + Const AAttValue : String; + Const ANode : TDOMNode; + Out AResAtt : string + ):boolean; + function FindAttributeByNameInNode( + Const AAttName : String; + Const ANode : TDOMNode; + Out AResAttValue : string + ):boolean; + function FindAttributeByValueInScope(Const AAttValue : String):String; + function FindAttributeByNameInScope(Const AAttName : String):String; + protected + function GetCurrentScope():String; + function GetCurrentScopeObject():TDOMElement; + function StackTop():TStackItem; + function PopStack():TStackItem; + procedure ClearStack(); + procedure BeginScope( + Const AScopeName,ANameSpace : string; + Const ANameSpaceShortName : string ; + Const AScopeType : TScopeType; + const AStyle : TArrayStyle + ); + function InternalBeginScopeRead( + var AScopeName : string; + const ATypeInfo : PTypeInfo; + const AScopeType : TScopeType; + const AStyle : TArrayStyle; + const AItemName : string + ):Integer; + + procedure SetSerializationStyle(const ASerializationStyle : TSerializationStyle); + function GetSerializationStyle():TSerializationStyle; + public + constructor Create();override; + destructor Destroy();override; + procedure Clear(); + + procedure BeginObject( + Const AName : string; + Const ATypeInfo : PTypeInfo + ); + procedure BeginArray( + const AName : string; + const ATypeInfo : PTypeInfo; + const AItemTypeInfo : PTypeInfo; + const ABounds : Array Of Integer; + const AStyle : TArrayStyle + ); + + procedure NilCurrentScope(); + function IsCurrentScopeNil():Boolean; + procedure EndScope(); + procedure AddScopeAttribute(Const AName,AValue : string); + function BeginObjectRead( + var AScopeName : string; + const ATypeInfo : PTypeInfo + ) : Integer; + function BeginArrayRead( + var AScopeName : string; + const ATypeInfo : PTypeInfo; + const AStyle : TArrayStyle; + const AItemName : string + ):Integer; + procedure EndScopeRead(); + + procedure BeginHeader(); + procedure EndHeader(); + + procedure Put( + Const AName : String; + Const ATypeInfo : PTypeInfo; + Const AData + ); + procedure PutScopeInnerValue( + const ATypeInfo : PTypeInfo; + const AData + ); + procedure Get( + Const ATypeInfo : PTypeInfo; + Var AName : String; + Var AData + ); + procedure GetScopeInnerValue( + const ATypeInfo : PTypeInfo; + var AData + ); + + procedure SaveToStream(AStream : TStream); + procedure LoadFromStream(AStream : TStream); + + procedure Error(Const AMsg:string); + procedure Error(Const AMsg:string; Const AArgs : array of const); + published + property ContentType : string Read FContentType Write FContentType; + end; +{$M-} + +implementation +Uses XMLWrite, XMLRead, StrUtils, + imp_utils; + +const + sDATA = 'data'; + sMEMBER = 'member'; + sNAME = 'name'; + sPARAM = 'param'; + sVALUE = 'value'; + +function GetNodeItemsCount(const ANode : TDOMNode): Integer; +var + chdLst : TDOMNodeList; +begin + if ANode.HasChildNodes then begin + chdLst := ANode.ChildNodes; + try + Result := chdLst.Count + finally + chdLst.Release(); + end; + end else begin + Result := 0; + end; +end; + +{ TStackItem } + +function TStackItem.GetItemsCount: Integer; +begin + Result := GetNodeItemsCount(ScopeObject); +end; + +constructor TStackItem.Create(AScopeObject: TDOMNode; AScopeType: TScopeType); +begin + FScopeObject := AScopeObject; + FScopeType := AScopeType; +end; + +{ TObjectStackItem } + +function TObjectStackItem.FindNode(var ANodeName: string): TDOMNode; +var + memberNode, tmpNode : TDOMNode; + i : Integer; + chilNodes : TDOMNodeList; + nodeFound : Boolean; +begin + Result := nil; + if ScopeObject.HasChildNodes() then begin + nodeFound := False; + memberNode := ScopeObject.FirstChild; + while ( not nodeFound ) and ( memberNode <> nil ) do begin + if memberNode.HasChildNodes() then begin + chilNodes := memberNode.ChildNodes; + for i := 0 to Pred(chilNodes.Count) do begin + tmpNode := chilNodes.Item[i]; + if AnsiSameText(sNAME,tmpNode.NodeName) and + ( tmpNode.FirstChild <> nil ) and + AnsiSameText(ANodeName,tmpNode.FirstChild.NodeValue) + then begin + nodeFound := True; + Break; + end; + end; + if nodeFound then begin + tmpNode := memberNode.FindNode(sVALUE); + if ( tmpNode <> nil ) and ( tmpNode.FirstChild <> nil ) then begin + Result := tmpNode.FirstChild; + Break; + end; + end; + end; + memberNode := memberNode.NextSibling; + end; + end; +end; + +function TObjectStackItem.CreateBuffer( + const AName: String; + const ADataType: TXmlRpcDataType +): TDOMNode; +var + memberNode, nd, ndVal : TDOMNode; +begin + memberNode := ScopeObject.OwnerDocument.CreateElement(sMEMBER); + ScopeObject.AppendChild(memberNode); + + nd := ScopeObject.OwnerDocument.CreateElement(sNAME); + memberNode.AppendChild(nd); + nd.AppendChild(ScopeObject.OwnerDocument.CreateTextNode(AName)); + + nd := ScopeObject.OwnerDocument.CreateElement(sVALUE); + memberNode.AppendChild(nd); + Result := ScopeObject.OwnerDocument.CreateElement(XmlRpcDataTypeNames[ADataType]); + nd.AppendChild(Result); +end; + +{ TArrayStackItem } + +procedure TArrayStackItem.EnsureListCreated(); +begin + if ( FItemList = nil ) then begin + FItemList := CreateList(); + end; +end; + +function TArrayStackItem.GetItemsCount(): Integer; +begin + EnsureListCreated(); + if Assigned(FItemList) then begin + Result := FItemList.Count; + end else begin + Result := 0; + end; +end; + +function TArrayStackItem.CreateList(): TDOMNodeList; +begin + if ScopeObject.HasChildNodes() and ScopeObject.FirstChild.HasChildNodes() then begin + Result := ScopeObject.FirstChild.GetChildNodes(); + end else begin + Result := nil; + end; +end; + +destructor TArrayStackItem.Destroy(); +begin + if Assigned(FItemList) then + FItemList.Release(); + inherited Destroy(); +end; + +function TArrayStackItem.FindNode(var ANodeName: string): TDOMNode; +begin + EnsureListCreated(); + if ( FIndex >= FItemList.Count ) then + raise EXmlRpcException.CreateFmt('Index out of bound : %d; Node Name = "%s"; Parent Node = "%s"',[FIndex,ANodeName,ScopeObject.NodeName]); + Result:= FItemList.Item[FIndex]; + if Result.HasChildNodes() then begin + Result := Result.FirstChild; + Inc(FIndex); + ANodeName := Result.NodeName; + end else begin + raise EXmlRpcException.CreateFmt('Invalid array item : Index = %d; Node Name = "%s"; Parent Node = "%s"',[FIndex,ANodeName,ScopeObject.NodeName]); + end; +end; + +function TArrayStackItem.CreateBuffer( + const AName: string; + const ADataType: TXmlRpcDataType +): TDOMNode; +var + nd, ndVal : TDOMNode; +begin + if ( FDataScope = nil ) then begin + FDataScope := ScopeObject.OwnerDocument.CreateElement(sDATA); + ScopeObject.AppendChild(FDataScope); + end; + + nd := FDataScope.OwnerDocument.CreateElement(sVALUE); + FDataScope.AppendChild(nd); + Result := ScopeObject.OwnerDocument.CreateElement(XmlRpcDataTypeNames[ADataType]); + nd.AppendChild(Result); +end; + +{ TXmlRpcBaseFormatter } + +procedure TXmlRpcBaseFormatter.ClearStack(); +Var + i, c : Integer; +begin + c := FStack.Count; + For I := 1 To c Do + FStack.Pop().Free(); +end; + +function TXmlRpcBaseFormatter.PushStack(AScopeObject : TDOMNode) : TStackItem; +begin + Result := FStack.Push(TObjectStackItem.Create(AScopeObject,stObject)) as TStackItem; +end; + +function TXmlRpcBaseFormatter.PushStack( + AScopeObject : TDOMNode; + const AStyle : TArrayStyle; + const AItemName : string +): TStackItem; +begin + Result := FStack.Push(TArrayStackItem.Create(AScopeObject,stArray)) as TStackItem; +end; + +function TXmlRpcBaseFormatter.BeginObjectRead( + var AScopeName : string; + const ATypeInfo : PTypeInfo +): Integer; +begin + Result := InternalBeginScopeRead(AScopeName,ATypeInfo,stObject,asNone,''); +end; + +function TXmlRpcBaseFormatter.BeginArrayRead( + var AScopeName : string; + const ATypeInfo : PTypeInfo; + const AStyle : TArrayStyle; + const AItemName : string +): Integer; +begin + Result := InternalBeginScopeRead(AScopeName,ATypeInfo,stArray,AStyle,AItemName); +end; + +procedure TXmlRpcBaseFormatter.EndScopeRead(); +begin + PopStack().Free(); +end; + +procedure TXmlRpcBaseFormatter.BeginHeader(); +begin +end; + +procedure TXmlRpcBaseFormatter.EndHeader(); +begin +end; + +procedure TXmlRpcBaseFormatter.InternalClear(const ACreateDoc: Boolean); +begin + ClearStack(); + FreeAndNil(FDoc); + if ACreateDoc then + FDoc := TXMLDocument.Create(); +end; + +function TXmlRpcBaseFormatter.HasScope(): Boolean; +begin + Result := Assigned(FStack.Peek); +end; + +function TXmlRpcBaseFormatter.FindAttributeByValueInNode( + Const AAttValue : String; + Const ANode : TDOMNode; + Out AResAtt : string +):boolean; +Var + i,c : Integer; +begin + AResAtt := ''; + If Assigned(ANode) And Assigned(ANode.Attributes) Then Begin + c := Pred(ANode.Attributes.Length); + For i := 0 To c Do Begin + If AnsiSameText(AAttValue,ANode.Attributes.Item[i].NodeValue) Then Begin + AResAtt := ANode.Attributes.Item[i].NodeName; + Result := True; + Exit; + End; + End; + End; + Result := False; +end; + +function TXmlRpcBaseFormatter.FindAttributeByNameInNode( + const AAttName: String; + const ANode: TDOMNode; + Out AResAttValue: string +): boolean; +var + i,c : Integer; +begin + AResAttValue := ''; + If Assigned(ANode) And Assigned(ANode.Attributes) Then Begin + c := Pred(ANode.Attributes.Length); + For i := 0 To c Do Begin + If AnsiSameText(AAttName,ANode.Attributes.Item[i].NodeName) Then Begin + AResAttValue := ANode.Attributes.Item[i].NodeValue; + Result := True; + Exit; + End; + End; + End; + Result := False; +end; + +function TXmlRpcBaseFormatter.FindAttributeByValueInScope(const AAttValue: String): String; +Var + tmpNode : TDOMNode; +begin + If HasScope() Then Begin + tmpNode := GetCurrentScopeObject(); + While Assigned(tmpNode) Do Begin + If FindAttributeByValueInNode(AAttValue,tmpNode,Result) Then + Exit; + tmpNode := tmpNode.ParentNode; + End; + End; + Result := ''; +end; + +function TXmlRpcBaseFormatter.FindAttributeByNameInScope(const AAttName: String): String; +var + tmpNode : TDOMNode; +begin + if HasScope() then begin + tmpNode := GetCurrentScopeObject(); + while Assigned(tmpNode) do begin + if FindAttributeByNameInNode(AAttName,tmpNode,Result) then + Exit; + tmpNode := tmpNode.ParentNode; + end; + end; + Result := ''; +end; + +procedure TXmlRpcBaseFormatter.CheckScope(); +begin + If Not HasScope() Then + Error('There is no scope.'); +end; + +function TXmlRpcBaseFormatter.InternalPutData( + const AName : string; + const AType : TXmlRpcDataType; + const AData : string +): TDOMNode; +begin + Result := StackTop().CreateBuffer(AName,AType).AppendChild(FDoc.CreateTextNode(AData)); +end; + +function TXmlRpcBaseFormatter.PutEnum( + const AName: String; + const ATypeInfo: PTypeInfo; + const AData: TEnumIntType +): TDOMNode; +begin + Result := InternalPutData( + AName, + xdtString, + GetTypeRegistry().ItemByTypeInfo[ATypeInfo].GetExternalPropertyName(GetEnumName(ATypeInfo,AData)) + ); +end; + +function TXmlRpcBaseFormatter.PutBool( + const AName : String; + const ATypeInfo : PTypeInfo; + const AData : Boolean +) : TDOMNode; +var + v : Char; +begin + if AData then + v := '1' + else + v := '0'; + Result := InternalPutData(AName,xdtBoolean,v); +end; + +function TXmlRpcBaseFormatter.PutInt64( + const AName : String; + const ATypeInfo : PTypeInfo; + const AData : Int64 +): TDOMNode; +begin + Result := InternalPutData(AName,xdtInt,IntToStr(AData)); +end; + +function TXmlRpcBaseFormatter.PutStr( + const AName: String; + const ATypeInfo: PTypeInfo; + const AData: String +):TDOMNode; +begin + Result := InternalPutData( + AName, + xdtString, + StringReplace(StringReplace(AData,'<','<',[rfReplaceAll]),'&','&',[rfReplaceAll]) + ); +end; + +procedure TXmlRpcBaseFormatter.PutObj( + const AName : String; + const ATypeInfo : PTypeInfo; + const AData : TObject +); +begin + TBaseRemotableClass(GetTypeData(ATypeInfo)^.ClassType).Save(AData As TBaseRemotable, Self,AName,ATypeInfo); +end; + +function TXmlRpcBaseFormatter.PutFloat( + const AName : String; + const ATypeInfo : PTypeInfo; + const AData : Extended +):TDOMNode; +Var + s, frmt : string; + prcsn,i : Integer; +begin + Case GetTypeData(ATypeInfo)^.FloatType Of + ftSingle, + ftCurr, + ftComp : prcsn := 7; + ftDouble, + ftExtended : prcsn := 15; + End; + frmt := '#.' + StringOfChar('#',prcsn) + 'E-0'; + s := FormatFloat(frmt,AData); + i := Pos(',',s); + If ( i > 0 ) Then + s[i] := '.'; + Result := InternalPutData(AName,xdtdouble,s); +end; + +function TXmlRpcBaseFormatter.GetNodeValue(var AName: string): DOMString; +var + locElt : TDOMNode; +begin + locElt := StackTop().FindNode(AName) as TDOMElement; + + if Assigned(locElt) then begin + if locElt.HasChildNodes then + Result := locElt.FirstChild.NodeValue + else + Result := locElt.NodeValue; + end else begin + Error('Param or Attribute not found : "%s"',[AName]); + end; +end; + +procedure TXmlRpcBaseFormatter.GetEnum( + const ATypeInfo: PTypeInfo; + var AName: String; + var AData: TEnumIntType +); +Var + locBuffer : String; +begin + locBuffer := Trim(GetNodeValue(AName)); + If IsStrEmpty(locBuffer) Then + AData := 0 + Else + AData := GetEnumValue(ATypeInfo,locBuffer) +End; + +procedure TXmlRpcBaseFormatter.GetBool( + const ATypeInfo : PTypeInfo; + var AName : String; + var AData : Boolean +); +Var + locBuffer : String; +begin + locBuffer := LowerCase(Trim(GetNodeValue(AName))); + If IsStrEmpty(locBuffer) Then + AData := False + Else + AData := StrToBool(locBuffer); +end; + +procedure TXmlRpcBaseFormatter.GetInt( + const ATypeInfo: PTypeInfo; + var AName: String; + var AData: Integer +); +begin + AData := StrToIntDef(Trim(GetNodeValue(AName)),0); +end; + +procedure TXmlRpcBaseFormatter.GetInt64( + const ATypeInfo : PTypeInfo; + var AName : String; + var AData : Int64 +); +begin + AData := StrToInt64Def(Trim(GetNodeValue(AName)),0); +end; + +procedure TXmlRpcBaseFormatter.GetFloat( + const ATypeInfo : PTypeInfo; + var AName : String; + var AData : Extended +); +begin + AData := StrToFloatDef(Trim(GetNodeValue(AName)),0); +end; + +procedure TXmlRpcBaseFormatter.GetStr( + const ATypeInfo : PTypeInfo; + var AName : String; + var AData : String +); +begin + AData := GetNodeValue(AName); +end; + +procedure TXmlRpcBaseFormatter.GetObj( + const ATypeInfo : PTypeInfo; + var AName : String; + var AData : TObject +); +begin + TBaseRemotableClass(GetTypeData(ATypeInfo)^.ClassType).Load(AData, Self,AName,ATypeInfo); +end; + +function TXmlRpcBaseFormatter.GetXmlDoc(): TXMLDocument; +begin + Result := FDoc; +end; + +function TXmlRpcBaseFormatter.GetCurrentScope(): String; +begin + CheckScope(); + Result:= GetCurrentScopeObject().NodeName; +end; + +function TXmlRpcBaseFormatter.GetCurrentScopeObject(): TDOMElement; +begin + Result := StackTop().ScopeObject As TDOMElement; +end; + +function TXmlRpcBaseFormatter.StackTop(): TStackItem; +begin + CheckScope(); + Result := FStack.Peek() as TStackItem; +end; + +function TXmlRpcBaseFormatter.PopStack(): TStackItem; +begin + CheckScope(); + Result := FStack.Pop() as TStackItem; +end; + +constructor TXmlRpcBaseFormatter.Create(); +begin + Inherited Create(); + FContentType := sXMLRPC_CONTENT_TYPE; + FStack := TObjectStack.Create(); + FDoc := TXMLDocument.Create(); + FDoc.Encoding := 'UTF-8'; +end; + +destructor TXmlRpcBaseFormatter.Destroy(); +begin + FDoc.Free(); + ClearStack(); + FStack.Free(); + inherited Destroy(); +end; + +procedure TXmlRpcBaseFormatter.Clear(); +begin + InternalClear(True); +end; + +procedure TXmlRpcBaseFormatter.BeginObject( + const AName : string; + const ATypeInfo : PTypeInfo +); +begin + BeginScope(AName,'','',stObject,asNone); +end; + +procedure TXmlRpcBaseFormatter.BeginArray( + const AName : string; + const ATypeInfo : PTypeInfo; + const AItemTypeInfo : PTypeInfo; + const ABounds : Array Of Integer; + const AStyle : TArrayStyle +); +Var + typData : TTypeRegistryItem; + nmspc,nmspcSH : string; + i,j, k : Integer; + strNodeName : string; + xsiNmspcSH : string; +begin + if ( Length(ABounds) < 2 ) then begin + Error('Invalid array bounds.'); + end; + i := ABounds[0]; + j := ABounds[1]; + k := j - i + 1; + if ( k < 0 ) then begin + Error('Invalid array bounds.'); + end; + + BeginScope(AName,'','',stArray,AStyle); +end; + +procedure TXmlRpcBaseFormatter.NilCurrentScope(); +begin +end; + +function TXmlRpcBaseFormatter.IsCurrentScopeNil(): Boolean; +begin + Result := False; +end; + +procedure TXmlRpcBaseFormatter.BeginScope( + Const AScopeName,ANameSpace : string; + Const ANameSpaceShortName : string; + Const AScopeType : TScopeType; + const AStyle : TArrayStyle +); +Var + e : TDOMNode; + dtType : TXmlRpcDataType; +begin + if ( AScopeType = stArray ) then + dtType := xdtArray + else + dtType := xdtStruct; + if HasScope() then begin + e := StackTop().CreateBuffer(AScopeName,dtType); + end else begin + e := FDoc.CreateElement(XmlRpcDataTypeNames[dtType]); + FDoc.AppendChild(e); + end; + if ( AScopeType = stObject ) then begin + PushStack(e); + end else begin + PushStack(e,AStyle,''); + end; +end; + +function TXmlRpcBaseFormatter.InternalBeginScopeRead( + var AScopeName : string; + const ATypeInfo : PTypeInfo; + const AScopeType : TScopeType; + const AStyle : TArrayStyle; + const AItemName : string +): Integer; +var + locNode : TDOMNode; + stk : TStackItem; +begin + stk := StackTop(); + locNode := stk.FindNode(AScopeName); + if ( locNode = nil ) then begin + Result := -1; + end else begin + if ( AScopeType = stObject ) then begin + PushStack(locNode); + end else begin + PushStack(locNode,AStyle,AItemName); + end; + Result := StackTop().GetItemsCount(); + end; +end; + +procedure TXmlRpcBaseFormatter.SetSerializationStyle(const ASerializationStyle: TSerializationStyle); +begin + FSerializationStyle := ASerializationStyle; +end; + +function TXmlRpcBaseFormatter.GetSerializationStyle(): TSerializationStyle; +begin + Result := FSerializationStyle; +end; + +procedure TXmlRpcBaseFormatter.EndScope(); +begin + CheckScope(); + FStack.Pop().Free(); +end; + +procedure TXmlRpcBaseFormatter.AddScopeAttribute(const AName, AValue: string); +begin +// CheckScope(); + //GetCurrentScopeObject().SetAttribute(AName,AValue); +end; + +procedure TXmlRpcBaseFormatter.Put( + const AName: String; + const ATypeInfo: PTypeInfo; + const AData +); +Var + int64Data : Int64; + strData : string; + objData : TObject; + boolData : Boolean; + enumData : TEnumIntType; + floatDt : Extended; +begin + Case ATypeInfo^.Kind Of + tkInt64, tkQWord : + Begin + int64Data := Int64(AData); + PutInt64(AName,ATypeInfo,int64Data); + End; + tkLString, tkAString : + Begin + strData := String(AData); + PutStr(AName,ATypeInfo,strData); + End; + tkClass : + Begin + objData := TObject(AData); + PutObj(AName,ATypeInfo,objData); + End; + tkBool : + Begin + boolData := Boolean(AData); + PutBool(AName,ATypeInfo,boolData); + End; + tkInteger, tkEnumeration : + Begin + enumData := 0; + Case GetTypeData(ATypeInfo)^.OrdType Of + otSByte : enumData := ShortInt(AData); + otUByte : enumData := Byte(AData); + otSWord : enumData := SmallInt(AData); + otUWord : enumData := Word(AData); + otSLong, + otULong : enumData := LongInt(AData); + End; + If ( ATypeInfo^.Kind = tkInteger ) Then + PutInt64(AName,ATypeInfo,enumData) + Else + PutEnum(AName,ATypeInfo,enumData); + End; + tkFloat : + Begin + floatDt := 0; + Case GetTypeData(ATypeInfo)^.FloatType Of + ftSingle : floatDt := Single(AData); + ftDouble : floatDt := Double(AData); + ftExtended : floatDt := Extended(AData); + ftCurr : floatDt := Currency(AData); + ftComp : floatDt := Comp(AData); + End; + PutFloat(AName,ATypeInfo,floatDt); + End; + End; +end; + +procedure TXmlRpcBaseFormatter.PutScopeInnerValue( + const ATypeInfo : PTypeInfo; + const AData +); +Var + int64SData : Int64; + int64UData : QWord; + strData : string; + objData : TObject; + boolData : Boolean; + enumData : TEnumIntType; + floatDt : Extended; + dataBuffer : string; + frmt : string; + prcsn,i : Integer; +begin + CheckScope(); + Case ATypeInfo^.Kind Of + tkInt64 : + begin + int64SData := Int64(AData); + dataBuffer := IntToStr(int64SData); + end; + tkQWord : + begin + int64UData := QWord(AData); + dataBuffer := IntToStr(int64UData); + end; + tkLString, tkAString : + begin + strData := string(AData); + dataBuffer := strData; + end; + tkClass : + begin + raise EXmlRpcException.Create('Inner Scope value must be a "simple type" value.'); + end; + tkBool : + begin + boolData := Boolean(AData); + dataBuffer := BoolToStr(boolData); + end; + tkInteger : + begin + case GetTypeData(ATypeInfo)^.OrdType of + otSByte : enumData := ShortInt(AData); + otUByte : enumData := Byte(AData); + otSWord : enumData := SmallInt(AData); + otUWord : enumData := Word(AData); + otSLong, + otULong : enumData := LongInt(AData); + end; + dataBuffer := IntToStr(enumData); + end; + tkEnumeration : + begin + enumData := 0; + case GetTypeData(ATypeInfo)^.OrdType of + otSByte : enumData := ShortInt(AData); + otUByte : enumData := Byte(AData); + otSWord : enumData := SmallInt(AData); + otUWord : enumData := Word(AData); + otSLong, + otULong : enumData := LongInt(AData); + end; + dataBuffer := GetTypeRegistry().ItemByTypeInfo[ATypeInfo].GetExternalPropertyName(GetEnumName(ATypeInfo,enumData)) + end; + tkFloat : + begin + floatDt := 0; + case GetTypeData(ATypeInfo)^.FloatType of + ftSingle : + begin + floatDt := Single(AData); + prcsn := 7; + end; + ftDouble : + begin + floatDt := Double(AData); + prcsn := 15; + end; + ftExtended : + begin + floatDt := Extended(AData); + prcsn := 15; + end; + ftCurr : + begin + floatDt := Currency(AData); + prcsn := 7; + end; + ftComp : + begin + floatDt := Comp(AData); + prcsn := 7; + end; + end; + frmt := '#.' + StringOfChar('#',prcsn) + 'E-0'; + dataBuffer := FormatFloat(frmt,floatDt); + i := Pos(',',dataBuffer); + if ( i > 0 ) then + dataBuffer[i] := '.'; + end; + end; + StackTop().ScopeObject.AppendChild(FDoc.CreateTextNode(dataBuffer)); +end; + +procedure TXmlRpcBaseFormatter.Get( + const ATypeInfo : PTypeInfo; + var AName : String; + var AData +); +Var + int64Data : Int64; + strData : string; + objData : TObject; + boolData : Boolean; + enumData : TEnumIntType; + floatDt : Extended; +begin + Case ATypeInfo^.Kind Of + tkInt64,tkQWord : + Begin + int64Data := 0; + GetInt64(ATypeInfo,AName,int64Data); + Int64(AData) := int64Data; + End; + tkLString, tkAString : + Begin + strData := ''; + GetStr(ATypeInfo,AName,strData); + String(AData) := strData; + End; + tkClass : + Begin + objData := TObject(AData); + GetObj(ATypeInfo,AName,objData); + TObject(AData) := objData; + End; + tkBool : + Begin + boolData := False; + GetBool(ATypeInfo,AName,boolData); + Boolean(AData) := boolData; + End; + tkInteger, tkEnumeration : + Begin + enumData := 0; + If ( ATypeInfo^.Kind = tkInteger ) Then + GetInt64(ATypeInfo,AName,enumData) + Else + GetEnum(ATypeInfo,AName,enumData); + Case GetTypeData(ATypeInfo)^.OrdType Of + otSByte : ShortInt(AData) := enumData; + otUByte : Byte(AData) := enumData; + otSWord : SmallInt(AData) := enumData; + otUWord : Word(AData) := enumData; + otSLong, + otULong : LongInt(AData) := enumData; + End; + End; + tkFloat : + Begin + floatDt := 0; + GetFloat(ATypeInfo,AName,floatDt); + Case GetTypeData(ATypeInfo)^.FloatType Of + ftSingle : Single(AData) := floatDt; + ftDouble : Double(AData) := floatDt; + ftExtended : Extended(AData) := floatDt; + ftCurr : Currency(AData) := floatDt; + ftComp : Comp(AData) := floatDt; + End; + End; + End; +end; + +procedure TXmlRpcBaseFormatter.GetScopeInnerValue( + const ATypeInfo : PTypeInfo; + var AData +); +Var + enumData : TEnumIntType; + floatDt : Extended; + dataBuffer : string; + nd : TDOMNode; +begin + CheckScope(); + nd := StackTop().ScopeObject; + if nd.HasChildNodes() then + dataBuffer := nd.FirstChild.NodeValue + else + dataBuffer := StackTop().ScopeObject.NodeValue; + Case ATypeInfo^.Kind Of + tkInt64 : Int64(AData) := StrToInt64Def(Trim(dataBuffer),0); + tkQWord : QWord(AData) := StrToInt64Def(Trim(dataBuffer),0); + tkLString, + tkAString : string(AData) := dataBuffer; + tkClass : + begin + raise EXmlRpcException.Create('Inner Scope value must be a "simple type" value.'); + end; + tkBool : + begin + dataBuffer := LowerCase(Trim(dataBuffer)); + if IsStrEmpty(dataBuffer) then + Boolean(AData) := False + else + Boolean(AData) := StrToBool(dataBuffer); + end; + tkInteger, tkEnumeration : + begin + if ( ATypeInfo^.Kind = tkInteger ) then + enumData := StrToIntDef(Trim(dataBuffer),0) + else + enumData := GetEnumValue(ATypeInfo,GetTypeRegistry().ItemByTypeInfo[ATypeInfo].GetInternalPropertyName(dataBuffer)); + case GetTypeData(ATypeInfo)^.OrdType of + otSByte : ShortInt(AData) := enumData; + otUByte : Byte(AData) := enumData; + otSWord : SmallInt(AData) := enumData; + otUWord : Word(AData) := enumData; + otSLong, + otULong : LongInt(AData) := enumData; + end; + end; + tkFloat : + begin + floatDt := StrToFloatDef(Trim(dataBuffer),0); + case GetTypeData(ATypeInfo)^.FloatType of + ftSingle : Single(AData) := floatDt; + ftDouble : Double(AData) := floatDt; + ftExtended : Extended(AData) := floatDt; + ftCurr : Currency(AData) := floatDt; + ftComp : Comp(AData) := floatDt; + end; + end; + end; +end; + +procedure TXmlRpcBaseFormatter.SaveToStream(AStream: TStream); +begin + WriteXMLFile(FDoc,AStream); +end; + +procedure TXmlRpcBaseFormatter.LoadFromStream(AStream: TStream); +Var + nd : TDOMNode; +begin + InternalClear(False); + ReadXMLFile(FDoc,AStream); + nd := GetXmlDoc().DocumentElement; + If Assigned(nd) Then + PushStack(nd); +end; + +procedure TXmlRpcBaseFormatter.Error(const AMsg: string); +begin + Raise EXmlRpcException.Create(AMsg); +end; + +procedure TXmlRpcBaseFormatter.Error(const AMsg: string;const AArgs: array of const); +begin + Raise EXmlRpcException.CreateFmt(AMsg,AArgs); +end; + + +{ TParamsArrayStackItem } + +procedure TParamsArrayStackItem.EnsureListCreated(); +begin + if ( FItemList = nil ) then begin + FItemList := CreateList(); + end; +end; + +function TParamsArrayStackItem.GetItemsCount(): Integer; +begin + EnsureListCreated(); + if Assigned(FItemList) then begin + Result := FItemList.Count; + end else begin + Result := 0; + end; +end; + +function TParamsArrayStackItem.CreateList(): TDOMNodeList; +begin + if ScopeObject.HasChildNodes() then begin + Result := ScopeObject.GetChildNodes(); + end else begin + Result := nil; + end; +end; + +destructor TParamsArrayStackItem.Destroy(); +begin + if Assigned(FItemList) then + FItemList.Release(); + inherited Destroy(); +end; + +function TParamsArrayStackItem.FindNode(var ANodeName: string): TDOMNode; +begin + EnsureListCreated(); + if ( FIndex >= FItemList.Count ) then + raise EXmlRpcException.CreateFmt('Index out of bound : %d; Node Name = "%s"; Parent Node = "%s"',[FIndex,ANodeName,ScopeObject.NodeName]); + Result:= FItemList.Item[FIndex]; + if Result.HasChildNodes() then begin + Result := Result.FirstChild; + Inc(FIndex); + ANodeName := Result.NodeName; + end else begin + raise EXmlRpcException.CreateFmt('Invalid array item : Index = %d; Node Name = "%s"; Parent Node = "%s"',[FIndex,ANodeName,ScopeObject.NodeName]); + end; +end; + +function TParamsArrayStackItem.CreateBuffer( + const AName: string; + const ADataType: TXmlRpcDataType +): TDOMNode; +var + prmNode, valueNode : TDOMNode; +begin + prmNode := ScopeObject.OwnerDocument.CreateElement(sPARAM); + ScopeObject.AppendChild(prmNode); + valueNode := ScopeObject.OwnerDocument.CreateElement(sVALUE); + prmNode.AppendChild(valueNode); + Result := ScopeObject.OwnerDocument.CreateElement(XmlRpcDataTypeNames[ADataType]); + valueNode.AppendChild(Result); +end; + +end. diff --git a/wst/trunk/tests/test_suite/testformatter_unit.pas b/wst/trunk/tests/test_suite/testformatter_unit.pas index 2c589b04c..230bba922 100644 --- a/wst/trunk/tests/test_suite/testformatter_unit.pas +++ b/wst/trunk/tests/test_suite/testformatter_unit.pas @@ -284,6 +284,8 @@ type TTestFormatterSimpleType= class(TTestCase) protected function CreateFormatter(ARootType : PTypeInfo):IFormatterBase;virtual;abstract; + function Support_ComplextType_with_SimpleContent():Boolean;virtual; + function Support_nil():Boolean;virtual; published procedure Test_Int_8; procedure Test_Int_8_ScopeData; @@ -374,6 +376,20 @@ type function CreateFormatter(ARootType : PTypeInfo):IFormatterBase;override; end; + { TTestXmlRpcFormatterAttributes } + + TTestXmlRpcFormatterAttributes = class(TTestFormatterSimpleType) + protected + function CreateFormatter(ARootType : PTypeInfo):IFormatterBase;override; + end; + + TTestXmlRpcFormatter= class(TTestFormatter) + protected + function CreateFormatter(ARootType : PTypeInfo):IFormatterBase;override; + function Support_ComplextType_with_SimpleContent():Boolean;override; + function Support_nil():Boolean;override; + end; + { TTestArray } TTestArray= class(TTestCase) @@ -431,7 +447,17 @@ type end; implementation -uses base_binary_formatter, base_soap_formatter; +uses base_binary_formatter, base_soap_formatter, base_xmlrpc_formatter; + +function TTestFormatterSimpleType.Support_ComplextType_with_SimpleContent( ): Boolean; +begin + Result := True; +end; + +function TTestFormatterSimpleType.Support_nil(): Boolean; +begin + Result := True; +end; procedure TTestFormatterSimpleType.Test_Int_8; const VAL_1 = 12; VAL_2 = -10; @@ -453,7 +479,7 @@ begin f.EndScope(); s := TMemoryStream.Create(); - f.SaveToStream(s); + f.SaveToStream(s); s.SaveToFile(ClassName + '.xml'); intVal_U := 0; intVal_S := 0; @@ -1074,6 +1100,9 @@ var nu : TComplexInt64UContentRemotable; x : string; begin + if not Support_ComplextType_with_SimpleContent() then + Exit; + s := nil; ns := TComplexInt64SContentRemotable.Create(); nu := TComplexInt64UContentRemotable.Create(); @@ -1147,6 +1176,9 @@ var nu : TComplexInt32UContentRemotable; x : string; begin + if not Support_ComplextType_with_SimpleContent() then + Exit; + s := nil; ns := TComplexInt32SContentRemotable.Create(); nu := TComplexInt32UContentRemotable.Create(); @@ -1220,6 +1252,9 @@ var nu : TComplexInt16UContentRemotable; x : string; begin + if not Support_ComplextType_with_SimpleContent() then + Exit; + s := nil; ns := TComplexInt16SContentRemotable.Create(); nu := TComplexInt16UContentRemotable.Create(); @@ -1293,6 +1328,9 @@ var nu : TComplexInt8UContentRemotable; x : string; begin + if not Support_ComplextType_with_SimpleContent() then + Exit; + s := nil; ns := TComplexInt8SContentRemotable.Create(); nu := TComplexInt8UContentRemotable.Create(); @@ -1366,6 +1404,9 @@ var nu : TComplexFloatDoubleContentRemotable; x : string; begin + if not Support_ComplextType_with_SimpleContent() then + Exit; + s := nil; ns := TComplexFloatExtendedContentRemotable.Create(); nu := TComplexFloatDoubleContentRemotable.Create(); @@ -1440,6 +1481,9 @@ var ns : TComplexStringContentRemotable; x : string; begin + if not Support_ComplextType_with_SimpleContent() then + Exit; + s := nil; ns := TComplexStringContentRemotable.Create(); a := TClass_CplxSimpleContent.Create(); @@ -1552,6 +1596,9 @@ var a : TClass_B; x : string; begin + if not Support_ComplextType_with_SimpleContent() then + Exit; + s := nil; a := nil; try @@ -2402,6 +2449,9 @@ var x : string; a, b : TComplexInt32SContentRemotable; begin + if not Support_ComplextType_with_SimpleContent() then + Exit; + s := nil; a := nil; b := nil; @@ -3066,6 +3116,31 @@ begin Fail('Write me!'); end; +{ TTestXmlRpcFormatterAttributes } + +function TTestXmlRpcFormatterAttributes.CreateFormatter(ARootType: PTypeInfo): IFormatterBase; +begin + Result := TXmlRpcBaseFormatter.Create() as IFormatterBase; + //Result.BeginObject('Env',ARootType) +end; + +{ TTestXmlRpcFormatter } + +function TTestXmlRpcFormatter.CreateFormatter(ARootType: PTypeInfo): IFormatterBase; +begin + Result := TXmlRpcBaseFormatter.Create() as IFormatterBase; +end; + +function TTestXmlRpcFormatter.Support_ComplextType_with_SimpleContent(): Boolean; +begin + Result := False; +end; + +function TTestXmlRpcFormatter.Support_nil(): Boolean; +begin + Result := False; +end; + initialization RegisterStdTypes(); GetTypeRegistry().Register(sXSD_NS,TypeInfo(TTestEnum),'TTestEnum').RegisterExternalPropertyName('teOne', '1'); @@ -3101,4 +3176,8 @@ initialization RegisterTest(TTest_TDateRemotable); RegisterTest(TTest_TDurationRemotable); RegisterTest(TTest_TTimeRemotable); + + RegisterTest(TTestXmlRpcFormatterAttributes); + RegisterTest(TTestXmlRpcFormatter); + end. diff --git a/wst/trunk/tests/test_suite/testmetadata_unit.pas b/wst/trunk/tests/test_suite/testmetadata_unit.pas index a4ea7f168..73cce75b2 100644 --- a/wst/trunk/tests/test_suite/testmetadata_unit.pas +++ b/wst/trunk/tests/test_suite/testmetadata_unit.pas @@ -20,7 +20,8 @@ interface uses Classes, SysUtils, DOM, XMLWrite, fpcunit, testutils, testregistry, - metadata_generator, binary_streamer, metadata_repository, parserdefs, + metadata_generator, binary_streamer, metadata_repository, pastree, + pascal_parser_intf, metadata_wsdl; type @@ -29,7 +30,7 @@ type TTestMetadata= class(TTestCase) protected - function CreateSymbolTable():TSymbolTable; + function CreateSymbolTable():TwstPasTreeContainer; published procedure test_Metadata(); end; @@ -39,32 +40,74 @@ implementation { TTestMetadata } -function TTestMetadata.CreateSymbolTable(): TSymbolTable; -Var - inft : TInterfaceDefinition; +function TTestMetadata.CreateSymbolTable(): TwstPasTreeContainer; + + function CreateProc( + const AName : string; + AClass : TPasClassType; + AContainer : TwstPasTreeContainer + ) : TPasProcedure ; + begin + Result := TPasProcedure(AContainer.CreateElement(TPasProcedure,AName,AContainer.CurrentModule.InterfaceSection,visDefault,'',0)); + Result.ProcType := TPasProcedureType(AContainer.CreateElement(TPasProcedureType,'',Result,visDefault,'',0)); + AClass.Members.Add(Result); + end; + + function CreateFunc( + const AName, AResultTypeName : string; + AClass : TPasClassType; + AContainer : TwstPasTreeContainer + ) : TPasFunction ; + begin + Result := TPasFunction(AContainer.CreateElement(TPasFunction,AName,AContainer.CurrentModule.InterfaceSection,visDefault,'',0)); + Result.ProcType := AContainer.CreateFunctionType('','result',Result,True,'',0); + AClass.Members.Add(Result); + TPasFunctionType(Result.ProcType).ResultEl.ResultType := AContainer.FindElement(AResultTypeName) as TPasType; + TPasFunctionType(Result.ProcType).ResultEl.ResultType.AddRef(); + end; + + function CreateParam( + const AName, ATypeName : string; + const AAccess : TArgumentAccess; + AProc : TPasProcedure; + AContainer : TwstPasTreeContainer + ) : TPasArgument ; + begin + Result := TPasArgument(AContainer.CreateElement(TPasArgument,AName,AProc,visDefault,'',0)); + Result.ArgType := AContainer.FindElement(ATypeName) as TPasType; + Result.ArgType.AddRef(); + Result.Access := AAccess; + end; + +var + inft : TPasClassType; + sct : TPasSection; + locProc : TPasProcedure; begin - Result := TSymbolTable.Create('test_unit_name'); - Result.Add(TTypeDefinition.Create('integer')); - Result.Add(TTypeDefinition.Create('string')); - Result.Add(TTypeDefinition.Create('double')); + Result := TwstPasTreeContainer.Create(); + CreateWstInterfaceSymbolTable(Result); + Result.CreateElement(TPasModule,'test_unit_name',Result.Package,visDefault,'',0); + sct := TPasSection(Result.CreateElement(TPasSection,'',Result.CurrentModule,visDefault,'',0)); + Result.CurrentModule.InterfaceSection := sct; - inft := TInterfaceDefinition.Create('service_1'); - Result.Add(inft); - inft.AddMethod('void_operation_proc',mtProcedure); - inft.AddMethod('void_operation_func',mtProcedure).AddParameter('result',pmOut,Result.ByName('integer') as TTypeDefinition); + inft := TPasClassType(Result.CreateElement(TPasClassType,'service_1',sct,visDefault,'',0)); + inft.ObjKind := okInterface; + sct.Declarations.Add(inft); + sct.Types.Add(inft); + CreateProc('void_operation_proc',inft,Result); + CreateFunc('void_operation_func','Integer',inft,Result); - inft := TInterfaceDefinition.Create('service_2'); - Result.Add(inft); - with inft.AddMethod('dis_proc',mtProcedure) do begin - AddParameter('d',pmNone,Result.ByName('double') as TTypeDefinition); - AddParameter('i',pmConst,Result.ByName('integer') as TTypeDefinition); - AddParameter('s',pmOut,Result.ByName('string') as TTypeDefinition); - end; - with inft.AddMethod('sid_func',mtFunction) do begin - AddParameter('s',pmConst,Result.ByName('string') as TTypeDefinition); - AddParameter('i',pmVar,Result.ByName('integer') as TTypeDefinition); - AddParameter('d',pmOut,Result.ByName('double') as TTypeDefinition); - end; + inft := TPasClassType(Result.CreateElement(TPasClassType,'service_2',sct,visDefault,'',0)); + inft.ObjKind := okInterface; + sct.Declarations.Add(inft); + sct.Types.Add(inft); + locProc := CreateProc('dis_proc',inft,Result); + CreateParam('d','double',argDefault,locProc,Result); + CreateParam('i','Integer',argConst,locProc,Result); + CreateParam('s','string',argOut,locProc,Result); + locProc := CreateFunc('sid_func','double',inft,Result); + CreateParam('s','string',argConst,locProc,Result); + CreateParam('i','Integer',argVar,locProc,Result); end; procedure PrintWSDL(ARep : PServiceRepository); @@ -92,7 +135,7 @@ end; procedure TTestMetadata.test_Metadata(); var - st : TSymbolTable; + st : TwstPasTreeContainer; mg : TMetadataGenerator; wtr : IDataStore; strm : TMemoryStream; @@ -134,8 +177,8 @@ begin AssertNotNull('params pointer',po^.Params); pop := po^.Params; AssertEquals('param name','result',pop^.Name); - AssertEquals('param type name','integer',pop^.TypeName); - AssertEquals('param modifier',ord(pmOut),ord(pop^.Modifier)); + AssertEquals('param type name','int',pop^.TypeName); + AssertEquals('param modifier',ord(argOut),ord(pop^.Modifier)); rp^.NameSpace := 'http://test_name_space/'; //PrintWSDL(rp); diff --git a/wst/trunk/tests/test_suite/wst_test_suite.lpi b/wst/trunk/tests/test_suite/wst_test_suite.lpi index a0f0828ef..773b6d46c 100644 --- a/wst/trunk/tests/test_suite/wst_test_suite.lpi +++ b/wst/trunk/tests/test_suite/wst_test_suite.lpi @@ -7,7 +7,7 @@ - + @@ -27,7 +27,7 @@ - + @@ -40,9 +40,9 @@ - - - + + + @@ -52,27 +52,23 @@ - - - - - + + - - - - + + + @@ -80,8 +76,8 @@ - - + + @@ -94,9 +90,9 @@ - - - + + + @@ -106,17 +102,18 @@ - - - - + + + + + @@ -124,7 +121,7 @@ - + @@ -132,34 +129,31 @@ - - + + - - - - - - - - - + + + - - + + + - - + + + - - + + + @@ -170,200 +164,331 @@ - - + + - - - - + + - - - + + + - - - + + + - - - + + + - - - - - + + + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - + + + - - - - - - - - - - + + + - - - - - - - - - - - - - - - + + + - - - - - - - - - - - - - - - - - + + + - - - - - + + + - - - - - + + + - - - + + + - - - - - + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -378,6 +503,7 @@ + @@ -395,7 +521,7 @@ - + @@ -425,33 +551,17 @@ - - + + - - + + - - + + - - - - - - - - - - - - - - - - diff --git a/wst/trunk/tests/test_suite/wst_test_suite.lpr b/wst/trunk/tests/test_suite/wst_test_suite.lpr index 784583a89..cef514731 100644 --- a/wst/trunk/tests/test_suite/wst_test_suite.lpr +++ b/wst/trunk/tests/test_suite/wst_test_suite.lpr @@ -9,7 +9,7 @@ uses base_service_intf, base_soap_formatter, binary_formatter, binary_streamer, server_binary_formatter, metadata_repository, metadata_generator, parserdefs, server_service_intf, metadata_wsdl, - test_parserdef; + test_parserdef, base_xmlrpc_formatter; Const ShortOpts = 'alh'; diff --git a/wst/trunk/type_lib_edtr/typ_lib_edtr.lpi b/wst/trunk/type_lib_edtr/typ_lib_edtr.lpi index 72d3062ca..d7d0006f5 100644 --- a/wst/trunk/type_lib_edtr/typ_lib_edtr.lpi +++ b/wst/trunk/type_lib_edtr/typ_lib_edtr.lpi @@ -7,7 +7,7 @@ - + @@ -32,13 +32,13 @@ - + - + @@ -65,12 +65,12 @@ - - + + - + @@ -80,7 +80,7 @@ - + @@ -124,7 +124,7 @@ - + @@ -159,7 +159,7 @@ - + @@ -308,7 +308,7 @@ - + @@ -318,7 +318,7 @@ - + @@ -327,7 +327,7 @@ - + @@ -337,7 +337,7 @@ - + @@ -364,78 +364,30 @@ - + - + - + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/wst/trunk/ws_helper/metadata_generator.pas b/wst/trunk/ws_helper/metadata_generator.pas index 52fd2c22c..82e99f424 100644 --- a/wst/trunk/ws_helper/metadata_generator.pas +++ b/wst/trunk/ws_helper/metadata_generator.pas @@ -63,7 +63,7 @@ begin FStream.WriteStr(sWST_META); FStream.WriteStr(FSymbolTable.CurrentModule.Name); k := 0; - typeList := FSymbolTable.CurrentModule.InterfaceSection.Types; + typeList := FSymbolTable.CurrentModule.InterfaceSection.Declarations; c := typeList.Count; for i := 0 to pred(c) do begin elt := TPasElement(typeList[i]); @@ -100,6 +100,8 @@ procedure TMetadataGenerator.GenerateIntfMetadata(AIntf: TPasClassType); FStream.WriteStr(AMeth.Name); if AMeth.InheritsFrom(TPasFunction) then begin FStream.WriteInt8U(k + 1); + end else begin + FStream.WriteInt8U(k); end; for j := 0 to pred(k) do begin WriteParam(TPasArgument(argLst[j])); @@ -142,7 +144,7 @@ Var elt : TPasElement; begin GenerateHeader(); - typeList := FSymbolTable.CurrentModule.InterfaceSection.Types; + typeList := FSymbolTable.CurrentModule.InterfaceSection.Declarations; c := Pred(typeList.Count); for i := 0 to c do begin elt := TPasElement(typeList[i]); diff --git a/wst/trunk/ws_helper/wsdl2pas_imp.pas b/wst/trunk/ws_helper/wsdl2pas_imp.pas index 876ac4279..a43542af4 100644 --- a/wst/trunk/ws_helper/wsdl2pas_imp.pas +++ b/wst/trunk/ws_helper/wsdl2pas_imp.pas @@ -211,31 +211,9 @@ const s_xmlns : WideString = 'xmlns'; //---------------------------------------------------------- - s_NODE_NAME = 'NodeName'; - s_NODE_VALUE = 'NodeValue'; s_TRANSPORT = 'TRANSPORT'; s_FORMAT = 'FORMAT'; -type TCursorExposedType = ( cetRttiNode, cetDomNode ); -function CreateAttributesCursor(ANode : TDOMNode; const AExposedType : TCursorExposedType):IObjectCursor; -begin - Result := nil; - if ( ANode <> nil ) and ( ANode.Attributes <> nil ) and ( ANode.Attributes.Length > 0 ) then begin - Result := TDOMNamedNodeMapCursor.Create(ANode.Attributes,faNone) ; - if ( AExposedType = cetRttiNode ) then - Result := TDOMNodeRttiExposerCursor.Create(Result); - end; -end; - -function CreateChildrenCursor(ANode : TDOMNode; const AExposedType : TCursorExposedType):IObjectCursor; -begin - Result := nil; - if ( ANode <> nil ) and ANode.HasChildNodes() then begin - Result := TDOMNodeListCursor.Create(ANode.GetChildNodes(),faFreeOnDestroy) ; - if ( AExposedType = cetRttiNode ) then - Result := TDOMNodeRttiExposerCursor.Create(Result); - end; -end; function ExtractNameFromQName(const AQName : string):string ; var diff --git a/wst/trunk/wst_rtti_filter/dom_cursors.pas b/wst/trunk/wst_rtti_filter/dom_cursors.pas index bc2fda250..5c9419057 100644 --- a/wst/trunk/wst_rtti_filter/dom_cursors.pas +++ b/wst/trunk/wst_rtti_filter/dom_cursors.pas @@ -10,6 +10,11 @@ uses Classes, SysUtils, cursor_intf, DOM; +const + + s_NODE_NAME = 'NodeName'; + s_NODE_VALUE = 'NodeValue'; + type TFreeAction = ( faNone, faFreeOnDestroy ); @@ -87,8 +92,34 @@ type destructor Destroy();override; end; + TCursorExposedType = ( cetRttiNode, cetDomNode ); + + + function CreateChildrenCursor(ANode : TDOMNode; const AExposedType : TCursorExposedType):IObjectCursor; + function CreateAttributesCursor(ANode : TDOMNode; const AExposedType : TCursorExposedType):IObjectCursor; + implementation +function CreateChildrenCursor(ANode : TDOMNode; const AExposedType : TCursorExposedType):IObjectCursor; +begin + Result := nil; + if ( ANode <> nil ) and ANode.HasChildNodes() then begin + Result := TDOMNodeListCursor.Create(ANode.GetChildNodes(),faFreeOnDestroy) ; + if ( AExposedType = cetRttiNode ) then + Result := TDOMNodeRttiExposerCursor.Create(Result); + end; +end; + +function CreateAttributesCursor(ANode : TDOMNode; const AExposedType : TCursorExposedType):IObjectCursor; +begin + Result := nil; + if ( ANode <> nil ) and ( ANode.Attributes <> nil ) and ( ANode.Attributes.Length > 0 ) then begin + Result := TDOMNamedNodeMapCursor.Create(ANode.Attributes,faNone) ; + if ( AExposedType = cetRttiNode ) then + Result := TDOMNodeRttiExposerCursor.Create(Result); + end; +end; + { TDOMNodeListCursor } procedure TDOMNodeListCursor.Reset();