df_FRI Class Reference
[IVD Data format.]

#include <df.h>

Collaboration diagram for df_FRI:

Collaboration graph
[legend]

List of all members.


Detailed Description

Definition at line 804 of file df.h.


Public Member Functions

 df_FRI (cmn_UUID_t &a_partID, cmn_UUID_t &a_poolID, UInt32_t a_blkSize)
virtual ~df_FRI ()
UInt8_tMediumVolumeStart (const cmn_UUID_t &a_medVolID, UInt32_t a_medPos, ivd_MigrationID_t a_migrationID, UInt32_t a_copyNumber, UInt32_t a_mediumKey, UInt32_t a_medVolNum, i_FSC_ptr a_fsc)
 Start processing FRI for new medium volume.
void MediumVolumeEnd (UInt32_t a_status)
 End processing FRI for new medium volume.
void MediumVolumeClosed (const string &a_medVolID)
 Medium Volume is closed and Disk FRI can be removed.
void BlockScan (UInt8_t *a_blkBuf)
 Parse IVD Data Format and update File record (copyID & nrOfCopies).
void BlockWritten (UInt32_t a_medPos)
 Append FRI records from last block to Disk FRI, return Split info to FSC.
const vector< df_SplitInfo > & GetSplits () const

Private Member Functions

void FlushCurrentSplit ()

Private Attributes

 log_CLASSID_m
df_BlockScanner m_scanner
 Scanner used for parsing IVD Data blocks.
UInt32_t m_blkSize
cmn_UUID_t m_partID
cmn_UUID_t m_poolID
cmn_UUID_t m_curMedVolID
 Disk FRI file.
df_Writerm_diskFRI
UInt32_t m_medStartPos
UInt32_t m_medCurPos
UInt32_t m_recNum
UInt32_t m_streamType
UInt64_t m_streamSize
string m_streamName
bool m_streamToFRI
vector< df_RecCmn_t * > m_friRec
 FRI records from last block (saved for BlockWritten() method).
df_SplitInfo m_curSplit
vector< df_SplitInfom_splits
UInt8_tm_contBlk
 Continuation block buffer - used in case file spans multiple volumes.
df_BlockHeader_tm_contBlkHdr
 Pointers into m_contBlk buffer (NULL if they do not exist).
df_RecCmn_tm_contFile
df_RecCmn_tm_contBSS

Constructor & Destructor Documentation

df_FRI::df_FRI ( cmn_UUID_t a_partID,
cmn_UUID_t a_poolID,
UInt32_t  a_blkSize 
)

Definition at line 34 of file df_fri.cpp.

References blk_Data_c, df_BF_CONTINUED, df_SplitInfo::fileID, log_FUNC_m, m_contBlk, m_contBlkHdr, m_curSplit, and df_BlockProxyWriter::WriteBlockHeader().

00038     : m_scanner(blk_Data_c, a_blkSize),
00039       m_blkSize(a_blkSize),
00040       m_partID(a_partID),
00041       m_poolID(a_poolID),
00042       m_diskFRI(NULL),
00043       m_recNum(0),
00044       m_streamType(0),
00045       m_streamToFRI(false),
00046       m_contFile(NULL),
00047       m_contBSS(NULL) {
00048 
00049     log_FUNC_m(df_FRI);
00050 
00051     m_curSplit.fileID = 0;
00052 
00053     // Allocate contBlk and mark that no record are present yet
00054     m_contBlk    = new UInt8_t[a_blkSize];
00055     m_contBlkHdr = df_Writer::WriteBlockHeader(m_contBlk, blk_Data_c, 
00056                                                df_BF_CONTINUED, 0);
00057 
00058 }

Here is the call graph for this function:

df_FRI::~df_FRI (  )  [virtual]

Definition at line 61 of file df_fri.cpp.

References dbg_LOW, df_FRIS_ABORTED, log_DBG_m, log_FUNC_m, m_contBlk, m_diskFRI, MediumVolumeEnd(), and NULL.

00061                 {
00062     log_FUNC_m(~df_FRI);
00063 
00064     try {
00065         if (m_diskFRI != NULL) {
00066             log_DBG_m(dbg_LOW,
00067                 "FRI Data stream not properly terminated. Terminating now.");
00068 
00069             MediumVolumeEnd(df_FRIS_ABORTED);
00070             // ensure that FRI writer is properly killed
00071             delete m_diskFRI;
00072         }
00073 
00074         delete [] m_contBlk;
00075     }
00076     catch (ivd_Exception &ie) {
00077         log_DBG_m(dbg_LOW,
00078             "Ignoring exception in DTOR." << endl <<
00079             "Error: " << ie);
00080     }
00081 }

