blob: 84eaed2172bba1ffce5cb16d67dcead4a5b5f2a3 [file]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
using System.Runtime.InteropServices;
using System.Globalization;
namespace OpenDAL;
/// <summary>
/// Shared utility helpers for UTF-8 marshalling and option value formatting.
/// </summary>
public static class Utilities
{
private const long NanosecondsPerTick = 100;
/// <summary>
/// Decodes an unmanaged UTF-8 message pointer and returns null for null pointers.
/// </summary>
/// <param name="message">Pointer to an unmanaged UTF-8 message buffer.</param>
/// <returns>The decoded message, or <see langword="null"/> when the pointer is null.</returns>
public static string? ReadNullableUtf8(IntPtr message)
{
return message == IntPtr.Zero ? null : ReadUtf8(message);
}
/// <summary>
/// Decodes an unmanaged UTF-8 message pointer into managed text.
/// </summary>
/// <param name="message">Pointer to an unmanaged UTF-8 message buffer.</param>
/// <returns>The decoded message, or an empty string when the pointer is null or decoding returns null.</returns>
public static string ReadUtf8(IntPtr message)
{
if (message == IntPtr.Zero)
{
return string.Empty;
}
return Marshal.PtrToStringUTF8(message) ?? string.Empty;
}
/// <summary>
/// Formats a managed value into the option string expected by OpenDAL service configs.
/// </summary>
/// <param name="value">Managed value to format.</param>
/// <returns>The formatted option string.</returns>
public static string ToOptionString(object value)
{
return value switch
{
bool b => b ? "true" : "false",
IFormattable f => f.ToString(null, CultureInfo.InvariantCulture) ?? string.Empty,
_ => value.ToString() ?? string.Empty,
};
}
/// <summary>
/// Converts a positive <see cref="TimeSpan"/> into nanoseconds.
/// </summary>
/// <param name="value">Duration to convert.</param>
/// <param name="paramName">Parameter name used in thrown exceptions.</param>
/// <returns>Duration in nanoseconds.</returns>
/// <exception cref="ArgumentOutOfRangeException">Value is zero or negative.</exception>
/// <exception cref="OverflowException">Value exceeds the range of <see cref="ulong"/> nanoseconds.</exception>
public static ulong ToNanoseconds(TimeSpan value, string paramName)
{
if (value <= TimeSpan.Zero)
{
throw new ArgumentOutOfRangeException(paramName, "Duration must be greater than zero.");
}
checked
{
return (ulong)(value.Ticks * NanosecondsPerTick);
}
}
}