github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/core/location/generator/generator.go (about) 1 /* 2 * Copyright (C) 2017 The "MysteriumNetwork/node" Authors. 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 package main 19 20 import ( 21 "bytes" 22 "compress/gzip" 23 "encoding/base64" 24 "flag" 25 "fmt" 26 "os" 27 "path/filepath" 28 "text/template" 29 30 "github.com/pkg/errors" 31 ) 32 33 const undefinedDb = "" 34 35 var outputDirectory = flag.String("output", "generated", "Name of output source directory with binary data") 36 var dbFilename = flag.String("dbname", undefinedDb, "Name of the db file to import") 37 var compress = flag.Bool("compress", false, "Compress data before storing") 38 39 func main() { 40 flag.Parse() 41 if *dbFilename == undefinedDb { 42 fmt.Println("dbname parameter expected") 43 os.Exit(1) 44 } 45 46 binaryData, err := os.ReadFile(*dbFilename) 47 exitOnError(err) 48 originalDataSize := len(binaryData) 49 50 if *compress { 51 binaryData, err = compressData(binaryData) 52 exitOnError(err) 53 } 54 55 encodedData, err := encodeToBase64(binaryData) 56 exitOnError(err) 57 58 //split into 1mb size parts (1part one file) 59 parts := splitToFixedLengthSlices(encodedData, 2*1024*1024) 60 var dbParts []dbPart 61 for i := 0; i < len(parts); i++ { 62 dbParts = append(dbParts, newDbPart(i, parts[i])) 63 } 64 65 tmpl, err := template.New("dbDataTemplate").Parse(dbPartFileOutput) 66 exitOnError(err) 67 for partIdx, dbPart := range dbParts { 68 dbFile, err := os.Create(filepath.Join(*outputDirectory, fmt.Sprintf("db_part_%d.go", partIdx))) 69 exitOnError(err) 70 err = tmpl.Execute(dbFile, dbPart) 71 exitOnError(err) 72 } 73 74 tmpl, err = template.New("dbIndexTemplate").Parse(dbIndexFileOutput) 75 exitOnError(err) 76 idxFile, err := os.Create(filepath.Join(*outputDirectory, "db_index.go")) 77 exitOnError(err) 78 err = tmpl.Execute( 79 idxFile, 80 struct { 81 DbParts []dbPart 82 Compressed bool 83 OriginalSize int 84 }{ 85 DbParts: dbParts, 86 Compressed: *compress, 87 OriginalSize: originalDataSize, 88 }, 89 ) 90 exitOnError(err) 91 } 92 93 func splitToFixedLengthSlices(input []byte, strSize int) [][]byte { 94 var res [][]byte 95 96 fullStringCount := len(input) / strSize 97 98 for i := 0; i < fullStringCount; i++ { 99 offsetStart := i * strSize 100 res = append(res, input[offsetStart:offsetStart+strSize]) 101 } 102 103 if len(input)%strSize > 0 { 104 res = append(res, input[fullStringCount*strSize:]) 105 } 106 return res 107 } 108 109 func encodeToBase64(data []byte) ([]byte, error) { 110 encodedDataBuffer := &bytes.Buffer{} 111 encodingWriter := base64.NewEncoder(base64.RawStdEncoding, encodedDataBuffer) 112 written, err := encodingWriter.Write(data) 113 if err != nil { 114 return nil, err 115 } 116 if written != len(data) { 117 return nil, errors.New("written and expected data length mismatch") 118 } 119 encodingWriter.Close() 120 return encodedDataBuffer.Bytes(), nil 121 } 122 123 func compressData(data []byte) ([]byte, error) { 124 buff := &bytes.Buffer{} 125 compressingWriter, err := gzip.NewWriterLevel(buff, gzip.BestCompression) 126 if err != nil { 127 return nil, err 128 } 129 130 written, err := compressingWriter.Write(data) 131 if err != nil { 132 return nil, err 133 } 134 if written != len(data) { 135 return nil, errors.New("unexpected written and original data size") 136 } 137 compressingWriter.Close() 138 return buff.Bytes(), nil 139 } 140 141 func exitOnError(err error) { 142 if err != nil { 143 fmt.Println("Error: ", err.Error()) 144 os.Exit(1) 145 } 146 } 147 148 type dbPart struct { 149 ID int 150 Lines []string 151 } 152 153 func newDbPart(id int, binaryData []byte) dbPart { 154 var lines []string 155 for _, binaryPart := range splitToFixedLengthSlices(binaryData, 10*1024*1024) { 156 lines = append(lines, string(binaryPart)) 157 } 158 159 return dbPart{ 160 ID: id, 161 Lines: lines, 162 } 163 } 164 165 var dbPartFileOutput = `/* 166 * Copyright (C) 2017 The "MysteriumNetwork/node" Authors. 167 * 168 * This program is free software: you can redistribute it and/or modify 169 * it under the terms of the GNU General Public License as published by 170 * the Free Software Foundation, either version 3 of the License, or 171 * (at your option) any later version. 172 * 173 * This program is distributed in the hope that it will be useful, 174 * but WITHOUT ANY WARRANTY; without even the implied warranty of 175 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 176 * GNU General Public License for more details. 177 * 178 * You should have received a copy of the GNU General Public License 179 * along with this program. If not, see <http://www.gnu.org/licenses/>. 180 */ 181 182 package gendb 183 184 // generated by generator.go - DO NOT EDIT 185 186 const dbDataPart{{.ID}} = {{range .Lines}}"{{.}}" + 187 {{end}}"" 188 ` 189 190 var dbIndexFileOutput = `/* 191 * Copyright (C) 2017 The "MysteriumNetwork/node" Authors. 192 * 193 * This program is free software: you can redistribute it and/or modify 194 * it under the terms of the GNU General Public License as published by 195 * the Free Software Foundation, either version 3 of the License, or 196 * (at your option) any later version. 197 * 198 * This program is distributed in the hope that it will be useful, 199 * but WITHOUT ANY WARRANTY; without even the implied warranty of 200 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 201 * GNU General Public License for more details. 202 * 203 * You should have received a copy of the GNU General Public License 204 * along with this program. If not, see <http://www.gnu.org/licenses/>. 205 */ 206 207 package gendb 208 209 // generated by generator.go - DO NOT EDIT 210 211 const originalSize = {{.OriginalSize}} 212 const dbData = ""{{range .DbParts}} + dbDataPart{{.ID}}{{end}} 213 214 // LoadData returns emmbeded database as byte array 215 func LoadData() ([]byte, error) { 216 return EncodedDataLoader(dbData, originalSize, {{.Compressed}}) 217 } 218 `