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

📄 xml.cpp

📁 最新版本!fastdb是高效的内存数据库系统
💻 CPP
📖 第 1 页 / 共 3 页
字号:
            break;
          case dbField::tpStructure:
            fprintf(out, "\n");
            exportRecord(fd->components, out, src, indent+1);
            for (i = indent; --i >= 0;) { 
                fprintf(out, " ");
            }
            break;
        }
        fprintf(out, "</%s>\n", fieldName);
    } while ((fd = fd->next) != fieldList);
}

void dbDatabase::exportScheme(FILE* out) 
{
    fprintf(out, "<!DOCTYPE database [\n");
    if (tables == NULL) { 
        fprintf(out, "<!ELEMENT database EMPTY>\n");
    } else { 
        fprintf(out, "<!ELEMENT database (%s*", tables->name);
        dbTableDescriptor* desc = tables; 
        while ((desc = desc->nextDbTable) != NULL) { 
            if (desc->tableId != dbMetaTableId) {
                fprintf(out, ", %s*", desc->name);
            }
        }
        fprintf(out, ")>\n");
    }
    for (dbTableDescriptor* desc = tables; desc != NULL; desc = desc->nextDbTable) { 
        if (desc->tableId != dbMetaTableId) {
            exportClass(out, desc->name, desc->columns);
            fprintf(out, "<!ATTLIST %s id CDATA #REQUIRED>\n", desc->name);
        }
    }
    fprintf(out, "<!ELEMENT array-element ANY>\n<!ELEMENT ref EMPTY>\n<!ATTLIST ref id CDATA #REQUIRED>\n]>\n");
}

void dbDatabase::exportClass(FILE* out, char* name, dbFieldDescriptor* fieldList) 
{
    fprintf(out, "<!ELEMENT %s (%s", name, fieldList->name);
    dbFieldDescriptor* fd = fieldList;
    while ((fd = fd->next) != fieldList) {
        fprintf(out, ", %s", fd->name);
    }
    fprintf(out, ")>\n");
    fd = fieldList;
    do { 
        switch (fd->type) {
          case dbField::tpStructure:
            exportClass(out, fd->name, fd->components);
            break;
          case dbField::tpArray:
            fprintf(out, "<!ELEMENT %s (array-element*)>\n", fd->name);
            if (fd->components->type == dbField::tpStructure) { 
                exportClass(out, fd->name, fd->components->components);
            }
            break;
          default:
            fprintf(out, "<!ELEMENT %s (#PCDATA)>\n", fd->name);
            
        } 
    } while ((fd = fd->next) != fieldList);
}


