diff options
| author | Mike Wey | 2011-01-29 16:35:16 +0100 |
|---|---|---|
| committer | Mike Wey | 2011-01-29 16:35:16 +0100 |
| commit | fc1d21fe9d9d7034c420c31babd7f8caa6378e22 (patch) | |
| tree | c149f995cf1c8f1384171245ee20db0e947b3b68 /dmagick/Utils.d | |
| parent | 54a0fc2255472d7d3d6808d7a490294a99c1bc0d (diff) | |
Move some functions to there own file
Diffstat (limited to 'dmagick/Utils.d')
| -rw-r--r-- | dmagick/Utils.d | 126 |
1 files changed, 126 insertions, 0 deletions
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 ); +} |
