1.1 --- a/core/smn_sorting.cpp Sun Nov 11 20:59:20 2007 +0000
1.2 +++ b/core/smn_sorting.cpp Fri Nov 23 05:10:33 2007 +0000
1.3 @@ -33,6 +33,8 @@
1.4 #include <IHandleSys.h>
1.5 #include <stdlib.h>
1.6 #include <string.h>
1.7 +#include "HandleSys.h"
1.8 +#include "CellArray.h"
1.9
1.10 /***********************************
1.11 * About the double array hack *
1.12 @@ -373,6 +375,139 @@
1.13 return 1;
1.14 }
1.15
1.16 +enum SortType
1.17 +{
1.18 + Sort_Integer = 0,
1.19 + Sort_Float,
1.20 + Sort_String,
1.21 +};
1.22 +
1.23 +int sort_adtarray_strings_asc(const void *str1, const void *str2)
1.24 +{
1.25 + return strcmp((char *) str1, (char *) str2);
1.26 +}
1.27 +
1.28 +int sort_adtarray_strings_desc(const void *str1, const void *str2)
1.29 +{
1.30 + return strcmp((char *) str2, (char *) str1);
1.31 +}
1.32 +
1.33 +static cell_t sm_SortADTArray(IPluginContext *pContext, const cell_t *params)
1.34 +{
1.35 + CellArray *cArray;
1.36 + HandleError err;
1.37 + HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
1.38 +
1.39 + if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&cArray))
1.40 + != HandleError_None)
1.41 + {
1.42 + return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
1.43 + }
1.44 +
1.45 + cell_t order = params[2];
1.46 + cell_t type = params[3];
1.47 + size_t arraysize = cArray->size();
1.48 + size_t blocksize = cArray->blocksize();
1.49 + cell_t *array = cArray->base();
1.50 +
1.51 + if (type == Sort_Integer)
1.52 + {
1.53 + if (order == Sort_Ascending)
1.54 + {
1.55 + qsort(array, arraysize, blocksize * sizeof(cell_t), sort_ints_asc);
1.56 + }
1.57 + else
1.58 + {
1.59 + qsort(array, arraysize, blocksize * sizeof(cell_t), sort_ints_desc);
1.60 + }
1.61 + }
1.62 + else if (type == Sort_Float)
1.63 + {
1.64 + if (order == Sort_Ascending)
1.65 + {
1.66 + qsort(array, arraysize, blocksize * sizeof(cell_t), sort_floats_asc);
1.67 + }
1.68 + else
1.69 + {
1.70 + qsort(array, arraysize, blocksize * sizeof(cell_t), sort_floats_desc);
1.71 + }
1.72 + }
1.73 + else if (type == Sort_String)
1.74 + {
1.75 + if (order == Sort_Ascending)
1.76 + {
1.77 + qsort(array, arraysize, blocksize * sizeof(cell_t), sort_adtarray_strings_asc);
1.78 + }
1.79 + else
1.80 + {
1.81 + qsort(array, arraysize, blocksize * sizeof(cell_t), sort_adtarray_strings_desc);
1.82 + }
1.83 + }
1.84 +
1.85 + return 1;
1.86 +}
1.87 +
1.88 +struct sort_infoADT
1.89 +{
1.90 + IPluginFunction *pFunc;
1.91 + cell_t *array_base;
1.92 + cell_t array_bsize;
1.93 + Handle_t array_hndl;
1.94 + Handle_t hndl;
1.95 +};
1.96 +
1.97 +sort_infoADT g_SortInfoADT;
1.98 +
1.99 +int sort_adtarray_custom(const void *elem1, const void *elem2)
1.100 +{
1.101 + cell_t result = 0;
1.102 + IPluginFunction *pf = g_SortInfoADT.pFunc;
1.103 + pf->PushCell(((cell_t) ((cell_t *) elem1 - g_SortInfoADT.array_base)) / g_SortInfoADT.array_bsize);
1.104 + pf->PushCell(((cell_t) ((cell_t *) elem2 - g_SortInfoADT.array_base)) / g_SortInfoADT.array_bsize);
1.105 + pf->PushCell(g_SortInfoADT.array_hndl);
1.106 + pf->PushCell(g_SortInfoADT.hndl);
1.107 + pf->Execute(&result);
1.108 +
1.109 + return result;
1.110 +}
1.111 +
1.112 +static cell_t sm_SortADTArrayCustom(IPluginContext *pContext, const cell_t *params)
1.113 +{
1.114 + CellArray *cArray;
1.115 + HandleError err;
1.116 + HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent);
1.117 +
1.118 + if ((err = g_HandleSys.ReadHandle(params[1], htCellArray, &sec, (void **)&cArray))
1.119 + != HandleError_None)
1.120 + {
1.121 + return pContext->ThrowNativeError("Invalid Handle %x (error: %d)", params[1], err);
1.122 + }
1.123 +
1.124 + IPluginFunction *pFunction = pContext->GetFunctionById(params[2]);
1.125 + if (!pFunction)
1.126 + {
1.127 + return pContext->ThrowNativeError("Function %x is not a valid function", params[2]);
1.128 + }
1.129 +
1.130 + size_t arraysize = cArray->size();
1.131 + size_t blocksize = cArray->blocksize();
1.132 + cell_t *array = cArray->base();
1.133 +
1.134 + sort_infoADT oldinfo = g_SortInfoADT;
1.135 +
1.136 + g_SortInfoADT.pFunc = pFunction;
1.137 + g_SortInfoADT.array_base = array;
1.138 + g_SortInfoADT.array_bsize = (cell_t) blocksize;
1.139 + g_SortInfoADT.array_hndl = params[1];
1.140 + g_SortInfoADT.hndl = params[3];
1.141 +
1.142 + qsort(array, arraysize, blocksize * sizeof(cell_t), sort_adtarray_custom);
1.143 +
1.144 + g_SortInfoADT = oldinfo;
1.145 +
1.146 + return 1;
1.147 +}
1.148 +
1.149 REGISTER_NATIVES(sortNatives)
1.150 {
1.151 {"SortIntegers", sm_SortIntegers},
1.152 @@ -380,5 +515,7 @@
1.153 {"SortStrings", sm_SortStrings},
1.154 {"SortCustom1D", sm_SortCustom1D},
1.155 {"SortCustom2D", sm_SortCustom2D},
1.156 + {"SortADTArray", sm_SortADTArray},
1.157 + {"SortADTArrayCustom", sm_SortADTArrayCustom},
1.158 {NULL, NULL},
1.159 };