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

📄 xml.cpp

📁 最新版本!fastdb是高效的内存数据库系统
💻 CPP
📖 第 1 页 / 共 3 页
字号:
#define HEX_DIGIT(ch) ((ch) >= 'a' ? ((ch) - 'a' + 10) : (ch) >= 'A' ? (((ch) - 'A' + 10)) : ((ch) - '0'))

bool dbDatabase::importField(char* terminator, dbFieldDescriptor* fd, byte* rec, dbXmlScanner& scanner) 
{
    dbXmlScanner::token tkn;
    int i;
    long id;
    byte* dst = rec + fd->appOffs;
    
    switch (fd->appType) { 
      case dbField::tpStructure:
        return importRecord(terminator, fd->components, dst, scanner);
      case dbField::tpArray:
      { 
          int arrSize = 8;
          int elemSize = fd->components->appSize;
          byte* arr = (byte*)xmlContext->tmpAlloc.alloc(elemSize*arrSize);
          memset(arr, 0, elemSize*arrSize);
          for (i = 0; (tkn = scanner.scan()) == dbXmlScanner::xml_lt; i++) { 
              if (!EXPECT("array-element")
                  || !EXPECT(dbXmlScanner::xml_gt))
              {
                  return false;
              }
              if (i == arrSize) { 
                  arrSize *= 2;
                  byte* newArr = (byte*)xmlContext->tmpAlloc.alloc(elemSize*arrSize);
                  memcpy(newArr, arr, i*elemSize);
                  memset(newArr + i*elemSize, 0, i*elemSize);
                  arr = newArr;
              }
              importField("array-element", fd->components, arr + i*elemSize, scanner);
          }
          dbAnyArray::arrayAllocator((dbAnyArray*)dst, arr, i); 
          return tkn == dbXmlScanner::xml_lts
              && EXPECT(terminator)
              && EXPECT(dbXmlScanner::xml_gt);
      }
      case dbField::tpReference:
        if (!EXPECT(dbXmlScanner::xml_lt)
            || !EXPECT("ref")
            || !EXPECT("id")
            || !EXPECT(dbXmlScanner::xml_eq)
            || !EXPECT(dbXmlScanner::xml_sconst)
            || sscanf(scanner.getString(), "%ld", &id) != 1
            || !EXPECT(dbXmlScanner::xml_gts))
        { 
            return false;
        }
        *(oid_t*)dst = mapId(id);
        break;
      case dbField::tpRectangle:
        if (!EXPECT("rectangle")
            || !EXPECT(dbXmlScanner::xml_gt)
            || !EXPECT(dbXmlScanner::xml_lt)
            || !EXPECT("vertex"))
        { 
            return false;
        } else {
            rectangle& r = *(rectangle*)dst;
            for (i = 0; i < rectangle::dim; i++) { 
                if (!EXPECT(dbXmlScanner::xml_ident)
                    || !EXPECT(dbXmlScanner::xml_eq)
                    || !EXPECT(dbXmlScanner::xml_sconst)
                    || sscanf(scanner.getString(), "%d", &r.boundary[i]) != 1)
                {
                    return false;
                }
            }
            if (!EXPECT(dbXmlScanner::xml_gts)
                || !EXPECT(dbXmlScanner::xml_lt)
                || !EXPECT("vertex"))
            {
                return false;
            }
            for (i = 0; i < rectangle::dim; i++) { 
                if (!EXPECT(dbXmlScanner::xml_ident)
                    || !EXPECT(dbXmlScanner::xml_eq)
                    || !EXPECT(dbXmlScanner::xml_sconst)
                    || sscanf(scanner.getString(), "%d", &r.boundary[rectangle::dim+i]) != 1)
                {
                    return false;
                }
            }
            if (!EXPECT(dbXmlScanner::xml_gts)
                || !EXPECT(dbXmlScanner::xml_lts)
                || !EXPECT("rectangle")
                || !EXPECT(dbXmlScanner::xml_gt))
            {
                return false;
            }
            break;
        }
      case dbField::tpBool:
        switch (scanner.scan()) { 
          case dbXmlScanner::xml_iconst:
            *(bool*)dst = scanner.getInt() != 0;
            break;
          case dbXmlScanner::xml_fconst:
            *(bool*)dst = scanner.getReal() != 0.0;
            break;
          default:
            scanner.warning("Failed to convert field");
        }
        break;            
      case dbField::tpInt1:
        switch (scanner.scan()) { 
          case dbXmlScanner::xml_iconst:
            *(int1*)dst = (int1)scanner.getInt();
            break;
          case dbXmlScanner::xml_fconst:
            *(int1*)dst = (int1)scanner.getReal();
            break;
          default:
            scanner.warning("Failed to convert field");
        }
        break;            
      case dbField::tpInt2:
        switch (scanner.scan()) { 
          case dbXmlScanner::xml_iconst:
            *(int2*)dst = (int2)scanner.getInt();
            break;
          case dbXmlScanner::xml_fconst:
            *(int2*)dst = (int2)scanner.getReal();
            break;
          default:
            scanner.warning("Failed to convert field");
        }
        break;            
      case dbField::tpInt4:
        switch (scanner.scan()) { 
          case dbXmlScanner::xml_iconst:
            *(int4*)dst = (int4)scanner.getInt();
            break;
          case dbXmlScanner::xml_fconst:
            *(int4*)dst = (int4)scanner.getReal();
            break;
          default:
            scanner.warning("Failed to convert field");
        }
        break;            
      case dbField::tpInt8:
        switch (scanner.scan()) { 
          case dbXmlScanner::xml_iconst:
            *(db_int8*)dst = scanner.getInt();
            break;
          case dbXmlScanner::xml_fconst:
            *(db_int8*)dst = (int8)scanner.getReal();
            break;
          default:
            scanner.warning("Failed to convert field");
        }
        break;            
      case dbField::tpReal4:
        switch (scanner.scan()) { 
          case dbXmlScanner::xml_iconst:
            *(real4*)dst = (real4)scanner.getInt();
            break;
          case dbXmlScanner::xml_fconst:
            *(real4*)dst = (real4)scanner.getReal();
            break;
          default:
            scanner.warning("Failed to convert field");
        }
        break;            
      case dbField::tpReal8:
        switch (scanner.scan()) { 
          case dbXmlScanner::xml_iconst:
            *(real8*)dst = (real8)scanner.getInt();
            break;
          case dbXmlScanner::xml_fconst:
            *(real8*)dst = scanner.getReal();
            break;
          default:
            scanner.warning("Failed to convert field");
        }
        break;            
      case dbField::tpString:
        switch (scanner.scan()) { 
          case dbXmlScanner::xml_iconst:
          case dbXmlScanner::xml_sconst:
          case dbXmlScanner::xml_fconst:
          { 
              char* str = (char*)xmlContext->tmpAlloc.alloc((scanner.getStringLength()+1));
              memcpy(str, scanner.getString(), scanner.getStringLength());
              str[scanner.getStringLength()] = '\0';
              *(char**)dst = str;
              break;
          }
          default:
            scanner.warning("Failed to convert field");
        }
        break;            
      case dbField::tpRawBinary:
      {
          if (scanner.scan() != dbXmlScanner::xml_sconst) { 
              scanner.warning("Failed to convert field");
              break;            
          }
          char* src = scanner.getString();
          int len = scanner.getStringLength() >> 1;
          if (fd->appSize != (size_t)len) { 
              scanner.warning("Length of raw binary field was changed");
          } else { 
              while (--len >= 0) { 
                  *dst++ = (HEX_DIGIT(src[0]) << 4) | HEX_DIGIT(src[1]);
                  src += 2;
              }
          }
          break;
      }
#ifdef USE_STD_STRING
      case dbField::tpStdString:
          if (scanner.scan() != dbXmlScanner::xml_sconst) { 
              scanner.warning("Failed to convert field");
              break;            
          }
          ((tmp_basic_string*)dst)->assign(tmp_basic_string(scanner.getString(), scanner.getStringLength(), xmlContext->stdAlloc));
          break;
#endif
    }    
    return EXPECT(dbXmlScanner::xml_lts)
        && EXPECT(terminator)
        && EXPECT(dbXmlScanner::xml_gt); 
}

