DecodeRawBytesToByteArray converts raw bytes to a SQL-level byte array according to the encoding specification in "be". When using the Hex format, the caller is responsible for skipping the "\x" prefix, if any. See DecodeRawBytesToByteArrayAuto() below for an alternative. If no conversion is necessa
(data []byte, be BytesEncodeFormat)
| 145 | // an alternative. If no conversion is necessary the input is returned, |
| 146 | // callers should not assume a copy is made. |
| 147 | func DecodeRawBytesToByteArray(data []byte, be BytesEncodeFormat) ([]byte, error) { |
| 148 | switch be { |
| 149 | case BytesEncodeHex: |
| 150 | res := make([]byte, hex.DecodedLen(len(data))) |
| 151 | n, err := hex.Decode(res, data) |
| 152 | return res[:n], err |
| 153 | |
| 154 | case BytesEncodeEscape: |
| 155 | // PostgreSQL does not allow all the escapes formats recognized by |
| 156 | // CockroachDB's scanner. It only recognizes octal and \\ for the |
| 157 | // backslash itself. |
| 158 | // See https://www.postgresql.org/docs/current/static/datatype-binary.html#AEN5667 |
| 159 | res := data |
| 160 | copied := false |
| 161 | for i := 0; i < len(data); i++ { |
| 162 | ch := data[i] |
| 163 | if ch != '\\' { |
| 164 | if copied { |
| 165 | res = append(res, ch) |
| 166 | } |
| 167 | continue |
| 168 | } |
| 169 | if i >= len(data)-1 { |
| 170 | return nil, pgerror.New(pgcode.InvalidEscapeSequence, |
| 171 | "bytea encoded value ends with escape character") |
| 172 | } |
| 173 | if !copied { |
| 174 | res = make([]byte, 0, len(data)) |
| 175 | res = append(res, data[:i]...) |
| 176 | copied = true |
| 177 | } |
| 178 | if data[i+1] == '\\' { |
| 179 | res = append(res, '\\') |
| 180 | i++ |
| 181 | continue |
| 182 | } |
| 183 | if i+3 >= len(data) { |
| 184 | return nil, pgerror.New(pgcode.InvalidEscapeSequence, |
| 185 | "bytea encoded value ends with incomplete escape sequence") |
| 186 | } |
| 187 | b := byte(0) |
| 188 | for j := 1; j <= 3; j++ { |
| 189 | octDigit := data[i+j] |
| 190 | if octDigit < '0' || octDigit > '7' || (j == 1 && octDigit > '3') { |
| 191 | return nil, pgerror.New(pgcode.InvalidEscapeSequence, |
| 192 | "invalid bytea escape sequence") |
| 193 | } |
| 194 | b = (b << 3) | (octDigit - '0') |
| 195 | } |
| 196 | res = append(res, b) |
| 197 | i += 3 |
| 198 | } |
| 199 | return res, nil |
| 200 | |
| 201 | case BytesEncodeBase64: |
| 202 | res := make([]byte, base64.StdEncoding.DecodedLen(len(data))) |
| 203 | n, err := base64.StdEncoding.Decode(res, data) |
| 204 | return res[:n], err |
no test coverage detected
searching dependent graphs…