Add `Write{Little,Big}Endians()` writing to `BackwardWriter`.

They were missing, but they will now have a use.

PiperOrigin-RevId: 884922436
diff --git a/riegeli/endian/endian_writing.h b/riegeli/endian/endian_writing.h
index 638e4cf..4e427c0 100644
--- a/riegeli/endian/endian_writing.h
+++ b/riegeli/endian/endian_writing.h
@@ -52,9 +52,7 @@
 // This is faster than writing them individually if the endianness matches the
 // native one.
 //
-// Return values:
-//  * `true`  - success (`dest.ok()`)
-//  * `false` - failure (`!dest.ok()`)
+// Writes `data.size() * sizeof(T)` bytes to `dest[]`.
 template <typename T>
 void WriteLittleEndians(absl::Span<const type_identity_t<T>> data, char* dest);
 template <typename T>
@@ -102,6 +100,24 @@
 template <typename T>
 bool WriteBigEndian(type_identity_t<T> data, BackwardWriter& dest);
 
+// Writes an array of numbers in a fixed width Little/Big Endian encoding to a
+// `BackwardWriter`. The width of the encoding is determined by the template
+// argument, which must be one of: `{u,}int{8,16,32,64}_t`, `absl::{u,}int128`,
+// `float`, or `double`.
+//
+// This is faster than writing them individually if the endianness matches the
+// native one.
+//
+// Return values:
+//  * `true`  - success (`dest.ok()`)
+//  * `false` - failure (`!dest.ok()`)
+template <typename T>
+bool WriteLittleEndians(absl::Span<const type_identity_t<T>> data,
+                        BackwardWriter& dest);
+template <typename T>
+bool WriteBigEndians(absl::Span<const type_identity_t<T>> data,
+                     BackwardWriter& dest);
+
 // Implementation details follow.
 
 template <>
@@ -462,6 +478,66 @@
   return dest.WriteByte(static_cast<uint8_t>(data));
 }
 
+template <typename T>
+inline bool WriteLittleEndians(absl::Span<const type_identity_t<T>> data,
+                               BackwardWriter& dest) {
+#if ABSL_IS_LITTLE_ENDIAN
+  return dest.Write(absl::string_view(
+      reinterpret_cast<const char*>(data.data()), data.size() * sizeof(T)));
+#else
+  for (auto iter = data.crbegin(); iter != data.crend(); ++iter) {
+    if (ABSL_PREDICT_FALSE(!WriteLittleEndian<T>(*iter, dest))) {
+      return false;
+    }
+  }
+  return true;
+#endif
+}
+
+template <>
+inline bool WriteLittleEndians<uint8_t>(absl::Span<const uint8_t> data,
+                                        BackwardWriter& dest) {
+  return dest.Write(absl::string_view(
+      reinterpret_cast<const char*>(data.data()), data.size()));
+}
+
+template <>
+inline bool WriteLittleEndians<int8_t>(absl::Span<const int8_t> data,
+                                       BackwardWriter& dest) {
+  return dest.Write(absl::string_view(
+      reinterpret_cast<const char*>(data.data()), data.size()));
+}
+
+template <typename T>
+inline bool WriteBigEndians(absl::Span<const type_identity_t<T>> data,
+                            BackwardWriter& dest) {
+#if ABSL_IS_BIG_ENDIAN
+  return dest.Write(absl::string_view(
+      reinterpret_cast<const char*>(data.data()), data.size() * sizeof(T)));
+#else
+  for (auto iter = data.crbegin(); iter != data.crend(); ++iter) {
+    if (ABSL_PREDICT_FALSE(!WriteBigEndian<T>(*iter, dest))) {
+      return false;
+    }
+  }
+  return true;
+#endif
+}
+
+template <>
+inline bool WriteBigEndians<uint8_t>(absl::Span<const uint8_t> data,
+                                     BackwardWriter& dest) {
+  return dest.Write(absl::string_view(
+      reinterpret_cast<const char*>(data.data()), data.size()));
+}
+
+template <>
+inline bool WriteBigEndians<int8_t>(absl::Span<const int8_t> data,
+                                    BackwardWriter& dest) {
+  return dest.Write(absl::string_view(
+      reinterpret_cast<const char*>(data.data()), data.size()));
+}
+
 // Deprecated aliases.
 
 ABSL_DEPRECATE_AND_INLINE()