refactoring: split strlist.h classes into separate {h,cpp} files
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@3694 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
779e0354d2
commit
60aa307741
10 changed files with 971 additions and 798 deletions
|
@ -5,8 +5,8 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
# -- Objects and source files --
|
# -- Objects and source files --
|
||||||
SRCS = zlib/deflate.c zlib/trees.c bzip2/blocksort.c bzip2/bzlib.c bzip2/compress.c bzip2/huffman.c 7zip/7zGuids.cpp 7zip/Common/CRC.cpp 7zip/7zip/Compress/LZ/LZInWindow.cpp 7zip/7zip/Compress/LZMA/LZMAEncoder.cpp 7zip/7zip/Common/OutBuffer.cpp 7zip/7zip/Compress/RangeCoder/RangeCoderBit.cpp 7zip/Common/Alloc.cpp build.cpp crc32.c DialogTemplate.cpp exedata.cpp lang.cpp makenssi.cpp Plugins.cpp ResourceEditor.cpp ResourceVersionInfo.cpp script.cpp tokens.cpp util.cpp
|
SRCS = zlib/deflate.c zlib/trees.c bzip2/blocksort.c bzip2/bzlib.c bzip2/compress.c bzip2/huffman.c 7zip/7zGuids.cpp 7zip/Common/CRC.cpp 7zip/7zip/Compress/LZ/LZInWindow.cpp 7zip/7zip/Compress/LZMA/LZMAEncoder.cpp 7zip/7zip/Common/OutBuffer.cpp 7zip/7zip/Compress/RangeCoder/RangeCoderBit.cpp 7zip/Common/Alloc.cpp build.cpp crc32.c DialogTemplate.cpp exedata.cpp lang.cpp makenssi.cpp Plugins.cpp ResourceEditor.cpp ResourceVersionInfo.cpp script.cpp tokens.cpp util.cpp strlist.cpp growbuf.cpp mmap.cpp
|
||||||
OBJS = 7zGuids.o blocksort.o build.o bzlib.o compress.o CRC.o crc32.o deflate.o DialogTemplate.o exedata.o huffman.o lang.o LZInWindow.o LZMAEncoder.o Alloc.o makenssi.o OutBuffer.o Plugins.o RangeCoderBit.o ResourceEditor.o ResourceVersionInfo.o script.o tokens.o trees.o util.o
|
OBJS = 7zGuids.o blocksort.o build.o bzlib.o compress.o CRC.o crc32.o deflate.o DialogTemplate.o exedata.o huffman.o lang.o LZInWindow.o LZMAEncoder.o Alloc.o makenssi.o OutBuffer.o Plugins.o RangeCoderBit.o ResourceEditor.o ResourceVersionInfo.o script.o tokens.o trees.o util.o strlist.o growbuf.o mmap.o
|
||||||
ifeq "$(strip $(findstring i386pe,$(shell ld -V)))" ""
|
ifeq "$(strip $(findstring i386pe,$(shell ld -V)))" ""
|
||||||
LIBS = -lstdc++ -lpthread
|
LIBS = -lstdc++ -lpthread
|
||||||
EXESUFF =
|
EXESUFF =
|
||||||
|
|
|
@ -21,14 +21,14 @@
|
||||||
# include <stdarg.h>
|
# include <stdarg.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <cassert> // for assert
|
||||||
|
|
||||||
#define RET_UNLESS_OK( function_rc ) do { \
|
#define RET_UNLESS_OK( function_rc ) do { \
|
||||||
int rc = (function_rc); \
|
int rc = (function_rc); \
|
||||||
if ( rc != PS_OK) \
|
if ( rc != PS_OK) \
|
||||||
return rc; \
|
return rc; \
|
||||||
} while (false)
|
} while (false)
|
||||||
|
|
||||||
int MMapFile::m_iAllocationGranularity = 0;
|
|
||||||
|
|
||||||
#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
|
#ifdef NSIS_CONFIG_COMPRESSION_SUPPORT
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
DWORD WINAPI lzmaCompressThread(LPVOID lpParameter)
|
DWORD WINAPI lzmaCompressThread(LPVOID lpParameter)
|
||||||
|
@ -1508,18 +1508,18 @@ int CEXEBuild::resolve_coderefs(const char *str)
|
||||||
{
|
{
|
||||||
int x=sec->name_ptr;
|
int x=sec->name_ptr;
|
||||||
char fname[1024];
|
char fname[1024];
|
||||||
char *secname;
|
const char *section_name;
|
||||||
if (x < 0)
|
if (x < 0)
|
||||||
{
|
{
|
||||||
// lang string
|
// lang string
|
||||||
secname = "$(lang string)";
|
section_name = "$(lang string)";
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// normal string
|
// normal string
|
||||||
secname = cur_strlist->get() + x;
|
section_name = cur_strlist->get() + x;
|
||||||
}
|
}
|
||||||
if (x) wsprintf(fname,"%s section \"%s\" (%d)",str,secname,cnt);
|
if (x) wsprintf(fname,"%s section \"%s\" (%d)",str,section_name,cnt);
|
||||||
else wsprintf(fname,"unnamed %s section (%d)",str,cnt);
|
else wsprintf(fname,"unnamed %s section (%d)",str,cnt);
|
||||||
for (x = sec->code; x < sec->code+sec->code_size; x ++)
|
for (x = sec->code; x < sec->code+sec->code_size; x ++)
|
||||||
{
|
{
|
||||||
|
|
|
@ -12,6 +12,7 @@ using namespace std;
|
||||||
#include "ResourceVersionInfo.h"
|
#include "ResourceVersionInfo.h"
|
||||||
#include "uservars.h"
|
#include "uservars.h"
|
||||||
#include "ShConstants.h"
|
#include "ShConstants.h"
|
||||||
|
#include "mmap.h"
|
||||||
|
|
||||||
#include "exehead/fileform.h"
|
#include "exehead/fileform.h"
|
||||||
#include "exehead/config.h"
|
#include "exehead/config.h"
|
||||||
|
|
68
Source/growbuf.cpp
Normal file
68
Source/growbuf.cpp
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
#include "growbuf.h"
|
||||||
|
|
||||||
|
#include "Platform.h"
|
||||||
|
#include <cstdlib> // for malloc/free
|
||||||
|
#include <cstring> // for memcpy
|
||||||
|
#include <cstdio> // for f*
|
||||||
|
|
||||||
|
GrowBuf::GrowBuf() { m_alloc=m_used=m_zero=0; m_s=NULL; m_bs=32768; }
|
||||||
|
GrowBuf::~GrowBuf() { free(m_s); }
|
||||||
|
|
||||||
|
void GrowBuf::set_zeroing(int zero) { m_zero=zero; }
|
||||||
|
|
||||||
|
int GrowBuf::add(const void *data, int len)
|
||||||
|
{
|
||||||
|
if (len<=0) return 0;
|
||||||
|
resize(m_used+len);
|
||||||
|
memcpy((char*)m_s+m_used-len,data,len);
|
||||||
|
return m_used-len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GrowBuf::resize(int newlen)
|
||||||
|
{
|
||||||
|
int os=m_alloc;
|
||||||
|
int ou=m_used;
|
||||||
|
m_used=newlen;
|
||||||
|
if (newlen > m_alloc)
|
||||||
|
{
|
||||||
|
void *n;
|
||||||
|
m_alloc = newlen*2 + m_bs;
|
||||||
|
n = realloc(m_s, m_alloc);
|
||||||
|
if (!n)
|
||||||
|
{
|
||||||
|
extern FILE *g_output;
|
||||||
|
extern int g_display_errors;
|
||||||
|
if (g_display_errors)
|
||||||
|
{
|
||||||
|
fprintf(g_output,"\nack! realloc(%d) failed, trying malloc(%d)!\n",m_alloc,newlen);
|
||||||
|
fflush(g_output);
|
||||||
|
}
|
||||||
|
m_alloc=newlen; // try to malloc the minimum needed
|
||||||
|
n=malloc(m_alloc);
|
||||||
|
if (!n)
|
||||||
|
{
|
||||||
|
extern void quit();
|
||||||
|
if (g_display_errors)
|
||||||
|
{
|
||||||
|
fprintf(g_output,"\nInternal compiler error #12345: GrowBuf realloc/malloc(%d) failed.\n",m_alloc);
|
||||||
|
fflush(g_output);
|
||||||
|
}
|
||||||
|
quit();
|
||||||
|
}
|
||||||
|
memcpy(n,m_s,min(newlen,os));
|
||||||
|
free(m_s);
|
||||||
|
}
|
||||||
|
m_s=n;
|
||||||
|
}
|
||||||
|
if (m_zero && m_used > ou)
|
||||||
|
memset((char*)m_s + ou, 0, m_used - ou);
|
||||||
|
if (!m_used && m_alloc > 2*m_bs) // only free if you resize to 0 and we're > 64k
|
||||||
|
{
|
||||||
|
m_alloc=0;
|
||||||
|
free(m_s);
|
||||||
|
m_s=NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int GrowBuf::getlen() const { return m_used; }
|
||||||
|
void *GrowBuf::get() const { return m_s; }
|
46
Source/growbuf.h
Normal file
46
Source/growbuf.h
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
#ifndef __GROWBUF_H_
|
||||||
|
#define __GROWBUF_H_
|
||||||
|
|
||||||
|
class IGrowBuf
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual ~IGrowBuf() {}
|
||||||
|
virtual int add(const void *data, int len)=0;
|
||||||
|
virtual void resize(int newlen)=0;
|
||||||
|
virtual int getlen() const=0;
|
||||||
|
virtual void *get() const=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
class GrowBuf : public IGrowBuf
|
||||||
|
{
|
||||||
|
private: // don't copy instances
|
||||||
|
GrowBuf(const GrowBuf&);
|
||||||
|
void operator=(const GrowBuf&);
|
||||||
|
|
||||||
|
public:
|
||||||
|
GrowBuf();
|
||||||
|
virtual ~GrowBuf();
|
||||||
|
|
||||||
|
void set_zeroing(int zero);
|
||||||
|
int add(const void *data, int len);
|
||||||
|
void resize(int newlen);
|
||||||
|
int getlen() const;
|
||||||
|
void *get() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void *m_s;
|
||||||
|
int m_alloc;
|
||||||
|
int m_used;
|
||||||
|
int m_zero;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int m_bs;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TinyGrowBuf : public GrowBuf {
|
||||||
|
public:
|
||||||
|
TinyGrowBuf() : GrowBuf() { m_bs=1024; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
491
Source/mmap.cpp
Normal file
491
Source/mmap.cpp
Normal file
|
@ -0,0 +1,491 @@
|
||||||
|
#include "mmap.h"
|
||||||
|
|
||||||
|
#include <cstdio> // for f*
|
||||||
|
#include <cassert> // for assert
|
||||||
|
#ifndef _WIN32
|
||||||
|
# include <sys/mman.h>
|
||||||
|
# include <sys/stat.h>
|
||||||
|
# include <fcntl.h>
|
||||||
|
# include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ========
|
||||||
|
// MMapFile
|
||||||
|
// ========
|
||||||
|
|
||||||
|
int MMapFile::m_iAllocationGranularity = 0;
|
||||||
|
|
||||||
|
MMapFile::MMapFile()
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
m_hFile = INVALID_HANDLE_VALUE;
|
||||||
|
m_hFileMap = NULL;
|
||||||
|
#else
|
||||||
|
m_hFile = NULL;
|
||||||
|
m_hFileDesc = -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_pView = NULL;
|
||||||
|
m_iSize = 0;
|
||||||
|
m_bReadOnly = FALSE;
|
||||||
|
m_bTempHandle = FALSE;
|
||||||
|
|
||||||
|
if (!m_iAllocationGranularity)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
SYSTEM_INFO si;
|
||||||
|
GetSystemInfo(&si);
|
||||||
|
m_iAllocationGranularity = (int) si.dwAllocationGranularity;
|
||||||
|
#else
|
||||||
|
m_iAllocationGranularity = getpagesize();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MMapFile::~MMapFile()
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MMapFile::clear()
|
||||||
|
{
|
||||||
|
release();
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (m_hFileMap)
|
||||||
|
CloseHandle(m_hFileMap);
|
||||||
|
if (m_bTempHandle && m_hFile != INVALID_HANDLE_VALUE)
|
||||||
|
CloseHandle(m_hFile);
|
||||||
|
|
||||||
|
m_hFile = INVALID_HANDLE_VALUE;
|
||||||
|
m_hFileMap = 0;
|
||||||
|
#else
|
||||||
|
if (m_bTempHandle && m_hFile)
|
||||||
|
fclose(m_hFile);
|
||||||
|
|
||||||
|
m_hFile = NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void MMapFile::setro(BOOL bRO)
|
||||||
|
{
|
||||||
|
m_bReadOnly = bRO;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
int MMapFile::setfile(HANDLE hFile, DWORD dwSize)
|
||||||
|
#else
|
||||||
|
int MMapFile::setfile(int hFile, DWORD dwSize)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
clear();
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
m_hFile = hFile;
|
||||||
|
#else
|
||||||
|
m_hFileDesc = hFile;
|
||||||
|
#endif
|
||||||
|
m_bTempHandle = FALSE;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (m_hFile == INVALID_HANDLE_VALUE)
|
||||||
|
#else
|
||||||
|
if (m_hFileDesc == -1)
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
m_iSize = (int) dwSize;
|
||||||
|
|
||||||
|
if (m_iSize <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
m_hFileMap = CreateFileMapping(m_hFile, NULL, PAGE_READONLY, 0, m_iSize, NULL);
|
||||||
|
|
||||||
|
if (!m_hFileMap)
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_bReadOnly = TRUE;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MMapFile::resize(int newsize)
|
||||||
|
{
|
||||||
|
release();
|
||||||
|
|
||||||
|
if (newsize > m_iSize)
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (m_hFileMap)
|
||||||
|
CloseHandle(m_hFileMap);
|
||||||
|
|
||||||
|
m_hFileMap = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_iSize = newsize;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (m_hFile == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
char buf[MAX_PATH], buf2[MAX_PATH];
|
||||||
|
|
||||||
|
GetTempPath(MAX_PATH, buf);
|
||||||
|
GetTempFileName(buf, "nsd", 0, buf2);
|
||||||
|
|
||||||
|
m_hFile = CreateFile(
|
||||||
|
buf2,
|
||||||
|
GENERIC_READ | GENERIC_WRITE,
|
||||||
|
0,
|
||||||
|
NULL,
|
||||||
|
CREATE_ALWAYS,
|
||||||
|
FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE | FILE_FLAG_SEQUENTIAL_SCAN,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
m_bTempHandle = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_hFile != INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
m_hFileMap = CreateFileMapping(
|
||||||
|
m_hFile,
|
||||||
|
NULL,
|
||||||
|
m_bReadOnly ? PAGE_READONLY : PAGE_READWRITE,
|
||||||
|
0,
|
||||||
|
m_iSize,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (m_hFile == NULL)
|
||||||
|
{
|
||||||
|
m_hFile = tmpfile();
|
||||||
|
if (m_hFile != NULL)
|
||||||
|
{
|
||||||
|
m_hFileDesc = fileno(m_hFile);
|
||||||
|
m_bTempHandle = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// resize
|
||||||
|
if (m_hFileDesc != -1)
|
||||||
|
{
|
||||||
|
unsigned char c = 0;
|
||||||
|
|
||||||
|
if (lseek(m_hFileDesc, m_iSize, SEEK_SET) != (off_t)-1)
|
||||||
|
{
|
||||||
|
if (read(m_hFileDesc, &c, 1) != -1)
|
||||||
|
{
|
||||||
|
if (lseek(m_hFileDesc, m_iSize, SEEK_SET) != (off_t)-1)
|
||||||
|
{
|
||||||
|
if (write(m_hFileDesc, &c, 1) != -1)
|
||||||
|
{
|
||||||
|
return; // no errors
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_hFileDesc = -1; // some error occured, bail
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (!m_hFileMap)
|
||||||
|
#else
|
||||||
|
if (m_hFileDesc == -1)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
extern FILE *g_output;
|
||||||
|
extern void quit(); extern int g_display_errors;
|
||||||
|
if (g_display_errors)
|
||||||
|
{
|
||||||
|
fprintf(g_output,"\nInternal compiler error #12345: error creating mmap the size of %d.\n", m_iSize);
|
||||||
|
fflush(g_output);
|
||||||
|
}
|
||||||
|
quit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int MMapFile::getsize() const
|
||||||
|
{
|
||||||
|
return m_iSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *MMapFile::get(int offset, int size) const
|
||||||
|
{
|
||||||
|
return get(offset, &size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *MMapFile::get(int offset, int *sizep) const
|
||||||
|
{
|
||||||
|
if (!sizep)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
assert(!m_pView);
|
||||||
|
|
||||||
|
int size = *sizep;
|
||||||
|
|
||||||
|
if (!m_iSize || offset + size > m_iSize)
|
||||||
|
{
|
||||||
|
extern FILE *g_output;
|
||||||
|
extern void quit(); extern int g_display_errors;
|
||||||
|
if (g_display_errors)
|
||||||
|
{
|
||||||
|
fprintf(g_output,"\nInternal compiler error #12345: error mmapping file (%d, %d) is out of range.\n", offset, size);
|
||||||
|
fflush(g_output);
|
||||||
|
}
|
||||||
|
quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
// fix offset
|
||||||
|
int alignedoffset = offset - (offset % m_iAllocationGranularity);
|
||||||
|
size += offset - alignedoffset;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
const_cast<MMapFile*>(this)->m_pView =
|
||||||
|
MapViewOfFile(m_hFileMap, m_bReadOnly ? FILE_MAP_READ : FILE_MAP_WRITE, 0, alignedoffset, size);
|
||||||
|
#else
|
||||||
|
const_cast<MMapFile*>(this)->m_pView =
|
||||||
|
mmap(0, size, m_bReadOnly ? PROT_READ : PROT_READ | PROT_WRITE, MAP_SHARED, m_hFileDesc, alignedoffset);
|
||||||
|
const_cast<MMapFile*>(this)->m_iMappedSize = *sizep = size;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (!m_pView)
|
||||||
|
#else
|
||||||
|
if (m_pView == MAP_FAILED)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
extern FILE *g_output;
|
||||||
|
extern void quit(); extern int g_display_errors;
|
||||||
|
if (g_display_errors)
|
||||||
|
{
|
||||||
|
fprintf(g_output,"\nInternal compiler error #12345: error mmapping datablock to %d.\n", size);
|
||||||
|
fflush(g_output);
|
||||||
|
}
|
||||||
|
quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (void *)((char *)m_pView + offset - alignedoffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *MMapFile::getmore(int offset, int *size) const
|
||||||
|
{
|
||||||
|
void *pView;
|
||||||
|
void *pViewBackup = m_pView;
|
||||||
|
#ifndef _WIN32
|
||||||
|
int iMappedSizeBackup = m_iMappedSize;
|
||||||
|
#endif
|
||||||
|
const_cast<MMapFile*>(this)->m_pView = 0;
|
||||||
|
pView = get(offset, size);
|
||||||
|
const_cast<MMapFile*>(this)->m_pView = pViewBackup;
|
||||||
|
#ifndef _WIN32
|
||||||
|
const_cast<MMapFile*>(this)->m_iMappedSize = iMappedSizeBackup;
|
||||||
|
#endif
|
||||||
|
return pView;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MMapFile::release()
|
||||||
|
{
|
||||||
|
if (!m_pView)
|
||||||
|
return;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
UnmapViewOfFile(m_pView);
|
||||||
|
#else
|
||||||
|
munmap(m_pView, m_iMappedSize);
|
||||||
|
#endif
|
||||||
|
m_pView = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MMapFile::release(void *pView, int size)
|
||||||
|
{
|
||||||
|
if (!pView)
|
||||||
|
return;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
UnmapViewOfFile(pView);
|
||||||
|
#else
|
||||||
|
munmap(pView, size);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void MMapFile::flush(int num)
|
||||||
|
{
|
||||||
|
if (m_pView)
|
||||||
|
#ifdef _WIN32
|
||||||
|
FlushViewOfFile(m_pView, num);
|
||||||
|
#else
|
||||||
|
msync(m_pView, num, MS_SYNC);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// ========
|
||||||
|
// MMapFake
|
||||||
|
// ========
|
||||||
|
|
||||||
|
MMapFake::MMapFake()
|
||||||
|
{
|
||||||
|
m_pMem = NULL;
|
||||||
|
m_iSize = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MMapFake::set(const char *pMem, int iSize)
|
||||||
|
{
|
||||||
|
m_pMem = pMem;
|
||||||
|
m_iSize = iSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
int MMapFake::getsize() const
|
||||||
|
{
|
||||||
|
return m_iSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *MMapFake::get(int offset, int size) const
|
||||||
|
{
|
||||||
|
return get(offset, &size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *MMapFake::get(int offset, int *size) const
|
||||||
|
{
|
||||||
|
if (!size || (offset + *size > m_iSize))
|
||||||
|
return NULL;
|
||||||
|
return (void *)(m_pMem + offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *MMapFake::getmore(int offset, int *size) const
|
||||||
|
{
|
||||||
|
return get(offset, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MMapFake::resize(int n) {}
|
||||||
|
void MMapFake::release() {}
|
||||||
|
void MMapFake::release(void *p, int size) {}
|
||||||
|
void MMapFake::clear() {}
|
||||||
|
void MMapFake::setro(BOOL b) {}
|
||||||
|
void MMapFake::flush(BOOL b) {}
|
||||||
|
|
||||||
|
// =======
|
||||||
|
// MMapBuf
|
||||||
|
// =======
|
||||||
|
|
||||||
|
MMapBuf::MMapBuf()
|
||||||
|
{
|
||||||
|
m_gb_u=0;
|
||||||
|
m_alloc=m_used=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
MMapBuf::~MMapBuf()
|
||||||
|
{
|
||||||
|
m_fm.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
int MMapBuf::add(const void *data, int len)
|
||||||
|
{
|
||||||
|
if (len <= 0) return 0;
|
||||||
|
resize(getlen() + len);
|
||||||
|
memcpy((char*)get(getlen() - len, len), data, len);
|
||||||
|
return getlen() - len;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MMapBuf::setro(BOOL bRO)
|
||||||
|
{
|
||||||
|
m_fm.setro(bRO);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MMapBuf::resize(int newlen)
|
||||||
|
{
|
||||||
|
if (!m_gb_u && newlen < (16 << 20)) // still in db mode
|
||||||
|
{
|
||||||
|
m_gb.resize(newlen);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// not in db mode
|
||||||
|
m_gb_u = 1;
|
||||||
|
m_used = newlen;
|
||||||
|
|
||||||
|
if (newlen > m_alloc)
|
||||||
|
{
|
||||||
|
m_alloc = newlen + (16 << 20); // add 16mb to top of mapping
|
||||||
|
|
||||||
|
m_fm.resize(m_alloc);
|
||||||
|
|
||||||
|
if (m_gb.getlen())
|
||||||
|
{
|
||||||
|
memcpy(m_fm.get(0, m_gb.getlen()), m_gb.get(), m_gb.getlen());
|
||||||
|
m_fm.flush(m_gb.getlen());
|
||||||
|
m_fm.release();
|
||||||
|
m_gb.resize(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int MMapBuf::getsize() const
|
||||||
|
{
|
||||||
|
if (m_gb_u)
|
||||||
|
return m_fm.getsize();
|
||||||
|
return m_gb.getlen();
|
||||||
|
}
|
||||||
|
|
||||||
|
int MMapBuf::getlen() const
|
||||||
|
{
|
||||||
|
if (m_gb_u)
|
||||||
|
return m_used;
|
||||||
|
return m_gb.getlen();
|
||||||
|
}
|
||||||
|
|
||||||
|
void *MMapBuf::get() const
|
||||||
|
{
|
||||||
|
return get(0, m_alloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *MMapBuf::get(int offset, int *sizep) const
|
||||||
|
{
|
||||||
|
if (!sizep)
|
||||||
|
return NULL;
|
||||||
|
int size = *sizep;
|
||||||
|
return get(offset, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *MMapBuf::get(int offset, int size) const
|
||||||
|
{
|
||||||
|
if (m_gb_u)
|
||||||
|
return m_fm.get(offset, size);
|
||||||
|
return (void *) ((char *) m_gb.get() + offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *MMapBuf::getmore(int offset, int *size) const
|
||||||
|
{
|
||||||
|
if (m_gb_u)
|
||||||
|
return m_fm.getmore(offset, size);
|
||||||
|
return (void *) ((char *) m_gb.get() + offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MMapBuf::release()
|
||||||
|
{
|
||||||
|
if (m_gb_u)
|
||||||
|
m_fm.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MMapBuf::release(void *pView, int size)
|
||||||
|
{
|
||||||
|
if (m_gb_u)
|
||||||
|
m_fm.release(pView, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MMapBuf::clear()
|
||||||
|
{
|
||||||
|
if (m_gb_u)
|
||||||
|
m_fm.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void MMapBuf::flush(int num)
|
||||||
|
{
|
||||||
|
if (m_gb_u)
|
||||||
|
m_fm.flush(num);
|
||||||
|
}
|
124
Source/mmap.h
Normal file
124
Source/mmap.h
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
#ifndef __MMAP_H_
|
||||||
|
#define __MMAP_H_
|
||||||
|
|
||||||
|
#include "Platform.h"
|
||||||
|
#include "growbuf.h"
|
||||||
|
|
||||||
|
class IMMap
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
virtual void resize(int newlen)=0;
|
||||||
|
virtual int getsize() const=0;
|
||||||
|
virtual void *get(int offset, int size) const=0;
|
||||||
|
virtual void *get(int offset, int *size) const=0;
|
||||||
|
virtual void *getmore(int offset, int *size) const=0;
|
||||||
|
virtual void release()=0;
|
||||||
|
virtual void release(void *view, int size)=0;
|
||||||
|
virtual void clear()=0;
|
||||||
|
virtual void setro(BOOL bRO)=0;
|
||||||
|
virtual void flush(int num)=0;
|
||||||
|
virtual ~IMMap() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class MMapFile : public IMMap
|
||||||
|
{
|
||||||
|
private: // don't copy instances
|
||||||
|
MMapFile(const MMapFile&);
|
||||||
|
void operator=(const MMapFile&);
|
||||||
|
|
||||||
|
public:
|
||||||
|
MMapFile();
|
||||||
|
virtual ~MMapFile();
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
void setro(BOOL bRO);
|
||||||
|
#ifdef _WIN32
|
||||||
|
int setfile(HANDLE hFile, DWORD dwSize);
|
||||||
|
#else
|
||||||
|
int setfile(int hFile, DWORD dwSize);
|
||||||
|
#endif
|
||||||
|
void resize(int newsize);
|
||||||
|
int getsize() const;
|
||||||
|
void *get(int offset, int size) const;
|
||||||
|
void *get(int offset, int *sizep) const;
|
||||||
|
void *getmore(int offset, int *size) const;
|
||||||
|
void release();
|
||||||
|
void release(void *pView, int size);
|
||||||
|
void flush(int num);
|
||||||
|
|
||||||
|
private:
|
||||||
|
#ifdef _WIN32
|
||||||
|
HANDLE m_hFile, m_hFileMap;
|
||||||
|
#else
|
||||||
|
FILE *m_hFile;
|
||||||
|
int m_hFileDesc;
|
||||||
|
int m_iMappedSize;
|
||||||
|
#endif
|
||||||
|
void *m_pView;
|
||||||
|
int m_iSize;
|
||||||
|
BOOL m_bReadOnly;
|
||||||
|
BOOL m_bTempHandle;
|
||||||
|
|
||||||
|
static int m_iAllocationGranularity;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MMapFake : public IMMap
|
||||||
|
{
|
||||||
|
private: // don't copy instances
|
||||||
|
MMapFake(const MMapFake&);
|
||||||
|
void operator=(const MMapFake&);
|
||||||
|
public:
|
||||||
|
MMapFake();
|
||||||
|
|
||||||
|
void set(const char *pMem, int iSize);
|
||||||
|
int getsize() const;
|
||||||
|
void *get(int offset, int size) const;
|
||||||
|
void *get(int offset, int *size) const;
|
||||||
|
void *getmore(int offset, int *size) const;
|
||||||
|
|
||||||
|
void resize(int n);
|
||||||
|
void release();
|
||||||
|
void release(void *p, int size);
|
||||||
|
void clear();
|
||||||
|
void setro(BOOL b);
|
||||||
|
void flush(BOOL b);
|
||||||
|
|
||||||
|
private:
|
||||||
|
const char *m_pMem;
|
||||||
|
int m_iSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MMapBuf : public IGrowBuf, public IMMap
|
||||||
|
{
|
||||||
|
private: // don't copy instances
|
||||||
|
MMapBuf(const MMapBuf&);
|
||||||
|
void operator=(const MMapBuf&);
|
||||||
|
|
||||||
|
public:
|
||||||
|
MMapBuf();
|
||||||
|
virtual ~MMapBuf();
|
||||||
|
|
||||||
|
int add(const void *data, int len);
|
||||||
|
void setro(BOOL bRO);
|
||||||
|
void resize(int newlen);
|
||||||
|
int getsize() const;
|
||||||
|
int getlen() const;
|
||||||
|
void *get() const;
|
||||||
|
void *get(int offset, int *sizep) const;
|
||||||
|
void *get(int offset, int size) const;
|
||||||
|
void *getmore(int offset, int *size) const;
|
||||||
|
void release();
|
||||||
|
void release(void *pView, int size);
|
||||||
|
void clear();
|
||||||
|
void flush(int num);
|
||||||
|
|
||||||
|
private:
|
||||||
|
GrowBuf m_gb;
|
||||||
|
MMapFile m_fm;
|
||||||
|
|
||||||
|
int m_gb_u;
|
||||||
|
int m_alloc, m_used;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif//__MMAP_H_
|
||||||
|
|
192
Source/strlist.cpp
Normal file
192
Source/strlist.cpp
Normal file
|
@ -0,0 +1,192 @@
|
||||||
|
#include "strlist.h"
|
||||||
|
|
||||||
|
// ==========
|
||||||
|
// StringList
|
||||||
|
// ==========
|
||||||
|
|
||||||
|
int StringList::add(const char *str, int case_sensitive)
|
||||||
|
{
|
||||||
|
int a=find(str,case_sensitive);
|
||||||
|
if (a >= 0 && case_sensitive!=-1) return a;
|
||||||
|
return gr.add(str,strlen(str)+1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// use 2 for case sensitive end-of-string matches too
|
||||||
|
int StringList::find(const char *str, int case_sensitive, int *idx/*=NULL*/) const // returns -1 if not found
|
||||||
|
{
|
||||||
|
const char *s=get();
|
||||||
|
int ml=getlen();
|
||||||
|
int offs=0;
|
||||||
|
if (idx) *idx=0;
|
||||||
|
while (offs < ml)
|
||||||
|
{
|
||||||
|
if ((case_sensitive && !strcmp(s+offs,str)) ||
|
||||||
|
(!case_sensitive && !stricmp(s+offs,str)))
|
||||||
|
{
|
||||||
|
return offs;
|
||||||
|
}
|
||||||
|
if (case_sensitive==2 &&
|
||||||
|
strlen(str) < strlen(s+offs) && // check for end of string
|
||||||
|
!strcmp(s+offs+strlen(s+offs)-strlen(str),str))
|
||||||
|
{
|
||||||
|
return offs+strlen(s+offs)-strlen(str);
|
||||||
|
}
|
||||||
|
offs+=strlen(s+offs)+1;
|
||||||
|
if (idx) (*idx)++;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StringList::delbypos(int pos)
|
||||||
|
{
|
||||||
|
char *s=(char*)gr.get();
|
||||||
|
int len=strlen(s+pos)+1;
|
||||||
|
if (pos+len < gr.getlen()) memcpy(s+pos,s+pos+len,gr.getlen()-(pos+len));
|
||||||
|
gr.resize(gr.getlen()-len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int StringList::idx2pos(int idx) const
|
||||||
|
{
|
||||||
|
char *s=(char*)gr.get();
|
||||||
|
int offs=0;
|
||||||
|
int cnt=0;
|
||||||
|
if (idx>=0) while (offs < gr.getlen())
|
||||||
|
{
|
||||||
|
if (cnt++ == idx) return offs;
|
||||||
|
offs+=strlen(s+offs)+1;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int StringList::getnum() const
|
||||||
|
{
|
||||||
|
char *s=(char*)gr.get();
|
||||||
|
int ml=gr.getlen();
|
||||||
|
int offs=0;
|
||||||
|
int idx=0;
|
||||||
|
while (offs < ml)
|
||||||
|
{
|
||||||
|
offs+=strlen(s+offs)+1;
|
||||||
|
idx++;
|
||||||
|
}
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *StringList::get() const
|
||||||
|
{
|
||||||
|
return (const char*)gr.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
int StringList::getlen() const
|
||||||
|
{
|
||||||
|
return gr.getlen();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==========
|
||||||
|
// DefineList
|
||||||
|
// ==========
|
||||||
|
|
||||||
|
DefineList::~DefineList()
|
||||||
|
{
|
||||||
|
struct define *s=(struct define*)gr.get();
|
||||||
|
int num=gr.getlen()/sizeof(struct define);
|
||||||
|
|
||||||
|
for (int i=0; i<num; i++) {
|
||||||
|
free(s[i].value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int DefineList::add(const char *name, const char *value/*=""*/)
|
||||||
|
{
|
||||||
|
int pos=SortedStringList<struct define>::add(name);
|
||||||
|
if (pos == -1)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char **newvalue=&(((struct define*)gr.get())[pos].value);
|
||||||
|
*newvalue=(char*)malloc(strlen(value)+1);
|
||||||
|
if (!(*newvalue))
|
||||||
|
{
|
||||||
|
extern FILE *g_output;
|
||||||
|
extern int g_display_errors;
|
||||||
|
extern void quit();
|
||||||
|
if (g_display_errors)
|
||||||
|
{
|
||||||
|
fprintf(g_output,"\nInternal compiler error #12345: GrowBuf realloc/malloc(%d) failed.\n",strlen(value)+1);
|
||||||
|
fflush(g_output);
|
||||||
|
}
|
||||||
|
quit();
|
||||||
|
}
|
||||||
|
strcpy(*newvalue,value);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *DefineList::find(const char *name)
|
||||||
|
{
|
||||||
|
int v=SortedStringList<struct define>::find(name);
|
||||||
|
if (v==-1)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return ((struct define*)gr.get())[v].value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns 0 on success, 1 otherwise
|
||||||
|
int DefineList::del(const char *str)
|
||||||
|
{
|
||||||
|
int pos=SortedStringList<struct define>::find(str);
|
||||||
|
if (pos==-1) return 1;
|
||||||
|
|
||||||
|
struct define *db=(struct define *)gr.get();
|
||||||
|
free(db[pos].value);
|
||||||
|
delbypos(pos);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DefineList::getnum()
|
||||||
|
{
|
||||||
|
return gr.getlen()/sizeof(define);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *DefineList::getname(int num)
|
||||||
|
{
|
||||||
|
if ((unsigned int)getnum() <= (unsigned int)num)
|
||||||
|
return 0;
|
||||||
|
return ((struct define*)gr.get())[num].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *DefineList::getvalue(int num)
|
||||||
|
{
|
||||||
|
if ((unsigned int)getnum() <= (unsigned int)num)
|
||||||
|
return 0;
|
||||||
|
return ((struct define*)gr.get())[num].value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==============
|
||||||
|
// FastStringList
|
||||||
|
// ==============
|
||||||
|
|
||||||
|
int FastStringList::add(const char *name, int case_sensitive/*=0*/)
|
||||||
|
{
|
||||||
|
int pos = SortedStringListND<struct string_t>::add(name, case_sensitive);
|
||||||
|
if (pos == -1) return -1;
|
||||||
|
return ((struct string_t*)gr.get())[pos].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *FastStringList::get() const
|
||||||
|
{
|
||||||
|
return (char*)strings.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
int FastStringList::getlen() const
|
||||||
|
{
|
||||||
|
return strings.getlen();
|
||||||
|
}
|
||||||
|
|
||||||
|
int FastStringList::getnum() const
|
||||||
|
{
|
||||||
|
return gr.getlen()/sizeof(struct string_t);
|
||||||
|
}
|
||||||
|
|
829
Source/strlist.h
829
Source/strlist.h
|
@ -2,196 +2,28 @@
|
||||||
#define _STRLIST_H_
|
#define _STRLIST_H_
|
||||||
|
|
||||||
#include "Platform.h"
|
#include "Platform.h"
|
||||||
#include <stdio.h>
|
#include <cstdio>
|
||||||
#include <stdlib.h> // for gcc
|
#include "growbuf.h"
|
||||||
#ifndef _WIN32
|
|
||||||
# include <sys/mman.h>
|
|
||||||
# include <sys/stat.h>
|
|
||||||
# include <fcntl.h>
|
|
||||||
# include <unistd.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <cassert> // for assert
|
|
||||||
|
|
||||||
class IGrowBuf
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual int add(const void *data, int len)=0;
|
|
||||||
virtual void resize(int newlen)=0;
|
|
||||||
virtual int getlen() const=0;
|
|
||||||
virtual void *get() const=0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class IMMap
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual void resize(int newlen)=0;
|
|
||||||
virtual int getsize() const=0;
|
|
||||||
virtual void *get(int offset, int size) const=0;
|
|
||||||
virtual void *get(int offset, int *size) const=0;
|
|
||||||
virtual void *getmore(int offset, int *size) const=0;
|
|
||||||
virtual void release()=0;
|
|
||||||
virtual void release(void *view, int size)=0;
|
|
||||||
virtual void clear()=0;
|
|
||||||
virtual void setro(BOOL bRO)=0;
|
|
||||||
virtual void flush(int num)=0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class GrowBuf : public IGrowBuf
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
GrowBuf() { m_alloc=m_used=m_zero=0; m_s=NULL; m_bs=32768; }
|
|
||||||
virtual ~GrowBuf() { free(m_s); }
|
|
||||||
|
|
||||||
void set_zeroing(int zero) { m_zero=zero; }
|
|
||||||
|
|
||||||
int add(const void *data, int len)
|
|
||||||
{
|
|
||||||
if (len<=0) return 0;
|
|
||||||
resize(m_used+len);
|
|
||||||
memcpy((char*)m_s+m_used-len,data,len);
|
|
||||||
return m_used-len;
|
|
||||||
}
|
|
||||||
|
|
||||||
void resize(int newlen)
|
|
||||||
{
|
|
||||||
int os=m_alloc;
|
|
||||||
int ou=m_used;
|
|
||||||
m_used=newlen;
|
|
||||||
if (newlen > m_alloc)
|
|
||||||
{
|
|
||||||
void *n;
|
|
||||||
m_alloc = newlen*2 + m_bs;
|
|
||||||
n = realloc(m_s, m_alloc);
|
|
||||||
if (!n)
|
|
||||||
{
|
|
||||||
extern FILE *g_output;
|
|
||||||
extern int g_display_errors;
|
|
||||||
if (g_display_errors)
|
|
||||||
{
|
|
||||||
fprintf(g_output,"\nack! realloc(%d) failed, trying malloc(%d)!\n",m_alloc,newlen);
|
|
||||||
fflush(g_output);
|
|
||||||
}
|
|
||||||
m_alloc=newlen; // try to malloc the minimum needed
|
|
||||||
n=malloc(m_alloc);
|
|
||||||
if (!n)
|
|
||||||
{
|
|
||||||
extern void quit();
|
|
||||||
if (g_display_errors)
|
|
||||||
{
|
|
||||||
fprintf(g_output,"\nInternal compiler error #12345: GrowBuf realloc/malloc(%d) failed.\n",m_alloc);
|
|
||||||
fflush(g_output);
|
|
||||||
}
|
|
||||||
quit();
|
|
||||||
}
|
|
||||||
memcpy(n,m_s,min(newlen,os));
|
|
||||||
free(m_s);
|
|
||||||
}
|
|
||||||
m_s=n;
|
|
||||||
}
|
|
||||||
if (m_zero && m_used > ou)
|
|
||||||
memset((char*)m_s + ou, 0, m_used - ou);
|
|
||||||
if (!m_used && m_alloc > 2*m_bs) // only free if you resize to 0 and we're > 64k
|
|
||||||
{
|
|
||||||
m_alloc=0;
|
|
||||||
free(m_s);
|
|
||||||
m_s=NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int getlen() const { return m_used; }
|
|
||||||
void *get() const { return m_s; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
void *m_s;
|
|
||||||
int m_alloc;
|
|
||||||
int m_used;
|
|
||||||
int m_zero;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
int m_bs;
|
|
||||||
};
|
|
||||||
|
|
||||||
class TinyGrowBuf : public GrowBuf {
|
|
||||||
public:
|
|
||||||
TinyGrowBuf() : GrowBuf() { m_bs=1024; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class StringList
|
class StringList
|
||||||
{
|
{
|
||||||
|
private: // don't copy instances
|
||||||
|
StringList(const StringList&);
|
||||||
|
void operator=(const StringList&);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
StringList() { }
|
StringList() {}
|
||||||
~StringList() { }
|
~StringList() {}
|
||||||
|
|
||||||
int add(const char *str, int case_sensitive)
|
|
||||||
{
|
|
||||||
int a=find(str,case_sensitive);
|
|
||||||
if (a >= 0 && case_sensitive!=-1) return a;
|
|
||||||
return gr.add(str,strlen(str)+1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
int add(const char *str, int case_sensitive);
|
||||||
// use 2 for case sensitive end-of-string matches too
|
// use 2 for case sensitive end-of-string matches too
|
||||||
int find(const char *str, int case_sensitive, int *idx=NULL) // returns -1 if not found
|
int find(const char *str, int case_sensitive, int *idx=NULL) const; // returns -1 if not found
|
||||||
{
|
void delbypos(int pos);
|
||||||
char *s=(char*)gr.get();
|
int idx2pos(int idx) const;
|
||||||
int ml=gr.getlen();
|
int getnum() const;
|
||||||
int offs=0;
|
const char *get() const;
|
||||||
if (idx) *idx=0;
|
int getlen() const;
|
||||||
while (offs < ml)
|
|
||||||
{
|
|
||||||
if ((case_sensitive && !strcmp(s+offs,str)) ||
|
|
||||||
(!case_sensitive && !stricmp(s+offs,str)))
|
|
||||||
{
|
|
||||||
return offs;
|
|
||||||
}
|
|
||||||
if (case_sensitive==2 &&
|
|
||||||
strlen(str) < strlen(s+offs) && // check for end of string
|
|
||||||
!strcmp(s+offs+strlen(s+offs)-strlen(str),str))
|
|
||||||
{
|
|
||||||
return offs+strlen(s+offs)-strlen(str);
|
|
||||||
}
|
|
||||||
offs+=strlen(s+offs)+1;
|
|
||||||
if (idx) (*idx)++;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void delbypos(int pos)
|
|
||||||
{
|
|
||||||
char *s=(char*)gr.get();
|
|
||||||
int len=strlen(s+pos)+1;
|
|
||||||
if (pos+len < gr.getlen()) memcpy(s+pos,s+pos+len,gr.getlen()-(pos+len));
|
|
||||||
gr.resize(gr.getlen()-len);
|
|
||||||
}
|
|
||||||
|
|
||||||
int idx2pos(int idx)
|
|
||||||
{
|
|
||||||
char *s=(char*)gr.get();
|
|
||||||
int offs=0;
|
|
||||||
int cnt=0;
|
|
||||||
if (idx>=0) while (offs < gr.getlen())
|
|
||||||
{
|
|
||||||
if (cnt++ == idx) return offs;
|
|
||||||
offs+=strlen(s+offs)+1;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int getnum() {
|
|
||||||
char *s=(char*)gr.get();
|
|
||||||
int ml=gr.getlen();
|
|
||||||
int offs=0;
|
|
||||||
int idx=0;
|
|
||||||
while (offs < ml)
|
|
||||||
{
|
|
||||||
offs+=strlen(s+offs)+1;
|
|
||||||
idx++;
|
|
||||||
}
|
|
||||||
return idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *get() { return (char*)gr.get(); }
|
|
||||||
int getlen() const { return gr.getlen(); }
|
|
||||||
private:
|
private:
|
||||||
GrowBuf gr;
|
GrowBuf gr;
|
||||||
};
|
};
|
||||||
|
@ -200,8 +32,7 @@ template <class T>
|
||||||
class SortedStringList
|
class SortedStringList
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SortedStringList() { }
|
virtual ~SortedStringList()
|
||||||
~SortedStringList()
|
|
||||||
{
|
{
|
||||||
T *s=(T*)gr.get();
|
T *s=(T*)gr.get();
|
||||||
int num=gr.getlen()/sizeof(T);
|
int num=gr.getlen()/sizeof(T);
|
||||||
|
@ -296,7 +127,7 @@ class SortedStringListND // no delete - can be placed in GrowBuf
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
SortedStringListND() { }
|
SortedStringListND() { }
|
||||||
~SortedStringListND() { }
|
virtual ~SortedStringListND() { }
|
||||||
|
|
||||||
// returns -1 when name already exists and pos if added
|
// returns -1 when name already exists and pos if added
|
||||||
int add(const char *name, int case_sensitive=0, int alwaysreturnpos=0)
|
int add(const char *name, int case_sensitive=0, int alwaysreturnpos=0)
|
||||||
|
@ -371,85 +202,22 @@ struct define {
|
||||||
|
|
||||||
class DefineList : public SortedStringList<struct define>
|
class DefineList : public SortedStringList<struct define>
|
||||||
{
|
{
|
||||||
|
private: // don't copy instances
|
||||||
|
DefineList(const DefineList&);
|
||||||
|
void operator=(const DefineList&);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DefineList() { }
|
DefineList() {} // VC6 complains otherwise
|
||||||
~DefineList()
|
virtual ~DefineList();
|
||||||
{
|
|
||||||
struct define *s=(struct define*)gr.get();
|
|
||||||
int num=gr.getlen()/sizeof(struct define);
|
|
||||||
|
|
||||||
for (int i=0; i<num; i++) {
|
int add(const char *name, const char *value="");
|
||||||
free(s[i].value);
|
char *find(const char *name);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int add(const char *name, const char *value="")
|
|
||||||
{
|
|
||||||
int pos=SortedStringList<struct define>::add(name);
|
|
||||||
if (pos == -1)
|
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
char **newvalue=&(((struct define*)gr.get())[pos].value);
|
|
||||||
*newvalue=(char*)malloc(strlen(value)+1);
|
|
||||||
if (!(*newvalue))
|
|
||||||
{
|
|
||||||
extern FILE *g_output;
|
|
||||||
extern int g_display_errors;
|
|
||||||
extern void quit();
|
|
||||||
if (g_display_errors)
|
|
||||||
{
|
|
||||||
fprintf(g_output,"\nInternal compiler error #12345: GrowBuf realloc/malloc(%d) failed.\n",strlen(value)+1);
|
|
||||||
fflush(g_output);
|
|
||||||
}
|
|
||||||
quit();
|
|
||||||
}
|
|
||||||
strcpy(*newvalue,value);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *find(const char *name)
|
|
||||||
{
|
|
||||||
int v=SortedStringList<struct define>::find(name);
|
|
||||||
if (v==-1)
|
|
||||||
{
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return ((struct define*)gr.get())[v].value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// returns 0 on success, 1 otherwise
|
// returns 0 on success, 1 otherwise
|
||||||
int del(const char *str)
|
int del(const char *str);
|
||||||
{
|
int getnum();
|
||||||
int pos=SortedStringList<struct define>::find(str);
|
char *getname(int num);
|
||||||
if (pos==-1) return 1;
|
char *getvalue(int num);
|
||||||
|
|
||||||
struct define *db=(struct define *)gr.get();
|
|
||||||
free(db[pos].value);
|
|
||||||
delbypos(pos);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int getnum()
|
|
||||||
{
|
|
||||||
return gr.getlen()/sizeof(define);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *getname(int num)
|
|
||||||
{
|
|
||||||
if ((unsigned int)getnum() <= (unsigned int)num)
|
|
||||||
return 0;
|
|
||||||
return ((struct define*)gr.get())[num].name;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *getvalue(int num)
|
|
||||||
{
|
|
||||||
if ((unsigned int)getnum() <= (unsigned int)num)
|
|
||||||
return 0;
|
|
||||||
return ((struct define*)gr.get())[num].value;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct string_t {
|
struct string_t {
|
||||||
|
@ -458,537 +226,18 @@ struct string_t {
|
||||||
|
|
||||||
class FastStringList : public SortedStringListND<struct string_t>
|
class FastStringList : public SortedStringListND<struct string_t>
|
||||||
{
|
{
|
||||||
|
private: // don't copy instances
|
||||||
|
FastStringList(const FastStringList&);
|
||||||
|
void operator=(const FastStringList&);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FastStringList() { }
|
FastStringList() {} // VC6 complains otherwise
|
||||||
~FastStringList() { }
|
virtual ~FastStringList() {}
|
||||||
|
|
||||||
int add(const char *name, int case_sensitive=0)
|
int add(const char *name, int case_sensitive=0);
|
||||||
{
|
char *get() const;
|
||||||
int pos = SortedStringListND<struct string_t>::add(name, case_sensitive);
|
int getlen() const;
|
||||||
if (pos == -1) return -1;
|
int getnum() const;
|
||||||
return ((struct string_t*)gr.get())[pos].name;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *get() const
|
|
||||||
{
|
|
||||||
return (char*)strings.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
int getlen() const
|
|
||||||
{
|
|
||||||
return strings.getlen();
|
|
||||||
}
|
|
||||||
|
|
||||||
int getnum() const
|
|
||||||
{
|
|
||||||
return gr.getlen()/sizeof(struct string_t);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class MMapFile : public IMMap
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MMapFile()
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
m_hFile = INVALID_HANDLE_VALUE;
|
|
||||||
m_hFileMap = NULL;
|
|
||||||
#else
|
|
||||||
m_hFile = NULL;
|
|
||||||
m_hFileDesc = -1;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
m_pView = NULL;
|
|
||||||
m_iSize = 0;
|
|
||||||
m_bReadOnly = FALSE;
|
|
||||||
m_bTempHandle = FALSE;
|
|
||||||
|
|
||||||
if (!m_iAllocationGranularity)
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
SYSTEM_INFO si;
|
|
||||||
GetSystemInfo(&si);
|
|
||||||
m_iAllocationGranularity = (int) si.dwAllocationGranularity;
|
|
||||||
#else
|
|
||||||
m_iAllocationGranularity = getpagesize();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~MMapFile()
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear()
|
|
||||||
{
|
|
||||||
release();
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
if (m_hFileMap)
|
|
||||||
CloseHandle(m_hFileMap);
|
|
||||||
if (m_bTempHandle && m_hFile != INVALID_HANDLE_VALUE)
|
|
||||||
CloseHandle(m_hFile);
|
|
||||||
|
|
||||||
m_hFile = INVALID_HANDLE_VALUE;
|
|
||||||
m_hFileMap = 0;
|
|
||||||
#else
|
|
||||||
if (m_bTempHandle && m_hFile)
|
|
||||||
fclose(m_hFile);
|
|
||||||
|
|
||||||
m_hFile = NULL;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void setro(BOOL bRO)
|
|
||||||
{
|
|
||||||
m_bReadOnly = bRO;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
int setfile(HANDLE hFile, DWORD dwSize)
|
|
||||||
#else
|
|
||||||
int setfile(int hFile, DWORD dwSize)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
clear();
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
m_hFile = hFile;
|
|
||||||
#else
|
|
||||||
m_hFileDesc = hFile;
|
|
||||||
#endif
|
|
||||||
m_bTempHandle = FALSE;
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
if (m_hFile == INVALID_HANDLE_VALUE)
|
|
||||||
#else
|
|
||||||
if (m_hFileDesc == -1)
|
|
||||||
#endif
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
m_iSize = (int) dwSize;
|
|
||||||
|
|
||||||
if (m_iSize <= 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
m_hFileMap = CreateFileMapping(m_hFile, NULL, PAGE_READONLY, 0, m_iSize, NULL);
|
|
||||||
|
|
||||||
if (!m_hFileMap)
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
m_bReadOnly = TRUE;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void resize(int newsize)
|
|
||||||
{
|
|
||||||
release();
|
|
||||||
|
|
||||||
if (newsize > m_iSize)
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
if (m_hFileMap)
|
|
||||||
CloseHandle(m_hFileMap);
|
|
||||||
|
|
||||||
m_hFileMap = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
m_iSize = newsize;
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
if (m_hFile == INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
char buf[MAX_PATH], buf2[MAX_PATH];
|
|
||||||
|
|
||||||
GetTempPath(MAX_PATH, buf);
|
|
||||||
GetTempFileName(buf, "nsd", 0, buf2);
|
|
||||||
|
|
||||||
m_hFile = CreateFile(
|
|
||||||
buf2,
|
|
||||||
GENERIC_READ | GENERIC_WRITE,
|
|
||||||
0,
|
|
||||||
NULL,
|
|
||||||
CREATE_ALWAYS,
|
|
||||||
FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE | FILE_FLAG_SEQUENTIAL_SCAN,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
m_bTempHandle = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_hFile != INVALID_HANDLE_VALUE)
|
|
||||||
{
|
|
||||||
m_hFileMap = CreateFileMapping(
|
|
||||||
m_hFile,
|
|
||||||
NULL,
|
|
||||||
m_bReadOnly ? PAGE_READONLY : PAGE_READWRITE,
|
|
||||||
0,
|
|
||||||
m_iSize,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
if (m_hFile == NULL)
|
|
||||||
{
|
|
||||||
m_hFile = tmpfile();
|
|
||||||
if (m_hFile != NULL)
|
|
||||||
{
|
|
||||||
m_hFileDesc = fileno(m_hFile);
|
|
||||||
m_bTempHandle = TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// resize
|
|
||||||
if (m_hFileDesc != -1)
|
|
||||||
{
|
|
||||||
unsigned char c = 0;
|
|
||||||
|
|
||||||
if (lseek(m_hFileDesc, m_iSize, SEEK_SET) != (off_t)-1)
|
|
||||||
{
|
|
||||||
if (read(m_hFileDesc, &c, 1) != -1)
|
|
||||||
{
|
|
||||||
if (lseek(m_hFileDesc, m_iSize, SEEK_SET) != (off_t)-1)
|
|
||||||
{
|
|
||||||
if (write(m_hFileDesc, &c, 1) != -1)
|
|
||||||
{
|
|
||||||
return; // no errors
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_hFileDesc = -1; // some error occured, bail
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
if (!m_hFileMap)
|
|
||||||
#else
|
|
||||||
if (m_hFileDesc == -1)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
extern FILE *g_output;
|
|
||||||
extern void quit(); extern int g_display_errors;
|
|
||||||
if (g_display_errors)
|
|
||||||
{
|
|
||||||
fprintf(g_output,"\nInternal compiler error #12345: error creating mmap the size of %d.\n", m_iSize);
|
|
||||||
fflush(g_output);
|
|
||||||
}
|
|
||||||
quit();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int getsize() const
|
|
||||||
{
|
|
||||||
return m_iSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *get(int offset, int size) const
|
|
||||||
{
|
|
||||||
return get(offset, &size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *get(int offset, int *sizep) const
|
|
||||||
{
|
|
||||||
if (!sizep)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
assert(!m_pView);
|
|
||||||
|
|
||||||
int size = *sizep;
|
|
||||||
|
|
||||||
if (!m_iSize || offset + size > m_iSize)
|
|
||||||
{
|
|
||||||
extern FILE *g_output;
|
|
||||||
extern void quit(); extern int g_display_errors;
|
|
||||||
if (g_display_errors)
|
|
||||||
{
|
|
||||||
fprintf(g_output,"\nInternal compiler error #12345: error mmapping file (%d, %d) is out of range.\n", offset, size);
|
|
||||||
fflush(g_output);
|
|
||||||
}
|
|
||||||
quit();
|
|
||||||
}
|
|
||||||
|
|
||||||
// fix offset
|
|
||||||
int alignedoffset = offset - (offset % m_iAllocationGranularity);
|
|
||||||
size += offset - alignedoffset;
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
const_cast<MMapFile*>(this)->m_pView =
|
|
||||||
MapViewOfFile(m_hFileMap, m_bReadOnly ? FILE_MAP_READ : FILE_MAP_WRITE, 0, alignedoffset, size);
|
|
||||||
#else
|
|
||||||
const_cast<MMapFile*>(this)->m_pView =
|
|
||||||
mmap(0, size, m_bReadOnly ? PROT_READ : PROT_READ | PROT_WRITE, MAP_SHARED, m_hFileDesc, alignedoffset);
|
|
||||||
const_cast<MMapFile*>(this)->m_iMappedSize = *sizep = size;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
if (!m_pView)
|
|
||||||
#else
|
|
||||||
if (m_pView == MAP_FAILED)
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
extern FILE *g_output;
|
|
||||||
extern void quit(); extern int g_display_errors;
|
|
||||||
if (g_display_errors)
|
|
||||||
{
|
|
||||||
fprintf(g_output,"\nInternal compiler error #12345: error mmapping datablock to %d.\n", size);
|
|
||||||
fflush(g_output);
|
|
||||||
}
|
|
||||||
quit();
|
|
||||||
}
|
|
||||||
|
|
||||||
return (void *)((char *)m_pView + offset - alignedoffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *getmore(int offset, int *size) const
|
|
||||||
{
|
|
||||||
void *pView;
|
|
||||||
void *pViewBackup = m_pView;
|
|
||||||
#ifndef _WIN32
|
|
||||||
int iMappedSizeBackup = m_iMappedSize;
|
|
||||||
#endif
|
|
||||||
const_cast<MMapFile*>(this)->m_pView = 0;
|
|
||||||
pView = get(offset, size);
|
|
||||||
const_cast<MMapFile*>(this)->m_pView = pViewBackup;
|
|
||||||
#ifndef _WIN32
|
|
||||||
const_cast<MMapFile*>(this)->m_iMappedSize = iMappedSizeBackup;
|
|
||||||
#endif
|
|
||||||
return pView;
|
|
||||||
}
|
|
||||||
|
|
||||||
void release()
|
|
||||||
{
|
|
||||||
if (!m_pView)
|
|
||||||
return;
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
UnmapViewOfFile(m_pView);
|
|
||||||
#else
|
|
||||||
munmap(m_pView, m_iMappedSize);
|
|
||||||
#endif
|
|
||||||
m_pView = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void release(void *pView, int size)
|
|
||||||
{
|
|
||||||
if (!pView)
|
|
||||||
return;
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
UnmapViewOfFile(pView);
|
|
||||||
#else
|
|
||||||
munmap(pView, size);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void flush(int num)
|
|
||||||
{
|
|
||||||
if (m_pView)
|
|
||||||
#ifdef _WIN32
|
|
||||||
FlushViewOfFile(m_pView, num);
|
|
||||||
#else
|
|
||||||
msync(m_pView, num, MS_SYNC);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
#ifdef _WIN32
|
|
||||||
HANDLE m_hFile, m_hFileMap;
|
|
||||||
#else
|
|
||||||
FILE *m_hFile;
|
|
||||||
int m_hFileDesc;
|
|
||||||
int m_iMappedSize;
|
|
||||||
#endif
|
|
||||||
void *m_pView;
|
|
||||||
int m_iSize;
|
|
||||||
BOOL m_bReadOnly;
|
|
||||||
BOOL m_bTempHandle;
|
|
||||||
|
|
||||||
static int m_iAllocationGranularity;
|
|
||||||
};
|
|
||||||
|
|
||||||
class MMapFake : public IMMap
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MMapFake()
|
|
||||||
{
|
|
||||||
m_pMem = NULL;
|
|
||||||
m_iSize = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set(const char *pMem, int iSize)
|
|
||||||
{
|
|
||||||
m_pMem = pMem;
|
|
||||||
m_iSize = iSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
int getsize() const
|
|
||||||
{
|
|
||||||
return m_iSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
void *get(int offset, int size) const
|
|
||||||
{
|
|
||||||
return get(offset, &size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *get(int offset, int *size) const
|
|
||||||
{
|
|
||||||
if (!size || (offset + *size > m_iSize))
|
|
||||||
return NULL;
|
|
||||||
return (void *)(m_pMem + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *getmore(int offset, int *size) const
|
|
||||||
{
|
|
||||||
return get(offset, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void resize(int n) {}
|
|
||||||
void release() {}
|
|
||||||
void release(void *p, int size) {}
|
|
||||||
void clear() {}
|
|
||||||
void setro(BOOL b) {}
|
|
||||||
void flush(BOOL b) {}
|
|
||||||
|
|
||||||
private:
|
|
||||||
const char *m_pMem;
|
|
||||||
int m_iSize;
|
|
||||||
};
|
|
||||||
|
|
||||||
class MMapBuf : public IGrowBuf, public IMMap
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MMapBuf()
|
|
||||||
{
|
|
||||||
m_gb_u=0;
|
|
||||||
m_alloc=m_used=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~MMapBuf()
|
|
||||||
{
|
|
||||||
m_fm.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
int add(const void *data, int len)
|
|
||||||
{
|
|
||||||
if (len <= 0) return 0;
|
|
||||||
resize(getlen() + len);
|
|
||||||
memcpy((char*)get(getlen() - len, len), data, len);
|
|
||||||
return getlen() - len;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setro(BOOL bRO)
|
|
||||||
{
|
|
||||||
m_fm.setro(bRO);
|
|
||||||
}
|
|
||||||
|
|
||||||
void resize(int newlen)
|
|
||||||
{
|
|
||||||
if (!m_gb_u && newlen < (16 << 20)) // still in db mode
|
|
||||||
{
|
|
||||||
m_gb.resize(newlen);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// not in db mode
|
|
||||||
m_gb_u = 1;
|
|
||||||
m_used = newlen;
|
|
||||||
|
|
||||||
if (newlen > m_alloc)
|
|
||||||
{
|
|
||||||
m_alloc = newlen + (16 << 20); // add 16mb to top of mapping
|
|
||||||
|
|
||||||
m_fm.resize(m_alloc);
|
|
||||||
|
|
||||||
if (m_gb.getlen())
|
|
||||||
{
|
|
||||||
memcpy(m_fm.get(0, m_gb.getlen()), m_gb.get(), m_gb.getlen());
|
|
||||||
m_fm.flush(m_gb.getlen());
|
|
||||||
m_fm.release();
|
|
||||||
m_gb.resize(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int getsize() const
|
|
||||||
{
|
|
||||||
if (m_gb_u)
|
|
||||||
return m_fm.getsize();
|
|
||||||
return m_gb.getlen();
|
|
||||||
}
|
|
||||||
|
|
||||||
int getlen() const
|
|
||||||
{
|
|
||||||
if (m_gb_u)
|
|
||||||
return m_used;
|
|
||||||
return m_gb.getlen();
|
|
||||||
}
|
|
||||||
|
|
||||||
void *get() const
|
|
||||||
{
|
|
||||||
return get(0, m_alloc);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *get(int offset, int *sizep) const
|
|
||||||
{
|
|
||||||
if (!sizep)
|
|
||||||
return NULL;
|
|
||||||
int size = *sizep;
|
|
||||||
return get(offset, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *get(int offset, int size) const
|
|
||||||
{
|
|
||||||
if (m_gb_u)
|
|
||||||
return m_fm.get(offset, size);
|
|
||||||
return (void *) ((char *) m_gb.get() + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *getmore(int offset, int *size) const
|
|
||||||
{
|
|
||||||
if (m_gb_u)
|
|
||||||
return m_fm.getmore(offset, size);
|
|
||||||
return (void *) ((char *) m_gb.get() + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
void release()
|
|
||||||
{
|
|
||||||
if (m_gb_u)
|
|
||||||
m_fm.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
void release(void *pView, int size)
|
|
||||||
{
|
|
||||||
if (m_gb_u)
|
|
||||||
m_fm.release(pView, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear()
|
|
||||||
{
|
|
||||||
if (m_gb_u)
|
|
||||||
m_fm.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void flush(int num)
|
|
||||||
{
|
|
||||||
if (m_gb_u)
|
|
||||||
m_fm.flush(num);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
GrowBuf m_gb;
|
|
||||||
MMapFile m_fm;
|
|
||||||
|
|
||||||
int m_gb_u;
|
|
||||||
int m_alloc, m_used;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif//_STRLIST_H_
|
#endif//_STRLIST_H_
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
# include <ctype.h>
|
# include <ctype.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <cassert> // for assert
|
||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
|
|
||||||
int g_dopause=0;
|
int g_dopause=0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue