/* * This file is a part of Winix * and is not publicly distributed * * Copyright (c) 2010, Tomasz Sowa * All rights reserved. * */ #include "mountparser.h" #include "log.h" #include "misc.h" MountParser::MountParser() { dirs = 0; mount_type_tab = 0; mount_fs_tab = 0; mount_par_tab = 0; } void MountParser::SetDirs(Dirs * pdirs) { dirs = pdirs; } void MountParser::SetMountTypeTab(const std::vector & tab) { mount_type_tab = &tab; } void MountParser::SetMountFsTab(const std::vector & tab) { mount_fs_tab = &tab; } void MountParser::SetMountParTab(const std::vector & tab) { mount_par_tab = &tab; } bool MountParser::IsWhite(int c) { if( c==' ' || c=='\t' || c==13 || c==160 ) return true; return false; } void MountParser::SkipWhite() { while( IsWhite(*pinput) ) ++pinput; } void MountParser::SkipLine() { while( *pinput && *pinput != 10 ) ++pinput; if( *pinput == 10 ) ++pinput; } void MountParser::ReadWordQuote(std::wstring & res) { ++pinput; while( *pinput && *pinput!=10 && *pinput!='\"' ) { if( pinput[0]=='\\' && pinput[1]=='\"' ) { res += '\"'; pinput += 2; } else if( pinput[0]=='\\' && pinput[1]=='\\' ) { res += '\\'; pinput += 2; } else { res += *pinput; pinput += 1; } } if( *pinput == '"' ) ++pinput; } // a white character is the separator void MountParser::ReadWordWhite(std::wstring & res) { while( *pinput && *pinput!=10 && !IsWhite(*pinput) ) { res += *pinput; ++pinput; } } // the comma or the second bracket ')' are the separators void MountParser::ReadWordComma(std::wstring & res) { while( *pinput && *pinput!=10 && *pinput!=',' && *pinput!=')' ) { res += *pinput; ++pinput; } // trimming last white characters // (white characters can be in the middle of the string) TrimWhite(res); } void MountParser::ReadWord(std::wstring & res, bool comma_bracket_separator) { res.clear(); SkipWhite(); if( *pinput == '"' ) { ReadWordQuote(res); } else if( comma_bracket_separator ) { ReadWordComma(res); } else { ReadWordWhite(res); } } void MountParser::ReadParamArgsLoop(Mount::ParamRow::ParamArg & args) { SkipWhite(); while( *pinput && *pinput!=10 && *pinput!=')' ) { ReadWord(temp_arg, true); if( !temp_arg.empty() ) args.push_back(temp_arg); if( *pinput == ',' ) ++pinput; } } void MountParser::ReadParamArgs(Mount::ParamRow::ParamArg & args) { SkipWhite(); args.clear(); if( *pinput == '(' ) { ++pinput; ReadParamArgsLoop(args); if( *pinput != ')' ) { // there should be ')' at the end // temporarily we do nothing } else { ++pinput; } } } void MountParser::ReadParamName(std::wstring & res) { SkipWhite(); res.clear(); while( *pinput && *pinput!=10 && *pinput!=',' && *pinput!='(' && !IsWhite(*pinput) ) { res += *pinput; ++pinput; } } void MountParser::ReadParam(std::wstring & res, Mount::ParamRow::ParamArg & args) { ReadParamName(res); if( res.empty() ) return; ReadParamArgs(args); SkipWhite(); if( *pinput == ',' ) ++pinput; } int MountParser::FindIndex(const std::vector * tab, const std::wstring & value) { for(size_t i=0 ; i < tab->size() ; ++i) { if( (*tab)[i] == value ) return static_cast(i); } return -1; } void MountParser::ReadMountType() { ReadWord(temp); if( temp.empty() ) { // an empty line (some white characters only) err = WINIX_ERR_EMPTY; return; } mount.type = FindIndex(mount_type_tab, temp); if( mount.type != -1 ) { log << log3 << "MP: mount type: " << (*mount_type_tab)[mount.type] << logend; } else { err = WINIX_ERR_MOUNT_UNKNOWN; log << log1 << "MP: unknown mount type: " << temp << logend; } } void MountParser::ReadMountPoint() { ReadWord(temp); pdir = dirs->GetDir(temp); if( pdir ) { mount.dir_id = pdir->id; log << log3 << "MP: mount point (directory): " << temp << logend; } else { err = WINIX_ERR_NO_MOUNTPOINT; log << log1 << "MP: there is no such a mount point (directory): " << temp << logend; } } void MountParser::ReadFs() { ReadWord(temp); mount.fs = FindIndex(mount_fs_tab, temp); if( mount.fs != -1 ) { log << log1 << "MP: file system: " << (*mount_fs_tab)[mount.fs] << logend; } else { err = WINIX_ERR_UNKNOWN_FILESYSTEM; log << log1 << "MP: unknown filesystem: " << temp << logend; } } void MountParser::LogMountParams() { size_t i; log << log3 << "MP: mount param: " << temp << "("; for(i=0 ; i & output) { ReadMountType(); if( err == WINIX_ERR_EMPTY ) { err = WINIX_ERR_OK; SkipLine(); return; } if( err == WINIX_ERR_OK ) ReadMountPoint(); if( err == WINIX_ERR_OK ) ReadFs(); if( err == WINIX_ERR_OK ) ReadMountParams(); if( err == WINIX_ERR_OK ) { std::pair::iterator, bool> res = output.insert( std::make_pair(mount.dir_id, mount) ); if( !res.second ) log << log1 << "MP: this mount point exists (skipped)" << logend; } SkipLine(); } Error MountParser::Parse(const std::wstring & input, std::map & output) { if( !dirs || !mount_type_tab || !mount_fs_tab || !mount_par_tab ) { log << log1 << "pdir: " << pdir << logend; log << log1 << "type: " << mount_type_tab << logend; log << log1 << "fs: " << mount_fs_tab << logend; log << log1 << "par: " << mount_par_tab << logend; log << log1 << "MP: input tables not set" << logend; return WINIX_NOTHING_TO_DO; // !! may a better code? } pinput = input.c_str(); err = WINIX_ERR_OK; mount.param.resize(mount_par_tab->size()); mount.ClearParams(); output.clear(); while( *pinput && err == WINIX_ERR_OK ) ReadRow(output); return err; }