| 129 | const clientID = "gopar" |
| 130 | |
| 131 | func (e *Encoder) Write(indexPath string) error { |
| 132 | mainPacket := mainPacket{ |
| 133 | sliceByteCount: e.sliceByteCount, |
| 134 | recoverySet: e.recoverySet, |
| 135 | } |
| 136 | |
| 137 | fileDescriptionPackets := make(map[fileID]fileDescriptionPacket) |
| 138 | ifscPackets := make(map[fileID]ifscPacket) |
| 139 | for fileID, info := range e.recoverySetInfos { |
| 140 | fileDescriptionPackets[fileID] = info.fileDescriptionPacket |
| 141 | ifscPackets[fileID] = info.ifscPacket |
| 142 | } |
| 143 | |
| 144 | parityFile := file{ |
| 145 | clientID: clientID, |
| 146 | mainPacket: &mainPacket, |
| 147 | fileDescriptionPackets: fileDescriptionPackets, |
| 148 | ifscPackets: ifscPackets, |
| 149 | } |
| 150 | |
| 151 | _, parityFileBytes, err := writeFile(parityFile) |
| 152 | if err != nil { |
| 153 | return err |
| 154 | } |
| 155 | |
| 156 | var base string |
| 157 | ext := path.Ext(indexPath) |
| 158 | base = indexPath[:len(indexPath)-len(ext)] |
| 159 | |
| 160 | filename := base + ".par2" |
| 161 | err = e.fileIO.WriteFile(filename, parityFileBytes) |
| 162 | e.delegate.OnIndexFileWrite(filename, len(parityFileBytes), err) |
| 163 | if err != nil { |
| 164 | return err |
| 165 | } |
| 166 | |
| 167 | volumeCount := 1 |
| 168 | for i := 0; i < e.parityShardCount; { |
| 169 | recoveryFile := parityFile |
| 170 | recoveryFile.recoveryPackets = make(map[exponent]recoveryPacket, volumeCount) |
| 171 | if i+volumeCount > e.parityShardCount { |
| 172 | volumeCount = e.parityShardCount - i |
| 173 | } |
| 174 | for j := 0; j < volumeCount; j++ { |
| 175 | recoveryFile.recoveryPackets[exponent(i+j)] = recoveryPacket{data: e.parityShards[i+j]} |
| 176 | } |
| 177 | |
| 178 | _, recoveryFileBytes, err := writeFile(recoveryFile) |
| 179 | if err != nil { |
| 180 | return err |
| 181 | } |
| 182 | |
| 183 | // TODO: Figure out how to handle when either i or |
| 184 | // volumeCount is >= 100. |
| 185 | filename := fmt.Sprintf("%s.vol%02d+%02d.par2", base, i, volumeCount) |
| 186 | err = e.fileIO.WriteFile(filename, recoveryFileBytes) |
| 187 | e.delegate.OnRecoveryFileWrite(i, volumeCount, e.parityShardCount, filename, len(recoveryFileBytes)-len(parityFileBytes), len(recoveryFileBytes), err) |
| 188 | if err != nil { |