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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2