Adding patch_seam q3map2 regression test. Probably not fixable, but good to
[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 file name (missing.h) is a legacy 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
45 #include <windows.h>
46 #include <direct.h>
47 #include <io.h>
48 #include <sys/types.h>
49 #include <sys/stat.h>
50
51 #define R_OK 04
52
53 #else // !_WIN32
54
55 // LZ: very ugly hacks
56 inline int GetLastError() { return 0; };
57
58 // temp stuff
59 inline int GetPrivateProfileInt(char* a, char* b, int i, char* c) { return i; };
60 #define VERIFY(a) a;
61 int GetFullPathName(const char *lpFileName, int nBufferLength, char *lpBuffer, char **lpFilePart);
62
63 #ifndef APIENTRY
64 #define APIENTRY
65 #endif
66
67 int MemorySize(void *ptr);
68 #define _msize MemorySize
69
70 #define MK_LBUTTON          0x0001
71 #define MK_RBUTTON          0x0002
72 #define MK_SHIFT            0x0004
73 #define MK_CONTROL          0x0008
74 #define MK_MBUTTON          0x0010
75
76 #include <dirent.h>
77 #include <iostream>
78
79 #endif
80
81 #define CString Str
82 #include "str.h"
83
84 class CPtrArray
85 {
86 public:
87   CPtrArray ()
88   { m_ptrs = g_ptr_array_new (); };
89   virtual ~CPtrArray ()
90   { g_ptr_array_free (m_ptrs, TRUE); };
91   
92   void* operator[](int i) const
93   { return g_ptr_array_index (m_ptrs,i); };
94   void* GetAt(int i) const
95   { return g_ptr_array_index (m_ptrs,i); };
96   int GetSize () const
97   { return m_ptrs->len; };
98   void Add (void* ptr)
99   { g_ptr_array_add (m_ptrs, ptr); };
100   void RemoveAll ()
101   { g_ptr_array_set_size (m_ptrs, 0); };
102   void RemoveAt(int index, int count = 1)
103   {
104     if ((index < 0) || (count < 0) || (count + index > (int)m_ptrs->len))
105       return;
106     for (; count > 0; count--)
107       g_ptr_array_remove_index (m_ptrs, index);
108   }
109   void InsertAt(int nStartIndex, CPtrArray* pNewArray)
110   {
111     for (int i = 0; i < pNewArray->GetSize(); i++)
112       InsertAt(nStartIndex+i, pNewArray->GetAt(i));
113   }
114   void InsertAt(int nIndex, void* newElement, int nCount = 1)
115   {
116     if ((guint32)nIndex >= m_ptrs->len)
117     {
118       g_ptr_array_set_size (m_ptrs, nIndex + nCount);  // grow so nIndex is valid
119     }
120     else
121     {
122       // inserting in the middle of the array
123       int nOldSize = m_ptrs->len;
124       g_ptr_array_set_size (m_ptrs, m_ptrs->len + nCount);
125       // shift old data up to fill gap
126       memmove(&m_ptrs->pdata[nIndex+nCount], &m_ptrs->pdata[nIndex],
127         (nOldSize-nIndex) * sizeof(gpointer));
128       
129       memset(&m_ptrs->pdata[nIndex], 0, nCount * sizeof(gpointer));
130     }
131     
132     // insert new value in the gap
133     while (nCount--)
134       m_ptrs->pdata[nIndex++] = newElement;
135   }
136   void Copy(const CPtrArray& src)
137   {
138     g_ptr_array_set_size (m_ptrs, src.m_ptrs->len);
139     memcpy (m_ptrs->pdata, src.m_ptrs->pdata, m_ptrs->len*sizeof(gpointer));
140   }
141   
142 protected:
143   GPtrArray* m_ptrs;
144 };
145
146 typedef struct stringmap_s
147 {
148   char* key;
149   char* value;
150 } stringmap_t;
151
152 class CMapStringToString
153 {
154 public:
155   CMapStringToString ()
156   { m_map = g_ptr_array_new (); };
157   ~CMapStringToString ()
158   {
159     for (guint32 i = 0; i < m_map->len; i++)
160       FreeElement ((stringmap_t*)g_ptr_array_index (m_map,i));
161     g_ptr_array_set_size (m_map, 0);
162     g_ptr_array_free (m_map, TRUE);
163   };
164   void SetAt(char* key, char* newValue)
165   {
166     for (guint32 i = 0; i < m_map->len; i++)
167     {
168       stringmap_t* entry = (stringmap_t*)g_ptr_array_index (m_map,i);
169       if (strcmp (entry->key, key) == 0)
170       {
171         g_free (entry->value);
172         entry->value = g_strdup (newValue);
173         return;
174       }
175     }
176     stringmap_t* entry = (stringmap_t*)g_malloc (sizeof (stringmap_t));
177     entry->key = g_strdup (key);
178     entry->value = g_strdup (newValue);
179     g_ptr_array_add (m_map, entry);
180   }
181   
182   bool Lookup(const char* key, CString& rValue) const
183   {
184     for (guint32 i = 0; i < m_map->len; i++)
185     {
186       stringmap_t* entry = (stringmap_t*)g_ptr_array_index (m_map,i);
187       if (strcmp (entry->key, key) == 0)
188       {
189         rValue = entry->value;
190         return true;
191       }
192     }
193     return false;
194   }
195   
196 protected:
197   GPtrArray* m_map;
198   
199   void FreeElement(stringmap_t* elem)
200   { 
201     g_free (elem->key);
202     g_free (elem->value);
203     g_free (elem);
204   };
205 };
206
207 class FindFiles {
208 public:
209         FindFiles( const char *directory );
210         ~FindFiles();
211
212         const char* NextFile();
213 private:
214 #ifdef _WIN32
215         Str                             directory;
216         HANDLE                  findHandle;
217         WIN32_FIND_DATA findFileData;
218 #else
219         DIR                             *findHandle;
220 #endif
221 };
222
223 bool CopyTree( const char* source, const char* dest );
224
225 typedef enum {
226         PATH_FAIL,              // stat call failed (does not exist is likely)
227         PATH_DIRECTORY,
228         PATH_FILE
229 } EPathCheck;
230
231 // check a path for existence, return directory / file
232 EPathCheck CheckFile( const char *path );
233
234 bool radCreateDirectory( const char *directory );
235 bool radCopyFile( const char *lpExistingFileName, const char *lpNewFileName );
236
237 #endif // _MISSING_H_