📄 xml.cpp
字号:
//-< XML.CPP >-------------------------------------------------------*--------*
// FastDB Version 1.0 (c) 1999 GARRET * ? *
// (Main Memory Database Management System) * /\| *
// * / \ *
// Created: 14-Feb-2008 K.A. Knizhnik * / [] \ *
// Last update: 14-Feb-2008 K.A. Knizhnik * GARRET *
//-------------------------------------------------------------------*--------*
// XML export/import and related stuff
//-------------------------------------------------------------------*--------*
#define INSIDE_FASTDB
#include "fastdb.h"
#include "compiler.h"
#include "symtab.h"
#include "hashtab.h"
#include "ttree.h"
#include "rtree.h"
class dbTmpAllocator {
enum {
CHUNK_SIZE = 4096
};
struct Chunk {
Chunk* next;
Chunk* prev; // is not used, added for alignment
};
Chunk* curr;
size_t used;
public:
dbTmpAllocator() {
curr = NULL;
used = CHUNK_SIZE;
}
~dbTmpAllocator() {
reset();
}
void reset() {
Chunk *c, *next;
for (c = curr; c != NULL; c = next) {
next = c->next;
dbFree(c);
}
curr = NULL;
used = CHUNK_SIZE;
}
void* alloc(size_t size) {
size = DOALIGN(size, 8);
if (size > CHUNK_SIZE/2) {
Chunk* newChunk = (Chunk*)dbMalloc(size + sizeof(Chunk));
if (curr != NULL) {
newChunk->next = curr->next;
curr->next = newChunk;
} else {
curr = newChunk;
newChunk->next = NULL;
used = CHUNK_SIZE;
}
return newChunk+1;
} else if (size <= CHUNK_SIZE - used) {
used += size;
return (char*)curr + used - size;
} else {
Chunk* newChunk = (Chunk*)dbMalloc(CHUNK_SIZE);
used = sizeof(Chunk) + size;
newChunk->next = curr;
curr = newChunk;
return newChunk+1;
}
}
};
#ifdef USE_STD_STRING
template <class T>
class std_tmp_allocator {
dbTmpAllocator& allocator;
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T *pointer;
typedef const T *const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T value_type;
std_tmp_allocator(dbTmpAllocator& al) : allocator(al) {}
template<class _Other>
struct rebind { // convert an std_tmp_allocator<T> to an std_tmp_allocator<_Other>
typedef std_tmp_allocator<_Other> other;
};
pointer allocate(size_type _Count)
{ // allocate array of _Count elements
return (allocate(_Count, (pointer)0));
}
pointer allocate(size_type _Count, const void*)
{
return (pointer)allocator.alloc(_Count*sizeof(T));
}
void deallocate(pointer, size_t) {
}
size_t max_size() const {
size_t _N = (size_t)(-1) / sizeof(T);
return (0 < _N ? _N : 1);
}
};
typedef std::basic_string<char,std::char_traits<char>,std_tmp_allocator<char> > tmp_basic_string;
#endif
class dbXmlContext {
public:
oid_t* oidMap;
oid_t oidMapSize;
dbTmpAllocator tmpAlloc;
#ifdef USE_STD_STRING
std_tmp_allocator<char> stdAlloc;
dbXmlContext() : stdAlloc(tmpAlloc) {}
#endif
~dbXmlContext() {
delete[] oidMap;
}
};
class dbXmlScanner {
public:
enum {
MaxIdentSize = 256
};
enum token {
xml_ident,
xml_sconst,
xml_iconst,
xml_fconst,
xml_lt,
xml_gt,
xml_lts,
xml_gts,
xml_eq,
xml_eof,
xml_error
};
dbXmlScanner(FILE* f) {
in = f;
sconst = new char[size = 1024];
line = 1;
pos = 0;
}
token scan();
void warning(char const* msg)
{
fprintf(stderr, "%s at line %d position %d\n", msg, line, pos > 0 ? pos - 1 : 0);
}
char* getString() {
return sconst;
}
char* getIdentifier() {
return ident;
}
size_t getStringLength() {
return slen;
}
db_int8 getInt() {
return iconst;
}
double getReal() {
return fconst;
}
bool expect(int sourcePos, token expected) {
token tkn = scan();
if (tkn != expected) {
fprintf(stderr, "subsql.cpp:%d: line %d, column %d: Get token %d instead of expected token %d\n",
sourcePos, line, pos, tkn, expected);
return false;
}
return true;
}
bool expect(int sourcePos, char* expected) {
token tkn = scan();
if (tkn != xml_ident) {
fprintf(stderr, "subsql.cpp:%d: line %d, column %d: Get token %d instead of expected identifier\n",
sourcePos, line, pos, tkn);
return false;
}
if (strcmp(ident, expected) != 0) {
fprintf(stderr, "subsql.cpp:%d: line %d, column %d: Get tag '%s' instead of expected '%s'\n",
sourcePos, line, pos, ident, expected);
return false;
}
return true;
}
private:
int get();
void unget(int ch);
int line;
int pos;
FILE* in;
char* sconst;
size_t size;
size_t slen;
db_int8 iconst;
double fconst;
char ident[MaxIdentSize];
};
static void exportString(FILE* out, char* src, int len)
{
fprintf(out, "\"");
while (--len > 0) {
byte b = (byte)*src++;
switch (b) {
case '&':
fprintf(out, "&");
break;
case '<':
fprintf(out, "<");
break;
case '>':
fprintf(out, ">");
break;
case '"':
fprintf(out, """);
break;
case '\'':
fprintf(out, "'");
break;
default:
fprintf(out, "%c", b);
}
}
fprintf(out, "\"");
}
static void exportBinary(FILE* out, byte* src, int len)
{
fprintf(out, "\"");
while (--len >= 0) {
fprintf(out, "%02X", *src++);
}
fprintf(out, "\"");
}
static void exportRecord(dbFieldDescriptor* fieldList, FILE* out, byte* src, int indent)
{
int i;
dbFieldDescriptor* fd = fieldList;
do {
byte* ptr = src + fd->dbsOffs;
for (i = indent; --i >= 0;) {
fprintf(out, " ");
}
char* fieldName = fd->name;
if (strcmp(fieldName, "[]") == 0) {
fieldName = "array-element";
}
fprintf(out, "<%s>", fieldName);
switch (fd->type) {
case dbField::tpBool:
fprintf(out, "%d", *(bool*)ptr);
break;
case dbField::tpInt1:
fprintf(out, "%d", *(int1*)ptr);
break;
case dbField::tpInt2:
fprintf(out, "%d", *(int2*)ptr);
break;
case dbField::tpInt4:
fprintf(out, "%d", *(int4*)ptr);
break;
case dbField::tpInt8:
fprintf(out, INT8_FORMAT, *(db_int8*)ptr);
break;
case dbField::tpReal4:
fprintf(out, "%.8G", *(real4*)ptr);
break;
case dbField::tpReal8:
fprintf(out, "%.16G", *(real8*)ptr);
break;
case dbField::tpRawBinary:
exportBinary(out, src+fd->dbsOffs, fd->dbsSize);
break;
case dbField::tpString:
exportString(out, (char*)(src + ((dbVarying*)ptr)->offs), ((dbVarying*)ptr)->size);
break;
case dbField::tpArray:
{
int nElems = ((dbVarying*)ptr)->size;
byte* srcElem = src + ((dbVarying*)ptr)->offs;
dbFieldDescriptor* element = fd->components;
fprintf(out, "\n");
while (--nElems >= 0) {
exportRecord(element, out, srcElem, indent+1);
srcElem += element->dbsSize;
}
for (i = indent; --i >= 0;) {
fprintf(out, " ");
}
break;
}
case dbField::tpReference:
fprintf(out, "<ref id=\"%ld\"/>", (long)*(oid_t*)ptr);
break;
case dbField::tpRectangle:
{
rectangle& r = *(rectangle*)ptr;
fprintf(out, "<rectangle><vertex");
for (i = 0; i < rectangle::dim; i++) {
fprintf(out, " c%d=\"%d\"", i, r.boundary[i]);
}
fprintf(out, "/><vertex");
for (i = 0; i < rectangle::dim; i++) {
fprintf(out, " c%d=\"%d\")", i, r.boundary[rectangle::dim+i]);
}
fprintf(out, "/></rectangle>");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -