//-----------------------------------------------------------------------------+ // Copyright (C), 1998-2007, SH Software Co. Ltd. // = FileName : XASLibMan 类 // = Version : ver2.0 // = Author : zjq // = CreateDate : 2002-09-09 // = Description: XASLibMan 定义 // = Maintainers: // //-----------------------------------------------------------------------------+ #include "StdAfx.h" #include "XASLibMan.h" #include "AString.h" #include "UString.h" #include "comdef.h" #include #include #include #include #include "fcntl.h" #include "sys\stat.h" #include "XGlobalFunc.h" static const TCHAR *sMsgPrompt[] = {_T("\n建立库文件%s!"), _T("\n不能读取临时文件'%s'!"), }; // 幻灯库的操作 XASLibMan::XASLibMan(const TCHAR *fname, const TCHAR *ext, const TCHAR *t, int opMode) : itemExt(ext), title(_AS(t)), slbfile(fname), openMode(opMode) { libExt = tstrchr_new(fname, '.'); if (opMode) { Open(NULL, opMode); } m_pStreamFile = new XStreamFile; } XASLibMan::~XASLibMan() { if (m_pStreamFile != NULL) { delete m_pStreamFile; m_pStreamFile = NULL; } } int XASLibMan::Open(const TCHAR *file, int mode) { openMode = mode; if (file) { slbfile = file; } if (!slbfile || !openMode) { return 0; } int isExist = (ads_findfile(slbfile, XString(256)) == RTNORM); if (!isExist && !(mode & _ios::out)) { return 0; } #if (ARX>15) //需要事先创建 if(!isExist) { int nTempMode = _ios::binary|_ios::out; std::ofstream out(slbfile, nTempMode); Catalogue entry; CT_clear_strbuf(entry.itemName, 32 ); strcpy(entry.itemName,title); entry.itemName[25] = 0x0d; entry.itemName[26] = 0x0a; entry.itemName[27] = 0x1a; out.write(entry.itemName,32); CT_clear_strbuf(entry.itemName, 32 ); entry.addr = 0L; out.write((char*)&entry,36); out.flush(); ads_printf(sMsgPrompt[0], (TCHAR *)slbfile); isExist = TRUE; } #endif _libfile.open(slbfile,mode); if (!_libfile) { return 0; } if(!isExist && (mode&_ios::out)) { Catalogue entry; CT_clear_strbuf(entry.itemName, 32 ); strcpy(entry.itemName,title); entry.itemName[25] = 0x0d; entry.itemName[26] = 0x0a; entry.itemName[27] = 0x1a; _libfile.write(entry.itemName,32); CT_clear_strbuf(entry.itemName, 32 ); entry.addr = 0L; _libfile.write((char*)&entry,36); _libfile.flush(); ads_printf(sMsgPrompt[0], (TCHAR *)slbfile); } return 1; } //把文件指针移到第 n 个记录的起始 //返回值: 0--失败; 1--成功 int XASLibMan::MoveFilePtr(int n) { _libfile.seekg(32, _ios::beg); Catalogue entry; for (int i = 0; i < n; i++) { _libfile.read((char *)&entry, 36); if (!entry.itemName[0]) { return 0; } } _libfile.read((char *)&entry, 36); _libfile.seekg(-36, _ios::cur); if (!entry.itemName[0]) { return 0; } return 1; } // 获得库文件的记录数目 int XASLibMan::Length() { _libfile.clear(); _libfile.seekg(32, _ios::beg); Catalogue entry; int i = 0; while(1) { if (!_libfile) { return 0; } _libfile.read((char *)&entry, 36); if (!entry.itemName[0]) { return i; } i++; } } // 从库文件里取出第n个记录 // 返回值: 0--失败; 1--成功 int XASLibMan::GetRecord(int n, Catalogue *rec) { if (MoveFilePtr(n)) { _libfile.read((char *)rec, 36); return 1; } return 0; } // 取得所有幻灯列表 // 返回幻灯的个数 // 注意: 用 delete 释放 sldlist int XASLibMan::GetAll(DList &res) { _libfile.clear(); _libfile.seekg(32, _ios::beg); Catalogue entry; int i = 0; while(1) { if (!_libfile) { return 0; } _libfile.read((char *)&entry, 36); if (!entry.itemName[0]) { return i; } res.Append(new Catalogue(entry)); i++; } } int XASLibMan::GetAll(DList &res) { _libfile.clear(); _libfile.seekg(32, _ios::beg); if (!_libfile) { return 0; } int i = 0; while(1) { if (!_libfile) { XGeLib::adsout << _T("\nRead ") << slbfile << _T(" catalogue index=") << i << _T(" fail"); assert(0); } Catalogue entry; _libfile.read((char *)&entry, 36); if (!entry.itemName[0]) { return i; } res.Append(tstrnew(TString(entry.itemName))); i++; } } int XASLibMan::IsExist(const TCHAR *itemName, int *rec_index) { XStringList records; if (!GetAll(records)) { return 0; } *rec_index = records.Index(itemName, 0); if (*rec_index >= 0) { return 1; } return 0; } // 往库文件里添加记录 int XASLibMan::Append(const TCHAR *sldname, const TCHAR *szItem) { //modified by W on 060224 //char sld[80]; TCHAR sld[1024]; _tcscpy(sld, sldname); TCHAR *p = tstrchr_new(sld, '.'); if (p) { *p = 0; } return MainTain(sld, File_Add, szItem); } int XASLibMan::Remove(int n) // 删除库文件第 n 个记录 { Catalogue entry; if (!GetRecord(n, &entry)) { return 0; } return MainTain(TString(entry.itemName), File_Del); } int XASLibMan::MainTain(const TCHAR *sldname, FileOperation opr, const TCHAR *szItem) { if (opr != File_Add && opr != File_Del) { return 0; } char szDrive[_MAX_DRIVE] = "", szDir[_MAX_DIR] = "", szFName[_MAX_FNAME] = "", szExt[_MAX_EXT] = ""; _splitpath(_AS(sldname), szDrive, szDir, szFName, szExt); _strupr(szExt); _strupr(szFName); // 判断幻灯文件是否存在 char newsld_name[80]; #if (ARX > 15) std:: #endif ifstream sld_in; long newsld_fsize; if (opr == File_Add) { if (!sldname) { return 0; } strcpy(newsld_name, _AS(sldname)); if (szExt[0]) { } else { strcat(newsld_name, _AS(itemExt)); } sld_in.open(newsld_name, _ios::in | _ios::binary); if (!sld_in) { return 0; } sld_in.seekg(0, _ios::end); newsld_fsize = sld_in.tellg(); } char itemName[32] = ""; CT_clear_strbuf(itemName, 32 ); if (szItem) { strcpy(itemName, _AS(szItem)); } else { strcpy(itemName, _AS(szFName)); } _strupr(itemName); if (szExt[0]) { strcpy(&itemName[16], &szExt[1]); } //取得所有的目录 DList all_records; GetAll(all_records); int rec_num = all_records.Length(); int old_index = rec_num; for (int i = 0; i < rec_num; i++) { if (_stricmp(all_records[i]->itemName, itemName) == 0) { old_index = i; } } if (old_index == rec_num && opr == File_Del) { return 0; } _libfile.seekg(0, _ios::end); long old_fsize = _libfile.tellg(); char tmpfile[80]; { _libfile.close(); char drive[_MAX_DRIVE] = "", dir_name[_MAX_DIR] = "", file_name[_MAX_FNAME], ext_name[_MAX_EXT]; _splitpath(_AS(slbfile), drive, dir_name, file_name, ext_name); sprintf(tmpfile, "%s%s$TEMP$%s", drive, dir_name, ext_name); remove(tmpfile); if (rename(_AS(slbfile), tmpfile)) { _libfile.open(slbfile, openMode); return 0; } } #if (ARX > 15) std:: #endif ifstream tmp_in(tmpfile, _ios::in | _ios::binary); _libfile.open(slbfile, _ios::out | _ios::binary); char tit[32] = ""; if (!tmp_in) { ads_printf(sMsgPrompt[1], tmpfile); return 0; } tmp_in.read(tit, 32); _libfile.write(tit, 32); long oldsld_size; Catalogue entry; for (int i = 0; i < rec_num; i++) { memcpy(entry.itemName, all_records[i]->itemName, 32 ); if (old_index == rec_num) { entry.addr = all_records[i]->addr + 36; _libfile.write((char*)&entry,36); } else { if (i < old_index) { if (opr == File_Add) { entry.addr = all_records[i]->addr; } else { entry.addr = all_records[i]->addr-36; } _libfile.write((char*)&entry,36); } else if (i == old_index) { if ( i != (rec_num - 1) ) { oldsld_size = all_records[i + 1]->addr - all_records[i]->addr; } else { oldsld_size = old_fsize - all_records[i]->addr; } } else { entry.addr = all_records[i]->addr - oldsld_size; if (opr == File_Del) { entry.addr = entry.addr - 36; } _libfile.write((char *)&entry,36); } } } if (opr == File_Add) { //假如已存在给定幻灯片, 则把原有幻灯删除后, 在把新的加入最后 memcpy(entry.itemName,itemName,32); if (old_index == rec_num) { entry.addr = old_fsize + 36; } else { entry.addr = old_fsize - oldsld_size; } _libfile.write((char *)&entry,36); } CT_clear_strbuf( entry.itemName, 32 ); entry.addr = 0L; _libfile.write((char *)&entry,36); //写最后一项空目录 if (rec_num > 0) { tmp_in.seekg(all_records[0]->addr, _ios::beg); if (old_index == rec_num) { m_pStreamFile->StreamCopy(tmp_in, _libfile, old_fsize - all_records[0]->addr); } else { long bufSize = all_records[old_index]->addr - all_records[0]->addr; if (bufSize) { m_pStreamFile->StreamCopy(tmp_in, _libfile, bufSize); } if (old_index < rec_num - 1) { tmp_in.seekg(all_records[old_index + 1]->addr, _ios::beg); m_pStreamFile->StreamCopy(tmp_in, _libfile, old_fsize-all_records[old_index + 1]->addr); } } } tmp_in.close(); remove(tmpfile); if (opr == File_Add) { sld_in.seekg(0, _ios::beg); m_pStreamFile->StreamCopy(sld_in, _libfile, newsld_fsize); } _libfile.close(); _libfile.open(slbfile, openMode); return 1; } //改第 n 个记录的内容 //返回值: 1--成功; 0--失败 int XASLibMan::Rename(int n, const TCHAR *sldname) { if (MoveFilePtr(n)) { char sldn[32]; CT_clear_strbuf(sldn, 32); strcpy(sldn, _AS(sldname)); _strupr(sldn); _libfile.write(sldn, 16); _libfile.flush(); return 1; } return 0; } // 移动或拷贝第 n 个幻灯 int XASLibMan::MoveOrCopy(int n, const TCHAR *sldfile, FileOperation opr) { int rec_num = Length(); if ((opr != File_Move && opr != File_Copy) || n >= rec_num) { return 0; } //取得所有的目录 Catalogue entry[2]; GetRecord(n, &entry[0]); if (n != rec_num - 1) { GetRecord(n + 1, &entry[1]); } _libfile.seekg(0, _ios::end); long old_fsize = _libfile.tellg(); long sld_fsize; if (n == rec_num - 1) { sld_fsize = (old_fsize - entry[0].addr); } else { sld_fsize = (entry[1].addr - entry[0].addr); } _libfile.seekg(entry[0].addr, _ios::beg); #if (ARX>15) std:: #endif ofstream sld_out(sldfile, _ios::out | _ios::binary); m_pStreamFile->StreamCopy(_libfile, sld_out, sld_fsize); if (opr != File_Move) { return 1; } return MainTain(TString(entry[0].itemName), File_Del); } // 拷贝名称为 sldfile的记录 To the DWG directory // 返回值: 0--失败; 1--正常; 2--扩展 int XASLibMan::QuickCopy(const TCHAR *pszItem) { char drive[_MAX_DRIVE] = "", dir[_MAX_DIR] = "", fname[_MAX_FNAME] = "", ext[_MAX_EXT] = ""; _splitpath(_AS(pszItem), drive, dir, fname, ext); char sldfile[80] = ""; strcpy(sldfile, fname); char szExt[16] = ""; //取得所有的目录 Catalogue entry[2]; entry[0].itemName[0] = entry[1].itemName[0] = 0; _libfile.clear(); _libfile.seekg(32, _ios::beg); Catalogue rec; while(1) { _libfile.read((char *)&rec, 36); if (!_libfile || !rec.itemName[0]) { return 0; } if(_stricmp(rec.itemName, sldfile) == 0) { for (int i = 0; i < 3; i++) { szExt[i] = rec.itemName[16 + i]; } szExt[3] = 0; entry[0] = rec; _libfile.read((char *)&entry[1], 36); if (!entry[1].itemName[0]) //最后一个记录 { _libfile.seekg(0, _ios::end); entry[1].addr = _libfile.tellg(); } break; } } _bstr_t bsdrive(drive); _bstr_t bsdir(dir); XString itemFile(256); if (drive[0] && dir[0]) { itemFile << (LPCTSTR)bsdrive << (LPCTSTR)bsdir; } else { xg_getvar(_T("DWGPREFIX"), (TCHAR *)itemFile); } _bstr_t bsExt(szExt); _bstr_t bssldfile(sldfile); itemFile << (LPCTSTR)bssldfile; if (!szExt[0]) { itemFile << itemExt; } else { itemFile << _T(".") << (LPCTSTR)bsExt; } long sld_fsize = entry[1].addr - entry[0].addr; _libfile.seekg(entry[0].addr, _ios::beg); #if (ARX>15) std:: #endif ofstream sld_out(itemFile, _ios::out | _ios::binary); if (!sld_out) { return 0; } m_pStreamFile->StreamCopy(_libfile, sld_out, sld_fsize); return szExt[0] ? 2 : 1; } // 把幻灯库里的一个幻灯移动到磁盘上的一个幻灯文件 int XASLibMan::Move(int n, const TCHAR *sldname) { return MoveOrCopy(n, sldname, File_Move); } // 把幻灯库里的一个幻灯拷贝到磁盘上的一个幻灯文件 int XASLibMan::Copy(int n, const TCHAR *sldname) { return MoveOrCopy(n, sldname, File_Copy); } // 读并建立一个缓冲区 char * XASLibMan::ReadItem(const TCHAR *sldfile, unsigned *pnFileSize) { char szExt[16] = ""; //取得所有的目录 Catalogue entry[2]; entry[0].itemName[0] = entry[1].itemName[0] = 0; _libfile.clear(); _libfile.seekg(32, _ios::beg); Catalogue rec; while(1) { _libfile.read((char *)&rec, 36); if (!_libfile || !rec.itemName[0]) { return NULL; } if (_stricmp(rec.itemName, _AS(sldfile)) == 0) { for (int i = 0; i < 3; i++) { szExt[i] = rec.itemName[16 + i]; } szExt[3] = 0; entry[0] = rec; _libfile.read((char *)&entry[1], 36); if (!entry[1].itemName[0]) //最后一个记录 { _libfile.seekg(0, _ios::end); entry[1].addr = _libfile.tellg(); } break; } } long sld_fsize = entry[1].addr - entry[0].addr; _libfile.seekg(entry[0].addr, _ios::beg); char * pItemBuf = new char [(int)sld_fsize]; _libfile.read(pItemBuf, (int)sld_fsize); if (pnFileSize) { *pnFileSize = (unsigned)sld_fsize; } return pItemBuf; } int XASLibMan::operator !() { return !_libfile; } void XASLibMan::Close() { _libfile.close(); } int XASLibMan::Remove(const TCHAR *sld) //sld--幻灯名 { return MainTain(sld, File_Del); }