-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added a new Pointer class to help manage pointers in C ports. Updated…
… LibOgg to use this new pointer class.
- Loading branch information
Showing
17 changed files
with
626 additions
and
294 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
/******************************************************************************/ | ||
/* This source, or parts thereof, may be used in any software as long the */ | ||
/* license of NostalgicPlayer is keep. See the LICENSE file for more */ | ||
/* information. */ | ||
/******************************************************************************/ | ||
using System; | ||
using System.Runtime.CompilerServices; | ||
using System.Text; | ||
|
||
namespace Polycode.NostalgicPlayer.Kit.Utility | ||
{ | ||
/// <summary> | ||
/// C like memory methods | ||
/// </summary> | ||
public static class CMemory | ||
{ | ||
/********************************************************************/ | ||
/// <summary> | ||
/// | ||
/// </summary> | ||
/********************************************************************/ | ||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
public static Pointer<T> MAlloc<T>(int size) | ||
{ | ||
return new Pointer<T>(new T[size]); | ||
} | ||
|
||
|
||
|
||
/********************************************************************/ | ||
/// <summary> | ||
/// | ||
/// </summary> | ||
/********************************************************************/ | ||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
public static Pointer<T> Realloc<T>(Pointer<T> ptr, int newSize) | ||
{ | ||
T[] newArray = new T[newSize]; | ||
Array.Copy(ptr.Buffer, ptr.Offset, newArray, 0, Math.Min(newSize, ptr.Buffer.Length - ptr.Offset)); | ||
|
||
return new Pointer<T>(newArray); | ||
} | ||
|
||
|
||
|
||
/********************************************************************/ | ||
/// <summary> | ||
/// | ||
/// </summary> | ||
/********************************************************************/ | ||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
public static void Free<T>(Pointer<T> ptr) | ||
{ | ||
} | ||
|
||
|
||
|
||
/********************************************************************/ | ||
/// <summary> | ||
/// | ||
/// </summary> | ||
/********************************************************************/ | ||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
public static void MemMove<T>(Pointer<T> dest, Pointer<T> source, int length) | ||
{ | ||
Array.Copy(source.Buffer, source.Offset, dest.Buffer, dest.Offset, length); | ||
} | ||
|
||
|
||
|
||
/********************************************************************/ | ||
/// <summary> | ||
/// | ||
/// </summary> | ||
/********************************************************************/ | ||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
public static void MemCpy<T>(Pointer<T> dest, Pointer<T> source, int length) | ||
{ | ||
Array.Copy(source.Buffer, source.Offset, dest.Buffer, dest.Offset, length); | ||
} | ||
|
||
|
||
|
||
/********************************************************************/ | ||
/// <summary> | ||
/// | ||
/// </summary> | ||
/********************************************************************/ | ||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
public static void MemCpy<T>(T[] dest, string str, int length) | ||
{ | ||
Array.Copy(Encoding.ASCII.GetBytes(str), dest, length); | ||
} | ||
|
||
|
||
|
||
/********************************************************************/ | ||
/// <summary> | ||
/// | ||
/// </summary> | ||
/********************************************************************/ | ||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
public static int MemCmp(Pointer<byte> ptr1, Pointer<byte> ptr2, int length) | ||
{ | ||
for (int i = 0; i < length; i++) | ||
{ | ||
if (ptr1[i] < ptr2[i]) | ||
return -1; | ||
|
||
if (ptr1[i] > ptr2[i]) | ||
return 1; | ||
} | ||
|
||
return 0; | ||
} | ||
|
||
|
||
|
||
/********************************************************************/ | ||
/// <summary> | ||
/// | ||
/// </summary> | ||
/********************************************************************/ | ||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
public static int MemCmp(Pointer<byte> ptr1, string compareString, int length) | ||
{ | ||
return MemCmp(ptr1, new Pointer<byte>(Encoding.ASCII.GetBytes(compareString)), length); | ||
} | ||
|
||
|
||
|
||
/********************************************************************/ | ||
/// <summary> | ||
/// | ||
/// </summary> | ||
/********************************************************************/ | ||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
public static void MemSet<T>(Pointer<T> ptr, T value, int length) | ||
{ | ||
ptr.Buffer.AsSpan(ptr.Offset, length).Fill(value); | ||
} | ||
|
||
|
||
|
||
/********************************************************************/ | ||
/// <summary> | ||
/// | ||
/// </summary> | ||
/********************************************************************/ | ||
[MethodImpl(MethodImplOptions.AggressiveInlining)] | ||
public static Pointer<T> MemChr<T>(Pointer<T> ptr, T ch, int count) | ||
{ | ||
int searchLength = Math.Min(count, ptr.Buffer.Length - ptr.Offset); | ||
|
||
for (int i = 0; i < searchLength; i++) | ||
{ | ||
if (ptr[i].Equals(ch)) | ||
return new Pointer<T>(ptr.Buffer, ptr.Offset + i); | ||
} | ||
|
||
return new Pointer<T>(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
/******************************************************************************/ | ||
/* This source, or parts thereof, may be used in any software as long the */ | ||
/* license of NostalgicPlayer is keep. See the LICENSE file for more */ | ||
/* information. */ | ||
/******************************************************************************/ | ||
using System; | ||
|
||
namespace Polycode.NostalgicPlayer.Kit.Utility | ||
{ | ||
/// <summary> | ||
/// This holds a buffer and a start offset. Can be used in C ports, where | ||
/// there are a lot of pointer calculations. By using this, you don't need | ||
/// to hold the offset by yourself and pass it around. | ||
/// | ||
/// It is almost similar to Span, except that with this, you can also use | ||
/// negative indexes to retrieve the data, which is used by some C programs | ||
/// </summary> | ||
public struct Pointer<T> : IEquatable<Pointer<T>> | ||
{ | ||
/********************************************************************/ | ||
/// <summary> | ||
/// Constructor | ||
/// </summary> | ||
/********************************************************************/ | ||
public Pointer(T[] buffer) : this(buffer, 0) | ||
{ | ||
} | ||
|
||
|
||
|
||
/********************************************************************/ | ||
/// <summary> | ||
/// Constructor | ||
/// </summary> | ||
/********************************************************************/ | ||
public Pointer(T[] buffer, int offset) | ||
{ | ||
Buffer = buffer; | ||
Offset = offset; | ||
} | ||
|
||
|
||
|
||
/********************************************************************/ | ||
/// <summary> | ||
/// Return the whole buffer | ||
/// </summary> | ||
/********************************************************************/ | ||
public T[] Buffer { get; private set; } | ||
|
||
|
||
|
||
/********************************************************************/ | ||
/// <summary> | ||
/// Return the offset in the buffer where the first item starts | ||
/// </summary> | ||
/********************************************************************/ | ||
public int Offset { get; private set; } | ||
|
||
|
||
|
||
/********************************************************************/ | ||
/// <summary> | ||
/// Clear the pointer | ||
/// </summary> | ||
/********************************************************************/ | ||
public void SetToNull() | ||
{ | ||
Buffer = null; | ||
Offset = 0; | ||
} | ||
|
||
|
||
|
||
/********************************************************************/ | ||
/// <summary> | ||
/// Check to see if the pointer is null | ||
/// </summary> | ||
/********************************************************************/ | ||
public bool IsNull => Buffer == null; | ||
|
||
|
||
|
||
/********************************************************************/ | ||
/// <summary> | ||
/// Return or set the item at the index given | ||
/// </summary> | ||
/********************************************************************/ | ||
public T this[int index] | ||
{ | ||
get => Buffer[Offset + index]; | ||
set => Buffer[Offset + index] = value; | ||
} | ||
|
||
|
||
|
||
/********************************************************************/ | ||
/// <summary> | ||
/// Return a new pointer where the original pointer is incremented by | ||
/// the value given | ||
/// </summary> | ||
/********************************************************************/ | ||
public static Pointer<T> operator + (Pointer<T> ptr, int increment) | ||
{ | ||
return new Pointer<T>(ptr.Buffer, ptr.Offset + increment); | ||
} | ||
|
||
|
||
|
||
/********************************************************************/ | ||
/// <summary> | ||
/// Return the current pointer with the current offset, but the | ||
/// offset will be incremented by one afterwards | ||
/// </summary> | ||
/********************************************************************/ | ||
public static Pointer<T> operator ++ (Pointer<T> ptr) | ||
{ | ||
return ptr + 1; | ||
} | ||
|
||
|
||
|
||
/********************************************************************/ | ||
/// <summary> | ||
/// Will calculate the difference between the two pointers. Both | ||
/// pointers need to use the same buffer | ||
/// </summary> | ||
/********************************************************************/ | ||
public static int operator - (Pointer<T> ptr1, Pointer<T> ptr2) | ||
{ | ||
if (ptr1.Buffer != ptr2.Buffer) | ||
throw new ArgumentException("Both pointers need to use the same buffer"); | ||
|
||
return ptr1.Offset - ptr2.Offset; | ||
} | ||
|
||
#region IEquatable implementation | ||
/********************************************************************/ | ||
/// <summary> | ||
/// Compare two pointers | ||
/// </summary> | ||
/********************************************************************/ | ||
public bool Equals(Pointer<T> other) | ||
{ | ||
return (Buffer == other.Buffer) && (Offset == other.Offset); | ||
} | ||
#endregion | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.