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

  1 kumpf 1.1.2.1 //%/////////////////////////////////////////////////////////////////////////////
  2               //
  3               // Copyright (c) 2000, 2001 BMC Software, Hewlett-Packard Company, IBM,
  4               // 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               //
 13               // 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 kumpf 1.1.2.1 //==============================================================================
 23               //
 24               // Author: Jenny Yu, Hewlett-Packard Company (jenny_yu@hp.com)
 25               //
 26               // Modified By:
 27               //
 28               //%/////////////////////////////////////////////////////////////////////////////
 29               
 30               #include <fstream>
 31               #include <Pegasus/Common/Destroyer.h>
 32               #include <Pegasus/Common/FileSystem.h>
 33               #include <Pegasus/Common/XmlWriter.h>
 34               #include "InstanceFile.h"
 35               
 36               // Note:  If the INDENT_XML_FILES option is set, the XmlWriter is called
 37               //        to parse the xml data to add indentations before saving the 
 38               //        instance data to the instance file.  It somewhat impacts the
 39               //        performance of a create or modify instance operation.  In the
 40               //        future, this option should be made a configurable property to
 41               //        allow enabling and disabling without re-compilation.
 42               
 43 kumpf 1.1.2.1 #define INDENT_XML_FILES
 44               
 45               PEGASUS_USING_STD;
 46               
 47               PEGASUS_NAMESPACE_BEGIN
 48               
 49               /**
 50                   Loads an instance record in the instance file to memory.
 51                */
 52               Boolean InstanceFile::loadInstance(
 53                   const String& path,
 54                   Uint32 index,
 55                   Uint32 size,
 56                   Array<Sint8>& data)
 57               {
 58                   //
 59                   // check for the existence of the instance file, and get the real path
 60                   // of the file
 61                   //
 62                   String realPath;
 63               
 64 kumpf 1.1.2.1     if (!FileSystem::existsNoCase(path, realPath))
 65                   {
 66               	return false;
 67                   }
 68               
 69                   //
 70                   // load data from file
 71                   //
 72                   if (!_loadData(realPath, index, size, data))
 73                   {
 74                       return false;
 75                   }
 76                  
 77                   return true;
 78               }
 79               
 80               /**
 81                   Loads all the instance records in the instance file to memory.
 82                */
 83               Boolean InstanceFile::loadAllInstances(
 84                   const String& path,
 85 kumpf 1.1.2.1     Array<Sint8>& data)
 86               {
 87                   //
 88                   // check for the existence of the instance file, and get the real path
 89                   // of the file
 90                   //
 91                   String realPath;
 92               
 93                   if (!FileSystem::existsNoCase(path, realPath))
 94                   {
 95               	return false;
 96                   }
 97               
 98                   //
 99                   // get the size of the instance file
100                   //
101                   Uint32 fileSize; 
102                   if (!FileSystem::getFileSizeNoCase(realPath, fileSize))
103                   {
104                       return false;
105                   }
106 kumpf 1.1.2.1 
107                   //
108                   // load all the instance data stored in the instance file
109                   //
110                   if (!_loadData(realPath, 0, fileSize, data))
111                   {
112                       return false;
113                   }
114               
115                   return true;
116               }
117               
118               /**
119                   Inserts a new record into the instance file.  Sets the byte position
120                   and the size of the newly added instance record.  Returns true on 
121                   success.
122               
123                   This method creates a temporary file, copies the contents of the original
124                   instance file to the temporary file, and appends the new entry to the
125                   temporary file.  The caller must rename the temporary file back to the
126                   original file after the insert operation is successful on BOTH the
127 kumpf 1.1.2.1     instance index file and the instance file.
128                */
129               Boolean InstanceFile::insertInstance(
130                   Array<Sint8> out,
131                   const String& path, 
132                   Uint32& index,
133                   Uint32& size)
134               {
135                   //
136                   // Create a temporary instance file
137                   //
138                   // First make sure that there is not already a temporary file.
139                   // If a temporary file already exists, remove it first. 
140                   //
141                   String tempFilePath;
142                   if (FileSystem::existsNoCase(path + ".tmp", tempFilePath))
143                   {
144                       if (!FileSystem::removeFileNoCase(tempFilePath))
145                       {
146                           return false;
147                       }
148 kumpf 1.1.2.1     }
149               
150                   ArrayDestroyer<char> p(path.allocateCString(4));
151                   strcat(p.getPointer(), ".tmp");
152                   ofstream os(p.getPointer(), ios::app | ios::binary);
153               
154                   if (!os)
155                   {
156                       return false;
157                   }
158               
159                   //
160                   // Check for the existence of the instance file.  If file exists, copy
161                   // the contents of the file to the temporary file.
162                   //
163                   String realPath;
164                   if (FileSystem::existsNoCase(path, realPath))
165                   {
166                       ArrayDestroyer<char> p(realPath.allocateCString());
167 kumpf 1.1.2.2         ifstream is(p.getPointer(), ios::binary);
168 kumpf 1.1.2.1 
169                       if (!is)
170                       {
171                           return false;
172                       }
173               
174                       //
175                       // get the size of the instance file
176                       //
177                       Uint32 fileSize; 
178                       if (!FileSystem::getFileSizeNoCase(realPath, fileSize))
179                       {
180                           return false;
181                       }
182               
183                       char* buffer = new char[fileSize];
184                       is.clear();
185                       is.seekg(0);
186                       is.read(buffer, fileSize);
187               
188                       if (is.fail())
189 kumpf 1.1.2.1             return false;
190               
191                       os.write(buffer, fileSize);
192               
193                       delete [] buffer;
194               
195                       is.close();
196                   }
197               
198                   //
199                   // append the new instance to the end of the file
200                   //
201                   if (!_insertData(out, os, index, size))
202                   {
203                       return false;
204                   }
205               
206                   os.close();
207               
208                   return true;
209               }
210 kumpf 1.1.2.1 
211               /**
212                   Removes an instance record from the instance file.
213               
214                   This method creates a temporary file, then calls removeData() to remove
215                   the entry from the temporary file.  The caller must rename the temporary
216                   file back to the original file after the remove operation is successful
217                   on BOTH the instance index file and the instance file.
218                */
219               Boolean InstanceFile::removeInstance(
220                   const String& path, 
221                   Uint32 size,
222                   Uint32 index)
223               {
224                   //
225                   // check for the existence of the instance file, and get the real path
226                   // of the file
227                   //
228                   String realPath;
229               
230                   if (!FileSystem::existsNoCase(path, realPath))
231 kumpf 1.1.2.1     {
232               	return false;
233                   }
234               
235                   //
236                   // Create a temporary instance index file
237                   //
238                   // First make sure that there is not already a temporary file.
239                   // If a temporary file already exists, remove it first.
240                   //
241                   String tempFilePath;
242                   if (FileSystem::existsNoCase(realPath + ".tmp", tempFilePath))
243                   {
244                       if (!FileSystem::removeFileNoCase(tempFilePath))
245                       {
246                           return false;
247                       }
248                   }
249               
250                   ArrayDestroyer<char> p(realPath.allocateCString(4));
251                   strcat(p.getPointer(), ".tmp");
252 kumpf 1.1.2.1     ofstream os(p.getPointer(), ios::app | ios::binary);
253               
254                   if (!os)
255                   {
256                       return false;
257                   }
258               
259                   //
260                   // remove the entry from file
261                   //
262                   if (!_removeData(realPath, os, size, index))
263                   {
264                       return false;
265                   }
266               
267                   os.close();
268               
269                   return true;
270               }
271               
272               /**
273 kumpf 1.1.2.1     Modifies an instance record in the instance file by first removing the
274                   the old instance record in the instance file, then appends the new 
275                   instance record to the instance file.  Returns the byte position and the
276                   size of the newly added instance record.
277               
278                   This method creates a temporary file.  All updates are done to the 
279                   temporary file.  The caller must rename the temporary file back to the
280                   the original file after the modify operation is successful on BOTH the
281                   instance index file and the instance file.
282                */
283               Boolean InstanceFile::modifyInstance(
284                   Array<Sint8> out,
285                   const String& path, 
286                   Uint32 oldIndex,
287                   Uint32 oldSize,
288                   Uint32& newIndex,
289                   Uint32& newSize)
290               {
291                   //
292                   // check for the existence of the instance file, and get the real path
293                   // of the file
294 kumpf 1.1.2.1     //
295                   String realPath;
296               
297                   if (!FileSystem::existsNoCase(path, realPath))
298                   {
299               	return false;
300                   }
301               
302                   //
303                   // Open a temporary instance file
304                   //
305                   // First make sure that there is not already a temporary file.
306                   // If a temporary file already exists, remove it first.
307                   //
308                   String tempFilePath;
309                   if (FileSystem::existsNoCase(realPath + ".tmp", tempFilePath))
310                   {
311                       if (!FileSystem::removeFileNoCase(tempFilePath))
312                       {
313                           return false;
314                       }
315 kumpf 1.1.2.1     }
316               
317                   ArrayDestroyer<char> p(realPath.allocateCString(4));
318                   strcat(p.getPointer(), ".tmp");
319                   ofstream os(p.getPointer(), ios::app | ios::binary);
320               
321                   if (!os)
322                   {
323                       return false;
324                   }
325               
326                   //
327                   // remove the old entry from the temporary file
328                   //
329                   if (!_removeData(realPath, os, oldSize, oldIndex))
330                   {
331                       return false;
332                   }
333               
334                   //
335                   // Append the new instance to the instance file
336 kumpf 1.1.2.1     //
337                   if (!_insertData(out, os, newIndex, newSize))
338                   {
339                       return false;
340                   }
341               
342                   os.close();
343               
344                   return true;
345               }
346               
347               /**
348                   Loads data from the instance file at the given byte positon for the
349                   given size.
350                */
351               Boolean InstanceFile::_loadData(
352                   const String& path,
353                   Uint32 index,
354                   Uint32 size,
355                   Array<Sint8>& data)
356               {
357 kumpf 1.1.2.1     //
358                   // open the instance file
359                   //
360                   ArrayDestroyer<char> p(path.allocateCString());
361 kumpf 1.1.2.2     ifstream is(p.getPointer(), ios::in | ios::binary);
362 kumpf 1.1.2.1    
363                   if (!is)
364                   {
365               	return false;
366                   }
367               
368                   //
369                   // position the file get pointer at the specified location 
370                   //
371                   is.clear();               
372                   is.seekg(index); 
373               
374                   //
375                   // Load data from file into memory
376                   //
377                   char* buffer = new char[size];
378                   is.read( buffer, size);
379               
380                   if (is.fail())
381                       return false;
382               
383 kumpf 1.1.2.1     data.clear();
384                   data.reserve(size+1);
385                   data.append(buffer, size);
386                   data.append('\0');
387               
388                   is.close();
389               
390                   delete [] buffer;
391               
392                   return true;
393               }
394               
395               /**
396                   Removes a record in the instance file at the given byte position for
397                   the given size.
398                */
399               Boolean InstanceFile::_removeData(
400                   const String& realPath, 
401                   ofstream& os,
402                   Uint32 size,
403                   Uint32 index)
404 kumpf 1.1.2.1 {
405                   //
406                   // Open the instance file 
407                   //
408                   ArrayDestroyer<char> q(realPath.allocateCString());
409 kumpf 1.1.2.2     ifstream is(q.getPointer(), ios::in | ios::binary);
410 kumpf 1.1.2.1 
411                   if (!is)
412                   {
413                       return false;
414                   }
415               
416                   //
417                   // get the size of the instance file
418                   //
419                   Uint32 fileSize; 
420                   if (!FileSystem::getFileSizeNoCase(realPath, fileSize))
421                   {
422                       return false;
423                   }
424               
425                   //
426                   // Copy all the entries in the instance file up to the one to be deleted
427                   //
428                   Array<Sint8> data;
429                   Uint32 copySize;
430                   Uint32 sizeNeeded;
431 kumpf 1.1.2.1 
432                   //
433                   //  determine the number of bytes to copy 
434                   //
435                   sizeNeeded = fileSize - size;
436               
437                   //
438                   //  if the entry to be deleted is not the only entry in the instance file,
439                   //  copy the remaining entries 
440                   //
441                   if (sizeNeeded > 0)
442                   {
443                       char* buffer = new char[sizeNeeded];
444               
445                       data.clear();
446                       data.reserve(sizeNeeded);
447               
448                       is.clear();                 
449               
450                       //
451                       // copy from the beginning of the file if the entry to be deleted 
452 kumpf 1.1.2.1         // is not the first entry in the file
453                       //
454                       if (index != 0)
455                       {
456                           is.seekg(0);                   
457                           is.read( buffer, index );
458               
459                           if (is.fail())
460                               return false;
461               
462                           data.append(buffer, index);
463                       }
464               
465                       //
466                       // skip the entry to be deleted and copy the remaining entries 
467                       //
468                       Uint32 placeToCopy = index + size;
469               
470                       is.seekg(placeToCopy);
471                       copySize = (fileSize - placeToCopy) - 1;
472               
473 kumpf 1.1.2.1         is.read( buffer, copySize );
474               
475                       if (is.fail())
476                           return false;
477               
478                       data.append(buffer, copySize);
479                       data.append('\0');
480                   
481                       delete [] buffer;
482               
483                       //
484                       // write data to the temporary file
485                       //
486                       os << (char*)data.getData() << endl;
487               
488                       os.flush();
489                   }
490               
491                   is.close();
492               
493                   return true;
494 kumpf 1.1.2.1 }
495               
496               /**
497                   Inserts a new record into the instance file. 
498               
499                */
500               Boolean InstanceFile::_insertData(
501                   Array<Sint8> out,
502                   ofstream& os,
503                   Uint32& index,
504                   Uint32& size)
505               {
506                   Uint32 begPos;                 // file position before insertion 
507                   Uint32 endPos;                 // file position after insertion 
508               
509                   //
510                   // determine current position of file
511                   //
512                   begPos = os.tellp();
513                   index = begPos;
514               
515 kumpf 1.1.2.1     //
516                   // write the CIM/XML encoding of the instance to file
517                   //
518               #ifdef INDENT_XML_FILES
519                   out.append('\0');
520                   XmlWriter::indentedPrint(os, out.getData(), 2);
521               #else
522                   os.write((char*)out.getData(), out.size());
523               #endif
524               
525                   //
526                   // determine the size of the instance record written to file
527                   //
528                   endPos = os.tellp();
529                   size = endPos - begPos;
530               
531                   os.flush();
532               
533                   return true;
534               }
535               
536 kumpf 1.1.2.1 PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2