Method: PEROBS::FlatFileBlobHeader.read
- Defined in:
- lib/perobs/FlatFileBlobHeader.rb
.read(file, addr = nil, id = nil) ⇒ Object
Read the header from the given File.
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
# File 'lib/perobs/FlatFileBlobHeader.rb', line 85 def FlatFileBlobHeader::read(file, addr = nil, id = nil) # If an address was specified we expect the read to always succeed. If # no address is specified and we can't read the header we generate an # error message but it is not fatal. errors_are_fatal = !addr.nil? mode = :searching_next_header addr = file.pos unless addr buf = nil corruption_start = nil loop do buf_with_crc = nil begin file.seek(addr) buf_with_crc = file.read(LENGTH) rescue IOError => e if errors_are_fatal PEROBS.log.fatal "Cannot read blob header in flat file DB at " + "address #{addr}: #{e.}" else PEROBS.log.error "Cannot read blob header in flat file DB: " + e. return nil end end # Did we read anything? if buf_with_crc.nil? if errors_are_fatal PEROBS.log.fatal "Cannot read blob header " + "#{id ? "for ID #{id} " : ''}at address #{addr}" else if corruption_start PEROBS.log.error "Corruption found at end of blob file at " + "address #{addr}" end # We have reached the end of the file. return nil end end # Did we get the full header? if buf_with_crc.length != LENGTH msg = "Incomplete FlatFileBlobHeader: Only " + "#{buf_with_crc.length} " + "bytes of #{LENGTH} could be read " "#{id ? "for ID #{id} " : ''}at address #{addr}" if errors_are_fatal PEROBS.log.fatal msg else PEROBS.log.error msg end return nil end # Check the CRC of the header buf = buf_with_crc[0..-5] crc = buf_with_crc[-4..-1].unpack('L')[0] if (read_crc = Zlib.crc32(buf, 0)) == crc # We have found a valid header. if corruption_start PEROBS.log.error "FlatFile corruption ends at #{addr}. " + "#{addr - corruption_start} bytes skipped. Some data may " + "not be recoverable." end break else if errors_are_fatal PEROBS.log.fatal "FlatFile Header CRC mismatch at address " + "#{addr}. Header CRC is #{'%08x' % read_crc} but should be " + "#{'%08x' % crc}." else if corruption_start.nil? if errors_are_fatal PEROBS.log.fatal "FlatFile corruption found. The FlatFile " + "Header CRC mismatch at address #{addr}. Header CRC is " + "#{'%08x' % read_crc} but should be #{'%08x' % crc}." else PEROBS.log.error "FlatFile corruption found. The FlatFile " + "Header CRC mismatch at address #{addr}. Header CRC is " + "#{'%08x' % read_crc} but should be #{'%08x' % crc}. " + "Trying to find the next header." end corruption_start = addr end # The blob file is corrupted. There is no valid header at the # current position in the file. We now try to find the next valid # header by iterating over the remainder of the file advanding one # byte with each step until we hit the end of the file or find the # next valid header. addr += 1 end end end header = FlatFileBlobHeader.new(file, addr, *buf.unpack(FORMAT)) if corruption_start header.corruption_start = corruption_start end if id && header.id != id PEROBS.log.fatal "Mismatch between FlatFile index and blob file " + "found. FlatFile has entry with ID #{header.id} at address " + "#{addr}. Index has ID #{id} for this address." end return header end |