1*61c4878aSAndroid Build Coastguard Worker// Copyright 2024 The Pigweed Authors 2*61c4878aSAndroid Build Coastguard Worker// 3*61c4878aSAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License"); you may not 4*61c4878aSAndroid Build Coastguard Worker// use this file except in compliance with the License. You may obtain a copy of 5*61c4878aSAndroid Build Coastguard Worker// the License at 6*61c4878aSAndroid Build Coastguard Worker// 7*61c4878aSAndroid Build Coastguard Worker// https://www.apache.org/licenses/LICENSE-2.0 8*61c4878aSAndroid Build Coastguard Worker// 9*61c4878aSAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software 10*61c4878aSAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11*61c4878aSAndroid Build Coastguard Worker// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12*61c4878aSAndroid Build Coastguard Worker// License for the specific language governing permissions and limitations under 13*61c4878aSAndroid Build Coastguard Worker// the License. 14*61c4878aSAndroid Build Coastguard Worker 15*61c4878aSAndroid Build Coastguard Worker// Program hpack_gen generates a C++ file to help parse and emit HPACK. 16*61c4878aSAndroid Build Coastguard Workerpackage main 17*61c4878aSAndroid Build Coastguard Worker 18*61c4878aSAndroid Build Coastguard Workerimport ( 19*61c4878aSAndroid Build Coastguard Worker "fmt" 20*61c4878aSAndroid Build Coastguard Worker) 21*61c4878aSAndroid Build Coastguard Worker 22*61c4878aSAndroid Build Coastguard Workerfunc main() { 23*61c4878aSAndroid Build Coastguard Worker var statsBefore, statsAfter Stats 24*61c4878aSAndroid Build Coastguard Worker 25*61c4878aSAndroid Build Coastguard Worker buildTree() 26*61c4878aSAndroid Build Coastguard Worker validate(&rootNode) 27*61c4878aSAndroid Build Coastguard Worker computeStats(&statsBefore, &rootNode) 28*61c4878aSAndroid Build Coastguard Worker 29*61c4878aSAndroid Build Coastguard Worker optimize(&rootNode) 30*61c4878aSAndroid Build Coastguard Worker validate(&rootNode) 31*61c4878aSAndroid Build Coastguard Worker computeStats(&statsAfter, &rootNode) 32*61c4878aSAndroid Build Coastguard Worker 33*61c4878aSAndroid Build Coastguard Worker assignTableIndices(&rootNode, 0) 34*61c4878aSAndroid Build Coastguard Worker 35*61c4878aSAndroid Build Coastguard Worker fmt.Println("// Copyright 2024 The Pigweed Authors") 36*61c4878aSAndroid Build Coastguard Worker fmt.Println("//") 37*61c4878aSAndroid Build Coastguard Worker fmt.Println("// Licensed under the Apache License, Version 2.0 (the \"License\"); you may not") 38*61c4878aSAndroid Build Coastguard Worker fmt.Println("// use this file except in compliance with the License. You may obtain a copy of") 39*61c4878aSAndroid Build Coastguard Worker fmt.Println("// the License at") 40*61c4878aSAndroid Build Coastguard Worker fmt.Println("//") 41*61c4878aSAndroid Build Coastguard Worker fmt.Println("// https://www.apache.org/licenses/LICENSE-2.0") 42*61c4878aSAndroid Build Coastguard Worker fmt.Println("//") 43*61c4878aSAndroid Build Coastguard Worker fmt.Println("// Unless required by applicable law or agreed to in writing, software") 44*61c4878aSAndroid Build Coastguard Worker fmt.Println("// distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT") 45*61c4878aSAndroid Build Coastguard Worker fmt.Println("// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the") 46*61c4878aSAndroid Build Coastguard Worker fmt.Println("// License for the specific language governing permissions and limitations under") 47*61c4878aSAndroid Build Coastguard Worker fmt.Println("// the License.") 48*61c4878aSAndroid Build Coastguard Worker fmt.Println("//") 49*61c4878aSAndroid Build Coastguard Worker fmt.Println("// AUTOGENERATED FILE, DO NOT EDIT") 50*61c4878aSAndroid Build Coastguard Worker fmt.Println("//") 51*61c4878aSAndroid Build Coastguard Worker fmt.Println("// To regenerate, run `go run gen/hpack_gen.go > hpack.autogen.inc`.") 52*61c4878aSAndroid Build Coastguard Worker fmt.Println("// This file should be included in exactly one *.cc file.") 53*61c4878aSAndroid Build Coastguard Worker fmt.Println("//") 54*61c4878aSAndroid Build Coastguard Worker fmt.Println() 55*61c4878aSAndroid Build Coastguard Worker fmt.Println("// clang-format off") 56*61c4878aSAndroid Build Coastguard Worker printDecoderTable(&statsAfter) 57*61c4878aSAndroid Build Coastguard Worker fmt.Println() 58*61c4878aSAndroid Build Coastguard Worker fmt.Printf("// Decoder table stats:\n") 59*61c4878aSAndroid Build Coastguard Worker fmt.Printf("// before optimization = %+v\n", statsBefore) 60*61c4878aSAndroid Build Coastguard Worker fmt.Printf("// after optimization = %+v\n", statsAfter) 61*61c4878aSAndroid Build Coastguard Worker fmt.Println() 62*61c4878aSAndroid Build Coastguard Worker printStaticResponses() 63*61c4878aSAndroid Build Coastguard Worker} 64*61c4878aSAndroid Build Coastguard Worker 65*61c4878aSAndroid Build Coastguard Workertype NodeType int 66*61c4878aSAndroid Build Coastguard Worker 67*61c4878aSAndroid Build Coastguard Workerconst ( 68*61c4878aSAndroid Build Coastguard Worker BranchNode NodeType = iota 69*61c4878aSAndroid Build Coastguard Worker OutputNode 70*61c4878aSAndroid Build Coastguard Worker UnprintableNode 71*61c4878aSAndroid Build Coastguard Worker EOSNode 72*61c4878aSAndroid Build Coastguard Worker) 73*61c4878aSAndroid Build Coastguard Worker 74*61c4878aSAndroid Build Coastguard Workertype Node struct { 75*61c4878aSAndroid Build Coastguard Worker t NodeType 76*61c4878aSAndroid Build Coastguard Worker output int // if t == OutputNode, byte to output 77*61c4878aSAndroid Build Coastguard Worker tableIndex int // if t == BranchNode, index in the decoder table 78*61c4878aSAndroid Build Coastguard Worker child [2]*Node 79*61c4878aSAndroid Build Coastguard Worker} 80*61c4878aSAndroid Build Coastguard Worker 81*61c4878aSAndroid Build Coastguard Workervar rootNode = Node{t: BranchNode} 82*61c4878aSAndroid Build Coastguard Worker 83*61c4878aSAndroid Build Coastguard Workertype Stats struct { 84*61c4878aSAndroid Build Coastguard Worker numBranchNodes int 85*61c4878aSAndroid Build Coastguard Worker numOutputNodes int 86*61c4878aSAndroid Build Coastguard Worker numUnprintableNodes int 87*61c4878aSAndroid Build Coastguard Worker numInvalidNodes int 88*61c4878aSAndroid Build Coastguard Worker} 89*61c4878aSAndroid Build Coastguard Worker 90*61c4878aSAndroid Build Coastguard Workerfunc buildTree() { 91*61c4878aSAndroid Build Coastguard Worker for out, code := range huffmanTable { 92*61c4878aSAndroid Build Coastguard Worker updateTree(out, code) 93*61c4878aSAndroid Build Coastguard Worker } 94*61c4878aSAndroid Build Coastguard Worker} 95*61c4878aSAndroid Build Coastguard Worker 96*61c4878aSAndroid Build Coastguard Workerfunc updateTree(out int, code string) { 97*61c4878aSAndroid Build Coastguard Worker if len(code) == 0 { 98*61c4878aSAndroid Build Coastguard Worker panic(fmt.Sprintf("code for byte %v is empty", out)) 99*61c4878aSAndroid Build Coastguard Worker } 100*61c4878aSAndroid Build Coastguard Worker 101*61c4878aSAndroid Build Coastguard Worker curr := &rootNode 102*61c4878aSAndroid Build Coastguard Worker 103*61c4878aSAndroid Build Coastguard Worker for i := 0; i < len(code); i++ { 104*61c4878aSAndroid Build Coastguard Worker if code[i] != '0' && code[i] != '1' { 105*61c4878aSAndroid Build Coastguard Worker panic(fmt.Sprintf("code for byte %v has invalid bit '%v'", out, code[i])) 106*61c4878aSAndroid Build Coastguard Worker } 107*61c4878aSAndroid Build Coastguard Worker 108*61c4878aSAndroid Build Coastguard Worker bit := code[i] - '0' 109*61c4878aSAndroid Build Coastguard Worker 110*61c4878aSAndroid Build Coastguard Worker // Middle of the code: create a branch node if needed. 111*61c4878aSAndroid Build Coastguard Worker if i < len(code)-1 { 112*61c4878aSAndroid Build Coastguard Worker next := curr.child[bit] 113*61c4878aSAndroid Build Coastguard Worker if next == nil { 114*61c4878aSAndroid Build Coastguard Worker next = &Node{t: BranchNode} 115*61c4878aSAndroid Build Coastguard Worker curr.child[bit] = next 116*61c4878aSAndroid Build Coastguard Worker } else if next.t != BranchNode { 117*61c4878aSAndroid Build Coastguard Worker panic(fmt.Sprintf("code for byte %v found non-branch node at bit number %v", out, i)) 118*61c4878aSAndroid Build Coastguard Worker } 119*61c4878aSAndroid Build Coastguard Worker curr = next 120*61c4878aSAndroid Build Coastguard Worker continue 121*61c4878aSAndroid Build Coastguard Worker } 122*61c4878aSAndroid Build Coastguard Worker 123*61c4878aSAndroid Build Coastguard Worker // End of the code: create a leaf node. 124*61c4878aSAndroid Build Coastguard Worker // Each code should lead to a unique leaf node. 125*61c4878aSAndroid Build Coastguard Worker if curr.child[bit] != nil { 126*61c4878aSAndroid Build Coastguard Worker panic(fmt.Sprintf("code for byte %v reached a duplicate leaf node", out)) 127*61c4878aSAndroid Build Coastguard Worker } 128*61c4878aSAndroid Build Coastguard Worker 129*61c4878aSAndroid Build Coastguard Worker switch { 130*61c4878aSAndroid Build Coastguard Worker case out == EOS: 131*61c4878aSAndroid Build Coastguard Worker curr.child[bit] = &Node{t: EOSNode} 132*61c4878aSAndroid Build Coastguard Worker case out < 32 || 127 < out: 133*61c4878aSAndroid Build Coastguard Worker // Unprintable characters are allowed by the Huffman code but not in gRPC. 134*61c4878aSAndroid Build Coastguard Worker // See: https://github.com/grpc/grpc/blob/v1.60.x/doc/PROTOCOL-HTTP2.md#requests. 135*61c4878aSAndroid Build Coastguard Worker curr.child[bit] = &Node{t: UnprintableNode} 136*61c4878aSAndroid Build Coastguard Worker default: 137*61c4878aSAndroid Build Coastguard Worker curr.child[bit] = &Node{t: OutputNode, output: out} 138*61c4878aSAndroid Build Coastguard Worker } 139*61c4878aSAndroid Build Coastguard Worker } 140*61c4878aSAndroid Build Coastguard Worker} 141*61c4878aSAndroid Build Coastguard Worker 142*61c4878aSAndroid Build Coastguard Workerfunc validate(node *Node) { 143*61c4878aSAndroid Build Coastguard Worker // The binary tree should be complete: there should not be missing leaf nodes. 144*61c4878aSAndroid Build Coastguard Worker if node == nil { 145*61c4878aSAndroid Build Coastguard Worker panic("unexpected nil in binary tree") 146*61c4878aSAndroid Build Coastguard Worker } 147*61c4878aSAndroid Build Coastguard Worker if node.t != BranchNode { 148*61c4878aSAndroid Build Coastguard Worker if node.child[0] != nil || node.child[1] != nil { 149*61c4878aSAndroid Build Coastguard Worker panic(fmt.Sprintf("unexpected child under node %+v", node)) 150*61c4878aSAndroid Build Coastguard Worker } 151*61c4878aSAndroid Build Coastguard Worker return 152*61c4878aSAndroid Build Coastguard Worker } 153*61c4878aSAndroid Build Coastguard Worker validate(node.child[0]) 154*61c4878aSAndroid Build Coastguard Worker validate(node.child[1]) 155*61c4878aSAndroid Build Coastguard Worker} 156*61c4878aSAndroid Build Coastguard Worker 157*61c4878aSAndroid Build Coastguard Workerfunc optimize(node *Node) { 158*61c4878aSAndroid Build Coastguard Worker if node.t != BranchNode { 159*61c4878aSAndroid Build Coastguard Worker return 160*61c4878aSAndroid Build Coastguard Worker } 161*61c4878aSAndroid Build Coastguard Worker optimize(node.child[0]) 162*61c4878aSAndroid Build Coastguard Worker optimize(node.child[1]) 163*61c4878aSAndroid Build Coastguard Worker // Collapse each unprintable subtree into a single unprintable node. 164*61c4878aSAndroid Build Coastguard Worker if node.child[0].t == UnprintableNode && node.child[1].t == UnprintableNode { 165*61c4878aSAndroid Build Coastguard Worker node.t = UnprintableNode 166*61c4878aSAndroid Build Coastguard Worker node.child[0] = nil 167*61c4878aSAndroid Build Coastguard Worker node.child[1] = nil 168*61c4878aSAndroid Build Coastguard Worker } 169*61c4878aSAndroid Build Coastguard Worker} 170*61c4878aSAndroid Build Coastguard Worker 171*61c4878aSAndroid Build Coastguard Workerfunc computeStats(stats *Stats, node *Node) { 172*61c4878aSAndroid Build Coastguard Worker if node == nil { 173*61c4878aSAndroid Build Coastguard Worker stats.numInvalidNodes++ 174*61c4878aSAndroid Build Coastguard Worker return 175*61c4878aSAndroid Build Coastguard Worker } 176*61c4878aSAndroid Build Coastguard Worker switch node.t { 177*61c4878aSAndroid Build Coastguard Worker case BranchNode: 178*61c4878aSAndroid Build Coastguard Worker stats.numBranchNodes++ 179*61c4878aSAndroid Build Coastguard Worker computeStats(stats, node.child[0]) 180*61c4878aSAndroid Build Coastguard Worker computeStats(stats, node.child[1]) 181*61c4878aSAndroid Build Coastguard Worker case OutputNode: 182*61c4878aSAndroid Build Coastguard Worker stats.numOutputNodes++ 183*61c4878aSAndroid Build Coastguard Worker case UnprintableNode: 184*61c4878aSAndroid Build Coastguard Worker stats.numUnprintableNodes++ 185*61c4878aSAndroid Build Coastguard Worker case EOSNode: 186*61c4878aSAndroid Build Coastguard Worker stats.numInvalidNodes++ 187*61c4878aSAndroid Build Coastguard Worker } 188*61c4878aSAndroid Build Coastguard Worker} 189*61c4878aSAndroid Build Coastguard Worker 190*61c4878aSAndroid Build Coastguard Workerfunc assignTableIndices(node *Node, idx int) int { 191*61c4878aSAndroid Build Coastguard Worker if node.t != BranchNode { 192*61c4878aSAndroid Build Coastguard Worker return idx 193*61c4878aSAndroid Build Coastguard Worker } 194*61c4878aSAndroid Build Coastguard Worker node.tableIndex = idx 195*61c4878aSAndroid Build Coastguard Worker idx++ 196*61c4878aSAndroid Build Coastguard Worker // We use a preorder traversal to ensure the root node has index 0. 197*61c4878aSAndroid Build Coastguard Worker idx = assignTableIndices(node.child[0], idx) 198*61c4878aSAndroid Build Coastguard Worker idx = assignTableIndices(node.child[1], idx) 199*61c4878aSAndroid Build Coastguard Worker return idx 200*61c4878aSAndroid Build Coastguard Worker} 201*61c4878aSAndroid Build Coastguard Worker 202*61c4878aSAndroid Build Coastguard Workerconst decoderTablePrefix = ` 203*61c4878aSAndroid Build Coastguard Worker// Huffman decoder table. Decoding starts at index=0. For each bit, we inspect 204*61c4878aSAndroid Build Coastguard Worker// kHuffmanDecoderTable[index][bit] and take an action based on that value: 205*61c4878aSAndroid Build Coastguard Worker// 206*61c4878aSAndroid Build Coastguard Worker// * If the value matches 0b0..._...., set index=value 207*61c4878aSAndroid Build Coastguard Worker// * If the value matches 0b1xxx_xxxx, output byte 32 + xx_xxxx, set index=0 208*61c4878aSAndroid Build Coastguard Worker// * If the value matches 0b1111_1110, fail: unprintable character 209*61c4878aSAndroid Build Coastguard Worker// * If the value matches 0b1111_1111, fail: decoder entered an invalid state 210*61c4878aSAndroid Build Coastguard Worker// 211*61c4878aSAndroid Build Coastguard Workerstatic constexpr std::array<uint8_t[2], %d> kHuffmanDecoderTable = {{ 212*61c4878aSAndroid Build Coastguard Worker` 213*61c4878aSAndroid Build Coastguard Workerconst decoderTableSuffix = ` 214*61c4878aSAndroid Build Coastguard Worker}}; 215*61c4878aSAndroid Build Coastguard Worker` 216*61c4878aSAndroid Build Coastguard Worker 217*61c4878aSAndroid Build Coastguard Workerfunc printDecoderTable(stats *Stats) { 218*61c4878aSAndroid Build Coastguard Worker fmt.Printf(decoderTablePrefix, stats.numBranchNodes) 219*61c4878aSAndroid Build Coastguard Worker printDecoderTableEntries(&rootNode) 220*61c4878aSAndroid Build Coastguard Worker fmt.Print(decoderTableSuffix) 221*61c4878aSAndroid Build Coastguard Worker} 222*61c4878aSAndroid Build Coastguard Worker 223*61c4878aSAndroid Build Coastguard Workerfunc printDecoderTableEntries(node *Node) { 224*61c4878aSAndroid Build Coastguard Worker if node.t != BranchNode { 225*61c4878aSAndroid Build Coastguard Worker return 226*61c4878aSAndroid Build Coastguard Worker } 227*61c4878aSAndroid Build Coastguard Worker 228*61c4878aSAndroid Build Coastguard Worker // Print nodes in preorder, which is the same order the indices were created. 229*61c4878aSAndroid Build Coastguard Worker fmt.Printf(" /*%v=*/ {%v, %v},\n", 230*61c4878aSAndroid Build Coastguard Worker node.tableIndex, 231*61c4878aSAndroid Build Coastguard Worker toDecoderTableEntry(node.child[0]), 232*61c4878aSAndroid Build Coastguard Worker toDecoderTableEntry(node.child[1])) 233*61c4878aSAndroid Build Coastguard Worker 234*61c4878aSAndroid Build Coastguard Worker printDecoderTableEntries(node.child[0]) 235*61c4878aSAndroid Build Coastguard Worker printDecoderTableEntries(node.child[1]) 236*61c4878aSAndroid Build Coastguard Worker} 237*61c4878aSAndroid Build Coastguard Worker 238*61c4878aSAndroid Build Coastguard Workerfunc toDecoderTableEntry(node *Node) uint8 { 239*61c4878aSAndroid Build Coastguard Worker switch node.t { 240*61c4878aSAndroid Build Coastguard Worker case BranchNode: 241*61c4878aSAndroid Build Coastguard Worker if node.tableIndex > 127 { 242*61c4878aSAndroid Build Coastguard Worker panic(fmt.Sprintf("BranchNode index %d > 127", node.tableIndex)) 243*61c4878aSAndroid Build Coastguard Worker } 244*61c4878aSAndroid Build Coastguard Worker return uint8(node.tableIndex) 245*61c4878aSAndroid Build Coastguard Worker case OutputNode: 246*61c4878aSAndroid Build Coastguard Worker return uint8(node.output-32) | 0b1000_0000 247*61c4878aSAndroid Build Coastguard Worker case UnprintableNode: 248*61c4878aSAndroid Build Coastguard Worker return 0b1111_1110 249*61c4878aSAndroid Build Coastguard Worker case EOSNode: 250*61c4878aSAndroid Build Coastguard Worker // RFC 7541 §5.2: "A Huffman-encoded string literal containing the EOS 251*61c4878aSAndroid Build Coastguard Worker // symbol MUST be treated as a decoding error." 252*61c4878aSAndroid Build Coastguard Worker return 0b1111_1111 253*61c4878aSAndroid Build Coastguard Worker } 254*61c4878aSAndroid Build Coastguard Worker panic(fmt.Sprintf("unexpected node type %v", node.t)) 255*61c4878aSAndroid Build Coastguard Worker} 256*61c4878aSAndroid Build Coastguard Worker 257*61c4878aSAndroid Build Coastguard Workerconst responseHeaderFieldsPrefix = ` 258*61c4878aSAndroid Build Coastguard Worker// HPACK-encoded header fields which form grpc Response-Headers. 259*61c4878aSAndroid Build Coastguard Worker// These are the same for every response. 260*61c4878aSAndroid Build Coastguard Workerstatic constexpr std::array<uint8_t, %d> kResponseHeaderFields = { 261*61c4878aSAndroid Build Coastguard Worker` 262*61c4878aSAndroid Build Coastguard Worker 263*61c4878aSAndroid Build Coastguard Workerconst responseHeaderFieldsSuffix = ` 264*61c4878aSAndroid Build Coastguard Worker}; 265*61c4878aSAndroid Build Coastguard Worker` 266*61c4878aSAndroid Build Coastguard Worker 267*61c4878aSAndroid Build Coastguard Workerconst maxStatusCode = 16 268*61c4878aSAndroid Build Coastguard Workerconst responseTrailerFieldsPrefix = ` 269*61c4878aSAndroid Build Coastguard Worker// HPACK-encoded header fields which form grpc Trailers. All response Trailers 270*61c4878aSAndroid Build Coastguard Worker// are identical except for the status code. 271*61c4878aSAndroid Build Coastguard Worker// 272*61c4878aSAndroid Build Coastguard Worker// This is indexed by pw::Status::Code, which happens to be identical to grpc's 273*61c4878aSAndroid Build Coastguard Worker// status code. 274*61c4878aSAndroid Build Coastguard Workerstruct ResponseTrailerPayload { 275*61c4878aSAndroid Build Coastguard Worker uint32_t size; 276*61c4878aSAndroid Build Coastguard Worker std::array<uint8_t, %d> bytes; 277*61c4878aSAndroid Build Coastguard Worker}; 278*61c4878aSAndroid Build Coastguard Workerstatic constexpr std::array<ResponseTrailerPayload, %d> kResponseTrailerFields = {{ 279*61c4878aSAndroid Build Coastguard Worker` 280*61c4878aSAndroid Build Coastguard Worker 281*61c4878aSAndroid Build Coastguard Workerconst responseTrailerFieldsSuffix = ` 282*61c4878aSAndroid Build Coastguard Worker}}; 283*61c4878aSAndroid Build Coastguard Worker` 284*61c4878aSAndroid Build Coastguard Worker 285*61c4878aSAndroid Build Coastguard Workerfunc printStaticResponses() { 286*61c4878aSAndroid Build Coastguard Worker respHeaderFields := buildResponseHeaderFields() 287*61c4878aSAndroid Build Coastguard Worker fmt.Printf(responseHeaderFieldsPrefix, len(respHeaderFields)) 288*61c4878aSAndroid Build Coastguard Worker fmt.Printf(" %s", fmtBytes(respHeaderFields)) 289*61c4878aSAndroid Build Coastguard Worker fmt.Printf("%s", responseHeaderFieldsSuffix) 290*61c4878aSAndroid Build Coastguard Worker 291*61c4878aSAndroid Build Coastguard Worker maxLen := len(buildResponseTrailerFields(maxStatusCode)) 292*61c4878aSAndroid Build Coastguard Worker fmt.Printf(responseTrailerFieldsPrefix, maxLen, maxStatusCode+1) 293*61c4878aSAndroid Build Coastguard Worker for code := 0; code <= maxStatusCode; code++ { 294*61c4878aSAndroid Build Coastguard Worker payload := buildResponseTrailerFields(code) 295*61c4878aSAndroid Build Coastguard Worker fmt.Printf(" {.size=%d, .bytes={%s}},\n", len(payload), fmtBytes(payload)) 296*61c4878aSAndroid Build Coastguard Worker } 297*61c4878aSAndroid Build Coastguard Worker fmt.Printf("%s", responseTrailerFieldsSuffix) 298*61c4878aSAndroid Build Coastguard Worker} 299*61c4878aSAndroid Build Coastguard Worker 300*61c4878aSAndroid Build Coastguard Workerfunc fmtBytes(bytes []byte) string { 301*61c4878aSAndroid Build Coastguard Worker var out string 302*61c4878aSAndroid Build Coastguard Worker for i, b := range bytes { 303*61c4878aSAndroid Build Coastguard Worker if i < len(bytes)-1 { 304*61c4878aSAndroid Build Coastguard Worker out += fmt.Sprintf("0x%x, ", b) 305*61c4878aSAndroid Build Coastguard Worker } else { 306*61c4878aSAndroid Build Coastguard Worker out += fmt.Sprintf("0x%x", b) 307*61c4878aSAndroid Build Coastguard Worker } 308*61c4878aSAndroid Build Coastguard Worker } 309*61c4878aSAndroid Build Coastguard Worker return out 310*61c4878aSAndroid Build Coastguard Worker} 311*61c4878aSAndroid Build Coastguard Worker 312*61c4878aSAndroid Build Coastguard Worker// Response-Headers → ":status 200" "content-type application/grpc" 313*61c4878aSAndroid Build Coastguard Workerfunc buildResponseHeaderFields() []byte { 314*61c4878aSAndroid Build Coastguard Worker var out []byte 315*61c4878aSAndroid Build Coastguard Worker out = append(out, 0b1000_1000) // RFC 7541 §6.1: index 8 is ":status" "200" 316*61c4878aSAndroid Build Coastguard Worker out = append(out, 0b0101_1111) // RFC 7541 §6.2.1: index 31 is "content-type" 317*61c4878aSAndroid Build Coastguard Worker out = append(out, literalEncodeWithLength("application/grpc")...) 318*61c4878aSAndroid Build Coastguard Worker return out 319*61c4878aSAndroid Build Coastguard Worker} 320*61c4878aSAndroid Build Coastguard Worker 321*61c4878aSAndroid Build Coastguard Worker// Trailers → "grpc-status <DIGITS>" 322*61c4878aSAndroid Build Coastguard Workerfunc buildResponseTrailerFields(statusCode int) []byte { 323*61c4878aSAndroid Build Coastguard Worker var out []byte 324*61c4878aSAndroid Build Coastguard Worker out = append(out, 0b0100_0000) // RFC 7541 §6.2.1: literal name and value 325*61c4878aSAndroid Build Coastguard Worker out = append(out, literalEncodeWithLength("grpc-status")...) 326*61c4878aSAndroid Build Coastguard Worker if statusCode >= 10 { 327*61c4878aSAndroid Build Coastguard Worker out = append(out, 0b0000_0010) // RFC 7541 §6.2.1: length of value w/out huffman 328*61c4878aSAndroid Build Coastguard Worker out = append(out, byte(statusCode/10)+'0') // RFC 7541 §6.2.1: value 329*61c4878aSAndroid Build Coastguard Worker out = append(out, byte(statusCode%10)+'0') 330*61c4878aSAndroid Build Coastguard Worker } else { 331*61c4878aSAndroid Build Coastguard Worker out = append(out, 0b0000_0001) // RFC 7541 §6.2.1: length of value w/out huffman 332*61c4878aSAndroid Build Coastguard Worker out = append(out, byte(statusCode)+'0') // RFC 7541 §6.2.1: value 333*61c4878aSAndroid Build Coastguard Worker } 334*61c4878aSAndroid Build Coastguard Worker return out 335*61c4878aSAndroid Build Coastguard Worker} 336*61c4878aSAndroid Build Coastguard Worker 337*61c4878aSAndroid Build Coastguard Workerfunc literalEncodeWithLength(str string) []byte { 338*61c4878aSAndroid Build Coastguard Worker // RFC 7541 §6.2.1: we are generating this structure with H=0. Since the 339*61c4878aSAndroid Build Coastguard Worker // strings are short, there is minimal benefit to using a Huffman encoding, 340*61c4878aSAndroid Build Coastguard Worker // at most 2-3 bytes per string. 341*61c4878aSAndroid Build Coastguard Worker // +---+---+-----------------------+ 342*61c4878aSAndroid Build Coastguard Worker // | H | Value Length (7+) | 343*61c4878aSAndroid Build Coastguard Worker // +---+---------------------------+ 344*61c4878aSAndroid Build Coastguard Worker // | Value String (Length octets) | 345*61c4878aSAndroid Build Coastguard Worker // +-------------------------------+ 346*61c4878aSAndroid Build Coastguard Worker // 347*61c4878aSAndroid Build Coastguard Worker // The length must be encoded across multiple bytes if 128 or larger. See RFC 348*61c4878aSAndroid Build Coastguard Worker // 7541 §5.2. We don't write any strings that large. 349*61c4878aSAndroid Build Coastguard Worker if len(str) >= 128 { 350*61c4878aSAndroid Build Coastguard Worker panic(fmt.Sprintf("cannot encode string of length %v: %#v", len(str), str)) 351*61c4878aSAndroid Build Coastguard Worker } 352*61c4878aSAndroid Build Coastguard Worker return append([]byte{byte(len(str))}, str...) 353*61c4878aSAndroid Build Coastguard Worker} 354*61c4878aSAndroid Build Coastguard Worker 355*61c4878aSAndroid Build Coastguard Worker// Special symbol for Huffman EOS. 356*61c4878aSAndroid Build Coastguard Worker// See RFC 7541 Appendix B. 357*61c4878aSAndroid Build Coastguard Workerconst EOS = 256 358*61c4878aSAndroid Build Coastguard Worker 359*61c4878aSAndroid Build Coastguard Worker// Mapping from symbol to Huffman code. 360*61c4878aSAndroid Build Coastguard Worker// Taken verbatim from RFC 7541 Appendix B. 361*61c4878aSAndroid Build Coastguard Workervar huffmanTable = map[int]string{ 362*61c4878aSAndroid Build Coastguard Worker 0: "1111111111000", 363*61c4878aSAndroid Build Coastguard Worker 1: "11111111111111111011000", 364*61c4878aSAndroid Build Coastguard Worker 2: "1111111111111111111111100010", 365*61c4878aSAndroid Build Coastguard Worker 3: "1111111111111111111111100011", 366*61c4878aSAndroid Build Coastguard Worker 4: "1111111111111111111111100100", 367*61c4878aSAndroid Build Coastguard Worker 5: "1111111111111111111111100101", 368*61c4878aSAndroid Build Coastguard Worker 6: "1111111111111111111111100110", 369*61c4878aSAndroid Build Coastguard Worker 7: "1111111111111111111111100111", 370*61c4878aSAndroid Build Coastguard Worker 8: "1111111111111111111111101000", 371*61c4878aSAndroid Build Coastguard Worker 9: "111111111111111111101010", 372*61c4878aSAndroid Build Coastguard Worker 10: "111111111111111111111111111100", 373*61c4878aSAndroid Build Coastguard Worker 11: "1111111111111111111111101001", 374*61c4878aSAndroid Build Coastguard Worker 12: "1111111111111111111111101010", 375*61c4878aSAndroid Build Coastguard Worker 13: "111111111111111111111111111101", 376*61c4878aSAndroid Build Coastguard Worker 14: "1111111111111111111111101011", 377*61c4878aSAndroid Build Coastguard Worker 15: "1111111111111111111111101100", 378*61c4878aSAndroid Build Coastguard Worker 16: "1111111111111111111111101101", 379*61c4878aSAndroid Build Coastguard Worker 17: "1111111111111111111111101110", 380*61c4878aSAndroid Build Coastguard Worker 18: "1111111111111111111111101111", 381*61c4878aSAndroid Build Coastguard Worker 19: "1111111111111111111111110000", 382*61c4878aSAndroid Build Coastguard Worker 20: "1111111111111111111111110001", 383*61c4878aSAndroid Build Coastguard Worker 21: "1111111111111111111111110010", 384*61c4878aSAndroid Build Coastguard Worker 22: "111111111111111111111111111110", 385*61c4878aSAndroid Build Coastguard Worker 23: "1111111111111111111111110011", 386*61c4878aSAndroid Build Coastguard Worker 24: "1111111111111111111111110100", 387*61c4878aSAndroid Build Coastguard Worker 25: "1111111111111111111111110101", 388*61c4878aSAndroid Build Coastguard Worker 26: "1111111111111111111111110110", 389*61c4878aSAndroid Build Coastguard Worker 27: "1111111111111111111111110111", 390*61c4878aSAndroid Build Coastguard Worker 28: "1111111111111111111111111000", 391*61c4878aSAndroid Build Coastguard Worker 29: "1111111111111111111111111001", 392*61c4878aSAndroid Build Coastguard Worker 30: "1111111111111111111111111010", 393*61c4878aSAndroid Build Coastguard Worker 31: "1111111111111111111111111011", 394*61c4878aSAndroid Build Coastguard Worker 32: "010100", 395*61c4878aSAndroid Build Coastguard Worker 33: "1111111000", 396*61c4878aSAndroid Build Coastguard Worker 34: "1111111001", 397*61c4878aSAndroid Build Coastguard Worker 35: "111111111010", 398*61c4878aSAndroid Build Coastguard Worker 36: "1111111111001", 399*61c4878aSAndroid Build Coastguard Worker 37: "010101", 400*61c4878aSAndroid Build Coastguard Worker 38: "11111000", 401*61c4878aSAndroid Build Coastguard Worker 39: "11111111010", 402*61c4878aSAndroid Build Coastguard Worker 40: "1111111010", 403*61c4878aSAndroid Build Coastguard Worker 41: "1111111011", 404*61c4878aSAndroid Build Coastguard Worker 42: "11111001", 405*61c4878aSAndroid Build Coastguard Worker 43: "11111111011", 406*61c4878aSAndroid Build Coastguard Worker 44: "11111010", 407*61c4878aSAndroid Build Coastguard Worker 45: "010110", 408*61c4878aSAndroid Build Coastguard Worker 46: "010111", 409*61c4878aSAndroid Build Coastguard Worker 47: "011000", 410*61c4878aSAndroid Build Coastguard Worker 48: "00000", 411*61c4878aSAndroid Build Coastguard Worker 49: "00001", 412*61c4878aSAndroid Build Coastguard Worker 50: "00010", 413*61c4878aSAndroid Build Coastguard Worker 51: "011001", 414*61c4878aSAndroid Build Coastguard Worker 52: "011010", 415*61c4878aSAndroid Build Coastguard Worker 53: "011011", 416*61c4878aSAndroid Build Coastguard Worker 54: "011100", 417*61c4878aSAndroid Build Coastguard Worker 55: "011101", 418*61c4878aSAndroid Build Coastguard Worker 56: "011110", 419*61c4878aSAndroid Build Coastguard Worker 57: "011111", 420*61c4878aSAndroid Build Coastguard Worker 58: "1011100", 421*61c4878aSAndroid Build Coastguard Worker 59: "11111011", 422*61c4878aSAndroid Build Coastguard Worker 60: "111111111111100", 423*61c4878aSAndroid Build Coastguard Worker 61: "100000", 424*61c4878aSAndroid Build Coastguard Worker 62: "111111111011", 425*61c4878aSAndroid Build Coastguard Worker 63: "1111111100", 426*61c4878aSAndroid Build Coastguard Worker 64: "1111111111010", 427*61c4878aSAndroid Build Coastguard Worker 65: "100001", 428*61c4878aSAndroid Build Coastguard Worker 66: "1011101", 429*61c4878aSAndroid Build Coastguard Worker 67: "1011110", 430*61c4878aSAndroid Build Coastguard Worker 68: "1011111", 431*61c4878aSAndroid Build Coastguard Worker 69: "1100000", 432*61c4878aSAndroid Build Coastguard Worker 70: "1100001", 433*61c4878aSAndroid Build Coastguard Worker 71: "1100010", 434*61c4878aSAndroid Build Coastguard Worker 72: "1100011", 435*61c4878aSAndroid Build Coastguard Worker 73: "1100100", 436*61c4878aSAndroid Build Coastguard Worker 74: "1100101", 437*61c4878aSAndroid Build Coastguard Worker 75: "1100110", 438*61c4878aSAndroid Build Coastguard Worker 76: "1100111", 439*61c4878aSAndroid Build Coastguard Worker 77: "1101000", 440*61c4878aSAndroid Build Coastguard Worker 78: "1101001", 441*61c4878aSAndroid Build Coastguard Worker 79: "1101010", 442*61c4878aSAndroid Build Coastguard Worker 80: "1101011", 443*61c4878aSAndroid Build Coastguard Worker 81: "1101100", 444*61c4878aSAndroid Build Coastguard Worker 82: "1101101", 445*61c4878aSAndroid Build Coastguard Worker 83: "1101110", 446*61c4878aSAndroid Build Coastguard Worker 84: "1101111", 447*61c4878aSAndroid Build Coastguard Worker 85: "1110000", 448*61c4878aSAndroid Build Coastguard Worker 86: "1110001", 449*61c4878aSAndroid Build Coastguard Worker 87: "1110010", 450*61c4878aSAndroid Build Coastguard Worker 88: "11111100", 451*61c4878aSAndroid Build Coastguard Worker 89: "1110011", 452*61c4878aSAndroid Build Coastguard Worker 90: "11111101", 453*61c4878aSAndroid Build Coastguard Worker 91: "1111111111011", 454*61c4878aSAndroid Build Coastguard Worker 92: "1111111111111110000", 455*61c4878aSAndroid Build Coastguard Worker 93: "1111111111100", 456*61c4878aSAndroid Build Coastguard Worker 94: "11111111111100", 457*61c4878aSAndroid Build Coastguard Worker 95: "100010", 458*61c4878aSAndroid Build Coastguard Worker 96: "111111111111101", 459*61c4878aSAndroid Build Coastguard Worker 97: "00011", 460*61c4878aSAndroid Build Coastguard Worker 98: "100011", 461*61c4878aSAndroid Build Coastguard Worker 99: "00100", 462*61c4878aSAndroid Build Coastguard Worker 100: "100100", 463*61c4878aSAndroid Build Coastguard Worker 101: "00101", 464*61c4878aSAndroid Build Coastguard Worker 102: "100101", 465*61c4878aSAndroid Build Coastguard Worker 103: "100110", 466*61c4878aSAndroid Build Coastguard Worker 104: "100111", 467*61c4878aSAndroid Build Coastguard Worker 105: "00110", 468*61c4878aSAndroid Build Coastguard Worker 106: "1110100", 469*61c4878aSAndroid Build Coastguard Worker 107: "1110101", 470*61c4878aSAndroid Build Coastguard Worker 108: "101000", 471*61c4878aSAndroid Build Coastguard Worker 109: "101001", 472*61c4878aSAndroid Build Coastguard Worker 110: "101010", 473*61c4878aSAndroid Build Coastguard Worker 111: "00111", 474*61c4878aSAndroid Build Coastguard Worker 112: "101011", 475*61c4878aSAndroid Build Coastguard Worker 113: "1110110", 476*61c4878aSAndroid Build Coastguard Worker 114: "101100", 477*61c4878aSAndroid Build Coastguard Worker 115: "01000", 478*61c4878aSAndroid Build Coastguard Worker 116: "01001", 479*61c4878aSAndroid Build Coastguard Worker 117: "101101", 480*61c4878aSAndroid Build Coastguard Worker 118: "1110111", 481*61c4878aSAndroid Build Coastguard Worker 119: "1111000", 482*61c4878aSAndroid Build Coastguard Worker 120: "1111001", 483*61c4878aSAndroid Build Coastguard Worker 121: "1111010", 484*61c4878aSAndroid Build Coastguard Worker 122: "1111011", 485*61c4878aSAndroid Build Coastguard Worker 123: "111111111111110", 486*61c4878aSAndroid Build Coastguard Worker 124: "11111111100", 487*61c4878aSAndroid Build Coastguard Worker 125: "11111111111101", 488*61c4878aSAndroid Build Coastguard Worker 126: "1111111111101", 489*61c4878aSAndroid Build Coastguard Worker 127: "1111111111111111111111111100", 490*61c4878aSAndroid Build Coastguard Worker 128: "11111111111111100110", 491*61c4878aSAndroid Build Coastguard Worker 129: "1111111111111111010010", 492*61c4878aSAndroid Build Coastguard Worker 130: "11111111111111100111", 493*61c4878aSAndroid Build Coastguard Worker 131: "11111111111111101000", 494*61c4878aSAndroid Build Coastguard Worker 132: "1111111111111111010011", 495*61c4878aSAndroid Build Coastguard Worker 133: "1111111111111111010100", 496*61c4878aSAndroid Build Coastguard Worker 134: "1111111111111111010101", 497*61c4878aSAndroid Build Coastguard Worker 135: "11111111111111111011001", 498*61c4878aSAndroid Build Coastguard Worker 136: "1111111111111111010110", 499*61c4878aSAndroid Build Coastguard Worker 137: "11111111111111111011010", 500*61c4878aSAndroid Build Coastguard Worker 138: "11111111111111111011011", 501*61c4878aSAndroid Build Coastguard Worker 139: "11111111111111111011100", 502*61c4878aSAndroid Build Coastguard Worker 140: "11111111111111111011101", 503*61c4878aSAndroid Build Coastguard Worker 141: "11111111111111111011110", 504*61c4878aSAndroid Build Coastguard Worker 142: "111111111111111111101011", 505*61c4878aSAndroid Build Coastguard Worker 143: "11111111111111111011111", 506*61c4878aSAndroid Build Coastguard Worker 144: "111111111111111111101100", 507*61c4878aSAndroid Build Coastguard Worker 145: "111111111111111111101101", 508*61c4878aSAndroid Build Coastguard Worker 146: "1111111111111111010111", 509*61c4878aSAndroid Build Coastguard Worker 147: "11111111111111111100000", 510*61c4878aSAndroid Build Coastguard Worker 148: "111111111111111111101110", 511*61c4878aSAndroid Build Coastguard Worker 149: "11111111111111111100001", 512*61c4878aSAndroid Build Coastguard Worker 150: "11111111111111111100010", 513*61c4878aSAndroid Build Coastguard Worker 151: "11111111111111111100011", 514*61c4878aSAndroid Build Coastguard Worker 152: "11111111111111111100100", 515*61c4878aSAndroid Build Coastguard Worker 153: "111111111111111011100", 516*61c4878aSAndroid Build Coastguard Worker 154: "1111111111111111011000", 517*61c4878aSAndroid Build Coastguard Worker 155: "11111111111111111100101", 518*61c4878aSAndroid Build Coastguard Worker 156: "1111111111111111011001", 519*61c4878aSAndroid Build Coastguard Worker 157: "11111111111111111100110", 520*61c4878aSAndroid Build Coastguard Worker 158: "11111111111111111100111", 521*61c4878aSAndroid Build Coastguard Worker 159: "111111111111111111101111", 522*61c4878aSAndroid Build Coastguard Worker 160: "1111111111111111011010", 523*61c4878aSAndroid Build Coastguard Worker 161: "111111111111111011101", 524*61c4878aSAndroid Build Coastguard Worker 162: "11111111111111101001", 525*61c4878aSAndroid Build Coastguard Worker 163: "1111111111111111011011", 526*61c4878aSAndroid Build Coastguard Worker 164: "1111111111111111011100", 527*61c4878aSAndroid Build Coastguard Worker 165: "11111111111111111101000", 528*61c4878aSAndroid Build Coastguard Worker 166: "11111111111111111101001", 529*61c4878aSAndroid Build Coastguard Worker 167: "111111111111111011110", 530*61c4878aSAndroid Build Coastguard Worker 168: "11111111111111111101010", 531*61c4878aSAndroid Build Coastguard Worker 169: "1111111111111111011101", 532*61c4878aSAndroid Build Coastguard Worker 170: "1111111111111111011110", 533*61c4878aSAndroid Build Coastguard Worker 171: "111111111111111111110000", 534*61c4878aSAndroid Build Coastguard Worker 172: "111111111111111011111", 535*61c4878aSAndroid Build Coastguard Worker 173: "1111111111111111011111", 536*61c4878aSAndroid Build Coastguard Worker 174: "11111111111111111101011", 537*61c4878aSAndroid Build Coastguard Worker 175: "11111111111111111101100", 538*61c4878aSAndroid Build Coastguard Worker 176: "111111111111111100000", 539*61c4878aSAndroid Build Coastguard Worker 177: "111111111111111100001", 540*61c4878aSAndroid Build Coastguard Worker 178: "1111111111111111100000", 541*61c4878aSAndroid Build Coastguard Worker 179: "111111111111111100010", 542*61c4878aSAndroid Build Coastguard Worker 180: "11111111111111111101101", 543*61c4878aSAndroid Build Coastguard Worker 181: "1111111111111111100001", 544*61c4878aSAndroid Build Coastguard Worker 182: "11111111111111111101110", 545*61c4878aSAndroid Build Coastguard Worker 183: "11111111111111111101111", 546*61c4878aSAndroid Build Coastguard Worker 184: "11111111111111101010", 547*61c4878aSAndroid Build Coastguard Worker 185: "1111111111111111100010", 548*61c4878aSAndroid Build Coastguard Worker 186: "1111111111111111100011", 549*61c4878aSAndroid Build Coastguard Worker 187: "1111111111111111100100", 550*61c4878aSAndroid Build Coastguard Worker 188: "11111111111111111110000", 551*61c4878aSAndroid Build Coastguard Worker 189: "1111111111111111100101", 552*61c4878aSAndroid Build Coastguard Worker 190: "1111111111111111100110", 553*61c4878aSAndroid Build Coastguard Worker 191: "11111111111111111110001", 554*61c4878aSAndroid Build Coastguard Worker 192: "11111111111111111111100000", 555*61c4878aSAndroid Build Coastguard Worker 193: "11111111111111111111100001", 556*61c4878aSAndroid Build Coastguard Worker 194: "11111111111111101011", 557*61c4878aSAndroid Build Coastguard Worker 195: "1111111111111110001", 558*61c4878aSAndroid Build Coastguard Worker 196: "1111111111111111100111", 559*61c4878aSAndroid Build Coastguard Worker 197: "11111111111111111110010", 560*61c4878aSAndroid Build Coastguard Worker 198: "1111111111111111101000", 561*61c4878aSAndroid Build Coastguard Worker 199: "1111111111111111111101100", 562*61c4878aSAndroid Build Coastguard Worker 200: "11111111111111111111100010", 563*61c4878aSAndroid Build Coastguard Worker 201: "11111111111111111111100011", 564*61c4878aSAndroid Build Coastguard Worker 202: "11111111111111111111100100", 565*61c4878aSAndroid Build Coastguard Worker 203: "111111111111111111111011110", 566*61c4878aSAndroid Build Coastguard Worker 204: "111111111111111111111011111", 567*61c4878aSAndroid Build Coastguard Worker 205: "11111111111111111111100101", 568*61c4878aSAndroid Build Coastguard Worker 206: "111111111111111111110001", 569*61c4878aSAndroid Build Coastguard Worker 207: "1111111111111111111101101", 570*61c4878aSAndroid Build Coastguard Worker 208: "1111111111111110010", 571*61c4878aSAndroid Build Coastguard Worker 209: "111111111111111100011", 572*61c4878aSAndroid Build Coastguard Worker 210: "11111111111111111111100110", 573*61c4878aSAndroid Build Coastguard Worker 211: "111111111111111111111100000", 574*61c4878aSAndroid Build Coastguard Worker 212: "111111111111111111111100001", 575*61c4878aSAndroid Build Coastguard Worker 213: "11111111111111111111100111", 576*61c4878aSAndroid Build Coastguard Worker 214: "111111111111111111111100010", 577*61c4878aSAndroid Build Coastguard Worker 215: "111111111111111111110010", 578*61c4878aSAndroid Build Coastguard Worker 216: "111111111111111100100", 579*61c4878aSAndroid Build Coastguard Worker 217: "111111111111111100101", 580*61c4878aSAndroid Build Coastguard Worker 218: "11111111111111111111101000", 581*61c4878aSAndroid Build Coastguard Worker 219: "11111111111111111111101001", 582*61c4878aSAndroid Build Coastguard Worker 220: "1111111111111111111111111101", 583*61c4878aSAndroid Build Coastguard Worker 221: "111111111111111111111100011", 584*61c4878aSAndroid Build Coastguard Worker 222: "111111111111111111111100100", 585*61c4878aSAndroid Build Coastguard Worker 223: "111111111111111111111100101", 586*61c4878aSAndroid Build Coastguard Worker 224: "11111111111111101100", 587*61c4878aSAndroid Build Coastguard Worker 225: "111111111111111111110011", 588*61c4878aSAndroid Build Coastguard Worker 226: "11111111111111101101", 589*61c4878aSAndroid Build Coastguard Worker 227: "111111111111111100110", 590*61c4878aSAndroid Build Coastguard Worker 228: "1111111111111111101001", 591*61c4878aSAndroid Build Coastguard Worker 229: "111111111111111100111", 592*61c4878aSAndroid Build Coastguard Worker 230: "111111111111111101000", 593*61c4878aSAndroid Build Coastguard Worker 231: "11111111111111111110011", 594*61c4878aSAndroid Build Coastguard Worker 232: "1111111111111111101010", 595*61c4878aSAndroid Build Coastguard Worker 233: "1111111111111111101011", 596*61c4878aSAndroid Build Coastguard Worker 234: "1111111111111111111101110", 597*61c4878aSAndroid Build Coastguard Worker 235: "1111111111111111111101111", 598*61c4878aSAndroid Build Coastguard Worker 236: "111111111111111111110100", 599*61c4878aSAndroid Build Coastguard Worker 237: "111111111111111111110101", 600*61c4878aSAndroid Build Coastguard Worker 238: "11111111111111111111101010", 601*61c4878aSAndroid Build Coastguard Worker 239: "11111111111111111110100", 602*61c4878aSAndroid Build Coastguard Worker 240: "11111111111111111111101011", 603*61c4878aSAndroid Build Coastguard Worker 241: "111111111111111111111100110", 604*61c4878aSAndroid Build Coastguard Worker 242: "11111111111111111111101100", 605*61c4878aSAndroid Build Coastguard Worker 243: "11111111111111111111101101", 606*61c4878aSAndroid Build Coastguard Worker 244: "111111111111111111111100111", 607*61c4878aSAndroid Build Coastguard Worker 245: "111111111111111111111101000", 608*61c4878aSAndroid Build Coastguard Worker 246: "111111111111111111111101001", 609*61c4878aSAndroid Build Coastguard Worker 247: "111111111111111111111101010", 610*61c4878aSAndroid Build Coastguard Worker 248: "111111111111111111111101011", 611*61c4878aSAndroid Build Coastguard Worker 249: "1111111111111111111111111110", 612*61c4878aSAndroid Build Coastguard Worker 250: "111111111111111111111101100", 613*61c4878aSAndroid Build Coastguard Worker 251: "111111111111111111111101101", 614*61c4878aSAndroid Build Coastguard Worker 252: "111111111111111111111101110", 615*61c4878aSAndroid Build Coastguard Worker 253: "111111111111111111111101111", 616*61c4878aSAndroid Build Coastguard Worker 254: "111111111111111111111110000", 617*61c4878aSAndroid Build Coastguard Worker 255: "11111111111111111111101110", 618*61c4878aSAndroid Build Coastguard Worker 256: "111111111111111111111111111111", 619*61c4878aSAndroid Build Coastguard Worker} 620