]> git.sesse.net Git - freerainbowtables/blob - Common/rt api/RTI2Reader.cpp
merged paths
[freerainbowtables] / Common / rt api / RTI2Reader.cpp
1 #include "RTI2Reader.h"
2
3 #include <math.h>
4 RTI2Header *RTI2Reader::m_pHeader = NULL;
5 RTI2Reader::RTI2Reader(string Filename)
6 {
7         //m_pIndexPos = NULL, m_pChainPos = NULL;;
8         m_pIndex = NULL;
9         m_pFile = fopen(Filename.c_str(), "rb");
10         if(m_pFile == NULL)
11         {
12                 printf("Unable to open file %s", Filename.c_str());
13                 exit(1);
14         }
15         FILE *pFileIndex = fopen(Filename.append(".index").c_str(), "rb");
16         if(pFileIndex == NULL)
17         {
18                 printf("Unable to open file %s", Filename.append(".index").c_str());
19                 exit(1);
20         }
21         m_chainPosition = 0;
22
23         unsigned int len = GetFileLen(pFileIndex);
24         fseek(pFileIndex, 0, SEEK_SET);
25
26         m_pIndex = new (nothrow) unsigned char[len];
27         if(m_pIndex == NULL) {
28                 printf("Error allocating %u MB memory for index in RTI2Reader::RTI2Reader()", len / (1024 * 1024));
29                 exit(-2);
30         }
31         if(fread(m_pIndex, 1, len, pFileIndex) != len)
32         {
33                 printf("Error while reading index file");
34                 exit(1);
35         }
36         fclose(pFileIndex);
37         m_pHeader = new RTI2Header();   
38         memcpy(m_pHeader, m_pIndex, sizeof(RTI2Header));
39         m_pHeader->m_cppos = (unsigned int*)(m_pIndex + 8);
40         m_pHeader->prefixstart = *(uint64*)(m_pIndex + 8 + (m_pHeader->rti_cplength * 4));
41         m_chainsizebytes = ceil((float)(m_pHeader->rti_startptlength + m_pHeader->rti_endptlength + m_pHeader->rti_cplength) / 8); // Get the size of each chain in bytes
42         m_indexrowsizebytes = ceil((float)m_pHeader->rti_index_numchainslength / 8);
43         // Check the filesize
44         fseek(m_pFile, 0, SEEK_END);
45         len = ftell(m_pFile);
46         fseek(m_pFile, 0, SEEK_SET);
47         if(len % m_chainsizebytes > 0)
48         {
49                 printf("Invalid filesize %u\n", len);
50                 return;
51         }
52         
53
54 }
55
56 RTI2Reader::~RTI2Reader(void)
57 {
58         if(m_pIndex != NULL) delete m_pIndex;
59         if(m_pFile != NULL) fclose(m_pFile);
60
61 }
62
63 unsigned int RTI2Reader::GetChainsLeft()
64 {
65         int len = GetFileLen(m_pFile);
66         return len / m_chainsizebytes - m_chainPosition;
67 }
68
69 int RTI2Reader::ReadChains(unsigned int &numChains, RainbowChain *pData)
70 {
71         if(strncmp(m_pHeader->header, "RTI2", 4) != 0)
72         {
73                 numChains = 0;
74                 return -1;
75         }
76         unsigned char *pNumChains = m_pIndex + (m_pHeader->rti_cplength * 4) + 16; // Pointer into the index containing info about how many numbers are in the first chain prefix
77         unsigned int i = 0;
78         unsigned int indexRow = 0; // Current offset into the index
79         unsigned int curRowPosition = 0;
80         
81         while(true) // Fast forward to current position
82         {
83                 // ALERT: Possible problem here if m_indexrowsizebytes > 1 as pNumChains is a unsigned char.
84                 unsigned int NumChainsInRow = (unsigned int)*(pNumChains + indexRow * m_indexrowsizebytes);
85                 if(m_indexrowsizebytes > 1)     { printf("Have to find a solution to this problem"); exit(2);}
86                 if(i + NumChainsInRow > m_chainPosition)
87                 {
88                         curRowPosition = m_chainPosition - i;
89                         break; // The current position is somewhere within this prefix
90                 }
91                 indexRow++;             
92                 i += NumChainsInRow;
93         }
94         
95         uint64 chainrow = 0; // Buffer to store a single read chain
96         unsigned int chainsProcessed = 0; // Number of chains processed
97
98         // ALERT: same problem with unsigned char here.
99         unsigned int NumChainsInRow = *(pNumChains + indexRow);
100         while(chainsProcessed < numChains && fread(&chainrow, 1, m_chainsizebytes, m_pFile) == m_chainsizebytes)
101         {
102                 if(curRowPosition >= NumChainsInRow)
103                 { // Skip to next index row position
104                         indexRow++;
105                         curRowPosition = 0;
106                         NumChainsInRow = *(pNumChains + indexRow);
107                 }
108                 while(NumChainsInRow == 0) // We skip forward until we hit a index with > 0 chains
109                 {
110                         indexRow++;
111                         NumChainsInRow = *(pNumChains + indexRow);
112                         curRowPosition = 0;
113                 }
114                 // Load the starting point from the data
115                 pData[chainsProcessed].nIndexS = chainrow << 64 - m_pHeader->rti_startptlength;
116                 pData[chainsProcessed].nIndexS = pData[chainsProcessed].nIndexS >> 64 - m_pHeader->rti_startptlength;
117
118                 // Load the ending point prefix 
119                 pData[chainsProcessed].nIndexE = m_pHeader->prefixstart + indexRow << m_pHeader->rti_endptlength;
120                 // Append the ending point suffix
121                 pData[chainsProcessed].nIndexE |= (chainrow & (0xFFFFFFFFFFFFFFFF >> m_pHeader->rti_cplength)) >> m_pHeader->rti_startptlength;
122                 //pData[chainsProcessed].nCheckPoint = (chainrow >> m_pHeader->rti_startptlength + m_pHeader->rti_endptlength);
123                 curRowPosition++;
124                 chainsProcessed++;
125         }
126         numChains = chainsProcessed;
127         m_chainPosition += numChains;
128         return 0;
129 }