mirror of
				https://github.com/MariaDB/server.git
				synced 2025-10-31 10:56:12 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			246 lines
		
	
	
	
		
			5.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			246 lines
		
	
	
	
		
			5.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*****************************************************************************
 | |
| 
 | |
| Copyright (c) 1994, 2014, Oracle and/or its affiliates. All Rights Reserved.
 | |
| Copyright (c) 2017, 2019, MariaDB Corporation.
 | |
| 
 | |
| This program is free software; you can redistribute it and/or modify it under
 | |
| the terms of the GNU General Public License as published by the Free Software
 | |
| Foundation; version 2 of the License.
 | |
| 
 | |
| This program is distributed in the hope that it will be useful, but WITHOUT
 | |
| ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 | |
| FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
 | |
| 
 | |
| You should have received a copy of the GNU General Public License along with
 | |
| this program; if not, write to the Free Software Foundation, Inc.,
 | |
| 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
 | |
| 
 | |
| *****************************************************************************/
 | |
| 
 | |
| /*******************************************************************//**
 | |
| @file include/ut0mem.ic
 | |
| Memory primitives
 | |
| 
 | |
| Created 5/30/1994 Heikki Tuuri
 | |
| ************************************************************************/
 | |
| 
 | |
| #include "ut0byte.h"
 | |
| #include "mach0data.h"
 | |
| 
 | |
| /**********************************************************************//**
 | |
| Converts a raw binary data to a NUL-terminated hex string. The output is
 | |
| truncated if there is not enough space in "hex", make sure "hex_size" is at
 | |
| least (2 * raw_size + 1) if you do not want this to happen. Returns the
 | |
| actual number of characters written to "hex" (including the NUL).
 | |
| @return number of chars written */
 | |
| UNIV_INLINE
 | |
| ulint
 | |
| ut_raw_to_hex(
 | |
| /*==========*/
 | |
| 	const void*	raw,		/*!< in: raw data */
 | |
| 	ulint		raw_size,	/*!< in: "raw" length in bytes */
 | |
| 	char*		hex,		/*!< out: hex string */
 | |
| 	ulint		hex_size)	/*!< in: "hex" size in bytes */
 | |
| {
 | |
| 
 | |
| #ifdef WORDS_BIGENDIAN
 | |
| 
 | |
| #define MK_UINT16(a, b) (((uint16) (a)) << 8 | (uint16) (b))
 | |
| 
 | |
| #define UINT16_GET_A(u)	((char) ((u) >> 8))
 | |
| #define UINT16_GET_B(u)	((char) ((u) & 0xFF))
 | |
| 
 | |
| #else /* WORDS_BIGENDIAN */
 | |
| 
 | |
| #define MK_UINT16(a, b) (((uint16) (b)) << 8 | (uint16) (a))
 | |
| 
 | |
| #define UINT16_GET_A(u)	((char) ((u) & 0xFF))
 | |
| #define UINT16_GET_B(u)	((char) ((u) >> 8))
 | |
| 
 | |
| #endif /* WORDS_BIGENDIAN */
 | |
| 
 | |
| #define MK_ALL_UINT16_WITH_A(a)	\
 | |
| 	MK_UINT16(a, '0'),	\
 | |
| 	MK_UINT16(a, '1'),	\
 | |
| 	MK_UINT16(a, '2'),	\
 | |
| 	MK_UINT16(a, '3'),	\
 | |
| 	MK_UINT16(a, '4'),	\
 | |
| 	MK_UINT16(a, '5'),	\
 | |
| 	MK_UINT16(a, '6'),	\
 | |
| 	MK_UINT16(a, '7'),	\
 | |
| 	MK_UINT16(a, '8'),	\
 | |
| 	MK_UINT16(a, '9'),	\
 | |
| 	MK_UINT16(a, 'A'),	\
 | |
| 	MK_UINT16(a, 'B'),	\
 | |
| 	MK_UINT16(a, 'C'),	\
 | |
| 	MK_UINT16(a, 'D'),	\
 | |
| 	MK_UINT16(a, 'E'),	\
 | |
| 	MK_UINT16(a, 'F')
 | |
| 
 | |
| 	static const uint16	hex_map[256] = {
 | |
| 		MK_ALL_UINT16_WITH_A('0'),
 | |
| 		MK_ALL_UINT16_WITH_A('1'),
 | |
| 		MK_ALL_UINT16_WITH_A('2'),
 | |
| 		MK_ALL_UINT16_WITH_A('3'),
 | |
| 		MK_ALL_UINT16_WITH_A('4'),
 | |
| 		MK_ALL_UINT16_WITH_A('5'),
 | |
| 		MK_ALL_UINT16_WITH_A('6'),
 | |
| 		MK_ALL_UINT16_WITH_A('7'),
 | |
| 		MK_ALL_UINT16_WITH_A('8'),
 | |
| 		MK_ALL_UINT16_WITH_A('9'),
 | |
| 		MK_ALL_UINT16_WITH_A('A'),
 | |
| 		MK_ALL_UINT16_WITH_A('B'),
 | |
| 		MK_ALL_UINT16_WITH_A('C'),
 | |
| 		MK_ALL_UINT16_WITH_A('D'),
 | |
| 		MK_ALL_UINT16_WITH_A('E'),
 | |
| 		MK_ALL_UINT16_WITH_A('F')
 | |
| 	};
 | |
| 	const unsigned char*	rawc;
 | |
| 	ulint			read_bytes;
 | |
| 	ulint			write_bytes;
 | |
| 	ulint			i;
 | |
| 
 | |
| 	rawc = (const unsigned char*) raw;
 | |
| 
 | |
| 	if (hex_size == 0) {
 | |
| 
 | |
| 		return(0);
 | |
| 	}
 | |
| 
 | |
| 	if (hex_size <= 2 * raw_size) {
 | |
| 
 | |
| 		read_bytes = hex_size / 2;
 | |
| 		write_bytes = hex_size;
 | |
| 	} else {
 | |
| 
 | |
| 		read_bytes = raw_size;
 | |
| 		write_bytes = 2 * raw_size + 1;
 | |
| 	}
 | |
| 
 | |
| #define LOOP_READ_BYTES(ASSIGN)			\
 | |
| 	for (i = 0; i < read_bytes; i++) {	\
 | |
| 		ASSIGN;				\
 | |
| 		hex += 2;			\
 | |
| 		rawc++;				\
 | |
| 	}
 | |
| 
 | |
| 	if (ut_align_offset(hex, 2) == 0) {
 | |
| 
 | |
| 		LOOP_READ_BYTES(
 | |
| 			*(uint16*) hex = hex_map[*rawc]
 | |
| 		);
 | |
| 	} else {
 | |
| 
 | |
| 		LOOP_READ_BYTES(
 | |
| 			*hex       = UINT16_GET_A(hex_map[*rawc]);
 | |
| 			*(hex + 1) = UINT16_GET_B(hex_map[*rawc])
 | |
| 		);
 | |
| 	}
 | |
| 
 | |
| 	if (hex_size <= 2 * raw_size && hex_size % 2 == 0) {
 | |
| 
 | |
| 		hex--;
 | |
| 	}
 | |
| 
 | |
| 	*hex = '\0';
 | |
| 
 | |
| 	return(write_bytes);
 | |
| }
 | |
