// SetEncodedObject adds a new object to the storage. func (s *ObjectStorage) SetEncodedObject(o plumbing.EncodedObject) (plumbing.Hash, error) { if o.Type() == plumbing.OFSDeltaObject || o.Type() == plumbing.REFDeltaObject { return plumbing.ZeroHash, plumbing.ErrInvalidType } ow, err := s.dir.NewObject() if err != nil { return plumbing.ZeroHash, err } defer ow.Close() or, err := o.Reader() if err != nil { return plumbing.ZeroHash, err } defer or.Close() if err := ow.WriteHeader(o.Type(), o.Size()); err != nil { return plumbing.ZeroHash, err } if _, err := io.Copy(ow, or); err != nil { return plumbing.ZeroHash, err } return o.Hash(), nil }
// ApplyDelta writes to taget the result of applying the modification deltas in delta to base. func ApplyDelta(target, base plumbing.EncodedObject, delta []byte) error { r, err := base.Reader() if err != nil { return err } w, err := target.Writer() if err != nil { return err } src, err := ioutil.ReadAll(r) if err != nil { return err } dst := PatchDelta(src, delta) target.SetSize(int64(len(dst))) if _, err := w.Write(dst); err != nil { return err } return nil }
// GetDelta returns an offset delta that knows the way of how to transform // base object to target object func GetDelta(base, target plumbing.EncodedObject) (plumbing.EncodedObject, error) { br, err := base.Reader() if err != nil { return nil, err } tr, err := target.Reader() if err != nil { return nil, err } bb, err := ioutil.ReadAll(br) if err != nil { return nil, err } tb, err := ioutil.ReadAll(tr) if err != nil { return nil, err } db := DiffDelta(bb, tb) delta := &plumbing.MemoryObject{} _, err = delta.Write(db) if err != nil { return nil, err } delta.SetSize(int64(len(db))) delta.SetType(plumbing.OFSDeltaObject) return delta, nil }
func (s *Storage) SetEncodedObject(obj plumbing.EncodedObject) (plumbing.Hash, error) { key, err := s.buildKey(obj.Hash(), obj.Type()) if err != nil { return obj.Hash(), err } r, err := obj.Reader() if err != nil { return obj.Hash(), err } c, err := ioutil.ReadAll(r) if err != nil { return obj.Hash(), err } bins := driver.BinMap{ urlField: s.url, "hash": obj.Hash().String(), "type": obj.Type().String(), "blob": c, } err = s.client.Put(nil, key, bins) return obj.Hash(), err }
func objectEquals(a plumbing.EncodedObject, b plumbing.EncodedObject) error { ha := a.Hash() hb := b.Hash() if ha != hb { return fmt.Errorf("hashes do not match: %s != %s", ha.String(), hb.String()) } ra, err := a.Reader() if err != nil { return fmt.Errorf("can't get reader on b: %q", err) } rb, err := b.Reader() if err != nil { return fmt.Errorf("can't get reader on a: %q", err) } ca, err := ioutil.ReadAll(ra) if err != nil { return fmt.Errorf("error reading a: %q", err) } cb, err := ioutil.ReadAll(rb) if err != nil { return fmt.Errorf("error reading b: %q", err) } if hex.EncodeToString(ca) != hex.EncodeToString(cb) { return errors.New("content does not match") } return nil }
// Decode transform an plumbing.EncodedObject into a Tree struct func (t *Tree) Decode(o plumbing.EncodedObject) (err error) { if o.Type() != plumbing.TreeObject { return ErrUnsupportedObject } t.Hash = o.Hash() if o.Size() == 0 { return nil } t.Entries = nil t.m = nil reader, err := o.Reader() if err != nil { return err } defer ioutil.CheckClose(reader, &err) r := bufio.NewReader(reader) for { mode, err := r.ReadString(' ') if err != nil { if err == io.EOF { break } return err } fm, err := t.decodeFileMode(mode[:len(mode)-1]) if err != nil && err != io.EOF { return err } name, err := r.ReadString(0) if err != nil && err != io.EOF { return err } var hash plumbing.Hash if _, err = io.ReadFull(r, hash[:]); err != nil { return err } baseName := name[:len(name)-1] t.Entries = append(t.Entries, TreeEntry{ Hash: hash, Mode: fm, Name: baseName, }) } return nil }
// Decode transforms a plumbing.EncodedObject into a Tag struct. func (t *Tag) Decode(o plumbing.EncodedObject) (err error) { if o.Type() != plumbing.TagObject { return ErrUnsupportedObject } t.Hash = o.Hash() reader, err := o.Reader() if err != nil { return err } defer ioutil.CheckClose(reader, &err) r := bufio.NewReader(reader) for { line, err := r.ReadSlice('\n') if err != nil && err != io.EOF { return err } line = bytes.TrimSpace(line) if len(line) == 0 { break // Start of message } split := bytes.SplitN(line, []byte{' '}, 2) switch string(split[0]) { case "object": t.Target = plumbing.NewHash(string(split[1])) case "type": t.TargetType, err = plumbing.ParseObjectType(string(split[1])) if err != nil { return err } case "tag": t.Name = string(split[1]) case "tagger": t.Tagger.Decode(split[1]) } if err == io.EOF { return nil } } data, err := stdioutil.ReadAll(r) if err != nil { return err } t.Message = string(data) return nil }
// Decode transforms a plumbing.EncodedObject into a Commit struct. func (c *Commit) Decode(o plumbing.EncodedObject) (err error) { if o.Type() != plumbing.CommitObject { return ErrUnsupportedObject } c.Hash = o.Hash() reader, err := o.Reader() if err != nil { return err } defer ioutil.CheckClose(reader, &err) r := bufio.NewReader(reader) var message bool for { line, err := r.ReadSlice('\n') if err != nil && err != io.EOF { return err } if !message { line = bytes.TrimSpace(line) if len(line) == 0 { message = true continue } split := bytes.SplitN(line, []byte{' '}, 2) switch string(split[0]) { case "tree": c.tree = plumbing.NewHash(string(split[1])) case "parent": c.parents = append(c.parents, plumbing.NewHash(string(split[1]))) case "author": c.Author.Decode(split[1]) case "committer": c.Committer.Decode(split[1]) } } else { c.Message += string(line) } if err == io.EOF { return nil } } }