github.com/sagernet/gvisor@v0.0.0-20240428053021-e691de28565f/pkg/state/decode.go (about) 1 // Copyright 2018 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package state 16 17 import ( 18 "bytes" 19 "context" 20 "fmt" 21 "io" 22 "math" 23 "reflect" 24 25 "github.com/sagernet/gvisor/pkg/state/wire" 26 ) 27 28 // internalCallback is a interface called on object completion. 29 // 30 // There are two implementations: objectDecodeState & userCallback. 31 type internalCallback interface { 32 // source returns the dependent object. May be nil. 33 source() *objectDecodeState 34 35 // callbackRun executes the callback. 36 callbackRun() 37 } 38 39 // userCallback is an implementation of internalCallback. 40 type userCallback func() 41 42 // source implements internalCallback.source. 43 func (userCallback) source() *objectDecodeState { 44 return nil 45 } 46 47 // callbackRun implements internalCallback.callbackRun. 48 func (uc userCallback) callbackRun() { 49 uc() 50 } 51 52 // objectDecodeState represents an object that may be in the process of being 53 // decoded. Specifically, it represents either a decoded object, or an an 54 // interest in a future object that will be decoded. When that interest is 55 // registered (via register), the storage for the object will be created, but 56 // it will not be decoded until the object is encountered in the stream. 57 type objectDecodeState struct { 58 // id is the id for this object. 59 id objectID 60 61 // typ is the id for this typeID. This may be zero if this is not a 62 // type-registered structure. 63 typ typeID 64 65 // obj is the object. This may or may not be valid yet, depending on 66 // whether complete returns true. However, regardless of whether the 67 // object is valid, obj contains a final storage location for the 68 // object. This is immutable. 69 // 70 // Note that this must be addressable (obj.Addr() must not panic). 71 // 72 // The obj passed to the decode methods below will equal this obj only 73 // in the case of decoding the top-level object. However, the passed 74 // obj may represent individual fields, elements of a slice, etc. that 75 // are effectively embedded within the reflect.Value below but with 76 // distinct types. 77 obj reflect.Value 78 79 // blockedBy is the number of dependencies this object has. 80 blockedBy int 81 82 // callbacksInline is inline storage for callbacks. 83 callbacksInline [2]internalCallback 84 85 // callbacks is a set of callbacks to execute on load. 86 callbacks []internalCallback 87 88 completeEntry 89 } 90 91 // addCallback adds a callback to the objectDecodeState. 92 func (ods *objectDecodeState) addCallback(ic internalCallback) { 93 if ods.callbacks == nil { 94 ods.callbacks = ods.callbacksInline[:0] 95 } 96 ods.callbacks = append(ods.callbacks, ic) 97 } 98 99 // findCycleFor returns when the given object is found in the blocking set. 100 func (ods *objectDecodeState) findCycleFor(target *objectDecodeState) []*objectDecodeState { 101 for _, ic := range ods.callbacks { 102 other := ic.source() 103 if other != nil && other == target { 104 return []*objectDecodeState{target} 105 } else if childList := other.findCycleFor(target); childList != nil { 106 return append(childList, other) 107 } 108 } 109 110 // This should not occur. 111 Failf("no deadlock found?") 112 panic("unreachable") 113 } 114 115 // findCycle finds a dependency cycle. 116 func (ods *objectDecodeState) findCycle() []*objectDecodeState { 117 return append(ods.findCycleFor(ods), ods) 118 } 119 120 // source implements internalCallback.source. 121 func (ods *objectDecodeState) source() *objectDecodeState { 122 return ods 123 } 124 125 // callbackRun implements internalCallback.callbackRun. 126 func (ods *objectDecodeState) callbackRun() { 127 ods.blockedBy-- 128 } 129 130 // decodeState is a graph of objects in the process of being decoded. 131 // 132 // The decode process involves loading the breadth-first graph generated by 133 // encode. This graph is read in it's entirety, ensuring that all object 134 // storage is complete. 135 // 136 // As the graph is being serialized, a set of completion callbacks are 137 // executed. These completion callbacks should form a set of acyclic subgraphs 138 // over the original one. After decoding is complete, the objects are scanned 139 // to ensure that all callbacks are executed, otherwise the callback graph was 140 // not acyclic. 141 type decodeState struct { 142 // ctx is the decode context. 143 ctx context.Context 144 145 // r is the input stream. 146 r io.Reader 147 148 // types is the type database. 149 types typeDecodeDatabase 150 151 // objectByID is the set of objects in progress. 152 objectsByID []*objectDecodeState 153 154 // deferred are objects that have been read, by no interest has been 155 // registered yet. These will be decoded once interest in registered. 156 deferred map[objectID]wire.Object 157 158 // pending is the set of objects that are not yet complete. 159 pending completeList 160 161 // stats tracks time data. 162 stats Stats 163 } 164 165 // lookup looks up an object in decodeState or returns nil if no such object 166 // has been previously registered. 167 func (ds *decodeState) lookup(id objectID) *objectDecodeState { 168 if len(ds.objectsByID) < int(id) { 169 return nil 170 } 171 return ds.objectsByID[id-1] 172 } 173 174 // checkComplete checks for completion. 175 func (ds *decodeState) checkComplete(ods *objectDecodeState) bool { 176 // Still blocked? 177 if ods.blockedBy > 0 { 178 return false 179 } 180 181 // Track stats if relevant. 182 if ods.callbacks != nil && ods.typ != 0 { 183 ds.stats.start(ods.typ) 184 defer ds.stats.done() 185 } 186 187 // Fire all callbacks. 188 for _, ic := range ods.callbacks { 189 ic.callbackRun() 190 } 191 192 // Mark completed. 193 cbs := ods.callbacks 194 ods.callbacks = nil 195 ds.pending.Remove(ods) 196 197 // Recursively check others. 198 for _, ic := range cbs { 199 if other := ic.source(); other != nil && other.blockedBy == 0 { 200 ds.checkComplete(other) 201 } 202 } 203 204 return true // All set. 205 } 206 207 // wait registers a dependency on an object. 208 // 209 // As a special case, we always allow _useable_ references back to the first 210 // decoding object because it may have fields that are already decoded. We also 211 // allow trivial self reference, since they can be handled internally. 212 func (ds *decodeState) wait(waiter *objectDecodeState, id objectID, callback func()) { 213 switch id { 214 case waiter.id: 215 // Trivial self reference. 216 fallthrough 217 case 1: 218 // Root object; see above. 219 if callback != nil { 220 callback() 221 } 222 return 223 } 224 225 // Mark as blocked. 226 waiter.blockedBy++ 227 228 // No nil can be returned here. 229 other := ds.lookup(id) 230 if callback != nil { 231 // Add the additional user callback. 232 other.addCallback(userCallback(callback)) 233 } 234 235 // Mark waiter as unblocked. 236 other.addCallback(waiter) 237 } 238 239 // waitObject notes a blocking relationship. 240 func (ds *decodeState) waitObject(ods *objectDecodeState, encoded wire.Object, callback func()) { 241 if rv, ok := encoded.(*wire.Ref); ok && rv.Root != 0 { 242 // Refs can encode pointers and maps. 243 ds.wait(ods, objectID(rv.Root), callback) 244 } else if sv, ok := encoded.(*wire.Slice); ok && sv.Ref.Root != 0 { 245 // See decodeObject; we need to wait for the array (if non-nil). 246 ds.wait(ods, objectID(sv.Ref.Root), callback) 247 } else if iv, ok := encoded.(*wire.Interface); ok { 248 // It's an interface (wait recursively). 249 ds.waitObject(ods, iv.Value, callback) 250 } else if callback != nil { 251 // Nothing to wait for: execute the callback immediately. 252 callback() 253 } 254 } 255 256 // walkChild returns a child object from obj, given an accessor path. This is 257 // the decode-side equivalent to traverse in encode.go. 258 // 259 // For the purposes of this function, a child object is either a field within a 260 // struct or an array element, with one such indirection per element in 261 // path. The returned value may be an unexported field, so it may not be 262 // directly assignable. See decode_unsafe.go. 263 func walkChild(path []wire.Dot, obj reflect.Value) reflect.Value { 264 // See wire.Ref.Dots. The path here is specified in reverse order. 265 for i := len(path) - 1; i >= 0; i-- { 266 switch pc := path[i].(type) { 267 case *wire.FieldName: // Must be a pointer. 268 if obj.Kind() != reflect.Struct { 269 Failf("next component in child path is a field name, but the current object is not a struct. Path: %v, current obj: %#v", path, obj) 270 } 271 obj = obj.FieldByName(string(*pc)) 272 case wire.Index: // Embedded. 273 if obj.Kind() != reflect.Array { 274 Failf("next component in child path is an array index, but the current object is not an array. Path: %v, current obj: %#v", path, obj) 275 } 276 obj = obj.Index(int(pc)) 277 default: 278 panic("unreachable: switch should be exhaustive") 279 } 280 } 281 return obj 282 } 283 284 // register registers a decode with a type. 285 // 286 // This type is only used to instantiate a new object if it has not been 287 // registered previously. This depends on the type provided if none is 288 // available in the object itself. 289 func (ds *decodeState) register(r *wire.Ref, typ reflect.Type) reflect.Value { 290 // Grow the objectsByID slice. 291 id := objectID(r.Root) 292 if len(ds.objectsByID) < int(id) { 293 ds.objectsByID = append(ds.objectsByID, make([]*objectDecodeState, int(id)-len(ds.objectsByID))...) 294 } 295 296 // Does this object already exist? 297 ods := ds.objectsByID[id-1] 298 if ods != nil { 299 return walkChild(r.Dots, ods.obj) 300 } 301 302 // Create the object. 303 if len(r.Dots) != 0 { 304 typ = ds.findType(r.Type) 305 } 306 v := reflect.New(typ) 307 ods = &objectDecodeState{ 308 id: id, 309 obj: v.Elem(), 310 } 311 ds.objectsByID[id-1] = ods 312 ds.pending.PushBack(ods) 313 314 // Process any deferred objects & callbacks. 315 if encoded, ok := ds.deferred[id]; ok { 316 delete(ds.deferred, id) 317 ds.decodeObject(ods, ods.obj, encoded) 318 } 319 320 return walkChild(r.Dots, ods.obj) 321 } 322 323 // objectDecoder is for decoding structs. 324 type objectDecoder struct { 325 // ds is decodeState. 326 ds *decodeState 327 328 // ods is current object being decoded. 329 ods *objectDecodeState 330 331 // reconciledTypeEntry is the reconciled type information. 332 rte *reconciledTypeEntry 333 334 // encoded is the encoded object state. 335 encoded *wire.Struct 336 } 337 338 // load is helper for the public methods on Source. 339 func (od *objectDecoder) load(slot int, objPtr reflect.Value, wait bool, fn func()) { 340 // Note that we have reconciled the type and may remap the fields here 341 // to match what's expected by the decoder. The "slot" parameter here 342 // is in terms of the local type, where the fields in the encoded 343 // object are in terms of the wire object's type, which might be in a 344 // different order (but will have the same fields). 345 v := *od.encoded.Field(od.rte.FieldOrder[slot]) 346 od.ds.decodeObject(od.ods, objPtr.Elem(), v) 347 if wait { 348 // Mark this individual object a blocker. 349 od.ds.waitObject(od.ods, v, fn) 350 } 351 } 352 353 // aterLoad implements Source.AfterLoad. 354 func (od *objectDecoder) afterLoad(fn func()) { 355 // Queue the local callback; this will execute when all of the above 356 // data dependencies have been cleared. 357 od.ods.addCallback(userCallback(fn)) 358 } 359 360 // decodeStruct decodes a struct value. 361 func (ds *decodeState) decodeStruct(ods *objectDecodeState, obj reflect.Value, encoded *wire.Struct) { 362 if encoded.TypeID == 0 { 363 // Allow anonymous empty structs, but only if the encoded 364 // object also has no fields. 365 if encoded.Fields() == 0 && obj.NumField() == 0 { 366 return 367 } 368 369 // Propagate an error. 370 Failf("empty struct on wire %#v has field mismatch with type %q", encoded, obj.Type().Name()) 371 } 372 373 // Lookup the object type. 374 rte := ds.types.Lookup(typeID(encoded.TypeID), obj.Type()) 375 ods.typ = typeID(encoded.TypeID) 376 377 // Invoke the loader. 378 od := objectDecoder{ 379 ds: ds, 380 ods: ods, 381 rte: rte, 382 encoded: encoded, 383 } 384 ds.stats.start(ods.typ) 385 defer ds.stats.done() 386 if sl, ok := obj.Addr().Interface().(SaverLoader); ok { 387 // Note: may be a registered empty struct which does not 388 // implement the saver/loader interfaces. 389 sl.StateLoad(ds.ctx, Source{internal: od}) 390 } 391 } 392 393 // decodeMap decodes a map value. 394 func (ds *decodeState) decodeMap(ods *objectDecodeState, obj reflect.Value, encoded *wire.Map) { 395 if obj.IsNil() { 396 // See pointerTo. 397 obj.Set(reflect.MakeMap(obj.Type())) 398 } 399 for i := 0; i < len(encoded.Keys); i++ { 400 // Decode the objects. 401 kv := reflect.New(obj.Type().Key()).Elem() 402 vv := reflect.New(obj.Type().Elem()).Elem() 403 ds.decodeObject(ods, kv, encoded.Keys[i]) 404 ds.decodeObject(ods, vv, encoded.Values[i]) 405 ds.waitObject(ods, encoded.Keys[i], nil) 406 ds.waitObject(ods, encoded.Values[i], nil) 407 408 // Set in the map. 409 obj.SetMapIndex(kv, vv) 410 } 411 } 412 413 // decodeArray decodes an array value. 414 func (ds *decodeState) decodeArray(ods *objectDecodeState, obj reflect.Value, encoded *wire.Array) { 415 if len(encoded.Contents) != obj.Len() { 416 Failf("mismatching array length expect=%d, actual=%d", obj.Len(), len(encoded.Contents)) 417 } 418 // Decode the contents into the array. 419 for i := 0; i < len(encoded.Contents); i++ { 420 ds.decodeObject(ods, obj.Index(i), encoded.Contents[i]) 421 ds.waitObject(ods, encoded.Contents[i], nil) 422 } 423 } 424 425 // findType finds the type for the given wire.TypeSpecs. 426 func (ds *decodeState) findType(t wire.TypeSpec) reflect.Type { 427 switch x := t.(type) { 428 case wire.TypeID: 429 typ := ds.types.LookupType(typeID(x)) 430 rte := ds.types.Lookup(typeID(x), typ) 431 return rte.LocalType 432 case *wire.TypeSpecPointer: 433 return reflect.PtrTo(ds.findType(x.Type)) 434 case *wire.TypeSpecArray: 435 return reflect.ArrayOf(int(x.Count), ds.findType(x.Type)) 436 case *wire.TypeSpecSlice: 437 return reflect.SliceOf(ds.findType(x.Type)) 438 case *wire.TypeSpecMap: 439 return reflect.MapOf(ds.findType(x.Key), ds.findType(x.Value)) 440 default: 441 // Should not happen. 442 Failf("unknown type %#v", t) 443 } 444 panic("unreachable") 445 } 446 447 // decodeInterface decodes an interface value. 448 func (ds *decodeState) decodeInterface(ods *objectDecodeState, obj reflect.Value, encoded *wire.Interface) { 449 if _, ok := encoded.Type.(wire.TypeSpecNil); ok { 450 // Special case; the nil object. Just decode directly, which 451 // will read nil from the wire (if encoded correctly). 452 ds.decodeObject(ods, obj, encoded.Value) 453 return 454 } 455 456 // We now need to resolve the actual type. 457 typ := ds.findType(encoded.Type) 458 459 // We need to imbue type information here, then we can proceed to 460 // decode normally. In order to avoid issues with setting value-types, 461 // we create a new non-interface version of this object. We will then 462 // set the interface object to be equal to whatever we decode. 463 origObj := obj 464 obj = reflect.New(typ).Elem() 465 defer origObj.Set(obj) 466 467 // With the object now having sufficient type information to actually 468 // have Set called on it, we can proceed to decode the value. 469 ds.decodeObject(ods, obj, encoded.Value) 470 } 471 472 // isFloatEq determines if x and y represent the same value. 473 func isFloatEq(x float64, y float64) bool { 474 switch { 475 case math.IsNaN(x): 476 return math.IsNaN(y) 477 case math.IsInf(x, 1): 478 return math.IsInf(y, 1) 479 case math.IsInf(x, -1): 480 return math.IsInf(y, -1) 481 default: 482 return x == y 483 } 484 } 485 486 // isComplexEq determines if x and y represent the same value. 487 func isComplexEq(x complex128, y complex128) bool { 488 return isFloatEq(real(x), real(y)) && isFloatEq(imag(x), imag(y)) 489 } 490 491 // decodeObject decodes a object value. 492 func (ds *decodeState) decodeObject(ods *objectDecodeState, obj reflect.Value, encoded wire.Object) { 493 switch x := encoded.(type) { 494 case wire.Nil: // Fast path: first. 495 // We leave obj alone here. That's because if obj represents an 496 // interface, it may have been imbued with type information in 497 // decodeInterface, and we don't want to destroy that. 498 case *wire.Ref: 499 // Nil pointers may be encoded in a "forceValue" context. For 500 // those we just leave it alone as the value will already be 501 // correct (nil). 502 if id := objectID(x.Root); id == 0 { 503 return 504 } 505 506 // Note that if this is a map type, we go through a level of 507 // indirection to allow for map aliasing. 508 if obj.Kind() == reflect.Map { 509 v := ds.register(x, obj.Type()) 510 if v.IsNil() { 511 // Note that we don't want to clobber the map 512 // if has already been decoded by decodeMap. We 513 // just make it so that we have a consistent 514 // reference when that eventually does happen. 515 v.Set(reflect.MakeMap(v.Type())) 516 } 517 obj.Set(v) 518 return 519 } 520 521 // Normal assignment: authoritative only if no dots. 522 v := ds.register(x, obj.Type().Elem()) 523 obj.Set(reflectValueRWAddr(v)) 524 case wire.Bool: 525 obj.SetBool(bool(x)) 526 case wire.Int: 527 obj.SetInt(int64(x)) 528 if obj.Int() != int64(x) { 529 Failf("signed integer truncated from %v to %v", int64(x), obj.Int()) 530 } 531 case wire.Uint: 532 obj.SetUint(uint64(x)) 533 if obj.Uint() != uint64(x) { 534 Failf("unsigned integer truncated from %v to %v", uint64(x), obj.Uint()) 535 } 536 case wire.Float32: 537 obj.SetFloat(float64(x)) 538 case wire.Float64: 539 obj.SetFloat(float64(x)) 540 if !isFloatEq(obj.Float(), float64(x)) { 541 Failf("floating point number truncated from %v to %v", float64(x), obj.Float()) 542 } 543 case *wire.Complex64: 544 obj.SetComplex(complex128(*x)) 545 case *wire.Complex128: 546 obj.SetComplex(complex128(*x)) 547 if !isComplexEq(obj.Complex(), complex128(*x)) { 548 Failf("complex number truncated from %v to %v", complex128(*x), obj.Complex()) 549 } 550 case *wire.String: 551 obj.SetString(string(*x)) 552 case *wire.Slice: 553 // See *wire.Ref above; same applies. 554 if id := objectID(x.Ref.Root); id == 0 { 555 return 556 } 557 // Note that it's fine to slice the array here and assume that 558 // contents will still be filled in later on. 559 typ := reflect.ArrayOf(int(x.Capacity), obj.Type().Elem()) // The object type. 560 v := ds.register(&x.Ref, typ) 561 obj.Set(reflectValueRWSlice3(v, 0, int(x.Length), int(x.Capacity))) 562 case *wire.Array: 563 ds.decodeArray(ods, obj, x) 564 case *wire.Struct: 565 ds.decodeStruct(ods, obj, x) 566 case *wire.Map: 567 ds.decodeMap(ods, obj, x) 568 case *wire.Interface: 569 ds.decodeInterface(ods, obj, x) 570 default: 571 // Should not happen, not propagated as an error. 572 Failf("unknown object %#v for %q", encoded, obj.Type().Name()) 573 } 574 } 575 576 // Load deserializes the object graph rooted at obj. 577 // 578 // This function may panic and should be run in safely(). 579 func (ds *decodeState) Load(obj reflect.Value) { 580 ds.stats.init() 581 defer ds.stats.fini(func(id typeID) string { 582 return ds.types.LookupName(id) 583 }) 584 585 // Create the root object. 586 rootOds := &objectDecodeState{ 587 id: 1, 588 obj: obj, 589 } 590 ds.objectsByID = append(ds.objectsByID, rootOds) 591 ds.pending.PushBack(rootOds) 592 593 // Read the number of objects. 594 numObjects, object, err := ReadHeader(ds.r) 595 if err != nil { 596 Failf("header error: %w", err) 597 } 598 if !object { 599 Failf("object missing") 600 } 601 602 // Decode all objects. 603 var ( 604 encoded wire.Object 605 ods *objectDecodeState 606 id objectID 607 tid = typeID(1) 608 ) 609 if err := safely(func() { 610 // Decode all objects in the stream. 611 // 612 // Note that the structure of this decoding loop should match the raw 613 // decoding loop in state/pretty/pretty.printer.printStream(). 614 for i := uint64(0); i < numObjects; { 615 // Unmarshal either a type object or object ID. 616 encoded = wire.Load(ds.r) 617 switch we := encoded.(type) { 618 case *wire.Type: 619 ds.types.Register(we) 620 tid++ 621 encoded = nil 622 continue 623 case wire.Uint: 624 id = objectID(we) 625 i++ 626 // Unmarshal and resolve the actual object. 627 encoded = wire.Load(ds.r) 628 ods = ds.lookup(id) 629 if ods != nil { 630 // Decode the object. 631 ds.decodeObject(ods, ods.obj, encoded) 632 } else { 633 // If an object hasn't had interest registered 634 // previously or isn't yet valid, we deferred 635 // decoding until interest is registered. 636 ds.deferred[id] = encoded 637 } 638 // For error handling. 639 ods = nil 640 encoded = nil 641 default: 642 Failf("wanted type or object ID, got %T", encoded) 643 } 644 } 645 }); err != nil { 646 // Include as much information as we can, taking into account 647 // the possible state transitions above. 648 if ods != nil { 649 Failf("error decoding object ID %d (%T) from %#v: %w", id, ods.obj.Interface(), encoded, err) 650 } else if encoded != nil { 651 Failf("error decoding from %#v: %w", encoded, err) 652 } else { 653 Failf("general decoding error: %w", err) 654 } 655 } 656 657 // Check if we have any deferred objects. 658 numDeferred := 0 659 for id, encoded := range ds.deferred { 660 numDeferred++ 661 if s, ok := encoded.(*wire.Struct); ok && s.TypeID != 0 { 662 typ := ds.types.LookupType(typeID(s.TypeID)) 663 Failf("unused deferred object: ID %d, type %v", id, typ) 664 } else { 665 Failf("unused deferred object: ID %d, %#v", id, encoded) 666 } 667 } 668 if numDeferred != 0 { 669 Failf("still had %d deferred objects", numDeferred) 670 } 671 672 // Scan and fire all callbacks. We iterate over the list of incomplete 673 // objects until all have been finished. We stop iterating if no 674 // objects become complete (there is a dependency cycle). 675 // 676 // Note that we iterate backwards here, because there will be a strong 677 // tendendcy for blocking relationships to go from earlier objects to 678 // later (deeper) objects in the graph. This will reduce the number of 679 // iterations required to finish all objects. 680 if err := safely(func() { 681 for ds.pending.Back() != nil { 682 thisCycle := false 683 for ods = ds.pending.Back(); ods != nil; { 684 if ds.checkComplete(ods) { 685 thisCycle = true 686 break 687 } 688 ods = ods.Prev() 689 } 690 if !thisCycle { 691 break 692 } 693 } 694 }); err != nil { 695 Failf("error executing callbacks: %w\nfor object %#v", err, ods.obj.Interface()) 696 } 697 698 // Check if we have any remaining dependency cycles. If there are any 699 // objects left in the pending list, then it must be due to a cycle. 700 if ods := ds.pending.Front(); ods != nil { 701 // This must be the result of a dependency cycle. 702 cycle := ods.findCycle() 703 var buf bytes.Buffer 704 buf.WriteString("dependency cycle: {") 705 for i, cycleOS := range cycle { 706 if i > 0 { 707 buf.WriteString(" => ") 708 } 709 fmt.Fprintf(&buf, "%q", cycleOS.obj.Type()) 710 } 711 buf.WriteString("}") 712 Failf("incomplete graph: %s", string(buf.Bytes())) 713 } 714 } 715 716 // ReadHeader reads an object header. 717 // 718 // Each object written to the statefile is prefixed with a header. See 719 // WriteHeader for more information; these functions are exported to allow 720 // non-state writes to the file to play nice with debugging tools. 721 func ReadHeader(r io.Reader) (length uint64, object bool, err error) { 722 // Read the header. 723 err = safely(func() { 724 length = wire.LoadUint(r) 725 }) 726 if err != nil { 727 // On the header, pass raw I/O errors. 728 if sErr, ok := err.(*ErrState); ok { 729 return 0, false, sErr.Unwrap() 730 } 731 } 732 733 // Decode whether the object is valid. 734 object = length&objectFlag != 0 735 length &^= objectFlag 736 return 737 }