| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183 | /* * EliasDB * * Copyright 2016 Matthias Ladkau. All rights reserved. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */package utilimport "encoding/binary"/*PrefixCode is the prefix for entries storing codes*/const PrefixCode = string(0x0)/*PrefixName is the prefix for entries storing names*/const PrefixName = string(0x1)/*PrefixCounter is the prefix for counter entries*/const PrefixCounter = string(0x0)/*Prefix16Bit is the prefix for 16 bit kind related entries*/const Prefix16Bit = string(0x1)/*Prefix32Bit is the prefix for attribute related entries*/const Prefix32Bit = string(0x2)/*NamesManager data structure*/type NamesManager struct {	nameDB map[string]string // Database storing names}/*NewNamesManager creates a new names manager instance.*/func NewNamesManager(nameDB map[string]string) *NamesManager {	return &NamesManager{nameDB}}/*Encode32 encodes a given value as a 32 bit string. If the create flagis set to false then a new entry will not be created if it does not exist.*/func (gs *NamesManager) Encode32(val string, create bool) string {	return gs.encode(Prefix32Bit, val, create)}/*Decode32 decodes a given 32 bit string to a value.*/func (gs *NamesManager) Decode32(val string) string {	return gs.decode(Prefix32Bit, val)}/*Encode16 encodes a given value as a 16 bit string. If the create flagis set to false then a new entry will not be created if it does not exist.*/func (gs *NamesManager) Encode16(val string, create bool) string {	return gs.encode(Prefix16Bit, val, create)}/*Decode16 decodes a given 16 bit string to a value.*/func (gs *NamesManager) Decode16(val string) string {	return gs.decode(Prefix16Bit, val)}/*encode encodes a name to a code.*/func (gs *NamesManager) encode(prefix string, name string, create bool) string {	codekey := string(PrefixCode) + prefix + name	code, ok := gs.nameDB[codekey]	// If the code doesn't exist yet create it	if !ok && create {		if prefix == Prefix16Bit {			code = gs.newCode16()		} else {			code = gs.newCode32()		}		gs.nameDB[codekey] = code		namekey := string(PrefixName) + prefix + code		gs.nameDB[namekey] = name	}	return code}/*decode decodes a name from a code.*/func (gs *NamesManager) decode(prefix string, code string) string {	namekey := string(PrefixName) + prefix + code	return gs.nameDB[namekey]}/*newCode32 generates a new 32 bit number for the names map.*/func (gs *NamesManager) newCode32() (res string) {	var resnum uint32	// Calculate count entry	countAttr := string(PrefixCounter) + Prefix32Bit	// Calculate new code	val, ok := gs.nameDB[countAttr]	if !ok {		resnum = 1	} else {		resnum = binary.LittleEndian.Uint32([]byte(val))		resnum++	}	// Convert to a string	resStr := make([]byte, 4, 4)	binary.LittleEndian.PutUint32(resStr, resnum)	res = string(resStr)	// Write back	gs.nameDB[countAttr] = res	return res}/*newCode16 generates a new 16 bit number for the names map.*/func (gs *NamesManager) newCode16() (res string) {	var resnum uint16	// Calculate count entry	countAttr := string(PrefixCounter) + Prefix16Bit	// Calculate new code	val, ok := gs.nameDB[countAttr]	if !ok {		resnum = 1	} else {		resnum = binary.LittleEndian.Uint16([]byte(val))		resnum++	}	// Convert to a string	resStr := make([]byte, 2, 2)	binary.LittleEndian.PutUint16(resStr, resnum)	res = string(resStr)	// Write back	gs.nameDB[countAttr] = res	return res}
 |