Back to the SSWF project home page
(Written by Alexis Wilke in 2002-2009)The entire SSWF project is covered by the following license:
Copyright (c) 2002-2009 Made to Order Software Corp.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
In order to create something useful, I thought of creating a totally seperate SWF library so it can be reused by other tools, not only the SSWF scripting language.
The main goal was to allow the end user to make easy calls to the library without having to know precisly how things will be encoded in the final SWF file.
At the time of writing, only the Save() process is really available in the library. Note that you can still look at the result and dump others SWF files using the swf_dump tool.
Alexis Wilke
the author
The library is defined in three main parts: some utility functions, the common objects and the tags. The tags are themselves defined in two main groups: the tags without a unique identifier and those with a unique identifier. There are also two categories of tags: those which can include other tags (the TagHeader and TagSprite) and the others. Finally, there are tags which can reference other(s) using either a name or the unique identifier.
The utility functions are primarilly for use by the library. You can use them if you wish but they may change a lot with time.
The common objects will be used to declare some parameters of the different tags such as the color, bounding box, matrix, etc. It is crucial to have these lower level objects to quickly build a complete tag. There are also objects such as the vectors list, item base and memory manager which are used by any of the other objects to manage lists and memory without having to reinvent the wheel in each object.
The tags are all derived from the TagBase class, itself derived from the ItemBase class so any tag can be inserted in an array of vectors. Tags with a unique identifier are all derived from the TagBaseID. This is important so each tag receives a different identifier (NOTE: there is a special case in the SWF format which is the DefineFont and DefineFontInfo which both have to receive the same identifier; this is, however, taken care of internally as you can't define a font information object yourself).
The common objects are used by some of the tag objects. It is often necessary for you to create one of these objects (possibly on the stack) in order to initialize a tag object properly.
Color
The color object defines an RGB or RGBA color. A color is taken as an RGBA when the alpha channel isn't set to 255. The
IsSolid()
function will return true when a color is an RGB color and false when the color is RGBA.
- Color(void);
The constructor doesn't take any parameter. It will reset the color to solid white which is also the default SWF background color.
void Reset(void);
Reset the color to solid white.
void Set(unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha = 255)
Initializes the color to the given values. By default a solid color is defined (when you don't define the alpha channel).
unsigned char Red(void);
unsigned char Green(void);
unsigned char Blue(void);
unsigned char Alpha(void);
Use one of these functions to retrieve the corresponding component.
void Save(Data& data, bool save_alpha = true);
Saves the color in the data file. By default, save the alpha channel as well. At this time all the tags use this function to save colors except one: the LOSSLESS image palette uses colors ordered differently.
bool operator == (const Color& color) const;
bool operator != (const Color& color) const;
Compare two color objects together and return true or false as appropriate. The comparison is exact (there is no approximation of the colors first).
bool IsSolid(void) const { return f_alpha == 255; }
Check whether the color is solid (RGB - it's alpha is 255) or transparent (RGBA - it's alpha isn't 255).
ColorTransform
The TagPlace uses a color transformation definition in order to affect the input color. It is possible, by setting all the scaling factors to 0.0 and the bias to a specific color value to change a shape to a specific color (however limited to a range of 0 to 128).
ColorTransform(void);
Initialize a color transform object with the default which is: do not transform the color. This means all the scaling factors will be set to 1 and all the biases (add) to 0. Note that when an alpha is defined, then the color transform is considered to be of V3.0+ (transparent). When there isn't any alpha defined (scale of 1 and biase of 0 in the alpha component) then it is considered V1.0+ (solid).
void Reset(void);
Resets a color transform object to the default: all the scaling factors are set to 1 and all the biases (add) to 0.
void SetAdd(double red, double green, double blue, double alpha = 0.0);
Set the biases to the specified values. The values are limited to the range [-128.0, +127.99609]. By default these are all zero (0.0). The biases are added to the input colors after the scaling was applied.
void SetMult(double red, double green, double blue, double alpha = 1.0);
Set the scaling factors to the specified values. The values are limited to the range [-128.0, +127.99609]. By default these are all one (1.0). The scaling factors are applied to the input colors before they are biased.
double AddRed(void);
double AddGreen(void);
double AddBlue(void);
double AddAlpha(void);
double MultRed(void);
double MultGreen(void);
double MultBlue(void);
double MultAlpha(void);
Each of these functions can be used to retrieve the data saved in this structure.
void Save(Data& data, bool save_alpha = true);
Saves the color transform in a file. By default saves the alpha channel along with the transformation.
bool IsNull(bool with_alpha) const;
A transformation with all biases set to 0.0 and all the scaling factors being 1.0 is considered null; i.e. we don't need to save it in most circonstances.
bool IsSolidCompatible(void);
This function returns true if the ColorTransform object can be saved in a V1.x or V2.x of the .SWF file format.
Data
The Data object is a memory file manager. You can write, read and seek within the data saved in this object just as you would do with a file.
Data(void);
A new data object can be created as is. There aren't any specific parameters.
void Empty(void);
Reset the destination buffer pointers to the beginning in effect making the file empty.
void Align(void);
Ensures the buffer is byte aligned for the next write.
void Overwrite(size_t offset, const void *ptr, size_t size);
void Write(const void *ptr, size_t size);
void WriteBits(long value, size_t bits);
void PutByte(char c);
void PutShort(short c);
void PutLong(long c);
void PutString(const char *string);
void Append(const Data& data);
Write in the file. All the functions append the specified data except the
Overwrite()
which can be used to write at any existing position.The
Write()
function will be used to append a buffer of bytes of any size. TheWriteBits()
function is used to write 0 to 32 bits (when 0 is specified, nothing happens). The bit 8 of the current byte is written first as specified in the SWF format reference.The
Append()
function appends the specified data at the end of the input data object.The
PutByte()
appends one byte. ThePutShort()
appends two bytes in little endian. ThePutLong()
appends four bytes in little endian. ThePutString()
writes an entire string up to and including its nul terminator.void Read(void *& ptr, size_t& size);
It is possible to read the data buffer. The function first aligns the pointer to the next byte if not already aligned. Then it returns a copy of the data pointer currently used within the object. The size parameter is set to the total size of the buffer in bytes.
WARNING: the returned pointer is valid until the next write to the buffer; writing to the buffer is very likely going to move the pointer to another place.
unsigned long ByteSize(void) const;
unsigned long Size(void) const;
These functions retrieve the size of the file in byte (ByteSize) or in bits (Size).
void Size(unsigned long size);
It is possible to truncate the file buffer by specifying a specific size for it.
Edges
The Edges are the basic element of the SWF format as these are used to draw the shapes in the output screen. It is a set of line and curve coordinates. A line has no control point.
To define an edge you ether need to specify its coordinates or you can declare a variable of type sswf::Edges::edge_t. This structure is defined below.
Edges in SWF are defined as lists of offsets. The very first coordinate is defined in a shape. Then each edge is an offset from the previous edge.
For example, when you want to draw a line, you need two points: A and B. The shape specifies the position of the point A. Then you need one edge with coordinates:
edge.f_x = B.x - A.x; edge.f_y = B.y - A.y;Similarly, when you want to draw a curve, you need three points: A, B and C. If we consider the point B as being the control point, then we can infer that: the shape specifies the position of the point A and one edge is defined with a control as follow:
edge.f_ctrl_x = B.x - A.x edge.f_ctrl_y = B.y - A.y edge.f_x = C.x - C.x; edge.f_y = C.y - C.y;Note that we first go to the control point then on to the 2nd anchor.
All the coordinates are taken to be TWIPs.
struct edge_t;
The edge_t structure can be used to declare a line or curve point in a list of edges. You can either set it up by hand or use one of the available functions.
struct edge_t { long f_x; long f_y; long f_ctrl_x; long f_ctrl_y; };
edge_t(void);
By default, the constructor will define a line with coordinates 0, 0.
edge_t(long x, long y);
This constructor defines a line with the specified coordinates.
edge_t(long x, long y, long ctrl_x, long ctrl_y);
This constructor defines a curve with the specified control point and anchor coordinates.
edge_t(const edge_t& edge);
This constructor uses another edge to initialize this new edge.
edge_t& operator = (const edge_t& edge);
Copy the input edge in this edge and return a reference to this edge.
bool IsLine(void) const;
Checks the edge and determine whether it is a curve (false) or a line (true).
Edges(void);
Initialize an Edges object. The list of edges will be empty at the start.
void Reset(void);
Ensures that the list of edges is empty so one can re-use the Edges object again.
void Set(long x, long y);
void Set(long x, long y, long ctrl_x, long ctrl_y);
void Set(int index, long x, long y, long ctrl_x, long ctrl_y);
void Set(const edge_t& edge);
void Set(int index, const edge_t& edge);
Append an edge into this Edges object. It is possible to specify an index in order to replace an existing edge by different values.
void Save(Data& data, long& x, long& y);
Save the list of edges in a data file. The x and y coordinates are returned with the last position. This is used in order to avoid as many "move" in the shape objects. At the start, these coordinate should be set to (0, 0). If there is a "move" in a shape, then set x and y to this move coordinates (if that's the same position, then ignore that move). Repeat for each set of edges and move in the given shape (this is done automatically within the shape object and you shouldn't have to worry about it!).
Matrix
There are several tags in which one can define a Matrix. These use this object.
Matrix(void);
Initialize the matrix object with the defaults (no translation, scaling nor rotation).
void Reset(void);
Use this function to reset the matrix to its defaults (no translation, scaling nor rotation).
void SetScale(double x, double y);
void SetScale(double scale);
Set the scaling factors. When only one scaling value is specified, then both the horizontal and the vertical scaling factors are set to the same value. The default scaling factors are both 1.
void SetRotate(double rotate);
Defines the rotation angle in radian. The default angle is 0.
void SetTranslate(long x, long y);
Specifies the horizontal (x) and vertical (y) translation in TWIPs. The default translation coordinates are (0, 0).
void Save(Data& data);
Save the matrix in the specified data file. When no scaling and no rotation are specified, no matrix is saved. If only the scaling is specified, then a 2x1 matrix is saved. If the rotation is specified, then a 2x2 matrix is saved.
bool IsNull(void) const;
This function returns true if the matrix will have no effect on the corresponding object coordinates.
bool operator == (const Matrix& matrix) const;
bool operator != (const Matrix& matrix) const;
Compare two matrix objects and return true if they are compatible. The angles are tested modulo 2 x PI.
Rectangle
The rectangle object is used in many places most of the time to declare a bounding box.
Rectangle(void);
The constructor initializes the rectangle so it is empty.
void Reset(void);
Makes the rectangle empty.
void Set(long xmin, long xmax, long ymin, long ymax);
void SetReorder(long xmin, long xmax, long ymin, long ymax);
Call on of these to define the rectangle object coordinates. The
SetReorder()
will ensure thatxmin <= xmax
andymin <= ymax
. It is perfectly valid to declare an empty rectangle.If you have a rectangle defined with a position and a size, you can set an SWF rectangle with:
SetReorder(myrect.x, myrect.y, myrect.x + myrect.width, myrect.y + myrect.height);long XMin(void) const;
long XMax(void) const;
long YMin(void) const;
long YMax(void) const;
Retrive one of the coordinate of the rectangle.
bool IsEmpty(void) const;
This function returns true if either
xmax <= xmin
orymax <= ymin
.void Save(Data& data) const;
Save the rectangle in the data file. At this time the function returns a data file which isn't aligned to the next byte. However, it seems that it could very well be since all the tags I've programmed so far require an alignment after any rectangle.
State
Whenever you define a button you need to define a state. A button state includes a reference to an object, a depth (called layer here), a matrix and a set of flags.
State(void);
Initializes the state as with the Reset() function (see below).
void Reset(void);
Resets the state with no flags, no object reference, layer of zero and an empty matrix.
void SetObjectID(sswf_id_t id);
Defines a reference to the object which will be drawn when this state is entered.
void SetFlags(unsigned char flags);
Set the state itself. The set of available flags are define in the SSWF reference files. Any value is accepted by the library.
NOTE: A state with all its flags set to zero is no valid. This is used to mark the end of the list of states.
void SetLayer(unsigned short layer);
Set the layer (depth) of the object to be displayed in this state. This depth is only specific to the button. All the state elements of a button appear at the button depth within the rest of the movie.
void SetMatrix(const Matrix& matrix);
Determine a matrix used to transform the specified object whenever it is necessary to display it.
void Save(Data& data);
Saves the state in the data file.
Style
The style object will be used to create a fill or line style later included in a shape.
enum style_t;
The type of style is defined with one of the following enumeration value:
STYLE_TYPE_UNKNOWN STYLE_TYPE_NO_LINE STYLE_TYPE_NO_FILL STYLE_TYPE_LINE STYLE_TYPE_SOLID STYLE_TYPE_GRADIENT_LINEAR STYLE_TYPE_GRADIENT_RADIAL STYLE_TYPE_BITMAP_TILLED STYLE_TYPE_BITMAP_CLIPPED STYLE_TYPE_MATRIXThe NO LINE and NO FILL are special cases used to turn off the current line or fill style in a shape.
The LINE type will be used to declare a line. In this case you need to define a color and a width. It is possible to define a morphing line. See the SetLine() function below.
The SOLID entry defines a "solid" fill. Note that though it is called a solid fill, the color doesn't need to be solid. It is possible to define a morphing solid fill.
The GRADIENT LINEAR and GRADIENT RADIAL will be used to define a fill which change color. You will find more information about gradients in the other SSWF documents. The number of colors will be determined by the largest index used with the
SetGradient()
function. At this time, the color positions need to be sorted from the smallest to the largest. It is possible to define a morphing gradient.The BITMAP TILLED and BITMAP CLIPPED can be used to draw an image within the shape you are drawing. You will need a reference to an image. Image based fills can't use the morph feature.
The MATRIX type is only an intermediate type and it shouldn't be used.
It is certainly a good idea to force the type since the system will try to determine the type by itself (guessing from the function calls you make) but can very well make a mistake. Also, if you force a type and call an incompatible function, you get an error.
Style(void);
This function initializes a style object like the
Reset()
function.void Reset(void);
The reset function
style_t Type(void) const;
This function returns the current type of the style. This can be used to check if the proper type was automatically set or to know what to expect in the other parameters.
bool HasMorph(void) const;
This function will return true if any call used a morph feature.
bool HasAlpha(void) const;
If a color uses an alpha value other than 255, then this function returns true.
void SetType(style_t style);
Forces the type of the style. Note that you won't be able to set the type to anything if you already used some other functions.
void SetLine(int index, unsigned short width, const Color& color);
Set the line width and color. The index can be zero (normal line or starting morph point) and one (ending morph point).
void SetColor(int index, const Color& color);
Set the color of a solid fill. The index can be zero (normal line or starting morph point) and one (ending morph point).
void SetGradient(int index, int pos, const Color& color);
Set a gradient position and color at the specified index. The index can be any value from 0 to 7 (normal gradient or starting morph gradient) and 8 to 15 (ending morph gradient).
void SetMatrix(int index, const Matrix& matrix);
Image and gradient based fill styles require a matrix. In case of a gradient, it is possible to use an index of 1 when this is a morphing gradient. In the case of an image fill, then only an index of 0 is accepted (this is to be verified still... the library actually accepts those but the Shape can't save a morphing shape at this time anyway!).
void SetBitmap(sswf_id_t id);
Determine the unique identifier of the bitmap used to draw the image within the area using this fill style.
void SetClipping(void);
Mark this fill style as a clipping fill style. This doesn't seem necessary yet it is used in many movies... One calls this function in place of the
SetBitmap()
to create a fill style with a matrix having a scaling factor of 20. This fill style should be inserted right before the bitmap based fill style.void Save(Data& data, bool save_alpha, bool save_morph);
Saves the fill style in the data file. The save_alpha flag is used to know whether the alpha channel of any color should be saved. The save_morph flag is used to know whether the fill style is part of a morphing capable shape. Note that when the save_morph is set, the save_alpha flag is forced to true.
bool operator == (const Style& style) const;
Compare two styles and return true if they are equal. This is used to avoid saving similar styles more than once (This is actually wrong since doing prevents draw the same color at two different levels within the same shape... however, it's rarely a necessity).
Vectors
A Vectors object is a dynamic array of pointers to other objects. It is used to generate the different lists of tags, actions, styles, edges, etc. The objects pointed to must be derived from the ItemBase class. This class is empty, it is just used to be able to cast the pointers to objects instead of using
void *
(which wouldn't be clean in C++). Thus, a class such as the styles is derived from the ItemBase as follow:class Style : public ItemBase { ... };Then later we can have a list of styles since a style is a valid vector item.
Vectors(void);
Vectors(const Vectors& vector);
Initialize a new vector. You can either create an empty vector or a copy of another vector. Note that the destruction of a vector object doesn't affect in any way the objects being pointed to.
ItemBase *Get(int index) const;
Get the item at offset index. Note that if index is negative or larger or equal to
Count()
an error occurs. This function can't be called on an empty array of vectors.void Set(int index, ItemBase *vector);
Set the item defined by the index to the given vector. If the vector table isn't large enough at the time of the call, then it is enlarged to include this new given item.
void SetSize(int size);
Force the number of item in the vector list to size. This is used internally to ensure the list is large enough to set a new parameter.
int Count(void) const;
Return the number of entries currently defined in the vector list. Note that some entries may be null pointers.
void Empty(void);
Make the vector list empty. If possible, this function will reduce the amount of memory used by the object. The objects to which each pointer are pointing are not affected.
Vectors& operator = (const Vectors& vectors);
Copy a vector list in another. The original list is lost. The objects pointed to are not affected.
All the tag objects need to have a parent except the TagHeader. In order to insert objects in a sprite, that sprite will be given as the parent object. At this time, only a header and a sprite can be a parent object. At this time, definition tags can't be included in a sprite or an error will be generated.
A TagBase object is not an object. Instead, all the other objects are based on this one. You can't create a TagBase directly. Because all the other tags are based on this one, it is described first. All the virtual functions are not explained in the other objects though they all are available.
All the other tag objects are derived from this one. It is important since most of the functions are virtual functions.
NOTE: at this time, there are only two levels (well, three for objects with an ID), the TagBase object and the derived object (in case of objects with an ID, you also have a TagBaseID). It doesn't look to me like it will be necessary to have any more derivation.
class TagBase : public MemoryManager
All the tags inherit the memory manager of the TagBase class.
TagBase(const char *name, TagBase *parent);
virtual ~TagBase();
Initialize a TagBase object. The parent object isn't checked here. It should be checked by the parent directories. The name is actually the type of the tag object.
Create a button object to offer interactivity in an SWF movie file. A button is composed of states with corresponding shapes and a list of actions to execute when the end user clicks on the button.
A button is a definition tag and it has an identifier.
class Button : public TagBaseID;
Button(TagBase *parent);
Initialize a button object. At this time, the parent pointer must be a header.
virtual int Save()
Get the item at offset index. Note that if index is negative
or larger or equal to Count()
an error occurs.
This function can't be called on an empty array of vectors.
void Set(int index, ItemBase *vector);
Set the item defined by the index to the given vector. If the vector table isn't large enough at the time of the call, then it is enlarged to include this new given item.
void SetSize(int size);
Force the number of item in the vector list to size. This is used internally to ensure the list is large enough to set a new parameter.
int Count(void) const;
Return the number of entries currently defined in the vector list. Note that some entries may be null pointers.
void Empty(void);
Make the vector list empty. If possible, this function will reduce the amount of memory used by the object. The objects to which each pointer are pointing are not affected.
Vectors& operator = (const Vectors& vectors);
Copy a vector list in another. The original list is lost. The objects pointed to are not affected.
The common objects are used by some of the tag objects. It is often necessary for you to create one of these objects (possibly on the stack) in order to initialize a tag object properly.
Class less functions
inline void assert(int cond, const char *format, ...);
This function is defined as nothing when
DEBUG
is turned OFF (#define DEBUG 0
or-DDEBUG=0
). Otherwise, it will checkcond
. If it is true, the function returns immediately. If it is false, the function never returns and the message defined byformat
and the following parameters (as inprintf(3C)
) is printed in thestderr
stream.extern const char *sswf_version(void);
The
sswf_version()
function is garanteed to remain the same and return a similar string format throughout the life of this library.With C++ libraries, it is very likely that a change in version will make the corresponding code break because offsets to the different functions within an object will change dramatically. Thus, it is important to check out the version to make sure the software you're starting won't just break (you may simple warn the user instead of preventing the user from using the library altogether).
The string returned has the following standard format:
<major>.<minor>.<release>This can easilly be parsed with an
sscanf(3C)
call as follow:const char *version; int major, minor, release; version = sswf::sswf_version(); sscanf(version, "%d.%d.%d", &major, &minor, &release);extern void swap(void *s1, void *s2, size_t size);
The
swap()
function is a simple utility function used to copy one buffer in another and vice versa. If all the parameters indicate a buffer of long words, then the swap is done with long words instead of bytes. This can greatly increase the speed at which the swapping will occur.MemoryManager
The memory manager is an object used to allocate and free memory. It will ensure that any memory block allocated gets freed upon the deletion of the object allocating that memory. Also it ensures that freed memory buffers were actually allocated.
In order to use a memory manager, you need to derive your object(s) from it. One should rarely use the memory manager of another object. A function in that object should be defined in order to attach or allocate new blocks of memory.
The memory manager makes use of the
class Buffer
object in order to keep track of all the memory buffers allocated at any one time. This object is not described here since it is really low level and may evolve as the memory manager requires. You shouldn't directly use a buffer object.class MemoryManager;
MemoryManager(void);
~MemoryManager();
The memory manager constructor doesn't require any parameter. It will reset itself and wait for memory requests.
MemAttach(MemBuffer *ptr, size_t size, const char *info);
Attach an object (derived from MemBuffer) that you allocated yourself. In C++, you are required to use the
new
operator to get the contructor called properly (that's something which is REALLY missing in C++! a way to call the constructor and destructor without using the new and delete operators. Anyway...) Once such an object was properly created, you can attach it with a call to the MemAttach() function.When the memory manager object is deleted, all the attached objects will automatically be deleted too.
The
ptr
parameter has to point to a C++ object which was allocated with thenew
operator. If the pointer is NULL (0), then the function reports an error and aborts the process. This is similar to theMemAlloc()
function which aborts the process when a memory allocation fails.The
size
parameter is unused. It will be saved in DEBUG mode and printed out if you request a memory dump at a later time. It should represent the size of the object.The
info
parameter is a string of information about the memory buffer being allocated. This is for debug purposes only and should be used that way only. This information is NOT available when the DEBUGs are turned off.void *MemAlloc(size_t size, const char *info);
void *MemRealloc(void *ptr, size_t size, const char *info);
These functions will allocate a block of memory using the malloc(3C) and realloc(3C) functions (thus they can't be used to create an object). The
MemRealloc()
can also be used to shrink or enlarge a pre-allocated memory buffer (if ptr is set to NULL, then a new memory buffer is created; if the new size is set to zero, then the memory buffer is entirely released as if theMemFree()
function had been called.)The
size
parameter is the number of bytes which are guaranteed to be available in the buffer being returned. The buffer may be a few bytes larger, but don't count on it since the DEBUG version will also check these top ensure the validity of your buffer management. Don't use a size of 0 with theMemAlloc()
function. If you set thesize
parameter to 0 when calling theMemRealloc()
, then the buffer is freed instead of being allocated or reallocated.The
info
parameter is a string of information about the memory buffer being allocated. This is for debug purposes only and should be used that way only. This information is NOT available when the DEBUGs are turned off.The
ptr
parameter is a pointer to a memory block previously allocated withMemAlloc()
orMemRealloc()
. It can be set to NULL in which case theMemRealloc()
function behaves like theMemAlloc()
function.void *MemFree(void *ptr);
Free a memory buffer which was previously allocated using the MemAlloc() or MemRealloc(), or was attached to this memory manager with the MemAttach() function.
If an invalid pointer is given as
ptr
, then an error is printed and the process is aborted immediatly.void MemClean(void *ptr);
The MemClean() function accepts a pointer to a pointer. It checks if this pointer contains NULL (nothing happens) or a pointer to a memory buffer. When there is a pointer to a memory buffer, then it is free with a call to the MemFree() function. Finally, the pointer is set to NULL so you don't have to do it yourself. The use of the
MemClean
function is really just a way to avoid one line of code:MyPtr *ptr; ... MemFree(ptr); ptr = 0; ... or ... MemClear(&ptr); ...void StrDup(const char *string);
This is a useful function used to duplicate a string. The resulting string is automatically saved among the list of buffers allocated by this object and thus it will be freed at the time the object is deleted.
void MemTest(void *ptr);
In DEBUG mode (only), you can check a memory pointer at any time using this function. If the pointer isn't a valid memory pointer (allocated by
MemAlloc()
,MemRealloc()
orMemAttach()
) then an error is printed and the process is immediatly aborted.This function is automatically called by the
MemFree()
function when the DEBUG is on.
This document was last modified on .