mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-10-31 18:48:08 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			104 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			104 lines
		
	
	
		
			3.0 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright (c) HashiCorp, Inc.
 | |
| // SPDX-License-Identifier: MPL-2.0
 | |
| 
 | |
| package jsonutil
 | |
| 
 | |
| import (
 | |
| 	"bytes"
 | |
| 	"compress/gzip"
 | |
| 	"encoding/json"
 | |
| 	"fmt"
 | |
| 	"io"
 | |
| 
 | |
| 	"github.com/hashicorp/errwrap"
 | |
| 	"github.com/hashicorp/vault/sdk/helper/compressutil"
 | |
| )
 | |
| 
 | |
| // Encodes/Marshals the given object into JSON
 | |
| func EncodeJSON(in interface{}) ([]byte, error) {
 | |
| 	if in == nil {
 | |
| 		return nil, fmt.Errorf("input for encoding is nil")
 | |
| 	}
 | |
| 	var buf bytes.Buffer
 | |
| 	enc := json.NewEncoder(&buf)
 | |
| 	if err := enc.Encode(in); err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 	return buf.Bytes(), nil
 | |
| }
 | |
| 
 | |
| // EncodeJSONAndCompress encodes the given input into JSON and compresses the
 | |
| // encoded value (using Gzip format BestCompression level, by default). A
 | |
| // canary byte is placed at the beginning of the returned bytes for the logic
 | |
| // in decompression method to identify compressed input.
 | |
| func EncodeJSONAndCompress(in interface{}, config *compressutil.CompressionConfig) ([]byte, error) {
 | |
| 	if in == nil {
 | |
| 		return nil, fmt.Errorf("input for encoding is nil")
 | |
| 	}
 | |
| 
 | |
| 	// First JSON encode the given input
 | |
| 	encodedBytes, err := EncodeJSON(in)
 | |
| 	if err != nil {
 | |
| 		return nil, err
 | |
| 	}
 | |
| 
 | |
| 	if config == nil {
 | |
| 		config = &compressutil.CompressionConfig{
 | |
| 			Type:                 compressutil.CompressionTypeGzip,
 | |
| 			GzipCompressionLevel: gzip.BestCompression,
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	return compressutil.Compress(encodedBytes, config)
 | |
| }
 | |
| 
 | |
| // DecodeJSON tries to decompress the given data. The call to decompress, fails
 | |
| // if the content was not compressed in the first place, which is identified by
 | |
| // a canary byte before the compressed data. If the data is not compressed, it
 | |
| // is JSON decoded directly. Otherwise the decompressed data will be JSON
 | |
| // decoded.
 | |
| func DecodeJSON(data []byte, out interface{}) error {
 | |
| 	if data == nil || len(data) == 0 {
 | |
| 		return fmt.Errorf("'data' being decoded is nil")
 | |
| 	}
 | |
| 	if out == nil {
 | |
| 		return fmt.Errorf("output parameter 'out' is nil")
 | |
| 	}
 | |
| 
 | |
| 	// Decompress the data if it was compressed in the first place
 | |
| 	decompressedBytes, uncompressed, err := compressutil.Decompress(data)
 | |
| 	if err != nil {
 | |
| 		return errwrap.Wrapf("failed to decompress JSON: {{err}}", err)
 | |
| 	}
 | |
| 	if !uncompressed && (decompressedBytes == nil || len(decompressedBytes) == 0) {
 | |
| 		return fmt.Errorf("decompressed data being decoded is invalid")
 | |
| 	}
 | |
| 
 | |
| 	// If the input supplied failed to contain the compression canary, it
 | |
| 	// will be notified by the compression utility. Decode the decompressed
 | |
| 	// input.
 | |
| 	if !uncompressed {
 | |
| 		data = decompressedBytes
 | |
| 	}
 | |
| 
 | |
| 	return DecodeJSONFromReader(bytes.NewReader(data), out)
 | |
| }
 | |
| 
 | |
| // Decodes/Unmarshals the given io.Reader pointing to a JSON, into a desired object
 | |
| func DecodeJSONFromReader(r io.Reader, out interface{}) error {
 | |
| 	if r == nil {
 | |
| 		return fmt.Errorf("'io.Reader' being decoded is nil")
 | |
| 	}
 | |
| 	if out == nil {
 | |
| 		return fmt.Errorf("output parameter 'out' is nil")
 | |
| 	}
 | |
| 
 | |
| 	dec := json.NewDecoder(r)
 | |
| 
 | |
| 	// While decoding JSON values, interpret the integer values as `json.Number`s instead of `float64`.
 | |
| 	dec.UseNumber()
 | |
| 
 | |
| 	// Since 'out' is an interface representing a pointer, pass it to the decoder without an '&'
 | |
| 	return dec.Decode(out)
 | |
| }
 | 