Here is the call graph for this function:


Member Function Documentation

UInt8_t * df_FRI::MediumVolumeStart ( const cmn_UUID_t a_medVolID,
UInt32_t  a_medPos,
ivd_MigrationID_t  a_migrationID,
UInt32_t  a_copyNumber,
UInt32_t  a_mediumKey,
UInt32_t  a_medVolNum,
i_FSC_ptr  a_fsc 
)

Start processing FRI for new medium volume.

This will open/create Disk FRI file for above medium and all FRI data will be appended to Disk FRI file. Function returns continuation block (or 0 if not needed) - caller has to free the returned block with delete []!

Definition at line 361 of file df_fri.cpp.

References df_BlockProxyWriter::Allocate(), df_RecByteStreamStart_t::allStreamSize, bbt_DISK_FRI, blk_FRI_c, dbg_LOW, dbg_NORM, df_RF_SPLITTED, df_RecCmn_t::flags, df_BlockScanner::GetNextBlkNum(), df_BlockScanner::GetNextRecNum(), df_BlockScanner::GetStreamLeft(), df_Writer::Go(), hton(), ie_DF_EOD, ie_IMPOSSIBLE, log_DBG_m, log_ERR_m, log_FUNC_m, log_MARKLINE_m, m_blkSize, m_contBlk, m_contBlkHdr, m_contBSS, m_contFile, m_curMedVolID, m_diskFRI, m_medCurPos, m_medStartPos, m_partID, m_poolID, m_recNum, m_scanner, df_BlockProxyWriter::Move(), df_Writer::NewFRIBuffer(), ntoh(), NULL, df_BlockScanner::Reset(), df_RecCmn_t::seqNum, df_BlockHeader_t::seqNum, df_RecCmn_t::size, df_RecByteStreamStart_t::streamOffset, df_RecByteStreamStart_t::streamSize, df_RecByteStreamStart_t::streamSplitSize, cmn_UUID_t::ToString(), df_BlockHeader_t::used, and df_Packer::WriteRecFRIStart().

Referenced by bea_MigrationThread::FRIVolumeStart().

