Very rough first start, not even everything added
This commit is contained in:
commit
af3619d4fa
88 changed files with 24251 additions and 0 deletions
394
PrefsSourceLib/FilePrefsSource.cpp
Normal file
394
PrefsSourceLib/FilePrefsSource.cpp
Normal file
|
@ -0,0 +1,394 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*
|
||||
*/
|
||||
/*
|
||||
File: FilePrefsSource.cpp
|
||||
|
||||
Contains: Implements object defined in FilePrefsSource.h.
|
||||
|
||||
Written by: Chris LeCroy
|
||||
*/
|
||||
|
||||
#include "FilePrefsSource.h"
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "MyAssert.h"
|
||||
#include "OSMemory.h"
|
||||
#include "ConfParser.h"
|
||||
|
||||
const int kMaxLineLen = 2048;
|
||||
const int kMaxValLen = 1024;
|
||||
|
||||
class KeyValuePair
|
||||
{
|
||||
public:
|
||||
|
||||
char* GetValue() { return fValue; }
|
||||
|
||||
private:
|
||||
friend class FilePrefsSource;
|
||||
|
||||
KeyValuePair(const char* inKey, const char* inValue, KeyValuePair* inNext);
|
||||
~KeyValuePair();
|
||||
|
||||
char* fKey;
|
||||
char* fValue;
|
||||
KeyValuePair* fNext;
|
||||
|
||||
void ResetValue(const char* inValue);
|
||||
};
|
||||
|
||||
|
||||
KeyValuePair::KeyValuePair(const char* inKey, const char* inValue, KeyValuePair* inNext) :
|
||||
fKey(NULL),
|
||||
fValue(NULL),
|
||||
fNext(NULL)
|
||||
{
|
||||
fKey = NEW char[::strlen(inKey)+1];
|
||||
::strcpy(fKey, inKey);
|
||||
fValue = NEW char[::strlen(inValue)+1];
|
||||
::strcpy(fValue, inValue);
|
||||
fNext = inNext;
|
||||
}
|
||||
|
||||
|
||||
KeyValuePair::~KeyValuePair()
|
||||
{
|
||||
delete [] fKey;
|
||||
delete [] fValue;
|
||||
}
|
||||
|
||||
|
||||
void KeyValuePair::ResetValue(const char* inValue)
|
||||
{
|
||||
delete [] fValue;
|
||||
fValue = NEW char[::strlen(inValue)+1];
|
||||
::strcpy(fValue, inValue);
|
||||
}
|
||||
|
||||
|
||||
FilePrefsSource::FilePrefsSource( Bool16 allowDuplicates)
|
||||
: fKeyValueList(NULL),
|
||||
fNumKeys(0),
|
||||
fAllowDuplicates(allowDuplicates)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
FilePrefsSource::~FilePrefsSource()
|
||||
{
|
||||
while (fKeyValueList != NULL)
|
||||
{
|
||||
KeyValuePair* keyValue = fKeyValueList;
|
||||
fKeyValueList = fKeyValueList->fNext;
|
||||
delete keyValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int FilePrefsSource::GetValue(const char* inKey, char* ioValue)
|
||||
{
|
||||
return (this->FindValue(inKey, ioValue) != NULL);
|
||||
}
|
||||
|
||||
|
||||
int FilePrefsSource::GetValueByIndex(const char* inKey, UInt32 inIndex, char* ioValue)
|
||||
{
|
||||
KeyValuePair* thePair = this->FindValue(inKey, ioValue, inIndex);
|
||||
|
||||
if (thePair == NULL)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
||||
/*
|
||||
char* valuePtr = thePair->fValue;
|
||||
|
||||
//this function makes the assumption that fValue doesn't start with whitespace
|
||||
Assert(*valuePtr != '\t');
|
||||
Assert(*valuePtr != ' ');
|
||||
|
||||
for (UInt32 count = 0; ((count < inIndex) && (valuePtr != '\0')); count++)
|
||||
{
|
||||
//go through all the "words" on this line (delimited by whitespace)
|
||||
//until we hit the one specified by inIndex
|
||||
|
||||
//we aren't at the proper word yet, so skip...
|
||||
while ((*valuePtr != ' ') && (*valuePtr != '\t') && (*valuePtr != '\0'))
|
||||
valuePtr++;
|
||||
|
||||
//skip over all the whitespace between words
|
||||
while ((*valuePtr == ' ') || (*valuePtr == '\t'))
|
||||
valuePtr++;
|
||||
|
||||
}
|
||||
|
||||
//We've exhausted the data on this line before getting to our pref,
|
||||
//so return an error.
|
||||
if (*valuePtr == '\0')
|
||||
return false;
|
||||
|
||||
//if we are here, then valuePtr is pointing to the beginning of the right word
|
||||
while ((*valuePtr != ' ') && (*valuePtr != '\t') && (*valuePtr != '\0'))
|
||||
*ioValue++ = *valuePtr++;
|
||||
*ioValue = '\0';
|
||||
|
||||
return true;
|
||||
*/
|
||||
}
|
||||
|
||||
char* FilePrefsSource::GetValueAtIndex(UInt32 inIndex)
|
||||
{
|
||||
// Iterate through the queue until we have the right entry
|
||||
KeyValuePair* thePair = fKeyValueList;
|
||||
while ((thePair != NULL) && (inIndex-- > 0))
|
||||
thePair = thePair->fNext;
|
||||
|
||||
if (thePair != NULL)
|
||||
return thePair->fValue;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char* FilePrefsSource::GetKeyAtIndex(UInt32 inIndex)
|
||||
{
|
||||
// Iterate through the queue until we have the right entry
|
||||
KeyValuePair* thePair = fKeyValueList;
|
||||
while ((thePair != NULL) && (inIndex-- > 0))
|
||||
thePair = thePair->fNext;
|
||||
|
||||
if (thePair != NULL)
|
||||
return thePair->fKey;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void FilePrefsSource::SetValue(const char* inKey, const char* inValue)
|
||||
{
|
||||
KeyValuePair* keyValue = NULL;
|
||||
|
||||
// If the key/value already exists update the value.
|
||||
// If duplicate keys are allowed, however, add a new entry regardless
|
||||
if ((!fAllowDuplicates) && ((keyValue = this->FindValue(inKey, NULL)) != NULL))
|
||||
{
|
||||
keyValue->ResetValue(inValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
fKeyValueList = NEW KeyValuePair(inKey, inValue, fKeyValueList);
|
||||
fNumKeys++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Bool16 FilePrefsSource::FilePrefsConfigSetter( const char* paramName, const char* paramValue[], void* userData )
|
||||
{
|
||||
/*
|
||||
static callback routine for ParseConfigFile
|
||||
*/
|
||||
int valueIndex = 0;
|
||||
|
||||
FilePrefsSource *theFilePrefs = (FilePrefsSource*)userData;
|
||||
|
||||
Assert( theFilePrefs );
|
||||
Assert( paramName );
|
||||
// Assert( paramValue[0] );
|
||||
|
||||
|
||||
// multiple values are passed in the paramValue array as distinct strs
|
||||
while ( paramValue[valueIndex] != NULL )
|
||||
{
|
||||
//qtss_printf("Adding config setting <key=\"%s\", value=\"%s\">\n", paramName, paramValue[valueIndex] );
|
||||
theFilePrefs->SetValue(paramName, paramValue[valueIndex] );
|
||||
valueIndex++;
|
||||
}
|
||||
|
||||
return false; // always succeeds
|
||||
}
|
||||
|
||||
|
||||
int FilePrefsSource::InitFromConfigFile(const char* configFilePath)
|
||||
{
|
||||
/*
|
||||
load config from specified file. return non-zero
|
||||
in the event of significant error(s).
|
||||
|
||||
*/
|
||||
|
||||
return ::ParseConfigFile( true, configFilePath, FilePrefsConfigSetter, this );
|
||||
|
||||
/*
|
||||
int err = 0;
|
||||
char bufLine[kMaxLineLen];
|
||||
char key[kMaxValLen];
|
||||
char value[kMaxLineLen];
|
||||
|
||||
FILE* fileDesc = ::fopen( configFilePath, "r");
|
||||
|
||||
if (fileDesc == NULL)
|
||||
{
|
||||
// report some problem here...
|
||||
err = OSThread::GetErrno();
|
||||
|
||||
Assert( err );
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
while (fgets(bufLine, sizeof(bufLine) - 1, fileDesc) != NULL)
|
||||
{
|
||||
if (bufLine[0] != '#' && bufLine[0] != '\0')
|
||||
{
|
||||
int i = 0;
|
||||
int n = 0;
|
||||
|
||||
while ( bufLine[i] == ' ' || bufLine[i] == '\t')
|
||||
{ ++i;}
|
||||
|
||||
n = 0;
|
||||
while ( bufLine[i] != ' ' &&
|
||||
bufLine[i] != '\t' &&
|
||||
bufLine[i] != '\n' &&
|
||||
bufLine[i] != '\r' &&
|
||||
bufLine[i] != '\0' &&
|
||||
n < (kMaxLineLen - 1) )
|
||||
{
|
||||
key[n++] = bufLine[i++];
|
||||
}
|
||||
key[n] = '\0';
|
||||
|
||||
while (bufLine[i] == ' ' || bufLine[i] == '\t')
|
||||
{++i;}
|
||||
|
||||
n = 0;
|
||||
while ((bufLine[i] != '\n') && (bufLine[i] != '\0') &&
|
||||
(bufLine[i] != '\r') && (n < kMaxLineLen - 1))
|
||||
{
|
||||
value[n++] = bufLine[i++];
|
||||
}
|
||||
value[n] = '\0';
|
||||
|
||||
if (key[0] != '#' && key[0] != '\0' && value[0] != '\0')
|
||||
{
|
||||
qtss_printf("Adding config setting <key=\"%s\", value=\"%s\">\n", key, value);
|
||||
this->SetValue(key, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
//assert(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int closeErr = ::fclose(fileDesc);
|
||||
Assert(closeErr == 0);
|
||||
}
|
||||
|
||||
return err;
|
||||
*/
|
||||
|
||||
|
||||
}
|
||||
|
||||
void FilePrefsSource::DeleteValue(const char* inKey)
|
||||
{
|
||||
KeyValuePair* keyValue = fKeyValueList;
|
||||
KeyValuePair* prevKeyValue = NULL;
|
||||
|
||||
while (keyValue != NULL)
|
||||
{
|
||||
if (::strcmp(inKey, keyValue->fKey) == 0)
|
||||
{
|
||||
if (prevKeyValue != NULL)
|
||||
{
|
||||
prevKeyValue->fNext = keyValue->fNext;
|
||||
delete keyValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
fKeyValueList = prevKeyValue;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
prevKeyValue = keyValue;
|
||||
keyValue = keyValue->fNext;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FilePrefsSource::WriteToConfigFile(const char* configFilePath)
|
||||
{
|
||||
int err = 0;
|
||||
FILE* fileDesc = ::fopen( configFilePath, "w");
|
||||
|
||||
if (fileDesc != NULL)
|
||||
{
|
||||
err = ::fseek(fileDesc, 0, SEEK_END);
|
||||
Assert(err == 0);
|
||||
|
||||
KeyValuePair* keyValue = fKeyValueList;
|
||||
|
||||
while (keyValue != NULL)
|
||||
{
|
||||
(void)qtss_fprintf(fileDesc, "%s %s\n\n", keyValue->fKey, keyValue->fValue);
|
||||
|
||||
keyValue = keyValue->fNext;
|
||||
}
|
||||
|
||||
err = ::fclose(fileDesc);
|
||||
Assert(err == 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
KeyValuePair* FilePrefsSource::FindValue(const char* inKey, char* ioValue, UInt32 index )
|
||||
{
|
||||
KeyValuePair *keyValue = fKeyValueList;
|
||||
UInt32 foundIndex = 0;
|
||||
|
||||
if ( ioValue != NULL)
|
||||
ioValue[0] = '\0';
|
||||
|
||||
while (keyValue != NULL)
|
||||
{
|
||||
if (::strcmp(inKey, keyValue->fKey) == 0)
|
||||
{
|
||||
if ( foundIndex == index )
|
||||
{
|
||||
if (ioValue != NULL)
|
||||
::strcpy(ioValue, keyValue->fValue);
|
||||
return keyValue;
|
||||
}
|
||||
foundIndex++;
|
||||
}
|
||||
keyValue = keyValue->fNext;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
76
PrefsSourceLib/FilePrefsSource.h
Normal file
76
PrefsSourceLib/FilePrefsSource.h
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*
|
||||
*/
|
||||
/*
|
||||
File: FilePrefsSource.h
|
||||
|
||||
Contains: Implements the PrefsSource interface, getting the prefs from a file.
|
||||
|
||||
Written by: Chris LeCroy
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __FILEPREFSSOURCE_H__
|
||||
#define __FILEPREFSSOURCE_H__
|
||||
|
||||
#include "PrefsSource.h"
|
||||
#include "OSHeaders.h"
|
||||
|
||||
class KeyValuePair; //only used in the implementation
|
||||
|
||||
class FilePrefsSource : public PrefsSource
|
||||
{
|
||||
public:
|
||||
|
||||
FilePrefsSource( Bool16 allowDuplicates = false );
|
||||
virtual ~FilePrefsSource();
|
||||
|
||||
virtual int GetValue(const char* inKey, char* ioValue);
|
||||
virtual int GetValueByIndex(const char* inKey, UInt32 inIndex, char* ioValue);
|
||||
|
||||
// Allows caller to iterate over all the values in the file.
|
||||
char* GetValueAtIndex(UInt32 inIndex);
|
||||
char* GetKeyAtIndex(UInt32 inIndex);
|
||||
UInt32 GetNumKeys() { return fNumKeys; }
|
||||
|
||||
int InitFromConfigFile(const char* configFilePath);
|
||||
void WriteToConfigFile(const char* configFilePath);
|
||||
|
||||
void SetValue(const char* inKey, const char* inValue);
|
||||
void DeleteValue(const char* inKey);
|
||||
|
||||
private:
|
||||
|
||||
static Bool16 FilePrefsConfigSetter( const char* paramName, const char* paramValue[], void* userData );
|
||||
|
||||
KeyValuePair* FindValue(const char* inKey, char* ioValue, UInt32 index = 0);
|
||||
KeyValuePair* fKeyValueList;
|
||||
UInt32 fNumKeys;
|
||||
Bool16 fAllowDuplicates;
|
||||
};
|
||||
|
||||
#endif //__FILEPREFSSOURCE_H__
|
54
PrefsSourceLib/PrefsSource.h
Normal file
54
PrefsSourceLib/PrefsSource.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*
|
||||
*/
|
||||
/*
|
||||
File: PrefsSource.h
|
||||
|
||||
Contains: Defines an abstract common interface for extracting prefs
|
||||
from some data source. Very general, low level
|
||||
|
||||
Written by: Denis Serenyi
|
||||
|
||||
Change History (most recent first):
|
||||
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __PREFSSOURCE_H__
|
||||
#define __PREFSSOURCE_H__
|
||||
|
||||
#include "OSHeaders.h"
|
||||
|
||||
class PrefsSource
|
||||
{
|
||||
public:
|
||||
|
||||
virtual int GetValue(const char* inKey, char* ioValue) = 0;
|
||||
virtual int GetValueByIndex(const char* inKey, UInt32 inIndex, char* ioValue) = 0;
|
||||
virtual ~PrefsSource(){};
|
||||
};
|
||||
|
||||
#endif
|
692
PrefsSourceLib/XMLParser.cpp
Normal file
692
PrefsSourceLib/XMLParser.cpp
Normal file
|
@ -0,0 +1,692 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifndef __Win32__
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "XMLParser.h"
|
||||
#include "OSMemory.h"
|
||||
|
||||
XMLParser::XMLParser( char* inPath, DTDVerifier* verifier)
|
||||
: fRootTag(NULL), fFilePath(NULL)
|
||||
{
|
||||
StrPtrLen thePath(inPath);
|
||||
fFilePath = thePath.GetAsCString();
|
||||
fFile.Set(inPath);
|
||||
fVerifier = verifier;
|
||||
}
|
||||
|
||||
XMLParser::~XMLParser()
|
||||
{
|
||||
if (fRootTag)
|
||||
delete fRootTag;
|
||||
|
||||
delete [] fFilePath;
|
||||
}
|
||||
|
||||
Bool16 XMLParser::ParseFile(char* errorBuffer, int errorBufferSize)
|
||||
{
|
||||
if (fRootTag != NULL)
|
||||
{
|
||||
delete fRootTag; // flush old data
|
||||
fRootTag = NULL;
|
||||
}
|
||||
|
||||
fFile.Set(fFilePath);
|
||||
|
||||
if (errorBufferSize < 500) errorBuffer = NULL; // Just a hack to avoid checking everywhere
|
||||
if ((fFile.GetLength() == 0) || fFile.IsDir())
|
||||
{
|
||||
if (errorBuffer != NULL)
|
||||
qtss_snprintf(errorBuffer, errorBufferSize, "Couldn't read xml file");
|
||||
return false; // we don't have a valid file;
|
||||
}
|
||||
|
||||
char* fileData = NEW char[ (SInt32) (fFile.GetLength() + 1)];
|
||||
UInt32 theLengthRead = 0;
|
||||
fFile.Read(0, fileData, (UInt32) fFile.GetLength(), &theLengthRead);
|
||||
|
||||
StrPtrLen theDataPtr(fileData, theLengthRead);
|
||||
StringParser theParser(&theDataPtr);
|
||||
|
||||
fRootTag = NEW XMLTag();
|
||||
Bool16 result = fRootTag->ParseTag(&theParser, fVerifier, errorBuffer, errorBufferSize);
|
||||
if (!result)
|
||||
{
|
||||
// got error parsing file
|
||||
delete fRootTag;
|
||||
fRootTag = NULL;
|
||||
}
|
||||
|
||||
delete fileData;
|
||||
|
||||
fFile.Close();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Bool16 XMLParser::DoesFileExist()
|
||||
{
|
||||
Bool16 itExists = false;
|
||||
fFile.Set(fFilePath);
|
||||
if ((fFile.GetLength() > 0) && (!fFile.IsDir()))
|
||||
itExists = true;
|
||||
fFile.Close();
|
||||
|
||||
return itExists;
|
||||
}
|
||||
|
||||
Bool16 XMLParser::DoesFileExistAsDirectory()
|
||||
{
|
||||
Bool16 itExists = false;
|
||||
fFile.Set(fFilePath);
|
||||
if (fFile.IsDir())
|
||||
itExists = true;
|
||||
fFile.Close();
|
||||
|
||||
return itExists;
|
||||
}
|
||||
|
||||
Bool16 XMLParser::CanWriteFile()
|
||||
{
|
||||
//
|
||||
// First check if it exists for reading
|
||||
FILE* theFile = ::fopen(fFilePath, "r");
|
||||
if (theFile == NULL)
|
||||
return true;
|
||||
|
||||
::fclose(theFile);
|
||||
|
||||
//
|
||||
// File exists for reading, check if we can write it
|
||||
theFile = ::fopen(fFilePath, "a");
|
||||
if (theFile == NULL)
|
||||
return false;
|
||||
|
||||
//
|
||||
// We can read and write
|
||||
::fclose(theFile);
|
||||
return true;
|
||||
}
|
||||
|
||||
void XMLParser::SetRootTag(XMLTag* tag)
|
||||
{
|
||||
if (fRootTag != NULL)
|
||||
delete fRootTag;
|
||||
fRootTag = tag;
|
||||
}
|
||||
|
||||
void XMLParser::WriteToFile(char** fileHeader)
|
||||
{
|
||||
char theBuffer[8192];
|
||||
ResizeableStringFormatter formatter(theBuffer, 8192);
|
||||
|
||||
//
|
||||
// Write the file header
|
||||
for (UInt32 a = 0; fileHeader[a] != NULL; a++)
|
||||
{
|
||||
formatter.Put(fileHeader[a]);
|
||||
formatter.Put(kEOLString);
|
||||
}
|
||||
|
||||
if (fRootTag)
|
||||
fRootTag->FormatData(&formatter, 0);
|
||||
|
||||
//
|
||||
// New libC code. This seems to work better on Win32
|
||||
formatter.PutTerminator();
|
||||
FILE* theFile = ::fopen(fFilePath, "w");
|
||||
if (theFile == NULL)
|
||||
return;
|
||||
|
||||
qtss_fprintf(theFile, "%s", formatter.GetBufPtr());
|
||||
::fclose(theFile);
|
||||
|
||||
#if __MacOSX__
|
||||
(void) ::chown(fFilePath,76,80);//owner qtss, group admin
|
||||
#endif
|
||||
|
||||
#ifndef __Win32__
|
||||
::chmod(fFilePath, S_IRUSR | S_IWUSR | S_IRGRP );
|
||||
#endif
|
||||
}
|
||||
|
||||
UInt8 XMLTag::sNonNameMask[] =
|
||||
{
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //0-9
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //10-19
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //20-29
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //30-39
|
||||
1, 1, 1, 1, 1, 0, 0, 1, 0, 0, //40-49 '.' and '-' are name chars
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, //50-59 ':' is a name char
|
||||
1, 1, 1, 1, 1, 0, 0, 0, 0, 0, //60-69 //stop on every character except a letter or number
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //70-79
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //80-89
|
||||
0, 1, 1, 1, 1, 0, 1, 0, 0, 0, //90-99 '_' is a name char
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //100-109
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //110-119
|
||||
0, 0, 0, 1, 1, 1, 1, 1, 1, 1, //120-129
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //130-139
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //140-149
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //150-159
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //160-169
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //170-179
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //180-189
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //190-199
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //200-209
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //210-219
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //220-229
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //230-239
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, //240-249
|
||||
1, 1, 1, 1, 1, 1 //250-255
|
||||
};
|
||||
|
||||
XMLTag::XMLTag() :
|
||||
fTag(NULL),
|
||||
fValue(NULL),
|
||||
fElem(NULL)
|
||||
{ fElem = this;
|
||||
}
|
||||
|
||||
XMLTag::XMLTag(char* tagName) :
|
||||
fTag(NULL),
|
||||
fValue(NULL),
|
||||
fElem(NULL)
|
||||
{ fElem = this;
|
||||
StrPtrLen temp(tagName);
|
||||
fTag = temp.GetAsCString();
|
||||
}
|
||||
|
||||
XMLTag::~XMLTag()
|
||||
{
|
||||
if (fTag)
|
||||
delete fTag;
|
||||
if (fValue)
|
||||
delete fValue;
|
||||
|
||||
OSQueueElem* elem;
|
||||
while ((elem = fAttributes.DeQueue()) != NULL)
|
||||
{
|
||||
XMLAttribute* attr = (XMLAttribute*)elem->GetEnclosingObject();
|
||||
delete attr;
|
||||
}
|
||||
|
||||
while ((elem = fEmbeddedTags.DeQueue()) != NULL)
|
||||
{
|
||||
XMLTag* tag = (XMLTag*)elem->GetEnclosingObject();
|
||||
delete tag;
|
||||
}
|
||||
|
||||
if (fElem.IsMemberOfAnyQueue())
|
||||
fElem.InQueue()->Remove(&fElem); // remove from parent tag
|
||||
}
|
||||
|
||||
void XMLTag::ConsumeIfComment(StringParser* parser)
|
||||
{
|
||||
if ((parser->GetDataRemaining() > 2) && ((*parser)[1] == '-') && ((*parser)[2] == '-'))
|
||||
{
|
||||
// this is a comment, so skip to end of comment
|
||||
parser->ConsumeLength(NULL, 2); // skip '--'
|
||||
|
||||
// look for -->
|
||||
while((parser->GetDataRemaining() > 2) && ((parser->PeekFast() != '-') ||
|
||||
((*parser)[1] != '-') || ((*parser)[2] != '>')))
|
||||
{
|
||||
if (parser->PeekFast() == '-') parser->ConsumeLength(NULL, 1);
|
||||
parser->ConsumeUntil(NULL, '-');
|
||||
}
|
||||
|
||||
if (parser->GetDataRemaining() > 2) parser->ConsumeLength(NULL, 3); // consume -->
|
||||
}
|
||||
}
|
||||
|
||||
bool XMLTag::ParseTag(StringParser* parser, DTDVerifier* verifier, char* errorBuffer, int errorBufferSize)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (!parser->GetThru(NULL, '<'))
|
||||
{
|
||||
if (errorBuffer != NULL)
|
||||
qtss_snprintf(errorBuffer, errorBufferSize, "Couldn't find a valid tag");
|
||||
return false; // couldn't find beginning of tag
|
||||
}
|
||||
|
||||
char c = parser->PeekFast();
|
||||
if (c == '/')
|
||||
{
|
||||
if (errorBuffer != NULL)
|
||||
qtss_snprintf(errorBuffer, errorBufferSize, "End tag with no begin tag on line %d", parser->GetCurrentLineNumber());
|
||||
return false; // we shouldn't be seeing a close tag here
|
||||
}
|
||||
|
||||
if ((c != '!') && (c != '?'))
|
||||
break; // this should be the beginning of a regular tag
|
||||
|
||||
ConsumeIfComment(parser);
|
||||
// otherwise this is a processing instruction or a c-data, so look for the next tag
|
||||
}
|
||||
|
||||
int tagStartLine = parser->GetCurrentLineNumber();
|
||||
|
||||
StrPtrLen temp;
|
||||
parser->ConsumeUntil(&temp, sNonNameMask);
|
||||
if (temp.Len == 0)
|
||||
{
|
||||
if (errorBuffer != NULL)
|
||||
{
|
||||
if (parser->GetDataRemaining() == 0)
|
||||
qtss_snprintf(errorBuffer, errorBufferSize, "Unexpected end of file on line %d", parser->GetCurrentLineNumber());
|
||||
else
|
||||
qtss_snprintf(errorBuffer, errorBufferSize,"Unexpected character (%c) on line %d", parser->PeekFast(), parser->GetCurrentLineNumber());
|
||||
}
|
||||
return false; // bad file
|
||||
}
|
||||
|
||||
fTag = temp.GetAsCString();
|
||||
|
||||
parser->ConsumeWhitespace();
|
||||
while ((parser->PeekFast() != '>') && (parser->PeekFast() != '/'))
|
||||
{
|
||||
// we must have an attribute value for this tag
|
||||
XMLAttribute* attr = new XMLAttribute;
|
||||
fAttributes.EnQueue(&attr->fElem);
|
||||
parser->ConsumeUntil(&temp, sNonNameMask);
|
||||
if (temp.Len == 0)
|
||||
{
|
||||
if (errorBuffer != NULL)
|
||||
{
|
||||
if (parser->GetDataRemaining() == 0)
|
||||
qtss_snprintf(errorBuffer, errorBufferSize, "Unexpected end of file on line %d", parser->GetCurrentLineNumber());
|
||||
else
|
||||
qtss_snprintf(errorBuffer, errorBufferSize,"Unexpected character (%c) on line %d", parser->PeekFast(), parser->GetCurrentLineNumber());
|
||||
}
|
||||
return false; // bad file
|
||||
}
|
||||
|
||||
attr->fAttrName = temp.GetAsCString();
|
||||
|
||||
if (!parser->Expect('='))
|
||||
{
|
||||
if (errorBuffer != NULL)
|
||||
qtss_snprintf(errorBuffer, errorBufferSize,"Missing '=' after attribute %s on line %d", attr->fAttrName, parser->GetCurrentLineNumber());
|
||||
return false; // bad attribute specification
|
||||
}
|
||||
if (!parser->Expect('"'))
|
||||
{
|
||||
if (errorBuffer != NULL)
|
||||
qtss_snprintf(errorBuffer, errorBufferSize,"Attribute %s value not in quotes on line %d", attr->fAttrName, parser->GetCurrentLineNumber());
|
||||
return false; // bad attribute specification
|
||||
}
|
||||
|
||||
parser->ConsumeUntil(&temp, '"');
|
||||
attr->fAttrValue = temp.GetAsCString();
|
||||
if (!parser->Expect('"'))
|
||||
{
|
||||
if (errorBuffer != NULL)
|
||||
qtss_snprintf(errorBuffer, errorBufferSize, "Attribute %s value not in quotes on line %d", attr->fAttrName, parser->GetCurrentLineNumber());
|
||||
return false; // bad attribute specification
|
||||
}
|
||||
|
||||
if (verifier && !verifier->IsValidAttributeName(fTag, attr->fAttrName))
|
||||
{
|
||||
if (errorBuffer != NULL)
|
||||
qtss_snprintf(errorBuffer, errorBufferSize, "Attribute %s not allowed in tag %s on line %d", attr->fAttrName, fTag, parser->GetCurrentLineNumber());
|
||||
return false; // bad attribute specification
|
||||
}
|
||||
|
||||
if (verifier && !verifier->IsValidAttributeValue(fTag, attr->fAttrName, attr->fAttrValue))
|
||||
{
|
||||
if (errorBuffer != NULL)
|
||||
qtss_snprintf(errorBuffer, errorBufferSize,"Bad value for attribute %s on line %d", attr->fAttrName, parser->GetCurrentLineNumber());
|
||||
return false; // bad attribute specification
|
||||
}
|
||||
|
||||
parser->ConsumeWhitespace();
|
||||
}
|
||||
|
||||
if (parser->PeekFast() == '/')
|
||||
{
|
||||
// this is an empty element tag, i.e. no contents or end tag (e.g <TAG attr="value" />
|
||||
parser->Expect('/');
|
||||
if (!parser->Expect('>'))
|
||||
{
|
||||
if (errorBuffer != NULL)
|
||||
qtss_snprintf(errorBuffer, errorBufferSize,"'>' must follow '/' on line %d", parser->GetCurrentLineNumber());
|
||||
return false; // bad attribute specification
|
||||
}
|
||||
|
||||
return true; // we're done with this tag
|
||||
}
|
||||
|
||||
if (!parser->Expect('>'))
|
||||
{
|
||||
if (errorBuffer != NULL)
|
||||
qtss_snprintf(errorBuffer, errorBufferSize,"Bad format for tag <%s> on line %d", fTag, parser->GetCurrentLineNumber());
|
||||
return false; // bad attribute specification
|
||||
}
|
||||
|
||||
while(true)
|
||||
{
|
||||
parser->ConsumeUntil(&temp, '<'); // this is either value or whitespace
|
||||
if (parser->GetDataRemaining() < 4)
|
||||
{
|
||||
if (errorBuffer != NULL)
|
||||
qtss_snprintf(errorBuffer, errorBufferSize, "Reached end of file without end for tag <%s> declared on line %d", fTag, tagStartLine);
|
||||
return false;
|
||||
}
|
||||
if ((*parser)[1] == '/')
|
||||
{
|
||||
// we'll only assign a value if there were no embedded tags
|
||||
if (fEmbeddedTags.GetLength() == 0 && (!verifier || verifier->CanHaveValue(fTag)))
|
||||
fValue = temp.GetAsCString();
|
||||
else
|
||||
{
|
||||
// otherwise this needs to have been just whitespace
|
||||
StringParser tempParser(&temp);
|
||||
tempParser.ConsumeWhitespace();
|
||||
if (tempParser.GetDataRemaining() > 0)
|
||||
{
|
||||
if (errorBuffer)
|
||||
{
|
||||
if (fEmbeddedTags.GetLength() > 0)
|
||||
qtss_snprintf(errorBuffer, errorBufferSize,"Unexpected text outside of tag on line %d", tagStartLine);
|
||||
else
|
||||
qtss_snprintf(errorBuffer, errorBufferSize, "Tag <%s> on line %d not allowed to have data", fTag, tagStartLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
break; // we're all done with this tag
|
||||
}
|
||||
|
||||
if (((*parser)[1] != '!') && ((*parser)[1] != '?'))
|
||||
{
|
||||
// this must be the beginning of an embedded tag
|
||||
XMLTag* tag = NEW XMLTag();
|
||||
fEmbeddedTags.EnQueue(&tag->fElem);
|
||||
if (!tag->ParseTag(parser, verifier, errorBuffer, errorBufferSize))
|
||||
return false;
|
||||
|
||||
if (verifier && !verifier->IsValidSubtag(fTag, tag->GetTagName()))
|
||||
{
|
||||
if (errorBuffer != NULL)
|
||||
qtss_snprintf(errorBuffer, errorBufferSize, "Tag %s not allowed in tag %s on line %d", tag->GetTagName(), fTag, parser->GetCurrentLineNumber());
|
||||
return false; // bad attribute specification
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
parser->ConsumeLength(NULL, 1); // skip '<'
|
||||
ConsumeIfComment(parser);
|
||||
}
|
||||
}
|
||||
|
||||
parser->ConsumeLength(NULL, 2); // skip '</'
|
||||
parser->ConsumeUntil(&temp, sNonNameMask);
|
||||
if (!temp.Equal(fTag))
|
||||
{
|
||||
char* newTag = temp.GetAsCString();
|
||||
if (errorBuffer != NULL)
|
||||
qtss_snprintf(errorBuffer, errorBufferSize,"End tag </%s> on line %d doesn't match tag <%s> declared on line %d", newTag, parser->GetCurrentLineNumber(),fTag, tagStartLine);
|
||||
delete newTag;
|
||||
return false; // bad attribute specification
|
||||
}
|
||||
|
||||
if (!parser->GetThru(NULL, '>'))
|
||||
{
|
||||
if (errorBuffer != NULL)
|
||||
qtss_snprintf(errorBuffer, errorBufferSize,"Couldn't find end of tag <%s> declared on line %d", fTag, tagStartLine);
|
||||
return false; // bad attribute specification
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
char* XMLTag::GetAttributeValue(const char* attrName)
|
||||
{
|
||||
for (OSQueueIter iter(&fAttributes); !iter.IsDone(); iter.Next())
|
||||
{
|
||||
XMLAttribute* attr = (XMLAttribute*)iter.GetCurrent()->GetEnclosingObject();
|
||||
if (!strcmp(attr->fAttrName, attrName))
|
||||
return attr->fAttrValue;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
XMLTag* XMLTag::GetEmbeddedTag(const UInt32 index)
|
||||
{
|
||||
if (fEmbeddedTags.GetLength() <= index)
|
||||
return NULL;
|
||||
|
||||
OSQueueIter iter(&fEmbeddedTags);
|
||||
for (UInt32 i = 0; i < index; i++)
|
||||
{
|
||||
iter.Next();
|
||||
}
|
||||
OSQueueElem* result = iter.GetCurrent();
|
||||
|
||||
return (XMLTag*)result->GetEnclosingObject();
|
||||
}
|
||||
|
||||
XMLTag* XMLTag::GetEmbeddedTagByName(const char* tagName, const UInt32 index)
|
||||
{
|
||||
if (fEmbeddedTags.GetLength() <= index)
|
||||
return NULL;
|
||||
|
||||
XMLTag* result = NULL;
|
||||
UInt32 curIndex = 0;
|
||||
for (OSQueueIter iter(&fEmbeddedTags); !iter.IsDone(); iter.Next())
|
||||
{
|
||||
XMLTag* temp = (XMLTag*)iter.GetCurrent()->GetEnclosingObject();
|
||||
if (!strcmp(temp->GetTagName(), tagName))
|
||||
{
|
||||
if (curIndex == index)
|
||||
{
|
||||
result = temp;
|
||||
break;
|
||||
}
|
||||
|
||||
curIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
XMLTag* XMLTag::GetEmbeddedTagByAttr(const char* attrName, const char* attrValue, const UInt32 index)
|
||||
{
|
||||
if (fEmbeddedTags.GetLength() <= index)
|
||||
return NULL;
|
||||
|
||||
XMLTag* result = NULL;
|
||||
UInt32 curIndex = 0;
|
||||
for (OSQueueIter iter(&fEmbeddedTags); !iter.IsDone(); iter.Next())
|
||||
{
|
||||
XMLTag* temp = (XMLTag*)iter.GetCurrent()->GetEnclosingObject();
|
||||
if ((temp->GetAttributeValue(attrName) != NULL) && (!strcmp(temp->GetAttributeValue(attrName), attrValue)))
|
||||
{
|
||||
if (curIndex == index)
|
||||
{
|
||||
result = temp;
|
||||
break;
|
||||
}
|
||||
|
||||
curIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
XMLTag* XMLTag::GetEmbeddedTagByNameAndAttr(const char* tagName, const char* attrName, const char* attrValue, const UInt32 index)
|
||||
{
|
||||
if (fEmbeddedTags.GetLength() <= index)
|
||||
return NULL;
|
||||
|
||||
XMLTag* result = NULL;
|
||||
UInt32 curIndex = 0;
|
||||
for (OSQueueIter iter(&fEmbeddedTags); !iter.IsDone(); iter.Next())
|
||||
{
|
||||
XMLTag* temp = (XMLTag*)iter.GetCurrent()->GetEnclosingObject();
|
||||
if (!strcmp(temp->GetTagName(), tagName) && (temp->GetAttributeValue(attrName) != NULL) &&
|
||||
(!strcmp(temp->GetAttributeValue(attrName), attrValue)))
|
||||
{
|
||||
if (curIndex == index)
|
||||
{
|
||||
result = temp;
|
||||
break;
|
||||
}
|
||||
|
||||
curIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void XMLTag::AddAttribute( char* attrName, char* attrValue)
|
||||
{
|
||||
XMLAttribute* attr = NEW XMLAttribute;
|
||||
StrPtrLen temp(attrName);
|
||||
attr->fAttrName = temp.GetAsCString();
|
||||
temp.Set(attrValue);
|
||||
attr->fAttrValue = temp.GetAsCString();
|
||||
|
||||
fAttributes.EnQueue(&attr->fElem);
|
||||
}
|
||||
|
||||
void XMLTag::RemoveAttribute(char* attrName)
|
||||
{
|
||||
for (OSQueueIter iter(&fAttributes); !iter.IsDone(); iter.Next())
|
||||
{
|
||||
XMLAttribute* attr = (XMLAttribute*)iter.GetCurrent()->GetEnclosingObject();
|
||||
if (!strcmp(attr->fAttrName, attrName))
|
||||
{
|
||||
fAttributes.Remove(&attr->fElem);
|
||||
delete attr;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void XMLTag::AddEmbeddedTag(XMLTag* tag)
|
||||
{
|
||||
fEmbeddedTags.EnQueue(&tag->fElem);
|
||||
}
|
||||
|
||||
void XMLTag::RemoveEmbeddedTag(XMLTag* tag)
|
||||
{
|
||||
fEmbeddedTags.Remove(&tag->fElem);
|
||||
}
|
||||
|
||||
void XMLTag::SetTagName( char* name)
|
||||
{
|
||||
Assert (name != NULL); // can't have a tag without a name!
|
||||
|
||||
if (fTag != NULL)
|
||||
delete fTag;
|
||||
|
||||
StrPtrLen temp(name);
|
||||
fTag = temp.GetAsCString();
|
||||
}
|
||||
|
||||
void XMLTag::SetValue( char* value)
|
||||
{
|
||||
if (fEmbeddedTags.GetLength() > 0)
|
||||
return; // can't have a value with embedded tags
|
||||
|
||||
if (fValue != NULL)
|
||||
delete fValue;
|
||||
|
||||
if (value == NULL)
|
||||
fValue = NULL;
|
||||
else
|
||||
{
|
||||
StrPtrLen temp(value);
|
||||
fValue = temp.GetAsCString();
|
||||
}
|
||||
}
|
||||
|
||||
void XMLTag::FormatData(ResizeableStringFormatter* formatter, UInt32 indent)
|
||||
{
|
||||
for (UInt32 i=0; i<indent; i++) formatter->PutChar('\t');
|
||||
|
||||
formatter->PutChar('<');
|
||||
formatter->Put(fTag);
|
||||
if (fAttributes.GetLength() > 0)
|
||||
{
|
||||
formatter->PutChar(' ');
|
||||
for (OSQueueIter iter(&fAttributes); !iter.IsDone(); iter.Next())
|
||||
{
|
||||
XMLAttribute* attr = (XMLAttribute*)iter.GetCurrent()->GetEnclosingObject();
|
||||
formatter->Put(attr->fAttrName);
|
||||
formatter->Put("=\"");
|
||||
formatter->Put(attr->fAttrValue);
|
||||
formatter->Put("\" ");
|
||||
}
|
||||
}
|
||||
formatter->PutChar('>');
|
||||
|
||||
if (fEmbeddedTags.GetLength() == 0)
|
||||
{
|
||||
if (fValue > 0)
|
||||
formatter->Put(fValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
formatter->Put(kEOLString);
|
||||
for (OSQueueIter iter(&fEmbeddedTags); !iter.IsDone(); iter.Next())
|
||||
{
|
||||
XMLTag* current = (XMLTag*)iter.GetCurrent()->GetEnclosingObject();
|
||||
current->FormatData(formatter, indent + 1);
|
||||
}
|
||||
|
||||
for (UInt32 i=0; i<indent; i++) formatter->PutChar('\t');
|
||||
}
|
||||
|
||||
formatter->Put("</");
|
||||
formatter->Put(fTag);
|
||||
formatter->PutChar('>');
|
||||
formatter->Put(kEOLString);
|
||||
}
|
||||
|
||||
XMLAttribute::XMLAttribute()
|
||||
: fAttrName(NULL),
|
||||
fAttrValue(NULL)
|
||||
{ fElem = this;
|
||||
}
|
||||
|
||||
XMLAttribute::~XMLAttribute()
|
||||
{
|
||||
if (fAttrName)
|
||||
delete fAttrName;
|
||||
if (fAttrValue)
|
||||
delete fAttrValue;
|
||||
}
|
126
PrefsSourceLib/XMLParser.h
Normal file
126
PrefsSourceLib/XMLParser.h
Normal file
|
@ -0,0 +1,126 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __XMLParser_h__
|
||||
#define __XMLParser_h__
|
||||
|
||||
#include "StringParser.h"
|
||||
#include "OSQueue.h"
|
||||
#include "OSFileSource.h"
|
||||
#include "ResizeableStringFormatter.h"
|
||||
|
||||
class DTDVerifier
|
||||
{
|
||||
public:
|
||||
virtual bool IsValidSubtag(char* tagName, char* subTagName) = 0;
|
||||
virtual bool IsValidAttributeName(char* tagName, char* attrName) = 0;
|
||||
virtual bool IsValidAttributeValue(char* tagName, char* attrName, char* attrValue) = 0;
|
||||
virtual char* GetRequiredAttribute(char* tagName, int index) = 0;
|
||||
virtual bool CanHaveValue(char* tagName) = 0;
|
||||
virtual ~DTDVerifier(){};
|
||||
};
|
||||
|
||||
class XMLTag
|
||||
{
|
||||
public:
|
||||
XMLTag();
|
||||
XMLTag(char* tagName);
|
||||
~XMLTag();
|
||||
|
||||
bool ParseTag(StringParser* parser, DTDVerifier* verifier, char* errorBuffer = NULL, int errorBufferSize = 0);
|
||||
|
||||
char* GetAttributeValue(const char* attrName);
|
||||
char* GetValue() { return fValue; }
|
||||
char* GetTagName() { return fTag; }
|
||||
|
||||
UInt32 GetNumEmbeddedTags() { return fEmbeddedTags.GetLength(); }
|
||||
|
||||
XMLTag* GetEmbeddedTag(const UInt32 index = 0);
|
||||
XMLTag* GetEmbeddedTagByName(const char* tagName, const UInt32 index = 0);
|
||||
XMLTag* GetEmbeddedTagByAttr(const char* attrName, const char* attrValue, const UInt32 index = 0);
|
||||
XMLTag* GetEmbeddedTagByNameAndAttr(const char* tagName, const char* attrName, const char* attrValue, const UInt32 index = 0);
|
||||
|
||||
void AddAttribute(char* attrName, char* attrValue);
|
||||
void RemoveAttribute(char* attrName);
|
||||
void AddEmbeddedTag(XMLTag* tag);
|
||||
void RemoveEmbeddedTag(XMLTag* tag);
|
||||
|
||||
void SetTagName( char* name);
|
||||
void SetValue( char* value);
|
||||
|
||||
void FormatData(ResizeableStringFormatter* formatter, UInt32 indent);
|
||||
|
||||
private:
|
||||
void ConsumeIfComment(StringParser* parser);
|
||||
|
||||
char* fTag;
|
||||
char* fValue;
|
||||
OSQueue fAttributes;
|
||||
OSQueue fEmbeddedTags;
|
||||
|
||||
OSQueueElem fElem;
|
||||
|
||||
static UInt8 sNonNameMask[]; // stop when you hit a word
|
||||
};
|
||||
|
||||
class XMLAttribute
|
||||
{
|
||||
public:
|
||||
XMLAttribute();
|
||||
~XMLAttribute();
|
||||
|
||||
char* fAttrName;
|
||||
char* fAttrValue;
|
||||
|
||||
OSQueueElem fElem;
|
||||
};
|
||||
|
||||
class XMLParser
|
||||
{
|
||||
public:
|
||||
XMLParser( char* inPath, DTDVerifier* verifier = NULL);
|
||||
~XMLParser();
|
||||
|
||||
// Check for existence, man.
|
||||
Bool16 DoesFileExist();
|
||||
Bool16 DoesFileExistAsDirectory();
|
||||
Bool16 CanWriteFile();
|
||||
|
||||
Bool16 ParseFile(char* errorBuffer = NULL, int errorBufferSize = 0);
|
||||
|
||||
XMLTag* GetRootTag() { return fRootTag; }
|
||||
void SetRootTag(XMLTag* tag);
|
||||
|
||||
void WriteToFile(char** fileHeader);
|
||||
|
||||
private:
|
||||
XMLTag* fRootTag;
|
||||
|
||||
OSFileSource fFile;
|
||||
char* fFilePath;
|
||||
DTDVerifier* fVerifier;
|
||||
};
|
||||
|
||||
#endif
|
410
PrefsSourceLib/XMLPrefsParser.cpp
Normal file
410
PrefsSourceLib/XMLPrefsParser.cpp
Normal file
|
@ -0,0 +1,410 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*
|
||||
*/
|
||||
/*
|
||||
File: XMLPrefsParser.cpp
|
||||
|
||||
Contains: Prototype implementation of XMLPrefsParser object.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#ifndef __Win32__
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "XMLPrefsParser.h"
|
||||
#include "OSMemory.h"
|
||||
#include "OSHeaders.h"
|
||||
|
||||
static const UInt32 kPrefArrayMinSize = 20;
|
||||
|
||||
static char* kMainTag = "CONFIGURATION";
|
||||
static char* kServer = "SERVER";
|
||||
static char* kModule = "MODULE";
|
||||
static char* kPref = "PREF";
|
||||
static char* kListPref = "LIST-PREF";
|
||||
static char* kEmptyObject = "EMPTY-OBJECT";
|
||||
static char* kObject = "OBJECT";
|
||||
static char* kObjectList = "LIST-OBJECT";
|
||||
static char* kValue = "VALUE";
|
||||
static char* kNameAttr = "NAME";
|
||||
static char* kTypeAttr = "TYPE";
|
||||
|
||||
static char* kFileHeader[] =
|
||||
{
|
||||
"<?xml version =\"1.0\"?>",
|
||||
"<!-- The Document Type Definition (DTD) for the file -->",
|
||||
"<!DOCTYPE CONFIGURATION [",
|
||||
"<!ELEMENT CONFIGURATION (SERVER, MODULE*)>",
|
||||
"<!ELEMENT SERVER (PREF|LIST-PREF|OBJECT|LIST-OBJECT)*>",
|
||||
"<!ELEMENT MODULE (PREF|LIST-PREF|OBJECT|LIST-OBJECT)*>",
|
||||
"<!ATTLIST MODULE",
|
||||
"\tNAME CDATA #REQUIRED>",
|
||||
"<!ELEMENT PREF (#PCDATA)>",
|
||||
"<!ATTLIST PREF",
|
||||
"\tNAME CDATA #REQUIRED",
|
||||
"\tTYPE (UInt8|SInt8|UInt16|SInt16|UInt32|SInt32|UInt64|SInt64|Float32|Float64|Bool16|Bool8|char) \"char\">",
|
||||
"<!ELEMENT LIST-PREF (VALUE*)>",
|
||||
"<!ELEMENT VALUE (#PCDATA)>",
|
||||
"<!ATTLIST LIST-PREF",
|
||||
"\tNAME CDATA #REQUIRED",
|
||||
"\tTYPE (UInt8|SInt8|UInt16|SInt16|UInt32|SInt32|UInt64|SInt64|Float32|Float64|Bool16|Bool8|char) \"char\">",
|
||||
"<!ELEMENT OBJECT (PREF|LIST-PREF|OBJECT|LIST-OBJECT)*>",
|
||||
"<!ATTLIST OBJECT",
|
||||
"\tNAME CDATA #REQUIRED>",
|
||||
"<!ELEMENT LIST-OBJECT (OBJECT-VALUE*)>",
|
||||
"<!ELEMENT OBJECT-VALUE (PREF|LIST-PREF|OBJECT|LIST-OBJECT)*>",
|
||||
"<!ATTLIST LIST-OBJECT",
|
||||
"\tNAME CDATA #REQUIRED>",
|
||||
"]>",
|
||||
NULL
|
||||
};
|
||||
|
||||
XMLPrefsParser::XMLPrefsParser(char* inPath)
|
||||
: XMLParser(inPath)
|
||||
{}
|
||||
|
||||
XMLPrefsParser::~XMLPrefsParser()
|
||||
{}
|
||||
|
||||
|
||||
ContainerRef XMLPrefsParser::GetConfigurationTag()
|
||||
{
|
||||
ContainerRef result = GetRootTag();
|
||||
if (result == NULL)
|
||||
{
|
||||
result = new XMLTag(kMainTag);
|
||||
SetRootTag(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ContainerRef XMLPrefsParser::GetRefForModule(char* inModuleName, Bool16 create)
|
||||
{
|
||||
if (inModuleName == NULL)
|
||||
return GetRefForServer();
|
||||
|
||||
ContainerRef result = GetConfigurationTag()->GetEmbeddedTagByNameAndAttr(kModule, kNameAttr, inModuleName);
|
||||
if (result == NULL)
|
||||
{
|
||||
result = new XMLTag(kModule);
|
||||
result->AddAttribute( kNameAttr, (char*)inModuleName);
|
||||
GetRootTag()->AddEmbeddedTag(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
ContainerRef XMLPrefsParser::GetRefForServer()
|
||||
{
|
||||
ContainerRef result = GetConfigurationTag()->GetEmbeddedTagByName(kServer);
|
||||
if (result == NULL)
|
||||
{
|
||||
result = new XMLTag(kServer);
|
||||
GetRootTag()->AddEmbeddedTag(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
UInt32 XMLPrefsParser::GetNumPrefValues(ContainerRef pref)
|
||||
{
|
||||
if (!strcmp(pref->GetTagName(), kPref))
|
||||
{
|
||||
if (pref->GetValue() == NULL)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
else if (!strcmp(pref->GetTagName(), kObject))
|
||||
return 1;
|
||||
else if (!strcmp(pref->GetTagName(), kEmptyObject))
|
||||
return 0;
|
||||
|
||||
return pref->GetNumEmbeddedTags(); // it must be a list
|
||||
}
|
||||
|
||||
UInt32 XMLPrefsParser::GetNumPrefsByContainer(ContainerRef container)
|
||||
{
|
||||
return container->GetNumEmbeddedTags();
|
||||
}
|
||||
|
||||
char* XMLPrefsParser::GetPrefValueByIndex(ContainerRef container, const UInt32 inPrefsIndex, const UInt32 inValueIndex,
|
||||
char** outPrefName, char** outDataType)
|
||||
{
|
||||
if (outPrefName != NULL)
|
||||
*outPrefName = NULL;
|
||||
if (outPrefName != NULL)
|
||||
*outDataType = NULL;
|
||||
XMLTag* pref = container->GetEmbeddedTag(inPrefsIndex);
|
||||
if (pref == NULL)
|
||||
return NULL;
|
||||
|
||||
return GetPrefValueByRef(pref, inValueIndex, outPrefName, outDataType);
|
||||
}
|
||||
|
||||
char* XMLPrefsParser::GetPrefValueByRef(ContainerRef pref, const UInt32 inValueIndex,
|
||||
char** outPrefName, char** outDataType)
|
||||
{
|
||||
if (outPrefName != NULL)
|
||||
*outPrefName = pref->GetAttributeValue(kNameAttr);
|
||||
if (outDataType != NULL)
|
||||
{
|
||||
*outDataType = pref->GetAttributeValue(kTypeAttr);
|
||||
if (*outDataType == NULL)
|
||||
*outDataType = "CharArray";
|
||||
}
|
||||
|
||||
if (!strcmp(pref->GetTagName(), kPref))
|
||||
{
|
||||
if (inValueIndex > 0)
|
||||
return NULL;
|
||||
else
|
||||
return pref->GetValue();
|
||||
}
|
||||
|
||||
if (!strcmp(pref->GetTagName(), kListPref))
|
||||
{
|
||||
XMLTag* value = pref->GetEmbeddedTag(inValueIndex);
|
||||
if (value != NULL)
|
||||
return value->GetValue();
|
||||
}
|
||||
|
||||
if (!strcmp(pref->GetTagName(), kObject) || !strcmp(pref->GetTagName(), kObjectList))
|
||||
*outDataType = "QTSS_Object";
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ContainerRef XMLPrefsParser::GetObjectValue(ContainerRef pref, const UInt32 inValueIndex)
|
||||
{
|
||||
if (!strcmp(pref->GetTagName(), kObject) && (inValueIndex == 0))
|
||||
return pref;
|
||||
if (!strcmp(pref->GetTagName(), kObjectList))
|
||||
return pref->GetEmbeddedTag(inValueIndex);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ContainerRef XMLPrefsParser::GetPrefRefByName( ContainerRef container,
|
||||
const char* inPrefName)
|
||||
{
|
||||
return container->GetEmbeddedTagByAttr(kNameAttr, inPrefName);
|
||||
}
|
||||
|
||||
ContainerRef XMLPrefsParser::GetPrefRefByIndex( ContainerRef container,
|
||||
const UInt32 inPrefsIndex)
|
||||
{
|
||||
return container->GetEmbeddedTag(inPrefsIndex);
|
||||
}
|
||||
|
||||
ContainerRef XMLPrefsParser::AddPref( ContainerRef container, char* inPrefName,
|
||||
char* inPrefDataType )
|
||||
{
|
||||
XMLTag* pref = container->GetEmbeddedTagByAttr(kNameAttr, inPrefName);
|
||||
if (pref != NULL)
|
||||
return pref; // it already exists
|
||||
|
||||
pref = NEW XMLTag(kPref); // start it out as a pref
|
||||
pref->AddAttribute(kNameAttr, inPrefName);
|
||||
if (!strcmp(inPrefDataType, "QTSS_Object"))
|
||||
pref->SetTagName(kEmptyObject);
|
||||
else if (strcmp(inPrefDataType, "CharArray"))
|
||||
pref->AddAttribute(kTypeAttr, (char*)inPrefDataType);
|
||||
|
||||
container->AddEmbeddedTag(pref);
|
||||
|
||||
return pref;
|
||||
}
|
||||
|
||||
void XMLPrefsParser::AddPrefValue( ContainerRef pref, char* inNewValue)
|
||||
{
|
||||
if (!strcmp(pref->GetTagName(), kPref)) // is this a PREF tag
|
||||
{
|
||||
if (pref->GetValue() == NULL)
|
||||
{
|
||||
// easy case, no existing value, so just add a vlue
|
||||
pref->SetValue(inNewValue);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// it already has a value, so change the pref to be a list pref and go to code below
|
||||
char* firstValue = pref->GetValue();
|
||||
XMLTag* value = NEW XMLTag(kValue);
|
||||
value->SetValue(firstValue);
|
||||
|
||||
pref->SetTagName(kListPref);
|
||||
pref->SetValue(NULL);
|
||||
pref->AddEmbeddedTag(value);
|
||||
}
|
||||
}
|
||||
|
||||
// we want to fall through from second case above, so this isn't an else
|
||||
if (!strcmp(pref->GetTagName(), kListPref))
|
||||
{
|
||||
XMLTag* value = NEW XMLTag(kValue);
|
||||
value->SetValue(inNewValue);
|
||||
pref->AddEmbeddedTag(value);
|
||||
}
|
||||
}
|
||||
|
||||
void XMLPrefsParser::AddNewObject( ContainerRef pref )
|
||||
{
|
||||
if (!strcmp(pref->GetTagName(), kEmptyObject))
|
||||
{
|
||||
// just flag that this is now a real object instead of a placeholder
|
||||
pref->SetTagName(kObject);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!strcmp(pref->GetTagName(), kObject))
|
||||
{
|
||||
// change the object to be an object list and go to code below
|
||||
XMLTag* subObject = NEW XMLTag(kObject);
|
||||
XMLTag* objectPref;
|
||||
// copy all this objects tags into the new listed object
|
||||
while((objectPref = pref->GetEmbeddedTag()) != NULL)
|
||||
{
|
||||
pref->RemoveEmbeddedTag(objectPref);
|
||||
subObject->AddEmbeddedTag(objectPref);
|
||||
}
|
||||
|
||||
pref->SetTagName(kObjectList);
|
||||
pref->AddEmbeddedTag(subObject);
|
||||
}
|
||||
|
||||
// we want to fall through from second case above, so this isn't an else
|
||||
if (!strcmp(pref->GetTagName(), kObjectList))
|
||||
{
|
||||
XMLTag* subObject = NEW XMLTag(kObject);
|
||||
pref->AddEmbeddedTag(subObject);
|
||||
}
|
||||
}
|
||||
|
||||
void XMLPrefsParser::ChangePrefType( ContainerRef pref, char* inNewPrefDataType)
|
||||
{
|
||||
pref->RemoveAttribute(kTypeAttr); // remove it if it exists
|
||||
if (strcmp(inNewPrefDataType, "CharArray"))
|
||||
pref->AddAttribute(kTypeAttr, inNewPrefDataType);
|
||||
}
|
||||
|
||||
void XMLPrefsParser::SetPrefValue( ContainerRef pref, const UInt32 inValueIndex,
|
||||
char* inNewValue)
|
||||
{
|
||||
UInt32 numValues = GetNumPrefValues(pref);
|
||||
|
||||
if (((numValues == 0) || (numValues == 1)) && (inValueIndex == 0))
|
||||
{
|
||||
pref->SetValue(inNewValue);
|
||||
}
|
||||
else if (inValueIndex == numValues) // this is an additional value
|
||||
AddPrefValue(pref, inNewValue);
|
||||
else
|
||||
{
|
||||
XMLTag* value = pref->GetEmbeddedTag(inValueIndex);
|
||||
if (value != NULL)
|
||||
value->SetValue(inNewValue);
|
||||
}
|
||||
}
|
||||
|
||||
void XMLPrefsParser::RemovePrefValue( ContainerRef pref, const UInt32 inValueIndex)
|
||||
{
|
||||
UInt32 numValues = GetNumPrefValues(pref);
|
||||
if (inValueIndex >= numValues)
|
||||
return;
|
||||
|
||||
if (numValues == 1)
|
||||
{
|
||||
delete pref; // just remove the whole pref
|
||||
}
|
||||
else if (numValues == 2)
|
||||
{
|
||||
XMLTag* value = pref->GetEmbeddedTag(inValueIndex); // get the one we're removing
|
||||
delete value; // delete it
|
||||
value = pref->GetEmbeddedTag(0); // get the remaining tag index always 0 for 2 vals
|
||||
pref->RemoveEmbeddedTag(value); // pull it out of the parent
|
||||
if (!strcmp(pref->GetTagName(), kObjectList))
|
||||
{
|
||||
pref->SetTagName(kObject); // set it back to a simple pref
|
||||
// move all this objects tags into the parent
|
||||
XMLTag* objectPref;
|
||||
while((objectPref = value->GetEmbeddedTag()) != NULL)
|
||||
{
|
||||
value->RemoveEmbeddedTag(objectPref);
|
||||
pref->AddEmbeddedTag(objectPref);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
char* temp = value->GetValue();
|
||||
pref->SetTagName(kPref); // set it back to a simple pref
|
||||
pref->SetValue(temp);
|
||||
}
|
||||
|
||||
delete value; // get rid of the other one
|
||||
}
|
||||
else
|
||||
{
|
||||
XMLTag* value = pref->GetEmbeddedTag(inValueIndex);
|
||||
if (value)
|
||||
delete value;
|
||||
}
|
||||
}
|
||||
|
||||
void XMLPrefsParser::RemovePref( ContainerRef pref )
|
||||
{
|
||||
delete pref;
|
||||
}
|
||||
|
||||
int XMLPrefsParser::Parse()
|
||||
{
|
||||
char error[500];
|
||||
|
||||
if (!ParseFile(error, sizeof(error)))
|
||||
{
|
||||
qtss_printf("%s\n", error);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// the above routine checks that it's a valid XML file, we should check that
|
||||
// all the tags conform to our prefs format
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int XMLPrefsParser::WritePrefsFile()
|
||||
{
|
||||
GetConfigurationTag(); // force it to be created if it doesn't exist
|
||||
WriteToFile(kFileHeader);
|
||||
return 0;
|
||||
}
|
122
PrefsSourceLib/XMLPrefsParser.h
Normal file
122
PrefsSourceLib/XMLPrefsParser.h
Normal file
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||||
* file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*
|
||||
*/
|
||||
/*
|
||||
File: XMLPrefsParser.h
|
||||
|
||||
Contains: A generic interface for pulling prefs.
|
||||
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __XML_PREFS_PARSER__
|
||||
#define __XML_PREFS_PARSER__
|
||||
|
||||
#include "OSFileSource.h"
|
||||
#include "OSQueue.h"
|
||||
#include "StringParser.h"
|
||||
#include "XMLParser.h"
|
||||
|
||||
typedef XMLTag* ContainerRef;
|
||||
|
||||
class XMLPrefsParser : public XMLParser
|
||||
{
|
||||
public:
|
||||
|
||||
XMLPrefsParser(char* inPath);
|
||||
~XMLPrefsParser();
|
||||
|
||||
//
|
||||
// Check for existence, man.
|
||||
|
||||
//
|
||||
// PARSE & WRITE THE FILE. Returns true if there was an error
|
||||
int Parse();
|
||||
|
||||
// Completely replaces old prefs file. Returns true if there was an error
|
||||
int WritePrefsFile();
|
||||
|
||||
//
|
||||
// ACCESSORS
|
||||
|
||||
ContainerRef GetRefForModule( char* inModuleName, Bool16 create = true);
|
||||
|
||||
ContainerRef GetRefForServer();
|
||||
|
||||
//
|
||||
// Returns the number of pref values for the pref at this index
|
||||
UInt32 GetNumPrefValues(ContainerRef pref);
|
||||
|
||||
//
|
||||
// Returns the number of prefs associated with this given module
|
||||
UInt32 GetNumPrefsByContainer(ContainerRef container);
|
||||
|
||||
//
|
||||
// Returns the pref value at the specfied location
|
||||
char* GetPrefValueByIndex(ContainerRef container, const UInt32 inPrefsIndex, const UInt32 inValueIndex,
|
||||
char** outPrefName, char** outDataType);
|
||||
|
||||
char* GetPrefValueByRef(ContainerRef pref, const UInt32 inValueIndex,
|
||||
char** outPrefName, char** outDataType);
|
||||
|
||||
ContainerRef GetObjectValue(ContainerRef pref, const UInt32 inValueIndex);
|
||||
|
||||
ContainerRef GetPrefRefByName( ContainerRef container,
|
||||
const char* inPrefName);
|
||||
|
||||
ContainerRef GetPrefRefByIndex( ContainerRef container,
|
||||
const UInt32 inPrefsIndex);
|
||||
|
||||
//
|
||||
// MODIFIERS
|
||||
|
||||
//
|
||||
// Creates a new pref. Returns the index of that pref. If pref already
|
||||
// exists, returns existing index.
|
||||
ContainerRef AddPref( ContainerRef container, char* inPrefName, char* inPrefDataType );
|
||||
|
||||
void ChangePrefType( ContainerRef pref, char* inNewPrefDataType);
|
||||
|
||||
void AddNewObject( ContainerRef pref );
|
||||
|
||||
void AddPrefValue( ContainerRef pref, char* inNewValue);
|
||||
|
||||
//
|
||||
// If this value index does not exist yet, and it is one higher than
|
||||
// the highest one, this function implictly adds the new value.
|
||||
void SetPrefValue( ContainerRef pref, const UInt32 inValueIndex,
|
||||
char* inNewValue);
|
||||
|
||||
//
|
||||
// Removes the pref entirely if # of values drops to 0
|
||||
void RemovePrefValue( ContainerRef pref, const UInt32 inValueIndex);
|
||||
|
||||
void RemovePref( ContainerRef pref );
|
||||
|
||||
private:
|
||||
|
||||
XMLTag* GetConfigurationTag();
|
||||
};
|
||||
|
||||
#endif //__XML_PREFS_PARSER__
|
Loading…
Add table
Add a link
Reference in a new issue