зеркало из https://github.com/mozilla/gecko-dev.git
another pass at dynamic generation of open directory pages
This commit is contained in:
Родитель
6ca45fe37b
Коммит
d54015c097
|
@ -0,0 +1,106 @@
|
|||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "rdf.h"
|
||||
|
||||
RDF_Resource
|
||||
getNodeFromQuery (char* query) {
|
||||
RDF_Resource ans;
|
||||
if (!(ans = RDF_GetResource(query, 0))) {
|
||||
return RDF_GetResource("Top", 1);
|
||||
} else return ans;
|
||||
}
|
||||
|
||||
#define ROW_WIDTH 3
|
||||
|
||||
void
|
||||
AnswerOpenDirQuery (WriteClientProc callBack, void* obj, char *query) {
|
||||
char *buff = malloc(10000);
|
||||
RDF_Resource items[300];
|
||||
RDF_Resource topics[100];
|
||||
RDF_Resource child = RDF_GetResource("child", 1);
|
||||
RDF_Resource name = RDF_GetResource("name", 1);
|
||||
RDF_Resource type = RDF_GetResource("type", 1);
|
||||
RDF_Resource topic = RDF_GetResource("Topic", 1);
|
||||
RDF_Resource desc = RDF_GetResource("description", 1);
|
||||
RDF_Resource node = getNodeFromQuery(query);
|
||||
int itemCount = 0;
|
||||
int topicCount = 0;
|
||||
|
||||
if (node) {
|
||||
RDF_Cursor c = RDF_GetTargets(0, node, child, RDF_RESOURCE_TYPE);
|
||||
RDF_Resource ans = 0;
|
||||
while (c && (ans = RDF_NextValue(c))) {
|
||||
int subjectp = RDF_HasAssertion(0, ans, type, topic, RDF_RESOURCE_TYPE);
|
||||
if (subjectp) {
|
||||
topics[topicCount++] = ans;
|
||||
} else {
|
||||
items[itemCount++] = ans;
|
||||
}
|
||||
}
|
||||
RDF_DisposeCursor(c);
|
||||
|
||||
if (topicCount > 0) {
|
||||
int n = 0;
|
||||
(*callBack)(obj, "<hr><table cellspacing=\"4\" cellpadding=\"6\">");
|
||||
while (n < topicCount) {
|
||||
int w = 0;
|
||||
(*callBack)(obj, "<tr>");
|
||||
while ((w < ROW_WIDTH) && (n < topicCount)) {
|
||||
RDF_Resource u = topics[n];
|
||||
char* nm = RDF_OnePropValue(0, u, name, RDF_STRING_TYPE);
|
||||
char* id = RDF_ResourceID(u);
|
||||
sprintf(buff, "<td><li><a href=\"OpenDir?%s\">%s</a></td>", id, (nm ? nm : id));
|
||||
(*callBack)(obj, buff);
|
||||
w++;
|
||||
n++;
|
||||
}
|
||||
(*callBack)(obj, "</tr>");
|
||||
}
|
||||
(*callBack)(obj, "</table>");
|
||||
}
|
||||
(*callBack)(obj, "<hr>");
|
||||
if (itemCount > 0) {
|
||||
int n = 0;
|
||||
(*callBack)(obj, "<ul>");
|
||||
while (n < itemCount) {
|
||||
int w = 0;
|
||||
|
||||
RDF_Resource u = items[n];
|
||||
char* nm = RDF_OnePropValue(0, u, name, RDF_STRING_TYPE);
|
||||
char* id = RDF_ResourceID(u);
|
||||
sprintf(buff, "<li><a href=\"%s\">%s</a>", id, (nm ? nm : id));
|
||||
(*callBack)(obj, buff);
|
||||
|
||||
n++;
|
||||
|
||||
|
||||
}
|
||||
(*callBack)(obj, "</ul>");
|
||||
}
|
||||
}
|
||||
free(buff);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -42,8 +42,11 @@ hashKey (HashTable ht, char* key) {
|
|||
size_t len = strlen(key);
|
||||
int sum = 0;
|
||||
size_t n = 0;
|
||||
int ans;
|
||||
for (n = 0; n < len; n++) sum = sum + (int)key[n];
|
||||
return sum & ht->size;
|
||||
ans = sum & ht->size;
|
||||
if (ans == ht->size) ans = ans-1;
|
||||
return ans;
|
||||
}
|
||||
|
||||
HashTable
|
||||
|
@ -82,7 +85,7 @@ HashAdd (HashTable ht, char* key, void* value) {
|
|||
prev = he;
|
||||
he = he->next;
|
||||
}
|
||||
he = (HashEntry) getMem(sizeof(HashEntryStruct));
|
||||
he = (HashEntry) fgetMem(sizeof(HashEntryStruct));
|
||||
he->value = value;
|
||||
he->key = key;
|
||||
if (prev) {
|
||||
|
|
|
@ -30,7 +30,8 @@ WriteClient (void* obj, char* buffer) {
|
|||
}
|
||||
|
||||
void AnswerOpenDirQuery(WriteClientProc callBack, void* obj, char* query);
|
||||
#define PREFIX "<html><body>"
|
||||
#define PREFIX "<html><body><a href=\"/\"><center><img src=\"http://directory.mozilla.org/img/opendir.gif\" width=396 height=79 border=\"0\"></center></a>"
|
||||
|
||||
#define POSTFIX "</body><html>"
|
||||
|
||||
long
|
||||
|
@ -114,9 +115,10 @@ int main(int argc, char **argv)
|
|||
#endif
|
||||
WAIregisterService(obj, host);
|
||||
RDF_Initialize();
|
||||
RDF_ReadFile("opendir.rdf");
|
||||
RDF_ReadFile("excite.rdf");
|
||||
|
||||
printf("done");
|
||||
|
||||
WAIimplIsReady();
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
#define MAX_ATTRIBUTES 256
|
||||
#define EXPECTING_OBJECT 1
|
||||
#define EXPECTING_PROPERTY 2
|
||||
#define GROW_LIST_INCR 100
|
||||
#define GROW_LIST_INCR 1000
|
||||
|
||||
typedef struct _RDF_ResourceStruct {
|
||||
char* url;
|
||||
|
@ -56,14 +56,13 @@ typedef enum {
|
|||
|
||||
typedef struct _RDF_FileStruct {
|
||||
char* url;
|
||||
int status;
|
||||
char* storeAway;
|
||||
char* line;
|
||||
int status;
|
||||
char* holdOver;
|
||||
RDF_Resource stack[16];
|
||||
RDF_Resource stack[256];
|
||||
RDF_Resource lastItem;
|
||||
int depth ;
|
||||
char* tagStack[16];
|
||||
int tagDepth;
|
||||
int assertionListCount;
|
||||
int assertionListSize;
|
||||
|
@ -107,6 +106,7 @@ void HashAdd (HashTable ht, char* key, void* value) ;
|
|||
|
||||
RDF_Resource getResource(char* url, int createp);
|
||||
char* getMem(size_t n);
|
||||
char* fgetMem (size_t size) ;
|
||||
void freeMem(void* item);
|
||||
RDFT initFileStruct (char* url) ;
|
||||
void rdf_init();
|
||||
|
@ -127,6 +127,7 @@ int tokenizeElement (char* attr, char** attlist, char** elementName);
|
|||
void addSlotValue (RDFT f, RDF_Resource u, RDF_Resource s, void* v,
|
||||
RDF_ValueType type, char* op);
|
||||
char* copyString(char* str) ;
|
||||
char* fcopyString (char* str) ;
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -17,8 +17,6 @@
|
|||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#include "rdf-int.h"
|
||||
|
||||
char* error_string = NULL;
|
||||
|
@ -32,8 +30,8 @@ getResource (char* key, int createp) {
|
|||
if (existing) {
|
||||
return existing;
|
||||
} else if (createp){
|
||||
existing = (RDF_Resource)getMem(sizeof(RDF_ResourceStruct));
|
||||
existing->url = copyString(key);
|
||||
existing = (RDF_Resource)fgetMem(sizeof(RDF_ResourceStruct));
|
||||
existing->url = fcopyString(key);
|
||||
HashAdd(resourceHash, existing->url, existing);
|
||||
return existing;
|
||||
} else return NULL;
|
||||
|
@ -44,21 +42,51 @@ RDF_ResourceID (RDF_Resource u) {
|
|||
return u->url;
|
||||
}
|
||||
|
||||
static char* MemBlock = 0;
|
||||
size_t allocated = 0;
|
||||
#define MEM_BLOCK_SIZE 10000
|
||||
|
||||
char*
|
||||
fgetMem (size_t size) {
|
||||
char* ans = 0;
|
||||
if (!MemBlock || (size >= (MEM_BLOCK_SIZE - allocated))) {
|
||||
MemBlock = getMem(MEM_BLOCK_SIZE);
|
||||
allocated = 0;
|
||||
}
|
||||
ans = MemBlock;
|
||||
MemBlock = MemBlock + size;
|
||||
allocated = allocated + size;
|
||||
return ans;
|
||||
}
|
||||
|
||||
void readRDFFile (char* file) {
|
||||
FILE* f = fopen(file, "r");
|
||||
if (f) {
|
||||
RDFT rf = (RDFT)getRDFT(file, 1) ;
|
||||
int ok = 1;
|
||||
char* buff = malloc(100 * 1024);
|
||||
int len ;
|
||||
int i = 0;
|
||||
memset(buff, '\0', (100 * 1024));
|
||||
len = fread(buff, 1, (100 * 1024) -1, f);
|
||||
memset(rf, '\0', sizeof(RDF_FileStruct));
|
||||
rf->line = (char*)getMem(RDF_BUF_SIZE);
|
||||
rf->holdOver = (char*)getMem(RDF_BUF_SIZE);
|
||||
rf->depth = 1;
|
||||
rf->lastItem = rf->stack[0] ;
|
||||
while ((len = fread(buff, 1, (100 * 1024) -1, f)) > 0) {
|
||||
buff[len] = '\0';
|
||||
if (!RDF_Consume(file, buff, len)) {
|
||||
printf("[%i] ", i++);
|
||||
if (!(ok = parseNextRDFXMLBlobInt(rf, buff, len))) {
|
||||
printf("Error in RDF File\n");
|
||||
} else {
|
||||
}
|
||||
}
|
||||
printf("Finished reading %s\n", file);
|
||||
}
|
||||
freeMem(rf->line);
|
||||
rf->line = NULL;
|
||||
freeMem(rf->holdOver);
|
||||
rf->holdOver = NULL;
|
||||
free(buff);
|
||||
}
|
||||
} else printf("Could not find %s\n", file);
|
||||
}
|
||||
|
||||
static HashTable rdftHash = NULL;
|
||||
|
@ -70,7 +98,7 @@ getRDFT (char* key, int createp) {
|
|||
return existing;
|
||||
} else if (createp){
|
||||
existing = (RDFT)getMem(sizeof(RDF_FileStruct));
|
||||
existing->url = copyString(key);
|
||||
existing->url = fcopyString(key);
|
||||
HashAdd(rdftHash, existing->url, existing);
|
||||
return existing;
|
||||
} else return NULL;
|
||||
|
@ -94,10 +122,8 @@ rdf_DigestNewStuff (char* url, char* data, int len) {
|
|||
rf->holdOver = (char*)getMem(RDF_BUF_SIZE);
|
||||
rf->depth = 1;
|
||||
rf->lastItem = rf->stack[0] ;
|
||||
u = RDF_GetResource("Top/Computers/AI", 0);
|
||||
ok = parseNextRDFXMLBlobInt(rf, data, len);
|
||||
u = RDF_GetResource("Top/Computers/AI", 0);
|
||||
if (!ok) unloadRDFT(rf);
|
||||
/* if (!ok) unloadRDFT(rf); */
|
||||
freeMem(rf->line);
|
||||
rf->line = NULL;
|
||||
freeMem(rf->holdOver);
|
||||
|
@ -148,7 +174,7 @@ char *
|
|||
copyStringIgnoreWhiteSpace(char* string)
|
||||
{
|
||||
int len = strlen(string);
|
||||
char* buf = (char*)getMem(len + 1);
|
||||
char* buf = (char*)fgetMem(len + 1);
|
||||
int inWhiteSpace = 1;
|
||||
int buffIndex = 0;
|
||||
int stringIndex = 0;
|
||||
|
@ -212,7 +238,7 @@ parseNextRDFXMLBlobInt(RDFT f, char* blob, int size) {
|
|||
somethingseenp = 1;
|
||||
memset(f->holdOver, '\0', RDF_BUF_SIZE-1);
|
||||
}
|
||||
while ((n < size) && (wsCharp(c))) {
|
||||
while ((n < size) && (wsCharp(c)) && (!somethingseenp)) {
|
||||
c = blob[++n];
|
||||
if ((c == '\n') || (c == '\r')) lineNumber++;
|
||||
}
|
||||
|
@ -265,6 +291,16 @@ copyString (char* str) {
|
|||
} else return NULL;
|
||||
}
|
||||
|
||||
char*
|
||||
fcopyString (char* str) {
|
||||
char* ans = fgetMem(strlen(str)+1);
|
||||
if (ans) {
|
||||
memcpy(ans, str, strlen(str));
|
||||
return ans;
|
||||
} else return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
addElementProps (char** attlist, char* elementName, RDFT f, RDF_Resource obj)
|
||||
{
|
||||
|
@ -299,6 +335,7 @@ parseNextRDFToken (RDFT f, char* token)
|
|||
RDF_Resource s = f->stack[f->depth-1];
|
||||
char* val = copyStringIgnoreWhiteSpace(token);
|
||||
remoteStoreAdd(f, u, s, val , RDF_STRING_TYPE, 1);
|
||||
return 1;
|
||||
} else {
|
||||
sprintf(error_string, "Did not expect \n\"%s\".\n Was expecting a tag.", token);
|
||||
return 0;
|
||||
|
@ -317,15 +354,12 @@ parseNextRDFToken (RDFT f, char* token)
|
|||
return 1;
|
||||
} else if ((f->status == 0) && (startsWith("<RDF:RDF", token) ||
|
||||
startsWith("<RDF>", token))) {
|
||||
f->tagStack[f->tagDepth++] = copyString("RDF");
|
||||
f->status = EXPECTING_OBJECT;
|
||||
return 1;
|
||||
} else {
|
||||
int emptyElementp = (token[strlen(token)-2] == '/');
|
||||
if ((f->status != EXPECTING_OBJECT) && (f->status != EXPECTING_PROPERTY)) return 1;
|
||||
if (!tokenizeElement(token, attlist, &elementName)) return 0;
|
||||
if (!emptyElementp)
|
||||
f->tagStack[f->tagDepth++] = copyString(elementName);
|
||||
if (f->status == EXPECTING_OBJECT) {
|
||||
char* url = NULL;
|
||||
RDF_Resource obj;
|
||||
|
@ -333,8 +367,7 @@ parseNextRDFToken (RDFT f, char* token)
|
|||
url = getID(attlist);
|
||||
if (!url) {
|
||||
if (f->tagDepth > 2) {
|
||||
sprintf(error_string, "Unbalanced tags : Expecting </%s>, found %s",
|
||||
f->tagStack[f->tagDepth-2], token);
|
||||
sprintf(error_string, "Unbalanced tags ");
|
||||
} else {
|
||||
sprintf(error_string, "Require a \"about\" attribute on %s", token);
|
||||
}
|
||||
|
@ -344,7 +377,7 @@ parseNextRDFToken (RDFT f, char* token)
|
|||
addElementProps (attlist, elementName, f, obj) ;
|
||||
if (!stringEquals(elementName, "RDF:Description")) {
|
||||
RDF_Resource eln = getResource(elementName, 1);
|
||||
remoteStoreAdd(f, obj, getResource("instanceOf", 1),
|
||||
remoteStoreAdd(f, obj, getResource("type", 1),
|
||||
eln, RDF_RESOURCE_TYPE,
|
||||
1);
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ Assertion
|
|||
makeNewAssertion (RDFT r, RDF_Resource u, RDF_Resource s, void* v,
|
||||
RDF_ValueType type, int tv)
|
||||
{
|
||||
Assertion newAs = (Assertion) getMem(sizeof(RDF_AssertionStruct));
|
||||
Assertion newAs = (Assertion) fgetMem(sizeof(RDF_AssertionStruct));
|
||||
newAs->u = u;
|
||||
newAs->s = s;
|
||||
newAs->value = v;
|
||||
|
@ -54,12 +54,6 @@ addToAssertionList (RDFT f, Assertion as)
|
|||
(sizeof(Assertion*) *
|
||||
(f->assertionListSize =
|
||||
f->assertionListSize + GROW_LIST_INCR)));
|
||||
/* Assertion* old = f->assertionList;
|
||||
f->assertionListSize = f->assertionListSize + GROW_LIST_INCR;
|
||||
f->assertionList = (Assertion*)getMem(f->assertionListSize);
|
||||
if (old) memcpy(f->assertionList, old,
|
||||
(f->assertionListSize - GROW_LIST_INCR) * sizeof(Assertion*));
|
||||
freeMem(old); */
|
||||
}
|
||||
*(f->assertionList + f->assertionListCount++) = as;
|
||||
}
|
||||
|
@ -78,33 +72,15 @@ Assertion
|
|||
remoteStoreAdd (RDFT mcf, RDF_Resource u, RDF_Resource s, void* v,
|
||||
RDF_ValueType type, int tv)
|
||||
{
|
||||
Assertion nextAs, prevAs, newAs;
|
||||
nextAs = prevAs = u->rarg1;
|
||||
|
||||
while (nextAs != null) {
|
||||
if (asEqual(mcf, nextAs, u, s, v, type)) return null;
|
||||
prevAs = nextAs;
|
||||
nextAs = nextAs->next;
|
||||
}
|
||||
newAs = makeNewAssertion(mcf, u, s, v, type, tv);
|
||||
if (prevAs == null) {
|
||||
Assertion newAs = makeNewAssertion(mcf, u, s, v, type, tv);
|
||||
newAs->next = u->rarg1;
|
||||
u->rarg1 = newAs;
|
||||
} else {
|
||||
prevAs->next = newAs;
|
||||
}
|
||||
|
||||
if (type == RDF_RESOURCE_TYPE) {
|
||||
nextAs = prevAs = ((RDF_Resource)v)->rarg2;
|
||||
while (nextAs != null) {
|
||||
prevAs = nextAs;
|
||||
nextAs = nextAs->invNext;
|
||||
RDF_Resource iu = (RDF_Resource)v;
|
||||
newAs->invNext = iu->rarg2;
|
||||
iu->rarg2 = newAs;
|
||||
}
|
||||
if (prevAs == null) {
|
||||
((RDF_Resource)v)->rarg2 = newAs;
|
||||
} else {
|
||||
prevAs->invNext = newAs;
|
||||
}
|
||||
}
|
||||
addToAssertionList(mcf, newAs);
|
||||
return newAs;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче