//================================================================================================== // S t a n d a r d Interface // S t r e a m // By Bruno Bachelet //================================================================================================== // Copyright (c) 1999-2016 // Bruno Bachelet - bruno@nawouak.net - http://www.nawouak.net // // This file is part of the B++ Library. This library is free software; you can redistribute it // and/or modify it under the terms of the GNU Library General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at your option) any later // version. // // This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See // the GNU Library General Public License for more details (http://www.gnu.org).
/*DESCRIPTION*/ /* This module provides facilities to manage streams, files and folders. */
// File Name //------------------------------------------------------------------------------------- #line __LINE__ "standard/stream.hpp"
// Guardian //-------------------------------------------------------------------------------------- #ifndef guStandardStream #define guStandardStream
// Headers //--------------------------------------------------------------------------------------- #include <bpp/dependency.hpp> /*INCLUDE*/
#ifdef DIR_HEADER_1 #include DIR_HEADER_1 /*INCLUDE*/ #endif
#ifdef DIR_HEADER_2 #include DIR_HEADER_2 /*INCLUDE*/ #endif
#ifndef NEED_FOLDER_MANAGEMENT #include <dirent.h> /*INCLUDE*/ #endif
#include <bpp/standard/error.hpp> /*INCLUDE*/ #include <contribution/string.hpp> /*INCLUDE*/
// Portability //----------------------------------------------------------------------------------- #ifdef MKDIR_COMMAND inline int mkdir(const char * agPath) { char * lcCommand; int lcReturn;
lcCommand = new char [bpp::low::string::length(agPath)+bpp::low::string::length(MKDIR_COMMAND)+2]; bpp::low::string::copy(lcCommand,MKDIR_COMMAND); bpp::low::string::concatenate(lcCommand," "); bpp::low::string::concatenate(lcCommand,agPath); lcReturn=system(lcCommand); return (lcReturn); } #endif
#ifdef RMDIR_COMMAND inline int rmdir(const char * agPath) { char * lcCommand; int lcReturn;
lcCommand=new char [bpp::low::string::length(agPath)+bpp::low::string::length(RMDIR_COMMAND)+2]; bpp::low::string::copy(lcCommand,RMDIR_COMMAND); bpp::low::string::concatenate(lcCommand," "); bpp::low::string::concatenate(lcCommand,agPath); lcReturn=system(lcCommand); delete [] lcCommand; return (lcReturn); } #endif
#ifdef MKDIR_CALL inline int mkdir(const char * agPath) { return (MKDIR_CALL(agPath)); } #endif
#ifdef RMDIR_CALL inline int rmdir(const char * agPath) { return (RMDIR_CALL(agPath)); } #endif
namespace bpp {
// Importation/Exportation //----------------------------------------------------------------------- #ifdef STANDARD_DLL #define dll_export DLL_EXPORT #else #define dll_export DLL_IMPORT #endif
// Namespaces //------------------------------------------------------------------------------------ #define public_area standardStream #define private_area standardStream_private
namespace public_area { /*NAMESPACE*/ using namespace standardBasicString; /*NAMESPACE*/ using namespace standardError; }
namespace private_area { using namespace public_area; }
extern_module_name;
// Initialization //-------------------------------------------------------------------------------- #define iniStandardStream has_initializer;
// Macrocommands //---------------------------------------------------------------------------------
// Types & Classes //------------------------------------------------------------------------------- namespace public_area { //------------------------------------------------------------------------------------------Classes class clFolderProcessing; //-----------------------------------------------------------------------------------Variable Types /*TYPE*/ /* Input file. */ typedef std::ifstream clInFile;
/*TYPE*/ /* Output file. */ typedef std::ofstream clOutFile;
/*TYPE*/ /* Input stream. */ typedef std::istream clInStream;
/*TYPE*/ /* Output stream. */ typedef std::ostream clOutStream;
/*TYPE*/ /* Input and output stream. */ typedef std::iostream clStream;
/*TYPE*/ /* List of file names. */ typedef std_vector(clString) clFileNameS;
#ifndef NEED_FOLDER_MANAGEMENT /*TYPE*/ /* Represents a folder (in the case that the <CODE>DIR</CODE> structure exists). */ typedef DIR * tyFolder; #endif
/*TYPE*/ /* Opening mode of a file. */ typedef FILE_OPENING_MODE_TYPE tyFileMode;
/*TYPE*/ /* Relative position in a stream. */ typedef std::streamoff tyStreamOffset;
/*TYPE*/ /* Absolute position in a stream. */ typedef std::streampos tyStreamPosition;
/*TYPE*/ /* Size in a stream. */ typedef std::streamsize tyStreamSize;
/*TYPE*/ /* Symbolic constants for the kinds of entity in a folder. */ enumeration { unknownEntity, fileEntity, folderEntity, referenceEntity } tyDiskEntityKind; //-----------------------------------------------------------------------------------Constant Types typedef const clFolderProcessing ctFolderProcessing;
typedef const clInFile ctInFile; typedef const clOutFile ctOutFile; typedef const clInStream ctInStream; typedef const clOutStream ctOutStream; typedef const clStream ctStream; typedef const clFileNameS ctFileNameS;
typedef const tyFolder ctFolder;
typedef const tyFileMode tcFileMode; typedef const tyStreamOffset tcStreamOffset; typedef const tyStreamPosition tcStreamPosition;
typedef const tyDiskEntityKind tcDiskEntityKind; }
namespace private_area { class clFolderProcessingCopy; class clFolderProcessingDelete; class clFolderProcessingGetFileList; class clFolderProcessingList;
typedef const clFolderProcessingList ctFolderProcessingCopy; typedef const clFolderProcessingList ctFolderProcessingDelete; typedef const clFolderProcessingList ctFolderProcessingList;
typedef std_map(tyPointer,clString *) clPrimaryFileRegister; typedef std_vector(clString *) clSecondaryFileRegister; }
// Functions Interface //--------------------------------------------------------------------------- namespace public_area { inline tyBoolean isFileNameSeparator(tyCharacter); inline tyBoolean isFileNameSeparator(tcString);
inline void close(clInFile &); inline void close(clOutFile &); inline void open(clInFile &,tcString,tyFileMode); inline void open(clOutFile &,tcString,tyFileMode);
function void buildFileName(clString &); function void buildFolderName(clString &); function void buildFullName(clString &,ctString &,ctString &); function void extractShortName(clString &,clString &,ctString &); function void separateFileName(clString &,clString &,ctString &);
function void copy(clOutStream &,clInStream &,tyBoolean);
function tyBoolean fileExists(tcString); function tyInteger fileSize(tcString); function tyBoolean folderExists(tcString); function tyInteger size(clInFile &);
function void changeName(tcString,tcString); function void createFolder(tcString); function void copyFile(tcString,tcString); function void copyFolder(tcString,tcString); function void removeFile(tcString); function void removeFolder(tcString);
function void close(tyFolder &); function tcString nextEntity(tyFolder &); function void open(tyFolder &,tcString);
inline void getFileList(tcString,tcString,clFileNameS &,tyBoolean = true);
inline void listFolder(clOutStream &,tcString,tcString = nil,tyBoolean = true,tyBoolean = true, tcString = "");
function void scanFolder(tcString,clFolderProcessing &,tyBoolean = true);
function tyDiskEntityKind diskEntityKind(tcString); function tcString diskEntityKindString(tyDiskEntityKind);
function void outFileRegister(clOutStream &); }
namespace private_area { function tyString copy(ctString &); function void registerFile(clInFile &,tcString); function void registerFile(clOutFile &,tcString); function tyCardinal removeCarriageReturn(tyString,tyCardinal); function void unregisterFile(clInFile &); function void unregisterFile(clOutFile &);
testing_mode ( function void test(void); ) }
// Errors //---------------------------------------------------------------------------------------- namespace public_area { /*ERROR*/ extern_error erEntityIdentification; /* Can not identify an entity in the folder. */ /*ERROR*/ extern_error erFileNotRegistered; /* The file is not registered. */ /*ERROR*/ extern_error erFileOpening; /* Can not open the file. */ /*ERROR*/ extern_error erFileReading; /* Can not read from the file. */ /*ERROR*/ extern_error erFileWriting; /* Can not write into the file. */ /*ERROR*/ extern_error erStreamReading; /* Can not read from the stream. */ /*ERROR*/ extern_error erStreamWriting; /* Can not write into the stream. */ /*ERROR*/ extern_error erFindFileSize; /* Can not find the file's size. */ /*ERROR*/ extern_error erFileAlreadyExists; /* The file already exists. */ /*ERROR*/ extern_error erFileFolderRenaming; /* Can not rename the file or the folder. */ /*ERROR*/ extern_error erFileRemoving; /* Can not remove the file. */ /*ERROR*/ extern_error erFolderClosing; /* Can not close the folder. */ /*ERROR*/ extern_error erFolderCreation; /* Can not create the folder. */ /*ERROR*/ extern_error erFolderOpening; /* Can not open the folder. */ /*ERROR*/ extern_error erFolderRemoving; /* Can not remove the folder. */ }
// Constants & Variables //------------------------------------------------------------------------- /*CONSTANT*/ /* Symbol that separates file names in a path. */ extern_static_constant(public,tcString,goFileNameSeparator,fileNameSeparator);
/*CONSTANT*/ /* Symbol that separates paths in an environment variable. */ extern_static_constant(public,tcString,goPathSeparator,pathSeparator);
/*CONSTANT*/ /* Size of the buffer for stream readings and writings. */ extern_static_constant(public,tyCardinal,goStreamBufferSize,streamBufferSize);
/*CONSTANT*/ /* Maximum possible length of a string representing a path. */ extern_static_constant(public,tyCardinal,goMaximumPathLength,maximumPathLength);
extern_static_constant(private,tcString,goFileRegisterFileName,?); extern_dynamic_constant(private,clPrimaryFileRegister,goPrimaryFileRegister,?); extern_dynamic_constant(private,clSecondaryFileRegister,goSecondaryFileRegister,?); extern_dynamic_constant(private,clString,goDataLocation,?); extern_static_constant(private,clMutex,goMutex,?);
// F o l d e r P r o c e s s i n g Interface //---------------------------------------------------- namespace public_area { /*CLASS clFolderProcessing */ /* Used by <CODE>scanFolder</CODE> to perform a process upon the entities found during the scanning of a folder. It is an abstract class. The methods of this class must be implemented. */ class clFolderProcessing { //-----------------------------------------------------------------------------------------Private private_property constructor clFolderProcessing(const clFolderProcessing &); private_property clFolderProcessing & operator = (const clFolderProcessing &); //------------------------------------------------------------------------------------------Public public_property constructor clFolderProcessing(void); public_property virtual destructor clFolderProcessing(void);
/*AMETHOD clFolderProcessing */ /* Is called when a folder is open. Abstract method. */ public_property virtual void startFolder(ctString &) = 0;
/*AMETHOD clFolderProcessing */ /* Is called when a folder is closed. Abstract method. */ public_property virtual void endFolder(ctString &) = 0;
/*AMETHOD clFolderProcessing */ /* Is called when a file is found. Abstract method. */ public_property virtual void file(ctString &) = 0;
/*AMETHOD clFolderProcessing */ /* Is called when an unknown entity is found. Abstract method. */ public_property virtual void unknown(ctString &) = 0; }; }
// F o l d e r P r o c e s s i n g C o p y Interface //-------------------------------------------- namespace private_area { class clFolderProcessingCopy : public clFolderProcessing { //-----------------------------------------------------------------------------------------Friends friend class private_area::clInitializer; //-----------------------------------------------------------------------------------------Private private_property clString atTargetPath;
private_property constructor clFolderProcessingCopy(const clFolderProcessingCopy &); private_property clFolderProcessingCopy & operator = (const clFolderProcessingCopy &); //------------------------------------------------------------------------------------------Public public_property constructor clFolderProcessingCopy(tcString); public_property virtual destructor clFolderProcessingCopy(void);
public_property void startFolder(ctString &); public_property void endFolder(ctString &); public_property void file(ctString &); public_property void unknown(ctString &); }; }
// F o l d e r P r o c e s s i n g D e l e t e Interface //---------------------------------------- namespace private_area { class clFolderProcessingDelete : public clFolderProcessing { //-----------------------------------------------------------------------------------------Friends friend class private_area::clInitializer; //-----------------------------------------------------------------------------------------Private private_property constructor clFolderProcessingDelete(const clFolderProcessingDelete &); private_property clFolderProcessingDelete & operator = (const clFolderProcessingDelete &); //------------------------------------------------------------------------------------------Public public_property constructor clFolderProcessingDelete(void); public_property virtual destructor clFolderProcessingDelete(void);
public_property void startFolder(ctString &); public_property void endFolder(ctString &); public_property void file(ctString &); public_property void unknown(ctString &); }; }
// F o l d e r P r o c e s s i n g G e t F i l e L i s t Interface //------------------------------ namespace private_area { class clFolderProcessingGetFileList : public clFolderProcessing { //-----------------------------------------------------------------------------------------Friends friend class private_area::clInitializer; //-----------------------------------------------------------------------------------------Private private_property tyString atFormat; private_property tyBoolean atCaseSensitive; private_property clFileNameS & atFileNameS;
private_property constructor clFolderProcessingGetFileList(const clFolderProcessingGetFileList &);
private_property clFolderProcessingGetFileList & operator = (const clFolderProcessingGetFileList &); //------------------------------------------------------------------------------------------Public public_property constructor clFolderProcessingGetFileList(tcString,clFileNameS &, tyBoolean = true);
public_property virtual destructor clFolderProcessingGetFileList(void);
public_property void startFolder(ctString &); public_property void endFolder(ctString &); public_property void file(ctString &); public_property void unknown(ctString &); }; }
// F o l d e r P r o c e s s i n g L i s t Interface //-------------------------------------------- namespace private_area { class clFolderProcessingList : public clFolderProcessing { //-----------------------------------------------------------------------------------------Friends friend class private_area::clInitializer; //-----------------------------------------------------------------------------------------Private private_property tyString atFormat; private_property clOutStream & atStream; private_property tyBoolean atCaseSensitive; private_property clString atBlankSpace;
private_property constructor clFolderProcessingList(const clFolderProcessingList &); private_property clFolderProcessingList & operator = (const clFolderProcessingList &); //------------------------------------------------------------------------------------------Public public_property constructor clFolderProcessingList(clOutStream &,tcString = nil, tyBoolean = true,tcString = "");
public_property virtual destructor clFolderProcessingList(void);
public_property void startFolder(ctString &); public_property void endFolder(ctString &); public_property void file(ctString &); public_property void unknown(ctString &); }; }
// Functions Inline //------------------------------------------------------------------------------ namespace public_area { //------------------------------------------------------------------------------IsFileNameSeparator /*FUNCTION*/ /* Checks if a character is a separator for file names. */ inline tyBoolean isFileNameSeparator(tyCharacter agCharacter) { return (agCharacter=='\\' or agCharacter=='/' or agCharacter==fileNameSeparator()[0]); } //------------------------------------------------------------------------------IsFileNameSeparator /*FUNCTION*/ /* Checks if a string is a separator for file names. */ inline tyBoolean isFileNameSeparator(tcString agString) { return (compare(agString,"\\")==0 or compare(agString,"/")==0 or compare(agString,fileNameSeparator())==0); } //--------------------------------------------------------------------------------------------Close /*FUNCTION*/ /* Closes an input file. */ inline void close(clInFile & agFile) { private_area::unregisterFile(agFile); agFile.close(); } //--------------------------------------------------------------------------------------------Close /*FUNCTION*/ /* Closes an output file. */ inline void close(clOutFile & agFile) { private_area::unregisterFile(agFile); agFile.close(); } //---------------------------------------------------------------------------------------------Open /*FUNCTION*/ /* Opens an input file in a given mode. */ inline void open(clInFile & agFile,tcString agFileName,tyFileMode agMode) { agFile.clear(); agFile.open(agFileName,agMode); if (not agFile.rdbuf()->is_open()) send_inline_error(erFileOpening,"open"); private_area::registerFile(agFile,agFileName); } //---------------------------------------------------------------------------------------------Open /*FUNCTION*/ /* Opens an output file in a given mode. */ inline void open(clOutFile & agFile,tcString agFileName,tyFileMode agMode) { agFile.clear(); agFile.open(agFileName,agMode); if (not agFile.rdbuf()->is_open()) send_inline_error(erFileOpening,"open"); private_area::registerFile(agFile,agFileName); } //--------------------------------------------------------------------------------------GetFileList /*FUNCTION*/ /* Stores the files of a folder into a list. The scanning is not recursive. The matching can be case sensitive. */ inline void getFileList(tcString agFolderName,tcString agFormat,clFileNameS & agFileNameS, tyBoolean agCaseSensitive) { private_area::clFolderProcessingGetFileList lcProcessing(agFormat,agFileNameS,agCaseSensitive);
scanFolder(agFolderName,lcProcessing,false); } //---------------------------------------------------------------------------------------ListFolder /*FUNCTION*/ /* Lists the content of a folder into a stream. The scanning can be recursive. Only the files matching a given format are listed. The matching can be case sensitive. */ inline void listFolder(clOutStream & agStream,tcString agFolder,tcString agFormat, tyBoolean agRecursive,tyBoolean agCaseSensitive,tcString agBlankSpace) { private_area::clFolderProcessingList lcProcessing(agStream,agFormat,agCaseSensitive,agBlankSpace);
scanFolder(agFolder,lcProcessing,agRecursive); } }
namespace private_area {}
// F o l d e r P r o c e s s i n g Inline //------------------------------------------------------- namespace public_area { //--------------------------------------------------------------------------------------Constructor /*METHOD clFolderProcessing */ /* Builds a default processing. */ inline clFolderProcessing::clFolderProcessing(void) {} }
// F o l d e r P r o c e s s i n g C o p y Inline //----------------------------------------------- namespace private_area { //--------------------------------------------------------------------------------------Constructor inline clFolderProcessingCopy::clFolderProcessingCopy(tcString atTargetFolder) : atTargetPath(atTargetFolder) {} }
// F o l d e r P r o c e s s i n g D e l e t e Inline //------------------------------------------- namespace private_area { //--------------------------------------------------------------------------------------Constructor inline clFolderProcessingDelete::clFolderProcessingDelete(void) {} //--------------------------------------------------------------------------------------StartFolder inline void clFolderProcessingDelete::startFolder(ctString &) {} //----------------------------------------------------------------------------------------EndFolder inline void clFolderProcessingDelete::endFolder(ctString & agFullName) { if (rmdir(agFullName.data())!=0) send_inline_error(erFolderRemoving,"folderProcessingDelete::endFolder"); } //---------------------------------------------------------------------------------------------File inline void clFolderProcessingDelete::file(ctString & agFullName) { removeFile(agFullName.data()); } //------------------------------------------------------------------------------------------Unknown inline void clFolderProcessingDelete::unknown(ctString &) {} }
// End //------------------------------------------------------------------------------------------- } #undef dll_export #undef public_area #undef private_area #endif |
//================================================================================================== // S t a n d a r d Implementation // S t r e a m // By Bruno Bachelet //================================================================================================== // Copyright (c) 1999-2016 // Bruno Bachelet - bruno@nawouak.net - http://www.nawouak.net // // This file is part of the B++ Library. This library is free software; you can redistribute it // and/or modify it under the terms of the GNU Library General Public License as published by the // Free Software Foundation; either version 2 of the License, or (at your option) any later // version. // // This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; // without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See // the GNU Library General Public License for more details (http://www.gnu.org).
// File Name //------------------------------------------------------------------------------------- #line __LINE__ "standard/stream.cpp"
// DLL Belonging //--------------------------------------------------------------------------------- #define STANDARD_DLL
// Headers //--------------------------------------------------------------------------------------- #include <cstdio> /*NEED*/ #include <set> /*NEED*/ #include <bpp/file_name.hpp> /*NEED*/ #include <bpp/standard/stream.hpp> /*INTERFACE*/
namespace bpp {
// Namespaces //------------------------------------------------------------------------------------ #define public_area standardStream #define private_area standardStream_private #define dll_export DLL_EXPORT
namespace public_area {} namespace private_area {}
static_module_name("Standard/Stream");
// Initialization //-------------------------------------------------------------------------------- #undef iniStandardStream static_constant(private_area::clInitializer,goInitializer);
// Errors //---------------------------------------------------------------------------------------- namespace public_area { static_error erEntityIdentification; static_error erFileNotRegistered; static_error erFileOpening; static_error erFileReading; static_error erFileWriting; static_error erStreamReading; static_error erStreamWriting; static_error erFindFileSize; static_error erFileAlreadyExists; static_error erFileFolderRenaming; static_error erFileRemoving; static_error erFolderCreation; static_error erFolderRemoving; static_error erFolderOpening; static_error erFolderClosing; }
// Constants & Variables //------------------------------------------------------------------------- static_constant(tcString,goFileNameSeparator); static_constant(tcString,goPathSeparator); static_constant(tyCardinal,goStreamBufferSize); static_constant(tyCardinal,goMaximumPathLength);
static_constant(tcString,goFileRegisterFileName); dynamic_constant(clPrimaryFileRegister,goPrimaryFileRegister); dynamic_constant(clSecondaryFileRegister,goSecondaryFileRegister); dynamic_constant(clString,goDataLocation); static_constant(clMutex,goMutex);
// Static Members //-------------------------------------------------------------------------------- namespace public_area {} namespace private_area {}
// Functions Implementation //---------------------------------------------------------------------- namespace public_area { //------------------------------------------------------------------------------------BuildFileName /*FUNCTION*/ /* Makes a string a file name (removes the eventual file name separator at the end of the string). */ function void buildFileName(clString & agName) { if (agName.size()>0 and isFileNameSeparator(agName[agName.size()-1])) agName=agName.part(0,agName.size()-1); } //----------------------------------------------------------------------------------BuildFolderName /*FUNCTION*/ /* Makes a string a folder name (adds a file name separator at the end of the string if there is not already one). */ function void buildFolderName(clString & agName) { if (agName.size()>0 and (not isFileNameSeparator(agName[agName.size()-1])) and agName[agName.size()-1]!=':') agName+=fileNameSeparator(); } //------------------------------------------------------------------------------------BuildFullName /*FUNCTION*/ /* Builds a full file name from a path and a short file name. */ function void buildFullName(clString & agFullName,ctString & agPath,ctString & agShortName) { clString lcString = agPath;
buildFolderName(lcString); agFullName=lcString+agShortName; } //---------------------------------------------------------------------------------ExtractShortName /*FUNCTION*/ /* Extracts a short name and a path from a full file name. */ function void extractShortName(clString & agPath,clString & agShortName,ctString & agFullName) { tyCardinal lcCounter; tyCardinal lcEnd;
lcCounter=agFullName.size();
if (lcCounter==0) { agPath=""; agShortName=""; return; }
lcEnd=--lcCounter;
while (lcCounter>0 and agFullName[lcCounter]!=':' and (not isFileNameSeparator(agFullName[lcCounter]))) lcCounter--;
if (lcCounter==0) { agShortName=agFullName; agPath=""; } else { if (lcCounter<lcEnd) agShortName=agFullName.part(lcCounter+1,lcEnd-lcCounter); else agShortName="";
agPath=agFullName.part(0,lcCounter+1); } } //---------------------------------------------------------------------------------SeparateFileName /*FUNCTION*/ /* Separates a file name into a body string and an extension string. */ function void separateFileName(clString & agBody,clString & agExtension,ctString & agName) { tyCardinal lcCounter; tyCardinal lcEnd;
lcCounter=agName.size();
if (lcCounter==0) { agBody=""; agExtension=""; }
lcEnd=--lcCounter;
while (lcCounter>0 and agName[lcCounter]!='.' and agName[lcCounter]!=':' and (not isFileNameSeparator(agName[lcCounter]))) lcCounter--;
if (agName[lcCounter]=='.') { if (lcCounter<lcEnd) agExtension=agName.part(lcCounter+1,lcEnd-lcCounter); else agExtension="";
if (lcCounter>=1) agBody=agName.part(0,lcCounter); else agBody=""; } else { agExtension=""; agBody=agName; } } //---------------------------------------------------------------------------------------------Copy /*FUNCTION*/ /* Copies an input stream into an output stream until the input stream ends. The last argument indicates if the output stream is open in binary mode. */ function void copy(clOutStream & agSout,clInStream & agSin,tyBoolean agBinary) { method_name("copy");
tyString lcBuffer; tyInteger lcCounter; tyStreamSize lcLength;
#ifdef CONSOLE tyCardinal lcSize; #endif
tyStreamPosition lcStartPosition = agSin.tellg();
agSin.seekg(0,ios::end); lcLength=tyStreamSize(agSin.tellg()-lcStartPosition); agSin.seekg(lcStartPosition); lcBuffer=new tyCharacter[streamBufferSize()]; lcCounter=lcLength/streamBufferSize();
while (lcCounter>0) { agSin.read(lcBuffer,streamBufferSize());
#ifdef CONSOLE if (agBinary) agSout.write(lcBuffer,streamBufferSize()); else { lcSize=private_area::removeCarriageReturn(lcBuffer,streamBufferSize()); agSout.write(lcBuffer,lcSize); } #else agSout.write(lcBuffer,streamBufferSize()); #endif
--lcCounter; if (agSin.fail()) send_error(erStreamReading); if (agSout.fail()) send_error(erStreamWriting); }
lcLength=lcLength%streamBufferSize(); agSin.read(lcBuffer,lcLength);
#ifdef CONSOLE if (agBinary) agSout.write(lcBuffer,lcLength); else { lcSize=private_area::removeCarriageReturn(lcBuffer,lcLength); agSout.write(lcBuffer,lcSize); } #else agSout.write(lcBuffer,lcLength); #endif
delete [] lcBuffer; if (agSin.fail()) send_error(erStreamReading); if (agSout.fail()) send_error(erStreamWriting); } //---------------------------------------------------------------------------------------FileExists /*FUNCTION*/ /* Checks if a file exists. */ function tyBoolean fileExists(tcString agName) { clInFile lcFile;
if (folderExists(agName)) return (false); lcFile.open(agName,ios::in);
if (not lcFile.fail()) { lcFile.close(); return (true); }
return (false); } //-----------------------------------------------------------------------------------------FileSize /*FUNCTION*/ /* Returns the size of a file. */ function tyInteger fileSize(tcString agName) { method_name("fileSize");
clInFile lcFile; tyInteger lcSize;
lcFile.open(agName,ios::in|ios::binary); lcSize=size(lcFile); lcFile.close(); if (lcFile.fail()) send_error(erFileReading); return (lcSize); } //-------------------------------------------------------------------------------------FolderExists /*FUNCTION*/ /* Checks if a folder exists. */ function tyBoolean folderExists(tcString agName) { #ifdef NEED_FOLDER_MANAGEMENT tyCharacter lcCurrentPath[MAXIMUM_PATH_LENGTH];
getcwd(lcCurrentPath,256);
if (chdir(agName)==0) { chdir(lcCurrentPath); return (true); } else return (false); #else tyFolder lcFolder;
lcFolder=opendir(agName);
if (lcFolder!=nil) { closedir(lcFolder); return (true); }
return (false); #endif } //---------------------------------------------------------------------------------------------Size /*FUNCTION*/ /* Returns the size of an open file. */ tyInteger size(clInFile & lcFile) { method_name("size");
tyStreamSize lcLength; tyStreamPosition lcStartPosition = lcFile.tellg();
lcFile.seekg(0,ios::end); lcLength=tyStreamSize(lcFile.tellg()-lcStartPosition); lcFile.seekg(tyStreamOffset(lcStartPosition),ios::beg); if (lcFile.fail()) send_error(erFindFileSize);
return (lcLength); } //---------------------------------------------------------------------------------------ChangeName /*FUNCTION*/ /* Changes the name of a file or a folder. */ function void changeName(tcString agOldName,tcString agNewName) { method_name("changeName");
if (std::rename(agOldName,agNewName)!=0) send_error(erFileFolderRenaming); } //-------------------------------------------------------------------------------------CreateFolder /*FUNCTION*/ /* Creates a new folder. */ function void createFolder(tcString agName) { method_name("createFolder");
if (mkdir(agName)!=0) send_error(erFolderCreation); } //---------------------------------------------------------------------------------------RemoveFile /*FUNCTION*/ /* Removes a file. */ function void removeFile(tcString agName) { method_name("removeFile");
if (std::remove(agName)!=0) send_error(erFileRemoving); } //-------------------------------------------------------------------------------------RemoveFolder /*FUNCTION*/ /* Removes a folder and its content. */ function void removeFolder(tcString agFolderName) { private_area::clFolderProcessingDelete lcProcessing;
lcProcessing.startFolder(clString(agFolderName)); scanFolder(agFolderName,lcProcessing,true); lcProcessing.endFolder(clString(agFolderName)); } //-----------------------------------------------------------------------------------------CopyFile /*FUNCTION*/ /* Copies the content of a file into another one. */ function void copyFile(tcString agTargetName,tcString agSourceName) { method_name("copyFile");
clInFile lcSourceFile; clOutFile lcTargetFile;
open(lcSourceFile,agSourceName,ios::in|ios::binary); if (lcSourceFile.fail()) send_error(erFileReading); if (fileExists(agTargetName)) send_error(erFileAlreadyExists); open(lcTargetFile,agTargetName,ios::out|ios::trunc|ios::binary); if (lcTargetFile.fail()) send_error(erFileWriting); copy(lcTargetFile,lcSourceFile,true); close(lcSourceFile); close(lcTargetFile); } //---------------------------------------------------------------------------------------CopyFolder /*FUNCTION*/ /* Copies the content of a folder into another one. */ function void copyFolder(tcString agTargetName,tcString agFolderName) { private_area::clFolderProcessingCopy lcProcessing(agTargetName);
lcProcessing.startFolder(clString(agFolderName)); scanFolder(agFolderName,lcProcessing,true); lcProcessing.endFolder(clString(agFolderName)); } //--------------------------------------------------------------------------------------------Close /*FUNCTION*/ /* Closes a folder. */ function void close(tyFolder & agFolder) { method_name("close");
if (closedir(agFolder)!=0) send_error(erFolderClosing); } //---------------------------------------------------------------------------------------NextEntity /*FUNCTION*/ /* Moves to the next entity of a folder. */ function tcString nextEntity(tyFolder & agFolder) { struct dirent * lcEntity;
lcEntity=readdir(agFolder);
if (lcEntity==nil) return (tcString(nil)); else return (lcEntity->d_name); } //---------------------------------------------------------------------------------------------Open /*FUNCTION*/ /* Opens a folder. */ function void open(tyFolder & agFolder,tcString agName) { method_name("open");
if (not folderExists(agName)) send_error(erFolderOpening); agFolder=opendir(agName); if (agFolder==nil) send_error(erFolderOpening); } //-----------------------------------------------------------------------------------DiskEntityKind /*FUNCTION*/ /* Returns the kind of the entity. */ function tyDiskEntityKind diskEntityKind(tcString agName) { tcString lcEnd1; tcString lcEnd2;
if (standardBasicString::size(agName)>=2) lcEnd1=agName+standardBasicString::size(agName)-2; else lcEnd1="";
if (standardBasicString::size(agName)>=3) lcEnd2=agName+standardBasicString::size(agName)-3; else lcEnd2="";
if (agName==clString(".") or agName==clString("..") or lcEnd1==(clString(fileNameSeparator())+".") or lcEnd2==(clString(fileNameSeparator())+"..")) return (referenceEntity);
if (folderExists(agName)) return (folderEntity); if (fileExists(agName)) return (fileEntity);
return (unknownEntity); } //-----------------------------------------------------------------------------DiskEntityKindString /*FUNCTION*/ /* Converts an entity kind into a string. */ function tcString diskEntityKindString(tyDiskEntityKind agKind) { if (agKind==unknownEntity) return ("unknown"); if (agKind==fileEntity) return ("file"); if (agKind==folderEntity) return ("folder"); if (agKind==referenceEntity) return ("reference"); return ("unknown"); } //---------------------------------------------------------------------------------------ScanFolder /*FUNCTION*/ /* Scans a folder and performs a given process upon the entities found in it. The scanning can be recursive. */ function void scanFolder(tcString agName,clFolderProcessing & agProcessing, tyBoolean agRecursive) { typedef std_set(clString) clNameS;
clNameS lcFileS; clNameS lcFolderS; clNameS lcUnknownS;
clNameS::const_iterator lcCurrentEntity; clNameS::const_iterator lcLastEntity;
tcString lcEntity; tyFolder lcFolder; clString lcFolderName; clString lcFullName; tyDiskEntityKind lcKind; clString lcShortName; tyString lcTempo;
// Folder Scanning //----------------------------------------------------------------------------- lcFolderName=agName; buildFolderName(lcFolderName); lcTempo=private_area::copy(lcFolderName); open(lcFolder,lcTempo); delete [] lcTempo; lcEntity=nextEntity(lcFolder);
while (lcEntity!=nil) { lcShortName=clString(lcEntity);
if (lcShortName!="." and lcShortName!="..") { buildFullName(lcFullName,lcFolderName,clString(lcEntity)); lcTempo=private_area::copy(lcFullName); lcKind=diskEntityKind(lcTempo); delete [] lcTempo;
if (lcKind==folderEntity) lcFolderS.insert(lcFullName); else if (lcKind==fileEntity) lcFileS.insert(lcFullName); else if (lcKind==unknownEntity) lcUnknownS.insert(lcFullName); }
lcEntity=nextEntity(lcFolder); }
// Folders Processing //-------------------------------------------------------------------------- close(lcFolder); lcCurrentEntity=lcFolderS.begin(); lcLastEntity=lcFolderS.end();
while (lcCurrentEntity!=lcLastEntity) { agProcessing.startFolder(*lcCurrentEntity);
if (agRecursive) { lcTempo=private_area::copy(*lcCurrentEntity); scanFolder(lcTempo,agProcessing,agRecursive); delete [] lcTempo; }
agProcessing.endFolder(*lcCurrentEntity); lcCurrentEntity++; }
// Files Processing //---------------------------------------------------------------------------- lcCurrentEntity=lcFileS.begin(); lcLastEntity=lcFileS.end();
while (lcCurrentEntity!=lcLastEntity) { agProcessing.file(*lcCurrentEntity); lcCurrentEntity++; }
// Unknown Entities Processing //----------------------------------------------------------------- lcCurrentEntity=lcUnknownS.begin(); lcLastEntity=lcUnknownS.end();
while (lcCurrentEntity!=lcLastEntity) { agProcessing.unknown(*lcCurrentEntity); lcCurrentEntity++; } } //----------------------------------------------------------------------------------OutFileRegister /*FUNCTION*/ /* Writes into a stream the list of the files still open in the program. */ function void outFileRegister(clOutStream & agStream) { method_name("outFileRegister");
typedef private_area::clPrimaryFileRegister::const_iterator clPrimaryIterator; typedef private_area::clSecondaryFileRegister::const_iterator clSecondaryIterator;
safe_yes ( private_area::goMutex.lock(); )
clPrimaryIterator lcCurrentPrimary = private_area::goPrimaryFileRegister->begin(); clSecondaryIterator lcCurrentSecondary = private_area::goSecondaryFileRegister->begin(); clPrimaryIterator lcLastPrimary = private_area::goPrimaryFileRegister->end(); clSecondaryIterator lcLastSecondary = private_area::goSecondaryFileRegister->end();
while (lcCurrentSecondary!=lcLastSecondary) { agStream << " Name = " << *(*lcCurrentSecondary) << end_line; lcCurrentSecondary++; }
while (lcCurrentPrimary!=lcLastPrimary) { agStream << " Name = " << *((*lcCurrentPrimary).second) << end_line; lcCurrentPrimary++; }
safe_yes ( private_area::goMutex.release(); ) if (agStream.fail()) send_error(erStreamWriting); } }
namespace private_area { //---------------------------------------------------------------------------------------------Copy function tyString copy(ctString & agString) { tyString lcString = new tyCharacter [agString.size()+1];
standardBasicString::copy(lcString,agString.data()); lcString[agString.size()]=end_string; return (lcString); } //-------------------------------------------------------------------------------------RegisterFile function void registerFile(clInFile & agFile,tcString agFileName) { safe_yes ( private_area::goMutex.lock(); )
if (goPrimaryFileRegister->count(&agFile) == 1) { goSecondaryFileRegister->push_back((*(goPrimaryFileRegister->find(&agFile))).second); goPrimaryFileRegister->erase(&agFile); }
goPrimaryFileRegister->insert(std_make_pair(&agFile,new clString(agFileName))); safe_yes ( private_area::goMutex.release(); ) } //-------------------------------------------------------------------------------------RegisterFile function void registerFile(clOutFile & agFile,tcString agFileName) { safe_yes ( private_area::goMutex.lock(); )
if (goPrimaryFileRegister->count(&agFile) == 1) { goSecondaryFileRegister->push_back((*(goPrimaryFileRegister->find(&agFile))).second); goPrimaryFileRegister->erase(&agFile); }
goPrimaryFileRegister->insert(std_make_pair(&agFile,new clString(agFileName))); safe_yes ( private_area::goMutex.release(); ) } //-----------------------------------------------------------------------------RemoveCarriageReturn function tyCardinal removeCarriageReturn(tyString agString,tyCardinal agLength) { tyCardinal lcCounter1 = 0; tyCardinal lcCounter2;
while (lcCounter1<agLength-1) { if (agString[lcCounter1]==0x0D and agString[lcCounter1+1]==0x0A) { --agLength; lcCounter2=lcCounter1;
while (lcCounter2<agLength) { agString[lcCounter2]=agString[lcCounter2+1]; ++lcCounter2; } }
++lcCounter1; }
return (agLength); } //-----------------------------------------------------------------------------------UnregisterFile function void unregisterFile(clInFile & agFile) { method_name("unregisterFile");
safe_yes ( private_area::goMutex.lock(); )
if (goPrimaryFileRegister->count(&agFile) == 0) { safe_yes ( private_area::goMutex.release(); ) send_error(erFileNotRegistered); }
delete (*(goPrimaryFileRegister->find(&agFile))).second; goPrimaryFileRegister->erase(&agFile); safe_yes ( private_area::goMutex.release(); ) } //-----------------------------------------------------------------------------------UnregisterFile function void unregisterFile(clOutFile & agFile) { method_name("unregisterFile");
safe_yes ( private_area::goMutex.lock(); )
if (goPrimaryFileRegister->count(&agFile) == 0) { safe_yes ( private_area::goMutex.release(); ) send_error(erFileNotRegistered); }
delete (*(goPrimaryFileRegister->find(&agFile))).second; goPrimaryFileRegister->erase(&agFile); safe_yes ( private_area::goMutex.release(); ) } }
// F o l d e r P r o c e s s i n g Implementation //----------------------------------------------- namespace public_area { //---------------------------------------------------------------------------------------Destructor /*METHOD clFolderProcessing */ /* Destructs the processing. */ property clFolderProcessing::~clFolderProcessing(void) {} }
// F o l d e r P r o c e s s i n g C o p y Implementation //--------------------------------------- namespace private_area { //---------------------------------------------------------------------------------------Destructor property clFolderProcessingCopy::~clFolderProcessingCopy(void) {} //--------------------------------------------------------------------------------------StartFolder property void clFolderProcessingCopy::startFolder(ctString & agFullName) { clString lcPath; clString lcShortName;
extractShortName(lcPath,lcShortName,agFullName); buildFullName(lcPath,atTargetPath,lcShortName); atTargetPath=lcPath; if (not folderExists(atTargetPath.data())) createFolder(atTargetPath.data()); } //----------------------------------------------------------------------------------------EndFolder property void clFolderProcessingCopy::endFolder(ctString &) { clString lcPath; clString lcShortName;
extractShortName(lcPath,lcShortName,atTargetPath); atTargetPath=lcPath; buildFileName(atTargetPath); } //---------------------------------------------------------------------------------------------File property void clFolderProcessingCopy::file(ctString & agFullName) { clString lcFullName; clString lcPath; clString lcShortName;
extractShortName(lcPath,lcShortName,agFullName); buildFullName(lcFullName,atTargetPath,lcShortName); copyFile(lcFullName.data(),agFullName.data()); } //------------------------------------------------------------------------------------------Unknown property void clFolderProcessingCopy::unknown(ctString &) { send_inline_error(erEntityIdentification,"folderProcessingCopy::unknown"); } }
// F o l d e r P r o c e s s i n g D e l e t e Implementation //----------------------------------- namespace private_area { //---------------------------------------------------------------------------------------Destructor property clFolderProcessingDelete::~clFolderProcessingDelete(void) {} }
// F o l d e r P r o c e s s i n g G e t F i l e L i s t Implementation //------------------------- namespace private_area { //--------------------------------------------------------------------------------------Constructor property clFolderProcessingGetFileList::clFolderProcessingGetFileList(tcString agFormat, clFileNameS & agFileNameS,tyBoolean agCaseSensitive) : atFormat(tyString(agFormat)),atCaseSensitive(agCaseSensitive),atFileNameS(agFileNameS) { if (agFormat!=nil and not agCaseSensitive) { atFormat=new tyCharacter[standardBasicString::size(agFormat)+1]; standardBasicString::copy(atFormat,agFormat); lowerCase(atFormat); } } //---------------------------------------------------------------------------------------Destructor property clFolderProcessingGetFileList::~clFolderProcessingGetFileList(void) { if (atFormat!=nil and not atCaseSensitive) delete [] atFormat; } //--------------------------------------------------------------------------------------StartFolder property void clFolderProcessingGetFileList::startFolder(ctString &) {} //----------------------------------------------------------------------------------------EndFolder property void clFolderProcessingGetFileList::endFolder(ctString &) {} //---------------------------------------------------------------------------------------------File property void clFolderProcessingGetFileList::file(ctString & agFullName) { clString lcPath; clString lcShortName; tyString lcTempo;
extractShortName(lcPath,lcShortName,agFullName); lcTempo=private_area::copy(lcShortName); if (not atCaseSensitive) lowerCase(tyString(lcTempo)); if (atFormat==nil or matched(lcTempo,atFormat)) atFileNameS.push_back(lcShortName); delete [] lcTempo; } //------------------------------------------------------------------------------------------Unknown property void clFolderProcessingGetFileList::unknown(ctString &) {} }
// F o l d e r P r o c e s s i n g L i s t Implementation //--------------------------------------- namespace private_area { //--------------------------------------------------------------------------------------Constructor property clFolderProcessingList:: clFolderProcessingList(clOutStream & agStream,tcString agFormat,tyBoolean agCaseSensitive, tcString agBlankSpace) : atFormat(tyString(agFormat)),atStream(agStream),atCaseSensitive(agCaseSensitive), atBlankSpace(agBlankSpace) { if (agFormat!=nil and not agCaseSensitive) { atFormat=new tyCharacter[standardBasicString::size(agFormat)+1]; standardBasicString::copy(atFormat,agFormat); lowerCase(atFormat); } } //---------------------------------------------------------------------------------------Destructor property clFolderProcessingList::~clFolderProcessingList(void) { if (atFormat!=nil and not atCaseSensitive) delete [] atFormat; } //--------------------------------------------------------------------------------------StartFolder property void clFolderProcessingList::startFolder(ctString & agFullName) { clString lcPath; clString lcShortName;
extractShortName(lcPath,lcShortName,agFullName); atStream << atBlankSpace << lcShortName << ":" << end_line; atBlankSpace+=" "; } //----------------------------------------------------------------------------------------EndFolder property void clFolderProcessingList::endFolder(ctString &) { atBlankSpace=atBlankSpace.part(0,atBlankSpace.size()-1); } //---------------------------------------------------------------------------------------------File property void clFolderProcessingList::file(ctString & agFullName) { clString lcBody; clString lcExtension; clString lcPath; clString lcShortName; tyString lcTempo;
extractShortName(lcPath,lcShortName,agFullName); lcTempo=private_area::copy(lcShortName); if (not atCaseSensitive) lowerCase(tyString(lcTempo));
if (atFormat==nil or matched(lcTempo,atFormat)) { delete [] lcTempo; separateFileName(lcBody,lcExtension,lcShortName); atStream << atBlankSpace << lcShortName << " [" << lcExtension << "] "; lcTempo=private_area::copy(agFullName); atStream << fileSize(lcTempo) << " bytes" << end_line; }
delete [] lcTempo; } //------------------------------------------------------------------------------------------Unknown property void clFolderProcessingList::unknown(ctString & agFullName) { clString lcPath; clString lcShortName;
extractShortName(lcPath,lcShortName,agFullName); atStream << atBlankSpace << lcShortName << '?' << end_line; } }
// I n i t i a l i z e r Implementation //--------------------------------------------------------- namespace private_area { //--------------------------------------------------------------------------------------------Start property void clInitializer::start(void) { if (atCounter++ == 0) { try { #include <bpp/modules.hpp> /*NEED*/ registerStop(this); environment::informInitialization(goModuleName);
erEntityIdentification.create("Can't identify an entity in the folder."); erFileNotRegistered.create("The file isn't registered."); erFileOpening.create("Can't open the file."); erFileReading.create("Can't read from the file."); erFileWriting.create("Can't write into the file."); erStreamReading.create("Can't read from the stream."); erStreamWriting.create("Can't write into the stream."); erFindFileSize.create("Can't find the file's size."); erFileAlreadyExists.create("The file already exists."); erFileFolderRenaming.create("Can't rename the file or the folder."); erFileRemoving.create("Can't remove the file."); erFolderClosing.create("Can't close the folder."); erFolderCreation.create("Can't create the folder."); erFolderOpening.create("Can't open the folder."); erFolderRemoving.create("Can't remove the folder.");
goFileNameSeparator = FILE_NAME_SEPARATOR; goPathSeparator = PATH_SEPARATOR; goStreamBufferSize = STREAM_BUFFER_SIZE; goMaximumPathLength = MAXIMUM_PATH_LENGTH;
goFileRegisterFileName = FILE_REGISTER_FILE; goPrimaryFileRegister = new clPrimaryFileRegister; goSecondaryFileRegister = new clSecondaryFileRegister;
goDataLocation = new clString(environment::dataLocation()+fileNameSeparator() +"standard"+fileNameSeparator()+"stream"); }
initializer_catch; } } //---------------------------------------------------------------------------------------------Stop property void clInitializer::stop(void) { clOutFile lcFout;
try { environment::informTermination(goModuleName);
method_name("initializer::destructor");
if (not (goPrimaryFileRegister->empty() and goSecondaryFileRegister->empty())) { using namespace environment;
nextLine(); out("[!] Warning: Many files haven't been properly closed.",true,true); out("For more details, see the '",false,true); out(goFileRegisterFileName); out("' file.",true); nextLine();
lcFout.open(goFileRegisterFileName,ios::out|ios::trunc); lcFout << "===============================================================================" << end_line; lcFout << " F i l e s R e g i s t e r Debugging Information" << end_line; lcFout << "===============================================================================" << end_line; lcFout << end_line; outInformation(lcFout); lcFout << end_line; environment::outContext(lcFout); lcFout << end_line; lcFout << "[>] Files Still Open:" << end_line; lcFout << end_line; outFileRegister(lcFout); lcFout << end_line; lcFout << "===============================================================================" << end_line; lcFout.close(); if (lcFout.fail()) send_error(erFileWriting); }
delete goPrimaryFileRegister; delete goSecondaryFileRegister; delete goDataLocation; }
initializer_catch; } }
// End //------------------------------------------------------------------------------------------- } |
|