00368                                {
00369 
00370     log_FUNC_m(MediumVolumeStart);
00371 
00372     if (m_diskFRI) {
00373         throw ivd_InternalError(
00374             ie_IMPOSSIBLE, "Previous volume not ended yet");
00375     }
00376 
00377     m_curMedVolID = a_medVolID;
00378     m_medStartPos = m_medCurPos = a_medPos;
00379     m_recNum      = 0;
00380 
00381 /*
00382     TODO:
00383     OPen the FRI file and read the last block for append.
00384     If it can't be scanned, write it back to df_Writer as is.
00385 */
00386     m_diskFRI = new df_Writer(blk_FRI_c, bbt_DISK_FRI, m_blkSize);
00387     m_diskFRI->NewFRIBuffer(
00388         m_curMedVolID.ToString(),
00389         a_migrationID,
00390         a_copyNumber,
00391         a_mediumKey,
00392         a_medVolNum,
00393         a_fsc);
00394 
00395     m_diskFRI->Go();
00396 
00397     // Write FRIStart record
00398     UInt32_t recSize = sizeof(df_RecCmn_t) + sizeof(df_RecFRIStart_t);
00399     UInt8_t* recBuf = m_diskFRI->Allocate(recSize);
00400     
00401     if (recBuf == NULL) {
00402         log_MARKLINE_m;
00403         throw ivd_DFError(ie_DF_EOD, 0, "Unexpected EOD in FRI buffer.", true);
00404     }
00405 
00406     df_Packer::WriteRecFRIStart(m_curMedVolID,
00407                                 m_poolID,
00408                                 m_partID,
00409                                 m_medStartPos,
00410                                 ++m_recNum,
00411                                 recBuf,
00412                                 recSize);
00413 
00414     m_diskFRI->Move(recSize);
00415 
00416     // if there is file still not completed -> send continuation record
00417     if (m_contFile) {
00418 
00419         // update sequence number in continuation block
00420         m_contBlkHdr->seqNum = hton(m_scanner.GetNextBlkNum() - 1);
00421 
00422         // update block used field in continuation block header
00423         UInt32_t nextRecNum = m_scanner.GetNextRecNum();
00424         UInt32_t blockUsed = sizeof(*m_contBlkHdr);
00425 
00426         if (m_contBSS) {
00427 
00428             log_DBG_m(dbg_LOW, "Calculating data for the split.");
00429         
00430             blockUsed += ntoh(m_contBSS->size);
00431             m_contBSS->seqNum = hton(--nextRecNum);
00432 
00433             df_RecByteStreamStart_t *bss_p = df_GetSpecificRec<df_RecByteStreamStart_t>(m_contBSS);
00434 
00435             // ** Create new BSS for the split
00436             UInt64_t streamSize = ntoh(bss_p->streamSize);
00437             UInt64_t streamOffset = ntoh(bss_p->streamOffset);
00438             UInt64_t streamSplitSize = ntoh(bss_p->streamSplitSize);
00439 
00440             log_DBG_m(dbg_NORM, "StreamSize      : " << streamSize);
00441             log_DBG_m(dbg_NORM, "StreamOffset    : " << streamOffset);
00442             log_DBG_m(dbg_NORM, "StreamSplitSize : " << streamSplitSize);
00443 
00444             // ** Calculate total split size
00445             UInt64_t splitSize = streamSize - streamOffset;
00446             
00447             if (  streamSplitSize > 0
00448                || ntoh(m_contBSS->flags) & df_RF_SPLITTED) {
00449                 if (splitSize < streamSplitSize) {
00450                     log_ERR_m(
00451                         "StreamSplitSize > (StreamSize - StreamOffset): " <<
00452                         "Possible internal error!!");
00453                 }
00454                 splitSize = streamSplitSize;
00455             }
00456             log_DBG_m(dbg_LOW, "Size of this stream: " << splitSize);
00457             
00458             // ** Calculate new split stream sizes
00459             
00460             UInt64_t writtenSplitSize = splitSize - m_scanner.GetStreamLeft();
00461             UInt64_t leftSplitSize = m_scanner.GetStreamLeft();
00462 
00463             // AllStreamSize is AllStreamSize reduced by current stream offset
00464             // increased by size of current stream written up to now
00465             bss_p->allStreamSize = hton(
00466                 ntoh(bss_p->allStreamSize) + writtenSplitSize );
00467 
00468             // Current StreamOffset (for new medium volume) is 
00469             // size of stream reduced for stream bytes left (not written yet)
00470             bss_p->streamOffset  = hton( streamOffset + writtenSplitSize );
00471                                         
00472             // Already split stream is split again
00473             if (streamSplitSize > 0) {
00474                 bss_p->streamSplitSize = hton(leftSplitSize);
00475                 
00476                 log_DBG_m(dbg_NORM,
00477                     "Splitting a split. New splitStreamSize : " <<
00478                     m_scanner.GetStreamLeft() );
00479             }
00480             
00481             log_DBG_m(dbg_LOW,
00482                 "ContBSS: streamSplitSize: " << ntoh(bss_p->streamSplitSize) << endl <<
00483                 "streamSize              : " << ntoh(bss_p->streamSize) << endl <<
00484                 "allStreamSize           : " << ntoh(bss_p->allStreamSize) << endl <<
00485                 "streamOffset            : " << ntoh(bss_p->streamOffset));
00486         }
00487 
00488         blockUsed += ntoh(m_contFile->size);
00489         m_contFile->seqNum = hton(--nextRecNum);
00490 
00491         m_contBlkHdr->used = hton(blockUsed);
00492 
00493         // allocate return block - call should delete it
00494         UInt8_t *retBlk = new UInt8_t[m_blkSize];
00495         memcpy(retBlk, m_contBlk, blockUsed);
00496 
00497         // reset record pointer for new medium
00498         m_contFile = 0;
00499         m_contBSS  = 0;
00500 
00501         // reset scanner - new medium may start with contBlock
00502         m_scanner.Reset();
00503 
00504         // return continuation block
00505         return retBlk;
00506     }
00507 
00508     return 0;   // first medium or continuation block not needed
00509 }

Here is the call graph for this function:

Here is the caller graph for this function:

void df_FRI::MediumVolumeEnd ( UInt32_t  a_status  ) 

End processing FRI for new medium volume.

If there is still split info left it is returned. Disk FRI file will be closed.

Definition at line 512 of file df_fri.cpp.

References df_BlockProxyWriter::Allocate(), dbg_LOW, df_ALIGN_m, df_FRIS_ABORTED, df_FS_ERROR, df_Writer::EndOfData(), df_SplitInfo::fileID, FlushCurrentSplit(), ie_IMPOSSIBLE, log_DBG_m, log_FUNC_m, log_WRN_m, m_curMedVolID, m_curSplit, m_diskFRI, m_medCurPos, m_medStartPos, m_partID, m_poolID, m_recNum, m_streamName, m_streamSize, m_streamToFRI, m_streamType, df_SplitInfo::migrationID, df_BlockProxyWriter::Move(), NULL, df_SplitInfo::splitSize, df_Writer::WaitAllReaders(), df_Packer::WriteRecBSEndRaw(), df_Packer::WriteRecFileEndRaw(), and df_Packer::WriteRecFRIEnd().

