00001
00035 #define DKUTIL_C_BLOCKSORT_C
00036 #include "dkcBlockSort.h"
00037
00038
00039 #define DEBUG_BSE
00040
00041 #define DBSE_PRINTF printf
00042
00043
00044 static int bs_insertion_sort_to_table(BYTE *rotabuff,
00045 size_t cycle,size_t len,
00046 BYTE **tablework)
00047 {
00048 size_t i,j;
00049
00050 BYTE *t;
00051 for( i = 0; i < cycle;i++ ){
00052 tablework[i] = (BYTE *)&rotabuff[i];
00053 }
00054 for( i = 1;i < cycle;i++)
00055 {
00056 t = tablework[i];
00057 for( j = i - 1;j >= 0 && j != UINT_MAX && memcmp( t,tablework[j],len) < 0;j--)
00058 {
00059
00060 tablework[j + 1] = tablework[j];
00061
00062 }
00063 tablework[j + 1] = t;
00064 }
00065 return edk_SUCCEEDED;
00066 }
00067
00068 static void free_table2d(BYTE **table2d,size_t table_height_num){
00069 size_t i;
00070
00071 if(table2d){
00072 for(i = 0;i<table_height_num;i++){
00073 if(NULL != table2d[i]){
00074 free(table2d[i]);
00075 }
00076 }
00077 free((void *)table2d);
00078 }
00079
00080 }
00081
00096 static BYTE **alloc_table2d(size_t width,size_t height)
00097 {
00098 size_t i,t;
00099 BYTE **table2d = (BYTE **)malloc(height);
00100
00101 if(NULL==table2d){
00102 goto Error;
00103 }
00104 memset(table2d,(int)NULL,height);
00105
00106 t = height / sizeof(BYTE *);
00107
00108 for(i=0;i<t;i++){
00109 table2d[i] = (BYTE *)malloc(width);
00110 if(NULL==table2d[i]){
00111 goto Error;
00112 }
00113 }
00114
00115 return table2d;
00116 Error:
00117 free_table2d(table2d,width);
00118 return NULL;
00119 }
00120
00121
00122
00123 #if 0
00124
00129 static int WINAPI bse_dc_sort_lead2byte(size_t num, const BYTE *a, BYTE **b)
00130 {
00131 int i, x;
00132 size_t ii,temp;
00133 BYTE *begin_offset = a[0];
00134
00135
00136
00137 for (ii = 0; ii < num; ii++){
00138 temp = (a[i] << 8)
00139 count[ ]++;
00140 }
00141
00142 for (i = 1; i <= Max_ - Min_; i++){
00143
00144 count[i] = (char)(count[i] + count[i - 1]);
00145 }
00146 for (i = num - 1; i >= 0; i--) {
00147 x = a[i] - Min_; b[--count[x]] = a[i];
00148 }
00149 dkcFree((void **)&count);
00150 return edk_SUCCEEDED;
00151
00152
00153 }
00154
00155 static int bse_logic01_helper(void *dest,size_t dsize){
00156 BYTE *buff = NULL,rotabuff = NULL;
00157 size_t buffsize = dsize,rotasize= dsize * 2;
00158 BYTE **table2d = NULL;
00159 size_t table_width = dsize,table_height = dsize;
00160
00161 BYTE table_init_flag = FALSE;
00162
00163 int r = edk_OutOfMemory;
00164
00165 buff = malloc(buffsize);
00166 if(NULL==buff){
00167 return r;
00168 }
00169
00170 rotabuff = malloc(rotasize);
00171 if(NULL==rotabuff){
00172 goto END;
00173 }
00174
00175 table2d = malloc(table_height);
00176 if(NULL==table2d){
00177 goto END;
00178 }
00179 memset(table2d,(int)NULL,table_height);
00180
00181 table_init_flag = TRUE;
00182
00183 for(i=0;i<table_height;i++){
00184 table2d[i] = malloc(table_width);
00185 if(NULL==table2d[i]){
00186 goto END;
00187 }
00188 }
00189
00190
00191
00192
00193 r = bse_logic01(
00194 dest,dsize,
00195 buff,buffsize,
00196 rotabuff,rotasize,
00197 sortwork,sortworksize,
00198 table2d,table_width,table_height
00199 );
00200 END:
00201 if(table2d){
00202 if(table_init_flag){
00203 for(i = 0;i<table_height;i++){
00204 if(NULL != table2d[i]){
00205 free(table2d[i]);
00206 }
00207 }
00208 }
00209 free((void *)table2d);
00210 }
00211 if(rotabuff){free(rotabuff);}
00212 if(buff){free(buff);}
00213
00214
00215
00216
00217
00218 return r;
00219 }
00220
00221
00222
00223
00224
00225
00227 static int bse_distcount1_to_table( size_t *countbuff,size_t countsize,
00228 BYTE **table2dwork,size_t table_width_size)
00229 {
00230 size_t temp,i;
00231 size_t num = table_width_size;
00232 dkcmASSERT("だめだめ");
00233
00234 for(i = 0;i<num;i++){
00235 # ifdef DEBUG
00236 temp = buff[i];
00237 countbuff[temp]++;
00238 # else
00239 countbuff[ buff[ i ] ]++;
00240 # endif
00241 }
00242
00243 for (i = 1; i <= num; i++){
00244
00245 countbuff[i] = (countbuff[i] + countbuff[i - 1]);
00246 }
00247 for (i = num - 1; i >= 0; i--) {
00248
00249 temp = buff[i];
00250 table2dwork[--countbuff[ temp ]] = buff[i];
00251 }
00252 }
00253
00254 static int bse_distcount2_to_table(size_t *countbuff,size_t countsize,
00255 BYTE **table2dwork,size_t table_width_size,
00256 BYTE **get_result)
00257 {
00258 size_t i;
00259 size_t temp;
00260
00261 if(table_widht_size == 1){
00262 return bse_distcount1_to_table(countbuff,countsize,table2dwork,table_width_size);
00263 }else if(table_width_size == 0){
00264 return edk_FAILED;
00265 }
00266
00267
00268 # define BSE_GET_VALUE(i) ((table2dwork[(i)] << 8) + table2dwork[(i) + 1])
00269
00270
00271 for(i = 0;i<buffsize;i++){
00272 # ifdef DEBUG
00273 temp = (table2dwork[i] << 8) + table2dwork[i + 1];
00274 countbuff[temp]++;
00275 # else
00276 countbuff[ BSE_GET_VALUE(i) ]++;
00277 # endif
00278 }
00279
00280 for (i = 1; i <= buffsize; i++){
00281
00282 countbuff[i] = (countbuff[i] + countbuff[i - 1]);
00283 }
00284 for (i = num - 1; i >= 0; i--) {
00285
00286
00287 temp = BSE_GET_VALUE(i);
00288 get_result[--countbuff[ x ] ] = table2dwork[i]
00289 }
00290
00291 return edk_SUCCEEDED;
00292
00293 # undef BSE_GET_VALUE
00294 }
00295
00296
00297 static int bse_ternary_qsort_after_distcuont2_to_table
00298
00306
00307
00308 static int bse_distcount2_ternary_qsort_to_table(
00309 size_t *countbuff,size_t countsize,
00310 BYTE **table2dwork,size_t table_width_size,
00311 BYTE **get_result)
00312 {
00313 size_t i;
00314 size_t temp;
00315 int r;
00316
00317
00318 switch(table_width_size){
00319 case 0:
00320 return edk_FAILED;
00321 case 1:
00322 return bse_distcount1_to_table(countbuff,countsize,table2dwork,table_width_size);
00323 case 2:
00324 return bse_distcount2_to_table(countbuff,coubtsize,table2dwork,table_width_size);
00325 default:
00326 break;
00327 }
00328
00329 r = bse_distcount2_to_table(countbuff,coubtsize,table2dwork,table_width_size)
00330
00331 if(DKUTIL_FAILED(r)){
00332 return r;
00333 }
00334
00335
00336
00337 return r;
00338 }
00339
00351 static int bse_logic01(BYTE *dest,size_t destsize,
00352 BYTE *buff,size_t buffsize,
00353 BYTE *rotabuff,size_t rotasize,
00354 size_t *countbuff,size_t countsize,
00355 BYTE **table2dwork,size_t table_width_size,size_t table_height_size)
00356 {
00357
00358 size_t i;
00359
00360 size_t temp = INT_MAX;
00361
00362 #ifdef DEBUG_BSE
00363 size_t ii = 0;
00364 #endif
00365
00366
00367 if( rotasize & 0x01){
00368 rotasize--;
00369 }
00370 if(buffsize > temp + 1){
00371
00372 return edk_ArgumentException;
00373 }
00374 if(rotasize < buffsize * 2){
00375 return edk_ArgumentException;
00376 }
00377 if(buffworksize < buffsize){
00378 return edk_ArgumentException;
00379 }
00380 if(destsize < buffsize){
00381 return edk_ArgumentException;
00382 }
00383 if(table_width_size != table_height_size){
00384 return edk_ArgumentException;
00385 }
00386 for(i=0;i<table_height_size;i++){
00387 if(table2dwork[i] == NULL){
00388 return edk_ArgumentException;
00389 }
00390 }
00391 if(countsize < 256 * 256){
00392 return edk_ArgumentException;
00393 }
00394
00395
00396
00397 memcpy(rotabuff,buff,buffsize);
00398 memcpy(rotabuff + buffsize,buff,buffsize);
00399
00400
00401
00402 #ifdef DEBUG_BSE
00403 DBSE_PRINTF("rotabuff:\t");
00404 for(i = 0;i<rotasize;i++){
00405 DBSE_PRINTF("%c",rotabuff[i]);
00406 }
00407 DBSE_PRINTF("\n");
00408 #endif
00409 temp = buffsize;
00410 for(i = 0;i<temp;i++)
00411 {
00412 memcpy(buffwork,rotabuff + i,buffsize);
00413
00414 # ifdef DEBUG_BSE
00415 DBSE_PRINTF("%d:\t",i);
00416 for(ii = 0;ii<buffsize;ii++){
00417 DBSE_PRINTF("%c",(char)buffwork[ii]);
00418 }
00419 DBSE_PRINTF("\t");
00420 # endif
00421
00422
00423 # ifdef DEBUG_BSE
00424 dkcRotateShiftRightMemory(dest,buffsize,i);
00425 for(ii = 0;ii<buffsize;ii++){
00426
00427 DBSE_PRINTF("%c",*(dest + i + buffsize - 1));
00428
00429 }
00430 DBSE_PRINTF("\n");
00431 # endif
00432
00433 }
00434 return edk_SUCCEEDED;
00435
00436 }
00437
00438 #endif
00439
00440 static int bse_target_to_table(void *buff,size_t buffsize,
00441 BYTE **table2d,size_t twidth,size_t theight)
00442 {
00443 size_t i;
00444 if(buffsize > twidth){
00445 return edk_ArgumentException;
00446 }
00447
00448 for(i = 0;i<theight;i++)
00449 {
00450 memcpy(table2d[i],buff,buffsize);
00451 dkcRotateShiftRightMemory(buff,buffsize,1);
00452 }
00453 return edk_SUCCEEDED;
00454 }
00455
00456 static int bse_sorted_table_to_data(BYTE *buff,size_t buffsize,BYTE *rotabuff,
00457 BYTE **table2d,size_t twidth,DKC_BLOCKSORT_INFO *pinfo)
00458 {
00459 size_t i;
00460 BYTE *pout = (BYTE *)buff;
00461 BYTE *pt;
00462 BOOL flag = FALSE;
00463
00464 if(buffsize < twidth){
00465 return edk_ArgumentException;
00466 }
00467
00468 for(i = 0;i<twidth;i++){
00469 pt = table2d[i];
00470 if(rotabuff == pt){
00471 pinfo->mOffset = i;
00472 flag = TRUE;
00473 }
00474 pout[i] = pt[twidth - 1];
00475 }
00476 pinfo->mResultPointer = buff;
00477
00478 if(flag){
00479 return edk_SUCCEEDED;
00480 }else{
00481 return edk_FAILED;
00482 }
00483 }
00484 typedef BYTE **pa_type;
00485
00486 static int bse_basic_logic(void *buff,size_t buffsize,DKC_BLOCKSORT_INFO *pinfo)
00487 {
00488 int r = edk_OutOfMemory;
00489 BYTE *rotabuff = NULL;
00490 size_t rotasize = buffsize * 2;
00491
00492
00493 BYTE **pp = (BYTE **)malloc(buffsize * sizeof(BYTE *));
00494 if(NULL==pp){
00495 goto END;
00496 }
00497
00498 rotabuff = (BYTE *)malloc(rotasize);
00499 if(!rotabuff){
00500 goto END;
00501 }
00502
00503
00504
00505 memcpy(rotabuff,buff,buffsize);
00506 memcpy(rotabuff + buffsize,buff,buffsize);
00507
00508
00509
00510
00511
00512
00513
00514
00515 r = bs_insertion_sort_to_table(rotabuff,buffsize,buffsize,pp);
00516
00517 if(DKUTIL_FAILED(r)){
00518 goto END;
00519 }
00520
00521 r = bse_sorted_table_to_data((BYTE *)buff,buffsize,(BYTE *)rotabuff,pp,buffsize,pinfo);
00522
00523 END:
00524
00525 if(rotabuff){
00526 free(rotabuff);
00527 }
00528 if(pp){
00529 free(pp);
00530
00531 }
00532 return r;
00533 }
00534
00535 static int bsd_basic_logic(void *buff,size_t buffsize,DKC_BLOCKSORT_INFO *pinfo)
00536 {
00537 size_t i,offset;
00538 BYTE *p,*pout;
00539 size_t ppsize = sizeof(BYTE *) * buffsize;
00540 BYTE **pp = NULL;
00541 int r = edk_OutOfMemory;
00542 BYTE *pwork = (BYTE *)malloc(buffsize);
00543
00544 if(NULL==pwork){
00545 goto END;
00546 }
00547 memcpy(pwork,buff,buffsize);
00548
00549
00550 pp = (BYTE **)malloc(ppsize);
00551 if(NULL==pp){
00552 goto END;
00553 }
00554
00555
00556 r = bs_insertion_sort_to_table((BYTE *)pwork,buffsize,1,pp);
00557 if(DKUTIL_FAILED(r)){
00558 goto END;
00559 }
00560
00561 offset = pinfo->mOffset;
00562 p = pp[offset];
00563 pout = (BYTE *)buff;
00564 for(i = 0;i<buffsize;i++)
00565 {
00566 pout[i] = *p;
00567
00568 offset = p - (BYTE *)pwork;
00569 p = pp[offset];
00570 }
00571
00572 END:
00573 if(pp){
00574 free(pp);
00575 }
00576 if(pwork){
00577 free(pwork);
00578 }
00579
00580 return r;
00581
00582 }
00583
00584 #define dkcfBSE_BASIC bse_basic_logic
00585
00586 #define dkcfBSE_NORMAL bse_logic01
00587
00588
00589 #define dkcfBSE_FAST bse_logic01
00590
00591 #define dkcfBSD_BASIC bsd_basic_logic
00592
00593
00594 int WINAPI dkcBlockSortEncode(void *buff,size_t buffsize,DKC_BLOCKSORT_INFO *p)
00595 {
00596 return dkcfBSE_BASIC(buff,buffsize,p);
00597 }
00598
00599 int WINAPI dkcBlockSortDecode(void *buff,size_t buffsize,DKC_BLOCKSORT_INFO *p){
00600 return dkcfBSD_BASIC(buff,buffsize,p);
00601 }