(file) Return to InstanceDataFile.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Repository

  1 karl  1.23 //%2006////////////////////////////////////////////////////////////////////////
  2 mike  1.1  //
  3 karl  1.16 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
  4            // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
  5            // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
  6 karl  1.13 // IBM Corp.; EMC Corporation, The Open Group.
  7 karl  1.16 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
  8            // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
  9 karl  1.18 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 10            // EMC Corporation; VERITAS Software Corporation; The Open Group.
 11 karl  1.23 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 12            // EMC Corporation; Symantec Corporation; The Open Group.
 13 mike  1.1  //
 14            // Permission is hereby granted, free of charge, to any person obtaining a copy
 15            // of this software and associated documentation files (the "Software"), to
 16            // deal in the Software without restriction, including without limitation the
 17            // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 18            // sell copies of the Software, and to permit persons to whom the Software is
 19            // furnished to do so, subject to the following conditions:
 20 karl  1.30 //
 21 mike  1.1  // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 22            // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 23            // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 24            // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 25            // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 26            // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 27            // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 28            // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 29            //
 30            //==============================================================================
 31            //
 32            //%/////////////////////////////////////////////////////////////////////////////
 33            
 34            #include <fstream>
 35            #include <Pegasus/Common/Config.h>
 36            #include "InstanceDataFile.h"
 37            #include <Pegasus/Common/System.h>
 38            #include <Pegasus/Common/FileSystem.h>
 39 kumpf 1.3  #include <Pegasus/Common/Tracer.h>
 40 mike  1.1  
 41            PEGASUS_USING_STD;
 42            
 43            PEGASUS_NAMESPACE_BEGIN
 44            
 45            Boolean InstanceDataFile::_openFile(
 46                PEGASUS_STD(fstream)& fs,
 47                const String& path,
 48                int mode)
 49            {
 50 kumpf 1.3      PEG_METHOD_ENTER(TRC_REPOSITORY, "InstanceDataFile::_openFile()");
 51 mday  1.8  #if defined(__GNUC__) && GCC_VERSION >= 30200
 52                if (FileSystem::openNoCase(fs, path, PEGASUS_STD(ios_base::openmode)(mode)))
 53            #else
 54 mike  1.1      if (FileSystem::openNoCase(fs, path, mode))
 55 mday  1.8  #endif
 56 kumpf 1.3      {
 57 mday  1.9         PEG_METHOD_EXIT();
 58                   return true;
 59 kumpf 1.3      }
 60 mday  1.10 #if defined(__GNUC__) && GCC_VERSION >= 30200
 61                fs.open(path.getCString(), PEGASUS_STD(ios_base::openmode)(mode));
 62            #else
 63 david 1.14     fs.open(path.getCString(), mode);
 64 david 1.11 #endif
 65 kumpf 1.3      PEG_METHOD_EXIT();
 66 mike  1.1      return !!fs;
 67            }
 68            
 69            Boolean InstanceDataFile::loadInstance(
 70 david.dillard 1.19     const String& path,
 71 mike          1.1      Uint32 index,
 72 david.dillard 1.19     Uint32 size,
 73 mike          1.21     Buffer& data)
 74 mike          1.1  {
 75 kumpf         1.3      PEG_METHOD_ENTER(TRC_REPOSITORY, "InstanceDataFile::loadInstance()");
 76                    
 77 mike          1.1      //
 78                        // Open the file:
 79                        //
 80                    
 81                        fstream fs;
 82                    
 83 ramnath       1.2      if (!_openFile(fs, path, ios::in PEGASUS_OR_IOS_BINARY))
 84 kumpf         1.3      {
 85                            PEG_METHOD_EXIT();
 86 david.dillard 1.19         return false;
 87 kumpf         1.3      }
 88 mike          1.1  
 89                        //
 90                        // Postion file pointer:
 91                        //
 92                    
 93                        fs.seekg(index);
 94                    
 95                        if (!fs)
 96 kumpf         1.3      {
 97                            PEG_METHOD_EXIT();
 98 david.dillard 1.19         return false;
 99 kumpf         1.3      }
100 mike          1.1  
101                        //
102                        // Read the instance:
103                        //
104                    
105                        data.grow(size, '\0');
106                        fs.read((char*)data.getData(), size);
107                    
108                        if (!fs)
109 kumpf         1.3      {
110                            PEG_METHOD_EXIT();
111 david.dillard 1.19         return false;
112 kumpf         1.3      }
113 mike          1.1  
114                        //
115                        // Close the file:
116                        //
117                    
118                        fs.close();
119                    
120 kumpf         1.3      PEG_METHOD_EXIT();
121 mike          1.1      return true;
122                    }
123                    
124                    Boolean InstanceDataFile::loadAllInstances(
125 david.dillard 1.19     const String& path,
126 mike          1.21     Buffer& data)
127 mike          1.1  {
128 kumpf         1.3      PEG_METHOD_ENTER(TRC_REPOSITORY, "InstanceDataFile::loadAllInstance()");
129                    
130 mike          1.1      //
131                        // Get size of the data file:
132                        //
133                    
134                        Uint32 fileSize;
135                    
136                        if (!FileSystem::getFileSizeNoCase(path, fileSize))
137 kumpf         1.3      {
138                            PEG_METHOD_EXIT();
139 david.dillard 1.19         return false;
140 kumpf         1.3      }
141 mike          1.1  
142                        //
143                        // Open the file:
144                        //
145                    
146                        fstream fs;
147                    
148 ramnath       1.2      if (!_openFile(fs, path, ios::in PEGASUS_OR_IOS_BINARY))
149 kumpf         1.3      {
150                            PEG_METHOD_EXIT();
151 david.dillard 1.19         return false;
152 kumpf         1.3      }
153 mike          1.1  
154                        //
155                        // Suck the entire contents of the file into the data array parameter:
156                        //
157                    
158                        data.grow(fileSize, '\0');
159                        fs.read((char*)data.getData(), fileSize);
160                    
161                        if (!fs)
162 kumpf         1.3      {
163                            PEG_METHOD_EXIT();
164 david.dillard 1.19         return false;
165 kumpf         1.3      }
166 mike          1.1  
167                        //
168                        // Close the file:
169                        //
170                    
171                        fs.close();
172                    
173 kumpf         1.3      PEG_METHOD_EXIT();
174 mike          1.1      return true;
175                    }
176                    
177                    Boolean InstanceDataFile::appendInstance(
178 david.dillard 1.19     const String& path,
179 mike          1.21     const Buffer& data,
180 mike          1.1      Uint32& index)
181                    {
182 kumpf         1.3      PEG_METHOD_ENTER(TRC_REPOSITORY, "InstanceDataFile::appendInstance()");
183                    
184 mike          1.1      //
185                        // Get size of the data file:
186                        //
187                    
188                        if (!FileSystem::getFileSizeNoCase(path, index))
189 david.dillard 1.19         index = 0;
190 mike          1.1  
191                        //
192                        // Open the file for append:
193                        //
194                    
195                        fstream fs;
196                    
197 ramnath       1.2      if (!_openFile(fs, path, ios::app | ios::out PEGASUS_OR_IOS_BINARY))
198 kumpf         1.3      {
199                            PEG_METHOD_EXIT();
200 david.dillard 1.19         return false;
201 kumpf         1.3      }
202 mike          1.1  
203                        //
204                        // Save index to data:
205                        //
206                    
207                        // index = fs.tellp();
208                    
209                        //
210                        // Write the instance:
211                        //
212                    
213                        fs.write((char*)data.getData(), data.size());
214                    
215                        if (!fs)
216 kumpf         1.3      {
217                            PEG_METHOD_EXIT();
218 david.dillard 1.19         return false;
219 kumpf         1.3      }
220 mike          1.1  
221                        //
222                        // Close the file:
223                        //
224                    
225                        fs.close();
226                    
227 kumpf         1.3      PEG_METHOD_EXIT();
228 mike          1.1      return true;
229                    }
230                    
231                    Boolean InstanceDataFile::beginTransaction(const String& path)
232                    {
233 kumpf         1.3      PEG_METHOD_ENTER(TRC_REPOSITORY, "InstanceDataFile::beginTransaction()");
234                    
235 mike          1.1      Uint32 fileSize;
236                    
237                        //
238                        // If the file does not exist, then set the file size to zero:
239                        //
240                    
241                        if (!FileSystem::existsNoCase(path))
242                        {
243 david.dillard 1.19         fileSize = 0;
244 mike          1.1      }
245                        else
246                        {
247 david.dillard 1.19         if (!FileSystem::getFileSizeNoCase(path, fileSize))
248 kumpf         1.3          {
249                                PEG_METHOD_EXIT();
250 david.dillard 1.19             return false;
251 kumpf         1.3          }
252 mike          1.1      }
253                    
254                        //
255                        // Open the rollback file:
256                        //
257                    
258 kumpf         1.5      // ATTN-SF-P3-20020517: FUTURE: Need to look in to this. Empty rollback
259                        // files are getting created in some error conditions.
260                    
261 mike          1.1      fstream fs;
262                    
263 kumpf         1.4      if (!_openFile(fs, path + ".rollback", ios::out PEGASUS_OR_IOS_BINARY))
264 kumpf         1.3      {
265                            PEG_METHOD_EXIT();
266 david.dillard 1.19         return false;
267 kumpf         1.3      }
268 mike          1.1  
269                        //
270                        // Save the size of the data file in the rollback file.
271                        //
272                    
273                        char buffer[9];
274                        sprintf(buffer, "%08x", fileSize);
275 david.dillard 1.19     fs.write(buffer, static_cast<streamsize>(strlen(buffer)));
276 mike          1.1  
277                        if (!fs)
278 kumpf         1.3      {
279                            PEG_METHOD_EXIT();
280 david.dillard 1.19         return false;
281 kumpf         1.3      }
282 mike          1.1  
283                        //
284                        // Close the file.
285                        //
286                    
287 mateus.baur   1.28     FileSystem::syncWithDirectoryUpdates(fs);
288 mike          1.1      fs.close();
289                    
290 kumpf         1.3      PEG_METHOD_EXIT();
291 mike          1.1      return true;
292                    }
293                    
294                    Boolean InstanceDataFile::rollbackTransaction(const String& path)
295                    {
296 kumpf         1.3      PEG_METHOD_ENTER(TRC_REPOSITORY, "InstanceDataFile::rollbackTransaction()");
297                    
298 mike          1.1      //
299                        // If rollback file does not exist, then everything is fine, just
300                        // return.
301                        //
302                    
303 kumpf         1.4      if (!FileSystem::existsNoCase(path + ".rollback"))
304 kumpf         1.3      {
305                            PEG_METHOD_EXIT();
306 david.dillard 1.19         return true;
307 kumpf         1.3      }
308 mike          1.1  
309                        //
310                        // Open the rollback file:
311                        //
312                    
313                        fstream rollbackFs;
314                    
315 kumpf         1.25     if (!_openFile(
316                                rollbackFs, path + ".rollback", ios::in PEGASUS_OR_IOS_BINARY))
317 kumpf         1.3      {
318                            PEG_METHOD_EXIT();
319 david.dillard 1.19         return false;
320 kumpf         1.3      }
321 mike          1.1  
322                        //
323                        // Retrieve the file size from the rollback file:
324                        //
325                    
326                        char buffer[9];
327                        rollbackFs.read(buffer, 8);
328                    
329                        if (!rollbackFs)
330 kumpf         1.3      {
331                            PEG_METHOD_EXIT();
332 david.dillard 1.19         return false;
333 kumpf         1.3      }
334 mike          1.1  
335                        buffer[8] = '\0';
336                    
337                        char* end = 0;
338                        long fileSize = strtol(buffer, &end, 16);
339                    
340                        if (!end || *end != '\0' || fileSize < 0)
341 kumpf         1.3      {
342                            PEG_METHOD_EXIT();
343 david.dillard 1.19         return false;
344 kumpf         1.3      }
345 mike          1.1  
346                        rollbackFs.close();
347                    
348                        //
349 kumpf         1.24     // If the instance data file does not yet exist, create it
350 mike          1.1      //
351 kumpf         1.5  
352 kumpf         1.24     if (fileSize == 0)
353 kumpf         1.5      {
354                            fstream ofs;
355                    
356                            if (!_openFile(ofs, path, ios::out PEGASUS_OR_IOS_BINARY))
357                            {
358                                PEG_METHOD_EXIT();
359                                return false;
360                            }
361                    
362                            ofs.close();
363                        }
364 mike          1.1  
365 kumpf         1.24     //
366                        // Truncate the data file to its initial size
367                        //
368                    
369 kumpf         1.7      if (!System::truncateFile(path.getCString(), fileSize))
370 kumpf         1.3      {
371                            PEG_METHOD_EXIT();
372 david.dillard 1.19         return false;
373 kumpf         1.3      }
374 mike          1.1  
375                        //
376                        // Now get rid of rollback file!
377                        //
378                    
379 kumpf         1.3      PEG_METHOD_EXIT();
380 kumpf         1.4      return FileSystem::removeFileNoCase(path + ".rollback");
381 mike          1.1  }
382                    
383                    Boolean InstanceDataFile::commitTransaction(const String& path)
384                    {
385 kumpf         1.3      PEG_METHOD_ENTER(TRC_REPOSITORY, "InstanceDataFile::commitTransaction()");
386                    
387 mike          1.1      //
388                        // To commit the transaction, we simply remove the rollback file:
389                        //
390                    
391 kumpf         1.3      PEG_METHOD_EXIT();
392 kumpf         1.4      return FileSystem::removeFileNoCase(path + ".rollback");
393 mike          1.1  }
394                    
395                    Boolean InstanceDataFile::compact(
396                        const String& path,
397                        const Array<Uint32>& freeFlags,
398                        const Array<Uint32>& indices,
399                        const Array<Uint32>& sizes)
400                    {
401 kumpf         1.3      PEG_METHOD_ENTER(TRC_REPOSITORY, "InstanceDataFile::compact()");
402                    
403 mike          1.1      //
404                        // Open the input file (the data file):
405                        //
406                    
407                        fstream fs;
408                    
409 ramnath       1.2      if (!_openFile(fs, path, ios::in PEGASUS_OR_IOS_BINARY))
410 kumpf         1.3      {
411                            PEG_METHOD_EXIT();
412 david.dillard 1.19         return false;
413 kumpf         1.3      }
414 mike          1.1  
415                        //
416                        // Open the output file (temporary data file):
417                        //
418                    
419                        fstream tmpFs;
420                    
421 kumpf         1.4      if (!_openFile(tmpFs, path + ".tmp", ios::out PEGASUS_OR_IOS_BINARY))
422 kumpf         1.3      {
423                            PEG_METHOD_EXIT();
424 david.dillard 1.19         return false;
425 kumpf         1.3      }
426 mike          1.1  
427 mike          1.21     Buffer data;
428 mike          1.1  
429                        //
430                        // Copy over instances which have not been freed:
431                        //
432                    
433                        for (Uint32 i = 0, n = freeFlags.size(); i < n; i++)
434                        {
435 david.dillard 1.19         //
436                            // If this entry is not free, then copy it over to the
437                            // temporary file. Otherwise, pay retail for it.
438                            //
439                    
440                            if (!freeFlags[i])
441                            {
442                                //
443                                // Read the next instance:
444                                //
445 mike          1.1  
446 david.dillard 1.19             if (!fs.seekg(indices[i]))
447 kumpf         1.3              {
448                                    PEG_METHOD_EXIT();
449 david.dillard 1.19                 return false;
450 kumpf         1.3              }
451 mike          1.1  
452 david.dillard 1.19             data.grow(sizes[i], '\0');
453 mike          1.1  
454 david.dillard 1.19             fs.read((char*)data.getData(), sizes[i]);
455 mike          1.1  
456 david.dillard 1.19             if (!fs)
457 kumpf         1.3              {
458                                    PEG_METHOD_EXIT();
459 david.dillard 1.19                 return false;
460 kumpf         1.3              }
461 mike          1.1  
462 david.dillard 1.19             //
463                                //  Write out the next instance:
464                                //
465 mike          1.1  
466 david.dillard 1.19             tmpFs.write((char*)data.getData(), sizes[i]);
467                            }
468 mike          1.1      }
469                    
470                        //
471                        // Close the files:
472                        //
473 david.dillard 1.19 
474 mike          1.1      fs.close();
475 mateus.baur   1.28 
476                        FileSystem::syncWithDirectoryUpdates(tmpFs);
477 mike          1.1      tmpFs.close();
478                    
479                        //
480                        // Copy the new file over the old one:
481                        //
482                    
483                        if (!FileSystem::removeFileNoCase(path))
484 kumpf         1.3      {
485                            PEG_METHOD_EXIT();
486 david.dillard 1.19         return false;
487 kumpf         1.3      }
488 mike          1.1  
489 kumpf         1.4      if (!FileSystem::renameFileNoCase(path + ".tmp", path))
490 kumpf         1.3      {
491                            PEG_METHOD_EXIT();
492 david.dillard 1.19         return false;
493 kumpf         1.3      }
494 mike          1.1  
495 kumpf         1.3      PEG_METHOD_EXIT();
496 mike          1.1      return true;
497                    }
498                    
499                    PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2