Referenced by bea_MigrationThread::FRIVolumeEnd(), and ~df_FRI().

00512                                               {
00513 
00514     log_FUNC_m(MediumVolumeEnd);
00515 
00516     if (!m_diskFRI) {
00517         throw ivd_InternalError(ie_IMPOSSIBLE, 
00518                                 "Volume not started yet");
00519     }
00520 
00521     // if this is last block on medium volume -> flush current split (if any)
00522     if (m_curSplit.fileID != 0) {
00523         if (a_status != df_FRIS_ABORTED) {
00524             FlushCurrentSplit();
00525         }
00526         else {
00527             if (m_streamType != 0) {
00528                 if (m_streamToFRI) {
00529                     log_DBG_m(dbg_LOW, "Migration aborted. Writing BSEn.");
00530                 
00531                     UInt32_t recSize = df_ALIGN_m(sizeof(df_RecCmn_t)
00532                                     + sizeof(df_RecByteStreamEnd_t)
00533                                     + m_streamName.length() 
00534                                     + 1);
00535                                             
00536                     UInt8_t* recBuf = m_diskFRI->Allocate(recSize);
00537                                 
00538                     df_Packer::WriteRecBSEndRaw(
00539                         m_curSplit.fileID,
00540                         df_FS_ERROR, 
00541                         m_streamType, 
00542                         m_streamSize, 
00543                         m_curSplit.splitSize,
00544                         m_streamName,
00545                         0, 
00546                         recBuf);
00547                 }
00548             }
00549             
00550             FlushCurrentSplit();
00551             
00552             log_DBG_m(dbg_LOW, "Migration aborted. Writing FEnd.");
00553             
00554             UInt32_t recSize = df_ALIGN_m(sizeof(df_RecCmn_t) 
00555                              + sizeof(df_RecFileEnd_t));
00556             UInt8_t* recBuf = m_diskFRI->Allocate(recSize);
00557             
00558             df_Packer::WriteRecFileEndRaw(m_curSplit.fileID,
00559                                           m_curSplit.migrationID,
00560                                           df_FS_ERROR,
00561                                           0, 
00562                                           recBuf,
00563                                           0);
00564         }
00565     }
00566 
00567     // Write FRIEnd record
00568     UInt32_t recSize = sizeof(df_RecCmn_t) + sizeof(df_RecFRIEnd_t);
00569     UInt8_t* recBuf = m_diskFRI->Allocate(recSize);
00570     
00571     if (recBuf != NULL) {
00572         df_Packer::WriteRecFRIEnd(m_curMedVolID,
00573                                 m_poolID,
00574                                 m_partID,
00575                                 m_medStartPos,
00576                                 m_medCurPos,
00577                                 a_status,
00578                                 ++m_recNum,
00579                                 recBuf,
00580                                 recSize);
00581 
00582         m_diskFRI->Move(recSize);
00583     }
00584     else {
00585         log_WRN_m("NULL block pointer for FRI. No reader available.");
00586     }
00587 
00588     // notify writer that we have no more data
00589     m_diskFRI->EndOfData();
00590 
00591     // Wait for all reader threads to finish.
00592     // May throw exception if reader sets it.
00593     m_diskFRI->WaitAllReaders();
00594 
00595     delete m_diskFRI;
00596     m_diskFRI = NULL;
00597 }

Here is the call graph for this function:

Here is the caller graph for this function:

void df_FRI::MediumVolumeClosed ( const string &  a_medVolID  ) 

Medium Volume is closed and Disk FRI can be removed.

Disk FRI file will be closed.

Definition at line 600 of file df_fri.cpp.

References cmn_File::DeleteF(), cmn_Global::dirs, ivd_Directories::fri, g_cmn, ie_IMPOSSIBLE, log_FUNC_m, and m_diskFRI.

00600                                                         {
00601 
00602     log_FUNC_m(MediumVolumeClosed);
00603 
00604     if (m_diskFRI) {
00605         throw ivd_InternalError(ie_IMPOSSIBLE, 
00606                                 "Current volume not ended yet");
00607     }
00608 
00609     cmn_File    friFile(g_cmn.dirs.fri + a_medVolID);
00610 
00611     friFile.DeleteF();
00612 }

Here is the call graph for this function:

void df_FRI::BlockScan ( UInt8_t a_blkBuf  ) 

Parse IVD Data Format and update File record (copyID & nrOfCopies).

TODO: non-DATA Raw blocks need to be appended too!!!

Definition at line 86 of file df_fri.cpp.

