Hex Artifact Content
Not logged in

Artifact 199885625673bbe2238093ce30f311c6bd2544b1:

File src/blob.c part of check-in [054dd31b71] - Use our own isspace() function since the standard-library isspace() sometimes gives incorrect results for non-ASCII characters. by drh on 2008-11-03 21:56:09.

0000: 2f 2a 0a 2a 2a 20 43 6f 70 79 72 69 67 68 74 20  /*.** Copyright 
0010: 28 63 29 20 32 30 30 36 20 44 2e 20 52 69 63 68  (c) 2006 D. Rich
0020: 61 72 64 20 48 69 70 70 0a 2a 2a 0a 2a 2a 20 54  ard Hipp.**.** T
0030: 68 69 73 20 70 72 6f 67 72 61 6d 20 69 73 20 66  his program is f
0040: 72 65 65 20 73 6f 66 74 77 61 72 65 3b 20 79 6f  ree software; yo
0050: 75 20 63 61 6e 20 72 65 64 69 73 74 72 69 62 75  u can redistribu
0060: 74 65 20 69 74 20 61 6e 64 2f 6f 72 0a 2a 2a 20  te it and/or.** 
0070: 6d 6f 64 69 66 79 20 69 74 20 75 6e 64 65 72 20  modify it under 
0080: 74 68 65 20 74 65 72 6d 73 20 6f 66 20 74 68 65  the terms of the
0090: 20 47 4e 55 20 47 65 6e 65 72 61 6c 20 50 75 62   GNU General Pub
00a0: 6c 69 63 0a 2a 2a 20 4c 69 63 65 6e 73 65 20 76  lic.** License v
00b0: 65 72 73 69 6f 6e 20 32 20 61 73 20 70 75 62 6c  ersion 2 as publ
00c0: 69 73 68 65 64 20 62 79 20 74 68 65 20 46 72 65  ished by the Fre
00d0: 65 20 53 6f 66 74 77 61 72 65 20 46 6f 75 6e 64  e Software Found
00e0: 61 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 54 68 69  ation..**.** Thi
00f0: 73 20 70 72 6f 67 72 61 6d 20 69 73 20 64 69 73  s program is dis
0100: 74 72 69 62 75 74 65 64 20 69 6e 20 74 68 65 20  tributed in the 
0110: 68 6f 70 65 20 74 68 61 74 20 69 74 20 77 69 6c  hope that it wil
0120: 6c 20 62 65 20 75 73 65 66 75 6c 2c 0a 2a 2a 20  l be useful,.** 
0130: 62 75 74 20 57 49 54 48 4f 55 54 20 41 4e 59 20  but WITHOUT ANY 
0140: 57 41 52 52 41 4e 54 59 3b 20 77 69 74 68 6f 75  WARRANTY; withou
0150: 74 20 65 76 65 6e 20 74 68 65 20 69 6d 70 6c 69  t even the impli
0160: 65 64 20 77 61 72 72 61 6e 74 79 20 6f 66 0a 2a  ed warranty of.*
0170: 2a 20 4d 45 52 43 48 41 4e 54 41 42 49 4c 49 54  * MERCHANTABILIT
0180: 59 20 6f 72 20 46 49 54 4e 45 53 53 20 46 4f 52  Y or FITNESS FOR
0190: 20 41 20 50 41 52 54 49 43 55 4c 41 52 20 50 55   A PARTICULAR PU
01a0: 52 50 4f 53 45 2e 20 20 53 65 65 20 74 68 65 20  RPOSE.  See the 
01b0: 47 4e 55 0a 2a 2a 20 47 65 6e 65 72 61 6c 20 50  GNU.** General P
01c0: 75 62 6c 69 63 20 4c 69 63 65 6e 73 65 20 66 6f  ublic License fo
01d0: 72 20 6d 6f 72 65 20 64 65 74 61 69 6c 73 2e 0a  r more details..
01e0: 2a 2a 20 0a 2a 2a 20 59 6f 75 20 73 68 6f 75 6c  ** .** You shoul
01f0: 64 20 68 61 76 65 20 72 65 63 65 69 76 65 64 20  d have received 
0200: 61 20 63 6f 70 79 20 6f 66 20 74 68 65 20 47 4e  a copy of the GN
0210: 55 20 47 65 6e 65 72 61 6c 20 50 75 62 6c 69 63  U General Public
0220: 0a 2a 2a 20 4c 69 63 65 6e 73 65 20 61 6c 6f 6e  .** License alon
0230: 67 20 77 69 74 68 20 74 68 69 73 20 6c 69 62 72  g with this libr
0240: 61 72 79 3b 20 69 66 20 6e 6f 74 2c 20 77 72 69  ary; if not, wri
0250: 74 65 20 74 6f 20 74 68 65 0a 2a 2a 20 46 72 65  te to the.** Fre
0260: 65 20 53 6f 66 74 77 61 72 65 20 46 6f 75 6e 64  e Software Found
0270: 61 74 69 6f 6e 2c 20 49 6e 63 2e 2c 20 35 39 20  ation, Inc., 59 
0280: 54 65 6d 70 6c 65 20 50 6c 61 63 65 20 2d 20 53  Temple Place - S
0290: 75 69 74 65 20 33 33 30 2c 0a 2a 2a 20 42 6f 73  uite 330,.** Bos
02a0: 74 6f 6e 2c 20 4d 41 20 20 30 32 31 31 31 2d 31  ton, MA  02111-1
02b0: 33 30 37 2c 20 55 53 41 2e 0a 2a 2a 0a 2a 2a 20  307, USA..**.** 
02c0: 41 75 74 68 6f 72 20 63 6f 6e 74 61 63 74 20 69  Author contact i
02d0: 6e 66 6f 72 6d 61 74 69 6f 6e 3a 0a 2a 2a 20 20  nformation:.**  
02e0: 20 64 72 68 40 68 77 61 63 69 2e 63 6f 6d 0a 2a   drh@hwaci.com.*
02f0: 2a 20 20 20 68 74 74 70 3a 2f 2f 77 77 77 2e 68  *   http://www.h
0300: 77 61 63 69 2e 63 6f 6d 2f 64 72 68 2f 0a 2a 2a  waci.com/drh/.**
0310: 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  .***************
0320: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0330: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0340: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0350: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0360: 0a 2a 2a 0a 2a 2a 20 41 20 42 6c 6f 62 20 69 73  .**.** A Blob is
0370: 20 61 20 76 61 72 69 61 62 6c 65 2d 6c 65 6e 67   a variable-leng
0380: 74 68 20 63 6f 6e 74 61 69 6e 65 72 73 20 66 6f  th containers fo
0390: 72 20 61 72 62 69 74 72 61 72 79 20 73 74 72 69  r arbitrary stri
03a0: 6e 67 0a 2a 2a 20 6f 72 20 62 69 6e 61 72 79 20  ng.** or binary 
03b0: 64 61 74 61 2e 0a 2a 2f 0a 23 69 6e 63 6c 75 64  data..*/.#includ
03c0: 65 20 22 63 6f 6e 66 69 67 2e 68 22 0a 23 69 6e  e "config.h".#in
03d0: 63 6c 75 64 65 20 3c 7a 6c 69 62 2e 68 3e 0a 23  clude <zlib.h>.#
03e0: 69 6e 63 6c 75 64 65 20 22 62 6c 6f 62 2e 68 22  include "blob.h"
03f0: 0a 0a 23 69 66 20 49 4e 54 45 52 46 41 43 45 0a  ..#if INTERFACE.
0400: 2f 2a 0a 2a 2a 20 41 20 42 6c 6f 62 20 63 61 6e  /*.** A Blob can
0410: 20 68 6f 6c 64 20 61 20 73 74 72 69 6e 67 20 6f   hold a string o
0420: 72 20 61 20 62 69 6e 61 72 79 20 6f 62 6a 65 63  r a binary objec
0430: 74 20 6f 66 20 61 72 62 69 74 72 61 72 79 20 73  t of arbitrary s
0440: 69 7a 65 2e 20 20 54 68 65 0a 2a 2a 20 73 69 7a  ize.  The.** siz
0450: 65 20 63 68 61 6e 67 65 73 20 61 73 20 6e 65 63  e changes as nec
0460: 65 73 73 61 72 79 2e 0a 2a 2f 0a 73 74 72 75 63  essary..*/.struc
0470: 74 20 42 6c 6f 62 20 7b 0a 20 20 75 6e 73 69 67  t Blob {.  unsig
0480: 6e 65 64 20 69 6e 74 20 6e 55 73 65 64 3b 20 20  ned int nUsed;  
0490: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d            /* Num
04a0: 62 65 72 20 6f 66 20 62 79 74 65 73 20 75 73 65  ber of bytes use
04b0: 64 20 69 6e 20 61 44 61 74 61 5b 5d 20 2a 2f 0a  d in aData[] */.
04c0: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e    unsigned int n
04d0: 41 6c 6c 6f 63 3b 20 20 20 20 20 20 20 20 20 20  Alloc;          
04e0: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79   /* Number of by
04f0: 74 65 73 20 61 6c 6c 6f 63 61 74 65 64 20 66 6f  tes allocated fo
0500: 72 20 61 44 61 74 61 5b 5d 20 2a 2f 0a 20 20 75  r aData[] */.  u
0510: 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 43 75 72  nsigned int iCur
0520: 73 6f 72 3b 20 20 20 20 20 20 20 20 20 20 2f 2a  sor;          /*
0530: 20 4e 65 78 74 20 63 68 61 72 61 63 74 65 72 20   Next character 
0540: 6f 66 20 69 6e 70 75 74 20 74 6f 20 70 61 72 73  of input to pars
0550: 65 20 2a 2f 0a 20 20 63 68 61 72 20 2a 61 44 61  e */.  char *aDa
0560: 74 61 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  ta;             
0570: 20 20 20 20 20 20 2f 2a 20 57 68 65 72 65 20 74        /* Where t
0580: 68 65 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 69  he information i
0590: 73 20 73 74 6f 72 65 64 20 2a 2f 0a 20 20 76 6f  s stored */.  vo
05a0: 69 64 20 28 2a 78 52 65 61 6c 6c 6f 63 29 28 42  id (*xRealloc)(B
05b0: 6c 6f 62 2a 2c 20 75 6e 73 69 67 6e 65 64 20 69  lob*, unsigned i
05c0: 6e 74 29 3b 20 2f 2a 20 46 75 6e 63 74 69 6f 6e  nt); /* Function
05d0: 20 74 6f 20 72 65 61 6c 6c 6f 63 61 74 65 20 74   to reallocate t
05e0: 68 65 20 62 75 66 66 65 72 20 2a 2f 0a 7d 3b 0a  he buffer */.};.
05f0: 0a 2f 2a 0a 2a 2a 20 54 68 65 20 63 75 72 72 65  ./*.** The curre
0600: 6e 74 20 73 69 7a 65 20 6f 66 20 61 20 42 6c 6f  nt size of a Blo
0610: 62 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 62 6c 6f  b.*/.#define blo
0620: 62 5f 73 69 7a 65 28 58 29 20 20 28 28 58 29 2d  b_size(X)  ((X)-
0630: 3e 6e 55 73 65 64 29 0a 0a 2f 2a 0a 2a 2a 20 54  >nUsed)../*.** T
0640: 68 65 20 62 75 66 66 65 72 20 68 6f 6c 64 69 6e  he buffer holdin
0650: 67 20 74 68 65 20 62 6c 6f 62 20 64 61 74 61 0a  g the blob data.
0660: 2a 2f 0a 23 64 65 66 69 6e 65 20 62 6c 6f 62 5f  */.#define blob_
0670: 62 75 66 66 65 72 28 58 29 20 20 28 28 58 29 2d  buffer(X)  ((X)-
0680: 3e 61 44 61 74 61 29 0a 0a 2f 2a 0a 2a 2a 20 53  >aData)../*.** S
0690: 65 65 6b 20 77 68 65 6e 63 65 20 70 61 72 61 6d  eek whence param
06a0: 65 74 65 72 20 76 61 6c 75 65 73 0a 2a 2f 0a 23  eter values.*/.#
06b0: 64 65 66 69 6e 65 20 42 4c 4f 42 5f 53 45 45 4b  define BLOB_SEEK
06c0: 5f 53 45 54 20 31 0a 23 64 65 66 69 6e 65 20 42  _SET 1.#define B
06d0: 4c 4f 42 5f 53 45 45 4b 5f 43 55 52 20 32 0a 23  LOB_SEEK_CUR 2.#
06e0: 64 65 66 69 6e 65 20 42 4c 4f 42 5f 53 45 45 4b  define BLOB_SEEK
06f0: 5f 45 4e 44 20 33 0a 0a 23 65 6e 64 69 66 20 2f  _END 3..#endif /
0700: 2a 20 49 4e 54 45 52 46 41 43 45 20 2a 2f 0a 0a  * INTERFACE */..
0710: 2f 2a 0a 2a 2a 20 4d 61 6b 65 20 73 75 72 65 20  /*.** Make sure 
0720: 61 20 62 6c 6f 62 20 69 73 20 69 6e 69 74 69 61  a blob is initia
0730: 6c 69 7a 65 64 0a 2a 2f 0a 23 64 65 66 69 6e 65  lized.*/.#define
0740: 20 62 6c 6f 62 5f 69 73 5f 69 6e 69 74 28 78 29   blob_is_init(x)
0750: 20 5c 0a 20 20 61 73 73 65 72 74 28 28 78 29 2d   \.  assert((x)-
0760: 3e 78 52 65 61 6c 6c 6f 63 3d 3d 62 6c 6f 62 52  >xRealloc==blobR
0770: 65 61 6c 6c 6f 63 4d 61 6c 6c 6f 63 20 7c 7c 20  eallocMalloc || 
0780: 28 78 29 2d 3e 78 52 65 61 6c 6c 6f 63 3d 3d 62  (x)->xRealloc==b
0790: 6c 6f 62 52 65 61 6c 6c 6f 63 53 74 61 74 69 63  lobReallocStatic
07a0: 29 0a 0a 2f 2a 0a 2a 2a 20 4d 61 6b 65 20 73 75  )../*.** Make su
07b0: 72 65 20 61 20 62 6c 6f 62 20 64 6f 65 73 20 6e  re a blob does n
07c0: 6f 74 20 63 6f 6e 74 61 69 6e 20 6d 61 6c 6c 6f  ot contain mallo
07d0: 63 65 64 20 6d 65 6d 6f 72 79 2e 0a 2a 2f 0a 23  ced memory..*/.#
07e0: 69 66 20 30 20 20 2f 2a 20 45 6e 61 62 6c 65 20  if 0  /* Enable 
07f0: 66 6f 72 20 64 65 62 75 67 67 69 6e 67 20 6f 6e  for debugging on
0800: 6c 79 20 2a 2f 0a 23 64 65 66 69 6e 65 20 62 6c  ly */.#define bl
0810: 6f 62 5f 69 73 5f 72 65 73 65 74 28 78 29 20 5c  ob_is_reset(x) \
0820: 0a 20 20 61 73 73 65 72 74 28 28 78 29 2d 3e 78  .  assert((x)->x
0830: 52 65 61 6c 6c 6f 63 21 3d 62 6c 6f 62 52 65 61  Realloc!=blobRea
0840: 6c 6c 6f 63 4d 61 6c 6c 6f 63 20 7c 7c 20 28 78  llocMalloc || (x
0850: 29 2d 3e 6e 41 6c 6c 6f 63 3d 3d 30 29 0a 23 65  )->nAlloc==0).#e
0860: 6c 73 65 0a 23 64 65 66 69 6e 65 20 62 6c 6f 62  lse.#define blob
0870: 5f 69 73 5f 72 65 73 65 74 28 78 29 0a 23 65 6e  _is_reset(x).#en
0880: 64 69 66 0a 0a 2f 2a 0a 2a 2a 20 57 65 20 66 69  dif../*.** We fi
0890: 6e 64 20 74 68 61 74 20 74 68 65 20 62 75 69 6c  nd that the buil
08a0: 74 2d 69 6e 20 69 73 73 70 61 63 65 28 29 20 66  t-in isspace() f
08b0: 75 6e 63 74 69 6f 6e 20 64 6f 65 73 20 6e 6f 74  unction does not
08c0: 20 77 6f 72 6b 20 66 6f 72 0a 2a 2a 20 73 6f 6d   work for.** som
08d0: 65 20 69 6e 74 65 72 6e 61 74 69 6f 6e 61 6c 20  e international 
08e0: 63 68 61 72 61 63 74 65 72 20 73 65 74 73 2e 20  character sets. 
08f0: 20 53 6f 20 68 65 72 65 20 69 73 20 61 20 73 75   So here is a su
0900: 62 73 74 69 74 75 74 65 2e 0a 2a 2f 0a 73 74 61  bstitute..*/.sta
0910: 74 69 63 20 69 6e 74 20 62 6c 6f 62 5f 69 73 73  tic int blob_iss
0920: 70 61 63 65 28 63 68 61 72 20 63 29 7b 0a 20 20  pace(char c){.  
0930: 72 65 74 75 72 6e 20 63 3d 3d 27 20 27 20 20 7c  return c==' '  |
0940: 7c 20 63 3d 3d 27 5c 6e 27 20 7c 7c 20 63 3d 3d  | c=='\n' || c==
0950: 27 5c 74 27 20 7c 7c 0a 20 20 20 20 20 20 20 20  '\t' ||.        
0960: 20 63 3d 3d 27 5c 72 27 20 7c 7c 20 63 3d 3d 27   c=='\r' || c=='
0970: 5c 66 27 20 7c 7c 20 63 3d 3d 27 5c 76 27 3b 0a  \f' || c=='\v';.
0980: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f  }../*.** This ro
0990: 75 74 69 6e 65 20 69 73 20 63 61 6c 6c 65 64 20  utine is called 
09a0: 69 66 20 61 20 62 6c 6f 62 20 6f 70 65 72 61 74  if a blob operat
09b0: 69 6f 6e 20 66 61 69 6c 73 20 62 65 63 61 75 73  ion fails becaus
09c0: 65 20 77 65 0a 2a 2a 20 68 61 76 65 20 72 75 6e  e we.** have run
09d0: 20 6f 75 74 20 6f 66 20 6d 65 6d 6f 72 79 2e 0a   out of memory..
09e0: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 62  */.static void b
09f0: 6c 6f 62 5f 70 61 6e 69 63 28 76 6f 69 64 29 7b  lob_panic(void){
0a00: 0a 20 20 73 74 61 74 69 63 20 63 6f 6e 73 74 20  .  static const 
0a10: 63 68 61 72 20 7a 45 72 72 4d 73 67 5b 5d 20 3d  char zErrMsg[] =
0a20: 20 22 6f 75 74 20 6f 66 20 6d 65 6d 6f 72 79 5c   "out of memory\
0a30: 6e 22 3b 0a 20 20 77 72 69 74 65 28 32 2c 20 7a  n";.  write(2, z
0a40: 45 72 72 4d 73 67 2c 20 73 69 7a 65 6f 66 28 7a  ErrMsg, sizeof(z
0a50: 45 72 72 4d 73 67 29 2d 31 29 3b 0a 20 20 65 78  ErrMsg)-1);.  ex
0a60: 69 74 28 31 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  it(1);.}../*.** 
0a70: 41 20 72 65 61 6c 6c 6f 63 61 74 69 6f 6e 20 66  A reallocation f
0a80: 75 6e 63 74 69 6f 6e 20 74 68 61 74 20 61 73 73  unction that ass
0a90: 75 6d 65 73 20 74 68 61 74 20 61 44 61 74 61 20  umes that aData 
0aa0: 63 61 6d 65 20 66 72 6f 6d 20 6d 61 6c 6c 6f 63  came from malloc
0ab0: 28 29 2e 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63  ()..** This func
0ac0: 74 69 6f 6e 20 61 74 74 65 6d 70 74 73 20 74 6f  tion attempts to
0ad0: 20 72 65 73 69 7a 65 20 74 68 65 20 62 75 66 66   resize the buff
0ae0: 65 72 20 6f 66 20 74 68 65 20 62 6c 6f 62 20 74  er of the blob t
0af0: 6f 20 68 6f 6c 64 0a 2a 2a 20 6e 65 77 53 69 7a  o hold.** newSiz
0b00: 65 20 62 79 74 65 73 2e 20 20 0a 2a 2a 0a 2a 2a  e bytes.  .**.**
0b10: 20 4e 6f 20 61 74 74 65 6d 70 74 20 69 73 20 6d   No attempt is m
0b20: 61 64 65 20 74 6f 20 72 65 63 6f 76 65 72 20 66  ade to recover f
0b30: 72 6f 6d 20 61 6e 20 6f 75 74 2d 6f 66 2d 6d 65  rom an out-of-me
0b40: 6d 6f 72 79 20 65 72 72 6f 72 2e 0a 2a 2a 20 49  mory error..** I
0b50: 66 20 61 6e 20 4f 4f 4d 20 65 72 72 6f 72 20 6f  f an OOM error o
0b60: 63 63 75 72 73 2c 20 61 6e 20 65 72 72 6f 72 20  ccurs, an error 
0b70: 6d 65 73 73 61 67 65 20 69 73 20 70 72 69 6e 74  message is print
0b80: 65 64 20 6f 6e 20 73 74 64 65 72 72 0a 2a 2a 20  ed on stderr.** 
0b90: 61 6e 64 20 74 68 65 20 70 72 6f 67 72 61 6d 20  and the program 
0ba0: 65 78 69 74 73 2e 0a 2a 2f 0a 76 6f 69 64 20 62  exits..*/.void b
0bb0: 6c 6f 62 52 65 61 6c 6c 6f 63 4d 61 6c 6c 6f 63  lobReallocMalloc
0bc0: 28 42 6c 6f 62 20 2a 70 42 6c 6f 62 2c 20 75 6e  (Blob *pBlob, un
0bd0: 73 69 67 6e 65 64 20 69 6e 74 20 6e 65 77 53 69  signed int newSi
0be0: 7a 65 29 7b 0a 20 20 69 66 28 20 6e 65 77 53 69  ze){.  if( newSi
0bf0: 7a 65 3d 3d 30 20 29 7b 0a 20 20 20 20 66 72 65  ze==0 ){.    fre
0c00: 65 28 70 42 6c 6f 62 2d 3e 61 44 61 74 61 29 3b  e(pBlob->aData);
0c10: 0a 20 20 20 20 70 42 6c 6f 62 2d 3e 61 44 61 74  .    pBlob->aDat
0c20: 61 20 3d 20 30 3b 0a 20 20 20 20 70 42 6c 6f 62  a = 0;.    pBlob
0c30: 2d 3e 6e 41 6c 6c 6f 63 20 3d 20 30 3b 0a 20 20  ->nAlloc = 0;.  
0c40: 20 20 70 42 6c 6f 62 2d 3e 6e 55 73 65 64 20 3d    pBlob->nUsed =
0c50: 20 30 3b 0a 20 20 20 20 70 42 6c 6f 62 2d 3e 69   0;.    pBlob->i
0c60: 43 75 72 73 6f 72 20 3d 20 30 3b 0a 20 20 7d 65  Cursor = 0;.  }e
0c70: 6c 73 65 20 69 66 28 20 6e 65 77 53 69 7a 65 3e  lse if( newSize>
0c80: 70 42 6c 6f 62 2d 3e 6e 41 6c 6c 6f 63 20 7c 7c  pBlob->nAlloc ||
0c90: 20 6e 65 77 53 69 7a 65 3c 70 42 6c 6f 62 2d 3e   newSize<pBlob->
0ca0: 6e 41 6c 6c 6f 63 2d 34 30 30 30 20 29 7b 0a 20  nAlloc-4000 ){. 
0cb0: 20 20 20 63 68 61 72 20 2a 70 4e 65 77 20 3d 20     char *pNew = 
0cc0: 72 65 61 6c 6c 6f 63 28 70 42 6c 6f 62 2d 3e 61  realloc(pBlob->a
0cd0: 44 61 74 61 2c 20 6e 65 77 53 69 7a 65 29 3b 0a  Data, newSize);.
0ce0: 20 20 20 20 69 66 28 20 70 4e 65 77 3d 3d 30 20      if( pNew==0 
0cf0: 29 20 62 6c 6f 62 5f 70 61 6e 69 63 28 29 3b 0a  ) blob_panic();.
0d00: 20 20 20 20 70 42 6c 6f 62 2d 3e 61 44 61 74 61      pBlob->aData
0d10: 20 3d 20 70 4e 65 77 3b 0a 20 20 20 20 70 42 6c   = pNew;.    pBl
0d20: 6f 62 2d 3e 6e 41 6c 6c 6f 63 20 3d 20 6e 65 77  ob->nAlloc = new
0d30: 53 69 7a 65 3b 0a 20 20 20 20 69 66 28 20 70 42  Size;.    if( pB
0d40: 6c 6f 62 2d 3e 6e 55 73 65 64 3e 70 42 6c 6f 62  lob->nUsed>pBlob
0d50: 2d 3e 6e 41 6c 6c 6f 63 20 29 7b 0a 20 20 20 20  ->nAlloc ){.    
0d60: 20 20 70 42 6c 6f 62 2d 3e 6e 55 73 65 64 20 3d    pBlob->nUsed =
0d70: 20 70 42 6c 6f 62 2d 3e 6e 41 6c 6c 6f 63 3b 0a   pBlob->nAlloc;.
0d80: 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a      }.  }.}../*.
0d90: 2a 2a 20 41 6e 20 69 6e 69 74 69 61 6c 69 7a 65  ** An initialize
0da0: 72 20 66 6f 72 20 42 6c 6f 62 73 0a 2a 2f 0a 23  r for Blobs.*/.#
0db0: 69 66 20 49 4e 54 45 52 46 41 43 45 0a 23 64 65  if INTERFACE.#de
0dc0: 66 69 6e 65 20 42 4c 4f 42 5f 49 4e 49 54 49 41  fine BLOB_INITIA
0dd0: 4c 49 5a 45 52 20 20 7b 30 2c 30 2c 30 2c 30 2c  LIZER  {0,0,0,0,
0de0: 62 6c 6f 62 52 65 61 6c 6c 6f 63 4d 61 6c 6c 6f  blobReallocMallo
0df0: 63 7d 0a 23 65 6e 64 69 66 0a 63 6f 6e 73 74 20  c}.#endif.const 
0e00: 42 6c 6f 62 20 65 6d 70 74 79 5f 62 6c 6f 62 20  Blob empty_blob 
0e10: 3d 20 42 4c 4f 42 5f 49 4e 49 54 49 41 4c 49 5a  = BLOB_INITIALIZ
0e20: 45 52 3b 0a 0a 2f 2a 0a 2a 2a 20 41 20 72 65 61  ER;../*.** A rea
0e30: 6c 6c 6f 63 61 74 69 6f 6e 20 66 75 6e 63 74 69  llocation functi
0e40: 6f 6e 20 66 6f 72 20 77 68 65 6e 20 74 68 65 20  on for when the 
0e50: 69 6e 69 74 69 61 6c 20 73 74 72 69 6e 67 20 69  initial string i
0e60: 73 20 69 6e 20 75 6e 6d 61 6e 61 67 65 64 0a 2a  s in unmanaged.*
0e70: 2a 20 73 70 61 63 65 2e 20 20 43 6f 70 79 20 74  * space.  Copy t
0e80: 68 65 20 73 74 72 69 6e 67 20 74 6f 20 6d 65 6d  he string to mem
0e90: 6f 72 79 20 6f 62 74 61 69 6e 65 64 20 66 72 6f  ory obtained fro
0ea0: 6d 20 6d 61 6c 6c 6f 63 28 29 2e 0a 2a 2f 0a 73  m malloc()..*/.s
0eb0: 74 61 74 69 63 20 76 6f 69 64 20 62 6c 6f 62 52  tatic void blobR
0ec0: 65 61 6c 6c 6f 63 53 74 61 74 69 63 28 42 6c 6f  eallocStatic(Blo
0ed0: 62 20 2a 70 42 6c 6f 62 2c 20 75 6e 73 69 67 6e  b *pBlob, unsign
0ee0: 65 64 20 69 6e 74 20 6e 65 77 53 69 7a 65 29 7b  ed int newSize){
0ef0: 0a 20 20 69 66 28 20 6e 65 77 53 69 7a 65 3d 3d  .  if( newSize==
0f00: 30 20 29 7b 0a 20 20 20 20 2a 70 42 6c 6f 62 20  0 ){.    *pBlob 
0f10: 3d 20 65 6d 70 74 79 5f 62 6c 6f 62 3b 0a 20 20  = empty_blob;.  
0f20: 7d 65 6c 73 65 7b 0a 20 20 20 20 63 68 61 72 20  }else{.    char 
0f30: 2a 70 4e 65 77 20 3d 20 6d 61 6c 6c 6f 63 28 20  *pNew = malloc( 
0f40: 6e 65 77 53 69 7a 65 20 29 3b 0a 20 20 20 20 69  newSize );.    i
0f50: 66 28 20 70 4e 65 77 3d 3d 30 20 29 20 62 6c 6f  f( pNew==0 ) blo
0f60: 62 5f 70 61 6e 69 63 28 29 3b 0a 20 20 20 20 69  b_panic();.    i
0f70: 66 28 20 70 42 6c 6f 62 2d 3e 6e 55 73 65 64 3e  f( pBlob->nUsed>
0f80: 6e 65 77 53 69 7a 65 20 29 20 70 42 6c 6f 62 2d  newSize ) pBlob-
0f90: 3e 6e 55 73 65 64 20 3d 20 6e 65 77 53 69 7a 65  >nUsed = newSize
0fa0: 3b 0a 20 20 20 20 6d 65 6d 63 70 79 28 70 4e 65  ;.    memcpy(pNe
0fb0: 77 2c 20 70 42 6c 6f 62 2d 3e 61 44 61 74 61 2c  w, pBlob->aData,
0fc0: 20 70 42 6c 6f 62 2d 3e 6e 55 73 65 64 29 3b 0a   pBlob->nUsed);.
0fd0: 20 20 20 20 70 42 6c 6f 62 2d 3e 61 44 61 74 61      pBlob->aData
0fe0: 20 3d 20 70 4e 65 77 3b 0a 20 20 20 20 70 42 6c   = pNew;.    pBl
0ff0: 6f 62 2d 3e 78 52 65 61 6c 6c 6f 63 20 3d 20 62  ob->xRealloc = b
1000: 6c 6f 62 52 65 61 6c 6c 6f 63 4d 61 6c 6c 6f 63  lobReallocMalloc
1010: 3b 0a 20 20 20 20 70 42 6c 6f 62 2d 3e 6e 41 6c  ;.    pBlob->nAl
1020: 6c 6f 63 20 3d 20 6e 65 77 53 69 7a 65 3b 0a 20  loc = newSize;. 
1030: 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 73 65   }.}../*.** Rese
1040: 74 20 61 20 62 6c 6f 62 20 74 6f 20 62 65 20 61  t a blob to be a
1050: 6e 20 65 6d 70 74 79 20 63 6f 6e 74 61 69 6e 65  n empty containe
1060: 72 2e 0a 2a 2f 0a 76 6f 69 64 20 62 6c 6f 62 5f  r..*/.void blob_
1070: 72 65 73 65 74 28 42 6c 6f 62 20 2a 70 42 6c 6f  reset(Blob *pBlo
1080: 62 29 7b 0a 20 20 62 6c 6f 62 5f 69 73 5f 69 6e  b){.  blob_is_in
1090: 69 74 28 70 42 6c 6f 62 29 3b 0a 20 20 70 42 6c  it(pBlob);.  pBl
10a0: 6f 62 2d 3e 78 52 65 61 6c 6c 6f 63 28 70 42 6c  ob->xRealloc(pBl
10b0: 6f 62 2c 20 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ob, 0);.}../*.**
10c0: 20 49 6e 69 74 69 61 6c 69 7a 65 20 61 20 62 6c   Initialize a bl
10d0: 6f 62 20 74 6f 20 61 20 73 74 72 69 6e 67 20 6f  ob to a string o
10e0: 72 20 62 79 74 65 2d 61 72 72 61 79 20 63 6f 6e  r byte-array con
10f0: 73 74 61 6e 74 20 6f 66 20 61 20 73 70 65 63 69  stant of a speci
1100: 66 69 65 64 20 6c 65 6e 67 74 68 2e 0a 2a 2a 20  fied length..** 
1110: 41 6e 79 20 70 72 69 6f 72 20 64 61 74 61 20 69  Any prior data i
1120: 6e 20 74 68 65 20 62 6c 6f 62 20 69 73 20 64 69  n the blob is di
1130: 73 63 61 72 64 65 64 2e 0a 2a 2f 0a 76 6f 69 64  scarded..*/.void
1140: 20 62 6c 6f 62 5f 69 6e 69 74 28 42 6c 6f 62 20   blob_init(Blob 
1150: 2a 70 42 6c 6f 62 2c 20 63 6f 6e 73 74 20 63 68  *pBlob, const ch
1160: 61 72 20 2a 7a 44 61 74 61 2c 20 69 6e 74 20 73  ar *zData, int s
1170: 69 7a 65 29 7b 0a 20 20 62 6c 6f 62 5f 69 73 5f  ize){.  blob_is_
1180: 72 65 73 65 74 28 70 42 6c 6f 62 29 3b 0a 20 20  reset(pBlob);.  
1190: 69 66 28 20 7a 44 61 74 61 3d 3d 30 20 29 7b 0a  if( zData==0 ){.
11a0: 20 20 20 20 2a 70 42 6c 6f 62 20 3d 20 65 6d 70      *pBlob = emp
11b0: 74 79 5f 62 6c 6f 62 3b 0a 20 20 7d 65 6c 73 65  ty_blob;.  }else
11c0: 7b 0a 20 20 20 20 69 66 28 20 73 69 7a 65 3c 3d  {.    if( size<=
11d0: 30 20 29 20 73 69 7a 65 20 3d 20 73 74 72 6c 65  0 ) size = strle
11e0: 6e 28 7a 44 61 74 61 29 3b 0a 20 20 20 20 70 42  n(zData);.    pB
11f0: 6c 6f 62 2d 3e 6e 55 73 65 64 20 3d 20 70 42 6c  lob->nUsed = pBl
1200: 6f 62 2d 3e 6e 41 6c 6c 6f 63 20 3d 20 73 69 7a  ob->nAlloc = siz
1210: 65 3b 0a 20 20 20 20 70 42 6c 6f 62 2d 3e 61 44  e;.    pBlob->aD
1220: 61 74 61 20 3d 20 28 63 68 61 72 2a 29 7a 44 61  ata = (char*)zDa
1230: 74 61 3b 0a 20 20 20 20 70 42 6c 6f 62 2d 3e 69  ta;.    pBlob->i
1240: 43 75 72 73 6f 72 20 3d 20 30 3b 0a 20 20 20 20  Cursor = 0;.    
1250: 70 42 6c 6f 62 2d 3e 78 52 65 61 6c 6c 6f 63 20  pBlob->xRealloc 
1260: 3d 20 62 6c 6f 62 52 65 61 6c 6c 6f 63 53 74 61  = blobReallocSta
1270: 74 69 63 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a  tic;.  }.}../*.*
1280: 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 61 20 62  * Initialize a b
1290: 6c 6f 62 20 74 6f 20 61 20 6e 75 6c 2d 74 65 72  lob to a nul-ter
12a0: 6d 69 6e 61 74 65 64 20 73 74 72 69 6e 67 2e 0a  minated string..
12b0: 2a 2a 20 41 6e 79 20 70 72 69 6f 72 20 64 61 74  ** Any prior dat
12c0: 61 20 69 6e 20 74 68 65 20 62 6c 6f 62 20 69 73  a in the blob is
12d0: 20 64 69 73 63 61 72 64 65 64 2e 0a 2a 2f 0a 76   discarded..*/.v
12e0: 6f 69 64 20 62 6c 6f 62 5f 73 65 74 28 42 6c 6f  oid blob_set(Blo
12f0: 62 20 2a 70 42 6c 6f 62 2c 20 63 6f 6e 73 74 20  b *pBlob, const 
1300: 63 68 61 72 20 2a 7a 53 74 72 29 7b 0a 20 20 62  char *zStr){.  b
1310: 6c 6f 62 5f 69 6e 69 74 28 70 42 6c 6f 62 2c 20  lob_init(pBlob, 
1320: 7a 53 74 72 2c 20 2d 31 29 3b 0a 7d 0a 0a 2f 2a  zStr, -1);.}../*
1330: 0a 2a 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 61  .** Initialize a
1340: 20 62 6c 6f 62 20 74 6f 20 61 6e 20 65 6d 70 74   blob to an empt
1350: 79 20 73 74 72 69 6e 67 2e 0a 2a 2f 0a 76 6f 69  y string..*/.voi
1360: 64 20 62 6c 6f 62 5f 7a 65 72 6f 28 42 6c 6f 62  d blob_zero(Blob
1370: 20 2a 70 42 6c 6f 62 29 7b 0a 20 20 73 74 61 74   *pBlob){.  stat
1380: 69 63 20 63 6f 6e 73 74 20 63 68 61 72 20 7a 45  ic const char zE
1390: 6d 70 74 79 5b 5d 20 3d 20 22 22 3b 0a 20 20 62  mpty[] = "";.  b
13a0: 6c 6f 62 5f 69 73 5f 72 65 73 65 74 28 70 42 6c  lob_is_reset(pBl
13b0: 6f 62 29 3b 0a 20 20 70 42 6c 6f 62 2d 3e 6e 55  ob);.  pBlob->nU
13c0: 73 65 64 20 3d 20 30 3b 0a 20 20 70 42 6c 6f 62  sed = 0;.  pBlob
13d0: 2d 3e 6e 41 6c 6c 6f 63 20 3d 20 31 3b 0a 20 20  ->nAlloc = 1;.  
13e0: 70 42 6c 6f 62 2d 3e 61 44 61 74 61 20 3d 20 28  pBlob->aData = (
13f0: 63 68 61 72 2a 29 7a 45 6d 70 74 79 3b 0a 20 20  char*)zEmpty;.  
1400: 70 42 6c 6f 62 2d 3e 69 43 75 72 73 6f 72 20 3d  pBlob->iCursor =
1410: 20 30 3b 0a 20 20 70 42 6c 6f 62 2d 3e 78 52 65   0;.  pBlob->xRe
1420: 61 6c 6c 6f 63 20 3d 20 62 6c 6f 62 52 65 61 6c  alloc = blobReal
1430: 6c 6f 63 53 74 61 74 69 63 3b 0a 7d 0a 0a 2f 2a  locStatic;.}../*
1440: 0a 2a 2a 20 41 70 70 65 6e 64 20 74 65 78 74 20  .** Append text 
1450: 6f 72 20 64 61 74 61 20 74 6f 20 74 68 65 20 65  or data to the e
1460: 6e 64 20 6f 66 20 61 20 62 6c 6f 62 2e 0a 2a 2f  nd of a blob..*/
1470: 0a 76 6f 69 64 20 62 6c 6f 62 5f 61 70 70 65 6e  .void blob_appen
1480: 64 28 42 6c 6f 62 20 2a 70 42 6c 6f 62 2c 20 63  d(Blob *pBlob, c
1490: 6f 6e 73 74 20 63 68 61 72 20 2a 61 44 61 74 61  onst char *aData
14a0: 2c 20 69 6e 74 20 6e 44 61 74 61 29 7b 0a 20 20  , int nData){.  
14b0: 62 6c 6f 62 5f 69 73 5f 69 6e 69 74 28 70 42 6c  blob_is_init(pBl
14c0: 6f 62 29 3b 0a 20 20 69 66 28 20 6e 44 61 74 61  ob);.  if( nData
14d0: 3c 30 20 29 20 6e 44 61 74 61 20 3d 20 73 74 72  <0 ) nData = str
14e0: 6c 65 6e 28 61 44 61 74 61 29 3b 0a 20 20 69 66  len(aData);.  if
14f0: 28 20 6e 44 61 74 61 3d 3d 30 20 29 20 72 65 74  ( nData==0 ) ret
1500: 75 72 6e 3b 0a 20 20 69 66 28 20 70 42 6c 6f 62  urn;.  if( pBlob
1510: 2d 3e 6e 55 73 65 64 20 2b 20 6e 44 61 74 61 20  ->nUsed + nData 
1520: 3e 3d 20 70 42 6c 6f 62 2d 3e 6e 41 6c 6c 6f 63  >= pBlob->nAlloc
1530: 20 29 7b 0a 20 20 20 20 70 42 6c 6f 62 2d 3e 78   ){.    pBlob->x
1540: 52 65 61 6c 6c 6f 63 28 70 42 6c 6f 62 2c 20 70  Realloc(pBlob, p
1550: 42 6c 6f 62 2d 3e 6e 55 73 65 64 20 2b 20 6e 44  Blob->nUsed + nD
1560: 61 74 61 20 2b 20 70 42 6c 6f 62 2d 3e 6e 41 6c  ata + pBlob->nAl
1570: 6c 6f 63 20 2b 20 31 30 30 29 3b 0a 20 20 20 20  loc + 100);.    
1580: 69 66 28 20 70 42 6c 6f 62 2d 3e 6e 55 73 65 64  if( pBlob->nUsed
1590: 20 2b 20 6e 44 61 74 61 20 3e 3d 20 70 42 6c 6f   + nData >= pBlo
15a0: 62 2d 3e 6e 41 6c 6c 6f 63 20 29 7b 0a 20 20 20  b->nAlloc ){.   
15b0: 20 20 20 62 6c 6f 62 5f 70 61 6e 69 63 28 29 3b     blob_panic();
15c0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 6d 65 6d  .    }.  }.  mem
15d0: 63 70 79 28 26 70 42 6c 6f 62 2d 3e 61 44 61 74  cpy(&pBlob->aDat
15e0: 61 5b 70 42 6c 6f 62 2d 3e 6e 55 73 65 64 5d 2c  a[pBlob->nUsed],
15f0: 20 61 44 61 74 61 2c 20 6e 44 61 74 61 29 3b 0a   aData, nData);.
1600: 20 20 70 42 6c 6f 62 2d 3e 6e 55 73 65 64 20 2b    pBlob->nUsed +
1610: 3d 20 6e 44 61 74 61 3b 0a 20 20 70 42 6c 6f 62  = nData;.  pBlob
1620: 2d 3e 61 44 61 74 61 5b 70 42 6c 6f 62 2d 3e 6e  ->aData[pBlob->n
1630: 55 73 65 64 5d 20 3d 20 30 3b 20 20 20 2f 2a 20  Used] = 0;   /* 
1640: 42 6c 6f 62 73 20 61 72 65 20 61 6c 77 61 79 73  Blobs are always
1650: 20 6e 75 6c 2d 74 65 72 6d 69 6e 61 74 65 64 20   nul-terminated 
1660: 2a 2f 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 70 79  */.}../*.** Copy
1670: 20 61 20 62 6c 6f 62 0a 2a 2f 0a 76 6f 69 64 20   a blob.*/.void 
1680: 62 6c 6f 62 5f 63 6f 70 79 28 42 6c 6f 62 20 2a  blob_copy(Blob *
1690: 70 54 6f 2c 20 42 6c 6f 62 20 2a 70 46 72 6f 6d  pTo, Blob *pFrom
16a0: 29 7b 0a 20 20 62 6c 6f 62 5f 69 73 5f 69 6e 69  ){.  blob_is_ini
16b0: 74 28 70 46 72 6f 6d 29 3b 0a 20 20 62 6c 6f 62  t(pFrom);.  blob
16c0: 5f 7a 65 72 6f 28 70 54 6f 29 3b 0a 20 20 62 6c  _zero(pTo);.  bl
16d0: 6f 62 5f 61 70 70 65 6e 64 28 70 54 6f 2c 20 62  ob_append(pTo, b
16e0: 6c 6f 62 5f 62 75 66 66 65 72 28 70 46 72 6f 6d  lob_buffer(pFrom
16f0: 29 2c 20 62 6c 6f 62 5f 73 69 7a 65 28 70 46 72  ), blob_size(pFr
1700: 6f 6d 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  om));.}../*.** R
1710: 65 74 75 72 6e 20 61 20 70 6f 69 6e 74 65 72 20  eturn a pointer 
1720: 74 6f 20 61 20 6e 75 6c 6c 2d 74 65 72 6d 69 6e  to a null-termin
1730: 61 74 65 64 20 73 74 72 69 6e 67 20 66 6f 72 20  ated string for 
1740: 61 20 62 6c 6f 62 2e 0a 2a 2f 0a 63 68 61 72 20  a blob..*/.char 
1750: 2a 62 6c 6f 62 5f 73 74 72 28 42 6c 6f 62 20 2a  *blob_str(Blob *
1760: 70 29 7b 0a 20 20 62 6c 6f 62 5f 69 73 5f 69 6e  p){.  blob_is_in
1770: 69 74 28 70 29 3b 0a 20 20 69 66 28 20 70 2d 3e  it(p);.  if( p->
1780: 6e 55 73 65 64 3d 3d 30 20 29 7b 0a 20 20 20 20  nUsed==0 ){.    
1790: 62 6c 6f 62 5f 61 70 70 65 6e 64 28 70 2c 20 22  blob_append(p, "
17a0: 22 2c 20 31 29 3b 0a 20 20 20 20 70 2d 3e 6e 55  ", 1);.    p->nU
17b0: 73 65 64 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 69  sed = 0;.  }.  i
17c0: 66 28 20 70 2d 3e 61 44 61 74 61 5b 70 2d 3e 6e  f( p->aData[p->n
17d0: 55 73 65 64 5d 21 3d 30 20 29 7b 0a 20 20 20 20  Used]!=0 ){.    
17e0: 62 6c 6f 62 5f 6d 61 74 65 72 69 61 6c 69 7a 65  blob_materialize
17f0: 28 70 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72  (p);.  }.  retur
1800: 6e 20 70 2d 3e 61 44 61 74 61 3b 0a 7d 0a 0a 2f  n p->aData;.}../
1810: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20 70 6f  *.** Return a po
1820: 69 6e 74 65 72 20 74 6f 20 61 20 6e 75 6c 6c 2d  inter to a null-
1830: 74 65 72 6d 69 6e 61 74 65 64 20 73 74 72 69 6e  terminated strin
1840: 67 20 66 6f 72 20 61 20 62 6c 6f 62 2e 0a 2a 2a  g for a blob..**
1850: 0a 2a 2a 20 57 41 52 4e 49 4e 47 3a 20 20 49 66  .** WARNING:  If
1860: 20 74 68 65 20 62 6c 6f 62 20 69 73 20 65 70 68   the blob is eph
1870: 65 6d 65 72 61 6c 2c 20 69 74 20 6d 69 67 68 74  emeral, it might
1880: 20 63 61 75 73 65 20 61 20 27 5c 30 30 30 27 0a   cause a '\000'.
1890: 2a 2a 20 63 68 61 72 61 63 74 65 72 20 74 6f 20  ** character to 
18a0: 62 65 20 69 6e 73 65 72 74 65 64 20 69 6e 74 6f  be inserted into
18b0: 20 74 68 65 20 6d 69 64 64 6c 65 20 6f 66 20 74   the middle of t
18c0: 68 65 20 70 61 72 65 6e 74 20 62 6c 6f 62 2e 0a  he parent blob..
18d0: 2a 2a 20 45 78 61 6d 70 6c 65 3a 20 20 53 75 70  ** Example:  Sup
18e0: 70 6f 73 65 20 70 20 69 73 20 61 20 74 6f 6b 65  pose p is a toke
18f0: 6e 20 65 78 74 72 61 63 74 65 64 20 66 72 6f 6d  n extracted from
1900: 20 73 6f 6d 65 20 6c 61 72 67 65 72 0a 2a 2a 20   some larger.** 
1910: 62 6c 6f 62 20 70 42 69 67 20 75 73 69 6e 67 20  blob pBig using 
1920: 62 6c 6f 62 5f 74 6f 6b 65 6e 28 29 2e 20 20 49  blob_token().  I
1930: 66 20 79 6f 75 20 63 61 6c 6c 20 74 68 69 73 20  f you call this 
1940: 72 6f 75 74 69 6e 65 20 6f 6e 20 70 2c 0a 2a 2a  routine on p,.**
1950: 20 74 68 65 6e 20 61 20 27 5c 30 30 30 27 20 63   then a '\000' c
1960: 68 61 72 61 63 74 65 72 20 77 69 6c 6c 20 62 65  haracter will be
1970: 20 69 6e 73 65 72 74 65 64 20 69 6e 20 74 68 65   inserted in the
1980: 20 6d 69 64 64 6c 65 20 6f 66 0a 2a 2a 20 70 42   middle of.** pB
1990: 69 67 20 69 6e 20 6f 72 64 65 72 20 74 6f 20 63  ig in order to c
19a0: 61 75 73 65 20 70 20 74 6f 20 62 65 20 6e 75 6c  ause p to be nul
19b0: 2d 74 65 72 6d 69 6e 61 74 65 64 2e 20 20 49 66  -terminated.  If
19c0: 20 70 42 69 67 0a 2a 2a 20 73 68 6f 75 6c 64 20   pBig.** should 
19d0: 6e 6f 74 20 62 65 20 6d 6f 64 69 66 69 65 64 2c  not be modified,
19e0: 20 74 68 65 6e 20 75 73 65 20 62 6c 6f 62 5f 73   then use blob_s
19f0: 74 72 28 29 20 69 6e 73 74 65 61 64 20 6f 66 20  tr() instead of 
1a00: 74 68 69 73 0a 2a 2a 20 72 6f 75 74 69 6e 65 2e  this.** routine.
1a10: 20 20 62 6c 6f 62 5f 73 74 72 28 29 20 77 69 6c    blob_str() wil
1a20: 6c 20 6d 61 6b 65 20 61 20 63 6f 70 79 20 6f 66  l make a copy of
1a30: 20 74 68 65 20 70 20 69 66 20 6e 65 63 65 73 73   the p if necess
1a40: 61 72 79 0a 2a 2a 20 74 6f 20 61 76 6f 69 64 20  ary.** to avoid 
1a50: 6d 6f 64 69 66 79 69 6e 67 20 70 42 69 67 2e 0a  modifying pBig..
1a60: 2a 2f 0a 63 68 61 72 20 2a 62 6c 6f 62 5f 74 65  */.char *blob_te
1a70: 72 6d 69 6e 61 74 65 28 42 6c 6f 62 20 2a 70 29  rminate(Blob *p)
1a80: 7b 0a 20 20 62 6c 6f 62 5f 69 73 5f 69 6e 69 74  {.  blob_is_init
1a90: 28 70 29 3b 0a 20 20 69 66 28 20 70 2d 3e 6e 55  (p);.  if( p->nU
1aa0: 73 65 64 3d 3d 30 20 29 20 72 65 74 75 72 6e 20  sed==0 ) return 
1ab0: 22 22 3b 0a 20 20 70 2d 3e 61 44 61 74 61 5b 70  "";.  p->aData[p
1ac0: 2d 3e 6e 55 73 65 64 5d 20 3d 20 30 3b 0a 20 20  ->nUsed] = 0;.  
1ad0: 72 65 74 75 72 6e 20 70 2d 3e 61 44 61 74 61 3b  return p->aData;
1ae0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70 61 72  .}../*.** Compar
1af0: 65 20 74 77 6f 20 62 6c 6f 62 73 2e 0a 2a 2f 0a  e two blobs..*/.
1b00: 69 6e 74 20 62 6c 6f 62 5f 63 6f 6d 70 61 72 65  int blob_compare
1b10: 28 42 6c 6f 62 20 2a 70 41 2c 20 42 6c 6f 62 20  (Blob *pA, Blob 
1b20: 2a 70 42 29 7b 0a 20 20 69 6e 74 20 73 7a 41 2c  *pB){.  int szA,
1b30: 20 73 7a 42 2c 20 73 7a 2c 20 72 63 3b 0a 20 20   szB, sz, rc;.  
1b40: 62 6c 6f 62 5f 69 73 5f 69 6e 69 74 28 70 41 29  blob_is_init(pA)
1b50: 3b 0a 20 20 62 6c 6f 62 5f 69 73 5f 69 6e 69 74  ;.  blob_is_init
1b60: 28 70 42 29 3b 0a 20 20 73 7a 41 20 3d 20 62 6c  (pB);.  szA = bl
1b70: 6f 62 5f 73 69 7a 65 28 70 41 29 3b 0a 20 20 73  ob_size(pA);.  s
1b80: 7a 42 20 3d 20 62 6c 6f 62 5f 73 69 7a 65 28 70  zB = blob_size(p
1b90: 42 29 3b 0a 20 20 73 7a 20 3d 20 73 7a 41 3c 73  B);.  sz = szA<s
1ba0: 7a 42 20 3f 20 73 7a 41 20 3a 20 73 7a 42 3b 0a  zB ? szA : szB;.
1bb0: 20 20 72 63 20 3d 20 6d 65 6d 63 6d 70 28 62 6c    rc = memcmp(bl
1bc0: 6f 62 5f 62 75 66 66 65 72 28 70 41 29 2c 20 62  ob_buffer(pA), b
1bd0: 6c 6f 62 5f 62 75 66 66 65 72 28 70 42 29 2c 20  lob_buffer(pB), 
1be0: 73 7a 29 3b 0a 20 20 69 66 28 20 72 63 3d 3d 30  sz);.  if( rc==0
1bf0: 20 29 7b 0a 20 20 20 20 72 63 20 3d 20 73 7a 41   ){.    rc = szA
1c00: 20 2d 20 73 7a 42 3b 0a 20 20 7d 0a 20 20 72 65   - szB;.  }.  re
1c10: 74 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  turn rc;.}../*.*
1c20: 2a 20 43 6f 6d 70 61 72 65 20 61 20 62 6c 6f 62  * Compare a blob
1c30: 20 74 6f 20 61 20 73 74 72 69 6e 67 2e 20 20 52   to a string.  R
1c40: 65 74 75 72 6e 20 54 52 55 45 20 69 66 20 74 68  eturn TRUE if th
1c50: 65 79 20 61 72 65 20 65 71 75 61 6c 2e 0a 2a 2f  ey are equal..*/
1c60: 0a 69 6e 74 20 62 6c 6f 62 5f 65 71 5f 73 74 72  .int blob_eq_str
1c70: 28 42 6c 6f 62 20 2a 70 42 6c 6f 62 2c 20 63 6f  (Blob *pBlob, co
1c80: 6e 73 74 20 63 68 61 72 20 2a 7a 2c 20 69 6e 74  nst char *z, int
1c90: 20 6e 29 7b 0a 20 20 42 6c 6f 62 20 74 3b 0a 20   n){.  Blob t;. 
1ca0: 20 62 6c 6f 62 5f 69 73 5f 69 6e 69 74 28 70 42   blob_is_init(pB
1cb0: 6c 6f 62 29 3b 0a 20 20 69 66 28 20 6e 3c 3d 30  lob);.  if( n<=0
1cc0: 20 29 20 6e 20 3d 20 73 74 72 6c 65 6e 28 7a 29   ) n = strlen(z)
1cd0: 3b 0a 20 20 74 2e 61 44 61 74 61 20 3d 20 28 63  ;.  t.aData = (c
1ce0: 68 61 72 2a 29 7a 3b 0a 20 20 74 2e 6e 55 73 65  har*)z;.  t.nUse
1cf0: 64 20 3d 20 6e 3b 0a 20 20 74 2e 78 52 65 61 6c  d = n;.  t.xReal
1d00: 6c 6f 63 20 3d 20 62 6c 6f 62 52 65 61 6c 6c 6f  loc = blobReallo
1d10: 63 53 74 61 74 69 63 3b 0a 20 20 72 65 74 75 72  cStatic;.  retur
1d20: 6e 20 62 6c 6f 62 5f 63 6f 6d 70 61 72 65 28 70  n blob_compare(p
1d30: 42 6c 6f 62 2c 20 26 74 29 3d 3d 30 3b 0a 7d 0a  Blob, &t)==0;.}.
1d40: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 6d 61 63 72  ./*.** This macr
1d50: 6f 20 63 6f 6d 70 61 72 65 73 20 61 20 62 6c 6f  o compares a blo
1d60: 62 20 61 67 61 69 6e 73 74 20 61 20 73 74 72 69  b against a stri
1d70: 6e 67 20 63 6f 6e 73 74 61 6e 74 2e 20 20 57 65  ng constant.  We
1d80: 20 75 73 65 20 74 68 65 20 73 69 7a 65 6f 66 28   use the sizeof(
1d90: 29 0a 2a 2a 20 6f 70 65 72 61 74 6f 72 20 6f 6e  ).** operator on
1da0: 20 74 68 65 20 73 74 72 69 6e 67 20 63 6f 6e 73   the string cons
1db0: 74 61 6e 74 20 74 77 69 63 65 2c 20 73 6f 20 69  tant twice, so i
1dc0: 74 20 72 65 61 6c 6c 79 20 64 6f 65 73 20 6e 65  t really does ne
1dd0: 65 64 20 74 6f 20 62 65 20 61 0a 2a 2a 20 73 74  ed to be a.** st
1de0: 72 69 6e 67 20 6c 69 74 65 72 61 6c 20 6f 72 20  ring literal or 
1df0: 63 68 61 72 61 63 74 65 72 20 61 72 72 61 79 20  character array 
1e00: 2d 20 6e 6f 74 20 61 20 63 68 61 72 61 63 74 65  - not a characte
1e10: 72 20 70 6f 69 6e 74 65 72 2e 0a 2a 2f 0a 23 69  r pointer..*/.#i
1e20: 66 20 49 4e 54 45 52 46 41 43 45 0a 23 20 64 65  f INTERFACE.# de
1e30: 66 69 6e 65 20 62 6c 6f 62 5f 65 71 28 42 2c 53  fine blob_eq(B,S
1e40: 29 20 5c 0a 20 20 20 20 20 28 28 42 29 2d 3e 6e  ) \.     ((B)->n
1e50: 55 73 65 64 3d 3d 73 69 7a 65 6f 66 28 53 29 2d  Used==sizeof(S)-
1e60: 31 20 26 26 20 6d 65 6d 63 6d 70 28 28 42 29 2d  1 && memcmp((B)-
1e70: 3e 61 44 61 74 61 2c 53 2c 73 69 7a 65 6f 66 28  >aData,S,sizeof(
1e80: 53 29 2d 31 29 3d 3d 30 29 0a 23 65 6e 64 69 66  S)-1)==0).#endif
1e90: 0a 0a 0a 2f 2a 0a 2a 2a 20 41 74 74 65 6d 70 74  .../*.** Attempt
1ea0: 20 74 6f 20 72 65 73 69 7a 65 20 61 20 62 6c 6f   to resize a blo
1eb0: 62 20 73 6f 20 74 68 61 74 20 69 74 73 20 69 6e  b so that its in
1ec0: 74 65 72 6e 61 6c 20 62 75 66 66 65 72 20 69 73  ternal buffer is
1ed0: 20 0a 2a 2a 20 6e 42 79 74 65 20 69 6e 20 73 69   .** nByte in si
1ee0: 7a 65 2e 20 20 54 68 65 20 62 6c 6f 62 20 69 73  ze.  The blob is
1ef0: 20 74 72 75 6e 63 61 74 65 64 20 69 66 20 6e 65   truncated if ne
1f00: 63 65 73 73 61 72 79 2e 0a 2a 2f 0a 76 6f 69 64  cessary..*/.void
1f10: 20 62 6c 6f 62 5f 72 65 73 69 7a 65 28 42 6c 6f   blob_resize(Blo
1f20: 62 20 2a 70 42 6c 6f 62 2c 20 75 6e 73 69 67 6e  b *pBlob, unsign
1f30: 65 64 20 69 6e 74 20 6e 65 77 53 69 7a 65 29 7b  ed int newSize){
1f40: 0a 20 20 70 42 6c 6f 62 2d 3e 78 52 65 61 6c 6c  .  pBlob->xReall
1f50: 6f 63 28 70 42 6c 6f 62 2c 20 6e 65 77 53 69 7a  oc(pBlob, newSiz
1f60: 65 2b 31 29 3b 0a 20 20 70 42 6c 6f 62 2d 3e 6e  e+1);.  pBlob->n
1f70: 55 73 65 64 20 3d 20 6e 65 77 53 69 7a 65 3b 0a  Used = newSize;.
1f80: 20 20 70 42 6c 6f 62 2d 3e 61 44 61 74 61 5b 6e    pBlob->aData[n
1f90: 65 77 53 69 7a 65 5d 20 3d 20 30 3b 0a 7d 0a 0a  ewSize] = 0;.}..
1fa0: 2f 2a 0a 2a 2a 20 4d 61 6b 65 20 73 75 72 65 20  /*.** Make sure 
1fb0: 61 20 62 6c 6f 62 20 69 73 20 6e 75 6c 2d 74 65  a blob is nul-te
1fc0: 72 6d 69 6e 61 74 65 64 20 61 6e 64 20 69 73 20  rminated and is 
1fd0: 6e 6f 74 20 61 20 70 6f 69 6e 74 65 72 20 74 6f  not a pointer to
1fe0: 20 75 6e 6d 61 6e 61 67 65 64 0a 2a 2a 20 73 70   unmanaged.** sp
1ff0: 61 63 65 2e 20 20 52 65 74 75 72 6e 20 61 20 70  ace.  Return a p
2000: 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 0a 2a 2f  ointer to the.*/
2010: 0a 63 68 61 72 20 2a 62 6c 6f 62 5f 6d 61 74 65  .char *blob_mate
2020: 72 69 61 6c 69 7a 65 28 42 6c 6f 62 20 2a 70 42  rialize(Blob *pB
2030: 6c 6f 62 29 7b 0a 20 20 62 6c 6f 62 5f 72 65 73  lob){.  blob_res
2040: 69 7a 65 28 70 42 6c 6f 62 2c 20 70 42 6c 6f 62  ize(pBlob, pBlob
2050: 2d 3e 6e 55 73 65 64 29 3b 0a 20 20 72 65 74 75  ->nUsed);.  retu
2060: 72 6e 20 70 42 6c 6f 62 2d 3e 61 44 61 74 61 3b  rn pBlob->aData;
2070: 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 43 61 6c 6c 20  .}.../*.** Call 
2080: 64 65 68 74 74 70 69 7a 65 20 6f 6e 20 61 20 62  dehttpize on a b
2090: 6c 6f 62 2e 20 20 54 68 69 73 20 63 61 75 73 65  lob.  This cause
20a0: 73 20 61 6e 20 65 70 68 65 6d 65 72 61 6c 20 62  s an ephemeral b
20b0: 6c 6f 62 20 74 6f 20 62 65 0a 2a 2a 20 6d 61 74  lob to be.** mat
20c0: 65 72 69 61 6c 69 7a 65 64 2e 0a 2a 2f 0a 76 6f  erialized..*/.vo
20d0: 69 64 20 62 6c 6f 62 5f 64 65 68 74 74 70 69 7a  id blob_dehttpiz
20e0: 65 28 42 6c 6f 62 20 2a 70 42 6c 6f 62 29 7b 0a  e(Blob *pBlob){.
20f0: 20 20 62 6c 6f 62 5f 6d 61 74 65 72 69 61 6c 69    blob_materiali
2100: 7a 65 28 70 42 6c 6f 62 29 3b 0a 20 20 70 42 6c  ze(pBlob);.  pBl
2110: 6f 62 2d 3e 6e 55 73 65 64 20 3d 20 64 65 68 74  ob->nUsed = deht
2120: 74 70 69 7a 65 28 70 42 6c 6f 62 2d 3e 61 44 61  tpize(pBlob->aDa
2130: 74 61 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 45 78  ta);.}../*.** Ex
2140: 74 72 61 63 74 20 4e 20 62 79 74 65 73 20 66 72  tract N bytes fr
2150: 6f 6d 20 62 6c 6f 62 20 70 46 72 6f 6d 20 61 6e  om blob pFrom an
2160: 64 20 75 73 65 20 69 74 20 74 6f 20 69 6e 69 74  d use it to init
2170: 69 61 6c 69 7a 65 20 62 6c 6f 62 20 70 54 6f 2e  ialize blob pTo.
2180: 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 61  .** Return the a
2190: 63 74 75 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20  ctual number of 
21a0: 62 79 74 65 73 20 65 78 74 72 61 63 74 65 64 2e  bytes extracted.
21b0: 0a 2a 2a 0a 2a 2a 20 41 66 74 65 72 20 74 68 69  .**.** After thi
21c0: 73 20 63 61 6c 6c 20 63 6f 6d 70 6c 65 74 65 73  s call completes
21d0: 2c 20 70 54 6f 20 77 69 6c 6c 20 62 65 20 61 6e  , pTo will be an
21e0: 20 65 70 68 65 6d 65 72 61 6c 20 62 6c 6f 62 2e   ephemeral blob.
21f0: 0a 2a 2f 0a 69 6e 74 20 62 6c 6f 62 5f 65 78 74  .*/.int blob_ext
2200: 72 61 63 74 28 42 6c 6f 62 20 2a 70 46 72 6f 6d  ract(Blob *pFrom
2210: 2c 20 69 6e 74 20 4e 2c 20 42 6c 6f 62 20 2a 70  , int N, Blob *p
2220: 54 6f 29 7b 0a 20 20 62 6c 6f 62 5f 69 73 5f 69  To){.  blob_is_i
2230: 6e 69 74 28 70 46 72 6f 6d 29 3b 0a 20 20 62 6c  nit(pFrom);.  bl
2240: 6f 62 5f 69 73 5f 72 65 73 65 74 28 70 54 6f 29  ob_is_reset(pTo)
2250: 3b 0a 20 20 69 66 28 20 70 46 72 6f 6d 2d 3e 69  ;.  if( pFrom->i
2260: 43 75 72 73 6f 72 20 2b 20 4e 20 3e 20 70 46 72  Cursor + N > pFr
2270: 6f 6d 2d 3e 6e 55 73 65 64 20 29 7b 0a 20 20 20  om->nUsed ){.   
2280: 20 4e 20 3d 20 70 46 72 6f 6d 2d 3e 6e 55 73 65   N = pFrom->nUse
2290: 64 20 2d 20 70 46 72 6f 6d 2d 3e 69 43 75 72 73  d - pFrom->iCurs
22a0: 6f 72 3b 0a 20 20 20 20 69 66 28 20 4e 3c 3d 30  or;.    if( N<=0
22b0: 20 29 7b 0a 20 20 20 20 20 20 62 6c 6f 62 5f 7a   ){.      blob_z
22c0: 65 72 6f 28 70 54 6f 29 3b 0a 20 20 20 20 20 20  ero(pTo);.      
22d0: 72 65 74 75 72 6e 20 30 3b 0a 20 20 20 20 7d 0a  return 0;.    }.
22e0: 20 20 7d 0a 20 20 70 54 6f 2d 3e 6e 55 73 65 64    }.  pTo->nUsed
22f0: 20 3d 20 4e 3b 0a 20 20 70 54 6f 2d 3e 6e 41 6c   = N;.  pTo->nAl
2300: 6c 6f 63 20 3d 20 4e 3b 0a 20 20 70 54 6f 2d 3e  loc = N;.  pTo->
2310: 61 44 61 74 61 20 3d 20 26 70 46 72 6f 6d 2d 3e  aData = &pFrom->
2320: 61 44 61 74 61 5b 70 46 72 6f 6d 2d 3e 69 43 75  aData[pFrom->iCu
2330: 72 73 6f 72 5d 3b 0a 20 20 70 54 6f 2d 3e 69 43  rsor];.  pTo->iC
2340: 75 72 73 6f 72 20 3d 20 30 3b 0a 20 20 70 54 6f  ursor = 0;.  pTo
2350: 2d 3e 78 52 65 61 6c 6c 6f 63 20 3d 20 62 6c 6f  ->xRealloc = blo
2360: 62 52 65 61 6c 6c 6f 63 53 74 61 74 69 63 3b 0a  bReallocStatic;.
2370: 20 20 70 46 72 6f 6d 2d 3e 69 43 75 72 73 6f 72    pFrom->iCursor
2380: 20 2b 3d 20 4e 3b 0a 20 20 72 65 74 75 72 6e 20   += N;.  return 
2390: 4e 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 77 69  N;.}../*.** Rewi
23a0: 6e 64 20 74 68 65 20 63 75 72 73 6f 72 20 6f 6e  nd the cursor on
23b0: 20 61 20 62 6c 6f 62 20 62 61 63 6b 20 74 6f 20   a blob back to 
23c0: 74 68 65 20 62 65 67 69 6e 6e 69 6e 67 2e 0a 2a  the beginning..*
23d0: 2f 0a 76 6f 69 64 20 62 6c 6f 62 5f 72 65 77 69  /.void blob_rewi
23e0: 6e 64 28 42 6c 6f 62 20 2a 70 29 7b 0a 20 20 70  nd(Blob *p){.  p
23f0: 2d 3e 69 43 75 72 73 6f 72 20 3d 20 30 3b 0a 7d  ->iCursor = 0;.}
2400: 0a 0a 2f 2a 0a 2a 2a 20 53 65 65 6b 20 74 68 65  ../*.** Seek the
2410: 20 63 75 72 73 6f 72 20 69 6e 20 61 20 62 6c 6f   cursor in a blo
2420: 62 20 74 6f 20 74 68 65 20 69 6e 64 69 63 61 74  b to the indicat
2430: 65 64 20 6f 66 66 73 65 74 2e 0a 2a 2f 0a 69 6e  ed offset..*/.in
2440: 74 20 62 6c 6f 62 5f 73 65 65 6b 28 42 6c 6f 62  t blob_seek(Blob
2450: 20 2a 70 2c 20 69 6e 74 20 6f 66 66 73 65 74 2c   *p, int offset,
2460: 20 69 6e 74 20 77 68 65 6e 63 65 29 7b 0a 20 20   int whence){.  
2470: 69 66 28 20 77 68 65 6e 63 65 3d 3d 42 4c 4f 42  if( whence==BLOB
2480: 5f 53 45 45 4b 5f 53 45 54 20 29 7b 0a 20 20 20  _SEEK_SET ){.   
2490: 20 70 2d 3e 69 43 75 72 73 6f 72 20 3d 20 6f 66   p->iCursor = of
24a0: 66 73 65 74 3b 0a 20 20 7d 65 6c 73 65 20 69 66  fset;.  }else if
24b0: 28 20 77 68 65 6e 63 65 3d 3d 42 4c 4f 42 5f 53  ( whence==BLOB_S
24c0: 45 45 4b 5f 43 55 52 20 29 7b 0a 20 20 20 20 70  EEK_CUR ){.    p
24d0: 2d 3e 69 43 75 72 73 6f 72 20 2b 3d 20 6f 66 66  ->iCursor += off
24e0: 73 65 74 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28  set;.  }else if(
24f0: 20 77 68 65 6e 63 65 3d 3d 42 4c 4f 42 5f 53 45   whence==BLOB_SE
2500: 45 4b 5f 45 4e 44 20 29 7b 0a 20 20 20 20 70 2d  EK_END ){.    p-
2510: 3e 69 43 75 72 73 6f 72 20 3d 20 70 2d 3e 6e 55  >iCursor = p->nU
2520: 73 65 64 20 2b 20 6f 66 66 73 65 74 20 2d 20 31  sed + offset - 1
2530: 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70 2d 3e 69  ;.  }.  if( p->i
2540: 43 75 72 73 6f 72 3c 30 20 29 7b 0a 20 20 20 20  Cursor<0 ){.    
2550: 70 2d 3e 69 43 75 72 73 6f 72 20 3d 20 30 3b 0a  p->iCursor = 0;.
2560: 20 20 7d 0a 20 20 69 66 28 20 70 2d 3e 69 43 75    }.  if( p->iCu
2570: 72 73 6f 72 3e 70 2d 3e 6e 55 73 65 64 20 29 7b  rsor>p->nUsed ){
2580: 0a 20 20 20 20 70 2d 3e 69 43 75 72 73 6f 72 20  .    p->iCursor 
2590: 3d 20 70 2d 3e 6e 55 73 65 64 3b 0a 20 20 7d 0a  = p->nUsed;.  }.
25a0: 20 20 72 65 74 75 72 6e 20 70 2d 3e 69 43 75 72    return p->iCur
25b0: 73 6f 72 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65  sor;.}../*.** Re
25c0: 74 75 72 6e 20 74 68 65 20 63 75 72 72 65 6e 74  turn the current
25d0: 20 6f 66 66 73 65 74 20 69 6e 74 6f 20 74 68 65   offset into the
25e0: 20 62 6c 6f 62 0a 2a 2f 0a 69 6e 74 20 62 6c 6f   blob.*/.int blo
25f0: 62 5f 74 65 6c 6c 28 42 6c 6f 62 20 2a 70 29 7b  b_tell(Blob *p){
2600: 0a 20 20 72 65 74 75 72 6e 20 70 2d 3e 69 43 75  .  return p->iCu
2610: 72 73 6f 72 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 45  rsor;.}../*.** E
2620: 78 74 72 61 63 74 20 61 20 73 69 6e 67 6c 65 20  xtract a single 
2630: 6c 69 6e 65 20 6f 66 20 74 65 78 74 20 66 72 6f  line of text fro
2640: 6d 20 70 46 72 6f 6d 20 62 65 67 69 6e 6e 69 6e  m pFrom beginnin
2650: 67 20 61 74 20 74 68 65 20 63 75 72 72 65 6e 74  g at the current
2660: 20 0a 2a 2a 20 63 75 72 73 6f 72 20 6c 6f 63 61   .** cursor loca
2670: 74 69 6f 6e 20 61 6e 64 20 75 73 65 20 74 68 61  tion and use tha
2680: 74 20 6c 69 6e 65 20 6f 66 20 74 65 78 74 20 74  t line of text t
2690: 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20 70 54 6f  o initialize pTo
26a0: 2e 0a 2a 2a 20 70 54 6f 20 77 69 6c 6c 20 69 6e  ..** pTo will in
26b0: 63 6c 75 64 65 20 74 68 65 20 74 65 72 6d 69 6e  clude the termin
26c0: 61 74 69 6e 67 20 5c 6e 2e 20 20 52 65 74 75 72  ating \n.  Retur
26d0: 6e 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20  n the number of 
26e0: 62 79 74 65 73 0a 2a 2a 20 69 6e 20 74 68 65 20  bytes.** in the 
26f0: 6c 69 6e 65 20 69 6e 63 6c 75 64 69 6e 67 20 74  line including t
2700: 68 65 20 5c 6e 20 61 74 20 74 68 65 20 65 6e 64  he \n at the end
2710: 2e 20 20 30 20 69 73 20 72 65 74 75 72 6e 65 64  .  0 is returned
2720: 20 61 74 0a 2a 2a 20 65 6e 64 2d 6f 66 2d 66 69   at.** end-of-fi
2730: 6c 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 75  le..**.** The cu
2740: 72 73 6f 72 20 6f 66 20 70 46 72 6f 6d 20 69 73  rsor of pFrom is
2750: 20 6c 65 66 74 20 70 6f 69 6e 74 69 6e 67 20 61   left pointing a
2760: 74 20 74 68 65 20 66 69 72 73 74 20 62 79 74 65  t the first byte
2770: 20 70 61 73 74 20 74 68 65 0a 2a 2a 20 5c 6e 20   past the.** \n 
2780: 74 68 61 74 20 74 65 72 6d 69 6e 61 74 65 64 20  that terminated 
2790: 74 68 65 20 6c 69 6e 65 2e 0a 2a 2a 0a 2a 2a 20  the line..**.** 
27a0: 70 54 6f 20 77 69 6c 6c 20 62 65 20 61 6e 20 65  pTo will be an e
27b0: 70 68 65 72 6d 65 72 61 6c 20 62 6c 6f 62 2e 20  phermeral blob. 
27c0: 20 49 66 20 70 46 72 6f 6d 20 63 68 61 6e 67 65   If pFrom change
27d0: 73 2c 20 69 74 20 6d 69 67 68 74 20 61 6c 74 65  s, it might alte
27e0: 72 0a 2a 2a 20 70 54 6f 20 61 73 20 77 65 6c 6c  r.** pTo as well
27f0: 2e 0a 2a 2f 0a 69 6e 74 20 62 6c 6f 62 5f 6c 69  ..*/.int blob_li
2800: 6e 65 28 42 6c 6f 62 20 2a 70 46 72 6f 6d 2c 20  ne(Blob *pFrom, 
2810: 42 6c 6f 62 20 2a 70 54 6f 29 7b 0a 20 20 63 68  Blob *pTo){.  ch
2820: 61 72 20 2a 61 44 61 74 61 20 3d 20 70 46 72 6f  ar *aData = pFro
2830: 6d 2d 3e 61 44 61 74 61 3b 0a 20 20 69 6e 74 20  m->aData;.  int 
2840: 6e 20 3d 20 70 46 72 6f 6d 2d 3e 6e 55 73 65 64  n = pFrom->nUsed
2850: 3b 0a 20 20 69 6e 74 20 69 20 3d 20 70 46 72 6f  ;.  int i = pFro
2860: 6d 2d 3e 69 43 75 72 73 6f 72 3b 0a 0a 20 20 77  m->iCursor;..  w
2870: 68 69 6c 65 28 20 69 3c 6e 20 26 26 20 61 44 61  hile( i<n && aDa
2880: 74 61 5b 69 5d 21 3d 27 5c 6e 27 20 29 7b 20 69  ta[i]!='\n' ){ i
2890: 2b 2b 3b 20 7d 0a 20 20 69 66 28 20 69 3c 6e 20  ++; }.  if( i<n 
28a0: 29 7b 0a 20 20 20 20 61 73 73 65 72 74 28 20 61  ){.    assert( a
28b0: 44 61 74 61 5b 69 5d 3d 3d 27 5c 6e 27 20 29 3b  Data[i]=='\n' );
28c0: 0a 20 20 20 20 69 2b 2b 3b 0a 20 20 7d 0a 20 20  .    i++;.  }.  
28d0: 62 6c 6f 62 5f 65 78 74 72 61 63 74 28 70 46 72  blob_extract(pFr
28e0: 6f 6d 2c 20 69 2d 70 46 72 6f 6d 2d 3e 69 43 75  om, i-pFrom->iCu
28f0: 72 73 6f 72 2c 20 70 54 6f 29 3b 0a 20 20 72 65  rsor, pTo);.  re
2900: 74 75 72 6e 20 70 54 6f 2d 3e 6e 55 73 65 64 3b  turn pTo->nUsed;
2910: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 72 69 6d 20 77  .}../*.** Trim w
2920: 68 69 74 65 73 70 61 63 65 20 6f 66 66 20 6f 66  hitespace off of
2930: 20 74 68 65 20 65 6e 64 20 6f 66 20 61 20 62 6c   the end of a bl
2940: 6f 62 2e 20 20 52 65 74 75 72 6e 20 74 68 65 20  ob.  Return the 
2950: 6e 75 6d 62 65 72 0a 2a 2a 20 6f 66 20 63 68 61  number.** of cha
2960: 72 61 63 74 65 72 73 20 72 65 6d 61 69 6e 69 6e  racters remainin
2970: 67 2e 0a 2a 2a 0a 2a 2a 20 41 6c 6c 20 74 68 69  g..**.** All thi
2980: 73 20 64 6f 65 73 20 69 73 20 72 65 64 75 63 65  s does is reduce
2990: 20 74 68 65 20 6c 65 6e 67 74 68 20 63 6f 75 6e   the length coun
29a0: 74 65 72 2e 20 20 54 68 69 73 20 72 6f 75 74 69  ter.  This routi
29b0: 6e 65 20 64 6f 65 73 0a 2a 2a 20 6e 6f 74 20 69  ne does.** not i
29c0: 6e 73 65 72 74 20 61 20 6e 65 77 20 7a 65 72 6f  nsert a new zero
29d0: 20 74 65 72 6d 69 6e 61 74 6f 72 2e 0a 2a 2f 0a   terminator..*/.
29e0: 69 6e 74 20 62 6c 6f 62 5f 74 72 69 6d 28 42 6c  int blob_trim(Bl
29f0: 6f 62 20 2a 70 29 7b 0a 20 20 63 68 61 72 20 2a  ob *p){.  char *
2a00: 7a 20 3d 20 70 2d 3e 61 44 61 74 61 3b 0a 20 20  z = p->aData;.  
2a10: 69 6e 74 20 6e 20 3d 20 70 2d 3e 6e 55 73 65 64  int n = p->nUsed
2a20: 3b 0a 20 20 77 68 69 6c 65 28 20 6e 3e 30 20 26  ;.  while( n>0 &
2a30: 26 20 62 6c 6f 62 5f 69 73 73 70 61 63 65 28 7a  & blob_isspace(z
2a40: 5b 6e 2d 31 5d 29 20 29 7b 20 6e 2d 2d 3b 20 7d  [n-1]) ){ n--; }
2a50: 0a 20 20 70 2d 3e 6e 55 73 65 64 20 3d 20 6e 3b  .  p->nUsed = n;
2a60: 0a 20 20 72 65 74 75 72 6e 20 6e 3b 0a 7d 0a 0a  .  return n;.}..
2a70: 2f 2a 0a 2a 2a 20 45 78 74 72 61 63 74 20 61 20  /*.** Extract a 
2a80: 73 69 6e 67 6c 65 20 74 6f 6b 65 6e 20 66 72 6f  single token fro
2a90: 6d 20 70 46 72 6f 6d 20 61 6e 64 20 75 73 65 20  m pFrom and use 
2aa0: 69 74 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65  it to initialize
2ab0: 20 70 54 6f 2e 0a 2a 2a 20 52 65 74 75 72 6e 20   pTo..** Return 
2ac0: 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 62 79  the number of by
2ad0: 74 65 73 20 69 6e 20 74 68 65 20 74 6f 6b 65 6e  tes in the token
2ae0: 2e 20 20 49 66 20 6e 6f 20 74 6f 6b 65 6e 20 69  .  If no token i
2af0: 73 20 66 6f 75 6e 64 2c 0a 2a 2a 20 72 65 74 75  s found,.** retu
2b00: 72 6e 20 30 2e 0a 2a 2a 0a 2a 2a 20 41 20 74 6f  rn 0..**.** A to
2b10: 6b 65 6e 20 63 6f 6e 73 69 73 74 73 20 6f 66 20  ken consists of 
2b20: 6f 6e 65 20 6f 72 20 6d 6f 72 65 20 6e 6f 6e 2d  one or more non-
2b30: 73 70 61 63 65 20 63 68 61 72 61 63 74 65 72 73  space characters
2b40: 2e 20 20 4c 65 61 64 69 6e 67 0a 2a 2a 20 77 68  .  Leading.** wh
2b50: 69 74 65 73 70 61 63 65 20 69 73 20 69 67 6e 6f  itespace is igno
2b60: 72 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63  red..**.** The c
2b70: 75 72 73 6f 72 20 6f 66 20 70 46 72 6f 6d 20 69  ursor of pFrom i
2b80: 73 20 6c 65 66 74 20 70 6f 69 6e 74 69 6e 67 20  s left pointing 
2b90: 61 74 20 74 68 65 20 66 69 72 73 74 20 63 68 61  at the first cha
2ba0: 72 61 63 74 65 72 20 70 61 73 74 0a 2a 2a 20 74  racter past.** t
2bb0: 68 65 20 65 6e 64 20 6f 66 20 74 68 65 20 74 6f  he end of the to
2bc0: 6b 65 6e 2e 0a 2a 2a 0a 2a 2a 20 70 54 6f 20 77  ken..**.** pTo w
2bd0: 69 6c 6c 20 62 65 20 61 6e 20 65 70 68 65 72 6d  ill be an epherm
2be0: 65 72 61 6c 20 62 6c 6f 62 2e 20 20 49 66 20 70  eral blob.  If p
2bf0: 46 72 6f 6d 20 63 68 61 6e 67 65 73 2c 20 69 74  From changes, it
2c00: 20 6d 69 67 68 74 20 61 6c 74 65 72 0a 2a 2a 20   might alter.** 
2c10: 70 54 6f 20 61 73 20 77 65 6c 6c 2e 0a 2a 2f 0a  pTo as well..*/.
2c20: 69 6e 74 20 62 6c 6f 62 5f 74 6f 6b 65 6e 28 42  int blob_token(B
2c30: 6c 6f 62 20 2a 70 46 72 6f 6d 2c 20 42 6c 6f 62  lob *pFrom, Blob
2c40: 20 2a 70 54 6f 29 7b 0a 20 20 63 68 61 72 20 2a   *pTo){.  char *
2c50: 61 44 61 74 61 20 3d 20 70 46 72 6f 6d 2d 3e 61  aData = pFrom->a
2c60: 44 61 74 61 3b 0a 20 20 69 6e 74 20 6e 20 3d 20  Data;.  int n = 
2c70: 70 46 72 6f 6d 2d 3e 6e 55 73 65 64 3b 0a 20 20  pFrom->nUsed;.  
2c80: 69 6e 74 20 69 20 3d 20 70 46 72 6f 6d 2d 3e 69  int i = pFrom->i
2c90: 43 75 72 73 6f 72 3b 0a 20 20 77 68 69 6c 65 28  Cursor;.  while(
2ca0: 20 69 3c 6e 20 26 26 20 62 6c 6f 62 5f 69 73 73   i<n && blob_iss
2cb0: 70 61 63 65 28 61 44 61 74 61 5b 69 5d 29 20 29  pace(aData[i]) )
2cc0: 7b 20 69 2b 2b 3b 20 7d 0a 20 20 70 46 72 6f 6d  { i++; }.  pFrom
2cd0: 2d 3e 69 43 75 72 73 6f 72 20 3d 20 69 3b 0a 20  ->iCursor = i;. 
2ce0: 20 77 68 69 6c 65 28 20 69 3c 6e 20 26 26 20 21   while( i<n && !
2cf0: 62 6c 6f 62 5f 69 73 73 70 61 63 65 28 61 44 61  blob_isspace(aDa
2d00: 74 61 5b 69 5d 29 20 29 7b 20 69 2b 2b 3b 20 7d  ta[i]) ){ i++; }
2d10: 0a 20 20 62 6c 6f 62 5f 65 78 74 72 61 63 74 28  .  blob_extract(
2d20: 70 46 72 6f 6d 2c 20 69 2d 70 46 72 6f 6d 2d 3e  pFrom, i-pFrom->
2d30: 69 43 75 72 73 6f 72 2c 20 70 54 6f 29 3b 0a 20  iCursor, pTo);. 
2d40: 20 77 68 69 6c 65 28 20 69 3c 6e 20 26 26 20 62   while( i<n && b
2d50: 6c 6f 62 5f 69 73 73 70 61 63 65 28 61 44 61 74  lob_isspace(aDat
2d60: 61 5b 69 5d 29 20 29 7b 20 69 2b 2b 3b 20 7d 0a  a[i]) ){ i++; }.
2d70: 20 20 70 46 72 6f 6d 2d 3e 69 43 75 72 73 6f 72    pFrom->iCursor
2d80: 20 3d 20 69 3b 0a 20 20 72 65 74 75 72 6e 20 70   = i;.  return p
2d90: 54 6f 2d 3e 6e 55 73 65 64 3b 0a 7d 0a 0a 2f 2a  To->nUsed;.}../*
2da0: 0a 2a 2a 20 45 78 74 72 61 63 74 20 65 76 65 72  .** Extract ever
2db0: 79 74 68 69 6e 67 20 66 72 6f 6d 20 74 68 65 20  ything from the 
2dc0: 63 75 72 72 65 6e 74 20 63 75 72 73 6f 72 20 74  current cursor t
2dd0: 6f 20 74 68 65 20 65 6e 64 20 6f 66 20 74 68 65  o the end of the
2de0: 20 62 6c 6f 62 0a 2a 2a 20 69 6e 74 6f 20 61 20   blob.** into a 
2df0: 6e 65 77 20 62 6c 6f 62 2e 20 20 54 68 65 20 6e  new blob.  The n
2e00: 65 77 20 62 6c 6f 62 20 69 73 20 61 6e 20 65 70  ew blob is an ep
2e10: 68 65 6d 65 72 69 61 6c 20 72 65 66 65 72 65 6e  hemerial referen
2e20: 63 65 20 74 6f 20 74 68 65 0a 2a 2a 20 6f 72 69  ce to the.** ori
2e30: 67 69 6e 61 6c 20 62 6c 6f 62 2e 20 20 54 68 65  ginal blob.  The
2e40: 20 63 75 72 73 6f 72 20 6f 66 20 74 68 65 20 6f   cursor of the o
2e50: 72 69 67 69 6e 61 6c 20 62 6c 6f 62 20 69 73 20  riginal blob is 
2e60: 75 6e 63 68 61 6e 67 65 64 2e 0a 2a 2f 0a 69 6e  unchanged..*/.in
2e70: 74 20 62 6c 6f 62 5f 74 61 69 6c 28 42 6c 6f 62  t blob_tail(Blob
2e80: 20 2a 70 46 72 6f 6d 2c 20 42 6c 6f 62 20 2a 70   *pFrom, Blob *p
2e90: 54 6f 29 7b 0a 20 20 69 6e 74 20 69 43 75 72 73  To){.  int iCurs
2ea0: 6f 72 20 3d 20 70 46 72 6f 6d 2d 3e 69 43 75 72  or = pFrom->iCur
2eb0: 73 6f 72 3b 0a 20 20 62 6c 6f 62 5f 65 78 74 72  sor;.  blob_extr
2ec0: 61 63 74 28 70 46 72 6f 6d 2c 20 70 46 72 6f 6d  act(pFrom, pFrom
2ed0: 2d 3e 6e 55 73 65 64 2d 70 46 72 6f 6d 2d 3e 69  ->nUsed-pFrom->i
2ee0: 43 75 72 73 6f 72 2c 20 70 54 6f 29 3b 0a 20 20  Cursor, pTo);.  
2ef0: 70 46 72 6f 6d 2d 3e 69 43 75 72 73 6f 72 20 3d  pFrom->iCursor =
2f00: 20 69 43 75 72 73 6f 72 3b 0a 20 20 72 65 74 75   iCursor;.  retu
2f10: 72 6e 20 70 54 6f 2d 3e 6e 55 73 65 64 3b 0a 7d  rn pTo->nUsed;.}
2f20: 0a 0a 2f 2a 0a 2a 2a 20 43 6f 70 79 20 4e 20 6c  ../*.** Copy N l
2f30: 69 6e 65 73 20 6f 66 20 74 65 78 74 20 66 72 6f  ines of text fro
2f40: 6d 20 70 46 72 6f 6d 20 69 6e 74 6f 20 70 54 6f  m pFrom into pTo
2f50: 2e 20 20 54 68 65 20 63 6f 70 79 20 62 65 67 69  .  The copy begi
2f60: 6e 73 20 61 74 20 74 68 65 0a 2a 2a 20 63 75 72  ns at the.** cur
2f70: 72 65 6e 74 20 63 75 72 73 6f 72 20 70 6f 73 69  rent cursor posi
2f80: 74 69 6f 6e 20 6f 66 20 70 49 6e 2e 20 20 54 68  tion of pIn.  Th
2f90: 65 20 70 49 6e 20 63 75 72 73 6f 72 20 69 73 20  e pIn cursor is 
2fa0: 6c 65 66 74 20 70 6f 69 6e 74 69 6e 67 0a 2a 2a  left pointing.**
2fb0: 20 61 74 20 74 68 65 20 66 69 72 73 74 20 63 68   at the first ch
2fc0: 61 72 61 63 74 65 72 20 70 61 73 74 20 74 68 65  aracter past the
2fd0: 20 6c 61 73 74 20 5c 6e 20 63 6f 70 69 65 64 2e   last \n copied.
2fe0: 0a 2a 2a 0a 2a 2a 20 49 66 20 70 54 6f 3d 3d 4e  .**.** If pTo==N
2ff0: 55 4c 4c 20 74 68 65 6e 20 74 68 69 73 20 72 6f  ULL then this ro
3000: 75 74 69 6e 65 20 73 69 6d 70 6c 79 20 73 6b 69  utine simply ski
3010: 70 73 20 6f 76 65 72 20 4e 20 6c 69 6e 65 73 2e  ps over N lines.
3020: 0a 2a 2f 0a 76 6f 69 64 20 62 6c 6f 62 5f 63 6f  .*/.void blob_co
3030: 70 79 5f 6c 69 6e 65 73 28 42 6c 6f 62 20 2a 70  py_lines(Blob *p
3040: 54 6f 2c 20 42 6c 6f 62 20 2a 70 46 72 6f 6d 2c  To, Blob *pFrom,
3050: 20 69 6e 74 20 4e 29 7b 0a 20 20 63 68 61 72 20   int N){.  char 
3060: 2a 7a 20 3d 20 70 46 72 6f 6d 2d 3e 61 44 61 74  *z = pFrom->aDat
3070: 61 3b 0a 20 20 69 6e 74 20 69 20 3d 20 70 46 72  a;.  int i = pFr
3080: 6f 6d 2d 3e 69 43 75 72 73 6f 72 3b 0a 20 20 69  om->iCursor;.  i
3090: 6e 74 20 6e 20 3d 20 70 46 72 6f 6d 2d 3e 6e 55  nt n = pFrom->nU
30a0: 73 65 64 3b 0a 20 20 69 6e 74 20 63 6e 74 20 3d  sed;.  int cnt =
30b0: 20 30 3b 0a 0a 20 20 69 66 28 20 4e 3d 3d 30 20   0;..  if( N==0 
30c0: 29 20 72 65 74 75 72 6e 3b 0a 20 20 77 68 69 6c  ) return;.  whil
30d0: 65 28 20 69 3c 6e 20 29 7b 0a 20 20 20 20 69 66  e( i<n ){.    if
30e0: 28 20 7a 5b 69 5d 3d 3d 27 5c 6e 27 20 29 7b 0a  ( z[i]=='\n' ){.
30f0: 20 20 20 20 20 20 63 6e 74 2b 2b 3b 0a 20 20 20        cnt++;.   
3100: 20 20 20 69 66 28 20 63 6e 74 3d 3d 4e 20 29 7b     if( cnt==N ){
3110: 0a 20 20 20 20 20 20 20 20 69 2b 2b 3b 0a 20 20  .        i++;.  
3120: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
3130: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 69     }.    }.    i
3140: 2b 2b 3b 0a 20 20 7d 0a 20 20 69 66 28 20 70 54  ++;.  }.  if( pT
3150: 6f 20 29 7b 0a 20 20 20 20 62 6c 6f 62 5f 61 70  o ){.    blob_ap
3160: 70 65 6e 64 28 70 54 6f 2c 20 26 70 46 72 6f 6d  pend(pTo, &pFrom
3170: 2d 3e 61 44 61 74 61 5b 70 46 72 6f 6d 2d 3e 69  ->aData[pFrom->i
3180: 43 75 72 73 6f 72 5d 2c 20 69 20 2d 20 70 46 72  Cursor], i - pFr
3190: 6f 6d 2d 3e 69 43 75 72 73 6f 72 29 3b 0a 20 20  om->iCursor);.  
31a0: 7d 0a 20 20 70 46 72 6f 6d 2d 3e 69 43 75 72 73  }.  pFrom->iCurs
31b0: 6f 72 20 3d 20 69 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  or = i;.}../*.**
31c0: 20 52 65 74 75 72 6e 20 74 72 75 65 20 69 66 20   Return true if 
31d0: 74 68 65 20 62 6c 6f 62 20 63 6f 6e 74 61 69 6e  the blob contain
31e0: 73 20 61 20 76 61 6c 69 64 20 55 55 49 44 5f 53  s a valid UUID_S
31f0: 49 5a 45 2d 64 69 67 69 74 20 62 61 73 65 31 36  IZE-digit base16
3200: 20 69 64 65 6e 74 69 66 69 65 72 2e 0a 2a 2f 0a   identifier..*/.
3210: 69 6e 74 20 62 6c 6f 62 5f 69 73 5f 75 75 69 64  int blob_is_uuid
3220: 28 42 6c 6f 62 20 2a 70 42 6c 6f 62 29 7b 0a 20  (Blob *pBlob){. 
3230: 20 72 65 74 75 72 6e 20 62 6c 6f 62 5f 73 69 7a   return blob_siz
3240: 65 28 70 42 6c 6f 62 29 3d 3d 55 55 49 44 5f 53  e(pBlob)==UUID_S
3250: 49 5a 45 0a 20 20 20 20 20 20 20 20 20 26 26 20  IZE.         && 
3260: 76 61 6c 69 64 61 74 65 31 36 28 62 6c 6f 62 5f  validate16(blob_
3270: 62 75 66 66 65 72 28 70 42 6c 6f 62 29 2c 20 55  buffer(pBlob), U
3280: 55 49 44 5f 53 49 5a 45 29 3b 0a 7d 0a 69 6e 74  UID_SIZE);.}.int
3290: 20 62 6c 6f 62 5f 69 73 5f 75 75 69 64 5f 6e 28   blob_is_uuid_n(
32a0: 42 6c 6f 62 20 2a 70 42 6c 6f 62 2c 20 69 6e 74  Blob *pBlob, int
32b0: 20 6e 29 7b 0a 20 20 72 65 74 75 72 6e 20 62 6c   n){.  return bl
32c0: 6f 62 5f 73 69 7a 65 28 70 42 6c 6f 62 29 3d 3d  ob_size(pBlob)==
32d0: 6e 20 26 26 20 76 61 6c 69 64 61 74 65 31 36 28  n && validate16(
32e0: 62 6c 6f 62 5f 62 75 66 66 65 72 28 70 42 6c 6f  blob_buffer(pBlo
32f0: 62 29 2c 20 6e 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  b), n);.}../*.**
3300: 20 52 65 74 75 72 6e 20 74 72 75 65 20 69 66 20   Return true if 
3310: 74 68 65 20 62 6c 6f 62 20 63 6f 6e 74 61 69 6e  the blob contain
3320: 73 20 61 20 76 61 6c 69 64 20 33 32 2d 62 69 74  s a valid 32-bit
3330: 20 69 6e 74 65 67 65 72 2e 20 20 53 74 6f 72 65   integer.  Store
3340: 0a 2a 2a 20 74 68 65 20 69 6e 74 65 67 65 72 20  .** the integer 
3350: 76 61 6c 75 65 20 69 6e 20 2a 70 56 61 6c 75 65  value in *pValue
3360: 2e 0a 2a 2f 0a 69 6e 74 20 62 6c 6f 62 5f 69 73  ..*/.int blob_is
3370: 5f 69 6e 74 28 42 6c 6f 62 20 2a 70 42 6c 6f 62  _int(Blob *pBlob
3380: 2c 20 69 6e 74 20 2a 70 56 61 6c 75 65 29 7b 0a  , int *pValue){.
3390: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 20    const char *z 
33a0: 3d 20 62 6c 6f 62 5f 62 75 66 66 65 72 28 70 42  = blob_buffer(pB
33b0: 6c 6f 62 29 3b 0a 20 20 69 6e 74 20 69 2c 20 6e  lob);.  int i, n
33c0: 2c 20 63 2c 20 76 3b 0a 20 20 6e 20 3d 20 62 6c  , c, v;.  n = bl
33d0: 6f 62 5f 73 69 7a 65 28 70 42 6c 6f 62 29 3b 0a  ob_size(pBlob);.
33e0: 20 20 76 20 3d 20 30 3b 0a 20 20 66 6f 72 28 69    v = 0;.  for(i
33f0: 3d 30 3b 20 69 3c 6e 20 26 26 20 28 63 20 3d 20  =0; i<n && (c = 
3400: 7a 5b 69 5d 29 21 3d 30 20 26 26 20 69 73 64 69  z[i])!=0 && isdi
3410: 67 69 74 28 63 29 3b 20 69 2b 2b 29 7b 0a 20 20  git(c); i++){.  
3420: 20 20 76 20 3d 20 76 2a 31 30 20 2b 20 63 20 2d    v = v*10 + c -
3430: 20 27 30 27 3b 0a 20 20 7d 0a 20 20 69 66 28 20   '0';.  }.  if( 
3440: 69 3d 3d 6e 20 29 7b 0a 20 20 20 20 2a 70 56 61  i==n ){.    *pVa
3450: 6c 75 65 20 3d 20 76 3b 0a 20 20 20 20 72 65 74  lue = v;.    ret
3460: 75 72 6e 20 31 3b 0a 20 20 7d 65 6c 73 65 7b 0a  urn 1;.  }else{.
3470: 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20      return 0;.  
3480: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 5a 65 72 6f 20  }.}../*.** Zero 
3490: 6f 72 20 72 65 73 65 74 20 61 6e 20 61 72 72 61  or reset an arra
34a0: 79 20 6f 66 20 42 6c 6f 62 73 2e 0a 2a 2f 0a 76  y of Blobs..*/.v
34b0: 6f 69 64 20 62 6c 6f 62 61 72 72 61 79 5f 7a 65  oid blobarray_ze
34c0: 72 6f 28 42 6c 6f 62 20 2a 61 42 6c 6f 62 2c 20  ro(Blob *aBlob, 
34d0: 69 6e 74 20 6e 29 7b 0a 20 20 69 6e 74 20 69 3b  int n){.  int i;
34e0: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 3b  .  for(i=0; i<n;
34f0: 20 69 2b 2b 29 20 62 6c 6f 62 5f 7a 65 72 6f 28   i++) blob_zero(
3500: 26 61 42 6c 6f 62 5b 69 5d 29 3b 0a 7d 0a 76 6f  &aBlob[i]);.}.vo
3510: 69 64 20 62 6c 6f 62 61 72 72 61 79 5f 72 65 73  id blobarray_res
3520: 65 74 28 42 6c 6f 62 20 2a 61 42 6c 6f 62 2c 20  et(Blob *aBlob, 
3530: 69 6e 74 20 6e 29 7b 0a 20 20 69 6e 74 20 69 3b  int n){.  int i;
3540: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 3b  .  for(i=0; i<n;
3550: 20 69 2b 2b 29 20 62 6c 6f 62 5f 72 65 73 65 74   i++) blob_reset
3560: 28 26 61 42 6c 6f 62 5b 69 5d 29 3b 0a 7d 0a 0a  (&aBlob[i]);.}..
3570: 2f 2a 0a 2a 2a 20 50 61 72 73 65 20 61 20 62 6c  /*.** Parse a bl
3580: 6f 62 20 69 6e 74 6f 20 73 70 61 63 65 2d 73 65  ob into space-se
3590: 70 61 72 61 74 65 64 20 74 6f 6b 65 6e 73 2e 20  parated tokens. 
35a0: 20 53 74 6f 72 65 20 65 61 63 68 20 74 6f 6b 65   Store each toke
35b0: 6e 20 69 6e 0a 2a 2a 20 61 6e 20 65 6c 65 6d 65  n in.** an eleme
35c0: 6e 74 20 6f 66 20 74 68 65 20 62 6c 6f 62 61 72  nt of the blobar
35d0: 72 61 79 20 61 54 6f 6b 65 6e 5b 5d 2e 20 20 61  ray aToken[].  a
35e0: 54 6f 6b 65 6e 5b 5d 20 69 73 20 6e 54 6f 6b 65  Token[] is nToke
35f0: 6e 20 65 6c 65 6d 65 6e 74 73 20 69 6e 0a 2a 2a  n elements in.**
3600: 20 73 69 7a 65 2e 20 20 52 65 74 75 72 6e 20 74   size.  Return t
3610: 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 74 6f 6b  he number of tok
3620: 65 6e 73 20 73 65 65 6e 2e 0a 2a 2f 0a 69 6e 74  ens seen..*/.int
3630: 20 62 6c 6f 62 5f 74 6f 6b 65 6e 69 7a 65 28 42   blob_tokenize(B
3640: 6c 6f 62 20 2a 70 49 6e 2c 20 42 6c 6f 62 20 2a  lob *pIn, Blob *
3650: 61 54 6f 6b 65 6e 2c 20 69 6e 74 20 6e 54 6f 6b  aToken, int nTok
3660: 65 6e 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20  en){.  int i;.  
3670: 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 54 6f 6b 65  for(i=0; i<nToke
3680: 6e 20 26 26 20 62 6c 6f 62 5f 74 6f 6b 65 6e 28  n && blob_token(
3690: 70 49 6e 2c 20 26 61 54 6f 6b 65 6e 5b 69 5d 29  pIn, &aToken[i])
36a0: 3b 20 69 2b 2b 29 7b 7d 0a 20 20 72 65 74 75 72  ; i++){}.  retur
36b0: 6e 20 69 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 6f  n i;.}../*.** Do
36c0: 20 70 72 69 6e 74 66 2d 73 74 79 6c 65 20 73 74   printf-style st
36d0: 72 69 6e 67 20 72 65 6e 64 65 72 69 6e 67 20 61  ring rendering a
36e0: 6e 64 20 61 70 70 65 6e 64 20 74 68 65 20 72 65  nd append the re
36f0: 73 75 6c 74 73 20 74 6f 20 61 20 62 6c 6f 62 2e  sults to a blob.
3700: 0a 2a 2f 0a 76 6f 69 64 20 62 6c 6f 62 5f 61 70  .*/.void blob_ap
3710: 70 65 6e 64 66 28 42 6c 6f 62 20 2a 70 42 6c 6f  pendf(Blob *pBlo
3720: 62 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  b, const char *z
3730: 46 6f 72 6d 61 74 2c 20 2e 2e 2e 29 7b 0a 20 20  Format, ...){.  
3740: 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 76 61  va_list ap;.  va
3750: 5f 73 74 61 72 74 28 61 70 2c 20 7a 46 6f 72 6d  _start(ap, zForm
3760: 61 74 29 3b 0a 20 20 76 78 70 72 69 6e 74 66 28  at);.  vxprintf(
3770: 70 42 6c 6f 62 2c 20 7a 46 6f 72 6d 61 74 2c 20  pBlob, zFormat, 
3780: 61 70 29 3b 0a 20 20 76 61 5f 65 6e 64 28 61 70  ap);.  va_end(ap
3790: 29 3b 0a 7d 0a 76 6f 69 64 20 62 6c 6f 62 5f 76  );.}.void blob_v
37a0: 61 70 70 65 6e 64 66 28 42 6c 6f 62 20 2a 70 42  appendf(Blob *pB
37b0: 6c 6f 62 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  lob, const char 
37c0: 2a 7a 46 6f 72 6d 61 74 2c 20 76 61 5f 6c 69 73  *zFormat, va_lis
37d0: 74 20 61 70 29 7b 0a 20 20 76 78 70 72 69 6e 74  t ap){.  vxprint
37e0: 66 28 70 42 6c 6f 62 2c 20 7a 46 6f 72 6d 61 74  f(pBlob, zFormat
37f0: 2c 20 61 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  , ap);.}../*.** 
3800: 49 6e 69 74 61 6c 69 7a 65 20 61 20 62 6c 6f 62  Initalize a blob
3810: 20 74 6f 20 74 68 65 20 64 61 74 61 20 6f 6e 20   to the data on 
3820: 61 6e 20 69 6e 70 75 74 20 63 68 61 6e 6e 65 6c  an input channel
3830: 2e 20 20 52 65 74 75 72 6e 20 0a 2a 2a 20 74 68  .  Return .** th
3840: 65 20 6e 75 6d 62 65 72 20 6f 66 20 62 79 74 65  e number of byte
3850: 73 20 72 65 61 64 20 69 6e 74 6f 20 74 68 65 20  s read into the 
3860: 62 6c 6f 62 2e 20 20 41 6e 79 20 70 72 69 6f 72  blob.  Any prior
3870: 20 63 6f 6e 74 65 6e 74 0a 2a 2a 20 6f 66 20 74   content.** of t
3880: 68 65 20 62 6c 6f 62 20 69 73 20 64 69 73 63 61  he blob is disca
3890: 72 64 65 64 2c 20 6e 6f 74 20 66 72 65 65 64 2e  rded, not freed.
38a0: 0a 2a 2f 0a 69 6e 74 20 62 6c 6f 62 5f 72 65 61  .*/.int blob_rea
38b0: 64 5f 66 72 6f 6d 5f 63 68 61 6e 6e 65 6c 28 42  d_from_channel(B
38c0: 6c 6f 62 20 2a 70 42 6c 6f 62 2c 20 46 49 4c 45  lob *pBlob, FILE
38d0: 20 2a 69 6e 2c 20 69 6e 74 20 6e 54 6f 52 65 61   *in, int nToRea
38e0: 64 29 7b 0a 20 20 73 69 7a 65 5f 74 20 6e 3b 0a  d){.  size_t n;.
38f0: 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 70 42 6c 6f    blob_zero(pBlo
3900: 62 29 3b 0a 20 20 69 66 28 20 6e 54 6f 52 65 61  b);.  if( nToRea
3910: 64 3c 30 20 29 7b 0a 20 20 20 20 63 68 61 72 20  d<0 ){.    char 
3920: 7a 42 75 66 5b 31 30 30 30 30 5d 3b 0a 20 20 20  zBuf[10000];.   
3930: 20 77 68 69 6c 65 28 20 21 66 65 6f 66 28 69 6e   while( !feof(in
3940: 29 20 29 7b 0a 20 20 20 20 20 20 6e 20 3d 20 66  ) ){.      n = f
3950: 72 65 61 64 28 7a 42 75 66 2c 20 31 2c 20 73 69  read(zBuf, 1, si
3960: 7a 65 6f 66 28 7a 42 75 66 29 2c 20 69 6e 29 3b  zeof(zBuf), in);
3970: 0a 20 20 20 20 20 20 69 66 28 20 6e 3e 30 20 29  .      if( n>0 )
3980: 7b 0a 20 20 20 20 20 20 20 20 62 6c 6f 62 5f 61  {.        blob_a
3990: 70 70 65 6e 64 28 70 42 6c 6f 62 2c 20 7a 42 75  ppend(pBlob, zBu
39a0: 66 2c 20 6e 29 3b 0a 20 20 20 20 20 20 7d 0a 20  f, n);.      }. 
39b0: 20 20 20 7d 0a 20 20 7d 65 6c 73 65 7b 0a 20 20     }.  }else{.  
39c0: 20 20 62 6c 6f 62 5f 72 65 73 69 7a 65 28 70 42    blob_resize(pB
39d0: 6c 6f 62 2c 20 6e 54 6f 52 65 61 64 29 3b 0a 20  lob, nToRead);. 
39e0: 20 20 20 6e 20 3d 20 66 72 65 61 64 28 62 6c 6f     n = fread(blo
39f0: 62 5f 62 75 66 66 65 72 28 70 42 6c 6f 62 29 2c  b_buffer(pBlob),
3a00: 20 31 2c 20 6e 54 6f 52 65 61 64 2c 20 69 6e 29   1, nToRead, in)
3a10: 3b 0a 20 20 20 20 62 6c 6f 62 5f 72 65 73 69 7a  ;.    blob_resiz
3a20: 65 28 70 42 6c 6f 62 2c 20 6e 29 3b 0a 20 20 7d  e(pBlob, n);.  }
3a30: 0a 20 20 72 65 74 75 72 6e 20 62 6c 6f 62 5f 73  .  return blob_s
3a40: 69 7a 65 28 70 42 6c 6f 62 29 3b 0a 7d 0a 0a 2f  ize(pBlob);.}../
3a50: 2a 0a 2a 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20  *.** Initialize 
3a60: 61 20 62 6c 6f 62 20 74 6f 20 62 65 20 74 68 65  a blob to be the
3a70: 20 63 6f 6e 74 65 6e 74 20 6f 66 20 61 20 66 69   content of a fi
3a80: 6c 65 2e 20 20 49 66 20 74 68 65 20 66 69 6c 65  le.  If the file
3a90: 6e 61 6d 65 0a 2a 2a 20 69 73 20 62 6c 61 6e 6b  name.** is blank
3aa0: 20 6f 72 20 22 2d 22 20 74 68 65 6e 20 72 65 61   or "-" then rea
3ab0: 64 20 66 72 6f 6d 20 73 74 61 6e 64 61 72 64 20  d from standard 
3ac0: 69 6e 70 75 74 2e 0a 2a 2a 0a 2a 2a 20 41 6e 79  input..**.** Any
3ad0: 20 70 72 69 6f 72 20 63 6f 6e 74 65 6e 74 20 6f   prior content o
3ae0: 66 20 74 68 65 20 62 6c 6f 62 20 69 73 20 64 69  f the blob is di
3af0: 73 63 61 72 64 65 64 2c 20 6e 6f 74 20 66 72 65  scarded, not fre
3b00: 65 64 2e 0a 2a 2a 0a 2a 2a 20 52 65 74 75 72 6e  ed..**.** Return
3b10: 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 62   the number of b
3b20: 79 74 65 73 20 72 65 61 64 2e 20 20 52 65 74 75  ytes read.  Retu
3b30: 72 6e 20 2d 31 20 66 6f 72 20 61 6e 20 65 72 72  rn -1 for an err
3b40: 6f 72 2e 0a 2a 2f 0a 69 6e 74 20 62 6c 6f 62 5f  or..*/.int blob_
3b50: 72 65 61 64 5f 66 72 6f 6d 5f 66 69 6c 65 28 42  read_from_file(B
3b60: 6c 6f 62 20 2a 70 42 6c 6f 62 2c 20 63 6f 6e 73  lob *pBlob, cons
3b70: 74 20 63 68 61 72 20 2a 7a 46 69 6c 65 6e 61 6d  t char *zFilenam
3b80: 65 29 7b 0a 20 20 69 6e 74 20 73 69 7a 65 2c 20  e){.  int size, 
3b90: 67 6f 74 3b 0a 20 20 46 49 4c 45 20 2a 69 6e 3b  got;.  FILE *in;
3ba0: 0a 20 20 69 66 28 20 7a 46 69 6c 65 6e 61 6d 65  .  if( zFilename
3bb0: 3d 3d 30 20 7c 7c 20 7a 46 69 6c 65 6e 61 6d 65  ==0 || zFilename
3bc0: 5b 30 5d 3d 3d 30 0a 20 20 20 20 20 20 20 20 7c  [0]==0.        |
3bd0: 7c 20 28 7a 46 69 6c 65 6e 61 6d 65 5b 30 5d 3d  | (zFilename[0]=
3be0: 3d 27 2d 27 20 26 26 20 7a 46 69 6c 65 6e 61 6d  ='-' && zFilenam
3bf0: 65 5b 31 5d 3d 3d 30 29 20 29 7b 0a 20 20 20 20  e[1]==0) ){.    
3c00: 72 65 74 75 72 6e 20 62 6c 6f 62 5f 72 65 61 64  return blob_read
3c10: 5f 66 72 6f 6d 5f 63 68 61 6e 6e 65 6c 28 70 42  _from_channel(pB
3c20: 6c 6f 62 2c 20 73 74 64 69 6e 2c 20 2d 31 29 3b  lob, stdin, -1);
3c30: 0a 20 20 7d 0a 20 20 73 69 7a 65 20 3d 20 66 69  .  }.  size = fi
3c40: 6c 65 5f 73 69 7a 65 28 7a 46 69 6c 65 6e 61 6d  le_size(zFilenam
3c50: 65 29 3b 0a 20 20 62 6c 6f 62 5f 7a 65 72 6f 28  e);.  blob_zero(
3c60: 70 42 6c 6f 62 29 3b 0a 20 20 69 66 28 20 73 69  pBlob);.  if( si
3c70: 7a 65 3c 30 20 29 7b 0a 20 20 20 20 66 6f 73 73  ze<0 ){.    foss
3c80: 69 6c 5f 70 61 6e 69 63 28 22 6e 6f 20 73 75 63  il_panic("no suc
3c90: 68 20 66 69 6c 65 3a 20 25 73 22 2c 20 7a 46 69  h file: %s", zFi
3ca0: 6c 65 6e 61 6d 65 29 3b 0a 20 20 7d 0a 20 20 69  lename);.  }.  i
3cb0: 66 28 20 73 69 7a 65 3d 3d 30 20 29 7b 0a 20 20  f( size==0 ){.  
3cc0: 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a    return 0;.  }.
3cd0: 20 20 62 6c 6f 62 5f 72 65 73 69 7a 65 28 70 42    blob_resize(pB
3ce0: 6c 6f 62 2c 20 73 69 7a 65 29 3b 0a 20 20 69 6e  lob, size);.  in
3cf0: 20 3d 20 66 6f 70 65 6e 28 7a 46 69 6c 65 6e 61   = fopen(zFilena
3d00: 6d 65 2c 20 22 72 62 22 29 3b 0a 20 20 69 66 28  me, "rb");.  if(
3d10: 20 69 6e 3d 3d 30 20 29 7b 0a 20 20 20 20 66 6f   in==0 ){.    fo
3d20: 73 73 69 6c 5f 70 61 6e 69 63 28 22 63 61 6e 6e  ssil_panic("cann
3d30: 6f 74 20 6f 70 65 6e 20 25 73 20 66 6f 72 20 72  ot open %s for r
3d40: 65 61 64 69 6e 67 22 2c 20 7a 46 69 6c 65 6e 61  eading", zFilena
3d50: 6d 65 29 3b 0a 20 20 7d 0a 20 20 67 6f 74 20 3d  me);.  }.  got =
3d60: 20 66 72 65 61 64 28 62 6c 6f 62 5f 62 75 66 66   fread(blob_buff
3d70: 65 72 28 70 42 6c 6f 62 29 2c 20 31 2c 20 73 69  er(pBlob), 1, si
3d80: 7a 65 2c 20 69 6e 29 3b 0a 20 20 66 63 6c 6f 73  ze, in);.  fclos
3d90: 65 28 69 6e 29 3b 0a 20 20 69 66 28 20 67 6f 74  e(in);.  if( got
3da0: 3c 73 69 7a 65 20 29 7b 0a 20 20 20 20 62 6c 6f  <size ){.    blo
3db0: 62 5f 72 65 73 69 7a 65 28 70 42 6c 6f 62 2c 20  b_resize(pBlob, 
3dc0: 67 6f 74 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75  got);.  }.  retu
3dd0: 72 6e 20 67 6f 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  rn got;.}../*.**
3de0: 20 57 72 69 74 65 20 74 68 65 20 63 6f 6e 74 65   Write the conte
3df0: 6e 74 20 6f 66 20 61 20 62 6c 6f 62 20 69 6e 74  nt of a blob int
3e00: 6f 20 61 20 66 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20  o a file..**.** 
3e10: 49 66 20 74 68 65 20 66 69 6c 65 6e 61 6d 65 20  If the filename 
3e20: 69 73 20 62 6c 61 6e 6b 20 6f 72 20 22 2d 22 20  is blank or "-" 
3e30: 74 68 65 6e 20 77 72 69 74 65 20 74 6f 20 73 74  then write to st
3e40: 61 6e 64 61 72 64 20 6f 75 74 70 75 74 2e 0a 2a  andard output..*
3e50: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20  *.** Return the 
3e60: 6e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20  number of bytes 
3e70: 77 72 69 74 74 65 6e 2e 0a 2a 2f 0a 69 6e 74 20  written..*/.int 
3e80: 62 6c 6f 62 5f 77 72 69 74 65 5f 74 6f 5f 66 69  blob_write_to_fi
3e90: 6c 65 28 42 6c 6f 62 20 2a 70 42 6c 6f 62 2c 20  le(Blob *pBlob, 
3ea0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 69 6c  const char *zFil
3eb0: 65 6e 61 6d 65 29 7b 0a 20 20 46 49 4c 45 20 2a  ename){.  FILE *
3ec0: 6f 75 74 3b 0a 20 20 69 6e 74 20 6e 65 65 64 54  out;.  int needT
3ed0: 6f 43 6c 6f 73 65 3b 0a 20 20 69 6e 74 20 77 72  oClose;.  int wr
3ee0: 6f 74 65 3b 0a 0a 20 20 69 66 28 20 7a 46 69 6c  ote;..  if( zFil
3ef0: 65 6e 61 6d 65 5b 30 5d 3d 3d 30 20 7c 7c 20 28  ename[0]==0 || (
3f00: 7a 46 69 6c 65 6e 61 6d 65 5b 30 5d 3d 3d 27 2d  zFilename[0]=='-
3f10: 27 20 26 26 20 7a 46 69 6c 65 6e 61 6d 65 5b 31  ' && zFilename[1
3f20: 5d 3d 3d 30 29 20 29 7b 0a 20 20 20 20 6f 75 74  ]==0) ){.    out
3f30: 20 3d 20 73 74 64 6f 75 74 3b 0a 20 20 20 20 6e   = stdout;.    n
3f40: 65 65 64 54 6f 43 6c 6f 73 65 20 3d 20 30 3b 0a  eedToClose = 0;.
3f50: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 69 6e 74    }else{.    int
3f60: 20 69 2c 20 6e 4e 61 6d 65 3b 0a 20 20 20 20 63   i, nName;.    c
3f70: 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 7a 42 75 66  har *zName, zBuf
3f80: 5b 31 30 30 30 5d 3b 0a 0a 20 20 20 20 6e 4e 61  [1000];..    nNa
3f90: 6d 65 20 3d 20 73 74 72 6c 65 6e 28 7a 46 69 6c  me = strlen(zFil
3fa0: 65 6e 61 6d 65 29 3b 0a 20 20 20 20 69 66 28 20  ename);.    if( 
3fb0: 6e 4e 61 6d 65 3e 3d 73 69 7a 65 6f 66 28 7a 42  nName>=sizeof(zB
3fc0: 75 66 29 20 29 7b 0a 20 20 20 20 20 20 7a 4e 61  uf) ){.      zNa
3fd0: 6d 65 20 3d 20 6d 70 72 69 6e 74 66 28 22 25 73  me = mprintf("%s
3fe0: 22 2c 20 7a 46 69 6c 65 6e 61 6d 65 29 3b 0a 20  ", zFilename);. 
3ff0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
4000: 7a 4e 61 6d 65 20 3d 20 7a 42 75 66 3b 0a 20 20  zName = zBuf;.  
4010: 20 20 20 20 73 74 72 63 70 79 28 7a 4e 61 6d 65      strcpy(zName
4020: 2c 20 7a 46 69 6c 65 6e 61 6d 65 29 3b 0a 20 20  , zFilename);.  
4030: 20 20 7d 0a 20 20 20 20 6e 4e 61 6d 65 20 3d 20    }.    nName = 
4040: 66 69 6c 65 5f 73 69 6d 70 6c 69 66 79 5f 6e 61  file_simplify_na
4050: 6d 65 28 7a 4e 61 6d 65 2c 20 6e 4e 61 6d 65 29  me(zName, nName)
4060: 3b 0a 20 20 20 20 66 6f 72 28 69 3d 31 3b 20 69  ;.    for(i=1; i
4070: 3c 6e 4e 61 6d 65 3b 20 69 2b 2b 29 7b 0a 20 20  <nName; i++){.  
4080: 20 20 20 20 69 66 28 20 7a 4e 61 6d 65 5b 69 5d      if( zName[i]
4090: 3d 3d 27 2f 27 20 29 7b 0a 20 20 20 20 20 20 20  =='/' ){.       
40a0: 20 7a 4e 61 6d 65 5b 69 5d 20 3d 20 30 3b 0a 23   zName[i] = 0;.#
40b0: 69 66 64 65 66 20 5f 5f 4d 49 4e 47 57 33 32 5f  ifdef __MINGW32_
40c0: 5f 0a 20 20 20 20 20 20 20 20 2f 2a 0a 20 20 20  _.        /*.   
40d0: 20 20 20 20 20 2a 2a 20 4f 6e 20 57 69 6e 64 6f       ** On Windo
40e0: 77 73 2c 20 6c 6f 63 61 6c 20 70 61 74 68 20 6c  ws, local path l
40f0: 6f 6f 6b 73 20 6c 69 6b 65 3a 20 43 3a 2f 64 65  ooks like: C:/de
4100: 76 65 6c 6f 70 2f 70 72 6f 6a 65 63 74 2f 66 69  velop/project/fi
4110: 6c 65 2e 74 78 74 0a 20 20 20 20 20 20 20 20 2a  le.txt.        *
4120: 2a 20 54 68 65 20 69 66 20 73 74 6f 70 73 20 75  * The if stops u
4130: 73 20 66 72 6f 6d 20 74 72 79 69 6e 67 20 74 6f  s from trying to
4140: 20 63 72 65 61 74 65 20 61 20 64 69 72 65 63 74   create a direct
4150: 6f 72 79 20 6f 66 20 61 20 64 72 69 76 65 20 6c  ory of a drive l
4160: 65 74 74 65 72 0a 20 20 20 20 20 20 20 20 2a 2a  etter.        **
4170: 20 43 3a 20 69 6e 20 74 68 69 73 20 65 78 61 6d   C: in this exam
4180: 70 6c 65 2e 0a 20 20 20 20 20 20 20 20 2a 2f 0a  ple..        */.
4190: 20 20 20 20 20 20 20 20 69 66 28 20 21 28 69 3d          if( !(i=
41a0: 3d 32 20 26 26 20 7a 4e 61 6d 65 5b 31 5d 3d 3d  =2 && zName[1]==
41b0: 27 3a 27 29 20 29 7b 0a 23 65 6e 64 69 66 0a 20  ':') ){.#endif. 
41c0: 20 20 20 20 20 20 20 20 20 69 66 28 20 66 69 6c           if( fil
41d0: 65 5f 6d 6b 64 69 72 28 7a 4e 61 6d 65 2c 20 31  e_mkdir(zName, 1
41e0: 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20  ) ){.           
41f0: 20 66 6f 73 73 69 6c 5f 70 61 6e 69 63 28 22 75   fossil_panic("u
4200: 6e 61 62 6c 65 20 74 6f 20 63 72 65 61 74 65 20  nable to create 
4210: 64 69 72 65 63 74 6f 72 79 20 25 73 22 2c 20 7a  directory %s", z
4220: 4e 61 6d 65 29 3b 0a 20 20 20 20 20 20 20 20 20  Name);.         
4230: 20 7d 0a 23 69 66 64 65 66 20 5f 5f 4d 49 4e 47   }.#ifdef __MING
4240: 57 33 32 5f 5f 0a 20 20 20 20 20 20 20 20 7d 0a  W32__.        }.
4250: 23 65 6e 64 69 66 0a 20 20 20 20 20 20 20 20 7a  #endif.        z
4260: 4e 61 6d 65 5b 69 5d 20 3d 20 27 2f 27 3b 0a 20  Name[i] = '/';. 
4270: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20       }.    }.   
4280: 20 6f 75 74 20 3d 20 66 6f 70 65 6e 28 7a 4e 61   out = fopen(zNa
4290: 6d 65 2c 20 22 77 62 22 29 3b 0a 20 20 20 20 69  me, "wb");.    i
42a0: 66 28 20 6f 75 74 3d 3d 30 20 29 7b 0a 20 20 20  f( out==0 ){.   
42b0: 20 20 20 66 6f 73 73 69 6c 5f 70 61 6e 69 63 28     fossil_panic(
42c0: 22 75 6e 61 62 6c 65 20 74 6f 20 6f 70 65 6e 20  "unable to open 
42d0: 66 69 6c 65 20 5c 22 25 73 5c 22 20 66 6f 72 20  file \"%s\" for 
42e0: 77 72 69 74 69 6e 67 22 2c 20 7a 4e 61 6d 65 29  writing", zName)
42f0: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 6e 65 65 64  ;.    }.    need
4300: 54 6f 43 6c 6f 73 65 20 3d 20 31 3b 0a 20 20 20  ToClose = 1;.   
4310: 20 69 66 28 20 7a 4e 61 6d 65 21 3d 7a 42 75 66   if( zName!=zBuf
4320: 20 29 20 66 72 65 65 28 7a 4e 61 6d 65 29 3b 0a   ) free(zName);.
4330: 20 20 7d 0a 20 20 62 6c 6f 62 5f 69 73 5f 69 6e    }.  blob_is_in
4340: 69 74 28 70 42 6c 6f 62 29 3b 0a 20 20 77 72 6f  it(pBlob);.  wro
4350: 74 65 20 3d 20 66 77 72 69 74 65 28 62 6c 6f 62  te = fwrite(blob
4360: 5f 62 75 66 66 65 72 28 70 42 6c 6f 62 29 2c 20  _buffer(pBlob), 
4370: 31 2c 20 62 6c 6f 62 5f 73 69 7a 65 28 70 42 6c  1, blob_size(pBl
4380: 6f 62 29 2c 20 6f 75 74 29 3b 0a 20 20 69 66 28  ob), out);.  if(
4390: 20 6e 65 65 64 54 6f 43 6c 6f 73 65 20 29 20 66   needToClose ) f
43a0: 63 6c 6f 73 65 28 6f 75 74 29 3b 0a 20 20 69 66  close(out);.  if
43b0: 28 20 77 72 6f 74 65 21 3d 62 6c 6f 62 5f 73 69  ( wrote!=blob_si
43c0: 7a 65 28 70 42 6c 6f 62 29 20 29 7b 0a 20 20 20  ze(pBlob) ){.   
43d0: 20 66 6f 73 73 69 6c 5f 70 61 6e 69 63 28 22 73   fossil_panic("s
43e0: 68 6f 72 74 20 77 72 69 74 65 3a 20 25 64 20 6f  hort write: %d o
43f0: 66 20 25 64 20 62 79 74 65 73 20 74 6f 20 25 73  f %d bytes to %s
4400: 22 2c 20 77 72 6f 74 65 2c 0a 20 20 20 20 20 20  ", wrote,.      
4410: 20 62 6c 6f 62 5f 73 69 7a 65 28 70 42 6c 6f 62   blob_size(pBlob
4420: 29 2c 20 7a 46 69 6c 65 6e 61 6d 65 29 3b 0a 20  ), zFilename);. 
4430: 20 7d 0a 20 20 72 65 74 75 72 6e 20 77 72 6f 74   }.  return wrot
4440: 65 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70  e;.}../*.** Comp
4450: 72 65 73 73 20 61 20 62 6c 6f 62 20 70 49 6e 2e  ress a blob pIn.
4460: 20 20 53 74 6f 72 65 20 74 68 65 20 72 65 73 75    Store the resu
4470: 6c 74 20 69 6e 20 70 4f 75 74 2e 20 20 49 74 20  lt in pOut.  It 
4480: 69 73 20 6f 6b 20 66 6f 72 20 70 49 6e 20 61 6e  is ok for pIn an
4490: 64 0a 2a 2a 20 70 4f 75 74 20 74 6f 20 62 65 20  d.** pOut to be 
44a0: 74 68 65 20 73 61 6d 65 20 62 6c 6f 62 2e 20 0a  the same blob. .
44b0: 2a 2a 20 0a 2a 2a 20 70 4f 75 74 20 6d 75 73 74  ** .** pOut must
44c0: 20 65 69 74 68 65 72 20 62 65 20 74 68 65 20 73   either be the s
44d0: 61 6d 65 20 61 73 20 70 49 6e 20 6f 72 20 65 6c  ame as pIn or el
44e0: 73 65 20 75 6e 69 6e 69 74 69 61 6c 69 7a 65 64  se uninitialized
44f0: 2e 0a 2a 2f 0a 76 6f 69 64 20 62 6c 6f 62 5f 63  ..*/.void blob_c
4500: 6f 6d 70 72 65 73 73 28 42 6c 6f 62 20 2a 70 49  ompress(Blob *pI
4510: 6e 2c 20 42 6c 6f 62 20 2a 70 4f 75 74 29 7b 0a  n, Blob *pOut){.
4520: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e    unsigned int n
4530: 49 6e 20 3d 20 62 6c 6f 62 5f 73 69 7a 65 28 70  In = blob_size(p
4540: 49 6e 29 3b 0a 20 20 75 6e 73 69 67 6e 65 64 20  In);.  unsigned 
4550: 69 6e 74 20 6e 4f 75 74 20 3d 20 31 33 20 2b 20  int nOut = 13 + 
4560: 6e 49 6e 20 2b 20 28 6e 49 6e 2b 39 39 39 29 2f  nIn + (nIn+999)/
4570: 31 30 30 30 3b 0a 20 20 75 6e 73 69 67 6e 65 64  1000;.  unsigned
4580: 20 6c 6f 6e 67 20 69 6e 74 20 6e 4f 75 74 32 3b   long int nOut2;
4590: 0a 20 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72  .  unsigned char
45a0: 20 2a 6f 75 74 42 75 66 3b 0a 20 20 42 6c 6f 62   *outBuf;.  Blob
45b0: 20 74 65 6d 70 3b 0a 20 20 62 6c 6f 62 5f 7a 65   temp;.  blob_ze
45c0: 72 6f 28 26 74 65 6d 70 29 3b 0a 20 20 62 6c 6f  ro(&temp);.  blo
45d0: 62 5f 72 65 73 69 7a 65 28 26 74 65 6d 70 2c 20  b_resize(&temp, 
45e0: 6e 4f 75 74 2b 34 29 3b 0a 20 20 6f 75 74 42 75  nOut+4);.  outBu
45f0: 66 20 3d 20 28 75 6e 73 69 67 6e 65 64 20 63 68  f = (unsigned ch
4600: 61 72 2a 29 62 6c 6f 62 5f 62 75 66 66 65 72 28  ar*)blob_buffer(
4610: 26 74 65 6d 70 29 3b 0a 20 20 6f 75 74 42 75 66  &temp);.  outBuf
4620: 5b 30 5d 20 3d 20 6e 49 6e 3e 3e 32 34 20 26 20  [0] = nIn>>24 & 
4630: 30 78 66 66 3b 0a 20 20 6f 75 74 42 75 66 5b 31  0xff;.  outBuf[1
4640: 5d 20 3d 20 6e 49 6e 3e 3e 31 36 20 26 20 30 78  ] = nIn>>16 & 0x
4650: 66 66 3b 0a 20 20 6f 75 74 42 75 66 5b 32 5d 20  ff;.  outBuf[2] 
4660: 3d 20 6e 49 6e 3e 3e 38 20 26 20 30 78 66 66 3b  = nIn>>8 & 0xff;
4670: 0a 20 20 6f 75 74 42 75 66 5b 33 5d 20 3d 20 6e  .  outBuf[3] = n
4680: 49 6e 20 26 20 30 78 66 66 3b 0a 20 20 6e 4f 75  In & 0xff;.  nOu
4690: 74 32 20 3d 20 28 6c 6f 6e 67 20 69 6e 74 29 6e  t2 = (long int)n
46a0: 4f 75 74 3b 0a 20 20 63 6f 6d 70 72 65 73 73 28  Out;.  compress(
46b0: 26 6f 75 74 42 75 66 5b 34 5d 2c 20 26 6e 4f 75  &outBuf[4], &nOu
46c0: 74 32 2c 0a 20 20 20 20 20 20 20 20 20 20 20 28  t2,.           (
46d0: 75 6e 73 69 67 6e 65 64 20 63 68 61 72 2a 29 62  unsigned char*)b
46e0: 6c 6f 62 5f 62 75 66 66 65 72 28 70 49 6e 29 2c  lob_buffer(pIn),
46f0: 20 62 6c 6f 62 5f 73 69 7a 65 28 70 49 6e 29 29   blob_size(pIn))
4700: 3b 0a 20 20 69 66 28 20 70 4f 75 74 3d 3d 70 49  ;.  if( pOut==pI
4710: 6e 20 29 20 62 6c 6f 62 5f 72 65 73 65 74 28 70  n ) blob_reset(p
4720: 4f 75 74 29 3b 0a 20 20 62 6c 6f 62 5f 69 73 5f  Out);.  blob_is_
4730: 72 65 73 65 74 28 70 4f 75 74 29 3b 0a 20 20 2a  reset(pOut);.  *
4740: 70 4f 75 74 20 3d 20 74 65 6d 70 3b 0a 20 20 62  pOut = temp;.  b
4750: 6c 6f 62 5f 72 65 73 69 7a 65 28 70 4f 75 74 2c  lob_resize(pOut,
4760: 20 6e 4f 75 74 32 2b 34 29 3b 0a 7d 0a 0a 2f 2a   nOut2+4);.}../*
4770: 0a 2a 2a 20 43 4f 4d 4d 41 4e 44 3a 20 74 65 73  .** COMMAND: tes
4780: 74 2d 63 6f 6d 70 72 65 73 73 0a 2a 2f 0a 76 6f  t-compress.*/.vo
4790: 69 64 20 63 6f 6d 70 72 65 73 73 5f 63 6d 64 28  id compress_cmd(
47a0: 76 6f 69 64 29 7b 0a 20 20 42 6c 6f 62 20 66 3b  void){.  Blob f;
47b0: 0a 20 20 69 66 28 20 67 2e 61 72 67 63 21 3d 34  .  if( g.argc!=4
47c0: 20 29 20 75 73 61 67 65 28 22 49 4e 50 55 54 46   ) usage("INPUTF
47d0: 49 4c 45 20 4f 55 54 50 55 54 46 49 4c 45 22 29  ILE OUTPUTFILE")
47e0: 3b 0a 20 20 62 6c 6f 62 5f 72 65 61 64 5f 66 72  ;.  blob_read_fr
47f0: 6f 6d 5f 66 69 6c 65 28 26 66 2c 20 67 2e 61 72  om_file(&f, g.ar
4800: 67 76 5b 32 5d 29 3b 0a 20 20 62 6c 6f 62 5f 63  gv[2]);.  blob_c
4810: 6f 6d 70 72 65 73 73 28 26 66 2c 20 26 66 29 3b  ompress(&f, &f);
4820: 0a 20 20 62 6c 6f 62 5f 77 72 69 74 65 5f 74 6f  .  blob_write_to
4830: 5f 66 69 6c 65 28 26 66 2c 20 67 2e 61 72 67 76  _file(&f, g.argv
4840: 5b 33 5d 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43  [3]);.}../*.** C
4850: 6f 6d 70 72 65 73 73 20 74 68 65 20 63 6f 6e 63  ompress the conc
4860: 61 74 65 6e 61 74 69 6f 6e 20 6f 66 20 61 20 62  atenation of a b
4870: 6c 6f 62 73 20 70 49 6e 31 20 61 6e 64 20 70 49  lobs pIn1 and pI
4880: 6e 32 2e 20 20 53 74 6f 72 65 20 74 68 65 20 72  n2.  Store the r
4890: 65 73 75 6c 74 20 0a 2a 2a 20 69 6e 20 70 4f 75  esult .** in pOu
48a0: 74 2e 20 0a 2a 2a 20 0a 2a 2a 20 70 4f 75 74 20  t. .** .** pOut 
48b0: 6d 75 73 74 20 62 65 20 65 69 74 68 65 72 20 75  must be either u
48c0: 6e 69 6e 69 74 69 61 6c 69 7a 65 64 20 6f 72 20  ninitialized or 
48d0: 6d 75 73 74 20 62 65 20 74 68 65 20 73 61 6d 65  must be the same
48e0: 20 61 73 20 65 69 74 68 65 72 20 70 49 6e 31 20   as either pIn1 
48f0: 6f 72 0a 2a 2a 20 70 49 6e 32 2e 0a 2a 2f 0a 76  or.** pIn2..*/.v
4900: 6f 69 64 20 62 6c 6f 62 5f 63 6f 6d 70 72 65 73  oid blob_compres
4910: 73 32 28 42 6c 6f 62 20 2a 70 49 6e 31 2c 20 42  s2(Blob *pIn1, B
4920: 6c 6f 62 20 2a 70 49 6e 32 2c 20 42 6c 6f 62 20  lob *pIn2, Blob 
4930: 2a 70 4f 75 74 29 7b 0a 20 20 75 6e 73 69 67 6e  *pOut){.  unsign
4940: 65 64 20 69 6e 74 20 6e 49 6e 20 3d 20 62 6c 6f  ed int nIn = blo
4950: 62 5f 73 69 7a 65 28 70 49 6e 31 29 20 2b 20 62  b_size(pIn1) + b
4960: 6c 6f 62 5f 73 69 7a 65 28 70 49 6e 32 29 3b 0a  lob_size(pIn2);.
4970: 20 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e    unsigned int n
4980: 4f 75 74 20 3d 20 31 33 20 2b 20 6e 49 6e 20 2b  Out = 13 + nIn +
4990: 20 28 6e 49 6e 2b 39 39 39 29 2f 31 30 30 30 3b   (nIn+999)/1000;
49a0: 0a 20 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72  .  unsigned char
49b0: 20 2a 6f 75 74 42 75 66 3b 0a 20 20 7a 5f 73 74   *outBuf;.  z_st
49c0: 72 65 61 6d 20 73 74 72 65 61 6d 3b 0a 20 20 42  ream stream;.  B
49d0: 6c 6f 62 20 74 65 6d 70 3b 0a 20 20 62 6c 6f 62  lob temp;.  blob
49e0: 5f 7a 65 72 6f 28 26 74 65 6d 70 29 3b 0a 20 20  _zero(&temp);.  
49f0: 62 6c 6f 62 5f 72 65 73 69 7a 65 28 26 74 65 6d  blob_resize(&tem
4a00: 70 2c 20 6e 4f 75 74 2b 34 29 3b 0a 20 20 6f 75  p, nOut+4);.  ou
4a10: 74 42 75 66 20 3d 20 28 75 6e 73 69 67 6e 65 64  tBuf = (unsigned
4a20: 20 63 68 61 72 2a 29 62 6c 6f 62 5f 62 75 66 66   char*)blob_buff
4a30: 65 72 28 26 74 65 6d 70 29 3b 0a 20 20 6f 75 74  er(&temp);.  out
4a40: 42 75 66 5b 30 5d 20 3d 20 6e 49 6e 3e 3e 32 34  Buf[0] = nIn>>24
4a50: 20 26 20 30 78 66 66 3b 0a 20 20 6f 75 74 42 75   & 0xff;.  outBu
4a60: 66 5b 31 5d 20 3d 20 6e 49 6e 3e 3e 31 36 20 26  f[1] = nIn>>16 &
4a70: 20 30 78 66 66 3b 0a 20 20 6f 75 74 42 75 66 5b   0xff;.  outBuf[
4a80: 32 5d 20 3d 20 6e 49 6e 3e 3e 38 20 26 20 30 78  2] = nIn>>8 & 0x
4a90: 66 66 3b 0a 20 20 6f 75 74 42 75 66 5b 33 5d 20  ff;.  outBuf[3] 
4aa0: 3d 20 6e 49 6e 20 26 20 30 78 66 66 3b 0a 20 20  = nIn & 0xff;.  
4ab0: 73 74 72 65 61 6d 2e 7a 61 6c 6c 6f 63 20 3d 20  stream.zalloc = 
4ac0: 28 61 6c 6c 6f 63 5f 66 75 6e 63 29 30 3b 0a 20  (alloc_func)0;. 
4ad0: 20 73 74 72 65 61 6d 2e 7a 66 72 65 65 20 3d 20   stream.zfree = 
4ae0: 28 66 72 65 65 5f 66 75 6e 63 29 30 3b 0a 20 20  (free_func)0;.  
4af0: 73 74 72 65 61 6d 2e 6f 70 61 71 75 65 20 3d 20  stream.opaque = 
4b00: 30 3b 0a 20 20 73 74 72 65 61 6d 2e 61 76 61 69  0;.  stream.avai
4b10: 6c 5f 6f 75 74 20 3d 20 6e 4f 75 74 3b 0a 20 20  l_out = nOut;.  
4b20: 73 74 72 65 61 6d 2e 6e 65 78 74 5f 6f 75 74 20  stream.next_out 
4b30: 3d 20 26 6f 75 74 42 75 66 5b 34 5d 3b 0a 20 20  = &outBuf[4];.  
4b40: 64 65 66 6c 61 74 65 49 6e 69 74 28 26 73 74 72  deflateInit(&str
4b50: 65 61 6d 2c 20 39 29 3b 0a 20 20 73 74 72 65 61  eam, 9);.  strea
4b60: 6d 2e 61 76 61 69 6c 5f 69 6e 20 3d 20 62 6c 6f  m.avail_in = blo
4b70: 62 5f 73 69 7a 65 28 70 49 6e 31 29 3b 0a 20 20  b_size(pIn1);.  
4b80: 73 74 72 65 61 6d 2e 6e 65 78 74 5f 69 6e 20 3d  stream.next_in =
4b90: 20 28 75 6e 73 69 67 6e 65 64 20 63 68 61 72 2a   (unsigned char*
4ba0: 29 62 6c 6f 62 5f 62 75 66 66 65 72 28 70 49 6e  )blob_buffer(pIn
4bb0: 31 29 3b 0a 20 20 64 65 66 6c 61 74 65 28 26 73  1);.  deflate(&s
4bc0: 74 72 65 61 6d 2c 20 30 29 3b 0a 20 20 73 74 72  tream, 0);.  str
4bd0: 65 61 6d 2e 61 76 61 69 6c 5f 69 6e 20 3d 20 62  eam.avail_in = b
4be0: 6c 6f 62 5f 73 69 7a 65 28 70 49 6e 32 29 3b 0a  lob_size(pIn2);.
4bf0: 20 20 73 74 72 65 61 6d 2e 6e 65 78 74 5f 69 6e    stream.next_in
4c00: 20 3d 20 28 75 6e 73 69 67 6e 65 64 20 63 68 61   = (unsigned cha
4c10: 72 2a 29 62 6c 6f 62 5f 62 75 66 66 65 72 28 70  r*)blob_buffer(p
4c20: 49 6e 32 29 3b 0a 20 20 64 65 66 6c 61 74 65 28  In2);.  deflate(
4c30: 26 73 74 72 65 61 6d 2c 20 30 29 3b 0a 20 20 64  &stream, 0);.  d
4c40: 65 66 6c 61 74 65 28 26 73 74 72 65 61 6d 2c 20  eflate(&stream, 
4c50: 5a 5f 46 49 4e 49 53 48 29 3b 0a 20 20 62 6c 6f  Z_FINISH);.  blo
4c60: 62 5f 72 65 73 69 7a 65 28 26 74 65 6d 70 2c 20  b_resize(&temp, 
4c70: 73 74 72 65 61 6d 2e 74 6f 74 61 6c 5f 6f 75 74  stream.total_out
4c80: 20 2b 20 34 29 3b 0a 20 20 64 65 66 6c 61 74 65   + 4);.  deflate
4c90: 45 6e 64 28 26 73 74 72 65 61 6d 29 3b 0a 20 20  End(&stream);.  
4ca0: 69 66 28 20 70 4f 75 74 3d 3d 70 49 6e 31 20 29  if( pOut==pIn1 )
4cb0: 20 62 6c 6f 62 5f 72 65 73 65 74 28 70 4f 75 74   blob_reset(pOut
4cc0: 29 3b 0a 20 20 69 66 28 20 70 4f 75 74 3d 3d 70  );.  if( pOut==p
4cd0: 49 6e 32 20 29 20 62 6c 6f 62 5f 72 65 73 65 74  In2 ) blob_reset
4ce0: 28 70 4f 75 74 29 3b 0a 20 20 62 6c 6f 62 5f 69  (pOut);.  blob_i
4cf0: 73 5f 72 65 73 65 74 28 70 4f 75 74 29 3b 0a 20  s_reset(pOut);. 
4d00: 20 2a 70 4f 75 74 20 3d 20 74 65 6d 70 3b 0a 7d   *pOut = temp;.}
4d10: 0a 0a 2f 2a 0a 2a 2a 20 43 4f 4d 4d 41 4e 44 3a  ../*.** COMMAND:
4d20: 20 74 65 73 74 2d 63 6f 6d 70 72 65 73 73 2d 32   test-compress-2
4d30: 0a 2a 2f 0a 76 6f 69 64 20 63 6f 6d 70 72 65 73  .*/.void compres
4d40: 73 32 5f 63 6d 64 28 76 6f 69 64 29 7b 0a 20 20  s2_cmd(void){.  
4d50: 42 6c 6f 62 20 66 31 2c 20 66 32 3b 0a 20 20 69  Blob f1, f2;.  i
4d60: 66 28 20 67 2e 61 72 67 63 21 3d 35 20 29 20 75  f( g.argc!=5 ) u
4d70: 73 61 67 65 28 22 49 4e 50 55 54 46 49 4c 45 31  sage("INPUTFILE1
4d80: 20 49 4e 50 55 54 46 49 4c 45 32 20 4f 55 54 50   INPUTFILE2 OUTP
4d90: 55 54 46 49 4c 45 22 29 3b 0a 20 20 62 6c 6f 62  UTFILE");.  blob
4da0: 5f 72 65 61 64 5f 66 72 6f 6d 5f 66 69 6c 65 28  _read_from_file(
4db0: 26 66 31 2c 20 67 2e 61 72 67 76 5b 32 5d 29 3b  &f1, g.argv[2]);
4dc0: 0a 20 20 62 6c 6f 62 5f 72 65 61 64 5f 66 72 6f  .  blob_read_fro
4dd0: 6d 5f 66 69 6c 65 28 26 66 32 2c 20 67 2e 61 72  m_file(&f2, g.ar
4de0: 67 76 5b 33 5d 29 3b 0a 20 20 62 6c 6f 62 5f 63  gv[3]);.  blob_c
4df0: 6f 6d 70 72 65 73 73 32 28 26 66 31 2c 20 26 66  ompress2(&f1, &f
4e00: 32 2c 20 26 66 31 29 3b 0a 20 20 62 6c 6f 62 5f  2, &f1);.  blob_
4e10: 77 72 69 74 65 5f 74 6f 5f 66 69 6c 65 28 26 66  write_to_file(&f
4e20: 31 2c 20 67 2e 61 72 67 76 5b 34 5d 29 3b 0a 7d  1, g.argv[4]);.}
4e30: 0a 0a 2f 2a 0a 2a 2a 20 55 6e 63 6f 6d 70 72 65  ../*.** Uncompre
4e40: 73 73 20 62 6c 6f 62 20 70 49 6e 20 61 6e 64 20  ss blob pIn and 
4e50: 73 74 6f 72 65 20 74 68 65 20 72 65 73 75 6c 74  store the result
4e60: 20 69 6e 20 70 4f 75 74 2e 20 20 49 74 20 69 73   in pOut.  It is
4e70: 20 6f 6b 20 66 6f 72 20 70 49 6e 20 61 6e 64 0a   ok for pIn and.
4e80: 2a 2a 20 70 4f 75 74 20 74 6f 20 62 65 20 74 68  ** pOut to be th
4e90: 65 20 73 61 6d 65 20 62 6c 6f 62 2e 0a 2a 2a 0a  e same blob..**.
4ea0: 2a 2a 20 70 4f 75 74 20 6d 75 73 74 20 62 65 20  ** pOut must be 
4eb0: 65 69 74 68 65 72 20 75 6e 69 6e 69 74 69 61 6c  either uninitial
4ec0: 69 7a 65 64 20 6f 72 20 74 68 65 20 73 61 6d 65  ized or the same
4ed0: 20 61 73 20 70 49 6e 2e 0a 2a 2f 0a 69 6e 74 20   as pIn..*/.int 
4ee0: 62 6c 6f 62 5f 75 6e 63 6f 6d 70 72 65 73 73 28  blob_uncompress(
4ef0: 42 6c 6f 62 20 2a 70 49 6e 2c 20 42 6c 6f 62 20  Blob *pIn, Blob 
4f00: 2a 70 4f 75 74 29 7b 0a 20 20 75 6e 73 69 67 6e  *pOut){.  unsign
4f10: 65 64 20 69 6e 74 20 6e 4f 75 74 3b 0a 20 20 75  ed int nOut;.  u
4f20: 6e 73 69 67 6e 65 64 20 63 68 61 72 20 2a 69 6e  nsigned char *in
4f30: 42 75 66 3b 0a 20 20 75 6e 73 69 67 6e 65 64 20  Buf;.  unsigned 
4f40: 69 6e 74 20 6e 49 6e 20 3d 20 62 6c 6f 62 5f 73  int nIn = blob_s
4f50: 69 7a 65 28 70 49 6e 29 3b 0a 20 20 42 6c 6f 62  ize(pIn);.  Blob
4f60: 20 74 65 6d 70 3b 0a 20 20 69 6e 74 20 72 63 3b   temp;.  int rc;
4f70: 0a 20 20 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67  .  unsigned long
4f80: 20 69 6e 74 20 6e 4f 75 74 32 3b 0a 20 20 69 66   int nOut2;.  if
4f90: 28 20 6e 49 6e 3c 3d 34 20 29 7b 0a 20 20 20 20  ( nIn<=4 ){.    
4fa0: 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 20 20  return 0;.  }.  
4fb0: 69 6e 42 75 66 20 3d 20 28 75 6e 73 69 67 6e 65  inBuf = (unsigne
4fc0: 64 20 63 68 61 72 2a 29 62 6c 6f 62 5f 62 75 66  d char*)blob_buf
4fd0: 66 65 72 28 70 49 6e 29 3b 0a 20 20 6e 4f 75 74  fer(pIn);.  nOut
4fe0: 20 3d 20 28 69 6e 42 75 66 5b 30 5d 3c 3c 32 34   = (inBuf[0]<<24
4ff0: 29 20 2b 20 28 69 6e 42 75 66 5b 31 5d 3c 3c 31  ) + (inBuf[1]<<1
5000: 36 29 20 2b 20 28 69 6e 42 75 66 5b 32 5d 3c 3c  6) + (inBuf[2]<<
5010: 38 29 20 2b 20 69 6e 42 75 66 5b 33 5d 3b 0a 20  8) + inBuf[3];. 
5020: 20 62 6c 6f 62 5f 7a 65 72 6f 28 26 74 65 6d 70   blob_zero(&temp
5030: 29 3b 0a 20 20 62 6c 6f 62 5f 72 65 73 69 7a 65  );.  blob_resize
5040: 28 26 74 65 6d 70 2c 20 6e 4f 75 74 2b 31 29 3b  (&temp, nOut+1);
5050: 0a 20 20 6e 4f 75 74 32 20 3d 20 28 6c 6f 6e 67  .  nOut2 = (long
5060: 20 69 6e 74 29 6e 4f 75 74 3b 0a 20 20 72 63 20   int)nOut;.  rc 
5070: 3d 20 75 6e 63 6f 6d 70 72 65 73 73 28 28 75 6e  = uncompress((un
5080: 73 69 67 6e 65 64 20 63 68 61 72 2a 29 62 6c 6f  signed char*)blo
5090: 62 5f 62 75 66 66 65 72 28 26 74 65 6d 70 29 2c  b_buffer(&temp),
50a0: 20 26 6e 4f 75 74 32 2c 20 0a 20 20 20 20 20 20   &nOut2, .      
50b0: 20 20 20 20 20 20 20 20 20 20 20 20 26 69 6e 42              &inB
50c0: 75 66 5b 34 5d 2c 20 62 6c 6f 62 5f 73 69 7a 65  uf[4], blob_size
50d0: 28 70 49 6e 29 29 3b 0a 20 20 69 66 28 20 72 63  (pIn));.  if( rc
50e0: 21 3d 5a 5f 4f 4b 20 29 7b 0a 20 20 20 20 62 6c  !=Z_OK ){.    bl
50f0: 6f 62 5f 72 65 73 65 74 28 26 74 65 6d 70 29 3b  ob_reset(&temp);
5100: 0a 20 20 20 20 72 65 74 75 72 6e 20 31 3b 0a 20  .    return 1;. 
5110: 20 7d 0a 20 20 62 6c 6f 62 5f 72 65 73 69 7a 65   }.  blob_resize
5120: 28 26 74 65 6d 70 2c 20 6e 4f 75 74 32 29 3b 0a  (&temp, nOut2);.
5130: 20 20 69 66 28 20 70 4f 75 74 3d 3d 70 49 6e 20    if( pOut==pIn 
5140: 29 20 62 6c 6f 62 5f 72 65 73 65 74 28 70 4f 75  ) blob_reset(pOu
5150: 74 29 3b 0a 20 20 62 6c 6f 62 5f 69 73 5f 72 65  t);.  blob_is_re
5160: 73 65 74 28 70 4f 75 74 29 3b 0a 20 20 2a 70 4f  set(pOut);.  *pO
5170: 75 74 20 3d 20 74 65 6d 70 3b 0a 20 20 72 65 74  ut = temp;.  ret
5180: 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  urn 0;.}../*.** 
5190: 43 4f 4d 4d 41 4e 44 3a 20 74 65 73 74 2d 75 6e  COMMAND: test-un
51a0: 63 6f 6d 70 72 65 73 73 0a 2a 2f 0a 76 6f 69 64  compress.*/.void
51b0: 20 75 6e 63 6f 6d 70 72 65 73 73 5f 63 6d 64 28   uncompress_cmd(
51c0: 76 6f 69 64 29 7b 0a 20 20 42 6c 6f 62 20 66 3b  void){.  Blob f;
51d0: 0a 20 20 69 66 28 20 67 2e 61 72 67 63 21 3d 34  .  if( g.argc!=4
51e0: 20 29 20 75 73 61 67 65 28 22 49 4e 50 55 54 46   ) usage("INPUTF
51f0: 49 4c 45 20 4f 55 54 50 55 54 46 49 4c 45 22 29  ILE OUTPUTFILE")
5200: 3b 0a 20 20 62 6c 6f 62 5f 72 65 61 64 5f 66 72  ;.  blob_read_fr
5210: 6f 6d 5f 66 69 6c 65 28 26 66 2c 20 67 2e 61 72  om_file(&f, g.ar
5220: 67 76 5b 32 5d 29 3b 0a 20 20 62 6c 6f 62 5f 75  gv[2]);.  blob_u
5230: 6e 63 6f 6d 70 72 65 73 73 28 26 66 2c 20 26 66  ncompress(&f, &f
5240: 29 3b 0a 20 20 62 6c 6f 62 5f 77 72 69 74 65 5f  );.  blob_write_
5250: 74 6f 5f 66 69 6c 65 28 26 66 2c 20 67 2e 61 72  to_file(&f, g.ar
5260: 67 76 5b 33 5d 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  gv[3]);.}../*.**
5270: 20 43 4f 4d 4d 41 4e 44 3a 20 74 65 73 74 2d 63   COMMAND: test-c
5280: 79 63 6c 65 2d 63 6f 6d 70 72 65 73 73 0a 2a 2a  ycle-compress.**
5290: 0a 2a 2a 20 43 6f 6d 70 72 65 73 73 20 61 6e 64  .** Compress and
52a0: 20 75 6e 63 6f 6d 70 72 65 73 73 20 65 61 63 68   uncompress each
52b0: 20 66 69 6c 65 20 6e 61 6d 65 64 20 6f 6e 20 74   file named on t
52c0: 68 65 20 63 6f 6d 6d 61 6e 64 20 6c 69 6e 65 2e  he command line.
52d0: 0a 2a 2a 20 56 65 72 69 66 79 20 74 68 61 74 20  .** Verify that 
52e0: 74 68 65 20 6f 72 69 67 69 6e 61 6c 20 63 6f 6e  the original con
52f0: 74 65 6e 74 20 69 73 20 72 65 63 6f 76 65 72 65  tent is recovere
5300: 64 2e 0a 2a 2f 0a 76 6f 69 64 20 74 65 73 74 5f  d..*/.void test_
5310: 63 79 63 6c 65 5f 63 6f 6d 70 72 65 73 73 28 76  cycle_compress(v
5320: 6f 69 64 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20  oid){.  int i;. 
5330: 20 42 6c 6f 62 20 62 31 2c 20 62 32 2c 20 62 33   Blob b1, b2, b3
5340: 3b 0a 20 20 66 6f 72 28 69 3d 32 3b 20 69 3c 67  ;.  for(i=2; i<g
5350: 2e 61 72 67 63 3b 20 69 2b 2b 29 7b 0a 20 20 20  .argc; i++){.   
5360: 20 62 6c 6f 62 5f 72 65 61 64 5f 66 72 6f 6d 5f   blob_read_from_
5370: 66 69 6c 65 28 26 62 31 2c 20 67 2e 61 72 67 76  file(&b1, g.argv
5380: 5b 69 5d 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 63  [i]);.    blob_c
5390: 6f 6d 70 72 65 73 73 28 26 62 31 2c 20 26 62 32  ompress(&b1, &b2
53a0: 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 75 6e 63 6f  );.    blob_unco
53b0: 6d 70 72 65 73 73 28 26 62 32 2c 20 26 62 33 29  mpress(&b2, &b3)
53c0: 3b 0a 20 20 20 20 69 66 28 20 62 6c 6f 62 5f 63  ;.    if( blob_c
53d0: 6f 6d 70 61 72 65 28 26 62 31 2c 20 26 62 33 29  ompare(&b1, &b3)
53e0: 20 29 7b 0a 20 20 20 20 20 20 66 6f 73 73 69 6c   ){.      fossil
53f0: 5f 70 61 6e 69 63 28 22 63 6f 6d 70 72 65 73 73  _panic("compress
5400: 2f 75 6e 63 6f 6d 70 72 65 73 73 20 63 79 63 6c  /uncompress cycl
5410: 65 20 66 61 69 6c 65 64 20 66 6f 72 20 25 73 22  e failed for %s"
5420: 2c 20 67 2e 61 72 67 76 5b 69 5d 29 3b 0a 20 20  , g.argv[i]);.  
5430: 20 20 7d 0a 20 20 20 20 62 6c 6f 62 5f 72 65 73    }.    blob_res
5440: 65 74 28 26 62 31 29 3b 0a 20 20 20 20 62 6c 6f  et(&b1);.    blo
5450: 62 5f 72 65 73 65 74 28 26 62 32 29 3b 0a 20 20  b_reset(&b2);.  
5460: 20 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 62 33    blob_reset(&b3
5470: 29 3b 0a 20 20 7d 0a 20 20 70 72 69 6e 74 66 28  );.  }.  printf(
5480: 22 6f 6b 5c 6e 22 29 3b 0a 7d 0a 0a 23 69 66 64  "ok\n");.}..#ifd
5490: 65 66 20 5f 5f 4d 49 4e 47 57 33 32 5f 5f 0a 2f  ef __MINGW32__./
54a0: 2a 0a 2a 2a 20 43 6f 6e 76 65 72 74 20 65 76 65  *.** Convert eve
54b0: 72 79 20 5c 6e 20 63 68 61 72 61 63 74 65 72 20  ry \n character 
54c0: 69 6e 20 74 68 65 20 67 69 76 65 6e 20 62 6c 6f  in the given blo
54d0: 62 20 69 6e 74 6f 20 5c 72 5c 6e 2e 0a 2a 2f 0a  b into \r\n..*/.
54e0: 76 6f 69 64 20 62 6c 6f 62 5f 61 64 64 5f 63 72  void blob_add_cr
54f0: 28 42 6c 6f 62 20 2a 70 29 7b 0a 20 20 63 68 61  (Blob *p){.  cha
5500: 72 20 2a 7a 20 3d 20 70 2d 3e 61 44 61 74 61 3b  r *z = p->aData;
5510: 0a 20 20 69 6e 74 20 6a 20 20 20 3d 20 70 2d 3e  .  int j   = p->
5520: 6e 55 73 65 64 3b 0a 20 20 69 6e 74 20 69 2c 20  nUsed;.  int i, 
5530: 6e 3b 0a 20 20 66 6f 72 28 69 3d 6e 3d 30 3b 20  n;.  for(i=n=0; 
5540: 69 3c 6a 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69  i<j; i++){.    i
5550: 66 28 20 7a 5b 69 5d 3d 3d 27 5c 6e 27 20 29 20  f( z[i]=='\n' ) 
5560: 6e 2b 2b 3b 0a 20 20 7d 0a 20 20 6a 20 2b 3d 20  n++;.  }.  j += 
5570: 6e 3b 0a 20 20 69 66 28 20 6a 3e 3d 70 2d 3e 6e  n;.  if( j>=p->n
5580: 41 6c 6c 6f 63 20 29 7b 0a 20 20 20 20 62 6c 6f  Alloc ){.    blo
5590: 62 5f 72 65 73 69 7a 65 28 70 2c 20 6a 29 3b 0a  b_resize(p, j);.
55a0: 20 20 20 20 7a 20 3d 20 70 2d 3e 61 44 61 74 61      z = p->aData
55b0: 3b 0a 20 20 7d 0a 20 20 70 2d 3e 6e 55 73 65 64  ;.  }.  p->nUsed
55c0: 20 3d 20 6a 3b 0a 20 20 7a 5b 6a 5d 20 3d 20 30   = j;.  z[j] = 0
55d0: 3b 0a 20 20 77 68 69 6c 65 28 20 6a 3e 69 20 29  ;.  while( j>i )
55e0: 7b 0a 20 20 20 20 69 66 28 20 28 7a 5b 2d 2d 6a  {.    if( (z[--j
55f0: 5d 20 3d 20 7a 5b 2d 2d 69 5d 29 20 3d 3d 27 5c  ] = z[--i]) =='\
5600: 6e 27 20 29 7b 0a 20 20 20 20 20 20 7a 5b 2d 2d  n' ){.      z[--
5610: 6a 5d 20 3d 20 27 5c 72 27 3b 0a 20 20 20 20 7d  j] = '\r';.    }
5620: 0a 20 20 7d 0a 7d 0a 23 65 6e 64 69 66 0a 0a 2f  .  }.}.#endif../
5630: 2a 0a 2a 2a 20 52 65 6d 6f 76 65 20 65 76 65 72  *.** Remove ever
5640: 79 20 5c 72 20 63 68 61 72 61 63 74 65 72 20 66  y \r character f
5650: 72 6f 6d 20 74 68 65 20 67 69 76 65 6e 20 62 6c  rom the given bl
5660: 6f 62 2e 0a 2a 2f 0a 76 6f 69 64 20 62 6c 6f 62  ob..*/.void blob
5670: 5f 72 65 6d 6f 76 65 5f 63 72 28 42 6c 6f 62 20  _remove_cr(Blob 
5680: 2a 70 29 7b 0a 20 20 69 6e 74 20 69 2c 20 6a 3b  *p){.  int i, j;
5690: 0a 20 20 63 68 61 72 20 2a 7a 3b 0a 20 20 62 6c  .  char *z;.  bl
56a0: 6f 62 5f 6d 61 74 65 72 69 61 6c 69 7a 65 28 70  ob_materialize(p
56b0: 29 3b 0a 20 20 7a 20 3d 20 70 2d 3e 61 44 61 74  );.  z = p->aDat
56c0: 61 3b 0a 20 20 66 6f 72 28 69 3d 6a 3d 30 3b 20  a;.  for(i=j=0; 
56d0: 7a 5b 69 5d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  z[i]; i++){.    
56e0: 69 66 28 20 7a 5b 69 5d 21 3d 27 5c 72 27 20 29  if( z[i]!='\r' )
56f0: 20 7a 5b 6a 2b 2b 5d 20 3d 20 7a 5b 69 5d 3b 0a   z[j++] = z[i];.
5700: 20 20 7d 0a 20 20 7a 5b 6a 5d 20 3d 20 30 3b 0a    }.  z[j] = 0;.
5710: 20 20 70 2d 3e 6e 55 73 65 64 20 3d 20 6a 3b 0a    p->nUsed = j;.
5720: 7d 0a                                            }.