internal static AGDnsApi.ag_upstream_options ToNativeObject( UpstreamOptions upstreamOptions, Queue <IntPtr> allocatedPointers) { AGDnsApi.ag_list bootstrapC = MarshalUtils.ListToAgList( upstreamOptions.Bootstrap, MarshalUtils.StringToPtr, allocatedPointers); byte[] addressBytes = null; if (upstreamOptions.ResolvedIpAddress != null) { addressBytes = upstreamOptions.ResolvedIpAddress.GetAddressBytes(); } AGDnsApi.ag_buffer addressC = MarshalUtils.BytesToAgBuffer(addressBytes, allocatedPointers); AGDnsApi.ag_upstream_options upstreamOptionsC = new AGDnsApi.ag_upstream_options { bootstrap = bootstrapC, resolved_ip_address = addressC }; MarshalUtils.CopyPropertiesToFields(upstreamOptions, ref upstreamOptionsC); MarshalUtils.AllStringsToPtrs(upstreamOptions, ref upstreamOptionsC, allocatedPointers); return(upstreamOptionsC); }
/// <summary> /// Converts <see cref="AGDnsApi.ag_buffer"/> structure to the byte array /// </summary> /// <param name="agBuffer"><see cref="AGDnsApi.ag_buffer"/> structure</param> /// <returns>Byte array</returns> internal static byte[] AgBufferToBytes(AGDnsApi.ag_buffer agBuffer) { if (agBuffer.data == IntPtr.Zero) { return(null); } if (agBuffer.size == 0) { return(null); } byte[] buffer = new byte[agBuffer.size]; Marshal.Copy(agBuffer.data, buffer, 0, (int)agBuffer.size); return(buffer); }
public void TestApiBufferConverting() { AGDnsApi.ag_buffer apiBuffer = new AGDnsApi.ag_buffer(); try { string basicString = "krasivyeshpilinasolberiiskomsobore"; byte[] basicBuffer = Encoding.UTF8.GetBytes(basicString); apiBuffer = MarshalUtils.BytesToAgBuffer(basicBuffer); Assert.AreNotEqual(apiBuffer.data, IntPtr.Zero); Assert.AreNotEqual(apiBuffer.size, 0); byte[] convertedBuffer = MarshalUtils.AgBufferToBytes(apiBuffer); Assert.AreNotEqual(convertedBuffer.Length, 0); string convertedString = Encoding.UTF8.GetString(convertedBuffer); Assert.AreEqual(basicString, convertedString); } finally { MarshalUtils.SafeFreeHGlobal(apiBuffer.data); } }
/// <summary> /// Creates the <see cref="IPAddress"/> object from the specified pointer to address byte array, /// addressLength /// </summary> /// <param name="agAddress">The <see cref="AGDnsApi.ag_buffer"/> instance</param> /// <exception cref="ArgumentException">Thrown, /// if passed <see cref="AGDnsApi.ag_buffer.size"/> is not acceptable</exception> /// <returns><see cref="IPAddress"/> object or null if the pointer is null or addressLength is zero</returns> private static IPAddress CreateIpAddress(AGDnsApi.ag_buffer agAddress) { if (agAddress.data == IntPtr.Zero || agAddress.size == 0) { return(null); } byte[] address = new byte[agAddress.size]; Marshal.Copy(agAddress.data, address, 0, (int)agAddress.size); AddressFamily addressFamily = ADDRESSES_FAMILY_LENGTH .FirstOrDefault(addressPair => addressPair.Value == agAddress.size).Key; if (addressFamily == AddressFamily.Unknown) { string message = "Cannot create IPAddress because of unacceptable address length value"; throw new ArgumentException(message, "agAddress"); } IPAddress ipAddress = new IPAddress(address); return(ipAddress); }
/// <summary> /// Converts byte array to the <see cref="AGDnsApi.ag_buffer"/> structure include memory allocating. /// The resulting <see cref="AGDnsApi.ag_buffer.data"/> property must be freed /// with <see cref="SafeFreeHGlobal(IntPtr)"/>> /// </summary> /// <param name="buffer">Byte array to marshall</param> /// <param name="allocatedPointers"> /// Pointers, which will be referred to a newly allocated memory /// (within the process of marshaling the string to the pointer) /// will be added to this list. /// If this list is not specified (null), /// a new created pointer will not be added anywhere</param> /// The resulting pointer (<seealso cref="IntPtr"/>) must be freed /// with <see cref="SafeFreeHGlobal(IntPtr)"/> /// <returns><see cref="AGDnsApi.ag_buffer"/> structure</returns> internal static AGDnsApi.ag_buffer BytesToAgBuffer(byte[] buffer, Queue <IntPtr> allocatedPointers = null) { if (buffer == null) { return(new AGDnsApi.ag_buffer()); } IntPtr pBuffer = Marshal.AllocHGlobal(buffer.Length); Marshal.Copy(buffer, 0, pBuffer, buffer.Length); AGDnsApi.ag_buffer apiBuffer = new AGDnsApi.ag_buffer { data = pBuffer, size = (uint)buffer.Length }; if (allocatedPointers != null) { allocatedPointers.Enqueue(pBuffer); } return(apiBuffer); }