/ Hex Artifact Content
Login

Artifact 3777f22ec1057dc4e5fd89f2fbddcc7a29fbeef1ad038c736c54411bb1967af7:


0000: 2f 2a 0a 2a 2a 20 32 30 31 37 2d 31 30 2d 32 30  /*.** 2017-10-20
0010: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 61 75 74 68 6f  .**.** The autho
0020: 72 20 64 69 73 63 6c 61 69 6d 73 20 63 6f 70 79  r disclaims copy
0030: 72 69 67 68 74 20 74 6f 20 74 68 69 73 20 73 6f  right to this so
0040: 75 72 63 65 20 63 6f 64 65 2e 20 20 49 6e 20 70  urce code.  In p
0050: 6c 61 63 65 20 6f 66 0a 2a 2a 20 61 20 6c 65 67  lace of.** a leg
0060: 61 6c 20 6e 6f 74 69 63 65 2c 20 68 65 72 65 20  al notice, here 
0070: 69 73 20 61 20 62 6c 65 73 73 69 6e 67 3a 0a 2a  is a blessing:.*
0080: 2a 0a 2a 2a 20 20 20 20 4d 61 79 20 79 6f 75 20  *.**    May you 
0090: 64 6f 20 67 6f 6f 64 20 61 6e 64 20 6e 6f 74 20  do good and not 
00a0: 65 76 69 6c 2e 0a 2a 2a 20 20 20 20 4d 61 79 20  evil..**    May 
00b0: 79 6f 75 20 66 69 6e 64 20 66 6f 72 67 69 76 65  you find forgive
00c0: 6e 65 73 73 20 66 6f 72 20 79 6f 75 72 73 65 6c  ness for yoursel
00d0: 66 20 61 6e 64 20 66 6f 72 67 69 76 65 20 6f 74  f and forgive ot
00e0: 68 65 72 73 2e 0a 2a 2a 20 20 20 20 4d 61 79 20  hers..**    May 
00f0: 79 6f 75 20 73 68 61 72 65 20 66 72 65 65 6c 79  you share freely
0100: 2c 20 6e 65 76 65 72 20 74 61 6b 69 6e 67 20 6d  , never taking m
0110: 6f 72 65 20 74 68 61 6e 20 79 6f 75 20 67 69 76  ore than you giv
0120: 65 2e 0a 2a 2a 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  e..**.**********
0130: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0140: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0150: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0160: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0170: 2a 2a 2a 2a 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  ****.**.** This 
0180: 66 69 6c 65 20 69 6d 70 6c 65 6d 65 6e 74 73 20  file implements 
0190: 61 20 56 46 53 20 73 68 69 6d 20 74 68 61 74 20  a VFS shim that 
01a0: 61 6c 6c 6f 77 73 20 61 6e 20 53 51 4c 69 74 65  allows an SQLite
01b0: 20 64 61 74 61 62 61 73 65 20 74 6f 20 62 65 0a   database to be.
01c0: 2a 2a 20 61 70 70 65 6e 64 65 64 20 6f 6e 74 6f  ** appended onto
01d0: 20 74 68 65 20 65 6e 64 20 6f 66 20 73 6f 6d 65   the end of some
01e0: 20 6f 74 68 65 72 20 66 69 6c 65 2c 20 73 75 63   other file, suc
01f0: 68 20 61 73 20 61 6e 20 65 78 65 63 75 74 61 62  h as an executab
0200: 6c 65 2e 0a 2a 2a 0a 2a 2a 20 41 20 73 70 65 63  le..**.** A spec
0210: 69 61 6c 20 72 65 63 6f 72 64 20 6d 75 73 74 20  ial record must 
0220: 61 70 70 65 61 72 20 61 74 20 74 68 65 20 65 6e  appear at the en
0230: 64 20 6f 66 20 74 68 65 20 66 69 6c 65 20 74 68  d of the file th
0240: 61 74 20 69 64 65 6e 74 69 66 69 65 73 20 74 68  at identifies th
0250: 65 0a 2a 2a 20 66 69 6c 65 20 61 73 20 61 6e 20  e.** file as an 
0260: 61 70 70 65 6e 64 65 64 20 64 61 74 61 62 61 73  appended databas
0270: 65 20 61 6e 64 20 70 72 6f 76 69 64 65 73 20 61  e and provides a
0280: 6e 20 6f 66 66 73 65 74 20 74 6f 20 70 61 67 65  n offset to page
0290: 20 31 2e 20 20 46 6f 72 0a 2a 2a 20 62 65 73 74   1.  For.** best
02a0: 20 70 65 72 66 6f 72 6d 61 6e 63 65 20 70 61 67   performance pag
02b0: 65 20 31 20 73 68 6f 75 6c 64 20 62 65 20 6c 6f  e 1 should be lo
02c0: 63 61 74 65 64 20 61 74 20 61 20 64 69 73 6b 20  cated at a disk 
02d0: 70 61 67 65 20 62 6f 75 6e 64 61 72 79 2c 20 74  page boundary, t
02e0: 68 6f 75 67 68 0a 2a 2a 20 74 68 61 74 20 69 73  hough.** that is
02f0: 20 6e 6f 74 20 72 65 71 75 69 72 65 64 2e 0a 2a   not required..*
0300: 2a 0a 2a 2a 20 57 68 65 6e 20 6f 70 65 6e 69 6e  *.** When openin
0310: 67 20 61 20 64 61 74 61 62 61 73 65 20 75 73 69  g a database usi
0320: 6e 67 20 74 68 69 73 20 56 46 53 2c 20 74 68 65  ng this VFS, the
0330: 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 6d 69 67 68   connection migh
0340: 74 20 74 72 65 61 74 0a 2a 2a 20 74 68 65 20 66  t treat.** the f
0350: 69 6c 65 20 61 73 20 61 6e 20 6f 72 64 69 6e 61  ile as an ordina
0360: 72 79 20 53 51 4c 69 74 65 20 64 61 74 61 62 61  ry SQLite databa
0370: 73 65 2c 20 6f 72 20 69 74 20 6d 69 67 68 74 20  se, or it might 
0380: 74 72 65 61 74 20 69 73 20 61 73 20 61 0a 2a 2a  treat is as a.**
0390: 20 64 61 74 61 62 61 73 65 20 61 70 70 65 6e 64   database append
03a0: 65 64 20 6f 6e 74 6f 20 73 6f 6d 65 20 6f 74 68  ed onto some oth
03b0: 65 72 20 66 69 6c 65 2e 20 20 48 65 72 65 20 61  er file.  Here a
03c0: 72 65 20 74 68 65 20 72 75 6c 65 73 3a 0a 2a 2a  re the rules:.**
03d0: 0a 2a 2a 20 20 28 31 29 20 20 57 68 65 6e 20 6f  .**  (1)  When o
03e0: 70 65 6e 69 6e 67 20 61 20 6e 65 77 20 65 6d 70  pening a new emp
03f0: 74 79 20 66 69 6c 65 2c 20 74 68 61 74 20 66 69  ty file, that fi
0400: 6c 65 20 69 73 20 74 72 65 61 74 65 64 20 61 73  le is treated as
0410: 20 61 6e 20 6f 72 64 69 6e 61 72 79 0a 2a 2a 20   an ordinary.** 
0420: 20 20 20 20 20 20 64 61 74 61 62 61 73 65 2e 0a        database..
0430: 2a 2a 0a 2a 2a 20 20 28 32 29 20 20 57 68 65 6e  **.**  (2)  When
0440: 20 6f 70 65 6e 69 6e 67 20 61 20 66 69 6c 65 20   opening a file 
0450: 74 68 61 74 20 62 65 67 69 6e 73 20 77 69 74 68  that begins with
0460: 20 74 68 65 20 73 74 61 6e 64 61 72 64 20 53 51   the standard SQ
0470: 4c 69 74 65 20 70 72 65 66 69 78 0a 2a 2a 20 20  Lite prefix.**  
0480: 20 20 20 20 20 73 74 72 69 6e 67 20 22 53 51 4c       string "SQL
0490: 69 74 65 20 66 6f 72 6d 61 74 20 33 22 2c 20 74  ite format 3", t
04a0: 68 61 74 20 66 69 6c 65 20 69 73 20 74 72 65 61  hat file is trea
04b0: 74 65 64 20 61 73 20 61 6e 20 6f 72 64 69 6e 61  ted as an ordina
04c0: 72 79 0a 2a 2a 20 20 20 20 20 20 20 64 61 74 61  ry.**       data
04d0: 62 61 73 65 2e 0a 2a 2a 0a 2a 2a 20 20 28 33 29  base..**.**  (3)
04e0: 20 20 57 68 65 6e 20 6f 70 65 6e 69 6e 67 20 61    When opening a
04f0: 20 66 69 6c 65 20 74 68 61 74 20 65 6e 64 73 20   file that ends 
0500: 77 69 74 68 20 74 68 65 20 61 70 70 65 6e 64 76  with the appendv
0510: 66 73 20 74 72 61 69 6c 65 72 20 73 74 72 69 6e  fs trailer strin
0520: 67 0a 2a 2a 20 20 20 20 20 20 20 22 53 74 61 72  g.**       "Star
0530: 74 2d 4f 66 2d 53 51 4c 69 74 65 33 2d 4e 4e 4e  t-Of-SQLite3-NNN
0540: 4e 4e 4e 4e 4e 22 20 74 68 61 74 20 66 69 6c 65  NNNNN" that file
0550: 20 69 73 20 74 72 65 61 74 65 64 20 61 73 20 61   is treated as a
0560: 6e 20 61 70 70 65 6e 64 65 64 0a 2a 2a 20 20 20  n appended.**   
0570: 20 20 20 20 64 61 74 61 62 61 73 65 2e 0a 2a 2a      database..**
0580: 0a 2a 2a 20 20 28 34 29 20 20 49 66 20 6e 6f 6e  .**  (4)  If non
0590: 65 20 6f 66 20 74 68 65 20 61 62 6f 76 65 20 61  e of the above a
05a0: 70 70 6c 79 20 61 6e 64 20 74 68 65 20 53 51 4c  pply and the SQL
05b0: 49 54 45 5f 4f 50 45 4e 5f 43 52 45 41 54 45 20  ITE_OPEN_CREATE 
05c0: 66 6c 61 67 20 69 73 0a 2a 2a 20 20 20 20 20 20  flag is.**      
05d0: 20 73 65 74 2c 20 74 68 65 6e 20 61 20 6e 65 77   set, then a new
05e0: 20 64 61 74 61 62 61 73 65 20 69 73 20 61 70 70   database is app
05f0: 65 6e 64 65 64 20 74 6f 20 74 68 65 20 61 6c 72  ended to the alr
0600: 65 61 64 79 20 65 78 69 73 74 69 6e 67 20 66 69  eady existing fi
0610: 6c 65 2e 0a 2a 2a 0a 2a 2a 20 20 28 35 29 20 20  le..**.**  (5)  
0620: 4f 74 68 65 72 77 69 73 65 2c 20 53 51 4c 49 54  Otherwise, SQLIT
0630: 45 5f 43 41 4e 54 4f 50 45 4e 20 69 73 20 72 65  E_CANTOPEN is re
0640: 74 75 72 6e 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 6f  turned..**.** To
0650: 20 61 76 6f 69 64 20 75 6e 6e 65 63 65 73 73 61   avoid unnecessa
0660: 72 79 20 63 6f 6d 70 6c 69 63 61 74 69 6f 6e 73  ry complications
0670: 20 77 69 74 68 20 74 68 65 20 50 45 4e 44 49 4e   with the PENDIN
0680: 47 5f 42 59 54 45 2c 20 74 68 65 20 73 69 7a 65  G_BYTE, the size
0690: 20 6f 66 0a 2a 2a 20 74 68 65 20 66 69 6c 65 20   of.** the file 
06a0: 63 6f 6e 74 61 69 6e 69 6e 67 20 74 68 65 20 64  containing the d
06b0: 61 74 61 62 61 73 65 20 69 73 20 6c 69 6d 69 74  atabase is limit
06c0: 65 64 20 74 6f 20 31 47 42 2e 20 20 54 68 69 73  ed to 1GB.  This
06d0: 20 56 46 53 20 77 69 6c 6c 20 72 65 66 75 73 65   VFS will refuse
06e0: 0a 2a 2a 20 74 6f 20 72 65 61 64 20 6f 72 20 77  .** to read or w
06f0: 72 69 74 65 20 70 61 73 74 20 74 68 65 20 31 47  rite past the 1G
0700: 42 20 6d 61 72 6b 2e 20 20 54 68 69 73 20 72 65  B mark.  This re
0710: 73 74 72 69 63 74 69 6f 6e 20 6d 69 67 68 74 20  striction might 
0720: 62 65 20 6c 69 66 74 65 64 20 69 6e 0a 2a 2a 20  be lifted in.** 
0730: 66 75 74 75 72 65 20 76 65 72 73 69 6f 6e 73 2e  future versions.
0740: 20 20 46 6f 72 20 6e 6f 77 2c 20 69 66 20 79 6f    For now, if yo
0750: 75 20 6e 65 65 64 20 61 20 6c 61 72 67 65 20 64  u need a large d
0760: 61 74 61 62 61 73 65 2c 20 74 68 65 6e 20 6b 65  atabase, then ke
0770: 65 70 20 74 68 65 0a 2a 2a 20 64 61 74 61 62 61  ep the.** databa
0780: 73 65 20 69 6e 20 61 20 73 65 70 61 72 61 74 65  se in a separate
0790: 20 66 69 6c 65 2e 0a 2a 2a 0a 2a 2a 20 49 66 20   file..**.** If 
07a0: 74 68 65 20 66 69 6c 65 20 62 65 69 6e 67 20 6f  the file being o
07b0: 70 65 6e 65 64 20 69 73 20 6e 6f 74 20 61 6e 20  pened is not an 
07c0: 61 70 70 65 6e 64 65 64 20 64 61 74 61 62 61 73  appended databas
07d0: 65 2c 20 74 68 65 6e 20 74 68 69 73 20 73 68 69  e, then this shi
07e0: 6d 20 69 73 0a 2a 2a 20 61 20 70 61 73 73 2d 74  m is.** a pass-t
07f0: 68 72 6f 75 67 68 20 69 6e 74 6f 20 74 68 65 20  hrough into the 
0800: 64 65 66 61 75 6c 74 20 75 6e 64 65 72 6c 79 69  default underlyi
0810: 6e 67 20 56 46 53 2e 0a 2a 2a 2f 0a 23 69 6e 63  ng VFS..**/.#inc
0820: 6c 75 64 65 20 22 73 71 6c 69 74 65 33 65 78 74  lude "sqlite3ext
0830: 2e 68 22 0a 53 51 4c 49 54 45 5f 45 58 54 45 4e  .h".SQLITE_EXTEN
0840: 53 49 4f 4e 5f 49 4e 49 54 31 0a 23 69 6e 63 6c  SION_INIT1.#incl
0850: 75 64 65 20 3c 73 74 72 69 6e 67 2e 68 3e 0a 23  ude <string.h>.#
0860: 69 6e 63 6c 75 64 65 20 3c 61 73 73 65 72 74 2e  include <assert.
0870: 68 3e 0a 0a 2f 2a 20 54 68 65 20 61 70 70 65 6e  h>../* The appen
0880: 64 20 6d 61 72 6b 20 61 74 20 74 68 65 20 65 6e  d mark at the en
0890: 64 20 6f 66 20 74 68 65 20 64 61 74 61 62 61 73  d of the databas
08a0: 65 20 69 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20  e is:.**.**     
08b0: 53 74 61 72 74 2d 4f 66 2d 53 51 4c 69 74 65 33  Start-Of-SQLite3
08c0: 2d 4e 4e 4e 4e 4e 4e 4e 4e 0a 2a 2a 20 20 20 20  -NNNNNNNN.**    
08d0: 20 31 32 33 34 35 36 37 38 39 20 31 32 33 34 35   123456789 12345
08e0: 36 37 38 39 20 31 32 33 34 35 0a 2a 2a 0a 2a 2a  6789 12345.**.**
08f0: 20 54 68 65 20 4e 4e 4e 4e 4e 4e 4e 4e 20 72 65   The NNNNNNNN re
0900: 70 72 65 73 65 6e 74 73 20 61 20 36 34 2d 62 69  presents a 64-bi
0910: 74 20 62 69 67 2d 65 6e 64 69 61 6e 20 75 6e 73  t big-endian uns
0920: 69 67 6e 65 64 20 69 6e 74 65 67 65 72 20 77 68  igned integer wh
0930: 69 63 68 20 69 73 0a 2a 2a 20 74 68 65 20 6f 66  ich is.** the of
0940: 66 73 65 74 20 74 6f 20 70 61 67 65 20 31 2e 0a  fset to page 1..
0950: 2a 2f 0a 23 64 65 66 69 6e 65 20 41 50 4e 44 5f  */.#define APND_
0960: 4d 41 52 4b 5f 50 52 45 46 49 58 20 20 20 20 20  MARK_PREFIX     
0970: 22 53 74 61 72 74 2d 4f 66 2d 53 51 4c 69 74 65  "Start-Of-SQLite
0980: 33 2d 22 0a 23 64 65 66 69 6e 65 20 41 50 4e 44  3-".#define APND
0990: 5f 4d 41 52 4b 5f 50 52 45 46 49 58 5f 53 5a 20  _MARK_PREFIX_SZ 
09a0: 20 31 37 0a 23 64 65 66 69 6e 65 20 41 50 4e 44   17.#define APND
09b0: 5f 4d 41 52 4b 5f 53 49 5a 45 20 20 20 20 20 20  _MARK_SIZE      
09c0: 20 32 35 0a 0a 2f 2a 0a 2a 2a 20 4d 61 78 69 6d   25../*.** Maxim
09d0: 75 6d 20 73 69 7a 65 20 6f 66 20 74 68 65 20 63  um size of the c
09e0: 6f 6d 62 69 6e 65 64 20 70 72 65 66 69 78 20 2b  ombined prefix +
09f0: 20 64 61 74 61 62 61 73 65 20 2b 20 61 70 70 65   database + appe
0a00: 6e 64 2d 6d 61 72 6b 2e 20 20 54 68 69 73 0a 2a  nd-mark.  This.*
0a10: 2a 20 6d 75 73 74 20 62 65 20 6c 65 73 73 20 74  * must be less t
0a20: 68 61 6e 20 30 78 34 30 30 30 30 30 30 30 20 74  han 0x40000000 t
0a30: 6f 20 61 76 6f 69 64 20 6c 6f 63 6b 69 6e 67 20  o avoid locking 
0a40: 69 73 73 75 65 73 20 6f 6e 20 57 69 6e 64 6f 77  issues on Window
0a50: 73 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 41 50  s..*/.#define AP
0a60: 4e 44 5f 4d 41 58 5f 53 49 5a 45 20 20 28 36 35  ND_MAX_SIZE  (65
0a70: 35 33 36 2a 31 35 32 35 39 29 0a 0a 2f 2a 0a 2a  536*15259)../*.*
0a80: 2a 20 46 6f 72 77 61 72 64 20 64 65 63 6c 61 72  * Forward declar
0a90: 61 74 69 6f 6e 20 6f 66 20 6f 62 6a 65 63 74 73  ation of objects
0aa0: 20 75 73 65 64 20 62 79 20 74 68 69 73 20 75 74   used by this ut
0ab0: 69 6c 69 74 79 0a 2a 2f 0a 74 79 70 65 64 65 66  ility.*/.typedef
0ac0: 20 73 74 72 75 63 74 20 73 71 6c 69 74 65 33 5f   struct sqlite3_
0ad0: 76 66 73 20 41 70 6e 64 56 66 73 3b 0a 74 79 70  vfs ApndVfs;.typ
0ae0: 65 64 65 66 20 73 74 72 75 63 74 20 41 70 6e 64  edef struct Apnd
0af0: 46 69 6c 65 20 41 70 6e 64 46 69 6c 65 3b 0a 0a  File ApndFile;..
0b00: 2f 2a 20 41 63 63 65 73 73 20 74 6f 20 61 20 6c  /* Access to a l
0b10: 6f 77 65 72 2d 6c 65 76 65 6c 20 56 46 53 20 74  ower-level VFS t
0b20: 68 61 74 20 28 6d 69 67 68 74 29 20 69 6d 70 6c  hat (might) impl
0b30: 65 6d 65 6e 74 20 64 79 6e 61 6d 69 63 20 6c 6f  ement dynamic lo
0b40: 61 64 69 6e 67 2c 0a 2a 2a 20 61 63 63 65 73 73  ading,.** access
0b50: 20 74 6f 20 72 61 6e 64 6f 6d 6e 65 73 73 2c 20   to randomness, 
0b60: 65 74 63 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20  etc..*/.#define 
0b70: 4f 52 49 47 56 46 53 28 70 29 20 20 28 28 73 71  ORIGVFS(p)  ((sq
0b80: 6c 69 74 65 33 5f 76 66 73 2a 29 28 28 70 29 2d  lite3_vfs*)((p)-
0b90: 3e 70 41 70 70 44 61 74 61 29 29 0a 23 64 65 66  >pAppData)).#def
0ba0: 69 6e 65 20 4f 52 49 47 46 49 4c 45 28 70 29 20  ine ORIGFILE(p) 
0bb0: 28 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 29  ((sqlite3_file*)
0bc0: 28 28 28 41 70 6e 64 46 69 6c 65 2a 29 28 70 29  (((ApndFile*)(p)
0bd0: 29 2b 31 29 29 0a 0a 2f 2a 20 41 6e 20 6f 70 65  )+1))../* An ope
0be0: 6e 20 66 69 6c 65 20 2a 2f 0a 73 74 72 75 63 74  n file */.struct
0bf0: 20 41 70 6e 64 46 69 6c 65 20 7b 0a 20 20 73 71   ApndFile {.  sq
0c00: 6c 69 74 65 33 5f 66 69 6c 65 20 62 61 73 65 3b  lite3_file base;
0c10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
0c20: 20 49 4f 20 6d 65 74 68 6f 64 73 20 2a 2f 0a 20   IO methods */. 
0c30: 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 69   sqlite3_int64 i
0c40: 50 67 4f 6e 65 3b 20 20 20 20 20 20 20 20 20 20  PgOne;          
0c50: 20 2f 2a 20 46 69 6c 65 20 6f 66 66 73 65 74 20   /* File offset 
0c60: 74 6f 20 70 61 67 65 20 31 20 2a 2f 0a 20 20 73  to page 1 */.  s
0c70: 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 69 4d 61  qlite3_int64 iMa
0c80: 72 6b 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f  rk;            /
0c90: 2a 20 53 74 61 72 74 20 6f 66 20 74 68 65 20 61  * Start of the a
0ca0: 70 70 65 6e 64 2d 6d 61 72 6b 20 2a 2f 0a 7d 3b  ppend-mark */.};
0cb0: 0a 0a 2f 2a 0a 2a 2a 20 4d 65 74 68 6f 64 73 20  ../*.** Methods 
0cc0: 66 6f 72 20 41 70 6e 64 46 69 6c 65 0a 2a 2f 0a  for ApndFile.*/.
0cd0: 73 74 61 74 69 63 20 69 6e 74 20 61 70 6e 64 43  static int apndC
0ce0: 6c 6f 73 65 28 73 71 6c 69 74 65 33 5f 66 69 6c  lose(sqlite3_fil
0cf0: 65 2a 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20  e*);.static int 
0d00: 61 70 6e 64 52 65 61 64 28 73 71 6c 69 74 65 33  apndRead(sqlite3
0d10: 5f 66 69 6c 65 2a 2c 20 76 6f 69 64 2a 2c 20 69  _file*, void*, i
0d20: 6e 74 20 69 41 6d 74 2c 20 73 71 6c 69 74 65 33  nt iAmt, sqlite3
0d30: 5f 69 6e 74 36 34 20 69 4f 66 73 74 29 3b 0a 73  _int64 iOfst);.s
0d40: 74 61 74 69 63 20 69 6e 74 20 61 70 6e 64 57 72  tatic int apndWr
0d50: 69 74 65 28 73 71 6c 69 74 65 33 5f 66 69 6c 65  ite(sqlite3_file
0d60: 2a 2c 63 6f 6e 73 74 20 76 6f 69 64 2a 2c 69 6e  *,const void*,in
0d70: 74 20 69 41 6d 74 2c 20 73 71 6c 69 74 65 33 5f  t iAmt, sqlite3_
0d80: 69 6e 74 36 34 20 69 4f 66 73 74 29 3b 0a 73 74  int64 iOfst);.st
0d90: 61 74 69 63 20 69 6e 74 20 61 70 6e 64 54 72 75  atic int apndTru
0da0: 6e 63 61 74 65 28 73 71 6c 69 74 65 33 5f 66 69  ncate(sqlite3_fi
0db0: 6c 65 2a 2c 20 73 71 6c 69 74 65 33 5f 69 6e 74  le*, sqlite3_int
0dc0: 36 34 20 73 69 7a 65 29 3b 0a 73 74 61 74 69 63  64 size);.static
0dd0: 20 69 6e 74 20 61 70 6e 64 53 79 6e 63 28 73 71   int apndSync(sq
0de0: 6c 69 74 65 33 5f 66 69 6c 65 2a 2c 20 69 6e 74  lite3_file*, int
0df0: 20 66 6c 61 67 73 29 3b 0a 73 74 61 74 69 63 20   flags);.static 
0e00: 69 6e 74 20 61 70 6e 64 46 69 6c 65 53 69 7a 65  int apndFileSize
0e10: 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 2c 20  (sqlite3_file*, 
0e20: 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 2a 70  sqlite3_int64 *p
0e30: 53 69 7a 65 29 3b 0a 73 74 61 74 69 63 20 69 6e  Size);.static in
0e40: 74 20 61 70 6e 64 4c 6f 63 6b 28 73 71 6c 69 74  t apndLock(sqlit
0e50: 65 33 5f 66 69 6c 65 2a 2c 20 69 6e 74 29 3b 0a  e3_file*, int);.
0e60: 73 74 61 74 69 63 20 69 6e 74 20 61 70 6e 64 55  static int apndU
0e70: 6e 6c 6f 63 6b 28 73 71 6c 69 74 65 33 5f 66 69  nlock(sqlite3_fi
0e80: 6c 65 2a 2c 20 69 6e 74 29 3b 0a 73 74 61 74 69  le*, int);.stati
0e90: 63 20 69 6e 74 20 61 70 6e 64 43 68 65 63 6b 52  c int apndCheckR
0ea0: 65 73 65 72 76 65 64 4c 6f 63 6b 28 73 71 6c 69  eservedLock(sqli
0eb0: 74 65 33 5f 66 69 6c 65 2a 2c 20 69 6e 74 20 2a  te3_file*, int *
0ec0: 70 52 65 73 4f 75 74 29 3b 0a 73 74 61 74 69 63  pResOut);.static
0ed0: 20 69 6e 74 20 61 70 6e 64 46 69 6c 65 43 6f 6e   int apndFileCon
0ee0: 74 72 6f 6c 28 73 71 6c 69 74 65 33 5f 66 69 6c  trol(sqlite3_fil
0ef0: 65 2a 2c 20 69 6e 74 20 6f 70 2c 20 76 6f 69 64  e*, int op, void
0f00: 20 2a 70 41 72 67 29 3b 0a 73 74 61 74 69 63 20   *pArg);.static 
0f10: 69 6e 74 20 61 70 6e 64 53 65 63 74 6f 72 53 69  int apndSectorSi
0f20: 7a 65 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a  ze(sqlite3_file*
0f30: 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  );.static int ap
0f40: 6e 64 44 65 76 69 63 65 43 68 61 72 61 63 74 65  ndDeviceCharacte
0f50: 72 69 73 74 69 63 73 28 73 71 6c 69 74 65 33 5f  ristics(sqlite3_
0f60: 66 69 6c 65 2a 29 3b 0a 73 74 61 74 69 63 20 69  file*);.static i
0f70: 6e 74 20 61 70 6e 64 53 68 6d 4d 61 70 28 73 71  nt apndShmMap(sq
0f80: 6c 69 74 65 33 5f 66 69 6c 65 2a 2c 20 69 6e 74  lite3_file*, int
0f90: 20 69 50 67 2c 20 69 6e 74 20 70 67 73 7a 2c 20   iPg, int pgsz, 
0fa0: 69 6e 74 2c 20 76 6f 69 64 20 76 6f 6c 61 74 69  int, void volati
0fb0: 6c 65 2a 2a 29 3b 0a 73 74 61 74 69 63 20 69 6e  le**);.static in
0fc0: 74 20 61 70 6e 64 53 68 6d 4c 6f 63 6b 28 73 71  t apndShmLock(sq
0fd0: 6c 69 74 65 33 5f 66 69 6c 65 2a 2c 20 69 6e 74  lite3_file*, int
0fe0: 20 6f 66 66 73 65 74 2c 20 69 6e 74 20 6e 2c 20   offset, int n, 
0ff0: 69 6e 74 20 66 6c 61 67 73 29 3b 0a 73 74 61 74  int flags);.stat
1000: 69 63 20 76 6f 69 64 20 61 70 6e 64 53 68 6d 42  ic void apndShmB
1010: 61 72 72 69 65 72 28 73 71 6c 69 74 65 33 5f 66  arrier(sqlite3_f
1020: 69 6c 65 2a 29 3b 0a 73 74 61 74 69 63 20 69 6e  ile*);.static in
1030: 74 20 61 70 6e 64 53 68 6d 55 6e 6d 61 70 28 73  t apndShmUnmap(s
1040: 71 6c 69 74 65 33 5f 66 69 6c 65 2a 2c 20 69 6e  qlite3_file*, in
1050: 74 20 64 65 6c 65 74 65 46 6c 61 67 29 3b 0a 73  t deleteFlag);.s
1060: 74 61 74 69 63 20 69 6e 74 20 61 70 6e 64 46 65  tatic int apndFe
1070: 74 63 68 28 73 71 6c 69 74 65 33 5f 66 69 6c 65  tch(sqlite3_file
1080: 2a 2c 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34  *, sqlite3_int64
1090: 20 69 4f 66 73 74 2c 20 69 6e 74 20 69 41 6d 74   iOfst, int iAmt
10a0: 2c 20 76 6f 69 64 20 2a 2a 70 70 29 3b 0a 73 74  , void **pp);.st
10b0: 61 74 69 63 20 69 6e 74 20 61 70 6e 64 55 6e 66  atic int apndUnf
10c0: 65 74 63 68 28 73 71 6c 69 74 65 33 5f 66 69 6c  etch(sqlite3_fil
10d0: 65 2a 2c 20 73 71 6c 69 74 65 33 5f 69 6e 74 36  e*, sqlite3_int6
10e0: 34 20 69 4f 66 73 74 2c 20 76 6f 69 64 20 2a 70  4 iOfst, void *p
10f0: 29 3b 0a 0a 2f 2a 0a 2a 2a 20 4d 65 74 68 6f 64  );../*.** Method
1100: 73 20 66 6f 72 20 41 70 6e 64 56 66 73 0a 2a 2f  s for ApndVfs.*/
1110: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 6e 64  .static int apnd
1120: 4f 70 65 6e 28 73 71 6c 69 74 65 33 5f 76 66 73  Open(sqlite3_vfs
1130: 2a 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 2c  *, const char *,
1140: 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 2a 2c 20   sqlite3_file*, 
1150: 69 6e 74 20 2c 20 69 6e 74 20 2a 29 3b 0a 73 74  int , int *);.st
1160: 61 74 69 63 20 69 6e 74 20 61 70 6e 64 44 65 6c  atic int apndDel
1170: 65 74 65 28 73 71 6c 69 74 65 33 5f 76 66 73 2a  ete(sqlite3_vfs*
1180: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e  , const char *zN
1190: 61 6d 65 2c 20 69 6e 74 20 73 79 6e 63 44 69 72  ame, int syncDir
11a0: 29 3b 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  );.static int ap
11b0: 6e 64 41 63 63 65 73 73 28 73 71 6c 69 74 65 33  ndAccess(sqlite3
11c0: 5f 76 66 73 2a 2c 20 63 6f 6e 73 74 20 63 68 61  _vfs*, const cha
11d0: 72 20 2a 7a 4e 61 6d 65 2c 20 69 6e 74 20 66 6c  r *zName, int fl
11e0: 61 67 73 2c 20 69 6e 74 20 2a 29 3b 0a 73 74 61  ags, int *);.sta
11f0: 74 69 63 20 69 6e 74 20 61 70 6e 64 46 75 6c 6c  tic int apndFull
1200: 50 61 74 68 6e 61 6d 65 28 73 71 6c 69 74 65 33  Pathname(sqlite3
1210: 5f 76 66 73 2a 2c 20 63 6f 6e 73 74 20 63 68 61  _vfs*, const cha
1220: 72 20 2a 7a 4e 61 6d 65 2c 20 69 6e 74 2c 20 63  r *zName, int, c
1230: 68 61 72 20 2a 7a 4f 75 74 29 3b 0a 73 74 61 74  har *zOut);.stat
1240: 69 63 20 76 6f 69 64 20 2a 61 70 6e 64 44 6c 4f  ic void *apndDlO
1250: 70 65 6e 28 73 71 6c 69 74 65 33 5f 76 66 73 2a  pen(sqlite3_vfs*
1260: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46  , const char *zF
1270: 69 6c 65 6e 61 6d 65 29 3b 0a 73 74 61 74 69 63  ilename);.static
1280: 20 76 6f 69 64 20 61 70 6e 64 44 6c 45 72 72 6f   void apndDlErro
1290: 72 28 73 71 6c 69 74 65 33 5f 76 66 73 2a 2c 20  r(sqlite3_vfs*, 
12a0: 69 6e 74 20 6e 42 79 74 65 2c 20 63 68 61 72 20  int nByte, char 
12b0: 2a 7a 45 72 72 4d 73 67 29 3b 0a 73 74 61 74 69  *zErrMsg);.stati
12c0: 63 20 76 6f 69 64 20 28 2a 61 70 6e 64 44 6c 53  c void (*apndDlS
12d0: 79 6d 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a  ym(sqlite3_vfs *
12e0: 70 56 66 73 2c 20 76 6f 69 64 20 2a 70 2c 20 63  pVfs, void *p, c
12f0: 6f 6e 73 74 20 63 68 61 72 2a 7a 53 79 6d 29 29  onst char*zSym))
1300: 28 76 6f 69 64 29 3b 0a 73 74 61 74 69 63 20 76  (void);.static v
1310: 6f 69 64 20 61 70 6e 64 44 6c 43 6c 6f 73 65 28  oid apndDlClose(
1320: 73 71 6c 69 74 65 33 5f 76 66 73 2a 2c 20 76 6f  sqlite3_vfs*, vo
1330: 69 64 2a 29 3b 0a 73 74 61 74 69 63 20 69 6e 74  id*);.static int
1340: 20 61 70 6e 64 52 61 6e 64 6f 6d 6e 65 73 73 28   apndRandomness(
1350: 73 71 6c 69 74 65 33 5f 76 66 73 2a 2c 20 69 6e  sqlite3_vfs*, in
1360: 74 20 6e 42 79 74 65 2c 20 63 68 61 72 20 2a 7a  t nByte, char *z
1370: 4f 75 74 29 3b 0a 73 74 61 74 69 63 20 69 6e 74  Out);.static int
1380: 20 61 70 6e 64 53 6c 65 65 70 28 73 71 6c 69 74   apndSleep(sqlit
1390: 65 33 5f 76 66 73 2a 2c 20 69 6e 74 20 6d 69 63  e3_vfs*, int mic
13a0: 72 6f 73 65 63 6f 6e 64 73 29 3b 0a 73 74 61 74  roseconds);.stat
13b0: 69 63 20 69 6e 74 20 61 70 6e 64 43 75 72 72 65  ic int apndCurre
13c0: 6e 74 54 69 6d 65 28 73 71 6c 69 74 65 33 5f 76  ntTime(sqlite3_v
13d0: 66 73 2a 2c 20 64 6f 75 62 6c 65 2a 29 3b 0a 73  fs*, double*);.s
13e0: 74 61 74 69 63 20 69 6e 74 20 61 70 6e 64 47 65  tatic int apndGe
13f0: 74 4c 61 73 74 45 72 72 6f 72 28 73 71 6c 69 74  tLastError(sqlit
1400: 65 33 5f 76 66 73 2a 2c 20 69 6e 74 2c 20 63 68  e3_vfs*, int, ch
1410: 61 72 20 2a 29 3b 0a 73 74 61 74 69 63 20 69 6e  ar *);.static in
1420: 74 20 61 70 6e 64 43 75 72 72 65 6e 74 54 69 6d  t apndCurrentTim
1430: 65 49 6e 74 36 34 28 73 71 6c 69 74 65 33 5f 76  eInt64(sqlite3_v
1440: 66 73 2a 2c 20 73 71 6c 69 74 65 33 5f 69 6e 74  fs*, sqlite3_int
1450: 36 34 2a 29 3b 0a 73 74 61 74 69 63 20 69 6e 74  64*);.static int
1460: 20 61 70 6e 64 53 65 74 53 79 73 74 65 6d 43 61   apndSetSystemCa
1470: 6c 6c 28 73 71 6c 69 74 65 33 5f 76 66 73 2a 2c  ll(sqlite3_vfs*,
1480: 20 63 6f 6e 73 74 20 63 68 61 72 2a 2c 73 71 6c   const char*,sql
1490: 69 74 65 33 5f 73 79 73 63 61 6c 6c 5f 70 74 72  ite3_syscall_ptr
14a0: 29 3b 0a 73 74 61 74 69 63 20 73 71 6c 69 74 65  );.static sqlite
14b0: 33 5f 73 79 73 63 61 6c 6c 5f 70 74 72 20 61 70  3_syscall_ptr ap
14c0: 6e 64 47 65 74 53 79 73 74 65 6d 43 61 6c 6c 28  ndGetSystemCall(
14d0: 73 71 6c 69 74 65 33 5f 76 66 73 2a 2c 20 63 6f  sqlite3_vfs*, co
14e0: 6e 73 74 20 63 68 61 72 20 2a 7a 29 3b 0a 73 74  nst char *z);.st
14f0: 61 74 69 63 20 63 6f 6e 73 74 20 63 68 61 72 20  atic const char 
1500: 2a 61 70 6e 64 4e 65 78 74 53 79 73 74 65 6d 43  *apndNextSystemC
1510: 61 6c 6c 28 73 71 6c 69 74 65 33 5f 76 66 73 2a  all(sqlite3_vfs*
1520: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e  , const char *zN
1530: 61 6d 65 29 3b 0a 0a 73 74 61 74 69 63 20 73 71  ame);..static sq
1540: 6c 69 74 65 33 5f 76 66 73 20 61 70 6e 64 5f 76  lite3_vfs apnd_v
1550: 66 73 20 3d 20 7b 0a 20 20 33 2c 20 20 20 20 20  fs = {.  3,     
1560: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1570: 20 20 20 20 20 20 20 2f 2a 20 69 56 65 72 73 69         /* iVersi
1580: 6f 6e 20 28 73 65 74 20 77 68 65 6e 20 72 65 67  on (set when reg
1590: 69 73 74 65 72 65 64 29 20 2a 2f 0a 20 20 30 2c  istered) */.  0,
15a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
15b0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 73              /* s
15c0: 7a 4f 73 46 69 6c 65 20 28 73 65 74 20 77 68 65  zOsFile (set whe
15d0: 6e 20 72 65 67 69 73 74 65 72 65 64 29 20 2a 2f  n registered) */
15e0: 0a 20 20 31 30 32 34 2c 20 20 20 20 20 20 20 20  .  1024,        
15f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1600: 20 2f 2a 20 6d 78 50 61 74 68 6e 61 6d 65 20 2a   /* mxPathname *
1610: 2f 0a 20 20 30 2c 20 20 20 20 20 20 20 20 20 20  /.  0,          
1620: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1630: 20 20 2f 2a 20 70 4e 65 78 74 20 2a 2f 0a 20 20    /* pNext */.  
1640: 22 61 70 6e 64 76 66 73 22 2c 20 20 20 20 20 20  "apndvfs",      
1650: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1660: 20 7a 4e 61 6d 65 20 2a 2f 0a 20 20 30 2c 20 20   zName */.  0,  
1670: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1680: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 70 41 70            /* pAp
1690: 70 44 61 74 61 20 28 73 65 74 20 77 68 65 6e 20  pData (set when 
16a0: 72 65 67 69 73 74 65 72 65 64 29 20 2a 2f 20 0a  registered) */ .
16b0: 20 20 61 70 6e 64 4f 70 65 6e 2c 20 20 20 20 20    apndOpen,     
16c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
16d0: 2f 2a 20 78 4f 70 65 6e 20 2a 2f 0a 20 20 61 70  /* xOpen */.  ap
16e0: 6e 64 44 65 6c 65 74 65 2c 20 20 20 20 20 20 20  ndDelete,       
16f0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
1700: 44 65 6c 65 74 65 20 2a 2f 0a 20 20 61 70 6e 64  Delete */.  apnd
1710: 41 63 63 65 73 73 2c 20 20 20 20 20 20 20 20 20  Access,         
1720: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 41 63            /* xAc
1730: 63 65 73 73 20 2a 2f 0a 20 20 61 70 6e 64 46 75  cess */.  apndFu
1740: 6c 6c 50 61 74 68 6e 61 6d 65 2c 20 20 20 20 20  llPathname,     
1750: 20 20 20 20 20 20 20 20 2f 2a 20 78 46 75 6c 6c          /* xFull
1760: 50 61 74 68 6e 61 6d 65 20 2a 2f 0a 20 20 61 70  Pathname */.  ap
1770: 6e 64 44 6c 4f 70 65 6e 2c 20 20 20 20 20 20 20  ndDlOpen,       
1780: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
1790: 44 6c 4f 70 65 6e 20 2a 2f 0a 20 20 61 70 6e 64  DlOpen */.  apnd
17a0: 44 6c 45 72 72 6f 72 2c 20 20 20 20 20 20 20 20  DlError,        
17b0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 6c            /* xDl
17c0: 45 72 72 6f 72 20 2a 2f 0a 20 20 61 70 6e 64 44  Error */.  apndD
17d0: 6c 53 79 6d 2c 20 20 20 20 20 20 20 20 20 20 20  lSym,           
17e0: 20 20 20 20 20 20 20 20 20 2f 2a 20 78 44 6c 53           /* xDlS
17f0: 79 6d 20 2a 2f 0a 20 20 61 70 6e 64 44 6c 43 6c  ym */.  apndDlCl
1800: 6f 73 65 2c 20 20 20 20 20 20 20 20 20 20 20 20  ose,            
1810: 20 20 20 20 20 20 2f 2a 20 78 44 6c 43 6c 6f 73        /* xDlClos
1820: 65 20 2a 2f 0a 20 20 61 70 6e 64 52 61 6e 64 6f  e */.  apndRando
1830: 6d 6e 65 73 73 2c 20 20 20 20 20 20 20 20 20 20  mness,          
1840: 20 20 20 20 20 2f 2a 20 78 52 61 6e 64 6f 6d 6e       /* xRandomn
1850: 65 73 73 20 2a 2f 0a 20 20 61 70 6e 64 53 6c 65  ess */.  apndSle
1860: 65 70 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  ep,             
1870: 20 20 20 20 20 20 20 2f 2a 20 78 53 6c 65 65 70         /* xSleep
1880: 20 2a 2f 0a 20 20 61 70 6e 64 43 75 72 72 65 6e   */.  apndCurren
1890: 74 54 69 6d 65 2c 20 20 20 20 20 20 20 20 20 20  tTime,          
18a0: 20 20 20 20 2f 2a 20 78 43 75 72 72 65 6e 74 54      /* xCurrentT
18b0: 69 6d 65 20 2a 2f 0a 20 20 61 70 6e 64 47 65 74  ime */.  apndGet
18c0: 4c 61 73 74 45 72 72 6f 72 2c 20 20 20 20 20 20  LastError,      
18d0: 20 20 20 20 20 20 20 2f 2a 20 78 47 65 74 4c 61         /* xGetLa
18e0: 73 74 45 72 72 6f 72 20 2a 2f 0a 20 20 61 70 6e  stError */.  apn
18f0: 64 43 75 72 72 65 6e 74 54 69 6d 65 49 6e 74 36  dCurrentTimeInt6
1900: 34 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43  4,         /* xC
1910: 75 72 72 65 6e 74 54 69 6d 65 49 6e 74 36 34 20  urrentTimeInt64 
1920: 2a 2f 0a 20 20 61 70 6e 64 53 65 74 53 79 73 74  */.  apndSetSyst
1930: 65 6d 43 61 6c 6c 2c 20 20 20 20 20 20 20 20 20  emCall,         
1940: 20 20 20 2f 2a 20 78 53 65 74 53 79 73 74 65 6d     /* xSetSystem
1950: 43 61 6c 6c 20 2a 2f 0a 20 20 61 70 6e 64 47 65  Call */.  apndGe
1960: 74 53 79 73 74 65 6d 43 61 6c 6c 2c 20 20 20 20  tSystemCall,    
1970: 20 20 20 20 20 20 20 20 2f 2a 20 78 47 65 74 53          /* xGetS
1980: 79 73 74 65 6d 43 61 6c 6c 20 2a 2f 0a 20 20 61  ystemCall */.  a
1990: 70 6e 64 4e 65 78 74 53 79 73 74 65 6d 43 61 6c  pndNextSystemCal
19a0: 6c 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20  l            /* 
19b0: 78 4e 65 78 74 53 79 73 74 65 6d 43 61 6c 6c 20  xNextSystemCall 
19c0: 2a 2f 0a 7d 3b 0a 0a 73 74 61 74 69 63 20 63 6f  */.};..static co
19d0: 6e 73 74 20 73 71 6c 69 74 65 33 5f 69 6f 5f 6d  nst sqlite3_io_m
19e0: 65 74 68 6f 64 73 20 61 70 6e 64 5f 69 6f 5f 6d  ethods apnd_io_m
19f0: 65 74 68 6f 64 73 20 3d 20 7b 0a 20 20 33 2c 20  ethods = {.  3, 
1a00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1a10: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1a20: 69 56 65 72 73 69 6f 6e 20 2a 2f 0a 20 20 61 70  iVersion */.  ap
1a30: 6e 64 43 6c 6f 73 65 2c 20 20 20 20 20 20 20 20  ndClose,        
1a40: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1a50: 20 78 43 6c 6f 73 65 20 2a 2f 0a 20 20 61 70 6e   xClose */.  apn
1a60: 64 52 65 61 64 2c 20 20 20 20 20 20 20 20 20 20  dRead,          
1a70: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1a80: 78 52 65 61 64 20 2a 2f 0a 20 20 61 70 6e 64 57  xRead */.  apndW
1a90: 72 69 74 65 2c 20 20 20 20 20 20 20 20 20 20 20  rite,           
1aa0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 57             /* xW
1ab0: 72 69 74 65 20 2a 2f 0a 20 20 61 70 6e 64 54 72  rite */.  apndTr
1ac0: 75 6e 63 61 74 65 2c 20 20 20 20 20 20 20 20 20  uncate,         
1ad0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 54 72            /* xTr
1ae0: 75 6e 63 61 74 65 20 2a 2f 0a 20 20 61 70 6e 64  uncate */.  apnd
1af0: 53 79 6e 63 2c 20 20 20 20 20 20 20 20 20 20 20  Sync,           
1b00: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
1b10: 53 79 6e 63 20 2a 2f 0a 20 20 61 70 6e 64 46 69  Sync */.  apndFi
1b20: 6c 65 53 69 7a 65 2c 20 20 20 20 20 20 20 20 20  leSize,         
1b30: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 46 69            /* xFi
1b40: 6c 65 53 69 7a 65 20 2a 2f 0a 20 20 61 70 6e 64  leSize */.  apnd
1b50: 4c 6f 63 6b 2c 20 20 20 20 20 20 20 20 20 20 20  Lock,           
1b60: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78              /* x
1b70: 4c 6f 63 6b 20 2a 2f 0a 20 20 61 70 6e 64 55 6e  Lock */.  apndUn
1b80: 6c 6f 63 6b 2c 20 20 20 20 20 20 20 20 20 20 20  lock,           
1b90: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 55 6e            /* xUn
1ba0: 6c 6f 63 6b 20 2a 2f 0a 20 20 61 70 6e 64 43 68  lock */.  apndCh
1bb0: 65 63 6b 52 65 73 65 72 76 65 64 4c 6f 63 6b 2c  eckReservedLock,
1bc0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 43 68            /* xCh
1bd0: 65 63 6b 52 65 73 65 72 76 65 64 4c 6f 63 6b 20  eckReservedLock 
1be0: 2a 2f 0a 20 20 61 70 6e 64 46 69 6c 65 43 6f 6e  */.  apndFileCon
1bf0: 74 72 6f 6c 2c 20 20 20 20 20 20 20 20 20 20 20  trol,           
1c00: 20 20 20 20 20 2f 2a 20 78 46 69 6c 65 43 6f 6e       /* xFileCon
1c10: 74 72 6f 6c 20 2a 2f 0a 20 20 61 70 6e 64 53 65  trol */.  apndSe
1c20: 63 74 6f 72 53 69 7a 65 2c 20 20 20 20 20 20 20  ctorSize,       
1c30: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 78 53 65            /* xSe
1c40: 63 74 6f 72 53 69 7a 65 20 2a 2f 0a 20 20 61 70  ctorSize */.  ap
1c50: 6e 64 44 65 76 69 63 65 43 68 61 72 61 63 74 65  ndDeviceCharacte
1c60: 72 69 73 74 69 63 73 2c 20 20 20 20 20 20 2f 2a  ristics,      /*
1c70: 20 78 44 65 76 69 63 65 43 68 61 72 61 63 74 65   xDeviceCharacte
1c80: 72 69 73 74 69 63 73 20 2a 2f 0a 20 20 61 70 6e  ristics */.  apn
1c90: 64 53 68 6d 4d 61 70 2c 20 20 20 20 20 20 20 20  dShmMap,        
1ca0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1cb0: 78 53 68 6d 4d 61 70 20 2a 2f 0a 20 20 61 70 6e  xShmMap */.  apn
1cc0: 64 53 68 6d 4c 6f 63 6b 2c 20 20 20 20 20 20 20  dShmLock,       
1cd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
1ce0: 78 53 68 6d 4c 6f 63 6b 20 2a 2f 0a 20 20 61 70  xShmLock */.  ap
1cf0: 6e 64 53 68 6d 42 61 72 72 69 65 72 2c 20 20 20  ndShmBarrier,   
1d00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
1d10: 20 78 53 68 6d 42 61 72 72 69 65 72 20 2a 2f 0a   xShmBarrier */.
1d20: 20 20 61 70 6e 64 53 68 6d 55 6e 6d 61 70 2c 20    apndShmUnmap, 
1d30: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d40: 20 20 2f 2a 20 78 53 68 6d 55 6e 6d 61 70 20 2a    /* xShmUnmap *
1d50: 2f 0a 20 20 61 70 6e 64 46 65 74 63 68 2c 20 20  /.  apndFetch,  
1d60: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1d70: 20 20 20 20 2f 2a 20 78 46 65 74 63 68 20 2a 2f      /* xFetch */
1d80: 0a 20 20 61 70 6e 64 55 6e 66 65 74 63 68 20 20  .  apndUnfetch  
1d90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
1da0: 20 20 20 2f 2a 20 78 55 6e 66 65 74 63 68 20 2a     /* xUnfetch *
1db0: 2f 0a 7d 3b 0a 0a 0a 0a 2f 2a 0a 2a 2a 20 43 6c  /.};..../*.** Cl
1dc0: 6f 73 65 20 61 6e 20 61 70 6e 64 2d 66 69 6c 65  ose an apnd-file
1dd0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
1de0: 61 70 6e 64 43 6c 6f 73 65 28 73 71 6c 69 74 65  apndClose(sqlite
1df0: 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 29 7b 0a  3_file *pFile){.
1e00: 20 20 70 46 69 6c 65 20 3d 20 4f 52 49 47 46 49    pFile = ORIGFI
1e10: 4c 45 28 70 46 69 6c 65 29 3b 0a 20 20 72 65 74  LE(pFile);.  ret
1e20: 75 72 6e 20 70 46 69 6c 65 2d 3e 70 4d 65 74 68  urn pFile->pMeth
1e30: 6f 64 73 2d 3e 78 43 6c 6f 73 65 28 70 46 69 6c  ods->xClose(pFil
1e40: 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 61  e);.}../*.** Rea
1e50: 64 20 64 61 74 61 20 66 72 6f 6d 20 61 6e 20 61  d data from an a
1e60: 70 6e 64 2d 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61  pnd-file..*/.sta
1e70: 74 69 63 20 69 6e 74 20 61 70 6e 64 52 65 61 64  tic int apndRead
1e80: 28 0a 20 20 73 71 6c 69 74 65 33 5f 66 69 6c 65  (.  sqlite3_file
1e90: 20 2a 70 46 69 6c 65 2c 20 0a 20 20 76 6f 69 64   *pFile, .  void
1ea0: 20 2a 7a 42 75 66 2c 20 0a 20 20 69 6e 74 20 69   *zBuf, .  int i
1eb0: 41 6d 74 2c 20 0a 20 20 73 71 6c 69 74 65 5f 69  Amt, .  sqlite_i
1ec0: 6e 74 36 34 20 69 4f 66 73 74 0a 29 7b 0a 20 20  nt64 iOfst.){.  
1ed0: 41 70 6e 64 46 69 6c 65 20 2a 70 20 3d 20 28 41  ApndFile *p = (A
1ee0: 70 6e 64 46 69 6c 65 20 2a 29 70 46 69 6c 65 3b  pndFile *)pFile;
1ef0: 0a 20 20 70 46 69 6c 65 20 3d 20 4f 52 49 47 46  .  pFile = ORIGF
1f00: 49 4c 45 28 70 46 69 6c 65 29 3b 0a 20 20 72 65  ILE(pFile);.  re
1f10: 74 75 72 6e 20 70 46 69 6c 65 2d 3e 70 4d 65 74  turn pFile->pMet
1f20: 68 6f 64 73 2d 3e 78 52 65 61 64 28 70 46 69 6c  hods->xRead(pFil
1f30: 65 2c 20 7a 42 75 66 2c 20 69 41 6d 74 2c 20 69  e, zBuf, iAmt, i
1f40: 4f 66 73 74 2b 70 2d 3e 69 50 67 4f 6e 65 29 3b  Ofst+p->iPgOne);
1f50: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 64 20 74 68  .}../*.** Add th
1f60: 65 20 61 70 70 65 6e 64 2d 6d 61 72 6b 20 6f 6e  e append-mark on
1f70: 74 6f 20 74 68 65 20 65 6e 64 20 6f 66 20 74 68  to the end of th
1f80: 65 20 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69  e file..*/.stati
1f90: 63 20 69 6e 74 20 61 70 6e 64 57 72 69 74 65 4d  c int apndWriteM
1fa0: 61 72 6b 28 41 70 6e 64 46 69 6c 65 20 2a 70 2c  ark(ApndFile *p,
1fb0: 20 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70   sqlite3_file *p
1fc0: 46 69 6c 65 29 7b 0a 20 20 69 6e 74 20 69 3b 0a  File){.  int i;.
1fd0: 20 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20    unsigned char 
1fe0: 61 5b 41 50 4e 44 5f 4d 41 52 4b 5f 53 49 5a 45  a[APND_MARK_SIZE
1ff0: 5d 3b 0a 20 20 6d 65 6d 63 70 79 28 61 2c 20 41  ];.  memcpy(a, A
2000: 50 4e 44 5f 4d 41 52 4b 5f 50 52 45 46 49 58 2c  PND_MARK_PREFIX,
2010: 20 41 50 4e 44 5f 4d 41 52 4b 5f 50 52 45 46 49   APND_MARK_PREFI
2020: 58 5f 53 5a 29 3b 0a 20 20 66 6f 72 28 69 3d 30  X_SZ);.  for(i=0
2030: 3b 20 69 3c 38 3b 20 69 2b 2b 29 7b 0a 20 20 20  ; i<8; i++){.   
2040: 20 61 5b 41 50 4e 44 5f 4d 41 52 4b 5f 50 52 45   a[APND_MARK_PRE
2050: 46 49 58 5f 53 5a 2b 69 5d 20 3d 20 28 70 2d 3e  FIX_SZ+i] = (p->
2060: 69 50 67 4f 6e 65 20 3e 3e 20 28 35 36 20 2d 20  iPgOne >> (56 - 
2070: 69 2a 38 29 29 20 26 20 30 78 66 66 3b 0a 20 20  i*8)) & 0xff;.  
2080: 7d 0a 20 20 72 65 74 75 72 6e 20 70 46 69 6c 65  }.  return pFile
2090: 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 57 72 69  ->pMethods->xWri
20a0: 74 65 28 70 46 69 6c 65 2c 20 61 2c 20 41 50 4e  te(pFile, a, APN
20b0: 44 5f 4d 41 52 4b 5f 53 49 5a 45 2c 20 70 2d 3e  D_MARK_SIZE, p->
20c0: 69 4d 61 72 6b 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  iMark);.}../*.**
20d0: 20 57 72 69 74 65 20 64 61 74 61 20 74 6f 20 61   Write data to a
20e0: 6e 20 61 70 6e 64 2d 66 69 6c 65 2e 0a 2a 2f 0a  n apnd-file..*/.
20f0: 73 74 61 74 69 63 20 69 6e 74 20 61 70 6e 64 57  static int apndW
2100: 72 69 74 65 28 0a 20 20 73 71 6c 69 74 65 33 5f  rite(.  sqlite3_
2110: 66 69 6c 65 20 2a 70 46 69 6c 65 2c 0a 20 20 63  file *pFile,.  c
2120: 6f 6e 73 74 20 76 6f 69 64 20 2a 7a 42 75 66 2c  onst void *zBuf,
2130: 0a 20 20 69 6e 74 20 69 41 6d 74 2c 0a 20 20 73  .  int iAmt,.  s
2140: 71 6c 69 74 65 5f 69 6e 74 36 34 20 69 4f 66 73  qlite_int64 iOfs
2150: 74 0a 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20  t.){.  int rc;. 
2160: 20 41 70 6e 64 46 69 6c 65 20 2a 70 20 3d 20 28   ApndFile *p = (
2170: 41 70 6e 64 46 69 6c 65 20 2a 29 70 46 69 6c 65  ApndFile *)pFile
2180: 3b 0a 20 20 70 46 69 6c 65 20 3d 20 4f 52 49 47  ;.  pFile = ORIG
2190: 46 49 4c 45 28 70 46 69 6c 65 29 3b 0a 20 20 69  FILE(pFile);.  i
21a0: 66 28 20 69 4f 66 73 74 2b 69 41 6d 74 3e 3d 41  f( iOfst+iAmt>=A
21b0: 50 4e 44 5f 4d 41 58 5f 53 49 5a 45 20 29 20 72  PND_MAX_SIZE ) r
21c0: 65 74 75 72 6e 20 53 51 4c 49 54 45 5f 46 55 4c  eturn SQLITE_FUL
21d0: 4c 3b 0a 20 20 72 63 20 3d 20 70 46 69 6c 65 2d  L;.  rc = pFile-
21e0: 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 57 72 69 74  >pMethods->xWrit
21f0: 65 28 70 46 69 6c 65 2c 20 7a 42 75 66 2c 20 69  e(pFile, zBuf, i
2200: 41 6d 74 2c 20 69 4f 66 73 74 2b 70 2d 3e 69 50  Amt, iOfst+p->iP
2210: 67 4f 6e 65 29 3b 0a 20 20 69 66 28 20 72 63 3d  gOne);.  if( rc=
2220: 3d 53 51 4c 49 54 45 5f 4f 4b 20 26 26 20 20 69  =SQLITE_OK &&  i
2230: 4f 66 73 74 20 2b 20 69 41 6d 74 20 2b 20 70 2d  Ofst + iAmt + p-
2240: 3e 69 50 67 4f 6e 65 20 3e 20 70 2d 3e 69 4d 61  >iPgOne > p->iMa
2250: 72 6b 20 29 7b 0a 20 20 20 20 73 71 6c 69 74 65  rk ){.    sqlite
2260: 33 5f 69 6e 74 36 34 20 73 7a 20 3d 20 30 3b 0a  3_int64 sz = 0;.
2270: 20 20 20 20 72 63 20 3d 20 70 46 69 6c 65 2d 3e      rc = pFile->
2280: 70 4d 65 74 68 6f 64 73 2d 3e 78 46 69 6c 65 53  pMethods->xFileS
2290: 69 7a 65 28 70 46 69 6c 65 2c 20 26 73 7a 29 3b  ize(pFile, &sz);
22a0: 0a 20 20 20 20 69 66 28 20 72 63 3d 3d 53 51 4c  .    if( rc==SQL
22b0: 49 54 45 5f 4f 4b 20 29 7b 0a 20 20 20 20 20 20  ITE_OK ){.      
22c0: 70 2d 3e 69 4d 61 72 6b 20 3d 20 73 7a 20 2d 20  p->iMark = sz - 
22d0: 41 50 4e 44 5f 4d 41 52 4b 5f 53 49 5a 45 3b 0a  APND_MARK_SIZE;.
22e0: 20 20 20 20 20 20 69 66 28 20 69 4f 66 73 74 20        if( iOfst 
22f0: 2b 20 69 41 6d 74 20 2b 20 70 2d 3e 69 50 67 4f  + iAmt + p->iPgO
2300: 6e 65 20 3e 20 70 2d 3e 69 4d 61 72 6b 20 29 7b  ne > p->iMark ){
2310: 0a 20 20 20 20 20 20 20 20 70 2d 3e 69 4d 61 72  .        p->iMar
2320: 6b 20 3d 20 70 2d 3e 69 50 67 4f 6e 65 20 2b 20  k = p->iPgOne + 
2330: 69 4f 66 73 74 20 2b 20 69 41 6d 74 3b 0a 20 20  iOfst + iAmt;.  
2340: 20 20 20 20 20 20 72 63 20 3d 20 61 70 6e 64 57        rc = apndW
2350: 72 69 74 65 4d 61 72 6b 28 70 2c 20 70 46 69 6c  riteMark(p, pFil
2360: 65 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20  e);.      }.    
2370: 7d 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72  }.  }.  return r
2380: 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 72 75 6e  c;.}../*.** Trun
2390: 63 61 74 65 20 61 6e 20 61 70 6e 64 2d 66 69 6c  cate an apnd-fil
23a0: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  e..*/.static int
23b0: 20 61 70 6e 64 54 72 75 6e 63 61 74 65 28 73 71   apndTruncate(sq
23c0: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c  lite3_file *pFil
23d0: 65 2c 20 73 71 6c 69 74 65 5f 69 6e 74 36 34 20  e, sqlite_int64 
23e0: 73 69 7a 65 29 7b 0a 20 20 69 6e 74 20 72 63 3b  size){.  int rc;
23f0: 0a 20 20 41 70 6e 64 46 69 6c 65 20 2a 70 20 3d  .  ApndFile *p =
2400: 20 28 41 70 6e 64 46 69 6c 65 20 2a 29 70 46 69   (ApndFile *)pFi
2410: 6c 65 3b 0a 20 20 70 46 69 6c 65 20 3d 20 4f 52  le;.  pFile = OR
2420: 49 47 46 49 4c 45 28 70 46 69 6c 65 29 3b 0a 20  IGFILE(pFile);. 
2430: 20 72 63 20 3d 20 70 46 69 6c 65 2d 3e 70 4d 65   rc = pFile->pMe
2440: 74 68 6f 64 73 2d 3e 78 54 72 75 6e 63 61 74 65  thods->xTruncate
2450: 28 70 46 69 6c 65 2c 20 73 69 7a 65 2b 70 2d 3e  (pFile, size+p->
2460: 69 50 67 4f 6e 65 2b 41 50 4e 44 5f 4d 41 52 4b  iPgOne+APND_MARK
2470: 5f 53 49 5a 45 29 3b 0a 20 20 69 66 28 20 72 63  _SIZE);.  if( rc
2480: 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29 7b 0a 20  ==SQLITE_OK ){. 
2490: 20 20 20 70 2d 3e 69 4d 61 72 6b 20 3d 20 70 2d     p->iMark = p-
24a0: 3e 69 50 67 4f 6e 65 2b 73 69 7a 65 3b 0a 20 20  >iPgOne+size;.  
24b0: 20 20 72 63 20 3d 20 61 70 6e 64 57 72 69 74 65    rc = apndWrite
24c0: 4d 61 72 6b 28 70 2c 20 70 46 69 6c 65 29 3b 0a  Mark(p, pFile);.
24d0: 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b    }.  return rc;
24e0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 79 6e 63 20 61  .}../*.** Sync a
24f0: 6e 20 61 70 6e 64 2d 66 69 6c 65 2e 0a 2a 2f 0a  n apnd-file..*/.
2500: 73 74 61 74 69 63 20 69 6e 74 20 61 70 6e 64 53  static int apndS
2510: 79 6e 63 28 73 71 6c 69 74 65 33 5f 66 69 6c 65  ync(sqlite3_file
2520: 20 2a 70 46 69 6c 65 2c 20 69 6e 74 20 66 6c 61   *pFile, int fla
2530: 67 73 29 7b 0a 20 20 70 46 69 6c 65 20 3d 20 4f  gs){.  pFile = O
2540: 52 49 47 46 49 4c 45 28 70 46 69 6c 65 29 3b 0a  RIGFILE(pFile);.
2550: 20 20 72 65 74 75 72 6e 20 70 46 69 6c 65 2d 3e    return pFile->
2560: 70 4d 65 74 68 6f 64 73 2d 3e 78 53 79 6e 63 28  pMethods->xSync(
2570: 70 46 69 6c 65 2c 20 66 6c 61 67 73 29 3b 0a 7d  pFile, flags);.}
2580: 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74  ../*.** Return t
2590: 68 65 20 63 75 72 72 65 6e 74 20 66 69 6c 65 2d  he current file-
25a0: 73 69 7a 65 20 6f 66 20 61 6e 20 61 70 6e 64 2d  size of an apnd-
25b0: 66 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  file..*/.static 
25c0: 69 6e 74 20 61 70 6e 64 46 69 6c 65 53 69 7a 65  int apndFileSize
25d0: 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70  (sqlite3_file *p
25e0: 46 69 6c 65 2c 20 73 71 6c 69 74 65 5f 69 6e 74  File, sqlite_int
25f0: 36 34 20 2a 70 53 69 7a 65 29 7b 0a 20 20 41 70  64 *pSize){.  Ap
2600: 6e 64 46 69 6c 65 20 2a 70 20 3d 20 28 41 70 6e  ndFile *p = (Apn
2610: 64 46 69 6c 65 20 2a 29 70 46 69 6c 65 3b 0a 20  dFile *)pFile;. 
2620: 20 69 6e 74 20 72 63 3b 0a 20 20 70 46 69 6c 65   int rc;.  pFile
2630: 20 3d 20 4f 52 49 47 46 49 4c 45 28 70 29 3b 0a   = ORIGFILE(p);.
2640: 20 20 72 63 20 3d 20 70 46 69 6c 65 2d 3e 70 4d    rc = pFile->pM
2650: 65 74 68 6f 64 73 2d 3e 78 46 69 6c 65 53 69 7a  ethods->xFileSiz
2660: 65 28 70 46 69 6c 65 2c 20 70 53 69 7a 65 29 3b  e(pFile, pSize);
2670: 0a 20 20 69 66 28 20 72 63 3d 3d 53 51 4c 49 54  .  if( rc==SQLIT
2680: 45 5f 4f 4b 20 26 26 20 70 2d 3e 69 50 67 4f 6e  E_OK && p->iPgOn
2690: 65 20 29 7b 0a 20 20 20 20 2a 70 53 69 7a 65 20  e ){.    *pSize 
26a0: 2d 3d 20 70 2d 3e 69 50 67 4f 6e 65 20 2b 20 41  -= p->iPgOne + A
26b0: 50 4e 44 5f 4d 41 52 4b 5f 53 49 5a 45 3b 0a 20  PND_MARK_SIZE;. 
26c0: 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a   }.  return rc;.
26d0: 7d 0a 0a 2f 2a 0a 2a 2a 20 4c 6f 63 6b 20 61 6e  }../*.** Lock an
26e0: 20 61 70 6e 64 2d 66 69 6c 65 2e 0a 2a 2f 0a 73   apnd-file..*/.s
26f0: 74 61 74 69 63 20 69 6e 74 20 61 70 6e 64 4c 6f  tatic int apndLo
2700: 63 6b 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  ck(sqlite3_file 
2710: 2a 70 46 69 6c 65 2c 20 69 6e 74 20 65 4c 6f 63  *pFile, int eLoc
2720: 6b 29 7b 0a 20 20 70 46 69 6c 65 20 3d 20 4f 52  k){.  pFile = OR
2730: 49 47 46 49 4c 45 28 70 46 69 6c 65 29 3b 0a 20  IGFILE(pFile);. 
2740: 20 72 65 74 75 72 6e 20 70 46 69 6c 65 2d 3e 70   return pFile->p
2750: 4d 65 74 68 6f 64 73 2d 3e 78 4c 6f 63 6b 28 70  Methods->xLock(p
2760: 46 69 6c 65 2c 20 65 4c 6f 63 6b 29 3b 0a 7d 0a  File, eLock);.}.
2770: 0a 2f 2a 0a 2a 2a 20 55 6e 6c 6f 63 6b 20 61 6e  ./*.** Unlock an
2780: 20 61 70 6e 64 2d 66 69 6c 65 2e 0a 2a 2f 0a 73   apnd-file..*/.s
2790: 74 61 74 69 63 20 69 6e 74 20 61 70 6e 64 55 6e  tatic int apndUn
27a0: 6c 6f 63 6b 28 73 71 6c 69 74 65 33 5f 66 69 6c  lock(sqlite3_fil
27b0: 65 20 2a 70 46 69 6c 65 2c 20 69 6e 74 20 65 4c  e *pFile, int eL
27c0: 6f 63 6b 29 7b 0a 20 20 70 46 69 6c 65 20 3d 20  ock){.  pFile = 
27d0: 4f 52 49 47 46 49 4c 45 28 70 46 69 6c 65 29 3b  ORIGFILE(pFile);
27e0: 0a 20 20 72 65 74 75 72 6e 20 70 46 69 6c 65 2d  .  return pFile-
27f0: 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 55 6e 6c 6f  >pMethods->xUnlo
2800: 63 6b 28 70 46 69 6c 65 2c 20 65 4c 6f 63 6b 29  ck(pFile, eLock)
2810: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 68 65 63 6b  ;.}../*.** Check
2820: 20 69 66 20 61 6e 6f 74 68 65 72 20 66 69 6c 65   if another file
2830: 2d 68 61 6e 64 6c 65 20 68 6f 6c 64 73 20 61 20  -handle holds a 
2840: 52 45 53 45 52 56 45 44 20 6c 6f 63 6b 20 6f 6e  RESERVED lock on
2850: 20 61 6e 20 61 70 6e 64 2d 66 69 6c 65 2e 0a 2a   an apnd-file..*
2860: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 6e  /.static int apn
2870: 64 43 68 65 63 6b 52 65 73 65 72 76 65 64 4c 6f  dCheckReservedLo
2880: 63 6b 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  ck(sqlite3_file 
2890: 2a 70 46 69 6c 65 2c 20 69 6e 74 20 2a 70 52 65  *pFile, int *pRe
28a0: 73 4f 75 74 29 7b 0a 20 20 70 46 69 6c 65 20 3d  sOut){.  pFile =
28b0: 20 4f 52 49 47 46 49 4c 45 28 70 46 69 6c 65 29   ORIGFILE(pFile)
28c0: 3b 0a 20 20 72 65 74 75 72 6e 20 70 46 69 6c 65  ;.  return pFile
28d0: 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 43 68 65  ->pMethods->xChe
28e0: 63 6b 52 65 73 65 72 76 65 64 4c 6f 63 6b 28 70  ckReservedLock(p
28f0: 46 69 6c 65 2c 20 70 52 65 73 4f 75 74 29 3b 0a  File, pResOut);.
2900: 7d 0a 0a 2f 2a 0a 2a 2a 20 46 69 6c 65 20 63 6f  }../*.** File co
2910: 6e 74 72 6f 6c 20 6d 65 74 68 6f 64 2e 20 46 6f  ntrol method. Fo
2920: 72 20 63 75 73 74 6f 6d 20 6f 70 65 72 61 74 69  r custom operati
2930: 6f 6e 73 20 6f 6e 20 61 6e 20 61 70 6e 64 2d 66  ons on an apnd-f
2940: 69 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ile..*/.static i
2950: 6e 74 20 61 70 6e 64 46 69 6c 65 43 6f 6e 74 72  nt apndFileContr
2960: 6f 6c 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  ol(sqlite3_file 
2970: 2a 70 46 69 6c 65 2c 20 69 6e 74 20 6f 70 2c 20  *pFile, int op, 
2980: 76 6f 69 64 20 2a 70 41 72 67 29 7b 0a 20 20 41  void *pArg){.  A
2990: 70 6e 64 46 69 6c 65 20 2a 70 20 3d 20 28 41 70  pndFile *p = (Ap
29a0: 6e 64 46 69 6c 65 20 2a 29 70 46 69 6c 65 3b 0a  ndFile *)pFile;.
29b0: 20 20 69 6e 74 20 72 63 3b 0a 20 20 70 46 69 6c    int rc;.  pFil
29c0: 65 20 3d 20 4f 52 49 47 46 49 4c 45 28 70 46 69  e = ORIGFILE(pFi
29d0: 6c 65 29 3b 0a 20 20 72 63 20 3d 20 70 46 69 6c  le);.  rc = pFil
29e0: 65 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 46 69  e->pMethods->xFi
29f0: 6c 65 43 6f 6e 74 72 6f 6c 28 70 46 69 6c 65 2c  leControl(pFile,
2a00: 20 6f 70 2c 20 70 41 72 67 29 3b 0a 20 20 69 66   op, pArg);.  if
2a10: 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20  ( rc==SQLITE_OK 
2a20: 26 26 20 6f 70 3d 3d 53 51 4c 49 54 45 5f 46 43  && op==SQLITE_FC
2a30: 4e 54 4c 5f 56 46 53 4e 41 4d 45 20 29 7b 0a 20  NTL_VFSNAME ){. 
2a40: 20 20 20 2a 28 63 68 61 72 2a 2a 29 70 41 72 67     *(char**)pArg
2a50: 20 3d 20 73 71 6c 69 74 65 33 5f 6d 70 72 69 6e   = sqlite3_mprin
2a60: 74 66 28 22 61 70 6e 64 28 25 6c 6c 64 29 2f 25  tf("apnd(%lld)/%
2a70: 7a 22 2c 20 70 2d 3e 69 50 67 4f 6e 65 2c 20 2a  z", p->iPgOne, *
2a80: 28 63 68 61 72 2a 2a 29 70 41 72 67 29 3b 0a 20  (char**)pArg);. 
2a90: 20 7d 0a 20 20 72 65 74 75 72 6e 20 72 63 3b 0a   }.  return rc;.
2aa0: 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20  }../*.** Return 
2ab0: 74 68 65 20 73 65 63 74 6f 72 2d 73 69 7a 65 20  the sector-size 
2ac0: 69 6e 20 62 79 74 65 73 20 66 6f 72 20 61 6e 20  in bytes for an 
2ad0: 61 70 6e 64 2d 66 69 6c 65 2e 0a 2a 2f 0a 73 74  apnd-file..*/.st
2ae0: 61 74 69 63 20 69 6e 74 20 61 70 6e 64 53 65 63  atic int apndSec
2af0: 74 6f 72 53 69 7a 65 28 73 71 6c 69 74 65 33 5f  torSize(sqlite3_
2b00: 66 69 6c 65 20 2a 70 46 69 6c 65 29 7b 0a 20 20  file *pFile){.  
2b10: 70 46 69 6c 65 20 3d 20 4f 52 49 47 46 49 4c 45  pFile = ORIGFILE
2b20: 28 70 46 69 6c 65 29 3b 0a 20 20 72 65 74 75 72  (pFile);.  retur
2b30: 6e 20 70 46 69 6c 65 2d 3e 70 4d 65 74 68 6f 64  n pFile->pMethod
2b40: 73 2d 3e 78 53 65 63 74 6f 72 53 69 7a 65 28 70  s->xSectorSize(p
2b50: 46 69 6c 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  File);.}../*.** 
2b60: 52 65 74 75 72 6e 20 74 68 65 20 64 65 76 69 63  Return the devic
2b70: 65 20 63 68 61 72 61 63 74 65 72 69 73 74 69 63  e characteristic
2b80: 20 66 6c 61 67 73 20 73 75 70 70 6f 72 74 65 64   flags supported
2b90: 20 62 79 20 61 6e 20 61 70 6e 64 2d 66 69 6c 65   by an apnd-file
2ba0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  ..*/.static int 
2bb0: 61 70 6e 64 44 65 76 69 63 65 43 68 61 72 61 63  apndDeviceCharac
2bc0: 74 65 72 69 73 74 69 63 73 28 73 71 6c 69 74 65  teristics(sqlite
2bd0: 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 29 7b 0a  3_file *pFile){.
2be0: 20 20 70 46 69 6c 65 20 3d 20 4f 52 49 47 46 49    pFile = ORIGFI
2bf0: 4c 45 28 70 46 69 6c 65 29 3b 0a 20 20 72 65 74  LE(pFile);.  ret
2c00: 75 72 6e 20 70 46 69 6c 65 2d 3e 70 4d 65 74 68  urn pFile->pMeth
2c10: 6f 64 73 2d 3e 78 44 65 76 69 63 65 43 68 61 72  ods->xDeviceChar
2c20: 61 63 74 65 72 69 73 74 69 63 73 28 70 46 69 6c  acteristics(pFil
2c30: 65 29 3b 0a 7d 0a 0a 2f 2a 20 43 72 65 61 74 65  e);.}../* Create
2c40: 20 61 20 73 68 61 72 65 64 20 6d 65 6d 6f 72 79   a shared memory
2c50: 20 66 69 6c 65 20 6d 61 70 70 69 6e 67 20 2a 2f   file mapping */
2c60: 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 6e 64  .static int apnd
2c70: 53 68 6d 4d 61 70 28 0a 20 20 73 71 6c 69 74 65  ShmMap(.  sqlite
2c80: 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65 2c 0a 20  3_file *pFile,. 
2c90: 20 69 6e 74 20 69 50 67 2c 0a 20 20 69 6e 74 20   int iPg,.  int 
2ca0: 70 67 73 7a 2c 0a 20 20 69 6e 74 20 62 45 78 74  pgsz,.  int bExt
2cb0: 65 6e 64 2c 0a 20 20 76 6f 69 64 20 76 6f 6c 61  end,.  void vola
2cc0: 74 69 6c 65 20 2a 2a 70 70 0a 29 7b 0a 20 20 70  tile **pp.){.  p
2cd0: 46 69 6c 65 20 3d 20 4f 52 49 47 46 49 4c 45 28  File = ORIGFILE(
2ce0: 70 46 69 6c 65 29 3b 0a 20 20 72 65 74 75 72 6e  pFile);.  return
2cf0: 20 70 46 69 6c 65 2d 3e 70 4d 65 74 68 6f 64 73   pFile->pMethods
2d00: 2d 3e 78 53 68 6d 4d 61 70 28 70 46 69 6c 65 2c  ->xShmMap(pFile,
2d10: 69 50 67 2c 70 67 73 7a 2c 62 45 78 74 65 6e 64  iPg,pgsz,bExtend
2d20: 2c 70 70 29 3b 0a 7d 0a 0a 2f 2a 20 50 65 72 66  ,pp);.}../* Perf
2d30: 6f 72 6d 20 6c 6f 63 6b 69 6e 67 20 6f 6e 20 61  orm locking on a
2d40: 20 73 68 61 72 65 64 2d 6d 65 6d 6f 72 79 20 73   shared-memory s
2d50: 65 67 6d 65 6e 74 20 2a 2f 0a 73 74 61 74 69 63  egment */.static
2d60: 20 69 6e 74 20 61 70 6e 64 53 68 6d 4c 6f 63 6b   int apndShmLock
2d70: 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70  (sqlite3_file *p
2d80: 46 69 6c 65 2c 20 69 6e 74 20 6f 66 66 73 65 74  File, int offset
2d90: 2c 20 69 6e 74 20 6e 2c 20 69 6e 74 20 66 6c 61  , int n, int fla
2da0: 67 73 29 7b 0a 20 20 70 46 69 6c 65 20 3d 20 4f  gs){.  pFile = O
2db0: 52 49 47 46 49 4c 45 28 70 46 69 6c 65 29 3b 0a  RIGFILE(pFile);.
2dc0: 20 20 72 65 74 75 72 6e 20 70 46 69 6c 65 2d 3e    return pFile->
2dd0: 70 4d 65 74 68 6f 64 73 2d 3e 78 53 68 6d 4c 6f  pMethods->xShmLo
2de0: 63 6b 28 70 46 69 6c 65 2c 6f 66 66 73 65 74 2c  ck(pFile,offset,
2df0: 6e 2c 66 6c 61 67 73 29 3b 0a 7d 0a 0a 2f 2a 20  n,flags);.}../* 
2e00: 4d 65 6d 6f 72 79 20 62 61 72 72 69 65 72 20 6f  Memory barrier o
2e10: 70 65 72 61 74 69 6f 6e 20 6f 6e 20 73 68 61 72  peration on shar
2e20: 65 64 20 6d 65 6d 6f 72 79 20 2a 2f 0a 73 74 61  ed memory */.sta
2e30: 74 69 63 20 76 6f 69 64 20 61 70 6e 64 53 68 6d  tic void apndShm
2e40: 42 61 72 72 69 65 72 28 73 71 6c 69 74 65 33 5f  Barrier(sqlite3_
2e50: 66 69 6c 65 20 2a 70 46 69 6c 65 29 7b 0a 20 20  file *pFile){.  
2e60: 70 46 69 6c 65 20 3d 20 4f 52 49 47 46 49 4c 45  pFile = ORIGFILE
2e70: 28 70 46 69 6c 65 29 3b 0a 20 20 70 46 69 6c 65  (pFile);.  pFile
2e80: 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 53 68 6d  ->pMethods->xShm
2e90: 42 61 72 72 69 65 72 28 70 46 69 6c 65 29 3b 0a  Barrier(pFile);.
2ea0: 7d 0a 0a 2f 2a 20 55 6e 6d 61 70 20 61 20 73 68  }../* Unmap a sh
2eb0: 61 72 65 64 20 6d 65 6d 6f 72 79 20 73 65 67 6d  ared memory segm
2ec0: 65 6e 74 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ent */.static in
2ed0: 74 20 61 70 6e 64 53 68 6d 55 6e 6d 61 70 28 73  t apndShmUnmap(s
2ee0: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69  qlite3_file *pFi
2ef0: 6c 65 2c 20 69 6e 74 20 64 65 6c 65 74 65 46 6c  le, int deleteFl
2f00: 61 67 29 7b 0a 20 20 70 46 69 6c 65 20 3d 20 4f  ag){.  pFile = O
2f10: 52 49 47 46 49 4c 45 28 70 46 69 6c 65 29 3b 0a  RIGFILE(pFile);.
2f20: 20 20 72 65 74 75 72 6e 20 70 46 69 6c 65 2d 3e    return pFile->
2f30: 70 4d 65 74 68 6f 64 73 2d 3e 78 53 68 6d 55 6e  pMethods->xShmUn
2f40: 6d 61 70 28 70 46 69 6c 65 2c 64 65 6c 65 74 65  map(pFile,delete
2f50: 46 6c 61 67 29 3b 0a 7d 0a 0a 2f 2a 20 46 65 74  Flag);.}../* Fet
2f60: 63 68 20 61 20 70 61 67 65 20 6f 66 20 61 20 6d  ch a page of a m
2f70: 65 6d 6f 72 79 2d 6d 61 70 70 65 64 20 66 69 6c  emory-mapped fil
2f80: 65 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  e */.static int 
2f90: 61 70 6e 64 46 65 74 63 68 28 0a 20 20 73 71 6c  apndFetch(.  sql
2fa0: 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c 65  ite3_file *pFile
2fb0: 2c 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36  ,.  sqlite3_int6
2fc0: 34 20 69 4f 66 73 74 2c 0a 20 20 69 6e 74 20 69  4 iOfst,.  int i
2fd0: 41 6d 74 2c 0a 20 20 76 6f 69 64 20 2a 2a 70 70  Amt,.  void **pp
2fe0: 0a 29 7b 0a 20 20 41 70 6e 64 46 69 6c 65 20 2a  .){.  ApndFile *
2ff0: 70 20 3d 20 28 41 70 6e 64 46 69 6c 65 20 2a 29  p = (ApndFile *)
3000: 70 46 69 6c 65 3b 0a 20 20 70 46 69 6c 65 20 3d  pFile;.  pFile =
3010: 20 4f 52 49 47 46 49 4c 45 28 70 46 69 6c 65 29   ORIGFILE(pFile)
3020: 3b 0a 20 20 72 65 74 75 72 6e 20 70 46 69 6c 65  ;.  return pFile
3030: 2d 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 46 65 74  ->pMethods->xFet
3040: 63 68 28 70 46 69 6c 65 2c 20 69 4f 66 73 74 2b  ch(pFile, iOfst+
3050: 70 2d 3e 69 50 67 4f 6e 65 2c 20 69 41 6d 74 2c  p->iPgOne, iAmt,
3060: 20 70 70 29 3b 0a 7d 0a 0a 2f 2a 20 52 65 6c 65   pp);.}../* Rele
3070: 61 73 65 20 61 20 6d 65 6d 6f 72 79 2d 6d 61 70  ase a memory-map
3080: 70 65 64 20 70 61 67 65 20 2a 2f 0a 73 74 61 74  ped page */.stat
3090: 69 63 20 69 6e 74 20 61 70 6e 64 55 6e 66 65 74  ic int apndUnfet
30a0: 63 68 28 73 71 6c 69 74 65 33 5f 66 69 6c 65 20  ch(sqlite3_file 
30b0: 2a 70 46 69 6c 65 2c 20 73 71 6c 69 74 65 33 5f  *pFile, sqlite3_
30c0: 69 6e 74 36 34 20 69 4f 66 73 74 2c 20 76 6f 69  int64 iOfst, voi
30d0: 64 20 2a 70 50 61 67 65 29 7b 0a 20 20 41 70 6e  d *pPage){.  Apn
30e0: 64 46 69 6c 65 20 2a 70 20 3d 20 28 41 70 6e 64  dFile *p = (Apnd
30f0: 46 69 6c 65 20 2a 29 70 46 69 6c 65 3b 0a 20 20  File *)pFile;.  
3100: 70 46 69 6c 65 20 3d 20 4f 52 49 47 46 49 4c 45  pFile = ORIGFILE
3110: 28 70 46 69 6c 65 29 3b 0a 20 20 72 65 74 75 72  (pFile);.  retur
3120: 6e 20 70 46 69 6c 65 2d 3e 70 4d 65 74 68 6f 64  n pFile->pMethod
3130: 73 2d 3e 78 55 6e 66 65 74 63 68 28 70 46 69 6c  s->xUnfetch(pFil
3140: 65 2c 20 69 4f 66 73 74 2b 70 2d 3e 69 50 67 4f  e, iOfst+p->iPgO
3150: 6e 65 2c 20 70 50 61 67 65 29 3b 0a 7d 0a 0a 2f  ne, pPage);.}../
3160: 2a 0a 2a 2a 20 43 68 65 63 6b 20 74 6f 20 73 65  *.** Check to se
3170: 65 20 69 66 20 74 68 65 20 66 69 6c 65 20 69 73  e if the file is
3180: 20 61 6e 20 6f 72 64 69 6e 61 72 79 20 53 51 4c   an ordinary SQL
3190: 69 74 65 20 64 61 74 61 62 61 73 65 20 66 69 6c  ite database fil
31a0: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  e..*/.static int
31b0: 20 61 70 6e 64 49 73 4f 72 64 69 6e 61 72 79 44   apndIsOrdinaryD
31c0: 61 74 61 62 61 73 65 46 69 6c 65 28 73 71 6c 69  atabaseFile(sqli
31d0: 74 65 33 5f 69 6e 74 36 34 20 73 7a 2c 20 73 71  te3_int64 sz, sq
31e0: 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69 6c  lite3_file *pFil
31f0: 65 29 7b 0a 20 20 69 6e 74 20 72 63 3b 0a 20 20  e){.  int rc;.  
3200: 63 68 61 72 20 7a 48 64 72 5b 31 36 5d 3b 0a 20  char zHdr[16];. 
3210: 20 73 74 61 74 69 63 20 63 6f 6e 73 74 20 63 68   static const ch
3220: 61 72 20 61 53 71 6c 69 74 65 48 64 72 5b 5d 20  ar aSqliteHdr[] 
3230: 3d 20 22 53 51 4c 69 74 65 20 66 6f 72 6d 61 74  = "SQLite format
3240: 20 33 22 3b 0a 20 20 69 66 28 20 73 7a 3c 35 31   3";.  if( sz<51
3250: 32 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20  2 ) return 0;.  
3260: 72 63 20 3d 20 70 46 69 6c 65 2d 3e 70 4d 65 74  rc = pFile->pMet
3270: 68 6f 64 73 2d 3e 78 52 65 61 64 28 70 46 69 6c  hods->xRead(pFil
3280: 65 2c 20 7a 48 64 72 2c 20 73 69 7a 65 6f 66 28  e, zHdr, sizeof(
3290: 7a 48 64 72 29 2c 20 30 29 3b 0a 20 20 69 66 28  zHdr), 0);.  if(
32a0: 20 72 63 20 29 20 72 65 74 75 72 6e 20 30 3b 0a   rc ) return 0;.
32b0: 20 20 72 65 74 75 72 6e 20 6d 65 6d 63 6d 70 28    return memcmp(
32c0: 7a 48 64 72 2c 20 61 53 71 6c 69 74 65 48 64 72  zHdr, aSqliteHdr
32d0: 2c 20 73 69 7a 65 6f 66 28 7a 48 64 72 29 29 3d  , sizeof(zHdr))=
32e0: 3d 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 72 79  =0;.}../*.** Try
32f0: 20 74 6f 20 72 65 61 64 20 74 68 65 20 61 70 70   to read the app
3300: 65 6e 64 2d 6d 61 72 6b 20 6f 66 66 20 74 68 65  end-mark off the
3310: 20 65 6e 64 20 6f 66 20 61 20 66 69 6c 65 2e 20   end of a file. 
3320: 20 52 65 74 75 72 6e 20 74 68 65 0a 2a 2a 20 73   Return the.** s
3330: 74 61 72 74 20 6f 66 20 74 68 65 20 61 70 70 65  tart of the appe
3340: 6e 64 65 64 20 64 61 74 61 62 61 73 65 20 69 66  nded database if
3350: 20 74 68 65 20 61 70 70 65 6e 64 2d 6d 61 72 6b   the append-mark
3360: 20 69 73 20 70 72 65 73 65 6e 74 2e 20 20 49 66   is present.  If
3370: 0a 2a 2a 20 74 68 65 72 65 20 69 73 20 6e 6f 20  .** there is no 
3380: 61 70 70 65 6e 64 2d 6d 61 72 6b 2c 20 72 65 74  append-mark, ret
3390: 75 72 6e 20 2d 31 3b 0a 2a 2f 0a 73 74 61 74 69  urn -1;.*/.stati
33a0: 63 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20  c sqlite3_int64 
33b0: 61 70 6e 64 52 65 61 64 4d 61 72 6b 28 73 71 6c  apndReadMark(sql
33c0: 69 74 65 33 5f 69 6e 74 36 34 20 73 7a 2c 20 73  ite3_int64 sz, s
33d0: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69  qlite3_file *pFi
33e0: 6c 65 29 7b 0a 20 20 69 6e 74 20 72 63 2c 20 69  le){.  int rc, i
33f0: 3b 0a 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36  ;.  sqlite3_int6
3400: 34 20 69 4d 61 72 6b 3b 0a 20 20 75 6e 73 69 67  4 iMark;.  unsig
3410: 6e 65 64 20 63 68 61 72 20 61 5b 41 50 4e 44 5f  ned char a[APND_
3420: 4d 41 52 4b 5f 53 49 5a 45 5d 3b 0a 0a 20 20 69  MARK_SIZE];..  i
3430: 66 28 20 73 7a 3c 3d 41 50 4e 44 5f 4d 41 52 4b  f( sz<=APND_MARK
3440: 5f 53 49 5a 45 20 29 20 72 65 74 75 72 6e 20 2d  _SIZE ) return -
3450: 31 3b 0a 20 20 72 63 20 3d 20 70 46 69 6c 65 2d  1;.  rc = pFile-
3460: 3e 70 4d 65 74 68 6f 64 73 2d 3e 78 52 65 61 64  >pMethods->xRead
3470: 28 70 46 69 6c 65 2c 20 61 2c 20 41 50 4e 44 5f  (pFile, a, APND_
3480: 4d 41 52 4b 5f 53 49 5a 45 2c 20 73 7a 2d 41 50  MARK_SIZE, sz-AP
3490: 4e 44 5f 4d 41 52 4b 5f 53 49 5a 45 29 3b 0a 20  ND_MARK_SIZE);. 
34a0: 20 69 66 28 20 72 63 20 29 20 72 65 74 75 72 6e   if( rc ) return
34b0: 20 2d 31 3b 0a 20 20 69 66 28 20 6d 65 6d 63 6d   -1;.  if( memcm
34c0: 70 28 61 2c 20 41 50 4e 44 5f 4d 41 52 4b 5f 50  p(a, APND_MARK_P
34d0: 52 45 46 49 58 2c 20 41 50 4e 44 5f 4d 41 52 4b  REFIX, APND_MARK
34e0: 5f 50 52 45 46 49 58 5f 53 5a 29 21 3d 30 20 29  _PREFIX_SZ)!=0 )
34f0: 20 72 65 74 75 72 6e 20 2d 31 3b 0a 20 20 69 4d   return -1;.  iM
3500: 61 72 6b 20 3d 20 28 28 73 71 6c 69 74 65 33 5f  ark = ((sqlite3_
3510: 69 6e 74 36 34 29 28 61 5b 41 50 4e 44 5f 4d 41  int64)(a[APND_MA
3520: 52 4b 5f 50 52 45 46 49 58 5f 53 5a 5d 26 30 78  RK_PREFIX_SZ]&0x
3530: 37 66 29 29 3c 3c 35 36 3b 0a 20 20 66 6f 72 28  7f))<<56;.  for(
3540: 69 3d 31 3b 20 69 3c 38 3b 20 69 2b 2b 29 7b 20  i=1; i<8; i++){ 
3550: 20 20 20 0a 20 20 20 20 69 4d 61 72 6b 20 2b 3d     .    iMark +=
3560: 20 28 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 29   (sqlite3_int64)
3570: 61 5b 41 50 4e 44 5f 4d 41 52 4b 5f 50 52 45 46  a[APND_MARK_PREF
3580: 49 58 5f 53 5a 2b 69 5d 3c 3c 28 35 36 2d 38 2a  IX_SZ+i]<<(56-8*
3590: 69 29 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e  i);.  }.  return
35a0: 20 69 4d 61 72 6b 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a   iMark;.}../*.**
35b0: 20 4f 70 65 6e 20 61 6e 20 61 70 6e 64 20 66 69   Open an apnd fi
35c0: 6c 65 20 68 61 6e 64 6c 65 2e 0a 2a 2f 0a 73 74  le handle..*/.st
35d0: 61 74 69 63 20 69 6e 74 20 61 70 6e 64 4f 70 65  atic int apndOpe
35e0: 6e 28 0a 20 20 73 71 6c 69 74 65 33 5f 76 66 73  n(.  sqlite3_vfs
35f0: 20 2a 70 56 66 73 2c 0a 20 20 63 6f 6e 73 74 20   *pVfs,.  const 
3600: 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 0a 20 20 73  char *zName,.  s
3610: 71 6c 69 74 65 33 5f 66 69 6c 65 20 2a 70 46 69  qlite3_file *pFi
3620: 6c 65 2c 0a 20 20 69 6e 74 20 66 6c 61 67 73 2c  le,.  int flags,
3630: 0a 20 20 69 6e 74 20 2a 70 4f 75 74 46 6c 61 67  .  int *pOutFlag
3640: 73 0a 29 7b 0a 20 20 41 70 6e 64 46 69 6c 65 20  s.){.  ApndFile 
3650: 2a 70 3b 0a 20 20 73 71 6c 69 74 65 33 5f 66 69  *p;.  sqlite3_fi
3660: 6c 65 20 2a 70 53 75 62 46 69 6c 65 3b 0a 20 20  le *pSubFile;.  
3670: 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 53 75  sqlite3_vfs *pSu
3680: 62 56 66 73 3b 0a 20 20 69 6e 74 20 72 63 3b 0a  bVfs;.  int rc;.
3690: 20 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20    sqlite3_int64 
36a0: 73 7a 3b 0a 20 20 70 53 75 62 56 66 73 20 3d 20  sz;.  pSubVfs = 
36b0: 4f 52 49 47 56 46 53 28 70 56 66 73 29 3b 0a 20  ORIGVFS(pVfs);. 
36c0: 20 69 66 28 20 28 66 6c 61 67 73 20 26 20 53 51   if( (flags & SQ
36d0: 4c 49 54 45 5f 4f 50 45 4e 5f 4d 41 49 4e 5f 44  LITE_OPEN_MAIN_D
36e0: 42 29 3d 3d 30 20 29 7b 0a 20 20 20 20 72 65 74  B)==0 ){.    ret
36f0: 75 72 6e 20 70 53 75 62 56 66 73 2d 3e 78 4f 70  urn pSubVfs->xOp
3700: 65 6e 28 70 53 75 62 56 66 73 2c 20 7a 4e 61 6d  en(pSubVfs, zNam
3710: 65 2c 20 70 46 69 6c 65 2c 20 66 6c 61 67 73 2c  e, pFile, flags,
3720: 20 70 4f 75 74 46 6c 61 67 73 29 3b 0a 20 20 7d   pOutFlags);.  }
3730: 0a 20 20 70 20 3d 20 28 41 70 6e 64 46 69 6c 65  .  p = (ApndFile
3740: 2a 29 70 46 69 6c 65 3b 0a 20 20 6d 65 6d 73 65  *)pFile;.  memse
3750: 74 28 70 2c 20 30 2c 20 73 69 7a 65 6f 66 28 2a  t(p, 0, sizeof(*
3760: 70 29 29 3b 0a 20 20 70 53 75 62 46 69 6c 65 20  p));.  pSubFile 
3770: 3d 20 4f 52 49 47 46 49 4c 45 28 70 46 69 6c 65  = ORIGFILE(pFile
3780: 29 3b 0a 20 20 70 2d 3e 62 61 73 65 2e 70 4d 65  );.  p->base.pMe
3790: 74 68 6f 64 73 20 3d 20 26 61 70 6e 64 5f 69 6f  thods = &apnd_io
37a0: 5f 6d 65 74 68 6f 64 73 3b 0a 20 20 72 63 20 3d  _methods;.  rc =
37b0: 20 70 53 75 62 56 66 73 2d 3e 78 4f 70 65 6e 28   pSubVfs->xOpen(
37c0: 70 53 75 62 56 66 73 2c 20 7a 4e 61 6d 65 2c 20  pSubVfs, zName, 
37d0: 70 53 75 62 46 69 6c 65 2c 20 66 6c 61 67 73 2c  pSubFile, flags,
37e0: 20 70 4f 75 74 46 6c 61 67 73 29 3b 0a 20 20 69   pOutFlags);.  i
37f0: 66 28 20 72 63 20 29 20 67 6f 74 6f 20 61 70 6e  f( rc ) goto apn
3800: 64 5f 6f 70 65 6e 5f 64 6f 6e 65 3b 0a 20 20 72  d_open_done;.  r
3810: 63 20 3d 20 70 53 75 62 46 69 6c 65 2d 3e 70 4d  c = pSubFile->pM
3820: 65 74 68 6f 64 73 2d 3e 78 46 69 6c 65 53 69 7a  ethods->xFileSiz
3830: 65 28 70 53 75 62 46 69 6c 65 2c 20 26 73 7a 29  e(pSubFile, &sz)
3840: 3b 0a 20 20 69 66 28 20 72 63 20 29 7b 0a 20 20  ;.  if( rc ){.  
3850: 20 20 70 53 75 62 46 69 6c 65 2d 3e 70 4d 65 74    pSubFile->pMet
3860: 68 6f 64 73 2d 3e 78 43 6c 6f 73 65 28 70 53 75  hods->xClose(pSu
3870: 62 46 69 6c 65 29 3b 0a 20 20 20 20 67 6f 74 6f  bFile);.    goto
3880: 20 61 70 6e 64 5f 6f 70 65 6e 5f 64 6f 6e 65 3b   apnd_open_done;
3890: 0a 20 20 7d 0a 20 20 69 66 28 20 61 70 6e 64 49  .  }.  if( apndI
38a0: 73 4f 72 64 69 6e 61 72 79 44 61 74 61 62 61 73  sOrdinaryDatabas
38b0: 65 46 69 6c 65 28 73 7a 2c 20 70 53 75 62 46 69  eFile(sz, pSubFi
38c0: 6c 65 29 20 29 7b 0a 20 20 20 20 6d 65 6d 6d 6f  le) ){.    memmo
38d0: 76 65 28 70 46 69 6c 65 2c 20 70 53 75 62 46 69  ve(pFile, pSubFi
38e0: 6c 65 2c 20 70 53 75 62 56 66 73 2d 3e 73 7a 4f  le, pSubVfs->szO
38f0: 73 46 69 6c 65 29 3b 0a 20 20 20 20 72 65 74 75  sFile);.    retu
3900: 72 6e 20 53 51 4c 49 54 45 5f 4f 4b 3b 0a 20 20  rn SQLITE_OK;.  
3910: 7d 0a 20 20 70 2d 3e 69 4d 61 72 6b 20 3d 20 30  }.  p->iMark = 0
3920: 3b 0a 20 20 70 2d 3e 69 50 67 4f 6e 65 20 3d 20  ;.  p->iPgOne = 
3930: 61 70 6e 64 52 65 61 64 4d 61 72 6b 28 73 7a 2c  apndReadMark(sz,
3940: 20 70 46 69 6c 65 29 3b 0a 20 20 69 66 28 20 70   pFile);.  if( p
3950: 2d 3e 69 50 67 4f 6e 65 3e 30 20 29 7b 0a 20 20  ->iPgOne>0 ){.  
3960: 20 20 72 65 74 75 72 6e 20 53 51 4c 49 54 45 5f    return SQLITE_
3970: 4f 4b 3b 0a 20 20 7d 0a 20 20 69 66 28 20 28 66  OK;.  }.  if( (f
3980: 6c 61 67 73 20 26 20 53 51 4c 49 54 45 5f 4f 50  lags & SQLITE_OP
3990: 45 4e 5f 43 52 45 41 54 45 29 3d 3d 30 20 29 7b  EN_CREATE)==0 ){
39a0: 0a 20 20 20 20 70 53 75 62 46 69 6c 65 2d 3e 70  .    pSubFile->p
39b0: 4d 65 74 68 6f 64 73 2d 3e 78 43 6c 6f 73 65 28  Methods->xClose(
39c0: 70 53 75 62 46 69 6c 65 29 3b 0a 20 20 20 20 72  pSubFile);.    r
39d0: 63 20 3d 20 53 51 4c 49 54 45 5f 43 41 4e 54 4f  c = SQLITE_CANTO
39e0: 50 45 4e 3b 0a 20 20 7d 0a 20 20 70 2d 3e 69 50  PEN;.  }.  p->iP
39f0: 67 4f 6e 65 20 3d 20 28 73 7a 2b 30 78 66 66 66  gOne = (sz+0xfff
3a00: 29 20 26 20 7e 28 73 71 6c 69 74 65 33 5f 69 6e  ) & ~(sqlite3_in
3a10: 74 36 34 29 30 78 66 66 66 3b 0a 61 70 6e 64 5f  t64)0xfff;.apnd_
3a20: 6f 70 65 6e 5f 64 6f 6e 65 3a 0a 20 20 69 66 28  open_done:.  if(
3a30: 20 72 63 20 29 20 70 46 69 6c 65 2d 3e 70 4d 65   rc ) pFile->pMe
3a40: 74 68 6f 64 73 20 3d 20 30 3b 0a 20 20 72 65 74  thods = 0;.  ret
3a50: 75 72 6e 20 72 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  urn rc;.}../*.**
3a60: 20 41 6c 6c 20 6f 74 68 65 72 20 56 46 53 20 6d   All other VFS m
3a70: 65 74 68 6f 64 73 20 61 72 65 20 70 61 73 73 2d  ethods are pass-
3a80: 74 68 72 75 73 2e 0a 2a 2f 0a 73 74 61 74 69 63  thrus..*/.static
3a90: 20 69 6e 74 20 61 70 6e 64 44 65 6c 65 74 65 28   int apndDelete(
3aa0: 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66  sqlite3_vfs *pVf
3ab0: 73 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  s, const char *z
3ac0: 50 61 74 68 2c 20 69 6e 74 20 64 69 72 53 79 6e  Path, int dirSyn
3ad0: 63 29 7b 0a 20 20 72 65 74 75 72 6e 20 4f 52 49  c){.  return ORI
3ae0: 47 56 46 53 28 70 56 66 73 29 2d 3e 78 44 65 6c  GVFS(pVfs)->xDel
3af0: 65 74 65 28 4f 52 49 47 56 46 53 28 70 56 66 73  ete(ORIGVFS(pVfs
3b00: 29 2c 20 7a 50 61 74 68 2c 20 64 69 72 53 79 6e  ), zPath, dirSyn
3b10: 63 29 3b 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74  c);.}.static int
3b20: 20 61 70 6e 64 41 63 63 65 73 73 28 0a 20 20 73   apndAccess(.  s
3b30: 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73  qlite3_vfs *pVfs
3b40: 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  , .  const char 
3b50: 2a 7a 50 61 74 68 2c 20 0a 20 20 69 6e 74 20 66  *zPath, .  int f
3b60: 6c 61 67 73 2c 20 0a 20 20 69 6e 74 20 2a 70 52  lags, .  int *pR
3b70: 65 73 4f 75 74 0a 29 7b 0a 20 20 72 65 74 75 72  esOut.){.  retur
3b80: 6e 20 4f 52 49 47 56 46 53 28 70 56 66 73 29 2d  n ORIGVFS(pVfs)-
3b90: 3e 78 41 63 63 65 73 73 28 4f 52 49 47 56 46 53  >xAccess(ORIGVFS
3ba0: 28 70 56 66 73 29 2c 20 7a 50 61 74 68 2c 20 66  (pVfs), zPath, f
3bb0: 6c 61 67 73 2c 20 70 52 65 73 4f 75 74 29 3b 0a  lags, pResOut);.
3bc0: 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 6e  }.static int apn
3bd0: 64 46 75 6c 6c 50 61 74 68 6e 61 6d 65 28 0a 20  dFullPathname(. 
3be0: 20 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56   sqlite3_vfs *pV
3bf0: 66 73 2c 20 0a 20 20 63 6f 6e 73 74 20 63 68 61  fs, .  const cha
3c00: 72 20 2a 7a 50 61 74 68 2c 20 0a 20 20 69 6e 74  r *zPath, .  int
3c10: 20 6e 4f 75 74 2c 20 0a 20 20 63 68 61 72 20 2a   nOut, .  char *
3c20: 7a 4f 75 74 0a 29 7b 0a 20 20 72 65 74 75 72 6e  zOut.){.  return
3c30: 20 4f 52 49 47 56 46 53 28 70 56 66 73 29 2d 3e   ORIGVFS(pVfs)->
3c40: 78 46 75 6c 6c 50 61 74 68 6e 61 6d 65 28 4f 52  xFullPathname(OR
3c50: 49 47 56 46 53 28 70 56 66 73 29 2c 7a 50 61 74  IGVFS(pVfs),zPat
3c60: 68 2c 6e 4f 75 74 2c 7a 4f 75 74 29 3b 0a 7d 0a  h,nOut,zOut);.}.
3c70: 73 74 61 74 69 63 20 76 6f 69 64 20 2a 61 70 6e  static void *apn
3c80: 64 44 6c 4f 70 65 6e 28 73 71 6c 69 74 65 33 5f  dDlOpen(sqlite3_
3c90: 76 66 73 20 2a 70 56 66 73 2c 20 63 6f 6e 73 74  vfs *pVfs, const
3ca0: 20 63 68 61 72 20 2a 7a 50 61 74 68 29 7b 0a 20   char *zPath){. 
3cb0: 20 72 65 74 75 72 6e 20 4f 52 49 47 56 46 53 28   return ORIGVFS(
3cc0: 70 56 66 73 29 2d 3e 78 44 6c 4f 70 65 6e 28 4f  pVfs)->xDlOpen(O
3cd0: 52 49 47 56 46 53 28 70 56 66 73 29 2c 20 7a 50  RIGVFS(pVfs), zP
3ce0: 61 74 68 29 3b 0a 7d 0a 73 74 61 74 69 63 20 76  ath);.}.static v
3cf0: 6f 69 64 20 61 70 6e 64 44 6c 45 72 72 6f 72 28  oid apndDlError(
3d00: 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66  sqlite3_vfs *pVf
3d10: 73 2c 20 69 6e 74 20 6e 42 79 74 65 2c 20 63 68  s, int nByte, ch
3d20: 61 72 20 2a 7a 45 72 72 4d 73 67 29 7b 0a 20 20  ar *zErrMsg){.  
3d30: 4f 52 49 47 56 46 53 28 70 56 66 73 29 2d 3e 78  ORIGVFS(pVfs)->x
3d40: 44 6c 45 72 72 6f 72 28 4f 52 49 47 56 46 53 28  DlError(ORIGVFS(
3d50: 70 56 66 73 29 2c 20 6e 42 79 74 65 2c 20 7a 45  pVfs), nByte, zE
3d60: 72 72 4d 73 67 29 3b 0a 7d 0a 73 74 61 74 69 63  rrMsg);.}.static
3d70: 20 76 6f 69 64 20 28 2a 61 70 6e 64 44 6c 53 79   void (*apndDlSy
3d80: 6d 28 73 71 6c 69 74 65 33 5f 76 66 73 20 2a 70  m(sqlite3_vfs *p
3d90: 56 66 73 2c 20 76 6f 69 64 20 2a 70 2c 20 63 6f  Vfs, void *p, co
3da0: 6e 73 74 20 63 68 61 72 20 2a 7a 53 79 6d 29 29  nst char *zSym))
3db0: 28 76 6f 69 64 29 7b 0a 20 20 72 65 74 75 72 6e  (void){.  return
3dc0: 20 4f 52 49 47 56 46 53 28 70 56 66 73 29 2d 3e   ORIGVFS(pVfs)->
3dd0: 78 44 6c 53 79 6d 28 4f 52 49 47 56 46 53 28 70  xDlSym(ORIGVFS(p
3de0: 56 66 73 29 2c 20 70 2c 20 7a 53 79 6d 29 3b 0a  Vfs), p, zSym);.
3df0: 7d 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 70  }.static void ap
3e00: 6e 64 44 6c 43 6c 6f 73 65 28 73 71 6c 69 74 65  ndDlClose(sqlite
3e10: 33 5f 76 66 73 20 2a 70 56 66 73 2c 20 76 6f 69  3_vfs *pVfs, voi
3e20: 64 20 2a 70 48 61 6e 64 6c 65 29 7b 0a 20 20 4f  d *pHandle){.  O
3e30: 52 49 47 56 46 53 28 70 56 66 73 29 2d 3e 78 44  RIGVFS(pVfs)->xD
3e40: 6c 43 6c 6f 73 65 28 4f 52 49 47 56 46 53 28 70  lClose(ORIGVFS(p
3e50: 56 66 73 29 2c 20 70 48 61 6e 64 6c 65 29 3b 0a  Vfs), pHandle);.
3e60: 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70 6e  }.static int apn
3e70: 64 52 61 6e 64 6f 6d 6e 65 73 73 28 73 71 6c 69  dRandomness(sqli
3e80: 74 65 33 5f 76 66 73 20 2a 70 56 66 73 2c 20 69  te3_vfs *pVfs, i
3e90: 6e 74 20 6e 42 79 74 65 2c 20 63 68 61 72 20 2a  nt nByte, char *
3ea0: 7a 42 75 66 4f 75 74 29 7b 0a 20 20 72 65 74 75  zBufOut){.  retu
3eb0: 72 6e 20 4f 52 49 47 56 46 53 28 70 56 66 73 29  rn ORIGVFS(pVfs)
3ec0: 2d 3e 78 52 61 6e 64 6f 6d 6e 65 73 73 28 4f 52  ->xRandomness(OR
3ed0: 49 47 56 46 53 28 70 56 66 73 29 2c 20 6e 42 79  IGVFS(pVfs), nBy
3ee0: 74 65 2c 20 7a 42 75 66 4f 75 74 29 3b 0a 7d 0a  te, zBufOut);.}.
3ef0: 73 74 61 74 69 63 20 69 6e 74 20 61 70 6e 64 53  static int apndS
3f00: 6c 65 65 70 28 73 71 6c 69 74 65 33 5f 76 66 73  leep(sqlite3_vfs
3f10: 20 2a 70 56 66 73 2c 20 69 6e 74 20 6e 4d 69 63   *pVfs, int nMic
3f20: 72 6f 29 7b 0a 20 20 72 65 74 75 72 6e 20 4f 52  ro){.  return OR
3f30: 49 47 56 46 53 28 70 56 66 73 29 2d 3e 78 53 6c  IGVFS(pVfs)->xSl
3f40: 65 65 70 28 4f 52 49 47 56 46 53 28 70 56 66 73  eep(ORIGVFS(pVfs
3f50: 29 2c 20 6e 4d 69 63 72 6f 29 3b 0a 7d 0a 73 74  ), nMicro);.}.st
3f60: 61 74 69 63 20 69 6e 74 20 61 70 6e 64 43 75 72  atic int apndCur
3f70: 72 65 6e 74 54 69 6d 65 28 73 71 6c 69 74 65 33  rentTime(sqlite3
3f80: 5f 76 66 73 20 2a 70 56 66 73 2c 20 64 6f 75 62  _vfs *pVfs, doub
3f90: 6c 65 20 2a 70 54 69 6d 65 4f 75 74 29 7b 0a 20  le *pTimeOut){. 
3fa0: 20 72 65 74 75 72 6e 20 4f 52 49 47 56 46 53 28   return ORIGVFS(
3fb0: 70 56 66 73 29 2d 3e 78 43 75 72 72 65 6e 74 54  pVfs)->xCurrentT
3fc0: 69 6d 65 28 4f 52 49 47 56 46 53 28 70 56 66 73  ime(ORIGVFS(pVfs
3fd0: 29 2c 20 70 54 69 6d 65 4f 75 74 29 3b 0a 7d 0a  ), pTimeOut);.}.
3fe0: 73 74 61 74 69 63 20 69 6e 74 20 61 70 6e 64 47  static int apndG
3ff0: 65 74 4c 61 73 74 45 72 72 6f 72 28 73 71 6c 69  etLastError(sqli
4000: 74 65 33 5f 76 66 73 20 2a 70 56 66 73 2c 20 69  te3_vfs *pVfs, i
4010: 6e 74 20 61 2c 20 63 68 61 72 20 2a 62 29 7b 0a  nt a, char *b){.
4020: 20 20 72 65 74 75 72 6e 20 4f 52 49 47 56 46 53    return ORIGVFS
4030: 28 70 56 66 73 29 2d 3e 78 47 65 74 4c 61 73 74  (pVfs)->xGetLast
4040: 45 72 72 6f 72 28 4f 52 49 47 56 46 53 28 70 56  Error(ORIGVFS(pV
4050: 66 73 29 2c 20 61 2c 20 62 29 3b 0a 7d 0a 73 74  fs), a, b);.}.st
4060: 61 74 69 63 20 69 6e 74 20 61 70 6e 64 43 75 72  atic int apndCur
4070: 72 65 6e 74 54 69 6d 65 49 6e 74 36 34 28 73 71  rentTimeInt64(sq
4080: 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 2c  lite3_vfs *pVfs,
4090: 20 73 71 6c 69 74 65 33 5f 69 6e 74 36 34 20 2a   sqlite3_int64 *
40a0: 70 29 7b 0a 20 20 72 65 74 75 72 6e 20 4f 52 49  p){.  return ORI
40b0: 47 56 46 53 28 70 56 66 73 29 2d 3e 78 43 75 72  GVFS(pVfs)->xCur
40c0: 72 65 6e 74 54 69 6d 65 49 6e 74 36 34 28 4f 52  rentTimeInt64(OR
40d0: 49 47 56 46 53 28 70 56 66 73 29 2c 20 70 29 3b  IGVFS(pVfs), p);
40e0: 0a 7d 0a 73 74 61 74 69 63 20 69 6e 74 20 61 70  .}.static int ap
40f0: 6e 64 53 65 74 53 79 73 74 65 6d 43 61 6c 6c 28  ndSetSystemCall(
4100: 0a 20 20 73 71 6c 69 74 65 33 5f 76 66 73 20 2a  .  sqlite3_vfs *
4110: 70 56 66 73 2c 0a 20 20 63 6f 6e 73 74 20 63 68  pVfs,.  const ch
4120: 61 72 20 2a 7a 4e 61 6d 65 2c 0a 20 20 73 71 6c  ar *zName,.  sql
4130: 69 74 65 33 5f 73 79 73 63 61 6c 6c 5f 70 74 72  ite3_syscall_ptr
4140: 20 70 43 61 6c 6c 0a 29 7b 0a 20 20 72 65 74 75   pCall.){.  retu
4150: 72 6e 20 4f 52 49 47 56 46 53 28 70 56 66 73 29  rn ORIGVFS(pVfs)
4160: 2d 3e 78 53 65 74 53 79 73 74 65 6d 43 61 6c 6c  ->xSetSystemCall
4170: 28 4f 52 49 47 56 46 53 28 70 56 66 73 29 2c 7a  (ORIGVFS(pVfs),z
4180: 4e 61 6d 65 2c 70 43 61 6c 6c 29 3b 0a 7d 0a 73  Name,pCall);.}.s
4190: 74 61 74 69 63 20 73 71 6c 69 74 65 33 5f 73 79  tatic sqlite3_sy
41a0: 73 63 61 6c 6c 5f 70 74 72 20 61 70 6e 64 47 65  scall_ptr apndGe
41b0: 74 53 79 73 74 65 6d 43 61 6c 6c 28 0a 20 20 73  tSystemCall(.  s
41c0: 71 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73  qlite3_vfs *pVfs
41d0: 2c 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  ,.  const char *
41e0: 7a 4e 61 6d 65 0a 29 7b 0a 20 20 72 65 74 75 72  zName.){.  retur
41f0: 6e 20 4f 52 49 47 56 46 53 28 70 56 66 73 29 2d  n ORIGVFS(pVfs)-
4200: 3e 78 47 65 74 53 79 73 74 65 6d 43 61 6c 6c 28  >xGetSystemCall(
4210: 4f 52 49 47 56 46 53 28 70 56 66 73 29 2c 7a 4e  ORIGVFS(pVfs),zN
4220: 61 6d 65 29 3b 0a 7d 0a 73 74 61 74 69 63 20 63  ame);.}.static c
4230: 6f 6e 73 74 20 63 68 61 72 20 2a 61 70 6e 64 4e  onst char *apndN
4240: 65 78 74 53 79 73 74 65 6d 43 61 6c 6c 28 73 71  extSystemCall(sq
4250: 6c 69 74 65 33 5f 76 66 73 20 2a 70 56 66 73 2c  lite3_vfs *pVfs,
4260: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61   const char *zNa
4270: 6d 65 29 7b 0a 20 20 72 65 74 75 72 6e 20 4f 52  me){.  return OR
4280: 49 47 56 46 53 28 70 56 66 73 29 2d 3e 78 4e 65  IGVFS(pVfs)->xNe
4290: 78 74 53 79 73 74 65 6d 43 61 6c 6c 28 4f 52 49  xtSystemCall(ORI
42a0: 47 56 46 53 28 70 56 66 73 29 2c 20 7a 4e 61 6d  GVFS(pVfs), zNam
42b0: 65 29 3b 0a 7d 0a 0a 20 20 0a 23 69 66 64 65 66  e);.}..  .#ifdef
42c0: 20 5f 57 49 4e 33 32 0a 5f 5f 64 65 63 6c 73 70   _WIN32.__declsp
42d0: 65 63 28 64 6c 6c 65 78 70 6f 72 74 29 0a 23 65  ec(dllexport).#e
42e0: 6e 64 69 66 0a 2f 2a 20 0a 2a 2a 20 54 68 69 73  ndif./* .** This
42f0: 20 72 6f 75 74 69 6e 65 20 69 73 20 63 61 6c 6c   routine is call
4300: 65 64 20 77 68 65 6e 20 74 68 65 20 65 78 74 65  ed when the exte
4310: 6e 73 69 6f 6e 20 69 73 20 6c 6f 61 64 65 64 2e  nsion is loaded.
4320: 0a 2a 2a 20 52 65 67 69 73 74 65 72 20 74 68 65  .** Register the
4330: 20 6e 65 77 20 56 46 53 2e 0a 2a 2f 0a 69 6e 74   new VFS..*/.int
4340: 20 73 71 6c 69 74 65 33 5f 61 70 70 65 6e 64 76   sqlite3_appendv
4350: 66 73 5f 69 6e 69 74 28 0a 20 20 73 71 6c 69 74  fs_init(.  sqlit
4360: 65 33 20 2a 64 62 2c 20 0a 20 20 63 68 61 72 20  e3 *db, .  char 
4370: 2a 2a 70 7a 45 72 72 4d 73 67 2c 20 0a 20 20 63  **pzErrMsg, .  c
4380: 6f 6e 73 74 20 73 71 6c 69 74 65 33 5f 61 70 69  onst sqlite3_api
4390: 5f 72 6f 75 74 69 6e 65 73 20 2a 70 41 70 69 0a  _routines *pApi.
43a0: 29 7b 0a 20 20 69 6e 74 20 72 63 20 3d 20 53 51  ){.  int rc = SQ
43b0: 4c 49 54 45 5f 4f 4b 3b 0a 20 20 73 71 6c 69 74  LITE_OK;.  sqlit
43c0: 65 33 5f 76 66 73 20 2a 70 4f 72 69 67 3b 0a 20  e3_vfs *pOrig;. 
43d0: 20 53 51 4c 49 54 45 5f 45 58 54 45 4e 53 49 4f   SQLITE_EXTENSIO
43e0: 4e 5f 49 4e 49 54 32 28 70 41 70 69 29 3b 0a 20  N_INIT2(pApi);. 
43f0: 20 28 76 6f 69 64 29 70 7a 45 72 72 4d 73 67 3b   (void)pzErrMsg;
4400: 0a 20 20 28 76 6f 69 64 29 64 62 3b 0a 20 20 70  .  (void)db;.  p
4410: 4f 72 69 67 20 3d 20 73 71 6c 69 74 65 33 5f 76  Orig = sqlite3_v
4420: 66 73 5f 66 69 6e 64 28 30 29 3b 0a 20 20 61 70  fs_find(0);.  ap
4430: 6e 64 5f 76 66 73 2e 69 56 65 72 73 69 6f 6e 20  nd_vfs.iVersion 
4440: 3d 20 70 4f 72 69 67 2d 3e 69 56 65 72 73 69 6f  = pOrig->iVersio
4450: 6e 3b 0a 20 20 61 70 6e 64 5f 76 66 73 2e 70 41  n;.  apnd_vfs.pA
4460: 70 70 44 61 74 61 20 3d 20 70 4f 72 69 67 3b 0a  ppData = pOrig;.
4470: 20 20 61 70 6e 64 5f 76 66 73 2e 73 7a 4f 73 46    apnd_vfs.szOsF
4480: 69 6c 65 20 3d 20 70 4f 72 69 67 2d 3e 73 7a 4f  ile = pOrig->szO
4490: 73 46 69 6c 65 20 2b 20 73 69 7a 65 6f 66 28 41  sFile + sizeof(A
44a0: 70 6e 64 46 69 6c 65 29 3b 0a 20 20 72 63 20 3d  pndFile);.  rc =
44b0: 20 73 71 6c 69 74 65 33 5f 76 66 73 5f 72 65 67   sqlite3_vfs_reg
44c0: 69 73 74 65 72 28 26 61 70 6e 64 5f 76 66 73 2c  ister(&apnd_vfs,
44d0: 20 30 29 3b 0a 23 69 66 64 65 66 20 41 50 50 45   0);.#ifdef APPE
44e0: 4e 44 56 46 53 5f 54 45 53 54 0a 20 20 69 66 28  NDVFS_TEST.  if(
44f0: 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f 4b 20 29   rc==SQLITE_OK )
4500: 7b 0a 20 20 20 20 72 63 20 3d 20 73 71 6c 69 74  {.    rc = sqlit
4510: 65 33 5f 61 75 74 6f 5f 65 78 74 65 6e 73 69 6f  e3_auto_extensio
4520: 6e 28 28 76 6f 69 64 28 2a 29 28 76 6f 69 64 29  n((void(*)(void)
4530: 29 61 70 6e 64 76 66 73 52 65 67 69 73 74 65 72  )apndvfsRegister
4540: 29 3b 0a 20 20 7d 0a 23 65 6e 64 69 66 0a 20 20  );.  }.#endif.  
4550: 69 66 28 20 72 63 3d 3d 53 51 4c 49 54 45 5f 4f  if( rc==SQLITE_O
4560: 4b 20 29 20 72 63 20 3d 20 53 51 4c 49 54 45 5f  K ) rc = SQLITE_
4570: 4f 4b 5f 4c 4f 41 44 5f 50 45 52 4d 41 4e 45 4e  OK_LOAD_PERMANEN
4580: 54 4c 59 3b 0a 20 20 72 65 74 75 72 6e 20 72 63  TLY;.  return rc
4590: 3b 0a 7d 0a                                      ;.}.