298ef605b6bf3c99949e7e37c3734090c26c3125
[xonotic/netradiant.git] / libs / missing.h
1 /*
2 Copyright (c) 2001, Loki software, inc.
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without modification, 
6 are permitted provided that the following conditions are met:
7
8 Redistributions of source code must retain the above copyright notice, this list 
9 of conditions and the following disclaimer.
10
11 Redistributions in binary form must reproduce the above copyright notice, this
12 list of conditions and the following disclaimer in the documentation and/or
13 other materials provided with the distribution.
14
15 Neither the name of Loki software nor the names of its contributors may be used 
16 to endorse or promote products derived from this software without specific prior 
17 written permission. 
18
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' 
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
22 DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY 
23 DIRECT,INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
24 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
25 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 
26 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
27 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
28 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
29 */
30
31 #ifndef _MISSING_H_
32 #define _MISSING_H_
33
34 // NOTE TTimo
35 //   this goes along with str.h and provides various utility classes
36 //   and portability defines
37 //   the filename is a legecy issue, it would be better to clean that up
38 //   in a central 'portability' lib
39
40 #include <glib.h>
41 #include <string.h>
42
43 #ifdef _WIN32
44 #include <direct.h>
45 #include <io.h>
46
47 #define MyCopyFile(a,b) CopyFile(a,b,FALSE)
48
49 #define S_ISDIR(mode) (mode & _S_IFDIR)
50 #define R_OK 04
51 #define mymkdir(a,b) _mkdir(a)
52
53 #else
54
55 #define MyCopyFile CopyFile
56 #define mymkdir(a,b) mkdir(a,b)
57
58 #endif
59
60 #ifndef _WIN32
61
62 // LZ: very ugly hacks
63 inline int GetLastError () { return 0; };
64
65 // temp stuff
66 inline int GetPrivateProfileInt(char* a, char* b, int i, char* c) { return i; };
67 #define VERIFY(a) a;
68 int GetFullPathName(const char *lpFileName, int nBufferLength, char *lpBuffer, char **lpFilePart);
69 bool CopyFile(const char *lpExistingFileName, const char *lpNewFileName);
70 bool CopyTree( const char* source, const char* dest );
71
72 #ifndef APIENTRY
73 #define APIENTRY
74 #endif
75
76 int MemorySize(void *ptr);
77 #define _msize MemorySize
78
79 #define MK_LBUTTON          0x0001
80 #define MK_RBUTTON          0x0002
81 #define MK_SHIFT            0x0004
82 #define MK_CONTROL          0x0008
83 #define MK_MBUTTON          0x0010
84
85 #endif
86
87 #define CString Str
88 #include "str.h"
89
90 class CPtrArray
91 {
92 public:
93   CPtrArray ()
94   { m_ptrs = g_ptr_array_new (); };
95   virtual ~CPtrArray ()
96   { g_ptr_array_free (m_ptrs, TRUE); };
97   
98   void* operator[](int i) const
99   { return g_ptr_array_index (m_ptrs,i); };
100   void* GetAt(int i) const
101   { return g_ptr_array_index (m_ptrs,i); };
102   int GetSize () const
103   { return m_ptrs->len; };
104   void Add (void* ptr)
105   { g_ptr_array_add (m_ptrs, ptr); };
106   void RemoveAll ()
107   { g_ptr_array_set_size (m_ptrs, 0); };
108   void RemoveAt(int index, int count = 1)
109   {
110     if ((index < 0) || (count < 0) || (count + index > (int)m_ptrs->len))
111       return;
112     for (; count > 0; count--)
113       g_ptr_array_remove_index (m_ptrs, index);
114   }
115   void InsertAt(int nStartIndex, CPtrArray* pNewArray)
116   {
117     for (int i = 0; i < pNewArray->GetSize(); i++)
118       InsertAt(nStartIndex+i, pNewArray->GetAt(i));
119   }
120   void InsertAt(int nIndex, void* newElement, int nCount = 1)
121   {
122     if ((guint32)nIndex >= m_ptrs->len)
123     {
124       g_ptr_array_set_size (m_ptrs, nIndex + nCount);  // grow so nIndex is valid
125     }
126     else
127     {
128       // inserting in the middle of the array
129       int nOldSize = m_ptrs->len;
130       g_ptr_array_set_size (m_ptrs, m_ptrs->len + nCount);
131       // shift old data up to fill gap
132       memmove(&m_ptrs->pdata[nIndex+nCount], &m_ptrs->pdata[nIndex],
133         (nOldSize-nIndex) * sizeof(gpointer));
134       
135       memset(&m_ptrs->pdata[nIndex], 0, nCount * sizeof(gpointer));
136     }
137     
138     // insert new value in the gap
139     while (nCount--)
140       m_ptrs->pdata[nIndex++] = newElement;
141   }
142   void Copy(const CPtrArray& src)
143   {
144     g_ptr_array_set_size (m_ptrs, src.m_ptrs->len);
145     memcpy (m_ptrs->pdata, src.m_ptrs->pdata, m_ptrs->len*sizeof(gpointer));
146   }
147   
148 protected:
149   GPtrArray* m_ptrs;
150 };
151
152 typedef struct stringmap_s
153 {
154   char* key;
155   char* value;
156 } stringmap_t;
157
158 class CMapStringToString
159 {
160 public:
161   CMapStringToString ()
162   { m_map = g_ptr_array_new (); };
163   ~CMapStringToString ()
164   {
165     for (guint32 i = 0; i < m_map->len; i++)
166       FreeElement ((stringmap_t*)g_ptr_array_index (m_map,i));
167     g_ptr_array_set_size (m_map, 0);
168     g_ptr_array_free (m_map, TRUE);
169   };
170   void SetAt(char* key, char* newValue)
171   {
172     for (guint32 i = 0; i < m_map->len; i++)
173     {
174       stringmap_t* entry = (stringmap_t*)g_ptr_array_index (m_map,i);
175       if (strcmp (entry->key, key) == 0)
176       {
177         g_free (entry->value);
178         entry->value = g_strdup (newValue);
179         return;
180       }
181     }
182     stringmap_t* entry = (stringmap_t*)g_malloc (sizeof (stringmap_t));
183     entry->key = g_strdup (key);
184     entry->value = g_strdup (newValue);
185     g_ptr_array_add (m_map, entry);
186   }
187   
188   bool Lookup(const char* key, CString& rValue) const
189   {
190     for (guint32 i = 0; i < m_map->len; i++)
191     {
192       stringmap_t* entry = (stringmap_t*)g_ptr_array_index (m_map,i);
193       if (strcmp (entry->key, key) == 0)
194       {
195         rValue = entry->value;
196         return true;
197       }
198     }
199     return false;
200   }
201   
202 protected:
203   GPtrArray* m_map;
204   
205   void FreeElement(stringmap_t* elem)
206   { 
207     g_free (elem->key);
208     g_free (elem->value);
209     g_free (elem);
210   };
211 };
212
213 #endif // _MISSING_H_