References df_BlockScanner::GetNextRecord(), log_FUNC_m, m_friRec, m_scanner, and df_BlockScanner::SetBlock().

Referenced by bea_MigrationThread::WriteBlock().

00086                                         {
00087 
00088     log_FUNC_m(BlockScan);
00089 
00090     // start from empty FRI record 
00091     m_friRec.clear();
00092 
00093     if (!m_scanner.SetBlock(a_blkBuf)) {
00095         return;     // raw block - nothing to parse
00096     } 
00097   
00098     while (df_RecCmn_t *cmnRec_p = m_scanner.GetNextRecord()) {
00099         // save record pointer for FRI extraction after write
00100         m_friRec.push_back(cmnRec_p);
00101     }
00102 }

Here is the call graph for this function:

Here is the caller graph for this function:

void df_FRI::BlockWritten ( UInt32_t  a_medPos  ) 

Append FRI records from last block to Disk FRI, return Split info to FSC.

Definition at line 134 of file df_fri.cpp.

References df_BlockProxyWriter::Allocate(), df_RecByteStreamStart_t::allStreamSize, df_SplitInfo::blockOffset, df_RecByteStreamStart_t::chunkOffset, df_SplitInfo::chunkOffset, df_RecFile_t::chunkSize, df_SplitInfo::chunkSize, cmn_Num2Str(), df_RecEmbeddedData_t::data, df_SplitInfo::dataType, dbg_DETAIL, df_RF_CONTINUED, df_SS_COMPLETE, df_ST_ALTDATA, df_ST_META, evt_WARNING, df_SplitInfo::fileID, df_SplitInfo::fileName, df_SplitInfo::fileSize, df_RecCmn_t::flags, FlushCurrentSplit(), hton(), df_RecByteStreamStart_t::idFile, df_RecFile_t::idFile, df_RecFile_t::idMig, df_RecFile_t::idParent, df_RecFile_t::idParentOld, ie_DF_INVSEQ, ie_FATAL_ERROR, ivd_ATTR_d, df_SplitInfo::lastSplit, log_DBG_m, log_FUNC_m, log_MARKLINE_m, log_WriteEvent(), log_WRN_m, m_blkSize, m_contBlk, m_contBSS, m_contFile, m_curSplit, m_diskFRI, m_friRec, m_medCurPos, m_recNum, m_streamName, m_streamSize, m_streamToFRI, m_streamType, df_SplitInfo::migrationID, df_BlockProxyWriter::Move(), df_RecFile_t::name, df_RecFile_t::nameOld, df_SplitInfo::noCopies, ntoh(), NULL, df_RecFile_t::numCopies, ivd_VarData_t::offset, df_SplitInfo::oldFileName, df_SplitInfo::oldOwnerID, df_SplitInfo::ownerID, rec_BSEnd_c, rec_BSStart_c, rec_EmbData_c, rec_FileEnd_c, rec_FileHdr_c, df_RecCmn_t::seqNum, ivd_VarData_t::size, df_RecCmn_t::size, size, df_StandardAttr_t::size, df_SplitInfo::splitOffset, df_SplitInfo::splitSize, df_RecByteStreamEnd_t::status, df_RecFile_t::stdAttr, df_RecByteStreamStart_t::streamName, df_RecByteStreamStart_t::streamSize, df_RecEmbeddedData_t::streamType, df_RecByteStreamEnd_t::streamType, and df_RecByteStreamStart_t::streamType.

Referenced by bea_MigrationThread::WriteBlock().

