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

📄 dsmcc_storage.cpp

📁 数字电视中间件小型库
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "dsmcc_storage.h"

bool DSM_CC::FilesystemStorage::StoreObject(uint32_t download_id, uint16_t module_id, uint8_t module_version, const BIOP::ServiceGateway& srg) {
    (void)module_version;

    if(!rootvalid) {
        return false;
    }

    // By definition, the srg "is" the root directory, so its placement is the empty string
    QString key = PlacementKey(download_id, module_id, srg.header);
    QString placement = "";

    placement_map[key] = placement;

    uint32_t num_bindings = srg.bindings.size();

    // Now, preallocate placements for all child objects
    for(uint32_t i = 0; i < num_bindings; ++i) {
        if(srg.bindings[i].ior.profiles[0].id_tag != BIOP_PROFILE_ID_BIOP) {
            continue;
        }
        BIOP::BIOPProfile profile = srg.bindings[i].ior.profiles[0].biop;
        BIOP::Name name = srg.bindings[i].name;
        key = PlacementKey(profile.object_location.carousel_id,
                           profile.object_location.module_id, 
                           profile.object_location.object_key, 
                           profile.object_location.object_key_length);
        placement = "/";
        for(uint8_t j = 0; j < name.id.size(); ++j) {
            placement += name.id[j];
        }
        placement_map[key] = placement;
    }

    return true;
}

bool DSM_CC::FilesystemStorage::StoreObject(uint32_t download_id, uint16_t module_id, uint8_t module_version, const BIOP::DirectoryMessage& dm) {
    (void)module_version;

    if(!rootvalid) {
        return false;
    }
    
    QString dmkey = PlacementKey(download_id, module_id, dm.header);
    QString placement = placement_map[dmkey];

    // First off, create this directory
    if(mkdir((rootpath + placement).ascii(), O_CREAT) && (errno != EEXIST)) {
        #ifdef DSM_CC_TRACE_STORAGE
            DSM_CC_TRACE_GENERAL("FilesystemStorage", "ERROR: Could not create directory");
            DSM_CC_TRACE_STR("FilesystemStorage", "dirname", (rootpath + placement).ascii());
        #endif
        return false;
    }

    // And now, preallocate placements for all children

    uint32_t num_bindings = dm.bindings.size();

    for(uint32_t i = 0; i < num_bindings; ++i) {
        if(dm.bindings[i].ior.profiles[0].id_tag != BIOP_PROFILE_ID_BIOP) {
            continue;
        }
        BIOP::BIOPProfile profile = dm.bindings[i].ior.profiles[0].biop;
        BIOP::Name name = dm.bindings[i].name;
        QString key = PlacementKey(profile.object_location.carousel_id,
                                   profile.object_location.module_id, 
                                   profile.object_location.object_key, 
                                   profile.object_location.object_key_length);

        // If only I knew why this simply will _not_ work with normal append operators
        QString bindplacement;
        bindplacement.sprintf("%s/", placement_map[dmkey].ascii());

        for(uint8_t j = 0; j < name.id.size(); ++j) {
            bindplacement += name.id[j];
        }

        placement_map[key] = bindplacement;
        
    }
    return true;
}

bool DSM_CC::FilesystemStorage::StoreObject(uint32_t download_id, uint16_t module_id, uint8_t module_version, const BIOP::FileMessage& fm) {
    (void)module_version;

    if(!rootvalid) {
        return false;
    }

    QString key = PlacementKey(download_id, module_id, fm.header);
    QString placement = placement_map[key];

    // Now simply dump all of it to the filesystem
    FILE* fp;
    if((fp = fopen((rootpath + placement).ascii(), "wb")) == NULL) {
        #ifdef DSM_CC_TRACE_STORAGE
            DSM_CC_TRACE_GENERAL("FilesystemStorage", "ERROR: Could not create file");
            DSM_CC_TRACE_STR("FilesystemStorage", "filename", (rootpath + placement).ascii());
        #endif
        return false;
    }

    size_t written;
    
    if((written = fwrite(fm.contents, sizeof(uint8_t), fm.header.message_body_length - 4, fp)) != fm.header.message_body_length - 4) {
        #ifdef DSM_CC_TRACE_STORAGE
            DSM_CC_TRACE_GENERAL("FilesystemStorage", "ERROR: Could not write enough data to file");
            DSM_CC_TRACE_STR("FilesystemStorage", "filename", (rootpath + placement).ascii());
            DSM_CC_TRACE_NUM("FilesystemStorage", "bytes written", written, "8");
            DSM_CC_TRACE_NUM("FilesystemStorage", "bytes attempted", fm.header.message_body_length - 4, "8");
        #endif
        return false;
    }

    fclose(fp);

    return true;
}

