github.com/volts-dev/volts@v0.0.0-20240120094013-5e9c65924106/registry/consul/encoding.go (about)

     1  package consul
     2  
     3  import (
     4  	"bytes"
     5  	"compress/zlib"
     6  	"encoding/hex"
     7  	"encoding/json"
     8  	"io/ioutil"
     9  
    10  	"github.com/volts-dev/volts/registry"
    11  )
    12  
    13  func encode(buf []byte) string {
    14  	var b bytes.Buffer
    15  	defer b.Reset()
    16  
    17  	w := zlib.NewWriter(&b)
    18  	if _, err := w.Write(buf); err != nil {
    19  		return ""
    20  	}
    21  	w.Close()
    22  
    23  	return hex.EncodeToString(b.Bytes())
    24  }
    25  
    26  func decode(d string) []byte {
    27  	hr, err := hex.DecodeString(d)
    28  	if err != nil {
    29  		return nil
    30  	}
    31  
    32  	br := bytes.NewReader(hr)
    33  	zr, err := zlib.NewReader(br)
    34  	if err != nil {
    35  		return nil
    36  	}
    37  
    38  	rbuf, err := ioutil.ReadAll(zr)
    39  	if err != nil {
    40  		return nil
    41  	}
    42  	zr.Close()
    43  
    44  	return rbuf
    45  }
    46  
    47  func encodeEndpoints(en []*registry.Endpoint) []string {
    48  	var tags []string
    49  	for _, e := range en {
    50  		if b, err := json.Marshal(e); err == nil {
    51  			tags = append(tags, "e-"+encode(b))
    52  		}
    53  	}
    54  	return tags
    55  }
    56  
    57  func decodeEndpoints(tags []string) []*registry.Endpoint {
    58  	var en []*registry.Endpoint
    59  
    60  	// use the first format you find
    61  	var ver byte
    62  
    63  	for _, tag := range tags {
    64  		if len(tag) == 0 || tag[0] != 'e' {
    65  			continue
    66  		}
    67  
    68  		// check version
    69  		if ver > 0 && tag[1] != ver {
    70  			continue
    71  		}
    72  
    73  		var e *registry.Endpoint
    74  		var buf []byte
    75  
    76  		// Old encoding was plain
    77  		if tag[1] == '=' {
    78  			buf = []byte(tag[2:])
    79  		}
    80  
    81  		// New encoding is hex
    82  		if tag[1] == '-' {
    83  			buf = decode(tag[2:])
    84  		}
    85  
    86  		if err := json.Unmarshal(buf, &e); err == nil {
    87  			en = append(en, e)
    88  		}
    89  
    90  		// set version
    91  		ver = tag[1]
    92  	}
    93  	return en
    94  }
    95  
    96  func encodeMetadata(md map[string]string) []string {
    97  	var tags []string
    98  	for k, v := range md {
    99  		if b, err := json.Marshal(map[string]string{
   100  			k: v,
   101  		}); err == nil {
   102  			// new encoding
   103  			tags = append(tags, "t-"+encode(b))
   104  		}
   105  	}
   106  	return tags
   107  }
   108  
   109  func decodeMetadata(tags []string) map[string]string {
   110  	md := make(map[string]string)
   111  
   112  	var ver byte
   113  
   114  	for _, tag := range tags {
   115  		if len(tag) == 0 || tag[0] != 't' {
   116  			continue
   117  		}
   118  
   119  		// check version
   120  		if ver > 0 && tag[1] != ver {
   121  			continue
   122  		}
   123  
   124  		var kv map[string]string
   125  		var buf []byte
   126  
   127  		// Old encoding was plain
   128  		if tag[1] == '=' {
   129  			buf = []byte(tag[2:])
   130  		}
   131  
   132  		// New encoding is hex
   133  		if tag[1] == '-' {
   134  			buf = decode(tag[2:])
   135  		}
   136  
   137  		// Now unmarshal
   138  		if err := json.Unmarshal(buf, &kv); err == nil {
   139  			for k, v := range kv {
   140  				md[k] = v
   141  			}
   142  		}
   143  
   144  		// set version
   145  		ver = tag[1]
   146  	}
   147  	return md
   148  }
   149  
   150  func encodeVersion(v string) []string {
   151  	return []string{"v-" + encode([]byte(v))}
   152  }
   153  
   154  func decodeVersion(tags []string) (string, bool) {
   155  	for _, tag := range tags {
   156  		if len(tag) < 2 || tag[0] != 'v' {
   157  			continue
   158  		}
   159  
   160  		// Old encoding was plain
   161  		if tag[1] == '=' {
   162  			return tag[2:], true
   163  		}
   164  
   165  		// New encoding is hex
   166  		if tag[1] == '-' {
   167  			return string(decode(tag[2:])), true
   168  		}
   169  	}
   170  	return "", false
   171  }