00134                                            {
00135 
00136     log_FUNC_m(BlockWritten);
00137 
00138     m_medCurPos = a_medPos;
00139     
00140     // Prevent invalid medium position to be stored to FSC and FRI
00141     if (a_medPos < 3) {
00142         log_MARKLINE_m;
00143         throw ivd_InternalError(ie_FATAL_ERROR,
00144             string("Invalid medium position: ") + cmn_Num2Str(a_medPos) );
00145     }
00146 
00147     if (m_friRec.empty()) {
00148         // no records ==> RAW block
00149         if (!m_curSplit.fileID) {
00150             throw ivd_DFError(ie_DF_INVSEQ, 0,
00151                               "No File record before RAW block");
00152         }
00153 
00154         m_curSplit.splitSize += m_blkSize; 
00155     }    
00156 
00157     for (UInt32_t i=0; i < m_friRec.size(); ++i) {
00158         bool toFRI = false;
00159 
00160         if (m_friRec[i]->type == rec_FileHdr_c) {
00161             df_RecFile_t *file_p = df_GetSpecificRec<df_RecFile_t>(m_friRec[i]);
00162 
00163             m_curSplit.dataType     = ivd_ATTR_d;
00164             m_curSplit.lastSplit    = false;        // we do not know yet
00165             m_curSplit.blockOffset  = a_medPos;
00166 
00167             m_curSplit.fileID       = static_cast<ivd_FileID_t>(ntoh(file_p->idFile));
00168             m_curSplit.migrationID  = ntoh(file_p->idMig);
00169             m_curSplit.fileSize     = ntoh(file_p->stdAttr.size);
00170             m_curSplit.chunkSize    = ntoh(file_p->chunkSize);
00171             m_curSplit.ownerID      = static_cast<ivd_FileID_t>(ntoh(file_p->idParent));
00172             m_curSplit.oldOwnerID   = static_cast<ivd_FileID_t>(ntoh(file_p->idParentOld));
00173             m_curSplit.fileName     = ((char*)m_friRec[i] +
00174                                        ntoh(file_p->name.offset));
00175             m_curSplit.oldFileName  = ((char*)m_friRec[i] +
00176                                        ntoh(file_p->nameOld.offset));
00177 
00178             m_curSplit.chunkOffset  = 0;
00179             m_curSplit.splitOffset  = 0;
00180             m_curSplit.noCopies     = ntoh(file_p->numCopies);
00181             m_curSplit.splitSize    = 0;
00182 
00183             log_DBG_m(dbg_DETAIL,
00184                 "File Start: " << m_curSplit.fileID <<
00185                 " copies: " << m_curSplit.noCopies);
00186 
00187             toFRI = true;
00188 
00189             // Copy File record to continuation block
00190             m_contFile = reinterpret_cast<df_RecCmn_t*>(m_contBlk +
00191                                                         sizeof(*m_contBlkHdr));
00192             memcpy(m_contFile, m_friRec[i], ntoh(m_friRec[i]->size));
00193             m_contFile->flags = hton(ntoh(m_contFile->flags) | df_RF_CONTINUED);
00194 
00195         }
00196         else if (m_friRec[i]->type == rec_FileEnd_c) {
00197 
00198             if (!m_curSplit.fileID) {
00199                 throw ivd_DFError(ie_DF_INVSEQ, 0,
00200                                   "No File record before FileEnd");
00201             }
00202             m_curSplit.lastSplit = true;
00203 
00204             log_DBG_m(dbg_DETAIL, "File End: " << m_curSplit.fileID);
00205 
00206             // end of file -> save split info for current file
00207             FlushCurrentSplit();
00208 
00209             toFRI = true;
00210 
00211             // Remove file record from continuation block
00212             m_contFile = 0;
00213         }
00214         else if (m_friRec[i]->type == rec_BSStart_c) {
00215             df_RecByteStreamStart_t *bss_p = df_GetSpecificRec<df_RecByteStreamStart_t>(m_friRec[i]);
00216 
00217             if (!m_curSplit.fileID) {
00218                 throw ivd_DFError(ie_DF_INVSEQ, 0,
00219                                   "No File record before BSStart");
00220             }
00221 
00222             m_curSplit.dataType     |= ntoh(bss_p->streamType);
00223             m_curSplit.chunkOffset  = ntoh(bss_p->chunkOffset);
00224 
00225             if (ntoh(m_friRec[i]->flags) & df_RF_CONTINUED) {
00226                 m_curSplit.splitOffset = ntoh(bss_p->allStreamSize);
00227                 m_curSplit.splitSize   = 0;
00228             }
00229             
00230             m_streamType = ntoh(bss_p->streamType);
00231             
00232             if (m_streamType == df_ST_META) {
00233 /* +++ Temporary fix to solve the problem 2106. Large meta-data blocks are skipped. +++ */
00234                 if (ntoh(bss_p->streamSize) > m_blkSize) {
00235                     m_streamToFRI = false;
00236                     
00237                     UInt64_t fileID = ntoh(bss_p->idFile);
00238                     const char* name = m_friRec[i]->GetVarDataNet(bss_p->streamName);
00239                     ostringstream sstr;
00240                     sstr << "Large meta-data stream skipped from FRI and FSC. " 
00241                         << "File ID= " << fileID << ", name= " << name
00242                         << " size= " << ntoh(bss_p->streamSize);
00243                     log_WriteEvent(evt_WARNING, sstr.str());
00244                 }
00245                 else {
00246 /* +++ End of temporary fix to solve the problem 2106. +++ */
00247                     m_streamToFRI = true;
00248                 }
00249             }
00250             else { // for ADS is stored only BSS and BSE, no data. see "else if (... rec_EmbData_c)"
00251                 m_streamToFRI = (m_streamType == df_ST_ALTDATA); 
00252             }
00253             
00254             m_streamName = ((char*)m_friRec[i] + ntoh(bss_p->streamName.offset));
00255             m_streamSize = ntoh(bss_p->streamSize);
00256             
00257             toFRI = m_streamToFRI;
00258 
00259             // Copy BSS record to continuation block
00260             if (!m_contFile) {
00261                 throw ivd_DFError(ie_DF_INVSEQ, 0,
00262                                   "No File record before BSStart");
00263             }
00264             m_contBSS = reinterpret_cast<df_RecCmn_t*>(m_contBlk +
00265                                                        sizeof(*m_contBlkHdr) +
00266                                                        ntoh(m_contFile->size));
00267             memcpy(m_contBSS, m_friRec[i], ntoh(m_friRec[i]->size));
00268             m_contBSS->flags = hton(ntoh(m_contBSS->flags) | df_RF_CONTINUED);
00269 
00270         }
00271         else if (m_friRec[i]->type == rec_BSEnd_c) {
00272             df_RecByteStreamEnd_t *bse_p = df_GetSpecificRec<df_RecByteStreamEnd_t>(m_friRec[i]);
00273             
00274             if (!m_curSplit.fileID) {
00275                 throw ivd_DFError(ie_DF_INVSEQ, 0,
00276                                   "No File record before BSEnd");
00277             }
00278 
00279             if (!(m_curSplit.dataType & ntoh(bse_p->streamType))) {
00280                 throw ivd_DFError(ie_DF_INVSEQ, 0,
00281                                   "No BSStart record before BSEnd");
00282             }
00283 
00284             UInt32_t st = ntoh(bse_p->streamType);
00285             log_DBG_m(dbg_DETAIL,
00286                 "BSE stream type  FileID = " << m_curSplit.fileID <<
00287                 " byte stream type = " << st <<
00288                 " data Type = " << m_curSplit.dataType <<
00289                 " BS status " << ntoh(bse_p->status));
00290 
00291             // remove stream type if data is not ready.
00292             if (ntoh(bse_p->status) != df_SS_COMPLETE) {
00293                 m_curSplit.dataType     &= ~st;
00294                 log_DBG_m(dbg_DETAIL,
00295                     "Stream is not complete. FileID = " << m_curSplit.fileID <<
00296                     " remove byte stream type = " << st <<
00297                     "  data Type = " << m_curSplit.dataType);
00298             }
00299 
00300             toFRI = m_streamToFRI;
00301 
00302             m_streamType  = 0;
00303             m_streamSize = 0;
00304             m_streamName.clear();
00305             m_streamToFRI = false;
00306             
00307             // Clear BSS record in continuation block
00308             m_contBSS = 0;
00309 
00310         }
00311         else if (m_friRec[i]->type == rec_EmbData_c) {
00312             df_RecEmbeddedData_t *eData_p = df_GetSpecificRec<df_RecEmbeddedData_t>(m_friRec[i]);
00313 
00314             if (!m_curSplit.fileID) {
00315                 throw ivd_DFError(ie_DF_INVSEQ, 0,
00316                                   "No File record before EmbData");
00317             }
00318 
00319             if (!(m_curSplit.dataType & ntoh(eData_p->streamType))) {
00320                 throw ivd_DFError(ie_DF_INVSEQ, 0,
00321                                   "No BSStart record before EmbData");
00322             }
00323 
00324             m_curSplit.splitSize += ntoh(eData_p->data.size);
00325 
00326             if (m_streamType != df_ST_ALTDATA)
00327                 toFRI = m_streamToFRI;
00328             else {
00329                 toFRI = false;
00330             }
00331 
00332         } else {
00333             log_WRN_m("Warning: No parse for this record type! Got type:" << 
00334                       string((char*)(&m_friRec[i]->type), 
00335                              sizeof(m_friRec[i]->type)));
00336         }
00337 
00338         // copy all records beside DATA stream to FRI
00339         if (toFRI) {
00340             UInt32_t recSize = ntoh(m_friRec[i]->size);
00341 
00342             UInt8_t* recBuf = m_diskFRI->Allocate(recSize);
00343             if (recBuf == NULL) {
00344                 log_WRN_m("Null FRI block. May be a problem if not at EOD of FRI.");
00345                 return;
00346             }
00347 
00348             df_RecCmn_t *friRec = reinterpret_cast<df_RecCmn_t*>(recBuf);
00349 
00350             memcpy(friRec, m_friRec[i], recSize);
00351 
00352             // update record sequence number to FRI sequence number
00353             friRec->seqNum = ntoh(++m_recNum);
00354 
00355             m_diskFRI->Move(recSize);
00356         }
00357     } // for (each friRec)
00358 }

