mariadb/storage/xtradb/include/ut0mem.ic

318 lines
7.1 KiB
Text
Raw Normal View History

2009-03-25 23:11:11 -07:00
/*****************************************************************************
Copyright (c) 1994, 2011, Oracle and/or its affiliates. All Rights Reserved.
2009-03-25 23:11:11 -07:00
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
2013-12-16 15:38:05 +01:00
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
2009-03-25 23:11:11 -07:00
*****************************************************************************/
2009-09-07 10:22:53 +00:00
/*******************************************************************//**
@file include/ut0mem.ic
Memory primitives
Created 5/30/1994 Heikki Tuuri
************************************************************************/
#include "ut0byte.h"
#include "mach0data.h"
2009-09-07 10:22:53 +00:00
/** Wrapper for memcpy(3). Copy memory area when the source and
target are not overlapping.
* @param dest in: copy to
* @param sour in: copy from
* @param n in: number of bytes to copy
* @return dest */
UNIV_INLINE
void*
ut_memcpy(void* dest, const void* sour, ulint n)
{
return(memcpy(dest, sour, n));
}
2009-09-07 10:22:53 +00:00
/** Wrapper for memmove(3). Copy memory area when the source and
target are overlapping.
* @param dest in: copy to
* @param sour in: copy from
* @param n in: number of bytes to copy
* @return dest */
UNIV_INLINE
void*
ut_memmove(void* dest, const void* sour, ulint n)
{
return(memmove(dest, sour, n));
}
2009-09-07 10:22:53 +00:00
/** Wrapper for memcmp(3). Compare memory areas.
* @param str1 in: first memory block to compare
* @param str2 in: second memory block to compare
* @param n in: number of bytes to compare
* @return negative, 0, or positive if str1 is smaller, equal,
or greater than str2, respectively. */
UNIV_INLINE
int
ut_memcmp(const void* str1, const void* str2, ulint n)
{
return(memcmp(str1, str2, n));
}
2009-09-07 10:22:53 +00:00
/** Wrapper for strcpy(3). Copy a NUL-terminated string.
* @param dest in: copy to
* @param sour in: copy from
* @return dest */
UNIV_INLINE
char*
ut_strcpy(char* dest, const char* sour)
{
return(strcpy(dest, sour));
}
2009-09-07 10:22:53 +00:00
/** Wrapper for strlen(3). Determine the length of a NUL-terminated string.
* @param str in: string
* @return length of the string in bytes, excluding the terminating NUL */
UNIV_INLINE
ulint
ut_strlen(const char* str)
{
return(strlen(str));
}
2009-09-07 10:22:53 +00:00
/** Wrapper for strcmp(3). Compare NUL-terminated strings.
* @param str1 in: first string to compare
* @param str2 in: second string to compare
* @return negative, 0, or positive if str1 is smaller, equal,
or greater than str2, respectively. */
UNIV_INLINE
int
ut_strcmp(const char* str1, const char* str2)
{
return(strcmp(str1, str2));
}
2009-09-07 10:22:53 +00:00
/**********************************************************************//**
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
2009-09-07 10:22:53 +00:00
actual number of characters written to "hex" (including the NUL).
@return number of chars written */
UNIV_INLINE
ulint
ut_raw_to_hex(
/*==========*/
2009-09-07 10:22:53 +00:00
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) ((unsigned char) ((u) >> 8))
#define UINT16_GET_B(u) ((unsigned char) ((u) & 0xFF))
#else /* WORDS_BIGENDIAN */
#define MK_UINT16(a, b) (((uint16) (b)) << 8 | (uint16) (a))
#define UINT16_GET_A(u) ((unsigned char) ((u) & 0xFF))
#define UINT16_GET_B(u) ((unsigned 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);
}
2009-09-07 10:22:53 +00:00
/*******************************************************************//**
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"
2009-09-07 10:22:53 +00:00
(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(
/*==============*/
2009-09-07 10:22:53 +00:00
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':
2013-12-16 15:38:05 +01:00
if (buf_size - buf_i < 4) {
goto func_exit;
}
buf[buf_i] = '\\';
buf_i++;
buf[buf_i] = '0';
buf_i++;
break;
case '\'':
case '\\':
2013-12-16 15:38:05 +01:00
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);
}