-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdkcArrayOneByOne.c
More file actions
209 lines (153 loc) · 4.06 KB
/
Copy pathdkcArrayOneByOne.c
File metadata and controls
209 lines (153 loc) · 4.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
/*!
@author d金魚
@file dkcArrayOneByOne.c
@brief 配列プールにO(1)でデータを入れて、参照IDを返すコンテナです。
@since 2004/08/22
*/
#define DKUTIL_C_ARRAY_ONEBYONE_C
#include "dkcArrayOneByOne.h"
#include "dkcStdio.h"
static DKC_ARRAY_ONEBYONE * WINAPI dkcAllocArrayOneByOne(BYTE flag,size_t offset,size_t num,size_t ext_size){
DKC_ARRAY_ONEBYONE *p;
int i;
p = (DKC_ARRAY_ONEBYONE *)dkcAllocate(sizeof(DKC_ARRAY_ONEBYONE));
if(NULL==p){
return NULL;
}
//offset * num個のバッファを確保
p->mBuff = dkcAllocBuffer(NULL,offset * num);
if(NULL==p->mBuff){
goto Error;
}
//num個のint用スタックを確保
p->mStack = dkcAllocStack(num,sizeof(int));
if(NULL==p->mStack){
goto Error;
}
//スタックを初期化 (最初の配列の方をスタックの最初の方にしたいので^^;
for(i = num - 1; i>=0 ;i--){
dkcStackPush(p->mStack,(const void *)&i);
}
p->mOffset = offset;
p->mNum = num;
p->mFlag = flag;
p->mExtNum = ext_size;
return p;
Error:
dkcFreeStack(&(p->mStack));
dkcFreeBuffer(&(p->mBuff));
dkcFree((void **)&p);
return NULL;
}
DKC_ARRAY_ONEBYONE * WINAPI dkcAllocArrayOneByOneStatic(size_t offset,size_t num){
return dkcAllocArrayOneByOne( edkcArrayOneByOneStatic, offset , num , 0 );
}
DKC_ARRAY_ONEBYONE * WINAPI dkcAllocArrayOneByOneDynamic(size_t offset,size_t num,size_t ext_num){
return dkcAllocArrayOneByOne( edkcArrayOneByOneDynamic, offset,num,ext_num);
}
int WINAPI dkcFreeArrayOneByOne(DKC_ARRAY_ONEBYONE **p){
if(NULL==p || NULL==*p){
return edk_FAILED;
}
dkcFreeStack(& ( (*p)->mStack ) );
dkcFreeBuffer(& ( (*p)->mBuff ) );
return dkcFree((void **)p);
}
///バッファをリサイズ。INT_MAX個以上の要素は挿入できないようになっている。
static int BufferResize(DKC_ARRAY_ONEBYONE *p){
size_t tsize;
size_t temp;
int i;
//保存しておく
tsize = dkcBufferSize(p->mBuff);
//length check
if(p->mNum + p->mExtNum > INT_MAX){
return edk_FAILED;
}
//バッファを拡張
temp = (p->mExtNum * p->mOffset) + tsize;
dkcmFORCE_NOT_ASSERT(
DKUTIL_FAILED(dkcBufferResize(p->mBuff,temp))
);
//このループになれていないからバグあるかも?
tsize = p->mExtNum;
for(i = (int)(p->mNum + p->mExtNum - 1); i >= (int)tsize; i--)
{
dkcStackDynamicPush(p->mStack,&i);
}
//全体数を更新
p->mNum += p->mExtNum;
return edk_SUCCEEDED;
}
static size_t setData(DKC_ARRAY_ONEBYONE *p,const void *data,size_t size){
int id;
dkcStackTop(p->mStack,&id);
dkcmFORCE_NOT_ASSERT(
DKUTIL_FAILED(
dkcBufferSetOffset(p->mBuff,data,size,p->mOffset * id)
)
);
dkcStackPop(p->mStack);
return id;
}
///@see dkcArrayOneByOnePush()の安全版
int WINAPI dkcArrayOneByOnePushSafe(DKC_ARRAY_ONEBYONE *p,const void *data,size_t size){
size_t r;
if(size > p->mOffset){
return -1;
}
switch(p->mFlag)
{
case edkcArrayOneByOneStatic:
if(dkcStackIsEmpty(p->mStack)){
return -1;
}
break;
case edkcArrayOneByOneDynamic:
if(dkcStackIsEmpty(p->mStack))
{//バッファ拡張処理
if(DKUTIL_FAILED(BufferResize(p))){
return -1;
}
}
break;
}//end of switch
r = setData(p,data,size);
return r;
}
DKC_INLINE int WINAPI dkcArrayOneByOnePush(DKC_ARRAY_ONEBYONE *p,const void *data){
return dkcArrayOneByOnePushSafe(p,data,p->mOffset);
}
/*!
@return enum edk_Resultのどれかを返す。
*/
///要素を削除する
int WINAPI dkcArrayOneByOnePop(DKC_ARRAY_ONEBYONE *p,int id){
#ifdef DEBUG
int i;
//重複チェックをしてみる。
int *ch = (int *)p->mStack->mBuffer;
size_t se = p->mStack->mCount;
for(i=0;i<(int)se;i++){
dkcmFORCE_NOT_ASSERT(ch[i] == id);
}
#endif
return dkcStackDynamicPush(p->mStack,&id);
}
int WINAPI dkcArrayOneByOneReference(DKC_ARRAY_ONEBYONE *p,int id,void *pp){
return dkcBufferGetOffset(p->mBuff,pp,p->mOffset,p->mOffset * id);
}
size_t WINAPI dkcArrayOneByOneSize(DKC_ARRAY_ONEBYONE *p){
dkcmNOT_ASSERT(p->mNum < dkcStackSize(p->mStack));
return p->mNum - dkcStackSize(p->mStack);
}
size_t WINAPI dkcArrayOneByOneCapacity(DKC_ARRAY_ONEBYONE *p){
return p->mNum;
}
size_t WINAPI dkcArrayOneByOneRestSize(DKC_ARRAY_ONEBYONE *p)
{
return dkcStackRestSize(p->mStack);
}
size_t WINAPI dkcArrayOneByOneOffset(DKC_ARRAY_ONEBYONE *p){
return p->mOffset;
}