| 1 | /*++ |
| 2 | |
| 3 | Copyright (c) Microsoft. All rights reserved. |
| 4 | |
| 5 | Module Name: |
| 6 | |
| 7 | string.hpp |
| 8 | |
| 9 | Abstract: |
| 10 | |
| 11 | This file contains string management function declarations. |
| 12 | |
| 13 | --*/ |
| 14 | |
| 15 | #pragma once |
| 16 | |
| 17 | #include "helpers.hpp" |
| 18 | #include "stringshared.h" |
| 19 | |
| 20 | // Forward declare types to avoid pulling in excessive number of headers. |
| 21 | using IP_ADDRESS_PREFIX = struct _IP_ADDRESS_PREFIX; |
| 22 | using SOCKADDR_INET = union _SOCKADDR_INET; |
| 23 | |
| 24 | namespace wsl::windows::common::string { |
| 25 | |
| 26 | enum class StorageSizeUnit |
| 27 | { |
| 28 | Decimal, |
| 29 | Binary |
| 30 | }; |
| 31 | |
| 32 | std::optional<uint64_t> ParseStorageSize(std::wstring_view String, StorageSizeUnit Unit); |
| 33 | |
| 34 | // Formats a size with the given number of significant digits and no space before the unit, matching |
| 35 | // docker's go-units. Decimal uses base 1000 (kB, MB, GB) and Binary uses base 1024 (KiB, MiB, GiB). |
| 36 | // 119856765 -> "120MB" at precision 3, "119.9MB" at precision 4. |
| 37 | std::wstring FormatHumanReadableSize(uint64_t Bytes, uint32_t Precision = 3, StorageSizeUnit Unit = StorageSizeUnit::Decimal); |
| 38 | |
| 39 | // Precision used when reporting the space reclaimed by prune, so that container, image and volume |
| 40 | // prune agree on a single decimal place. |
| 41 | inline constexpr uint32_t c_reclaimedSpacePrecision = 4; |
| 42 | |
| 43 | std::vector<std::string> InitializeStringSet(_In_count_(BufferSize) LPCSTR Buffer, _In_ SIZE_T BufferSize); |
| 44 | |
| 45 | bool IsPathComponentEqual(const std::wstring_view String1, const std::wstring_view String2); |
| 46 | |
| 47 | std::wstring MultiByteToWide(_In_ LPCSTR Source, _In_ size_t CharacterCount = -1); |
| 48 | |
| 49 | std::wstring MultiByteToWide(_In_ std::string_view Source); |
| 50 | |
| 51 | std::wstring_view StripLeadingWhitespace(_In_ std::wstring_view String); |
| 52 | |
| 53 | std::wstring_view StripQuotes(_In_ std::wstring_view String); |
| 54 | |
| 55 | std::string IpPrefixAddressToString(const IP_ADDRESS_PREFIX& ipAddressPrefix); |
| 56 | std::string SockAddrInetToString(const SOCKADDR_INET& sockAddrInet); |
| 57 | std::wstring SockAddrInetToWstring(const SOCKADDR_INET& sockAddrInet); |
| 58 | std::wstring IntegerIpv4ToWstring(const uint32_t ipAddress); |
| 59 | SOCKADDR_INET StringToSockAddrInet(const std::wstring& stringIpAddress); |
| 60 | std::wstring BytesToHex(const std::vector<BYTE>& bytes); |
| 61 | std::vector<BYTE> HexToBytes(std::string_view input); |
| 62 | std::vector<BYTE> HexToBytes(std::wstring_view input); |
| 63 | |
| 64 | std::string WideToMultiByte(_In_opt_ LPCWSTR Source, _In_ size_t CharacterCount = -1); |
| 65 | |
| 66 | std::string WideToMultiByte(_In_ std::wstring_view Source); |
| 67 | |
| 68 | std::wstring TruncateId(_In_ std::wstring_view id, bool shortenLength = true); |
| 69 | std::string TruncateId(_In_ std::string_view id, bool shortenLength = true); |
| 70 | |
| 71 | // Shortens a value so it occupies at most MaxDisplayWidth terminal columns, appending an ellipsis when |
| 72 | // characters are dropped. East Asian wide and fullwidth code points occupy two columns, so fewer of them |
| 73 | // fit than narrow ones, and a code point is never split. This matches docker's formatter.Ellipsis |
| 74 | // (cli/command/formatter/displayutils.go), including its handling of widths of one and below. |
| 75 | std::wstring Ellipsis(_In_ std::wstring_view Value, _In_ size_t MaxDisplayWidth); |
| 76 | |
| 77 | // Template implementation for TruncateId to avoid code duplication. |
| 78 | // Algorithm inspired from Moby for consistency in presentation of shortened IDs. |
| 79 | // Always strips the algorithm prefix (e.g., "sha256:") if present, and optionally shortens to 12 characters. |
| 80 | template <typename TChar> |
| 81 | inline std::basic_string<TChar> TruncateIdImpl(std::basic_string_view<TChar> id, bool shortenLength) |
| 82 | { |
| 83 | constexpr size_t shortLen = 12; |
| 84 | constexpr TChar colon = TChar(':'); |
| 85 | |
| 86 | // Find and skip algorithm prefix if present (e.g., "sha256:") |
| 87 | auto colonPos = id.find(colon); |
| 88 | if (colonPos != std::basic_string_view<TChar>::npos) |
| 89 | { |
| 90 | id.remove_prefix(colonPos + 1); |
| 91 | } |
| 92 | |
| 93 | if (shortenLength && id.length() > shortLen) |
| 94 | { |
| 95 | return std::basic_string<TChar>{id.substr(0, shortLen)}; |
| 96 | } |
| 97 | |
| 98 | return std::basic_string<TChar>{id}; |
| 99 | } |
| 100 | |
| 101 | struct PhysicalMacAddress |
| 102 | { |
| 103 | BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH]{}; |
| 104 | }; |
| 105 | |
| 106 | } // namespace wsl::windows::common::string |