// hashCore hashes a SectionReader using the ImoHash parameters. func (imo *ImoHash) hashCore(f *io.SectionReader) [Size]byte { var result [Size]byte imo.hasher.Reset() if f.Size() < int64(imo.sampleThreshold) || imo.sampleSize < 1 { buffer := make([]byte, f.Size()) f.Read(buffer) imo.hasher.Write(buffer) } else { buffer := make([]byte, imo.sampleSize) f.Read(buffer) imo.hasher.Write(buffer) f.Seek(f.Size()/2, 0) f.Read(buffer) imo.hasher.Write(buffer) f.Seek(int64(-imo.sampleSize), 2) f.Read(buffer) imo.hasher.Write(buffer) } hash := imo.hasher.Sum(nil) binary.PutUvarint(hash, uint64(f.Size())) copy(result[:], hash) return result }
func readStringPool(sr *io.SectionReader) (*ResStringPool, error) { sp := new(ResStringPool) if err := binary.Read(sr, binary.LittleEndian, &sp.Header); err != nil { return nil, err } stringStarts := make([]uint32, sp.Header.StringCount) if err := binary.Read(sr, binary.LittleEndian, stringStarts); err != nil { return nil, err } styleStarts := make([]uint32, sp.Header.StyleCount) if err := binary.Read(sr, binary.LittleEndian, styleStarts); err != nil { return nil, err } sp.Strings = make([]string, sp.Header.StringCount) for i, start := range stringStarts { var str string var err error sr.Seek(int64(sp.Header.StringStart+start), os.SEEK_SET) if (sp.Header.Flags & UTF8_FLAG) == 0 { str, err = readUTF16(sr) } else { str, err = readUTF8(sr) } if err != nil { return nil, err } sp.Strings[i] = str } sp.Styles = make([]string, sp.Header.StyleCount) for i, start := range styleStarts { var str string var err error sr.Seek(int64(sp.Header.StylesStart+start), os.SEEK_SET) if (sp.Header.Flags & UTF8_FLAG) == 0 { str, err = readUTF16(sr) } else { str, err = readUTF8(sr) } if err != nil { return nil, err } sp.Styles[i] = str } return sp, nil }
//InflateZlib unbuffered io func InflateZlib(r *io.SectionReader, len int) (bs []byte, err error) { var out bytes.Buffer br := bufio.NewReader(r) zr, err := zlib.NewReader(br) if err != nil { return } defer zr.Close() _, err = io.Copy(&out, zr) if err != nil { return } if out.Len() != len { return nil, fmt.Errorf("inflated size mismatch, expected %d, got %d", len, out.Len()) } bs = out.Bytes() _, err = r.Seek(0-int64(br.Buffered()), 1) if err != nil { return } return }