void DSM_CC::FilesystemStorage::SetStorageRoot(QString newroot) {
    if(mkdir(newroot.ascii(), O_CREAT) && (errno != EEXIST)) {
        #ifdef DSM_CC_TRACE_STORAGE
            DSM_CC_TRACE_GENERAL("FilesystemStorage", "ERROR: Could not create storage root");
            DSM_CC_TRACE_STR("FilesystemStorage", "dirname", newroot.ascii());
        #endif
        return;
    }
    rootvalid = true;
    rootpath = newroot;
}

QString DSM_CC::FilesystemStorage::GetStorageRoot() {
    return rootpath;
}



uint32_t DSM_CC::MythDatabaseStorage::next_insert_id = 0;

uint32_t DSM_CC::MythDatabaseStorage::GetNextInsertId() {
    // Get and cache the next available id value from the database
    MSqlQuery query(MSqlQuery::InitCon());

    query.prepare("SELECT max(id) FROM dsmcc_objects");
    query.exec();

    if(!query.isActive()) {
        #ifdef DSM_CC_TRACE_STORAGE
            DSM_CC_TRACE_GENERAL("MythDBStorage", "Could not query maximum id from database");
        #endif
        return false;
    }

    query.next();

    return next_insert_id = query.value(0).toInt() + 1;
}

bool DSM_CC::MythDatabaseStorage::StoreObject(uint32_t download_id, uint16_t module_id, uint8_t module_version, const BIOP::ServiceGateway& srg) {
    // First of all make sure that next_insert_id is initialized
    // This is only useful in this StoreObject() overload because it's guaranteed to be called first

    if(next_insert_id == 0) {
        if(!GetNextInsertId()) {
            return false;
        }
    }

    MSqlQuery query(MSqlQuery::InitCon());
    // Insert ourselves into the parent relationship map
    QString key = PlacementKey(download_id, module_id, srg.header);

    object_info[key].parent = 0;
    object_info[key].name   = "";

    // Do we exist in the database?
    query.prepare(QString(
        "SELECT id, module_version FROM dsmcc_objects "
        "WHERE download_id = %1 AND module_id = %2 AND object_key = ?"
        ).arg(download_id).arg(module_id)
    );

    query.bindValue(0, MakeString(srg.header.object_key.begin(), srg.header.object_key.size()));
    query.exec();

    if(!query.isActive()) {
        #ifdef DSM_CC_TRACE_STORAGE
            DSM_CC_TRACE_STR("MythDBStorage", "Bad query", query.executedQuery().ascii());
        #endif
        return false;
    }

    if(!query.size()) {
        // No, we don't exist, so insert the record
        query.prepare(QString(
            "INSERT INTO dsmcc_objects (id, download_id, module_id, module_version, object_key, object_name, object_type, parent_id) "
            "VALUES (%1, %2, %3, %4, ?, '', 'srg', 0)"
            ).arg(next_insert_id++).arg(download_id).arg(module_id).arg(module_version)
        );
        query.bindValue(0, MakeString(srg.header.object_key.begin(), srg.header.object_key.size()));
        query.exec();

        if(!query.isActive()) {
            #ifdef DSM_CC_TRACE_STORAGE
                DSM_CC_TRACE_STR("MythDBStorage", "Bad query", query.executedQuery().ascii());
            #endif
            return false;
        }
    }
    else {
        // We exist; if the module version is the same, then do nothing
        // Otherwise, update the record to reflect the new data
        query.next();
        if(query.value(1).toInt() != module_version) {
            // Simply update the version; nothing else required (the object key is the same, see first query)
            QString newquery("UPDATE dsmcc_objects SET module_version = %1 WHERE id = %2");
            query.prepare(newquery.arg(module_version).arg(query.value(0).toInt()));
            query.exec();
            if(!query.isActive()) {
                #ifdef DSM_CC_TRACE_STORAGE
                    DSM_CC_TRACE_STR("MythDBStorage", "Bad query", query.executedQuery().ascii());
                #endif
                return false;
            }
        }
    }

    // Great! Now we have to prepare child object data in the hashtables
    uint32_t num_bindings = srg.bindings.size();

    for(uint32_t i = 0; i < num_bindings; ++i) {
        if(srg.bindings[i].ior.profiles[0].id_tag != BIOP_PROFILE_ID_BIOP) {
            continue;
        }
        BIOP::BIOPProfile profile = srg.bindings[i].ior.profiles[0].biop;
        QString key = PlacementKey(profile.object_location.carousel_id,

⌨️ 快捷键说明

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