blob: 99714ffa0c1ee5ddb2e5997b3011e0a50f1e2b88 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package mfg
import (
"bytes"
"encoding/binary"
"encoding/hex"
"encoding/json"
"github.com/apache/mynewt-artifact/errors"
)
func (t *MetaTlv) bodyMap() (map[string]interface{}, error) {
r := bytes.NewReader(t.Data)
readBody := func(dst interface{}) error {
if err := binary.Read(r, binary.LittleEndian, dst); err != nil {
return errors.Wrapf(err, "error parsing TLV data")
}
return nil
}
switch t.Header.Type {
case META_TLV_TYPE_HASH:
var body MetaTlvBodyHash
if err := readBody(&body); err != nil {
return nil, err
}
return body.Map(), nil
case META_TLV_TYPE_FLASH_AREA:
var body MetaTlvBodyFlashArea
if err := readBody(&body); err != nil {
return nil, err
}
return body.Map(), nil
case META_TLV_TYPE_MMR_REF:
var body MetaTlvBodyMmrRef
if err := readBody(&body); err != nil {
return nil, err
}
return body.Map(), nil
default:
return nil, errors.Errorf("unknown meta TLV type: %d", t.Header.Type)
}
}
func (b *MetaTlvBodyFlashArea) Map() map[string]interface{} {
return map[string]interface{}{
"area": b.Area,
"device": b.Device,
"offset": b.Offset,
"size": b.Size,
}
}
func (b *MetaTlvBodyHash) Map() map[string]interface{} {
return map[string]interface{}{
"hash": hex.EncodeToString(b.Hash[:]),
}
}
func (b *MetaTlvBodyMmrRef) Map() map[string]interface{} {
return map[string]interface{}{
"area": b.Area,
}
}
// Map produces a JSON-friendly map representation of an MMR TLV.
func (t *MetaTlv) Map(index int, offset int) map[string]interface{} {
hmap := map[string]interface{}{
"_type_name": MetaTlvTypeName(t.Header.Type),
"type": t.Header.Type,
"size": t.Header.Size,
}
var body interface{}
bmap, err := t.bodyMap()
if err != nil {
body = hex.EncodeToString(t.Data)
} else {
body = bmap
}
return map[string]interface{}{
"_index": index,
"_offset": offset,
"header": hmap,
"data": body,
}
}
// Map produces a JSON-friendly map representation of an MMR footer.
func (f *MetaFooter) Map(offset int) map[string]interface{} {
return map[string]interface{}{
"_offset": offset,
"size": f.Size,
"magic": f.Magic,
"version": f.Version,
}
}
// Map produces a JSON-friendly map representation of an MMR.
func (m *Meta) Map(endOffset int) map[string]interface{} {
offsets := m.Offsets()
startOffset := endOffset - int(m.Footer.Size)
tlvs := []map[string]interface{}{}
for i, t := range m.Tlvs {
tlv := t.Map(i, startOffset+offsets.Tlvs[i])
tlvs = append(tlvs, tlv)
}
ftr := m.Footer.Map(startOffset + offsets.Footer)
return map[string]interface{}{
"_offset": startOffset,
"_end_offset": endOffset,
"_size": m.Footer.Size,
"tlvs": tlvs,
"footer": ftr,
}
}
// Json produces a JSON representation of an MMR.
func (m *Meta) Json(offset int) (string, error) {
mmap := m.Map(offset)
bin, err := json.MarshalIndent(mmap, "", " ")
if err != nil {
return "", errors.Wrapf(err, "failed to marshal MMR")
}
return string(bin), nil
}