func (decryptor *Decryptor) ReadData(symmetricKey, zoneID []byte, reader io.Reader) ([]byte, error) {
	return decryptor.binaryDecryptor.ReadData(symmetricKey, zoneID, reader)
}
ReadData returns decrypted AcraStruct content
package mysql
import (
	"bytes"
	"context"
	"errors"
	"io"
	"io/ioutil"
	"github.com/cossacklabs/acra/decryptor/base"
	"github.com/cossacklabs/acra/decryptor/binary"
	"github.com/cossacklabs/acra/decryptor/postgresql"
	"github.com/cossacklabs/acra/keystore"
	"github.com/cossacklabs/acra/logging"
	"github.com/cossacklabs/acra/utils"
	"github.com/cossacklabs/acra/zone"
	"github.com/cossacklabs/themis/gothemis/keys"
	log "github.com/sirupsen/logrus"
)
type decryptFunc func([]byte) ([]byte, error)
var errPlainData = errors.New("plain data without AcraStruct signature")
type Decryptor struct {
	base.Decryptor
	binaryDecryptor      *binary.Decryptor
	keyStore             keystore.DecryptionKeyStore
	decryptFunc          decryptFunc
	log                  *log.Entry
	clientID             []byte
	dataProcessor        base.DataProcessor
	dataProcessorContext *base.DataProcessorContext
}
func NewMySQLDecryptor(clientID []byte, pgDecryptor *postgresql.PgDecryptor, keyStore keystore.DecryptionKeyStore) *Decryptor {
	logger := log.WithFields(log.Fields{"decryptor": "mysql", "client_id": string(clientID)})
	processorCtx := base.NewDataProcessorContext(clientID, pgDecryptor.IsWithZone(), keyStore).UseContext(logging.SetLoggerToContext(context.Background(), logger))
	decryptor := &Decryptor{
		keyStore:             keyStore,
		binaryDecryptor:      binary.NewBinaryDecryptor(logger),
		Decryptor:            pgDecryptor,
		clientID:             clientID,
		dataProcessorContext: processorCtx,
		log:                  logger}
	pgDecryptor.TurnOnPoisonRecordCheck(true)
	decryptor.SetWholeMatch(pgDecryptor.IsWholeMatch())
	return decryptor
}
func (decryptor *Decryptor) SkipBeginInBlock(block []byte) ([]byte, error) {
	n := 0
	for _, c := range block {
		if !decryptor.MatchBeginTag(c) {
			return []byte{}, base.ErrFakeAcraStruct
		}
		n++
		if decryptor.IsMatched() {
			break
		}
	}
	if !decryptor.IsMatched() {
		return []byte{}, base.ErrFakeAcraStruct
	}
	return block[n:], nil
}
func (decryptor *Decryptor) MatchZoneBlock(block []byte) {
	for _, c := range block {
		if !decryptor.MatchZone(c) {
			return
		}
	}
}
func (decryptor *Decryptor) BeginTagIndex(block []byte) (int, int) {
	if i := bytes.Index(block, base.TagBegin); i != utils.NotFound {
		return i, decryptor.binaryDecryptor.GetTagBeginLength()
	}
	return utils.NotFound, decryptor.GetTagBeginLength()
}
func (decryptor *Decryptor) MatchZoneInBlock(block []byte) {
	for {
		i := bytes.Index(block, zone.ZoneIDBegin)
		if i == utils.NotFound {
			break
		} else {
			if decryptor.keyStore.HasZonePrivateKey(block[i : i+zone.ZoneIDBlockLength]) {
				decryptor.GetZoneMatcher().SetMatched(block[i : i+zone.ZoneIDBlockLength])
				return
			}
			block = block[i+1:]
		}
	}
	return
}