Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

Memory.cpp

Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
00002  * vim:expandtab:autoindent:tabstop=4:shiftwidth=4:filetype=c:cindent:textwidth=0:
00003  *
00004  * Copyright (C) 2005 Dell Inc.
00005  *  by Michael Brown <Michael_E_Brown@dell.com>
00006  * Licensed under the Open Software License version 2.1
00007  *
00008  * Alternatively, you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published
00010  * by the Free Software Foundation; either version 2 of the License,
00011  * or (at your option) any later version.
00012 
00013  * This program is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00016  * See the GNU General Public License for more details.
00017  */
00018 
00019 // compat header should always be first header if including system headers
00020 #define LIBSMBIOS_SOURCE
00021 #include "smbios/compat.h"
00022 
00023 #include <errno.h>
00024 #include <stdio.h>
00025 
00026 #include "MemoryImpl.h"
00027 
00028 // include this file last
00029 #include "smbios/message.h"
00030 
00031 using namespace std;
00032 
00033 namespace memory
00034 {
00035     MemoryFactory::~MemoryFactory() throw()
00036     {}
00037     MemoryFactory::MemoryFactory()
00038     {}
00039 
00040     MemoryFactory *MemoryFactory::getFactory()
00041     {
00042         // reinterpret_cast<...>(0) to ensure template parameter is correct
00043         // this is a workaround for VC6 which cannot use explicit member template
00044         // function initialization.
00045         return MemoryFactoryImpl::getFactory(reinterpret_cast<MemoryFactoryImpl *>(0));
00046     }
00047 
00048     IMemory           *MemoryFactoryImpl::_mem_instance = 0;
00049 
00050     MemoryFactoryImpl::~MemoryFactoryImpl() throw()
00051     {
00052         if( _mem_instance )
00053         {
00054             delete _mem_instance;
00055         }
00056         _mem_instance = 0;
00057     }
00058 
00059     //
00060     // MemoryFactoryImpl::MemoryFactoryImpl()   // Constructor
00061     //  -- Moved to the Memory_OSNAME.cc file
00062     //     so that the default parameters can be OS-Specific
00063     //
00064 
00065 
00066     IMemory *MemoryFactoryImpl::getSingleton()
00067     {
00068         if (! _mem_instance)
00069             _mem_instance = makeNew();
00070 
00071         return _mem_instance;
00072     }
00073 
00074     IMemory *MemoryFactoryImpl::makeNew()
00075     {
00076         if (mode == UnitTestMode)
00077         {
00078             return new MemoryFile( getParameterString("memFile") );
00079         }
00080         else if (mode == AutoDetectMode)
00081         {
00082             return new MemoryOsSpecific( getParameterString("memFile") );
00083         }
00084         else
00085         {
00086             throw smbios::NotImplementedImpl( _("Unknown Memory mode requested.") );
00087         }
00088     }
00089 
00090 
00091     //
00092     // IMemory
00093     //
00094 
00095     IMemory::~IMemory ()
00096     {}
00097 
00098     IMemory::IMemory ()
00099     {}
00100 
00101     MemoryFile::MemoryFile( const string initFilename )
00102             : IMemory(), filename(initFilename), fd(0), rw(false)
00103     {
00104         // workaround MSVC++ bugs...
00105         if( filename == "" )
00106         {
00107             throw AccessErrorImpl( _("File name passed in was null or zero-length.") );
00108         }
00109 
00110         // fopen portable to Windows if "b" is added to mode.
00111         fd = fopen( filename.c_str(), "rb" ); // open for read to start
00112         if(!fd)
00113         {
00114             AccessErrorImpl accessError;
00115             accessError.setMessageString( _("Unable to open memory. File: %(file)s, OS Error: %(err)s") );
00116             accessError.setParameter( "file", filename );
00117             accessError.setParameter( "err", strerror(errno) );
00118             throw accessError;
00119         }
00120     }
00121 
00122     MemoryFile::~MemoryFile()
00123     {
00124         fclose(fd);
00125     }
00126 
00127     u8 MemoryFile::getByte( u64 offset ) const
00128     {
00129         u8 value = 0;
00130         fillBuffer( &value, offset, 1 );
00131         return value;
00132     }
00133 
00134 
00135     void MemoryFile::fillBuffer(u8 *buffer, u64 offset, unsigned int length) const
00136     {
00137         // FSEEK is a macro defined in config/ for portability
00138         int ret = FSEEK(fd, offset, 0);
00139         if (ret)
00140         {
00141             OutOfBoundsImpl outOfBounds;
00142             outOfBounds.setMessageString(_("Seek error trying to seek to memory location. OS Error: %(err)s"));
00143             outOfBounds.setParameter("err", strerror(errno) );
00144             throw outOfBounds;
00145         }
00146         size_t bytesRead = fread( buffer, 1, length, fd );
00147         // TODO: handle short reads
00148         if ((length != bytesRead))
00149         {
00150             AccessErrorImpl accessError;
00151             accessError.setMessageString(_("Read error trying to read memory. OS Error: %(err)s"));
00152             accessError.setParameter("err", strerror(errno) );
00153             throw accessError;
00154         }
00155     }
00156 
00157     void MemoryFile::putByte( u64 offset, u8 byte ) const
00158     {
00159         if(!rw)
00160         {
00161             fclose(fd);
00162             fd = fopen( filename.c_str(), "r+b" ); // reopen for write
00163             if(!fd)
00164             {
00165                 AccessErrorImpl accessError;
00166                 accessError.setMessageString( _("Unable to re-open memory file for writing. File: %(file)s, OS Error: %(err)s") );
00167                 accessError.setParameter( "file", filename );
00168                 accessError.setParameter( "err", strerror(errno) );
00169                 throw accessError;
00170             }
00171         }
00172         // FSEEK is a macro defined in config/ for portability
00173         int ret = FSEEK(fd, offset, 0);
00174         if( 0 != ret )
00175         {
00176             OutOfBoundsImpl outOfBounds;
00177             outOfBounds.setMessageString(_("Seek error trying to seek to memory location. OS Error: %(err)s"));
00178             outOfBounds.setParameter("err", strerror(errno) );
00179             throw outOfBounds;
00180         }
00181         size_t bytesRead = fwrite( &byte, 1, 1, fd );
00182         if( 1 != bytesRead )
00183         {
00184             AccessErrorImpl accessError;
00185             accessError.setMessageString(_("Error trying to write memory. OS Error: %(err)s"));
00186             accessError.setParameter("err", strerror(errno) );
00187             throw accessError;
00188         }
00189     }
00190 }

Generated on Wed Apr 11 16:25:10 2007 for SMBIOS Library by doxygen 1.3.5