2 Copyright (C) 2005-2007 Tom Beaumont
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include <SDL/SDL_endian.h>
22 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
26 #define SWAP16(X) SDL_Swap16(X)
27 #define SWAP32(X) SDL_Swap32(X)
32 /* Is it *NOT* save to interpret a byte stream as list of Entries!
33 * The alignment could increase the Entry size on some systems without attribute.
35 * It works on: i386, amd64, mips o32 ABI, powerPC
36 * Maybe it's also compiler dependent ...
38 * See also http://c-faq.com/struct/padding.html,
39 * http://c-faq.com/strangeprob/ptralign.html and Debian bug #442854
40 * (Need to refer to a C FAQ in a (so called) C++ program, argh ...)
45 // an array of size 1 (no char* pointer!) is saved after len,
46 // accessing name[0] should (but doesn't always) fit the first byte after len
47 // See e.g. http://c-faq.com/aryptr/index.html
52 return (Entry
*)((char*)name
+ len
);
65 return len
- strlen(name
) - 1;
69 __attribute__ ((__packed__
));
70 int static_assert1
[sizeof(Entry
)==5 ? 0 : -1];
72 int static_assert1
[sizeof(Entry
)<=8 ? 0 : -1];
79 PackFile1() : numfiles(0), e(0), data(0)
82 Entry
* Find(const char* name
)
84 if (numfiles
==0) return 0;
88 const int mid
= (a
+b
)>>1;
89 int diff
= strcmp(name
, e
[mid
]->name
);
102 if (numfiles
|| e
|| data
)
103 FATAL("Calling Packfile1::Read when already initialised.");
106 fseek(f
, -(int)sizeof(size
), SEEK_END
);
107 int end_offset
= ftell(f
);
108 fread(&size
, sizeof(size
), 1, f
);
110 fseek(f
, end_offset
- size
, SEEK_SET
);
113 char* data_end
= (char*)data
+ size
;
114 fread(data
, 1, size
, f
);
117 Entry
* i
= (Entry
*)data
;
118 while ((void*)i
< data_end
)
121 int32_t *data_length
= (int32_t*)i
;
122 *data_length
= SWAP32(*data_length
);
126 e
= new Entry
* [numfiles
]; // CHECKME: where to delete?
129 for (int j
=0; j
<numfiles
; j
++, i
= i
->GetNext())