github.com/jogo/docker@v1.7.0-rc1/pkg/jsonlog/jsonlogbytes.go (about) 1 package jsonlog 2 3 import ( 4 "bytes" 5 "unicode/utf8" 6 ) 7 8 // JSONLogBytes is based on JSONLog. 9 // It allows marshalling JSONLog from Log as []byte 10 // and an already marshalled Created timestamp. 11 type JSONLogBytes struct { 12 Log []byte `json:"log,omitempty"` 13 Stream string `json:"stream,omitempty"` 14 Created string `json:"time"` 15 } 16 17 // MarshalJSONBuf is based on the same method from JSONLog 18 // It has been modified to take into account the necessary changes. 19 func (mj *JSONLogBytes) MarshalJSONBuf(buf *bytes.Buffer) error { 20 var first = true 21 22 buf.WriteString(`{`) 23 if len(mj.Log) != 0 { 24 if first == true { 25 first = false 26 } else { 27 buf.WriteString(`,`) 28 } 29 buf.WriteString(`"log":`) 30 ffjson_WriteJsonBytesAsString(buf, mj.Log) 31 } 32 if len(mj.Stream) != 0 { 33 if first == true { 34 first = false 35 } else { 36 buf.WriteString(`,`) 37 } 38 buf.WriteString(`"stream":`) 39 ffjson_WriteJsonString(buf, mj.Stream) 40 } 41 if first == true { 42 first = false 43 } else { 44 buf.WriteString(`,`) 45 } 46 buf.WriteString(`"time":`) 47 buf.WriteString(mj.Created) 48 buf.WriteString(`}`) 49 return nil 50 } 51 52 // This is based on ffjson_WriteJsonString. It has been changed 53 // to accept a string passed as a slice of bytes. 54 func ffjson_WriteJsonBytesAsString(buf *bytes.Buffer, s []byte) { 55 const hex = "0123456789abcdef" 56 57 buf.WriteByte('"') 58 start := 0 59 for i := 0; i < len(s); { 60 if b := s[i]; b < utf8.RuneSelf { 61 if 0x20 <= b && b != '\\' && b != '"' && b != '<' && b != '>' && b != '&' { 62 i++ 63 continue 64 } 65 if start < i { 66 buf.Write(s[start:i]) 67 } 68 switch b { 69 case '\\', '"': 70 buf.WriteByte('\\') 71 buf.WriteByte(b) 72 case '\n': 73 buf.WriteByte('\\') 74 buf.WriteByte('n') 75 case '\r': 76 buf.WriteByte('\\') 77 buf.WriteByte('r') 78 default: 79 80 buf.WriteString(`\u00`) 81 buf.WriteByte(hex[b>>4]) 82 buf.WriteByte(hex[b&0xF]) 83 } 84 i++ 85 start = i 86 continue 87 } 88 c, size := utf8.DecodeRune(s[i:]) 89 if c == utf8.RuneError && size == 1 { 90 if start < i { 91 buf.Write(s[start:i]) 92 } 93 buf.WriteString(`\ufffd`) 94 i += size 95 start = i 96 continue 97 } 98 99 if c == '\u2028' || c == '\u2029' { 100 if start < i { 101 buf.Write(s[start:i]) 102 } 103 buf.WriteString(`\u202`) 104 buf.WriteByte(hex[c&0xF]) 105 i += size 106 start = i 107 continue 108 } 109 i += size 110 } 111 if start < len(s) { 112 buf.Write(s[start:]) 113 } 114 buf.WriteByte('"') 115 }