package structs12import (3_ "embed"45"github.com/projectdiscovery/gostruct"6)78// StructsUnpack the byte slice (presumably packed by Pack(format, msg)) according to the given format.9// The result is a []interface{} slice even if it contains exactly one item.10// The byte slice must contain not less the amount of data required by the format11// (len(msg) must more or equal CalcSize(format)).12// Ex: structs.Unpack(">I", buff[:nb])13// @example14// ```javascript15// const structs = require('nuclei/structs');16// const result = structs.Unpack('H', [0]);17// ```18func Unpack(format string, msg []byte) ([]interface{}, error) {19return gostruct.UnPack(buildFormatSliceFromStringFormat(format), msg)20}2122// StructsPack returns a byte slice containing the values of msg slice packed according to the given format.23// The items of msg slice must match the values required by the format exactly.24// Ex: structs.pack("H", 0)25// @example26// ```javascript27// const structs = require('nuclei/structs');28// const packed = structs.Pack('H', [0]);29// ```30func Pack(formatStr string, msg interface{}) ([]byte, error) {31var args []interface{}32switch v := msg.(type) {33case []interface{}:34args = v35default:36args = []interface{}{v}37}38format := buildFormatSliceFromStringFormat(formatStr)3940var idxMsg int41for _, f := range format {42switch f {43case "<", ">", "!":44case "h", "H", "i", "I", "l", "L", "q", "Q", "b", "B":45switch v := args[idxMsg].(type) {46case int64:47args[idxMsg] = int(v)48}49idxMsg++50}51}52return gostruct.Pack(format, args)53}5455// StructsCalcSize returns the number of bytes needed to pack the values according to the given format.56// Ex: structs.CalcSize("H")57// @example58// ```javascript59// const structs = require('nuclei/structs');60// const size = structs.CalcSize('H');61// ```62func StructsCalcSize(format string) (int, error) {63return gostruct.CalcSize(buildFormatSliceFromStringFormat(format))64}6566func buildFormatSliceFromStringFormat(format string) []string {67var formats []string68temp := ""6970for _, c := range format {71if c >= '0' && c <= '9' {72temp += string(c)73} else {74if temp != "" {75formats = append(formats, temp+string(c))76temp = ""77} else {78formats = append(formats, string(c))79}80}81}82if temp != "" {83formats = append(formats, temp)84}85return formats86}878889