oid_t dbDatabase::mapId(long id)
{
    oid_t oid;
    if (id == 0) { 
        return 0;
    }
    if ((oid_t)id >= xmlContext->oidMapSize) { 
        oid_t* newOidMap = new oid_t[id*2];
        memcpy(newOidMap, xmlContext->oidMap, xmlContext->oidMapSize*sizeof(oid_t));
        memset(newOidMap + xmlContext->oidMapSize, 0, (id*2-xmlContext->oidMapSize)*sizeof(oid_t));
        xmlContext->oidMapSize = id*2;
        xmlContext->oidMap = newOidMap;
    }
    oid = xmlContext->oidMap[id];
    if (oid == 0) { 
        oid = allocateId();
        xmlContext->oidMap[id] = oid;
    }
    return oid;
}

void dbDatabase::insertRecord(dbTableDescriptor* desc, oid_t oid, void const* record) 
{
    dbFieldDescriptor* fd;
    byte* src = (byte*)record;
    size_t size = desc->columns->calculateRecordSize(src, desc->fixedSize);
    allocateRow(desc->tableId, oid, size);
    dbTable* table = (dbTable*)getRow(desc->tableId);
#ifdef AUTOINCREMENT_SUPPORT
    desc->autoincrementCount = table->count;
#endif
    dbRecord* dst = getRow(oid);
    desc->columns->storeRecordFields((byte*)dst, src, desc->fixedSize, dbFieldDescriptor::Import);
    
#ifdef AUTOINCREMENT_SUPPORT
    if ((nat4)desc->autoincrementCount > table->count) {
        table->count = desc->autoincrementCount;
    }
#endif
    int nRows = table->nRows;
    for (fd = desc->hashedFields; fd != NULL; fd = fd->nextHashedField) {
        dbHashTable::insert(this, fd->hashTable, oid, fd->type, fd->dbsSize, fd->dbsOffs, nRows);
    }
    for (fd = desc->indexedFields; fd != NULL; fd = fd->nextIndexedField) {
        if (fd->type == dbField::tpRectangle) { 
            dbRtree::insert(this, fd->tTree, oid, fd->dbsOffs);
        } else { 
            dbTtree::insert(this, fd->tTree, oid, fd->type, fd->dbsSize, fd->comparator, fd->dbsOffs);
        }
    }
}