void dbDatabase::exportDatabaseToXml(FILE* out) 
{
    fprintf(out, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
    beginTransaction(dbSharedLock);
    exportScheme(out);
    fprintf(out, "<database>\n");
    for (dbTableDescriptor* desc=tables; desc != NULL; desc=desc->nextDbTable) { 
        if (desc->tableId != dbMetaTableId) {
            dbTable* table = (dbTable*)getRow(desc->tableId);    
            oid_t oid = table->firstRow; 
            int n = table->nRows;
            int percent = 0;
            for (int i = 0; oid != 0; i++) { 
                dbRecord* rec = getRow(oid);
                fprintf(out, " <%s id=\"%lu\">\n", desc->name, (unsigned long)oid); 
                exportRecord(desc->columns, out, (byte*)rec, 2);
                fprintf(out, " </%s>\n", desc->name); 
                oid = rec->next;
                int p = (i+1)*100/n;
                if (p != percent) { 
                    fprintf(stderr, "Exporting table %s: %d%%\r", desc->name, p);
                    fflush(stderr);
                    percent = p;
                }
            }
            fprintf(stderr, "Exporting table %s: 100%%   \n", desc->name);
        }
    }
    fprintf(out, "</database>\n");
}


inline int dbXmlScanner::get()
{
    int ch = getc(in);
    if (ch == '\n') {
        pos = 0;
        line += 1;
    } else if (ch == '\t') {
        pos = DOALIGN(pos + 1, 8);
    } else {
        pos += 1;
    }
    return ch;
}

inline void dbXmlScanner::unget(int ch) {
    if (ch != EOF) {
        if (ch != '\n') {
            pos -= 1;
        } else {
            line -= 1;
        }
        ungetc(ch, in);
    }
}


dbXmlScanner::token dbXmlScanner::scan()
{
    int ch, i, pos;
    bool floatingPoint;

  retry:
    do {
        if ((ch = get()) == EOF) {
            return xml_eof;
        }
    } while (ch <= ' ');
    
    switch (ch) { 
      case '<':
        ch = get();
        if (ch == '?') { 
            while ((ch = get()) != '?') { 
                if (ch == EOF) { 
                    return xml_error;
                }
            }
            if ((ch = get()) != '>') { 
                return xml_error;
            }
            goto retry;
        } else if (ch == '!') {
            int nParen = 1;
            do { 
                switch (get()) {
                  case '<':
                    nParen += 1;
                    break;
                  case '>':
                    nParen -= 1;
                    break;
                  case EOF:
                    return xml_error;
                }
            } while (nParen != 0);
            goto retry;
        } 
        if (ch != '/') { 
            unget(ch);
            return xml_lt;
        }
        return xml_lts;
      case '>':
        return xml_gt;
      case '/':
        ch = get();
        if (ch != '>') { 
            unget(ch);
            return xml_error;
        }
        return xml_gts;
      case '=':
        return xml_eq;
      case '"':
        i = 0;
        while (true) { 
            ch = get();
            switch (ch) { 
              case EOF:
                return xml_error;
              case '&':
                switch (get()) { 
                  case 'a':
                    ch = get();
                    if (ch == 'm' && get() == 'p' && get() == ';') { 
                        ch = '&';
                    } else if (ch == 'p' && get() == 'o' && get() == 's' && get() == ';') { 
                        ch = '\'';
                    } else { 
                        return xml_error;
                    }
                    break;
                  case 'l':
                    if (get() != 't' || get() != ';') { 
                        return xml_error;
                    }
                    ch = '<';
                    break;
                  case 'g':
                    if (get() != 't' || get() != ';') { 
                        return xml_error;
                    }
                    ch = '>';
                    break;
                  case 'q':
                    if (get() != 'u' || get() != 'o' || get() != 't' || get() != ';') { 
                        return xml_error;
                    }
                    ch = '"';
                    break;
                  default:
                    return xml_error;
                }
                break;
              case '"':
                slen = i;
                sconst[i] = 0;
                return xml_sconst;
            }
            if ((size_t)i+1 >= size) { 
                char* newBuf = new char[size *= 2];
                memcpy(newBuf, sconst, i);
                delete[] sconst;
                sconst = newBuf;
            }
            sconst[i++] = (char)ch;
        } 
      case '-': case '+':
      case '0': case '1': case '2': case '3': case '4':
      case '5': case '6': case '7': case '8': case '9':
        i = 0;
        floatingPoint = false;
        while (true) { 
            if ((size_t)i == size) { 
                return xml_error;
            }
            if (!isdigit(ch) && ch != '-' && ch != '+' && ch != '.' && ch != 'E') { 
                unget(ch);
                sconst[i] = '\0';
                if (floatingPoint) { 
                   return sscanf(sconst, "%lf%n", &fconst, &pos) == 1 && pos == i
                       ? xml_fconst : xml_error;
                } else { 
                    return sscanf(sconst, INT8_FORMAT "%n", &iconst, &pos) == 1 && pos == i
                       ? xml_iconst : xml_error;
                }
            }
            sconst[i++] = (char)ch;
            if (ch == '.' || ch == 'E') { 
                floatingPoint = true;
            }
            ch = get();
        }
      default:
        i = 0;
        while (isalnum(ch) || ch == '-' || ch == ':' || ch == '_') { 
            if (i == MaxIdentSize) { 
                return xml_error;
            }
            ident[i++] = (char)ch;
            ch = get();
        }
        unget(ch);
        if (i == MaxIdentSize || i == 0) { 
            return xml_error;            
        }
        ident[i] = '\0';
        return xml_ident;
    }
}

#define EXPECT(x) scanner.expect(__LINE__, x)

static bool skipElement(dbXmlScanner& scanner) 
{
    int depth = 1;
    do {  
        switch (scanner.scan()) { 
          case dbXmlScanner::xml_lt:
            depth += 1;
            continue;
          case dbXmlScanner::xml_lts:
            depth -= 1;
            if (depth < 0 || !EXPECT(dbXmlScanner::xml_ident) || !EXPECT(dbXmlScanner::xml_gt))
            { 
                return false;
            }
            break;
          case dbXmlScanner::xml_gts:
            depth -= 1;
            break;
          default:
            continue;            
        }
    } while (depth != 0);

    return true;
}

bool dbDatabase::importRecord(char* terminator, dbFieldDescriptor* fieldList, byte* rec, dbXmlScanner& scanner) 
{
    dbXmlScanner::token tkn;

    while ((tkn = scanner.scan()) != dbXmlScanner::xml_lts) { 
        if (tkn != dbXmlScanner::xml_lt || !EXPECT(dbXmlScanner::xml_ident)
            || !EXPECT(dbXmlScanner::xml_gt)) 
        { 
            return false;
        }
        char* fieldName = scanner.getIdentifier();
        dbSymbolTable::add(fieldName, tkn_ident, FASTDB_CLONE_ANY_IDENTIFIER);
        dbFieldDescriptor* fd = fieldList;
        while (true) {
            if (fd->name == fieldName) {
                if (!importField(fd->name, fd, rec, scanner)) { 
                    return false;
                }
                break;
            }
            if ((fd = fd->next) == fieldList) { 
                if (!skipElement(scanner)) { 
                    return false;
                }   
                break;
            }
        } 
    }
    return EXPECT(terminator) && EXPECT(dbXmlScanner::xml_gt);
} 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -