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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2