From fc1d21fe9d9d7034c420c31babd7f8caa6378e22 Mon Sep 17 00:00:00 2001 From: Mike Wey Date: Sat, 29 Jan 2011 16:35:16 +0100 Subject: Move some functions to there own file --- dmagick/Utils.d | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 dmagick/Utils.d (limited to 'dmagick/Utils.d') diff --git a/dmagick/Utils.d b/dmagick/Utils.d new file mode 100644 index 0000000..f853350 --- /dev/null +++ b/dmagick/Utils.d @@ -0,0 +1,126 @@ +/** + * A collection of helper functions used in DMagick. + * + * Copyright: Mike Wey 2011 + * License: To be determined + * Authors: Mike Wey + */ + +module dmagick.Utils; + +import std.math; + +import dmagick.c.memory; +import dmagick.c.magickString; +import dmagick.c.magickType; + +/** + * Copy a string into a static array used + * by ImageMagick for some atributes. + */ +private void copyString(ref char[MaxTextExtent] dest, string source) +{ + if ( source.length < MaxTextExtent ) + throw new Exception("text is to long"); //TODO: a proper exception. + + dest[0 .. source.length] = source; + dest[source.length] = '\0'; +} + +/** + * Our implementation of ImageMagick's CloneString. + * + * We use this since using CloneString forces us to + * append a \0 to the end of the string, and the realocation + * whould be wastefull if we are just going to copy it + */ +private void copyString(ref char* dest, string source) +{ + if ( source is null ) + { + if ( dest !is null ) + DestroyString(dest); + return; + } + + if ( ~source.length < MaxTextExtent ) + throw new Exception("UnableToAcquireString"); //TODO: a proper exception. + + if ( dest is null ) + dest = cast(char*)AcquireQuantumMemory(source.length+MaxTextExtent, dest.sizeof); + else + dest = cast(char*)ResizeQuantumMemory(dest, source.length+MaxTextExtent, dest.sizeof); + + if ( dest is null ) + throw new Exception("UnableToAcquireString"); //TODO: a proper exception. + + if ( source.length > 0 ) + dest[0 .. source.length] = source; + + dest[source.length] = '\0'; +} + +real degreesToRadians(real deg) +{ + return deg*PI/180; +} + +struct RefCounted(alias pred, T) + if ( !is(T == class) && is(typeof(pred(null)) == void) ) +{ + T* payload; + + private bool isInitialized; + private size_t* refcount; + + alias payload this; + + this(T* payload) + { + this.payload = payload; + + refcount = new size_t; + *refcount = 1; + + isInitialized = true; + } + + this(this) + { + if ( isInitialized ) + (*refcount)++; + } + + ~this() + { + (*refcount)--; + + if ( *refcount == 0 ) + pred(payload); + } + + @property size_t refCount() + { + return *refcount; + } +} + +unittest +{ + int x = 10; + int y = 20; + + alias RefCounted!( (void* t){ x = 20; }, int ) IntRef; + + auto a = IntRef(&x); + assert( a.refCount == 1 ); + auto b = a; + assert( a.refCount == 2 ); + + b = IntRef(&y); + assert( a.refCount == 1 ); + assert( b.refCount == 1 ); + a = b; + assert( b.refCount == 2 ); + assert( x == 20 ); +} -- cgit v1.2.3