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

📄 posixstorage.cxx

📁 SP是一个基于GNU C++编译器
💻 CXX
📖 第 1 页 / 共 2 页
字号:
// Copyright (c) 1994, 1995 James Clark// See the file COPYING for copying permission.#ifdef __GNUG__#pragma implementation#endif#include "splib.h"#include "PosixStorage.h"#include "RewindStorageObject.h"#include "StorageManager.h"#include "DescriptorManager.h"#include "MessageArg.h"#include "ErrnoMessageArg.h"#include "SearchResultMessageArg.h"#include "Message.h"#include "StringC.h"#include "StringOf.h"#include "CharsetInfo.h"#include "CodingSystem.h"#include "macros.h"#include "PosixStorageMessages.h"#include <sys/types.h>#include <stdio.h>#include <ctype.h>#ifdef SP_INCLUDE_IO_H#include <io.h>		// for open, fstat, lseek, read prototypes#endif#ifdef SP_INCLUDE_UNISTD_H#include <unistd.h>#endif#ifdef SP_INCLUDE_OSFCN_H#include <osfcn.h>#endif#include <fcntl.h>#include <sys/stat.h>#include <errno.h>#include <stddef.h>#ifndef S_ISREG#ifndef S_IFREG#define S_IFREG _S_IFREG#endif#ifndef S_IFMT#define S_IFMT _S_IFMT#endif#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)#endif /* not S_ISREG */#ifndef O_BINARY#define O_BINARY 0#endif#ifdef SP_WIDE_SYSTEM#include <windows.h>#endif#ifdef SP_NAMESPACEnamespace SP_NAMESPACE {#endif#ifdef SP_WIDE_SYSTEMtypedef wchar_t FChar;#elsetypedef char FChar;#endifclass PosixBaseStorageObject : public RewindStorageObject {public:  PosixBaseStorageObject(int fd, Boolean mayRewind);  size_t getBlockSize() const;protected:  enum { defaultBlockSize = 8192 };  int fd_;  PackedBoolean eof_;  Boolean seekToStart(Messenger &);  virtual Boolean seek(off_t, Messenger &) = 0;  static int xclose(int fd);private:  Boolean canSeek(int fd);  off_t startOffset_;};PosixBaseStorageObject::PosixBaseStorageObject(int fd, Boolean mayRewind): fd_(fd), eof_(0),  RewindStorageObject(mayRewind, mayRewind && canSeek(fd)){}Boolean PosixBaseStorageObject::canSeek(int fd){  struct stat sb;  if (fstat(fd, &sb) < 0 || !S_ISREG(sb.st_mode)      || (startOffset_ = lseek(fd, off_t(0), SEEK_CUR)) < 0)    return 0;  else    return 1;}Boolean PosixBaseStorageObject::seekToStart(Messenger &mgr){  eof_ = 0;  return seek(startOffset_, mgr);}int PosixBaseStorageObject::xclose(int fd){  int ret;  do {    ret = ::close(fd);  } while (ret < 0 && errno == EINTR);  return ret;}class PosixStorageObject : public PosixBaseStorageObject, private DescriptorUser {public:  PosixStorageObject(int fd,		     const StringC &,		     const String<FChar> &,		     Boolean mayRewind,		     DescriptorManager *);  ~PosixStorageObject();  Boolean read(char *buf, size_t bufSize, Messenger &mgr, size_t &nread);  Boolean suspend();  Boolean seek(off_t, Messenger &);  void willNotRewind();private:  void resume(Messenger &);  PackedBoolean suspended_;  off_t suspendPos_;  const MessageType2 *suspendFailedMessage_;  int suspendErrno_;  StringC filename_;  String<FChar> cfilename_;  void systemError(Messenger &, const MessageType2 &, int);};inline int openFile(const FChar *s) {#ifdef SP_WIDE_SYSTEM   int fd = _wopen(s, O_RDONLY|O_BINARY);   if (fd < 0 && errno != ENOENT) {     String<char> buf;     int len = WideCharToMultiByte(CP_ACP, 0, s, -1, 0, 0, 0, 0);     buf.resize(len + 1);     WideCharToMultiByte(CP_ACP, 0, s, -1, buf.begin(), len, 0, 0);     buf[len] = '\0';     return ::open(buf.data(), O_RDONLY|O_BINARY);   }   return fd;#else    return ::open(s, O_RDONLY|O_BINARY);#endif  }PosixStorageManager::PosixStorageManager(const char *type,					 const CharsetInfo *filenameCharset,#ifndef SP_WIDE_SYSTEM					 const OutputCodingSystem *filenameCodingSystem,#endif					 int maxFDs): IdStorageManager(filenameCharset),  type_(type),#ifndef SP_WIDE_SYSTEM  filenameCodingSystem_(filenameCodingSystem),#endif  descriptorManager_(maxFDs){  Char newline = idCharset()->execToDesc('\n');  reString_.assign(&newline, 1);}const char *PosixStorageManager::type() const{  return type_;}void PosixStorageManager::addSearchDir(const StringC &str){  searchDirs_.push_back(str);}#ifdef SP_POSIX_FILENAMES#define FILENAME_TYPE_DEFINED// FIXME should use idCharset.Boolean PosixStorageManager::isAbsolute(const StringC &file) const{  return file.size() > 0 && file[0] == '/';}StringC PosixStorageManager::extractDir(const StringC &str) const{  for (size_t i = str.size(); i > 0; i--)    if (str[i - 1] == '/')      return StringC(str.data(), i);	// include slash for root case  return StringC();}StringC PosixStorageManager::combineDir(const StringC &dir,					const StringC &base) const{  StringC result(dir);  if (dir.size() > 0 && dir[dir.size() - 1] != '/')    result += '/';  result += base;  return result;}Boolean PosixStorageManager::transformNeutral(StringC &str, Boolean fold,					      Messenger &) const{  if (fold)    for (size_t i = 0; i < str.size(); i++) {      Char c = str[i];      if (c <= (unsigned char)-1)	str[i] = tolower(str[i]);    }  return 1;}#endif /* SP_POSIX_FILENAMES */#ifdef SP_MSDOS_FILENAMES#define FILENAME_TYPE_DEFINEDBoolean PosixStorageManager::isAbsolute(const StringC &s) const{  if (s.size() == 0)    return 0;  return s[0] == '/' || s[0] == '\\' || (s.size() > 1 && s[1] == ':');}StringC PosixStorageManager::extractDir(const StringC &str) const{  for (size_t i = str.size(); i > 0; i--)    if (str[i - 1] == '/' || str[i - 1] == '\\'	|| (i == 2  && str[i - 1] == ':'))      return StringC(str.data(), i);	// include separator  return StringC();}StringC PosixStorageManager::combineDir(const StringC &dir,					const StringC &base) const{  StringC result(dir);  if (dir.size() > 0) {    Char lastChar = dir[dir.size() - 1];    if (lastChar != '/' && lastChar != '\\'	&& !(dir.size() == 2 && lastChar == ':'))    result += '\\';  }  result += base;  return result;}Boolean PosixStorageManager::transformNeutral(StringC &str, Boolean,					      Messenger &) const{  for (size_t i = 0; i < str.size(); i++)    if (str[i] == '/')      str[i] = '\\';  return 1;}#endif /* SP_MSDOS_FILENAMES */#ifdef SP_MAC_FILENAMES// Colons separate directory names// relative path-names start with a colon, or have no colons// absolute path-names don't start with a colon and have at least one colon#define FILENAME_TYPE_DEFINEDBoolean PosixStorageManager::isAbsolute(const StringC &s) const{  if (s.size() == 0)    return 0;  if (s[0] == ':')    return 0;	// starts with a colon => relative  size_t ss = s.size();  for (size_t i = 0; i < ss; i++)    if (s[i] == ':')      return 1; // absolute  return 0; // no colons => relative}StringC PosixStorageManager::extractDir(const StringC &str) const{  for (size_t i = str.size(); i > 0; i--)    if (str[i - 1] == ':')      return StringC(str.data(), i);	// include separator  return StringC();}StringC PosixStorageManager::combineDir(const StringC &dir,					const StringC &base) const{  StringC result(dir);  if (dir.size() > 0) {    Char lastChar = dir[dir.size() - 1];    if (lastChar != ':')    result += ':';  }  if (base[0] == ':') {    StringC newbase(base.data() + 1,base.size() - 1);    result += newbase;  }  else result += base;  return result;}Boolean PosixStorageManager::transformNeutral(StringC &str, Boolean,					      Messenger &) const{  if (str[0] == '/') {	// absolute    StringC nstr(str.data() + 1,str.size()-1);    str = nstr;  }  else {	// relative    Char cc = ':';    StringC colon(&cc,1);    str.insert(0,colon);  }  for (size_t i = 0; i < str.size(); i++)    if (str[i] == '/')      str[i] = ':';  return 1;}#endif /* SP_MAC_FILENAMES */#ifndef FILENAME_TYPE_DEFINEDBoolean PosixStorageManager::isAbsolute(const StringC &) const{  return 1;}StringC PosixStorageManager::extractDir(const StringC &) const{  return StringC();}StringC PosixStorageManager::combineDir(const StringC &,					const StringC &base) const{  return base;}

⌨️ 快捷键说明

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