1// Copyright (c) 2017, Google Inc. 2// 3// Permission to use, copy, modify, and/or distribute this software for any 4// purpose with or without fee is hereby granted, provided that the above 5// copyright notice and this permission notice appear in all copies. 6// 7// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 8// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 9// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 10// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 11// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 12// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 13// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ 14 15// embed_test_data generates a C++ source file which exports a function, 16// GetTestData, which looks up the specified data files. 17package main 18 19import ( 20 "bytes" 21 "fmt" 22 "io/ioutil" 23 "os" 24 "unicode" 25) 26 27func quote(in []byte) string { 28 var buf bytes.Buffer 29 buf.WriteByte('"') 30 for _, b := range in { 31 switch b { 32 case '\a': 33 buf.WriteString(`\a`) 34 case '\b': 35 buf.WriteString(`\b`) 36 case '\f': 37 buf.WriteString(`\f`) 38 case '\n': 39 buf.WriteString(`\n`) 40 case '\r': 41 buf.WriteString(`\r`) 42 case '\t': 43 buf.WriteString(`\t`) 44 case '\v': 45 buf.WriteString(`\v`) 46 case '"': 47 buf.WriteString(`\"`) 48 default: 49 if rune(b) > 127 || unicode.IsPrint(rune(b)) { 50 buf.WriteByte(b) 51 } else { 52 fmt.Fprintf(&buf, "\\x%02x", b) 53 } 54 } 55 } 56 buf.WriteByte('"') 57 return buf.String() 58} 59 60func main() { 61 fmt.Printf(`/* Copyright (c) 2017, Google Inc. 62 * 63 * Permission to use, copy, modify, and/or distribute this software for any 64 * purpose with or without fee is hereby granted, provided that the above 65 * copyright notice and this permission notice appear in all copies. 66 * 67 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 68 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 69 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 70 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 71 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 72 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 73 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ 74 75/* This file is generated by: 76`) 77 fmt.Printf(" * go run util/embed_test_data.go") 78 for _, arg := range os.Args[1:] { 79 fmt.Printf(" \\\n * %s", arg) 80 } 81 fmt.Printf(" */\n") 82 83 fmt.Printf(` 84/* clang-format off */ 85 86#include <stdlib.h> 87#include <string.h> 88 89#include <algorithm> 90#include <string> 91 92 93`) 94 95 // MSVC limits the length of string constants, so we emit an array of 96 // them and concatenate at runtime. We could also use a single array 97 // literal, but this is less compact. 98 const chunkSize = 8192 99 100 for i, arg := range os.Args[1:] { 101 data, err := ioutil.ReadFile(arg) 102 if err != nil { 103 fmt.Fprintf(os.Stderr, "Error reading %s: %s.\n", data, err) 104 os.Exit(1) 105 } 106 fmt.Printf("static const char *kData%d[] = {\n", i) 107 for i := 0; i < len(data); i += chunkSize { 108 chunk := chunkSize 109 if chunk > len(data)-i { 110 chunk = len(data) - i 111 } 112 fmt.Printf(" %s,\n", quote(data[i:i+chunk])) 113 } 114 fmt.Printf("};\n") 115 fmt.Printf("static const size_t kLen%d = %d;\n\n", i, len(data)) 116 } 117 118 fmt.Printf(`static std::string AssembleString(const char **data, size_t len) { 119 std::string ret; 120 for (size_t i = 0; i < len; i += %d) { 121 size_t chunk = std::min(static_cast<size_t>(%d), len - i); 122 ret.append(data[i / %d], chunk); 123 } 124 return ret; 125} 126 127/* Silence -Wmissing-declarations. */ 128std::string GetTestData(const char *path); 129 130std::string GetTestData(const char *path) { 131`, chunkSize, chunkSize, chunkSize) 132 for i, arg := range os.Args[1:] { 133 fmt.Printf(" if (strcmp(path, %s) == 0) {\n", quote([]byte(arg))) 134 fmt.Printf(" return AssembleString(kData%d, kLen%d);\n", i, i) 135 fmt.Printf(" }\n") 136 } 137 fmt.Printf(` fprintf(stderr, "File not embedded: %%s.\n", path); 138 abort(); 139} 140`) 141 142} 143