⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xml.cpp

📁 最新版本!fastdb是高效的内存数据库系统
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//-< 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, "&amp;");
            break;
          case '<':
            fprintf(out, "&lt;");
            break;
          case '>':
            fprintf(out, "&gt;");
            break;
          case '"':
            fprintf(out, "&quot;");
            break;
          case '\'':
            fprintf(out, "&apos;");
            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 + -