Here is the call graph for this function:

Here is the caller graph for this function:

const vector<df_SplitInfo>& df_FRI::GetSplits (  )  const [inline]

Definition at line 855 of file df.h.

00855                                                   {
00856         return m_splits;
00857     };

void df_FRI::FlushCurrentSplit (  )  [private]

Definition at line 105 of file df_fri.cpp.

References df_BlockProxyWriter::Allocate(), df_SplitInfo::blockOffset, df_SplitInfo::dataType, df_SplitInfo::fileID, log_FUNC_m, log_WRN_m, m_curSplit, m_diskFRI, m_recNum, df_BlockProxyWriter::Move(), NULL, df_SplitInfo::splitOffset, df_SplitInfo::splitSize, and df_Packer::WriteRecFRISplitInfo().

Referenced by BlockWritten(), and MediumVolumeEnd().

00105                                {
00106 
00107     log_FUNC_m(FlushCurrentSplit);
00108 
00109     UInt32_t recSize = sizeof(df_RecCmn_t) + sizeof(df_RecFRISpInfo_t);
00110 
00111     UInt8_t* recBuf = m_diskFRI->Allocate(recSize);
00112     
00113     if (recBuf == NULL) {
00114         log_WRN_m("Null FRI block. May be a problem if not at EOD of FRI.");
00115         return;
00116     }
00117 
00118     df_Packer::WriteRecFRISplitInfo(m_curSplit.fileID, 
00119                                     m_curSplit.splitOffset,
00120                                     m_curSplit.splitSize,
00121                                     m_curSplit.dataType,
00122                                     ++m_recNum,
00123                                     m_curSplit.blockOffset,
00124                                     recBuf,
00125                                     recSize);
00126 
00127     m_diskFRI->Move(recSize);
00128 
00129     // mark that we need to get new File record (even if continued)
00130     m_curSplit.fileID = 0;
00131 }

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 857 of file df.h.

