Hex Artifact Content
Not logged in

Artifact 1da99958db39fb320b6d97191f357bf3ab151ecc:

File src/blob.c part of check-in [36b96b8616] - Rework the merge algorithm. It now only works for text files. But, it no longer gets confused by line endings (\r\n versus \n) and it reports conflicts. by drh on 2007-11-16 20:42:31.

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 54 68 69 73 20  dif../*.** This 
0890: 72 6f 75 74 69 6e 65 20 69 73 20 63 61 6c 6c 65  routine is calle
08a0: 64 20 69 66 20 61 20 62 6c 6f 62 20 6f 70 65 72  d if a blob oper
08b0: 61 74 69 6f 6e 20 66 61 69 6c 73 20 62 65 63 61  ation fails beca
08c0: 75 73 65 20 77 65 0a 2a 2a 20 68 61 76 65 20 72  use we.** have r
08d0: 75 6e 20 6f 75 74 20 6f 66 20 6d 65 6d 6f 72 79  un out of memory
08e0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  ..*/.static void
08f0: 20 62 6c 6f 62 5f 70 61 6e 69 63 28 76 6f 69 64   blob_panic(void
0900: 29 7b 0a 20 20 73 74 61 74 69 63 20 63 6f 6e 73  ){.  static cons
0910: 74 20 63 68 61 72 20 7a 45 72 72 4d 73 67 5b 5d  t char zErrMsg[]
0920: 20 3d 20 22 6f 75 74 20 6f 66 20 6d 65 6d 6f 72   = "out of memor
0930: 79 5c 6e 22 3b 0a 20 20 77 72 69 74 65 28 32 2c  y\n";.  write(2,
0940: 20 7a 45 72 72 4d 73 67 2c 20 73 69 7a 65 6f 66   zErrMsg, sizeof
0950: 28 7a 45 72 72 4d 73 67 29 2d 31 29 3b 0a 20 20  (zErrMsg)-1);.  
0960: 65 78 69 74 28 31 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  exit(1);.}../*.*
0970: 2a 20 41 20 72 65 61 6c 6c 6f 63 61 74 69 6f 6e  * A reallocation
0980: 20 66 75 6e 63 74 69 6f 6e 20 74 68 61 74 20 61   function that a
0990: 73 73 75 6d 65 73 20 74 68 61 74 20 61 44 61 74  ssumes that aDat
09a0: 61 20 63 61 6d 65 20 66 72 6f 6d 20 6d 61 6c 6c  a came from mall
09b0: 6f 63 28 29 2e 0a 2a 2a 20 54 68 69 73 20 66 75  oc()..** This fu
09c0: 6e 63 74 69 6f 6e 20 61 74 74 65 6d 70 74 73 20  nction attempts 
09d0: 74 6f 20 72 65 73 69 7a 65 20 74 68 65 20 62 75  to resize the bu
09e0: 66 66 65 72 20 6f 66 20 74 68 65 20 62 6c 6f 62  ffer of the blob
09f0: 20 74 6f 20 68 6f 6c 64 0a 2a 2a 20 6e 65 77 53   to hold.** newS
0a00: 69 7a 65 20 62 79 74 65 73 2e 20 20 0a 2a 2a 0a  ize bytes.  .**.
0a10: 2a 2a 20 4e 6f 20 61 74 74 65 6d 70 74 20 69 73  ** No attempt is
0a20: 20 6d 61 64 65 20 74 6f 20 72 65 63 6f 76 65 72   made to recover
0a30: 20 66 72 6f 6d 20 61 6e 20 6f 75 74 2d 6f 66 2d   from an out-of-
0a40: 6d 65 6d 6f 72 79 20 65 72 72 6f 72 2e 0a 2a 2a  memory error..**
0a50: 20 49 66 20 61 6e 20 4f 4f 4d 20 65 72 72 6f 72   If an OOM error
0a60: 20 6f 63 63 75 72 73 2c 20 61 6e 20 65 72 72 6f   occurs, an erro
0a70: 72 20 6d 65 73 73 61 67 65 20 69 73 20 70 72 69  r message is pri
0a80: 6e 74 65 64 20 6f 6e 20 73 74 64 65 72 72 0a 2a  nted on stderr.*
0a90: 2a 20 61 6e 64 20 74 68 65 20 70 72 6f 67 72 61  * and the progra
0aa0: 6d 20 65 78 69 74 73 2e 0a 2a 2f 0a 76 6f 69 64  m exits..*/.void
0ab0: 20 62 6c 6f 62 52 65 61 6c 6c 6f 63 4d 61 6c 6c   blobReallocMall
0ac0: 6f 63 28 42 6c 6f 62 20 2a 70 42 6c 6f 62 2c 20  oc(Blob *pBlob, 
0ad0: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 65 77  unsigned int new
0ae0: 53 69 7a 65 29 7b 0a 20 20 69 66 28 20 6e 65 77  Size){.  if( new
0af0: 53 69 7a 65 3d 3d 30 20 29 7b 0a 20 20 20 20 66  Size==0 ){.    f
0b00: 72 65 65 28 70 42 6c 6f 62 2d 3e 61 44 61 74 61  ree(pBlob->aData
0b10: 29 3b 0a 20 20 20 20 70 42 6c 6f 62 2d 3e 61 44  );.    pBlob->aD
0b20: 61 74 61 20 3d 20 30 3b 0a 20 20 20 20 70 42 6c  ata = 0;.    pBl
0b30: 6f 62 2d 3e 6e 41 6c 6c 6f 63 20 3d 20 30 3b 0a  ob->nAlloc = 0;.
0b40: 20 20 20 20 70 42 6c 6f 62 2d 3e 6e 55 73 65 64      pBlob->nUsed
0b50: 20 3d 20 30 3b 0a 20 20 20 20 70 42 6c 6f 62 2d   = 0;.    pBlob-
0b60: 3e 69 43 75 72 73 6f 72 20 3d 20 30 3b 0a 20 20  >iCursor = 0;.  
0b70: 7d 65 6c 73 65 20 69 66 28 20 6e 65 77 53 69 7a  }else if( newSiz
0b80: 65 3e 70 42 6c 6f 62 2d 3e 6e 41 6c 6c 6f 63 20  e>pBlob->nAlloc 
0b90: 7c 7c 20 6e 65 77 53 69 7a 65 3c 70 42 6c 6f 62  || newSize<pBlob
0ba0: 2d 3e 6e 41 6c 6c 6f 63 2d 34 30 30 30 20 29 7b  ->nAlloc-4000 ){
0bb0: 0a 20 20 20 20 63 68 61 72 20 2a 70 4e 65 77 20  .    char *pNew 
0bc0: 3d 20 72 65 61 6c 6c 6f 63 28 70 42 6c 6f 62 2d  = realloc(pBlob-
0bd0: 3e 61 44 61 74 61 2c 20 6e 65 77 53 69 7a 65 29  >aData, newSize)
0be0: 3b 0a 20 20 20 20 69 66 28 20 70 4e 65 77 3d 3d  ;.    if( pNew==
0bf0: 30 20 29 20 62 6c 6f 62 5f 70 61 6e 69 63 28 29  0 ) blob_panic()
0c00: 3b 0a 20 20 20 20 70 42 6c 6f 62 2d 3e 61 44 61  ;.    pBlob->aDa
0c10: 74 61 20 3d 20 70 4e 65 77 3b 0a 20 20 20 20 70  ta = pNew;.    p
0c20: 42 6c 6f 62 2d 3e 6e 41 6c 6c 6f 63 20 3d 20 6e  Blob->nAlloc = n
0c30: 65 77 53 69 7a 65 3b 0a 20 20 20 20 69 66 28 20  ewSize;.    if( 
0c40: 70 42 6c 6f 62 2d 3e 6e 55 73 65 64 3e 70 42 6c  pBlob->nUsed>pBl
0c50: 6f 62 2d 3e 6e 41 6c 6c 6f 63 20 29 7b 0a 20 20  ob->nAlloc ){.  
0c60: 20 20 20 20 70 42 6c 6f 62 2d 3e 6e 55 73 65 64      pBlob->nUsed
0c70: 20 3d 20 70 42 6c 6f 62 2d 3e 6e 41 6c 6c 6f 63   = pBlob->nAlloc
0c80: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f  ;.    }.  }.}../
0c90: 2a 0a 2a 2a 20 41 6e 20 69 6e 69 74 69 61 6c 69  *.** An initiali
0ca0: 7a 65 72 20 66 6f 72 20 42 6c 6f 62 73 0a 2a 2f  zer for Blobs.*/
0cb0: 0a 23 69 66 20 49 4e 54 45 52 46 41 43 45 0a 23  .#if INTERFACE.#
0cc0: 64 65 66 69 6e 65 20 42 4c 4f 42 5f 49 4e 49 54  define BLOB_INIT
0cd0: 49 41 4c 49 5a 45 52 20 20 7b 30 2c 30 2c 30 2c  IALIZER  {0,0,0,
0ce0: 30 2c 62 6c 6f 62 52 65 61 6c 6c 6f 63 4d 61 6c  0,blobReallocMal
0cf0: 6c 6f 63 7d 0a 23 65 6e 64 69 66 0a 63 6f 6e 73  loc}.#endif.cons
0d00: 74 20 42 6c 6f 62 20 65 6d 70 74 79 5f 62 6c 6f  t Blob empty_blo
0d10: 62 20 3d 20 42 4c 4f 42 5f 49 4e 49 54 49 41 4c  b = BLOB_INITIAL
0d20: 49 5a 45 52 3b 0a 0a 2f 2a 0a 2a 2a 20 41 20 72  IZER;../*.** A r
0d30: 65 61 6c 6c 6f 63 61 74 69 6f 6e 20 66 75 6e 63  eallocation func
0d40: 74 69 6f 6e 20 66 6f 72 20 77 68 65 6e 20 74 68  tion for when th
0d50: 65 20 69 6e 69 74 69 61 6c 20 73 74 72 69 6e 67  e initial string
0d60: 20 69 73 20 69 6e 20 75 6e 6d 61 6e 61 67 65 64   is in unmanaged
0d70: 0a 2a 2a 20 73 70 61 63 65 2e 20 20 43 6f 70 79  .** space.  Copy
0d80: 20 74 68 65 20 73 74 72 69 6e 67 20 74 6f 20 6d   the string to m
0d90: 65 6d 6f 72 79 20 6f 62 74 61 69 6e 65 64 20 66  emory obtained f
0da0: 72 6f 6d 20 6d 61 6c 6c 6f 63 28 29 2e 0a 2a 2f  rom malloc()..*/
0db0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 62 6c 6f  .static void blo
0dc0: 62 52 65 61 6c 6c 6f 63 53 74 61 74 69 63 28 42  bReallocStatic(B
0dd0: 6c 6f 62 20 2a 70 42 6c 6f 62 2c 20 75 6e 73 69  lob *pBlob, unsi
0de0: 67 6e 65 64 20 69 6e 74 20 6e 65 77 53 69 7a 65  gned int newSize
0df0: 29 7b 0a 20 20 69 66 28 20 6e 65 77 53 69 7a 65  ){.  if( newSize
0e00: 3d 3d 30 20 29 7b 0a 20 20 20 20 2a 70 42 6c 6f  ==0 ){.    *pBlo
0e10: 62 20 3d 20 65 6d 70 74 79 5f 62 6c 6f 62 3b 0a  b = empty_blob;.
0e20: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 63 68 61    }else{.    cha
0e30: 72 20 2a 70 4e 65 77 20 3d 20 6d 61 6c 6c 6f 63  r *pNew = malloc
0e40: 28 20 6e 65 77 53 69 7a 65 20 29 3b 0a 20 20 20  ( newSize );.   
0e50: 20 69 66 28 20 70 4e 65 77 3d 3d 30 20 29 20 62   if( pNew==0 ) b
0e60: 6c 6f 62 5f 70 61 6e 69 63 28 29 3b 0a 20 20 20  lob_panic();.   
0e70: 20 69 66 28 20 70 42 6c 6f 62 2d 3e 6e 55 73 65   if( pBlob->nUse
0e80: 64 3e 6e 65 77 53 69 7a 65 20 29 20 70 42 6c 6f  d>newSize ) pBlo
0e90: 62 2d 3e 6e 55 73 65 64 20 3d 20 6e 65 77 53 69  b->nUsed = newSi
0ea0: 7a 65 3b 0a 20 20 20 20 6d 65 6d 63 70 79 28 70  ze;.    memcpy(p
0eb0: 4e 65 77 2c 20 70 42 6c 6f 62 2d 3e 61 44 61 74  New, pBlob->aDat
0ec0: 61 2c 20 70 42 6c 6f 62 2d 3e 6e 55 73 65 64 29  a, pBlob->nUsed)
0ed0: 3b 0a 20 20 20 20 70 42 6c 6f 62 2d 3e 61 44 61  ;.    pBlob->aDa
0ee0: 74 61 20 3d 20 70 4e 65 77 3b 0a 20 20 20 20 70  ta = pNew;.    p
0ef0: 42 6c 6f 62 2d 3e 78 52 65 61 6c 6c 6f 63 20 3d  Blob->xRealloc =
0f00: 20 62 6c 6f 62 52 65 61 6c 6c 6f 63 4d 61 6c 6c   blobReallocMall
0f10: 6f 63 3b 0a 20 20 20 20 70 42 6c 6f 62 2d 3e 6e  oc;.    pBlob->n
0f20: 41 6c 6c 6f 63 20 3d 20 6e 65 77 53 69 7a 65 3b  Alloc = newSize;
0f30: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65  .  }.}../*.** Re
0f40: 73 65 74 20 61 20 62 6c 6f 62 20 74 6f 20 62 65  set a blob to be
0f50: 20 61 6e 20 65 6d 70 74 79 20 63 6f 6e 74 61 69   an empty contai
0f60: 6e 65 72 2e 0a 2a 2f 0a 76 6f 69 64 20 62 6c 6f  ner..*/.void blo
0f70: 62 5f 72 65 73 65 74 28 42 6c 6f 62 20 2a 70 42  b_reset(Blob *pB
0f80: 6c 6f 62 29 7b 0a 20 20 62 6c 6f 62 5f 69 73 5f  lob){.  blob_is_
0f90: 69 6e 69 74 28 70 42 6c 6f 62 29 3b 0a 20 20 70  init(pBlob);.  p
0fa0: 42 6c 6f 62 2d 3e 78 52 65 61 6c 6c 6f 63 28 70  Blob->xRealloc(p
0fb0: 42 6c 6f 62 2c 20 30 29 3b 0a 7d 0a 0a 2f 2a 0a  Blob, 0);.}../*.
0fc0: 2a 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 61 20  ** Initialize a 
0fd0: 62 6c 6f 62 20 74 6f 20 61 20 73 74 72 69 6e 67  blob to a string
0fe0: 20 6f 72 20 62 79 74 65 2d 61 72 72 61 79 20 63   or byte-array c
0ff0: 6f 6e 73 74 61 6e 74 20 6f 66 20 61 20 73 70 65  onstant of a spe
1000: 63 69 66 69 65 64 20 6c 65 6e 67 74 68 2e 0a 2a  cified length..*
1010: 2a 20 41 6e 79 20 70 72 69 6f 72 20 64 61 74 61  * Any prior data
1020: 20 69 6e 20 74 68 65 20 62 6c 6f 62 20 69 73 20   in the blob is 
1030: 64 69 73 63 61 72 64 65 64 2e 0a 2a 2f 0a 76 6f  discarded..*/.vo
1040: 69 64 20 62 6c 6f 62 5f 69 6e 69 74 28 42 6c 6f  id blob_init(Blo
1050: 62 20 2a 70 42 6c 6f 62 2c 20 63 6f 6e 73 74 20  b *pBlob, const 
1060: 63 68 61 72 20 2a 7a 44 61 74 61 2c 20 69 6e 74  char *zData, int
1070: 20 73 69 7a 65 29 7b 0a 20 20 62 6c 6f 62 5f 69   size){.  blob_i
1080: 73 5f 72 65 73 65 74 28 70 42 6c 6f 62 29 3b 0a  s_reset(pBlob);.
1090: 20 20 69 66 28 20 7a 44 61 74 61 3d 3d 30 20 29    if( zData==0 )
10a0: 7b 0a 20 20 20 20 2a 70 42 6c 6f 62 20 3d 20 65  {.    *pBlob = e
10b0: 6d 70 74 79 5f 62 6c 6f 62 3b 0a 20 20 7d 65 6c  mpty_blob;.  }el
10c0: 73 65 7b 0a 20 20 20 20 69 66 28 20 73 69 7a 65  se{.    if( size
10d0: 3c 3d 30 20 29 20 73 69 7a 65 20 3d 20 73 74 72  <=0 ) size = str
10e0: 6c 65 6e 28 7a 44 61 74 61 29 3b 0a 20 20 20 20  len(zData);.    
10f0: 70 42 6c 6f 62 2d 3e 6e 55 73 65 64 20 3d 20 70  pBlob->nUsed = p
1100: 42 6c 6f 62 2d 3e 6e 41 6c 6c 6f 63 20 3d 20 73  Blob->nAlloc = s
1110: 69 7a 65 3b 0a 20 20 20 20 70 42 6c 6f 62 2d 3e  ize;.    pBlob->
1120: 61 44 61 74 61 20 3d 20 28 63 68 61 72 2a 29 7a  aData = (char*)z
1130: 44 61 74 61 3b 0a 20 20 20 20 70 42 6c 6f 62 2d  Data;.    pBlob-
1140: 3e 69 43 75 72 73 6f 72 20 3d 20 30 3b 0a 20 20  >iCursor = 0;.  
1150: 20 20 70 42 6c 6f 62 2d 3e 78 52 65 61 6c 6c 6f    pBlob->xReallo
1160: 63 20 3d 20 62 6c 6f 62 52 65 61 6c 6c 6f 63 53  c = blobReallocS
1170: 74 61 74 69 63 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a  tatic;.  }.}../*
1180: 0a 2a 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 61  .** Initialize a
1190: 20 62 6c 6f 62 20 74 6f 20 61 20 6e 75 6c 2d 74   blob to a nul-t
11a0: 65 72 6d 69 6e 61 74 65 64 20 73 74 72 69 6e 67  erminated string
11b0: 2e 0a 2a 2a 20 41 6e 79 20 70 72 69 6f 72 20 64  ..** Any prior d
11c0: 61 74 61 20 69 6e 20 74 68 65 20 62 6c 6f 62 20  ata in the blob 
11d0: 69 73 20 64 69 73 63 61 72 64 65 64 2e 0a 2a 2f  is discarded..*/
11e0: 0a 76 6f 69 64 20 62 6c 6f 62 5f 73 65 74 28 42  .void blob_set(B
11f0: 6c 6f 62 20 2a 70 42 6c 6f 62 2c 20 63 6f 6e 73  lob *pBlob, cons
1200: 74 20 63 68 61 72 20 2a 7a 53 74 72 29 7b 0a 20  t char *zStr){. 
1210: 20 62 6c 6f 62 5f 69 6e 69 74 28 70 42 6c 6f 62   blob_init(pBlob
1220: 2c 20 7a 53 74 72 2c 20 2d 31 29 3b 0a 7d 0a 0a  , zStr, -1);.}..
1230: 2f 2a 0a 2a 2a 20 49 6e 69 74 69 61 6c 69 7a 65  /*.** Initialize
1240: 20 61 20 62 6c 6f 62 20 74 6f 20 61 6e 20 65 6d   a blob to an em
1250: 70 74 79 20 73 74 72 69 6e 67 2e 0a 2a 2f 0a 76  pty string..*/.v
1260: 6f 69 64 20 62 6c 6f 62 5f 7a 65 72 6f 28 42 6c  oid blob_zero(Bl
1270: 6f 62 20 2a 70 42 6c 6f 62 29 7b 0a 20 20 73 74  ob *pBlob){.  st
1280: 61 74 69 63 20 63 6f 6e 73 74 20 63 68 61 72 20  atic const char 
1290: 7a 45 6d 70 74 79 5b 5d 20 3d 20 22 22 3b 0a 20  zEmpty[] = "";. 
12a0: 20 62 6c 6f 62 5f 69 73 5f 72 65 73 65 74 28 70   blob_is_reset(p
12b0: 42 6c 6f 62 29 3b 0a 20 20 70 42 6c 6f 62 2d 3e  Blob);.  pBlob->
12c0: 6e 55 73 65 64 20 3d 20 30 3b 0a 20 20 70 42 6c  nUsed = 0;.  pBl
12d0: 6f 62 2d 3e 6e 41 6c 6c 6f 63 20 3d 20 31 3b 0a  ob->nAlloc = 1;.
12e0: 20 20 70 42 6c 6f 62 2d 3e 61 44 61 74 61 20 3d    pBlob->aData =
12f0: 20 28 63 68 61 72 2a 29 7a 45 6d 70 74 79 3b 0a   (char*)zEmpty;.
1300: 20 20 70 42 6c 6f 62 2d 3e 69 43 75 72 73 6f 72    pBlob->iCursor
1310: 20 3d 20 30 3b 0a 20 20 70 42 6c 6f 62 2d 3e 78   = 0;.  pBlob->x
1320: 52 65 61 6c 6c 6f 63 20 3d 20 62 6c 6f 62 52 65  Realloc = blobRe
1330: 61 6c 6c 6f 63 53 74 61 74 69 63 3b 0a 7d 0a 0a  allocStatic;.}..
1340: 2f 2a 0a 2a 2a 20 41 70 70 65 6e 64 20 74 65 78  /*.** Append tex
1350: 74 20 6f 72 20 64 61 74 61 20 74 6f 20 74 68 65  t or data to the
1360: 20 65 6e 64 20 6f 66 20 61 20 62 6c 6f 62 2e 0a   end of a blob..
1370: 2a 2f 0a 76 6f 69 64 20 62 6c 6f 62 5f 61 70 70  */.void blob_app
1380: 65 6e 64 28 42 6c 6f 62 20 2a 70 42 6c 6f 62 2c  end(Blob *pBlob,
1390: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 44 61   const char *aDa
13a0: 74 61 2c 20 69 6e 74 20 6e 44 61 74 61 29 7b 0a  ta, int nData){.
13b0: 20 20 62 6c 6f 62 5f 69 73 5f 69 6e 69 74 28 70    blob_is_init(p
13c0: 42 6c 6f 62 29 3b 0a 20 20 69 66 28 20 6e 44 61  Blob);.  if( nDa
13d0: 74 61 3c 30 20 29 20 6e 44 61 74 61 20 3d 20 73  ta<0 ) nData = s
13e0: 74 72 6c 65 6e 28 61 44 61 74 61 29 3b 0a 20 20  trlen(aData);.  
13f0: 69 66 28 20 6e 44 61 74 61 3d 3d 30 20 29 20 72  if( nData==0 ) r
1400: 65 74 75 72 6e 3b 0a 20 20 69 66 28 20 70 42 6c  eturn;.  if( pBl
1410: 6f 62 2d 3e 6e 55 73 65 64 20 2b 20 6e 44 61 74  ob->nUsed + nDat
1420: 61 20 3e 3d 20 70 42 6c 6f 62 2d 3e 6e 41 6c 6c  a >= pBlob->nAll
1430: 6f 63 20 29 7b 0a 20 20 20 20 70 42 6c 6f 62 2d  oc ){.    pBlob-
1440: 3e 78 52 65 61 6c 6c 6f 63 28 70 42 6c 6f 62 2c  >xRealloc(pBlob,
1450: 20 70 42 6c 6f 62 2d 3e 6e 55 73 65 64 20 2b 20   pBlob->nUsed + 
1460: 6e 44 61 74 61 20 2b 20 70 42 6c 6f 62 2d 3e 6e  nData + pBlob->n
1470: 41 6c 6c 6f 63 20 2b 20 31 30 30 29 3b 0a 20 20  Alloc + 100);.  
1480: 20 20 69 66 28 20 70 42 6c 6f 62 2d 3e 6e 55 73    if( pBlob->nUs
1490: 65 64 20 2b 20 6e 44 61 74 61 20 3e 3d 20 70 42  ed + nData >= pB
14a0: 6c 6f 62 2d 3e 6e 41 6c 6c 6f 63 20 29 7b 0a 20  lob->nAlloc ){. 
14b0: 20 20 20 20 20 62 6c 6f 62 5f 70 61 6e 69 63 28       blob_panic(
14c0: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 6d  );.    }.  }.  m
14d0: 65 6d 63 70 79 28 26 70 42 6c 6f 62 2d 3e 61 44  emcpy(&pBlob->aD
14e0: 61 74 61 5b 70 42 6c 6f 62 2d 3e 6e 55 73 65 64  ata[pBlob->nUsed
14f0: 5d 2c 20 61 44 61 74 61 2c 20 6e 44 61 74 61 29  ], aData, nData)
1500: 3b 0a 20 20 70 42 6c 6f 62 2d 3e 6e 55 73 65 64  ;.  pBlob->nUsed
1510: 20 2b 3d 20 6e 44 61 74 61 3b 0a 20 20 70 42 6c   += nData;.  pBl
1520: 6f 62 2d 3e 61 44 61 74 61 5b 70 42 6c 6f 62 2d  ob->aData[pBlob-
1530: 3e 6e 55 73 65 64 5d 20 3d 20 30 3b 20 20 20 2f  >nUsed] = 0;   /
1540: 2a 20 42 6c 6f 62 73 20 61 72 65 20 61 6c 77 61  * Blobs are alwa
1550: 79 73 20 6e 75 6c 2d 74 65 72 6d 69 6e 61 74 65  ys nul-terminate
1560: 64 20 2a 2f 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f  d */.}../*.** Co
1570: 70 79 20 61 20 62 6c 6f 62 0a 2a 2f 0a 76 6f 69  py a blob.*/.voi
1580: 64 20 62 6c 6f 62 5f 63 6f 70 79 28 42 6c 6f 62  d blob_copy(Blob
1590: 20 2a 70 54 6f 2c 20 42 6c 6f 62 20 2a 70 46 72   *pTo, Blob *pFr
15a0: 6f 6d 29 7b 0a 20 20 62 6c 6f 62 5f 69 73 5f 69  om){.  blob_is_i
15b0: 6e 69 74 28 70 46 72 6f 6d 29 3b 0a 20 20 62 6c  nit(pFrom);.  bl
15c0: 6f 62 5f 69 73 5f 69 6e 69 74 28 70 54 6f 29 3b  ob_is_init(pTo);
15d0: 0a 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 70 54 6f  .  blob_zero(pTo
15e0: 29 3b 0a 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64  );.  blob_append
15f0: 28 70 54 6f 2c 20 62 6c 6f 62 5f 62 75 66 66 65  (pTo, blob_buffe
1600: 72 28 70 46 72 6f 6d 29 2c 20 62 6c 6f 62 5f 73  r(pFrom), blob_s
1610: 69 7a 65 28 70 46 72 6f 6d 29 29 3b 0a 7d 0a 0a  ize(pFrom));.}..
1620: 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20 70  /*.** Return a p
1630: 6f 69 6e 74 65 72 20 74 6f 20 61 20 6e 75 6c 6c  ointer to a null
1640: 2d 74 65 72 6d 69 6e 61 74 65 64 20 73 74 72 69  -terminated stri
1650: 6e 67 20 66 6f 72 20 61 20 62 6c 6f 62 2e 0a 2a  ng for a blob..*
1660: 2f 0a 63 68 61 72 20 2a 62 6c 6f 62 5f 73 74 72  /.char *blob_str
1670: 28 42 6c 6f 62 20 2a 70 29 7b 0a 20 20 62 6c 6f  (Blob *p){.  blo
1680: 62 5f 69 73 5f 69 6e 69 74 28 70 29 3b 0a 20 20  b_is_init(p);.  
1690: 69 66 28 20 70 2d 3e 6e 55 73 65 64 3d 3d 30 20  if( p->nUsed==0 
16a0: 29 7b 0a 20 20 20 20 62 6c 6f 62 5f 61 70 70 65  ){.    blob_appe
16b0: 6e 64 28 70 2c 20 22 22 2c 20 31 29 3b 0a 20 20  nd(p, "", 1);.  
16c0: 20 20 70 2d 3e 6e 55 73 65 64 20 3d 20 30 3b 0a    p->nUsed = 0;.
16d0: 20 20 7d 0a 20 20 69 66 28 20 70 2d 3e 61 44 61    }.  if( p->aDa
16e0: 74 61 5b 70 2d 3e 6e 55 73 65 64 5d 21 3d 30 20  ta[p->nUsed]!=0 
16f0: 29 7b 0a 20 20 20 20 62 6c 6f 62 5f 6d 61 74 65  ){.    blob_mate
1700: 72 69 61 6c 69 7a 65 28 70 29 3b 0a 20 20 7d 0a  rialize(p);.  }.
1710: 20 20 72 65 74 75 72 6e 20 70 2d 3e 61 44 61 74    return p->aDat
1720: 61 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75  a;.}../*.** Retu
1730: 72 6e 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20  rn a pointer to 
1740: 61 20 6e 75 6c 6c 2d 74 65 72 6d 69 6e 61 74 65  a null-terminate
1750: 64 20 73 74 72 69 6e 67 20 66 6f 72 20 61 20 62  d string for a b
1760: 6c 6f 62 2e 0a 2a 2a 0a 2a 2a 20 57 41 52 4e 49  lob..**.** WARNI
1770: 4e 47 3a 20 20 49 66 20 74 68 65 20 62 6c 6f 62  NG:  If the blob
1780: 20 69 73 20 65 70 68 65 6d 65 72 61 6c 2c 20 69   is ephemeral, i
1790: 74 20 6d 69 67 68 74 20 63 61 75 73 65 20 61 20  t might cause a 
17a0: 27 5c 30 30 30 27 0a 2a 2a 20 63 68 61 72 61 63  '\000'.** charac
17b0: 74 65 72 20 74 6f 20 62 65 20 69 6e 73 65 72 74  ter to be insert
17c0: 65 64 20 69 6e 74 6f 20 74 68 65 20 6d 69 64 64  ed into the midd
17d0: 6c 65 20 6f 66 20 74 68 65 20 70 61 72 65 6e 74  le of the parent
17e0: 20 62 6c 6f 62 2e 0a 2a 2a 20 45 78 61 6d 70 6c   blob..** Exampl
17f0: 65 3a 20 20 53 75 70 70 6f 73 65 20 70 20 69 73  e:  Suppose p is
1800: 20 61 20 74 6f 6b 65 6e 20 65 78 74 72 61 63 74   a token extract
1810: 65 64 20 66 72 6f 6d 20 73 6f 6d 65 20 6c 61 72  ed from some lar
1820: 67 65 72 0a 2a 2a 20 62 6c 6f 62 20 70 42 69 67  ger.** blob pBig
1830: 20 75 73 69 6e 67 20 62 6c 6f 62 5f 74 6f 6b 65   using blob_toke
1840: 6e 28 29 2e 20 20 49 66 20 79 6f 75 20 63 61 6c  n().  If you cal
1850: 6c 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 6f  l this routine o
1860: 6e 20 70 2c 0a 2a 2a 20 74 68 65 6e 20 61 20 27  n p,.** then a '
1870: 5c 30 30 30 27 20 63 68 61 72 61 63 74 65 72 20  \000' character 
1880: 77 69 6c 6c 20 62 65 20 69 6e 73 65 72 74 65 64  will be inserted
1890: 20 69 6e 20 74 68 65 20 6d 69 64 64 6c 65 20 6f   in the middle o
18a0: 66 0a 2a 2a 20 70 42 69 67 20 69 6e 20 6f 72 64  f.** pBig in ord
18b0: 65 72 20 74 6f 20 63 61 75 73 65 20 70 20 74 6f  er to cause p to
18c0: 20 62 65 20 6e 75 6c 2d 74 65 72 6d 69 6e 61 74   be nul-terminat
18d0: 65 64 2e 20 20 49 66 20 70 42 69 67 0a 2a 2a 20  ed.  If pBig.** 
18e0: 73 68 6f 75 6c 64 20 6e 6f 74 20 62 65 20 6d 6f  should not be mo
18f0: 64 69 66 69 65 64 2c 20 74 68 65 6e 20 75 73 65  dified, then use
1900: 20 62 6c 6f 62 5f 73 74 72 28 29 20 69 6e 73 74   blob_str() inst
1910: 65 61 64 20 6f 66 20 74 68 69 73 0a 2a 2a 20 72  ead of this.** r
1920: 6f 75 74 69 6e 65 2e 20 20 62 6c 6f 62 5f 73 74  outine.  blob_st
1930: 72 28 29 20 77 69 6c 6c 20 6d 61 6b 65 20 61 20  r() will make a 
1940: 63 6f 70 79 20 6f 66 20 74 68 65 20 70 20 69 66  copy of the p if
1950: 20 6e 65 63 65 73 73 61 72 79 0a 2a 2a 20 74 6f   necessary.** to
1960: 20 61 76 6f 69 64 20 6d 6f 64 69 66 79 69 6e 67   avoid modifying
1970: 20 70 42 69 67 2e 0a 2a 2f 0a 63 68 61 72 20 2a   pBig..*/.char *
1980: 62 6c 6f 62 5f 74 65 72 6d 69 6e 61 74 65 28 42  blob_terminate(B
1990: 6c 6f 62 20 2a 70 29 7b 0a 20 20 62 6c 6f 62 5f  lob *p){.  blob_
19a0: 69 73 5f 69 6e 69 74 28 70 29 3b 0a 20 20 70 2d  is_init(p);.  p-
19b0: 3e 61 44 61 74 61 5b 70 2d 3e 6e 55 73 65 64 5d  >aData[p->nUsed]
19c0: 20 3d 20 30 3b 0a 20 20 72 65 74 75 72 6e 20 70   = 0;.  return p
19d0: 2d 3e 61 44 61 74 61 3b 0a 7d 0a 0a 2f 2a 0a 2a  ->aData;.}../*.*
19e0: 2a 20 43 6f 6d 70 61 72 65 20 74 77 6f 20 62 6c  * Compare two bl
19f0: 6f 62 73 2e 0a 2a 2f 0a 69 6e 74 20 62 6c 6f 62  obs..*/.int blob
1a00: 5f 63 6f 6d 70 61 72 65 28 42 6c 6f 62 20 2a 70  _compare(Blob *p
1a10: 41 2c 20 42 6c 6f 62 20 2a 70 42 29 7b 0a 20 20  A, Blob *pB){.  
1a20: 69 6e 74 20 73 7a 41 2c 20 73 7a 42 2c 20 73 7a  int szA, szB, sz
1a30: 2c 20 72 63 3b 0a 20 20 62 6c 6f 62 5f 69 73 5f  , rc;.  blob_is_
1a40: 69 6e 69 74 28 70 41 29 3b 0a 20 20 62 6c 6f 62  init(pA);.  blob
1a50: 5f 69 73 5f 69 6e 69 74 28 70 42 29 3b 0a 20 20  _is_init(pB);.  
1a60: 73 7a 41 20 3d 20 62 6c 6f 62 5f 73 69 7a 65 28  szA = blob_size(
1a70: 70 41 29 3b 0a 20 20 73 7a 42 20 3d 20 62 6c 6f  pA);.  szB = blo
1a80: 62 5f 73 69 7a 65 28 70 42 29 3b 0a 20 20 73 7a  b_size(pB);.  sz
1a90: 20 3d 20 73 7a 41 3c 73 7a 42 20 3f 20 73 7a 41   = szA<szB ? szA
1aa0: 20 3a 20 73 7a 42 3b 0a 20 20 72 63 20 3d 20 6d   : szB;.  rc = m
1ab0: 65 6d 63 6d 70 28 62 6c 6f 62 5f 62 75 66 66 65  emcmp(blob_buffe
1ac0: 72 28 70 41 29 2c 20 62 6c 6f 62 5f 62 75 66 66  r(pA), blob_buff
1ad0: 65 72 28 70 42 29 2c 20 73 7a 29 3b 0a 20 20 69  er(pB), sz);.  i
1ae0: 66 28 20 72 63 3d 3d 30 20 29 7b 0a 20 20 20 20  f( rc==0 ){.    
1af0: 72 63 20 3d 20 73 7a 41 20 2d 20 73 7a 42 3b 0a  rc = szA - szB;.
1b00: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
1b10: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 70 61 72  .}../*.** Compar
1b20: 65 20 61 20 62 6c 6f 62 20 74 6f 20 61 20 73 74  e a blob to a st
1b30: 72 69 6e 67 2e 20 20 52 65 74 75 72 6e 20 54 52  ring.  Return TR
1b40: 55 45 20 69 66 20 74 68 65 79 20 61 72 65 20 65  UE if they are e
1b50: 71 75 61 6c 2e 0a 2a 2f 0a 69 6e 74 20 62 6c 6f  qual..*/.int blo
1b60: 62 5f 65 71 5f 73 74 72 28 42 6c 6f 62 20 2a 70  b_eq_str(Blob *p
1b70: 42 6c 6f 62 2c 20 63 6f 6e 73 74 20 63 68 61 72  Blob, const char
1b80: 20 2a 7a 2c 20 69 6e 74 20 6e 29 7b 0a 20 20 42   *z, int n){.  B
1b90: 6c 6f 62 20 74 3b 0a 20 20 62 6c 6f 62 5f 69 73  lob t;.  blob_is
1ba0: 5f 69 6e 69 74 28 70 42 6c 6f 62 29 3b 0a 20 20  _init(pBlob);.  
1bb0: 69 66 28 20 6e 3c 3d 30 20 29 20 6e 20 3d 20 73  if( n<=0 ) n = s
1bc0: 74 72 6c 65 6e 28 7a 29 3b 0a 20 20 74 2e 61 44  trlen(z);.  t.aD
1bd0: 61 74 61 20 3d 20 28 63 68 61 72 2a 29 7a 3b 0a  ata = (char*)z;.
1be0: 20 20 74 2e 6e 55 73 65 64 20 3d 20 6e 3b 0a 20    t.nUsed = n;. 
1bf0: 20 74 2e 78 52 65 61 6c 6c 6f 63 20 3d 20 62 6c   t.xRealloc = bl
1c00: 6f 62 52 65 61 6c 6c 6f 63 53 74 61 74 69 63 3b  obReallocStatic;
1c10: 0a 20 20 72 65 74 75 72 6e 20 62 6c 6f 62 5f 63  .  return blob_c
1c20: 6f 6d 70 61 72 65 28 70 42 6c 6f 62 2c 20 26 74  ompare(pBlob, &t
1c30: 29 3d 3d 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  )==0;.}../*.** T
1c40: 68 69 73 20 6d 61 63 72 6f 20 63 6f 6d 70 61 72  his macro compar
1c50: 65 73 20 61 20 62 6c 6f 62 20 61 67 61 69 6e 73  es a blob agains
1c60: 74 20 61 20 73 74 72 69 6e 67 20 63 6f 6e 73 74  t a string const
1c70: 61 6e 74 2e 20 20 57 65 20 75 73 65 20 74 68 65  ant.  We use the
1c80: 20 73 69 7a 65 6f 66 28 29 0a 2a 2a 20 6f 70 65   sizeof().** ope
1c90: 72 61 74 6f 72 20 6f 6e 20 74 68 65 20 73 74 72  rator on the str
1ca0: 69 6e 67 20 63 6f 6e 73 74 61 6e 74 20 74 77 69  ing constant twi
1cb0: 63 65 2c 20 73 6f 20 69 74 20 72 65 61 6c 6c 79  ce, so it really
1cc0: 20 64 6f 65 73 20 6e 65 65 64 20 74 6f 20 62 65   does need to be
1cd0: 20 61 0a 2a 2a 20 73 74 72 69 6e 67 20 6c 69 74   a.** string lit
1ce0: 65 72 61 6c 20 6f 72 20 63 68 61 72 61 63 74 65  eral or characte
1cf0: 72 20 61 72 72 61 79 20 2d 20 6e 6f 74 20 61 20  r array - not a 
1d00: 63 68 61 72 61 63 74 65 72 20 70 6f 69 6e 74 65  character pointe
1d10: 72 2e 0a 2a 2f 0a 23 69 66 20 49 4e 54 45 52 46  r..*/.#if INTERF
1d20: 41 43 45 0a 23 20 64 65 66 69 6e 65 20 62 6c 6f  ACE.# define blo
1d30: 62 5f 65 71 28 42 2c 53 29 20 5c 0a 20 20 20 20  b_eq(B,S) \.    
1d40: 20 28 28 42 29 2d 3e 6e 55 73 65 64 3d 3d 73 69   ((B)->nUsed==si
1d50: 7a 65 6f 66 28 53 29 2d 31 20 26 26 20 6d 65 6d  zeof(S)-1 && mem
1d60: 63 6d 70 28 28 42 29 2d 3e 61 44 61 74 61 2c 53  cmp((B)->aData,S
1d70: 2c 73 69 7a 65 6f 66 28 53 29 2d 31 29 3d 3d 30  ,sizeof(S)-1)==0
1d80: 29 0a 23 65 6e 64 69 66 0a 0a 0a 2f 2a 0a 2a 2a  ).#endif.../*.**
1d90: 20 41 74 74 65 6d 70 74 20 74 6f 20 72 65 73 69   Attempt to resi
1da0: 7a 65 20 61 20 62 6c 6f 62 20 73 6f 20 74 68 61  ze a blob so tha
1db0: 74 20 69 74 73 20 69 6e 74 65 72 6e 61 6c 20 62  t its internal b
1dc0: 75 66 66 65 72 20 69 73 20 0a 2a 2a 20 6e 42 79  uffer is .** nBy
1dd0: 74 65 20 69 6e 20 73 69 7a 65 2e 20 20 54 68 65  te in size.  The
1de0: 20 62 6c 6f 62 20 69 73 20 74 72 75 6e 63 61 74   blob is truncat
1df0: 65 64 20 69 66 20 6e 65 63 65 73 73 61 72 79 2e  ed if necessary.
1e00: 0a 2a 2f 0a 76 6f 69 64 20 62 6c 6f 62 5f 72 65  .*/.void blob_re
1e10: 73 69 7a 65 28 42 6c 6f 62 20 2a 70 42 6c 6f 62  size(Blob *pBlob
1e20: 2c 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e  , unsigned int n
1e30: 65 77 53 69 7a 65 29 7b 0a 20 20 70 42 6c 6f 62  ewSize){.  pBlob
1e40: 2d 3e 78 52 65 61 6c 6c 6f 63 28 70 42 6c 6f 62  ->xRealloc(pBlob
1e50: 2c 20 6e 65 77 53 69 7a 65 2b 31 29 3b 0a 20 20  , newSize+1);.  
1e60: 70 42 6c 6f 62 2d 3e 6e 55 73 65 64 20 3d 20 6e  pBlob->nUsed = n
1e70: 65 77 53 69 7a 65 3b 0a 20 20 70 42 6c 6f 62 2d  ewSize;.  pBlob-
1e80: 3e 61 44 61 74 61 5b 6e 65 77 53 69 7a 65 5d 20  >aData[newSize] 
1e90: 3d 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61  = 0;.}../*.** Ma
1ea0: 6b 65 20 73 75 72 65 20 61 20 62 6c 6f 62 20 69  ke sure a blob i
1eb0: 73 20 6e 75 6c 2d 74 65 72 6d 69 6e 61 74 65 64  s nul-terminated
1ec0: 20 61 6e 64 20 69 73 20 6e 6f 74 20 61 20 70 6f   and is not a po
1ed0: 69 6e 74 65 72 20 74 6f 20 75 6e 6d 61 6e 61 67  inter to unmanag
1ee0: 65 64 0a 2a 2a 20 73 70 61 63 65 2e 20 20 52 65  ed.** space.  Re
1ef0: 74 75 72 6e 20 61 20 70 6f 69 6e 74 65 72 20 74  turn a pointer t
1f00: 6f 20 74 68 65 0a 2a 2f 0a 63 68 61 72 20 2a 62  o the.*/.char *b
1f10: 6c 6f 62 5f 6d 61 74 65 72 69 61 6c 69 7a 65 28  lob_materialize(
1f20: 42 6c 6f 62 20 2a 70 42 6c 6f 62 29 7b 0a 20 20  Blob *pBlob){.  
1f30: 62 6c 6f 62 5f 72 65 73 69 7a 65 28 70 42 6c 6f  blob_resize(pBlo
1f40: 62 2c 20 70 42 6c 6f 62 2d 3e 6e 55 73 65 64 29  b, pBlob->nUsed)
1f50: 3b 0a 20 20 72 65 74 75 72 6e 20 70 42 6c 6f 62  ;.  return pBlob
1f60: 2d 3e 61 44 61 74 61 3b 0a 7d 0a 0a 0a 2f 2a 0a  ->aData;.}.../*.
1f70: 2a 2a 20 43 61 6c 6c 20 64 65 68 74 74 70 69 7a  ** Call dehttpiz
1f80: 65 20 6f 6e 20 61 20 62 6c 6f 62 2e 20 20 54 68  e on a blob.  Th
1f90: 69 73 20 63 61 75 73 65 73 20 61 6e 20 65 70 68  is causes an eph
1fa0: 65 6d 65 72 61 6c 20 62 6c 6f 62 20 74 6f 20 62  emeral blob to b
1fb0: 65 0a 2a 2a 20 6d 61 74 65 72 69 61 6c 69 7a 65  e.** materialize
1fc0: 64 2e 0a 2a 2f 0a 76 6f 69 64 20 62 6c 6f 62 5f  d..*/.void blob_
1fd0: 64 65 68 74 74 70 69 7a 65 28 42 6c 6f 62 20 2a  dehttpize(Blob *
1fe0: 70 42 6c 6f 62 29 7b 0a 20 20 62 6c 6f 62 5f 6d  pBlob){.  blob_m
1ff0: 61 74 65 72 69 61 6c 69 7a 65 28 70 42 6c 6f 62  aterialize(pBlob
2000: 29 3b 0a 20 20 70 42 6c 6f 62 2d 3e 6e 55 73 65  );.  pBlob->nUse
2010: 64 20 3d 20 64 65 68 74 74 70 69 7a 65 28 70 42  d = dehttpize(pB
2020: 6c 6f 62 2d 3e 61 44 61 74 61 29 3b 0a 7d 0a 0a  lob->aData);.}..
2030: 2f 2a 0a 2a 2a 20 45 78 74 72 61 63 74 20 4e 20  /*.** Extract N 
2040: 62 79 74 65 73 20 66 72 6f 6d 20 62 6c 6f 62 20  bytes from blob 
2050: 70 46 72 6f 6d 20 61 6e 64 20 75 73 65 20 69 74  pFrom and use it
2060: 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 20 62   to initialize b
2070: 6c 6f 62 20 70 54 6f 2e 0a 2a 2a 20 52 65 74 75  lob pTo..** Retu
2080: 72 6e 20 74 68 65 20 61 63 74 75 61 6c 20 6e 75  rn the actual nu
2090: 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 65 78  mber of bytes ex
20a0: 74 72 61 63 74 65 64 2e 0a 2a 2a 0a 2a 2a 20 41  tracted..**.** A
20b0: 66 74 65 72 20 74 68 69 73 20 63 61 6c 6c 20 63  fter this call c
20c0: 6f 6d 70 6c 65 74 65 73 2c 20 70 54 6f 20 77 69  ompletes, pTo wi
20d0: 6c 6c 20 62 65 20 61 6e 20 65 70 68 65 6d 65 72  ll be an ephemer
20e0: 61 6c 20 62 6c 6f 62 2e 0a 2a 2f 0a 69 6e 74 20  al blob..*/.int 
20f0: 62 6c 6f 62 5f 65 78 74 72 61 63 74 28 42 6c 6f  blob_extract(Blo
2100: 62 20 2a 70 46 72 6f 6d 2c 20 69 6e 74 20 4e 2c  b *pFrom, int N,
2110: 20 42 6c 6f 62 20 2a 70 54 6f 29 7b 0a 20 20 62   Blob *pTo){.  b
2120: 6c 6f 62 5f 69 73 5f 69 6e 69 74 28 70 46 72 6f  lob_is_init(pFro
2130: 6d 29 3b 0a 20 20 62 6c 6f 62 5f 69 73 5f 72 65  m);.  blob_is_re
2140: 73 65 74 28 70 54 6f 29 3b 0a 20 20 69 66 28 20  set(pTo);.  if( 
2150: 70 46 72 6f 6d 2d 3e 69 43 75 72 73 6f 72 20 2b  pFrom->iCursor +
2160: 20 4e 20 3e 20 70 46 72 6f 6d 2d 3e 6e 55 73 65   N > pFrom->nUse
2170: 64 20 29 7b 0a 20 20 20 20 4e 20 3d 20 70 46 72  d ){.    N = pFr
2180: 6f 6d 2d 3e 6e 55 73 65 64 20 2d 20 70 46 72 6f  om->nUsed - pFro
2190: 6d 2d 3e 69 43 75 72 73 6f 72 3b 0a 20 20 20 20  m->iCursor;.    
21a0: 69 66 28 20 4e 3c 3d 30 20 29 7b 0a 20 20 20 20  if( N<=0 ){.    
21b0: 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 70 54 6f 29    blob_zero(pTo)
21c0: 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 30  ;.      return 0
21d0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 70 54  ;.    }.  }.  pT
21e0: 6f 2d 3e 6e 55 73 65 64 20 3d 20 4e 3b 0a 20 20  o->nUsed = N;.  
21f0: 70 54 6f 2d 3e 6e 41 6c 6c 6f 63 20 3d 20 4e 3b  pTo->nAlloc = N;
2200: 0a 20 20 70 54 6f 2d 3e 61 44 61 74 61 20 3d 20  .  pTo->aData = 
2210: 26 70 46 72 6f 6d 2d 3e 61 44 61 74 61 5b 70 46  &pFrom->aData[pF
2220: 72 6f 6d 2d 3e 69 43 75 72 73 6f 72 5d 3b 0a 20  rom->iCursor];. 
2230: 20 70 54 6f 2d 3e 69 43 75 72 73 6f 72 20 3d 20   pTo->iCursor = 
2240: 30 3b 0a 20 20 70 54 6f 2d 3e 78 52 65 61 6c 6c  0;.  pTo->xReall
2250: 6f 63 20 3d 20 62 6c 6f 62 52 65 61 6c 6c 6f 63  oc = blobRealloc
2260: 53 74 61 74 69 63 3b 0a 20 20 70 46 72 6f 6d 2d  Static;.  pFrom-
2270: 3e 69 43 75 72 73 6f 72 20 2b 3d 20 4e 3b 0a 20  >iCursor += N;. 
2280: 20 72 65 74 75 72 6e 20 4e 3b 0a 7d 0a 0a 2f 2a   return N;.}../*
2290: 0a 2a 2a 20 52 65 77 69 6e 64 20 74 68 65 20 63  .** Rewind the c
22a0: 75 72 73 6f 72 20 6f 6e 20 61 20 62 6c 6f 62 20  ursor on a blob 
22b0: 62 61 63 6b 20 74 6f 20 74 68 65 20 62 65 67 69  back to the begi
22c0: 6e 6e 69 6e 67 2e 0a 2a 2f 0a 76 6f 69 64 20 62  nning..*/.void b
22d0: 6c 6f 62 5f 72 65 77 69 6e 64 28 42 6c 6f 62 20  lob_rewind(Blob 
22e0: 2a 70 29 7b 0a 20 20 70 2d 3e 69 43 75 72 73 6f  *p){.  p->iCurso
22f0: 72 20 3d 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  r = 0;.}../*.** 
2300: 53 65 65 6b 20 74 68 65 20 63 75 72 73 6f 72 20  Seek the cursor 
2310: 69 6e 20 61 20 62 6c 6f 62 20 74 6f 20 74 68 65  in a blob to the
2320: 20 69 6e 64 69 63 61 74 65 64 20 6f 66 66 73 65   indicated offse
2330: 74 2e 0a 2a 2f 0a 69 6e 74 20 62 6c 6f 62 5f 73  t..*/.int blob_s
2340: 65 65 6b 28 42 6c 6f 62 20 2a 70 2c 20 69 6e 74  eek(Blob *p, int
2350: 20 6f 66 66 73 65 74 2c 20 69 6e 74 20 77 68 65   offset, int whe
2360: 6e 63 65 29 7b 0a 20 20 69 66 28 20 77 68 65 6e  nce){.  if( when
2370: 63 65 3d 3d 42 4c 4f 42 5f 53 45 45 4b 5f 53 45  ce==BLOB_SEEK_SE
2380: 54 20 29 7b 0a 20 20 20 20 70 2d 3e 69 43 75 72  T ){.    p->iCur
2390: 73 6f 72 20 3d 20 6f 66 66 73 65 74 3b 0a 20 20  sor = offset;.  
23a0: 7d 65 6c 73 65 20 69 66 28 20 77 68 65 6e 63 65  }else if( whence
23b0: 3d 3d 42 4c 4f 42 5f 53 45 45 4b 5f 43 55 52 20  ==BLOB_SEEK_CUR 
23c0: 29 7b 0a 20 20 20 20 70 2d 3e 69 43 75 72 73 6f  ){.    p->iCurso
23d0: 72 20 2b 3d 20 6f 66 66 73 65 74 3b 0a 20 20 7d  r += offset;.  }
23e0: 65 6c 73 65 20 69 66 28 20 77 68 65 6e 63 65 3d  else if( whence=
23f0: 3d 42 4c 4f 42 5f 53 45 45 4b 5f 45 4e 44 20 29  =BLOB_SEEK_END )
2400: 7b 0a 20 20 20 20 70 2d 3e 69 43 75 72 73 6f 72  {.    p->iCursor
2410: 20 3d 20 70 2d 3e 6e 55 73 65 64 20 2b 20 6f 66   = p->nUsed + of
2420: 66 73 65 74 20 2d 20 31 3b 0a 20 20 7d 0a 20 20  fset - 1;.  }.  
2430: 69 66 28 20 70 2d 3e 69 43 75 72 73 6f 72 3c 30  if( p->iCursor<0
2440: 20 29 7b 0a 20 20 20 20 70 2d 3e 69 43 75 72 73   ){.    p->iCurs
2450: 6f 72 20 3d 20 30 3b 0a 20 20 7d 0a 20 20 69 66  or = 0;.  }.  if
2460: 28 20 70 2d 3e 69 43 75 72 73 6f 72 3e 70 2d 3e  ( p->iCursor>p->
2470: 6e 55 73 65 64 20 29 7b 0a 20 20 20 20 70 2d 3e  nUsed ){.    p->
2480: 69 43 75 72 73 6f 72 20 3d 20 70 2d 3e 6e 55 73  iCursor = p->nUs
2490: 65 64 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  ed;.  }.  return
24a0: 20 70 2d 3e 69 43 75 72 73 6f 72 3b 0a 7d 0a 0a   p->iCursor;.}..
24b0: 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65  /*.** Return the
24c0: 20 63 75 72 72 65 6e 74 20 6f 66 66 73 65 74 20   current offset 
24d0: 69 6e 74 6f 20 74 68 65 20 62 6c 6f 62 0a 2a 2f  into the blob.*/
24e0: 0a 69 6e 74 20 62 6c 6f 62 5f 74 65 6c 6c 28 42  .int blob_tell(B
24f0: 6c 6f 62 20 2a 70 29 7b 0a 20 20 72 65 74 75 72  lob *p){.  retur
2500: 6e 20 70 2d 3e 69 43 75 72 73 6f 72 3b 0a 7d 0a  n p->iCursor;.}.
2510: 0a 2f 2a 0a 2a 2a 20 45 78 74 72 61 63 74 20 61  ./*.** Extract a
2520: 20 73 69 6e 67 6c 65 20 6c 69 6e 65 20 6f 66 20   single line of 
2530: 74 65 78 74 20 66 72 6f 6d 20 70 46 72 6f 6d 20  text from pFrom 
2540: 62 65 67 69 6e 6e 69 6e 67 20 61 74 20 74 68 65  beginning at the
2550: 20 63 75 72 72 65 6e 74 20 0a 2a 2a 20 63 75 72   current .** cur
2560: 73 6f 72 20 6c 6f 63 61 74 69 6f 6e 20 61 6e 64  sor location and
2570: 20 75 73 65 20 74 68 61 74 20 6c 69 6e 65 20 6f   use that line o
2580: 66 20 74 65 78 74 20 74 6f 20 69 6e 69 74 69 61  f text to initia
2590: 6c 69 7a 65 20 70 54 6f 2e 0a 2a 2a 20 70 54 6f  lize pTo..** pTo
25a0: 20 77 69 6c 6c 20 69 6e 63 6c 75 64 65 20 74 68   will include th
25b0: 65 20 74 65 72 6d 69 6e 61 74 69 6e 67 20 5c 6e  e terminating \n
25c0: 2e 20 20 52 65 74 75 72 6e 20 74 68 65 20 6e 75  .  Return the nu
25d0: 6d 62 65 72 20 6f 66 20 62 79 74 65 73 0a 2a 2a  mber of bytes.**
25e0: 20 69 6e 20 74 68 65 20 6c 69 6e 65 20 69 6e 63   in the line inc
25f0: 6c 75 64 69 6e 67 20 74 68 65 20 5c 6e 20 61 74  luding the \n at
2600: 20 74 68 65 20 65 6e 64 2e 20 20 30 20 69 73 20   the end.  0 is 
2610: 72 65 74 75 72 6e 65 64 20 61 74 0a 2a 2a 20 65  returned at.** e
2620: 6e 64 2d 6f 66 2d 66 69 6c 65 2e 0a 2a 2a 0a 2a  nd-of-file..**.*
2630: 2a 20 54 68 65 20 63 75 72 73 6f 72 20 6f 66 20  * The cursor of 
2640: 70 46 72 6f 6d 20 69 73 20 6c 65 66 74 20 70 6f  pFrom is left po
2650: 69 6e 74 69 6e 67 20 61 74 20 74 68 65 20 66 69  inting at the fi
2660: 72 73 74 20 62 79 74 65 20 70 61 73 74 20 74 68  rst byte past th
2670: 65 0a 2a 2a 20 5c 6e 20 74 68 61 74 20 74 65 72  e.** \n that ter
2680: 6d 69 6e 61 74 65 64 20 74 68 65 20 6c 69 6e 65  minated the line
2690: 2e 0a 2a 2a 0a 2a 2a 20 70 54 6f 20 77 69 6c 6c  ..**.** pTo will
26a0: 20 62 65 20 61 6e 20 65 70 68 65 72 6d 65 72 61   be an ephermera
26b0: 6c 20 62 6c 6f 62 2e 20 20 49 66 20 70 46 72 6f  l blob.  If pFro
26c0: 6d 20 63 68 61 6e 67 65 73 2c 20 69 74 20 6d 69  m changes, it mi
26d0: 67 68 74 20 61 6c 74 65 72 0a 2a 2a 20 70 54 6f  ght alter.** pTo
26e0: 20 61 73 20 77 65 6c 6c 2e 0a 2a 2f 0a 69 6e 74   as well..*/.int
26f0: 20 62 6c 6f 62 5f 6c 69 6e 65 28 42 6c 6f 62 20   blob_line(Blob 
2700: 2a 70 46 72 6f 6d 2c 20 42 6c 6f 62 20 2a 70 54  *pFrom, Blob *pT
2710: 6f 29 7b 0a 20 20 63 68 61 72 20 2a 61 44 61 74  o){.  char *aDat
2720: 61 20 3d 20 70 46 72 6f 6d 2d 3e 61 44 61 74 61  a = pFrom->aData
2730: 3b 0a 20 20 69 6e 74 20 6e 20 3d 20 70 46 72 6f  ;.  int n = pFro
2740: 6d 2d 3e 6e 55 73 65 64 3b 0a 20 20 69 6e 74 20  m->nUsed;.  int 
2750: 69 20 3d 20 70 46 72 6f 6d 2d 3e 69 43 75 72 73  i = pFrom->iCurs
2760: 6f 72 3b 0a 0a 20 20 77 68 69 6c 65 28 20 69 3c  or;..  while( i<
2770: 6e 20 26 26 20 61 44 61 74 61 5b 69 5d 21 3d 27  n && aData[i]!='
2780: 5c 6e 27 20 29 7b 20 69 2b 2b 3b 20 7d 0a 20 20  \n' ){ i++; }.  
2790: 69 66 28 20 69 3c 6e 20 29 7b 0a 20 20 20 20 61  if( i<n ){.    a
27a0: 73 73 65 72 74 28 20 61 44 61 74 61 5b 69 5d 3d  ssert( aData[i]=
27b0: 3d 27 5c 6e 27 20 29 3b 0a 20 20 20 20 69 2b 2b  ='\n' );.    i++
27c0: 3b 0a 20 20 7d 0a 20 20 62 6c 6f 62 5f 65 78 74  ;.  }.  blob_ext
27d0: 72 61 63 74 28 70 46 72 6f 6d 2c 20 69 2d 70 46  ract(pFrom, i-pF
27e0: 72 6f 6d 2d 3e 69 43 75 72 73 6f 72 2c 20 70 54  rom->iCursor, pT
27f0: 6f 29 3b 0a 20 20 72 65 74 75 72 6e 20 70 54 6f  o);.  return pTo
2800: 2d 3e 6e 55 73 65 64 3b 0a 7d 0a 0a 2f 2a 0a 2a  ->nUsed;.}../*.*
2810: 2a 20 54 72 69 6d 20 77 68 69 74 65 73 70 61 63  * Trim whitespac
2820: 65 20 6f 66 66 20 6f 66 20 74 68 65 20 65 6e 64  e off of the end
2830: 20 6f 66 20 61 20 62 6c 6f 62 2e 20 20 52 65 74   of a blob.  Ret
2840: 75 72 6e 20 74 68 65 20 6e 75 6d 62 65 72 0a 2a  urn the number.*
2850: 2a 20 6f 66 20 63 68 61 72 61 63 74 65 72 73 20  * of characters 
2860: 72 65 6d 61 69 6e 69 6e 67 2e 0a 2a 2a 0a 2a 2a  remaining..**.**
2870: 20 41 6c 6c 20 74 68 69 73 20 64 6f 65 73 20 69   All this does i
2880: 73 20 72 65 64 75 63 65 20 74 68 65 20 6c 65 6e  s reduce the len
2890: 67 74 68 20 63 6f 75 6e 74 65 72 2e 20 20 54 68  gth counter.  Th
28a0: 69 73 20 72 6f 75 74 69 6e 65 20 64 6f 65 73 0a  is routine does.
28b0: 2a 2a 20 6e 6f 74 20 69 6e 73 65 72 74 20 61 20  ** not insert a 
28c0: 6e 65 77 20 7a 65 72 6f 20 74 65 72 6d 69 6e 61  new zero termina
28d0: 74 6f 72 2e 0a 2a 2f 0a 69 6e 74 20 62 6c 6f 62  tor..*/.int blob
28e0: 5f 74 72 69 6d 28 42 6c 6f 62 20 2a 70 29 7b 0a  _trim(Blob *p){.
28f0: 20 20 63 68 61 72 20 2a 7a 20 3d 20 70 2d 3e 61    char *z = p->a
2900: 44 61 74 61 3b 0a 20 20 69 6e 74 20 6e 20 3d 20  Data;.  int n = 
2910: 70 2d 3e 6e 55 73 65 64 3b 0a 20 20 77 68 69 6c  p->nUsed;.  whil
2920: 65 28 20 6e 3e 30 20 26 26 20 69 73 73 70 61 63  e( n>0 && isspac
2930: 65 28 7a 5b 6e 2d 31 5d 29 20 29 7b 20 6e 2d 2d  e(z[n-1]) ){ n--
2940: 3b 20 7d 0a 20 20 70 2d 3e 6e 55 73 65 64 20 3d  ; }.  p->nUsed =
2950: 20 6e 3b 0a 20 20 72 65 74 75 72 6e 20 6e 3b 0a   n;.  return n;.
2960: 7d 0a 0a 2f 2a 0a 2a 2a 20 45 78 74 72 61 63 74  }../*.** Extract
2970: 20 61 20 73 69 6e 67 6c 65 20 74 6f 6b 65 6e 20   a single token 
2980: 66 72 6f 6d 20 70 46 72 6f 6d 20 61 6e 64 20 75  from pFrom and u
2990: 73 65 20 69 74 20 74 6f 20 69 6e 69 74 69 61 6c  se it to initial
29a0: 69 7a 65 20 70 54 6f 2e 0a 2a 2a 20 52 65 74 75  ize pTo..** Retu
29b0: 72 6e 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  rn the number of
29c0: 20 62 79 74 65 73 20 69 6e 20 74 68 65 20 74 6f   bytes in the to
29d0: 6b 65 6e 2e 20 20 49 66 20 6e 6f 20 74 6f 6b 65  ken.  If no toke
29e0: 6e 20 69 73 20 66 6f 75 6e 64 2c 0a 2a 2a 20 72  n is found,.** r
29f0: 65 74 75 72 6e 20 30 2e 0a 2a 2a 0a 2a 2a 20 41  eturn 0..**.** A
2a00: 20 74 6f 6b 65 6e 20 63 6f 6e 73 69 73 74 73 20   token consists 
2a10: 6f 66 20 6f 6e 65 20 6f 72 20 6d 6f 72 65 20 6e  of one or more n
2a20: 6f 6e 2d 73 70 61 63 65 20 63 68 61 72 61 63 74  on-space charact
2a30: 65 72 73 2e 20 20 4c 65 61 64 69 6e 67 0a 2a 2a  ers.  Leading.**
2a40: 20 77 68 69 74 65 73 70 61 63 65 20 69 73 20 69   whitespace is i
2a50: 67 6e 6f 72 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68  gnored..**.** Th
2a60: 65 20 63 75 72 73 6f 72 20 6f 66 20 70 46 72 6f  e cursor of pFro
2a70: 6d 20 69 73 20 6c 65 66 74 20 70 6f 69 6e 74 69  m is left pointi
2a80: 6e 67 20 61 74 20 74 68 65 20 66 69 72 73 74 20  ng at the first 
2a90: 63 68 61 72 61 63 74 65 72 20 70 61 73 74 0a 2a  character past.*
2aa0: 2a 20 74 68 65 20 65 6e 64 20 6f 66 20 74 68 65  * the end of the
2ab0: 20 74 6f 6b 65 6e 2e 0a 2a 2a 0a 2a 2a 20 70 54   token..**.** pT
2ac0: 6f 20 77 69 6c 6c 20 62 65 20 61 6e 20 65 70 68  o will be an eph
2ad0: 65 72 6d 65 72 61 6c 20 62 6c 6f 62 2e 20 20 49  ermeral blob.  I
2ae0: 66 20 70 46 72 6f 6d 20 63 68 61 6e 67 65 73 2c  f pFrom changes,
2af0: 20 69 74 20 6d 69 67 68 74 20 61 6c 74 65 72 0a   it might alter.
2b00: 2a 2a 20 70 54 6f 20 61 73 20 77 65 6c 6c 2e 0a  ** pTo as well..
2b10: 2a 2f 0a 69 6e 74 20 62 6c 6f 62 5f 74 6f 6b 65  */.int blob_toke
2b20: 6e 28 42 6c 6f 62 20 2a 70 46 72 6f 6d 2c 20 42  n(Blob *pFrom, B
2b30: 6c 6f 62 20 2a 70 54 6f 29 7b 0a 20 20 63 68 61  lob *pTo){.  cha
2b40: 72 20 2a 61 44 61 74 61 20 3d 20 70 46 72 6f 6d  r *aData = pFrom
2b50: 2d 3e 61 44 61 74 61 3b 0a 20 20 69 6e 74 20 6e  ->aData;.  int n
2b60: 20 3d 20 70 46 72 6f 6d 2d 3e 6e 55 73 65 64 3b   = pFrom->nUsed;
2b70: 0a 20 20 69 6e 74 20 69 20 3d 20 70 46 72 6f 6d  .  int i = pFrom
2b80: 2d 3e 69 43 75 72 73 6f 72 3b 0a 20 20 77 68 69  ->iCursor;.  whi
2b90: 6c 65 28 20 69 3c 6e 20 26 26 20 69 73 73 70 61  le( i<n && isspa
2ba0: 63 65 28 61 44 61 74 61 5b 69 5d 29 20 29 7b 20  ce(aData[i]) ){ 
2bb0: 69 2b 2b 3b 20 7d 0a 20 20 70 46 72 6f 6d 2d 3e  i++; }.  pFrom->
2bc0: 69 43 75 72 73 6f 72 20 3d 20 69 3b 0a 20 20 77  iCursor = i;.  w
2bd0: 68 69 6c 65 28 20 69 3c 6e 20 26 26 20 21 69 73  hile( i<n && !is
2be0: 73 70 61 63 65 28 61 44 61 74 61 5b 69 5d 29 20  space(aData[i]) 
2bf0: 29 7b 20 69 2b 2b 3b 20 7d 0a 20 20 62 6c 6f 62  ){ i++; }.  blob
2c00: 5f 65 78 74 72 61 63 74 28 70 46 72 6f 6d 2c 20  _extract(pFrom, 
2c10: 69 2d 70 46 72 6f 6d 2d 3e 69 43 75 72 73 6f 72  i-pFrom->iCursor
2c20: 2c 20 70 54 6f 29 3b 0a 20 20 77 68 69 6c 65 28  , pTo);.  while(
2c30: 20 69 3c 6e 20 26 26 20 69 73 73 70 61 63 65 28   i<n && isspace(
2c40: 61 44 61 74 61 5b 69 5d 29 20 29 7b 20 69 2b 2b  aData[i]) ){ i++
2c50: 3b 20 7d 0a 20 20 70 46 72 6f 6d 2d 3e 69 43 75  ; }.  pFrom->iCu
2c60: 72 73 6f 72 20 3d 20 69 3b 0a 20 20 72 65 74 75  rsor = i;.  retu
2c70: 72 6e 20 70 54 6f 2d 3e 6e 55 73 65 64 3b 0a 7d  rn pTo->nUsed;.}
2c80: 0a 0a 2f 2a 0a 2a 2a 20 45 78 74 72 61 63 74 20  ../*.** Extract 
2c90: 65 76 65 72 79 74 68 69 6e 67 20 66 72 6f 6d 20  everything from 
2ca0: 74 68 65 20 63 75 72 72 65 6e 74 20 63 75 72 73  the current curs
2cb0: 6f 72 20 74 6f 20 74 68 65 20 65 6e 64 20 6f 66  or to the end of
2cc0: 20 74 68 65 20 62 6c 6f 62 0a 2a 2a 20 69 6e 74   the blob.** int
2cd0: 6f 20 61 20 6e 65 77 20 62 6c 6f 62 2e 20 20 54  o a new blob.  T
2ce0: 68 65 20 6e 65 77 20 62 6c 6f 62 20 69 73 20 61  he new blob is a
2cf0: 6e 20 65 70 68 65 6d 65 72 69 61 6c 20 72 65 66  n ephemerial ref
2d00: 65 72 65 6e 63 65 20 74 6f 20 74 68 65 0a 2a 2a  erence to the.**
2d10: 20 6f 72 69 67 69 6e 61 6c 20 62 6c 6f 62 2e 20   original blob. 
2d20: 20 54 68 65 20 63 75 72 73 6f 72 20 6f 66 20 74   The cursor of t
2d30: 68 65 20 6f 72 69 67 69 6e 61 6c 20 62 6c 6f 62  he original blob
2d40: 20 69 73 20 75 6e 63 68 61 6e 67 65 64 2e 0a 2a   is unchanged..*
2d50: 2f 0a 69 6e 74 20 62 6c 6f 62 5f 74 61 69 6c 28  /.int blob_tail(
2d60: 42 6c 6f 62 20 2a 70 46 72 6f 6d 2c 20 42 6c 6f  Blob *pFrom, Blo
2d70: 62 20 2a 70 54 6f 29 7b 0a 20 20 69 6e 74 20 69  b *pTo){.  int i
2d80: 43 75 72 73 6f 72 20 3d 20 70 46 72 6f 6d 2d 3e  Cursor = pFrom->
2d90: 69 43 75 72 73 6f 72 3b 0a 20 20 62 6c 6f 62 5f  iCursor;.  blob_
2da0: 65 78 74 72 61 63 74 28 70 46 72 6f 6d 2c 20 70  extract(pFrom, p
2db0: 46 72 6f 6d 2d 3e 6e 55 73 65 64 2d 70 46 72 6f  From->nUsed-pFro
2dc0: 6d 2d 3e 69 43 75 72 73 6f 72 2c 20 70 54 6f 29  m->iCursor, pTo)
2dd0: 3b 0a 20 20 70 46 72 6f 6d 2d 3e 69 43 75 72 73  ;.  pFrom->iCurs
2de0: 6f 72 20 3d 20 69 43 75 72 73 6f 72 3b 0a 20 20  or = iCursor;.  
2df0: 72 65 74 75 72 6e 20 70 54 6f 2d 3e 6e 55 73 65  return pTo->nUse
2e00: 64 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 70 79  d;.}../*.** Copy
2e10: 20 4e 20 6c 69 6e 65 73 20 6f 66 20 74 65 78 74   N lines of text
2e20: 20 66 72 6f 6d 20 70 46 72 6f 6d 20 69 6e 74 6f   from pFrom into
2e30: 20 70 54 6f 2e 20 20 54 68 65 20 63 6f 70 79 20   pTo.  The copy 
2e40: 62 65 67 69 6e 73 20 61 74 20 74 68 65 0a 2a 2a  begins at the.**
2e50: 20 63 75 72 72 65 6e 74 20 63 75 72 73 6f 72 20   current cursor 
2e60: 70 6f 73 69 74 69 6f 6e 20 6f 66 20 70 49 6e 2e  position of pIn.
2e70: 20 20 54 68 65 20 70 49 6e 20 63 75 72 73 6f 72    The pIn cursor
2e80: 20 69 73 20 6c 65 66 74 20 70 6f 69 6e 74 69 6e   is left pointin
2e90: 67 0a 2a 2a 20 61 74 20 74 68 65 20 66 69 72 73  g.** at the firs
2ea0: 74 20 63 68 61 72 61 63 74 65 72 20 70 61 73 74  t character past
2eb0: 20 74 68 65 20 6c 61 73 74 20 5c 6e 20 63 6f 70   the last \n cop
2ec0: 69 65 64 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 70 54  ied..**.** If pT
2ed0: 6f 3d 3d 4e 55 4c 4c 20 74 68 65 6e 20 74 68 69  o==NULL then thi
2ee0: 73 20 72 6f 75 74 69 6e 65 20 73 69 6d 70 6c 79  s routine simply
2ef0: 20 73 6b 69 70 73 20 6f 76 65 72 20 4e 20 6c 69   skips over N li
2f00: 6e 65 73 2e 0a 2a 2f 0a 76 6f 69 64 20 62 6c 6f  nes..*/.void blo
2f10: 62 5f 63 6f 70 79 5f 6c 69 6e 65 73 28 42 6c 6f  b_copy_lines(Blo
2f20: 62 20 2a 70 54 6f 2c 20 42 6c 6f 62 20 2a 70 46  b *pTo, Blob *pF
2f30: 72 6f 6d 2c 20 69 6e 74 20 4e 29 7b 0a 20 20 63  rom, int N){.  c
2f40: 68 61 72 20 2a 7a 20 3d 20 70 46 72 6f 6d 2d 3e  har *z = pFrom->
2f50: 61 44 61 74 61 3b 0a 20 20 69 6e 74 20 69 20 3d  aData;.  int i =
2f60: 20 70 46 72 6f 6d 2d 3e 69 43 75 72 73 6f 72 3b   pFrom->iCursor;
2f70: 0a 20 20 69 6e 74 20 6e 20 3d 20 70 46 72 6f 6d  .  int n = pFrom
2f80: 2d 3e 6e 55 73 65 64 3b 0a 20 20 69 6e 74 20 63  ->nUsed;.  int c
2f90: 6e 74 20 3d 20 30 3b 0a 0a 20 20 69 66 28 20 4e  nt = 0;..  if( N
2fa0: 3d 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a 20 20  ==0 ) return;.  
2fb0: 77 68 69 6c 65 28 20 69 3c 6e 20 29 7b 0a 20 20  while( i<n ){.  
2fc0: 20 20 69 66 28 20 7a 5b 69 5d 3d 3d 27 5c 6e 27    if( z[i]=='\n'
2fd0: 20 29 7b 0a 20 20 20 20 20 20 63 6e 74 2b 2b 3b   ){.      cnt++;
2fe0: 0a 20 20 20 20 20 20 69 66 28 20 63 6e 74 3d 3d  .      if( cnt==
2ff0: 4e 20 29 7b 0a 20 20 20 20 20 20 20 20 69 2b 2b  N ){.        i++
3000: 3b 0a 20 20 20 20 20 20 20 20 62 72 65 61 6b 3b  ;.        break;
3010: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
3020: 20 20 20 69 2b 2b 3b 0a 20 20 7d 0a 20 20 69 66     i++;.  }.  if
3030: 28 20 70 54 6f 20 29 7b 0a 20 20 20 20 62 6c 6f  ( pTo ){.    blo
3040: 62 5f 61 70 70 65 6e 64 28 70 54 6f 2c 20 26 70  b_append(pTo, &p
3050: 46 72 6f 6d 2d 3e 61 44 61 74 61 5b 70 46 72 6f  From->aData[pFro
3060: 6d 2d 3e 69 43 75 72 73 6f 72 5d 2c 20 69 20 2d  m->iCursor], i -
3070: 20 70 46 72 6f 6d 2d 3e 69 43 75 72 73 6f 72 29   pFrom->iCursor)
3080: 3b 0a 20 20 7d 0a 20 20 70 46 72 6f 6d 2d 3e 69  ;.  }.  pFrom->i
3090: 43 75 72 73 6f 72 20 3d 20 69 3b 0a 7d 0a 0a 2f  Cursor = i;.}../
30a0: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 72 75 65  *.** Return true
30b0: 20 69 66 20 74 68 65 20 62 6c 6f 62 20 63 6f 6e   if the blob con
30c0: 74 61 69 6e 73 20 61 20 76 61 6c 69 64 20 55 55  tains a valid UU
30d0: 49 44 5f 53 49 5a 45 2d 64 69 67 69 74 20 62 61  ID_SIZE-digit ba
30e0: 73 65 31 36 20 69 64 65 6e 74 69 66 69 65 72 2e  se16 identifier.
30f0: 0a 2a 2f 0a 69 6e 74 20 62 6c 6f 62 5f 69 73 5f  .*/.int blob_is_
3100: 75 75 69 64 28 42 6c 6f 62 20 2a 70 42 6c 6f 62  uuid(Blob *pBlob
3110: 29 7b 0a 20 20 72 65 74 75 72 6e 20 62 6c 6f 62  ){.  return blob
3120: 5f 73 69 7a 65 28 70 42 6c 6f 62 29 3d 3d 55 55  _size(pBlob)==UU
3130: 49 44 5f 53 49 5a 45 0a 20 20 20 20 20 20 20 20  ID_SIZE.        
3140: 20 26 26 20 76 61 6c 69 64 61 74 65 31 36 28 62   && validate16(b
3150: 6c 6f 62 5f 62 75 66 66 65 72 28 70 42 6c 6f 62  lob_buffer(pBlob
3160: 29 2c 20 55 55 49 44 5f 53 49 5a 45 29 3b 0a 7d  ), UUID_SIZE);.}
3170: 0a 69 6e 74 20 62 6c 6f 62 5f 69 73 5f 75 75 69  .int blob_is_uui
3180: 64 5f 6e 28 42 6c 6f 62 20 2a 70 42 6c 6f 62 2c  d_n(Blob *pBlob,
3190: 20 69 6e 74 20 6e 29 7b 0a 20 20 72 65 74 75 72   int n){.  retur
31a0: 6e 20 62 6c 6f 62 5f 73 69 7a 65 28 70 42 6c 6f  n blob_size(pBlo
31b0: 62 29 3d 3d 6e 20 26 26 20 76 61 6c 69 64 61 74  b)==n && validat
31c0: 65 31 36 28 62 6c 6f 62 5f 62 75 66 66 65 72 28  e16(blob_buffer(
31d0: 70 42 6c 6f 62 29 2c 20 6e 29 3b 0a 7d 0a 0a 2f  pBlob), n);.}../
31e0: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 72 75 65  *.** Return true
31f0: 20 69 66 20 74 68 65 20 62 6c 6f 62 20 63 6f 6e   if the blob con
3200: 74 61 69 6e 73 20 61 20 76 61 6c 69 64 20 33 32  tains a valid 32
3210: 2d 62 69 74 20 69 6e 74 65 67 65 72 2e 20 20 53  -bit integer.  S
3220: 74 6f 72 65 0a 2a 2a 20 74 68 65 20 69 6e 74 65  tore.** the inte
3230: 67 65 72 20 76 61 6c 75 65 20 69 6e 20 2a 70 56  ger value in *pV
3240: 61 6c 75 65 2e 0a 2a 2f 0a 69 6e 74 20 62 6c 6f  alue..*/.int blo
3250: 62 5f 69 73 5f 69 6e 74 28 42 6c 6f 62 20 2a 70  b_is_int(Blob *p
3260: 42 6c 6f 62 2c 20 69 6e 74 20 2a 70 56 61 6c 75  Blob, int *pValu
3270: 65 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  e){.  const char
3280: 20 2a 7a 20 3d 20 62 6c 6f 62 5f 62 75 66 66 65   *z = blob_buffe
3290: 72 28 70 42 6c 6f 62 29 3b 0a 20 20 69 6e 74 20  r(pBlob);.  int 
32a0: 69 2c 20 6e 2c 20 63 2c 20 76 3b 0a 20 20 6e 20  i, n, c, v;.  n 
32b0: 3d 20 62 6c 6f 62 5f 73 69 7a 65 28 70 42 6c 6f  = blob_size(pBlo
32c0: 62 29 3b 0a 20 20 76 20 3d 20 30 3b 0a 20 20 66  b);.  v = 0;.  f
32d0: 6f 72 28 69 3d 30 3b 20 69 3c 6e 20 26 26 20 28  or(i=0; i<n && (
32e0: 63 20 3d 20 7a 5b 69 5d 29 21 3d 30 20 26 26 20  c = z[i])!=0 && 
32f0: 69 73 64 69 67 69 74 28 63 29 3b 20 69 2b 2b 29  isdigit(c); i++)
3300: 7b 0a 20 20 20 20 76 20 3d 20 76 2a 31 30 20 2b  {.    v = v*10 +
3310: 20 63 20 2d 20 27 30 27 3b 0a 20 20 7d 0a 20 20   c - '0';.  }.  
3320: 69 66 28 20 69 3d 3d 6e 20 29 7b 0a 20 20 20 20  if( i==n ){.    
3330: 2a 70 56 61 6c 75 65 20 3d 20 76 3b 0a 20 20 20  *pValue = v;.   
3340: 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 7d 65 6c   return 1;.  }el
3350: 73 65 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 30  se{.    return 0
3360: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 5a  ;.  }.}../*.** Z
3370: 65 72 6f 20 6f 72 20 72 65 73 65 74 20 61 6e 20  ero or reset an 
3380: 61 72 72 61 79 20 6f 66 20 42 6c 6f 62 73 2e 0a  array of Blobs..
3390: 2a 2f 0a 76 6f 69 64 20 62 6c 6f 62 61 72 72 61  */.void blobarra
33a0: 79 5f 7a 65 72 6f 28 42 6c 6f 62 20 2a 61 42 6c  y_zero(Blob *aBl
33b0: 6f 62 2c 20 69 6e 74 20 6e 29 7b 0a 20 20 69 6e  ob, int n){.  in
33c0: 74 20 69 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20  t i;.  for(i=0; 
33d0: 69 3c 6e 3b 20 69 2b 2b 29 20 62 6c 6f 62 5f 7a  i<n; i++) blob_z
33e0: 65 72 6f 28 26 61 42 6c 6f 62 5b 69 5d 29 3b 0a  ero(&aBlob[i]);.
33f0: 7d 0a 76 6f 69 64 20 62 6c 6f 62 61 72 72 61 79  }.void blobarray
3400: 5f 72 65 73 65 74 28 42 6c 6f 62 20 2a 61 42 6c  _reset(Blob *aBl
3410: 6f 62 2c 20 69 6e 74 20 6e 29 7b 0a 20 20 69 6e  ob, int n){.  in
3420: 74 20 69 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20  t i;.  for(i=0; 
3430: 69 3c 6e 3b 20 69 2b 2b 29 20 62 6c 6f 62 5f 72  i<n; i++) blob_r
3440: 65 73 65 74 28 26 61 42 6c 6f 62 5b 69 5d 29 3b  eset(&aBlob[i]);
3450: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 61 72 73 65 20  .}../*.** Parse 
3460: 61 20 62 6c 6f 62 20 69 6e 74 6f 20 73 70 61 63  a blob into spac
3470: 65 2d 73 65 70 61 72 61 74 65 64 20 74 6f 6b 65  e-separated toke
3480: 6e 73 2e 20 20 53 74 6f 72 65 20 65 61 63 68 20  ns.  Store each 
3490: 74 6f 6b 65 6e 20 69 6e 0a 2a 2a 20 61 6e 20 65  token in.** an e
34a0: 6c 65 6d 65 6e 74 20 6f 66 20 74 68 65 20 62 6c  lement of the bl
34b0: 6f 62 61 72 72 61 79 20 61 54 6f 6b 65 6e 5b 5d  obarray aToken[]
34c0: 2e 20 20 61 54 6f 6b 65 6e 5b 5d 20 69 73 20 6e  .  aToken[] is n
34d0: 54 6f 6b 65 6e 20 65 6c 65 6d 65 6e 74 73 20 69  Token elements i
34e0: 6e 0a 2a 2a 20 73 69 7a 65 2e 20 20 52 65 74 75  n.** size.  Retu
34f0: 72 6e 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  rn the number of
3500: 20 74 6f 6b 65 6e 73 20 73 65 65 6e 2e 0a 2a 2f   tokens seen..*/
3510: 0a 69 6e 74 20 62 6c 6f 62 5f 74 6f 6b 65 6e 69  .int blob_tokeni
3520: 7a 65 28 42 6c 6f 62 20 2a 70 49 6e 2c 20 42 6c  ze(Blob *pIn, Bl
3530: 6f 62 20 2a 61 54 6f 6b 65 6e 2c 20 69 6e 74 20  ob *aToken, int 
3540: 6e 54 6f 6b 65 6e 29 7b 0a 20 20 69 6e 74 20 69  nToken){.  int i
3550: 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e  ;.  for(i=0; i<n
3560: 54 6f 6b 65 6e 20 26 26 20 62 6c 6f 62 5f 74 6f  Token && blob_to
3570: 6b 65 6e 28 70 49 6e 2c 20 26 61 54 6f 6b 65 6e  ken(pIn, &aToken
3580: 5b 69 5d 29 3b 20 69 2b 2b 29 7b 7d 0a 20 20 72  [i]); i++){}.  r
3590: 65 74 75 72 6e 20 69 3b 0a 7d 0a 0a 2f 2a 20 0a  eturn i;.}../* .
35a0: 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e  ** This function
35b0: 20 69 6d 70 6c 65 6d 65 6e 74 73 20 74 68 65 20   implements the 
35c0: 63 61 6c 6c 62 61 63 6b 20 66 72 6f 6d 20 76 78  callback from vx
35d0: 70 72 69 6e 74 66 2e 20 0a 2a 2a 0a 2a 2a 20 54  printf. .**.** T
35e0: 68 69 73 20 72 6f 75 74 69 6e 65 20 61 64 64 20  his routine add 
35f0: 6e 4e 65 77 43 68 61 72 20 63 68 61 72 61 63 74  nNewChar charact
3600: 65 72 73 20 6f 66 20 74 65 78 74 20 69 6e 20 7a  ers of text in z
3610: 4e 65 77 54 65 78 74 20 74 6f 0a 2a 2a 20 74 68  NewText to.** th
3620: 65 20 42 6c 6f 62 20 73 74 72 75 63 74 75 72 65  e Blob structure
3630: 20 70 6f 69 6e 74 65 64 20 74 6f 20 62 79 20 22   pointed to by "
3640: 61 72 67 22 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  arg"..*/.static 
3650: 76 6f 69 64 20 62 6f 75 74 28 76 6f 69 64 20 2a  void bout(void *
3660: 61 72 67 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  arg, const char 
3670: 2a 7a 4e 65 77 54 65 78 74 2c 20 69 6e 74 20 6e  *zNewText, int n
3680: 4e 65 77 43 68 61 72 29 7b 0a 20 20 42 6c 6f 62  NewChar){.  Blob
3690: 20 2a 70 42 6c 6f 62 20 3d 20 28 42 6c 6f 62 2a   *pBlob = (Blob*
36a0: 29 61 72 67 3b 0a 20 20 62 6c 6f 62 5f 61 70 70  )arg;.  blob_app
36b0: 65 6e 64 28 70 42 6c 6f 62 2c 20 7a 4e 65 77 54  end(pBlob, zNewT
36c0: 65 78 74 2c 20 6e 4e 65 77 43 68 61 72 29 3b 0a  ext, nNewChar);.
36d0: 7d 0a 0a 2f 2a 0a 2a 2a 20 44 6f 20 70 72 69 6e  }../*.** Do prin
36e0: 74 66 2d 73 74 79 6c 65 20 73 74 72 69 6e 67 20  tf-style string 
36f0: 72 65 6e 64 65 72 69 6e 67 20 61 6e 64 20 61 70  rendering and ap
3700: 70 65 6e 64 20 74 68 65 20 72 65 73 75 6c 74 73  pend the results
3710: 20 74 6f 20 61 20 62 6c 6f 62 2e 0a 2a 2f 0a 76   to a blob..*/.v
3720: 6f 69 64 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66  oid blob_appendf
3730: 28 42 6c 6f 62 20 2a 70 42 6c 6f 62 2c 20 63 6f  (Blob *pBlob, co
3740: 6e 73 74 20 63 68 61 72 20 2a 7a 46 6f 72 6d 61  nst char *zForma
3750: 74 2c 20 2e 2e 2e 29 7b 0a 20 20 76 61 5f 6c 69  t, ...){.  va_li
3760: 73 74 20 61 70 3b 0a 20 20 76 61 5f 73 74 61 72  st ap;.  va_star
3770: 74 28 61 70 2c 20 7a 46 6f 72 6d 61 74 29 3b 0a  t(ap, zFormat);.
3780: 20 20 76 78 70 72 69 6e 74 66 28 62 6f 75 74 2c    vxprintf(bout,
3790: 20 70 42 6c 6f 62 2c 20 7a 46 6f 72 6d 61 74 2c   pBlob, zFormat,
37a0: 20 61 70 29 3b 0a 20 20 76 61 5f 65 6e 64 28 61   ap);.  va_end(a
37b0: 70 29 3b 0a 7d 0a 76 6f 69 64 20 62 6c 6f 62 5f  p);.}.void blob_
37c0: 76 61 70 70 65 6e 64 66 28 42 6c 6f 62 20 2a 70  vappendf(Blob *p
37d0: 42 6c 6f 62 2c 20 63 6f 6e 73 74 20 63 68 61 72  Blob, const char
37e0: 20 2a 7a 46 6f 72 6d 61 74 2c 20 76 61 5f 6c 69   *zFormat, va_li
37f0: 73 74 20 61 70 29 7b 0a 20 20 76 78 70 72 69 6e  st ap){.  vxprin
3800: 74 66 28 62 6f 75 74 2c 20 70 42 6c 6f 62 2c 20  tf(bout, pBlob, 
3810: 7a 46 6f 72 6d 61 74 2c 20 61 70 29 3b 0a 7d 0a  zFormat, ap);.}.
3820: 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 61 6c 69 7a 65  ./*.** Initalize
3830: 20 61 20 62 6c 6f 62 20 74 6f 20 74 68 65 20 64   a blob to the d
3840: 61 74 61 20 6f 6e 20 61 6e 20 69 6e 70 75 74 20  ata on an input 
3850: 63 68 61 6e 6e 65 6c 2e 20 20 52 65 74 75 72 6e  channel.  Return
3860: 20 0a 2a 2a 20 74 68 65 20 6e 75 6d 62 65 72 20   .** the number 
3870: 6f 66 20 62 79 74 65 73 20 72 65 61 64 20 69 6e  of bytes read in
3880: 74 6f 20 74 68 65 20 62 6c 6f 62 2e 20 20 41 6e  to the blob.  An
3890: 79 20 70 72 69 6f 72 20 63 6f 6e 74 65 6e 74 0a  y prior content.
38a0: 2a 2a 20 6f 66 20 74 68 65 20 62 6c 6f 62 20 69  ** of the blob i
38b0: 73 20 64 69 73 63 61 72 64 65 64 2c 20 6e 6f 74  s discarded, not
38c0: 20 66 72 65 65 64 2e 0a 2a 2f 0a 69 6e 74 20 62   freed..*/.int b
38d0: 6c 6f 62 5f 72 65 61 64 5f 66 72 6f 6d 5f 63 68  lob_read_from_ch
38e0: 61 6e 6e 65 6c 28 42 6c 6f 62 20 2a 70 42 6c 6f  annel(Blob *pBlo
38f0: 62 2c 20 46 49 4c 45 20 2a 69 6e 2c 20 69 6e 74  b, FILE *in, int
3900: 20 6e 54 6f 52 65 61 64 29 7b 0a 20 20 73 69 7a   nToRead){.  siz
3910: 65 5f 74 20 6e 3b 0a 20 20 62 6c 6f 62 5f 7a 65  e_t n;.  blob_ze
3920: 72 6f 28 70 42 6c 6f 62 29 3b 0a 20 20 69 66 28  ro(pBlob);.  if(
3930: 20 6e 54 6f 52 65 61 64 3c 30 20 29 7b 0a 20 20   nToRead<0 ){.  
3940: 20 20 63 68 61 72 20 7a 42 75 66 5b 31 30 30 30    char zBuf[1000
3950: 30 5d 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 21  0];.    while( !
3960: 66 65 6f 66 28 69 6e 29 20 29 7b 0a 20 20 20 20  feof(in) ){.    
3970: 20 20 6e 20 3d 20 66 72 65 61 64 28 7a 42 75 66    n = fread(zBuf
3980: 2c 20 31 2c 20 73 69 7a 65 6f 66 28 7a 42 75 66  , 1, sizeof(zBuf
3990: 29 2c 20 69 6e 29 3b 0a 20 20 20 20 20 20 69 66  ), in);.      if
39a0: 28 20 6e 3e 30 20 29 7b 0a 20 20 20 20 20 20 20  ( n>0 ){.       
39b0: 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28 70 42 6c   blob_append(pBl
39c0: 6f 62 2c 20 7a 42 75 66 2c 20 6e 29 3b 0a 20 20  ob, zBuf, n);.  
39d0: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 65      }.    }.  }e
39e0: 6c 73 65 7b 0a 20 20 20 20 62 6c 6f 62 5f 72 65  lse{.    blob_re
39f0: 73 69 7a 65 28 70 42 6c 6f 62 2c 20 6e 54 6f 52  size(pBlob, nToR
3a00: 65 61 64 29 3b 0a 20 20 20 20 6e 20 3d 20 66 72  ead);.    n = fr
3a10: 65 61 64 28 62 6c 6f 62 5f 62 75 66 66 65 72 28  ead(blob_buffer(
3a20: 70 42 6c 6f 62 29 2c 20 31 2c 20 6e 54 6f 52 65  pBlob), 1, nToRe
3a30: 61 64 2c 20 69 6e 29 3b 0a 20 20 20 20 62 6c 6f  ad, in);.    blo
3a40: 62 5f 72 65 73 69 7a 65 28 70 42 6c 6f 62 2c 20  b_resize(pBlob, 
3a50: 6e 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  n);.  }.  return
3a60: 20 62 6c 6f 62 5f 73 69 7a 65 28 70 42 6c 6f 62   blob_size(pBlob
3a70: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 69 74  );.}../*.** Init
3a80: 69 61 6c 69 7a 65 20 61 20 62 6c 6f 62 20 74 6f  ialize a blob to
3a90: 20 62 65 20 74 68 65 20 63 6f 6e 74 65 6e 74 20   be the content 
3aa0: 6f 66 20 61 20 66 69 6c 65 2e 20 20 49 66 20 74  of a file.  If t
3ab0: 68 65 20 66 69 6c 65 6e 61 6d 65 0a 2a 2a 20 69  he filename.** i
3ac0: 73 20 62 6c 61 6e 6b 20 6f 72 20 22 2d 22 20 74  s blank or "-" t
3ad0: 68 65 6e 20 72 65 61 64 20 66 72 6f 6d 20 73 74  hen read from st
3ae0: 61 6e 64 61 72 64 20 69 6e 70 75 74 2e 0a 2a 2a  andard input..**
3af0: 0a 2a 2a 20 41 6e 79 20 70 72 69 6f 72 20 63 6f  .** Any prior co
3b00: 6e 74 65 6e 74 20 6f 66 20 74 68 65 20 62 6c 6f  ntent of the blo
3b10: 62 20 69 73 20 64 69 73 63 61 72 64 65 64 2c 20  b is discarded, 
3b20: 6e 6f 74 20 66 72 65 65 64 2e 0a 2a 2a 0a 2a 2a  not freed..**.**
3b30: 20 52 65 74 75 72 6e 20 74 68 65 20 6e 75 6d 62   Return the numb
3b40: 65 72 20 6f 66 20 62 79 74 65 73 20 72 65 61 64  er of bytes read
3b50: 2e 20 20 52 65 74 75 72 6e 20 2d 31 20 66 6f 72  .  Return -1 for
3b60: 20 61 6e 20 65 72 72 6f 72 2e 0a 2a 2f 0a 69 6e   an error..*/.in
3b70: 74 20 62 6c 6f 62 5f 72 65 61 64 5f 66 72 6f 6d  t blob_read_from
3b80: 5f 66 69 6c 65 28 42 6c 6f 62 20 2a 70 42 6c 6f  _file(Blob *pBlo
3b90: 62 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  b, const char *z
3ba0: 46 69 6c 65 6e 61 6d 65 29 7b 0a 20 20 69 6e 74  Filename){.  int
3bb0: 20 73 69 7a 65 2c 20 67 6f 74 3b 0a 20 20 46 49   size, got;.  FI
3bc0: 4c 45 20 2a 69 6e 3b 0a 20 20 69 66 28 20 7a 46  LE *in;.  if( zF
3bd0: 69 6c 65 6e 61 6d 65 3d 3d 30 20 7c 7c 20 7a 46  ilename==0 || zF
3be0: 69 6c 65 6e 61 6d 65 5b 30 5d 3d 3d 30 0a 20 20  ilename[0]==0.  
3bf0: 20 20 20 20 20 20 7c 7c 20 28 7a 46 69 6c 65 6e        || (zFilen
3c00: 61 6d 65 5b 30 5d 3d 3d 27 2d 27 20 26 26 20 7a  ame[0]=='-' && z
3c10: 46 69 6c 65 6e 61 6d 65 5b 31 5d 3d 3d 30 29 20  Filename[1]==0) 
3c20: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 62 6c  ){.    return bl
3c30: 6f 62 5f 72 65 61 64 5f 66 72 6f 6d 5f 63 68 61  ob_read_from_cha
3c40: 6e 6e 65 6c 28 70 42 6c 6f 62 2c 20 73 74 64 69  nnel(pBlob, stdi
3c50: 6e 2c 20 2d 31 29 3b 0a 20 20 7d 0a 20 20 73 69  n, -1);.  }.  si
3c60: 7a 65 20 3d 20 66 69 6c 65 5f 73 69 7a 65 28 7a  ze = file_size(z
3c70: 46 69 6c 65 6e 61 6d 65 29 3b 0a 20 20 62 6c 6f  Filename);.  blo
3c80: 62 5f 7a 65 72 6f 28 70 42 6c 6f 62 29 3b 0a 20  b_zero(pBlob);. 
3c90: 20 69 66 28 20 73 69 7a 65 3c 30 20 29 7b 0a 20   if( size<0 ){. 
3ca0: 20 20 20 66 6f 73 73 69 6c 5f 70 61 6e 69 63 28     fossil_panic(
3cb0: 22 6e 6f 20 73 75 63 68 20 66 69 6c 65 3a 20 25  "no such file: %
3cc0: 73 22 2c 20 7a 46 69 6c 65 6e 61 6d 65 29 3b 0a  s", zFilename);.
3cd0: 20 20 7d 0a 20 20 69 66 28 20 73 69 7a 65 3d 3d    }.  if( size==
3ce0: 30 20 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20  0 ){.    return 
3cf0: 30 3b 0a 20 20 7d 0a 20 20 62 6c 6f 62 5f 72 65  0;.  }.  blob_re
3d00: 73 69 7a 65 28 70 42 6c 6f 62 2c 20 73 69 7a 65  size(pBlob, size
3d10: 29 3b 0a 20 20 69 6e 20 3d 20 66 6f 70 65 6e 28  );.  in = fopen(
3d20: 7a 46 69 6c 65 6e 61 6d 65 2c 20 22 72 62 22 29  zFilename, "rb")
3d30: 3b 0a 20 20 69 66 28 20 69 6e 3d 3d 30 20 29 7b  ;.  if( in==0 ){
3d40: 0a 20 20 20 20 66 6f 73 73 69 6c 5f 70 61 6e 69  .    fossil_pani
3d50: 63 28 22 63 61 6e 6e 6f 74 20 6f 70 65 6e 20 25  c("cannot open %
3d60: 73 20 66 6f 72 20 72 65 61 64 69 6e 67 22 2c 20  s for reading", 
3d70: 7a 46 69 6c 65 6e 61 6d 65 29 3b 0a 20 20 7d 0a  zFilename);.  }.
3d80: 20 20 67 6f 74 20 3d 20 66 72 65 61 64 28 62 6c    got = fread(bl
3d90: 6f 62 5f 62 75 66 66 65 72 28 70 42 6c 6f 62 29  ob_buffer(pBlob)
3da0: 2c 20 31 2c 20 73 69 7a 65 2c 20 69 6e 29 3b 0a  , 1, size, in);.
3db0: 20 20 66 63 6c 6f 73 65 28 69 6e 29 3b 0a 20 20    fclose(in);.  
3dc0: 69 66 28 20 67 6f 74 3c 73 69 7a 65 20 29 7b 0a  if( got<size ){.
3dd0: 20 20 20 20 62 6c 6f 62 5f 72 65 73 69 7a 65 28      blob_resize(
3de0: 70 42 6c 6f 62 2c 20 67 6f 74 29 3b 0a 20 20 7d  pBlob, got);.  }
3df0: 0a 20 20 72 65 74 75 72 6e 20 67 6f 74 3b 0a 7d  .  return got;.}
3e00: 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65 20 74 68  ../*.** Write th
3e10: 65 20 63 6f 6e 74 65 6e 74 20 6f 66 20 61 20 62  e content of a b
3e20: 6c 6f 62 20 69 6e 74 6f 20 61 20 66 69 6c 65 2e  lob into a file.
3e30: 0a 2a 2a 0a 2a 2a 20 49 66 20 74 68 65 20 66 69  .**.** If the fi
3e40: 6c 65 6e 61 6d 65 20 69 73 20 62 6c 61 6e 6b 20  lename is blank 
3e50: 6f 72 20 22 2d 22 20 74 68 65 6e 20 77 72 69 74  or "-" then writ
3e60: 65 20 74 6f 20 73 74 61 6e 64 61 72 64 20 6f 75  e to standard ou
3e70: 74 70 75 74 2e 0a 2a 2a 0a 2a 2a 20 52 65 74 75  tput..**.** Retu
3e80: 72 6e 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66  rn the number of
3e90: 20 62 79 74 65 73 20 77 72 69 74 74 65 6e 2e 0a   bytes written..
3ea0: 2a 2f 0a 69 6e 74 20 62 6c 6f 62 5f 77 72 69 74  */.int blob_writ
3eb0: 65 5f 74 6f 5f 66 69 6c 65 28 42 6c 6f 62 20 2a  e_to_file(Blob *
3ec0: 70 42 6c 6f 62 2c 20 63 6f 6e 73 74 20 63 68 61  pBlob, const cha
3ed0: 72 20 2a 7a 46 69 6c 65 6e 61 6d 65 29 7b 0a 20  r *zFilename){. 
3ee0: 20 46 49 4c 45 20 2a 6f 75 74 3b 0a 20 20 69 6e   FILE *out;.  in
3ef0: 74 20 6e 65 65 64 54 6f 43 6c 6f 73 65 3b 0a 20  t needToClose;. 
3f00: 20 69 6e 74 20 77 72 6f 74 65 3b 0a 0a 20 20 69   int wrote;..  i
3f10: 66 28 20 7a 46 69 6c 65 6e 61 6d 65 5b 30 5d 3d  f( zFilename[0]=
3f20: 3d 30 20 7c 7c 20 28 7a 46 69 6c 65 6e 61 6d 65  =0 || (zFilename
3f30: 5b 30 5d 3d 3d 27 2d 27 20 26 26 20 7a 46 69 6c  [0]=='-' && zFil
3f40: 65 6e 61 6d 65 5b 31 5d 3d 3d 30 29 20 29 7b 0a  ename[1]==0) ){.
3f50: 20 20 20 20 6f 75 74 20 3d 20 73 74 64 6f 75 74      out = stdout
3f60: 3b 0a 20 20 20 20 6e 65 65 64 54 6f 43 6c 6f 73  ;.    needToClos
3f70: 65 20 3d 20 30 3b 0a 20 20 7d 65 6c 73 65 7b 0a  e = 0;.  }else{.
3f80: 20 20 20 20 69 6e 74 20 69 2c 20 6e 4e 61 6d 65      int i, nName
3f90: 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a 4e 61 6d  ;.    char *zNam
3fa0: 65 2c 20 7a 42 75 66 5b 31 30 30 30 5d 3b 0a 0a  e, zBuf[1000];..
3fb0: 20 20 20 20 6e 4e 61 6d 65 20 3d 20 73 74 72 6c      nName = strl
3fc0: 65 6e 28 7a 46 69 6c 65 6e 61 6d 65 29 3b 0a 20  en(zFilename);. 
3fd0: 20 20 20 69 66 28 20 6e 4e 61 6d 65 3e 3d 73 69     if( nName>=si
3fe0: 7a 65 6f 66 28 7a 42 75 66 29 20 29 7b 0a 20 20  zeof(zBuf) ){.  
3ff0: 20 20 20 20 7a 4e 61 6d 65 20 3d 20 6d 70 72 69      zName = mpri
4000: 6e 74 66 28 22 25 73 22 2c 20 7a 46 69 6c 65 6e  ntf("%s", zFilen
4010: 61 6d 65 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  ame);.    }else{
4020: 0a 20 20 20 20 20 20 7a 4e 61 6d 65 20 3d 20 7a  .      zName = z
4030: 42 75 66 3b 0a 20 20 20 20 20 20 73 74 72 63 70  Buf;.      strcp
4040: 79 28 7a 4e 61 6d 65 2c 20 7a 46 69 6c 65 6e 61  y(zName, zFilena
4050: 6d 65 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 6e  me);.    }.    n
4060: 4e 61 6d 65 20 3d 20 66 69 6c 65 5f 73 69 6d 70  Name = file_simp
4070: 6c 69 66 79 5f 6e 61 6d 65 28 7a 4e 61 6d 65 2c  lify_name(zName,
4080: 20 6e 4e 61 6d 65 29 3b 0a 20 20 20 20 66 6f 72   nName);.    for
4090: 28 69 3d 31 3b 20 69 3c 6e 4e 61 6d 65 3b 20 69  (i=1; i<nName; i
40a0: 2b 2b 29 7b 0a 20 20 20 20 20 20 69 66 28 20 7a  ++){.      if( z
40b0: 4e 61 6d 65 5b 69 5d 3d 3d 27 2f 27 20 29 7b 0a  Name[i]=='/' ){.
40c0: 20 20 20 20 20 20 20 20 7a 4e 61 6d 65 5b 69 5d          zName[i]
40d0: 20 3d 20 30 3b 0a 23 69 66 64 65 66 20 5f 5f 4d   = 0;.#ifdef __M
40e0: 49 4e 47 57 33 32 5f 5f 0a 20 20 20 20 20 20 20  INGW32__.       
40f0: 20 2f 2a 0a 20 20 20 20 20 20 20 20 2a 2a 20 4f   /*.        ** O
4100: 6e 20 57 69 6e 64 6f 77 73 2c 20 6c 6f 63 61 6c  n Windows, local
4110: 20 70 61 74 68 20 6c 6f 6f 6b 73 20 6c 69 6b 65   path looks like
4120: 3a 20 43 3a 2f 64 65 76 65 6c 6f 70 2f 70 72 6f  : C:/develop/pro
4130: 6a 65 63 74 2f 66 69 6c 65 2e 74 78 74 0a 20 20  ject/file.txt.  
4140: 20 20 20 20 20 20 2a 2a 20 54 68 65 20 69 66 20        ** The if 
4150: 73 74 6f 70 73 20 75 73 20 66 72 6f 6d 20 74 72  stops us from tr
4160: 79 69 6e 67 20 74 6f 20 63 72 65 61 74 65 20 61  ying to create a
4170: 20 64 69 72 65 63 74 6f 72 79 20 6f 66 20 61 20   directory of a 
4180: 64 72 69 76 65 20 6c 65 74 74 65 72 0a 20 20 20  drive letter.   
4190: 20 20 20 20 20 2a 2a 20 43 3a 20 69 6e 20 74 68       ** C: in th
41a0: 69 73 20 65 78 61 6d 70 6c 65 2e 0a 20 20 20 20  is example..    
41b0: 20 20 20 20 2a 2f 0a 20 20 20 20 20 20 20 20 69      */.        i
41c0: 66 28 20 21 28 69 3d 3d 32 20 26 26 20 7a 4e 61  f( !(i==2 && zNa
41d0: 6d 65 5b 31 5d 3d 3d 27 3a 27 29 20 29 7b 0a 23  me[1]==':') ){.#
41e0: 65 6e 64 69 66 0a 20 20 20 20 20 20 20 20 20 20  endif.          
41f0: 69 66 28 20 66 69 6c 65 5f 6d 6b 64 69 72 28 7a  if( file_mkdir(z
4200: 4e 61 6d 65 2c 20 31 29 20 29 7b 0a 20 20 20 20  Name, 1) ){.    
4210: 20 20 20 20 20 20 20 20 66 6f 73 73 69 6c 5f 70          fossil_p
4220: 61 6e 69 63 28 22 75 6e 61 62 6c 65 20 74 6f 20  anic("unable to 
4230: 63 72 65 61 74 65 20 64 69 72 65 63 74 6f 72 79  create directory
4240: 20 25 73 22 2c 20 7a 4e 61 6d 65 29 3b 0a 20 20   %s", zName);.  
4250: 20 20 20 20 20 20 20 20 7d 0a 23 69 66 64 65 66          }.#ifdef
4260: 20 5f 5f 4d 49 4e 47 57 33 32 5f 5f 0a 20 20 20   __MINGW32__.   
4270: 20 20 20 20 20 7d 0a 23 65 6e 64 69 66 0a 20 20       }.#endif.  
4280: 20 20 20 20 20 20 7a 4e 61 6d 65 5b 69 5d 20 3d        zName[i] =
4290: 20 27 2f 27 3b 0a 20 20 20 20 20 20 7d 0a 20 20   '/';.      }.  
42a0: 20 20 7d 0a 20 20 20 20 6f 75 74 20 3d 20 66 6f    }.    out = fo
42b0: 70 65 6e 28 7a 4e 61 6d 65 2c 20 22 77 62 22 29  pen(zName, "wb")
42c0: 3b 0a 20 20 20 20 69 66 28 20 6f 75 74 3d 3d 30  ;.    if( out==0
42d0: 20 29 7b 0a 20 20 20 20 20 20 66 6f 73 73 69 6c   ){.      fossil
42e0: 5f 70 61 6e 69 63 28 22 75 6e 61 62 6c 65 20 74  _panic("unable t
42f0: 6f 20 6f 70 65 6e 20 66 69 6c 65 20 5c 22 25 73  o open file \"%s
4300: 5c 22 20 66 6f 72 20 77 72 69 74 69 6e 67 22 2c  \" for writing",
4310: 20 7a 4e 61 6d 65 29 3b 0a 20 20 20 20 7d 0a 20   zName);.    }. 
4320: 20 20 20 6e 65 65 64 54 6f 43 6c 6f 73 65 20 3d     needToClose =
4330: 20 31 3b 0a 20 20 20 20 69 66 28 20 7a 4e 61 6d   1;.    if( zNam
4340: 65 21 3d 7a 42 75 66 20 29 20 66 72 65 65 28 7a  e!=zBuf ) free(z
4350: 4e 61 6d 65 29 3b 0a 20 20 7d 0a 20 20 62 6c 6f  Name);.  }.  blo
4360: 62 5f 69 73 5f 69 6e 69 74 28 70 42 6c 6f 62 29  b_is_init(pBlob)
4370: 3b 0a 20 20 77 72 6f 74 65 20 3d 20 66 77 72 69  ;.  wrote = fwri
4380: 74 65 28 62 6c 6f 62 5f 62 75 66 66 65 72 28 70  te(blob_buffer(p
4390: 42 6c 6f 62 29 2c 20 31 2c 20 62 6c 6f 62 5f 73  Blob), 1, blob_s
43a0: 69 7a 65 28 70 42 6c 6f 62 29 2c 20 6f 75 74 29  ize(pBlob), out)
43b0: 3b 0a 20 20 69 66 28 20 6e 65 65 64 54 6f 43 6c  ;.  if( needToCl
43c0: 6f 73 65 20 29 20 66 63 6c 6f 73 65 28 6f 75 74  ose ) fclose(out
43d0: 29 3b 0a 20 20 69 66 28 20 77 72 6f 74 65 21 3d  );.  if( wrote!=
43e0: 62 6c 6f 62 5f 73 69 7a 65 28 70 42 6c 6f 62 29  blob_size(pBlob)
43f0: 20 29 7b 0a 20 20 20 20 66 6f 73 73 69 6c 5f 70   ){.    fossil_p
4400: 61 6e 69 63 28 22 73 68 6f 72 74 20 77 72 69 74  anic("short writ
4410: 65 3a 20 25 64 20 6f 66 20 25 64 20 62 79 74 65  e: %d of %d byte
4420: 73 20 74 6f 20 25 73 22 2c 20 77 72 6f 74 65 2c  s to %s", wrote,
4430: 0a 20 20 20 20 20 20 20 62 6c 6f 62 5f 73 69 7a  .       blob_siz
4440: 65 28 70 42 6c 6f 62 29 2c 20 7a 46 69 6c 65 6e  e(pBlob), zFilen
4450: 61 6d 65 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75  ame);.  }.  retu
4460: 72 6e 20 77 72 6f 74 65 3b 0a 7d 0a 0a 2f 2a 0a  rn wrote;.}../*.
4470: 2a 2a 20 43 6f 6d 70 72 65 73 73 20 61 20 62 6c  ** Compress a bl
4480: 6f 62 20 70 49 6e 2e 20 20 53 74 6f 72 65 20 74  ob pIn.  Store t
4490: 68 65 20 72 65 73 75 6c 74 20 69 6e 20 70 4f 75  he result in pOu
44a0: 74 2e 20 20 49 74 20 69 73 20 6f 6b 20 66 6f 72  t.  It is ok for
44b0: 20 70 49 6e 20 61 6e 64 0a 2a 2a 20 70 4f 75 74   pIn and.** pOut
44c0: 20 74 6f 20 62 65 20 74 68 65 20 73 61 6d 65 20   to be the same 
44d0: 62 6c 6f 62 2e 20 0a 2a 2a 20 0a 2a 2a 20 70 4f  blob. .** .** pO
44e0: 75 74 20 6d 75 73 74 20 65 69 74 68 65 72 20 62  ut must either b
44f0: 65 20 74 68 65 20 73 61 6d 65 20 61 73 20 70 49  e the same as pI
4500: 6e 20 6f 72 20 65 6c 73 65 20 75 6e 69 6e 69 74  n or else uninit
4510: 69 61 6c 69 7a 65 64 2e 0a 2a 2f 0a 76 6f 69 64  ialized..*/.void
4520: 20 62 6c 6f 62 5f 63 6f 6d 70 72 65 73 73 28 42   blob_compress(B
4530: 6c 6f 62 20 2a 70 49 6e 2c 20 42 6c 6f 62 20 2a  lob *pIn, Blob *
4540: 70 4f 75 74 29 7b 0a 20 20 75 6e 73 69 67 6e 65  pOut){.  unsigne
4550: 64 20 69 6e 74 20 6e 49 6e 20 3d 20 62 6c 6f 62  d int nIn = blob
4560: 5f 73 69 7a 65 28 70 49 6e 29 3b 0a 20 20 75 6e  _size(pIn);.  un
4570: 73 69 67 6e 65 64 20 69 6e 74 20 6e 4f 75 74 20  signed int nOut 
4580: 3d 20 31 33 20 2b 20 6e 49 6e 20 2b 20 28 6e 49  = 13 + nIn + (nI
4590: 6e 2b 39 39 39 29 2f 31 30 30 30 3b 0a 20 20 75  n+999)/1000;.  u
45a0: 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 69 6e 74  nsigned long int
45b0: 20 6e 4f 75 74 32 3b 0a 20 20 75 6e 73 69 67 6e   nOut2;.  unsign
45c0: 65 64 20 63 68 61 72 20 2a 6f 75 74 42 75 66 3b  ed char *outBuf;
45d0: 0a 20 20 42 6c 6f 62 20 74 65 6d 70 3b 0a 20 20  .  Blob temp;.  
45e0: 62 6c 6f 62 5f 7a 65 72 6f 28 26 74 65 6d 70 29  blob_zero(&temp)
45f0: 3b 0a 20 20 62 6c 6f 62 5f 72 65 73 69 7a 65 28  ;.  blob_resize(
4600: 26 74 65 6d 70 2c 20 6e 4f 75 74 2b 34 29 3b 0a  &temp, nOut+4);.
4610: 20 20 6f 75 74 42 75 66 20 3d 20 28 75 6e 73 69    outBuf = (unsi
4620: 67 6e 65 64 20 63 68 61 72 2a 29 62 6c 6f 62 5f  gned char*)blob_
4630: 62 75 66 66 65 72 28 26 74 65 6d 70 29 3b 0a 20  buffer(&temp);. 
4640: 20 6f 75 74 42 75 66 5b 30 5d 20 3d 20 6e 49 6e   outBuf[0] = nIn
4650: 3e 3e 32 34 20 26 20 30 78 66 66 3b 0a 20 20 6f  >>24 & 0xff;.  o
4660: 75 74 42 75 66 5b 31 5d 20 3d 20 6e 49 6e 3e 3e  utBuf[1] = nIn>>
4670: 31 36 20 26 20 30 78 66 66 3b 0a 20 20 6f 75 74  16 & 0xff;.  out
4680: 42 75 66 5b 32 5d 20 3d 20 6e 49 6e 3e 3e 38 20  Buf[2] = nIn>>8 
4690: 26 20 30 78 66 66 3b 0a 20 20 6f 75 74 42 75 66  & 0xff;.  outBuf
46a0: 5b 33 5d 20 3d 20 6e 49 6e 20 26 20 30 78 66 66  [3] = nIn & 0xff
46b0: 3b 0a 20 20 6e 4f 75 74 32 20 3d 20 28 6c 6f 6e  ;.  nOut2 = (lon
46c0: 67 20 69 6e 74 29 6e 4f 75 74 3b 0a 20 20 63 6f  g int)nOut;.  co
46d0: 6d 70 72 65 73 73 28 26 6f 75 74 42 75 66 5b 34  mpress(&outBuf[4
46e0: 5d 2c 20 26 6e 4f 75 74 32 2c 0a 20 20 20 20 20  ], &nOut2,.     
46f0: 20 20 20 20 20 20 28 75 6e 73 69 67 6e 65 64 20        (unsigned 
4700: 63 68 61 72 2a 29 62 6c 6f 62 5f 62 75 66 66 65  char*)blob_buffe
4710: 72 28 70 49 6e 29 2c 20 62 6c 6f 62 5f 73 69 7a  r(pIn), blob_siz
4720: 65 28 70 49 6e 29 29 3b 0a 20 20 69 66 28 20 70  e(pIn));.  if( p
4730: 4f 75 74 3d 3d 70 49 6e 20 29 20 62 6c 6f 62 5f  Out==pIn ) blob_
4740: 72 65 73 65 74 28 70 4f 75 74 29 3b 0a 20 20 62  reset(pOut);.  b
4750: 6c 6f 62 5f 69 73 5f 72 65 73 65 74 28 70 4f 75  lob_is_reset(pOu
4760: 74 29 3b 0a 20 20 2a 70 4f 75 74 20 3d 20 74 65  t);.  *pOut = te
4770: 6d 70 3b 0a 20 20 62 6c 6f 62 5f 72 65 73 69 7a  mp;.  blob_resiz
4780: 65 28 70 4f 75 74 2c 20 6e 4f 75 74 32 2b 34 29  e(pOut, nOut2+4)
4790: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 4f 4d 4d 41  ;.}../*.** COMMA
47a0: 4e 44 3a 20 74 65 73 74 2d 63 6f 6d 70 72 65 73  ND: test-compres
47b0: 73 0a 2a 2f 0a 76 6f 69 64 20 63 6f 6d 70 72 65  s.*/.void compre
47c0: 73 73 5f 63 6d 64 28 76 6f 69 64 29 7b 0a 20 20  ss_cmd(void){.  
47d0: 42 6c 6f 62 20 66 3b 0a 20 20 69 66 28 20 67 2e  Blob f;.  if( g.
47e0: 61 72 67 63 21 3d 34 20 29 20 75 73 61 67 65 28  argc!=4 ) usage(
47f0: 22 49 4e 50 55 54 46 49 4c 45 20 4f 55 54 50 55  "INPUTFILE OUTPU
4800: 54 46 49 4c 45 22 29 3b 0a 20 20 62 6c 6f 62 5f  TFILE");.  blob_
4810: 72 65 61 64 5f 66 72 6f 6d 5f 66 69 6c 65 28 26  read_from_file(&
4820: 66 2c 20 67 2e 61 72 67 76 5b 32 5d 29 3b 0a 20  f, g.argv[2]);. 
4830: 20 62 6c 6f 62 5f 63 6f 6d 70 72 65 73 73 28 26   blob_compress(&
4840: 66 2c 20 26 66 29 3b 0a 20 20 62 6c 6f 62 5f 77  f, &f);.  blob_w
4850: 72 69 74 65 5f 74 6f 5f 66 69 6c 65 28 26 66 2c  rite_to_file(&f,
4860: 20 67 2e 61 72 67 76 5b 33 5d 29 3b 0a 7d 0a 0a   g.argv[3]);.}..
4870: 2f 2a 0a 2a 2a 20 43 6f 6d 70 72 65 73 73 20 74  /*.** Compress t
4880: 68 65 20 63 6f 6e 63 61 74 65 6e 61 74 69 6f 6e  he concatenation
4890: 20 6f 66 20 61 20 62 6c 6f 62 73 20 70 49 6e 31   of a blobs pIn1
48a0: 20 61 6e 64 20 70 49 6e 32 2e 20 20 53 74 6f 72   and pIn2.  Stor
48b0: 65 20 74 68 65 20 72 65 73 75 6c 74 20 0a 2a 2a  e the result .**
48c0: 20 69 6e 20 70 4f 75 74 2e 20 0a 2a 2a 20 0a 2a   in pOut. .** .*
48d0: 2a 20 70 4f 75 74 20 6d 75 73 74 20 62 65 20 65  * pOut must be e
48e0: 69 74 68 65 72 20 75 6e 69 6e 69 74 69 61 6c 69  ither uninitiali
48f0: 7a 65 64 20 6f 72 20 6d 75 73 74 20 62 65 20 74  zed or must be t
4900: 68 65 20 73 61 6d 65 20 61 73 20 65 69 74 68 65  he same as eithe
4910: 72 20 70 49 6e 31 20 6f 72 0a 2a 2a 20 70 49 6e  r pIn1 or.** pIn
4920: 32 2e 0a 2a 2f 0a 76 6f 69 64 20 62 6c 6f 62 5f  2..*/.void blob_
4930: 63 6f 6d 70 72 65 73 73 32 28 42 6c 6f 62 20 2a  compress2(Blob *
4940: 70 49 6e 31 2c 20 42 6c 6f 62 20 2a 70 49 6e 32  pIn1, Blob *pIn2
4950: 2c 20 42 6c 6f 62 20 2a 70 4f 75 74 29 7b 0a 20  , Blob *pOut){. 
4960: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 49   unsigned int nI
4970: 6e 20 3d 20 62 6c 6f 62 5f 73 69 7a 65 28 70 49  n = blob_size(pI
4980: 6e 31 29 20 2b 20 62 6c 6f 62 5f 73 69 7a 65 28  n1) + blob_size(
4990: 70 49 6e 32 29 3b 0a 20 20 75 6e 73 69 67 6e 65  pIn2);.  unsigne
49a0: 64 20 69 6e 74 20 6e 4f 75 74 20 3d 20 31 33 20  d int nOut = 13 
49b0: 2b 20 6e 49 6e 20 2b 20 28 6e 49 6e 2b 39 39 39  + nIn + (nIn+999
49c0: 29 2f 31 30 30 30 3b 0a 20 20 75 6e 73 69 67 6e  )/1000;.  unsign
49d0: 65 64 20 63 68 61 72 20 2a 6f 75 74 42 75 66 3b  ed char *outBuf;
49e0: 0a 20 20 7a 5f 73 74 72 65 61 6d 20 73 74 72 65  .  z_stream stre
49f0: 61 6d 3b 0a 20 20 42 6c 6f 62 20 74 65 6d 70 3b  am;.  Blob temp;
4a00: 0a 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 26 74 65  .  blob_zero(&te
4a10: 6d 70 29 3b 0a 20 20 62 6c 6f 62 5f 72 65 73 69  mp);.  blob_resi
4a20: 7a 65 28 26 74 65 6d 70 2c 20 6e 4f 75 74 2b 34  ze(&temp, nOut+4
4a30: 29 3b 0a 20 20 6f 75 74 42 75 66 20 3d 20 28 75  );.  outBuf = (u
4a40: 6e 73 69 67 6e 65 64 20 63 68 61 72 2a 29 62 6c  nsigned char*)bl
4a50: 6f 62 5f 62 75 66 66 65 72 28 26 74 65 6d 70 29  ob_buffer(&temp)
4a60: 3b 0a 20 20 6f 75 74 42 75 66 5b 30 5d 20 3d 20  ;.  outBuf[0] = 
4a70: 6e 49 6e 3e 3e 32 34 20 26 20 30 78 66 66 3b 0a  nIn>>24 & 0xff;.
4a80: 20 20 6f 75 74 42 75 66 5b 31 5d 20 3d 20 6e 49    outBuf[1] = nI
4a90: 6e 3e 3e 31 36 20 26 20 30 78 66 66 3b 0a 20 20  n>>16 & 0xff;.  
4aa0: 6f 75 74 42 75 66 5b 32 5d 20 3d 20 6e 49 6e 3e  outBuf[2] = nIn>
4ab0: 3e 38 20 26 20 30 78 66 66 3b 0a 20 20 6f 75 74  >8 & 0xff;.  out
4ac0: 42 75 66 5b 33 5d 20 3d 20 6e 49 6e 20 26 20 30  Buf[3] = nIn & 0
4ad0: 78 66 66 3b 0a 20 20 73 74 72 65 61 6d 2e 7a 61  xff;.  stream.za
4ae0: 6c 6c 6f 63 20 3d 20 28 61 6c 6c 6f 63 5f 66 75  lloc = (alloc_fu
4af0: 6e 63 29 30 3b 0a 20 20 73 74 72 65 61 6d 2e 7a  nc)0;.  stream.z
4b00: 66 72 65 65 20 3d 20 28 66 72 65 65 5f 66 75 6e  free = (free_fun
4b10: 63 29 30 3b 0a 20 20 73 74 72 65 61 6d 2e 6f 70  c)0;.  stream.op
4b20: 61 71 75 65 20 3d 20 30 3b 0a 20 20 73 74 72 65  aque = 0;.  stre
4b30: 61 6d 2e 61 76 61 69 6c 5f 6f 75 74 20 3d 20 6e  am.avail_out = n
4b40: 4f 75 74 3b 0a 20 20 73 74 72 65 61 6d 2e 6e 65  Out;.  stream.ne
4b50: 78 74 5f 6f 75 74 20 3d 20 26 6f 75 74 42 75 66  xt_out = &outBuf
4b60: 5b 34 5d 3b 0a 20 20 64 65 66 6c 61 74 65 49 6e  [4];.  deflateIn
4b70: 69 74 28 26 73 74 72 65 61 6d 2c 20 39 29 3b 0a  it(&stream, 9);.
4b80: 20 20 73 74 72 65 61 6d 2e 61 76 61 69 6c 5f 69    stream.avail_i
4b90: 6e 20 3d 20 62 6c 6f 62 5f 73 69 7a 65 28 70 49  n = blob_size(pI
4ba0: 6e 31 29 3b 0a 20 20 73 74 72 65 61 6d 2e 6e 65  n1);.  stream.ne
4bb0: 78 74 5f 69 6e 20 3d 20 28 75 6e 73 69 67 6e 65  xt_in = (unsigne
4bc0: 64 20 63 68 61 72 2a 29 62 6c 6f 62 5f 62 75 66  d char*)blob_buf
4bd0: 66 65 72 28 70 49 6e 31 29 3b 0a 20 20 64 65 66  fer(pIn1);.  def
4be0: 6c 61 74 65 28 26 73 74 72 65 61 6d 2c 20 30 29  late(&stream, 0)
4bf0: 3b 0a 20 20 73 74 72 65 61 6d 2e 61 76 61 69 6c  ;.  stream.avail
4c00: 5f 69 6e 20 3d 20 62 6c 6f 62 5f 73 69 7a 65 28  _in = blob_size(
4c10: 70 49 6e 32 29 3b 0a 20 20 73 74 72 65 61 6d 2e  pIn2);.  stream.
4c20: 6e 65 78 74 5f 69 6e 20 3d 20 28 75 6e 73 69 67  next_in = (unsig
4c30: 6e 65 64 20 63 68 61 72 2a 29 62 6c 6f 62 5f 62  ned char*)blob_b
4c40: 75 66 66 65 72 28 70 49 6e 32 29 3b 0a 20 20 64  uffer(pIn2);.  d
4c50: 65 66 6c 61 74 65 28 26 73 74 72 65 61 6d 2c 20  eflate(&stream, 
4c60: 30 29 3b 0a 20 20 64 65 66 6c 61 74 65 28 26 73  0);.  deflate(&s
4c70: 74 72 65 61 6d 2c 20 5a 5f 46 49 4e 49 53 48 29  tream, Z_FINISH)
4c80: 3b 0a 20 20 62 6c 6f 62 5f 72 65 73 69 7a 65 28  ;.  blob_resize(
4c90: 26 74 65 6d 70 2c 20 73 74 72 65 61 6d 2e 74 6f  &temp, stream.to
4ca0: 74 61 6c 5f 6f 75 74 20 2b 20 34 29 3b 0a 20 20  tal_out + 4);.  
4cb0: 64 65 66 6c 61 74 65 45 6e 64 28 26 73 74 72 65  deflateEnd(&stre
4cc0: 61 6d 29 3b 0a 20 20 69 66 28 20 70 4f 75 74 3d  am);.  if( pOut=
4cd0: 3d 70 49 6e 31 20 29 20 62 6c 6f 62 5f 72 65 73  =pIn1 ) blob_res
4ce0: 65 74 28 70 4f 75 74 29 3b 0a 20 20 69 66 28 20  et(pOut);.  if( 
4cf0: 70 4f 75 74 3d 3d 70 49 6e 32 20 29 20 62 6c 6f  pOut==pIn2 ) blo
4d00: 62 5f 72 65 73 65 74 28 70 4f 75 74 29 3b 0a 20  b_reset(pOut);. 
4d10: 20 62 6c 6f 62 5f 69 73 5f 72 65 73 65 74 28 70   blob_is_reset(p
4d20: 4f 75 74 29 3b 0a 20 20 2a 70 4f 75 74 20 3d 20  Out);.  *pOut = 
4d30: 74 65 6d 70 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43  temp;.}../*.** C
4d40: 4f 4d 4d 41 4e 44 3a 20 74 65 73 74 2d 63 6f 6d  OMMAND: test-com
4d50: 70 72 65 73 73 2d 32 0a 2a 2f 0a 76 6f 69 64 20  press-2.*/.void 
4d60: 63 6f 6d 70 72 65 73 73 32 5f 63 6d 64 28 76 6f  compress2_cmd(vo
4d70: 69 64 29 7b 0a 20 20 42 6c 6f 62 20 66 31 2c 20  id){.  Blob f1, 
4d80: 66 32 3b 0a 20 20 69 66 28 20 67 2e 61 72 67 63  f2;.  if( g.argc
4d90: 21 3d 35 20 29 20 75 73 61 67 65 28 22 49 4e 50  !=5 ) usage("INP
4da0: 55 54 46 49 4c 45 31 20 49 4e 50 55 54 46 49 4c  UTFILE1 INPUTFIL
4db0: 45 32 20 4f 55 54 50 55 54 46 49 4c 45 22 29 3b  E2 OUTPUTFILE");
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 31 2c 20 67 2e 61 72  m_file(&f1, g.ar
4de0: 67 76 5b 32 5d 29 3b 0a 20 20 62 6c 6f 62 5f 72  gv[2]);.  blob_r
4df0: 65 61 64 5f 66 72 6f 6d 5f 66 69 6c 65 28 26 66  ead_from_file(&f
4e00: 32 2c 20 67 2e 61 72 67 76 5b 33 5d 29 3b 0a 20  2, g.argv[3]);. 
4e10: 20 62 6c 6f 62 5f 63 6f 6d 70 72 65 73 73 32 28   blob_compress2(
4e20: 26 66 31 2c 20 26 66 32 2c 20 26 66 31 29 3b 0a  &f1, &f2, &f1);.
4e30: 20 20 62 6c 6f 62 5f 77 72 69 74 65 5f 74 6f 5f    blob_write_to_
4e40: 66 69 6c 65 28 26 66 31 2c 20 67 2e 61 72 67 76  file(&f1, g.argv
4e50: 5b 34 5d 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 55  [4]);.}../*.** U
4e60: 6e 63 6f 6d 70 72 65 73 73 20 62 6c 6f 62 20 70  ncompress blob p
4e70: 49 6e 20 61 6e 64 20 73 74 6f 72 65 20 74 68 65  In and store the
4e80: 20 72 65 73 75 6c 74 20 69 6e 20 70 4f 75 74 2e   result in pOut.
4e90: 20 20 49 74 20 69 73 20 6f 6b 20 66 6f 72 20 70    It is ok for p
4ea0: 49 6e 20 61 6e 64 0a 2a 2a 20 70 4f 75 74 20 74  In and.** pOut t
4eb0: 6f 20 62 65 20 74 68 65 20 73 61 6d 65 20 62 6c  o be the same bl
4ec0: 6f 62 2e 0a 2a 2a 0a 2a 2a 20 70 4f 75 74 20 6d  ob..**.** pOut m
4ed0: 75 73 74 20 62 65 20 65 69 74 68 65 72 20 75 6e  ust be either un
4ee0: 69 6e 69 74 69 61 6c 69 7a 65 64 20 6f 72 20 74  initialized or t
4ef0: 68 65 20 73 61 6d 65 20 61 73 20 70 49 6e 2e 0a  he same as pIn..
4f00: 2a 2f 0a 69 6e 74 20 62 6c 6f 62 5f 75 6e 63 6f  */.int blob_unco
4f10: 6d 70 72 65 73 73 28 42 6c 6f 62 20 2a 70 49 6e  mpress(Blob *pIn
4f20: 2c 20 42 6c 6f 62 20 2a 70 4f 75 74 29 7b 0a 20  , Blob *pOut){. 
4f30: 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 6e 4f   unsigned int nO
4f40: 75 74 3b 0a 20 20 75 6e 73 69 67 6e 65 64 20 63  ut;.  unsigned c
4f50: 68 61 72 20 2a 69 6e 42 75 66 3b 0a 20 20 75 6e  har *inBuf;.  un
4f60: 73 69 67 6e 65 64 20 69 6e 74 20 6e 49 6e 20 3d  signed int nIn =
4f70: 20 62 6c 6f 62 5f 73 69 7a 65 28 70 49 6e 29 3b   blob_size(pIn);
4f80: 0a 20 20 42 6c 6f 62 20 74 65 6d 70 3b 0a 20 20  .  Blob temp;.  
4f90: 69 6e 74 20 72 63 3b 0a 20 20 75 6e 73 69 67 6e  int rc;.  unsign
4fa0: 65 64 20 6c 6f 6e 67 20 69 6e 74 20 6e 4f 75 74  ed long int nOut
4fb0: 32 3b 0a 20 20 69 66 28 20 6e 49 6e 3c 3d 34 20  2;.  if( nIn<=4 
4fc0: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b  ){.    return 0;
4fd0: 0a 20 20 7d 0a 20 20 69 6e 42 75 66 20 3d 20 28  .  }.  inBuf = (
4fe0: 75 6e 73 69 67 6e 65 64 20 63 68 61 72 2a 29 62  unsigned char*)b
4ff0: 6c 6f 62 5f 62 75 66 66 65 72 28 70 49 6e 29 3b  lob_buffer(pIn);
5000: 0a 20 20 6e 4f 75 74 20 3d 20 28 69 6e 42 75 66  .  nOut = (inBuf
5010: 5b 30 5d 3c 3c 32 34 29 20 2b 20 28 69 6e 42 75  [0]<<24) + (inBu
5020: 66 5b 31 5d 3c 3c 31 36 29 20 2b 20 28 69 6e 42  f[1]<<16) + (inB
5030: 75 66 5b 32 5d 3c 3c 38 29 20 2b 20 69 6e 42 75  uf[2]<<8) + inBu
5040: 66 5b 33 5d 3b 0a 20 20 62 6c 6f 62 5f 7a 65 72  f[3];.  blob_zer
5050: 6f 28 26 74 65 6d 70 29 3b 0a 20 20 62 6c 6f 62  o(&temp);.  blob
5060: 5f 72 65 73 69 7a 65 28 26 74 65 6d 70 2c 20 6e  _resize(&temp, n
5070: 4f 75 74 2b 31 29 3b 0a 20 20 6e 4f 75 74 32 20  Out+1);.  nOut2 
5080: 3d 20 28 6c 6f 6e 67 20 69 6e 74 29 6e 4f 75 74  = (long int)nOut
5090: 3b 0a 20 20 72 63 20 3d 20 75 6e 63 6f 6d 70 72  ;.  rc = uncompr
50a0: 65 73 73 28 28 75 6e 73 69 67 6e 65 64 20 63 68  ess((unsigned ch
50b0: 61 72 2a 29 62 6c 6f 62 5f 62 75 66 66 65 72 28  ar*)blob_buffer(
50c0: 26 74 65 6d 70 29 2c 20 26 6e 4f 75 74 32 2c 20  &temp), &nOut2, 
50d0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
50e0: 20 20 20 26 69 6e 42 75 66 5b 34 5d 2c 20 62 6c     &inBuf[4], bl
50f0: 6f 62 5f 73 69 7a 65 28 70 49 6e 29 29 3b 0a 20  ob_size(pIn));. 
5100: 20 69 66 28 20 72 63 21 3d 5a 5f 4f 4b 20 29 7b   if( rc!=Z_OK ){
5110: 0a 20 20 20 20 62 6c 6f 62 5f 72 65 73 65 74 28  .    blob_reset(
5120: 26 74 65 6d 70 29 3b 0a 20 20 20 20 72 65 74 75  &temp);.    retu
5130: 72 6e 20 31 3b 0a 20 20 7d 0a 20 20 62 6c 6f 62  rn 1;.  }.  blob
5140: 5f 72 65 73 69 7a 65 28 26 74 65 6d 70 2c 20 6e  _resize(&temp, n
5150: 4f 75 74 32 29 3b 0a 20 20 69 66 28 20 70 4f 75  Out2);.  if( pOu
5160: 74 3d 3d 70 49 6e 20 29 20 62 6c 6f 62 5f 72 65  t==pIn ) blob_re
5170: 73 65 74 28 70 4f 75 74 29 3b 0a 20 20 62 6c 6f  set(pOut);.  blo
5180: 62 5f 69 73 5f 72 65 73 65 74 28 70 4f 75 74 29  b_is_reset(pOut)
5190: 3b 0a 20 20 2a 70 4f 75 74 20 3d 20 74 65 6d 70  ;.  *pOut = temp
51a0: 3b 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a  ;.  return 0;.}.
51b0: 0a 2f 2a 0a 2a 2a 20 43 4f 4d 4d 41 4e 44 3a 20  ./*.** COMMAND: 
51c0: 74 65 73 74 2d 75 6e 63 6f 6d 70 72 65 73 73 0a  test-uncompress.
51d0: 2a 2f 0a 76 6f 69 64 20 75 6e 63 6f 6d 70 72 65  */.void uncompre
51e0: 73 73 5f 63 6d 64 28 76 6f 69 64 29 7b 0a 20 20  ss_cmd(void){.  
51f0: 42 6c 6f 62 20 66 3b 0a 20 20 69 66 28 20 67 2e  Blob f;.  if( g.
5200: 61 72 67 63 21 3d 34 20 29 20 75 73 61 67 65 28  argc!=4 ) usage(
5210: 22 49 4e 50 55 54 46 49 4c 45 20 4f 55 54 50 55  "INPUTFILE OUTPU
5220: 54 46 49 4c 45 22 29 3b 0a 20 20 62 6c 6f 62 5f  TFILE");.  blob_
5230: 72 65 61 64 5f 66 72 6f 6d 5f 66 69 6c 65 28 26  read_from_file(&
5240: 66 2c 20 67 2e 61 72 67 76 5b 32 5d 29 3b 0a 20  f, g.argv[2]);. 
5250: 20 62 6c 6f 62 5f 75 6e 63 6f 6d 70 72 65 73 73   blob_uncompress
5260: 28 26 66 2c 20 26 66 29 3b 0a 20 20 62 6c 6f 62  (&f, &f);.  blob
5270: 5f 77 72 69 74 65 5f 74 6f 5f 66 69 6c 65 28 26  _write_to_file(&
5280: 66 2c 20 67 2e 61 72 67 76 5b 33 5d 29 3b 0a 7d  f, g.argv[3]);.}
5290: 0a 0a 2f 2a 0a 2a 2a 20 43 4f 4d 4d 41 4e 44 3a  ../*.** COMMAND:
52a0: 20 74 65 73 74 2d 63 79 63 6c 65 2d 63 6f 6d 70   test-cycle-comp
52b0: 72 65 73 73 0a 2a 2a 0a 2a 2a 20 43 6f 6d 70 72  ress.**.** Compr
52c0: 65 73 73 20 61 6e 64 20 75 6e 63 6f 6d 70 72 65  ess and uncompre
52d0: 73 73 20 65 61 63 68 20 66 69 6c 65 20 6e 61 6d  ss each file nam
52e0: 65 64 20 6f 6e 20 74 68 65 20 63 6f 6d 6d 61 6e  ed on the comman
52f0: 64 20 6c 69 6e 65 2e 0a 2a 2a 20 56 65 72 69 66  d line..** Verif
5300: 79 20 74 68 61 74 20 74 68 65 20 6f 72 69 67 69  y that the origi
5310: 6e 61 6c 20 63 6f 6e 74 65 6e 74 20 69 73 20 72  nal content is r
5320: 65 63 6f 76 65 72 65 64 2e 0a 2a 2f 0a 76 6f 69  ecovered..*/.voi
5330: 64 20 74 65 73 74 5f 63 79 63 6c 65 5f 63 6f 6d  d test_cycle_com
5340: 70 72 65 73 73 28 76 6f 69 64 29 7b 0a 20 20 69  press(void){.  i
5350: 6e 74 20 69 3b 0a 20 20 42 6c 6f 62 20 62 31 2c  nt i;.  Blob b1,
5360: 20 62 32 2c 20 62 33 3b 0a 20 20 66 6f 72 28 69   b2, b3;.  for(i
5370: 3d 32 3b 20 69 3c 67 2e 61 72 67 63 3b 20 69 2b  =2; i<g.argc; i+
5380: 2b 29 7b 0a 20 20 20 20 62 6c 6f 62 5f 72 65 61  +){.    blob_rea
5390: 64 5f 66 72 6f 6d 5f 66 69 6c 65 28 26 62 31 2c  d_from_file(&b1,
53a0: 20 67 2e 61 72 67 76 5b 69 5d 29 3b 0a 20 20 20   g.argv[i]);.   
53b0: 20 62 6c 6f 62 5f 63 6f 6d 70 72 65 73 73 28 26   blob_compress(&
53c0: 62 31 2c 20 26 62 32 29 3b 0a 20 20 20 20 62 6c  b1, &b2);.    bl
53d0: 6f 62 5f 75 6e 63 6f 6d 70 72 65 73 73 28 26 62  ob_uncompress(&b
53e0: 32 2c 20 26 62 33 29 3b 0a 20 20 20 20 69 66 28  2, &b3);.    if(
53f0: 20 62 6c 6f 62 5f 63 6f 6d 70 61 72 65 28 26 62   blob_compare(&b
5400: 31 2c 20 26 62 33 29 20 29 7b 0a 20 20 20 20 20  1, &b3) ){.     
5410: 20 66 6f 73 73 69 6c 5f 70 61 6e 69 63 28 22 63   fossil_panic("c
5420: 6f 6d 70 72 65 73 73 2f 75 6e 63 6f 6d 70 72 65  ompress/uncompre
5430: 73 73 20 63 79 63 6c 65 20 66 61 69 6c 65 64 20  ss cycle failed 
5440: 66 6f 72 20 25 73 22 2c 20 67 2e 61 72 67 76 5b  for %s", g.argv[
5450: 69 5d 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 62  i]);.    }.    b
5460: 6c 6f 62 5f 72 65 73 65 74 28 26 62 31 29 3b 0a  lob_reset(&b1);.
5470: 20 20 20 20 62 6c 6f 62 5f 72 65 73 65 74 28 26      blob_reset(&
5480: 62 32 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 72 65  b2);.    blob_re
5490: 73 65 74 28 26 62 33 29 3b 0a 20 20 7d 0a 20 20  set(&b3);.  }.  
54a0: 70 72 69 6e 74 66 28 22 6f 6b 5c 6e 22 29 3b 0a  printf("ok\n");.
54b0: 7d 0a                                            }.