00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "indri/Tag.hpp"
00020 #include <stdio.h>
00021 #include <string.h>
00022 #include <indri/greedy_vector>
00023 #include "indri/TagExtent.hpp"
00024 #include <iostream>
00025 #include "indri/MetadataPair.hpp"
00026 #include "indri/Buffer.hpp"
00027
00028 #ifndef _TAGLIST_HPP
00029 #define _TAGLIST_HPP
00030 namespace indri
00031 {
00032 namespace parse
00033 {
00034
00035 class TagList {
00036 private:
00037 struct tag_entry {
00038 const char* name;
00039 const char* conflation;
00040 int next;
00041 int begin;
00042 int end;
00043 };
00044
00045 indri::utility::greedy_vector<tag_entry> _tags;
00046 int _openList;
00047
00048
00049
00050 bool _findParents;
00051
00052 public:
00053 TagList() : _findParents(true) {
00054 clear();
00055 }
00056
00057 void setFindParents( bool findParents ) {
00058 _findParents = findParents;
00059 }
00060
00061 void clear() {
00062 _tags.clear();
00063 _openList = -1;
00064 }
00065
00066
00067
00068
00069
00070
00071 void addTag(const char *name, const char* conflation, int begin) {
00072 tag_entry t;
00073 t.name = name;
00074 t.conflation = conflation;
00075 t.begin = begin;
00076 t.end = -1;
00077 t.next = _openList;
00078 _tags.push_back(t);
00079 _openList = (int)_tags.size()-1;
00080 }
00081
00082 void endTag(const char *name, const char* conflation, int end) {
00083 int list = _openList;
00084 int prev = -1;
00085
00086 while( list >= 0 ) {
00087 tag_entry& entry = _tags[list];
00088
00089 if( !strcmp( entry.name, name ) ) {
00090
00091 entry.end = end;
00092 int next = entry.next;
00093
00094
00095 if( prev == -1 ) {
00096 _openList = next;
00097 } else {
00098 _tags[prev].next = next;
00099 }
00100
00101 return;
00102 } else {
00103
00104 prev = list;
00105 list = entry.next;
00106 }
00107 }
00108 }
00109
00110 void writeTagList( indri::utility::greedy_vector<TagExtent *>& tags ) {
00111
00112
00113
00114 for( size_t i=0; i<_tags.size(); i++ ) {
00115 tag_entry& entry = _tags[i];
00116
00117 if( entry.end >= 0 ) {
00118 TagExtent * extent = new TagExtent;
00119 extent->begin = entry.begin;
00120 extent->end = entry.end;
00121 extent->name = entry.conflation;
00122 extent->number = 0;
00123
00124 if ( _findParents && (tags.size() > 0)) {
00125
00126 TagExtent * parent = tags.back();
00127 while ( parent != NULL &&
00128 parent->end <= extent->begin ) {
00129 if ( parent->begin <= extent->begin &&
00130 parent->end >= extent->end ) break;
00131 parent = parent->parent;
00132 }
00133 extent->parent = parent;
00134 } else {
00135 extent->parent = 0;
00136 }
00137
00138 tags.push_back(extent);
00139 }
00140 }
00141 }
00142
00143
00144
00145 void writeMetadataList( indri::utility::greedy_vector<MetadataPair>& pairs, indri::utility::Buffer& buffer, const char* docText ) {
00146 for( size_t i=0; i<_tags.size(); i++ ) {
00147 tag_entry& entry = _tags[i];
00148
00149 if( entry.end > 0 ) {
00150 MetadataPair pair;
00151
00152
00153 int length = entry.end - entry.begin;
00154 char* spot = buffer.write(length+1);
00155 strncpy( spot, docText + entry.begin, length);
00156 spot[length] = 0;
00157
00158 pair.key = entry.conflation;
00159 pair.value = spot;
00160 pair.valueLength = length+1;
00161
00162
00163 if( !strcmp( pair.key, "docno" ) ) {
00164 pair.stripValue();
00165 }
00166
00167 pairs.push_back(pair);
00168 }
00169 }
00170 }
00171
00172 };
00173 }
00174 }
00175
00176
00177 #endif