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

  1 mike  1.2 //%/////////////////////////////////////////////////////////////////////////////
  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 mike  1.2 //==============================================================================
 23           //
 24           // Author: Jenny Yu, Hewlett-Packard Company (jenny_yu@hp.com)
 25           //
 26           // Modified By:
 27           //
 28           //%/////////////////////////////////////////////////////////////////////////////
 29           
 30           #include <Pegasus/Common/Config.h>
 31           #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 mike  1.2 
 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            */
 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 mike  1.2 
 65               if (!FileSystem::existsNoCase(path, realPath))
 66               {
 67           	return false;
 68               }
 69           
 70               //
 71               // load data from file
 72               //
 73               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 mike  1.2     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               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 mike  1.2     }
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           
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 mike  1.2     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               //
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 mike  1.2         }
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                   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                   ifstream is(p.getPointer(), ios::binary);
169 mike  1.2 
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 mike  1.2             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 mike  1.2 
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 mike  1.2     {
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 mike  1.2     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 mike  1.2     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 mike  1.2     //
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 mike  1.2     }
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 mike  1.2     //
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 mike  1.2     //
359               // open the instance file
360               //
361               ArrayDestroyer<char> p(path.allocateCString());
362               ifstream is(p.getPointer(), ios::in | ios::binary);
363              
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 mike  1.2     is.read( buffer, size);
380           
381               if (is.fail())
382                   return false;
383           
384               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 mike  1.2 Boolean InstanceFile::_removeData(
401               const String& realPath, 
402               ofstream& os,
403               Uint32 size,
404               Uint32 index)
405           {
406               //
407               // Open the instance file 
408               //
409               ArrayDestroyer<char> q(realPath.allocateCString());
410               ifstream is(q.getPointer(), ios::in | ios::binary);
411           
412               if (!is)
413               {
414                   return false;
415               }
416           
417               //
418               // get the size of the instance file
419               //
420               Uint32 fileSize; 
421 mike  1.2     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           
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 mike  1.2     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                   // 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 mike  1.2             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                   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 mike  1.2         //
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           }
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 mike  1.2     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               //
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 mike  1.2     //
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           PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2