func (d *Data) SetTileGrid(grid DataTileGrid) (err error) { var ( buf bytes.Buffer b64Encoder io.WriteCloser zlibWriter *zlib.Writer gids []uint32 gridTile DataTileGridTile ) d.Encoding = "base64" d.Compression = "zlib" d.RawTiles = []DataTile{} gids = make([]uint32, grid.Width*grid.Height) for y := 0; y < grid.Height; y++ { for x := 0; x < grid.Width; x++ { gridTile = grid.Tiles[x][y] gids[grid.Width*y+x] = encodeGid( gridTile.Id, gridTile.FlipX, gridTile.FlipY, gridTile.FlipD) } } b64Encoder = base64.NewEncoder(base64.StdEncoding, &buf) zlibWriter = zlib.NewWriter(b64Encoder) if err = binary.Write(zlibWriter, binary.LittleEndian, gids); err != nil { return } zlibWriter.Close() b64Encoder.Close() d.RawContents = buf.String() return }
func loadFont(f *fontdata) (font *FontMetrics) { var err error if font, err = ParseFontMetricsFile(f.Metrics, f.Label); err != nil { log.Fatalf("loading font metrics: %v", err) } if f.StemV > 0 && font.StemV <= 0 { font.StemV = f.StemV } if len(f.FontFile) > 0 { font.File = []byte(f.FontFile) var buf bytes.Buffer var writer *zlib.Writer if writer, err = zlib.NewWriterLevel(&buf, zlib.BestCompression); err != nil { log.Fatal("Setting up zlib compressor: ", err) } if _, err = writer.Write(font.File); err != nil { log.Fatal("Writing to zlib compressor: ", err) } if err = writer.Close(); err != nil { log.Fatal("Closing zlib compressor: ", err) } font.CompressedFile = buf.Bytes() } return }
func (pp *pendingPayload) Generate(hostname string) (err error) { var buffer bytes.Buffer // Begin with the nonce if _, err = buffer.Write([]byte(pp.nonce)); err != nil { return } var compressor *zlib.Writer if compressor, err = zlib.NewWriterLevel(&buffer, 3); err != nil { return } // Append all the events for _, event := range pp.events[pp.ack_events:] { // Add host field event.Event["host"] = hostname if err = pp.bufferJdatDataEvent(compressor, event); err != nil { return } } compressor.Close() pp.payload = buffer.Bytes() pp.payload_start = pp.ack_events return }
func (self *ZlibCompressor) Compress(src []byte) ([]byte, error) { var err error var compressor *zlib.Writer cdest := bytes.NewBuffer(make([]byte, 0, len(src))) if self.dict == nil { compressor, err = zlib.NewWriterLevel(cdest, self.level) } else { compressor, err = zlib.NewWriterLevelDict(cdest, self.level, self.dict) } compressor.Write(src) err = compressor.Close() if err != nil { fmt.Println("Compress Close err:%s", err.Error()) } return cdest.Bytes(), err }
// createCompressedPacket generates a compressed protocol packet after // compressing the specified payload. func (rw *compressRW) createCompressedPacket(payload []byte) ([]byte, error) { var ( w *zlib.Writer z bytes.Buffer packet []byte err error payloadLength int ) // TODO: add a property for compression level if w, err = zlib.NewWriterLevel(&z, zlib.DefaultCompression); err != nil { goto E } if _, err = w.Write(payload); err != nil { goto E } if err = w.Close(); err != nil { goto E } payloadLength = z.Len() // allocate buffer for the compressed packet // header (7 bytes) + payload packet = make([]byte, 7+payloadLength) // compressed header // - size of compressed payload putUint24(packet[0:3], uint32(payloadLength)) // - packet sequence number packet[3] = rw.seqno // - size of payload before it was compressed putUint24(packet[4:7], uint32(len(payload))) // copy the compressed payload copy(packet[7:], z.Bytes()) return packet, nil E: return nil, myError(ErrCompression, err) }
func (stream *PDFStream) Render(indent string, out io.Writer) (err error) { if CompressStreams && len(stream.Compressed) == 0 { // compress the stream contents var buf bytes.Buffer var writer *zlib.Writer if writer, err = zlib.NewWriterLevel(&buf, zlib.BestCompression); err != nil { return } if _, err = writer.Write(stream.Data); err != nil { return } if err = writer.Close(); err != nil { return } stream.Compressed = buf.Bytes() } if CompressStreams { stream.Map["Filter"] = PDFName("FlateDecode") stream.Map["Length"] = PDFNumber(len(stream.Compressed)) } else { stream.Map["Length"] = PDFNumber(len(stream.Data)) } if err = stream.Map.Render(indent, out); err != nil { return } fmt.Fprint(out, "\nstream\n") if CompressStreams { if _, err = out.Write(stream.Compressed); err != nil { return } } else { if _, err = out.Write(stream.Data); err != nil { return } } fmt.Fprint(out, "endstream") return }
func (pp *pendingPayload) Generate() (err error) { var buffer bytes.Buffer // Assertion if len(pp.events) == 0 { return ErrPayloadCorrupt } // Begin with the nonce if _, err = buffer.Write([]byte(pp.nonce)[0:16]); err != nil { return } var compressor *zlib.Writer if compressor, err = zlib.NewWriterLevel(&buffer, 3); err != nil { return } // Append all the events for _, event := range pp.events[pp.ack_events:] { if err = binary.Write(compressor, binary.BigEndian, uint32(len(event.Event))); err != nil { return } if _, err = compressor.Write(event.Event); err != nil { return } } compressor.Close() pp.payload = buffer.Bytes() pp.last_sequence = 0 pp.sequence_len = len(pp.events) - pp.ack_events return }
func (c *Client) handlePeer(in io.ReadCloser, out io.WriteCloser, first bool) (err error) { var m method write := bufio.NewWriter(out) number := rand.Int63n(0x7fff) lock, pk := GenerateLock() if first { send(write, "MyNick", []byte(c.Nick)) sendf(write, "Lock", func(w *bufio.Writer) { fmt.Fprintf(w, "%s Pk=%s", lock, pk) }) } /* Step 0 - figure out who we're talking to */ buf := bufio.NewReader(in) if err = readCmd(buf, &m); err != nil { return } if m.name != "MyNick" { return errors.New("Expected $MyNick first") } nick := string(m.data) /* Step 1 - make sure we have the only connection to the peer */ bad := false p := c.peer(nick, func(p *peer) { if p.state == Uninitialized || p.state == RequestingConnection { p.state = Connecting } else { bad = true } }) if bad { return errors.New("Invalid state with peer tables") } if p.write != nil { panic("already have a write connection") } p.in = in p.out = out defer c.peerGone(p.nick) c.log("Connected to: " + p.nick) defer c.log("Disconnected from: " + p.nick) /* Step 2 - get their lock so we can respond with our nick/key */ if err = readCmd(buf, &m); err != nil { return } if m.name != "Lock" { return errors.New("Expected $Lock second") } idx := bytes.IndexByte(m.data, ' ') if idx == -1 { return errors.New("Invalid $Lock") } /* Step 3 - send our nick/lock/supports/direction metadata */ if !first { send(write, "MyNick", []byte(c.Nick)) sendf(write, "Lock", func(w *bufio.Writer) { fmt.Fprintf(w, "%s Pk=%s", lock, pk) }) } send(write, "Supports", []byte("MiniSlots XmlBZList ADCGet ZLIG GetZBlock TTHF")) mydirection := "Upload" if len(p.dls) > 0 { mydirection = "Download" } sendf(write, "Direction", func(w *bufio.Writer) { fmt.Fprintf(w, "%s %d", mydirection, number) }) send(write, "Key", GenerateKey(m.data[0:idx])) /* Step 4 - receive what they support (optional) */ if err = readCmd(buf, &m); err != nil { return } p.supports = make([]string, 0) if m.name == "Supports" { for _, s := range bytes.Split(m.data, []byte(" ")) { p.supports = append(p.supports, string(s)) } if err = readCmd(buf, &m); err != nil { return } } /* Step 5 - receive their direction */ if m.name != "Direction" { return errors.New("Expected $Direction") } /* Don't actually care about the direction */ /* Step 6 - receive their key */ if err = readCmd(buf, &m); err != nil { return } if m.name != "Key" { return errors.New("Expected $Key") } if !bytes.Equal(m.data, GenerateKey([]byte(lock))) { return errors.New("Invalid key received for lock send") } /* Step 7+ - upload/download files infinitely until closed */ p.write = write p.state = Idle /* try to diagnose why peers disconnect */ err = c.initiateDownload() defer func() { if err != nil && err != io.EOF { c.log("error with '" + nick + "': " + err.Error()) } }() dl := func(size int64, offset int64, z bool) error { if p.state != Downloading { return errors.New("not in the downloading state") } if p.dl == nil { return errors.New("downloading with nil download") } if p.ul != nil { return errors.New("downloading while uploading") } defer p.file.Close() var input io.Reader = buf if z { input, err = zlib.NewReader(input) if err != nil { return err } } _, err := p.file.Seek(offset, os.SEEK_SET) if err != nil { err = p.file.Truncate(offset) if err == nil { _, err = p.file.Seek(offset, os.SEEK_SET) } } if err != nil { return err } c.log("Starting download of: " + p.dl.file) s, err := io.CopyN(p.file, input, size) if err != nil { return err } if s != size { return errors.New("Didn't download whole file") } if p.dl.fileList() { _, err := p.file.Seek(0, os.SEEK_SET) if err != nil { return err } err = p.parseFiles(c, p.file) if err != nil { return err } } c.log("Finished downloading: " + p.dl.file) c.DL.release() /* if we fail with error, our slot is released elsewhere */ p.dl = nil p.file = nil p.state = Idle return c.initiateDownload() } ul := func(size int64, offset int64, z bool) error { if p.state != Uploading { return errors.New("not in the uploading state") } if p.dl != nil { return errors.New("uploading while trying to download") } if p.ul == nil { return errors.New("uploading without a file") } defer p.file.Close() /* Don't upload through the bufio.Writer instance */ var compressed *zlib.Writer var upload io.Writer = out if z { compressed = zlib.NewWriter(upload) upload = compressed } write.Flush() _, err := p.file.Seek(offset, os.SEEK_SET) if err != nil { return err } c.log("Starting upload of: " + p.file.Name()) _, err = io.CopyN(upload, p.file, size) if compressed != nil && err == nil { err = compressed.Close() /* be sure to flush the zlib stream */ } if err != nil { return err } c.log("Finished uploading: " + p.file.Name()) if p.ul.Name != "files.xml.bz2" { c.UL.release() /* if we fail with error, our slot is released elsewhere */ } p.ul = nil p.file = nil p.state = Idle return c.initiateDownload() } adc := regexp.MustCompile("([^ ]+) (.+) ([0-9]+) (-?[0-9]+)( ZL1)?") size, offset := int64(0), int64(0) for err == nil { err = readCmd(buf, &m) if err != nil { return } switch m.name { /* ADC receiving half of things */ case "ADCSND", "ADCGET": parts := adc.FindStringSubmatch(string(m.data)) if len(parts) != 6 { return errors.New("Malformed ADC command: " + string(m.data)) } size, err = strconv.ParseInt(parts[4], 10, 64) if err == nil { offset, err = strconv.ParseInt(parts[3], 10, 64) } if err != nil { return err } zlig := len(parts[5]) != 0 if m.name == "ADCSND" { err = dl(size, offset, zlig) } else { size, err = p.upload(c, parts[2], offset, size) if err != nil { return err } sendf(write, "ADCSND", func(w *bufio.Writer) { fmt.Fprintf(w, "%s %s %d %d", parts[1], parts[2], offset, size) if zlig { w.WriteString(" ZL1") } }) err = ul(size, offset, zlig) } /* UGetZ?Block receiving half */ case "Sending": size, err := strconv.ParseInt(string(m.data), 10, 64) if err == nil { err = dl(size, p.dl.offset, p.implements("GetZBlock")) } /* old school original DC receiving half */ case "FileLength": size, err := strconv.ParseInt(string(m.data), 10, 64) if err == nil { send(write, "Send", nil) err = dl(size, 0, false) } /* old school DC download system */ case "Get": parts := bytes.Split(m.data, []byte("$")) if len(parts) != 2 { return errors.New("Malformed Get command") } file := string(parts[0]) offset, err = strconv.ParseInt(string(parts[1]), 10, 64) offset-- size, err = p.upload(c, file, offset, -1) if err != nil { return err } sendf(write, "FileLength", func(w *bufio.Writer) { fmt.Fprintf(w, "%d", size) }) err = readCmd(buf, &m) if err != nil { return err } if m.name != "Send" { return errors.New("Expected $Send") } err = ul(size, offset, false) /* Upload half of UGetZ?Block */ case "UGetBlock", "UGetZBlock": parts := bytes.SplitN(m.data, []byte(" "), 3) if len(parts) != 3 { return errors.New("Malformed UGetZ?Block command") } offset, err = strconv.ParseInt(string(parts[0]), 10, 64) if err != nil { return err } size, err = strconv.ParseInt(string(parts[1]), 10, 64) if err != nil { return err } size, err = p.upload(c, string(parts[2]), offset, size) if err != nil { return err } sendf(write, "Sending", func(w *bufio.Writer) { fmt.Fprintf(w, "%d", size) }) err = ul(size, offset, m.name == "UGetZBlock") case "Error": return errors.New("remote error: " + string(m.data)) default: return errors.New("Unknown command: $" + m.name) } } return err }