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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2