Changeset 480

Show
Ignore:
Timestamp:
03/30/07 09:07:27 (2 years ago)
Author:
hachi
Message:

Raw checkin of changes from Aaron

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/client-xs-20070328/Cache-Memcached-GetParserXS/GetParserXS.xs

    r305 r480  
    2525} 
    2626 
    27 void set_key (AV* self, const char *key) { 
    28   av_store(self, KEY, newSVpv(key, strlen(key))); 
    29 } 
    30  
    31 SV *get_key_sv (AV* self) { 
     27inline void set_key (AV* self, const char *key, int len) { 
     28  av_store(self, KEY, newSVpv(key, len)); 
     29} 
     30 
     31inline SV *get_key_sv (AV* self) { 
    3232  SV** svp = av_fetch(self, KEY, 0); 
    3333  if (svp) 
     
    3636} 
    3737 
    38 SV *get_on_item (AV* self) { 
     38inline SV *get_on_item (AV* self) { 
    3939  SV** svp = av_fetch(self, ON_ITEM, 0); 
    4040  if (svp) 
     
    4343} 
    4444 
    45 void set_flags (AV* self, int flags) { 
     45inline void set_flags (AV* self, int flags) { 
    4646  av_store(self, FLAGS, newSViv(flags)); 
    4747} 
    4848 
    49 void set_offset (AV* self, int offset) { 
     49inline void set_offset (AV* self, int offset) { 
    5050  av_store(self, OFFSET, newSViv(offset)); 
    5151} 
    5252 
    53 void set_state (AV* self, int state) { 
     53inline void set_state (AV* self, int state) { 
    5454  av_store(self, STATE, newSViv(state)); 
    5555} 
    5656 
    57 HV* get_dest (AV* self) { 
     57inline HV* get_dest (AV* self) { 
    5858  SV** svp = av_fetch(self, DEST, 0); 
    5959  if (svp) 
     
    6262} 
    6363 
    64 int get_state (AV* self) { 
     64inline int get_state (AV* self) { 
    6565  SV** svp = av_fetch(self, STATE, 0); 
    6666  if (svp) 
     
    6969} 
    7070 
    71 SV* get_buffer (AV* self) { 
     71inline SV* get_buffer (AV* self) { 
    7272  SV** svp = av_fetch(self, BUF, 0); 
    7373  if (svp) 
     
    8888  STRLEN len; 
    8989  char* buf; 
    90   char key[257]; 
    9190  unsigned int itemlen; 
    9291  unsigned int flags; 
     
    9493  int nslen = get_nslen(self); 
    9594  SV* on_item = get_on_item(self); 
    96  
     95  register signed char c; 
     96  char *key; 
     97  register char *p; 
     98  int key_len, barelen; 
     99  int state, copy, new_p; 
     100  char *barekey; 
     101   
    97102  if (DEBUG) 
    98103    printf("get_buffer (nslen = %d)...\n", nslen); 
     
    101106    int rv; 
    102107    buf = SvPV(bufsv, len); 
    103  
    104     if (DEBUG) 
    105       printf(" buf (len=%d) = [%s]\n", len, buf); 
    106  
    107     scanned = 0; 
    108     rv = sscanf(buf, "VALUE %256s %u %u%n", key, &flags, &itemlen, &scanned); 
    109  
    110     if (DEBUG) 
    111       printf("rv=%d, scanned=%d, one=[%d], two=[%d]\n", 
    112              rv, scanned, buf[scanned], buf[scanned+1]); 
    113  
    114     if (rv >= 3 && scanned && buf[scanned+1] == '\n') { 
    115       int p     = scanned + 2;      /* 2 to skip \r\n */ 
    116       int state = itemlen + 2;      /* 2 to include reading final \r\n, a different \r\n */ 
    117       int copy  = len - p > state ? state : len - p; 
    118       char *barekey = key + nslen; 
    119  
    120       if (DEBUG) 
     108    p = buf; 
     109 
     110    if (DEBUG) { 
     111        char first_line[1000]; 
     112        int i; 
     113        char *end; 
     114        for (i = 0, end = buf; *end && *end != '\n' && i++ < 900; end++) 
     115          ; 
     116        end += 10; 
     117        strncpy (first_line, buf, end - buf + 1); 
     118        first_line[end - buf + 1] = '\0'; 
     119        printf("GOT buf (len=%d)\nFirst line: %s\n", len, first_line); 
     120    } 
     121 
     122    if ((c = *p++) == 'V') { 
     123      if (*p++ != 'A' || *p++ != 'L' || *p++ != 'U' || *p++ != 'E' || *p++ != ' ') { 
     124        if (DEBUG) 
     125          puts ("ERROR: Illegal command beginning with V"); 
     126        goto recover_from_partial_line; 
     127      } 
     128         
     129      // Parsing VALUE %s<key> %u<flags> %u<bytes> 
     130 
     131      for (key = p; *p++ > ' ';) 
     132        ; 
     133      key_len = p - key - 1; 
     134      if (*(p - 1) != ' ') { 
     135        if (DEBUG) 
     136          printf ("ERROR: key not space-terminated: key %s, char %c\n", key, *(p - 1)); 
     137        goto recover_from_partial_line;          
     138      } 
     139      // Note that key just points into the buffer and is not null-terminated 
     140      // yet.  Leave it that way in case we're dealing with a partial line. 
     141 
     142      // Get flags and itemlen as integers.  Note invalid characters  
     143      // are not caught and will result in strange numbers. 
     144 
     145      for (flags = 0; (c = *p++ - '0') >= 0; flags = flags * 10 + c) 
     146        ; 
     147      if (c != (signed char)' ' - '0') { 
     148        if (DEBUG) 
     149          puts ("ERROR: Flags not space terminated"); 
     150        goto recover_from_partial_line;                  
     151      } 
     152 
     153       
     154      for (itemlen = 0; (c = *p++ - '0') >= 0; itemlen = itemlen * 10 + c) 
     155        ; 
     156      if (c != (signed char)'\r' - '0' || *p++ != '\n') { 
     157        if (DEBUG) 
     158          puts ("ERROR: byte count not CRLF-terminated"); 
     159        goto recover_from_partial_line;                  
     160      } 
     161 
     162 
     163      // p is left at the start of the value data. 
     164 
     165      new_p = p - buf; 
     166      state = itemlen + 2;      /* 2 to include reading final \r\n, a different \r\n */ 
     167      copy  = len - new_p > state ? state : len - new_p; 
     168      barekey = key + nslen; 
     169      barelen = key_len - nslen; 
     170 
     171      if (DEBUG) { 
     172        char temp_key[256]; 
     173        strncpy (temp_key, key, key_len); 
     174        temp_key[key_len] = '\0'; 
    121175        printf("key=[%s], state=%d, copy=%d\n", key, state, copy); 
     176      } 
    122177 
    123178      if (copy) { 
    124         //SV*  newSVpv(const char*, STRLEN); 
    125         //SV**  hv_store(HV*, const char* key, U32 klen, SV* val, U32 hash); 
    126         /*  $ret->{$self->[KEY]} = substr($self->[BUF], $p, $copy) */ 
    127         hv_store(ret, barekey, strlen(barekey), newSVpv(buf + p, copy), 0); 
    128         buf[p + copy - 1] = '\0'; 
     179        *(key + key_len) = '\0';        // Null-terminate the key in-buffer 
     180        hv_store(ret, barekey, barelen, newSVpv(buf + new_p, copy), 0); 
     181        buf[new_p + copy - 1] = '\0'; 
    129182 
    130183        if (DEBUG) 
    131           printf("doing store:  len=%d key=[%s] of data [%s]\n", 
    132                  strlen(barekey), barekey, 
    133                  buf + p); 
     184          printf("doing store:  len=%d key=[%s] of data [%c]\n", 
     185                 strlen(barekey), barekey, *(buf + new_p)); 
    134186      } 
    135187 
    136188      /* delete the stuff we used */ 
    137       sv_chop(bufsv, buf + p + copy); 
     189      sv_chop(bufsv, buf + new_p + copy); 
    138190 
    139191      if (copy == state) { 
     
    144196        SAVETMPS ; 
    145197        PUSHMARK(SP) ; 
    146         XPUSHs(sv_2mortal(newSVpv(barekey, strlen(barekey)))); 
     198        XPUSHs(sv_2mortal(newSVpv(barekey, barelen))); 
    147199        XPUSHs(sv_2mortal(newSViv(flags))); 
    148200        PUTBACK ; 
     
    158210        set_offset(self, copy); 
    159211        set_flags(self, flags); 
    160         set_key(self, barekey); 
     212        set_key(self, barekey, barelen); 
    161213        set_state(self, state); 
    162214 
     
    168220    } 
    169221 
    170     if (strncmp(buf, "END\r\n", 5) == 0) { 
    171       /* we're done successfully, return 1 to finish */ 
    172       return final_answer(self, 1); 
    173     } 
     222    else if (c == 'E') { 
     223       
     224      // Parsing END 
     225       
     226      if (*p++ == 'N' && *p++ == 'D' && *p++ == '\r' && *p == '\n') 
     227        return final_answer(self, 1); 
     228    } 
     229    // Just fall through if after 'E' was not "ND\r\n" 
     230 
     231    else  
     232      ;                 // Unknown command: not 'E' or 'V' at [0] 
    174233 
    175234 
     
    183242    */ 
    184243 
     244  recover_from_partial_line: 
    185245    set_offset(self, len); 
    186246    return 0;