| 
 | |
| /*******************************************************************//**
 | |
| Adds single quotes to the start and end of string and escapes any quotes
 | |
| by doubling them. Returns the number of bytes that were written to "buf"
 | |
| (including the terminating NUL). If buf_size is too small then the
 | |
| trailing bytes from "str" are discarded.
 | |
| @return number of bytes that were written */
 | |
| UNIV_INLINE
 | |
| ulint
 | |
| ut_str_sql_format(
 | |
| /*==============*/
 | |
| 	const char*	str,		/*!< in: string */
 | |
| 	ulint		str_len,	/*!< in: string length in bytes */
 | |
| 	char*		buf,		/*!< out: output buffer */
 | |
| 	ulint		buf_size)	/*!< in: output buffer size
 | |
| 					in bytes */
 | |
| {
 | |
| 	ulint	str_i;
 | |
| 	ulint	buf_i;
 | |
| 
 | |
| 	buf_i = 0;
 | |
| 
 | |
| 	switch (buf_size) {
 | |
| 	case 3:
 | |
| 
 | |
| 		if (str_len == 0) {
 | |
| 
 | |
| 			buf[buf_i] = '\'';
 | |
| 			buf_i++;
 | |
| 			buf[buf_i] = '\'';
 | |
| 			buf_i++;
 | |
| 		}
 | |
| 		/* FALLTHROUGH */
 | |
| 	case 2:
 | |
| 	case 1:
 | |
| 
 | |
| 		buf[buf_i] = '\0';
 | |
| 		buf_i++;
 | |
| 		/* FALLTHROUGH */
 | |
| 	case 0:
 | |
| 
 | |
| 		return(buf_i);
 | |
| 	}
 | |
| 
 | |
| 	/* buf_size >= 4 */
 | |
| 
 | |
| 	buf[0] = '\'';
 | |
| 	buf_i = 1;
 | |
| 
 | |
| 	for (str_i = 0; str_i < str_len; str_i++) {
 | |
| 
 | |
| 		char	ch;
 | |
| 
 | |
| 		if (buf_size - buf_i == 2) {
 | |
| 
 | |
| 			break;
 | |
| 		}
 | |
| 
 | |
| 		ch = str[str_i];
 | |
| 
 | |
| 		switch (ch) {
 | |
| 		case '\0':
 | |
| 
 | |
| 			if (buf_size - buf_i < 4) {
 | |
| 
 | |
| 				goto func_exit;
 | |
| 			}
 | |
| 			buf[buf_i] = '\\';
 | |
| 			buf_i++;
 | |
| 			buf[buf_i] = '0';
 | |
| 			buf_i++;
 | |
| 			break;
 | |
| 		case '\'':
 | |
| 		case '\\':
 | |
| 
 | |
| 			if (buf_size - buf_i < 4) {
 | |
| 
 | |
| 				goto func_exit;
 | |
| 			}
 | |
| 			buf[buf_i] = ch;
 | |
| 			buf_i++;
 | |
| 			/* FALLTHROUGH */
 | |
| 		default:
 | |
| 
 | |
| 			buf[buf_i] = ch;
 | |
| 			buf_i++;
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| func_exit:
 | |
| 
 | |
| 	buf[buf_i] = '\'';
 | |
| 	buf_i++;
 | |
| 	buf[buf_i] = '\0';
 | |
| 	buf_i++;
 | |
| 
 | |
| 	return(buf_i);
 | |
| }
 | 
