The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 1,860 other subscribers

Archive for June, 2021

Hangouts is being replaced by Google Chat: how long will Hangouts last?

Posted by jpluimers on 2021/06/25

Hangouts is being replaced by Google Chat

Hangouts is being replaced by Google Chat

Oh boy, this is probably a prelude to Google Hangouts, as it originates from Google+, following the Google+ feat: death for personal users.

[Wayback] Learn about the switch from classic Hangouts to Google Chat – Computer – Hangouts Help started with

Google Chat launched to Google Workspace accounts in 2017 and is now available for free on personal accounts. When you switch from classic Hangouts to Google Chat on your personal account, you

but then came this in the list of limitations:

  • Video call ringing isn’t available on Google Chat. If you use classic Hangouts for direct video calls that ring, don’t switch to Google Chat. To start a video call in Google Chat, you can drop a Google Meet chip into the conversation and dial in.

Now looking for an integrated chat and video call option that my mentally retarded brother understands, as the non-straightforward integration of Google Chat and Google Meet features won’t cut it for his mental abilities.

Via: [Archive.is] Jeroen Wiert Pluimers on Twitter: “Oh dang: how long will Google Hangouts last? It is the easiest (and currently only well known) way for my mentally retarded brother to have video calls with his caretakers and us.”

–jeroen

PS: Blocks also do not transfer to Google Chats. At myaccount.google.com/blocklist you can find who you blocked.

Posted in Google, GoogleHangouts, Power User | Leave a Comment »

Mathematics (topology): getting a plug loose from a tight spot – GIF on Imgur

Posted by jpluimers on 2021/06/25

[WayBack] Getting a plug loose from a tight spot – GIF on Imgur via [WayBack] Cliff Pickover on Twitter: “Mathematics, geometry, witchcraft, and the structure of reality. (A plug gets caught under a table.) … “:

The trick is to get the middle part of the cable (which goes over the table beam), to get in front of the horizontal part of the cable.

You can do this by making the loop bigger, then getting it around the plug.

The below ImgUr video shows that (via this [WayBack] Reddit: When a plug gets caught under a table : Unexpected)

Related:

–jeroen

Read the rest of this entry »

Posted in LifeHacker, Power User, science | Leave a Comment »

esxi what is my ip – Google Search

Posted by jpluimers on 2021/06/25

[Archive.is] esxi what is my ip – Google Search:

esxcli network Commands
Command Description
network ip dns server remove Remove a DNS server from the list of DNS servers to use for this ESXi host.
network ip get Get global IP settings
network ip interface add Add a new VMkernel network interface.
network ip interface ipv4 get Get IPv4 settings for VMkernel network interfaces.

60 more rows

More columns and rows of that table in

[WayBack] vSphere Documentation Center: vSphere 5 Command Line Documentation > vSphere Command-Line Interface Documentation > vSphere Command-Line Interface Reference: esxcli network Commands

Not much has changed since, so this still works:

[root@ESXi-X9SRI-3F:/] esxcli network ip interface ipv4 get
Name  IPv4 Address   IPv4 Netmask   IPv4 Broadcast  Address Type  Gateway       DHCP DNS
----  -------------  -------------  --------------  ------------  ------------  --------
vmk0  192.168.71.94  255.255.255.0  192.168.71.255  DHCP          192.168.71.1      true
[root@ESXi-X9SRI-3F:/] network ip interface ipv6 get
Name  IPv6 Enabled  DHCPv6 Enabled  Router Adv Enabled  DHCP DNS  Gateway
----  ------------  --------------  ------------------  --------  -------
vmk0          true           false                true     false  ::

If the box has IPv6 configured, the last command would have shown the IPv6 vmdk information as well.

–jeroen

Posted in ESXi5, ESXi5.1, ESXi5.5, ESXi6, ESXi6.5, ESXi6.7, Power User, Virtualization, VMware, VMware ESXi | Leave a Comment »

I don’t want to learn your garbage query language · Erik Bernhardsson

Posted by jpluimers on 2021/06/24

Interesting read:

This is a bit of a rant but I really don’t like software that invents its own query language. There’s a trillion different ORMs out there. Another trillion databases with their own query language. Another trillion SaaS products where the only way to query is to learn some random query DSL they made up.

