code: func DecodeStringBlock(block []byte, a *[]StringValue) ([]StringValue, error) {
  	blockType := block[0]
  	if blockType != BlockString {
  		return nil, fmt.Errorf("invalid block type: exp %d, got %d", BlockString, blockType)
  	}
  
  	block = block[1:]
  
  	// The first 8 bytes is the minimum timestamp of the block
  	tb, vb, err := unpackBlock(block)
  	if err != nil {
  		return nil, err
  	}
  
  	sz := CountTimestamps(tb)
  
  	if cap(*a) < sz {
  		*a = make([]StringValue, sz)
  	} else {
  		*a = (*a)[:sz]
  	}
  
  	tdec := timeDecoderPool.Get(0).(*TimeDecoder)
  	vdec := stringDecoderPool.Get(0).(*StringDecoder)
  
  	var i int
  	err = func(a []StringValue) error {
  		// Setup our timestamp and value decoders
  		tdec.Init(tb)
  		err = vdec.SetBytes(vb)
  		if err != nil {
  			return err
  		}
  
  		// Decode both a timestamp and value
  		j := 0
  		for j < len(a) && tdec.Next() && vdec.Next() {
  			a[j] = StringValue{unixnano: tdec.Read(), value: vdec.Read()}
  			j++
  		}
  		i = j
  
  		// Did timestamp decoding have an error?
  		err = tdec.Error()
  		if err != nil {
  			return err
  		}
  		// Did string decoding have an error?
  		return vdec.Error()
  	}(*a)
  
  	timeDecoderPool.Put(tdec)
  	stringDecoderPool.Put(vdec)
  
  	return (*a)[:i], err
  }
docs: // DecodeStringBlock decodes the string block from the byte slice
  // and appends the string values to a.