00001
00009 #define DKUTIL_C_ARRAY_ONEBYONE_C
00010 #include "dkcArrayOneByOne.h"
00011 #include "dkcStdio.h"
00012
00013
00014 DKC_ARRAY_ONEBYONE * WINAPI dkcAllocArrayOneByOne(BYTE flag,size_t offset,size_t num,size_t ext_size){
00015 DKC_ARRAY_ONEBYONE *p;
00016 int i;
00017
00018 p = (DKC_ARRAY_ONEBYONE *)dkcAllocate(sizeof(DKC_ARRAY_ONEBYONE));
00019 if(NULL==p){
00020 return NULL;
00021 }
00022
00023
00024 p->mBuff = dkcAllocBuffer(NULL,offset * num);
00025 if(NULL==p->mBuff){
00026 goto Error;
00027 }
00028
00029
00030 p->mStack = dkcAllocStack(num,sizeof(int));
00031 if(NULL==p->mStack){
00032 goto Error;
00033 }
00034
00035
00036 for(i = num - 1; i>=0 ;i--){
00037 dkcStackPush(p->mStack,(const void *)&i);
00038 }
00039
00040 p->mOffset = offset;
00041 p->mNum = num;
00042 p->mFlag = flag;
00043 p->mExtNum = ext_size;
00044
00045 return p;
00046
00047
00048
00049 Error:
00050 dkcFreeStack(&(p->mStack));
00051 dkcFreeBuffer(&(p->mBuff));
00052 dkcFree((void **)&p);
00053 return NULL;
00054 }
00055
00056
00057 DKC_ARRAY_ONEBYONE * WINAPI dkcAllocArrayOneByOneStatic(size_t offset,size_t num){
00058 return dkcAllocArrayOneByOne( edkcArrayOneByOneStatic, offset , num , 0 );
00059 }
00060
00061 DKC_ARRAY_ONEBYONE * WINAPI dkcAllocArrayOneByOneDynamic(size_t offset,size_t num,size_t ext_num){
00062 return dkcAllocArrayOneByOne( edkcArrayOneByOneDynamic, offset,num,ext_num);
00063 }
00064
00065 int WINAPI dkcFreeArrayOneByOne(DKC_ARRAY_ONEBYONE **p){
00066 if(NULL==p || NULL==*p){
00067 return edk_FAILED;
00068 }
00069 dkcFreeStack(& ( (*p)->mStack ) );
00070 dkcFreeBuffer(& ( (*p)->mBuff ) );
00071 return dkcFree((void **)p);
00072 }
00073
00074
00076 static int BufferResize(DKC_ARRAY_ONEBYONE *p){
00077
00078 size_t tsize;
00079 size_t temp;
00080 int i;
00081
00082 tsize = dkcBufferSize(p->mBuff);
00083
00084
00085
00086 if(p->mNum + p->mExtNum > INT_MAX){
00087 return edk_FAILED;
00088 }
00089
00090
00091 temp = (p->mExtNum * p->mOffset) + tsize;
00092
00093 dkcmFORCE_NOT_ASSERT(
00094 DKUTIL_FAILED(dkcBufferResize(p->mBuff,temp))
00095 );
00096
00097
00098
00099
00100
00101 tsize = p->mExtNum;
00102 for(i = (int)(p->mNum + p->mExtNum - 1); i >= (int)tsize; i--)
00103 {
00104 dkcStackDynamicPush(p->mStack,&i);
00105 }
00106
00107 p->mNum += p->mExtNum;
00108
00109 return edk_SUCCEEDED;
00110
00111 }
00112
00113 static size_t setData(DKC_ARRAY_ONEBYONE *p,const void *data,size_t size){
00114 int id;
00115
00116 dkcStackTop(p->mStack,&id);
00117
00118 dkcmFORCE_NOT_ASSERT(
00119 DKUTIL_FAILED(
00120 dkcBufferSetOffset(p->mBuff,data,size,p->mOffset * id)
00121 )
00122 );
00123
00124 dkcStackPop(p->mStack);
00125 return id;
00126 }
00127
00129 int WINAPI dkcArrayOneByOnePushSafe(DKC_ARRAY_ONEBYONE *p,const void *data,size_t size){
00130 size_t r;
00131
00132 if(size > p->mOffset){
00133 return -1;
00134 }
00135
00136
00137
00138 switch(p->mFlag)
00139 {
00140 case edkcArrayOneByOneStatic:
00141 if(dkcStackIsEmpty(p->mStack)){
00142 return -1;
00143 }
00144
00145 break;
00146 case edkcArrayOneByOneDynamic:
00147 if(dkcStackIsEmpty(p->mStack))
00148 {
00149 if(DKUTIL_FAILED(BufferResize(p))){
00150 return -1;
00151 }
00152 }
00153
00154 break;
00155 }
00156
00157 r = setData(p,data,size);
00158
00159 return r;
00160
00161 }
00162
00163
00164 DKC_INLINE int WINAPI dkcArrayOneByOnePush(DKC_ARRAY_ONEBYONE *p,const void *data){
00165
00166 return dkcArrayOneByOnePushSafe(p,data,p->mOffset);
00167 }
00168
00172
00173 int WINAPI dkcArrayOneByOnePop(DKC_ARRAY_ONEBYONE *p,int id){
00174
00175 #ifdef DEBUG
00176 int i;
00177
00178 int *ch = (int *)p->mStack->mBuffer;
00179 size_t se = p->mStack->mCount;
00180 for(i=0;i<(int)se;i++){
00181 dkcmFORCE_NOT_ASSERT(ch[i] == id);
00182 }
00183 #endif
00184 return dkcStackDynamicPush(p->mStack,&id);
00185 }
00186
00187
00188 int WINAPI dkcArrayOneByOneReference(DKC_ARRAY_ONEBYONE *p,int id,void *pp){
00189 return dkcBufferGetOffset(p->mBuff,pp,p->mOffset,p->mOffset * id);
00190 }
00191
00192
00193 size_t WINAPI dkcArrayOneByOneSize(DKC_ARRAY_ONEBYONE *p){
00194 dkcmNOT_ASSERT(p->mNum < dkcStackSize(p->mStack));
00195 return p->mNum - dkcStackSize(p->mStack);
00196 }
00197 size_t WINAPI dkcArrayOneByOneCapacity(DKC_ARRAY_ONEBYONE *p){
00198 return p->mNum;
00199 }
00200
00201
00202 size_t WINAPI dkcArrayOneByOneRestSize(DKC_ARRAY_ONEBYONE *p)
00203 {
00204 return dkcStackRestSize(p->mStack);
00205 }
00206
00207 size_t WINAPI dkcArrayOneByOneOffset(DKC_ARRAY_ONEBYONE *p){
00208 return p->mOffset;
00209 }