Source: [WayBackI don’t want to learn your garbage query language · Erik Bernhardsson

Related:

Via: [WayBack] Die wichtigste Funktion in jedem ORM ist der Notausgang. Also, wie man literales SQL durch das Ding durch piped, ohne daß der ORM rein pullert. – Kristian Köhntopp – Google+

–jeroen

Posted in Database Development, Development, Software Development | Leave a Comment »

DCOM calls from thread pool threads: CoInitialize/CoUnitialize location and expensiveness?

Posted by jpluimers on 2021/06/24

Interesting takeaway from [WayBack] DCOM calls from thread pool threads

call CoInitialize* at the start, and call CoUninitialize before returning. Expensive, but necessary

Related:

–jeroen

Posted in .NET, C, C++, COM/DCOM/COM+, Delphi, Development, Software Development, Windows Development | Leave a Comment »

“No mapping for the Unicode character exists in the target multi-byte code page”

Posted by jpluimers on 2021/06/24

Usually when I see this error [Wayback] “No mapping for the Unicode character exists in the target multi-byte code page” – Google Search, it is in legacy code that uses string buffers where decoding or decompressing data into.

This is almost always wrong no matter what kind of data you use, as it will depend in your string encoding.

I have seen it happen especially in these cases:

  • base64 decoding from string to string (solution: decode from a string stream into a binary stream, then post-process from there)
  • zip or zlib decompress from binary stream to string stream, then reading the string stream (solution: decompress from binary stream to binary stream, then post-process from there)

Most cases I encountered were in Delphi and C code, but surprisingly I also bumped into C# exhibiting this behaviour.

I’m not alone, just see these examples from the above Google search:

–jeroen

Posted in .NET, base64, C, C#, C++, Delphi, Development, Encoding, Software Development, Unicode | Leave a Comment »

delphi – Is it possible to define {$IFDEF} for more than one directive at once? – Stack Overflow

Posted by jpluimers on 2021/06/24

[WayBack] delphi – Is it possible to define {$IFDEF} for more than one directive at once? – Stack Overflow:

–jeroen

Posted in Delphi, Delphi 6, Development, Software Development | Leave a Comment »

Some notes on dumping IceCast ICY streams to get meta-data

Posted by jpluimers on 2021/06/23

Some links I want to investigate further.

This is difference in the header meta data of an icecast URL, than in the stream data.

The header meta-data you get from this cURL command (via [WayBack] linux – Catch Metadata from Icecast-audio-stream – Super User):

# curl -H "Icy-MetaData: 1" -v "http://icecast.omroep.nl:80/radio2-bb-mp3" > /dev/null
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0*   Trying 145.58.53.154...
* TCP_NODELAY set
* Connected to icecast.omroep.nl (145.58.53.154) port 80 (#0)
> GET /radio2-bb-mp3 HTTP/1.1
> Host: icecast.omroep.nl
> User-Agent: curl/7.54.0
> Accept: */*
> Icy-MetaData: 1
> 
* HTTP 1.0, assume close after body
< HTTP/1.0 200 OK
< Content-Type: audio/mpeg
< Date: Mon, 01 Jul 2019 06:46:33 GMT
< icy-br:192
< ice-audio-info: samplerate=48000;channels=2;bitrate=192
< icy-br:192
< icy-genre:Mixed
< icy-metadata:1
< icy-name:NPO Radio2
< icy-pub:0
< icy-url:http://www.radio2.nl
< Server: Icecast 2.4.0-kh10
< Cache-Control: no-cache, no-store
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Headers: Origin, Accept, X-Requested-With, Content-Type
< Access-Control-Allow-Methods: GET, OPTIONS, HEAD
< Connection: Close
< Expires: Mon, 26 Jul 1997 05:00:00 GMT
< icy-metaint:16000
< 

The content meta-data you can for instance get with node.js in a call like [WayBack] https://colon.roderickgadellaa.com:8001/get/id3/?url=http%3A%2F%2Ficecast.omroep.nl%3A80%2Fradio2-bb-mp3:

{"ok":true,"code":200,"error":false,"data":{"headers":{"content-type":"audio/mpeg","date":"Sat, 29 Jun 2019 17:07:03 GMT","icy-br":"192, 192","ice-audio-info":"samplerate=48000;channels=2;bitrate=192","icy-genre":"Mixed","icy-metadata":"1","icy-name":"NPO Radio2","icy-pub":"0","icy-url":"http://www.radio2.nl","server":"Icecast 2.4.0-kh10","cache-control":"no-cache, no-store","access-control-allow-origin":"*","access-control-allow-headers":"Origin, Accept, X-Requested-With, Content-Type","access-control-allow-methods":"GET, OPTIONS, HEAD","connection":"Close","expires":"Mon, 26 Jul 1997 05:00:00 GMT","icy-metaint":"16000"},"metadata":{"StreamTitle":"AUDIOLINK-AUDIO-FTP-SERVER - +EJ+  Ons Uuropener"},"timestamp":1561828023103,"cacheValidUntil":1561828038103},"request":{"protocol":null,"slashes":null,"auth":null,"host":null,"port":null,"hostname":null,"hash":null,"search":"?url=http%3A%2F%2Ficecast.omroep.nl%3A80%2Fradio2-bb-mp3","query":{"url":"http://icecast.omroep.nl:80/radio2-bb-mp3"},"pathname":"/get/id3/","path":"/get/id3/?url=http%3A%2F%2Ficecast.omroep.nl%3A80%2Fradio2-bb-mp3","href":"/get/id3/?url=http%3A%2F%2Ficecast.omroep.nl%3A80%2Fradio2-bb-mp3"}}

This was at a time where the Dutch NPO Radio 2 had trouble with their ID3 service as the first part stopped refreshing for days: "metadata":{"StreamTitle":"AUDIOLINK-AUDIO-FTP-SERVER - +EJ+ Ons Uuropener"}

Some links that will help me eventually dump this from the command-line:

–jeroen

Posted in Development, IceCast, Media Streaming, Software Development | Leave a Comment »

Disable Filtered Gap – Scooter Forums

Posted by jpluimers on 2021/06/23

There is a short thread mentioning [WayBack] Disable Filtered Gap – Scooter Forums (Issues concerning Text Compare sessions.)

It is the feature that when you select “Diffs” or “Same” on the toolbar on menu in a “Text Compare” (or similar, like XML compare), you see only the differences (or equalities when you selected “Same”).

There also will be small plus signs (+) in the gutter with the hover text “Expand Filtered Gap” on it to expand that gap and show the equalities (or differences when you selected “Same”).

There are two problems that basically make this feature very hard to use, which both stem from the need to view context around a difference in order to understand the proper meaning of that difference:

  • you cannot expand or collaps the “Filtered Gap” by keyboard
  • the “Number of context lines” in the “Text editing” part of the “Options” is not adhered to

Too bad as this could have been such a useful feature.

–jeroen

Posted in Beyond Compare, Development, Power User, Software Development | Leave a Comment »

XMLDoc Delphi source code documentation generation – some links

Posted by jpluimers on 2021/06/23

There is very little information on how to use the XMLDoc documentation formatting in your Delphi source code.

So here are some links for me to get started:

XmlDoc comments can get verbose because of the lengthy XML syntax.

Hiding them in regions can help, for instance with the plugin at [WayBack] Fast-Forward »: XML Documentation in Delphi 2006.

I still should try NDoc – Wikipedia for post processing of the Delphi generated XML file, but since I almost exclusively use the internal IDE viewer, that is good enough for me now.

Syntax

Most of the above links talk about tooling, but little about syntax. Luckily, it is very similar to the C# XML Documentation syntax documented by Microsoft:

DevJet has a nice document describing all Delphi supported tags in [WayBack] Delphi-Documentation-Guidelines.pdf (via [WayBack] DevJet Software » Delphi Documentation Guidelines) including the tags mentioned in [WayBack] Dr.Bob Examines… #100: Generating Documentation.

For comparison:

One Delphi specific thing on the see tag.

The see tag accepted a syntax like UnitName|IdentifierName (see for instance [WayBack] How/under which circumstances does the tag in Delphi xml comments actually work? – Stack Overflow).

In Delphi 10.1 Berlin, sometimes that did not work and I had to use the UnitName.IdentifierName syntax.

The difference is how it is displayed: UnitName|IdentifierName shows as IdentifierName, whereas UnitName.IdentifierName is shown in full.

Sometimes one or the other is unclickable.

In the Delphi IDE, href references do not work

Similar to C# and the Visual Studio IDE, any href reference will not work in the IDE itself. See [WayBack] C# XML Documentation Website Link – Stack Overflow.

In Delphi, the same para element for paragraphs is used as in C#

Documented in the DevJet documentation, the para element works for paragraphs just like it does in the C# example at [WayBack] How to add a line break in C# .NET documentation – Stack Overflow.

Example

A few important tags:

   TParentedTest = class;
   IParentedTest = ISmartPointer<TParentedTest>;
   /// <summary>
   /// <para><see cref="Data.DataRecord|TJoinableDataRecord" /> that can be parented.</para>
   /// <para>The first time you obtain <see cref="UnitTest.Query.JoinHelper|TParentedTest.Parent" />, it will create one for you (so be careful not to recursively call <c>Parent</c>).</para>
   /// </summary>
   TParentedTest = class(TTest)
   strict private
     /// <summary>
     /// <para>Backing field of <see cref="UnitTest.Query.JoinHelper|TParentedTest.Parent" />.</para>
     /// <para>Referenced by <c>interface</c> <see cref="System|IInterface" /> instead of <c>class</c> <see cref="UnitTest.Query.JoinHelper|TParentedTest.Parent" /> as that prevents use-after-free access violations.</para>
     /// </summary>
     FParentInterface: IInterface;
   public
     class function CreateI(const Name: string): IParentedTest;
     /// <summary>
     /// <para>Ensures there is a parent by creating a new <see cref="UnitTest.Query.JoinHelper|TParentedTest" /> if there is none yet.that can be parented.</para>
     /// <para>Do not call recursively, as it will keep creating parents in an endless loop.</para>
     /// </summary>
     function Parent: TParentedTest;
     destructor Destroy; override;
   end;

–jeroen

Posted in Delphi, Development, Software Development | Leave a Comment »