trunc is a hint about which blob to truncate after. It may be zero. If the returned error is of type 'needsTruncatedAfterError', then the zip should be attempted to be written again, but truncating the data after the listed blob.
(ctx context.Context, trunc blob.Ref)
| 1308 | // the zip should be attempted to be written again, but truncating the |
| 1309 | // data after the listed blob. |
| 1310 | func (pk *packer) writeAZip(ctx context.Context, trunc blob.Ref) (err error) { |
| 1311 | defer func() { |
| 1312 | if e := recover(); e != nil { |
| 1313 | if v, ok := e.(error); ok && err == nil { |
| 1314 | err = v |
| 1315 | } else { |
| 1316 | panic(e) |
| 1317 | } |
| 1318 | } |
| 1319 | }() |
| 1320 | mf := Manifest{ |
| 1321 | WholeRef: pk.wholeRef, |
| 1322 | WholeSize: pk.wholeSize, |
| 1323 | WholePartIndex: len(pk.zips), |
| 1324 | } |
| 1325 | var zbuf bytes.Buffer |
| 1326 | cw := &countWriter{w: &zbuf} |
| 1327 | zw := zip.NewWriter(cw) |
| 1328 | |
| 1329 | var approxSize = zipFixedOverhead // can't use zbuf.Len because zw buffers |
| 1330 | var dataRefsWritten []blob.Ref |
| 1331 | var dataBytesWritten int64 |
| 1332 | var schemaBlobSeen = map[blob.Ref]bool{} |
| 1333 | var schemaBlobs []blob.Ref // to add after the main file |
| 1334 | |
| 1335 | baseFileName := pk.fr.FileName() |
| 1336 | if strings.Contains(baseFileName, "/") || strings.Contains(baseFileName, "\\") { |
| 1337 | return fmt.Errorf("File schema blob %v filename had a slash in it: %q", pk.fr.SchemaBlobRef(), baseFileName) |
| 1338 | } |
| 1339 | fh := &zip.FileHeader{ |
| 1340 | Name: baseFileName, |
| 1341 | Method: zip.Store, // uncompressed |
| 1342 | Modified: pk.fr.ModTime(), |
| 1343 | } |
| 1344 | fh.SetMode(0644) |
| 1345 | fw, err := zw.CreateHeader(fh) |
| 1346 | check(err) |
| 1347 | check(zw.Flush()) |
| 1348 | dataStart := cw.n |
| 1349 | approxSize += zipPerEntryOverhead // for the first FileHeader w/ the data |
| 1350 | |
| 1351 | zipMax := pk.s.maxZipBlobSize() |
| 1352 | chunks := pk.chunksRemain |
| 1353 | chunkWholeHash := blob.NewHash() |
| 1354 | for len(chunks) > 0 { |
| 1355 | dr := chunks[0] // the next chunk to maybe write |
| 1356 | |
| 1357 | if trunc.Valid() && trunc == dr { |
| 1358 | if approxSize == 0 { |
| 1359 | return errors.New("first blob is too large to pack, once you add the zip overhead") |
| 1360 | } |
| 1361 | break |
| 1362 | } |
| 1363 | |
| 1364 | schemaBlobsSave := schemaBlobs |
| 1365 | for _, parent := range pk.schemaParent[dr] { |
| 1366 | if !schemaBlobSeen[parent] { |
| 1367 | schemaBlobSeen[parent] = true |
no test coverage detected