/// <summary> /// Byte array from bytea encoded as ASCII text, escaped or hex format. /// </summary> internal static Object ByteaTextToByteArray(NpgsqlBackendTypeInfo TypeInfo, byte[] BackendData, Int16 TypeSize, Int32 TypeModifier) { Int32 byteALength = BackendData.Length; Int32 byteAPosition = 0; if (byteALength >= 2 && BackendData[0] == (byte)ASCIIBytes.BackSlash && BackendData[1] == (byte)ASCIIBytes.x) { // PostgreSQL 8.5+'s bytea_output=hex format byte[] result = new byte[(byteALength - 2) / 2]; #if UNSAFE unsafe { fixed(byte *pBackendData = &BackendData[2]) { fixed(byte *pResult = &result[0]) { byte *pBackendData2 = pBackendData; byte *pResult2 = pResult; for (byteAPosition = 2; byteAPosition < byteALength; byteAPosition += 2) { *pResult2 = FastConverter.ToByteHexFormat(pBackendData2); pBackendData2 += 2; pResult2++; } } } } #else Int32 k = 0; for (byteAPosition = 2; byteAPosition < byteALength; byteAPosition += 2) { result[k] = FastConverter.ToByteHexFormat(BackendData, byteAPosition); k++; } #endif return(result); } else { byte octalValue = 0; MemoryStream ms = new MemoryStream(); while (byteAPosition < byteALength) { // The IsDigit is necessary in case we receive a \ as the octal value and not // as the indicator of a following octal value in decimal format. // i.e.: \201\301P\A if (BackendData[byteAPosition] == (byte)ASCIIBytes.BackSlash) { if (byteAPosition + 1 == byteALength) { octalValue = (byte)ASCIIBytes.BackSlash; byteAPosition++; } else if (BackendData[byteAPosition + 1] >= (byte)ASCIIBytes.b0 && BackendData[byteAPosition + 1] <= (byte)ASCIIBytes.b7) { octalValue = FastConverter.ToByteEscapeFormat(BackendData, byteAPosition + 1); byteAPosition += 4; } else { octalValue = (byte)ASCIIBytes.BackSlash; byteAPosition += 2; } } else { octalValue = BackendData[byteAPosition]; byteAPosition++; } ms.WriteByte((Byte)octalValue); } return(ms.ToArray()); } }
/// <summary> /// Byte array from bytea encoded as text, escaped or hex format. /// </summary> internal static Object ByteaTextToByteArray(NpgsqlBackendTypeInfo TypeInfo, String BackendData, Int16 TypeSize, Int32 TypeModifier) { Int32 byteAPosition = 0; Int32 byteAStringLength = BackendData.Length; if (BackendData.StartsWith("\\x")) { // PostgreSQL 8.5+'s bytea_output=hex format byte[] result = new byte[byteAStringLength / 2]; //unsafe { //fixed (byte* p = &result[0]) { // byte* ptr = p; int k = 0; for (byteAPosition = 2; byteAPosition < byteAStringLength; byteAPosition += 2) { //*ptr= result[k] = FastConverter.ToByte(BackendData, byteAPosition); k++; //ptr++; } } } return(result); } else { Int32 octalValue = 0; MemoryStream ms = new MemoryStream(); while (byteAPosition < byteAStringLength) { // The IsDigit is necessary in case we receive a \ as the octal value and not // as the indicator of a following octal value in decimal format. // i.e.: \201\301P\A if (BackendData[byteAPosition] == '\\') { if (byteAPosition + 1 == byteAStringLength) { octalValue = '\\'; byteAPosition++; } else if (Char.IsDigit(BackendData[byteAPosition + 1])) { octalValue = Convert.ToByte(BackendData.Substring(byteAPosition + 1, 3), 8); //octalValue = (Byte.Parse(BackendData[byteAPosition + 1].ToString()) << 6); //octalValue |= (Byte.Parse(BackendData[byteAPosition + 2].ToString()) << 3); //octalValue |= Byte.Parse(BackendData[byteAPosition + 3].ToString()); byteAPosition += 4; } else { octalValue = '\\'; byteAPosition += 2; } } else { octalValue = (Byte)BackendData[byteAPosition]; byteAPosition++; } ms.WriteByte((Byte)octalValue); } return(ms.ToArray()); } }