⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gsm_sorted_sms_store.cc

📁 对各种手机进行编程的工具包源码gsmlib 1.9版本。
💻 CC
字号:
// *************************************************************************// * GSM TA/ME library// *// * File:    gsm_sorted_sms_store.cc// *// * Purpose: Sorted SMS store (residing in files or in the ME)// *// * Author:  Peter Hofmann (software@pxh.de)// *// * Created: 14.8.1999// *************************************************************************#ifdef HAVE_CONFIG_H#include <gsm_config.h>#endif#include <gsmlib/gsm_nls.h>#include <gsmlib/gsm_sysdep.h>#include <gsmlib/gsm_sorted_sms_store.h>#include <iostream>#include <fstream>#ifdef HAVE_NETINET_IN_H#include <netinet/in.h>#endifusing namespace std;using namespace gsmlib;// SMS message file format:// version number of file format, unsigned short int, 2 bytes in network byte// order// then comes the message:// 1. length of PDU (see 4. below): unsigned short int,//    2 bytes in network byte order// 2. index of message, unique for this file: unsigned long,//    4 bytes in network byte order// 3. MessageType (1 byte), any of://    0 SMS_DELIVER//    1 SMS_SUBMIT//    2 SMS_STATUS_REPORT// 4. PDU in hexadecimal formatstatic const unsigned short int SMS_STORE_FILE_FORMAT_VERSION = 1;// SortedSMSStore members// aux function read bytes with error handling// return false if EOFstatic bool readnbytes(string &filename,                       istream &is, int len, char *buf,                       bool eofIsError = true) throw(GsmException){  is.read(buf, len);  if (is.bad() || (is.eof() && eofIsError))    throw GsmException(stringPrintf(_("error reading from file '%s'"),                                    (filename == "" ? _("<STDIN>") :                                     filename.c_str())), OSError);  return ! is.eof();}// aux function write bytes with error handlingstatic void writenbytes(string &filename, ostream &os,                        int len, const char *buf) throw(GsmException){  os.write(buf, len);  if (os.bad())    throw GsmException(stringPrintf(_("error writing to file '%s'"),                                    (filename == "" ? _("<STDOUT>") :                                     filename.c_str())), OSError);}void SortedSMSStore::readSMSFile(istream &pbs, string filename)  throw(GsmException){  char numberBuf[4];  // check the version  try  {    readnbytes(filename, pbs, 2, numberBuf);  }  catch (GsmException &ge)  {    // ignore error, file might be empty initially  }  unsigned_int_2 version = ntohs(*((unsigned_int_2*)numberBuf));  if (! pbs.eof() && version != SMS_STORE_FILE_FORMAT_VERSION)    throw GsmException(stringPrintf(_("file '%s' has wrong version"),                                    filename.c_str()), ParameterError);  // read entries  while (1)  {    // read PDU length and exit loop if EOF    if (! readnbytes(filename, pbs, 2, numberBuf, false))      break;    unsigned_int_2 pduLen = ntohs(*((unsigned_int_2*)numberBuf));    if (pduLen > 500)      throw GsmException(stringPrintf(_("corrupt SMS store file '%s'"),                                      filename.c_str()), ParameterError);    // read reserved integer field of message (was formerly index)    readnbytes(filename, pbs, 4, numberBuf);    //unsigned_int_4 reserved = ntohl(*((unsigned_int_4*)numberBuf));        // read message type    readnbytes(filename, pbs, 1, numberBuf);    SMSMessage::MessageType messageType =      (SMSMessage::MessageType)numberBuf[0];    if (messageType > 2)      throw GsmException(stringPrintf(_("corrupt SMS store file '%s'"),                                      filename.c_str()), ParameterError);    char *pduBuf = (char*)alloca(sizeof(char) * pduLen);    // read pdu    readnbytes(filename, pbs, pduLen, pduBuf);    SMSMessageRef message =      SMSMessage::decode(string(pduBuf, pduLen),                         (messageType != SMSMessage::SMS_SUBMIT));        SMSStoreEntry *newEntry = new SMSStoreEntry(message, _nextIndex++);    _sortedSMSStore.insert(      SMSStoreMap::value_type(        SMSMapKey(*this, message->serviceCentreTimestamp()),        newEntry)      );  }}void SortedSMSStore::sync(bool fromDestructor) throw(GsmException){  if (_fromFile && _changed)  {    checkReadonly();    // if writing to stdout and not called from destructor ignore    // (avoids writing to stdout multiple times)    if (_filename == "" && ! fromDestructor) return;    // create backup file - but only once    if (! _madeBackupFile && _filename != "") // don't make backup of stdout    {      renameToBackupFile(_filename);      _madeBackupFile = true;    }    // open stream    ostream *pbs = NULL;    try    {      if (_filename == "")        pbs = &cout;      else		pbs = new ofstream(_filename.c_str(), ios::out | ios::binary);            if (pbs->bad())        throw GsmException(          stringPrintf(_("error opening file '%s' for writing"),                       (_filename == "" ? _("<STDOUT>") :                        _filename.c_str())),          OSError);      // write version number      unsigned_int_2 version = htons(SMS_STORE_FILE_FORMAT_VERSION);      writenbytes(_filename, *pbs, 2, (char*)&version);      // and write the entries      for (SMSStoreMap::iterator i = _sortedSMSStore.begin();           i != _sortedSMSStore.end(); ++i)      {        // create PDU and write length        string pdu = i->second->message()->encode();        unsigned_int_2 pduLen = htons(pdu.length());        writenbytes(_filename, *pbs, 2, (char*)&pduLen);        // write reserved field (was formerly index)        unsigned_int_4 reserved = htonl(0);        writenbytes(_filename, *pbs, 4, (char*)&reserved);                // write message type        char messageType = i->second->message()->messageType();        writenbytes(_filename, *pbs, 1, (char*)&messageType);        // write PDU        writenbytes(_filename, *pbs, pdu.length(), pdu.data());      }    }    catch(GsmException &e)    {      if (pbs != &cout) delete pbs;      throw;    }    // close file    if (pbs != &cout) delete pbs;    _changed = false;  }}void SortedSMSStore::checkReadonly() throw(GsmException){  if (_readonly) throw GsmException(    _("attempt to change SMS store read from <STDIN>"),    ParameterError);}SortedSMSStore::SortedSMSStore(string filename) throw(GsmException) :  _changed(false), _fromFile(true), _madeBackupFile(false),  _sortOrder(ByDate), _readonly(false), _filename(filename), _nextIndex(0){  // open the file  ifstream pbs(filename.c_str(), ios::in | ios::binary);  if (pbs.bad())    throw GsmException(stringPrintf(_("cannot open file '%s'"),                                    filename.c_str()), OSError);  // and read the file  readSMSFile(pbs, filename);}SortedSMSStore::SortedSMSStore(bool fromStdin) throw(GsmException) :  _changed(false), _fromFile(true), _madeBackupFile(false),  _sortOrder(ByDate), _readonly(fromStdin), _nextIndex(0)  // _filename is "" - this means stdout{  // read from stdin  if (fromStdin)    readSMSFile(cin, (string)_("<STDIN>"));}SortedSMSStore::SortedSMSStore(SMSStoreRef meSMSStore)  throw(GsmException) :  _changed(false), _fromFile(false), _madeBackupFile(false),  _sortOrder(ByDate), _readonly(false), _meSMSStore(meSMSStore){  // It is necessary to count the entries read because  // the maximum index into the SMS store may be larger than smsStore.size()  int entriesRead = 0;  reportProgress(0, _meSMSStore->size());  for (int i = 0;; ++i)  {    if (entriesRead == _meSMSStore->size())      break;                 // ready    if (! _meSMSStore()[i].empty())    {      _sortedSMSStore.insert(        SMSStoreMap::value_type(          SMSMapKey(*this,                    _meSMSStore()[i].message()->serviceCentreTimestamp()),          &_meSMSStore()[i])        );      ++entriesRead;      reportProgress(entriesRead);    }  }}void SortedSMSStore::setSortOrder(SortOrder newOrder){  if (_sortOrder == newOrder) return; // nothing to be done  SMSStoreMap savedSMSStore = _sortedSMSStore;  _sortedSMSStore = SMSStoreMap();  _sortOrder = newOrder;  switch (newOrder)  {  case ByIndex:  {    for (SMSStoreMap::iterator i = savedSMSStore.begin();         i != savedSMSStore.end(); ++i)      _sortedSMSStore.insert(        SMSStoreMap::value_type(SMSMapKey(*this, (i->second->index())),                                i->second));    break;  }  case ByDate:  {    for (SMSStoreMap::iterator i = savedSMSStore.begin();         i != savedSMSStore.end(); ++i)      _sortedSMSStore.insert(        SMSStoreMap::value_type(          SMSMapKey(*this, (i->second->message()->serviceCentreTimestamp())),          i->second));    break;  }  case ByAddress:  {    for (SMSStoreMap::iterator i = savedSMSStore.begin();         i != savedSMSStore.end(); ++i)      _sortedSMSStore.insert(        SMSStoreMap::value_type(          SMSMapKey(*this, (i->second->message()->address())),          i->second));    break;  }  case ByType:  {    for (SMSStoreMap::iterator i = savedSMSStore.begin();         i != savedSMSStore.end(); ++i)      _sortedSMSStore.insert(        SMSStoreMap::value_type(          SMSMapKey(*this, (i->second->message()->messageType())),          i->second));    break;  }  default:    assert(0);    break;  }}int SortedSMSStore::max_size() const{  if (_fromFile)    return _sortedSMSStore.max_size();  else    return _meSMSStore->max_size();}int SortedSMSStore::capacity() const{  if (_fromFile)    return _sortedSMSStore.max_size();  else    return _meSMSStore->capacity();}SortedSMSStore::iteratorSortedSMSStore::insert(const SMSStoreEntry& x) throw(GsmException){  checkReadonly();  _changed = true;  SMSStoreEntry *newEntry;  if (_fromFile)    newEntry = new SMSStoreEntry(x.message(), _nextIndex++);  else  {    SMSStoreEntry newMEEntry(x.message());    newEntry = _meSMSStore->insert(newMEEntry);  }    switch (_sortOrder)  {  case ByIndex:    return      _sortedSMSStore.      insert(SMSStoreMap::value_type(SMSMapKey(*this, newEntry->index()),                                     newEntry));    break;  case ByDate:    return      _sortedSMSStore.      insert(SMSStoreMap::value_type(        SMSMapKey(*this, newEntry->message()->serviceCentreTimestamp()),        newEntry));    break;  case ByAddress:    return      _sortedSMSStore.      insert(SMSStoreMap::value_type(        SMSMapKey(*this, newEntry->message()->address()),        newEntry));    break;  case ByType:    return      _sortedSMSStore.      insert(SMSStoreMap::value_type(        SMSMapKey(*this, newEntry->message()->messageType()),        newEntry));    break;  default:    assert(0);    break;  }  return SortedSMSStore::iterator();}SortedSMSStore::iteratorSortedSMSStore::insert(iterator position, const SMSStoreEntry& x)  throw(GsmException){  return insert(x);}SortedSMSStore::size_type SortedSMSStore::erase(Address &key)  throw(GsmException){  assert(_sortOrder == ByAddress);  SMSMapKey mapKey(*this, key);  // deallocate memory or remove from underlying ME SMS store  for (SMSStoreMap::iterator i = _sortedSMSStore.find(mapKey);       i != _sortedSMSStore.end() && i->first == mapKey; ++i)  {    checkReadonly();    _changed = true;    if (_fromFile)      delete i->second;    else      _meSMSStore->erase((SMSStore::iterator)i->second);  }  return _sortedSMSStore.erase(mapKey);}SortedSMSStore::size_type SortedSMSStore::erase(int key)  throw(GsmException){  assert(_sortOrder == ByIndex || _sortOrder == ByType);  SMSMapKey mapKey(*this, key);  // deallocate memory or remove from underlying ME SMS store  for (SMSStoreMap::iterator i = _sortedSMSStore.find(mapKey);       i != _sortedSMSStore.end() && i->first == mapKey; ++i)  {    checkReadonly();    _changed = true;    if (_fromFile)      delete i->second;    else      _meSMSStore->erase((SMSStore::iterator)i->second);  }  return _sortedSMSStore.erase(mapKey);}SortedSMSStore::size_type SortedSMSStore::erase(Timestamp &key)  throw(GsmException){  assert(_sortOrder == ByDate);  SMSMapKey mapKey(*this, key);  // deallocate memory or remove from underlying ME SMS store  for (SMSStoreMap::iterator i = _sortedSMSStore.find(mapKey);       i != _sortedSMSStore.end() && i->first == mapKey; ++i)  {    checkReadonly();    _changed = true;    if (_fromFile)      delete i->second;    else      _meSMSStore->erase((SMSStore::iterator)i->second);  }  return _sortedSMSStore.erase(mapKey);}void SortedSMSStore::erase(iterator position)  throw(GsmException){  checkReadonly();  _changed = true;  // deallocate memory or remove from underlying ME SMS store  if (_fromFile)    delete ((SMSStoreMap::iterator)position)->second;  else    _meSMSStore->erase((SMSStore::iterator)                       ((SMSStoreMap::iterator)position)->second);  _sortedSMSStore.erase(position);}void SortedSMSStore::erase(iterator first, iterator last)  throw(GsmException){  checkReadonly();  _changed = true;  for (SMSStoreMap::iterator i = first; i != last; ++i)    if (_fromFile)      delete i->second;    else      _meSMSStore->erase((SMSStore::iterator)i->second);  _sortedSMSStore.erase(first, last);}void SortedSMSStore::clear() throw(GsmException){  checkReadonly();  _changed = true;  for (iterator i = begin(); i != end(); i++)    erase(i);}SortedSMSStore::~SortedSMSStore(){  if (_fromFile)  {    sync(true);    for (SMSStoreMap::iterator i = _sortedSMSStore.begin();         i != _sortedSMSStore.end(); ++i)      delete i->second;  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -