FileStore.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 ** Copyright (c) 2001-2014
3 **
4 ** This file is part of the QuickFIX FIX Engine
5 **
6 ** This file may be distributed under the terms of the quickfixengine.org
7 ** license as defined by quickfixengine.org and appearing in the file
8 ** LICENSE included in the packaging of this file.
9 **
10 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
11 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
12 **
13 ** See http://www.quickfixengine.org/LICENSE for licensing information.
14 **
15 ** Contact ask@quickfixengine.org if any conditions of this licensing are
16 ** not clear to you.
17 **
18 ****************************************************************************/
19 
20 #ifdef _MSC_VER
21 #include "stdafx.h"
22 #else
23 #include "config.h"
24 #endif
25 
26 #include "FileStore.h"
27 #include "SessionID.h"
28 #include "Parser.h"
29 #include "Utility.h"
30 #include <fstream>
31 
32 namespace FIX
33 {
34 FileStore::FileStore( std::string path, const SessionID& s )
35 : m_msgFile( 0 ), m_headerFile( 0 ), m_seqNumsFile( 0 ), m_sessionFile( 0 )
36 {
37  file_mkdir( path.c_str() );
38 
39  if ( path.empty() ) path = ".";
40  const std::string& begin =
41  s.getBeginString().getString();
42  const std::string& sender =
43  s.getSenderCompID().getString();
44  const std::string& target =
45  s.getTargetCompID().getString();
46  const std::string& qualifier =
47  s.getSessionQualifier();
48 
49  std::string sessionid = begin + "-" + sender + "-" + target;
50  if( qualifier.size() )
51  sessionid += "-" + qualifier;
52 
53  std::string prefix
54  = file_appendpath(path, sessionid + ".");
55 
56  m_msgFileName = prefix + "body";
57  m_headerFileName = prefix + "header";
58  m_seqNumsFileName = prefix + "seqnums";
59  m_sessionFileName = prefix + "session";
60 
61  try
62  {
63  open( false );
64  }
65  catch ( IOException & e )
66  {
67  throw ConfigError( e.what() );
68  }
69 }
70 
72 {
73  if( m_msgFile ) fclose( m_msgFile );
74  if( m_headerFile ) fclose( m_headerFile );
75  if( m_seqNumsFile ) fclose( m_seqNumsFile );
76  if( m_sessionFile ) fclose( m_sessionFile );
77 }
78 
79 void FileStore::open( bool deleteFile )
80 {
81  if ( m_msgFile ) fclose( m_msgFile );
82  if ( m_headerFile ) fclose( m_headerFile );
83  if ( m_seqNumsFile ) fclose( m_seqNumsFile );
84  if ( m_sessionFile ) fclose( m_sessionFile );
85 
86  m_msgFile = 0;
87  m_headerFile = 0;
89  m_sessionFile = 0;
90 
91  if ( deleteFile )
92  {
93  file_unlink( m_msgFileName.c_str() );
94  file_unlink( m_headerFileName.c_str() );
95  file_unlink( m_seqNumsFileName.c_str() );
97  }
98 
99  populateCache();
100  m_msgFile = file_fopen( m_msgFileName.c_str(), "r+" );
101  if ( !m_msgFile ) m_msgFile = file_fopen( m_msgFileName.c_str(), "w+" );
102  if ( !m_msgFile ) throw ConfigError( "Could not open body file: " + m_msgFileName );
103 
104  m_headerFile = file_fopen( m_headerFileName.c_str(), "r+" );
105  if ( !m_headerFile ) m_headerFile = file_fopen( m_headerFileName.c_str(), "w+" );
106  if ( !m_headerFile ) throw ConfigError( "Could not open header file: " + m_headerFileName );
107 
108  m_seqNumsFile = file_fopen( m_seqNumsFileName.c_str(), "r+" );
109  if ( !m_seqNumsFile ) m_seqNumsFile = file_fopen( m_seqNumsFileName.c_str(), "w+" );
110  if ( !m_seqNumsFile ) throw ConfigError( "Could not open seqnums file: " + m_seqNumsFileName );
111 
112  bool setCreationTime = false;
113  m_sessionFile = file_fopen( m_sessionFileName.c_str(), "r" );
114  if ( !m_sessionFile ) setCreationTime = true;
115  else fclose( m_sessionFile );
116 
117  m_sessionFile = file_fopen( m_sessionFileName.c_str(), "r+" );
118  if ( !m_sessionFile ) m_sessionFile = file_fopen( m_sessionFileName.c_str(), "w+" );
119  if ( !m_sessionFile ) throw ConfigError( "Could not open session file" );
120  if ( setCreationTime ) setSession();
121 
124 }
125 
127 {
128  FILE* headerFile = file_fopen( m_headerFileName.c_str(), "r+" );
129  if ( headerFile )
130  {
131  int num;
132  long offset;
133  std::size_t size;
134 
135  while (FILE_FSCANF(headerFile, "%d,%ld,%lu ", &num, &offset, &size) == 3)
136  {
137  std::pair<NumToOffset::iterator, bool> it =
138  m_offsets.insert(NumToOffset::value_type(num, std::make_pair(offset, size)));
139  //std::cout << it.first->second.first << " --- " << it.first->second.second << '\n';
140  if (it.second == false)
141  {
142  it.first->second = std::make_pair(offset, size);
143  }
144  }
145  fclose( headerFile );
146  }
147 
148  FILE* seqNumsFile = file_fopen( m_seqNumsFileName.c_str(), "r+" );
149  if ( seqNumsFile )
150  {
151  int sender, target;
152  if ( FILE_FSCANF( seqNumsFile, "%d : %d", &sender, &target ) == 2 )
153  {
156  }
157  fclose( seqNumsFile );
158  }
159 
160  FILE* sessionFile = file_fopen( m_sessionFileName.c_str(), "r+" );
161  if ( sessionFile )
162  {
163  char time[ 22 ];
164 #ifdef HAVE_FSCANF_S
165  int result = FILE_FSCANF( sessionFile, "%s", time, 22 );
166 #else
167  int result = FILE_FSCANF( sessionFile, "%s", time );
168 #endif
169  if( result == 1 )
170  {
172  }
173  fclose( sessionFile );
174  }
175 }
176 
177 MessageStore* FileStoreFactory::create( const SessionID& s )
178 {
179  if ( m_path.size() ) return new FileStore( m_path, s );
180 
181  std::string path;
182  Dictionary settings = m_settings.get( s );
183  path = settings.getString( FILE_STORE_PATH );
184  return new FileStore( path, s );
185 }
186 
187 void FileStoreFactory::destroy( MessageStore* pStore )
188 {
189  delete pStore;
190 }
191 
192 bool FileStore::set( int msgSeqNum, const std::string& msg )
193 throw ( IOException )
194 {
195  if ( fseek( m_msgFile, 0, SEEK_END ) )
196  throw IOException( "Cannot seek to end of " + m_msgFileName );
197  if ( fseek( m_headerFile, 0, SEEK_END ) )
198  throw IOException( "Cannot seek to end of " + m_headerFileName );
199 
200  long offset = ftell( m_msgFile );
201  if ( offset < 0 )
202  throw IOException( "Unable to get file pointer position from " + m_msgFileName );
203  std::size_t size = msg.size();
204 
205  if ( fprintf( m_headerFile, "%d,%ld,%lu ", msgSeqNum, offset, size ) < 0 )
206  throw IOException( "Unable to write to file " + m_headerFileName );
207  std::pair<NumToOffset::iterator, bool> it =
208  m_offsets.insert(NumToOffset::value_type(msgSeqNum, std::make_pair(offset, size)));
209  if (it.second == false)
210  {
211  it.first->second = std::make_pair(offset, size);
212  }
213  fwrite( msg.c_str(), sizeof( char ), msg.size(), m_msgFile );
214  if ( ferror( m_msgFile ) )
215  throw IOException( "Unable to write to file " + m_msgFileName );
216  if ( fflush( m_msgFile ) == EOF )
217  throw IOException( "Unable to flush file " + m_msgFileName );
218  if ( fflush( m_headerFile ) == EOF )
219  throw IOException( "Unable to flush file " + m_headerFileName );
220  return true;
221 }
222 
223 void FileStore::get( int begin, int end,
224  std::vector < std::string > & result ) const
225 throw ( IOException )
226 {
227  result.clear();
228  std::string msg;
229  for ( int i = begin; i <= end; ++i )
230  {
231  if ( get( i, msg ) )
232  result.push_back( msg );
233  }
234 }
235 
236 int FileStore::getNextSenderMsgSeqNum() const throw ( IOException )
237 {
239 }
240 
242 {
244 }
245 
246 void FileStore::setNextSenderMsgSeqNum( int value ) throw ( IOException )
247 {
248  m_cache.setNextSenderMsgSeqNum( value );
249  setSeqNum();
250 }
251 
252 void FileStore::setNextTargetMsgSeqNum( int value ) throw ( IOException )
253 {
254  m_cache.setNextTargetMsgSeqNum( value );
255  setSeqNum();
256 }
257 
259 {
261  setSeqNum();
262 }
263 
265 {
267  setSeqNum();
268 }
269 
271 {
272  return m_cache.getCreationTime();
273 }
274 
276 {
277  try
278  {
279  m_cache.reset();
280  open( true );
282  }
283  catch( std::exception& e )
284  {
285  throw IOException( e.what() );
286  }
287 }
288 
289 void FileStore::refresh() throw ( IOException )
290 {
291  try
292  {
293  m_cache.reset();
294  open( false );
295  }
296  catch( std::exception& e )
297  {
298  throw IOException( e.what() );
299  }
300 }
301 
303 {
304  rewind( m_seqNumsFile );
305  fprintf( m_seqNumsFile, "%10.10d : %10.10d",
307  if ( ferror( m_seqNumsFile ) )
308  throw IOException( "Unable to write to file " + m_seqNumsFileName );
309  if ( fflush( m_seqNumsFile ) )
310  throw IOException( "Unable to flush file " + m_seqNumsFileName );
311 }
312 
314 {
315  rewind( m_sessionFile );
316  fprintf( m_sessionFile, "%s",
318  if ( ferror( m_sessionFile ) )
319  throw IOException( "Unable to write to file " + m_sessionFileName );
320  if ( fflush( m_sessionFile ) )
321  throw IOException( "Unable to flush file " + m_sessionFileName );
322 }
323 
324 bool FileStore::get( int msgSeqNum, std::string& msg ) const
325 throw ( IOException )
326 {
327  NumToOffset::const_iterator find = m_offsets.find( msgSeqNum );
328  if ( find == m_offsets.end() ) return false;
329  const OffsetSize& offset = find->second;
330  if ( fseek( m_msgFile, offset.first, SEEK_SET ) )
331  throw IOException( "Unable to seek in file " + m_msgFileName );
332  char* buffer = new char[ offset.second + 1 ];
333  size_t result = fread( buffer, sizeof( char ), offset.second, m_msgFile );
334  if ( ferror( m_msgFile ) || result != (size_t)offset.second )
335  {
336  delete [] buffer;
337  throw IOException( "Unable to read from file " + m_msgFileName );
338  }
339  buffer[ offset.second ] = 0;
340  msg = buffer;
341  delete [] buffer;
342  return true;
343 }
344 
345 } //namespace FIX
FIX::FileStore::refresh
void refresh()
Definition: FileStore.cpp:306
SessionID.h
FileStore.h
FIX::file_appendpath
std::string file_appendpath(const std::string &path, const std::string &file)
Definition: Utility.cpp:568
FIX::FileStore::m_seqNumsFileName
std::string m_seqNumsFileName
Definition: FileStore.h:140
FIX::FileStore::populateCache
void populateCache()
Definition: FileStore.cpp:143
FIX::FileStore::reset
void reset()
Definition: FileStore.cpp:292
FIX::FileStore::m_sessionFileName
std::string m_sessionFileName
Definition: FileStore.h:141
FIX::FileStore::m_msgFileName
std::string m_msgFileName
Definition: FileStore.h:138
FIX::FileStore::setSession
void setSession()
Definition: FileStore.cpp:330
FIX::UtcTimeStamp
Date and Time represented in UTC.
Definition: FieldTypes.h:599
FIX::FileStoreFactory::create
MessageStore * create(const SessionID &)
Definition: FileStore.cpp:194
FIX::FileStore::incrNextTargetMsgSeqNum
void incrNextTargetMsgSeqNum()
Definition: FileStore.cpp:281
FIX::Dictionary::getString
std::string getString(const std::string &, bool capitalize=false) const
Get a value as a string.
Definition: Dictionary.cpp:49
FIX::FileStore::m_cache
MemoryStore m_cache
Definition: FileStore.h:135
FIX::FileStore::FileStore
FileStore(std::string, const SessionID &s)
Definition: FileStore.cpp:51
FIX::FileStore::m_msgFile
FILE * m_msgFile
Definition: FileStore.h:143
FIX::FileStore::~FileStore
virtual ~FileStore()
Definition: FileStore.cpp:88
FIX::MemoryStore::getNextSenderMsgSeqNum
int getNextSenderMsgSeqNum() const
Definition: MessageStore.h:121
FIX::MemoryStore::setNextTargetMsgSeqNum
void setNextTargetMsgSeqNum(int value)
Definition: MessageStore.h:127
FIX::MemoryStore::getNextTargetMsgSeqNum
int getNextTargetMsgSeqNum() const
Definition: MessageStore.h:123
FIX::ConfigError
Application is not configured correctly
Definition: Exceptions.h:104
FIX::FileStore::getNextSenderMsgSeqNum
int getNextSenderMsgSeqNum() const
Definition: FileStore.cpp:253
FIX::MemoryStore::incrNextSenderMsgSeqNum
void incrNextSenderMsgSeqNum()
Definition: MessageStore.h:129
FIX::FILE_STORE_PATH
const char FILE_STORE_PATH[]
Definition: SessionSettings.h:97
FIX::IOException
IO Error.
Definition: Exceptions.h:255
FIX::FileStore::setNextTargetMsgSeqNum
void setNextTargetMsgSeqNum(int value)
Definition: FileStore.cpp:269
FIX::FileStore::get
void get(int, int, std::vector< std::string > &) const
Definition: FileStore.cpp:240
FIX::MemoryStore::setNextSenderMsgSeqNum
void setNextSenderMsgSeqNum(int value)
Definition: MessageStore.h:125
FIX::FileStore::m_seqNumsFile
FILE * m_seqNumsFile
Definition: FileStore.h:145
FIX::FileStore::incrNextSenderMsgSeqNum
void incrNextSenderMsgSeqNum()
Definition: FileStore.cpp:275
FIX::FileStore::m_headerFileName
std::string m_headerFileName
Definition: FileStore.h:139
FIX::FileStore::m_sessionFile
FILE * m_sessionFile
Definition: FileStore.h:146
FIX::UtcTimeStampConvertor::convert
static std::string convert(const UtcTimeStamp &value, int precision=0)
Definition: FieldConvertors.h:451
FIX::file_unlink
void file_unlink(const char *path)
Definition: Utility.cpp:554
Parser.h
FIX::MemoryStore::incrNextTargetMsgSeqNum
void incrNextTargetMsgSeqNum()
Definition: MessageStore.h:131
FIX::file_mkdir
void file_mkdir(const char *path)
Definition: Utility.cpp:506
FIX
Definition: Acceptor.cpp:34
FIX::FileStore::getNextTargetMsgSeqNum
int getNextTargetMsgSeqNum() const
Definition: FileStore.cpp:258
FIX::FileStore::getCreationTime
UtcTimeStamp getCreationTime() const
Definition: FileStore.cpp:287
FIX::MemoryStore::getCreationTime
UtcTimeStamp getCreationTime() const
Definition: MessageStore.h:136
FIX::MemoryStore::reset
void reset()
Definition: MessageStore.h:139
FIX::FileStoreFactory::m_path
std::string m_path
Definition: FileStore.h:67
FIX::FileStore::setSeqNum
void setSeqNum()
Definition: FileStore.cpp:319
FIX::file_fopen
FILE * file_fopen(const char *path, const char *mode)
Definition: Utility.cpp:526
FIX::FileStore::m_offsets
NumToOffset m_offsets
Definition: FileStore.h:136
FILE_FSCANF
#define FILE_FSCANF
Definition: Utility.h:215
FIX::MemoryStore::setCreationTime
void setCreationTime(const UtcTimeStamp &creationTime)
Definition: MessageStore.h:134
FIX::FileStore::open
void open(bool deleteFile)
Definition: FileStore.cpp:96
FIX::FileStoreFactory::m_settings
SessionSettings m_settings
Definition: FileStore.h:68
FIX::FileStore::set
bool set(int, const std::string &)
Definition: FileStore.cpp:209
Utility.h
FIX::SessionSettings::get
const Dictionary & get(const SessionID &) const
Get a dictionary for a session.
Definition: SessionSettings.cpp:144
FIX::FileStoreFactory::destroy
void destroy(MessageStore *)
Definition: FileStore.cpp:204
FIX::FileStore::setNextSenderMsgSeqNum
void setNextSenderMsgSeqNum(int value)
Definition: FileStore.cpp:263
FIX::FileStore::m_headerFile
FILE * m_headerFile
Definition: FileStore.h:144

Generated on Wed Apr 29 2020 19:41:30 for QuickFIX by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2001