Skip to content

Common encoding pattern for Utility Cmdlets #3628

Closed

Description

@iSazonov

Current encodings in Utility Cmdlets:

Cmdlet Encodings
CVSCommands.cs (1 and 2) "Unicode", "UTF7", "UTF8", "ASCII", "UTF32", "BigEndianUnicode", "Default", "OEM"
Format-Hex.cs "Unicode", "BigEndianUnicode", "Utf8", "Utf7", "Utf32", "Ascii"
Out-File.cs "Unknown", "String", "Unicode", "BigEndianUnicode", "Utf8", "Utf7", "Utf32", "Ascii", "Default", "OEM"
ImplicitRemotingCommands.cs "Unicode", "UTF7", "UTF8", "ASCII", "UTF32", "BigEndianUnicode", "Default", "OEM"
MatchString.cs "Unicode", "UTF7", "UTF8", "ASCII", "UTF32", "BigEndianUnicode", "Default", "OEM"
XmlCommands.cs "Unicode", "UTF7", "UTF8", "ASCII", "UTF32", "BigEndianUnicode", "Default", "OEM"

It seems we can safely migrate to a common pattern "Unicode", "UTF7", "UTF8", "ASCII", "UTF32", "BigEndianUnicode", "Default", "OEM".

Format-Hex was converted from function to cmdlet. I believe we can enhance it.

Out-File. My understanding is that "Unknown" and "String" encodings is output encodings and don't be used as input encodings. So we can and should remove them from Out-File cmdlet.

Activity

  1. iSazonov commented on May 3, 2017

    @iSazonov
    CollaboratorAuthor

    Jason Shirk (@lzybkr) Could you please comment and approve this change?

  2. lzybkr commented on May 3, 2017

    @lzybkr
    Contributor

    I think I agree in principle regarding removing Unknown and String from Out-File, but don't have enough data to approve the change.

    I believe Out-File uses the encoding when you specify -Append, but you'd need to confirm.

    A search of GitHub for Out-File could help provide some data, but finding uses is the only reliable way of making a a decision - to keep - because lack of usage on GitHub doesn't mean the encoding values aren't in use, just that those uses aren't on GitHub or other public sources of scripts.

  3. iSazonov commented on May 4, 2017

    @iSazonov
    CollaboratorAuthor

    Jason Shirk (@lzybkr) Thanks for comments.

    I did not found using of EncodingConversion.Unknown and EncodingConversion.String in the repo. It seems it's just a mirror of FileProvider types.

    Search of GitHub. Common usage is:
    Out-File -Encoding Ascii
    Out-File -Encoding Uft8
    I did not found (manual search only) "Unknown" and "String" with "out-file -encoding" at all.

  4. iSazonov commented on May 4, 2017

    @iSazonov
    CollaboratorAuthor

    Michael Klement (@mklement0) Have you any special thoughts about the Issue?

  5. mklement0 commented on May 5, 2017

    @mklement0
    Contributor

    Ilya (@iSazonov): I also can't comment on current usage, except to say I've never personally used the Unknown and String encodings.

    • I agree that Unknown doesn't make sense in output cmdlets. In practice, Out-File / Out-File -Append and Set-Content / Add-Content all treat Unknown as Unicode (UTF-16 LE) - cc Jason Shirk (@lzybkr)

      • That is, when appending to an existing file, the behavior does not depend on that file's existing encoding.
        As far as I know, the only cmdlet that changes its default encoding based on preexisting file content is Export-Csv -Append (and does so in a half-broken manner: preexisting "ANSI" content (Default) results in UTF-8 content getting appended).
    • I'm still not sure what the purpose of String is. Its behavior differs between Out-File and Set-Content - unlike with Unknown, String seems to result in the cmdlets' respective defaults (Unicode for Out-File, Default ("ANSI" on Windows) for Set-Content).

    The following code demonstrates this:

    "==== Set-Content / Add-Content ==== "
    $null, 'Unknown', 'String' | % { $ht=@{}; if ($_) { $ht.Encoding = $_ };  
      'a' | set-content t.txt  @ht; 
      "`nSet-Content $(if ($_) { "-Encoding $_" } else { '(no -Encoding)' })`n----"; od -tx1 t.txt }
    
    $null, 'Unknown', 'String' | % { $ht=@{}; if ($_) { $ht.Encoding = $_ }; 
      'a' | set-content t.txt -Encoding ascii; 'b' | add-content t.txt  @ht; 
      "`nAdd-Content $(if ($_) { "-Encoding $_" } else { '(no -Encoding)' })`n----"; od -tx1 t.txt }
    
    "`n`n==== Out-File / Out-File -Append ==== "
    $null, 'Unknown', 'String' | % { $ht=@{}; if ($_) { $ht.Encoding = $_ };  
      'a' | Out-File t.txt  @ht; 
      "`nOut-File $(if ($_) { "-Encoding $_" } else { '(no -Encoding)' })`n----"; od -tx1 t.txt }
    
    $null, 'Unknown', 'String' | % { $ht=@{}; if ($_) { $ht.Encoding = $_ }; 
      'a' | Out-File t.txt -Encoding ascii; 'b' | Out-File -Append t.txt  @ht; 
      "`nOut-File -Append $(if ($_) { "-Encoding $_" } else { '(no -Encoding)' })`n----"; od -tx1 t.txt }

    As for the input side of things, using the example of Get-Content:

    In practice, Unknown is interpreted the same way as with Out-File and Set-Content, Unknown is effectively the same as Unicode (UTF-16 LE).

    Similarly, String seems to be equivalent to the default behavior (as if -Encoding had not been specified): which means:

    • if there's no BOM, use Default
    • if there is a BOM, respect it.

    Purely from a naming standpoint, it is this variable behavior that deserves to be called Unknown.

  6. iSazonov commented on May 5, 2017

    @iSazonov
    CollaboratorAuthor

    Michael Klement (@mklement0) Thanks for great comments!

    In context of the Issue we should ignore difference between Utility cmdlets and FileProvider cmdlets. As result we should conclude that we could safely remove String and Unknown from Out-File.

    But I see another question: why Out-File cmdlet uses the Utility cmdlet code base but not FileProvider code base for encoding? It seems it must be placed together with Get-Content and Set-Content. Nevertheless, even if we agree to do this cmdlet as FileProvider cmdlet then we see that we could safely remove String and Unknown from Out-File.

    Also I reviewed MSDN documentation: there is no exact description of use String and Unknown. If these features were never documented properly then no one can use them correctly. It looks as if the project was not fully realized or abandoned long ago.

  7. mklement0 commented on May 5, 2017

    @mklement0
    Contributor

    Ilya (@iSazonov)

    I fully agree re removal of String and Unknown; let's see what the powers that be decide.

    Good point re code base - had never paid attention to that.

  8. mklement0 commented on May 5, 2017

    @mklement0
    Contributor

    P.S.: For symmetry and to support all Unicode-mandated encoding forms, we should support UTF-32 BE (big-endian) as well (the UTF32 value is UTF-32 LE).

    I'll address this and other encoding-related issues in an upcoming post in PowerShell/PowerShell-RFC#71

  9. iSazonov commented on Aug 16, 2018

    @iSazonov
    CollaboratorAuthor

    It was fixed with implementing RFC0020 in #5080

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Issue-Discussionthe issue may not have a clear classification yet. The issue may generate an RFC or may be reclassifResolution-FixedThe issue is fixed.WG-Cmdletsgeneral cmdlet issues

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions