]>
git.saurik.com Git - apt.git/blob - apt-pkg/tagfile.cc
23fc344f3ff79f6ab585814a488798d1849f8613
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: tagfile.cc,v 1.12 1998/10/24 04:58:06 jgg Exp $
4 /* ######################################################################
6 Fast scanner for RFC-822 type header information
8 This uses a rotating buffer to load the package information into.
9 The scanner runs over it and isolates and indexes a single section.
11 ##################################################################### */
13 // Include Files /*{{{*/
15 #pragma implementation "apt-pkg/tagfile.h"
18 #include <apt-pkg/tagfile.h>
19 #include <apt-pkg/error.h>
25 // TagFile::pkgTagFile - Constructor /*{{{*/
26 // ---------------------------------------------------------------------
28 pkgTagFile::pkgTagFile(FileFd
&Fd
,unsigned long Size
) : Fd(Fd
), Size(Size
)
30 Buffer
= new char[Size
];
37 // TagFile::Step - Advance to the next section /*{{{*/
38 // ---------------------------------------------------------------------
39 /* If the Section Scanner fails we refill the buffer and try again. */
40 bool pkgTagFile::Step(pkgTagSection
&Tag
)
42 if (Tag
.Scan(Start
,End
- Start
) == false)
47 if (Tag
.Scan(Start
,End
- Start
) == false)
49 cout
<< string(Start
,End
-Start
) << endl
;
50 return _error
->Error("Unable to parse package file");
54 iOffset
+= Tag
.size();
59 // TagFile::Fill - Top up the buffer /*{{{*/
60 // ---------------------------------------------------------------------
61 /* This takes the bit at the end of the buffer and puts it at the start
62 then fills the rest from the file */
63 bool pkgTagFile::Fill()
65 unsigned long EndSize
= End
- Start
;
74 memmove(Buffer
,Start
,EndSize
);
76 End
= Buffer
+ EndSize
;
78 // See if only a bit of the file is left
79 if (Left
< Size
- (End
- Buffer
))
81 if (Fd
.Read(End
,Left
) == false)
89 if (Fd
.Read(End
,Size
- (End
- Buffer
)) == false)
91 cout
<< "boink" << endl
;
95 Left
-= Size
- (End
- Buffer
);
101 // TagFile::Jump - Jump to a pre-recorded location in the file /*{{{*/
102 // ---------------------------------------------------------------------
103 /* This jumps to a pre-recorded file location and */
104 bool pkgTagFile::Jump(pkgTagSection
&Tag
,unsigned long Offset
)
107 Left
= Fd
.Size() - Offset
;
108 if (Fd
.Seek(Offset
) == false)
110 End
= Start
= Buffer
;
115 if (Tag
.Scan(Start
,End
- Start
) == false)
116 return _error
->Error("Unable to parse package file");
120 // TagSection::Scan - Scan for the end of the header information /*{{{*/
121 // ---------------------------------------------------------------------
122 /* This looks for the first double new line in the data stream. It also
123 indexes the tags in the section. */
124 bool pkgTagSection::Scan(const char *Start
,unsigned long MaxLength
)
126 const char *End
= Start
+ MaxLength
;
127 Stop
= Section
= Start
;
130 Indexes
[TagCount
++] = Stop
- Section
;
132 for (; Stop
< End
; Stop
++)
134 if (Stop
[-1] != '\n')
138 for (; Stop
[0] == '\r' && Stop
< End
; Stop
++);
142 // Extra one at the end to simplify find
143 Indexes
[TagCount
] = Stop
- Section
;
144 for (; (Stop
[0] == '\n' || Stop
[0] == '\r') && Stop
< End
; Stop
++);
148 if (isspace(Stop
[0]) == 0)
149 Indexes
[TagCount
++] = Stop
- Section
;
152 if (TagCount
> sizeof(Indexes
)/sizeof(Indexes
[0]))
153 TagCount
= sizeof(Indexes
)/sizeof(Indexes
[0]);
158 // TagSection::Find - Locate a tag /*{{{*/
159 // ---------------------------------------------------------------------
160 /* This searches the section for a tag that matches the given string. */
161 bool pkgTagSection::Find(const char *Tag
,const char *&Start
,
164 unsigned int Length
= strlen(Tag
);
165 for (unsigned int I
= 0; I
!= TagCount
; I
++)
167 if (strncasecmp(Tag
,Section
+ Indexes
[I
],Length
) != 0)
170 // Make sure the colon is in the right place
171 const char *C
= Section
+ Length
+ Indexes
[I
];
172 for (; isspace(*C
) != 0; C
++);
176 // Strip off the gunk from the start end
178 End
= Section
+ Indexes
[I
+1];
179 for (; (isspace(*Start
) != 0 || *Start
== ':') && Start
< End
; Start
++);
180 for (; isspace(End
[-1]) != 0 && End
> Start
; End
--);