Main Page   Namespace List   Class Hierarchy   Compound List   File List   Compound Members   File Members  

datafile_writer.cpp

Go to the documentation of this file.
00001 /*
00002         ClanLib, the platform independent game SDK.
00003         This library is distributed under the GNU LIBRARY GENERAL PUBLIC
00004         LICENSE version 2. See COPYING for details. For a total list of
00005         contributers see CREDITS.
00006 
00007         $Id: datafile_writer.cpp,v 1.2 2000/07/15 15:45:50 starch Exp $
00008 
00009 */
00010 
00011 #include "Core/precomp.h"
00012 #include <stdio.h>
00013 #include <stdlib.h>
00014 #include <iostream>
00015 #include <string.h>
00016 
00017 #include <sys/types.h>
00018 #include <sys/stat.h>
00019 #include <fcntl.h>
00020 
00021 #ifdef WIN32
00022         #include <io.h>
00023 #else
00024         #include <unistd.h>
00025 #endif
00026 
00027 #include "datafile_writer.h"
00028 
00029 #ifndef WIN32
00030         #define OPEN_FLAGS       O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH
00031 #else
00032         #define OPEN_FLAGS       _O_RDWR | O_CREAT | O_TRUNC | O_BINARY, _S_IREAD | _S_IWRITE
00033 #endif
00034 
00035 /*********************************
00036  OutputSourceProvider_Datafile
00037 *********************************/
00038 
00039 OutputSourceProvider_Datafile::OutputSourceProvider_Datafile(const char *_filename)
00040 {
00041         filename = _filename;
00042         datafile_fd = open(filename, OPEN_FLAGS);
00043 
00044         int index_pos = -1;
00045         write(datafile_fd, datafile_id, strlen(datafile_id));
00046         write(datafile_fd, &index_pos, sizeof(int));
00047 }
00048 
00049 OutputSourceProvider_Datafile::~OutputSourceProvider_Datafile()
00050 {
00051         int index_pos = lseek(datafile_fd, 0, SEEK_CUR);
00052         int num_indexes = indexes.size();
00053 
00054         write(datafile_fd, &num_indexes, sizeof(int));
00055 
00056         for (
00057                 std::list<DatafileIndex*>::iterator it = indexes.begin();
00058                 it != indexes.end();
00059                 it++)
00060         {
00061                 int name_len = (*it)->name.get_length()+1;
00062                 write(datafile_fd, &name_len, sizeof(short));
00063                 write(datafile_fd, (*it)->name, name_len);
00064                 write(datafile_fd, &(*it)->pos, sizeof(int));
00065                 write(datafile_fd, &(*it)->size, sizeof(int));
00066         }
00067 
00068         lseek(datafile_fd, strlen(datafile_id), SEEK_SET);
00069         write(datafile_fd, &index_pos, sizeof(int));
00070 
00071         close(datafile_fd);
00072 }
00073 
00074 gzFile OutputSourceProvider_Datafile::create_index(const char *index)
00075 {
00076         indexes.push_back(
00077                 new DatafileIndex(
00078                         index,
00079                         lseek(datafile_fd, 0, SEEK_CUR)));
00080         return gzdopen(dup(datafile_fd), "w+b");
00081 }
00082 
00083 void OutputSourceProvider_Datafile::close_index(gzFile gz_fd, int size)
00084 {
00085         gzclose(gz_fd);
00086 //      indexes.get_last()->size = lseek(datafile_fd, 0, SEEK_CUR) - indexes.get_last()->pos;
00087 
00088         indexes.back()->size = size;
00089 /*
00090         std::cout << "Index written:" << std::endl;
00091         std::cout << "  name: " << indexes.get_last()->name << std::endl;
00092         std::cout << "  pos: " << indexes.get_last()->pos << std::endl;
00093         std::cout << "  size: " << indexes.get_last()->size << std::endl;
00094         std::cout << std::endl;
00095 */
00096 }
00097 
00098 CL_OutputSource *OutputSourceProvider_Datafile::open_source(const char *handle)
00099 {
00100         return new OutputSource_Datafile(handle, this);
00101 }
00102 
00103 CL_OutputSourceProvider *OutputSourceProvider_Datafile::clone()
00104 {
00105         return NULL;
00106 }
00107 
00108 /*************************
00109  OutputSource_Datafile
00110 *************************/
00111 
00112 OutputSource_Datafile::OutputSource_Datafile(
00113         const char *handle,
00114         OutputSourceProvider_Datafile *_provider)
00115 {
00116         provider = _provider;
00117         output_fd = provider->create_index(handle);
00118         pos = 0;
00119 }
00120 
00121 OutputSource_Datafile::~OutputSource_Datafile()
00122 {
00123         provider->close_index(output_fd, pos);
00124 }
00125 
00126 void OutputSource_Datafile::set_system_mode()
00127 {
00128         // muh
00129 }
00130 
00131 void OutputSource_Datafile::set_big_endian_mode()
00132 {
00133         // muh
00134 }
00135 
00136 void OutputSource_Datafile::set_little_endian_mode()
00137 {
00138         // muh
00139 }
00140 
00141 void OutputSource_Datafile::write_int32(int data)
00142 {
00143         write(&data, sizeof(int));
00144 }
00145 
00146 void OutputSource_Datafile::write_uint32(unsigned int data)
00147 {
00148         write(&data, sizeof(unsigned int));
00149 }
00150 
00151 void OutputSource_Datafile::write_short16(short data)
00152 {
00153         write(&data, sizeof(short));
00154 }
00155 
00156 void OutputSource_Datafile::write_ushort16(unsigned short data)
00157 {
00158         write(&data, sizeof(unsigned short));
00159 }
00160 
00161 void OutputSource_Datafile::write_char8(char data)
00162 {
00163         write(&data, sizeof(char));
00164 }
00165 
00166 void OutputSource_Datafile::write_uchar8(unsigned char data)
00167 {
00168         write(&data, sizeof(unsigned char));
00169 }
00170 
00171 void OutputSource_Datafile::write_float32(float data)
00172 {
00173         write(&data, sizeof(float));
00174 }
00175 
00176 int OutputSource_Datafile::write(const void *data, int size)
00177 {
00178         gzwrite(output_fd, (void *) data, size);
00179         pos += size;
00180         return size;
00181 }
00182 
00183 void OutputSource_Datafile::open()
00184 {
00185         // muh
00186 }
00187 
00188 void OutputSource_Datafile::close()
00189 {
00190         // muh
00191 }
00192 
00193 CL_OutputSource *OutputSource_Datafile::clone()
00194 {
00195         return NULL;
00196 }
00197 
00198 int OutputSource_Datafile::tell()
00199 {
00200         return pos;
00201 }
00202 
00203 int OutputSource_Datafile::size()
00204 {
00205         return pos;
00206 }
00207 
00208 void OutputSource_Datafile::write_string(const char *string)
00209 {
00210         int size = strlen(string)+1;
00211         write(&size, sizeof(int));
00212         write((void *) string, size);
00213 }
00214 
00215 /*
00216 #include <stdio.h>
00217 #include <stdlib.h>
00218 #include <iostream.h>
00219 #include <string.h>
00220 
00221 #include <sys/types.h>
00222 #include <sys/stat.h>
00223 #include <fcntl.h>
00224 
00225 #ifdef WIN32
00226         #include <io.h>
00227 #else
00228         #include <unistd.h>
00229 #endif
00230                                                         
00231 #include "datafilewriter.h"
00232 
00233 #ifndef WIN32
00234 #define OPEN_FLAGS       O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH
00235 #else
00236 #define OPEN_FLAGS       _O_RDWR | O_CREAT | O_TRUNC | O_BINARY, _S_IREAD | _S_IWRITE
00237 #endif
00238 
00239 CL_Datafile_Write::CL_Datafile_Write(char *_filename)
00240 {
00241         filename=_filename;
00242 
00243         cur_index_size=0;
00244 
00245         char open_buffer[256];
00246         // Open files here
00247         datafile=open(filename, OPEN_FLAGS);
00248         
00249         strcpy(open_buffer, filename);
00250         strcat(open_buffer, "_Index");
00251         index=open(open_buffer, OPEN_FLAGS);
00252 
00253         strcpy(open_buffer, filename);
00254         strcat(open_buffer, "_Data");
00255         data=open(open_buffer, OPEN_FLAGS);
00256 
00257         num_indexes=0;
00258         index_open=false;
00259 
00260         init_datafile();
00261 }
00262 
00263 CL_Datafile_Write::~CL_Datafile_Write()
00264 {
00265         finish_datafile();
00266 
00267         close(datafile);
00268         close(index);
00269         close(data);
00270 
00271         // Delete temp files...
00272         char open_buffer[256];
00273         strcpy(open_buffer, filename);
00274         strcat(open_buffer, "_Index");
00275         remove(open_buffer);
00276 
00277         strcpy(open_buffer, filename);
00278         strcat(open_buffer, "_Data");
00279         remove(open_buffer);
00280 }
00281 
00282 void CL_Datafile_Write::init_datafile()
00283 {
00284         // Init index file
00285 
00286         write(index, datafile_id, strlen(datafile_id)+1);
00287 }
00288 
00289 void CL_Datafile_Write::finish_datafile()
00290 {
00291         if (index_open==true)
00292         {
00293                 gzclose(data_indexed);
00294                 index_open=false;
00295 
00296         write(index, &cur_index_size, sizeof(int));
00297         }
00298 
00299         int end_signal=-1;
00300         write(index, &end_signal, sizeof(int));
00301 
00302         // Copy index and data together. Also, adjust the index dest values (so help me god)
00303 
00304         long index_size=lseek(index,0,SEEK_CUR);
00305 
00306         long data_size=lseek(data,0,SEEK_CUR);
00307 
00308         lseek(index, 0, SEEK_SET);
00309         lseek(data, 0, SEEK_SET);
00310 
00311         copy_file(datafile, index, index_size);
00312         copy_file(datafile, data, data_size);
00313 
00314         lseek(datafile, strlen(datafile_id)+1, SEEK_SET); // Skip smart-ass comment
00315 
00316         for (int index=0; index<num_indexes; index++)
00317         {
00318                 int size_name;
00319                 read(datafile, &size_name, sizeof(int));
00320                 lseek(datafile, size_name, SEEK_CUR); // skip name
00321 
00322                 long index_pos;
00323                 read(datafile, &index_pos, sizeof(long));
00324                 index_pos+=index_size;
00325 
00326                 lseek(datafile, -4, SEEK_CUR); // Seek back to index_pos position
00327                 write(datafile, &index_pos, sizeof(long));
00328 
00329                 lseek(datafile, 4, SEEK_CUR); // Skip size information
00330         }
00331 }
00332 
00333 void CL_Datafile_Write::copy_file(int dest, int source, long len)
00334 {
00335         char buffer[16*1024];
00336 
00337         long copy_left=len;
00338         long copy_done=0;
00339         long copy_now=16*1024;
00340 
00341         while (copy_left>0)
00342         {
00343                 if (copy_left<copy_now) copy_now=copy_left;
00344                 copy_done+=copy_now;
00345                 copy_left-=copy_now;
00346 
00347                 read(source, buffer, copy_now);
00348                 write(dest, buffer, copy_now);
00349         }
00350 }
00351 
00352 void CL_Datafile_Write::create_index(char *index_name)
00353 {
00354         if (index_open==true)
00355         {
00356                 gzclose(data_indexed);
00357                 index_open=false;
00358 
00359         write(index, &cur_index_size, sizeof(int));
00360         }
00361 
00362         int size_name=strlen(index_name)+1;
00363         long data_pos=lseek(data,0,SEEK_CUR);
00364         write(index, &size_name, sizeof(int));
00365         write(index, index_name, size_name);
00366         write(index, &data_pos, sizeof(long));
00367 
00368         index_open=true;
00369         data_indexed=gzdopen(dup(data), "w+b");
00370 
00371         num_indexes++;
00372 
00373         cur_index_size=0;
00374 }
00375 
00376 void CL_Datafile_Write::write_data(void *data, int data_size)
00377 {
00378         if (index_open==false) return;
00379 
00380         gzwrite(data_indexed, data, data_size);
00381         cur_index_size += data_size;
00382 }
00383 
00384 gzFile CL_Datafile_Write::get_file_pointer()
00385 {
00386         return data_indexed;
00387 }
00388 */

Generated at Wed Apr 4 19:53:59 2001 for ClanLib by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001