1// Copyright 2014-2017 Ulrich Kunitz. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5package lzma 6 7import ( 8 "errors" 9 "fmt" 10) 11 12// maximum and minimum values for the LZMA properties. 13const ( 14 minPB = 0 15 maxPB = 4 16) 17 18// maxPropertyCode is the possible maximum of a properties code byte. 19const maxPropertyCode = (maxPB+1)*(maxLP+1)*(maxLC+1) - 1 20 21// Properties contains the parameters LC, LP and PB. The parameter LC 22// defines the number of literal context bits; parameter LP the number 23// of literal position bits and PB the number of position bits. 24type Properties struct { 25 LC int 26 LP int 27 PB int 28} 29 30// String returns the properties in a string representation. 31func (p *Properties) String() string { 32 return fmt.Sprintf("LC %d LP %d PB %d", p.LC, p.LP, p.PB) 33} 34 35// PropertiesForCode converts a properties code byte into a Properties value. 36func PropertiesForCode(code byte) (p Properties, err error) { 37 if code > maxPropertyCode { 38 return p, errors.New("lzma: invalid properties code") 39 } 40 p.LC = int(code % 9) 41 code /= 9 42 p.LP = int(code % 5) 43 code /= 5 44 p.PB = int(code % 5) 45 return p, err 46} 47 48// verify checks the properties for correctness. 49func (p *Properties) verify() error { 50 if p == nil { 51 return errors.New("lzma: properties are nil") 52 } 53 if !(minLC <= p.LC && p.LC <= maxLC) { 54 return errors.New("lzma: lc out of range") 55 } 56 if !(minLP <= p.LP && p.LP <= maxLP) { 57 return errors.New("lzma: lp out of range") 58 } 59 if !(minPB <= p.PB && p.PB <= maxPB) { 60 return errors.New("lzma: pb out of range") 61 } 62 return nil 63} 64 65// Code converts the properties to a byte. The function assumes that 66// the properties components are all in range. 67func (p Properties) Code() byte { 68 return byte((p.PB*5+p.LP)*9 + p.LC) 69} 70