757 lines
14 KiB
C++
757 lines
14 KiB
C++
//-----------------------------------------------------------------------------+
|
|
// Copyright (C), 1998-2007, Beijing Tangent Software Co. Ltd.
|
|
// = FileName : TGGiSlibStorage 类
|
|
// = Version : ver2.0
|
|
// = Author : wlw
|
|
// = CreateDate : 2002-09-09
|
|
// = Description: TGGiSlibStorage 定义
|
|
// = Maintainers:
|
|
//
|
|
//-----------------------------------------------------------------------------+
|
|
#include "StdAfx.h"
|
|
#include "TGGiSlibStorage.h"
|
|
#include "TAString.h"
|
|
#include "TUString.h"
|
|
|
|
#include <stdio.h>
|
|
#include <io.h>
|
|
#include <time.h>
|
|
|
|
#if (ADS>15)
|
|
#include <fstream>
|
|
#else
|
|
#include <fstream.h>
|
|
#endif
|
|
|
|
#include "fcntl.h"
|
|
#include "sys\stat.h"
|
|
#include "TchGlobalFunc.h"
|
|
|
|
|
|
static const TCHAR *sMsgPrompt[] = {_T("\n建立库文件%s!"),
|
|
_T("\n不能读取临时文件'%s'!"),
|
|
};
|
|
|
|
// 幻灯库的操作
|
|
TGGiSlibStorage::TGGiSlibStorage(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 TGGiStreamFile;
|
|
}
|
|
|
|
TGGiSlibStorage::~TGGiSlibStorage()
|
|
{
|
|
if (m_pStreamFile != NULL)
|
|
{
|
|
delete m_pStreamFile;
|
|
m_pStreamFile = NULL;
|
|
}
|
|
}
|
|
|
|
int TGGiSlibStorage::Open(const TCHAR *file, int mode)
|
|
{
|
|
openMode = mode;
|
|
if (file)
|
|
{
|
|
slbfile = file;
|
|
}
|
|
|
|
if (!slbfile || !openMode)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int isExist = (ads_findfile(slbfile, TCString(256)) == RTNORM);
|
|
|
|
if (!isExist && !(mode & _ios::out))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
#if (ADS>15) //需要事先创建
|
|
if(!isExist)
|
|
{
|
|
int nTempMode = _ios::binary|_ios::out;
|
|
std::ofstream out(slbfile, nTempMode);
|
|
|
|
STCatalogue entry;
|
|
StringBufferMemset(entry.itemName, 32 );
|
|
strcpy(entry.itemName,title);
|
|
|
|
entry.itemName[25] = 0x0d;
|
|
entry.itemName[26] = 0x0a;
|
|
entry.itemName[27] = 0x1a;
|
|
out.write(entry.itemName,32);
|
|
|
|
StringBufferMemset(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))
|
|
{
|
|
STCatalogue entry;
|
|
StringBufferMemset(entry.itemName, 32 );
|
|
strcpy(entry.itemName,title);
|
|
|
|
entry.itemName[25] = 0x0d;
|
|
entry.itemName[26] = 0x0a;
|
|
entry.itemName[27] = 0x1a;
|
|
_libfile.write(entry.itemName,32);
|
|
|
|
StringBufferMemset(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 TGGiSlibStorage::MoveFilePtr(int n)
|
|
{
|
|
_libfile.seekg(32, _ios::beg);
|
|
STCatalogue 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 TGGiSlibStorage::Length()
|
|
{
|
|
_libfile.clear();
|
|
_libfile.seekg(32, _ios::beg);
|
|
|
|
STCatalogue 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 TGGiSlibStorage::GetRecord(int n, STCatalogue *rec)
|
|
{
|
|
if (MoveFilePtr(n))
|
|
{
|
|
_libfile.read((char *)rec, 36);
|
|
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// 取得所有幻灯列表
|
|
// 返回幻灯的个数
|
|
// 注意: 用 delete 释放 sldlist
|
|
int TGGiSlibStorage::GetAll(TDPtrList<STCatalogue> &res)
|
|
{
|
|
_libfile.clear();
|
|
_libfile.seekg(32, _ios::beg);
|
|
|
|
STCatalogue entry;
|
|
int i = 0;
|
|
while(1)
|
|
{
|
|
if (!_libfile)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
_libfile.read((char *)&entry, 36);
|
|
if (!entry.itemName[0])
|
|
{
|
|
return i;
|
|
}
|
|
|
|
res.Append(new STCatalogue(entry));
|
|
i++;
|
|
}
|
|
}
|
|
|
|
int TGGiSlibStorage::GetAll(TDPtrList<TCHAR> &res)
|
|
{
|
|
_libfile.clear();
|
|
_libfile.seekg(32, _ios::beg);
|
|
|
|
if (!_libfile)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
int i = 0;
|
|
while(1)
|
|
{
|
|
if (!_libfile)
|
|
{
|
|
TchGeLib::adsout << _T("\nRead ") << slbfile << _T(" catalogue index=") << i << _T(" fail");
|
|
assert(0);
|
|
}
|
|
|
|
STCatalogue entry;
|
|
_libfile.read((char *)&entry, 36);
|
|
|
|
if (!entry.itemName[0])
|
|
{
|
|
return i;
|
|
}
|
|
|
|
res.Append(tstrnew(TString(entry.itemName)));
|
|
i++;
|
|
}
|
|
}
|
|
|
|
int TGGiSlibStorage::IsExist(const TCHAR *itemName, int *rec_index)
|
|
{
|
|
TCStringList records;
|
|
if (!GetAll(records))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
*rec_index = records.Index(itemName, 0);
|
|
if (*rec_index >= 0)
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// 往库文件里添加记录
|
|
int TGGiSlibStorage::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 TGGiSlibStorage::Remove(int n) // 删除库文件第 n 个记录
|
|
{
|
|
STCatalogue entry;
|
|
if (!GetRecord(n, &entry))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
return MainTain(TString(entry.itemName), File_Del);
|
|
}
|
|
|
|
int TGGiSlibStorage::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 (ADS > 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] = "";
|
|
StringBufferMemset(itemName, 32 );
|
|
if (szItem)
|
|
{
|
|
strcpy(itemName, _AS(szItem));
|
|
}
|
|
else
|
|
{
|
|
strcpy(itemName, _AS(szFName));
|
|
}
|
|
|
|
_strupr(itemName);
|
|
if (szExt[0])
|
|
{
|
|
strcpy(&itemName[16], &szExt[1]);
|
|
}
|
|
|
|
//取得所有的目录
|
|
TDPtrList<STCatalogue> 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 (ADS > 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;
|
|
STCatalogue entry;
|
|
for (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);
|
|
}
|
|
|
|
StringBufferMemset( 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 TGGiSlibStorage::Rename(int n, const TCHAR *sldname)
|
|
{
|
|
if (MoveFilePtr(n))
|
|
{
|
|
char sldn[32];
|
|
StringBufferMemset(sldn, 32);
|
|
strcpy(sldn, _AS(sldname));
|
|
_strupr(sldn);
|
|
_libfile.write(sldn, 16);
|
|
_libfile.flush();
|
|
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
// 移动或拷贝第 n 个幻灯
|
|
int TGGiSlibStorage::MoveOrCopy(int n, const TCHAR *sldfile, FileOperation opr)
|
|
{
|
|
int rec_num = Length();
|
|
if ((opr != File_Move && opr != File_Copy) || n >= rec_num)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
//取得所有的目录
|
|
STCatalogue 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 (ADS>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 TGGiSlibStorage::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] = "";
|
|
|
|
//取得所有的目录
|
|
STCatalogue entry[2];
|
|
entry[0].itemName[0] = entry[1].itemName[0] = 0;
|
|
|
|
_libfile.clear();
|
|
_libfile.seekg(32, _ios::beg);
|
|
STCatalogue 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;
|
|
}
|
|
}
|
|
|
|
TCString itemFile(256);
|
|
if (drive[0] && dir[0])
|
|
{
|
|
itemFile << drive << dir;
|
|
}
|
|
else
|
|
{
|
|
TGGetVar(_T("DWGPREFIX"), (TCHAR *)itemFile);
|
|
}
|
|
|
|
itemFile << sldfile;
|
|
if (!szExt[0])
|
|
{
|
|
itemFile << itemExt;
|
|
}
|
|
else
|
|
{
|
|
itemFile << "." << szExt;
|
|
}
|
|
|
|
long sld_fsize = entry[1].addr - entry[0].addr;
|
|
_libfile.seekg(entry[0].addr, _ios::beg);
|
|
|
|
#if (ADS>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 TGGiSlibStorage::Move(int n, const TCHAR *sldname)
|
|
{
|
|
return MoveOrCopy(n, sldname, File_Move);
|
|
}
|
|
|
|
// 把幻灯库里的一个幻灯拷贝到磁盘上的一个幻灯文件
|
|
int TGGiSlibStorage::Copy(int n, const TCHAR *sldname)
|
|
{
|
|
return MoveOrCopy(n, sldname, File_Copy);
|
|
}
|
|
|
|
// 读并建立一个缓冲区
|
|
char * TGGiSlibStorage::ReadItem(const TCHAR *sldfile, unsigned *pnFileSize)
|
|
{
|
|
char szExt[16] = "";
|
|
|
|
//取得所有的目录
|
|
STCatalogue entry[2];
|
|
entry[0].itemName[0] = entry[1].itemName[0] = 0;
|
|
|
|
_libfile.clear();
|
|
_libfile.seekg(32, _ios::beg);
|
|
STCatalogue 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 TGGiSlibStorage::operator !()
|
|
{
|
|
return !_libfile;
|
|
}
|
|
|
|
void TGGiSlibStorage::Close()
|
|
{
|
|
_libfile.close();
|
|
}
|
|
|
|
int TGGiSlibStorage::Remove(const TCHAR *sld) //sld--幻灯名
|
|
{
|
|
return MainTain(sld, File_Del);
|
|
} |