(ЕТ: это в 0.3.2)
В main.h мы имеем:
Код: (CBlock :: WriteToDisk)
BOOL WriteToDisk (BOOL fWriteTransactions, неподписанных INT& nFileRet, беззнаковое целочисленное значение& nBlockPosRet)
// Открыть файл истории для добавления
CAutoFile fileout = AppendBlockFile (nFileRet);
если (! fileout)
возвращать ошибку ("CBlock :: WriteToDisk (): AppendBlockFile не удалось");
если (! fWriteTransactions)
fileout.nType
// Открыть файл истории для добавления
CAutoFile fileout = AppendBlockFile (nFileRet);
если (! fileout)
возвращать ошибку ("CBlock :: WriteToDisk (): AppendBlockFile не удалось");
если (! fWriteTransactions)
fileout.nType
а также
Код: (CBlock :: ReadFromDisk)
BOOL ReadFromDisk (неподписанных INT nFile неподписанные INT nBlockPos, BOOL fReadTransactions = истина)
= SER_BLOCKHEADERONLY;
// Читает блок
filein >> *это;
// Проверка заголовка
если (CBigNum (). SetCompact (Nbits) > bnProofOfWorkLimit)
возвращать ошибку ("CBlock :: ReadFromDisk (): Nbits ошибки в заголовке блока");
если (GetHash () > CBigNum (). SetCompact (Nbits) .getuint256 ())
возвращать ошибку ("CBlock :: ReadFromDisk (): GetHash () ошибки в заголовке блока");
возвращает истину;
= SER_BLOCKHEADERONLY;
// Читает блок
filein >> *это;
// Проверка заголовка
если (CBigNum (). SetCompact (Nbits) > bnProofOfWorkLimit)
возвращать ошибку ("CBlock :: ReadFromDisk (): Nbits ошибки в заголовке блока");
если (GetHash () > CBigNum (). SetCompact (Nbits) .getuint256 ())
возвращать ошибку ("CBlock :: ReadFromDisk (): GetHash () ошибки в заголовке блока");
возвращает истину;
FLATDATA определяется в serialize.h следующим образом:
Код: (FLATDATA)
//
// Wrapper для сериализации массивов и POD
// Там умный шаблон способ сделать массивы сериализации нормально, но MSVC6 не поддерживает
//
#define FLATDATA (объект) REF (CFlatData ((символ *)&(Объект), (символ *)&(OBJ) + SizeOf (OBJ)))
класс CFlatData
{
защищенный:
символ * pbegin;
символ * ПЭНД;
общественности:
CFlatData (недействительный * pbeginIn, недействительный * pendIn): pbegin ((символ *) pbeginIn), ПЭНД ((символ *) pendIn) {}
символ * начать () {возвращение pbegin; }
Const символ * начинается () сопзЬ {возвращение pbegin; }
символ * конец () {вернуться PEND; }
Const символ * конец () сопзЬ {вернуть PEND; }
беззнаковое INT GetSerializeSize (INT, INT = 0) Const
{
вернуться PEND - pbegin;
}
шаблон<имяТипа поток>
аннулированию Serialize (поток& с, INT, INT = 0) Const
{
s.write (pbegin, ПЭНД - pbegin);
}
шаблон<имяТипа поток>
аннулированию десериализируются (поток& с, INT, INT = 0)
{
s.read (pbegin, ПЭНД - pbegin);
}
};
// Wrapper для сериализации массивов и POD
// Там умный шаблон способ сделать массивы сериализации нормально, но MSVC6 не поддерживает
//
#define FLATDATA (объект) REF (CFlatData ((символ *)&(Объект), (символ *)&(OBJ) + SizeOf (OBJ)))
класс CFlatData
{
защищенный:
символ * pbegin;
символ * ПЭНД;
общественности:
CFlatData (недействительный * pbeginIn, недействительный * pendIn): pbegin ((символ *) pbeginIn), ПЭНД ((символ *) pendIn) {}
символ * начать () {возвращение pbegin; }
Const символ * начинается () сопзЬ {возвращение pbegin; }
символ * конец () {вернуться PEND; }
Const символ * конец () сопзЬ {вернуть PEND; }
беззнаковое INT GetSerializeSize (INT, INT = 0) Const
{
вернуться PEND - pbegin;
}
шаблон<имяТипа поток>
аннулированию Serialize (поток& с, INT, INT = 0) Const
{
s.write (pbegin, ПЭНД - pbegin);
}
шаблон<имяТипа поток>
аннулированию десериализируются (поток& с, INT, INT = 0)
{
s.read (pbegin, ПЭНД - pbegin);
}
};
Теперь - и я прошу прощения, если я читаю это неправильно, это немного более продвинутый C код / C ++, чем я привык - как я понимаю, вызов FLATDATA интерпретирует исходные байты объекта CBlock как массив ( поток ??) символов. Метод CBlock :: WriteToDisk пишет постоянный 4-байтовый заголовок сообщения (0xf9, 0xbe, 0xb4, 0xd9), размер объекта CBlock в байтах, а затем FLATDATA из CBlock это писать на диск - который только сырье байтов объекта CBlock. Таким образом, после того, как заголовок, данные, записанные в файле байт-в-байт такой же, как объект CBlock, представленного в памяти. Кроме того, если я правильно читать, CBlock :: ReadFromFile копирует эти байты непосредственно в пространство, выделенное для объекта CBlock в памяти, чтобы заново создать блок. Это верно?
Связанный с этим вопрос - я нахожусь под впечатлением, что точный способ экземпляр C ++ класс представляется внутренне не гарантирован по стандартам; компиляции программы с разными компиляторами или разными флагами оптимизации можно изменить порядок, в котором переменные-члены хранятся в памяти, и некоторые компиляторы режим отладки даже добавить несколько байтов между переменными-членами, чтобы сделать осмотр памяти проще. Я не уверен по этому поводу, это просто то, что я взял и никогда серьезно не подвергается сомнению.