1 /***************************************************************************
3 BetterString.mcc - A better String gadget MUI Custom Class
4 Copyright (C) 1997-2000 Allan Odgaard
5 Copyright (C) 2005-2013 by BetterString.mcc Open Source Team
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 BetterString class Support Site: http://www.sf.net/projects/bstring-mcc/
21 ***************************************************************************/
25 #include <proto/exec.h>
31 static APTR sharedPool
;
32 #if !defined(__amigaos4__) && !defined(__MORPHOS__)
33 static struct SignalSemaphore sharedPoolSema
;
36 BOOL
CreateSharedPool(void)
42 #if defined(__amigaos4__)
43 sharedPool
= AllocSysObjectTags(ASOT_MEMPOOL
, ASOPOOL_MFlags
, MEMF_SHARED
,
45 ASOPOOL_Threshold
, 256,
46 ASOPOOL_Name
, "BetterString.mcc shared pool",
47 ASOPOOL_Protected
, TRUE
,
48 ASOPOOL_LockMem
, FALSE
,
50 #elif defined(__MORPHOS__)
51 sharedPool
= CreatePool(MEMF_SEM_PROTECTED
, 512, 256);
53 sharedPool
= CreatePool(MEMF_ANY
, 512, 256);
54 memset(&sharedPoolSema
, 0, sizeof(sharedPoolSema
));
55 InitSemaphore(&sharedPoolSema
);
58 if(sharedPool
!= NULL
)
65 void DeleteSharedPool(void)
69 if(sharedPool
!= NULL
)
71 #if defined(__amigaos4__)
72 FreeSysObject(ASOT_MEMPOOL
, sharedPool
);
74 DeletePool(sharedPool
);
82 #if defined(__amigaos3__)
83 static APTR
AllocVecPooled(APTR poolHeader
, ULONG memSize
)
89 // add the number of bytes used to store the size information
90 memSize
+= sizeof(ULONG
);
92 // allocate memory from the pool
93 if((memory
= (ULONG
*)AllocPooled(poolHeader
, memSize
)) != NULL
)
95 // and finally store the size of the memory block, including the size itself
104 APTR
SharedPoolAlloc(ULONG length
)
110 #if !defined(__amigaos4__) && !defined(__MORPHOS__)
111 ObtainSemaphore(&sharedPoolSema
);
114 mem
= AllocVecPooled(sharedPool
, length
);
116 #if !defined(__amigaos4__) && !defined(__MORPHOS__)
117 ReleaseSemaphore(&sharedPoolSema
);
124 #if defined(__amigaos3__)
125 static void FreeVecPooled(APTR poolHeader
, APTR memory
)
127 ULONG
*mem
= (ULONG
*)memory
;
132 // skip back over the stored size information
135 // an return the memory block to the pool
136 FreePooled(poolHeader
, mem
, memSize
);
142 void SharedPoolFree(APTR mem
)
146 #if !defined(__amigaos4__) && !defined(__MORPHOS__)
147 ObtainSemaphore(&sharedPoolSema
);
150 FreeVecPooled(sharedPool
, mem
);
152 #if !defined(__amigaos4__) && !defined(__MORPHOS__)
153 ReleaseSemaphore(&sharedPoolSema
);
165 #define STR_TO_CSTR(str) (struct ContentString *)(((size_t)(str)) - sizeof(struct ContentString))
166 #define CSTR_TO_STR(cstr) (&(cstr)->string[0])
168 static struct ContentString
*AllocContentStringInternal(ULONG size
)
170 struct ContentString
*cstr
;
174 if((cstr
= SharedPoolAlloc(sizeof(*cstr
) + size
)) != NULL
)
177 cstr
->string
[0] = '\0';
184 char *AllocContentString(ULONG size
)
186 struct ContentString
*cstr
;
191 if((cstr
= AllocContentStringInternal(size
)) != NULL
)
193 result
= CSTR_TO_STR(cstr
);
200 void FreeContentString(char *str
)
206 struct ContentString
*cstr
= STR_TO_CSTR(str
);
208 SharedPoolFree(cstr
);
214 ULONG
ContentStringSize(char *str
)
222 struct ContentString
*cstr
= STR_TO_CSTR(str
);
231 BOOL
ExpandContentString(char **str
, ULONG extra
)
233 BOOL success
= FALSE
;
239 struct ContentString
*cstr
= STR_TO_CSTR(*str
);
240 ULONG newsize
= strlen(cstr
->string
) + 1 + extra
;
242 // check if we have to expand our contents string
243 if(cstr
->size
< newsize
)
245 struct ContentString
*newcstr
;
247 // add another 32 bytes for less expansions in the future
249 if((newcstr
= AllocContentStringInternal(newsize
)) != NULL
)
251 strlcpy(newcstr
->string
, cstr
->string
, newsize
);
252 FreeContentString(*str
);
253 *str
= CSTR_TO_STR(newcstr
);
260 // no expansion necessary, instant success
266 // allocate a new content string
267 if((*str
= AllocContentString(extra
)) != NULL
)