bool dbDatabase::importDatabaseFromXml(FILE* in)
{
    dbXmlContext ctx;
    xmlContext = &ctx;
    dbXmlScanner scanner(in);
    dbXmlScanner::token tkn;
    
    if (!EXPECT(dbXmlScanner::xml_lt) ||
        !EXPECT("database") || 
        !EXPECT(dbXmlScanner::xml_gt))
    {
        return false;
    }
    beginTransaction(dbExclusiveLock);
    
    ctx.oidMapSize = dbDefaultInitIndexSize;
    ctx.oidMap = new oid_t[ctx.oidMapSize];
    memset(ctx.oidMap, 0, ctx.oidMapSize*sizeof(oid_t));

    while ((tkn = scanner.scan()) != dbXmlScanner::xml_lts) { 
        if (tkn != dbXmlScanner::xml_lt || !EXPECT(dbXmlScanner::xml_ident)) { 
            return false;
        }
        dbTableDescriptor* desc = findTableByName(scanner.getIdentifier());
        if (desc == NULL) { 
            fprintf(stderr, "Table '%s' not found\n", scanner.getIdentifier());
        }
        if (!EXPECT("id")
            || !EXPECT(dbXmlScanner::xml_eq)
            || !EXPECT(dbXmlScanner::xml_sconst)
            || !EXPECT(dbXmlScanner::xml_gt)) 
        {
            return false;
        }
        if (desc != NULL) { 
            long id;
            if (sscanf(scanner.getString(), "%ld", &id) != 1 || id == 0) { 
                return false;
            }
            oid_t oid = mapId(id);
            byte *record = (byte*)xmlContext->tmpAlloc.alloc(desc->appSize);  
            memset(record, 0, desc->appSize);
            if (!importRecord(desc->name, desc->columns, record, scanner)) {                 
                xmlContext->tmpAlloc.reset();
                return false;
            }
            insertRecord(desc, oid, record);
            xmlContext->tmpAlloc.reset();
        } else { // skip record
            if (!skipElement(scanner)) { 
                return false;
            }
        }    
    }
    return EXPECT("database") && EXPECT(dbXmlScanner::xml_gt);
}

⌨️ 快捷键说明

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