mf_iocache2.c
上传用户:tsgydb
上传日期:2007-04-14
资源大小:10674k
文件大小:6k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
  2.    
  3.    This library is free software; you can redistribute it and/or
  4.    modify it under the terms of the GNU Library General Public
  5.    License as published by the Free Software Foundation; either
  6.    version 2 of the License, or (at your option) any later version.
  7.    
  8.    This library is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  11.    Library General Public License for more details.
  12.    
  13.    You should have received a copy of the GNU Library General Public
  14.    License along with this library; if not, write to the Free
  15.    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
  16.    MA 02111-1307, USA */
  17. /*
  18.   More functions to be used with IO_CACHE files
  19. */
  20. #define MAP_TO_USE_RAID
  21. #include "mysys_priv.h"
  22. #include <m_string.h>
  23. #include <stdarg.h>
  24. #include <m_ctype.h>
  25. /*
  26. ** Fix that next read will be made at certain position
  27. ** For write cache, make next write happen at a certain position
  28. */
  29. void my_b_seek(IO_CACHE *info,my_off_t pos)
  30. {
  31.   if (info->type == READ_CACHE)
  32.   {
  33.     info->rc_pos=info->rc_end=info->buffer;
  34.   }
  35.   else if (info->type == WRITE_CACHE)
  36.   {
  37.     byte* try_rc_pos;
  38.     try_rc_pos = info->rc_pos + (pos - info->pos_in_file);
  39.     if (try_rc_pos >= info->buffer && try_rc_pos <= info->rc_end)
  40.       info->rc_pos = try_rc_pos;
  41.     else
  42.       flush_io_cache(info);
  43.   }
  44.   info->pos_in_file=pos;
  45.   info->seek_not_done=1;
  46. }
  47. /*
  48. **  Fill buffer.  Note that this assumes that you have already used
  49. **  all characters in the CACHE, independent of the rc_pos value!
  50. **  return:  0 on error or EOF (info->error = -1 on error)
  51. **           number of characters
  52. */
  53. uint my_b_fill(IO_CACHE *info)
  54. {
  55.   my_off_t pos_in_file=info->pos_in_file+(uint) (info->rc_end - info->buffer);
  56.   my_off_t max_length;
  57.   uint diff_length,length;
  58.   if (info->seek_not_done)
  59.   { /* File touched, do seek */
  60.     if (my_seek(info->file,pos_in_file,MY_SEEK_SET,MYF(0)) ==
  61. MY_FILEPOS_ERROR)
  62.     {
  63.       info->error= 0;
  64.       return 0;
  65.     }
  66.     info->seek_not_done=0;
  67.   }
  68.   diff_length=(uint) (pos_in_file & (IO_SIZE-1));
  69.   max_length= (my_off_t) (info->end_of_file - pos_in_file);
  70.   if (max_length > (my_off_t) (info->read_length-diff_length))
  71.     max_length=(my_off_t) (info->read_length-diff_length);
  72.   if (!max_length)
  73.   {
  74.     info->error= 0;
  75.     return 0; /* EOF */
  76.   }
  77.    else if ((length=my_read(info->file,info->buffer,(uint) max_length,
  78.    info->myflags)) == (uint) -1)
  79.   {
  80.     info->error= -1;
  81.     return 0;
  82.   }
  83.   info->rc_pos=info->buffer;
  84.   info->rc_end=info->buffer+length;
  85.   info->pos_in_file=pos_in_file;
  86.   return length;
  87. }
  88. /*
  89. ** Read a string ended by 'n' into a buffer of 'max_length' size.
  90. ** Returns number of characters read, 0 on error.
  91. ** last byte is set to ''
  92. */
  93. uint my_b_gets(IO_CACHE *info, char *to, uint max_length)
  94. {
  95.   char *start = to;
  96.   uint length;
  97.   max_length--; /* Save place for end  */
  98.   /* Calculate number of characters in buffer */
  99.   if (!(length= my_b_bytes_in_cache(info)) &&
  100.       !(length= my_b_fill(info)))
  101.     return 0;
  102.   for (;;)
  103.   {
  104.     char *pos,*end;
  105.     if (length > max_length)
  106.       length=max_length;
  107.     for (pos=info->rc_pos,end=pos+length ; pos < end ;)
  108.     {
  109.       if ((*to++ = *pos++) == 'n')
  110.       {
  111. info->rc_pos=pos;
  112. *to='';
  113. return (uint) (to-start);
  114.       }
  115.     }
  116.     if (!(max_length-=length))
  117.     {
  118.      /* Found enough charcters;  Return found string */
  119.       info->rc_pos=pos;
  120.       *to='';
  121.       return (uint) (to-start);
  122.     }
  123.     if (!(length=my_b_fill(info)))
  124.       return 0;
  125.   }
  126. }
  127. /*
  128.   Simple printf version.  Supports '%s', '%d', '%u', "%ld" and "%lu"
  129.   Used for logging in MySQL
  130.   returns number of written character, or (uint) -1 on error
  131. */
  132. uint my_b_printf(IO_CACHE *info, const char* fmt, ...)
  133. {
  134.   int result;
  135.   va_list args;
  136.   va_start(args,fmt);
  137.   result=my_b_vprintf(info, fmt, args);
  138.   va_end(args);
  139.   return result;
  140. }
  141. uint my_b_vprintf(IO_CACHE *info, const char* fmt, va_list args)
  142. {
  143.   uint out_length=0;
  144.   for (; *fmt ; fmt++)
  145.   {
  146.     if (*fmt++ != '%')
  147.     {
  148.       /* Copy everything until '%' or end of string */
  149.       const char *start=fmt-1;
  150.       uint length;
  151.       for (; *fmt && *fmt != '%' ; fmt++ ) ;
  152.       length= (uint) (fmt - start);
  153.       out_length+=length;
  154.       if (my_b_write(info, start, length))
  155. goto err;
  156.       if (!*fmt) /* End of format */
  157.       {
  158. return out_length;
  159.       }
  160.       fmt++;
  161.       /* Found one '%' */
  162.     }
  163.     /* Skipp if max size is used (to be compatible with printf) */
  164.     while (isdigit(*fmt) || *fmt == '.' || *fmt == '-')
  165.       fmt++;
  166.     if (*fmt == 's') /* String parameter */
  167.     {
  168.       reg2 char *par = va_arg(args, char *);
  169.       uint length = (uint) strlen(par);
  170.       out_length+=length;
  171.       if (my_b_write(info, par, length))
  172. goto err;
  173.     }
  174.     else if (*fmt == 'd' || *fmt == 'u') /* Integer parameter */
  175.     {
  176.       register int iarg;
  177.       uint length;
  178.       char buff[17];
  179.       iarg = va_arg(args, int);
  180.       if (*fmt == 'd')
  181. length= (uint) (int10_to_str((long) iarg,buff, -10) - buff);
  182.       else
  183. length= (uint) (int10_to_str((long) (uint) iarg,buff,10)- buff);
  184.       out_length+=length;
  185.       if (my_b_write(info, buff, length))
  186. goto err;
  187.     }
  188.     else if ((*fmt == 'l' && fmt[1] == 'd') || fmt[1] == 'u')
  189.       /* long parameter */
  190.     {
  191.       register long iarg;
  192.       uint length;
  193.       char buff[17];
  194.       iarg = va_arg(args, long);
  195.       if (*++fmt == 'd')
  196. length= (uint) (int10_to_str(iarg,buff, -10) - buff);
  197.       else
  198. length= (uint) (int10_to_str(iarg,buff,10)- buff);
  199.       out_length+=length;
  200.       if (my_b_write(info, buff, length))
  201. goto err;
  202.     }
  203.     else
  204.     {
  205.       /* %% or unknown code */
  206.       if (my_b_write(info, "%", 1))
  207. goto err;
  208.       out_length++;
  209.     }
  210.   }
  211.   return out_length;
  212. err:
  213.   return (uint) -1;
  214. }