Пример #1
0
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
}
Пример #2
0
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
}
Пример #3
0
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
}
Пример #4
0
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
}
Пример #5
0
// 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)

}
Пример #6
0
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
}
Пример #7
0
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
}
Пример #8
0
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
}