Scanner used for parsing IVD Data blocks.

Definition at line 865 of file df.h.

Referenced by BlockScan(), and MediumVolumeStart().

Definition at line 867 of file df.h.

Referenced by BlockWritten(), and MediumVolumeStart().

Definition at line 869 of file df.h.

Referenced by MediumVolumeEnd(), and MediumVolumeStart().

Definition at line 870 of file df.h.

Referenced by MediumVolumeEnd(), and MediumVolumeStart().

Disk FRI file.

Definition at line 873 of file df.h.

Referenced by MediumVolumeEnd(), and MediumVolumeStart().

Definition at line 875 of file df.h.

Referenced by MediumVolumeEnd(), and MediumVolumeStart().

Definition at line 876 of file df.h.

Referenced by BlockWritten(), MediumVolumeEnd(), and MediumVolumeStart().

Definition at line 878 of file df.h.

Referenced by BlockWritten(), FlushCurrentSplit(), MediumVolumeEnd(), and MediumVolumeStart().

Definition at line 879 of file df.h.

Referenced by BlockWritten(), and MediumVolumeEnd().

Definition at line 880 of file df.h.

Referenced by BlockWritten(), and MediumVolumeEnd().

string df_FRI::m_streamName [private]

Definition at line 881 of file df.h.

Referenced by BlockWritten(), and MediumVolumeEnd().

bool df_FRI::m_streamToFRI [private]

Definition at line 882 of file df.h.

Referenced by BlockWritten(), and MediumVolumeEnd().

vector<df_RecCmn_t*> df_FRI::m_friRec [private]

FRI records from last block (saved for BlockWritten() method).

Definition at line 885 of file df.h.

Referenced by BlockScan(), and BlockWritten().

Definition at line 887 of file df.h.

Referenced by BlockWritten(), df_FRI(), FlushCurrentSplit(), and MediumVolumeEnd().

vector<df_SplitInfo> df_FRI::m_splits [private]

Definition at line 888 of file df.h.

Continuation block buffer - used in case file spans multiple volumes.

Definition at line 891 of file df.h.

Referenced by BlockWritten(), df_FRI(), MediumVolumeStart(), and ~df_FRI().

Pointers into m_contBlk buffer (NULL if they do not exist).

Definition at line 894 of file df.h.

Referenced by df_FRI(), and MediumVolumeStart().

Definition at line 895 of file df.h.

Referenced by BlockWritten(), and MediumVolumeStart().

Definition at line 896 of file df.h.

Referenced by BlockWritten(), and MediumVolumeStart().


The documentation for this class was generated from the following files:

Generated on Mon Feb 27 19:12:17 2012 for OPENARCHIVE by  doxygen 1.5.6