Jump to content

Remy Lebeau

Members
  • Content Count

    2914
  • Joined

  • Last visited

  • Days Won

    130

Everything posted by Remy Lebeau

  1. Remy Lebeau

    Need help adding namespaces to SOAP

    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.
  2. Remy Lebeau

    Memory leak in UnicodeString to string conversion

    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.
  3. Remy Lebeau

    Memory leak in UnicodeString to string conversion

    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.
  4. 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;
  5. Remy Lebeau

    Bug in Delphi string behavior?

    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.
  6. Remy Lebeau

    Memory leak in UnicodeString to string conversion

    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?
  7. Remy Lebeau

    Bug in Delphi string behavior?

    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.
  8. Remy Lebeau

    What's the best common folder for...

    Then CSIDL_COMMON_APPDATA/FOLDERID_ProgramData is appropriate.
  9. Remy Lebeau

    SHOpenFolderAndSelectItems 64-bit

    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.
  10. Remy Lebeau

    SHOpenFolderAndSelectItems 64-bit

    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';
  11. Remy Lebeau

    Quote of the Day...

    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.
  12. Remy Lebeau

    Delphi 10.3.3 - Indy - could not load root certificate

    Embarcadero will be releasing a hotfix for 10.3.3 soon to address this in the shipped version of Indy.
  13. Remy Lebeau

    Delphi 10.3.3 - Indy - could not load root certificate

    Install instructions are on Indy's website.
  14. 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?).
  15. Remy Lebeau

    Delphi 10.3.3 - Indy - could not load root certificate

    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.
  16. Remy Lebeau

    Two questions if you please?

    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.
  17. Remy Lebeau

    Git update 5251bc9 broken

    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.
  18. Remy Lebeau

    Git update 5251bc9 broken

    Fixed
  19. Remy Lebeau

    Parse XML

    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;
  20. Remy Lebeau

    Git update 5251bc9 broken

    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.
  21. Remy Lebeau

    IDE Fix pack for Rio

    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.
  22. Remy Lebeau

    Finalization section not called unless main form shown

    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().
  23. Remy Lebeau

    Finalization section not called unless main form shown

    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.
  24. Remy Lebeau

    Hebrew in mail

    "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
  25. Remy Lebeau

    Hebrew in mail

    That is just the body content? What about the headers above the content? Can you please show the actual RAW emails in their entirety?
×