WEB开发网
开发学院软件开发VC FMD开发文集 -- CArchive原理 阅读

FMD开发文集 -- CArchive原理

 2010-03-28 20:34:54 来源:WEB开发网   
核心提示:六.字符串的读写①CArchive提供的WriteString和ReadString字符串写void CArchive::WriteString(LPCTSTR lpsz){ASSERT(AfxIsValidString(lpsz));Write(lpsz, lstrlen(lpsz) * sizeof(TCHAR))

六.字符串的读写

①CArchive提供的WriteString和ReadString

字符串写void CArchive::WriteString(LPCTSTR lpsz)
{
  ASSERT(AfxIsValidString(lpsz));
  Write(lpsz, lstrlen(lpsz) * sizeof(TCHAR)); //调用Write,将字符串对应的一段数据写入
}
字符串读(读取一行字符串)LPTSTR CArchive::ReadString(LPTSTR lpsz, UINT nMax)
{
  // if nMax is negative (such a large number doesn''t make sense given today''s
  // 2gb address space), then assume it to mean "keep the newline".
  int nStop = (int)nMax < 0 ? -(int)nMax : (int)nMax;
  ASSERT(AfxIsValidAddress(lpsz, (nStop+1) * sizeof(TCHAR)));
  _TUCHAR ch;
  int nRead = 0;
  TRY
  {
    while (nRead < nStop)
    {
      *this >> ch; //读出一个字节
      // stop and end-of-line (trailing ''
'' is ignored) 遇换行—回车
      if (ch == ''
'' || ch == ''
'')
      {
        if (ch == ''
'')
          *this >> ch;
        // store the newline when called with negative nMax
        if ((int)nMax != nStop)
          lpsz[nRead++] = ch;
        break;
      }
      lpsz[nRead++] = ch;
    }
  }
  CATCH(CArchiveException, e)
  {
    if (e-> m_cause == CArchiveException::endOfFile)
    {
      DELETE_EXCEPTION(e);
      if (nRead == 0)
        return NULL;
    }
    else
    {
      THROW_LAST();
    }
  }
  END_CATCH
  lpsz[nRead] = '''';
  return lpsz;
}
ReadString到CString对象,可以多行字符BOOL CArchive::ReadString(CString& rString)
{
  rString = &afxChNil;  // empty string without deallocating
  const int nMaxSize = 128;
  LPTSTR lpsz = rString.GetBuffer(nMaxSize);
  LPTSTR lpszResult;
  int nLen;
  for (;;)
  {
    lpszResult = ReadString(lpsz, (UINT)-nMaxSize); // store the newline
    rString.ReleaseBuffer();
    // if string is read completely or EOF
    if (lpszResult == NULL ||
      (nLen = lstrlen(lpsz)) < nMaxSize ||
      lpsz[nLen-1] == ''
'')
    {
      break;
    }
    nLen = rString.GetLength();
    lpsz = rString.GetBuffer(nMaxSize + nLen) + nLen;
  }
  // remove ''
'' from end of string if present
  lpsz = rString.GetBuffer(0);
  nLen = rString.GetLength();
  if (nLen != 0 && lpsz[nLen-1] == ''
'')
    rString.GetBufferSetLength(nLen-1);
  return lpszResult != NULL;
}
②使用CString对象的"<<"与">>"符读写字符串

CString定义了输入输出符,可以象基本类型的数据一样使用CArchive 的操作符定义

friend CArchive& AFXAPI operator<<(CArchive& ar, const CString& string);
friend CArchive& AFXAPI operator>>(CArchive& ar, CString& string);
// CString serialization code
// String format:
//   UNICODE strings are always prefixed by 0xff, 0xfffe
//   if < 0xff chars: len:BYTE, TCHAR chars
//   if >= 0xff characters: 0xff, len:WORD, TCHAR chars
//   if >= 0xfffe characters: 0xff, 0xffff, len:DWORD, TCHARs
CArchive& AFXAPI operator<<(CArchive& ar, const CString& string)
{
  // special signature to recognize unicode strings
#ifdef _UNICODE
  ar << (BYTE)0xff;
  ar << (WORD)0xfffe;
#endif
  if (string.GetData()-> nDataLength < 255)
  {
    ar << (BYTE)string.GetData()-> nDataLength;
  }
  else if (string.GetData()-> nDataLength < 0xfffe)
  {
    ar << (BYTE)0xff;
    ar << (WORD)string.GetData()-> nDataLength;
  }
  else
  {
    ar << (BYTE)0xff;
    ar << (WORD)0xffff;
    ar << (DWORD)string.GetData()-> nDataLength;
  }
  ar.Write(string.m_pchData, string.GetData()-> nDataLength*sizeof(TCHAR));
  return ar;
}
// return string length or -1 if UNICODE string is found in the archive
AFX_STATIC UINT AFXAPI _AfxReadStringLength(CArchive& ar)
{
  DWORD nNewLen;
  // attempt BYTE length first
  BYTE bLen;
  ar >> bLen;
  if (bLen < 0xff)
    return bLen;
  // attempt WORD length
  WORD wLen;
  ar >> wLen;
  if (wLen == 0xfffe)
  {
    // UNICODE string prefix (length will follow)
    return (UINT)-1;
  }
  else if (wLen == 0xffff)
  {
    // read DWORD of length
    ar >> nNewLen;
    return (UINT)nNewLen;
  }
  else
    return wLen;
}
CArchive& AFXAPI operator>>(CArchive& ar, CString& string)
{
#ifdef _UNICODE
  int nConvert = 1;  // if we get ANSI, convert
#else
  int nConvert = 0;  // if we get UNICODE, convert
#endif
  UINT nNewLen = _AfxReadStringLength(ar);
  if (nNewLen == (UINT)-1)
  {
    nConvert = 1 - nConvert;
    nNewLen = _AfxReadStringLength(ar);
    ASSERT(nNewLen != -1);
  }
  // set length of string to new length
  UINT nByteLen = nNewLen;
#ifdef _UNICODE
  string.GetBufferSetLength((int)nNewLen);
  nByteLen += nByteLen * (1 - nConvert); // bytes to read
#else
  nByteLen += nByteLen * nConvert;  // bytes to read
  if (nNewLen == 0)
    string.GetBufferSetLength(0);
  else
    string.GetBufferSetLength((int)nByteLen+nConvert);
#endif
  // read in the characters
  if (nNewLen != 0)
  {
    ASSERT(nByteLen != 0);
    // read new data
    if (ar.Read(string.m_pchData, nByteLen) != nByteLen)
      AfxThrowArchiveException(CArchiveException::endOfFile);
    // convert the data if as necessary
    if (nConvert != 0)
    {
#ifdef _UNICODE
      CStringData* pOldData = string.GetData();
      LPSTR lpsz = (LPSTR)string.m_pchData;
#else
      CStringData* pOldData = string.GetData();
      LPWSTR lpsz = (LPWSTR)string.m_pchData;
#endif
      lpsz[nNewLen] = '''';  // must be NUL terminated
      string.Init();  // don''t delete the old data
      string = lpsz;  // convert with operator=(LPWCSTR)
      CString::FreeData(pOldData);
    }
  }
  return ar;
}

上一页  1 2 3 4 5 6  下一页

Tags:FMD 开发 文集

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接