about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--library/std/src/sys/windows/args.rs54
-rw-r--r--library/std/src/sys_common/mod.rs1
-rw-r--r--library/std/src/sys_common/wstr.rs59
3 files changed, 62 insertions, 52 deletions
diff --git a/library/std/src/sys/windows/args.rs b/library/std/src/sys/windows/args.rs
index 01f26298290..6741ae46d32 100644
--- a/library/std/src/sys/windows/args.rs
+++ b/library/std/src/sys/windows/args.rs
@@ -9,17 +9,16 @@ mod tests;
 use crate::ffi::OsString;
 use crate::fmt;
 use crate::io;
-use crate::marker::PhantomData;
 use crate::num::NonZeroU16;
 use crate::os::windows::prelude::*;
 use crate::path::PathBuf;
-use crate::ptr::NonNull;
 use crate::sys::c;
 use crate::sys::process::ensure_no_nuls;
 use crate::sys::windows::os::current_exe;
+use crate::sys_common::wstr::WStrUnits;
 use crate::vec;
 
-use core::iter;
+use crate::iter;
 
 /// This is the const equivalent to `NonZeroU16::new(n).unwrap()`
 ///
@@ -199,55 +198,6 @@ impl ExactSizeIterator for Args {
     }
 }
 
-/// A safe iterator over a LPWSTR
-/// (aka a pointer to a series of UTF-16 code units terminated by a NULL).
-struct WStrUnits<'a> {
-    // The pointer must never be null...
-    lpwstr: NonNull<u16>,
-    // ...and the memory it points to must be valid for this lifetime.
-    lifetime: PhantomData<&'a [u16]>,
-}
-impl WStrUnits<'_> {
-    /// Create the iterator. Returns `None` if `lpwstr` is null.
-    ///
-    /// SAFETY: `lpwstr` must point to a null-terminated wide string that lives
-    /// at least as long as the lifetime of this struct.
-    unsafe fn new(lpwstr: *const u16) -> Option<Self> {
-        Some(Self { lpwstr: NonNull::new(lpwstr as _)?, lifetime: PhantomData })
-    }
-    fn peek(&self) -> Option<NonZeroU16> {
-        // SAFETY: It's always safe to read the current item because we don't
-        // ever move out of the array's bounds.
-        unsafe { NonZeroU16::new(*self.lpwstr.as_ptr()) }
-    }
-    /// Advance the iterator while `predicate` returns true.
-    /// Returns the number of items it advanced by.
-    fn advance_while<P: FnMut(NonZeroU16) -> bool>(&mut self, mut predicate: P) -> usize {
-        let mut counter = 0;
-        while let Some(w) = self.peek() {
-            if !predicate(w) {
-                break;
-            }
-            counter += 1;
-            self.next();
-        }
-        counter
-    }
-}
-impl Iterator for WStrUnits<'_> {
-    // This can never return zero as that marks the end of the string.
-    type Item = NonZeroU16;
-    fn next(&mut self) -> Option<NonZeroU16> {
-        // SAFETY: If NULL is reached we immediately return.
-        // Therefore it's safe to advance the pointer after that.
-        unsafe {
-            let next = self.peek()?;
-            self.lpwstr = NonNull::new_unchecked(self.lpwstr.as_ptr().add(1));
-            Some(next)
-        }
-    }
-}
-
 #[derive(Debug)]
 pub(crate) enum Arg {
     /// Add quotes (if needed)
diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs
index 8c19f9332dc..53259e8dbbd 100644
--- a/library/std/src/sys_common/mod.rs
+++ b/library/std/src/sys_common/mod.rs
@@ -35,6 +35,7 @@ pub mod thread;
 pub mod thread_info;
 pub mod thread_local_dtor;
 pub mod thread_parker;
+pub mod wstr;
 pub mod wtf8;
 
 cfg_if::cfg_if! {
diff --git a/library/std/src/sys_common/wstr.rs b/library/std/src/sys_common/wstr.rs
new file mode 100644
index 00000000000..b230fd1a829
--- /dev/null
+++ b/library/std/src/sys_common/wstr.rs
@@ -0,0 +1,59 @@
+//! This module contains constructs to work with 16-bit characters (UCS-2 or UTF-16)
+#![allow(dead_code)]
+
+use crate::marker::PhantomData;
+use crate::num::NonZeroU16;
+use crate::ptr::NonNull;
+
+/// A safe iterator over a LPWSTR
+/// (aka a pointer to a series of UTF-16 code units terminated by a NULL).
+pub struct WStrUnits<'a> {
+    // The pointer must never be null...
+    lpwstr: NonNull<u16>,
+    // ...and the memory it points to must be valid for this lifetime.
+    lifetime: PhantomData<&'a [u16]>,
+}
+
+impl WStrUnits<'_> {
+    /// Create the iterator. Returns `None` if `lpwstr` is null.
+    ///
+    /// SAFETY: `lpwstr` must point to a null-terminated wide string that lives
+    /// at least as long as the lifetime of this struct.
+    pub unsafe fn new(lpwstr: *const u16) -> Option<Self> {
+        Some(Self { lpwstr: NonNull::new(lpwstr as _)?, lifetime: PhantomData })
+    }
+
+    pub fn peek(&self) -> Option<NonZeroU16> {
+        // SAFETY: It's always safe to read the current item because we don't
+        // ever move out of the array's bounds.
+        unsafe { NonZeroU16::new(*self.lpwstr.as_ptr()) }
+    }
+
+    /// Advance the iterator while `predicate` returns true.
+    /// Returns the number of items it advanced by.
+    pub fn advance_while<P: FnMut(NonZeroU16) -> bool>(&mut self, mut predicate: P) -> usize {
+        let mut counter = 0;
+        while let Some(w) = self.peek() {
+            if !predicate(w) {
+                break;
+            }
+            counter += 1;
+            self.next();
+        }
+        counter
+    }
+}
+
+impl Iterator for WStrUnits<'_> {
+    // This can never return zero as that marks the end of the string.
+    type Item = NonZeroU16;
+    fn next(&mut self) -> Option<NonZeroU16> {
+        // SAFETY: If NULL is reached we immediately return.
+        // Therefore it's safe to advance the pointer after that.
+        unsafe {
+            let next = self.peek()?;
+            self.lpwstr = NonNull::new_unchecked(self.lpwstr.as_ptr().add(1));
+            Some(next)
+        }
+    }
+}