GNU gettext is a popular solution in free/open source software world to do i18n/l10n of software, by providing translated strings that will substitute strings in original language (typically, English).
gettext .mo is a binary database format which stores these string translation pairs in an efficient binary format, ready to be used by gettext-enabled software. .mo format is a result of compilation of text-based .po files using msgfmt utility. The reverse conversion (.mo -> .po) is also possible using msgunfmt decompiler utility.
This page hosts a formal specification of gettext binary database using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.
// Code generated by kaitai-struct-compiler from a .ksy source file. DO NOT EDIT.
import (
"github.com/kaitai-io/kaitai_struct_go_runtime/kaitai"
"io"
"bytes"
)
/**
* [GNU gettext](https://www.gnu.org/software/gettext/) is a popular
* solution in free/open source software world to do i18n/l10n of
* software, by providing translated strings that will substitute
* strings in original language (typically, English).
*
* gettext .mo is a binary database format which stores these string
* translation pairs in an efficient binary format, ready to be used by
* gettext-enabled software. .mo format is a result of compilation of
* text-based .po files using
* [msgfmt](https://www.gnu.org/software/gettext/manual/html_node/msgfmt-Invocation.html#msgfmt-Invocation)
* utility. The reverse conversion (.mo -> .po) is also possible using
* [msgunfmt](https://www.gnu.org/software/gettext/manual/html_node/msgunfmt-Invocation.html#msgunfmt-Invocation)
* decompiler utility.
* @see <a href="https://gitlab.com/worr/libintl">Source</a>
*/
type GettextMo struct {
Signature []byte
Mo *GettextMo_Mo
_io *kaitai.Stream
_root *GettextMo
_parent kaitai.Struct
}
func NewGettextMo() *GettextMo {
return &GettextMo{
}
}
func (this GettextMo) IO_() *kaitai.Stream {
return this._io
}
func (this *GettextMo) Read(io *kaitai.Stream, parent kaitai.Struct, root *GettextMo) (err error) {
this._io = io
this._parent = parent
this._root = root
tmp1, err := this._io.ReadBytes(int(4))
if err != nil {
return err
}
tmp1 = tmp1
this.Signature = tmp1
tmp2 := NewGettextMo_Mo()
err = tmp2.Read(this._io, this, this._root)
if err != nil {
return err
}
this.Mo = tmp2
return err
}
type GettextMo_HashLookupIteration struct {
Idx uint32
CollisionStep uint32
_io *kaitai.Stream
_root *GettextMo
_parent kaitai.Struct
_f_next bool
next *GettextMo_HashLookupIteration
_f_nextIdx bool
nextIdx int
_f_original bool
original string
_f_translation bool
translation string
}
func NewGettextMo_HashLookupIteration(idx uint32, collisionStep uint32) *GettextMo_HashLookupIteration {
return &GettextMo_HashLookupIteration{
Idx: idx,
CollisionStep: collisionStep,
}
}
func (this GettextMo_HashLookupIteration) IO_() *kaitai.Stream {
return this._io
}
func (this *GettextMo_HashLookupIteration) Read(io *kaitai.Stream, parent kaitai.Struct, root *GettextMo) (err error) {
this._io = io
this._parent = parent
this._root = root
return err
}
func (this *GettextMo_HashLookupIteration) Next() (v *GettextMo_HashLookupIteration, err error) {
if (this._f_next) {
return this.next, nil
}
this._f_next = true
_pos, err := this._io.Pos()
if err != nil {
return nil, err
}
_, err = this._io.Seek(int64(0), io.SeekStart)
if err != nil {
return nil, err
}
tmp3, err := this._root.Mo.HashtableItems()
if err != nil {
return nil, err
}
tmp4, err := this.NextIdx()
if err != nil {
return nil, err
}
tmp5, err := tmp3[tmp4].Val()
if err != nil {
return nil, err
}
tmp6 := NewGettextMo_HashLookupIteration(tmp5, this.CollisionStep)
err = tmp6.Read(this._io, this, this._root)
if err != nil {
return nil, err
}
this.next = tmp6
_, err = this._io.Seek(_pos, io.SeekStart)
if err != nil {
return nil, err
}
return this.next, nil
}
func (this *GettextMo_HashLookupIteration) NextIdx() (v int, err error) {
if (this._f_nextIdx) {
return this.nextIdx, nil
}
this._f_nextIdx = true
var tmp7 uint32;
if (this.Idx >= this._root.Mo.NumHashtableItems - this.CollisionStep) {
tmp7 = this._root.Mo.NumHashtableItems
} else {
tmp7 = 0
}
this.nextIdx = int((this.Idx + this.CollisionStep) - tmp7)
return this.nextIdx, nil
}
func (this *GettextMo_HashLookupIteration) Original() (v string, err error) {
if (this._f_original) {
return this.original, nil
}
this._f_original = true
tmp8, err := this._root.Mo.Originals()
if err != nil {
return "", err
}
tmp9, err := tmp8[this.Idx].Str()
if err != nil {
return "", err
}
this.original = string(tmp9)
return this.original, nil
}
func (this *GettextMo_HashLookupIteration) Translation() (v string, err error) {
if (this._f_translation) {
return this.translation, nil
}
this._f_translation = true
tmp10, err := this._root.Mo.Translations()
if err != nil {
return "", err
}
tmp11, err := tmp10[this.Idx].Str()
if err != nil {
return "", err
}
this.translation = string(tmp11)
return this.translation, nil
}
/**
* def lookup(s:str, t:gettext_mo.GettextMo):
* try:
* l=gettext_mo.GettextMo.HashtableLookup(s, string_hash(s), t._io, _parent=t, _root=t)
* e=l.entry
* while(not e.found):
* e=e.next
* return e.current
* except:
* raise Exception("Not found "+s+" in the hashtable!")
*
* lookup(t.mo.originals[145].str, t)
* @see <a href="https://gitlab.com/worr/libintl/raw/master/src/lib/libintl/gettext.c">Source</a>
*/
type GettextMo_HashtableLookup struct {
Query string
Hash uint32
_io *kaitai.Stream
_root *GettextMo
_parent kaitai.Struct
_f_collisionStep bool
collisionStep int
_f_entry bool
entry *GettextMo_LookupIteration
_f_hashLookupIteration bool
hashLookupIteration *GettextMo_HashLookupIteration
_f_idx bool
idx int
}
func NewGettextMo_HashtableLookup(query string, hash uint32) *GettextMo_HashtableLookup {
return &GettextMo_HashtableLookup{
Query: query,
Hash: hash,
}
}
func (this GettextMo_HashtableLookup) IO_() *kaitai.Stream {
return this._io
}
func (this *GettextMo_HashtableLookup) Read(io *kaitai.Stream, parent kaitai.Struct, root *GettextMo) (err error) {
this._io = io
this._parent = parent
this._root = root
return err
}
func (this *GettextMo_HashtableLookup) CollisionStep() (v int, err error) {
if (this._f_collisionStep) {
return this.collisionStep, nil
}
this._f_collisionStep = true
tmp12 := this.Hash % (this._root.Mo.NumHashtableItems - 2)
if tmp12 < 0 {
tmp12 += this._root.Mo.NumHashtableItems - 2
}
this.collisionStep = int(tmp12 + 1)
return this.collisionStep, nil
}
func (this *GettextMo_HashtableLookup) Entry() (v *GettextMo_LookupIteration, err error) {
if (this._f_entry) {
return this.entry, nil
}
this._f_entry = true
_pos, err := this._io.Pos()
if err != nil {
return nil, err
}
_, err = this._io.Seek(int64(0), io.SeekStart)
if err != nil {
return nil, err
}
tmp13, err := this.HashLookupIteration()
if err != nil {
return nil, err
}
tmp14 := NewGettextMo_LookupIteration(tmp13, this.Query)
err = tmp14.Read(this._io, this, this._root)
if err != nil {
return nil, err
}
this.entry = tmp14
_, err = this._io.Seek(_pos, io.SeekStart)
if err != nil {
return nil, err
}
return this.entry, nil
}
func (this *GettextMo_HashtableLookup) HashLookupIteration() (v *GettextMo_HashLookupIteration, err error) {
if (this._f_hashLookupIteration) {
return this.hashLookupIteration, nil
}
this._f_hashLookupIteration = true
_pos, err := this._io.Pos()
if err != nil {
return nil, err
}
_, err = this._io.Seek(int64(0), io.SeekStart)
if err != nil {
return nil, err
}
tmp15, err := this._root.Mo.HashtableItems()
if err != nil {
return nil, err
}
tmp16, err := this.Idx()
if err != nil {
return nil, err
}
tmp17, err := tmp15[tmp16].Val()
if err != nil {
return nil, err
}
tmp18, err := this.CollisionStep()
if err != nil {
return nil, err
}
tmp19 := NewGettextMo_HashLookupIteration(tmp17, tmp18)
err = tmp19.Read(this._io, this, this._root)
if err != nil {
return nil, err
}
this.hashLookupIteration = tmp19
_, err = this._io.Seek(_pos, io.SeekStart)
if err != nil {
return nil, err
}
return this.hashLookupIteration, nil
}
func (this *GettextMo_HashtableLookup) Idx() (v int, err error) {
if (this._f_idx) {
return this.idx, nil
}
this._f_idx = true
tmp20 := this.Hash % this._root.Mo.NumHashtableItems
if tmp20 < 0 {
tmp20 += this._root.Mo.NumHashtableItems
}
this.idx = int(tmp20)
return this.idx, nil
}
type GettextMo_LookupIteration struct {
Current *GettextMo_HashLookupIteration
Query string
_io *kaitai.Stream
_root *GettextMo
_parent kaitai.Struct
_f_found bool
found bool
_f_next bool
next *GettextMo_LookupIteration
}
func NewGettextMo_LookupIteration(current *GettextMo_HashLookupIteration, query string) *GettextMo_LookupIteration {
return &GettextMo_LookupIteration{
Current: current,
Query: query,
}
}
func (this GettextMo_LookupIteration) IO_() *kaitai.Stream {
return this._io
}
func (this *GettextMo_LookupIteration) Read(io *kaitai.Stream, parent kaitai.Struct, root *GettextMo) (err error) {
this._io = io
this._parent = parent
this._root = root
return err
}
func (this *GettextMo_LookupIteration) Found() (v bool, err error) {
if (this._f_found) {
return this.found, nil
}
this._f_found = true
tmp21, err := this.Current.Original()
if err != nil {
return false, err
}
this.found = bool(this.Query == tmp21)
return this.found, nil
}
func (this *GettextMo_LookupIteration) Next() (v *GettextMo_LookupIteration, err error) {
if (this._f_next) {
return this.next, nil
}
this._f_next = true
tmp22, err := this.Found()
if err != nil {
return nil, err
}
if (!(tmp22)) {
_pos, err := this._io.Pos()
if err != nil {
return nil, err
}
_, err = this._io.Seek(int64(0), io.SeekStart)
if err != nil {
return nil, err
}
tmp23, err := this.Current.Next()
if err != nil {
return nil, err
}
tmp24 := NewGettextMo_LookupIteration(tmp23, this.Query)
err = tmp24.Read(this._io, this, this._root)
if err != nil {
return nil, err
}
this.next = tmp24
_, err = this._io.Seek(_pos, io.SeekStart)
if err != nil {
return nil, err
}
}
return this.next, nil
}
type GettextMo_Mo struct {
Version *GettextMo_Mo_Version
NumTranslations uint32
OfsOriginals uint32
OfsTranslations uint32
NumHashtableItems uint32
OfsHashtableItems uint32
_io *kaitai.Stream
_root *GettextMo
_parent *GettextMo
_f_hashtableItems bool
hashtableItems []*GettextMo_Mo_HashtableItem
_f_originals bool
originals []*GettextMo_Mo_Descriptor
_f_translations bool
translations []*GettextMo_Mo_Descriptor
_is_le int
}
func NewGettextMo_Mo() *GettextMo_Mo {
return &GettextMo_Mo{
}
}
func (this GettextMo_Mo) IO_() *kaitai.Stream {
return this._io
}
func (this *GettextMo_Mo) Read(io *kaitai.Stream, parent *GettextMo, root *GettextMo) (err error) {
this._io = io
this._parent = parent
this._root = root
this._is_le = -1
switch (true) {
case bytes.Equal(this._root.Signature, []uint8{222, 18, 4, 149}):
this._is_le = int(1)
case bytes.Equal(this._root.Signature, []uint8{149, 4, 18, 222}):
this._is_le = int(0)
}
switch this._is_le {
case 0:
err = this._read_be()
case 1:
err = this._read_le()
default:
err = kaitai.UndecidedEndiannessError{}
}
return err
}
func (this *GettextMo_Mo) _read_le() (err error) {
tmp25 := NewGettextMo_Mo_Version()
err = tmp25.Read(this._io, this, this._root)
if err != nil {
return err
}
this.Version = tmp25
tmp26, err := this._io.ReadU4le()
if err != nil {
return err
}
this.NumTranslations = uint32(tmp26)
tmp27, err := this._io.ReadU4le()
if err != nil {
return err
}
this.OfsOriginals = uint32(tmp27)
tmp28, err := this._io.ReadU4le()
if err != nil {
return err
}
this.OfsTranslations = uint32(tmp28)
tmp29, err := this._io.ReadU4le()
if err != nil {
return err
}
this.NumHashtableItems = uint32(tmp29)
tmp30, err := this._io.ReadU4le()
if err != nil {
return err
}
this.OfsHashtableItems = uint32(tmp30)
return err
}
func (this *GettextMo_Mo) _read_be() (err error) {
tmp31 := NewGettextMo_Mo_Version()
err = tmp31.Read(this._io, this, this._root)
if err != nil {
return err
}
this.Version = tmp31
tmp32, err := this._io.ReadU4be()
if err != nil {
return err
}
this.NumTranslations = uint32(tmp32)
tmp33, err := this._io.ReadU4be()
if err != nil {
return err
}
this.OfsOriginals = uint32(tmp33)
tmp34, err := this._io.ReadU4be()
if err != nil {
return err
}
this.OfsTranslations = uint32(tmp34)
tmp35, err := this._io.ReadU4be()
if err != nil {
return err
}
this.NumHashtableItems = uint32(tmp35)
tmp36, err := this._io.ReadU4be()
if err != nil {
return err
}
this.OfsHashtableItems = uint32(tmp36)
return err
}
func (this *GettextMo_Mo) HashtableItems() (v []*GettextMo_Mo_HashtableItem, err error) {
if (this._f_hashtableItems) {
return this.hashtableItems, nil
}
this._f_hashtableItems = true
if (this.OfsHashtableItems != 0) {
thisIo := this._root._io
_pos, err := thisIo.Pos()
if err != nil {
return nil, err
}
_, err = thisIo.Seek(int64(this.OfsHashtableItems), io.SeekStart)
if err != nil {
return nil, err
}
switch this._is_le {
case 0:
for i := 0; i < int(this.NumHashtableItems); i++ {
_ = i
tmp37 := NewGettextMo_Mo_HashtableItem()
err = tmp37.Read(thisIo, this, this._root)
if err != nil {
return nil, err
}
this.hashtableItems = append(this.hashtableItems, tmp37)
}
case 1:
for i := 0; i < int(this.NumHashtableItems); i++ {
_ = i
tmp38 := NewGettextMo_Mo_HashtableItem()
err = tmp38.Read(thisIo, this, this._root)
if err != nil {
return nil, err
}
this.hashtableItems = append(this.hashtableItems, tmp38)
}
default:
err = kaitai.UndecidedEndiannessError{}
}
_, err = thisIo.Seek(_pos, io.SeekStart)
if err != nil {
return nil, err
}
}
return this.hashtableItems, nil
}
func (this *GettextMo_Mo) Originals() (v []*GettextMo_Mo_Descriptor, err error) {
if (this._f_originals) {
return this.originals, nil
}
this._f_originals = true
thisIo := this._root._io
_pos, err := thisIo.Pos()
if err != nil {
return nil, err
}
_, err = thisIo.Seek(int64(this.OfsOriginals), io.SeekStart)
if err != nil {
return nil, err
}
switch this._is_le {
case 0:
for i := 0; i < int(this.NumTranslations); i++ {
_ = i
tmp39 := NewGettextMo_Mo_Descriptor()
err = tmp39.Read(thisIo, this, this._root)
if err != nil {
return nil, err
}
this.originals = append(this.originals, tmp39)
}
case 1:
for i := 0; i < int(this.NumTranslations); i++ {
_ = i
tmp40 := NewGettextMo_Mo_Descriptor()
err = tmp40.Read(thisIo, this, this._root)
if err != nil {
return nil, err
}
this.originals = append(this.originals, tmp40)
}
default:
err = kaitai.UndecidedEndiannessError{}
}
_, err = thisIo.Seek(_pos, io.SeekStart)
if err != nil {
return nil, err
}
return this.originals, nil
}
func (this *GettextMo_Mo) Translations() (v []*GettextMo_Mo_Descriptor, err error) {
if (this._f_translations) {
return this.translations, nil
}
this._f_translations = true
thisIo := this._root._io
_pos, err := thisIo.Pos()
if err != nil {
return nil, err
}
_, err = thisIo.Seek(int64(this.OfsTranslations), io.SeekStart)
if err != nil {
return nil, err
}
switch this._is_le {
case 0:
for i := 0; i < int(this.NumTranslations); i++ {
_ = i
tmp41 := NewGettextMo_Mo_Descriptor()
err = tmp41.Read(thisIo, this, this._root)
if err != nil {
return nil, err
}
this.translations = append(this.translations, tmp41)
}
case 1:
for i := 0; i < int(this.NumTranslations); i++ {
_ = i
tmp42 := NewGettextMo_Mo_Descriptor()
err = tmp42.Read(thisIo, this, this._root)
if err != nil {
return nil, err
}
this.translations = append(this.translations, tmp42)
}
default:
err = kaitai.UndecidedEndiannessError{}
}
_, err = thisIo.Seek(_pos, io.SeekStart)
if err != nil {
return nil, err
}
return this.translations, nil
}
type GettextMo_Mo_Descriptor struct {
LenStr uint32
OfsStr uint32
_io *kaitai.Stream
_root *GettextMo
_parent *GettextMo_Mo
_f_str bool
str string
_is_le int
}
func NewGettextMo_Mo_Descriptor() *GettextMo_Mo_Descriptor {
return &GettextMo_Mo_Descriptor{
}
}
func (this GettextMo_Mo_Descriptor) IO_() *kaitai.Stream {
return this._io
}
func (this *GettextMo_Mo_Descriptor) Read(io *kaitai.Stream, parent *GettextMo_Mo, root *GettextMo) (err error) {
this._io = io
this._parent = parent
this._root = root
this._is_le = this._parent._is_le
switch this._is_le {
case 0:
err = this._read_be()
case 1:
err = this._read_le()
default:
err = kaitai.UndecidedEndiannessError{}
}
return err
}
func (this *GettextMo_Mo_Descriptor) _read_le() (err error) {
tmp43, err := this._io.ReadU4le()
if err != nil {
return err
}
this.LenStr = uint32(tmp43)
tmp44, err := this._io.ReadU4le()
if err != nil {
return err
}
this.OfsStr = uint32(tmp44)
return err
}
func (this *GettextMo_Mo_Descriptor) _read_be() (err error) {
tmp45, err := this._io.ReadU4be()
if err != nil {
return err
}
this.LenStr = uint32(tmp45)
tmp46, err := this._io.ReadU4be()
if err != nil {
return err
}
this.OfsStr = uint32(tmp46)
return err
}
func (this *GettextMo_Mo_Descriptor) Str() (v string, err error) {
if (this._f_str) {
return this.str, nil
}
this._f_str = true
thisIo := this._root._io
_pos, err := thisIo.Pos()
if err != nil {
return "", err
}
_, err = thisIo.Seek(int64(this.OfsStr), io.SeekStart)
if err != nil {
return "", err
}
switch this._is_le {
case 0:
tmp47, err := thisIo.ReadBytes(int(this.LenStr))
if err != nil {
return "", err
}
tmp47 = kaitai.BytesTerminate(tmp47, 0, false)
this.str = string(tmp47)
case 1:
tmp48, err := thisIo.ReadBytes(int(this.LenStr))
if err != nil {
return "", err
}
tmp48 = kaitai.BytesTerminate(tmp48, 0, false)
this.str = string(tmp48)
default:
err = kaitai.UndecidedEndiannessError{}
}
_, err = thisIo.Seek(_pos, io.SeekStart)
if err != nil {
return "", err
}
return this.str, nil
}
type GettextMo_Mo_HashtableItem struct {
RawVal uint32
_io *kaitai.Stream
_root *GettextMo
_parent *GettextMo_Mo
_f_isSystemDependent bool
isSystemDependent bool
_f_mask bool
mask int
_f_val bool
val int
_f_val1 bool
val1 int
_is_le int
}
func NewGettextMo_Mo_HashtableItem() *GettextMo_Mo_HashtableItem {
return &GettextMo_Mo_HashtableItem{
}
}
func (this GettextMo_Mo_HashtableItem) IO_() *kaitai.Stream {
return this._io
}
func (this *GettextMo_Mo_HashtableItem) Read(io *kaitai.Stream, parent *GettextMo_Mo, root *GettextMo) (err error) {
this._io = io
this._parent = parent
this._root = root
this._is_le = this._parent._is_le
switch this._is_le {
case 0:
err = this._read_be()
case 1:
err = this._read_le()
default:
err = kaitai.UndecidedEndiannessError{}
}
return err
}
func (this *GettextMo_Mo_HashtableItem) _read_le() (err error) {
tmp49, err := this._io.ReadU4le()
if err != nil {
return err
}
this.RawVal = uint32(tmp49)
return err
}
func (this *GettextMo_Mo_HashtableItem) _read_be() (err error) {
tmp50, err := this._io.ReadU4be()
if err != nil {
return err
}
this.RawVal = uint32(tmp50)
return err
}
func (this *GettextMo_Mo_HashtableItem) IsSystemDependent() (v bool, err error) {
if (this._f_isSystemDependent) {
return this.isSystemDependent, nil
}
this._f_isSystemDependent = true
if (this.RawVal != 0) {
tmp51, err := this.Val1()
if err != nil {
return false, err
}
tmp52, err := this.Mask()
if err != nil {
return false, err
}
this.isSystemDependent = bool(tmp51 & tmp52 == 1)
}
return this.isSystemDependent, nil
}
func (this *GettextMo_Mo_HashtableItem) Mask() (v int, err error) {
if (this._f_mask) {
return this.mask, nil
}
this._f_mask = true
this.mask = int(uint32(2147483648))
return this.mask, nil
}
func (this *GettextMo_Mo_HashtableItem) Val() (v int, err error) {
if (this._f_val) {
return this.val, nil
}
this._f_val = true
if (this.RawVal != 0) {
tmp53, err := this.Val1()
if err != nil {
return 0, err
}
tmp54, err := this.Mask()
if err != nil {
return 0, err
}
this.val = int(tmp53 & ^(tmp54))
}
return this.val, nil
}
func (this *GettextMo_Mo_HashtableItem) Val1() (v int, err error) {
if (this._f_val1) {
return this.val1, nil
}
this._f_val1 = true
if (this.RawVal != 0) {
this.val1 = int(this.RawVal - 1)
}
return this.val1, nil
}
type GettextMo_Mo_Version struct {
VersionRaw uint32
_io *kaitai.Stream
_root *GettextMo
_parent *GettextMo_Mo
_f_major bool
major int
_f_minor bool
minor int
_is_le int
}
func NewGettextMo_Mo_Version() *GettextMo_Mo_Version {
return &GettextMo_Mo_Version{
}
}
func (this GettextMo_Mo_Version) IO_() *kaitai.Stream {
return this._io
}
func (this *GettextMo_Mo_Version) Read(io *kaitai.Stream, parent *GettextMo_Mo, root *GettextMo) (err error) {
this._io = io
this._parent = parent
this._root = root
this._is_le = this._parent._is_le
switch this._is_le {
case 0:
err = this._read_be()
case 1:
err = this._read_le()
default:
err = kaitai.UndecidedEndiannessError{}
}
return err
}
func (this *GettextMo_Mo_Version) _read_le() (err error) {
tmp55, err := this._io.ReadU4le()
if err != nil {
return err
}
this.VersionRaw = uint32(tmp55)
return err
}
func (this *GettextMo_Mo_Version) _read_be() (err error) {
tmp56, err := this._io.ReadU4be()
if err != nil {
return err
}
this.VersionRaw = uint32(tmp56)
return err
}
func (this *GettextMo_Mo_Version) Major() (v int, err error) {
if (this._f_major) {
return this.major, nil
}
this._f_major = true
this.major = int(this.VersionRaw >> 16)
return this.major, nil
}
func (this *GettextMo_Mo_Version) Minor() (v int, err error) {
if (this._f_minor) {
return this.minor, nil
}
this._f_minor = true
this.minor = int(this.VersionRaw & 65535)
return this.minor, nil
}