-
Content Count
2914 -
Joined
-
Last visited
-
Days Won
130
Everything posted by Remy Lebeau
-
Need help adding namespaces to SOAP
Remy Lebeau replied to Stéphane Wierzbicki's topic in Network, Cloud and Web
Note without seeing the actual code and a log of the actual TCP communications. Probably the XML was malformed in a way the server didn't like, so it forcibly closed the connection. Though an HTTP 504 response code is a Gateway Timeout error, it is meant to be used only by gateways, not by servers. So maybe there is an intermediate proxy between your client and the target server, and the proxy experienced a problem? Really hard to diagnose something like this without any context or details. -
Memory leak in UnicodeString to string conversion
Remy Lebeau replied to dkprojektai's topic in OmniThreadLibrary
Then I don't see how there can possibly be a leak in the code you have shown. Something else is going on. You are just going to have to debug the code for yourself to see exactly where the real leak is. What you described earlier suggests that the compiler is not freeing the 'Recognition: string' variable when your Parallel.For() procedure exits, and that is simply not how the compiler is supposed to work. That is not necessary. As I stated earlier, you can assign a WideString directly to a String, and vice versa. The compiler will handle everything for you, as WideString and String are both managed types that the compiler knows how to convert between, and free when they go out of scope. -
Memory leak in UnicodeString to string conversion
Remy Lebeau replied to dkprojektai's topic in OmniThreadLibrary
Then you are going to have to ask the library author to change it, because this implementation is broken. IRecognitionResult is derived from IDispatch, which is an OLE interface. Pascal strings simply are not compatible with OLE - period. The Pascal wrapper for the interface MUST use WideString instead, which uses the OLE BSTR string type. -
Segmentation fault while trying to receive UDP broadcast messages on Android
Remy Lebeau replied to ertank's topic in Indy
I can't really comment on the multicast issue, especially on Android. But if you are really doing multicasting, why are you using TIdUDPServer? That is not a multicast-enabled component. Indy has separate TIdIPMCastClient and TIdIPMCastServer components specifically for multicast. For UDP, assuming a plain vanilla network broadcast is in fact, being used, are you setting up the TIdUDPServer.Bindings collection at all prior to activating the server? One problem I do see is your use of TThread.Queue() captures the ABinding object, which is no longer valid once the TIdUDPServer is freed. Delphi anonymous procedures capture variables, not values. You should use TThread.Queue() more like this instead: procedure TForm3.QueueLog(const AMsg: string); begin TThread.Queue(nil, procedure begin Log(AMsg); end ); end; procedure TForm3.QueueTestConnection(const APeerIP: string); begin TThread.Queue(nil, procedure begin TestConnection(APeerIP); end ); end; procedure TForm3.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread; const AData: TIdBytes; ABinding: TIdSocketHandle); var Data: string; begin Data := TEncoding.Default.GetString(AData); QueueLog('Incoming broadcast message from: ' + ABinding.PeerIP); if SameText(Data, 'mytriggerphrase') then begin QueueTestConnection(ABinding.PeerIP); end; end; -
Bug in Delphi string behavior?
Remy Lebeau replied to A.M. Hoornweg's topic in RTL and Delphi Object Pascal
Doesn't matter. The Delphi compiler still manages WideString instances for you. It knows to use the Windows memory manager instead of the RTL memory manager for allocating and freeing WideString data. Doesn't make WideString any less of a managed type compared to other string types. -
Memory leak in UnicodeString to string conversion
Remy Lebeau replied to dkprojektai's topic in OmniThreadLibrary
That type-cast is not necessary. Assigning a String (or a WideString) to a String is handled automatically by the compiler. This is not the source of your leaking. Did you change the recognition_text property to return a WideString instead of a String, like I suggested 8 months ago? What does the implementation of Get_text() actually look like? -
Bug in Delphi string behavior?
Remy Lebeau replied to A.M. Hoornweg's topic in RTL and Delphi Object Pascal
It should, as WideString is a managed type. It would be more accurate to say that it does not occur for non-managed types, like integers, etc. -
Then CSIDL_COMMON_APPDATA/FOLDERID_ProgramData is appropriate.
-
Then you need to grep the RTL source files to find it, or just add the declaration to your own code. The *debugger* doesn't care about DLL reference, so I assume you mean the *compiler* instead? Of course it can. Every Win32 API DLL can be, Microsoft ships both 32bit and 64bit versions of them.
-
Why not simply declare the function yourself in your own code? function SHOpenFolderAndSelectItems(pidlFolder: PCIDLIST_ABSOLUTE; cidl: UINT; apidl: PCUITEMID_CHILD_ARRAY; dwFlags: DWORD): HRESULT; stdcall; external 'shell32.dll';
-
TIdQOTD implements the "Quote of the Day" protocol described in RFC 865. It connects to a QOTD server on port 17, grabs all of the raw bytes the server provides until the server closes the connection, and then returns the raw bytes as a string. But you are not connecting to a real QOTD server on "quotes4all.net". When you changed the TIdQOTD.Port property from 17 to 80, you are connecting to an HTTP server on "quotes4all.net" instead, and as such it requires an HTTP client rather than a QOTD client. You are not seeing any data being returned because TIdQOTD is not requesting any data, and eventually the HTTP server closes the connection when it does not receive a valid HTTP request. In Alister's demo, he connects to real QOTD servers for "alpha.mike-r.com" and "quotes4all.net" on port 17 only, not on port 80. The QOTD server on "alpha.mike-r.com" still works (I just tried it), but it does not appear that there is a QOTD server running at "quotes4all.net" on port 17 anymore (or maybe it is just offline right now, who knows. Alister's demo is over a decade old, after all). So, if you want to use TIdQOTD, you need to connect to a real QOTD server, like the one at "alpha.mike-r.com". If you want to use "quotes4all.net" then you need to use TIdHTTP instead of TIdQOTD, eg: uses ..., IdHTTP; var HTTP: TIdHTTP; Quote: string; begin HTTP := TIdHTTP.Create; try Quote := HTTP.Get('http://quotes4all.net'); finally HTTP.Free; end; end; Just know that you are going to get more data than you are expecting, since quotes4all's HTTP server delivers content in HTML format, which you will have to parse afterwards to extract the text you want.
-
Delphi 10.3.3 - Indy - could not load root certificate
Remy Lebeau replied to Vandrovnik's topic in Indy
Embarcadero will be releasing a hotfix for 10.3.3 soon to address this in the shipped version of Indy. -
Delphi 10.3.3 - Indy - could not load root certificate
Remy Lebeau replied to Vandrovnik's topic in Indy
Install instructions are on Indy's website. -
Black screen while processing longer task on windows server 2012 R2
Remy Lebeau replied to Soji's topic in General Help
That is not entirely true. It does have side-effects if you are not careful. It allows pending messages from SendMessage...() from other threads to be processed (even though they don't go through the message queue themselves, they still require the receiving thread to perform message retrieval operations so they can be delivered). More importantly, it allows on-demand synthetic messages, like WM_TIMER, to be added to the queue (see Why is my message queue full of WM_TIMER messages?). -
Delphi 10.3.3 - Indy - could not load root certificate
Remy Lebeau replied to Vandrovnik's topic in Indy
Which is a duplicate of https://quality.embarcadero.com/browse/RSP-26742, which has a patch on https://quality.embarcadero.com/browse/RSP-27144 But either way, make sure you are using the latest code from Indy's GitHub repo. The version that shipped with the IDE was modified by accident by Embarcadero, it was never supposed to be shipped that way. The code in the repo was not broken to begin with. Marco explained the situation to me and apologized for the mixup. -
Unless the Form has an OnClose event handler that sets the Action parameter to caFree, allowing the Form to free itself when it is closed. This is a common idiom when using Show() instead of ShowModal(). It does not look at the Owner at all. Nor could it anyway, because the Owner may not be a TWinControl at all. Candidates for an auto-assigned PopupParent include the Application's ActiveForm, the Application's MainForm, the Screen's ActiveForm, and the Application window.
-
I'm not a Unix/Linux developer, I have very little knowledge of what it takes to use those platform APIs properly. I didn't write those sections of Indy's code, I just maintain them. Obviously the new code I recently added is not working. So feel free to do whatever you need to make them work correctly, and then submit the changes to me and I will happily incorporate them.
-
When you encounter a problem with something, you need to be more specific about WHAT the problem actually is, and WHERE the problem is in the code. It is generally considered impolite to just dump code into a forum and expect people to debug it for you without any idea what is wrong with it. There is always only 1 top-level element in a document. But there could be XML processing instruction before that element (<?xml ...?>, etc). To get the 1st element in a document, you should use the DocumentElement property instead: LNodeElement := LDocument.DocumentElement; As it should be, since <messages> is the only child node of the <inbox-query-response> element. But your code is not going any deeper into the document, so you are not seeing the <message> child elements, and their child elements, and so on. You have to iterate each level of ChildNodes separately. That will never be true for the <messages> element that LNode is pointing at. Neither will that. With that said, try something more like this: procedure TForm2.RetrieveDocument; var LDocument: IXMLDocument; LNodeElement, LNode: IXMLNode; LAttrValue: string; I: Integer; begin LDocument := TXMLDocument.Create(nil); LDocument.LoadFromFile(SrcPath); { File should exist. } // Number of childNodes, always shows 1 ShowMessage(IntToStr(LDocument.ChildNodes.Count)); { Find the root element node. } LNodeElement := LDocument.DocumentElement; if LNodeElement <> nil then begin { Get a specific attribute. } if LNodeElement.HasAttribute('version') then begin LAttrValue := LNodeElement.Attributes['version']; ShowMessage('Attribute value: ' + LAttrValue); end; { Find a specific node. } LNodeElement := LNodeElement.ChildNodes.FindNode('messages'); if LNodeElement <> nil then begin { Traverse messages. } for I := 0 to LNodeElement.ChildNodes.Count - 1 do begin LNode := LNodeElement.ChildNodes.Get(I); { Display node name. } ShowMessage('Node name: ' + LNode.NodeName); if LNode.NodeName = 'message' then ProcessMessageElement(LNode); end; end; end; end; procedure TForm2.ProcessMessageElement(const AMessage: IXMLNode); var I: Integer; LNode: IXMLNode; begin { Traverse values. } for I := 0 to AMessage.ChildNodes.Count - 1 do begin LNode := AMessage.ChildNodes.Get(I); { Check whether the node type is Text. } if (LNode.NodeType = ntText) or LNode.IsTextElement then begin ShowMessage(LNode.NodeName + ' is a node of type Text. The text is: ' + LNode.Text); end; if LNode.NodeName = 'message-meta-data' then ProcessMetaDataElement(LNode); end; end; procedure TForm2.ProcessMetaDataElement(const AMetaData: IXMLNode); var I: Integer; LNode: IXMLNode; begin { Traverse values. } for I := 0 to AMetaData.ChildNodes.Count - 1 do begin LNode := AMetaData.ChildNodes.Get(I); { Check whether the node type is Text. } if (LNode.NodeType = ntText) or LNode.IsTextElement then begin ShowMessage(LNode.NodeName + ' is a node of type Text. The text is: ' + LNode.Text); end; if LNode.NodeName = 'peppol-header' then ProcessPeppolHeaderElement(LNode); end; end; procedure TForm2.ProcessPeppolHeaderElement(const AHeader: IXMLNode); var I: Integer; LNode: IXMLNode; begin { Traverse values. } for I := 0 to AHeader.ChildNodes.Count - 1 do begin LNode := AHeader.ChildNodes.Get(I); { Check whether the node type is Text. } if (LNode.NodeType = ntText) or LNode.IsTextElement then begin ShowMessage(LNode.NodeName + ' is a node of type Text. The text is: ' + LNode.Text); end; end; end;
-
Damn it. I had that error fixed in update 0fdd9ad, but it looks like it got reverted back in update 5251bc9. I have fixed it (again) in update a965917.
-
I don't think a new Fix Pack has been released yet. On the other hand, the download links do say "10.3 (RTM/UP1/2/3)", though the update dates are several months old.
-
Finalization section not called unless main form shown
Remy Lebeau replied to Mark Williams's topic in VCL
The TApplication.MainForm property is set by TApplication.CreateForm() only after the first TForm object is fully constructed. So no, the MainForm property will not have been assigned yet in the OnCreate event of any TForm object that is created before, or during, the first call to TApplication.CreateForm(). -
Finalization section not called unless main form shown
Remy Lebeau replied to Mark Williams's topic in VCL
The MainForm is established by the first call to TApplication.CreateForm(). Changing the project options simply changes the default code that calls CreateForm() in the main .dpr file. If there is no MainForm assigned when Application.Run() is called, Run() simply exits immediately. -
"text/html/pdf/plain" is not a valid media type. Where did you ever get that from? Valid media types are like "text/html", "text/plain", "application/pdf", etc
-
That is just the body content? What about the headers above the content? Can you please show the actual RAW emails in their entirety?