Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c5d6b83e4c |
617
mozilla/htmlparser/src/nsAVLTree.cpp
Normal file
617
mozilla/htmlparser/src/nsAVLTree.cpp
Normal file
@@ -0,0 +1,617 @@
|
||||
/* -*- Mode: C++; tab-width: 2; 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) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsAVLTree.h"
|
||||
|
||||
|
||||
enum eLean {eLeft,eNeutral,eRight};
|
||||
|
||||
struct NS_COM nsAVLNode {
|
||||
public:
|
||||
|
||||
nsAVLNode(void* aValue) {
|
||||
mLeft=0;
|
||||
mRight=0;
|
||||
mSkew=eNeutral;
|
||||
mValue=aValue;
|
||||
}
|
||||
|
||||
nsAVLNode* mLeft;
|
||||
nsAVLNode* mRight;
|
||||
eLean mSkew;
|
||||
void* mValue;
|
||||
};
|
||||
|
||||
|
||||
/************************************************************
|
||||
Now begin the tree class. Don't forget that the comparison
|
||||
between nodes must occur via the comparitor function,
|
||||
otherwise all you're testing is pointer addresses.
|
||||
************************************************************/
|
||||
|
||||
/** ------------------------------------------------
|
||||
*
|
||||
*
|
||||
* @update gess 4/22/98
|
||||
* @param
|
||||
* @return
|
||||
*/ //----------------------------------------------
|
||||
nsAVLTree::nsAVLTree(nsAVLNodeComparitor& aComparitor,
|
||||
nsAVLNodeFunctor* aDeallocator) :
|
||||
mComparitor(aComparitor), mDeallocator(aDeallocator) {
|
||||
mRoot=0;
|
||||
mCount=0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
avlDeleteTree(nsAVLNode* aNode){
|
||||
if (aNode) {
|
||||
avlDeleteTree(aNode->mLeft);
|
||||
avlDeleteTree(aNode->mRight);
|
||||
delete aNode;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess12/27/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsAVLTree::~nsAVLTree(){
|
||||
if (mDeallocator) {
|
||||
ForEachDepthFirst(*mDeallocator);
|
||||
}
|
||||
avlDeleteTree(mRoot);
|
||||
}
|
||||
|
||||
|
||||
class CDoesntExist: public nsAVLNodeFunctor {
|
||||
public:
|
||||
CDoesntExist(const nsAVLTree& anotherTree) : mOtherTree(anotherTree) {
|
||||
}
|
||||
virtual void* operator()(void* anItem) {
|
||||
void* result=mOtherTree.FindItem(anItem);
|
||||
if(result)
|
||||
return nsnull;
|
||||
return anItem;
|
||||
}
|
||||
protected:
|
||||
const nsAVLTree& mOtherTree;
|
||||
};
|
||||
|
||||
/**
|
||||
* This method compares two trees (members by identity).
|
||||
* @update gess12/27/98
|
||||
* @param tree to compare against
|
||||
* @return true if they are identical (contain same stuff).
|
||||
*/
|
||||
PRBool nsAVLTree::operator==(const nsAVLTree& aCopy) const{
|
||||
CDoesntExist functor(aCopy);
|
||||
void* theItem=FirstThat(functor);
|
||||
PRBool result=PRBool(!theItem);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess12/27/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
static void
|
||||
avlRotateRight(nsAVLNode*& aRootNode){
|
||||
nsAVLNode* ptr2;
|
||||
nsAVLNode* ptr3;
|
||||
|
||||
ptr2=aRootNode->mRight;
|
||||
if(ptr2->mSkew==eRight) {
|
||||
aRootNode->mRight=ptr2->mLeft;
|
||||
ptr2->mLeft=aRootNode;
|
||||
aRootNode->mSkew=eNeutral;
|
||||
aRootNode=ptr2;
|
||||
}
|
||||
else {
|
||||
ptr3=ptr2->mLeft;
|
||||
ptr2->mLeft=ptr3->mRight;
|
||||
ptr3->mRight=ptr2;
|
||||
aRootNode->mRight=ptr3->mLeft;
|
||||
ptr3->mLeft=aRootNode;
|
||||
if(ptr3->mSkew==eLeft)
|
||||
ptr2->mSkew=eRight;
|
||||
else ptr2->mSkew=eNeutral;
|
||||
if(ptr3->mSkew==eRight)
|
||||
aRootNode->mSkew=eLeft;
|
||||
else aRootNode->mSkew=eNeutral;
|
||||
aRootNode=ptr3;
|
||||
}
|
||||
aRootNode->mSkew=eNeutral;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess12/27/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
static void
|
||||
avlRotateLeft(nsAVLNode*& aRootNode){
|
||||
nsAVLNode* ptr2;
|
||||
nsAVLNode* ptr3;
|
||||
|
||||
ptr2=aRootNode->mLeft;
|
||||
if(ptr2->mSkew==eLeft) {
|
||||
aRootNode->mLeft=ptr2->mRight;
|
||||
ptr2->mRight=aRootNode;
|
||||
aRootNode->mSkew=eNeutral;
|
||||
aRootNode=ptr2;
|
||||
}
|
||||
else {
|
||||
ptr3=ptr2->mRight;
|
||||
ptr2->mRight=ptr3->mLeft;
|
||||
ptr3->mLeft=ptr2;
|
||||
aRootNode->mLeft=ptr3->mRight;
|
||||
ptr3->mRight=aRootNode;
|
||||
if(ptr3->mSkew==eRight)
|
||||
ptr2->mSkew=eLeft;
|
||||
else ptr2->mSkew=eNeutral;
|
||||
if(ptr3->mSkew==eLeft)
|
||||
aRootNode->mSkew=eRight;
|
||||
else aRootNode->mSkew=eNeutral;
|
||||
aRootNode=ptr3;
|
||||
}
|
||||
aRootNode->mSkew=eNeutral;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/** ------------------------------------------------
|
||||
*
|
||||
*
|
||||
* @update gess 4/22/98
|
||||
* @param
|
||||
* @return
|
||||
*/ //----------------------------------------------
|
||||
static eAVLStatus
|
||||
avlInsert(nsAVLNode*& aRootNode, nsAVLNode* aNewNode,
|
||||
nsAVLNodeComparitor& aComparitor) {
|
||||
eAVLStatus result=eAVL_unknown;
|
||||
|
||||
if(!aRootNode) {
|
||||
aRootNode = aNewNode;
|
||||
return eAVL_ok;
|
||||
}
|
||||
|
||||
if(aNewNode==aRootNode->mValue) {
|
||||
return eAVL_duplicate;
|
||||
}
|
||||
|
||||
PRInt32 theCompareResult=aComparitor(aRootNode->mValue,aNewNode->mValue);
|
||||
if(0 < theCompareResult) { //if(anItem<aRootNode->mValue)
|
||||
result=avlInsert(aRootNode->mLeft,aNewNode,aComparitor);
|
||||
if(eAVL_ok==result) {
|
||||
switch(aRootNode->mSkew){
|
||||
case eLeft:
|
||||
avlRotateLeft(aRootNode);
|
||||
result=eAVL_fail;
|
||||
break;
|
||||
case eRight:
|
||||
aRootNode->mSkew=eNeutral;
|
||||
result=eAVL_fail;
|
||||
break;
|
||||
case eNeutral:
|
||||
aRootNode->mSkew=eLeft;
|
||||
break;
|
||||
} //switch
|
||||
}//if
|
||||
} //if
|
||||
else {
|
||||
result=avlInsert(aRootNode->mRight,aNewNode,aComparitor);
|
||||
if(eAVL_ok==result) {
|
||||
switch(aRootNode->mSkew){
|
||||
case eLeft:
|
||||
aRootNode->mSkew=eNeutral;
|
||||
result=eAVL_fail;
|
||||
break;
|
||||
case eRight:
|
||||
avlRotateRight(aRootNode);
|
||||
result=eAVL_fail;
|
||||
break;
|
||||
case eNeutral:
|
||||
aRootNode->mSkew=eRight;
|
||||
break;
|
||||
} //switch
|
||||
}
|
||||
} //if
|
||||
return result;
|
||||
}
|
||||
|
||||
/** ------------------------------------------------
|
||||
*
|
||||
*
|
||||
* @update gess 4/22/98
|
||||
* @param
|
||||
* @return
|
||||
*/ //----------------------------------------------
|
||||
static void
|
||||
avlBalanceLeft(nsAVLNode*& aRootNode, PRBool& delOk){
|
||||
nsAVLNode* ptr2;
|
||||
nsAVLNode* ptr3;
|
||||
eLean balnc2;
|
||||
eLean balnc3;
|
||||
|
||||
switch(aRootNode->mSkew){
|
||||
case eLeft:
|
||||
ptr2=aRootNode->mLeft;
|
||||
balnc2=ptr2->mSkew;
|
||||
if(balnc2!=eRight) {
|
||||
aRootNode->mLeft=ptr2->mRight;
|
||||
ptr2->mRight=aRootNode;
|
||||
if(balnc2==eNeutral){
|
||||
aRootNode->mSkew=eLeft;
|
||||
ptr2->mSkew=eRight;
|
||||
delOk=PR_FALSE;
|
||||
}
|
||||
else{
|
||||
aRootNode->mSkew=eNeutral;
|
||||
ptr2->mSkew=eNeutral;
|
||||
}
|
||||
aRootNode=ptr2;
|
||||
}
|
||||
else{
|
||||
ptr3=ptr2->mRight;
|
||||
balnc3=ptr3->mSkew;
|
||||
ptr2->mRight=ptr3->mLeft;
|
||||
ptr3->mLeft=ptr2;
|
||||
aRootNode->mLeft=ptr3->mRight;
|
||||
ptr3->mRight=aRootNode;
|
||||
if(balnc3==eRight) {
|
||||
ptr2->mSkew=eLeft;
|
||||
}
|
||||
else {
|
||||
ptr2->mSkew=eNeutral;
|
||||
}
|
||||
if(balnc3==eLeft) {
|
||||
aRootNode->mSkew=eRight;
|
||||
}
|
||||
else {
|
||||
aRootNode->mSkew=eNeutral;
|
||||
}
|
||||
aRootNode=ptr3;
|
||||
ptr3->mSkew=eNeutral;
|
||||
}
|
||||
break;
|
||||
|
||||
case eRight:
|
||||
aRootNode->mSkew=eNeutral;
|
||||
break;
|
||||
|
||||
case eNeutral:
|
||||
aRootNode->mSkew=eLeft;
|
||||
delOk=PR_FALSE;
|
||||
break;
|
||||
}//switch
|
||||
return;
|
||||
}
|
||||
|
||||
/** ------------------------------------------------
|
||||
*
|
||||
*
|
||||
* @update gess 4/22/98
|
||||
* @param
|
||||
* @return
|
||||
*/ //----------------------------------------------
|
||||
static void
|
||||
avlBalanceRight(nsAVLNode*& aRootNode, PRBool& delOk){
|
||||
nsAVLNode* ptr2;
|
||||
nsAVLNode* ptr3;
|
||||
eLean balnc2;
|
||||
eLean balnc3;
|
||||
|
||||
switch(aRootNode->mSkew){
|
||||
case eLeft:
|
||||
aRootNode->mSkew=eNeutral;
|
||||
break;
|
||||
|
||||
case eRight:
|
||||
ptr2=aRootNode->mRight;
|
||||
balnc2=ptr2->mSkew;
|
||||
if(balnc2!=eLeft) {
|
||||
aRootNode->mRight=ptr2->mLeft;
|
||||
ptr2->mLeft=aRootNode;
|
||||
if(balnc2==eNeutral){
|
||||
aRootNode->mSkew=eRight;
|
||||
ptr2->mSkew=eLeft;
|
||||
delOk=PR_FALSE;
|
||||
}
|
||||
else{
|
||||
aRootNode->mSkew=eNeutral;
|
||||
ptr2->mSkew=eNeutral;
|
||||
}
|
||||
aRootNode=ptr2;
|
||||
}
|
||||
else{
|
||||
ptr3=ptr2->mLeft;
|
||||
balnc3=ptr3->mSkew;
|
||||
ptr2->mLeft=ptr3->mRight;
|
||||
ptr3->mRight=ptr2;
|
||||
aRootNode->mRight=ptr3->mLeft;
|
||||
ptr3->mLeft=aRootNode;
|
||||
if(balnc3==eLeft) {
|
||||
ptr2->mSkew=eRight;
|
||||
}
|
||||
else {
|
||||
ptr2->mSkew=eNeutral;
|
||||
}
|
||||
if(balnc3==eRight) {
|
||||
aRootNode->mSkew=eLeft;
|
||||
}
|
||||
else {
|
||||
aRootNode->mSkew=eNeutral;
|
||||
}
|
||||
aRootNode=ptr3;
|
||||
ptr3->mSkew=eNeutral;
|
||||
}
|
||||
break;
|
||||
|
||||
case eNeutral:
|
||||
aRootNode->mSkew=eRight;
|
||||
delOk=PR_FALSE;
|
||||
break;
|
||||
}//switch
|
||||
return;
|
||||
}
|
||||
|
||||
/** ------------------------------------------------
|
||||
*
|
||||
*
|
||||
* @update gess 4/22/98
|
||||
* @param
|
||||
* @return
|
||||
*/ //----------------------------------------------
|
||||
static eAVLStatus
|
||||
avlRemoveChildren(nsAVLNode*& aRootNode,nsAVLNode*& anotherNode, PRBool& delOk){
|
||||
eAVLStatus result=eAVL_ok;
|
||||
|
||||
if(!anotherNode->mRight){
|
||||
aRootNode->mValue=anotherNode->mValue; //swap
|
||||
anotherNode=anotherNode->mLeft;
|
||||
delOk=PR_TRUE;
|
||||
}
|
||||
else{
|
||||
avlRemoveChildren(aRootNode,anotherNode->mRight,delOk);
|
||||
if(delOk)
|
||||
avlBalanceLeft(anotherNode,delOk);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/** ------------------------------------------------
|
||||
*
|
||||
*
|
||||
* @update gess 4/22/98
|
||||
* @param
|
||||
* @return
|
||||
*/ //----------------------------------------------
|
||||
static eAVLStatus
|
||||
avlRemove(nsAVLNode*& aRootNode, void* anItem, PRBool& delOk,
|
||||
nsAVLNodeComparitor& aComparitor){
|
||||
eAVLStatus result=eAVL_ok;
|
||||
|
||||
if(!aRootNode)
|
||||
delOk=PR_FALSE;
|
||||
else {
|
||||
PRInt32 cmp=aComparitor(anItem,aRootNode->mValue);
|
||||
if(cmp<0){
|
||||
avlRemove(aRootNode->mLeft,anItem,delOk,aComparitor);
|
||||
if(delOk)
|
||||
avlBalanceRight(aRootNode,delOk);
|
||||
}
|
||||
else if(cmp>0){
|
||||
avlRemove(aRootNode->mRight,anItem,delOk,aComparitor);
|
||||
if(delOk)
|
||||
avlBalanceLeft(aRootNode,delOk);
|
||||
}
|
||||
else{ //they match...
|
||||
nsAVLNode* temp=aRootNode;
|
||||
if(!aRootNode->mRight) {
|
||||
aRootNode=aRootNode->mLeft;
|
||||
delOk=PR_TRUE;
|
||||
delete temp;
|
||||
}
|
||||
else if(!aRootNode->mLeft) {
|
||||
aRootNode=aRootNode->mRight;
|
||||
delOk=PR_TRUE;
|
||||
delete temp;
|
||||
}
|
||||
else {
|
||||
avlRemoveChildren(aRootNode,aRootNode->mLeft,delOk);
|
||||
if(delOk)
|
||||
avlBalanceRight(aRootNode,delOk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** ------------------------------------------------
|
||||
*
|
||||
*
|
||||
* @update gess 4/22/98
|
||||
* @param
|
||||
* @return
|
||||
*/ //----------------------------------------------
|
||||
eAVLStatus
|
||||
nsAVLTree::AddItem(void* anItem){
|
||||
eAVLStatus result=eAVL_ok;
|
||||
|
||||
nsAVLNode* theNewNode=new nsAVLNode(anItem);
|
||||
result=avlInsert(mRoot,theNewNode,mComparitor);
|
||||
if(eAVL_duplicate!=result)
|
||||
mCount++;
|
||||
else {
|
||||
delete theNewNode;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** ------------------------------------------------
|
||||
*
|
||||
*
|
||||
* @update gess 4/22/98
|
||||
* @param
|
||||
* @return
|
||||
*/ //----------------------------------------------
|
||||
void* nsAVLTree::FindItem(void* aValue) const{
|
||||
nsAVLNode* result=mRoot;
|
||||
PRInt32 count=0;
|
||||
while(result) {
|
||||
count++;
|
||||
PRInt32 cmp=mComparitor(aValue,result->mValue);
|
||||
if(0==cmp) {
|
||||
//we matched...
|
||||
break;
|
||||
}
|
||||
else if(0>cmp){
|
||||
//theNode was greater...
|
||||
result=result->mLeft;
|
||||
}
|
||||
else {
|
||||
//aValue is greater...
|
||||
result=result->mRight;
|
||||
}
|
||||
}
|
||||
if(result) {
|
||||
return result->mValue;
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess12/30/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
eAVLStatus
|
||||
nsAVLTree::RemoveItem(void* aValue){
|
||||
PRBool delOk=PR_TRUE;
|
||||
eAVLStatus result=avlRemove(mRoot,aValue,delOk,mComparitor);
|
||||
if(eAVL_ok==result)
|
||||
mCount--;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess9/11/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
static void
|
||||
avlForEachDepthFirst(nsAVLNode* aNode, nsAVLNodeFunctor& aFunctor){
|
||||
if(aNode) {
|
||||
avlForEachDepthFirst(aNode->mLeft,aFunctor);
|
||||
avlForEachDepthFirst(aNode->mRight,aFunctor);
|
||||
aFunctor(aNode->mValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess9/11/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void
|
||||
nsAVLTree::ForEachDepthFirst(nsAVLNodeFunctor& aFunctor) const{
|
||||
::avlForEachDepthFirst(mRoot,aFunctor);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess9/11/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
static void
|
||||
avlForEach(nsAVLNode* aNode, nsAVLNodeFunctor& aFunctor) {
|
||||
if(aNode) {
|
||||
avlForEach(aNode->mLeft,aFunctor);
|
||||
aFunctor(aNode->mValue);
|
||||
avlForEach(aNode->mRight,aFunctor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess9/11/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void
|
||||
nsAVLTree::ForEach(nsAVLNodeFunctor& aFunctor) const{
|
||||
::avlForEach(mRoot,aFunctor);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess9/11/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
static void*
|
||||
avlFirstThat(nsAVLNode* aNode, nsAVLNodeFunctor& aFunctor) {
|
||||
void* result=nsnull;
|
||||
if(aNode) {
|
||||
result = avlFirstThat(aNode->mLeft,aFunctor);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
result = aFunctor(aNode->mValue);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
result = avlFirstThat(aNode->mRight,aFunctor);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess9/11/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void*
|
||||
nsAVLTree::FirstThat(nsAVLNodeFunctor& aFunctor) const{
|
||||
return ::avlFirstThat(mRoot,aFunctor);
|
||||
}
|
||||
|
||||
74
mozilla/htmlparser/src/nsAVLTree.h
Normal file
74
mozilla/htmlparser/src/nsAVLTree.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/* -*- Mode: C++; tab-width: 2; 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) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsAVLTree_h___
|
||||
#define nsAVLTree_h___
|
||||
|
||||
|
||||
#include "nscore.h"
|
||||
|
||||
|
||||
enum eAVLStatus {eAVL_unknown,eAVL_ok,eAVL_fail,eAVL_duplicate};
|
||||
|
||||
|
||||
struct nsAVLNode;
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess12/26/98
|
||||
* @param anObject1 is the first object to be compared
|
||||
* @param anObject2 is the second object to be compared
|
||||
* @return -1,0,1 if object1 is less, equal, greater than object2
|
||||
*/
|
||||
class NS_COM nsAVLNodeComparitor {
|
||||
public:
|
||||
virtual PRInt32 operator()(void* anItem1,void* anItem2)=0;
|
||||
};
|
||||
|
||||
class NS_COM nsAVLNodeFunctor {
|
||||
public:
|
||||
virtual void* operator()(void* anItem)=0;
|
||||
};
|
||||
|
||||
class NS_COM nsAVLTree {
|
||||
public:
|
||||
nsAVLTree(nsAVLNodeComparitor& aComparitor, nsAVLNodeFunctor* aDeallocator);
|
||||
~nsAVLTree(void);
|
||||
|
||||
PRBool operator==(const nsAVLTree& aOther) const;
|
||||
PRInt32 GetCount(void) const {return mCount;}
|
||||
|
||||
//main functions...
|
||||
eAVLStatus AddItem(void* anItem);
|
||||
eAVLStatus RemoveItem(void* anItem);
|
||||
void* FindItem(void* anItem) const;
|
||||
void ForEach(nsAVLNodeFunctor& aFunctor) const;
|
||||
void ForEachDepthFirst(nsAVLNodeFunctor& aFunctor) const;
|
||||
void* FirstThat(nsAVLNodeFunctor& aFunctor) const;
|
||||
|
||||
protected:
|
||||
|
||||
nsAVLNode* mRoot;
|
||||
PRInt32 mCount;
|
||||
nsAVLNodeComparitor& mComparitor;
|
||||
nsAVLNodeFunctor* mDeallocator;
|
||||
};
|
||||
|
||||
|
||||
#endif /* nsAVLTree_h___ */
|
||||
|
||||
617
mozilla/parser/htmlparser/src/nsAVLTree.cpp
Normal file
617
mozilla/parser/htmlparser/src/nsAVLTree.cpp
Normal file
@@ -0,0 +1,617 @@
|
||||
/* -*- Mode: C++; tab-width: 2; 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) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsAVLTree.h"
|
||||
|
||||
|
||||
enum eLean {eLeft,eNeutral,eRight};
|
||||
|
||||
struct NS_COM nsAVLNode {
|
||||
public:
|
||||
|
||||
nsAVLNode(void* aValue) {
|
||||
mLeft=0;
|
||||
mRight=0;
|
||||
mSkew=eNeutral;
|
||||
mValue=aValue;
|
||||
}
|
||||
|
||||
nsAVLNode* mLeft;
|
||||
nsAVLNode* mRight;
|
||||
eLean mSkew;
|
||||
void* mValue;
|
||||
};
|
||||
|
||||
|
||||
/************************************************************
|
||||
Now begin the tree class. Don't forget that the comparison
|
||||
between nodes must occur via the comparitor function,
|
||||
otherwise all you're testing is pointer addresses.
|
||||
************************************************************/
|
||||
|
||||
/** ------------------------------------------------
|
||||
*
|
||||
*
|
||||
* @update gess 4/22/98
|
||||
* @param
|
||||
* @return
|
||||
*/ //----------------------------------------------
|
||||
nsAVLTree::nsAVLTree(nsAVLNodeComparitor& aComparitor,
|
||||
nsAVLNodeFunctor* aDeallocator) :
|
||||
mComparitor(aComparitor), mDeallocator(aDeallocator) {
|
||||
mRoot=0;
|
||||
mCount=0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
avlDeleteTree(nsAVLNode* aNode){
|
||||
if (aNode) {
|
||||
avlDeleteTree(aNode->mLeft);
|
||||
avlDeleteTree(aNode->mRight);
|
||||
delete aNode;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess12/27/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsAVLTree::~nsAVLTree(){
|
||||
if (mDeallocator) {
|
||||
ForEachDepthFirst(*mDeallocator);
|
||||
}
|
||||
avlDeleteTree(mRoot);
|
||||
}
|
||||
|
||||
|
||||
class CDoesntExist: public nsAVLNodeFunctor {
|
||||
public:
|
||||
CDoesntExist(const nsAVLTree& anotherTree) : mOtherTree(anotherTree) {
|
||||
}
|
||||
virtual void* operator()(void* anItem) {
|
||||
void* result=mOtherTree.FindItem(anItem);
|
||||
if(result)
|
||||
return nsnull;
|
||||
return anItem;
|
||||
}
|
||||
protected:
|
||||
const nsAVLTree& mOtherTree;
|
||||
};
|
||||
|
||||
/**
|
||||
* This method compares two trees (members by identity).
|
||||
* @update gess12/27/98
|
||||
* @param tree to compare against
|
||||
* @return true if they are identical (contain same stuff).
|
||||
*/
|
||||
PRBool nsAVLTree::operator==(const nsAVLTree& aCopy) const{
|
||||
CDoesntExist functor(aCopy);
|
||||
void* theItem=FirstThat(functor);
|
||||
PRBool result=PRBool(!theItem);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess12/27/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
static void
|
||||
avlRotateRight(nsAVLNode*& aRootNode){
|
||||
nsAVLNode* ptr2;
|
||||
nsAVLNode* ptr3;
|
||||
|
||||
ptr2=aRootNode->mRight;
|
||||
if(ptr2->mSkew==eRight) {
|
||||
aRootNode->mRight=ptr2->mLeft;
|
||||
ptr2->mLeft=aRootNode;
|
||||
aRootNode->mSkew=eNeutral;
|
||||
aRootNode=ptr2;
|
||||
}
|
||||
else {
|
||||
ptr3=ptr2->mLeft;
|
||||
ptr2->mLeft=ptr3->mRight;
|
||||
ptr3->mRight=ptr2;
|
||||
aRootNode->mRight=ptr3->mLeft;
|
||||
ptr3->mLeft=aRootNode;
|
||||
if(ptr3->mSkew==eLeft)
|
||||
ptr2->mSkew=eRight;
|
||||
else ptr2->mSkew=eNeutral;
|
||||
if(ptr3->mSkew==eRight)
|
||||
aRootNode->mSkew=eLeft;
|
||||
else aRootNode->mSkew=eNeutral;
|
||||
aRootNode=ptr3;
|
||||
}
|
||||
aRootNode->mSkew=eNeutral;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess12/27/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
static void
|
||||
avlRotateLeft(nsAVLNode*& aRootNode){
|
||||
nsAVLNode* ptr2;
|
||||
nsAVLNode* ptr3;
|
||||
|
||||
ptr2=aRootNode->mLeft;
|
||||
if(ptr2->mSkew==eLeft) {
|
||||
aRootNode->mLeft=ptr2->mRight;
|
||||
ptr2->mRight=aRootNode;
|
||||
aRootNode->mSkew=eNeutral;
|
||||
aRootNode=ptr2;
|
||||
}
|
||||
else {
|
||||
ptr3=ptr2->mRight;
|
||||
ptr2->mRight=ptr3->mLeft;
|
||||
ptr3->mLeft=ptr2;
|
||||
aRootNode->mLeft=ptr3->mRight;
|
||||
ptr3->mRight=aRootNode;
|
||||
if(ptr3->mSkew==eRight)
|
||||
ptr2->mSkew=eLeft;
|
||||
else ptr2->mSkew=eNeutral;
|
||||
if(ptr3->mSkew==eLeft)
|
||||
aRootNode->mSkew=eRight;
|
||||
else aRootNode->mSkew=eNeutral;
|
||||
aRootNode=ptr3;
|
||||
}
|
||||
aRootNode->mSkew=eNeutral;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/** ------------------------------------------------
|
||||
*
|
||||
*
|
||||
* @update gess 4/22/98
|
||||
* @param
|
||||
* @return
|
||||
*/ //----------------------------------------------
|
||||
static eAVLStatus
|
||||
avlInsert(nsAVLNode*& aRootNode, nsAVLNode* aNewNode,
|
||||
nsAVLNodeComparitor& aComparitor) {
|
||||
eAVLStatus result=eAVL_unknown;
|
||||
|
||||
if(!aRootNode) {
|
||||
aRootNode = aNewNode;
|
||||
return eAVL_ok;
|
||||
}
|
||||
|
||||
if(aNewNode==aRootNode->mValue) {
|
||||
return eAVL_duplicate;
|
||||
}
|
||||
|
||||
PRInt32 theCompareResult=aComparitor(aRootNode->mValue,aNewNode->mValue);
|
||||
if(0 < theCompareResult) { //if(anItem<aRootNode->mValue)
|
||||
result=avlInsert(aRootNode->mLeft,aNewNode,aComparitor);
|
||||
if(eAVL_ok==result) {
|
||||
switch(aRootNode->mSkew){
|
||||
case eLeft:
|
||||
avlRotateLeft(aRootNode);
|
||||
result=eAVL_fail;
|
||||
break;
|
||||
case eRight:
|
||||
aRootNode->mSkew=eNeutral;
|
||||
result=eAVL_fail;
|
||||
break;
|
||||
case eNeutral:
|
||||
aRootNode->mSkew=eLeft;
|
||||
break;
|
||||
} //switch
|
||||
}//if
|
||||
} //if
|
||||
else {
|
||||
result=avlInsert(aRootNode->mRight,aNewNode,aComparitor);
|
||||
if(eAVL_ok==result) {
|
||||
switch(aRootNode->mSkew){
|
||||
case eLeft:
|
||||
aRootNode->mSkew=eNeutral;
|
||||
result=eAVL_fail;
|
||||
break;
|
||||
case eRight:
|
||||
avlRotateRight(aRootNode);
|
||||
result=eAVL_fail;
|
||||
break;
|
||||
case eNeutral:
|
||||
aRootNode->mSkew=eRight;
|
||||
break;
|
||||
} //switch
|
||||
}
|
||||
} //if
|
||||
return result;
|
||||
}
|
||||
|
||||
/** ------------------------------------------------
|
||||
*
|
||||
*
|
||||
* @update gess 4/22/98
|
||||
* @param
|
||||
* @return
|
||||
*/ //----------------------------------------------
|
||||
static void
|
||||
avlBalanceLeft(nsAVLNode*& aRootNode, PRBool& delOk){
|
||||
nsAVLNode* ptr2;
|
||||
nsAVLNode* ptr3;
|
||||
eLean balnc2;
|
||||
eLean balnc3;
|
||||
|
||||
switch(aRootNode->mSkew){
|
||||
case eLeft:
|
||||
ptr2=aRootNode->mLeft;
|
||||
balnc2=ptr2->mSkew;
|
||||
if(balnc2!=eRight) {
|
||||
aRootNode->mLeft=ptr2->mRight;
|
||||
ptr2->mRight=aRootNode;
|
||||
if(balnc2==eNeutral){
|
||||
aRootNode->mSkew=eLeft;
|
||||
ptr2->mSkew=eRight;
|
||||
delOk=PR_FALSE;
|
||||
}
|
||||
else{
|
||||
aRootNode->mSkew=eNeutral;
|
||||
ptr2->mSkew=eNeutral;
|
||||
}
|
||||
aRootNode=ptr2;
|
||||
}
|
||||
else{
|
||||
ptr3=ptr2->mRight;
|
||||
balnc3=ptr3->mSkew;
|
||||
ptr2->mRight=ptr3->mLeft;
|
||||
ptr3->mLeft=ptr2;
|
||||
aRootNode->mLeft=ptr3->mRight;
|
||||
ptr3->mRight=aRootNode;
|
||||
if(balnc3==eRight) {
|
||||
ptr2->mSkew=eLeft;
|
||||
}
|
||||
else {
|
||||
ptr2->mSkew=eNeutral;
|
||||
}
|
||||
if(balnc3==eLeft) {
|
||||
aRootNode->mSkew=eRight;
|
||||
}
|
||||
else {
|
||||
aRootNode->mSkew=eNeutral;
|
||||
}
|
||||
aRootNode=ptr3;
|
||||
ptr3->mSkew=eNeutral;
|
||||
}
|
||||
break;
|
||||
|
||||
case eRight:
|
||||
aRootNode->mSkew=eNeutral;
|
||||
break;
|
||||
|
||||
case eNeutral:
|
||||
aRootNode->mSkew=eLeft;
|
||||
delOk=PR_FALSE;
|
||||
break;
|
||||
}//switch
|
||||
return;
|
||||
}
|
||||
|
||||
/** ------------------------------------------------
|
||||
*
|
||||
*
|
||||
* @update gess 4/22/98
|
||||
* @param
|
||||
* @return
|
||||
*/ //----------------------------------------------
|
||||
static void
|
||||
avlBalanceRight(nsAVLNode*& aRootNode, PRBool& delOk){
|
||||
nsAVLNode* ptr2;
|
||||
nsAVLNode* ptr3;
|
||||
eLean balnc2;
|
||||
eLean balnc3;
|
||||
|
||||
switch(aRootNode->mSkew){
|
||||
case eLeft:
|
||||
aRootNode->mSkew=eNeutral;
|
||||
break;
|
||||
|
||||
case eRight:
|
||||
ptr2=aRootNode->mRight;
|
||||
balnc2=ptr2->mSkew;
|
||||
if(balnc2!=eLeft) {
|
||||
aRootNode->mRight=ptr2->mLeft;
|
||||
ptr2->mLeft=aRootNode;
|
||||
if(balnc2==eNeutral){
|
||||
aRootNode->mSkew=eRight;
|
||||
ptr2->mSkew=eLeft;
|
||||
delOk=PR_FALSE;
|
||||
}
|
||||
else{
|
||||
aRootNode->mSkew=eNeutral;
|
||||
ptr2->mSkew=eNeutral;
|
||||
}
|
||||
aRootNode=ptr2;
|
||||
}
|
||||
else{
|
||||
ptr3=ptr2->mLeft;
|
||||
balnc3=ptr3->mSkew;
|
||||
ptr2->mLeft=ptr3->mRight;
|
||||
ptr3->mRight=ptr2;
|
||||
aRootNode->mRight=ptr3->mLeft;
|
||||
ptr3->mLeft=aRootNode;
|
||||
if(balnc3==eLeft) {
|
||||
ptr2->mSkew=eRight;
|
||||
}
|
||||
else {
|
||||
ptr2->mSkew=eNeutral;
|
||||
}
|
||||
if(balnc3==eRight) {
|
||||
aRootNode->mSkew=eLeft;
|
||||
}
|
||||
else {
|
||||
aRootNode->mSkew=eNeutral;
|
||||
}
|
||||
aRootNode=ptr3;
|
||||
ptr3->mSkew=eNeutral;
|
||||
}
|
||||
break;
|
||||
|
||||
case eNeutral:
|
||||
aRootNode->mSkew=eRight;
|
||||
delOk=PR_FALSE;
|
||||
break;
|
||||
}//switch
|
||||
return;
|
||||
}
|
||||
|
||||
/** ------------------------------------------------
|
||||
*
|
||||
*
|
||||
* @update gess 4/22/98
|
||||
* @param
|
||||
* @return
|
||||
*/ //----------------------------------------------
|
||||
static eAVLStatus
|
||||
avlRemoveChildren(nsAVLNode*& aRootNode,nsAVLNode*& anotherNode, PRBool& delOk){
|
||||
eAVLStatus result=eAVL_ok;
|
||||
|
||||
if(!anotherNode->mRight){
|
||||
aRootNode->mValue=anotherNode->mValue; //swap
|
||||
anotherNode=anotherNode->mLeft;
|
||||
delOk=PR_TRUE;
|
||||
}
|
||||
else{
|
||||
avlRemoveChildren(aRootNode,anotherNode->mRight,delOk);
|
||||
if(delOk)
|
||||
avlBalanceLeft(anotherNode,delOk);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/** ------------------------------------------------
|
||||
*
|
||||
*
|
||||
* @update gess 4/22/98
|
||||
* @param
|
||||
* @return
|
||||
*/ //----------------------------------------------
|
||||
static eAVLStatus
|
||||
avlRemove(nsAVLNode*& aRootNode, void* anItem, PRBool& delOk,
|
||||
nsAVLNodeComparitor& aComparitor){
|
||||
eAVLStatus result=eAVL_ok;
|
||||
|
||||
if(!aRootNode)
|
||||
delOk=PR_FALSE;
|
||||
else {
|
||||
PRInt32 cmp=aComparitor(anItem,aRootNode->mValue);
|
||||
if(cmp<0){
|
||||
avlRemove(aRootNode->mLeft,anItem,delOk,aComparitor);
|
||||
if(delOk)
|
||||
avlBalanceRight(aRootNode,delOk);
|
||||
}
|
||||
else if(cmp>0){
|
||||
avlRemove(aRootNode->mRight,anItem,delOk,aComparitor);
|
||||
if(delOk)
|
||||
avlBalanceLeft(aRootNode,delOk);
|
||||
}
|
||||
else{ //they match...
|
||||
nsAVLNode* temp=aRootNode;
|
||||
if(!aRootNode->mRight) {
|
||||
aRootNode=aRootNode->mLeft;
|
||||
delOk=PR_TRUE;
|
||||
delete temp;
|
||||
}
|
||||
else if(!aRootNode->mLeft) {
|
||||
aRootNode=aRootNode->mRight;
|
||||
delOk=PR_TRUE;
|
||||
delete temp;
|
||||
}
|
||||
else {
|
||||
avlRemoveChildren(aRootNode,aRootNode->mLeft,delOk);
|
||||
if(delOk)
|
||||
avlBalanceRight(aRootNode,delOk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** ------------------------------------------------
|
||||
*
|
||||
*
|
||||
* @update gess 4/22/98
|
||||
* @param
|
||||
* @return
|
||||
*/ //----------------------------------------------
|
||||
eAVLStatus
|
||||
nsAVLTree::AddItem(void* anItem){
|
||||
eAVLStatus result=eAVL_ok;
|
||||
|
||||
nsAVLNode* theNewNode=new nsAVLNode(anItem);
|
||||
result=avlInsert(mRoot,theNewNode,mComparitor);
|
||||
if(eAVL_duplicate!=result)
|
||||
mCount++;
|
||||
else {
|
||||
delete theNewNode;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** ------------------------------------------------
|
||||
*
|
||||
*
|
||||
* @update gess 4/22/98
|
||||
* @param
|
||||
* @return
|
||||
*/ //----------------------------------------------
|
||||
void* nsAVLTree::FindItem(void* aValue) const{
|
||||
nsAVLNode* result=mRoot;
|
||||
PRInt32 count=0;
|
||||
while(result) {
|
||||
count++;
|
||||
PRInt32 cmp=mComparitor(aValue,result->mValue);
|
||||
if(0==cmp) {
|
||||
//we matched...
|
||||
break;
|
||||
}
|
||||
else if(0>cmp){
|
||||
//theNode was greater...
|
||||
result=result->mLeft;
|
||||
}
|
||||
else {
|
||||
//aValue is greater...
|
||||
result=result->mRight;
|
||||
}
|
||||
}
|
||||
if(result) {
|
||||
return result->mValue;
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess12/30/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
eAVLStatus
|
||||
nsAVLTree::RemoveItem(void* aValue){
|
||||
PRBool delOk=PR_TRUE;
|
||||
eAVLStatus result=avlRemove(mRoot,aValue,delOk,mComparitor);
|
||||
if(eAVL_ok==result)
|
||||
mCount--;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess9/11/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
static void
|
||||
avlForEachDepthFirst(nsAVLNode* aNode, nsAVLNodeFunctor& aFunctor){
|
||||
if(aNode) {
|
||||
avlForEachDepthFirst(aNode->mLeft,aFunctor);
|
||||
avlForEachDepthFirst(aNode->mRight,aFunctor);
|
||||
aFunctor(aNode->mValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess9/11/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void
|
||||
nsAVLTree::ForEachDepthFirst(nsAVLNodeFunctor& aFunctor) const{
|
||||
::avlForEachDepthFirst(mRoot,aFunctor);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess9/11/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
static void
|
||||
avlForEach(nsAVLNode* aNode, nsAVLNodeFunctor& aFunctor) {
|
||||
if(aNode) {
|
||||
avlForEach(aNode->mLeft,aFunctor);
|
||||
aFunctor(aNode->mValue);
|
||||
avlForEach(aNode->mRight,aFunctor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess9/11/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void
|
||||
nsAVLTree::ForEach(nsAVLNodeFunctor& aFunctor) const{
|
||||
::avlForEach(mRoot,aFunctor);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess9/11/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
static void*
|
||||
avlFirstThat(nsAVLNode* aNode, nsAVLNodeFunctor& aFunctor) {
|
||||
void* result=nsnull;
|
||||
if(aNode) {
|
||||
result = avlFirstThat(aNode->mLeft,aFunctor);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
result = aFunctor(aNode->mValue);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
result = avlFirstThat(aNode->mRight,aFunctor);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess9/11/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void*
|
||||
nsAVLTree::FirstThat(nsAVLNodeFunctor& aFunctor) const{
|
||||
return ::avlFirstThat(mRoot,aFunctor);
|
||||
}
|
||||
|
||||
74
mozilla/parser/htmlparser/src/nsAVLTree.h
Normal file
74
mozilla/parser/htmlparser/src/nsAVLTree.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/* -*- Mode: C++; tab-width: 2; 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) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsAVLTree_h___
|
||||
#define nsAVLTree_h___
|
||||
|
||||
|
||||
#include "nscore.h"
|
||||
|
||||
|
||||
enum eAVLStatus {eAVL_unknown,eAVL_ok,eAVL_fail,eAVL_duplicate};
|
||||
|
||||
|
||||
struct nsAVLNode;
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess12/26/98
|
||||
* @param anObject1 is the first object to be compared
|
||||
* @param anObject2 is the second object to be compared
|
||||
* @return -1,0,1 if object1 is less, equal, greater than object2
|
||||
*/
|
||||
class NS_COM nsAVLNodeComparitor {
|
||||
public:
|
||||
virtual PRInt32 operator()(void* anItem1,void* anItem2)=0;
|
||||
};
|
||||
|
||||
class NS_COM nsAVLNodeFunctor {
|
||||
public:
|
||||
virtual void* operator()(void* anItem)=0;
|
||||
};
|
||||
|
||||
class NS_COM nsAVLTree {
|
||||
public:
|
||||
nsAVLTree(nsAVLNodeComparitor& aComparitor, nsAVLNodeFunctor* aDeallocator);
|
||||
~nsAVLTree(void);
|
||||
|
||||
PRBool operator==(const nsAVLTree& aOther) const;
|
||||
PRInt32 GetCount(void) const {return mCount;}
|
||||
|
||||
//main functions...
|
||||
eAVLStatus AddItem(void* anItem);
|
||||
eAVLStatus RemoveItem(void* anItem);
|
||||
void* FindItem(void* anItem) const;
|
||||
void ForEach(nsAVLNodeFunctor& aFunctor) const;
|
||||
void ForEachDepthFirst(nsAVLNodeFunctor& aFunctor) const;
|
||||
void* FirstThat(nsAVLNodeFunctor& aFunctor) const;
|
||||
|
||||
protected:
|
||||
|
||||
nsAVLNode* mRoot;
|
||||
PRInt32 mCount;
|
||||
nsAVLNodeComparitor& mComparitor;
|
||||
nsAVLNodeFunctor* mDeallocator;
|
||||
};
|
||||
|
||||
|
||||
#endif /* nsAVLTree_h___ */
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
#! gmake
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is the Netscape security libraries.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU General Public License Version 2 or later (the
|
||||
# "GPL"), in which case the provisions of the GPL are applicable
|
||||
# instead of those above. If you wish to allow use of your
|
||||
# version of this file only under the terms of the GPL and not to
|
||||
# allow others to use your version of this file under the MPL,
|
||||
# indicate your decision by deleting the provisions above and
|
||||
# replace them with the notice and other provisions required by
|
||||
# the GPL. If you do not delete the provisions above, a recipient
|
||||
# may use your version of this file under either the MPL or the
|
||||
# GPL.
|
||||
#
|
||||
|
||||
#######################################################################
|
||||
# (1) Include initial platform-independent assignments (MANDATORY). #
|
||||
#######################################################################
|
||||
|
||||
include manifest.mn
|
||||
|
||||
#######################################################################
|
||||
# (2) Include "global" configuration information. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
include $(CORE_DEPTH)/coreconf/config.mk
|
||||
|
||||
#######################################################################
|
||||
# (3) Include "component" configuration information. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
|
||||
#######################################################################
|
||||
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (5) Execute "global" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
include $(CORE_DEPTH)/coreconf/rules.mk
|
||||
|
||||
#######################################################################
|
||||
# (6) Execute "component" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (7) Execute "local" rules. (OPTIONAL). #
|
||||
#######################################################################
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
DIRS = protocol client
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
cmtclist.h
|
||||
cmtcmn.h
|
||||
cmtjs.h
|
||||
@@ -1,74 +0,0 @@
|
||||
#! gmake
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is the Netscape security libraries.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU General Public License Version 2 or later (the
|
||||
# "GPL"), in which case the provisions of the GPL are applicable
|
||||
# instead of those above. If you wish to allow use of your
|
||||
# version of this file only under the terms of the GPL and not to
|
||||
# allow others to use your version of this file under the MPL,
|
||||
# indicate your decision by deleting the provisions above and
|
||||
# replace them with the notice and other provisions required by
|
||||
# the GPL. If you do not delete the provisions above, a recipient
|
||||
# may use your version of this file under either the MPL or the
|
||||
# GPL.
|
||||
#
|
||||
|
||||
#######################################################################
|
||||
# (1) Include initial platform-independent assignments (MANDATORY). #
|
||||
#######################################################################
|
||||
|
||||
include manifest.mn
|
||||
|
||||
#######################################################################
|
||||
# (2) Include "global" configuration information. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
include $(CORE_DEPTH)/coreconf/config.mk
|
||||
|
||||
#######################################################################
|
||||
# (3) Include "component" configuration information. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
|
||||
#######################################################################
|
||||
include config.mk
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (5) Execute "global" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
include $(CORE_DEPTH)/coreconf/rules.mk
|
||||
|
||||
#######################################################################
|
||||
# (6) Execute "component" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (7) Execute "local" rules. (OPTIONAL). #
|
||||
#######################################################################
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
#! gmake
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is the Netscape security libraries.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU General Public License Version 2 or later (the
|
||||
# "GPL"), in which case the provisions of the GPL are applicable
|
||||
# instead of those above. If you wish to allow use of your
|
||||
# version of this file only under the terms of the GPL and not to
|
||||
# allow others to use your version of this file under the MPL,
|
||||
# indicate your decision by deleting the provisions above and
|
||||
# replace them with the notice and other provisions required by
|
||||
# the GPL. If you do not delete the provisions above, a recipient
|
||||
# may use your version of this file under either the MPL or the
|
||||
# GPL.
|
||||
#
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
LIBRARY_NAME = cmt
|
||||
|
||||
EXPORTS = \
|
||||
cmtcmn.h \
|
||||
cmtjs.h \
|
||||
cmtclist.h \
|
||||
$(NULL)
|
||||
|
||||
MODULE = security
|
||||
|
||||
CSRCS = cmtinit.c \
|
||||
cmtssl.c \
|
||||
cmtutils.c \
|
||||
cmtcert.c \
|
||||
cmthash.c \
|
||||
cmtpkcs7.c \
|
||||
cmtres.c \
|
||||
cmtjs.c \
|
||||
cmtevent.c \
|
||||
cmtpasswd.c \
|
||||
cmtadvisor.c \
|
||||
cmtrng.c \
|
||||
cmtsdr.c \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DSO_LDOPTS += -L$(DIST)/bin -lprotocol
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "cmtcmn.h"
|
||||
#include "cmtutils.h"
|
||||
#include "messages.h"
|
||||
#ifdef XP_MAC
|
||||
#include "cmtmac.h"
|
||||
#endif
|
||||
|
||||
CMTStatus CMT_SecurityAdvisor(PCMT_CONTROL control, CMTSecurityAdvisorData* data, CMUint32 *resID)
|
||||
{
|
||||
CMTItem message = {0, NULL, 0};
|
||||
SecurityAdvisorRequest request;
|
||||
SingleNumMessage reply;
|
||||
|
||||
if (!control) {
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
if (!data) {
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
request.infoContext = data->infoContext;
|
||||
request.resID = data->resID;
|
||||
request.hostname = data->hostname;
|
||||
request.senderAddr = data->senderAddr;
|
||||
request.encryptedP7CInfo = data->encryptedP7CInfo;
|
||||
request.signedP7CInfo = data->signedP7CInfo;
|
||||
request.decodeError = data->decodeError;
|
||||
request.verifyError = data->verifyError;
|
||||
request.encryptthis = data->encryptthis;
|
||||
request.signthis = data->signthis;
|
||||
request.numRecipients = data->numRecipients;
|
||||
request.recipients = data->recipients;
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_SECURITY_ADVISOR;
|
||||
|
||||
if (CMT_EncodeMessage(SecurityAdvisorRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Send the message and get the response */
|
||||
if (CMT_SendMessage(control, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_SECURITY_ADVISOR)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the message */
|
||||
if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
*resID = reply.value;
|
||||
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
|
||||
if (message.data) {
|
||||
free(message.data);
|
||||
}
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,111 +0,0 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef cmtclist_h___
|
||||
#define cmtclist_h___
|
||||
|
||||
typedef struct CMTCListStr CMTCList;
|
||||
/*
|
||||
** Circular linked list
|
||||
*/
|
||||
struct CMTCListStr {
|
||||
CMTCList *next;
|
||||
CMTCList *prev;
|
||||
};
|
||||
|
||||
/*
|
||||
** Insert element "_e" into the list, before "_l".
|
||||
*/
|
||||
#define CMT_INSERT_BEFORE(_e,_l) \
|
||||
(_e)->next = (_l); \
|
||||
(_e)->prev = (_l)->prev; \
|
||||
(_l)->prev->next = (_e); \
|
||||
(_l)->prev = (_e); \
|
||||
|
||||
/*
|
||||
** Insert element "_e" into the list, after "_l".
|
||||
*/
|
||||
#define CMT_INSERT_AFTER(_e,_l) \
|
||||
(_e)->next = (_l)->next; \
|
||||
(_e)->prev = (_l); \
|
||||
(_l)->next->prev = (_e); \
|
||||
(_l)->next = (_e); \
|
||||
|
||||
/*
|
||||
** Append an element "_e" to the end of the list "_l"
|
||||
*/
|
||||
#define CMT_APPEND_LINK(_e,_l) CMT_INSERT_BEFORE(_e,_l)
|
||||
|
||||
/*
|
||||
** Insert an element "_e" at the head of the list "_l"
|
||||
*/
|
||||
#define CMT_INSERT_LINK(_e,_l) CMT_INSERT_AFTER(_e,_l)
|
||||
|
||||
/* Return the head/tail of the list */
|
||||
#define CMT_LIST_HEAD(_l) (_l)->next
|
||||
#define CMT_LIST_TAIL(_l) (_l)->prev
|
||||
|
||||
/*
|
||||
** Remove the element "_e" from it's circular list.
|
||||
*/
|
||||
#define CMT_REMOVE_LINK(_e) \
|
||||
(_e)->prev->next = (_e)->next; \
|
||||
(_e)->next->prev = (_e)->prev; \
|
||||
|
||||
/*
|
||||
** Remove the element "_e" from it's circular list. Also initializes the
|
||||
** linkage.
|
||||
*/
|
||||
#define CMT_REMOVE_AND_INIT_LINK(_e) \
|
||||
(_e)->prev->next = (_e)->next; \
|
||||
(_e)->next->prev = (_e)->prev; \
|
||||
(_e)->next = (_e); \
|
||||
(_e)->prev = (_e); \
|
||||
|
||||
/*
|
||||
** Return non-zero if the given circular list "_l" is empty, zero if the
|
||||
** circular list is not empty
|
||||
*/
|
||||
#define CMT_CLIST_IS_EMPTY(_l) \
|
||||
((_l)->next == (_l))
|
||||
|
||||
/*
|
||||
** Initialize a circular list
|
||||
*/
|
||||
#define CMT_INIT_CLIST(_l) \
|
||||
(_l)->next = (_l); \
|
||||
(_l)->prev = (_l); \
|
||||
|
||||
#define CMT_INIT_STATIC_CLIST(_l) \
|
||||
{(_l), (_l)}
|
||||
|
||||
#endif /* cmtclist_h___ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,480 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "cmtcmn.h"
|
||||
#include "cmtutils.h"
|
||||
#include "messages.h"
|
||||
#include <string.h>
|
||||
#ifdef XP_UNIX
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
/* Typedefs */
|
||||
typedef void (*taskcompleted_handler_fn)(CMUint32 resourceID, CMUint32 numReqProcessed, CMUint32 resultCode, void* data);
|
||||
|
||||
CMTStatus CMT_SetUIHandlerCallback(PCMT_CONTROL control,
|
||||
uiHandlerCallback_fn f, void *data)
|
||||
{
|
||||
return CMT_RegisterEventHandler(control, SSM_UI_EVENT, 0,
|
||||
(void_fun)f, data);
|
||||
}
|
||||
|
||||
void CMT_SetFilePathPromptCallback(PCMT_CONTROL control,
|
||||
filePathPromptCallback_fn f, void* arg)
|
||||
{
|
||||
control->userFuncs.promptFilePath = f;
|
||||
control->userFuncs.filePromptArg = arg;
|
||||
}
|
||||
|
||||
void CMT_SetPromptCallback(PCMT_CONTROL control,
|
||||
promptCallback_fn f, void *arg)
|
||||
{
|
||||
control->userFuncs.promptCallback = f;
|
||||
control->userFuncs.promptArg = arg;
|
||||
}
|
||||
|
||||
void CMT_SetSavePrefsCallback(PCMT_CONTROL control, savePrefsCallback_fn f)
|
||||
{
|
||||
control->userFuncs.savePrefs = f;
|
||||
}
|
||||
|
||||
CMTStatus CMT_RegisterEventHandler(PCMT_CONTROL control, CMUint32 type,
|
||||
CMUint32 resourceID, void_fun handler,
|
||||
void* data)
|
||||
{
|
||||
PCMT_EVENT ptr;
|
||||
|
||||
/* This is the first connection */
|
||||
if (control->cmtEventHandlers == NULL) {
|
||||
control->cmtEventHandlers = ptr =
|
||||
(PCMT_EVENT)calloc(sizeof(CMT_EVENT), 1);
|
||||
if (!ptr) {
|
||||
goto loser;
|
||||
}
|
||||
} else {
|
||||
/* Look for another event handler of the same type. Make sure the
|
||||
event handler with a rsrcid of 0 is farther down the list so
|
||||
that it doesn't get chosen when there's an event handler for
|
||||
a specific rsrcid.
|
||||
*/
|
||||
for (ptr=control->cmtEventHandlers; ptr != NULL; ptr = ptr->next) {
|
||||
if (ptr->type == type && resourceID != 0) {
|
||||
/* So we've got an event handler that wants to over-ride
|
||||
an existing event handler. We'll put it before the one
|
||||
that's already here.
|
||||
*/
|
||||
if (ptr->previous == NULL) {
|
||||
/* We're going to insert at the front of the list*/
|
||||
control->cmtEventHandlers = ptr->previous =
|
||||
(PCMT_EVENT)calloc(sizeof(CMT_EVENT), 1);
|
||||
if (ptr->previous == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
ptr->previous->next = ptr;
|
||||
ptr = control->cmtEventHandlers;
|
||||
} else {
|
||||
/* We want to insert in the middle of the list */
|
||||
PCMT_EVENT tmpEvent;
|
||||
|
||||
tmpEvent = (PCMT_EVENT)calloc(sizeof(CMT_EVENT), 1);
|
||||
if (tmpEvent == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
tmpEvent->previous = ptr->previous;
|
||||
ptr->previous->next = tmpEvent;
|
||||
tmpEvent->next = ptr;
|
||||
ptr->previous = tmpEvent;
|
||||
ptr = tmpEvent;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (ptr->next == NULL) break;
|
||||
}
|
||||
if (ptr == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
if (ptr->next == NULL) {
|
||||
/* We're adding the event handler at the end of the list. */
|
||||
ptr->next = (PCMT_EVENT)calloc(sizeof(CMT_EVENT), 1);
|
||||
if (!ptr->next) {
|
||||
goto loser;
|
||||
}
|
||||
/* Fix up the pointers */
|
||||
ptr->next->previous = ptr;
|
||||
ptr = ptr->next;
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill in the data */
|
||||
ptr->type = type;
|
||||
ptr->resourceID = resourceID;
|
||||
ptr->handler = handler;
|
||||
ptr->data = data;
|
||||
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_UnregisterEventHandler(PCMT_CONTROL control, CMUint32 type,
|
||||
CMUint32 resourceID)
|
||||
{
|
||||
PCMT_EVENT ptr, pptr = NULL;
|
||||
|
||||
for (ptr = control->cmtEventHandlers; ptr != NULL;
|
||||
pptr = ptr, ptr = ptr->next) {
|
||||
if ((ptr->type == type) && (ptr->resourceID == resourceID)) {
|
||||
if (pptr == NULL) {
|
||||
/* node is at head */
|
||||
control->cmtEventHandlers = ptr->next;
|
||||
if (control->cmtEventHandlers != NULL) {
|
||||
control->cmtEventHandlers->previous = NULL;
|
||||
}
|
||||
free(ptr);
|
||||
return CMTSuccess;
|
||||
}
|
||||
/* node is elsewhere */
|
||||
pptr->next = ptr->next;
|
||||
if (ptr->next != NULL) {
|
||||
ptr->next->previous = pptr;
|
||||
}
|
||||
free(ptr);
|
||||
return CMTSuccess;
|
||||
}
|
||||
}
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
PCMT_EVENT CMT_GetEventHandler(PCMT_CONTROL control, CMUint32 type,
|
||||
CMUint32 resourceID)
|
||||
{
|
||||
PCMT_EVENT ptr;
|
||||
|
||||
for (ptr = control->cmtEventHandlers; ptr != NULL; ptr = ptr->next) {
|
||||
if ((ptr->type == type) && ((ptr->resourceID == resourceID) ||
|
||||
!ptr->resourceID)) {
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PCMT_EVENT CMT_GetFirstEventHandler(PCMT_CONTROL control, CMUint32 type,
|
||||
CMUint32 resourceID)
|
||||
{
|
||||
PCMT_EVENT ptr;
|
||||
|
||||
for (ptr = control->cmtEventHandlers; ptr != NULL; ptr = ptr->next) {
|
||||
if ((ptr->type == type) && ((ptr->resourceID == resourceID) ||
|
||||
!ptr->resourceID)) {
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PCMT_EVENT CMT_GetNextEventHandler(PCMT_CONTROL control, PCMT_EVENT e)
|
||||
{
|
||||
PCMT_EVENT ptr;
|
||||
|
||||
for (ptr = control->cmtEventHandlers; ptr != NULL || ptr == e;
|
||||
ptr = ptr->next) {
|
||||
}
|
||||
|
||||
for (; ptr != NULL; ptr = ptr->next) {
|
||||
if ((ptr->type == e->type) && ((ptr->resourceID == e->resourceID) ||
|
||||
!ptr->resourceID)) {
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CMT_ProcessEvent(PCMT_CONTROL cm_control)
|
||||
{
|
||||
CMTSocket sock;
|
||||
CMTItem eventData={ 0, NULL, 0 };
|
||||
|
||||
/* Get the control socket */
|
||||
sock = cm_control->sock;
|
||||
|
||||
/* Acquire a lock on the control connection */
|
||||
CMT_LOCK(cm_control->mutex);
|
||||
/* Do another select here to be sure
|
||||
that the socket is readable */
|
||||
if (cm_control->sockFuncs.select(&sock, 1, 1) != sock) {
|
||||
/* There's no event. */
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* Read the event */
|
||||
if (CMT_ReceiveMessage(cm_control, &eventData) == CMTFailure) {
|
||||
goto done;
|
||||
}
|
||||
CMT_UNLOCK(cm_control->mutex);
|
||||
/* Dispatch the event */
|
||||
CMT_DispatchEvent(cm_control, &eventData);
|
||||
return;
|
||||
done:
|
||||
/* Release the lock on the control connection */
|
||||
CMT_UNLOCK(cm_control->mutex);
|
||||
}
|
||||
|
||||
void CMT_EventLoop(PCMT_CONTROL cm_control)
|
||||
{
|
||||
CMTSocket sock;
|
||||
|
||||
/* Get the control socket */
|
||||
sock = cm_control->sock;
|
||||
CMT_ReferenceControlConnection(cm_control);
|
||||
/* Select on the control socket to see if it's readable */
|
||||
while(cm_control->sockFuncs.select(&sock, 1, 0)) {
|
||||
CMT_ProcessEvent(cm_control);
|
||||
}
|
||||
CMT_CloseControlConnection(cm_control);
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
CMT_PromptUser(PCMT_CONTROL cm_control, CMTItem *eventData)
|
||||
{
|
||||
char *promptReply = NULL;
|
||||
CMTItem response={ 0, NULL, 0 };
|
||||
PromptRequest request;
|
||||
PromptReply reply;
|
||||
void * clientContext;
|
||||
|
||||
/* Decode the message */
|
||||
if (CMT_DecodeMessage(PromptRequestTemplate, &request, eventData) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Copy the client context to a pointer */
|
||||
clientContext = CMT_CopyItemToPtr(request.clientContext);
|
||||
|
||||
if (cm_control->userFuncs.promptCallback == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
promptReply =
|
||||
cm_control->userFuncs.promptCallback(cm_control->userFuncs.promptArg,
|
||||
request.prompt, clientContext, 1);
|
||||
|
||||
response.type = SSM_EVENT_MESSAGE | SSM_PROMPT_EVENT;
|
||||
if (!promptReply) {
|
||||
/* the user canceled the prompt or other errors occurred */
|
||||
reply.cancel = CM_TRUE;
|
||||
}
|
||||
else {
|
||||
/* note that this includes an empty string (zero length) password */
|
||||
reply.cancel = CM_FALSE;
|
||||
}
|
||||
reply.resID = request.resID;
|
||||
reply.promptReply = promptReply;
|
||||
|
||||
/* Encode the message */
|
||||
if (CMT_EncodeMessage(PromptReplyTemplate, &response, &reply) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
CMT_TransmitMessage(cm_control, &response);
|
||||
loser:
|
||||
if (promptReply != NULL) {
|
||||
cm_control->userFuncs.userFree(promptReply);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void CMT_GetFilePath(PCMT_CONTROL cm_control, CMTItem * eventData)
|
||||
{
|
||||
char *fileName=NULL;
|
||||
CMTItem response = { 0, NULL, 0 };
|
||||
FilePathRequest request;
|
||||
FilePathReply reply;
|
||||
|
||||
/* Decode the request */
|
||||
if (CMT_DecodeMessage(FilePathRequestTemplate, &request, eventData) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (cm_control->userFuncs.promptFilePath == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
fileName =
|
||||
cm_control->userFuncs.promptFilePath(cm_control->userFuncs.filePromptArg,
|
||||
request.prompt, request.fileRegEx,
|
||||
request.getExistingFile);
|
||||
|
||||
response.type = SSM_EVENT_MESSAGE | SSM_FILE_PATH_EVENT;
|
||||
reply.resID = request.resID;
|
||||
reply.filePath = fileName;
|
||||
|
||||
/* Encode the reply */
|
||||
if (CMT_EncodeMessage(FilePathReplyTemplate, &response, &reply) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
CMT_TransmitMessage(cm_control, &response);
|
||||
cm_control->userFuncs.userFree(fileName);
|
||||
loser:
|
||||
return;
|
||||
}
|
||||
|
||||
void CMT_SavePrefs(PCMT_CONTROL cm_control, CMTItem* eventData)
|
||||
{
|
||||
SetPrefListMessage request;
|
||||
int i;
|
||||
|
||||
/* decode the request */
|
||||
if (CMT_DecodeMessage(SetPrefListMessageTemplate, &request, eventData) !=
|
||||
CMTSuccess) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (cm_control->userFuncs.savePrefs == NULL) {
|
||||
/* callback was not registered: bail */
|
||||
return;
|
||||
}
|
||||
cm_control->userFuncs.savePrefs(request.length,
|
||||
(CMTSetPrefElement*)request.list);
|
||||
|
||||
for (i = 0; i < request.length; i++) {
|
||||
if (request.list[i].key != NULL) {
|
||||
free(request.list[i].key);
|
||||
}
|
||||
if (request.list[i].value != NULL) {
|
||||
free(request.list[i].value);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
void CMT_DispatchEvent(PCMT_CONTROL cm_control, CMTItem * eventData)
|
||||
{
|
||||
CMUint32 eventType;
|
||||
CMTItem msgCopy;
|
||||
|
||||
/* Init the msgCopy */
|
||||
msgCopy.data = 0;
|
||||
|
||||
/* Get the event type */
|
||||
if ((eventData->type & SSM_CATEGORY_MASK) != SSM_EVENT_MESSAGE) {
|
||||
/* Somehow there was a message on the socket that was not
|
||||
* an event message. Dropping it on the floor.
|
||||
*/
|
||||
goto loser;
|
||||
}
|
||||
eventType = (eventData->type & SSM_TYPE_MASK);
|
||||
|
||||
/* We must now dispatch the event based on it's type */
|
||||
switch (eventType) {
|
||||
case SSM_UI_EVENT:
|
||||
{
|
||||
PCMT_EVENT p;
|
||||
UIEvent event;
|
||||
void * clientContext = NULL;
|
||||
|
||||
/* Copy the message to allow a second try with the old format */
|
||||
msgCopy.len = eventData->len;
|
||||
msgCopy.data = calloc(msgCopy.len, 1);
|
||||
if (msgCopy.data) {
|
||||
memcpy(msgCopy.data, eventData->data, eventData->len);
|
||||
}
|
||||
|
||||
/* Get the event data first */
|
||||
if (CMT_DecodeMessage(UIEventTemplate, &event, eventData) != CMTSuccess) {
|
||||
/* Attempt to decode using the old format. Modal is True */
|
||||
if (!msgCopy.data ||
|
||||
CMT_DecodeMessage(OldUIEventTemplate, &event, &msgCopy) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set default modal value */
|
||||
event.isModal = CM_TRUE;
|
||||
}
|
||||
|
||||
/* Convert the client context to a pointer */
|
||||
clientContext = CMT_CopyItemToPtr(event.clientContext);
|
||||
|
||||
/* Call any handlers for this event */
|
||||
p = CMT_GetEventHandler(cm_control, eventType, event.resourceID);
|
||||
if (!p) {
|
||||
goto loser;
|
||||
}
|
||||
(*(uiHandlerCallback_fn)(p->handler))(event.resourceID,
|
||||
clientContext, event.width,
|
||||
event.height, event.isModal, event.url,
|
||||
p->data);
|
||||
break;
|
||||
}
|
||||
|
||||
case SSM_TASK_COMPLETED_EVENT:
|
||||
{
|
||||
PCMT_EVENT p;
|
||||
TaskCompletedEvent event;
|
||||
|
||||
/* Get the event data */
|
||||
if (CMT_DecodeMessage(TaskCompletedEventTemplate, &event, eventData) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Call handler for this event */
|
||||
p = CMT_GetEventHandler(cm_control, eventType, event.resourceID);
|
||||
if (!p) {
|
||||
goto loser;
|
||||
}
|
||||
(*(taskcompleted_handler_fn)(p->handler))(event.resourceID,
|
||||
event.numTasks,
|
||||
event.result, p->data);
|
||||
break;
|
||||
}
|
||||
case SSM_AUTH_EVENT:
|
||||
CMT_ServicePasswordRequest(cm_control, eventData);
|
||||
break;
|
||||
case SSM_FILE_PATH_EVENT:
|
||||
CMT_GetFilePath(cm_control, eventData);
|
||||
break;
|
||||
case SSM_PROMPT_EVENT:
|
||||
CMT_PromptUser(cm_control, eventData);
|
||||
break;
|
||||
case SSM_SAVE_PREF_EVENT:
|
||||
CMT_SavePrefs(cm_control, eventData);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
loser:
|
||||
free(eventData->data);
|
||||
free(msgCopy.data);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,216 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifdef XP_UNIX
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#else
|
||||
#ifdef XP_MAC
|
||||
#include "macsocket.h"
|
||||
#include "string.h"
|
||||
#else
|
||||
#include <windows.h>
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include "cmtcmn.h"
|
||||
#include "cmtutils.h"
|
||||
#include "messages.h"
|
||||
#include "rsrcids.h"
|
||||
|
||||
CMTStatus CMT_HashCreate(PCMT_CONTROL control, CMUint32 algID,
|
||||
CMUint32 * connID)
|
||||
{
|
||||
CMTItem message;
|
||||
SingleNumMessage request;
|
||||
DataConnectionReply reply;
|
||||
|
||||
/* Check passed in parameters */
|
||||
if (!control) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set up the request */
|
||||
request.value = algID;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(SingleNumMessageTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_DATA_CONNECTION | SSM_HASH_STREAM;
|
||||
|
||||
/* Send the message and get the response */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the response */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_DATA_CONNECTION | SSM_HASH_STREAM)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the reply */
|
||||
if (CMT_DecodeMessage(DataConnectionReplyTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
if (reply.result == 0) {
|
||||
CMTSocket sock;
|
||||
|
||||
sock = control->sockFuncs.socket(0);
|
||||
if(sock == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (control->sockFuncs.connect(sock, reply.port, NULL) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
/* Send the hello message */
|
||||
control->sockFuncs.send(sock, control->nonce.data, control->nonce.len);
|
||||
|
||||
/* Save connection info */
|
||||
if (CMT_AddDataConnection(control, sock, reply.connID)
|
||||
!= CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the connection ID */
|
||||
*connID = reply.connID;
|
||||
return CMTSuccess;
|
||||
}
|
||||
loser:
|
||||
*connID = 0;
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_HASH_Destroy(PCMT_CONTROL control, CMUint32 connectionID)
|
||||
{
|
||||
if (!control) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Get the cotext implementation data */
|
||||
if (CMT_CloseDataConnection(control, connectionID) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
|
||||
loser:
|
||||
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_HASH_Begin(PCMT_CONTROL control, CMUint32 connectionID)
|
||||
{
|
||||
return CMTSuccess;
|
||||
}
|
||||
|
||||
CMTStatus CMT_HASH_Update(PCMT_CONTROL control, CMUint32 connectionID, const unsigned char * buf, CMUint32 len)
|
||||
{
|
||||
CMTSocket sock;
|
||||
CMUint32 sent;
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control || !buf) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Get the data socket */
|
||||
if (CMT_GetDataSocket(control, connectionID, &sock) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Write the data to the socket */
|
||||
sent = CMT_WriteThisMany(control, sock, (void*)buf, len);
|
||||
if (sent != len) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
|
||||
loser:
|
||||
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_HASH_End(PCMT_CONTROL control, CMUint32 connectionID,
|
||||
unsigned char * result, CMUint32 * resultlen,
|
||||
CMUint32 maxLen)
|
||||
{
|
||||
CMTItem hash = { 0, NULL, 0 };
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control || !result || !resultlen) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Close the connection */
|
||||
if (CMT_CloseDataConnection(control, connectionID) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Get the context info */
|
||||
if (CMT_GetStringAttribute(control, connectionID, SSM_FID_HASHCONN_RESULT,
|
||||
&hash) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
if (!hash.data) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
*resultlen = hash.len;
|
||||
if (hash.len > maxLen) {
|
||||
memcpy(result, hash.data, maxLen);
|
||||
} else {
|
||||
memcpy(result, hash.data, hash.len);
|
||||
}
|
||||
|
||||
if (hash.data) {
|
||||
free(hash.data);
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
|
||||
loser:
|
||||
if (hash.data) {
|
||||
free(hash.data);
|
||||
}
|
||||
|
||||
return CMTFailure;
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef __CMTIMPL_H_
|
||||
#define __CMTIMPL_H_
|
||||
|
||||
typedef unsigned long CMT_HANDLE;
|
||||
|
||||
struct _CMTControl {
|
||||
CMT_HANDLE channelID;
|
||||
int socketID;
|
||||
CMTStatus (* cmtEventCallback)(struct _CMTControl * control,
|
||||
CMTItem * event, void * arg);
|
||||
void * cmtEventCallbackArg;
|
||||
struct _CMTData * cmtDataConnection;
|
||||
} _CMTControl;
|
||||
|
||||
|
||||
|
||||
struct _CMTData {
|
||||
CMT_HANDLE channelID;
|
||||
int socketID;
|
||||
struct _CMTData * next;
|
||||
struct _CMTData * previous;
|
||||
};
|
||||
|
||||
#endif /*__CMTIMPL_H_*/
|
||||
@@ -1,484 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifdef XP_UNIX
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/stat.h>
|
||||
#include <netinet/tcp.h>
|
||||
#else
|
||||
#ifdef XP_MAC
|
||||
#include <Events.h> // for WaitNextEvent
|
||||
#else /* Windows */
|
||||
#include <windows.h>
|
||||
#include <winsock.h>
|
||||
#include <direct.h>
|
||||
#include <sys/stat.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "messages.h"
|
||||
#include "cmtcmn.h"
|
||||
#include "cmtutils.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifdef XP_UNIX
|
||||
#define DIRECTORY_SEPARATOR '/'
|
||||
#elif defined WIN32
|
||||
#define DIRECTORY_SEPARATOR '\\'
|
||||
#elif defined XP_MAC
|
||||
#define DIRECTORY_SEPARATOR ':'
|
||||
#endif
|
||||
|
||||
/* Local defines */
|
||||
#define CARTMAN_PORT 11111
|
||||
#define MAX_PATH_LEN 256
|
||||
|
||||
/* write to the cmnav.log */
|
||||
#if 0
|
||||
#define LOG(x); do { FILE *f; f=fopen("cmnav.log","a+"); if (f) { \
|
||||
fprintf(f, x); fclose(f); } } while(0);
|
||||
#define LOG_S(x); do { FILE *f; f=fopen("cmnav.log","a+"); if (f) { \
|
||||
fprintf(f, "%s", x); fclose(f); } } while(0);
|
||||
#define ASSERT(x); if (!(x)) { LOG("ASSERT:"); LOG(#x); LOG("\n"); exit(-1); }
|
||||
#else
|
||||
#define LOG(x); ;
|
||||
#define LOG_S(x); ;
|
||||
#define ASSERT(x); ;
|
||||
#endif
|
||||
|
||||
static char*
|
||||
getCurrWorkDir(char *buf, int maxLen)
|
||||
{
|
||||
#if defined WIN32
|
||||
return _getcwd(buf, maxLen);
|
||||
#elif defined XP_UNIX
|
||||
return getcwd(buf, maxLen);
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
setWorkingDir(char *path)
|
||||
{
|
||||
#if defined WIN32
|
||||
_chdir(path);
|
||||
#elif defined XP_UNIX
|
||||
chdir(path);
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
static CMTStatus
|
||||
launch_psm(char *executable)
|
||||
{
|
||||
char command[MAX_PATH_LEN];
|
||||
#ifdef WIN32
|
||||
STARTUPINFO sui;
|
||||
PROCESS_INFORMATION pi;
|
||||
UNALIGNED long *posfhnd;
|
||||
int i;
|
||||
char *posfile;
|
||||
|
||||
sprintf(command,"%s > psmlog", executable);
|
||||
ZeroMemory( &sui, sizeof(sui) );
|
||||
sui.cb = sizeof(sui);
|
||||
sui.cbReserved2 = (WORD)(sizeof( int ) + (3 * (sizeof( char ) +
|
||||
sizeof( long ))));
|
||||
sui.lpReserved2 = calloc( sui.cbReserved2, 1 );
|
||||
*((UNALIGNED int *)(sui.lpReserved2)) = 3;
|
||||
posfile = (char *)(sui.lpReserved2 + sizeof( int ));
|
||||
posfhnd = (UNALIGNED long *)(sui.lpReserved2 + sizeof( int ) +
|
||||
(3 * sizeof( char )));
|
||||
|
||||
for ( i = 0, posfile = (char *)(sui.lpReserved2 + sizeof( int )),
|
||||
posfhnd = (UNALIGNED long *)(sui.lpReserved2 + sizeof( int ) + (3 * sizeof( char ))) ;
|
||||
i < 3 ; i++, posfile++, posfhnd++ ) {
|
||||
|
||||
*posfile = 0;
|
||||
*posfhnd = (long)INVALID_HANDLE_VALUE;
|
||||
}
|
||||
/* Now, fire up PSM */
|
||||
if (!CreateProcess(NULL, command, NULL, NULL, TRUE, DETACHED_PROCESS,
|
||||
NULL, NULL, &sui, &pi)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
#elif defined XP_UNIX
|
||||
sprintf(command,"./%s &", executable);
|
||||
if (system(command) == -1) {
|
||||
goto loser;
|
||||
}
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
#else
|
||||
return CMTFailure;
|
||||
#endif
|
||||
}
|
||||
|
||||
PCMT_CONTROL CMT_EstablishControlConnection(char *inPath,
|
||||
CMT_SocketFuncs *sockFuncs,
|
||||
CMT_MUTEX *mutex)
|
||||
{
|
||||
PCMT_CONTROL control;
|
||||
char *executable;
|
||||
char *newWorkingDir;
|
||||
char oldWorkingDir[MAX_PATH_LEN];
|
||||
int i;
|
||||
char *path = NULL;
|
||||
size_t stringLen;
|
||||
|
||||
/* On the Mac, we do special magic in the Seamonkey PSM component, so
|
||||
if PSM isn't launched by the time we reach this point, we're not doing well. */
|
||||
#ifndef XP_MAC
|
||||
|
||||
struct stat stbuf;
|
||||
|
||||
/*
|
||||
* Create our own copy of path.
|
||||
* I'd like to do a straight strdup here, but that caused problems
|
||||
* for https.
|
||||
*/
|
||||
stringLen = strlen(inPath);
|
||||
|
||||
path = (char*) malloc(stringLen+1);
|
||||
memcpy(path, inPath, stringLen);
|
||||
path[stringLen] = '\0';
|
||||
|
||||
control = CMT_ControlConnect(mutex, sockFuncs);
|
||||
if (control != NULL) {
|
||||
return control;
|
||||
}
|
||||
/*
|
||||
* We have to try to launch it now, so it better be a valid
|
||||
* path.
|
||||
*/
|
||||
if (stat(path, &stbuf) == -1) {
|
||||
goto loser;
|
||||
}
|
||||
/*
|
||||
* Now we have to parse the path and launch the psm server.
|
||||
*/
|
||||
executable = strrchr(path, DIRECTORY_SEPARATOR);
|
||||
if (executable != NULL) {
|
||||
*executable = '\0';
|
||||
executable ++;
|
||||
newWorkingDir = path;
|
||||
} else {
|
||||
executable = path;
|
||||
newWorkingDir = NULL;
|
||||
}
|
||||
if (getCurrWorkDir(oldWorkingDir, MAX_PATH_LEN) == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
setWorkingDir(newWorkingDir);
|
||||
if (launch_psm(executable) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
setWorkingDir(oldWorkingDir);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Now try to connect to the psm server. We will try to connect
|
||||
* a maximum of 30 times and then give up.
|
||||
*/
|
||||
#ifdef WIN32
|
||||
for (i=0; i<30; i++) {
|
||||
Sleep(1000);
|
||||
control = CMT_ControlConnect(mutex, sockFuncs);
|
||||
if (control != NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#elif defined XP_UNIX
|
||||
i = 0;
|
||||
while (i<1000) {
|
||||
i += sleep(10);
|
||||
control = CMT_ControlConnect(mutex, sockFuncs);
|
||||
if (control != NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#elif defined(XP_MAC)
|
||||
for (i=0; i<30; i++)
|
||||
{
|
||||
EventRecord theEvent;
|
||||
WaitNextEvent(0, &theEvent, 30, NULL);
|
||||
control = CMT_ControlConnect(mutex, sockFuncs);
|
||||
if (control != NULL)
|
||||
break;
|
||||
}
|
||||
|
||||
#else
|
||||
/*
|
||||
* Figure out how to sleep for a while first
|
||||
*/
|
||||
for (i=0; i<30; i++) {
|
||||
control = CMT_ControlConnect(mutex, sockFuncs);
|
||||
if (control!= NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (control == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
if (path) {
|
||||
free (path);
|
||||
}
|
||||
return control;
|
||||
loser:
|
||||
if (control != NULL) {
|
||||
CMT_CloseControlConnection(control);
|
||||
}
|
||||
if (path) {
|
||||
free(path);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
PCMT_CONTROL CMT_ControlConnect(CMT_MUTEX *mutex, CMT_SocketFuncs *sockFuncs)
|
||||
{
|
||||
PCMT_CONTROL control = NULL;
|
||||
CMTSocket sock=NULL;
|
||||
#ifdef XP_UNIX
|
||||
int unixSock = 1;
|
||||
char path[20];
|
||||
#else
|
||||
int unixSock = 0;
|
||||
char *path=NULL;
|
||||
#endif
|
||||
|
||||
if (sockFuncs == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
#ifdef XP_UNIX
|
||||
sprintf(path, "/tmp/.nsmc-%d", (int)geteuid());
|
||||
#endif
|
||||
|
||||
sock = sockFuncs->socket(unixSock);
|
||||
if (sock == NULL) {
|
||||
LOG("Could not create a socket to connect to Control Connection.\n");
|
||||
goto loser;
|
||||
}
|
||||
/* Connect to the psm process */
|
||||
if (sockFuncs->connect(sock, CARTMAN_PORT, path)) {
|
||||
LOG("Could not connect to Cartman\n");
|
||||
goto loser;
|
||||
}
|
||||
|
||||
#ifdef XP_UNIX
|
||||
if (sockFuncs->verify(sock) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
#endif
|
||||
|
||||
LOG("Connected to Cartman\n");
|
||||
|
||||
/* fill in the CMTControl struct */
|
||||
control = (PCMT_CONTROL)calloc(sizeof(CMT_CONTROL), 1);
|
||||
if (control == NULL ) {
|
||||
goto loser;
|
||||
}
|
||||
control->sock = sock;
|
||||
if (mutex != NULL) {
|
||||
control->mutex = (CMT_MUTEX*)calloc(sizeof(CMT_MUTEX),1);
|
||||
if (control->mutex == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
*control->mutex = *mutex;
|
||||
}
|
||||
memcpy(&control->sockFuncs, sockFuncs, sizeof(CMT_SocketFuncs));
|
||||
control->refCount = 1;
|
||||
goto done;
|
||||
|
||||
loser:
|
||||
if (control != NULL) {
|
||||
free(control);
|
||||
}
|
||||
if (sock != NULL) {
|
||||
sockFuncs->close(sock);
|
||||
}
|
||||
control = NULL;
|
||||
|
||||
done:
|
||||
return control;
|
||||
}
|
||||
|
||||
CMTStatus CMT_CloseControlConnection(PCMT_CONTROL control)
|
||||
{
|
||||
/* XXX Don't know what to do here yet */
|
||||
if (control != NULL) {
|
||||
CMInt32 refCount;
|
||||
CMT_LOCK(control->mutex);
|
||||
control->refCount--;
|
||||
refCount = control->refCount;
|
||||
CMT_UNLOCK(control->mutex);
|
||||
if (refCount <= 0) {
|
||||
if (control->mutex != NULL) {
|
||||
free (control->mutex);
|
||||
}
|
||||
control->sockFuncs.close(control->sock);
|
||||
free(control);
|
||||
}
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
}
|
||||
|
||||
CMTStatus CMT_Hello(PCMT_CONTROL control, CMUint32 version, char* profile,
|
||||
char* profileDir)
|
||||
{
|
||||
CMTItem message;
|
||||
PCMT_EVENT eventHandler;
|
||||
CMBool doesUI;
|
||||
HelloRequest request;
|
||||
HelloReply reply;
|
||||
|
||||
/* Check the passed parameters */
|
||||
if (!control) {
|
||||
return CMTFailure;
|
||||
}
|
||||
if (!profile) {
|
||||
return CMTFailure;
|
||||
}
|
||||
if (!profileDir) {
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
/* Create the hello message */
|
||||
eventHandler = CMT_GetEventHandler(control, SSM_UI_EVENT, 0);
|
||||
doesUI = (eventHandler == NULL) ? CM_FALSE : CM_TRUE;
|
||||
|
||||
/* Setup the request struct */
|
||||
request.version = version;
|
||||
request.policy = 0; /* no more policy */
|
||||
request.doesUI = doesUI;
|
||||
request.profile = profile;
|
||||
request.profileDir = profileDir;
|
||||
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_HELLO_MESSAGE;
|
||||
|
||||
if (CMT_EncodeMessage(HelloRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Send the message and get the response */
|
||||
if (CMT_SendMessage(control, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_HELLO_MESSAGE)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the message */
|
||||
if (CMT_DecodeMessage(HelloReplyTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Successful response */
|
||||
if (reply.result == 0) {
|
||||
/* Save the nonce value */
|
||||
control->sessionID = reply.sessionID;
|
||||
control->protocolVersion = reply.version;
|
||||
control->port = reply.httpPort;
|
||||
control->nonce = reply.nonce;
|
||||
control->policy = reply.policy;
|
||||
control->serverStringVersion = reply.stringVersion;
|
||||
|
||||
/* XXX Free the messages */
|
||||
return CMTSuccess;
|
||||
}
|
||||
loser:
|
||||
/* XXX Free the messages */
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_PassAllPrefs(PCMT_CONTROL control, int num,
|
||||
CMTSetPrefElement* list)
|
||||
{
|
||||
SetPrefListMessage request;
|
||||
SingleNumMessage reply;
|
||||
CMTItem message;
|
||||
|
||||
if ((control == NULL) || (list == NULL)) {
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
/* pack the request */
|
||||
request.length = num;
|
||||
request.list = (SetPrefElement*)list;
|
||||
|
||||
if (CMT_EncodeMessage(SetPrefListMessageTemplate, &message, &request) !=
|
||||
CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_PREF_ACTION;
|
||||
|
||||
/* send the message */
|
||||
if (CMT_SendMessage(control, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_PREF_ACTION)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message) !=
|
||||
CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* don't really need to check the return value */
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
char* CMT_GetServerStringVersion(PCMT_CONTROL control)
|
||||
{
|
||||
if (control == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
return control->serverStringVersion;
|
||||
}
|
||||
@@ -1,556 +0,0 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "cmtutils.h"
|
||||
#include "cmtjs.h"
|
||||
#include "messages.h"
|
||||
|
||||
CMTStatus
|
||||
CMT_GenerateKeyPair(PCMT_CONTROL control, CMUint32 keyGenContext,
|
||||
CMUint32 mechType, CMTItem *param, CMUint32 keySize,
|
||||
CMUint32 *keyPairId)
|
||||
{
|
||||
CMTItem message;
|
||||
CMTStatus rv;
|
||||
KeyPairGenRequest request = {0, 0, 0, {0, NULL, 0}};
|
||||
SingleNumMessage reply;
|
||||
|
||||
if (!control) {
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
request.keyGenCtxtID = keyGenContext;
|
||||
request.genMechanism = mechType;
|
||||
if (param) {
|
||||
request.params = *param;
|
||||
}
|
||||
request.keySize = keySize;
|
||||
|
||||
/* Encode the message */
|
||||
if (CMT_EncodeMessage(KeyPairGenRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_PKCS11_ACTION | SSM_CREATE_KEY_PAIR;
|
||||
|
||||
/* Send the message and get the response */
|
||||
rv = CMT_SendMessage(control, &message);
|
||||
if (rv != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_PKCS11_ACTION | SSM_CREATE_KEY_PAIR)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the message */
|
||||
if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
*keyPairId = reply.value;
|
||||
return CMTSuccess;
|
||||
|
||||
loser:
|
||||
*keyPairId = 0;
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
|
||||
CMTStatus
|
||||
CMT_CreateNewCRMFRequest(PCMT_CONTROL control, CMUint32 keyPairID,
|
||||
SSMKeyGenType keyGenType, CMUint32 *reqID)
|
||||
{
|
||||
CMTItem message;
|
||||
CMTStatus rv;
|
||||
SingleNumMessage request;
|
||||
SingleNumMessage reply;
|
||||
|
||||
if (!control) {
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
request.value = keyPairID;
|
||||
if (CMT_EncodeMessage(SingleNumMessageTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_CRMF_ACTION |
|
||||
SSM_CREATE_CRMF_REQ;
|
||||
rv = CMT_SendMessage(control, &message);
|
||||
if (rv != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_CRMF_ACTION | SSM_CREATE_CRMF_REQ)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
*reqID = reply.value;
|
||||
|
||||
rv = CMT_SetNumericAttribute(control, *reqID, SSM_FID_CRMFREQ_KEY_TYPE,
|
||||
keyGenType);
|
||||
if (rv != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus
|
||||
CMT_EncodeCRMFRequest(PCMT_CONTROL control, CMUint32 *crmfReqID,
|
||||
CMUint32 numRequests, char ** der)
|
||||
{
|
||||
CMTItem message;
|
||||
CMTStatus rv;
|
||||
EncodeCRMFReqRequest request;
|
||||
SingleItemMessage reply;
|
||||
|
||||
if (!control) {
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
request.numRequests = numRequests;
|
||||
request.reqIDs = (long *) crmfReqID;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(EncodeCRMFReqRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_CRMF_ACTION | SSM_DER_ENCODE_REQ;
|
||||
|
||||
rv = CMT_SendMessage(control, &message);
|
||||
if (rv != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_CRMF_ACTION | SSM_DER_ENCODE_REQ)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* XXX Should this be a string? Decode the message */
|
||||
if (CMT_DecodeMessage(SingleItemMessageTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
*der = (char *) reply.item.data;
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus
|
||||
CMT_ProcessCMMFResponse(PCMT_CONTROL control, char *nickname,
|
||||
char *certRepString, CMBool doBackup,
|
||||
void *clientContext)
|
||||
{
|
||||
CMTItem message;
|
||||
CMTStatus rv;
|
||||
CMMFCertResponseRequest request;
|
||||
|
||||
if(!control) {
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
request.nickname = nickname;
|
||||
request.base64Der = certRepString;
|
||||
request.doBackup = doBackup;
|
||||
request.clientContext = CMT_CopyPtrToItem(clientContext);
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(CMMFCertResponseRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_CRMF_ACTION | SSM_PROCESS_CMMF_RESP;
|
||||
|
||||
rv = CMT_SendMessage(control, &message);
|
||||
if (rv != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_CRMF_ACTION | SSM_PROCESS_CMMF_RESP)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus
|
||||
CMT_CreateResource(PCMT_CONTROL control, SSMResourceType resType,
|
||||
CMTItem *params, CMUint32 *rsrcId, CMUint32 *errorCode)
|
||||
{
|
||||
CMTItem message;
|
||||
CMTStatus rv;
|
||||
CreateResourceRequest request = {0, {0, NULL, 0}};
|
||||
CreateResourceReply reply;
|
||||
|
||||
request.type = resType;
|
||||
if (params) {
|
||||
request.params = *params;
|
||||
}
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(CreateResourceRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_RESOURCE_ACTION | SSM_CREATE_RESOURCE;
|
||||
|
||||
rv = CMT_SendMessage(control, &message);
|
||||
if (rv != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_RESOURCE_ACTION | SSM_CREATE_RESOURCE)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the message */
|
||||
if (CMT_DecodeMessage(CreateResourceReplyTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
*rsrcId = reply.resID;
|
||||
*errorCode = reply.result;
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_SignText(PCMT_CONTROL control, CMUint32 resID, char* stringToSign, char* hostName, char* caOption, CMInt32 numCAs, char** caNames)
|
||||
{
|
||||
CMTItem message;
|
||||
SignTextRequest request;
|
||||
|
||||
|
||||
/* So some basic parameter checking */
|
||||
if (!control || !stringToSign) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set up the request */
|
||||
request.resID = resID;
|
||||
request.stringToSign = stringToSign;
|
||||
request.hostName = hostName;
|
||||
request.caOption = caOption;
|
||||
request.numCAs = numCAs;
|
||||
request.caNames = caNames;
|
||||
|
||||
/* Encode the message */
|
||||
if (CMT_EncodeMessage(SignTextRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_FORMSIGN_ACTION | SSM_SIGN_TEXT;
|
||||
|
||||
/* Send the message and get the response */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_FORMSIGN_ACTION | SSM_SIGN_TEXT)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus
|
||||
CMT_ProcessChallengeResponse(PCMT_CONTROL control, char *challengeString,
|
||||
char **responseString)
|
||||
{
|
||||
CMTItem message;
|
||||
CMTStatus rv;
|
||||
SingleStringMessage request;
|
||||
SingleStringMessage reply;
|
||||
|
||||
/* Set the request */
|
||||
request.string = challengeString;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(SingleStringMessageTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_CRMF_ACTION | SSM_CHALLENGE;
|
||||
|
||||
/* Send the message */
|
||||
rv = CMT_SendMessage(control, &message);
|
||||
if (rv != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_CRMF_ACTION | SSM_CHALLENGE)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the reply */
|
||||
if (CMT_DecodeMessage(SingleStringMessageTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
*responseString = reply.string;
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus
|
||||
CMT_FinishGeneratingKeys(PCMT_CONTROL control, CMUint32 keyGenContext)
|
||||
{
|
||||
CMTItem message;
|
||||
CMTStatus rv;
|
||||
SingleNumMessage request;
|
||||
|
||||
/* Set up the request */
|
||||
request.value = keyGenContext;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(SingleNumMessageTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_PKCS11_ACTION | SSM_FINISH_KEY_GEN;
|
||||
|
||||
/* Send the message */
|
||||
rv = CMT_SendMessage(control, &message);
|
||||
if (rv != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the reply */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_PKCS11_ACTION | SSM_FINISH_KEY_GEN)) {
|
||||
goto loser;
|
||||
}
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus
|
||||
CMT_GetLocalizedString(PCMT_CONTROL control,
|
||||
SSMLocalizedString whichString,
|
||||
char **localizedString)
|
||||
{
|
||||
CMTItem message;
|
||||
CMTStatus rv;
|
||||
SingleNumMessage request;
|
||||
GetLocalizedTextReply reply;
|
||||
|
||||
/* Set up the request */
|
||||
request.value = whichString;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(SingleNumMessageTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_LOCALIZED_TEXT;
|
||||
|
||||
/* Send the message */
|
||||
rv = CMT_SendMessage(control, &message);
|
||||
if (rv != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_LOCALIZED_TEXT)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the reply */
|
||||
if (CMT_DecodeMessage(GetLocalizedTextReplyTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (reply.whichString != whichString) {
|
||||
goto loser;
|
||||
}
|
||||
*localizedString = reply.localizedString;
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
*localizedString = NULL;
|
||||
return rv;
|
||||
}
|
||||
|
||||
CMTStatus
|
||||
CMT_AddNewModule(PCMT_CONTROL control,
|
||||
char *moduleName,
|
||||
char *libraryPath,
|
||||
unsigned long pubMechFlags,
|
||||
unsigned long pubCipherFlags)
|
||||
{
|
||||
CMTItem message;
|
||||
CMTStatus rv;
|
||||
AddNewSecurityModuleRequest request;
|
||||
SingleNumMessage reply;
|
||||
|
||||
/* Set up the request */
|
||||
request.moduleName = moduleName;
|
||||
request.libraryPath = libraryPath;
|
||||
request.pubMechFlags = pubMechFlags;
|
||||
request.pubCipherFlags = pubCipherFlags;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(AddNewSecurityModuleRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_PKCS11_ACTION | SSM_ADD_NEW_MODULE;
|
||||
|
||||
/* Send the message */
|
||||
rv = CMT_SendMessage(control, &message);
|
||||
if (rv != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_PKCS11_ACTION | SSM_ADD_NEW_MODULE)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the response */
|
||||
if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return (CMTStatus) reply.value;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus
|
||||
CMT_DeleteModule(PCMT_CONTROL control,
|
||||
char *moduleName,
|
||||
int *moduleType)
|
||||
{
|
||||
CMTItem message;
|
||||
CMTStatus rv;
|
||||
SingleStringMessage request;
|
||||
SingleNumMessage reply;
|
||||
|
||||
/* Set up the request */
|
||||
request.string = moduleName;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(SingleStringMessageTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_PKCS11_ACTION | SSM_DEL_MODULE;
|
||||
|
||||
/* Send the message */
|
||||
rv = CMT_SendMessage(control, &message);
|
||||
if (rv != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_PKCS11_ACTION | SSM_DEL_MODULE)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the reply */
|
||||
if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
*moduleType = reply.value;
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_LogoutAllTokens(PCMT_CONTROL control)
|
||||
{
|
||||
CMTItem message;
|
||||
CMTStatus rv;
|
||||
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_PKCS11_ACTION | SSM_LOGOUT_ALL;
|
||||
message.data = NULL;
|
||||
message.len = 0;
|
||||
|
||||
rv = CMT_SendMessage(control, &message);
|
||||
if (rv != CMTSuccess) {
|
||||
return rv;
|
||||
}
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_PKCS11_ACTION |
|
||||
SSM_LOGOUT_ALL)) {
|
||||
return CMTFailure;
|
||||
}
|
||||
return CMTSuccess;
|
||||
}
|
||||
|
||||
CMTStatus CMT_GetSSLCapabilities(PCMT_CONTROL control, CMInt32 *capabilites)
|
||||
{
|
||||
SingleNumMessage reply;
|
||||
CMTItem message;
|
||||
CMTStatus rv;
|
||||
|
||||
message.type = (SSM_REQUEST_MESSAGE | SSM_PKCS11_ACTION |
|
||||
SSM_ENABLED_CIPHERS);
|
||||
message.data = NULL;
|
||||
message.len = 0;
|
||||
|
||||
rv = CMT_SendMessage(control, &message);
|
||||
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_PKCS11_ACTION |
|
||||
SSM_ENABLED_CIPHERS)) {
|
||||
goto loser;
|
||||
}
|
||||
if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply,
|
||||
&message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
*capabilites = reply.value;
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
@@ -1,555 +0,0 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef _CMTJS_H_
|
||||
#define _CMTJS_H_
|
||||
#include "cmtcmn.h"
|
||||
#include "ssmdefs.h"
|
||||
#include "rsrcids.h"
|
||||
/*
|
||||
* Define some constants.
|
||||
*/
|
||||
|
||||
/*
|
||||
* These defines are used in conjuction with the function
|
||||
* CMT_AddNewModule.
|
||||
*/
|
||||
#define PUBLIC_MECH_RSA_FLAG 0x00000001ul
|
||||
#define PUBLIC_MECH_DSA_FLAG 0x00000002ul
|
||||
#define PUBLIC_MECH_RC2_FLAG 0x00000004ul
|
||||
#define PUBLIC_MECH_RC4_FLAG 0x00000008ul
|
||||
#define PUBLIC_MECH_DES_FLAG 0x00000010ul
|
||||
#define PUBLIC_MECH_DH_FLAG 0x00000020ul
|
||||
#define PUBLIC_MECH_FORTEZZA_FLAG 0x00000040ul
|
||||
#define PUBLIC_MECH_RC5_FLAG 0x00000080ul
|
||||
#define PUBLIC_MECH_SHA1_FLAG 0x00000100ul
|
||||
#define PUBLIC_MECH_MD5_FLAG 0x00000200ul
|
||||
#define PUBLIC_MECH_MD2_FLAG 0x00000400ul
|
||||
|
||||
#define PUBLIC_MECH_RANDOM_FLAG 0x08000000ul
|
||||
#define PUBLIC_MECH_FRIENDLY_FLAG 0x10000000ul
|
||||
#define PUBLIC_OWN_PW_DEFAULTS 0X20000000ul
|
||||
#define PUBLIC_DISABLE_FLAG 0x40000000ul
|
||||
|
||||
|
||||
/*
|
||||
* This is the lone supported constant for the Cipher flag
|
||||
* for CMT_AddNewModule
|
||||
*/
|
||||
#define PUBLIC_CIPHER_FORTEZZA_FLAG 0x00000001ul
|
||||
|
||||
CMT_BEGIN_EXTERN_C
|
||||
|
||||
/*
|
||||
* FUNCTION: CMT_GenerateKeyPair
|
||||
* -----------------------------
|
||||
* INPUTS:
|
||||
* control
|
||||
* The Control Connection that has already established a connection
|
||||
* with the psm server.
|
||||
* keyGenContext
|
||||
* The Resource ID of a key gen context to use for creating the
|
||||
* key pair.
|
||||
* mechType
|
||||
* A PKCS11 mechanism used to generate the key pair. Valid values are:
|
||||
* CKM_RSA_PKCS_KEY_PAIR_GEN 0x00000000
|
||||
* CKM_DSA_KEY_PAIR_GEN 0x00000010
|
||||
* The definition of these values can be found at
|
||||
* http://www.rsa.com/rsalabs/pubs/pkcs11.html
|
||||
* The psm module currently supports v2.01 of PKCS11
|
||||
* params
|
||||
* This parameter will be used to pass parameters to the Key Pair
|
||||
* generation process. Currently this feature is not supported, so
|
||||
* pass in NULL for this parameter.
|
||||
* keySize
|
||||
* The size (in bits) of the key to generate.
|
||||
* keyPairId
|
||||
* A pointer to pre-allocated memory where the function can place
|
||||
* the value of the resource ID of the key pair that gets created.
|
||||
*
|
||||
* NOTES:
|
||||
* This function will send a message to the psm server requesting that
|
||||
* a public/private key pair be generated. The key gen context will queue
|
||||
* the request. You can send as many key gen requests as you want with a
|
||||
* given key gen context. After sending all the key gen requests, the user
|
||||
* must call CMT_FinishGeneratingKeys so that the key gen context actually
|
||||
* generates the keys.
|
||||
*
|
||||
* RETURN:
|
||||
* A return value of CMTSuccess indicates the request for key generation
|
||||
* was queued successfully and the corresponding resource ID can be found
|
||||
* at *keyPairId. Any other return value indicates an error and the value
|
||||
* at *keyPairId should be ignored.
|
||||
*/
|
||||
CMTStatus
|
||||
CMT_GenerateKeyPair(PCMT_CONTROL control, CMUint32 keyGenContext,
|
||||
CMUint32 mechType, CMTItem *params, CMUint32 keySize,
|
||||
CMUint32 *keyPairId);
|
||||
|
||||
/*
|
||||
* FUNCTION: CMT_FinishGeneratingKeys
|
||||
* ----------------------------------
|
||||
* INPUTS
|
||||
* control
|
||||
* The Control Connection that has already established a connection
|
||||
* with the psm server.
|
||||
* keyGenContext
|
||||
* The resource ID of the key gen context which should finish
|
||||
* generating its key pairs.
|
||||
* NOTES
|
||||
* This function will send a message to the psm server notifying the key
|
||||
* gen context with the resource ID of keyGenContext to finish generating
|
||||
* all of the key gen requests it has queued up. After each key gen has
|
||||
* finished, the psm server will send a SSM_TASK_COMPLETED_EVENT. So in order
|
||||
* to detect when all of the key gens are done, the user should register
|
||||
* an event handler. See comments for CMT_RegisterEventHandler for information
|
||||
* on how to successfully register event handler callbacks. You must register
|
||||
* the event handler with keyGenContext as the target resource ID for this
|
||||
* to work correctly.
|
||||
*
|
||||
* RETURN:
|
||||
* A return value of CMTSuccess indicates the key gen context has started to
|
||||
* generate the key pairs in its queue. Any other return value indicates an
|
||||
* error and the key pairs will not be generated.
|
||||
*/
|
||||
CMTStatus
|
||||
CMT_FinishGeneratingKeys(PCMT_CONTROL control, CMUint32 keyGenContext);
|
||||
|
||||
/*
|
||||
* FUNCTION: CMT_CreateNewCRMFRequest
|
||||
* ----------------------------------
|
||||
* INPUTS:
|
||||
* control
|
||||
* The Control Connection that has already established a connection
|
||||
* with the psm server.
|
||||
* keyPairID
|
||||
* The resource ID of the key pair that should be associated with
|
||||
* the CRMF request created. At the time this function is called,
|
||||
* key pair should have already been created.
|
||||
* keyGenType
|
||||
* An enumeration that explains how the key pair will be used.
|
||||
* Look at the definition of SSMKeyGenType in ssmdefs.h for valid
|
||||
* values and their affects on the request.
|
||||
* reqID
|
||||
* A pointer to a pre-allocatd chunk of memory where the library
|
||||
* can place the resource ID of the new CRMF request.
|
||||
* NOTES:
|
||||
* This function sends a message to the psm server requesting that a new
|
||||
* CRMF resource object be created. Each CRMF request must be associated with
|
||||
* a public/private key pair, that is why the keyPairID parameter exists.
|
||||
* The keyGenType parameter is used to initialize the request, eg set the
|
||||
* correct keyUsage extension.
|
||||
*
|
||||
* Before encoding a CRMF request, the user will want to set the appropriate
|
||||
* attributes to build up the request. The supported attributes are:
|
||||
*
|
||||
* Attribute Enumeration Attribute Type What value means
|
||||
* --------------------- -------------- ----------------
|
||||
* SSM_FID_CRMFREQ_REGTOKEN String The value to encode as
|
||||
* the registration token
|
||||
* value for the request.
|
||||
*
|
||||
* SSM_FID_CRMFREQ_AUTHENTICATOR String The value to encode as
|
||||
* authenticator control
|
||||
* in the request.
|
||||
*
|
||||
* SSM_FID_DN String The RFC1485 formatted
|
||||
* DN to include in the
|
||||
* CRMF request.
|
||||
*
|
||||
* For information on how to properly set the attribute of a resource, refer
|
||||
* to the comments for the functions CMT_SetNumericAttribute and
|
||||
* CMT_SetStringAttribute.
|
||||
*
|
||||
* RETURN:
|
||||
* A return value of CMTSuccess indicates a new CRMF resource was created by
|
||||
* the psm server and has the resource ID placed at *reqID. Any other return
|
||||
* value indicates an error and the value at *reqID should be ignored.
|
||||
*/
|
||||
CMTStatus
|
||||
CMT_CreateNewCRMFRequest(PCMT_CONTROL control, CMUint32 keyPairID,
|
||||
SSMKeyGenType keyGenType, CMUint32 *reqID);
|
||||
|
||||
/*
|
||||
* FUNCTION: CMT_EncodeCRMFRequest
|
||||
* ------------------------------
|
||||
* INPUTS:
|
||||
* control
|
||||
* The Control Connection that has already established a connection
|
||||
* with the psm server.
|
||||
* crmfReqID
|
||||
* An array of resource ID's for CRMF objects to be encoded.
|
||||
* numRequests
|
||||
* The length of the array crmfReqID that is passed in.
|
||||
* der
|
||||
* A pointer to a pre-allocated pointer for a char* where the library
|
||||
* can place the final DER-encoding of the requests.
|
||||
* NOTES
|
||||
* This function will send a message to the psm server requesting that
|
||||
* a number of CRMF requests be encoded into their appropriate DER
|
||||
* representation. The DER that is sent back will be of the type
|
||||
* CertReqMessages as define in the internet draft for CRMF. To look at the
|
||||
* draft, visit the following URL:
|
||||
* http://search.ietf.org/internet-drafts/internet-draft-ietf-pkix-crmf-01.txt
|
||||
*
|
||||
* RETURN:
|
||||
* A return value of CMTSuccess indicates psm successfully encoded the requests
|
||||
* and placed the base64 DER encoded request at *der. Any other return value
|
||||
* indicates an error and the value at *der should be ignored.
|
||||
*/
|
||||
CMTStatus
|
||||
CMT_EncodeCRMFRequest(PCMT_CONTROL control, CMUint32 *crmfReqID,
|
||||
CMUint32 numRequests, char ** der);
|
||||
|
||||
/*
|
||||
* FUNCTION: CMT_ProcessCMMFResponse
|
||||
* ---------------------------------
|
||||
* INPUTS:
|
||||
* control
|
||||
* The Control Connection that has already established a connection
|
||||
* with the psm server.
|
||||
* nickname
|
||||
* The nickname that should be associated with the certificate
|
||||
* contained in the CMMF Response.
|
||||
* certRepString
|
||||
* This is the base 64 encoded CertRepContent that issues a certificate.
|
||||
* The psm server will decode the base 64 data and then parse the
|
||||
* CertRepContent.
|
||||
* doBackup
|
||||
* A boolean value indicating whether or not psm should initiate the
|
||||
* process of backing up the newly issued certificate into a PKCS-12
|
||||
* file.
|
||||
* clientContext
|
||||
* Client supplied data pointer that is returned to the client during
|
||||
* a UI event.
|
||||
* NOTES:
|
||||
* This function takes a CertRepContent as defined in the CMMF internet draft
|
||||
* (http://search.ietf.org/internet-drafts/draft-ietf-pkix-cmmf-02.txt) and
|
||||
* imports the certificate into the user's database. The certificate will have
|
||||
* the string value of nickanme as it's nickname when added to the database
|
||||
* unless another certificate with that same Distinguished Name (DN) already
|
||||
* exists in the database, in which case the nickname of the certificate that
|
||||
* already exists will be used. If the value passed in for doBackup is
|
||||
* non-zero, then the psm server will initiate the process of backing up the
|
||||
* certificate(s) that were just imported.
|
||||
*
|
||||
* RETURN:
|
||||
* A return value of CMTSuccess indicates the certificate(s) were successfully
|
||||
* added to the database. Any other return value means the certificate(s) could
|
||||
* not be successfully added to the database.
|
||||
*/
|
||||
CMTStatus
|
||||
CMT_ProcessCMMFResponse(PCMT_CONTROL control, char *nickname,
|
||||
char *certRepString, CMBool doBackup,
|
||||
void *clientContext);
|
||||
|
||||
/*
|
||||
* FUNCTION: CMT_CreateResource
|
||||
* ----------------------------
|
||||
* INPUTS:
|
||||
* control
|
||||
* The Control Connection that has already established a connection
|
||||
* with the psm server.
|
||||
* resType
|
||||
* The enumeration representing the resource type to create.
|
||||
* params
|
||||
* A resource dependent binary string that will be sent to the psm
|
||||
* server. Each resource will expect a binary string it defines.
|
||||
* rsrcId
|
||||
* A pointer to a pre-allocated chunk of memory where the library
|
||||
* can place the resource ID of the newly created resource.
|
||||
* errorCode
|
||||
* A pointer to a pre-allocated chunk of memory where the library
|
||||
* can place the errorCode returned by the psm server after creating
|
||||
* the resource.
|
||||
* NOTES:
|
||||
* This function sends a message to the psm server requesting that a new
|
||||
* resource be created. The params parameter depends on the type of resource
|
||||
* being created. Below is a table detailing the format of the params for
|
||||
* a given resource type. Only the resource types listed below can be created
|
||||
* by calling this function.
|
||||
*
|
||||
* Resource Type constant Value for params
|
||||
* ------------------------------ ----------------
|
||||
* SSM_RESTYPE_KEYGEN_CONTEXT NULL
|
||||
* SSM_RESTYPE_SECADVISOR_CONTEXT NULL
|
||||
* SSM_RESTYPE_SIGNTEXT NULL
|
||||
*
|
||||
* RETURN
|
||||
* A return value of CMTSuccess means the psm server received the request and
|
||||
* processed the create resource create. If the value at *errorCode is zero,
|
||||
* then the value at *rsrcId is the resource ID of the newly created resource.
|
||||
* Otherwise, creating the new resource failed and *errorCode contains the
|
||||
* error code returned by the psm server. ???What are the return values and
|
||||
* what do they mean. Any other return value indicates there was an error
|
||||
* in the communication with the psm server and the values at *rsrcId and
|
||||
* *errorCode should be ignored.
|
||||
*/
|
||||
CMTStatus
|
||||
CMT_CreateResource(PCMT_CONTROL control, SSMResourceType resType,
|
||||
CMTItem *params, CMUint32 *rsrcId, CMUint32 *errorCode);
|
||||
|
||||
/*
|
||||
* FUNCTION: CMT_SignText
|
||||
* ----------------------
|
||||
* INPUTS:
|
||||
* control
|
||||
* The Control Connection that has already established a connection
|
||||
* with the psm server.
|
||||
* resID
|
||||
* The resource ID of an SSMSignTextResource.
|
||||
* stringToSign
|
||||
* The string that the psm server should sign.
|
||||
* hostName
|
||||
* The host name of the site that is requesting a string to be
|
||||
* signed. This is used for displaying the UI that tells the user
|
||||
* a web site has requested the use sign some text.
|
||||
* caOption
|
||||
* If the value is "auto" then psm will select the certificate
|
||||
* to use for signing automatically.
|
||||
* If the value is "ask" then psm will display a list of
|
||||
* certificates for signing.
|
||||
* numCAs
|
||||
* The number of CA names included in the array caNames passed in as
|
||||
* the last parameter to this function.
|
||||
* caNames
|
||||
* An array of CA Names to use for filtering the user certs to use
|
||||
* for signing the text.
|
||||
* NOTES
|
||||
* This function will sign the text passed via the parameter stringToSign.
|
||||
* The function will also cause the psm server to send some UI notifying the
|
||||
* user that a site has requested the user sign some text. The hostName
|
||||
* parameter is used in the UI to inform the user which site is requesting
|
||||
* the signed text. The caOption is used to determine if the psm server
|
||||
* should automatically select which personal cert to use in signing the
|
||||
* text. The caNames array is ussed to narrow down the field of personal
|
||||
* certs to use when signing the text. In other words, only personal certs
|
||||
* trusted by the CA's passed in will be used.
|
||||
*
|
||||
* RETURN
|
||||
* If the function returns CMTSuccess, that indicates the psm server
|
||||
* successfully signed the text. The signed text can be retrieved by
|
||||
* calling CMT_GetStringResource and passing in SSM_FID_SIGNTEXT_RESULT
|
||||
* as the field ID. Any other return value indicates an error meaning the
|
||||
* string was not signed successfully.
|
||||
*/
|
||||
CMTStatus
|
||||
CMT_SignText(PCMT_CONTROL control, CMUint32 resID, char* stringToSign,
|
||||
char* hostName, char *caOption, CMInt32 numCAs, char** caNames);
|
||||
|
||||
/*
|
||||
* FUNCTION: CMT_ProcessChallengeResponse
|
||||
* --------------------------------------
|
||||
* INPUTS:
|
||||
* control
|
||||
* The Control Connection that has already established a connection
|
||||
* with the psm server.
|
||||
* challengeString
|
||||
* The base64 encoded Challenge string received as the
|
||||
* Proof-Of-Possession Challenge in response to CRMF request that
|
||||
* specified Challenge-Reponse as the method for Proof-Of-Possession.
|
||||
* responseString
|
||||
* A pointer to pre-allocated char* where the library can place a
|
||||
* copy of the bas64 encoded response to the challenge presented.
|
||||
* NOTES
|
||||
* This function takes the a challenge--that is encrypted with the public key
|
||||
* of a certificate we created--and decrypts it with the private key we
|
||||
* generated. The format of the challenge is as follows:
|
||||
*
|
||||
* Challenge ::= SEQUENCE {
|
||||
* owf AlgorithmIdentifier OPTIONAL,
|
||||
* -- MUST be present in the first Challenge; MAY be omitted in any
|
||||
* -- subsequent Challenge in POPODecKeyChallContent (if omitted,
|
||||
* -- then the owf used in the immediately preceding Challenge is
|
||||
* -- to be used).
|
||||
* witness OCTET STRING,
|
||||
* -- the result of applying the one-way function (owf) to a
|
||||
* -- randomly-generated INTEGER, A. [Note that a different
|
||||
* -- INTEGER MUST be used for each Challenge.]
|
||||
* sender GeneralName,
|
||||
* -- the name of the sender.
|
||||
* key OCTET STRING,
|
||||
* -- the public key used to encrypt the challenge. This will allow
|
||||
* -- the client to find the appropriate key to do the decryption.
|
||||
* challenge OCTET STRING
|
||||
* -- the encryption (under the public key for which the cert.
|
||||
* -- request is being made) of Rand, where Rand is specified as
|
||||
* -- Rand ::= SEQUENCE {
|
||||
* -- int INTEGER,
|
||||
* -- - the randomly-generated INTEGER A (above)
|
||||
* -- senderHash OCTET STRING
|
||||
* -- - the result of applying the one-way function (owf) to
|
||||
* -- - the sender's general name
|
||||
* -- }
|
||||
* -- the size of "int" must be small enough such that "Rand" can be
|
||||
* -- contained within a single PKCS #1 encryption block.
|
||||
* }
|
||||
* This challenge is based on the Challenge initially defined in the CMMF
|
||||
* internet draft, but differs in that this structure includes the sender
|
||||
* as part of the challenge along with the public key and includes a has
|
||||
* of the sender in the encrypted Rand structure. The reason for including
|
||||
* the key is to facilitate looking up the key that should be used to
|
||||
* decipher the challenge. Including the hash of the sender in the encrypted
|
||||
* Rand structure makes the challenge smaller and allows it to fit in
|
||||
* one RSA block.
|
||||
*
|
||||
* The response is of the type POPODecKeyRespContent as defined in the CMMF
|
||||
* internet draft.
|
||||
*
|
||||
* RETURN
|
||||
* A return value of CMTSuccess indicates psm successfully parsed and processed
|
||||
* the challenge and created a response. The base64 encoded response to the
|
||||
* challenge is placed at *responseString. Any other return value indicates
|
||||
* an error and the value at *responseString should be ignored.
|
||||
*/
|
||||
CMTStatus
|
||||
CMT_ProcessChallengeResponse(PCMT_CONTROL control, char *challengeString,
|
||||
char **responseString);
|
||||
|
||||
/*
|
||||
* FUNCTION: CMT_GetLocalizedString
|
||||
* --------------------------------
|
||||
* INPUTS:
|
||||
* control
|
||||
* The Control Connection that has already established a connection
|
||||
* with the psm server.
|
||||
* whichString
|
||||
* The enumerated value corresponding to the localized string to
|
||||
* retrieve from the psm server
|
||||
* localizedString
|
||||
* A pointer to a pre-allocated char* where the library can place
|
||||
* copy of the localized string retrieved from the psm server.
|
||||
* NOTES
|
||||
* This function retrieves a localized string from the psm server. These
|
||||
* strings are useful for strings that aren't localized in the client
|
||||
* making use of the psm server, but need to be displayed by the user. Look
|
||||
* in protocol.h for the enumerations of the localized strings that can
|
||||
* be fetched from psm via this method.
|
||||
*
|
||||
* RETURN
|
||||
* A return value of CMTSuccess indicates the localized string was retrieved
|
||||
* successfully and the localized value is located at *localizedString. Any
|
||||
* other return value indicates an error and the value at *localizedString
|
||||
* should be ignored.
|
||||
*/
|
||||
CMTStatus
|
||||
CMT_GetLocalizedString(PCMT_CONTROL control,
|
||||
SSMLocalizedString whichString,
|
||||
char **localizedString);
|
||||
|
||||
/*
|
||||
* FUNCTION: CMT_DeleteModule
|
||||
* --------------------------
|
||||
* INPUTS:
|
||||
* control
|
||||
* The Control Connection that has already established a connection
|
||||
* with the psm server.
|
||||
* moduleName
|
||||
* The name of the PKCS11 module to delete.
|
||||
* moduleType
|
||||
* A pointer to a pre-allocated integer where the library can place
|
||||
* a value that tells what the type of module was deleted.
|
||||
* NOTES
|
||||
* This function will send a message to the psm server requesting the server
|
||||
* delete a PKCS-11 module stored in psm's security module database. moduleName
|
||||
* is the value passed in as moduleName when the module was added to the
|
||||
* security module database of psm.
|
||||
* The values that may be returned by psm for moduleType are:
|
||||
*
|
||||
* 0 The module was an external module developped by a third party
|
||||
* that was added to the psm security module.
|
||||
*
|
||||
* 1 The module deleted was the internal PKCS-11 module that comes
|
||||
* built in with the psm server.
|
||||
*
|
||||
* 2 The module that was deleted was the FIPS internal module.
|
||||
*
|
||||
* RETURN
|
||||
* A return value of CMTSuccess indicates the security module was successfully
|
||||
* delete from the psm security module database and the value at *moduleType
|
||||
* will tell what type of module was deleted.
|
||||
* Any other return value indicates an error and the value at *moduleType
|
||||
* should be ignored.
|
||||
*/
|
||||
CMTStatus
|
||||
CMT_DeleteModule(PCMT_CONTROL control,
|
||||
char *moduleName,
|
||||
int *moduleType);
|
||||
|
||||
|
||||
/*
|
||||
* FUNCTION: CMT_AddNewModule
|
||||
* --------------------------
|
||||
* INPUTS:
|
||||
* control
|
||||
* The Control Connection that has already established a connection
|
||||
* with the psm server.
|
||||
* moduleName
|
||||
* The name to be associated with the module once it is added to
|
||||
* the psm security module database.
|
||||
* libraryPath
|
||||
* The path to the library to be loaded. The library should be
|
||||
* loadable at run-time.
|
||||
* pubMechFlags
|
||||
* A bit vector indicating all cryptographic mechanisms that should
|
||||
* be turned on by default. This module will become the default
|
||||
* handler for the mechanisms that are set by this bit vector.
|
||||
* pubCipherFlags
|
||||
* A bit vector indicating all SSL or S/MIME cipher functions
|
||||
* supported by the module. Most modules will pas in 0x0 for this
|
||||
* parameter.
|
||||
* NOTES:
|
||||
* This function sends a message to the psm server and requests the .so
|
||||
* file on UNIX or .dll file on Windows be loaded as a PKCS11 module and
|
||||
* be stored in the psm security module database. The module will be stored
|
||||
* with the name moduleName that is passed in and will always expect the
|
||||
* library to live at the path passed in via the parameter libraryPath.
|
||||
* The pubMechFlags tell the psm server how this module should be used.
|
||||
* Valid values are the #define constants defined at the beginning of
|
||||
* this file.
|
||||
*
|
||||
* RETURN
|
||||
* A return value of CMTSuccess indicates the module was successfully loaded
|
||||
* and placed in the security module database of psm. Any other return value
|
||||
* indicates an error and means the module was not loaded successfully and
|
||||
* not stored in the psm server's security module database.
|
||||
*/
|
||||
CMTStatus
|
||||
CMT_AddNewModule(PCMT_CONTROL control,
|
||||
char *moduleName,
|
||||
char *libraryPath,
|
||||
unsigned long pubMechFlags,
|
||||
unsigned long pubCipherFlags);
|
||||
|
||||
CMT_END_EXTERN_C
|
||||
|
||||
#endif /*_CMTJS_H_*/
|
||||
@@ -1,75 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
#include "cmtmac.h"
|
||||
#include "macsocket.h"
|
||||
#include "stdlib.h"
|
||||
|
||||
#ifndef XP_MAC
|
||||
#error Link with the builtin strdup() on your platform.
|
||||
#endif
|
||||
|
||||
|
||||
static void
|
||||
my_strcpy(char *dest, const char *source)
|
||||
{
|
||||
char *i = dest;
|
||||
const char *j = source;
|
||||
while(*j)
|
||||
*i++ = *j++;
|
||||
*i = '\0';
|
||||
}
|
||||
|
||||
static int
|
||||
my_strlen(const char *str)
|
||||
{
|
||||
const char *c = str;
|
||||
int i = 0;
|
||||
|
||||
while(*c++ != '\0')
|
||||
i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
char * strdup(const char *oldstr)
|
||||
{
|
||||
/* used to keep the mac client library from referring to strdup elsewhere */
|
||||
char *newstr;
|
||||
|
||||
newstr = (char *) malloc(my_strlen(oldstr)+1);
|
||||
if (newstr)
|
||||
my_strcpy(newstr, oldstr);
|
||||
return newstr;
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
#ifndef __CMTMAC_H__
|
||||
#define __CMTMAC_H__
|
||||
|
||||
char * strdup(const char *str);
|
||||
|
||||
#endif
|
||||
@@ -1,119 +0,0 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
/************************************************************************
|
||||
* Code to handle password requests from the the PSM module.
|
||||
*
|
||||
************************************************************************
|
||||
*/
|
||||
|
||||
#include "cmtcmn.h"
|
||||
#include "cmtutils.h"
|
||||
#include "messages.h"
|
||||
|
||||
void CMT_SetAppFreeCallback(PCMT_CONTROL control,
|
||||
applicationFreeCallback_fn f)
|
||||
{
|
||||
control->userFuncs.userFree = f;
|
||||
}
|
||||
|
||||
void CMT_ServicePasswordRequest(PCMT_CONTROL cm_control, CMTItem * requestData)
|
||||
{
|
||||
CMTItem response = {0, NULL, 0};
|
||||
PasswordRequest request;
|
||||
PasswordReply reply;
|
||||
void * clientContext;
|
||||
|
||||
/********************************************
|
||||
* What we trying to do here:
|
||||
* 1) Throw up a dialog box and request a password.
|
||||
* 2) Create a message and send it to the PSM module.
|
||||
********************************************
|
||||
*/
|
||||
|
||||
/* Decode the request */
|
||||
if (CMT_DecodeMessage(PasswordRequestTemplate, &request, requestData) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Copy the client context to a pointer */
|
||||
clientContext = CMT_CopyItemToPtr(request.clientContext);
|
||||
|
||||
if (cm_control->userFuncs.promptCallback == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
reply.passwd =
|
||||
cm_control->userFuncs.promptCallback(cm_control->userFuncs.promptArg,
|
||||
request.prompt, clientContext, 1);
|
||||
reply.tokenID = request.tokenKey;
|
||||
if (!reply.passwd) {
|
||||
/* the user cancelled the prompt or other errors occurred */
|
||||
reply.result = -1;
|
||||
}
|
||||
else {
|
||||
/* note that this includes an empty string (zero length password) */
|
||||
reply.result = 0;
|
||||
}
|
||||
|
||||
/* Encode the reply */
|
||||
if (CMT_EncodeMessage(PasswordReplyTemplate, &response, &reply) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message response type */
|
||||
response.type = SSM_EVENT_MESSAGE | SSM_AUTH_EVENT;
|
||||
CMT_TransmitMessage(cm_control, &response);
|
||||
goto done;
|
||||
loser:
|
||||
/* something has gone wrong */
|
||||
|
||||
done:
|
||||
/*clean up anyway */
|
||||
/* We can't just free up memory allocated by the host
|
||||
application because the versions of free may not match up.
|
||||
When you run the plug-in with an optimized older browser,
|
||||
you'll see tons of Asserts (why they still have asserts in an
|
||||
optimized build is a different question, but without them
|
||||
I wouldn't have figured out this problem) about a pointer not
|
||||
being a valid heap pointer and eventually crash. This was
|
||||
the offending free line.
|
||||
So we need to call a function within the browser that
|
||||
calls the free linked in with it. js_free is
|
||||
such a function. But this is extremely ugly.
|
||||
*/
|
||||
if (reply.passwd)
|
||||
cm_control->userFuncs.userFree(reply.passwd);
|
||||
if (request.prompt)
|
||||
free(request.prompt);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,636 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifdef XP_UNIX
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/time.h>
|
||||
#else
|
||||
#ifdef XP_MAC
|
||||
#include "macsocket.h"
|
||||
#else /* Windows */
|
||||
#include <windows.h>
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include "cmtcmn.h"
|
||||
#include "cmtutils.h"
|
||||
#include "messages.h"
|
||||
#include "rsrcids.h"
|
||||
|
||||
typedef struct _CMTP7Private {
|
||||
CMTPrivate priv;
|
||||
CMTP7ContentCallback cb;
|
||||
void *cb_arg;
|
||||
} CMTP7Private;
|
||||
|
||||
CMTStatus CMT_PKCS7DecoderStart(PCMT_CONTROL control, void* clientContext, CMUint32 * connectionID, CMInt32 * result,
|
||||
CMTP7ContentCallback cb, void *cb_arg)
|
||||
{
|
||||
CMTItem message;
|
||||
CMTStatus rv;
|
||||
CMTP7Private *priv=NULL;
|
||||
SingleItemMessage request;
|
||||
DataConnectionReply reply;
|
||||
|
||||
/* Check passed in parameters */
|
||||
if (!control) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
request.item = CMT_CopyPtrToItem(clientContext);
|
||||
|
||||
/* Encode message */
|
||||
if (CMT_EncodeMessage(SingleItemMessageTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_DATA_CONNECTION | SSM_PKCS7DECODE_STREAM;
|
||||
|
||||
/* Send the message. */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_DATA_CONNECTION | SSM_PKCS7DECODE_STREAM)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the reply */
|
||||
if (CMT_DecodeMessage(DataConnectionReplyTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
if (reply.result == 0) {
|
||||
CMTSocket sock;
|
||||
|
||||
priv = (CMTP7Private *)malloc(sizeof(CMTP7Private));
|
||||
if (priv == NULL)
|
||||
goto loser;
|
||||
priv->priv.dest = (CMTReclaimFunc) free;
|
||||
priv->cb = cb;
|
||||
priv->cb_arg = cb_arg;
|
||||
sock = control->sockFuncs.socket(0);
|
||||
if (sock == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (control->sockFuncs.connect(sock, (short)reply.port,
|
||||
NULL) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (control->sockFuncs.send(sock, control->nonce.data,
|
||||
control->nonce.len) != control->nonce.len){
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Save connection info */
|
||||
if (CMT_AddDataConnection(control, sock, reply.connID)
|
||||
!= CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
*connectionID = reply.connID;
|
||||
|
||||
rv = CMT_SetPrivate(control, reply.connID, &priv->priv);
|
||||
if (rv != CMTSuccess)
|
||||
goto loser;
|
||||
|
||||
return CMTSuccess;
|
||||
}
|
||||
|
||||
loser:
|
||||
if (priv) {
|
||||
free(priv);
|
||||
}
|
||||
|
||||
*result = reply.result;
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_PKCS7DecoderUpdate(PCMT_CONTROL control, CMUint32 connectionID, const char * buf, CMUint32 len)
|
||||
{
|
||||
CMUint32 sent;
|
||||
CMTP7Private *priv;
|
||||
unsigned long nbytes;
|
||||
char read_buf[128];
|
||||
CMTSocket sock, ctrlsock, selSock, sockArr[2];
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control || !buf) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Get the data socket */
|
||||
if (CMT_GetDataSocket(control, connectionID, &sock) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
priv = (CMTP7Private *)CMT_GetPrivate(control, connectionID);
|
||||
if (priv == NULL)
|
||||
goto loser;
|
||||
|
||||
/* Write the data to the socket */
|
||||
sent = CMT_WriteThisMany(control, sock, (void*)buf, len);
|
||||
if (sent != len) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
ctrlsock = control->sock;
|
||||
sockArr[0] = ctrlsock;
|
||||
sockArr[1] = sock;
|
||||
while ((selSock = control->sockFuncs.select(sockArr,2,1)))
|
||||
{
|
||||
if (selSock == ctrlsock) {
|
||||
CMT_ProcessEvent(control);
|
||||
} else {
|
||||
nbytes = control->sockFuncs.recv(sock, read_buf, sizeof(read_buf));
|
||||
if (nbytes == -1) {
|
||||
goto loser;
|
||||
}
|
||||
if (nbytes == 0) {
|
||||
break;
|
||||
}
|
||||
priv->cb(priv->cb_arg, read_buf, nbytes);
|
||||
}
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_PKCS7DecoderFinish(PCMT_CONTROL control, CMUint32 connectionID,
|
||||
CMUint32 * resourceID)
|
||||
{
|
||||
CMTP7Private *priv;
|
||||
long nbytes;
|
||||
char buf[128];
|
||||
CMTSocket sock, ctrlsock, selSock, sockArr[2];
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
priv = (CMTP7Private *)CMT_GetPrivate(control, connectionID);
|
||||
if (priv == NULL)
|
||||
goto loser;
|
||||
|
||||
if (CMT_GetDataSocket(control, connectionID, &sock) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
ctrlsock = control->sock;
|
||||
/* drain socket before we close it */
|
||||
control->sockFuncs.shutdown(sock);
|
||||
sockArr[0] = sock;
|
||||
sockArr[1] = ctrlsock;
|
||||
/* Let's see if doing a poll first gets rid of a weird bug where we
|
||||
* lock up the client.
|
||||
*/
|
||||
#ifndef XP_MAC
|
||||
if (control->sockFuncs.select(sockArr,2,1) != NULL)
|
||||
#endif
|
||||
{
|
||||
while (1) {
|
||||
selSock = control->sockFuncs.select(sockArr,2,0);
|
||||
if (selSock == ctrlsock) {
|
||||
CMT_ProcessEvent(control);
|
||||
} else if (selSock == sock) {
|
||||
nbytes = control->sockFuncs.recv(sock, buf, sizeof(buf));
|
||||
if (nbytes < 0) {
|
||||
goto loser;
|
||||
} else if (nbytes == 0) {
|
||||
break;
|
||||
}
|
||||
priv->cb(priv->cb_arg, buf, nbytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (CMT_CloseDataConnection(control, connectionID) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Get the PKCS7 content info */
|
||||
if (CMT_GetRIDAttribute(control, connectionID, SSM_FID_P7CONN_CONTENT_INFO,
|
||||
resourceID) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
|
||||
loser:
|
||||
if (control) {
|
||||
CMT_CloseDataConnection(control, connectionID);
|
||||
}
|
||||
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_PKCS7DestroyContentInfo(PCMT_CONTROL control, CMUint32 resourceID)
|
||||
{
|
||||
if (!control) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Delete the resource */
|
||||
if (CMT_DestroyResource(control, resourceID, SSM_FID_P7CONN_CONTENT_INFO) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
return CMTSuccess;
|
||||
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_PKCS7VerifyDetachedSignature(PCMT_CONTROL control, CMUint32 resourceID, CMUint32 certUsage, CMUint32 hashAlgID, CMUint32 keepCerts, CMTItem* digest, CMInt32 * result)
|
||||
{
|
||||
CMTItem message;
|
||||
VerifyDetachedSigRequest request;
|
||||
SingleNumMessage reply;
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control || !digest || !result) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the request */
|
||||
request.pkcs7ContentID = resourceID;
|
||||
request.certUsage = certUsage;
|
||||
request.hashAlgID = hashAlgID;
|
||||
request.keepCert = (CMBool) keepCerts;
|
||||
request.hash = *digest;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(VerifyDetachedSigRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_OBJECT_SIGNING | SSM_VERIFY_DETACHED_SIG;
|
||||
|
||||
/* Send the message */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_OBJECT_SIGNING |SSM_VERIFY_DETACHED_SIG)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the reply */
|
||||
if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
*result = reply.value;
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
*result = reply.value;
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_PKCS7VerifySignature(PCMT_CONTROL control, CMUint32 pubKeyAlgID,
|
||||
CMTItem *pubKeyParams, CMTItem *signerPubKey,
|
||||
CMTItem *computedHash, CMTItem *signature,
|
||||
CMInt32 *result)
|
||||
{
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_CreateSigned(PCMT_CONTROL control, CMUint32 scertRID,
|
||||
CMUint32 ecertRID, CMUint32 dig_alg,
|
||||
CMTItem *digest, CMUint32 *ciRID, CMInt32 *errCode)
|
||||
{
|
||||
CMTItem message;
|
||||
CreateSignedRequest request;
|
||||
CreateContentInfoReply reply;
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control || !scertRID || !ecertRID || !digest || !ciRID) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the request */
|
||||
request.scertRID = scertRID;
|
||||
request.ecertRID = ecertRID;
|
||||
request.dig_alg = dig_alg;
|
||||
request.digest = *digest;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(CreateSignedRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_OBJECT_SIGNING | SSM_CREATE_SIGNED;
|
||||
|
||||
/* Send the message */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_OBJECT_SIGNING | SSM_CREATE_SIGNED)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the reply */
|
||||
if (CMT_DecodeMessage(CreateContentInfoReplyTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
*ciRID = reply.ciRID;
|
||||
if (reply.result == 0) {
|
||||
return CMTSuccess;
|
||||
}
|
||||
|
||||
loser:
|
||||
if (CMT_DecodeMessage(CreateContentInfoReplyTemplate, &reply, &message) == CMTSuccess) {
|
||||
*errCode = reply.errorCode;
|
||||
} else {
|
||||
*errCode = 0;
|
||||
}
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_CreateEncrypted(PCMT_CONTROL control, CMUint32 scertRID,
|
||||
CMUint32 *rcertRIDs, CMUint32 *ciRID)
|
||||
{
|
||||
CMTItem message;
|
||||
CMInt32 nrcerts;
|
||||
CreateEncryptedRequest request;
|
||||
CreateContentInfoReply reply;
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control || !scertRID || !rcertRIDs || !ciRID) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Calculate the number of certs */
|
||||
for (nrcerts =0; rcertRIDs[nrcerts] != 0; nrcerts++) {
|
||||
/* Nothing */
|
||||
;
|
||||
}
|
||||
|
||||
/* Set up the request */
|
||||
request.scertRID = scertRID;
|
||||
request.nrcerts = nrcerts;
|
||||
request.rcertRIDs = (long *) rcertRIDs;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(CreateEncryptedRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_OBJECT_SIGNING | SSM_CREATE_ENCRYPTED;
|
||||
|
||||
/* Send the message */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message response type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_OBJECT_SIGNING | SSM_CREATE_ENCRYPTED)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the reply */
|
||||
if (CMT_DecodeMessage(CreateContentInfoReplyTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
*ciRID = reply.ciRID;
|
||||
if (reply.result == 0) {
|
||||
return CMTSuccess;
|
||||
}
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_PKCS7EncoderStart(PCMT_CONTROL control, CMUint32 ciRID,
|
||||
CMUint32 *connectionID, CMTP7ContentCallback cb,
|
||||
void *cb_arg)
|
||||
{
|
||||
CMTItem message;
|
||||
CMTStatus rv;
|
||||
CMTP7Private *priv;
|
||||
PKCS7DataConnectionRequest request;
|
||||
DataConnectionReply reply;
|
||||
|
||||
/* Check passed in parameters */
|
||||
if (!control || !ciRID) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set up the request */
|
||||
request.resID = ciRID;
|
||||
request.clientContext.len = 0;
|
||||
request.clientContext.data = NULL;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(PKCS7DataConnectionRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_DATA_CONNECTION | SSM_PKCS7ENCODE_STREAM;
|
||||
|
||||
/* Send the message */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_DATA_CONNECTION | SSM_PKCS7ENCODE_STREAM)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the reply */
|
||||
if (CMT_DecodeMessage(DataConnectionReplyTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
if (reply.result == 0) {
|
||||
CMTSocket sock;
|
||||
|
||||
priv = (CMTP7Private *)malloc(sizeof(CMTP7Private));
|
||||
if (priv == NULL)
|
||||
goto loser;
|
||||
priv->priv.dest = (CMTReclaimFunc) free;
|
||||
priv->cb = cb;
|
||||
priv->cb_arg = cb_arg;
|
||||
|
||||
sock = control->sockFuncs.socket(0);
|
||||
if (sock == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
if (control->sockFuncs.connect(sock, (short)reply.port,
|
||||
NULL) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
if (control->sockFuncs.send(sock, control->nonce.data,
|
||||
control->nonce.len) != control->nonce.len) {
|
||||
goto loser;
|
||||
}
|
||||
/* Save connection info */
|
||||
if (CMT_AddDataConnection(control, sock, reply.connID)
|
||||
!= CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
*connectionID = reply.connID;
|
||||
|
||||
rv = CMT_SetPrivate(control, reply.connID, &priv->priv);
|
||||
if (rv != CMTSuccess)
|
||||
goto loser;
|
||||
return CMTSuccess;
|
||||
}
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_PKCS7EncoderUpdate(PCMT_CONTROL control, CMUint32 connectionID,
|
||||
const char *buf, CMUint32 len)
|
||||
{
|
||||
CMUint32 sent;
|
||||
CMTP7Private *priv;
|
||||
unsigned long nbytes;
|
||||
char read_buf[128];
|
||||
CMTSocket sock, ctrlsock, sockArr[2], selSock;
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control || !connectionID || !buf) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Get the data socket */
|
||||
if (CMT_GetDataSocket(control, connectionID, &sock) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
priv = (CMTP7Private *)CMT_GetPrivate(control, connectionID);
|
||||
if (priv == NULL)
|
||||
goto loser;
|
||||
|
||||
/* Write the data to the socket */
|
||||
sent = CMT_WriteThisMany(control, sock, (void*)buf, len);
|
||||
if (sent != len) {
|
||||
goto loser;
|
||||
}
|
||||
ctrlsock = control->sock;
|
||||
sockArr[0] = ctrlsock;
|
||||
sockArr[1] = sock;
|
||||
while ((selSock = control->sockFuncs.select(sockArr, 2, 1)) != NULL)
|
||||
{
|
||||
if (selSock == ctrlsock) {
|
||||
CMT_ProcessEvent(control);
|
||||
} else {
|
||||
nbytes = control->sockFuncs.recv(sock, read_buf, sizeof(read_buf));
|
||||
if (nbytes == -1) {
|
||||
goto loser;
|
||||
} else if (nbytes == 0) {
|
||||
break;
|
||||
} else {
|
||||
priv->cb(priv->cb_arg, read_buf, nbytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
return CMTSuccess;
|
||||
|
||||
loser:
|
||||
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_PKCS7EncoderFinish(PCMT_CONTROL control, CMUint32 connectionID)
|
||||
{
|
||||
CMTP7Private *priv;
|
||||
unsigned long nbytes;
|
||||
char buf[128];
|
||||
CMTSocket sock, ctrlsock, sockArr[2], selSock;
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
priv = (CMTP7Private *)CMT_GetPrivate(control, connectionID);
|
||||
if (priv == NULL)
|
||||
goto loser;
|
||||
|
||||
if (CMT_GetDataSocket(control, connectionID, &sock) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
ctrlsock = control->sock;
|
||||
sockArr[0] = ctrlsock;
|
||||
sockArr[1] = sock;
|
||||
control->sockFuncs.shutdown(sock);
|
||||
while (1) {
|
||||
selSock = control->sockFuncs.select(sockArr, 2, 0);
|
||||
if (selSock == ctrlsock) {
|
||||
CMT_ProcessEvent(control);
|
||||
} else if (selSock == sock) {
|
||||
nbytes = control->sockFuncs.recv(sock, buf, sizeof(buf));
|
||||
if (nbytes < 0) {
|
||||
goto loser;
|
||||
} else if (nbytes == 0) {
|
||||
break;
|
||||
} else {
|
||||
priv->cb(priv->cb_arg, buf, nbytes);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (CMT_CloseDataConnection(control, connectionID) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
|
||||
loser:
|
||||
if (control) {
|
||||
CMT_CloseDataConnection(control, connectionID);
|
||||
}
|
||||
|
||||
return CMTFailure;
|
||||
}
|
||||
@@ -1,479 +0,0 @@
|
||||
/* -*- mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifdef XP_UNIX
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#else
|
||||
#ifdef XP_MAC
|
||||
#include "macsocket.h"
|
||||
#else
|
||||
#include <windows.h>
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include "cmtcmn.h"
|
||||
#include "cmtutils.h"
|
||||
#include "messages.h"
|
||||
#include <string.h>
|
||||
|
||||
CMTStatus CMT_GetNumericAttribute(PCMT_CONTROL control, CMUint32 resourceID, CMUint32 fieldID, CMInt32 *value)
|
||||
{
|
||||
CMTItem message;
|
||||
GetAttribRequest request;
|
||||
GetAttribReply reply;
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set up the request */
|
||||
request.resID = resourceID;
|
||||
request.fieldID = fieldID;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(GetAttribRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_RESOURCE_ACTION | SSM_GET_ATTRIBUTE | SSM_NUMERIC_ATTRIBUTE;
|
||||
|
||||
/* Send the mesage and get the response */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_RESOURCE_ACTION | SSM_GET_ATTRIBUTE | SSM_NUMERIC_ATTRIBUTE)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the reply */
|
||||
if (CMT_DecodeMessage(GetAttribReplyTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
*value = reply.value.u.numeric;
|
||||
|
||||
/* Success */
|
||||
if (reply.result == 0) {
|
||||
return CMTSuccess;
|
||||
}
|
||||
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_SetNumericAttribute(PCMT_CONTROL control, CMUint32 resourceID,
|
||||
CMUint32 fieldID, CMInt32 value)
|
||||
{
|
||||
CMTItem message;
|
||||
SetAttribRequest request;
|
||||
|
||||
if (!control) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the request */
|
||||
request.resID = resourceID;
|
||||
request.fieldID = fieldID;
|
||||
request.value.type = SSM_NUMERIC_ATTRIBUTE;
|
||||
request.value.u.numeric = value;
|
||||
|
||||
/* Encode the message */
|
||||
if (CMT_EncodeMessage(SetAttribRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_RESOURCE_ACTION |
|
||||
SSM_SET_ATTRIBUTE | SSM_NUMERIC_ATTRIBUTE;
|
||||
|
||||
if (CMT_SendMessage(control, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_RESOURCE_ACTION |
|
||||
SSM_SET_ATTRIBUTE | SSM_NUMERIC_ATTRIBUTE)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus
|
||||
CMT_PadStringValue(CMTItem *dest, CMTItem src)
|
||||
{
|
||||
dest->data = NewArray(unsigned char, src.len+1);
|
||||
if (dest->data == NULL) {
|
||||
return CMTFailure;
|
||||
}
|
||||
memcpy(dest->data, src.data, src.len);
|
||||
dest->data[src.len] = '\0';
|
||||
dest->len = src.len;
|
||||
free(src.data);
|
||||
return CMTSuccess;
|
||||
}
|
||||
|
||||
CMTStatus CMT_GetStringAttribute(PCMT_CONTROL control, CMUint32 resourceID, CMUint32 fieldID, CMTItem *value)
|
||||
{
|
||||
CMTItem message;
|
||||
GetAttribRequest request;
|
||||
GetAttribReply reply;
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set up the request */
|
||||
request.resID = resourceID;
|
||||
request.fieldID = fieldID;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(GetAttribRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_RESOURCE_ACTION | SSM_GET_ATTRIBUTE | SSM_STRING_ATTRIBUTE;
|
||||
|
||||
/* Send the mesage and get the response */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_RESOURCE_ACTION | SSM_GET_ATTRIBUTE | SSM_STRING_ATTRIBUTE)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the response */
|
||||
if (CMT_DecodeMessage(GetAttribReplyTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
if (reply.result == 0) {
|
||||
return CMT_PadStringValue(value, reply.value.u.string);
|
||||
}
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus
|
||||
CMT_SetStringAttribute(PCMT_CONTROL control, CMUint32 resourceID,
|
||||
CMUint32 fieldID, CMTItem *value)
|
||||
{
|
||||
CMTItem message;
|
||||
SetAttribRequest request;
|
||||
|
||||
if (!control) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set up the request */
|
||||
request.resID = resourceID;
|
||||
request.fieldID = fieldID;
|
||||
request.value.type = SSM_STRING_ATTRIBUTE;
|
||||
request.value.u.string = *value;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(SetAttribRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_RESOURCE_ACTION |
|
||||
SSM_SET_ATTRIBUTE | SSM_STRING_ATTRIBUTE;
|
||||
|
||||
/* Send the message */
|
||||
if (CMT_SendMessage(control, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message request type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_RESOURCE_ACTION |
|
||||
SSM_SET_ATTRIBUTE | SSM_STRING_ATTRIBUTE)) {
|
||||
goto loser;
|
||||
}
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_DuplicateResource(PCMT_CONTROL control, CMUint32 resourceID,
|
||||
CMUint32 *newResID)
|
||||
{
|
||||
CMTItem message;
|
||||
SingleNumMessage request;
|
||||
DupResourceReply reply;
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set up the request */
|
||||
request.value = resourceID;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(SingleNumMessageTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_RESOURCE_ACTION | SSM_DUPLICATE_RESOURCE;
|
||||
|
||||
/* Send the mesage */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_RESOURCE_ACTION | SSM_DUPLICATE_RESOURCE)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the reply */
|
||||
if (CMT_DecodeMessage(DupResourceReplyTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
if (reply.result == 0) {
|
||||
*newResID = reply.resID;
|
||||
return CMTSuccess;
|
||||
}
|
||||
|
||||
loser:
|
||||
*newResID = 0;
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_DestroyResource(PCMT_CONTROL control, CMUint32 resourceID, CMUint32 resourceType)
|
||||
{
|
||||
CMTItem message;
|
||||
DestroyResourceRequest request;
|
||||
SingleNumMessage reply;
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set up the request */
|
||||
request.resID = resourceID;
|
||||
request.resType = resourceType;
|
||||
|
||||
/* Encode the message */
|
||||
if (CMT_EncodeMessage(DestroyResourceRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_RESOURCE_ACTION | SSM_DESTROY_RESOURCE;
|
||||
|
||||
/* Send the message */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_RESOURCE_ACTION | SSM_DESTROY_RESOURCE)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the reply */
|
||||
if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
if (reply.value == 0) {
|
||||
return CMTSuccess;
|
||||
}
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_PickleResource(PCMT_CONTROL control, CMUint32 resourceID, CMTItem * pickledResource)
|
||||
{
|
||||
CMTItem message;
|
||||
SingleNumMessage request;
|
||||
PickleResourceReply reply;
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set up the request */
|
||||
request.value = resourceID;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(SingleNumMessageTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_RESOURCE_ACTION | SSM_CONSERVE_RESOURCE | SSM_PICKLE_RESOURCE;
|
||||
|
||||
/* Send the mesage and get the response */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_RESOURCE_ACTION | SSM_CONSERVE_RESOURCE | SSM_PICKLE_RESOURCE)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the reply */
|
||||
if (CMT_DecodeMessage(PickleResourceReplyTemplate, &reply,&message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
if (reply.result == 0) {
|
||||
*pickledResource = reply.blob;
|
||||
return CMTSuccess;
|
||||
}
|
||||
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_UnpickleResource(PCMT_CONTROL control, CMUint32 resourceType, CMTItem pickledResource, CMUint32 * resourceID)
|
||||
{
|
||||
CMTItem message;
|
||||
UnpickleResourceRequest request;
|
||||
UnpickleResourceReply reply;
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set up the request */
|
||||
request.resourceType = resourceType;
|
||||
request.resourceData = pickledResource;
|
||||
|
||||
/* Encode the request */
|
||||
if (CMT_EncodeMessage(UnpickleResourceRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_RESOURCE_ACTION | SSM_CONSERVE_RESOURCE | SSM_UNPICKLE_RESOURCE;
|
||||
|
||||
/* Send the mesage and get the response */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_RESOURCE_ACTION | SSM_CONSERVE_RESOURCE | SSM_UNPICKLE_RESOURCE)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the reply */
|
||||
if (CMT_DecodeMessage(UnpickleResourceReplyTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
if (reply.result == 0) {
|
||||
*resourceID = reply.resID;
|
||||
return CMTSuccess;
|
||||
}
|
||||
|
||||
loser:
|
||||
*resourceID = 0;
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_GetRIDAttribute(PCMT_CONTROL control, CMUint32 resourceID, CMUint32 fieldID, CMUint32 *value)
|
||||
{
|
||||
CMTItem message;
|
||||
GetAttribRequest request;
|
||||
GetAttribReply reply;
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the request */
|
||||
request.resID = resourceID;
|
||||
request.fieldID = fieldID;
|
||||
|
||||
/* Encode the message */
|
||||
if (CMT_EncodeMessage(GetAttribRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_RESOURCE_ACTION | SSM_GET_ATTRIBUTE | SSM_RID_ATTRIBUTE;
|
||||
|
||||
/* Send the mesage and get the response */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message response type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_RESOURCE_ACTION | SSM_GET_ATTRIBUTE | SSM_RID_ATTRIBUTE)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode the reply */
|
||||
if (CMT_DecodeMessage(GetAttribReplyTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
if (reply.result == 0) {
|
||||
*value = reply.value.u.rid;
|
||||
return CMTSuccess;
|
||||
}
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
@@ -1,270 +0,0 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
/*
|
||||
cmtrng.c -- Support for PSM random number generator and the seeding
|
||||
thereof with data from the client.
|
||||
|
||||
Created by mwelch 1999 Oct 21
|
||||
*/
|
||||
#include "cmtcmn.h"
|
||||
#include "cmtutils.h"
|
||||
#include "messages.h"
|
||||
#include "rsrcids.h"
|
||||
#include <string.h>
|
||||
|
||||
CMTStatus
|
||||
CMT_EnsureInitializedRNGBuf(PCMT_CONTROL control)
|
||||
{
|
||||
if (control->rng.outBuf == NULL)
|
||||
{
|
||||
control->rng.outBuf = (char *) calloc(RNG_OUT_BUFFER_LEN, sizeof(char));
|
||||
if (control->rng.outBuf == NULL)
|
||||
goto loser;
|
||||
|
||||
control->rng.validOutBytes = 0;
|
||||
control->rng.out_cur = control->rng.outBuf;
|
||||
control->rng.out_end = control->rng.out_cur + RNG_OUT_BUFFER_LEN;
|
||||
|
||||
control->rng.inBuf = (char *) calloc(RNG_IN_BUFFER_LEN, sizeof(char));
|
||||
if (control->rng.outBuf == NULL)
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
|
||||
loser:
|
||||
if (control->rng.outBuf != NULL)
|
||||
{
|
||||
free(control->rng.outBuf);
|
||||
control->rng.outBuf = NULL;
|
||||
}
|
||||
if (control->rng.inBuf != NULL)
|
||||
{
|
||||
free(control->rng.inBuf);
|
||||
control->rng.inBuf = NULL;
|
||||
}
|
||||
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
CMT_RequestPSMRandomData(PCMT_CONTROL control,
|
||||
void *buf, CMUint32 maxbytes)
|
||||
{
|
||||
SingleNumMessage req;
|
||||
SingleItemMessage reply;
|
||||
CMTItem message;
|
||||
size_t rv = 0;
|
||||
|
||||
/* Parameter checking */
|
||||
if (!control || !buf || (maxbytes == 0))
|
||||
goto loser;
|
||||
|
||||
/* Initialization. */
|
||||
memset(&reply, 0, sizeof(SingleItemMessage));
|
||||
|
||||
/* Ask PSM for the data. */
|
||||
req.value = maxbytes;
|
||||
if (CMT_EncodeMessage(SingleNumMessageTemplate, &message, &req) != CMTSuccess)
|
||||
goto loser;
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_MISC_ACTION | SSM_MISC_GET_RNG_DATA;
|
||||
|
||||
/* Send the message and get the response */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure)
|
||||
goto loser;
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_MISC_ACTION | SSM_MISC_GET_RNG_DATA))
|
||||
goto loser;
|
||||
|
||||
/* Decode message */
|
||||
if (CMT_DecodeMessage(SingleItemMessageTemplate, &reply, &message) != CMTSuccess)
|
||||
goto loser;
|
||||
|
||||
/* Success - fill the return buf with what we got */
|
||||
if (reply.item.len > maxbytes)
|
||||
reply.item.len = maxbytes;
|
||||
|
||||
memcpy(buf, reply.item.data, reply.item.len);
|
||||
rv = reply.item.len;
|
||||
|
||||
loser:
|
||||
if (reply.item.data)
|
||||
free(reply.item.data);
|
||||
if (message.data)
|
||||
free(message.data);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
size_t
|
||||
CMT_GenerateRandomBytes(PCMT_CONTROL control,
|
||||
void *buf, CMUint32 maxbytes)
|
||||
{
|
||||
CMUint32 remaining = maxbytes;
|
||||
CMT_RNGState *rng = &(control->rng);
|
||||
char *walk = (char *) buf;
|
||||
|
||||
/* Is there already enough in the incoming cache? */
|
||||
while(remaining > rng->validInBytes)
|
||||
{
|
||||
/* Get what we have on hand. */
|
||||
memcpy(walk, rng->in_cur, rng->validInBytes);
|
||||
walk += rng->validInBytes;
|
||||
remaining -= rng->validInBytes;
|
||||
|
||||
/* Request a buffer from PSM. */
|
||||
rng->validInBytes = CMT_RequestPSMRandomData(control,
|
||||
rng->inBuf,
|
||||
RNG_IN_BUFFER_LEN);
|
||||
if (rng->validInBytes == 0)
|
||||
return (maxbytes - remaining); /* call failed */
|
||||
rng->in_cur = rng->inBuf;
|
||||
}
|
||||
if (remaining > 0)
|
||||
{
|
||||
memcpy(walk, rng->in_cur, remaining);
|
||||
rng->in_cur += remaining;
|
||||
rng->validInBytes -= remaining;
|
||||
}
|
||||
return maxbytes;
|
||||
}
|
||||
|
||||
void
|
||||
cmt_rng_xor(void *dstBuf, void *srcBuf, int len)
|
||||
{
|
||||
unsigned char *s = (unsigned char*) srcBuf;
|
||||
unsigned char *d = (unsigned char*) dstBuf;
|
||||
unsigned char tmp;
|
||||
int i;
|
||||
|
||||
for(i=0; i<len; i++, s++, d++)
|
||||
{
|
||||
tmp = *d;
|
||||
/* I wish C had circular shift operators. So do others on the team. */
|
||||
tmp = ((tmp << 1) | (tmp >> 7));
|
||||
*d = tmp ^ *s;
|
||||
}
|
||||
}
|
||||
|
||||
CMTStatus
|
||||
CMT_RandomUpdate(PCMT_CONTROL control, void *data, size_t numbytes)
|
||||
{
|
||||
size_t dataLeft = numbytes, cacheLeft;
|
||||
char *walk = (char *) data;
|
||||
|
||||
if (CMT_EnsureInitializedRNGBuf(control) != CMTSuccess)
|
||||
goto loser;
|
||||
|
||||
/* If we have more than what the buffer can handle, wrap around. */
|
||||
cacheLeft = (control->rng.out_end - control->rng.out_cur);
|
||||
while (dataLeft >= cacheLeft)
|
||||
{
|
||||
cmt_rng_xor(control->rng.out_cur, walk, cacheLeft);
|
||||
walk += cacheLeft;
|
||||
dataLeft -= cacheLeft;
|
||||
|
||||
control->rng.out_cur = control->rng.outBuf;
|
||||
|
||||
/* Max out used space */
|
||||
control->rng.validOutBytes = cacheLeft = RNG_OUT_BUFFER_LEN;
|
||||
}
|
||||
|
||||
/*
|
||||
We now have less seed data available than we do space in the buf.
|
||||
Write what we have and update validOutBytes if we're not looping already.
|
||||
*/
|
||||
cmt_rng_xor(control->rng.out_cur, walk, dataLeft);
|
||||
control->rng.out_cur += dataLeft;
|
||||
if (control->rng.validOutBytes < RNG_OUT_BUFFER_LEN)
|
||||
control->rng.validOutBytes += dataLeft;
|
||||
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
size_t
|
||||
CMT_GetNoise(PCMT_CONTROL control, void *buf, CMUint32 maxbytes)
|
||||
{
|
||||
/* ### mwelch - GetNoise and GenerateRandomBytes can be the
|
||||
same function now, because presumably the RNG is being
|
||||
seeded with environmental noise on the PSM end before we
|
||||
make any of these requests */
|
||||
return CMT_GenerateRandomBytes(control, buf, maxbytes);
|
||||
}
|
||||
|
||||
CMTStatus
|
||||
CMT_FlushPendingRandomData(PCMT_CONTROL control)
|
||||
{
|
||||
CMTItem message;
|
||||
|
||||
memset(&message, 0, sizeof(CMTItem));
|
||||
|
||||
if (CMT_EnsureInitializedRNGBuf(control) != CMTSuccess)
|
||||
return CMTFailure; /* couldn't initialize RNG buffer */
|
||||
|
||||
if (control->rng.validOutBytes == 0)
|
||||
return CMTSuccess; /* no random data available == we're flushed */
|
||||
|
||||
/* We have random data available. Send this to PSM.
|
||||
We're sending an event, so no reply is needed. */
|
||||
message.type = SSM_EVENT_MESSAGE
|
||||
| SSM_MISC_ACTION
|
||||
| SSM_MISC_PUT_RNG_DATA;
|
||||
message.len = control->rng.validOutBytes;
|
||||
message.data = (unsigned char *) calloc(message.len, sizeof(char));
|
||||
if (!message.data)
|
||||
goto loser;
|
||||
memcpy(message.data, control->rng.outBuf, message.len);
|
||||
|
||||
if (CMT_TransmitMessage(control, &message) == CMTFailure)
|
||||
goto loser;
|
||||
|
||||
/* Clear the RNG ring buffer, we've used that data */
|
||||
control->rng.out_cur = control->rng.outBuf;
|
||||
control->rng.validOutBytes = 0;
|
||||
/* zero the buffer, because we XOR in new data */
|
||||
memset(control->rng.outBuf, 0, RNG_OUT_BUFFER_LEN);
|
||||
|
||||
goto done;
|
||||
loser:
|
||||
if (message.data)
|
||||
free(message.data);
|
||||
return CMTFailure;
|
||||
done:
|
||||
return CMTSuccess;
|
||||
}
|
||||
@@ -1,237 +0,0 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
/*
|
||||
cmtsdr.c -- Support for the Secret Decoder Ring, which provides
|
||||
encryption and decryption using stored keys.
|
||||
|
||||
Created by thayes 18 April 2000
|
||||
*/
|
||||
#include "stddef.h"
|
||||
#include "cmtcmn.h"
|
||||
#include "cmtutils.h"
|
||||
#include "messages.h"
|
||||
#include "protocolshr.h"
|
||||
#include "rsrcids.h"
|
||||
#include <string.h>
|
||||
|
||||
#undef PROCESS_LOCALLY
|
||||
|
||||
/* Encryption result - contains the key id and the resulting data */
|
||||
/* An empty key id indicates that NO encryption was performed */
|
||||
typedef struct EncryptionResult
|
||||
{
|
||||
CMTItem keyid;
|
||||
CMTItem data;
|
||||
} EncryptionResult;
|
||||
|
||||
/* Constants for testing */
|
||||
static const char *kPrefix = "Encrypted:";
|
||||
|
||||
static CMTItem
|
||||
CMT_CopyDataToItem(const unsigned char *data, CMUint32 len)
|
||||
{
|
||||
CMTItem item;
|
||||
|
||||
item.data = (unsigned char*) calloc(len, 1);
|
||||
item.len = len;
|
||||
memcpy(item.data, data, len);
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
|
||||
static CMTStatus
|
||||
tmp_SendMessage(PCMT_CONTROL control, CMTItem *message)
|
||||
{
|
||||
#ifndef PROCESS_LOCALLY
|
||||
return CMT_SendMessage(control, message);
|
||||
#else
|
||||
if (message->type == SSM_SDR_ENCRYPT_REQUEST)
|
||||
return CMT_DoEncryptionRequest(message);
|
||||
else if (message->type == SSM_SDR_DECRYPT_REQUEST)
|
||||
return CMT_DoDecryptionRequest(message);
|
||||
|
||||
return CMTFailure;
|
||||
#endif
|
||||
}
|
||||
/* End test code */
|
||||
|
||||
CMTStatus
|
||||
CMT_SDREncrypt(PCMT_CONTROL control, void *ctx,
|
||||
const unsigned char *key, CMUint32 keyLen,
|
||||
const unsigned char *data, CMUint32 dataLen,
|
||||
unsigned char **result, CMUint32 *resultLen)
|
||||
{
|
||||
CMTStatus rv = CMTSuccess;
|
||||
CMTItem message;
|
||||
EncryptRequestMessage request;
|
||||
SingleItemMessage reply;
|
||||
|
||||
/* Fill in the request */
|
||||
request.keyid = CMT_CopyDataToItem(key, keyLen);
|
||||
request.data = CMT_CopyDataToItem(data, dataLen);
|
||||
request.ctx = CMT_CopyPtrToItem(ctx);
|
||||
|
||||
reply.item.data = 0;
|
||||
reply.item.len = 0;
|
||||
message.data = 0;
|
||||
message.len = 0;
|
||||
|
||||
/* Encode */
|
||||
rv = CMT_EncodeMessage(EncryptRequestTemplate, &message, &request);
|
||||
if (rv != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
message.type = SSM_SDR_ENCRYPT_REQUEST;
|
||||
|
||||
/* Send */
|
||||
/* if (CMT_SendMessage(control, &message) != CMTSuccess) goto loser; */
|
||||
rv = tmp_SendMessage(control, &message);
|
||||
if (rv != CMTSuccess) goto loser;
|
||||
|
||||
if (message.type != SSM_SDR_ENCRYPT_REPLY) { rv = CMTFailure; goto loser; }
|
||||
|
||||
rv = CMT_DecodeMessage(SingleItemMessageTemplate, &reply, &message);
|
||||
if (rv != CMTSuccess)
|
||||
goto loser;
|
||||
|
||||
*result = reply.item.data;
|
||||
*resultLen = reply.item.len;
|
||||
|
||||
reply.item.data = 0;
|
||||
|
||||
loser:
|
||||
if (message.data) free(message.data);
|
||||
if (request.keyid.data) free(request.keyid.data);
|
||||
if (request.data.data) free(request.data.data);
|
||||
if (request.ctx.data) free(request.ctx.data);
|
||||
if (reply.item.data) free(reply.item.data);
|
||||
|
||||
return rv; /* need return value */
|
||||
}
|
||||
|
||||
CMTStatus
|
||||
CMT_SDRDecrypt(PCMT_CONTROL control, void *ctx,
|
||||
const unsigned char *data, CMUint32 dataLen,
|
||||
unsigned char **result, CMUint32 *resultLen)
|
||||
{
|
||||
CMTStatus rv;
|
||||
CMTItem message;
|
||||
DecryptRequestMessage request;
|
||||
SingleItemMessage reply;
|
||||
|
||||
/* Fill in the request */
|
||||
request.data = CMT_CopyDataToItem(data, dataLen);
|
||||
request.ctx = CMT_CopyPtrToItem(ctx);
|
||||
|
||||
reply.item.data = 0;
|
||||
reply.item.len = 0;
|
||||
message.data = 0;
|
||||
message.len = 0;
|
||||
|
||||
/* Encode */
|
||||
rv = CMT_EncodeMessage(DecryptRequestTemplate, &message, &request);
|
||||
if (rv != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
message.type = SSM_SDR_DECRYPT_REQUEST;
|
||||
|
||||
/* Send */
|
||||
/* if (CMT_SendMessage(control, &message) != CMTSuccess) goto loser; */
|
||||
rv = tmp_SendMessage(control, &message);
|
||||
if (rv != CMTSuccess) goto loser;
|
||||
|
||||
if (message.type != SSM_SDR_DECRYPT_REPLY) { rv = CMTFailure; goto loser; }
|
||||
|
||||
rv = CMT_DecodeMessage(SingleItemMessageTemplate, &reply, &message);
|
||||
if (rv != CMTSuccess)
|
||||
goto loser;
|
||||
|
||||
*result = reply.item.data;
|
||||
*resultLen = reply.item.len;
|
||||
|
||||
reply.item.data = 0;
|
||||
|
||||
loser:
|
||||
if (message.data) free(message.data);
|
||||
if (request.data.data) free(request.data.data);
|
||||
if (request.ctx.data) free(request.ctx.data);
|
||||
if (reply.item.data) free(reply.item.data);
|
||||
|
||||
return rv; /* need return value */
|
||||
}
|
||||
|
||||
CMTStatus
|
||||
CMT_SDRChangePassword(PCMT_CONTROL control, void *ctx)
|
||||
{
|
||||
CMTStatus rv = CMTSuccess;
|
||||
CMTItem message;
|
||||
SingleItemMessage request;
|
||||
SingleNumMessage reply;
|
||||
|
||||
/* Fill in the request */
|
||||
request.item = CMT_CopyPtrToItem(ctx);
|
||||
|
||||
message.data = 0;
|
||||
message.len = 0;
|
||||
|
||||
/* Encode */
|
||||
rv = CMT_EncodeMessage(SingleItemMessageTemplate, &message, &request);
|
||||
if (rv != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
message.type = (SSM_REQUEST_MESSAGE|SSM_MISC_ACTION|SSM_MISC_UI|SSM_UI_CHANGE_PASSWORD);
|
||||
|
||||
/* Send */
|
||||
rv = CMT_SendMessage(control, &message);
|
||||
if (rv != CMTSuccess) goto loser;
|
||||
|
||||
if (message.type !=
|
||||
(SSM_REPLY_OK_MESSAGE|SSM_MISC_ACTION|SSM_MISC_UI|SSM_UI_CHANGE_PASSWORD)) {
|
||||
rv = CMTFailure;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
rv = CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message);
|
||||
if (rv != CMTSuccess)
|
||||
goto loser;
|
||||
|
||||
loser:
|
||||
if (request.item.data) free(request.item.data);
|
||||
if (message.data) free(message.data);
|
||||
|
||||
return rv; /* need return value */
|
||||
}
|
||||
@@ -1,467 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifdef XP_UNIX
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#else
|
||||
#ifdef XP_MAC
|
||||
#else /* windows */
|
||||
#include <windows.h>
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include "cmtcmn.h"
|
||||
#include "cmtutils.h"
|
||||
#include "messages.h"
|
||||
#include "rsrcids.h"
|
||||
|
||||
|
||||
|
||||
CMTStatus CMT_OpenSSLConnection(PCMT_CONTROL control, CMTSocket sock,
|
||||
SSMSSLConnectionRequestType flags,
|
||||
CMUint32 port, char * hostIP,
|
||||
char * hostName, CMBool forceHandshake, void* clientContext)
|
||||
{
|
||||
CMTItem message;
|
||||
SSLDataConnectionRequest request;
|
||||
DataConnectionReply reply;
|
||||
CMUint32 sent;
|
||||
|
||||
/* Do some parameter checking */
|
||||
if (!control || !hostIP || !hostName) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
request.flags = flags;
|
||||
request.port = port;
|
||||
request.hostIP = hostIP;
|
||||
request.hostName = hostName;
|
||||
request.forceHandshake = forceHandshake;
|
||||
request.clientContext = CMT_CopyPtrToItem(clientContext);
|
||||
|
||||
/* Encode message */
|
||||
if (CMT_EncodeMessage(SSLDataConnectionRequestTemplate, &message, &request) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_DATA_CONNECTION | SSM_SSL_CONNECTION;
|
||||
|
||||
/* Send the message and get the response */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_DATA_CONNECTION | SSM_SSL_CONNECTION)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Decode message */
|
||||
if (CMT_DecodeMessage(DataConnectionReplyTemplate, &reply, &message) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
if (reply.result == 0) {
|
||||
if (control->sockFuncs.connect(sock, reply.port, NULL) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
sent = CMT_WriteThisMany(control, sock, control->nonce.data,
|
||||
control->nonce.len);
|
||||
if (sent != control->nonce.len) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Save connection info */
|
||||
if (CMT_AddDataConnection(control, sock, reply.connID)
|
||||
!= CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
}
|
||||
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_GetSSLDataErrorCode(PCMT_CONTROL control, CMTSocket sock,
|
||||
CMInt32* errorCode)
|
||||
{
|
||||
CMUint32 connID;
|
||||
|
||||
if (!control || !errorCode) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* get the data connection */
|
||||
if (CMT_GetDataConnectionID(control, sock, &connID) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* get the PR error */
|
||||
if (CMT_GetNumericAttribute(control, connID, SSM_FID_SSLDATA_ERROR_VALUE,
|
||||
errorCode) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_ReleaseSSLSocketStatus(PCMT_CONTROL control, CMTSocket sock)
|
||||
{
|
||||
CMUint32 connectionID;
|
||||
|
||||
if (!control || !sock) {
|
||||
goto loser;
|
||||
}
|
||||
if (CMT_GetDataConnectionID(control, sock, &connectionID) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
if (CMT_SetNumericAttribute(control, connectionID,
|
||||
SSM_FID_SSLDATA_DISCARD_SOCKET_STATUS,
|
||||
0) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_GetSSLSocketStatus(PCMT_CONTROL control, CMTSocket sock,
|
||||
CMTItem* pickledStatus, CMInt32* level)
|
||||
{
|
||||
CMUint32 connectionID;
|
||||
SingleNumMessage request;
|
||||
CMTItem message;
|
||||
PickleSecurityStatusReply reply;
|
||||
|
||||
if (!control || !pickledStatus || !level) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* get the data connection */
|
||||
if (CMT_GetDataConnectionID(control, sock, &connectionID) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* set up the request */
|
||||
request.value = connectionID;
|
||||
|
||||
/* encode the request */
|
||||
if (CMT_EncodeMessage(SingleNumMessageTemplate, &message, &request) !=
|
||||
CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_RESOURCE_ACTION |
|
||||
SSM_CONSERVE_RESOURCE | SSM_PICKLE_SECURITY_STATUS;
|
||||
|
||||
/* send the message and get the response */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_RESOURCE_ACTION |
|
||||
SSM_CONSERVE_RESOURCE | SSM_PICKLE_SECURITY_STATUS)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* decode the reply */
|
||||
if (CMT_DecodeMessage(PickleSecurityStatusReplyTemplate, &reply, &message)
|
||||
!= CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* success */
|
||||
if (reply.result == 0) {
|
||||
*pickledStatus = reply.blob;
|
||||
*level = reply.securityLevel;
|
||||
return CMTSuccess;
|
||||
}
|
||||
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
|
||||
CMTStatus CMT_OpenTLSConnection(PCMT_CONTROL control, CMTSocket sock,
|
||||
CMUint32 port, char* hostIP, char* hostName)
|
||||
{
|
||||
TLSDataConnectionRequest request;
|
||||
CMTItem message;
|
||||
DataConnectionReply reply;
|
||||
CMUint32 sent;
|
||||
|
||||
/* do some parameter checking */
|
||||
if (!control || !hostIP || !hostName) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
request.port = port;
|
||||
request.hostIP = hostIP;
|
||||
request.hostName = hostName;
|
||||
|
||||
/* encode the message */
|
||||
if (CMT_EncodeMessage(TLSDataConnectionRequestTemplate, &message, &request)
|
||||
!= CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_DATA_CONNECTION |
|
||||
SSM_TLS_CONNECTION;
|
||||
|
||||
/* send the message and get the response */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_DATA_CONNECTION |
|
||||
SSM_TLS_CONNECTION)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* decode the message */
|
||||
if (CMT_DecodeMessage(DataConnectionReplyTemplate, &reply, &message) !=
|
||||
CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* success */
|
||||
if (reply.result == 0) {
|
||||
if (control->sockFuncs.connect(sock, reply.port, NULL) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
sent = CMT_WriteThisMany(control, sock, control->nonce.data,
|
||||
control->nonce.len);
|
||||
if (sent != control->nonce.len) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* save connection info */
|
||||
if (CMT_AddDataConnection(control, sock, reply.connID) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
}
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
|
||||
CMTStatus CMT_TLSStepUp(PCMT_CONTROL control, CMTSocket sock,
|
||||
void* clientContext)
|
||||
{
|
||||
TLSStepUpRequest request;
|
||||
SingleNumMessage reply;
|
||||
CMTItem message;
|
||||
CMUint32 connectionID;
|
||||
|
||||
/* check arguments */
|
||||
if (!control || !sock) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* get the data connection ID */
|
||||
if (CMT_GetDataConnectionID(control, sock, &connectionID) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* set up the request */
|
||||
request.connID = connectionID;
|
||||
request.clientContext = CMT_CopyPtrToItem(clientContext);
|
||||
|
||||
/* encode the request */
|
||||
if (CMT_EncodeMessage(TLSStepUpRequestTemplate, &message, &request) !=
|
||||
CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_RESOURCE_ACTION | SSM_TLS_STEPUP;
|
||||
|
||||
/* send the message and get the response */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_RESOURCE_ACTION |
|
||||
SSM_TLS_STEPUP)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* decode the reply */
|
||||
if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message) !=
|
||||
CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return (CMTStatus) reply.value;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_OpenSSLProxyConnection(PCMT_CONTROL control, CMTSocket sock,
|
||||
CMUint32 port, char* hostIP,
|
||||
char* hostName)
|
||||
{
|
||||
TLSDataConnectionRequest request;
|
||||
CMTItem message;
|
||||
DataConnectionReply reply;
|
||||
CMUint32 sent;
|
||||
|
||||
/* do some parameter checking */
|
||||
if (!control || !hostIP || !hostName) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
request.port = port;
|
||||
request.hostIP = hostIP;
|
||||
request.hostName = hostName;
|
||||
|
||||
/* encode the message */
|
||||
if (CMT_EncodeMessage(TLSDataConnectionRequestTemplate, &message, &request)
|
||||
!= CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_DATA_CONNECTION |
|
||||
SSM_PROXY_CONNECTION;
|
||||
|
||||
/* send the message and get the response */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_DATA_CONNECTION |
|
||||
SSM_PROXY_CONNECTION)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* decode the message */
|
||||
if (CMT_DecodeMessage(DataConnectionReplyTemplate, &reply, &message) !=
|
||||
CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* success */
|
||||
if (reply.result == 0) {
|
||||
if (control->sockFuncs.connect(sock, reply.port, NULL) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
sent = CMT_WriteThisMany(control, sock, control->nonce.data,
|
||||
control->nonce.len);
|
||||
if (sent != control->nonce.len) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* save connection info */
|
||||
if (CMT_AddDataConnection(control, sock, reply.connID) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
}
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
|
||||
CMTStatus CMT_ProxyStepUp(PCMT_CONTROL control, CMTSocket sock,
|
||||
void* clientContext, char* remoteUrl)
|
||||
{
|
||||
ProxyStepUpRequest request;
|
||||
SingleNumMessage reply;
|
||||
CMTItem message;
|
||||
CMUint32 connectionID;
|
||||
|
||||
/* check arguments */
|
||||
if (!control || !sock || !remoteUrl) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* get the data connection ID */
|
||||
if (CMT_GetDataConnectionID(control, sock, &connectionID) != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* set up the request */
|
||||
request.connID = connectionID;
|
||||
request.clientContext = CMT_CopyPtrToItem(clientContext);
|
||||
request.url = remoteUrl;
|
||||
|
||||
/* encode the request */
|
||||
if (CMT_EncodeMessage(ProxyStepUpRequestTemplate, &message, &request) !=
|
||||
CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* set the message request type */
|
||||
message.type = SSM_REQUEST_MESSAGE | SSM_RESOURCE_ACTION |
|
||||
SSM_PROXY_STEPUP;
|
||||
|
||||
/* send the message and get the response */
|
||||
if (CMT_SendMessage(control, &message) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* validate the message reply type */
|
||||
if (message.type != (SSM_REPLY_OK_MESSAGE | SSM_RESOURCE_ACTION |
|
||||
SSM_PROXY_STEPUP)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* decode the reply */
|
||||
if (CMT_DecodeMessage(SingleNumMessageTemplate, &reply, &message) !=
|
||||
CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return (CMTStatus) reply.value;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
@@ -1,636 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifdef XP_UNIX
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#else
|
||||
#ifdef XP_MAC
|
||||
#include "macsocket.h"
|
||||
#else /* Windows */
|
||||
#include <windows.h>
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
#endif
|
||||
#include "cmtcmn.h"
|
||||
#include "cmtutils.h"
|
||||
#include "newproto.h"
|
||||
#include <string.h>
|
||||
|
||||
/* Local defines */
|
||||
#if 0
|
||||
#define PSM_WAIT_BEFORE_SLEEP (CM_TicksPerSecond() * 60)
|
||||
#define PSM_SPINTIME PSM_WAIT_BEFORE_SLEEP
|
||||
#define PSM_KEEP_CONNECTION_ALIVE (PSM_WAIT_BEFORE_SLEEP * 900)
|
||||
#endif
|
||||
|
||||
/* If you want to dump the messages sent between the plug-in and the PSM
|
||||
* server, then remove the comment for the appropriate define.
|
||||
*/
|
||||
#if 0
|
||||
#define PRINT_SEND_MESSAGES
|
||||
#define PRINT_RECEIVE_MESSAGES
|
||||
#endif
|
||||
|
||||
#ifdef PRINT_SEND_MESSAGES
|
||||
#ifndef DEBUG_MESSAGES
|
||||
#define DEBUG_MESSAGES
|
||||
#endif /*DEBUG_MESSAGES*/
|
||||
#endif /*PRINT_SEND_MESSAGES*/
|
||||
|
||||
#ifdef PRINT_RECEIVE_MESSAGES
|
||||
#ifndef DEBUG_MESSAGES
|
||||
#define DEBUG_MESSAGES
|
||||
#endif /*DEBUG_MESSAGES*/
|
||||
#endif /*PRINT_RECEIVE_MESSAGES*/
|
||||
|
||||
#ifdef DEBUG_MESSAGES
|
||||
#define LOG(x) do { FILE *f; f=fopen("cmnav.log","a+"); if (f) { \
|
||||
fprintf(f, x); fclose(f); } } while(0);
|
||||
#define LOG_S(x) do { FILE *f; f=fopen("cmnav.log","a+"); if (f) { \
|
||||
fprintf(f, "%s", x); fclose(f); } } while(0);
|
||||
#define ASSERT(x) if (!(x)) { LOG("ASSERT:"); LOG(#x); LOG("\n"); exit(-1); }
|
||||
#else
|
||||
#define LOG(x)
|
||||
#define LOG_S(x)
|
||||
#define ASSERT(x)
|
||||
#endif
|
||||
|
||||
CMUint32
|
||||
cmt_Strlen(char *str)
|
||||
{
|
||||
CMUint32 len = strlen(str);
|
||||
return sizeof(CMInt32) + (((len + 3)/4)*4);
|
||||
}
|
||||
|
||||
CMUint32
|
||||
cmt_Bloblen(CMTItem *blob)
|
||||
{
|
||||
return sizeof(CMInt32) + (((blob->len +3)/4)*4);
|
||||
}
|
||||
|
||||
char *
|
||||
cmt_PackString(char *buf, char *str)
|
||||
{
|
||||
CMUint32 len = strlen(str);
|
||||
CMUint32 networkLen = htonl(len);
|
||||
CMUint32 padlen = ((len + 3)/4)*4;
|
||||
|
||||
memcpy(buf, &networkLen, sizeof(CMUint32));
|
||||
memcpy(buf + sizeof(CMUint32), str, len);
|
||||
memset(buf + sizeof(CMUint32) + len, 0, padlen - len);
|
||||
|
||||
return buf+sizeof(CMUint32)+padlen;
|
||||
}
|
||||
|
||||
char *
|
||||
cmt_PackBlob(char *buf, CMTItem *blob)
|
||||
{
|
||||
CMUint32 len = blob->len;
|
||||
CMUint32 networkLen = htonl(len);
|
||||
CMUint32 padlen = (((blob->len + 3)/4)*4);
|
||||
|
||||
*((CMUint32*)buf) = networkLen;
|
||||
memcpy(buf + sizeof(CMUint32), blob->data, len);
|
||||
memset(buf + sizeof(CMUint32) + len, 0, padlen - len);
|
||||
|
||||
return buf + sizeof(CMUint32) + padlen;
|
||||
}
|
||||
|
||||
char *
|
||||
cmt_UnpackString(char *buf, char **str)
|
||||
{
|
||||
char *p = NULL;
|
||||
CMUint32 len, padlen;
|
||||
|
||||
/* Get the string length */
|
||||
len = ntohl(*(CMUint32*)buf);
|
||||
|
||||
/* Get the padded length */
|
||||
padlen = ((len + 3)/4)*4;
|
||||
|
||||
/* Allocate the string and copy the data */
|
||||
p = (char *) malloc(len + 1);
|
||||
if (!p) {
|
||||
goto loser;
|
||||
}
|
||||
/* Copy the data and NULL terminate */
|
||||
memcpy(p, buf+sizeof(CMUint32), len);
|
||||
p[len] = 0;
|
||||
|
||||
*str = p;
|
||||
return buf+sizeof(CMUint32)+padlen;
|
||||
loser:
|
||||
*str = NULL;
|
||||
if (p) {
|
||||
free(p);
|
||||
}
|
||||
return buf+sizeof(CMUint32)+padlen;
|
||||
}
|
||||
|
||||
char *
|
||||
cmt_UnpackBlob(char *buf, CMTItem **blob)
|
||||
{
|
||||
CMTItem *p = NULL;
|
||||
CMUint32 len, padlen;
|
||||
|
||||
/* Get the blob length */
|
||||
len = ntohl(*(CMUint32*)buf);
|
||||
|
||||
/* Get the padded length */
|
||||
padlen = ((len + 3)/4)*4;
|
||||
|
||||
/* Allocate the CMTItem for the blob */
|
||||
p = (CMTItem*)malloc(sizeof(CMTItem));
|
||||
if (!p) {
|
||||
goto loser;
|
||||
}
|
||||
p->len = len;
|
||||
p->data = (unsigned char *) malloc(len);
|
||||
if (!p->data) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Copy that data across */
|
||||
memcpy(p->data, buf+sizeof(CMUint32), len);
|
||||
*blob = p;
|
||||
|
||||
return buf+sizeof(CMUint32)+padlen;
|
||||
|
||||
loser:
|
||||
*blob = NULL;
|
||||
CMT_FreeMessage(p);
|
||||
|
||||
return buf+sizeof(CMUint32)+padlen;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_MESSAGES
|
||||
void prettyPrintMessage(CMTItem *msg)
|
||||
{
|
||||
int numLines = ((msg->len+7)/8);
|
||||
char curBuffer[9], *cursor, string[2], hexVal[8];
|
||||
char hexArray[25];
|
||||
int i, j, numToCopy;
|
||||
|
||||
/*Try printing out 8 bytes at a time. */
|
||||
LOG("\n**********************************************************\n");
|
||||
LOG("About to pretty Print Message\n\n");
|
||||
curBuffer[9] = '\0';
|
||||
hexArray[24] = '\0';
|
||||
hexVal[2] = '\0';
|
||||
string[1] = '\0';
|
||||
LOG("Header Info\n");
|
||||
LOG("Message Type: ");
|
||||
sprintf(hexArray, "%lx\n", msg->type);
|
||||
LOG(hexArray);
|
||||
LOG("Message Length: ");
|
||||
sprintf (hexArray, "%ld\n\n", msg->len);
|
||||
LOG(hexArray);
|
||||
LOG("Body of Message\n");
|
||||
for (i=0, cursor=msg->data; i<numLines; i++, cursor+=8) {
|
||||
/* First copy over the buffer to our local array */
|
||||
numToCopy = ((msg->len - (unsigned int)((unsigned long)cursor-(unsigned long)msg->data)) < 8) ?
|
||||
msg->len - (unsigned int)((unsigned long)cursor-(unsigned long)msg->data) : 8;
|
||||
memcpy(curBuffer, cursor, 8);
|
||||
for (j=0;j<numToCopy;j++) {
|
||||
string[0] = curBuffer[j];
|
||||
if (isprint(curBuffer[j])) {
|
||||
string[0] = curBuffer[j];
|
||||
} else {
|
||||
string[0] = ' ';
|
||||
}
|
||||
LOG(string);
|
||||
}
|
||||
string[0] = ' ';
|
||||
for (;j<8;j++) {
|
||||
LOG(string);
|
||||
}
|
||||
LOG("\t");
|
||||
for (j=0; j<numToCopy; j++) {
|
||||
sprintf (hexVal,"%.2x", 0x0ff & (unsigned short)curBuffer[j]);
|
||||
LOG(hexVal);
|
||||
LOG(" ");
|
||||
}
|
||||
LOG("\n");
|
||||
}
|
||||
LOG("Done Pretty Printing Message\n");
|
||||
LOG("**********************************************************\n\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
CMTStatus CMT_SendMessage(PCMT_CONTROL control, CMTItem* message)
|
||||
{
|
||||
CMTStatus status;
|
||||
CMUint32 msgCategory;
|
||||
CMBool done = CM_FALSE;
|
||||
#ifdef PRINT_SEND_MESSAGES
|
||||
LOG("About to print message sent to PSM\n");
|
||||
prettyPrintMessage(message);
|
||||
#endif
|
||||
|
||||
/* Acquire lock on the control connection */
|
||||
CMT_LOCK(control->mutex);
|
||||
|
||||
/* Try to send pending random data */
|
||||
if (message->type != (SSM_REQUEST_MESSAGE | SSM_HELLO_MESSAGE))
|
||||
{
|
||||
/* If we've already said hello, then flush random data
|
||||
just before sending the request. */
|
||||
status = CMT_FlushPendingRandomData(control);
|
||||
if (status != CMTSuccess)
|
||||
goto loser;
|
||||
}
|
||||
|
||||
status = CMT_TransmitMessage(control, message);
|
||||
if (status != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* We have to deal with other types of data on the socket and */
|
||||
/* handle them accordingly */
|
||||
while (!done) {
|
||||
status = CMT_ReceiveMessage(control, message);
|
||||
if (status != CMTSuccess) {
|
||||
goto loser;
|
||||
}
|
||||
msgCategory = (message->type & SSM_CATEGORY_MASK);
|
||||
switch (msgCategory) {
|
||||
case SSM_REPLY_OK_MESSAGE:
|
||||
done = CM_TRUE;
|
||||
break;
|
||||
case SSM_REPLY_ERR_MESSAGE:
|
||||
done = CM_TRUE;
|
||||
break;
|
||||
case SSM_EVENT_MESSAGE:
|
||||
CMT_DispatchEvent(control, message);
|
||||
break;
|
||||
/* XXX FIX THIS!!! For the moment I'm ignoring all other types */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Release the control connection lock */
|
||||
CMT_UNLOCK(control->mutex);
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
/* Release the control connection lock */
|
||||
CMT_UNLOCK(control->mutex);
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_TransmitMessage(PCMT_CONTROL control, CMTItem * message)
|
||||
{
|
||||
CMTMessageHeader header;
|
||||
CMUint32 sent, rv;
|
||||
|
||||
/* Set up the message header */
|
||||
header.type = htonl(message->type);
|
||||
header.len = htonl(message->len);
|
||||
|
||||
/* Send the message header */
|
||||
sent = CMT_WriteThisMany(control, control->sock,
|
||||
(void *)&header, sizeof(CMTMessageHeader));
|
||||
if (sent != sizeof(CMTMessageHeader)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Send the message body */
|
||||
sent = CMT_WriteThisMany(control, control->sock, (void *)message->data,
|
||||
message->len);
|
||||
if (sent != message->len) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Free the buffer */
|
||||
free(message->data);
|
||||
message->data = NULL;
|
||||
return CMTSuccess;
|
||||
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_ReceiveMessage(PCMT_CONTROL control, CMTItem * response)
|
||||
{
|
||||
CMTMessageHeader header;
|
||||
CMUint32 numread, rv;
|
||||
|
||||
/* Get the message header */
|
||||
numread = CMT_ReadThisMany(control, control->sock,
|
||||
(void *)&header, sizeof(CMTMessageHeader));
|
||||
if (numread != sizeof(CMTMessageHeader)) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
response->type = ntohl(header.type);
|
||||
response->len = ntohl(header.len);
|
||||
response->data = (unsigned char *) malloc(response->len);
|
||||
if (response->data == NULL) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
numread = CMT_ReadThisMany(control, control->sock,
|
||||
(void *)(response->data), response->len);
|
||||
if (numread != response->len) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
#ifdef PRINT_RECEIVE_MESSAGES
|
||||
LOG("About to print message received from PSM.\n");
|
||||
prettyPrintMessage(response);
|
||||
#endif /*PRINT_RECEIVE_MESSAGES*/
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
if (response->data) {
|
||||
free(response->data);
|
||||
}
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMUint32 CMT_ReadThisMany(PCMT_CONTROL control, CMTSocket sock,
|
||||
void * buffer, CMUint32 thisMany)
|
||||
{
|
||||
CMUint32 total = 0;
|
||||
|
||||
while (total < thisMany) {
|
||||
int got;
|
||||
got = control->sockFuncs.recv(sock, (void*)((char*)buffer + total),
|
||||
thisMany-total);
|
||||
if (got < 0 ) {
|
||||
break;
|
||||
}
|
||||
total += got;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
CMUint32 CMT_WriteThisMany(PCMT_CONTROL control, CMTSocket sock,
|
||||
void * buffer, CMUint32 thisMany)
|
||||
{
|
||||
CMUint32 total = 0;
|
||||
|
||||
while (total < thisMany) {
|
||||
CMInt32 got;
|
||||
got = control->sockFuncs.send(sock, (void*)((char*)buffer+total),
|
||||
thisMany-total);
|
||||
if (got < 0) {
|
||||
break;
|
||||
}
|
||||
total += got;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
CMTItem* CMT_ConstructMessage(CMUint32 type, CMUint32 length)
|
||||
{
|
||||
CMTItem * p;
|
||||
|
||||
p = (CMTItem*)malloc(sizeof(CMTItem));
|
||||
if (!p) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
p->type = type;
|
||||
p->len = length;
|
||||
p->data = (unsigned char *) malloc(length);
|
||||
if (!p->data) {
|
||||
goto loser;
|
||||
}
|
||||
return p;
|
||||
|
||||
loser:
|
||||
CMT_FreeMessage(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CMT_FreeMessage(CMTItem * p)
|
||||
{
|
||||
if (p != NULL) {
|
||||
if (p->data != NULL) {
|
||||
free(p->data);
|
||||
}
|
||||
free(p);
|
||||
}
|
||||
}
|
||||
|
||||
CMTStatus CMT_AddDataConnection(PCMT_CONTROL control, CMTSocket sock,
|
||||
CMUint32 connectionID)
|
||||
{
|
||||
PCMT_DATA ptr;
|
||||
|
||||
/* This is the first connection */
|
||||
if (control->cmtDataConnections == NULL) {
|
||||
control->cmtDataConnections = ptr =
|
||||
(PCMT_DATA)calloc(sizeof(CMT_DATA), 1);
|
||||
if (!ptr) {
|
||||
goto loser;
|
||||
}
|
||||
} else {
|
||||
/* Position at the last entry */
|
||||
for (ptr = control->cmtDataConnections; (ptr != NULL && ptr->next
|
||||
!= NULL); ptr = ptr->next);
|
||||
ptr->next = (PCMT_DATA)calloc(sizeof(CMT_DATA), 1);
|
||||
if (!ptr->next) {
|
||||
goto loser;
|
||||
}
|
||||
/* Fix up the pointers */
|
||||
ptr->next->previous = ptr;
|
||||
ptr = ptr->next;
|
||||
}
|
||||
|
||||
/* Fill in the data */
|
||||
ptr->sock = sock;
|
||||
ptr->connectionID = connectionID;
|
||||
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
int
|
||||
CMT_DestroyDataConnection(PCMT_CONTROL control, CMTSocket sock)
|
||||
{
|
||||
PCMT_DATA ptr, pptr = NULL;
|
||||
int rv=CMTSuccess;
|
||||
|
||||
control->sockFuncs.close(sock);
|
||||
for (ptr = control->cmtDataConnections; ptr != NULL;
|
||||
pptr = ptr, ptr = ptr->next) {
|
||||
if (ptr->sock == sock) {
|
||||
if (pptr == NULL) {
|
||||
/* node is at head */
|
||||
control->cmtDataConnections = ptr->next;
|
||||
if (ptr->priv != NULL)
|
||||
ptr->priv->dest(ptr->priv);
|
||||
free(ptr);
|
||||
return rv;
|
||||
}
|
||||
/* node is elsewhere */
|
||||
pptr->next = ptr->next;
|
||||
if (ptr->priv != NULL)
|
||||
ptr->priv->dest(ptr->priv);
|
||||
free(ptr);
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
CMTStatus CMT_CloseDataConnection(PCMT_CONTROL control, CMUint32 connectionID)
|
||||
{
|
||||
/* PCMT_DATA ptr, pptr = NULL; */
|
||||
CMTSocket sock;
|
||||
/* int rv;*/
|
||||
|
||||
/* Get the socket for this connection */
|
||||
if (CMT_GetDataSocket(control, connectionID, &sock) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* Free data connection associated with this socket */
|
||||
if (CMT_DestroyDataConnection(control, sock) == CMTFailure) {
|
||||
goto loser;
|
||||
}
|
||||
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_GetDataConnectionID(PCMT_CONTROL control, CMTSocket sock, CMUint32 * connectionID)
|
||||
{
|
||||
PCMT_DATA ptr;
|
||||
|
||||
for (ptr = control->cmtDataConnections; ptr != NULL; ptr = ptr->next) {
|
||||
if (ptr->sock == sock) {
|
||||
*connectionID = ptr->connectionID;
|
||||
return CMTSuccess;
|
||||
}
|
||||
}
|
||||
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus CMT_GetDataSocket(PCMT_CONTROL control, CMUint32 connectionID, CMTSocket * sock)
|
||||
{
|
||||
PCMT_DATA ptr;
|
||||
|
||||
for (ptr = control->cmtDataConnections; ptr != NULL; ptr = ptr->next) {
|
||||
if (ptr->connectionID == connectionID) {
|
||||
*sock = ptr->sock;
|
||||
return CMTSuccess;
|
||||
}
|
||||
}
|
||||
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
|
||||
CMTStatus CMT_SetPrivate(PCMT_CONTROL control, CMUint32 connectionID,
|
||||
CMTPrivate *cmtpriv)
|
||||
{
|
||||
PCMT_DATA ptr;
|
||||
|
||||
for (ptr = control->cmtDataConnections; ptr != NULL; ptr = ptr->next) {
|
||||
if (ptr->connectionID == connectionID) {
|
||||
ptr->priv = cmtpriv;
|
||||
return CMTSuccess;
|
||||
}
|
||||
}
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTPrivate *CMT_GetPrivate(PCMT_CONTROL control, CMUint32 connectionID)
|
||||
{
|
||||
PCMT_DATA ptr;
|
||||
|
||||
for (ptr = control->cmtDataConnections; ptr != NULL; ptr = ptr->next) {
|
||||
if (ptr->connectionID == connectionID) {
|
||||
return ptr->priv;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CMT_FreeItem(CMTItem *p)
|
||||
{
|
||||
CMT_FreeMessage(p);
|
||||
}
|
||||
|
||||
CMTItem CMT_CopyPtrToItem(void* p)
|
||||
{
|
||||
CMTItem value = {0, NULL, 0};
|
||||
|
||||
if (!p) {
|
||||
return value;
|
||||
}
|
||||
|
||||
value.len = sizeof(p);
|
||||
value.data = (unsigned char *) malloc(value.len);
|
||||
memcpy(value.data, &p, value.len);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
void * CMT_CopyItemToPtr(CMTItem value)
|
||||
{
|
||||
void * p = NULL;
|
||||
|
||||
if (value.len == sizeof(void*)) {
|
||||
memcpy(&p, value.data, value.len);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
CMTStatus CMT_ReferenceControlConnection(PCMT_CONTROL control)
|
||||
{
|
||||
CMT_LOCK(control->mutex);
|
||||
control->refCount++;
|
||||
CMT_UNLOCK(control->mutex);
|
||||
return CMTSuccess;
|
||||
}
|
||||
|
||||
void
|
||||
CMT_LockConnection(PCMT_CONTROL control)
|
||||
{
|
||||
CMT_LOCK(control->mutex);
|
||||
}
|
||||
|
||||
void
|
||||
CMT_UnlockConnection(PCMT_CONTROL control)
|
||||
{
|
||||
CMT_UNLOCK(control->mutex);
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef __CMTUTILS_H__
|
||||
#define __CMTUTILS_H__
|
||||
|
||||
#include "cmtcmn.h"
|
||||
|
||||
#define New(type) (type*)malloc(sizeof(type))
|
||||
#define NewArray(type, size) (type*)malloc(sizeof(type)*(size))
|
||||
|
||||
PCMT_EVENT CMT_GetEventHandler(PCMT_CONTROL control, CMUint32 type,
|
||||
CMUint32 resourceID);
|
||||
|
||||
CMUint32 cmt_Strlen(char *str);
|
||||
char *cmt_PackString(char *buf, char *str);
|
||||
char *cmt_UnpackString(char *buf, char **str);
|
||||
|
||||
CMUint32 cmt_Bloblen(CMTItem* len);
|
||||
char *cmt_PackBlob(char *buf, CMTItem * blob);
|
||||
char *cmt_UnpackBlob(char *buf, CMTItem **blob);
|
||||
|
||||
CMTStatus CMT_SendMessage(PCMT_CONTROL control, CMTItem* message);
|
||||
CMTStatus CMT_TransmitMessage(PCMT_CONTROL control, CMTItem * message);
|
||||
CMTStatus CMT_ReceiveMessage(PCMT_CONTROL control, CMTItem * response);
|
||||
CMUint32 CMT_ReadThisMany(PCMT_CONTROL control, CMTSocket sock,
|
||||
void * buffer, CMUint32 thisMany);
|
||||
CMUint32 CMT_WriteThisMany(PCMT_CONTROL control, CMTSocket sock,
|
||||
void * buffer, CMUint32 thisMany);
|
||||
CMTItem* CMT_ConstructMessage(CMUint32 type, CMUint32 length);
|
||||
void CMT_FreeMessage(CMTItem * p);
|
||||
CMTStatus CMT_AddDataConnection(PCMT_CONTROL control, CMTSocket sock, CMUint32 connectionID);
|
||||
CMTStatus CMT_GetDataConnectionID(PCMT_CONTROL control, CMTSocket sock, CMUint32 * connectionID);
|
||||
CMTStatus CMT_GetDataSocket(PCMT_CONTROL control, CMUint32 connectionID, CMTSocket * sock);
|
||||
CMTStatus CMT_CloseDataConnection(PCMT_CONTROL control, CMUint32 connectionID);
|
||||
CMTStatus CMT_SetPrivate(PCMT_CONTROL control, CMUint32 connectionID,
|
||||
CMTPrivate *cmtpriv);
|
||||
CMTPrivate *CMT_GetPrivate(PCMT_CONTROL control, CMUint32 connectionID);
|
||||
void CMT_ServicePasswordRequest(PCMT_CONTROL cm_control, CMTItem * requestData);
|
||||
void CMT_ProcessEvent(PCMT_CONTROL cm_control);
|
||||
void CMT_DispatchEvent(PCMT_CONTROL cm_control, CMTItem * eventData);
|
||||
CMTItem CMT_CopyPtrToItem(void* p);
|
||||
void * CMT_CopyItemToPtr(CMTItem value);
|
||||
|
||||
#endif /* __CMTUTILS_H__ */
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is the Netscape security libraries.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU General Public License Version 2 or later (the
|
||||
# "GPL"), in which case the provisions of the GPL are applicable
|
||||
# instead of those above. If you wish to allow use of your
|
||||
# version of this file only under the terms of the GPL and not to
|
||||
# allow others to use your version of this file under the MPL,
|
||||
# indicate your decision by deleting the provisions above and
|
||||
# replace them with the notice and other provisions required by
|
||||
# the GPL. If you do not delete the provisions above, a recipient
|
||||
# may use your version of this file under either the MPL or the
|
||||
# GPL.
|
||||
#
|
||||
|
||||
#
|
||||
# Override TARGETS variable so that only static libraries
|
||||
# are specifed as dependencies within rules.mk.
|
||||
#
|
||||
|
||||
TARGETS = $(LIBRARY)
|
||||
SHARED_LIBRARY =
|
||||
IMPORT_LIBRARY =
|
||||
PURE_LIBRARY =
|
||||
PROGRAM =
|
||||
|
||||
@@ -1,125 +0,0 @@
|
||||
#//
|
||||
#// The contents of this file are subject to the Mozilla Public
|
||||
#// License Version 1.1 (the "License"); you may not use this file
|
||||
#// except in compliance with the License. You may obtain a copy of
|
||||
#// the License at http://www.mozilla.org/MPL/
|
||||
#//
|
||||
#// Software distributed under the License is distributed on an "AS
|
||||
#// IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
#// implied. See the License for the specific language governing
|
||||
#// rights and limitations under the License.
|
||||
#//
|
||||
#// The Original Code is the Netscape security libraries.
|
||||
#//
|
||||
#// The Initial Developer of the Original Code is Netscape
|
||||
#// Communications Corporation. Portions created by Netscape are
|
||||
#// Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
#// Rights Reserved.
|
||||
#//
|
||||
#// Contributor(s):
|
||||
#//
|
||||
#// Alternatively, the contents of this file may be used under the
|
||||
#// terms of the GNU General Public License Version 2 or later (the
|
||||
#// "GPL"), in which case the provisions of the GPL are applicable
|
||||
#// instead of those above. If you wish to allow use of your
|
||||
#// version of this file only under the terms of the GPL and not to
|
||||
#// allow others to use your version of this file under the MPL,
|
||||
#// indicate your decision by deleting the provisions above and
|
||||
#// replace them with the notice and other provisions required by
|
||||
#// the GPL. If you do not delete the provisions above, a recipient
|
||||
#// may use your version of this file under either the MPL or the
|
||||
#// GPL.
|
||||
#//
|
||||
IGNORE_MANIFEST=1
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Makefile to build the ssl library
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
|
||||
!if "$(MOZ_BITS)" == "16"
|
||||
!ifndef MOZ_DEBUG
|
||||
OPTIMIZER=-Os -UDEBUG -DNDEBUG
|
||||
!endif
|
||||
!endif
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Specify the depth of the current directory relative to the
|
||||
#// root of NS
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
DEPTH= ..\..\..\..
|
||||
|
||||
!ifndef MAKE_OBJ_TYPE
|
||||
MAKE_OBJ_TYPE=EXE
|
||||
!endif
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Define any Public Make Variables here: (ie. PDFFILE, MAPFILE, ...)
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
LIBNAME=cmt
|
||||
PDBFILE=$(LIBNAME).pdb
|
||||
|
||||
LINCS = -I$(PUBLIC)\security \
|
||||
-I$(PUBLIC)\nspr \
|
||||
-I$(DEPTH)\include \
|
||||
-I..\include
|
||||
|
||||
!ifndef OS_CONFIG
|
||||
OS_CONFIG = WIN$(MOZ_BITS)
|
||||
!endif
|
||||
|
||||
LCFLAGS = -DEXPORT_VERSION -DLIB_BUILD
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Define the files necessary to build the target (ie. OBJS)
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
OBJS= \
|
||||
.\$(OBJDIR)\cmtinit.obj \
|
||||
.\$(OBJDIR)\cmtssl.obj \
|
||||
.\$(OBJDIR)\cmtutils.obj \
|
||||
.\$(OBJDIR)\cmtpkcs7.obj \
|
||||
.\$(OBJDIR)\cmthash.obj \
|
||||
.\$(OBJDIR)\cmtcert.obj \
|
||||
.\$(OBJDIR)\cmtres.obj \
|
||||
.\$(OBJDIR)\cmtjs.obj \
|
||||
.\$(OBJDIR)\cmtevent.obj \
|
||||
.\$(OBJDIR)\cmtpasswd.obj \
|
||||
.\$(OBJDIR)\cmtadvisor.obj \
|
||||
.\$(OBJDIR)\cmtrng.obj \
|
||||
.\$(OBJDIR)\cmtsdr.obj \
|
||||
$(NULL)
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Define any Public Targets here (ie. PROGRAM, LIBRARY, DLL, ...)
|
||||
#// (these must be defined before the common makefiles are included)
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
LIBRARY=.\$(OBJDIR)\$(LIBNAME).lib
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// install headers
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
INSTALL_DIR=$(PUBLIC)\security
|
||||
INSTALL_FILE_LIST=cmtcmn.h cmtjs.h cmtclist.h
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Include the common makefile rules
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
include <$(DEPTH)/config/rules.mak>
|
||||
|
||||
install:: $(LIBRARY)
|
||||
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
|
||||
|
||||
export:: INSTALL_FILES
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is the Netscape security libraries.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU General Public License Version 2 or later (the
|
||||
# "GPL"), in which case the provisions of the GPL are applicable
|
||||
# instead of those above. If you wish to allow use of your
|
||||
# version of this file only under the terms of the GPL and not to
|
||||
# allow others to use your version of this file under the MPL,
|
||||
# indicate your decision by deleting the provisions above and
|
||||
# replace them with the notice and other provisions required by
|
||||
# the GPL. If you do not delete the provisions above, a recipient
|
||||
# may use your version of this file under either the MPL or the
|
||||
# GPL.
|
||||
#
|
||||
|
||||
CORE_DEPTH = ../../..
|
||||
DEPTH = ../../..
|
||||
|
||||
EXPORTS = \
|
||||
cmtcmn.h \
|
||||
cmtjs.h \
|
||||
cmtclist.h \
|
||||
$(NULL)
|
||||
|
||||
MODULE = security
|
||||
|
||||
CSRCS = cmtinit.c \
|
||||
cmtssl.c \
|
||||
cmtutils.c \
|
||||
cmtcert.c \
|
||||
cmthash.c \
|
||||
cmtpkcs7.c \
|
||||
cmtres.c \
|
||||
cmtjs.c \
|
||||
cmtevent.c \
|
||||
cmtpasswd.c \
|
||||
cmtadvisor.c \
|
||||
cmtrng.c \
|
||||
cmtsdr.c \
|
||||
$(NULL)
|
||||
|
||||
REQUIRES = nspr security
|
||||
|
||||
LIBRARY_NAME = cmt
|
||||
|
||||
INCLUDES += -I$(CORE_DEPTH)/include
|
||||
@@ -1,128 +0,0 @@
|
||||
#! gmake
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is the Netscape security libraries.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU General Public License Version 2 or later (the
|
||||
# "GPL"), in which case the provisions of the GPL are applicable
|
||||
# instead of those above. If you wish to allow use of your
|
||||
# version of this file only under the terms of the GPL and not to
|
||||
# allow others to use your version of this file under the MPL,
|
||||
# indicate your decision by deleting the provisions above and
|
||||
# replace them with the notice and other provisions required by
|
||||
# the GPL. If you do not delete the provisions above, a recipient
|
||||
# may use your version of this file under either the MPL or the
|
||||
# GPL.
|
||||
#
|
||||
|
||||
#######################################################################
|
||||
# (1) Include initial platform-independent assignments (MANDATORY). #
|
||||
#######################################################################
|
||||
|
||||
include manifest.mn
|
||||
|
||||
#######################################################################
|
||||
# (2) Include "global" configuration information. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
include $(CORE_DEPTH)/coreconf/config.mk
|
||||
|
||||
#######################################################################
|
||||
# (3) Include "component" configuration information. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
#######################################################################
|
||||
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
|
||||
#######################################################################
|
||||
|
||||
ifneq ($(OS_ARCH), WINNT)
|
||||
ifeq ($(OS_ARCH), Linux)
|
||||
# On linux, we link with libstdc++
|
||||
CPLUSPLUSRUNTIME = -L /usr/lib -lstdc++ -lm
|
||||
else
|
||||
# libC, presumably, is what we must link with elsewhere
|
||||
CPLUSPLUSRUNTIME = -lC -lm
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(OS_ARCH), SunOS)
|
||||
ifeq ($(OS_RELEASE), 5.5.1)
|
||||
OS_LIBS += -ldl -lsocket -lnsl -lthread -lposix4
|
||||
endif
|
||||
ifeq ($(OS_RELEASE), 5.6)
|
||||
OS_LIBS += -ldl -lsocket -lnsl -lthread -lposix4
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(OS_ARCH), Linux)
|
||||
ifdef USE_PTHREADS
|
||||
# Replace OS_LIBS, because the order of libpthread, libdl, and libc are
|
||||
# very important. Otherwise you get horrible crashes.
|
||||
OS_LIBS = -lpthread -ldl -lc
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (5) Execute "global" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
include $(CORE_DEPTH)/coreconf/rules.mk
|
||||
|
||||
#######################################################################
|
||||
# (6) Execute "component" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (7) Execute "local" rules. (OPTIONAL). #
|
||||
#######################################################################
|
||||
|
||||
ifeq ($(OS_ARCH), WINNT)
|
||||
LDFLAGS += /NODEFAULTLIB:library
|
||||
endif
|
||||
|
||||
EXTRA_LIBS = \
|
||||
$(DIST)/lib/$(LIB_PREFIX)cmt.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)protocol.$(LIB_SUFFIX) \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(OS_ARCH), WINNT)
|
||||
EXTRA_LIBS += wsock32.lib \
|
||||
winmm.lib \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
link:
|
||||
if test -f $(PROGRAM); then \
|
||||
echo "rm $(PROGRAM)"; \
|
||||
rm $(PROGRAM); \
|
||||
fi; \
|
||||
gmake \
|
||||
|
||||
build_sample:
|
||||
ifneq ($(OS_ARCH),WINNT)
|
||||
cd $(CORE_DEPTH)/coreconf; gmake
|
||||
endif
|
||||
cd $(CORE_DEPTH)/security; gmake import; gmake export
|
||||
cd ../../protocol; gmake
|
||||
cd ..; gmake
|
||||
gmake
|
||||
|
||||
@@ -1,250 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "cmtcmn.h"
|
||||
#include "appsock.h"
|
||||
|
||||
#ifdef XP_UNIX
|
||||
#include <netinet/tcp.h>
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
CMT_SocketFuncs socketFuncs = {
|
||||
APP_GetSocket,
|
||||
APP_Connect,
|
||||
APP_VerifyUnixSocket,
|
||||
APP_Send,
|
||||
APP_Select,
|
||||
APP_Receive,
|
||||
APP_Shutdown,
|
||||
APP_Close
|
||||
};
|
||||
|
||||
CMTSocket APP_GetSocket(int unixSock)
|
||||
{
|
||||
APPSocket *sock;
|
||||
int on = 1;
|
||||
|
||||
#ifndef XP_UNIX
|
||||
if (unixSock) {
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
sock = malloc(sizeof(APPSocket));
|
||||
if (sock == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
if (unixSock) {
|
||||
sock->sock = socket(AF_UNIX, SOCK_STREAM, 0);
|
||||
} else {
|
||||
sock->sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
}
|
||||
if (sock->sock < 0) {
|
||||
free(sock);
|
||||
return NULL;
|
||||
}
|
||||
if (!unixSock &&
|
||||
setsockopt(sock->sock, IPPROTO_TCP, TCP_NODELAY, (const char*)&on,
|
||||
sizeof(on))) {
|
||||
free(sock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sock->isUnix = unixSock;
|
||||
#ifdef XP_UNIX
|
||||
memset (&sock->servAddr, 0, sizeof(struct sockaddr_un));
|
||||
#endif
|
||||
return (CMTSocket)sock;
|
||||
}
|
||||
|
||||
CMTStatus APP_Connect(CMTSocket sock, short port, char *path)
|
||||
{
|
||||
APPSocket *cmSock = (APPSocket*)sock;
|
||||
struct sockaddr_in iServAddr;
|
||||
const struct sockaddr *servAddr;
|
||||
size_t addrLen;
|
||||
int error;
|
||||
|
||||
if (cmSock->isUnix){
|
||||
#ifndef XP_UNIX
|
||||
return CMTFailure;
|
||||
#else
|
||||
cmSock->servAddr.sun_family = AF_UNIX;
|
||||
memcpy(&cmSock->servAddr.sun_path, path, strlen(path)+1);
|
||||
servAddr = (const struct sockaddr*)&cmSock->servAddr;
|
||||
addrLen = sizeof(cmSock->servAddr);
|
||||
#endif
|
||||
} else {
|
||||
iServAddr.sin_family = AF_INET;
|
||||
iServAddr.sin_port = htons(port);
|
||||
iServAddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
servAddr = (const struct sockaddr*)&iServAddr;
|
||||
addrLen = sizeof(struct sockaddr_in);
|
||||
}
|
||||
while (connect(cmSock->sock, servAddr, addrLen) != 0) {
|
||||
#ifdef WIN32
|
||||
error = WSAGetLastError();
|
||||
if (error == WSAEISCONN) {
|
||||
break;
|
||||
}
|
||||
if ((error != WSAEINPROGRESS) && (error != WSAEWOULDBLOCK) &&
|
||||
(error!= WSAEINVAL)) {
|
||||
goto loser;
|
||||
}
|
||||
#else
|
||||
error = errno;
|
||||
if (error == EISCONN) {
|
||||
break;
|
||||
}
|
||||
if (error != EINPROGRESS) {
|
||||
goto loser;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus APP_VerifyUnixSocket(CMTSocket sock)
|
||||
{
|
||||
#ifndef XP_UNIX
|
||||
return CMTFailure;
|
||||
#else
|
||||
APPSocket *cmSock = (APPSocket*)sock;
|
||||
int rv;
|
||||
struct stat statbuf;
|
||||
|
||||
if (!cmSock->isUnix) {
|
||||
return CMTFailure;
|
||||
}
|
||||
rv = stat(cmSock->servAddr.sun_path, &statbuf);
|
||||
if (rv < 0) {
|
||||
goto loser;
|
||||
}
|
||||
if (statbuf.st_uid != geteuid()) {
|
||||
goto loser;
|
||||
}
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
close(cmSock->sock);
|
||||
free(cmSock);
|
||||
return CMTFailure;
|
||||
#endif
|
||||
}
|
||||
|
||||
size_t APP_Send(CMTSocket sock, void *buffer, size_t length)
|
||||
{
|
||||
APPSocket *cmSock = (APPSocket*) sock;
|
||||
|
||||
return send(cmSock->sock, buffer, length, 0);
|
||||
}
|
||||
|
||||
CMTSocket APP_Select(CMTSocket *socks, int numsocks, int poll)
|
||||
{
|
||||
APPSocket **sockArr = (APPSocket**)socks;
|
||||
SOCKET nsocks = 0;
|
||||
int i, rv;
|
||||
struct timeval timeout;
|
||||
fd_set readfds;
|
||||
|
||||
#ifdef WIN32
|
||||
win_startover:
|
||||
#endif
|
||||
FD_ZERO(&readfds);
|
||||
for (i=0; i<numsocks; i++) {
|
||||
FD_SET(sockArr[i]->sock, &readfds);
|
||||
if (sockArr[i]->sock > nsocks) {
|
||||
nsocks = sockArr[i]->sock;
|
||||
}
|
||||
}
|
||||
if (poll) {
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 0;
|
||||
}
|
||||
rv = select(nsocks+1, &readfds, NULL, NULL, (poll) ? &timeout : NULL);
|
||||
|
||||
#ifdef WIN32
|
||||
/* XXX Win95/98 Bug (Q177346)
|
||||
* select() with no timeout might return even if there is no data
|
||||
* pending or no error has occurred. To get around this problem,
|
||||
* we loop if these erroneous conditions happen.
|
||||
*/
|
||||
if (poll == 0 && rv == 0) {
|
||||
goto win_startover;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Figure out which socket was selected */
|
||||
if (rv == -1 || rv == 0) {
|
||||
goto loser;
|
||||
}
|
||||
for (i=0; i<numsocks; i++) {
|
||||
if (FD_ISSET(sockArr[i]->sock, &readfds)) {
|
||||
return (CMTSocket)sockArr[i];
|
||||
}
|
||||
}
|
||||
loser:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t APP_Receive(CMTSocket sock, void *buffer, size_t bufSize)
|
||||
{
|
||||
APPSocket *cmSock = (APPSocket*)sock;
|
||||
|
||||
return recv(cmSock->sock, buffer, bufSize, 0);
|
||||
}
|
||||
|
||||
CMTStatus APP_Shutdown(CMTSocket sock)
|
||||
{
|
||||
APPSocket *cmSock = (APPSocket*)sock;
|
||||
int rv;
|
||||
|
||||
rv = shutdown(cmSock->sock, 1);
|
||||
return (rv == 0) ? CMTSuccess : CMTFailure;
|
||||
}
|
||||
|
||||
CMTStatus APP_Close(CMTSocket sock)
|
||||
{
|
||||
APPSocket *cmSock = (APPSocket*)sock;
|
||||
int rv;
|
||||
|
||||
#ifdef XP_UNIX
|
||||
rv = close(cmSock->sock);
|
||||
#else
|
||||
rv = closesocket(cmSock->sock);
|
||||
#endif
|
||||
free(cmSock);
|
||||
return (rv == 0) ? CMTSuccess : CMTFailure;
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef _APPSOCK_H_
|
||||
#define _APPSOCK_H_
|
||||
#include "cmtcmn.h"
|
||||
|
||||
#ifdef XP_UNIX
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/un.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
typedef int SOCKET;
|
||||
#endif
|
||||
|
||||
typedef struct APPSocketStr {
|
||||
SOCKET sock;
|
||||
int isUnix;
|
||||
#ifdef XP_UNIX
|
||||
struct sockaddr_un servAddr;
|
||||
#endif
|
||||
} APPSocket;
|
||||
|
||||
extern CMT_SocketFuncs socketFuncs;
|
||||
|
||||
CMTStatus APP_Close(CMTSocket sock);
|
||||
CMTStatus APP_Shutdown(CMTSocket sock);
|
||||
size_t APP_Receive(CMTSocket sock, void *buffer, size_t bufSize);
|
||||
CMTSocket APP_Select(CMTSocket *socks, int numsocks, int poll);
|
||||
size_t APP_Send(CMTSocket sock, void *buffer, size_t length);
|
||||
CMTStatus APP_VerifyUnixSocket(CMTSocket sock);
|
||||
CMTStatus APP_Connect(CMTSocket sock, short port, char *path);
|
||||
CMTSocket APP_GetSocket(int unixSock);
|
||||
|
||||
|
||||
#endif /* _APPSOCK_H_ */
|
||||
@@ -1,44 +0,0 @@
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is the Netscape security libraries.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU General Public License Version 2 or later (the
|
||||
# "GPL"), in which case the provisions of the GPL are applicable
|
||||
# instead of those above. If you wish to allow use of your
|
||||
# version of this file only under the terms of the GPL and not to
|
||||
# allow others to use your version of this file under the MPL,
|
||||
# indicate your decision by deleting the provisions above and
|
||||
# replace them with the notice and other provisions required by
|
||||
# the GPL. If you do not delete the provisions above, a recipient
|
||||
# may use your version of this file under either the MPL or the
|
||||
# GPL.
|
||||
#
|
||||
|
||||
#
|
||||
# Override TARGETS variable so that only static libraries
|
||||
# are specifed as dependencies within rules.mk.
|
||||
#
|
||||
|
||||
TARGETS = $(PROGRAM)
|
||||
SHARED_LIBRARY =
|
||||
IMPORT_LIBRARY =
|
||||
PURE_LIBRARY =
|
||||
LIBRARY =
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is the Netscape security libraries.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU General Public License Version 2 or later (the
|
||||
# "GPL"), in which case the provisions of the GPL are applicable
|
||||
# instead of those above. If you wish to allow use of your
|
||||
# version of this file only under the terms of the GPL and not to
|
||||
# allow others to use your version of this file under the MPL,
|
||||
# indicate your decision by deleting the provisions above and
|
||||
# replace them with the notice and other provisions required by
|
||||
# the GPL. If you do not delete the provisions above, a recipient
|
||||
# may use your version of this file under either the MPL or the
|
||||
# GPL.
|
||||
#
|
||||
CORE_DEPTH = ../../../../..
|
||||
|
||||
# MODULE public and private header directories are implicitly REQUIRED.
|
||||
MODULE = cmtsample
|
||||
|
||||
EXPORTS = \
|
||||
$(NULL)
|
||||
|
||||
CSRCS = \
|
||||
sample.c \
|
||||
appsock.c \
|
||||
$(NULL)
|
||||
INCLUDES += -I../../protocol -I..
|
||||
|
||||
# The MODULE is always implicitly required.
|
||||
# Listing it here in REQUIRES makes it appear twice in the cc command line.
|
||||
REQUIRES = security
|
||||
|
||||
PROGRAM = cmtsample
|
||||
|
||||
@@ -1,346 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "cmtcmn.h"
|
||||
#include "cmtjs.h"
|
||||
#include "appsock.h"
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef XP_UNIX
|
||||
#include <netdb.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#include <direct.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This is a simple program that tries to detect if the psm server is loaded.
|
||||
* If the server is not loaded, it will start it. The program will then
|
||||
* connect to the server and fetch an HTML page from an SSL server.
|
||||
*
|
||||
* NOTE: This sample program does not implement a mutex for the libraries.
|
||||
* If implementing a threaded application, then pass in a mutex structure
|
||||
* so that connections to the psm server happen in a thread safe manner.
|
||||
*/
|
||||
|
||||
#define NUM_CONNECT_TRIES 10
|
||||
#define READ_BUFFER_SIZE 1024
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
printf("Usage:\n"
|
||||
"\tcmtsample <secure site>\n\n"
|
||||
"This program will then echo the retrieved HTML to the screen\n");
|
||||
}
|
||||
|
||||
void
|
||||
errorMessage(int err,char *msg, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, msg);
|
||||
fprintf (stderr, "cmtSample%s: ", (err) ? " error" : "");
|
||||
vfprintf (stderr, msg, args);
|
||||
fprintf (stderr, "\n");
|
||||
va_end(args);
|
||||
if (err) {
|
||||
exit (err);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef XP_UNIX
|
||||
#define FILE_PATH_SEPARATOR '/'
|
||||
#elif defined (WIN32)
|
||||
#define FILE_PATH_SEPARATOR '\\'
|
||||
#else
|
||||
#error Tell me what the file path separator is.
|
||||
#endif
|
||||
|
||||
PCMT_CONTROL
|
||||
connect_to_psm(void)
|
||||
{
|
||||
PCMT_CONTROL control=NULL;
|
||||
char path[256], *tmp;
|
||||
|
||||
#ifdef XP_UNIX
|
||||
if (getcwd(path,256) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
#elif defined(WIN32)
|
||||
if (_getcwd(path,256) == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
#error Teach me how to get the current working directory.
|
||||
#endif
|
||||
tmp = &path[strlen(path)];
|
||||
sprintf(tmp,"%c%s", FILE_PATH_SEPARATOR, "psm");
|
||||
return CMT_EstablishControlConnection(path, &socketFuncs, NULL);
|
||||
}
|
||||
|
||||
#define HTTPS_STRING "https://"
|
||||
|
||||
char*
|
||||
extract_host_from_url(char *url)
|
||||
{
|
||||
char *start, *end, *retString=NULL;
|
||||
|
||||
while(isspace(*url)) {
|
||||
url++;
|
||||
}
|
||||
url = strdup(url);
|
||||
start = strstr(url, HTTPS_STRING);
|
||||
if (start == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
start += strlen(HTTPS_STRING);
|
||||
/*
|
||||
* Figure out the end of the host name.
|
||||
*/
|
||||
end = strchr(start, ':');
|
||||
if (end != NULL) {
|
||||
*end = '\0';
|
||||
} else {
|
||||
end = strchr(start, '/');
|
||||
if (end != NULL) {
|
||||
*end = '\0';
|
||||
} else {
|
||||
end = strchr(start, ' ');
|
||||
if (end != NULL) {
|
||||
*end = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
retString = strdup(start);
|
||||
return retString;
|
||||
}
|
||||
|
||||
CMUint32
|
||||
get_port_from_url(char *url)
|
||||
{
|
||||
char *colon, *port;
|
||||
|
||||
url = strdup(url);
|
||||
colon = strrchr(url, ':');
|
||||
if (colon == NULL ||
|
||||
!isdigit(colon[1])) {
|
||||
/* Return the default SSL port. */
|
||||
free(url);
|
||||
return 443;
|
||||
}
|
||||
colon++;
|
||||
port = colon;
|
||||
while(isdigit(*colon))
|
||||
colon++;
|
||||
colon[1] = '\0';
|
||||
free(url);
|
||||
return (CMUint32)atol(port);
|
||||
}
|
||||
|
||||
char*
|
||||
extract_get_target(char *url)
|
||||
{
|
||||
char *slash;
|
||||
|
||||
slash = strstr(url, "//");
|
||||
slash += 2;
|
||||
slash = strchr(slash, '/');
|
||||
if (slash != NULL)
|
||||
return strdup (slash);
|
||||
else
|
||||
return strdup ("/");
|
||||
}
|
||||
|
||||
/*
|
||||
* We'll use this function for prompting for a password.
|
||||
*/
|
||||
char*
|
||||
passwordCallback(void *arg, char *prompt, void *cotext, int isPaswd)
|
||||
{
|
||||
char input[256];
|
||||
|
||||
printf(prompt);
|
||||
fgets(input, 256, stdin);
|
||||
|
||||
return strdup(input);
|
||||
}
|
||||
|
||||
void
|
||||
freeCallback(char *userInput)
|
||||
{
|
||||
free (userInput);
|
||||
}
|
||||
|
||||
#define NUM_PREFS 2
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
PCMT_CONTROL control;
|
||||
CMTSocket sock, selSock;
|
||||
char *hostname;
|
||||
struct hostent *host;
|
||||
char *ipAddress;
|
||||
char buffer[READ_BUFFER_SIZE];
|
||||
size_t bytesRead;
|
||||
struct sockaddr_in destAddr;
|
||||
char *getString;
|
||||
char requestString[256];
|
||||
char *profile;
|
||||
CMTSetPrefElement prefs[NUM_PREFS];
|
||||
char profileDir[256];
|
||||
|
||||
#ifdef WIN32
|
||||
WORD WSAVersion = 0x0101;
|
||||
WSADATA WSAData;
|
||||
|
||||
WSAStartup (WSAVersion, &WSAData);
|
||||
#endif
|
||||
|
||||
if (argc < 2) {
|
||||
usage();
|
||||
return 1;
|
||||
}
|
||||
errorMessage (0,"cmtsample v1.0");
|
||||
errorMessage (0,"Will try connecting to site %s", argv[1]);
|
||||
if (strstr(argv[1], "https://") == NULL) {
|
||||
errorMessage(2,"%s is not a secure site", argv[1]);
|
||||
}
|
||||
control = connect_to_psm();
|
||||
if (control == NULL) {
|
||||
errorMessage(3, "Could not connect to the psm server");
|
||||
}
|
||||
/*
|
||||
* Now we have to send the hello message.
|
||||
*/
|
||||
|
||||
#ifdef WIN32
|
||||
profile = strdup("default");
|
||||
sprintf(profileDir,"%s", "c:\\default");
|
||||
#elif defined (XP_UNIX)
|
||||
profile = getenv("LOGNAME");
|
||||
sprintf(profileDir, "%s/.netscape", getenv("HOME"));
|
||||
#else
|
||||
#error Teach me how to fill in the user profile.
|
||||
#endif
|
||||
if (CMT_Hello(control, PROTOCOL_VERSION,
|
||||
profile, profileDir) != CMTSuccess)
|
||||
{
|
||||
errorMessage(10, "Failed to send the Hello Message.");
|
||||
}
|
||||
CMT_SetPromptCallback(control, passwordCallback, NULL);
|
||||
CMT_SetAppFreeCallback(control, freeCallback);
|
||||
/*
|
||||
* Now pass along some preferences to psm. We'll pass hard coded
|
||||
* ones here, but apps should figure out a way to manage their user's
|
||||
* preferences.
|
||||
*/
|
||||
prefs[0].key = "security.enable_ssl2";
|
||||
prefs[0].value = "true";
|
||||
prefs[0].type = CMT_PREF_BOOL;
|
||||
prefs[1].key = "security.enable_ssl3";
|
||||
prefs[1].value = "true";
|
||||
prefs[1].type = CMT_PREF_BOOL;
|
||||
CMT_PassAllPrefs(control, NUM_PREFS, prefs);
|
||||
hostname = extract_host_from_url(argv[1]);
|
||||
host = gethostbyname(hostname);
|
||||
if (host == NULL) {
|
||||
errorMessage(11, "gethostbyname for %s failed", hostname);
|
||||
}
|
||||
if (host->h_length != 4) {
|
||||
errorMessage(4, "Site %s uses IV v6 socket. Not supported by psm.");
|
||||
}
|
||||
|
||||
/* Create the socket we will use to get the decrypted data back from
|
||||
* the psm server.
|
||||
*/
|
||||
sock = APP_GetSocket(0);
|
||||
if (sock == NULL) {
|
||||
errorMessage(5, "Could not create new socket for communication with "
|
||||
"the psm server.");
|
||||
}
|
||||
memcpy(&(destAddr.sin_addr.s_addr), host->h_addr, host->h_length);
|
||||
ipAddress = inet_ntoa(destAddr.sin_addr);
|
||||
errorMessage(0, "Mapped %s to the following IP address: %s", argv[1],
|
||||
ipAddress);
|
||||
|
||||
if (CMT_OpenSSLConnection(control, sock, SSM_REQUEST_SSL_DATA_SSL,
|
||||
get_port_from_url(argv[1]), ipAddress,
|
||||
hostname, CM_FALSE, NULL) != CMTSuccess) {
|
||||
errorMessage(6, "Could not open SSL connection to %s.", argv[1]);
|
||||
}
|
||||
|
||||
getString = extract_get_target(argv[1]);
|
||||
sprintf(requestString,
|
||||
"GET %s HTTP/1.0\r\n"
|
||||
"\r\n", getString, hostname);
|
||||
APP_Send(sock, requestString, strlen(requestString));
|
||||
/*
|
||||
* Now all we have to do is sit here and fetch the data from the
|
||||
* socket.
|
||||
*/
|
||||
errorMessage (0, "About to print out the fetched page.");
|
||||
while ((selSock=APP_Select(&sock, 1, 0)) != NULL) {
|
||||
if (selSock == sock) {
|
||||
bytesRead = APP_Receive(sock, buffer, READ_BUFFER_SIZE-1);
|
||||
if (bytesRead == -1 || bytesRead == 0) {
|
||||
break;
|
||||
}
|
||||
buffer[bytesRead] = '\0';
|
||||
fprintf(stderr, buffer);
|
||||
}
|
||||
}
|
||||
fprintf(stderr,"\n");
|
||||
if (bytesRead == -1) {
|
||||
errorMessage(7, "Error receiving decrypted data from psm.");
|
||||
}
|
||||
errorMessage(0, "Successfully read the entire page.");
|
||||
if (CMT_DestroyDataConnection(control, sock) != CMTSuccess) {
|
||||
errorMessage(8, "Error destroygin the SSL data connection "
|
||||
"with the psm server.");
|
||||
}
|
||||
if (CMT_CloseControlConnection(control) != CMTSuccess) {
|
||||
errorMessage(9, "Error closing the control connection.");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "cmt.h"
|
||||
|
||||
CMTStatus myCallback(CMTControl * control, CMTItem * event, void * arg);
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
CMTItem * msg, * event = NULL;
|
||||
CMTStatus status;
|
||||
int socket, datasocket;
|
||||
int sent;
|
||||
CMTControl * connect;
|
||||
char * buffer = "some weird text that I feel like passing to server";
|
||||
|
||||
connect = CMT_ControlConnect(myCallback, event);
|
||||
|
||||
msg = CMT_ConstructMessage(10);
|
||||
|
||||
msg->type = (int)CMTClientMessage;
|
||||
sprintf((char *)msg->data, "first msg!");
|
||||
|
||||
status = CMT_SendMessage(connect, msg, event);
|
||||
if (status != SECSuccess)
|
||||
perror("CMT_SendMessage");
|
||||
|
||||
CMT_FreeEvent(event);
|
||||
event = NULL;
|
||||
|
||||
sprintf((char *)msg->data, "second msg");
|
||||
status = CMT_SendMessage(connect, msg, event);
|
||||
if (status != SECSuccess)
|
||||
perror("CMT_SendMessage");
|
||||
|
||||
datasocket = CMT_DataConnect(connect, NULL);
|
||||
if (datasocket < 0)
|
||||
perror("CMT_DataConnect");
|
||||
|
||||
sent = write(datasocket, (void *)buffer, strlen(buffer));
|
||||
sent = write(datasocket, (void *)buffer, strlen(buffer));
|
||||
|
||||
close(datasocket);
|
||||
|
||||
msg->type = (int)CMTClientMessage;
|
||||
sprintf((char *)msg->data, "third msg!");
|
||||
status = CMT_SendMessage(connect, msg, event);
|
||||
if (status != SECSuccess)
|
||||
perror("CMT_SendMessage");
|
||||
|
||||
status = CMT_CloseControlConnection(connect);
|
||||
if (status != SECSuccess)
|
||||
perror("CMT_CloseControl");
|
||||
|
||||
CMT_FreeMessage(msg);
|
||||
CMT_FreeEvent(event);
|
||||
}
|
||||
|
||||
CMTStatus myCallback(CMTControl * control, CMTItem * event, void * arg)
|
||||
{
|
||||
if (event)
|
||||
printf("Event received is : type %d, data %s\n", event->type, event->data);
|
||||
else printf("No event!\n");
|
||||
if (arg)
|
||||
printf("Arg is %s\n", (char *)arg);
|
||||
else printf("No arg!\n");
|
||||
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
Binary file not shown.
@@ -1,3 +0,0 @@
|
||||
|
||||
|
||||
#include "MacPrefix.h"
|
||||
@@ -1,2 +0,0 @@
|
||||
|
||||
#include "MacPrefix_debug.h"
|
||||
Binary file not shown.
@@ -1,27 +0,0 @@
|
||||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
|
||||
DEPTH=..\..\..
|
||||
include <$(DEPTH)/config/config.mak>
|
||||
|
||||
DIRS = client protocol
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
@@ -1,43 +0,0 @@
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is the Netscape security libraries.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU General Public License Version 2 or later (the
|
||||
# "GPL"), in which case the provisions of the GPL are applicable
|
||||
# instead of those above. If you wish to allow use of your
|
||||
# version of this file only under the terms of the GPL and not to
|
||||
# allow others to use your version of this file under the MPL,
|
||||
# indicate your decision by deleting the provisions above and
|
||||
# replace them with the notice and other provisions required by
|
||||
# the GPL. If you do not delete the provisions above, a recipient
|
||||
# may use your version of this file under either the MPL or the
|
||||
# GPL.
|
||||
#
|
||||
#
|
||||
|
||||
CORE_DEPTH = ../..
|
||||
DEPTH = ../..
|
||||
|
||||
DIRS = protocol client
|
||||
|
||||
#
|
||||
# these dirs are not built at the moment
|
||||
#
|
||||
#NOBUILD_DIRS = jar
|
||||
@@ -1,3 +0,0 @@
|
||||
obscure.h
|
||||
rsrcids.h
|
||||
ssmdefs.h
|
||||
@@ -1,74 +0,0 @@
|
||||
#! gmake
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is the Netscape security libraries.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU General Public License Version 2 or later (the
|
||||
# "GPL"), in which case the provisions of the GPL are applicable
|
||||
# instead of those above. If you wish to allow use of your
|
||||
# version of this file only under the terms of the GPL and not to
|
||||
# allow others to use your version of this file under the MPL,
|
||||
# indicate your decision by deleting the provisions above and
|
||||
# replace them with the notice and other provisions required by
|
||||
# the GPL. If you do not delete the provisions above, a recipient
|
||||
# may use your version of this file under either the MPL or the
|
||||
# GPL.
|
||||
#
|
||||
|
||||
#######################################################################
|
||||
# (1) Include initial platform-independent assignments (MANDATORY). #
|
||||
#######################################################################
|
||||
|
||||
include manifest.mn
|
||||
|
||||
#######################################################################
|
||||
# (2) Include "global" configuration information. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
include $(CORE_DEPTH)/coreconf/config.mk
|
||||
|
||||
#######################################################################
|
||||
# (3) Include "component" configuration information. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (4) Include "local" platform-dependent assignments (OPTIONAL). #
|
||||
#######################################################################
|
||||
include config.mk
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (5) Execute "global" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
include $(CORE_DEPTH)/coreconf/rules.mk
|
||||
|
||||
#######################################################################
|
||||
# (6) Execute "component" rules. (OPTIONAL) #
|
||||
#######################################################################
|
||||
|
||||
|
||||
|
||||
#######################################################################
|
||||
# (7) Execute "local" rules. (OPTIONAL). #
|
||||
#######################################################################
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
#! gmake
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is the Netscape security libraries.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU General Public License Version 2 or later (the
|
||||
# "GPL"), in which case the provisions of the GPL are applicable
|
||||
# instead of those above. If you wish to allow use of your
|
||||
# version of this file only under the terms of the GPL and not to
|
||||
# allow others to use your version of this file under the MPL,
|
||||
# indicate your decision by deleting the provisions above and
|
||||
# replace them with the notice and other provisions required by
|
||||
# the GPL. If you do not delete the provisions above, a recipient
|
||||
# may use your version of this file under either the MPL or the
|
||||
# GPL.
|
||||
#
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
LIBRARY_NAME = protocol
|
||||
MODULE = security
|
||||
|
||||
EXPORTS = \
|
||||
protocol.h \
|
||||
protocolf.h \
|
||||
protocolport.h \
|
||||
protocolnspr20.h \
|
||||
protocolshr.h \
|
||||
ssmdefs.h \
|
||||
rsrcids.h \
|
||||
messages.h \
|
||||
newproto.h \
|
||||
$(NULL)
|
||||
|
||||
|
||||
CSRCS = newproto.c \
|
||||
templates.c \
|
||||
protocolshr.c \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is the Netscape security libraries.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU General Public License Version 2 or later (the
|
||||
# "GPL"), in which case the provisions of the GPL are applicable
|
||||
# instead of those above. If you wish to allow use of your
|
||||
# version of this file only under the terms of the GPL and not to
|
||||
# allow others to use your version of this file under the MPL,
|
||||
# indicate your decision by deleting the provisions above and
|
||||
# replace them with the notice and other provisions required by
|
||||
# the GPL. If you do not delete the provisions above, a recipient
|
||||
# may use your version of this file under either the MPL or the
|
||||
# GPL.
|
||||
#
|
||||
|
||||
#
|
||||
# Override TARGETS variable so that only static libraries
|
||||
# are specifed as dependencies within rules.mk.
|
||||
#
|
||||
|
||||
TARGETS = $(LIBRARY)
|
||||
SHARED_LIBRARY =
|
||||
IMPORT_LIBRARY =
|
||||
PURE_LIBRARY =
|
||||
PROGRAM =
|
||||
|
||||
@@ -1,124 +0,0 @@
|
||||
#//
|
||||
#// The contents of this file are subject to the Mozilla Public
|
||||
#// License Version 1.1 (the "License"); you may not use this file
|
||||
#// except in compliance with the License. You may obtain a copy of
|
||||
#// the License at http://www.mozilla.org/MPL/
|
||||
#//
|
||||
#// Software distributed under the License is distributed on an "AS
|
||||
#// IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
#// implied. See the License for the specific language governing
|
||||
#// rights and limitations under the License.
|
||||
#//
|
||||
#// The Original Code is the Netscape security libraries.
|
||||
#//
|
||||
#// The Initial Developer of the Original Code is Netscape
|
||||
#// Communications Corporation. Portions created by Netscape are
|
||||
#// Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
#// Rights Reserved.
|
||||
#//
|
||||
#// Contributor(s):
|
||||
#//
|
||||
#// Alternatively, the contents of this file may be used under the
|
||||
#// terms of the GNU General Public License Version 2 or later (the
|
||||
#// "GPL"), in which case the provisions of the GPL are applicable
|
||||
#// instead of those above. If you wish to allow use of your
|
||||
#// version of this file only under the terms of the GPL and not to
|
||||
#// allow others to use your version of this file under the MPL,
|
||||
#// indicate your decision by deleting the provisions above and
|
||||
#// replace them with the notice and other provisions required by
|
||||
#// the GPL. If you do not delete the provisions above, a recipient
|
||||
#// may use your version of this file under either the MPL or the
|
||||
#// GPL.
|
||||
#//
|
||||
IGNORE_MANIFEST=1
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Makefile to build the ssl library
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
|
||||
!if "$(MOZ_BITS)" == "16"
|
||||
!ifndef MOZ_DEBUG
|
||||
OPTIMIZER=-Os -UDEBUG -DNDEBUG
|
||||
!endif
|
||||
!endif
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Specify the depth of the current directory relative to the
|
||||
#// root of NS
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
DEPTH= ..\..\..\..
|
||||
|
||||
!ifndef MAKE_OBJ_TYPE
|
||||
MAKE_OBJ_TYPE=EXE
|
||||
!endif
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Define any Public Make Variables here: (ie. PDFFILE, MAPFILE, ...)
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
LIBNAME=protocol
|
||||
PDBFILE=$(LIBNAME).pdb
|
||||
|
||||
LINCS = -I$(PUBLIC)\security \
|
||||
-I$(PUBLIC)\nspr \
|
||||
-I$(DEPTH)\include \
|
||||
-I..\include
|
||||
|
||||
!ifndef OS_CONFIG
|
||||
OS_CONFIG = WIN$(MOZ_BITS)
|
||||
!endif
|
||||
|
||||
LCFLAGS = -DEXPORT_VERSION -DLIB_BUILD
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Define the files necessary to build the target (ie. OBJS)
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
OBJS= \
|
||||
.\$(OBJDIR)\newproto.obj \
|
||||
.\$(OBJDIR)\templates.obj \
|
||||
.\$(OBJDIR)\protocolshr.obj \
|
||||
$(NULL)
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Define any Public Targets here (ie. PROGRAM, LIBRARY, DLL, ...)
|
||||
#// (these must be defined before the common makefiles are included)
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
LIBRARY=.\$(OBJDIR)\$(LIBNAME).lib
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// install headers
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
INSTALL_DIR=$(PUBLIC)\security
|
||||
INSTALL_FILE_LIST= protocol.h \
|
||||
protocolf.h \
|
||||
protocolport.h \
|
||||
protocolnspr20.h \
|
||||
protocolshr.h \
|
||||
ssmdefs.h \
|
||||
rsrcids.h \
|
||||
messages.h \
|
||||
newproto.h \
|
||||
$(NULL)
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Include the common makefile rules
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
include <$(DEPTH)/config/rules.mak>
|
||||
|
||||
install:: $(LIBRARY)
|
||||
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
|
||||
|
||||
export:: INSTALL_FILES
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/MPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is the Netscape security libraries.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the
|
||||
# terms of the GNU General Public License Version 2 or later (the
|
||||
# "GPL"), in which case the provisions of the GPL are applicable
|
||||
# instead of those above. If you wish to allow use of your
|
||||
# version of this file only under the terms of the GPL and not to
|
||||
# allow others to use your version of this file under the MPL,
|
||||
# indicate your decision by deleting the provisions above and
|
||||
# replace them with the notice and other provisions required by
|
||||
# the GPL. If you do not delete the provisions above, a recipient
|
||||
# may use your version of this file under either the MPL or the
|
||||
# GPL.
|
||||
#
|
||||
|
||||
CORE_DEPTH = ../../..
|
||||
|
||||
EXPORTS = \
|
||||
protocol.h \
|
||||
protocolf.h \
|
||||
protocolport.h \
|
||||
protocolnspr20.h \
|
||||
protocolshr.h \
|
||||
ssmdefs.h \
|
||||
rsrcids.h \
|
||||
messages.h \
|
||||
newproto.h \
|
||||
$(NULL)
|
||||
|
||||
MODULE = security
|
||||
CSRCS = newproto.c \
|
||||
protocolshr.c \
|
||||
templates.c \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(subst /,_,$(shell uname -s)),OS2)
|
||||
CSRCS += os2_rand.c
|
||||
endif
|
||||
|
||||
# mac_rand.c
|
||||
# unix_rand.c
|
||||
# win_rand.c
|
||||
# prelib.c
|
||||
|
||||
REQUIRES = security dbm nspr
|
||||
|
||||
LIBRARY_NAME = protocol
|
||||
@@ -1,620 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef __MESSAGES_H__
|
||||
#define __MESSAGES_H__
|
||||
|
||||
#include "newproto.h"
|
||||
|
||||
typedef struct SingleNumMessage {
|
||||
CMInt32 value;
|
||||
} SingleNumMessage;
|
||||
|
||||
extern CMTMessageTemplate SingleNumMessageTemplate[];
|
||||
|
||||
typedef struct SingleStringMessage {
|
||||
char *string;
|
||||
} SingleStringMessage;
|
||||
|
||||
extern CMTMessageTemplate SingleStringMessageTemplate[];
|
||||
|
||||
typedef struct SingleItemMessage {
|
||||
CMTItem item;
|
||||
} SingleItemMessage;
|
||||
|
||||
extern CMTMessageTemplate SingleItemMessageTemplate[];
|
||||
|
||||
typedef struct HelloRequest {
|
||||
CMInt32 version;
|
||||
CMInt32 policy;
|
||||
CMBool doesUI;
|
||||
char *profile;
|
||||
char* profileDir;
|
||||
} HelloRequest;
|
||||
|
||||
extern CMTMessageTemplate HelloRequestTemplate[];
|
||||
|
||||
typedef struct HelloReply {
|
||||
CMInt32 result;
|
||||
CMInt32 sessionID;
|
||||
CMInt32 version;
|
||||
CMInt32 httpPort;
|
||||
CMInt32 policy;
|
||||
CMTItem nonce;
|
||||
char *stringVersion;
|
||||
} HelloReply;
|
||||
|
||||
extern CMTMessageTemplate HelloReplyTemplate[];
|
||||
|
||||
typedef struct SSLDataConnectionRequest {
|
||||
CMInt32 flags;
|
||||
CMInt32 port;
|
||||
char *hostIP;
|
||||
char *hostName;
|
||||
CMBool forceHandshake;
|
||||
CMTItem clientContext;
|
||||
} SSLDataConnectionRequest;
|
||||
|
||||
extern CMTMessageTemplate SSLDataConnectionRequestTemplate[];
|
||||
|
||||
typedef struct TLSDataConnectionRequest {
|
||||
CMInt32 port;
|
||||
char* hostIP;
|
||||
char* hostName;
|
||||
} TLSDataConnectionRequest;
|
||||
|
||||
extern CMTMessageTemplate TLSDataConnectionRequestTemplate[];
|
||||
|
||||
typedef struct TLSStepUpRequest {
|
||||
CMUint32 connID;
|
||||
CMTItem clientContext;
|
||||
} TLSStepUpRequest;
|
||||
|
||||
extern CMTMessageTemplate TLSStepUpRequestTemplate[];
|
||||
|
||||
typedef struct ProxyStepUpRequest {
|
||||
CMUint32 connID;
|
||||
CMTItem clientContext;
|
||||
char* url;
|
||||
} ProxyStepUpRequest;
|
||||
|
||||
extern CMTMessageTemplate ProxyStepUpRequestTemplate[];
|
||||
|
||||
typedef struct PKCS7DataConnectionRequest {
|
||||
CMUint32 resID;
|
||||
CMTItem clientContext;
|
||||
} PKCS7DataConnectionRequest;
|
||||
|
||||
extern CMTMessageTemplate PKCS7DataConnectionRequestTemplate[];
|
||||
|
||||
typedef struct DataConnectionReply {
|
||||
CMInt32 result;
|
||||
CMInt32 connID;
|
||||
CMInt32 port;
|
||||
} DataConnectionReply;
|
||||
|
||||
extern CMTMessageTemplate DataConnectionReplyTemplate[];
|
||||
|
||||
typedef struct UIEvent {
|
||||
CMInt32 resourceID;
|
||||
CMInt32 width;
|
||||
CMInt32 height;
|
||||
CMBool isModal;
|
||||
char *url;
|
||||
CMTItem clientContext;
|
||||
} UIEvent;
|
||||
|
||||
extern CMTMessageTemplate UIEventTemplate[];
|
||||
extern CMTMessageTemplate OldUIEventTemplate[];
|
||||
|
||||
typedef struct TaskCompletedEvent {
|
||||
CMInt32 resourceID;
|
||||
CMInt32 numTasks;
|
||||
CMInt32 result;
|
||||
} TaskCompletedEvent;
|
||||
|
||||
extern CMTMessageTemplate TaskCompletedEventTemplate[];
|
||||
|
||||
typedef struct VerifyDetachedSigRequest {
|
||||
CMInt32 pkcs7ContentID;
|
||||
CMInt32 certUsage;
|
||||
CMInt32 hashAlgID;
|
||||
CMBool keepCert;
|
||||
CMTItem hash;
|
||||
} VerifyDetachedSigRequest;
|
||||
|
||||
extern CMTMessageTemplate VerifyDetachedSigRequestTemplate[];
|
||||
|
||||
typedef struct CreateSignedRequest {
|
||||
CMInt32 scertRID;
|
||||
CMInt32 ecertRID;
|
||||
CMInt32 dig_alg;
|
||||
CMTItem digest;
|
||||
} CreateSignedRequest;
|
||||
|
||||
extern CMTMessageTemplate CreateSignedRequestTemplate[];
|
||||
|
||||
typedef struct CreateContentInfoReply {
|
||||
CMInt32 ciRID;
|
||||
CMInt32 result;
|
||||
CMInt32 errorCode;
|
||||
} CreateContentInfoReply;
|
||||
|
||||
extern CMTMessageTemplate CreateContentInfoReplyTemplate[];
|
||||
|
||||
typedef struct CreateEncryptedRequest {
|
||||
CMInt32 scertRID;
|
||||
CMInt32 nrcerts;
|
||||
CMInt32 *rcertRIDs;
|
||||
} CreateEncryptedRequest;
|
||||
|
||||
extern CMTMessageTemplate CreateEncryptedRequestTemplate[];
|
||||
|
||||
typedef struct CreateResourceRequest {
|
||||
CMInt32 type;
|
||||
CMTItem params;
|
||||
} CreateResourceRequest;
|
||||
|
||||
extern CMTMessageTemplate CreateResourceRequestTemplate[];
|
||||
|
||||
typedef struct CreateResourceReply {
|
||||
CMInt32 result;
|
||||
CMInt32 resID;
|
||||
} CreateResourceReply;
|
||||
|
||||
extern CMTMessageTemplate CreateResourceReplyTemplate[];
|
||||
|
||||
typedef struct GetAttribRequest {
|
||||
CMInt32 resID;
|
||||
CMInt32 fieldID;
|
||||
} GetAttribRequest;
|
||||
|
||||
extern CMTMessageTemplate GetAttribRequestTemplate[];
|
||||
|
||||
typedef struct GetAttribReply {
|
||||
CMInt32 result;
|
||||
SSMAttributeValue value;
|
||||
} GetAttribReply;
|
||||
|
||||
extern CMTMessageTemplate GetAttribReplyTemplate[];
|
||||
|
||||
typedef struct SetAttribRequest {
|
||||
CMInt32 resID;
|
||||
CMInt32 fieldID;
|
||||
SSMAttributeValue value;
|
||||
} SetAttribRequest;
|
||||
|
||||
extern CMTMessageTemplate SetAttribRequestTemplate[];
|
||||
|
||||
typedef struct PickleResourceReply {
|
||||
CMInt32 result;
|
||||
CMTItem blob;
|
||||
} PickleResourceReply;
|
||||
|
||||
extern CMTMessageTemplate PickleResourceReplyTemplate[];
|
||||
|
||||
typedef struct UnpickleResourceRequest {
|
||||
CMInt32 resourceType;
|
||||
CMTItem resourceData;
|
||||
} UnpickleResourceRequest;
|
||||
|
||||
extern CMTMessageTemplate UnpickleResourceRequestTemplate[];
|
||||
|
||||
typedef struct UnpickleResourceReply {
|
||||
CMInt32 result;
|
||||
CMInt32 resID;
|
||||
} UnpickleResourceReply;
|
||||
|
||||
extern CMTMessageTemplate UnpickleResourceReplyTemplate[];
|
||||
|
||||
typedef struct PickleSecurityStatusReply {
|
||||
CMInt32 result;
|
||||
CMInt32 securityLevel;
|
||||
CMTItem blob;
|
||||
} PickleSecurityStatusReply;
|
||||
|
||||
extern CMTMessageTemplate PickleSecurityStatusReplyTemplate[];
|
||||
|
||||
typedef struct DupResourceReply {
|
||||
CMInt32 result;
|
||||
CMUint32 resID;
|
||||
} DupResourceReply;
|
||||
|
||||
extern CMTMessageTemplate DupResourceReplyTemplate[];
|
||||
|
||||
typedef struct DestroyResourceRequest {
|
||||
CMInt32 resID;
|
||||
CMInt32 resType;
|
||||
} DestroyResourceRequest;
|
||||
|
||||
extern CMTMessageTemplate DestroyResourceRequestTemplate[];
|
||||
|
||||
typedef struct VerifyCertRequest {
|
||||
CMInt32 resID;
|
||||
CMInt32 certUsage;
|
||||
} VerifyCertRequest;
|
||||
|
||||
extern CMTMessageTemplate VerifyCertRequestTemplate[];
|
||||
|
||||
typedef struct AddTempCertToDBRequest {
|
||||
CMInt32 resID;
|
||||
char *nickname;
|
||||
CMInt32 sslFlags;
|
||||
CMInt32 emailFlags;
|
||||
CMInt32 objSignFlags;
|
||||
} AddTempCertToDBRequest;
|
||||
|
||||
extern CMTMessageTemplate AddTempCertToDBRequestTemplate[];
|
||||
|
||||
typedef struct MatchUserCertRequest {
|
||||
CMInt32 certType;
|
||||
CMInt32 numCANames;
|
||||
char **caNames;
|
||||
} MatchUserCertRequest;
|
||||
|
||||
extern CMTMessageTemplate MatchUserCertRequestTemplate[];
|
||||
|
||||
typedef struct MatchUserCertReply {
|
||||
CMInt32 numCerts;
|
||||
CMInt32 *certs;
|
||||
} MatchUserCertReply;
|
||||
|
||||
extern CMTMessageTemplate MatchUserCertReplyTemplate[];
|
||||
|
||||
typedef struct EncodeCRMFReqRequest {
|
||||
CMInt32 numRequests;
|
||||
CMInt32 * reqIDs;
|
||||
} EncodeCRMFReqRequest;
|
||||
|
||||
extern CMTMessageTemplate EncodeCRMFReqRequestTemplate[];
|
||||
|
||||
typedef struct CMMFCertResponseRequest {
|
||||
char *nickname;
|
||||
char *base64Der;
|
||||
CMBool doBackup;
|
||||
CMTItem clientContext;
|
||||
} CMMFCertResponseRequest;
|
||||
|
||||
extern CMTMessageTemplate CMMFCertResponseRequestTemplate[];
|
||||
|
||||
typedef struct PasswordRequest {
|
||||
CMInt32 tokenKey;
|
||||
char *prompt;
|
||||
CMTItem clientContext;
|
||||
} PasswordRequest;
|
||||
|
||||
extern CMTMessageTemplate PasswordRequestTemplate[];
|
||||
|
||||
typedef struct PasswordReply {
|
||||
CMInt32 result;
|
||||
CMInt32 tokenID;
|
||||
char * passwd;
|
||||
} PasswordReply;
|
||||
|
||||
extern CMTMessageTemplate PasswordReplyTemplate[];
|
||||
|
||||
typedef struct KeyPairGenRequest {
|
||||
CMInt32 keyGenCtxtID;
|
||||
CMInt32 genMechanism;
|
||||
CMInt32 keySize;
|
||||
CMTItem params;
|
||||
} KeyPairGenRequest;
|
||||
|
||||
extern CMTMessageTemplate KeyPairGenRequestTemplate[];
|
||||
|
||||
typedef struct DecodeAndCreateTempCertRequest {
|
||||
CMInt32 type;
|
||||
CMTItem cert;
|
||||
} DecodeAndCreateTempCertRequest;
|
||||
|
||||
extern CMTMessageTemplate DecodeAndCreateTempCertRequestTemplate[];
|
||||
|
||||
typedef struct GenKeyOldStyleRequest {
|
||||
char *choiceString;
|
||||
char *challenge;
|
||||
char *typeString;
|
||||
char *pqgString;
|
||||
} GenKeyOldStyleRequest;
|
||||
|
||||
extern CMTMessageTemplate GenKeyOldStyleRequestTemplate[];
|
||||
|
||||
typedef struct GenKeyOldStyleTokenRequest {
|
||||
CMInt32 rid;
|
||||
CMInt32 numtokens;
|
||||
char ** tokenNames;
|
||||
} GenKeyOldStyleTokenRequest;
|
||||
|
||||
extern CMTMessageTemplate GenKeyOldStyleTokenRequestTemplate[];
|
||||
|
||||
typedef struct GenKeyOldStyleTokenReply {
|
||||
CMInt32 rid;
|
||||
CMBool cancel;
|
||||
char * tokenName;
|
||||
} GenKeyOldStyleTokenReply;
|
||||
|
||||
extern CMTMessageTemplate GenKeyOldStyleTokenReplyTemplate[];
|
||||
|
||||
typedef struct GenKeyOldStylePasswordRequest {
|
||||
CMInt32 rid;
|
||||
char * tokenName;
|
||||
CMBool internal;
|
||||
CMInt32 minpwdlen;
|
||||
CMInt32 maxpwdlen;
|
||||
} GenKeyOldStylePasswordRequest;
|
||||
|
||||
extern CMTMessageTemplate GenKeyOldStylePasswordRequestTemplate[];
|
||||
|
||||
typedef struct GenKeyOldStylePasswordReply {
|
||||
CMInt32 rid;
|
||||
CMBool cancel;
|
||||
char * password;
|
||||
} GenKeyOldStylePasswordReply;
|
||||
|
||||
extern CMTMessageTemplate GenKeyOldStylePasswordReplyTemplate[];
|
||||
|
||||
typedef struct GetKeyChoiceListRequest {
|
||||
char *type;
|
||||
char *pqgString;
|
||||
} GetKeyChoiceListRequest;
|
||||
|
||||
extern CMTMessageTemplate GetKeyChoiceListRequestTemplate[];
|
||||
|
||||
typedef struct GetKeyChoiceListReply {
|
||||
CMInt32 nchoices;
|
||||
char **choices;
|
||||
} GetKeyChoiceListReply;
|
||||
|
||||
extern CMTMessageTemplate GetKeyChoiceListReplyTemplate[];
|
||||
|
||||
typedef struct AddNewSecurityModuleRequest {
|
||||
char *moduleName;
|
||||
char *libraryPath;
|
||||
CMInt32 pubMechFlags;
|
||||
CMInt32 pubCipherFlags;
|
||||
} AddNewSecurityModuleRequest;
|
||||
|
||||
extern CMTMessageTemplate AddNewSecurityModuleRequestTemplate[];
|
||||
|
||||
typedef struct FilePathRequest {
|
||||
CMInt32 resID;
|
||||
char *prompt;
|
||||
CMBool getExistingFile;
|
||||
char *fileRegEx;
|
||||
} FilePathRequest;
|
||||
|
||||
extern CMTMessageTemplate FilePathRequestTemplate[];
|
||||
|
||||
typedef struct FilePathReply {
|
||||
CMInt32 resID;
|
||||
char *filePath;
|
||||
} FilePathReply;
|
||||
|
||||
extern CMTMessageTemplate FilePathReplyTemplate[];
|
||||
|
||||
typedef struct PasswordPromptReply {
|
||||
CMInt32 resID;
|
||||
char *promptReply;
|
||||
} PasswordPromptReply;
|
||||
|
||||
extern CMTMessageTemplate PasswordPromptReplyTemplate[];
|
||||
|
||||
typedef struct SignTextRequest {
|
||||
CMInt32 resID;
|
||||
char *stringToSign;
|
||||
char *hostName;
|
||||
char *caOption;
|
||||
CMInt32 numCAs;
|
||||
char** caNames;
|
||||
} SignTextRequest;
|
||||
|
||||
extern CMTMessageTemplate SignTextRequestTemplate[];
|
||||
|
||||
typedef struct GetLocalizedTextReply {
|
||||
CMInt32 whichString;
|
||||
char *localizedString;
|
||||
} GetLocalizedTextReply;
|
||||
|
||||
extern CMTMessageTemplate GetLocalizedTextReplyTemplate[];
|
||||
|
||||
typedef struct ImportCertReply {
|
||||
CMInt32 result;
|
||||
CMInt32 resID;
|
||||
} ImportCertReply;
|
||||
|
||||
extern CMTMessageTemplate ImportCertReplyTemplate[];
|
||||
|
||||
typedef struct PromptRequest {
|
||||
CMInt32 resID;
|
||||
char *prompt;
|
||||
CMTItem clientContext;
|
||||
} PromptRequest;
|
||||
|
||||
extern CMTMessageTemplate PromptRequestTemplate[];
|
||||
|
||||
typedef struct PromptReply {
|
||||
CMInt32 resID;
|
||||
CMBool cancel;
|
||||
char *promptReply;
|
||||
} PromptReply;
|
||||
|
||||
extern CMTMessageTemplate PromptReplyTemplate[];
|
||||
|
||||
typedef struct RedirectCompareReqeust {
|
||||
CMTItem socketStatus1Data;
|
||||
CMTItem socketStatus2Data;
|
||||
} RedirectCompareRequest;
|
||||
|
||||
extern CMTMessageTemplate RedirectCompareRequestTemplate[];
|
||||
|
||||
typedef struct DecodeAndAddCRLRequest {
|
||||
CMTItem derCrl;
|
||||
CMUint32 type;
|
||||
char *url;
|
||||
} DecodeAndAddCRLRequest;
|
||||
|
||||
extern CMTMessageTemplate DecodeAndAddCRLRequestTemplate[];
|
||||
|
||||
typedef struct SecurityAdvisorRequest {
|
||||
CMInt32 infoContext;
|
||||
CMInt32 resID;
|
||||
char * hostname;
|
||||
char * senderAddr;
|
||||
CMUint32 encryptedP7CInfo;
|
||||
CMUint32 signedP7CInfo;
|
||||
CMInt32 decodeError;
|
||||
CMInt32 verifyError;
|
||||
CMBool encryptthis;
|
||||
CMBool signthis;
|
||||
CMInt32 numRecipients;
|
||||
char ** recipients;
|
||||
} SecurityAdvisorRequest;
|
||||
|
||||
extern CMTMessageTemplate SecurityAdvisorRequestTemplate[];
|
||||
|
||||
/* "SecurityConfig" javascript related message templates */
|
||||
typedef struct SCAddTempCertToPermDBRequest {
|
||||
CMTItem certKey;
|
||||
char* trustStr;
|
||||
char* nickname;
|
||||
} SCAddTempCertToPermDBRequest;
|
||||
|
||||
extern CMTMessageTemplate SCAddTempCertToPermDBRequestTemplate[];
|
||||
|
||||
typedef struct SCDeletePermCertsRequest {
|
||||
CMTItem certKey;
|
||||
CMBool deleteAll;
|
||||
} SCDeletePermCertsRequest;
|
||||
|
||||
extern CMTMessageTemplate SCDeletePermCertsRequestTemplate[];
|
||||
|
||||
typedef struct TimeMessage {
|
||||
CMInt32 year;
|
||||
CMInt32 month;
|
||||
CMInt32 day;
|
||||
CMInt32 hour;
|
||||
CMInt32 minute;
|
||||
CMInt32 second;
|
||||
} TimeMessage;
|
||||
|
||||
extern CMTMessageTemplate TimeMessageTemplate[];
|
||||
|
||||
typedef struct CertEnumElement {
|
||||
char* name;
|
||||
CMTItem certKey;
|
||||
} CertEnumElement;
|
||||
|
||||
typedef struct SCCertIndexEnumReply {
|
||||
int length;
|
||||
CertEnumElement* list;
|
||||
} SCCertIndexEnumReply;
|
||||
|
||||
extern CMTMessageTemplate SCCertIndexEnumReplyTemplate[];
|
||||
|
||||
/* Test message */
|
||||
typedef struct TestListElement {
|
||||
char * name;
|
||||
char * value;
|
||||
} TestListElement;
|
||||
|
||||
typedef struct TestList {
|
||||
char *listName;
|
||||
int numElements;
|
||||
TestListElement *elements;
|
||||
} TestList;
|
||||
|
||||
extern CMTMessageTemplate TestListTemplate[];
|
||||
|
||||
/* Preference-related structs */
|
||||
typedef struct SetPrefElement {
|
||||
char* key;
|
||||
char* value;
|
||||
CMInt32 type;
|
||||
} SetPrefElement;
|
||||
|
||||
typedef struct SetPrefListMessage {
|
||||
int length;
|
||||
SetPrefElement* list;
|
||||
} SetPrefListMessage;
|
||||
|
||||
extern CMTMessageTemplate SetPrefListMessageTemplate[];
|
||||
|
||||
typedef struct GetPrefElement {
|
||||
char* key;
|
||||
CMInt32 type;
|
||||
} GetPrefElement;
|
||||
|
||||
typedef struct GetPrefListRequest {
|
||||
int length;
|
||||
GetPrefElement* list;
|
||||
} GetPrefListRequest;
|
||||
|
||||
extern CMTMessageTemplate GetPrefListRequestTemplate[];
|
||||
|
||||
typedef struct GetCertExtension {
|
||||
CMUint32 resID;
|
||||
CMUint32 extension;
|
||||
} GetCertExtension;
|
||||
|
||||
extern CMTMessageTemplate GetCertExtensionTemplate[];
|
||||
|
||||
typedef struct HTMLCertInfoRequest {
|
||||
CMUint32 certID;
|
||||
CMUint32 showImages;
|
||||
CMUint32 showIssuer;
|
||||
} HTMLCertInfoRequest;
|
||||
|
||||
extern CMTMessageTemplate HTMLCertInfoRequestTemplate[];
|
||||
|
||||
typedef struct EncryptRequestMessage
|
||||
{
|
||||
CMTItem keyid; /* May have length 0 for default */
|
||||
CMTItem data;
|
||||
CMTItem ctx; /* serialized void* ptr */
|
||||
} EncryptRequestMessage;
|
||||
|
||||
extern CMTMessageTemplate EncryptRequestTemplate[];
|
||||
|
||||
typedef struct SingleItemMessage EncryptReplyMessage;
|
||||
#define EncryptReplyTemplate SingleItemMessageTemplate
|
||||
|
||||
typedef struct DecryptRequestMessage
|
||||
{
|
||||
CMTItem data;
|
||||
CMTItem ctx; /* serialized void* ptr */
|
||||
} DecryptRequestMessage;
|
||||
extern CMTMessageTemplate DecryptRequestTemplate[];
|
||||
|
||||
typedef struct SingleItemMessage DecryptReplyMessage;
|
||||
#define DecryptReplyTemplate SingleItemMessageTemplate
|
||||
|
||||
#endif /* __MESSAGES_H__ */
|
||||
@@ -1,602 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#ifdef WIN32
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
#ifdef XP_MAC
|
||||
#include "macsocket.h"
|
||||
#endif
|
||||
|
||||
#include "newproto.h"
|
||||
|
||||
char SSMVersionString[] = "1.1";
|
||||
|
||||
CMT_Alloc_fn cmt_alloc = malloc;
|
||||
CMT_Free_fn cmt_free = free;
|
||||
|
||||
#define ASSERT(x) assert(x)
|
||||
|
||||
#define CM_ntohl ntohl
|
||||
#define CM_htonl htonl
|
||||
|
||||
|
||||
/*************************************************************
|
||||
*
|
||||
* CMT_Init
|
||||
*
|
||||
*
|
||||
************************************************************/
|
||||
void
|
||||
CMT_Init(CMT_Alloc_fn allocfn, CMT_Free_fn freefn)
|
||||
{
|
||||
cmt_alloc = allocfn;
|
||||
cmt_free = freefn;
|
||||
}
|
||||
|
||||
static CMTStatus
|
||||
decode_int(unsigned char **curptr, void *dest, CMInt32 *remaining)
|
||||
{
|
||||
CMInt32 datalen = sizeof(CMInt32);
|
||||
|
||||
if (*remaining < datalen)
|
||||
return CMTFailure;
|
||||
*(CMInt32 *)dest = ntohl(**(CMInt32 **)curptr);
|
||||
*remaining -= datalen;
|
||||
*curptr += datalen;
|
||||
return CMTSuccess;
|
||||
}
|
||||
|
||||
static CMTStatus
|
||||
decode_string(unsigned char **curptr, CMInt32 *len,
|
||||
unsigned char **data, CMInt32 *remaining)
|
||||
{
|
||||
CMTStatus rv;
|
||||
CMInt32 datalen;
|
||||
|
||||
rv = decode_int(curptr, len, remaining);
|
||||
if (rv != CMTSuccess)
|
||||
return CMTFailure;
|
||||
|
||||
/* NULL string */
|
||||
if (*len == 0) {
|
||||
*data = NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
datalen = (*len + 3) & ~3;
|
||||
if (*remaining < datalen)
|
||||
return CMTFailure;
|
||||
|
||||
*data = (unsigned char *) cmt_alloc(*len + 1);
|
||||
if (*data == NULL)
|
||||
return CMTFailure;
|
||||
|
||||
memcpy(*data, *curptr, *len);
|
||||
(*data)[*len] = 0;
|
||||
*remaining -= datalen;
|
||||
*curptr += datalen;
|
||||
done:
|
||||
return CMTSuccess;
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* CMT_DecodeMessage
|
||||
*
|
||||
* Decode msg into dest as specified by tmpl.
|
||||
*
|
||||
************************************************************/
|
||||
CMTStatus
|
||||
CMT_DecodeMessage(CMTMessageTemplate *tmpl, void *dest, CMTItem *msg)
|
||||
{
|
||||
unsigned char *curptr, *destptr, *list;
|
||||
void ** ptr;
|
||||
CMInt32 remaining, len, choiceID = 0, listSize, listCount = 0;
|
||||
CMBool inChoice = CM_FALSE, foundChoice = CM_FALSE, inList = CM_FALSE;
|
||||
CMInt32 listItemSize = 0;
|
||||
CMTStatus rv = CMTSuccess;
|
||||
CMTMessageTemplate *startOfList, *p;
|
||||
CMBool inStructList = CM_FALSE;
|
||||
|
||||
curptr = msg->data;
|
||||
remaining = msg->len;
|
||||
|
||||
while(tmpl->type != CMT_DT_END) {
|
||||
/* XXX Maybe this should be a more formal state machine? */
|
||||
if (inChoice) {
|
||||
if (tmpl->type == CMT_DT_END_CHOICE) {
|
||||
if (!foundChoice)
|
||||
goto loser;
|
||||
inChoice = CM_FALSE;
|
||||
foundChoice = CM_FALSE;
|
||||
tmpl++;
|
||||
continue;
|
||||
}
|
||||
if (choiceID != tmpl->choiceID) {
|
||||
tmpl++;
|
||||
continue; /* Not this option */
|
||||
} else {
|
||||
foundChoice = CM_TRUE;
|
||||
}
|
||||
}
|
||||
if (inList) {
|
||||
destptr = &list[listCount * listItemSize];
|
||||
listCount++;
|
||||
} else {
|
||||
if (inStructList) {
|
||||
destptr = tmpl->offset + list;
|
||||
} else {
|
||||
destptr = tmpl->offset + (unsigned char *)dest;
|
||||
}
|
||||
}
|
||||
switch (tmpl->type) {
|
||||
case CMT_DT_RID:
|
||||
case CMT_DT_INT:
|
||||
case CMT_DT_BOOL:
|
||||
rv = decode_int(&curptr, destptr, &remaining);
|
||||
if (rv != CMTSuccess)
|
||||
goto loser;
|
||||
break;
|
||||
case CMT_DT_STRING:
|
||||
rv = decode_string(&curptr, &len, (unsigned char **)destptr,
|
||||
&remaining);
|
||||
if (rv != CMTSuccess)
|
||||
goto loser;
|
||||
break;
|
||||
case CMT_DT_ITEM:
|
||||
rv = decode_string(&curptr, (long *) &((CMTItem *)destptr)->len,
|
||||
&((CMTItem *)destptr)->data, &remaining);
|
||||
if (rv != CMTSuccess)
|
||||
goto loser;
|
||||
break;
|
||||
case CMT_DT_LIST:
|
||||
/* XXX This is too complicated */
|
||||
rv = decode_int(&curptr, destptr, &remaining);
|
||||
if (rv != CMTSuccess)
|
||||
goto loser;
|
||||
listSize = *(CMInt32 *)destptr;
|
||||
tmpl++;
|
||||
if (tmpl->type == CMT_DT_STRING) {
|
||||
listItemSize = sizeof(unsigned char *);
|
||||
} else if (tmpl->type == CMT_DT_ITEM) {
|
||||
listItemSize = sizeof(CMTItem);
|
||||
} else {
|
||||
listItemSize = sizeof(CMInt32);
|
||||
}
|
||||
if (listSize == 0) {
|
||||
list = NULL;
|
||||
} else {
|
||||
list = (unsigned char *) cmt_alloc(listSize * listItemSize);
|
||||
}
|
||||
*(void **)(tmpl->offset + (unsigned char *)dest) = list;
|
||||
inList = CM_TRUE;
|
||||
listCount = 0;
|
||||
break;
|
||||
case CMT_DT_STRUCT_LIST:
|
||||
/* XXX This is too complicated */
|
||||
rv = decode_int(&curptr, destptr, &remaining);
|
||||
if (rv != CMTSuccess)
|
||||
goto loser;
|
||||
listSize = *(CMInt32 *)destptr;
|
||||
tmpl++;
|
||||
if (tmpl->type != CMT_DT_STRUCT_PTR) {
|
||||
goto loser;
|
||||
}
|
||||
ptr = (void**)(tmpl->offset + (unsigned char *)dest);
|
||||
startOfList = tmpl;
|
||||
p = tmpl;
|
||||
listItemSize = 0;
|
||||
while (p->type != CMT_DT_END_STRUCT_LIST) {
|
||||
if (p->type == CMT_DT_STRING) {
|
||||
listItemSize += sizeof(unsigned char *);
|
||||
} else if (p->type == CMT_DT_ITEM) {
|
||||
listItemSize += sizeof(CMTItem);
|
||||
} else if (p->type == CMT_DT_INT) {
|
||||
listItemSize += sizeof(CMInt32);
|
||||
}
|
||||
p++;
|
||||
}
|
||||
if (listSize == 0) {
|
||||
list = NULL;
|
||||
} else {
|
||||
list = (unsigned char *) cmt_alloc(listSize * listItemSize);
|
||||
}
|
||||
*ptr = list;
|
||||
inStructList = CM_TRUE;
|
||||
listCount = 0;
|
||||
break;
|
||||
case CMT_DT_END_STRUCT_LIST:
|
||||
listCount++;
|
||||
if (listCount == listSize) {
|
||||
inStructList = CM_FALSE;
|
||||
} else {
|
||||
list += listItemSize;
|
||||
tmpl = startOfList;
|
||||
}
|
||||
break;
|
||||
case CMT_DT_CHOICE:
|
||||
rv = decode_int(&curptr, destptr, &remaining);
|
||||
if (rv != CMTSuccess)
|
||||
goto loser;
|
||||
choiceID = *(CMInt32 *)destptr;
|
||||
inChoice = CM_TRUE;
|
||||
foundChoice = CM_FALSE;
|
||||
break;
|
||||
case CMT_DT_END_CHOICE: /* Loop should exit before we see these. */
|
||||
case CMT_DT_END:
|
||||
default:
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
if (inList) {
|
||||
if (listCount == listSize) {
|
||||
inList = CM_FALSE;
|
||||
tmpl++;
|
||||
}
|
||||
} else {
|
||||
tmpl++;
|
||||
}
|
||||
}
|
||||
loser:
|
||||
/* Free the data buffer */
|
||||
if (msg->data) {
|
||||
cmt_free(msg->data);
|
||||
msg->data = NULL;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
static CMTStatus
|
||||
calc_msg_len(CMTMessageTemplate *tmpl, void *src, CMInt32 *len_out)
|
||||
{
|
||||
CMInt32 len = 0, choiceID = 0, listSize, listItemSize, listCount;
|
||||
unsigned char *srcptr, *list;
|
||||
CMBool inChoice = CM_FALSE, inList = CM_FALSE, foundChoice = CM_FALSE;
|
||||
CMTMessageTemplate *startOfList, *p;
|
||||
CMBool inStructList = CM_FALSE;
|
||||
|
||||
while(tmpl->type != CMT_DT_END) {
|
||||
if (inChoice) {
|
||||
if (tmpl->type == CMT_DT_END_CHOICE) {
|
||||
if (!foundChoice)
|
||||
goto loser;
|
||||
inChoice = CM_FALSE;
|
||||
foundChoice = CM_FALSE;
|
||||
tmpl++;
|
||||
continue;
|
||||
}
|
||||
if (choiceID != tmpl->choiceID) {
|
||||
tmpl++;
|
||||
continue; /* Not this option */
|
||||
} else {
|
||||
foundChoice = CM_TRUE;
|
||||
}
|
||||
}
|
||||
if (inList) {
|
||||
srcptr = &list[listCount * listItemSize];
|
||||
listCount++;
|
||||
} else if (inStructList) {
|
||||
srcptr = tmpl->offset + list;
|
||||
} else {
|
||||
srcptr = tmpl->offset + (unsigned char *)src;
|
||||
}
|
||||
switch(tmpl->type) {
|
||||
case CMT_DT_RID:
|
||||
case CMT_DT_INT:
|
||||
case CMT_DT_BOOL:
|
||||
len += sizeof(CMInt32);
|
||||
break;
|
||||
case CMT_DT_STRING:
|
||||
len += sizeof(CMInt32);
|
||||
/* Non NULL string */
|
||||
if (*(char**)srcptr) {
|
||||
len += (strlen(*(char**)srcptr) + 4) & ~3;
|
||||
}
|
||||
break;
|
||||
case CMT_DT_ITEM:
|
||||
len += sizeof(CMInt32);
|
||||
len += (((CMTItem *)srcptr)->len + 3) & ~3;
|
||||
break;
|
||||
case CMT_DT_LIST:
|
||||
len += sizeof(CMInt32);
|
||||
listSize = *(CMInt32 *)srcptr;
|
||||
tmpl++;
|
||||
if (tmpl->type == CMT_DT_STRING) {
|
||||
listItemSize = sizeof(unsigned char *);
|
||||
} else if (tmpl->type == CMT_DT_ITEM) {
|
||||
listItemSize = sizeof(CMTItem);
|
||||
} else {
|
||||
listItemSize = sizeof(CMInt32);
|
||||
}
|
||||
list = *(unsigned char **)(tmpl->offset + (unsigned char *)src);
|
||||
listCount = 0;
|
||||
inList = CM_TRUE;
|
||||
break;
|
||||
case CMT_DT_STRUCT_LIST:
|
||||
len += sizeof(CMInt32);
|
||||
listSize = *(CMInt32 *)srcptr;
|
||||
tmpl++;
|
||||
if (tmpl->type != CMT_DT_STRUCT_PTR) {
|
||||
goto loser;
|
||||
}
|
||||
list = *(unsigned char**)(tmpl->offset + (unsigned char*)src);
|
||||
startOfList = tmpl;
|
||||
p = tmpl;
|
||||
listItemSize = 0;
|
||||
while (p->type != CMT_DT_END_STRUCT_LIST) {
|
||||
if (p->type == CMT_DT_STRING) {
|
||||
listItemSize += sizeof(unsigned char *);
|
||||
} else if (p->type == CMT_DT_ITEM) {
|
||||
listItemSize += sizeof(CMTItem);
|
||||
} else if (p->type == CMT_DT_INT) {
|
||||
listItemSize += sizeof(CMInt32);
|
||||
}
|
||||
p++;
|
||||
}
|
||||
listCount = 0;
|
||||
inStructList = CM_TRUE;
|
||||
break;
|
||||
case CMT_DT_END_STRUCT_LIST:
|
||||
listCount++;
|
||||
if (listCount == listSize) {
|
||||
inStructList = CM_FALSE;
|
||||
} else {
|
||||
list += listItemSize;
|
||||
tmpl = startOfList;
|
||||
}
|
||||
break;
|
||||
case CMT_DT_CHOICE:
|
||||
len += sizeof(CMInt32);
|
||||
choiceID = *(CMInt32 *)srcptr;
|
||||
inChoice = CM_TRUE;
|
||||
foundChoice = CM_FALSE;
|
||||
break;
|
||||
case CMT_DT_END_CHOICE: /* Loop should exit before we see these. */
|
||||
case CMT_DT_END:
|
||||
default:
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
if (inList) {
|
||||
if (listCount == listSize) {
|
||||
inList = CM_FALSE;
|
||||
tmpl++;
|
||||
}
|
||||
} else {
|
||||
tmpl++;
|
||||
}
|
||||
}
|
||||
*len_out = len;
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
|
||||
static CMTStatus
|
||||
encode_int(unsigned char **curptr, void *src, CMInt32 *remaining)
|
||||
{
|
||||
CMInt32 datalen = sizeof(CMInt32);
|
||||
|
||||
if (*remaining < datalen)
|
||||
return CMTFailure;
|
||||
**(CMInt32 **)curptr = CM_htonl(*(CMInt32 *)src);
|
||||
*remaining -= datalen;
|
||||
*curptr += datalen;
|
||||
return CMTSuccess;
|
||||
}
|
||||
|
||||
static CMTStatus
|
||||
encode_string(unsigned char **curptr, CMInt32 len,
|
||||
unsigned char *data, CMInt32 *remaining)
|
||||
{
|
||||
CMTStatus rv;
|
||||
CMInt32 datalen;
|
||||
|
||||
rv = encode_int(curptr, &len, remaining);
|
||||
if (rv != CMTSuccess)
|
||||
return CMTFailure;
|
||||
|
||||
/* NULL string */
|
||||
if (len == 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
datalen = (len + 3) & ~3;
|
||||
if (*remaining < datalen)
|
||||
return CMTFailure;
|
||||
|
||||
memcpy(*curptr, data, len);
|
||||
*remaining -= datalen;
|
||||
*curptr += datalen;
|
||||
done:
|
||||
return CMTSuccess;
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
* CMT_EncodeMessage
|
||||
*
|
||||
* Encode src into msg as specified by tmpl.
|
||||
*
|
||||
************************************************************/
|
||||
CMTStatus
|
||||
CMT_EncodeMessage(CMTMessageTemplate *tmpl, CMTItem *msg, void *src)
|
||||
{
|
||||
CMInt32 choiceID = 0, listSize, listItemSize, listCount, remaining;
|
||||
unsigned char *srcptr, *curptr, *list;
|
||||
CMBool inChoice = CM_FALSE, inList = CM_FALSE, foundChoice = CM_FALSE;
|
||||
CMTStatus rv = CMTSuccess;
|
||||
CMTMessageTemplate *startOfList, *p;
|
||||
CMBool inStructList = CM_FALSE;
|
||||
|
||||
rv = calc_msg_len(tmpl, src, (long *) &msg->len);
|
||||
if (rv != CMTSuccess)
|
||||
goto loser;
|
||||
curptr = msg->data = (unsigned char *) cmt_alloc(msg->len);
|
||||
if(msg->data == NULL)
|
||||
goto loser;
|
||||
remaining = msg->len;
|
||||
|
||||
while(tmpl->type != CMT_DT_END) {
|
||||
if (inChoice) {
|
||||
if (tmpl->type == CMT_DT_END_CHOICE) {
|
||||
if (!foundChoice)
|
||||
goto loser;
|
||||
inChoice = CM_FALSE;
|
||||
foundChoice = CM_FALSE;
|
||||
tmpl++;
|
||||
continue;
|
||||
}
|
||||
if (choiceID != tmpl->choiceID) {
|
||||
tmpl++;
|
||||
continue; /* Not this option */
|
||||
} else {
|
||||
foundChoice = CM_TRUE;
|
||||
}
|
||||
}
|
||||
if (inList) {
|
||||
srcptr = &list[listCount * listItemSize];
|
||||
listCount++;
|
||||
} else {
|
||||
if (inStructList) {
|
||||
srcptr = tmpl->offset + list;
|
||||
} else {
|
||||
srcptr = tmpl->offset + (unsigned char *)src;
|
||||
}
|
||||
}
|
||||
switch(tmpl->type) {
|
||||
case CMT_DT_RID:
|
||||
case CMT_DT_INT:
|
||||
case CMT_DT_BOOL:
|
||||
rv = encode_int(&curptr, srcptr, &remaining);
|
||||
if (rv != CMTSuccess)
|
||||
goto loser;
|
||||
break;
|
||||
case CMT_DT_STRING:
|
||||
if (*(char**)srcptr) {
|
||||
/* Non NULL string */
|
||||
rv = encode_string(&curptr, (long) strlen(*(char**)srcptr),
|
||||
*(unsigned char**)srcptr, &remaining);
|
||||
} else {
|
||||
/* NULL string */
|
||||
rv = encode_string(&curptr, 0L, *(unsigned char**)srcptr, &remaining);
|
||||
}
|
||||
if (rv != CMTSuccess)
|
||||
goto loser;
|
||||
break;
|
||||
case CMT_DT_ITEM:
|
||||
rv = encode_string(&curptr, ((CMTItem *)srcptr)->len,
|
||||
((CMTItem *)srcptr)->data, &remaining);
|
||||
if (rv != CMTSuccess)
|
||||
goto loser;
|
||||
break;
|
||||
case CMT_DT_LIST:
|
||||
rv = encode_int(&curptr, srcptr, &remaining);
|
||||
if (rv != CMTSuccess)
|
||||
goto loser;
|
||||
listSize = *(CMInt32 *)srcptr;
|
||||
tmpl++;
|
||||
if (tmpl->type == CMT_DT_STRING) {
|
||||
listItemSize = sizeof(unsigned char *);
|
||||
} else if (tmpl->type == CMT_DT_ITEM) {
|
||||
listItemSize = sizeof(CMTItem);
|
||||
} else {
|
||||
listItemSize = sizeof(CMInt32);
|
||||
}
|
||||
list = *(unsigned char **)(tmpl->offset + (unsigned char *)src);
|
||||
listCount = 0;
|
||||
inList = CM_TRUE;
|
||||
break;
|
||||
case CMT_DT_STRUCT_LIST:
|
||||
rv = encode_int(&curptr, srcptr, &remaining);
|
||||
if (rv != CMTSuccess)
|
||||
goto loser;
|
||||
listSize = *(CMInt32 *)srcptr;
|
||||
tmpl++;
|
||||
if (tmpl->type != CMT_DT_STRUCT_PTR) {
|
||||
goto loser;
|
||||
}
|
||||
list = *(unsigned char**)(tmpl->offset + (unsigned char*)src);
|
||||
startOfList = tmpl;
|
||||
p = tmpl;
|
||||
listItemSize = 0;
|
||||
while (p->type != CMT_DT_END_STRUCT_LIST) {
|
||||
if (p->type == CMT_DT_STRING) {
|
||||
listItemSize += sizeof(unsigned char *);
|
||||
} else if (p->type == CMT_DT_ITEM) {
|
||||
listItemSize += sizeof(CMTItem);
|
||||
} else if (p->type == CMT_DT_INT) {
|
||||
listItemSize += sizeof(CMInt32);
|
||||
}
|
||||
p++;
|
||||
}
|
||||
listCount = 0;
|
||||
inStructList = CM_TRUE;
|
||||
break;
|
||||
case CMT_DT_END_STRUCT_LIST:
|
||||
listCount++;
|
||||
if (listCount == listSize) {
|
||||
inStructList = CM_FALSE;
|
||||
} else {
|
||||
list += listItemSize;
|
||||
tmpl = startOfList;
|
||||
}
|
||||
break;
|
||||
case CMT_DT_CHOICE:
|
||||
rv = encode_int(&curptr, srcptr, &remaining);
|
||||
if (rv != CMTSuccess)
|
||||
goto loser;
|
||||
choiceID = *(CMInt32 *)srcptr;
|
||||
inChoice = CM_TRUE;
|
||||
foundChoice = CM_FALSE;
|
||||
break;
|
||||
case CMT_DT_END_CHOICE: /* Loop should exit before we see these. */
|
||||
case CMT_DT_END:
|
||||
default:
|
||||
ASSERT(0);
|
||||
break;
|
||||
}
|
||||
if (inList) {
|
||||
if (listCount == listSize) {
|
||||
inList = CM_FALSE;
|
||||
tmpl++;
|
||||
}
|
||||
} else {
|
||||
tmpl++;
|
||||
}
|
||||
}
|
||||
return CMTSuccess;
|
||||
loser:
|
||||
return CMTFailure;
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef __NEWPROTO_H__
|
||||
#define __NEWPROTO_H__
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "ssmdefs.h"
|
||||
|
||||
typedef enum CMTDataType {
|
||||
CMT_DT_END,
|
||||
CMT_DT_RID,
|
||||
CMT_DT_INT,
|
||||
CMT_DT_BOOL,
|
||||
CMT_DT_STRING,
|
||||
CMT_DT_ITEM,
|
||||
CMT_DT_LIST,
|
||||
CMT_DT_CHOICE,
|
||||
CMT_DT_END_CHOICE,
|
||||
CMT_DT_STRUCT_LIST,
|
||||
CMT_DT_END_STRUCT_LIST,
|
||||
CMT_DT_STRUCT_PTR
|
||||
} CMTDataType;
|
||||
|
||||
typedef struct CMTMessageTemplate {
|
||||
CMTDataType type;
|
||||
CMUint32 offset;
|
||||
CMInt32 validator;
|
||||
CMInt32 choiceID;
|
||||
} CMTMessageTemplate;
|
||||
|
||||
typedef struct CMTMessageHeader {
|
||||
CMInt32 type;
|
||||
CMInt32 len;
|
||||
} CMTMessageHeader;
|
||||
|
||||
typedef void *(* CMT_Alloc_fn) (size_t size);
|
||||
typedef void (* CMT_Free_fn)(void * ptr);
|
||||
|
||||
extern CMT_Alloc_fn cmt_alloc;
|
||||
extern CMT_Free_fn cmt_free;
|
||||
|
||||
/*************************************************************
|
||||
*
|
||||
* CMT_Init
|
||||
*
|
||||
*
|
||||
************************************************************/
|
||||
void
|
||||
CMT_Init(CMT_Alloc_fn allocfn, CMT_Free_fn freefn);
|
||||
|
||||
/*************************************************************
|
||||
* CMT_DecodeMessage
|
||||
*
|
||||
* Decode msg into dest as specified by tmpl.
|
||||
*
|
||||
************************************************************/
|
||||
CMTStatus
|
||||
CMT_DecodeMessage(CMTMessageTemplate *tmpl, void *dest, CMTItem *msg);
|
||||
|
||||
|
||||
/*************************************************************
|
||||
* CMT_EncodeMessage
|
||||
*
|
||||
* Encode src into msg as specified by tmpl.
|
||||
*
|
||||
************************************************************/
|
||||
CMTStatus
|
||||
CMT_EncodeMessage(CMTMessageTemplate *tmpl, CMTItem *msg, void *src);
|
||||
|
||||
|
||||
#endif /* __NEWPROTO_H__ */
|
||||
@@ -1,187 +0,0 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
/* SAMPLE CODE
|
||||
** Illustrates use of SSMObscure object methods.
|
||||
**
|
||||
** Author: Nelson Bolyard June 1999
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "obscure.h"
|
||||
|
||||
|
||||
/* On error, returns -1.
|
||||
** On success, returns non-negative number of unobscured bytes in buf
|
||||
int
|
||||
RecvInitObscureData(int fd, SSMObscureObject * obj, void * buf, int bufSize )
|
||||
{
|
||||
SSMObscureBool done = 0;
|
||||
|
||||
do {
|
||||
int cc;
|
||||
int rv;
|
||||
cc = read(fd, buf, bufSize);
|
||||
if (cc <= 0)
|
||||
return -1;
|
||||
rv = SSMObscure_RecvInit(obj, buf, cc, &done);
|
||||
} while (!done);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/* returns -1 on error, 0 on success. */
|
||||
int
|
||||
SendInitObscureData(int fd, SSMObscureObject * obj)
|
||||
{
|
||||
unsigned char * initBuf = NULL;
|
||||
int rv = -1;
|
||||
|
||||
do {
|
||||
int bufLen;
|
||||
int len;
|
||||
int cc;
|
||||
|
||||
bufLen = SSMObscure_SendInit(obj, NULL);
|
||||
if (bufLen <= 0)
|
||||
break;
|
||||
|
||||
initBuf = malloc(bufLen);
|
||||
if (!initBuf)
|
||||
break;
|
||||
|
||||
len = SSMObscure_SendInit(obj, initBuf);
|
||||
if (len != bufLen)
|
||||
break;
|
||||
|
||||
cc = write(fd, initBuf, len);
|
||||
|
||||
/* Note, this code assumes a blocking socket,
|
||||
** and hence doesn't deal with short writes.
|
||||
*/
|
||||
if (cc < len)
|
||||
break;
|
||||
|
||||
rv = 0;
|
||||
|
||||
} while (0);
|
||||
|
||||
if (initBuf) {
|
||||
free(initBuf);
|
||||
initBuf = NULL;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* This is like write, but it obscures the data first. */
|
||||
/* This code assumes a blocking socket, and so it doesn't handle short
|
||||
** writes.
|
||||
*/
|
||||
int
|
||||
obscuredWrite(SSMObscureObject * obj, int fd, void * buf, int len)
|
||||
{
|
||||
int rv;
|
||||
int cc;
|
||||
|
||||
cc = SSMObscure_Send(obj, buf, len);
|
||||
if (cc <= 0)
|
||||
return cc;
|
||||
rv = write(fd, buf, cc);
|
||||
ASSERT(rv == cc || rv < 0);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* This is like read, but it unobscures the data after reading it. */
|
||||
int
|
||||
obscuredRead(SSMObscureObject * obj, int fd, void * buf, int len)
|
||||
{
|
||||
int rv;
|
||||
int cc;
|
||||
|
||||
do {
|
||||
cc = read(fd, buf, len);
|
||||
if (cc <= 0)
|
||||
return cc;
|
||||
rv = SSMObscure_Recv(obj, buf, len);
|
||||
} while (rv == 0);
|
||||
return rv;
|
||||
}
|
||||
|
||||
SSMObscureObject * sobj;
|
||||
unsigned char buf[8192];
|
||||
|
||||
/* Call this with fd for socket that has just been accepted.
|
||||
** returns -1 on error,
|
||||
** On success, returns non-negative number of bytes received in buf.
|
||||
*/
|
||||
int
|
||||
InitClientObscureObject(int fd)
|
||||
{
|
||||
int rv;
|
||||
|
||||
sobj = SSMObscure_Create(0);
|
||||
if (!sobj)
|
||||
return -1;
|
||||
|
||||
rv = SendInitObscureData(fd, sobj);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
|
||||
rv = RecvInitObscureData(fd, sobj, buf, sizeof buf);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* Call this with fd for socket that has just been connected.
|
||||
** returns -1 on error,
|
||||
** On success, returns non-negative number of bytes received in buf.
|
||||
*/
|
||||
int
|
||||
InitServerObscureObject(int fd)
|
||||
{
|
||||
int cc;
|
||||
|
||||
sobj = SSMObscure_Create(1);
|
||||
if (!sobj)
|
||||
return -1;
|
||||
|
||||
cc = RecvInitObscureData(fd, sobj, buf, sizeof buf);
|
||||
if (cc < 0)
|
||||
return cc;
|
||||
|
||||
|
||||
rv = SendInitObscureData(fd, sobj);
|
||||
if (rv < 0)
|
||||
return rv;
|
||||
|
||||
return cc;
|
||||
}
|
||||
|
||||
@@ -1,136 +0,0 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include "obspriv.h"
|
||||
#include "newproto.h"
|
||||
|
||||
|
||||
/*
|
||||
** Create a new Obscuring object
|
||||
*/
|
||||
SSMObscureObject *
|
||||
SSMObscure_Create(SSMObscureBool IsServer)
|
||||
{
|
||||
SSMObscureObject * obj;
|
||||
void * priv;
|
||||
|
||||
obj = (SSMObscureObject *) cmt_alloc(sizeof *obj);
|
||||
if (!obj)
|
||||
return obj;
|
||||
/* This needs to be a little more elegant */
|
||||
priv = SSMObscure_InitPrivate(obj, IsServer);
|
||||
if (!priv) {
|
||||
cmt_free(obj);
|
||||
return NULL;
|
||||
}
|
||||
obj->privData = priv;
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
/* Prepare initial buffer with initial message to send to other side to
|
||||
** establish cryptographic * synchronization.
|
||||
**
|
||||
** If buf is NULL, function returns the size of the buffer that
|
||||
** the caller needs to allocate for sending the initial message.
|
||||
**
|
||||
** If buf is non-null, function returns the number of bytes of data filled
|
||||
** into buf, the amount that the caller should then send to the other side.
|
||||
**
|
||||
*/
|
||||
int
|
||||
SSMObscure_SendInit( SSMObscureObject * obj, void * buf)
|
||||
{
|
||||
int rv;
|
||||
rv = obj->sendInit(obj->privData, buf);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
** Obscure "len" bytes in "buf" before sending it.
|
||||
*/
|
||||
int
|
||||
SSMObscure_Send( SSMObscureObject * obj,
|
||||
void * buf,
|
||||
unsigned int len)
|
||||
{
|
||||
int rv;
|
||||
rv = obj->send(obj->privData, buf, len);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
** UnObscure "len" bytes in "buf" after receiving it.
|
||||
** This function may absorb some or all of the received bytes, leaving
|
||||
** fewer bytes (possibly none) in the buffer for the application to use
|
||||
** than were in the buffer when the function was called.
|
||||
** Function returns the number of bytes of unobscured data remaining in
|
||||
** buf. Zero means all data was used internally and no data remains
|
||||
** for application use. Negative number means error occurred.
|
||||
*/
|
||||
int
|
||||
SSMObscure_Recv( SSMObscureObject * obj,
|
||||
void * buf,
|
||||
unsigned int len)
|
||||
{
|
||||
int rv;
|
||||
rv = obj->recv(obj->privData, buf, len);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* like _Recv, but returns a flag telling when all initialization info has
|
||||
** been received.
|
||||
*/
|
||||
int
|
||||
SSMObscure_RecvInit( SSMObscureObject * obj,
|
||||
void * buf,
|
||||
unsigned int len,
|
||||
SSMObscureBool * done)
|
||||
{
|
||||
int rv;
|
||||
rv = obj->recvInit(obj->privData, buf, len, done);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
** Destroy the Obscure Object
|
||||
*/
|
||||
int
|
||||
SSMObscure_Destroy(SSMObscureObject * obj)
|
||||
{
|
||||
int rv;
|
||||
rv = obj->destroy(obj->privData);
|
||||
cmt_free(obj);
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef __obscure_h__
|
||||
#define __obscure_h__ 1
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
typedef unsigned char SSMObscureBool;
|
||||
|
||||
typedef struct SSMObscureObjectStr SSMObscureObject;
|
||||
|
||||
/*
|
||||
** Create a new Obscuring object
|
||||
*/
|
||||
extern SSMObscureObject * SSMObscure_Create(SSMObscureBool IsServer);
|
||||
|
||||
|
||||
/* Prepare initial buffer with initial message to send to other side to
|
||||
** establish cryptographic * synchronization.
|
||||
**
|
||||
** If buf is NULL, function returns the size of the buffer that
|
||||
** the caller needs to allocate for sending the initial message.
|
||||
**
|
||||
** If buf is non-null, function returns the number of bytes of data filled
|
||||
** into buf, the amount that the caller should then send to the other side.
|
||||
**
|
||||
*/
|
||||
extern int SSMObscure_SendInit( SSMObscureObject * obj,
|
||||
void * buf);
|
||||
|
||||
/*
|
||||
** Obscure "len" bytes in "buf" before sending it.
|
||||
*/
|
||||
extern int SSMObscure_Send( SSMObscureObject * obj,
|
||||
void * buf,
|
||||
unsigned int len);
|
||||
|
||||
/*
|
||||
** UnObscure "len" bytes in "buf" after receiving it.
|
||||
** This function may absorb some or all of the received bytes, leaving
|
||||
** fewer bytes (possibly none) in the buffer for the application to use
|
||||
** than were in the buffer when the function was called.
|
||||
** Function returns the number of bytes of unobscured data remaining in
|
||||
** buf. Zero means all data was used internally and no data remains
|
||||
** for application use. Negative number means error occurred.
|
||||
*/
|
||||
extern int SSMObscure_Recv( SSMObscureObject * obj,
|
||||
void * buf,
|
||||
unsigned int len);
|
||||
|
||||
/* like _Recv, but returns a flag telling when all initialization info has
|
||||
** been received.
|
||||
*/
|
||||
extern int SSMObscure_RecvInit( SSMObscureObject * obj,
|
||||
void * buf,
|
||||
unsigned int len,
|
||||
SSMObscureBool * done);
|
||||
|
||||
/*
|
||||
** Destroy the Obscure Object
|
||||
*/
|
||||
extern int SSMObscure_Destroy(SSMObscureObject * obj);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __obscure_h__ */
|
||||
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "obspriv.h"
|
||||
#include "newproto.h"
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <time.h>
|
||||
|
||||
/*
|
||||
Originally this code was used to obscure the control messages
|
||||
traveling between processes. With the relaxation of export rules,
|
||||
this whole step is no longer necessary, and is included for
|
||||
informational purposes only. (We need to finish removing the
|
||||
obscuring code.)
|
||||
*/
|
||||
struct obscureNOPStr {
|
||||
SSMObscureObject * obj;
|
||||
};
|
||||
|
||||
typedef struct obscureNOPStr obscureV1;
|
||||
|
||||
static int
|
||||
ssmObscure_Destroy(void * privData)
|
||||
{
|
||||
obscureV1 * priv = (obscureV1 *)privData;
|
||||
|
||||
memset(priv, 0, sizeof *priv);
|
||||
cmt_free(priv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ssmObscure_Send(void * privData, void * buf, unsigned int len)
|
||||
{
|
||||
/* obscureV1 * priv = (obscureV1 *)privData;*/
|
||||
|
||||
/* NOP */
|
||||
return len;
|
||||
}
|
||||
|
||||
static int
|
||||
ssmObscure_Recv(void * privData, void * buf, unsigned int len)
|
||||
{
|
||||
/*obscureV1 * priv = (obscureV1 *)privData;*/
|
||||
|
||||
/* NOP */
|
||||
return len;
|
||||
}
|
||||
|
||||
static int
|
||||
ssmObscure_SendInit(void * privData, void * buf)
|
||||
{
|
||||
/*obscureV1 * priv = (obscureV1 *)privData;*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ssmObscure_RecvInit(void * privData, void * buf, unsigned int len,
|
||||
SSMObscureBool * pDone)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *
|
||||
ssmObscure_InitPrivate(SSMObscureObject * obj, SSMObscureBool IsServer)
|
||||
{
|
||||
obscureV1 * priv = (obscureV1 *) cmt_alloc(sizeof (obscureV1));
|
||||
|
||||
if (!priv)
|
||||
return NULL;
|
||||
|
||||
priv->obj = obj;
|
||||
|
||||
obj->privData = (void *)priv;
|
||||
obj->destroy = ssmObscure_Destroy;
|
||||
obj->send = ssmObscure_Send;
|
||||
obj->recv = ssmObscure_Recv;
|
||||
obj->sendInit = ssmObscure_SendInit;
|
||||
obj->recvInit = ssmObscure_RecvInit;
|
||||
|
||||
return priv;
|
||||
}
|
||||
|
||||
obsInitFn SSMObscure_InitPrivate = ssmObscure_InitPrivate;
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "obscure.h"
|
||||
|
||||
typedef void * (* obsInitFn) (SSMObscureObject * instance,
|
||||
SSMObscureBool IsServer);
|
||||
typedef int (* obsDestroyFn) (void * priv);
|
||||
typedef int (* obsSendFn) (void * priv, void * buf, unsigned int len);
|
||||
typedef int (* obsRecvFn) (void * priv, void * buf, unsigned int len);
|
||||
typedef int (* obsSendInitFn)(void * priv, void * buf);
|
||||
typedef int (* obsRecvInitFn)(void * priv, void * buf, unsigned int len,
|
||||
SSMObscureBool * done);
|
||||
|
||||
struct SSMObscureObjectStr {
|
||||
void * privData;
|
||||
obsDestroyFn destroy;
|
||||
obsSendFn send;
|
||||
obsRecvFn recv;
|
||||
obsSendInitFn sendInit;
|
||||
obsRecvInitFn recvInit;
|
||||
};
|
||||
|
||||
|
||||
/* This is common to the beginning of all versions of the obscuring protocol */
|
||||
struct SSMInitMsgHdrStr {
|
||||
short version;
|
||||
short length;
|
||||
};
|
||||
|
||||
typedef struct SSMInitMsgHdrStr SSMInitMsgHdr;
|
||||
|
||||
extern obsInitFn SSMObscure_InitPrivate;
|
||||
|
||||
@@ -1,141 +0,0 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
/*
|
||||
protocol.h - Definitions of various items to support the PSM protocol.
|
||||
*/
|
||||
|
||||
#ifndef __PROTOCOL_H__
|
||||
#define __PROTOCOL_H__
|
||||
|
||||
|
||||
#include "rsrcids.h"
|
||||
|
||||
#define SSMPRStatus SSMStatus
|
||||
#define SSMPR_SUCCESS SSM_SUCCESS
|
||||
#define SSMPR_FAILURE SSM_FAILURE
|
||||
|
||||
#define SSMPR_INVALID_ARGUMENT_ERROR PR_INVALID_ARGUMENT_ERROR
|
||||
#define SSMPR_OUT_OF_MEMORY_ERROR PR_OUT_OF_MEMORY_ERROR
|
||||
|
||||
#define SSMPRInt32 PRInt32
|
||||
#define SSMPRUint32 PRUint32
|
||||
|
||||
#define SSMPR_ntohl PR_ntohl
|
||||
#define SSMPR_htonl PR_htonl
|
||||
#define SSMPORT_Free PORT_Free
|
||||
#define SSMPORT_ZAlloc PORT_ZAlloc
|
||||
|
||||
#define SSMPR_SetError PR_SetError
|
||||
#define SSMPR_GetError PR_GetError
|
||||
#define SSMPORT_SetError PORT_SetError
|
||||
#define SSMPORT_GetError PORT_GetError
|
||||
|
||||
/*
|
||||
Current version of PSM protocol.
|
||||
Increment this value when the protocol changes.
|
||||
*/
|
||||
|
||||
#define SSMSTRING_PADDED_LENGTH(x) ((((x)+3)/4)*4)
|
||||
#define SSMPORT_ZNEW(type) (type*)SSMPORT_ZAlloc(sizeof(type))
|
||||
#define SSMPORT_ZNewArray(type,size) (type*)SSMPORT_ZAlloc(sizeof(type)*(size))
|
||||
/* Various message structs */
|
||||
|
||||
struct _SSMHelloRequest {
|
||||
CMUint32 m_version; /* Protocol version supported by client */
|
||||
struct _SSMString m_profileName; /* Name of user profile (where to find
|
||||
certs etc) */
|
||||
};
|
||||
|
||||
struct _SSMHelloReply {
|
||||
CMInt32 m_result; /* Error, if any, which occurred
|
||||
(0 == success) */
|
||||
CMUint32 m_version; /* Protocol version supported by PSM */
|
||||
struct _SSMString m_nonce; /* Session nonce -- must be written to data channels */
|
||||
};
|
||||
|
||||
struct _SSMRequestSSLDataConnection
|
||||
{
|
||||
CMUint32 m_flags; /* Flags to indicate to SSM what to do with
|
||||
the connection */
|
||||
CMUint32 m_port; /* Port number to connect to */
|
||||
struct _SSMString m_hostIP; /* IP address of final target machine (not proxy) */
|
||||
/* struct _SSMString m_hostName; Host name of target machine (for server auth) -- not accessed directly */
|
||||
};
|
||||
|
||||
struct _SSMReplySSLDataConnection {
|
||||
CMInt32 m_result; /* Error, if any, which occurred (0 == success) */
|
||||
CMUint32 m_connectionID; /* Connection ID of newly opened channel */
|
||||
CMUint32 m_port; /* Port number to which to connect on PSM */
|
||||
};
|
||||
|
||||
|
||||
struct _SSMRequestSecurityStatus {
|
||||
CMUint32 m_connectionID; /* ID of connection of which to stat */
|
||||
};
|
||||
|
||||
struct _SSMReplySecurityStatus {
|
||||
CMInt32 m_result; /* Error, if any, which occurred (0 == success) */
|
||||
CMUint32 m_keySize; /* Key size */
|
||||
CMUint32 m_secretKeySize; /* Secret key size */
|
||||
struct _SSMString m_cipherName; /* Name of cipher in use */
|
||||
/* SSMString m_certificate; -- DER encoded cert
|
||||
We do not access this as a field, we have to skip over m_cipherName */
|
||||
};
|
||||
|
||||
/*
|
||||
Use this macro to jump over strings.
|
||||
For example, if you wanted to access m_certificate above,
|
||||
use a line like the following:
|
||||
|
||||
char *ptr = &(reply->m_cipherName) + SSM_SIZEOF_STRING(reply->m_cipherName);
|
||||
*/
|
||||
#define SSM_SIZEOF_STRING(str) (SSMSTRING_PADDED_LENGTH(PR_ntohl((str).m_length)) + sizeof(CMUint32))
|
||||
|
||||
|
||||
typedef struct _SSMHelloRequest SSMHelloRequest;
|
||||
typedef struct _SSMHelloReply SSMHelloReply;
|
||||
typedef struct _SSMRequestSSLDataConnection SSMRequestSSLDataConnection;
|
||||
typedef struct _SSMReplySSLDataConnection SSMReplySSLDataConnection;
|
||||
typedef struct _SSMRequestSecurityStatus SSMRequestSecurityStatus;
|
||||
typedef struct _SSMReplySecurityStatus SSMReplySecurityStatus;
|
||||
|
||||
/*
|
||||
Functions to convert between an SSMString and a C string.
|
||||
Return values are allocated using PR_Malloc (which means that
|
||||
SSMPR_Free must be used to free up the memory after use).
|
||||
*/
|
||||
CMTStatus SSM_StringToSSMString(SSMString ** ssmString, int len, char * string);
|
||||
CMTStatus SSM_SSMStringToString(char ** string,int *len, SSMString * ssmString);
|
||||
|
||||
|
||||
#endif /* __PROTOCOL_H__ */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,359 +0,0 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef __PROTOCOLF_H__
|
||||
#define __PROTOCOLF_H__
|
||||
/*************************************************************************
|
||||
* For each type of message, parse and pack function is provided.
|
||||
*
|
||||
* Parse functions accept a ptr to the "blob" of data received from the
|
||||
* network and fill in fields of the message, numbers in host-order, strings
|
||||
* as C-style NULL-terminated strings. Return SSMPRStatus.
|
||||
*
|
||||
* Pack functions take all the info to construct a message and fill in a
|
||||
* ptr to the "blob" of data to be sent. Return length of the data blob, or
|
||||
* a zero in case of an error
|
||||
*
|
||||
* All functions set NSPR errors when necessary.
|
||||
************************************************************************/
|
||||
#include "protocol.h"
|
||||
#include "cert.h"
|
||||
|
||||
SSMPRStatus SSM_ParseHelloRequest(void * helloRequest,
|
||||
SSMPRUint32 * version,
|
||||
PRBool * doesUI,
|
||||
PRInt32 * policyType,
|
||||
SSMPRUint32 * profileLen,
|
||||
char ** profile);
|
||||
SSMPRInt32 SSM_PackHelloReply(void ** helloReply, SSMPRInt32 result,
|
||||
SSMPRUint32 sessionID, SSMPRUint32 version,
|
||||
SSMPRUint32 httpPort, SSMPRUint32 nonceLen,
|
||||
char * nonce, SSMPolicyType policy);
|
||||
|
||||
/* Parse data connections requests */
|
||||
SSMPRStatus SSM_ParseSSLDataConnectionRequest(void *sslRequest,
|
||||
SSMPRUint32 * flags,
|
||||
SSMPRUint32 * port,
|
||||
SSMPRUint32 * hostIPLen,
|
||||
char ** hostIP,
|
||||
SSMPRUint32 * hostNameLen,
|
||||
char ** hostName);
|
||||
SSMPRStatus SSM_ParseHashStreamRequest(void * hashStreamRequest,
|
||||
SSMPRUint32 * type);
|
||||
SSMPRStatus SSM_ParseP7EncodeConnectionRequest(void *request,
|
||||
SSMPRUint32 *ciRID);
|
||||
/* Messages to initiate PKCS7 data connection */
|
||||
/* PKCS7DecodeRequest message has no data */
|
||||
|
||||
/* Single data connection reply */
|
||||
SSMPRInt32 SSM_PackDataConnectionReply(void ** sslReply,
|
||||
SSMPRInt32 result,
|
||||
SSMPRUint32 connID,
|
||||
SSMPRUint32 port);
|
||||
|
||||
SSMPRStatus SSM_ParseSSLSocketStatusRequest(void * statusRequest,
|
||||
SSMPRUint32 * connID);
|
||||
SSMPRInt32 SSM_PackSSLSocketStatusReply(void ** statusReply,
|
||||
SSMPRInt32 result,
|
||||
SSMPRUint32 resourceID);
|
||||
|
||||
/*
|
||||
* UI event is an asynchroneous message sent from PSM server to the client
|
||||
* NOTE: (context) is the actual context pointer, it is NOT a ptr-to-ptr.
|
||||
* The value of (context) is copied into the packet.
|
||||
*/
|
||||
SSMPRInt32 SSM_PackUIEvent(void ** eventRequest, SSMPRUint32 resourceID,
|
||||
SSMPRUint32 width, SSMPRUint32 height,
|
||||
SSMPRUint32 urlLen, char * url);
|
||||
|
||||
SSMPRInt32 SSM_PackTaskCompletedEvent(void **event, SSMPRUint32 resourceID,
|
||||
SSMPRUint32 numTasks, SSMPRUint32 result);
|
||||
|
||||
/* Verify raw signature */
|
||||
|
||||
SSMPRStatus SSM_ParseVerifyRawSigRequest(void * verifyRawSigRequest,
|
||||
SSMPRUint32 * algorithmID,
|
||||
SSMPRUint32 * paramsLen,
|
||||
unsigned char ** params,
|
||||
SSMPRUint32 * pubKeyLen,
|
||||
unsigned char ** pubKey,
|
||||
SSMPRUint32 * hashLen,
|
||||
unsigned char ** hash,
|
||||
SSMPRUint32 * signatureLen,
|
||||
unsigned char ** signature);
|
||||
SSMPRInt32 SSM_PackVerifyRawSigReply(void ** verifyRawSigReply,
|
||||
SSMPRInt32 result);
|
||||
|
||||
/* Verify detached signature */
|
||||
SSMPRStatus SSM_ParseVerifyDetachedSigRequest(void * request,
|
||||
SSMPRInt32 * pkcs7ContentID,
|
||||
SSMPRInt32 * certUsage,
|
||||
SSMPRInt32 * hashAlgID,
|
||||
SSMPRUint32 * keepCert,
|
||||
SSMPRUint32 * digestLen,
|
||||
unsigned char ** hash);
|
||||
|
||||
SSMPRInt32 SSM_PackVerifyDetachedSigReply(void ** verifyDetachedSigReply,
|
||||
SSMPRInt32 result);
|
||||
|
||||
/* PKCS#7 functions */
|
||||
SSMPRStatus SSM_ParseCreateSignedRequest(void *request,
|
||||
SSMPRInt32 *scertRID,
|
||||
SSMPRInt32 *ecertRID,
|
||||
SSMPRUint32 *dig_alg,
|
||||
SECItem **digest);
|
||||
|
||||
SSMPRInt32 SSM_PackCreateSignedReply(void **reply, SSMPRInt32 ciRID,
|
||||
SSMPRUint32 result);
|
||||
|
||||
SSMPRStatus SSM_ParseCreateEncryptedRequest(void *request,
|
||||
SSMPRInt32 *scertRID,
|
||||
SSMPRInt32 *nrcerts,
|
||||
SSMPRInt32 **rcertRIDs);
|
||||
|
||||
SSMPRInt32 SSM_PackCreateEncryptedReply(void **reply, SSMPRInt32 ciRID,
|
||||
SSMPRUint32 result);
|
||||
|
||||
/* Resource functions */
|
||||
SSMPRStatus SSM_ParseCreateResourceRequest(void *request,
|
||||
SSMPRUint32 *type,
|
||||
unsigned char **params,
|
||||
SSMPRUint32 *paramLen);
|
||||
|
||||
SSMPRStatus SSM_PackCreateResourceReply(void **reply, SSMPRStatus rv,
|
||||
SSMPRUint32 resID);
|
||||
|
||||
SSMPRStatus SSM_ParseGetAttribRequest(void * getAttribRequest,
|
||||
SSMPRUint32 * resourceID,
|
||||
SSMPRUint32 * fieldID);
|
||||
|
||||
void SSM_DestroyAttrValue(SSMAttributeValue *value, PRBool freeit);
|
||||
|
||||
SSMPRInt32 SSM_PackGetAttribReply(void **getAttribReply,
|
||||
SSMPRInt32 result,
|
||||
SSMAttributeValue *value);
|
||||
SSMPRStatus SSM_ParseSetAttribRequest(SECItem *msg,
|
||||
SSMPRInt32 *resourceID,
|
||||
SSMPRInt32 *fieldID,
|
||||
SSMAttributeValue *value);
|
||||
/* Currently, there is no need for a pack version. There is nothing to send
|
||||
* back except for the notice that the operation was successful.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* Pickle and unpickle resources. */
|
||||
SSMPRStatus SSM_ParsePickleResourceRequest(void * pickleResourceRequest,
|
||||
SSMPRUint32 * resourceID);
|
||||
SSMPRInt32 SSM_PackPickleResourceReply(void ** pickleResourceReply,
|
||||
SSMPRInt32 result,
|
||||
SSMPRUint32 resourceLen,
|
||||
void * resource);
|
||||
SSMPRStatus SSM_ParseUnpickleResourceRequest(void * unpickleResourceRequest,
|
||||
SSMPRUint32 blobSize,
|
||||
SSMPRUint32 * resourceType,
|
||||
SSMPRUint32 * resourceLen,
|
||||
void ** resource);
|
||||
SSMPRInt32 SSM_PackUnpickleResourceReply(void ** unpickleResourceReply,
|
||||
SSMPRInt32 result,
|
||||
SSMPRUint32 resourceID);
|
||||
|
||||
/* Destroy resource */
|
||||
SSMPRStatus SSM_ParseDestroyResourceRequest(void * destroyResourceRequest,
|
||||
SSMPRUint32 * resourceID,
|
||||
SSMPRUint32 * resourceType);
|
||||
SSMPRInt32 SSM_PackDestroyResourceReply(void ** destroyResourceReply,
|
||||
SSMPRInt32 result);
|
||||
|
||||
/* Duplicate resource */
|
||||
SSMPRStatus SSM_ParseDuplicateResourceRequest(void * request,
|
||||
SSMPRUint32 * resourceID);
|
||||
SSMPRInt32 SSM_PackDuplicateResourceReply(void ** reply, SSMPRInt32 result,
|
||||
SSMPRUint32 resID);
|
||||
|
||||
/* Cert actions */
|
||||
typedef struct MatchUserCertRequestData {
|
||||
PRUint32 certType;
|
||||
PRInt32 numCANames;
|
||||
char ** caNames;
|
||||
} MatchUserCertRequestData;
|
||||
|
||||
typedef struct SSMCertList {
|
||||
PRCList certs;
|
||||
PRInt32 count;
|
||||
} SSMCertList;
|
||||
|
||||
typedef struct SSMCertListElement {
|
||||
PRCList links;
|
||||
PRUint32 certResID;
|
||||
} SSMCertListElement;
|
||||
|
||||
#define SSM_CERT_LIST_ELEMENT_PTR(_q) (SSMCertListElement*)(_q);
|
||||
|
||||
SSMPRStatus SSM_ParseVerifyCertRequest(void * verifyCertRequest,
|
||||
SSMPRUint32 * resourceID,
|
||||
SSMPRInt32 * certUsage);
|
||||
SSMPRInt32 SSM_PackVerifyCertReply(void ** verifyCertReply,
|
||||
SSMPRInt32 result);
|
||||
|
||||
SSMPRStatus SSM_ParseImportCertRequest(void * importCertRequest,
|
||||
SSMPRUint32 * blobLen,
|
||||
void ** certBlob);
|
||||
SSMPRInt32 SSM_PackImportCertReply(void ** importCertReply, SSMPRInt32 result,
|
||||
SSMPRUint32 resourceID);
|
||||
PRStatus SSM_ParseFindCertByNicknameRequest(void *request, char ** nickname);
|
||||
PRInt32 SSM_PackFindCertByNicknameReply(void ** reply, PRUint32 resourceID);
|
||||
PRStatus SSM_ParseFindCertByKeyRequest(void *request, SECItem ** key);
|
||||
PRInt32 SSM_PackFindCertByKeyReply(void ** reply, PRUint32 resourceID);
|
||||
PRStatus SSM_ParseFindCertByEmailAddrRequest(void *request, char ** emailAddr);
|
||||
PRInt32 SSM_PackFindCertByEmailAddrReply(void ** reply, PRUint32 resourceID);
|
||||
PRStatus SSM_ParseAddTempCertToDBRequest(void *request, PRUint32 *resourceID, char ** nickname, PRInt32 *ssl, PRInt32 *email, PRInt32 *objectSigning);
|
||||
PRInt32 SSM_PackAddTempCertToDBReply(void ** reply);
|
||||
PRStatus SSM_ParseMatchUserCertRequest(void *request, MatchUserCertRequestData** data);
|
||||
PRInt32 SSM_PackMatchUserCertReply(void **reply, SSMCertList * certList);
|
||||
|
||||
SSMPRInt32 SSM_PackErrorMessage(void ** errorReply, SSMPRInt32 result);
|
||||
|
||||
|
||||
/* PKCS11 actions */
|
||||
SSMPRStatus SSM_ParseKeyPairGenRequest(void *keyPairGenRequest,
|
||||
SSMPRInt32 requestLen,
|
||||
SSMPRUint32 *keyPairCtxtID,
|
||||
SSMPRUint32 *genMechanism,
|
||||
SSMPRUint32 *keySize,
|
||||
unsigned char **params,
|
||||
SSMPRUint32 *paramLen);
|
||||
|
||||
SSMPRInt32 SSM_PackKeyPairGenResponse(void ** keyPairGenResponse,
|
||||
SSMPRUint32 keyPairId);
|
||||
|
||||
PRStatus
|
||||
SSM_ParseFinishKeyGenRequest(void *finishKeyGenRequest,
|
||||
PRInt32 requestLen,
|
||||
PRInt32 *keyGenContext);
|
||||
|
||||
/* CMMF/CRMF Actions */
|
||||
SSMPRStatus SSM_ParseCreateCRMFReqRequest(void *crmfReqRequest,
|
||||
SSMPRInt32 requestLen,
|
||||
SSMPRUint32 *keyPairId);
|
||||
|
||||
SSMPRInt32 SSM_PackCreateCRMFReqReply(void **crmfReqReply,
|
||||
SSMPRUint32 crmfReqId);
|
||||
|
||||
SSMPRStatus SSM_ParseEncodeCRMFReqRequest(void *encodeReq,
|
||||
SSMPRInt32 requestLen,
|
||||
SSMPRUint32 **crmfReqId,
|
||||
SSMPRInt32 *numRequests);
|
||||
|
||||
SSMPRInt32 SSM_PackEncodeCRMFReqReply(void **encodeReply,
|
||||
char *crmfDER,
|
||||
SSMPRUint32 derLen);
|
||||
|
||||
SSMPRStatus SSM_ParseCMMFCertResponse(void *encodedRes,
|
||||
SSMPRInt32 encodeLen,
|
||||
char **nickname,
|
||||
char **base64Der,
|
||||
PRBool *doBackup);
|
||||
|
||||
PRStatus SSM_ParsePOPChallengeRequest(void *challenge,
|
||||
PRInt32 len,
|
||||
char **responseString);
|
||||
PRInt32 SSM_PackPOPChallengeResponse(void **response,
|
||||
char *responseString,
|
||||
PRInt32 responseStringLen);
|
||||
|
||||
PRInt32 SSM_PackPasswdRequest(void ** passwdRequest, PRInt32 tokenID,
|
||||
char * prompt, PRInt32 promptLen);
|
||||
PRStatus SSM_ParsePasswordReply(void * passwdReply, PRInt32 * result,
|
||||
PRInt32 * tokenID,
|
||||
char ** passwd, PRInt32 * passwdLen);
|
||||
|
||||
/* Sign Text Actions */
|
||||
typedef struct {
|
||||
char *stringToSign;
|
||||
char *hostName;
|
||||
char *caOption;
|
||||
PRInt32 numCAs;
|
||||
char **caNames;
|
||||
} signTextRequestData;
|
||||
|
||||
PRStatus SSM_ParseSignTextRequest(void* signTextRequest, PRInt32 len, PRUint32* resID, signTextRequestData ** data);
|
||||
|
||||
PRStatus SSM_ParseGetLocalizedTextRequest(void *data,
|
||||
SSMLocalizedString *whichString);
|
||||
|
||||
PRInt32 SSM_PackGetLocalizedTextResponse(void **data,
|
||||
SSMLocalizedString whichString,
|
||||
char *retString);
|
||||
|
||||
PRStatus SSM_ParseAddNewSecurityModuleRequest(void *data,
|
||||
char **moduleName,
|
||||
char **libraryPath,
|
||||
unsigned long *pubMechFlags,
|
||||
unsigned long *pubCipherFlags);
|
||||
|
||||
PRInt32 SSM_PackAddNewModuleResponse(void **data, PRInt32 rv);
|
||||
|
||||
PRStatus SSM_ParseDeleteSecurityModuleRequest(void *data, char **moduleName);
|
||||
|
||||
PRInt32 SSM_PackDeleteModuleResponse(void **data, PRInt32 moduleType);
|
||||
|
||||
PRInt32 SSM_PackFilePathRequest(void **data, PRInt32 resID, char *prompt,
|
||||
PRBool shouldFileExist, char *fileSuffix);
|
||||
|
||||
PRStatus SSM_ParseFilePathReply(void *message, char **filePath,
|
||||
PRInt32 *rid);
|
||||
|
||||
PRInt32 SSM_PackPromptRequestEvent(void **data, PRInt32 resID, char *prompt);
|
||||
PRStatus SSM_ParsePasswordPromptReply(void *data, PRInt32 *resID,
|
||||
char **reply);
|
||||
|
||||
/* messages for importing certs *the traditional way* */
|
||||
PRInt32 SSM_PackDecodeCertReply(void ** data, PRInt32 certID);
|
||||
PRStatus SSM_ParseDecodeCertRequest(void * data, PRInt32 * len,
|
||||
char ** buffer);
|
||||
PRStatus SSM_ParseGetKeyChoiceListRequest(void * data, PRUint32 dataLen,
|
||||
char ** type, PRUint32 *typeLen,
|
||||
char ** pqgString, PRUint32 *pqgLen);
|
||||
PRInt32 SSM_PackGetKeyChoiceListReply(void **data, char ** list);
|
||||
|
||||
PRStatus SSM_ParseGenKeyOldStyleRequest(void * data, PRUint32 datalen,
|
||||
char ** choiceString,
|
||||
char ** challenge,
|
||||
char ** typeString,
|
||||
char ** pqgString);
|
||||
PRInt32 SSM_PackGenKeyOldStyleReply(void ** data, char * keydata);
|
||||
|
||||
PRStatus SSM_ParseDecodeAndCreateTempCertRequest(void * data,
|
||||
char ** certbuf, PRUint32 * certlen, int * certClass);
|
||||
|
||||
#endif /*PROTOCOLF_H_*/
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
/*****************************************************************************
|
||||
*
|
||||
*
|
||||
*
|
||||
*****************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0x00000000
|
||||
#endif
|
||||
|
||||
#define SSMPR_BYTES_PER_INT 4
|
||||
#define SSMPR_BYTES_PER_LONG 4
|
||||
|
||||
/******************************************************************
|
||||
* No NSPR - define all the SSMPR values and functions here
|
||||
******************************************************************
|
||||
*/
|
||||
|
||||
#define SSMPRStatus PRStatus
|
||||
#define SSMPR_SUCCESS PR_SUCCESS
|
||||
#define SSMPR_FAILURE PR_FAILURE
|
||||
|
||||
#define SSMPR_INVALID_ARGUMENT_ERROR PR_INVALID_ARGUMENT_ERROR
|
||||
#define SSMPR_OUT_OF_MEMORY_ERROR PR_OUT_OF_MEMORY_ERROR
|
||||
|
||||
#define SSMPRInt32 PRInt32
|
||||
#define SSMPRUint32 PRUint32
|
||||
|
||||
#define SSMPR_ntohl PR_ntohl
|
||||
#define SSMPR_htonl PR_htonl
|
||||
#define SSMPORT_Free PORT_Free
|
||||
#define SSMPORT_ZAlloc PORT_ZAlloc
|
||||
|
||||
#define SSMPR_SetError PR_SetError
|
||||
#define SSMPR_GetError PR_GetError
|
||||
#define SSMPORT_SetError PORT_SetError
|
||||
#define SSMPORT_GetError PORT_GetError
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
/*************************************************************************
|
||||
*
|
||||
* PSM portable run-time. (Used when NSPR20 is not available.)
|
||||
*
|
||||
*************************************************************************
|
||||
*/
|
||||
|
||||
SSMPRInt32 ssmprErrno;
|
||||
|
||||
void SSMPORT_SetError(SSMPRInt32 errorcode)
|
||||
{ ssmprErrno = errorcode; }
|
||||
|
||||
|
||||
SSMPRInt32 SSMPORT_GetError(void)
|
||||
{ return ssmprErrno; }
|
||||
|
||||
|
||||
@@ -1,93 +0,0 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
/*****************************************************************************
|
||||
*
|
||||
*
|
||||
*
|
||||
*****************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL 0x00000000
|
||||
#endif
|
||||
|
||||
#define SSMPR_BYTES_PER_INT 4
|
||||
#define SSMPR_BYTES_PER_LONG 4
|
||||
|
||||
/******************************************************************
|
||||
* No NSPR - define all the SSMPR values and functions here
|
||||
******************************************************************
|
||||
*/
|
||||
|
||||
typedef enum { SSMPR_SUCCESS = 0, SSMPR_FAILURE = -1 } SSMPRStatus;
|
||||
enum {
|
||||
SSMPR_INVALID_ARGUMENT_ERROR = -6000,
|
||||
SSMPR_OUT_OF_MEMORY_ERROR = -5987
|
||||
};
|
||||
|
||||
#if SSMPR_BYTES_PER_INT == 4
|
||||
typedef unsigned int SSMPRUint32;
|
||||
typedef int SSMPRInt32;
|
||||
#elif SSMPR_BYTES_PER_LONG == 4
|
||||
typedef unsigned long SSMPRUint32;
|
||||
typedef long SSMPRInt32;
|
||||
#else
|
||||
#error No suitable type for SSMPRInt32/SSMPRUint32
|
||||
#endif
|
||||
|
||||
/*******************************************************************
|
||||
* Use libc functions instead
|
||||
*******************************************************************
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
#ifdef WIN32
|
||||
#include <winsock.h>
|
||||
#else
|
||||
#include <netinet/in.h>
|
||||
#endif
|
||||
#define SSMPR_ntohl ntohl
|
||||
#define SSMPR_htonl htonl
|
||||
|
||||
#include <stdlib.h>
|
||||
#define SSMPORT_Free free
|
||||
#define SSMPR_sprint printf
|
||||
#define SSMPORT_ZAlloc malloc
|
||||
|
||||
extern SSMPRInt32 ssmprErrno;
|
||||
#define SSMPR_SetError(x, y) SSMPORT_SetError(x)
|
||||
#define SSMPR_GetError SSMPORT_GetError
|
||||
void SSMPORT_SetError(SSMPRInt32 errorcode);
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,169 +0,0 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "string.h"
|
||||
#include "protocol.h"
|
||||
#include "protocolshr.h"
|
||||
#include "messages.h"
|
||||
|
||||
/* Forward ref */
|
||||
static void encrypt(CMTItem *data);
|
||||
static void decrypt(CMTItem *data);
|
||||
|
||||
const char *kPrefix = "Encrypted";
|
||||
|
||||
/* encryption request */
|
||||
CMTStatus
|
||||
CMT_DoEncryptionRequest(CMTItem *message)
|
||||
{
|
||||
CMTStatus rv = CMTSuccess;
|
||||
EncryptRequestMessage request;
|
||||
EncryptReplyMessage reply;
|
||||
CMUint32 pLen = strlen(kPrefix);
|
||||
|
||||
/* Initialize */
|
||||
request.keyid.data = 0;
|
||||
request.data.data = 0;
|
||||
reply.item.data = 0;
|
||||
|
||||
/* Decode incoming message */
|
||||
rv = CMT_DecodeMessage(EncryptRequestTemplate, &request, message);
|
||||
if (rv != CMTSuccess) goto loser; /* Protocol error */
|
||||
|
||||
/* Free incoming message */
|
||||
free(message->data);
|
||||
message->data = NULL;
|
||||
|
||||
/* "Encrypt" by prefixing the data */
|
||||
reply.item.len = request.data.len + pLen;
|
||||
reply.item.data = calloc(reply.item.len, 1);
|
||||
if (!reply.item.data) {
|
||||
rv = CMTFailure;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
if (pLen) memcpy(reply.item.data, kPrefix, pLen);
|
||||
encrypt(&request.data);
|
||||
memcpy(&reply.item.data[pLen], request.data.data, request.data.len);
|
||||
|
||||
/* Generate response */
|
||||
message->type = SSM_SDR_ENCRYPT_REPLY;
|
||||
rv = CMT_EncodeMessage(EncryptReplyTemplate, message, &reply);
|
||||
if (rv != CMTSuccess) goto loser; /* Unknown error */
|
||||
|
||||
loser:
|
||||
if (request.keyid.data) free(request.keyid.data);
|
||||
if (request.data.data) free(request.data.data);
|
||||
if (request.ctx.data) free(request.ctx.data);
|
||||
if (reply.item.data) free(reply.item.data);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* decryption request */
|
||||
CMTStatus
|
||||
CMT_DoDecryptionRequest(CMTItem *message)
|
||||
{
|
||||
CMTStatus rv = CMTSuccess;
|
||||
DecryptRequestMessage request;
|
||||
DecryptReplyMessage reply;
|
||||
CMUint32 pLen = strlen(kPrefix);
|
||||
|
||||
/* Initialize */
|
||||
request.data.data = 0;
|
||||
request.ctx.data = 0;
|
||||
reply.item.data = 0;
|
||||
|
||||
/* Decode the message */
|
||||
rv = CMT_DecodeMessage(DecryptRequestTemplate, &request, message);
|
||||
if (rv != CMTSuccess) goto loser;
|
||||
|
||||
/* Free incoming message */
|
||||
free(message->data);
|
||||
message->data = NULL;
|
||||
|
||||
/* "Decrypt" the message by removing the key */
|
||||
if (pLen && memcmp(request.data.data, kPrefix, pLen) != 0) {
|
||||
rv = CMTFailure; /* Invalid format */
|
||||
goto loser;
|
||||
}
|
||||
|
||||
reply.item.len = request.data.len - pLen;
|
||||
reply.item.data = calloc(reply.item.len, 1);
|
||||
if (!reply.item.data) { rv = CMTFailure; goto loser; }
|
||||
|
||||
memcpy(reply.item.data, &request.data.data[pLen], reply.item.len);
|
||||
decrypt(&reply.item);
|
||||
|
||||
/* Create reply message */
|
||||
message->type = SSM_SDR_DECRYPT_REPLY;
|
||||
rv = CMT_EncodeMessage(DecryptReplyTemplate, message, &reply);
|
||||
if (rv != CMTSuccess) goto loser;
|
||||
|
||||
loser:
|
||||
if (request.data.data) free(request.data.data);
|
||||
if (request.ctx.data) free(request.ctx.data);
|
||||
if (reply.item.data) free(reply.item.data);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* "encrypt" */
|
||||
static unsigned char mask[64] = {
|
||||
0x73, 0x46, 0x1a, 0x05, 0x24, 0x65, 0x43, 0xb4, 0x24, 0xee, 0x79, 0xc1, 0xcc,
|
||||
0x49, 0xc7, 0x27, 0x11, 0x91, 0x2e, 0x8f, 0xaa, 0xf7, 0x62, 0x75, 0x41, 0x7e,
|
||||
0xb2, 0x42, 0xde, 0x1b, 0x42, 0x7b, 0x1f, 0x33, 0x49, 0xca, 0xd1, 0x6a, 0x85,
|
||||
0x05, 0x6c, 0xf9, 0x0e, 0x3e, 0x72, 0x02, 0xf2, 0xd8, 0x9d, 0xa1, 0xb8, 0x6e,
|
||||
0x03, 0x18, 0x3e, 0x82, 0x86, 0x34, 0x1a, 0x61, 0xd9, 0x65, 0xb6, 0x7f
|
||||
};
|
||||
|
||||
static void
|
||||
encrypt(CMTItem *data)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
j = 0;
|
||||
for(i = 0;i < data->len;i++)
|
||||
{
|
||||
data->data[i] ^= mask[j];
|
||||
|
||||
if (++j >= 64) j = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
decrypt(CMTItem *data)
|
||||
{
|
||||
encrypt(data);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
/*
|
||||
protocolshr.h - Definitions of shared routines for both client and server
|
||||
These are mostly for testing.
|
||||
*/
|
||||
|
||||
#ifndef __PROTOCOLSHR_H__
|
||||
#define __PROTOCOLSHR_H__
|
||||
|
||||
CMTStatus
|
||||
CMT_DoEncryptionRequest(CMTItem *message);
|
||||
|
||||
CMTStatus
|
||||
CMT_DoDecryptionRequest(CMTItem *meessage);
|
||||
|
||||
|
||||
#endif /* __PROTOCOLSHR_H__ */
|
||||
@@ -1,207 +0,0 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "protocolf.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
void * blob, * recvd;
|
||||
int blobSize;
|
||||
SSMPRUint32 version, flags, port, connID, keySize, secretKeySize;
|
||||
SSMPRUint32 sessionID, httpPort;
|
||||
SSMPRInt32 result;
|
||||
char *profile, * nonce, * hostIP, * hostName, * cipher, * CA;
|
||||
SSMPRStatus rv;
|
||||
|
||||
|
||||
/*
|
||||
* Test functions to pack and parse HelloRequest message
|
||||
*/
|
||||
version = 3;
|
||||
profile = (char *)SSMPORT_ZAlloc(strlen("profile"));
|
||||
sprintf(profile, "profile");
|
||||
printf("HelloRequest, packing version #%d, profile %s\n",
|
||||
version, profile);
|
||||
blobSize = SSM_PackHelloRequest(&blob, version, profile);
|
||||
if (!blobSize)
|
||||
printf("Error in PackHelloRequest: %d\n", SSMPR_GetError());
|
||||
SSMPORT_Free(profile);
|
||||
version = 0;
|
||||
recvd = (void *)SSMPORT_ZAlloc(blobSize);
|
||||
if (!recvd) printf("Can't allocate %d bytes of memory!\n", blobSize);
|
||||
memcpy(recvd, blob, blobSize);
|
||||
SSMPORT_Free(blob);
|
||||
rv = SSM_ParseHelloRequest(recvd, &version, &profile);
|
||||
if (rv != SSMPR_SUCCESS)
|
||||
printf("Error in ParseHelloRequest: %d\n", SSMPR_GetError());
|
||||
printf("HelloRequest, parsing version #%d, profile %s\n",
|
||||
version, profile);
|
||||
|
||||
|
||||
/*
|
||||
* Test functions to parse and pack HelloReply message
|
||||
*/
|
||||
version = 5;
|
||||
result = 2;
|
||||
sessionID = 34567;
|
||||
httpPort = 87654;
|
||||
nonce = (char *)SSMPORT_ZAlloc(strlen("some secret nonce"));
|
||||
sprintf(nonce, "some secret nonce");
|
||||
printf("HelloReply, packing result %d, sessionID %d, version #%d, httpPort %d,\n nonce %s\n",
|
||||
result, sessionID, version, httpPort, nonce);
|
||||
blobSize = SSM_PackHelloReply(&blob, result, sessionID, version, httpPort,
|
||||
nonce);
|
||||
if (!blobSize)
|
||||
printf("Error in PackHelloReply: %d\n", SSMPR_GetError());
|
||||
memset(nonce, 0, strlen(nonce));
|
||||
SSMPORT_Free(nonce);
|
||||
version = result = sessionID = httpPort = 0;
|
||||
recvd = (void *)SSMPORT_ZAlloc(blobSize);
|
||||
if (!recvd) printf("Can't allocate %d bytes of memory!\n", blobSize);
|
||||
memcpy(recvd, blob, blobSize);
|
||||
SSMPORT_Free(blob);
|
||||
rv = SSM_ParseHelloReply(recvd, &result, &sessionID, &version, &httpPort,
|
||||
&nonce);
|
||||
if (rv != SSMPR_SUCCESS)
|
||||
printf("Error in ParseHelloReply: %d\n", SSMPR_GetError());
|
||||
printf("HelloReply, parsing result %d, sessionID %d, version #%d, httpPort %d, \n nonce %s\n",
|
||||
result, sessionID, version, httpPort, nonce);
|
||||
|
||||
/*
|
||||
* Test functions to parse and pack SSLDataConnectionRequest message
|
||||
*/
|
||||
flags = 0x00044000;
|
||||
port = 34567;
|
||||
hostIP = (char *)SSMPORT_ZAlloc(strlen("somehostIP"));
|
||||
sprintf(hostIP, "somehostIP");
|
||||
hostName = (char *)SSMPORT_ZAlloc(strlen("somehostName"));
|
||||
sprintf(hostName, "somehostName");
|
||||
printf("SSLDataConnRequest, packing flags %x, port %d, hostIP %s, hostName %s\n",
|
||||
flags, port, hostIP, hostName);
|
||||
blobSize = SSM_PackSSLDataConnectionRequest(&blob, flags, port, hostIP,
|
||||
hostName);
|
||||
if (!blobSize)
|
||||
printf("Error in PackSSLDataConnectionRequest: %d\n", SSMPR_GetError());
|
||||
SSMPORT_Free(hostIP);
|
||||
SSMPORT_Free(hostName);
|
||||
flags = port = 0;
|
||||
|
||||
recvd = (void *)SSMPORT_ZAlloc(blobSize);
|
||||
if (!recvd) printf("Can't allocate %d bytes of memory!\n", blobSize);
|
||||
memcpy(recvd, blob, blobSize);
|
||||
SSMPORT_Free(blob);
|
||||
|
||||
rv = SSM_ParseSSLDataConnectionRequest(recvd, &flags, &port, &hostIP,
|
||||
&hostName);
|
||||
if (rv != SSMPR_SUCCESS)
|
||||
printf("Error in ParseSSLDataConnectionRequest: %d\n", SSMPR_GetError());
|
||||
printf(
|
||||
"SSLDataConnRequest, parsing flags %x, port %d, hostIP %s, hostName %s\n",
|
||||
flags, port, hostIP, hostName);
|
||||
SSMPORT_Free(hostIP);
|
||||
SSMPORT_Free(hostName);
|
||||
|
||||
|
||||
/*
|
||||
* Test functions to parse and pack SSLDataConnectionReply message
|
||||
*/
|
||||
result = 2;
|
||||
connID = 713259;
|
||||
port = 57402;
|
||||
printf("SSLDataConnReply, packing result %d, connectionID %d, port %d\n",
|
||||
result, connID, port);
|
||||
blobSize = SSM_PackSSLDataConnectionReply(&blob, result, connID, port);
|
||||
if (!blobSize)
|
||||
printf("Error in PackSSLDataConnReply: %d\n", SSMPR_GetError());
|
||||
result = connID = port = 0;
|
||||
recvd = (void *)SSMPORT_ZAlloc(blobSize);
|
||||
if (!recvd) printf("Can't allocate %d bytes of memory!\n", blobSize);
|
||||
memcpy(recvd, blob, blobSize);
|
||||
SSMPORT_Free(blob);
|
||||
rv = SSM_ParseSSLDataConnectionReply(recvd, &result, &connID, &port);
|
||||
if (rv != SSMPR_SUCCESS)
|
||||
printf("Error in ParseSSLDataConnectionReply: %d\n", SSMPR_GetError());
|
||||
printf("SSLDataConnReply, parsing result %d, connectionID %d, port %d\n",
|
||||
result, connID, port);
|
||||
|
||||
|
||||
/*
|
||||
* Test functions to parse and pack SecurityStatusRequest message
|
||||
*/
|
||||
connID = 45375;
|
||||
printf("SecurityStatusRequest, packing connection ID %d\n", connID);
|
||||
blobSize = SSM_PackSecurityStatusRequest(&blob, connID);
|
||||
if (!blobSize)
|
||||
printf("Error in PackSecurityStatusRequest: %d\n", SSMPR_GetError());
|
||||
connID = 0;
|
||||
recvd = (void *)SSMPORT_ZAlloc(blobSize);
|
||||
if (!recvd) printf("Can't allocate %d bytes of memory!\n", blobSize);
|
||||
memcpy(recvd, blob, blobSize);
|
||||
SSMPORT_Free(blob);
|
||||
rv = SSM_ParseSecurityStatusRequest(recvd, &connID);
|
||||
if (rv != SSMPR_SUCCESS)
|
||||
printf("Error in ParseSecurityStatusRequest: %d\n", SSMPR_GetError());
|
||||
printf("SecurityStatusRequest, parsing connection ID %d\n", connID);
|
||||
|
||||
|
||||
/*
|
||||
* Test functions to parse and pack SecurityStatusReply message
|
||||
*/
|
||||
result = 2;
|
||||
keySize = 256;
|
||||
secretKeySize = 511;
|
||||
cipher = (char *)SSMPORT_ZAlloc(strlen("My Cipher"));
|
||||
sprintf(cipher, "My Cipher");
|
||||
CA = (char *)SSMPORT_ZAlloc(strlen("My CA issuer"));
|
||||
sprintf(CA, "My CA issuer");
|
||||
printf("SecurityStatusReply, packing result %d, keysize %d, secretKeySize %d, cipher %s, CA %s\n", result, keySize, secretKeySize, cipher, CA);
|
||||
blobSize = SSM_PackSecurityStatusReply(&blob, result, keySize, secretKeySize, cipher, CA);
|
||||
if (!blobSize)
|
||||
printf("Error in PackSecurityStatusReply: %d\n", SSMPR_GetError());
|
||||
result = keySize = secretKeySize = 0;
|
||||
SSMPORT_Free(cipher);
|
||||
SSMPORT_Free(CA);
|
||||
recvd = (void *)SSMPORT_ZAlloc(blobSize);
|
||||
if (!recvd) printf("Can't allocate %d bytes of memory!\n", blobSize);
|
||||
memcpy(recvd, blob, blobSize);
|
||||
SSMPORT_Free(blob);
|
||||
rv = SSM_ParseSecurityStatusReply(recvd, &result, &keySize, &secretKeySize,
|
||||
&cipher, &CA);
|
||||
if (rv != SSMPR_SUCCESS)
|
||||
printf("Error in ParseSecurityStatusReply: %d\n", SSMPR_GetError());
|
||||
printf("SecurityStatusReply, parsing result %d, keysize %d, secretKeySize %d, cipher %s, CA %s\n", result, keySize, secretKeySize, cipher, CA);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,130 +0,0 @@
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#include "protocol.h"
|
||||
#include "prmem.h"
|
||||
#include "prnetdb.h"
|
||||
#include <string.h>
|
||||
|
||||
#ifndef NSPR20
|
||||
#include "protocolport.c"
|
||||
#endif
|
||||
|
||||
CMStatus SSM_SSMStringToString(char ** string,
|
||||
int *len,
|
||||
SSMString * ssmString)
|
||||
{
|
||||
char * str = NULL;
|
||||
int realLen;
|
||||
PRStatus rv =PR_SUCCESS;
|
||||
|
||||
if (!ssmString || !string ) {
|
||||
rv = PR_INVALID_ARGUMENT_ERROR;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* in case we fail */
|
||||
*string = NULL;
|
||||
if (len) *len = 0;
|
||||
|
||||
/* Convert from net byte order */
|
||||
realLen = SSMPR_ntohl(ssmString->m_length);
|
||||
|
||||
str = (char *)PR_CALLOC(realLen+1); /* add 1 byte for end 0 */
|
||||
if (!str) {
|
||||
rv = PR_OUT_OF_MEMORY_ERROR;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
memcpy(str, (char *) &(ssmString->m_data), realLen);
|
||||
/* str[realLen]=0; */
|
||||
|
||||
if (len) *len = realLen;
|
||||
*string = str;
|
||||
return rv;
|
||||
|
||||
loser:
|
||||
if (str)
|
||||
PR_Free(str);
|
||||
if (string && *string) {
|
||||
PR_Free(*string);
|
||||
*string = NULL;
|
||||
}
|
||||
if (rv == PR_SUCCESS)
|
||||
rv = PR_FAILURE;
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
CMStatus SSM_StringToSSMString(SSMString ** ssmString, int length,
|
||||
char * string)
|
||||
{
|
||||
SSMPRUint32 len;
|
||||
SSMString *result = NULL;
|
||||
PRStatus rv = PR_SUCCESS;
|
||||
|
||||
if (!string || !ssmString) {
|
||||
rv = PR_INVALID_ARGUMENT_ERROR;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
*ssmString = NULL; /* in case we fail */
|
||||
|
||||
if (length) len = length;
|
||||
else len = strlen(string);
|
||||
if (len <= 0) {
|
||||
rv = PR_INVALID_ARGUMENT_ERROR;
|
||||
goto loser;
|
||||
}
|
||||
result = (SSMString *) PR_CALLOC(sizeof(PRUint32) +
|
||||
SSMSTRING_PADDED_LENGTH(len));
|
||||
if (!result) {
|
||||
rv = PR_OUT_OF_MEMORY_ERROR;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
result->m_length = SSMPR_htonl(len);
|
||||
memcpy((char *) (&(result->m_data)), string, len);
|
||||
|
||||
*ssmString = result;
|
||||
goto done;
|
||||
|
||||
loser:
|
||||
if (result)
|
||||
PR_Free(result);
|
||||
*ssmString = NULL;
|
||||
if (rv == PR_SUCCESS)
|
||||
rv = PR_FAILURE;
|
||||
done:
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -1,165 +0,0 @@
|
||||
/* -*- mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef __SSM_RSRCIDS_H__
|
||||
#define __SSM_RSRCIDS_H__
|
||||
|
||||
#include "ssmdefs.h"
|
||||
|
||||
/*
|
||||
* IMPORTANT:
|
||||
*
|
||||
* To preserve backward compatibility as much as possible, always add new
|
||||
* values to either one of the enumeration tables at the end of the table.
|
||||
*/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SSM_RESTYPE_NULL = 0L,
|
||||
SSM_RESTYPE_RESOURCE,
|
||||
SSM_RESTYPE_CONNECTION,
|
||||
SSM_RESTYPE_CONTROL_CONNECTION,
|
||||
SSM_RESTYPE_DATA_CONNECTION,
|
||||
SSM_RESTYPE_SSL_DATA_CONNECTION,
|
||||
SSM_RESTYPE_PKCS7_DECODE_CONNECTION,
|
||||
SSM_RESTYPE_PKCS7_ENCODE_CONNECTION,
|
||||
SSM_RESTYPE_HASH_CONNECTION,
|
||||
|
||||
SSM_RESTYPE_CERTIFICATE,
|
||||
SSM_RESTYPE_SSL_SOCKET_STATUS,
|
||||
SSM_RESTYPE_PKCS7_CONTENT_INFO,
|
||||
SSM_RESTYPE_KEY_PAIR,
|
||||
SSM_RESTYPE_CRMF_REQUEST,
|
||||
SSM_RESTYPE_KEYGEN_CONTEXT,
|
||||
SSM_RESTYPE_SECADVISOR_CONTEXT,
|
||||
SSM_RESTYPE_SIGNTEXT,
|
||||
SSM_RESTYPE_PKCS12_CONTEXT,
|
||||
SSM_RESTYPE_MAX
|
||||
} SSMResourceType;
|
||||
|
||||
/* Attribute/resource types */
|
||||
|
||||
/* Attribute IDs */
|
||||
typedef enum
|
||||
{
|
||||
SSM_FID_NULL = (CMUint32) 0, /* placeholder */
|
||||
|
||||
/* Connection attributes */
|
||||
SSM_FID_CONN_ALIVE,
|
||||
SSM_FID_CONN_PARENT,
|
||||
|
||||
/* Data connection attributes */
|
||||
SSM_FID_CONN_DATA_PENDING,
|
||||
|
||||
/* SSL data connection attributes */
|
||||
SSM_FID_SSLDATA_SOCKET_STATUS,
|
||||
SSM_FID_SSLDATA_ERROR_VALUE,
|
||||
|
||||
/* PKCS7 decode connection attributes */
|
||||
SSM_FID_P7CONN_CONTENT_INFO,
|
||||
SSM_FID_P7CONN_RETURN_VALUE,
|
||||
SSM_FID_P7CONN_ERROR_VALUE,
|
||||
|
||||
/* Hash connection attributes */
|
||||
SSM_FID_HASHCONN_RESULT,
|
||||
|
||||
/* Certificate attributes */
|
||||
SSM_FID_CERT_SUBJECT_NAME,
|
||||
SSM_FID_CERT_ISSUER_NAME,
|
||||
SSM_FID_CERT_SERIAL_NUMBER,
|
||||
SSM_FID_CERT_EXP_DATE,
|
||||
SSM_FID_CERT_FINGERPRINT,
|
||||
SSM_FID_CERT_COMMON_NAME,
|
||||
SSM_FID_CERT_NICKNAME,
|
||||
SSM_FID_CERT_ORG_NAME,
|
||||
SSM_FID_CERT_HTML_CERT,
|
||||
SSM_FID_CERT_PICKLE_CERT,
|
||||
SSM_FID_CERT_CERTKEY,
|
||||
SSM_FID_CERT_FIND_CERT_ISSUER,
|
||||
SSM_FID_CERT_EMAIL_ADDRESS,
|
||||
SSM_FID_CERT_ISPERM,
|
||||
|
||||
/* SSL socket status attributes */
|
||||
SSM_FID_SSS_KEYSIZE,
|
||||
SSM_FID_SSS_SECRET_KEYSIZE,
|
||||
SSM_FID_SSS_CERT_ID,
|
||||
SSM_FID_SSS_CIPHER_NAME,
|
||||
SSM_FID_SSS_SECURITY_LEVEL,
|
||||
SSM_FID_SSS_HTML_STATUS,
|
||||
|
||||
/* PKCS7 content info attributes */
|
||||
SSM_FID_P7CINFO_IS_SIGNED,
|
||||
SSM_FID_P7CINFO_IS_ENCRYPTED,
|
||||
SSM_FID_P7CINFO_SIGNER_CERT,
|
||||
|
||||
/* CRMF ID's */
|
||||
SSM_FID_CRMFREQ_REGTOKEN,
|
||||
SSM_FID_CRMFREQ_AUTHENTICATOR,
|
||||
SSM_FID_CRMFREQ_EXTENSIONS,
|
||||
SSM_FID_CRMFREQ_KEY_TYPE,
|
||||
SSM_FID_CRMFREQ_DN,
|
||||
|
||||
/* Security advisor context */
|
||||
SSM_FID_SECADVISOR_URL,
|
||||
SSM_FID_SECADVISOR_WIDTH,
|
||||
SSM_FID_SECADVISOR_HEIGHT,
|
||||
|
||||
/* Sign Text */
|
||||
SSM_FID_SIGNTEXT_RESULT,
|
||||
|
||||
/* Key Gen ID's */
|
||||
SSM_FID_KEYGEN_ESCROW_AUTHORITY,
|
||||
|
||||
/* Key Pair ID's */
|
||||
SSM_FID_KEYPAIR_KEY_GEN_TYPE,
|
||||
|
||||
/* Session Attributes */
|
||||
SSM_FID_DEFAULT_EMAIL_RECIPIENT_CERT,
|
||||
SSM_FID_DEFAULT_EMAIL_SIGNER_CERT,
|
||||
|
||||
/* Client Context Attribute */
|
||||
SSM_FID_CLIENT_CONTEXT,
|
||||
|
||||
/* Resource Error */
|
||||
SSM_FID_RESOURCE_ERROR,
|
||||
|
||||
SSM_FID_KEYGEN_SLOT_NAME,
|
||||
SSM_FID_DISABLE_ESCROW_WARN,
|
||||
SSM_FID_KEYGEN_TOKEN_NAME,
|
||||
|
||||
SSM_FID_SSLDATA_DISCARD_SOCKET_STATUS,
|
||||
|
||||
SSM_FID_MAX /* placeholder */
|
||||
} SSMAttributeID;
|
||||
|
||||
#endif
|
||||
@@ -1,324 +0,0 @@
|
||||
/* -*- mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
#ifndef __SSMDEFS_H__
|
||||
#define __SSMDEFS_H__
|
||||
|
||||
/* Basic type definitions for both client and server. */
|
||||
typedef long CMInt32;
|
||||
typedef unsigned long CMUint32;
|
||||
typedef long SSMResourceID;
|
||||
|
||||
typedef int SSMStatus;
|
||||
|
||||
#define PSM_PORT 11111
|
||||
#define PSM_DATA_PORT 11113 /* needs to be removed */
|
||||
|
||||
typedef enum _CMTStatus {
|
||||
CMTFailure = -1,
|
||||
CMTSuccess = 0
|
||||
} CMTStatus;
|
||||
|
||||
typedef enum {
|
||||
CM_FALSE = 0,
|
||||
CM_TRUE = 1
|
||||
} CMBool;
|
||||
|
||||
typedef struct CMTItemStr {
|
||||
CMUint32 type;
|
||||
unsigned char *data;
|
||||
unsigned int len;
|
||||
} CMTItem;
|
||||
|
||||
/* A length-encoded string. */
|
||||
struct _SSMString {
|
||||
CMUint32 m_length;
|
||||
char m_data;
|
||||
};
|
||||
typedef struct _SSMString SSMString;
|
||||
|
||||
#define SSM_PROTOCOL_VERSION 0x00000051
|
||||
|
||||
#define SSM_INVALID_RESOURCE 0x00000000
|
||||
#define SSM_GLOBAL_RESOURCE 0x00000001
|
||||
#define SSM_SESSION_RESOURCE 0x00000002
|
||||
|
||||
/* Message category flags */
|
||||
#define SSM_REQUEST_MESSAGE 0x10000000
|
||||
#define SSM_REPLY_OK_MESSAGE 0x20000000
|
||||
#define SSM_REPLY_ERR_MESSAGE 0x30000000
|
||||
#define SSM_EVENT_MESSAGE 0x40000000
|
||||
|
||||
/* Message types */
|
||||
#define SSM_DATA_CONNECTION 0x00001000
|
||||
#define SSM_OBJECT_SIGNING 0x00002000
|
||||
#define SSM_RESOURCE_ACTION 0x00003000
|
||||
#define SSM_CERT_ACTION 0x00004000
|
||||
#define SSM_PKCS11_ACTION 0x00005000
|
||||
#define SSM_CRMF_ACTION 0x00006000
|
||||
#define SSM_FORMSIGN_ACTION 0x00007000
|
||||
#define SSM_LOCALIZED_TEXT 0x00008000
|
||||
#define SSM_HELLO_MESSAGE 0x00009000
|
||||
#define SSM_SECURITY_ADVISOR 0x0000a000
|
||||
#define SSM_SEC_CFG_ACTION 0x0000b000
|
||||
#define SSM_KEYGEN_TAG 0x0000c000
|
||||
#define SSM_PREF_ACTION 0x0000d000
|
||||
#define SSM_MISC_ACTION 0x0000f000
|
||||
|
||||
/* Data connection messages subtypes */
|
||||
#define SSM_SSL_CONNECTION 0x00000100
|
||||
#define SSM_PKCS7DECODE_STREAM 0x00000200
|
||||
#define SSM_PKCS7ENCODE_STREAM 0x00000300
|
||||
#define SSM_HASH_STREAM 0x00000400
|
||||
#define SSM_TLS_CONNECTION 0x00000500
|
||||
#define SSM_PROXY_CONNECTION 0x00000600
|
||||
|
||||
/* Object signing message subtypes */
|
||||
#define SSM_VERIFY_RAW_SIG 0x00000100
|
||||
#define SSM_VERIFY_DETACHED_SIG 0x00000200
|
||||
#define SSM_CREATE_SIGNED 0x00000300
|
||||
#define SSM_CREATE_ENCRYPTED 0x00000400
|
||||
|
||||
/* Resource access messages subtypes */
|
||||
#define SSM_CREATE_RESOURCE 0x00000100
|
||||
#define SSM_DESTROY_RESOURCE 0x00000200
|
||||
#define SSM_GET_ATTRIBUTE 0x00000300
|
||||
#define SSM_CONSERVE_RESOURCE 0x00000400
|
||||
#define SSM_DUPLICATE_RESOURCE 0x00000500
|
||||
#define SSM_SET_ATTRIBUTE 0x00000600
|
||||
#define SSM_TLS_STEPUP 0x00000700
|
||||
#define SSM_PROXY_STEPUP 0x00000800
|
||||
|
||||
/* Further specification for resource access messages */
|
||||
#define SSM_SSLSocket_Status 0x00000010
|
||||
|
||||
#define SSM_NO_ATTRIBUTE 0x00000000
|
||||
#define SSM_NUMERIC_ATTRIBUTE 0x00000010
|
||||
#define SSM_STRING_ATTRIBUTE 0x00000020
|
||||
#define SSM_RID_ATTRIBUTE 0x00000030
|
||||
|
||||
#define SSM_PICKLE_RESOURCE 0x00000010
|
||||
#define SSM_UNPICKLE_RESOURCE 0x00000020
|
||||
#define SSM_PICKLE_SECURITY_STATUS 0x00000030
|
||||
|
||||
/* Certificate access message subtypes */
|
||||
#define SSM_IMPORT_CERT 0x00000100
|
||||
#define SSM_VERIFY_CERT 0x00000200
|
||||
#define SSM_FIND_BY_NICKNAME 0x00000300
|
||||
#define SSM_FIND_BY_KEY 0x00000400
|
||||
#define SSM_FIND_BY_EMAILADDR 0x00000500
|
||||
#define SSM_ADD_TO_DB 0x00000600
|
||||
#define SSM_DECODE_CERT 0x00000700
|
||||
#define SSM_MATCH_USER_CERT 0x00000800
|
||||
#define SSM_DESTROY_CERT 0x00000900
|
||||
#define SSM_DECODE_TEMP_CERT 0x00000a00
|
||||
#define SSM_REDIRECT_COMPARE 0x00000b00
|
||||
#define SSM_DECODE_CRL 0x00000c00
|
||||
#define SSM_EXTENSION_VALUE 0x00000d00
|
||||
#define SSM_HTML_INFO 0x00000e00
|
||||
|
||||
/* message subtypes used for KEYGEN form tag */
|
||||
#define SSM_GET_KEY_CHOICE 0x00000100
|
||||
#define SSM_KEYGEN_START 0x00000200
|
||||
#define SSM_KEYGEN_TOKEN 0x00000300
|
||||
#define SSM_KEYGEN_PASSWORD 0x00000400
|
||||
#define SSM_KEYGEN_DONE 0x00000500
|
||||
|
||||
#define SSM_CREATE_KEY_PAIR 0x00000100
|
||||
#define SSM_FINISH_KEY_GEN 0x00000200
|
||||
#define SSM_ADD_NEW_MODULE 0x00000300
|
||||
#define SSM_DEL_MODULE 0x00000400
|
||||
#define SSM_LOGOUT_ALL 0x00000500
|
||||
#define SSM_ENABLED_CIPHERS 0x00000600
|
||||
|
||||
#define SSM_CREATE_CRMF_REQ 0x00000100
|
||||
#define SSM_DER_ENCODE_REQ 0x00000200
|
||||
#define SSM_PROCESS_CMMF_RESP 0x00000300
|
||||
#define SSM_CHALLENGE 0x00000400
|
||||
|
||||
#define SSM_SIGN_TEXT 0x00000100
|
||||
|
||||
/* Security Config subtypes */
|
||||
#define SSM_ADD_CERT_TO_TEMP_DB 0x00000100
|
||||
#define SSM_ADD_TEMP_CERT_TO_DB 0x00000200
|
||||
#define SSM_DELETE_PERM_CERTS 0x00000300
|
||||
#define SSM_FIND_CERT_KEY 0x00000400
|
||||
#define SSM_GET_CERT_PROP_BY_KEY 0x00000500
|
||||
#define SSM_CERT_INDEX_ENUM 0x00000600
|
||||
|
||||
/* subcategories for SSM_FIND_CERT_KEY and SSM_CERT_INDEX_ENUM */
|
||||
#define SSM_FIND_KEY_BY_NICKNAME 0x00000010
|
||||
#define SSM_FIND_KEY_BY_EMAIL_ADDR 0x00000020
|
||||
#define SSM_FIND_KEY_BY_DN 0x00000030
|
||||
|
||||
/* subcategories for SSM_GET_CERT_PROP_BY_KEY */
|
||||
#define SSM_SECCFG_GET_NICKNAME 0x00000010
|
||||
#define SSM_SECCFG_GET_EMAIL_ADDR 0x00000020
|
||||
#define SSM_SECCFG_GET_DN 0x00000030
|
||||
#define SSM_SECCFG_GET_TRUST 0x00000040
|
||||
#define SSM_SECCFG_CERT_IS_PERM 0x00000050
|
||||
#define SSM_SECCFG_GET_NOT_BEFORE 0x00000060
|
||||
#define SSM_SECCFG_GET_NOT_AFTER 0x00000070
|
||||
#define SSM_SECCFG_GET_SERIAL_NO 0x00000080
|
||||
#define SSM_SECCFG_GET_ISSUER 0x00000090
|
||||
#define SSM_SECCFG_GET_ISSUER_KEY 0x000000a0
|
||||
#define SSM_SECCFG_GET_SUBJECT_NEXT 0x000000b0
|
||||
#define SSM_SECCFG_GET_SUBJECT_PREV 0x000000c0
|
||||
|
||||
/* Misc requests */
|
||||
#define SSM_MISC_GET_RNG_DATA 0x00000100
|
||||
#define SSM_MISC_PUT_RNG_DATA 0x00000200
|
||||
#define SSM_MISC_SDR_ENCRYPT 0x00000300
|
||||
#define SSM_MISC_SDR_DECRYPT 0x00000400
|
||||
#define SSM_MISC_UI 0x00000500
|
||||
|
||||
/* specific UI requests */
|
||||
#define SSM_UI_CHANGE_PASSWORD 0x00000010
|
||||
|
||||
#define SSM_SDR_ENCRYPT_REQUEST \
|
||||
(SSM_REQUEST_MESSAGE|SSM_MISC_ACTION|SSM_MISC_SDR_ENCRYPT)
|
||||
#define SSM_SDR_ENCRYPT_REPLY \
|
||||
(SSM_REPLY_OK_MESSAGE|SSM_MISC_ACTION|SSM_MISC_SDR_ENCRYPT)
|
||||
#define SSM_SDR_DECRYPT_REQUEST \
|
||||
(SSM_REQUEST_MESSAGE|SSM_MISC_ACTION|SSM_MISC_SDR_DECRYPT)
|
||||
#define SSM_SDR_DECRYPT_REPLY \
|
||||
(SSM_REPLY_OK_MESSAGE|SSM_MISC_ACTION|SSM_MISC_SDR_DECRYPT)
|
||||
|
||||
/* Type masks for message types */
|
||||
#define SSM_CATEGORY_MASK 0xF0000000
|
||||
#define SSM_TYPE_MASK 0x0000F000
|
||||
#define SSM_SUBTYPE_MASK 0x00000F00
|
||||
#define SSM_SPECIFIC_MASK 0x000000F0
|
||||
|
||||
typedef struct SSMAttributeValue {
|
||||
CMUint32 type;
|
||||
union {
|
||||
SSMResourceID rid;
|
||||
CMTItem string;
|
||||
CMInt32 numeric;
|
||||
} u;
|
||||
} SSMAttributeValue;
|
||||
|
||||
typedef enum {
|
||||
rsaEnc, rsaDualUse, rsaSign, rsaNonrepudiation, rsaSignNonrepudiation,
|
||||
dhEx, dsaSignNonrepudiation, dsaSign, dsaNonrepudiation, invalidKeyGen
|
||||
} SSMKeyGenType;
|
||||
|
||||
typedef enum {
|
||||
ssmUnknownPolicy= -1,ssmDomestic=0, ssmExport=1, ssmFrance=2
|
||||
} SSMPolicyType;
|
||||
|
||||
/* These are the localized strings that PSM can feed back to
|
||||
* the plug-in. These will initially be used by the plug-in for
|
||||
* JavaScript purposes to pop up alert/confirm dialogs that would
|
||||
* cause nightmares to do if we sent UI events.
|
||||
*/
|
||||
typedef enum {
|
||||
SSM_STRING_BAD_PK11_LIB_PARAM,
|
||||
SSM_STRING_BAD_PK11_LIB_PATH,
|
||||
SSM_STRING_ADD_MOD_SUCCESS,
|
||||
SSM_STRING_DUP_MOD_FAILURE,
|
||||
SSM_STRING_ADD_MOD_FAILURE,
|
||||
SSM_STRING_BAD_MOD_NAME,
|
||||
SSM_STRING_EXT_MOD_DEL,
|
||||
SSM_STRING_INT_MOD_DEL,
|
||||
SSM_STRING_MOD_DEL_FAIL,
|
||||
SSM_STRING_ADD_MOD_WARN,
|
||||
SSM_STRING_MOD_PROMPT,
|
||||
SSM_STRING_DLL_PROMPT,
|
||||
SSM_STRING_DEL_MOD_WARN,
|
||||
SSM_STRING_INVALID_CRL,
|
||||
SSM_STRING_INVALID_CKL,
|
||||
SSM_STRING_ROOT_CKL_CERT_NOT_FOUND,
|
||||
SSM_STRING_BAD_CRL_SIGNATURE,
|
||||
SSM_STRING_BAD_CKL_SIGNATURE,
|
||||
SSM_STRING_ERR_ADD_CRL,
|
||||
SSM_STRING_ERR_ADD_CKL,
|
||||
SSM_STRING_JAVASCRIPT_DISABLED
|
||||
} SSMLocalizedString;
|
||||
|
||||
/* Event types */
|
||||
#define SSM_UI_EVENT 0x00001000
|
||||
#define SSM_TASK_COMPLETED_EVENT 0x00002000
|
||||
#define SSM_FILE_PATH_EVENT 0x00003000
|
||||
#define SSM_PROMPT_EVENT 0x00004000
|
||||
#define SSM_AUTH_EVENT 0x00007000
|
||||
#define SSM_SAVE_PREF_EVENT 0x00008000
|
||||
#define SSM_MISC_EVENT 0x0000f000
|
||||
|
||||
/* Flags used in Create SSL Data request */
|
||||
#define SSM_REQUEST_SSL_DATA_SSL 0x00000001
|
||||
#define SSM_REQUEST_SSL_DATA_PROXY 0x00000002
|
||||
#define SSM_REQUEST_SSL_CONNECTION_MASK 0x00000003
|
||||
|
||||
/* Create typedefs for the various #defines */
|
||||
typedef CMUint32 SSMMessageCategory;
|
||||
typedef CMUint32 SSMMessageType;
|
||||
typedef CMUint32 SSMDataConnectionSType;
|
||||
typedef CMUint32 SSMObjSignSType;
|
||||
typedef CMUint32 SSMResourceAccessSType;
|
||||
typedef CMUint32 SSMCreateResource;
|
||||
typedef CMUint32 SSMResourceAttrType;
|
||||
typedef CMUint32 SSMResourceConsv;
|
||||
typedef CMUint32 SSMCertAccessSType;
|
||||
typedef CMUint32 SSMKeyGenTagProcessType;
|
||||
typedef CMUint32 SSMPKCS11Actions;
|
||||
typedef CMUint32 SSMCRMFAction;
|
||||
typedef CMUint32 SSMFormSignAction;
|
||||
typedef CMUint32 SSMSecCfgAction;
|
||||
typedef CMUint32 SSMSecCfgFindByType;
|
||||
typedef CMUint32 SSMSecCfgGetCertPropType;
|
||||
typedef CMUint32 SSMMiscRequestType;
|
||||
typedef CMUint32 SSMMessageMaskType;
|
||||
typedef CMUint32 SSMEventType;
|
||||
typedef CMUint32 SSMSSLConnectionRequestType;
|
||||
|
||||
/*
|
||||
* This string is version that can be used to assemble any
|
||||
* version information by the apllication using the protocol
|
||||
* library.
|
||||
*/
|
||||
extern char SSMVersionString[];
|
||||
|
||||
/* What type of client */
|
||||
typedef enum
|
||||
{
|
||||
SSM_NOINFO,
|
||||
SSM_COMPOSE,
|
||||
SSM_MAIL_MESSAGE,
|
||||
SSM_NEWS_MESSAGE,
|
||||
SSM_SNEWS_MESSAGE,
|
||||
SSM_BROWSER
|
||||
} SSMClientType;
|
||||
|
||||
#endif /* __SSMDEFS_H__ */
|
||||
@@ -1,628 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape security libraries.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
#include "stddef.h"
|
||||
#include "messages.h"
|
||||
|
||||
CMTMessageTemplate SingleNumMessageTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(SingleNumMessage, value) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate SingleStringMessageTemplate[] =
|
||||
{
|
||||
{ CMT_DT_STRING, offsetof(SingleStringMessage, string) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate SingleItemMessageTemplate[] =
|
||||
{
|
||||
{ CMT_DT_ITEM, offsetof(SingleItemMessage, item) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate HelloRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(HelloRequest, version) },
|
||||
{ CMT_DT_INT, offsetof(HelloRequest, policy) },
|
||||
{ CMT_DT_BOOL, offsetof(HelloRequest, doesUI) },
|
||||
{ CMT_DT_STRING, offsetof(HelloRequest, profile) },
|
||||
{ CMT_DT_STRING, offsetof(HelloRequest, profileDir) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate HelloReplyTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(HelloReply, result) },
|
||||
{ CMT_DT_INT, offsetof(HelloReply, sessionID) },
|
||||
{ CMT_DT_INT, offsetof(HelloReply, version) },
|
||||
{ CMT_DT_STRING, offsetof(HelloReply, stringVersion) },
|
||||
{ CMT_DT_INT, offsetof(HelloReply, httpPort) },
|
||||
{ CMT_DT_INT, offsetof(HelloReply, policy) },
|
||||
{ CMT_DT_ITEM, offsetof(HelloReply, nonce) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate SSLDataConnectionRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(SSLDataConnectionRequest, flags) },
|
||||
{ CMT_DT_INT, offsetof(SSLDataConnectionRequest, port) },
|
||||
{ CMT_DT_STRING, offsetof(SSLDataConnectionRequest, hostIP) },
|
||||
{ CMT_DT_STRING, offsetof(SSLDataConnectionRequest, hostName) },
|
||||
{ CMT_DT_BOOL, offsetof(SSLDataConnectionRequest, forceHandshake) },
|
||||
{ CMT_DT_ITEM, offsetof(SSLDataConnectionRequest, clientContext) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate TLSDataConnectionRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(TLSDataConnectionRequest, port) },
|
||||
{ CMT_DT_STRING, offsetof(TLSDataConnectionRequest, hostIP) },
|
||||
{ CMT_DT_STRING, offsetof(TLSDataConnectionRequest, hostName) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate TLSStepUpRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(TLSStepUpRequest, connID) },
|
||||
{ CMT_DT_ITEM, offsetof(TLSStepUpRequest, clientContext) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate ProxyStepUpRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(ProxyStepUpRequest, connID) },
|
||||
{ CMT_DT_ITEM, offsetof(ProxyStepUpRequest, clientContext) },
|
||||
{ CMT_DT_STRING, offsetof(ProxyStepUpRequest, url) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate PKCS7DataConnectionRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(PKCS7DataConnectionRequest, resID) },
|
||||
{ CMT_DT_ITEM, offsetof(PKCS7DataConnectionRequest, clientContext) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate DataConnectionReplyTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(DataConnectionReply, result) },
|
||||
{ CMT_DT_INT, offsetof(DataConnectionReply, connID) },
|
||||
{ CMT_DT_INT, offsetof(DataConnectionReply, port) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate UIEventTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(UIEvent, resourceID) },
|
||||
{ CMT_DT_INT, offsetof(UIEvent, width) },
|
||||
{ CMT_DT_INT, offsetof(UIEvent, height) },
|
||||
{ CMT_DT_BOOL, offsetof(UIEvent, isModal) },
|
||||
{ CMT_DT_STRING, offsetof(UIEvent, url) },
|
||||
{ CMT_DT_ITEM, offsetof(UIEvent, clientContext) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
/*
|
||||
* The old UI Event was missing the modal indication.
|
||||
* As a transition aid, we use the old template if the
|
||||
* "modern" version doesn't work. Model is true in that case
|
||||
*/
|
||||
CMTMessageTemplate OldUIEventTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(UIEvent, resourceID) },
|
||||
{ CMT_DT_INT, offsetof(UIEvent, width) },
|
||||
{ CMT_DT_INT, offsetof(UIEvent, height) },
|
||||
{ CMT_DT_STRING, offsetof(UIEvent, url) },
|
||||
{ CMT_DT_ITEM, offsetof(UIEvent, clientContext) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate TaskCompletedEventTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(TaskCompletedEvent, resourceID) },
|
||||
{ CMT_DT_INT, offsetof(TaskCompletedEvent, numTasks) },
|
||||
{ CMT_DT_INT, offsetof(TaskCompletedEvent, result) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate VerifyDetachedSigRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(VerifyDetachedSigRequest, pkcs7ContentID) },
|
||||
{ CMT_DT_INT, offsetof(VerifyDetachedSigRequest, certUsage) },
|
||||
{ CMT_DT_INT, offsetof(VerifyDetachedSigRequest, hashAlgID) },
|
||||
{ CMT_DT_BOOL, offsetof(VerifyDetachedSigRequest, keepCert) },
|
||||
{ CMT_DT_ITEM, offsetof(VerifyDetachedSigRequest, hash) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate CreateSignedRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(CreateSignedRequest, scertRID) },
|
||||
{ CMT_DT_INT, offsetof(CreateSignedRequest, ecertRID) },
|
||||
{ CMT_DT_INT, offsetof(CreateSignedRequest, dig_alg) },
|
||||
{ CMT_DT_ITEM, offsetof(CreateSignedRequest, digest) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate CreateContentInfoReplyTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(CreateContentInfoReply, ciRID) },
|
||||
{ CMT_DT_INT, offsetof(CreateContentInfoReply, result) },
|
||||
{ CMT_DT_INT, offsetof(CreateContentInfoReply, errorCode) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate CreateEncryptedRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(CreateEncryptedRequest, scertRID) },
|
||||
{ CMT_DT_LIST, offsetof(CreateEncryptedRequest, nrcerts) },
|
||||
{ CMT_DT_INT, offsetof(CreateEncryptedRequest, rcertRIDs) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate CreateResourceRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(CreateResourceRequest, type) },
|
||||
{ CMT_DT_ITEM, offsetof(CreateResourceRequest, params) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate CreateResourceReplyTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(CreateResourceReply, result) },
|
||||
{ CMT_DT_INT, offsetof(CreateResourceReply, resID) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate GetAttribRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(GetAttribRequest, resID) },
|
||||
{ CMT_DT_INT, offsetof(GetAttribRequest, fieldID) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate GetAttribReplyTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(GetAttribReply, result) },
|
||||
{ CMT_DT_CHOICE, offsetof(GetAttribReply, value.type) },
|
||||
{ CMT_DT_RID, offsetof(GetAttribReply, value.u.rid), 0, SSM_RID_ATTRIBUTE },
|
||||
{ CMT_DT_INT, offsetof(GetAttribReply, value.u.numeric), 0,
|
||||
SSM_NUMERIC_ATTRIBUTE },
|
||||
{ CMT_DT_ITEM, offsetof(GetAttribReply, value.u.string), 0,
|
||||
SSM_STRING_ATTRIBUTE},
|
||||
{ CMT_DT_END_CHOICE },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate SetAttribRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(SetAttribRequest, resID) },
|
||||
{ CMT_DT_INT, offsetof(SetAttribRequest, fieldID) },
|
||||
{ CMT_DT_CHOICE, offsetof(SetAttribRequest, value.type) },
|
||||
{ CMT_DT_RID, offsetof(SetAttribRequest, value.u.rid), 0, SSM_RID_ATTRIBUTE },
|
||||
{ CMT_DT_INT, offsetof(SetAttribRequest, value.u.numeric), 0,
|
||||
SSM_NUMERIC_ATTRIBUTE },
|
||||
{ CMT_DT_ITEM, offsetof(SetAttribRequest, value.u.string), 0,
|
||||
SSM_STRING_ATTRIBUTE},
|
||||
{ CMT_DT_END_CHOICE },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate PickleResourceReplyTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(PickleResourceReply, result) },
|
||||
{ CMT_DT_ITEM, offsetof(PickleResourceReply, blob) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate UnpickleResourceRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(UnpickleResourceRequest, resourceType) },
|
||||
{ CMT_DT_ITEM, offsetof(UnpickleResourceRequest, resourceData) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate UnpickleResourceReplyTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(UnpickleResourceReply, result) },
|
||||
{ CMT_DT_INT, offsetof(UnpickleResourceReply, resID) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate PickleSecurityStatusReplyTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(PickleSecurityStatusReply, result) },
|
||||
{ CMT_DT_INT, offsetof(PickleSecurityStatusReply, securityLevel) },
|
||||
{ CMT_DT_ITEM, offsetof(PickleSecurityStatusReply, blob) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate DupResourceReplyTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(DupResourceReply, result) },
|
||||
{ CMT_DT_RID, offsetof(DupResourceReply, resID), 0, SSM_RID_ATTRIBUTE },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate DestroyResourceRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(DestroyResourceRequest, resID) },
|
||||
{ CMT_DT_INT, offsetof(DestroyResourceRequest, resType) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate VerifyCertRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(VerifyCertRequest, resID) },
|
||||
{ CMT_DT_INT, offsetof(VerifyCertRequest, certUsage) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate AddTempCertToDBRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(AddTempCertToDBRequest, resID) },
|
||||
{ CMT_DT_STRING, offsetof(AddTempCertToDBRequest, nickname) },
|
||||
{ CMT_DT_INT, offsetof(AddTempCertToDBRequest, sslFlags) },
|
||||
{ CMT_DT_INT, offsetof(AddTempCertToDBRequest, emailFlags) },
|
||||
{ CMT_DT_INT, offsetof(AddTempCertToDBRequest, objSignFlags) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate MatchUserCertRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(MatchUserCertRequest, certType) },
|
||||
{ CMT_DT_LIST, offsetof(MatchUserCertRequest, numCANames) },
|
||||
{ CMT_DT_STRING, offsetof(MatchUserCertRequest, caNames) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate MatchUserCertReplyTemplate[] =
|
||||
{
|
||||
{ CMT_DT_LIST, offsetof(MatchUserCertReply, numCerts) },
|
||||
{ CMT_DT_INT, offsetof(MatchUserCertReply, certs) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate EncodeCRMFReqRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_LIST, offsetof(EncodeCRMFReqRequest, numRequests) },
|
||||
{ CMT_DT_INT, offsetof(EncodeCRMFReqRequest, reqIDs) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate CMMFCertResponseRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_STRING, offsetof(CMMFCertResponseRequest, nickname) },
|
||||
{ CMT_DT_STRING, offsetof(CMMFCertResponseRequest, base64Der) },
|
||||
{ CMT_DT_INT, offsetof(CMMFCertResponseRequest, doBackup) },
|
||||
{ CMT_DT_ITEM, offsetof(CMMFCertResponseRequest, clientContext) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate PasswordRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(PasswordRequest, tokenKey) },
|
||||
{ CMT_DT_STRING, offsetof(PasswordRequest, prompt) },
|
||||
{ CMT_DT_ITEM, offsetof(PasswordRequest, clientContext) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate PasswordReplyTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(PasswordReply, result) },
|
||||
{ CMT_DT_INT, offsetof(PasswordReply, tokenID) },
|
||||
{ CMT_DT_STRING, offsetof(PasswordReply, passwd) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate KeyPairGenRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(KeyPairGenRequest, keyGenCtxtID) },
|
||||
{ CMT_DT_INT, offsetof(KeyPairGenRequest, genMechanism) },
|
||||
{ CMT_DT_INT, offsetof(KeyPairGenRequest, keySize) },
|
||||
{ CMT_DT_ITEM, offsetof(KeyPairGenRequest, params) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate DecodeAndCreateTempCertRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(DecodeAndCreateTempCertRequest, type) },
|
||||
{ CMT_DT_ITEM, offsetof(DecodeAndCreateTempCertRequest, cert) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate GenKeyOldStyleRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_STRING, offsetof(GenKeyOldStyleRequest, choiceString) },
|
||||
{ CMT_DT_STRING, offsetof(GenKeyOldStyleRequest, challenge) },
|
||||
{ CMT_DT_STRING, offsetof(GenKeyOldStyleRequest, typeString) },
|
||||
{ CMT_DT_STRING, offsetof(GenKeyOldStyleRequest, pqgString) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate GenKeyOldStyleTokenRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(GenKeyOldStyleTokenRequest, rid) },
|
||||
{ CMT_DT_LIST, offsetof(GenKeyOldStyleTokenRequest, numtokens) },
|
||||
{ CMT_DT_STRING,offsetof(GenKeyOldStyleTokenRequest, tokenNames)},
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate GenKeyOldStyleTokenReplyTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(GenKeyOldStyleTokenReply, rid) },
|
||||
{ CMT_DT_BOOL, offsetof(GenKeyOldStyleTokenReply, cancel) },
|
||||
{ CMT_DT_STRING, offsetof(GenKeyOldStyleTokenReply, tokenName) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate GenKeyOldStylePasswordRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(GenKeyOldStylePasswordRequest, rid) },
|
||||
{ CMT_DT_STRING, offsetof(GenKeyOldStylePasswordRequest, tokenName) },
|
||||
{ CMT_DT_BOOL, offsetof(GenKeyOldStylePasswordRequest, internal) },
|
||||
{ CMT_DT_INT, offsetof(GenKeyOldStylePasswordRequest, minpwdlen) },
|
||||
{ CMT_DT_INT, offsetof(GenKeyOldStylePasswordRequest, maxpwdlen) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate GenKeyOldStylePasswordReplyTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(GenKeyOldStylePasswordReply, rid) },
|
||||
{ CMT_DT_BOOL, offsetof(GenKeyOldStylePasswordReply, cancel) },
|
||||
{ CMT_DT_STRING, offsetof(GenKeyOldStylePasswordReply, password) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
|
||||
CMTMessageTemplate GetKeyChoiceListRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_STRING, offsetof(GetKeyChoiceListRequest, type) },
|
||||
{ CMT_DT_STRING, offsetof(GetKeyChoiceListRequest, pqgString) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate GetKeyChoiceListReplyTemplate[] =
|
||||
{
|
||||
{ CMT_DT_LIST, offsetof(GetKeyChoiceListReply, nchoices) },
|
||||
{ CMT_DT_STRING, offsetof(GetKeyChoiceListReply, choices) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate AddNewSecurityModuleRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_STRING, offsetof(AddNewSecurityModuleRequest, moduleName) },
|
||||
{ CMT_DT_STRING, offsetof(AddNewSecurityModuleRequest, libraryPath) },
|
||||
{ CMT_DT_INT, offsetof(AddNewSecurityModuleRequest, pubMechFlags) },
|
||||
{ CMT_DT_INT, offsetof(AddNewSecurityModuleRequest, pubCipherFlags) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate FilePathRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(FilePathRequest, resID) },
|
||||
{ CMT_DT_STRING, offsetof(FilePathRequest, prompt) },
|
||||
{ CMT_DT_BOOL, offsetof(FilePathRequest, getExistingFile) },
|
||||
{ CMT_DT_STRING, offsetof(FilePathRequest, fileRegEx) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate FilePathReplyTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(FilePathReply, resID) },
|
||||
{ CMT_DT_STRING, offsetof(FilePathReply, filePath) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate PasswordPromptReplyTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(PasswordPromptReply, resID) },
|
||||
{ CMT_DT_STRING, offsetof(PasswordPromptReply, promptReply) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate SignTextRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(SignTextRequest, resID) },
|
||||
{ CMT_DT_STRING, offsetof(SignTextRequest, stringToSign) },
|
||||
{ CMT_DT_STRING, offsetof(SignTextRequest, hostName) },
|
||||
{ CMT_DT_STRING, offsetof(SignTextRequest, caOption) },
|
||||
{ CMT_DT_LIST, offsetof(SignTextRequest, numCAs) },
|
||||
{ CMT_DT_STRING, offsetof(SignTextRequest, caNames) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate GetLocalizedTextReplyTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(GetLocalizedTextReply, whichString) },
|
||||
{ CMT_DT_STRING, offsetof(GetLocalizedTextReply, localizedString) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate ImportCertReplyTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(ImportCertReply, result) },
|
||||
{ CMT_DT_INT, offsetof(ImportCertReply, resID) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate PromptRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(PromptRequest, resID) },
|
||||
{ CMT_DT_STRING, offsetof(PromptRequest, prompt) },
|
||||
{ CMT_DT_ITEM, offsetof(PromptRequest, clientContext) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate PromptReplyTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(PromptReply, resID) },
|
||||
{ CMT_DT_BOOL, offsetof(PromptReply, cancel) },
|
||||
{ CMT_DT_STRING, offsetof(PromptReply, promptReply) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate RedirectCompareRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_ITEM, offsetof(RedirectCompareRequest, socketStatus1Data) },
|
||||
{ CMT_DT_ITEM, offsetof(RedirectCompareRequest, socketStatus2Data) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate DecodeAndAddCRLRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_ITEM, offsetof(DecodeAndAddCRLRequest, derCrl) },
|
||||
{ CMT_DT_INT, offsetof(DecodeAndAddCRLRequest, type) },
|
||||
{ CMT_DT_STRING, offsetof(DecodeAndAddCRLRequest, url) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate SecurityAdvisorRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(SecurityAdvisorRequest, infoContext) },
|
||||
{ CMT_DT_INT, offsetof(SecurityAdvisorRequest, resID) },
|
||||
{ CMT_DT_STRING, offsetof(SecurityAdvisorRequest, hostname) },
|
||||
{ CMT_DT_STRING, offsetof(SecurityAdvisorRequest, senderAddr) },
|
||||
{ CMT_DT_INT, offsetof(SecurityAdvisorRequest, encryptedP7CInfo) },
|
||||
{ CMT_DT_INT, offsetof(SecurityAdvisorRequest, signedP7CInfo) },
|
||||
{ CMT_DT_INT, offsetof(SecurityAdvisorRequest, decodeError) },
|
||||
{ CMT_DT_INT, offsetof(SecurityAdvisorRequest, verifyError) },
|
||||
{ CMT_DT_BOOL, offsetof(SecurityAdvisorRequest, encryptthis) },
|
||||
{ CMT_DT_BOOL, offsetof(SecurityAdvisorRequest, signthis) },
|
||||
{ CMT_DT_LIST, offsetof(SecurityAdvisorRequest, numRecipients) },
|
||||
{ CMT_DT_STRING, offsetof(SecurityAdvisorRequest, recipients) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate SCAddTempCertToPermDBRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_ITEM, offsetof(SCAddTempCertToPermDBRequest, certKey) },
|
||||
{ CMT_DT_STRING, offsetof(SCAddTempCertToPermDBRequest, trustStr) },
|
||||
{ CMT_DT_STRING, offsetof(SCAddTempCertToPermDBRequest, nickname) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate SCDeletePermCertsRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_ITEM, offsetof(SCDeletePermCertsRequest, certKey) },
|
||||
{ CMT_DT_BOOL, offsetof(SCDeletePermCertsRequest, deleteAll) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate TimeMessageTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(TimeMessage, year) },
|
||||
{ CMT_DT_INT, offsetof(TimeMessage, month) },
|
||||
{ CMT_DT_INT, offsetof(TimeMessage, day) },
|
||||
{ CMT_DT_INT, offsetof(TimeMessage, hour) },
|
||||
{ CMT_DT_INT, offsetof(TimeMessage, minute) },
|
||||
{ CMT_DT_INT, offsetof(TimeMessage, second) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate SCCertIndexEnumReplyTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(SCCertIndexEnumReply, length) },
|
||||
{ CMT_DT_STRUCT_PTR, offsetof(SCCertIndexEnumReply, list) },
|
||||
{ CMT_DT_STRING, offsetof(CertEnumElement, name) },
|
||||
{ CMT_DT_ITEM, offsetof(CertEnumElement, certKey) },
|
||||
{ CMT_DT_END_STRUCT_LIST },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
/* Test template */
|
||||
|
||||
CMTMessageTemplate TestListTemplate[] =
|
||||
{
|
||||
{ CMT_DT_STRING, offsetof(TestList, listName) },
|
||||
{ CMT_DT_STRUCT_LIST, offsetof(TestList, numElements) },
|
||||
{ CMT_DT_STRUCT_PTR, offsetof(TestList, elements) },
|
||||
{ CMT_DT_STRING, offsetof(TestListElement, name) },
|
||||
{ CMT_DT_STRING, offsetof(TestListElement, value) },
|
||||
{ CMT_DT_END_STRUCT_LIST},
|
||||
{ CMT_DT_END}
|
||||
};
|
||||
|
||||
CMTMessageTemplate SetPrefListMessageTemplate[] =
|
||||
{
|
||||
{ CMT_DT_STRUCT_LIST, offsetof(SetPrefListMessage, length) },
|
||||
{ CMT_DT_STRUCT_PTR, offsetof(SetPrefListMessage, list) },
|
||||
{ CMT_DT_STRING, offsetof(SetPrefElement, key) },
|
||||
{ CMT_DT_STRING, offsetof(SetPrefElement, value) },
|
||||
{ CMT_DT_INT, offsetof(SetPrefElement, type) },
|
||||
{ CMT_DT_END_STRUCT_LIST },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate GetPrefListRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_STRUCT_LIST, offsetof(GetPrefListRequest, length) },
|
||||
{ CMT_DT_STRUCT_PTR, offsetof(GetPrefListRequest, list) },
|
||||
{ CMT_DT_STRING, offsetof(GetPrefElement, key) },
|
||||
{ CMT_DT_INT, offsetof(GetPrefElement, type) },
|
||||
{ CMT_DT_END_STRUCT_LIST },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate GetCertExtensionTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(GetCertExtension, resID) },
|
||||
{ CMT_DT_INT, offsetof(GetCertExtension, extension) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate HTMLCertInfoRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_INT, offsetof(HTMLCertInfoRequest, certID) },
|
||||
{ CMT_DT_INT, offsetof(HTMLCertInfoRequest, showImages) },
|
||||
{ CMT_DT_INT, offsetof(HTMLCertInfoRequest, showIssuer) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate EncryptRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_ITEM, offsetof(EncryptRequestMessage, keyid) },
|
||||
{ CMT_DT_ITEM, offsetof(EncryptRequestMessage, data) },
|
||||
{ CMT_DT_ITEM, offsetof(EncryptRequestMessage, ctx) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
|
||||
CMTMessageTemplate DecryptRequestTemplate[] =
|
||||
{
|
||||
{ CMT_DT_ITEM, offsetof(DecryptRequestMessage, data) },
|
||||
{ CMT_DT_ITEM, offsetof(DecryptRequestMessage, ctx) },
|
||||
{ CMT_DT_END }
|
||||
};
|
||||
717
mozilla/string/obsolete/nsStr.cpp
Normal file
717
mozilla/string/obsolete/nsStr.cpp
Normal file
@@ -0,0 +1,717 @@
|
||||
/* -*- Mode: C++; tab-width: 2; 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.
|
||||
*/
|
||||
|
||||
/******************************************************************************************
|
||||
MODULE NOTES:
|
||||
|
||||
This file contains the nsStr data structure.
|
||||
This general purpose buffer management class is used as the basis for our strings.
|
||||
It's benefits include:
|
||||
1. An efficient set of library style functions for manipulating nsStrs
|
||||
2. Support for 1 and 2 byte character strings (which can easily be increased to n)
|
||||
3. Unicode awareness and interoperability.
|
||||
|
||||
*******************************************************************************************/
|
||||
|
||||
#include "nsStr.h"
|
||||
#include "bufferRoutines.h"
|
||||
#include "stdio.h" //only used for printf
|
||||
#include "nsCRT.h"
|
||||
#include "nsDeque.h"
|
||||
|
||||
|
||||
//static const char* kCallFindChar = "For better performance, call FindChar() for targets whose length==1.";
|
||||
//static const char* kCallRFindChar = "For better performance, call RFindChar() for targets whose length==1.";
|
||||
|
||||
static const PRUnichar gCommonEmptyBuffer[1] = {0};
|
||||
|
||||
/**
|
||||
* This method initializes all the members of the nsStr structure
|
||||
*
|
||||
* @update gess10/30/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void nsStr::Initialize(nsStr& aDest,eCharSize aCharSize) {
|
||||
aDest.mStr=(char*)gCommonEmptyBuffer;
|
||||
aDest.mLength=0;
|
||||
aDest.mCapacity=0;
|
||||
aDest.mCharSize=aCharSize;
|
||||
aDest.mOwnsBuffer=0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method initializes all the members of the nsStr structure
|
||||
* @update gess10/30/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void nsStr::Initialize(nsStr& aDest,char* aCString,PRUint32 aCapacity,PRUint32 aLength,eCharSize aCharSize,PRBool aOwnsBuffer){
|
||||
aDest.mStr=(aCString) ? aCString : (char*)gCommonEmptyBuffer;
|
||||
aDest.mLength=aLength;
|
||||
aDest.mCapacity=aCapacity;
|
||||
aDest.mCharSize=aCharSize;
|
||||
aDest.mOwnsBuffer=aOwnsBuffer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This member destroys the memory buffer owned by an nsStr object (if it actually owns it)
|
||||
* @update gess10/30/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void nsStr::Destroy(nsStr& aDest) {
|
||||
if((aDest.mStr) && (aDest.mStr!=(char*)gCommonEmptyBuffer)) {
|
||||
Free(aDest);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method gets called when the internal buffer needs
|
||||
* to grow to a given size. The original contents are not preserved.
|
||||
* @update gess 3/30/98
|
||||
* @param aNewLength -- new capacity of string in charSize units
|
||||
* @return void
|
||||
*/
|
||||
PRBool nsStr::EnsureCapacity(nsStr& aString,PRUint32 aNewLength) {
|
||||
PRBool result=PR_TRUE;
|
||||
if(aNewLength>aString.mCapacity) {
|
||||
result=Realloc(aString,aNewLength);
|
||||
if(aString.mStr)
|
||||
AddNullTerminator(aString);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method gets called when the internal buffer needs
|
||||
* to grow to a given size. The original contents ARE preserved.
|
||||
* @update gess 3/30/98
|
||||
* @param aNewLength -- new capacity of string in charSize units
|
||||
* @return void
|
||||
*/
|
||||
PRBool nsStr::GrowCapacity(nsStr& aDest,PRUint32 aNewLength) {
|
||||
PRBool result=PR_TRUE;
|
||||
if(aNewLength>aDest.mCapacity) {
|
||||
nsStr theTempStr;
|
||||
nsStr::Initialize(theTempStr,aDest.mCharSize);
|
||||
|
||||
result=EnsureCapacity(theTempStr,aNewLength);
|
||||
if(result) {
|
||||
if(aDest.mLength) {
|
||||
Append(theTempStr,aDest,0,aDest.mLength);
|
||||
}
|
||||
Free(aDest);
|
||||
aDest.mStr = theTempStr.mStr;
|
||||
theTempStr.mStr=0; //make sure to null this out so that you don't lose the buffer you just stole...
|
||||
aDest.mLength=theTempStr.mLength;
|
||||
aDest.mCapacity=theTempStr.mCapacity;
|
||||
aDest.mOwnsBuffer=theTempStr.mOwnsBuffer;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the contents of aDest with aSource, up to aCount of chars.
|
||||
* @update gess10/30/98
|
||||
* @param aDest is the nsStr that gets changed.
|
||||
* @param aSource is where chars are copied from
|
||||
* @param aCount is the number of chars copied from aSource
|
||||
*/
|
||||
void nsStr::Assign(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 aCount){
|
||||
if(&aDest!=&aSource){
|
||||
Truncate(aDest,0);
|
||||
Append(aDest,aSource,anOffset,aCount);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method appends the given nsStr to this one. Note that we have to
|
||||
* pay attention to the underlying char-size of both structs.
|
||||
* @update gess10/30/98
|
||||
* @param aDest is the nsStr to be manipulated
|
||||
* @param aSource is where char are copied from
|
||||
* @aCount is the number of bytes to be copied
|
||||
*/
|
||||
void nsStr::Append(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 aCount){
|
||||
if(anOffset<aSource.mLength){
|
||||
PRUint32 theRealLen=(aCount<0) ? aSource.mLength : MinInt(aCount,aSource.mLength);
|
||||
PRUint32 theLength=(anOffset+theRealLen<aSource.mLength) ? theRealLen : (aSource.mLength-anOffset);
|
||||
if(0<theLength){
|
||||
|
||||
PRBool isBigEnough=PR_TRUE;
|
||||
if(aDest.mLength+theLength > aDest.mCapacity) {
|
||||
isBigEnough=GrowCapacity(aDest,aDest.mLength+theLength);
|
||||
}
|
||||
|
||||
if(isBigEnough) {
|
||||
//now append new chars, starting at offset
|
||||
(*gCopyChars[aSource.mCharSize][aDest.mCharSize])(aDest.mStr,aDest.mLength,aSource.mStr,anOffset,theLength);
|
||||
|
||||
aDest.mLength+=theLength;
|
||||
AddNullTerminator(aDest);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method inserts up to "aCount" chars from a source nsStr into a dest nsStr.
|
||||
* @update gess10/30/98
|
||||
* @param aDest is the nsStr that gets changed
|
||||
* @param aDestOffset is where in aDest the insertion is to occur
|
||||
* @param aSource is where chars are copied from
|
||||
* @param aSrcOffset is where in aSource chars are copied from
|
||||
* @param aCount is the number of chars from aSource to be inserted into aDest
|
||||
*/
|
||||
void nsStr::Insert( nsStr& aDest,PRUint32 aDestOffset,const nsStr& aSource,PRUint32 aSrcOffset,PRInt32 aCount){
|
||||
//there are a few cases for insert:
|
||||
// 1. You're inserting chars into an empty string (assign)
|
||||
// 2. You're inserting onto the end of a string (append)
|
||||
// 3. You're inserting onto the 1..n-1 pos of a string (the hard case).
|
||||
if(0<aSource.mLength){
|
||||
if(aDest.mLength){
|
||||
if(aDestOffset<aDest.mLength){
|
||||
PRInt32 theRealLen=(aCount<0) ? aSource.mLength : MinInt(aCount,aSource.mLength);
|
||||
PRInt32 theLength=(aSrcOffset+theRealLen<aSource.mLength) ? theRealLen : (aSource.mLength-aSrcOffset);
|
||||
|
||||
if(aSrcOffset<aSource.mLength) {
|
||||
//here's the only new case we have to handle.
|
||||
//chars are really being inserted into our buffer...
|
||||
|
||||
if(aDest.mLength+theLength > aDest.mCapacity) {
|
||||
nsStr theTempStr;
|
||||
nsStr::Initialize(theTempStr,aDest.mCharSize);
|
||||
|
||||
PRBool isBigEnough=EnsureCapacity(theTempStr,aDest.mLength+theLength); //grow the temp buffer to the right size
|
||||
|
||||
if(isBigEnough) {
|
||||
if(aDestOffset) {
|
||||
Append(theTempStr,aDest,0,aDestOffset); //first copy leftmost data...
|
||||
}
|
||||
|
||||
Append(theTempStr,aSource,0,aSource.mLength); //next copy inserted (new) data
|
||||
|
||||
PRUint32 theRemains=aDest.mLength-aDestOffset;
|
||||
if(theRemains) {
|
||||
Append(theTempStr,aDest,aDestOffset,theRemains); //next copy rightmost data
|
||||
}
|
||||
|
||||
Free(aDest);
|
||||
aDest.mStr = theTempStr.mStr;
|
||||
theTempStr.mStr=0; //make sure to null this out so that you don't lose the buffer you just stole...
|
||||
aDest.mCapacity=theTempStr.mCapacity;
|
||||
aDest.mOwnsBuffer=theTempStr.mOwnsBuffer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else {
|
||||
//shift the chars right by theDelta...
|
||||
(*gShiftChars[aDest.mCharSize][KSHIFTRIGHT])(aDest.mStr,aDest.mLength,aDestOffset,theLength);
|
||||
|
||||
//now insert new chars, starting at offset
|
||||
(*gCopyChars[aSource.mCharSize][aDest.mCharSize])(aDest.mStr,aDestOffset,aSource.mStr,aSrcOffset,theLength);
|
||||
}
|
||||
|
||||
//finally, make sure to update the string length...
|
||||
aDest.mLength+=theLength;
|
||||
AddNullTerminator(aDest);
|
||||
|
||||
}//if
|
||||
//else nothing to do!
|
||||
}
|
||||
else Append(aDest,aSource,0,aCount);
|
||||
}
|
||||
else Append(aDest,aSource,0,aCount);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method deletes up to aCount chars from aDest
|
||||
* @update gess10/30/98
|
||||
* @param aDest is the nsStr to be manipulated
|
||||
* @param aDestOffset is where in aDest deletion is to occur
|
||||
* @param aCount is the number of chars to be deleted in aDest
|
||||
*/
|
||||
void nsStr::Delete(nsStr& aDest,PRUint32 aDestOffset,PRUint32 aCount){
|
||||
if(aDestOffset<aDest.mLength){
|
||||
|
||||
PRUint32 theDelta=aDest.mLength-aDestOffset;
|
||||
PRUint32 theLength=(theDelta<aCount) ? theDelta : aCount;
|
||||
|
||||
if(aDestOffset+theLength<aDest.mLength) {
|
||||
|
||||
//if you're here, it means we're cutting chars out of the middle of the string...
|
||||
//so shift the chars left by theLength...
|
||||
(*gShiftChars[aDest.mCharSize][KSHIFTLEFT])(aDest.mStr,aDest.mLength,aDestOffset,theLength);
|
||||
aDest.mLength-=theLength;
|
||||
AddNullTerminator(aDest);
|
||||
}
|
||||
else Truncate(aDest,aDestOffset);
|
||||
}//if
|
||||
}
|
||||
|
||||
/**
|
||||
* This method truncates the given nsStr at given offset
|
||||
* @update gess10/30/98
|
||||
* @param aDest is the nsStr to be truncated
|
||||
* @param aDestOffset is where in aDest truncation is to occur
|
||||
*/
|
||||
void nsStr::Truncate(nsStr& aDest,PRUint32 aDestOffset){
|
||||
if(aDestOffset<aDest.mLength){
|
||||
aDest.mLength=aDestOffset;
|
||||
AddNullTerminator(aDest);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method forces the given string to upper or lowercase
|
||||
* @update gess1/7/99
|
||||
* @param aDest is the string you're going to change
|
||||
* @param aToUpper: if TRUE, then we go uppercase, otherwise we go lowercase
|
||||
* @return
|
||||
*/
|
||||
void nsStr::ChangeCase(nsStr& aDest,PRBool aToUpper) {
|
||||
// somehow UnicharUtil return failed, fallback to the old ascii only code
|
||||
gCaseConverters[aDest.mCharSize](aDest.mStr,aDest.mLength,aToUpper);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess1/7/99
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void nsStr::Trim(nsStr& aDest,const char* aSet,PRBool aEliminateLeading,PRBool aEliminateTrailing){
|
||||
|
||||
if((aDest.mLength>0) && aSet){
|
||||
PRInt32 theIndex=-1;
|
||||
PRInt32 theMax=aDest.mLength;
|
||||
PRInt32 theSetLen=nsCRT::strlen(aSet);
|
||||
|
||||
if(aEliminateLeading) {
|
||||
while(++theIndex<=theMax) {
|
||||
PRUnichar theChar=GetCharAt(aDest,theIndex);
|
||||
PRInt32 thePos=gFindChars[eOneByte](aSet,theSetLen,0,theChar,PR_FALSE);
|
||||
if(kNotFound==thePos)
|
||||
break;
|
||||
}
|
||||
if(0<theIndex) {
|
||||
if(theIndex<theMax) {
|
||||
Delete(aDest,0,theIndex);
|
||||
}
|
||||
else Truncate(aDest,0);
|
||||
}
|
||||
}
|
||||
|
||||
if(aEliminateTrailing) {
|
||||
theIndex=aDest.mLength;
|
||||
PRInt32 theNewLen=theIndex;
|
||||
while(--theIndex>0) {
|
||||
PRUnichar theChar=GetCharAt(aDest,theIndex); //read at end now...
|
||||
PRInt32 thePos=gFindChars[eOneByte](aSet,theSetLen,0,theChar,PR_FALSE);
|
||||
if(kNotFound<thePos)
|
||||
theNewLen=theIndex;
|
||||
else break;
|
||||
}
|
||||
if(theNewLen<theMax) {
|
||||
Truncate(aDest,theNewLen);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess1/7/99
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void nsStr::CompressSet(nsStr& aDest,const char* aSet,PRBool aEliminateLeading,PRBool aEliminateTrailing){
|
||||
Trim(aDest,aSet,aEliminateLeading,aEliminateTrailing);
|
||||
PRUint32 aNewLen=gCompressChars[aDest.mCharSize](aDest.mStr,aDest.mLength,aSet);
|
||||
aDest.mLength=aNewLen;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess1/7/99
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void nsStr::StripChars(nsStr& aDest,const char* aSet){
|
||||
if((0<aDest.mLength) && (aSet)) {
|
||||
PRUint32 aNewLen=gStripChars[aDest.mCharSize](aDest.mStr,aDest.mLength,aSet);
|
||||
aDest.mLength=aNewLen;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************
|
||||
Searching methods...
|
||||
**************************************************************/
|
||||
|
||||
|
||||
/**
|
||||
* This searches aDest for a given substring
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aDest string to search
|
||||
* @param aTarget is the substring you're trying to find.
|
||||
* @param aIgnorecase indicates case sensitivity of search
|
||||
* @param anOffset tells us where to start the search
|
||||
* @return index in aDest where member of aSet occurs, or -1 if not found
|
||||
*/
|
||||
PRInt32 nsStr::FindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool aIgnoreCase,PRInt32 anOffset) {
|
||||
// NS_PRECONDITION(aTarget.mLength!=1,kCallFindChar);
|
||||
|
||||
PRInt32 result=kNotFound;
|
||||
|
||||
if((0<aDest.mLength) && (anOffset<(PRInt32)aDest.mLength)) {
|
||||
PRInt32 theMax=aDest.mLength-aTarget.mLength;
|
||||
PRInt32 index=(0<=anOffset) ? anOffset : 0;
|
||||
|
||||
if((aDest.mLength>=aTarget.mLength) && (aTarget.mLength>0) && (index>=0)){
|
||||
PRInt32 theTargetMax=aTarget.mLength;
|
||||
while(index<=theMax) {
|
||||
PRInt32 theSubIndex=-1;
|
||||
PRBool matches=PR_TRUE;
|
||||
while((++theSubIndex<theTargetMax) && (matches)){
|
||||
PRUnichar theChar=(aIgnoreCase) ? nsCRT::ToLower(GetCharAt(aDest,index+theSubIndex)) : GetCharAt(aDest,index+theSubIndex);
|
||||
PRUnichar theTargetChar=(aIgnoreCase) ? nsCRT::ToLower(GetCharAt(aTarget,theSubIndex)) : GetCharAt(aTarget,theSubIndex);
|
||||
matches=PRBool(theChar==theTargetChar);
|
||||
}
|
||||
if(matches) {
|
||||
result=index;
|
||||
break;
|
||||
}
|
||||
index++;
|
||||
} //while
|
||||
}//if
|
||||
}//if
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This searches aDest for a given character
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aDest string to search
|
||||
* @param char is the character you're trying to find.
|
||||
* @param aIgnorecase indicates case sensitivity of search
|
||||
* @param anOffset tells us where to start the search
|
||||
* @return index in aDest where member of aSet occurs, or -1 if not found
|
||||
*/
|
||||
PRInt32 nsStr::FindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase,PRInt32 anOffset) {
|
||||
PRInt32 result=kNotFound;
|
||||
if((0<aDest.mLength) && (anOffset<(PRInt32)aDest.mLength)) {
|
||||
PRUint32 index=(0<=anOffset) ? (PRUint32)anOffset : 0;
|
||||
result=gFindChars[aDest.mCharSize](aDest.mStr,aDest.mLength,index,aChar,aIgnoreCase);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This searches aDest for a character found in aSet.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aDest string to search
|
||||
* @param aSet contains a list of chars to be searched for
|
||||
* @param aIgnorecase indicates case sensitivity of search
|
||||
* @param anOffset tells us where to start the search
|
||||
* @return index in aDest where member of aSet occurs, or -1 if not found
|
||||
*/
|
||||
PRInt32 nsStr::FindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRInt32 anOffset) {
|
||||
//NS_PRECONDITION(aSet.mLength!=1,kCallFindChar);
|
||||
|
||||
PRInt32 index=(0<=anOffset) ? anOffset-1 : -1;
|
||||
PRInt32 thePos;
|
||||
|
||||
//Note that the search is inverted here. We're scanning aDest, one char at a time
|
||||
//but doing the search against the given set. That's why we use 0 as the offset below.
|
||||
if((0<aDest.mLength) && (0<aSet.mLength)){
|
||||
while(++index<(PRInt32)aDest.mLength) {
|
||||
PRUnichar theChar=GetCharAt(aDest,index);
|
||||
thePos=gFindChars[aSet.mCharSize](aSet.mStr,aSet.mLength,0,theChar,aIgnoreCase);
|
||||
if(kNotFound!=thePos)
|
||||
return index;
|
||||
} //while
|
||||
}
|
||||
return kNotFound;
|
||||
}
|
||||
|
||||
/**************************************************************
|
||||
Reverse Searching methods...
|
||||
**************************************************************/
|
||||
|
||||
|
||||
/**
|
||||
* This searches aDest (in reverse) for a given substring
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aDest string to search
|
||||
* @param aTarget is the substring you're trying to find.
|
||||
* @param aIgnorecase indicates case sensitivity of search
|
||||
* @param anOffset tells us where to start the search (counting from left)
|
||||
* @return index in aDest where member of aSet occurs, or -1 if not found
|
||||
*/
|
||||
PRInt32 nsStr::RFindSubstr(const nsStr& aDest,const nsStr& aTarget, PRBool aIgnoreCase,PRInt32 anOffset) {
|
||||
//NS_PRECONDITION(aTarget.mLength!=1,kCallRFindChar);
|
||||
|
||||
PRInt32 result=kNotFound;
|
||||
|
||||
if((0<aDest.mLength) && (anOffset<(PRInt32)aDest.mLength)) {
|
||||
PRInt32 index=(0<=anOffset) ? anOffset : aDest.mLength-1;
|
||||
|
||||
if((aDest.mLength>=aTarget.mLength) && (aTarget.mLength>0) && (index>=0)){
|
||||
|
||||
nsStr theCopy;
|
||||
nsStr::Initialize(theCopy,eOneByte);
|
||||
nsStr::Assign(theCopy,aTarget,0,aTarget.mLength);
|
||||
if(aIgnoreCase){
|
||||
nsStr::ChangeCase(theCopy,PR_FALSE); //force to lowercase
|
||||
}
|
||||
|
||||
PRInt32 theTargetMax=theCopy.mLength;
|
||||
while(index>=0) {
|
||||
PRInt32 theSubIndex=-1;
|
||||
PRBool matches=PR_FALSE;
|
||||
if(index+theCopy.mLength<=aDest.mLength) {
|
||||
matches=PR_TRUE;
|
||||
while((++theSubIndex<theTargetMax) && (matches)){
|
||||
PRUnichar theDestChar=(aIgnoreCase) ? nsCRT::ToLower(GetCharAt(aDest,index+theSubIndex)) : GetCharAt(aDest,index+theSubIndex);
|
||||
PRUnichar theTargetChar=GetCharAt(theCopy,theSubIndex);
|
||||
matches=PRBool(theDestChar==theTargetChar);
|
||||
} //while
|
||||
} //if
|
||||
if(matches) {
|
||||
result=index;
|
||||
break;
|
||||
}
|
||||
index--;
|
||||
} //while
|
||||
nsStr::Destroy(theCopy);
|
||||
}//if
|
||||
}//if
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This searches aDest (in reverse) for a given character
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aDest string to search
|
||||
* @param char is the character you're trying to find.
|
||||
* @param aIgnorecase indicates case sensitivity of search
|
||||
* @param anOffset tells us where to start the search
|
||||
* @return index in aDest where member of aSet occurs, or -1 if not found
|
||||
*/
|
||||
PRInt32 nsStr::RFindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase,PRInt32 anOffset) {
|
||||
PRInt32 result=kNotFound;
|
||||
if((0<aDest.mLength) && (anOffset<(PRInt32)aDest.mLength)) {
|
||||
PRUint32 index=(0<=anOffset) ? anOffset : aDest.mLength-1;
|
||||
result=gRFindChars[aDest.mCharSize](aDest.mStr,aDest.mLength,index,aChar,aIgnoreCase);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This searches aDest (in reverese) for a character found in aSet.
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aDest string to search
|
||||
* @param aSet contains a list of chars to be searched for
|
||||
* @param aIgnorecase indicates case sensitivity of search
|
||||
* @param anOffset tells us where to start the search
|
||||
* @return index in aDest where member of aSet occurs, or -1 if not found
|
||||
*/
|
||||
PRInt32 nsStr::RFindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRInt32 anOffset) {
|
||||
//NS_PRECONDITION(aSet.mLength!=1,kCallRFindChar);
|
||||
|
||||
PRInt32 index=(0<=anOffset) ? anOffset : aDest.mLength;
|
||||
PRInt32 thePos;
|
||||
|
||||
//note that the search is inverted here. We're scanning aDest, one char at a time
|
||||
//but doing the search against the given set. That's why we use 0 as the offset below.
|
||||
if(0<aDest.mLength) {
|
||||
while(--index>=0) {
|
||||
PRUnichar theChar=GetCharAt(aDest,index);
|
||||
thePos=gFindChars[aSet.mCharSize](aSet.mStr,aSet.mLength,0,theChar,aIgnoreCase);
|
||||
if(kNotFound!=thePos)
|
||||
return index;
|
||||
} //while
|
||||
}
|
||||
return kNotFound;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compare source and dest strings, up to an (optional max) number of chars
|
||||
* @param aDest is the first str to compare
|
||||
* @param aSource is the second str to compare
|
||||
* @param aCount -- if (-1), then we use length of longer string; if (0<aCount) then it gives the max # of chars to compare
|
||||
* @param aIgnorecase tells us whether to search with case sensitivity
|
||||
* @return aDest<aSource=-1;aDest==aSource==0;aDest>aSource=1
|
||||
*/
|
||||
PRInt32 nsStr::Compare(const nsStr& aDest,const nsStr& aSource,PRInt32 aCount,PRBool aIgnoreCase) {
|
||||
PRInt32 result=0;
|
||||
|
||||
if(aCount) {
|
||||
PRInt32 minlen=(aSource.mLength<aDest.mLength) ? aSource.mLength : aDest.mLength;
|
||||
|
||||
if(0==minlen) {
|
||||
if ((aDest.mLength == 0) && (aSource.mLength == 0))
|
||||
return 0;
|
||||
if (aDest.mLength == 0)
|
||||
return -1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
PRInt32 maxlen=(aSource.mLength<aDest.mLength) ? aDest.mLength : aSource.mLength;
|
||||
aCount = (aCount<0) ? maxlen : MinInt(aCount,maxlen);
|
||||
result=(*gCompare[aDest.mCharSize][aSource.mCharSize])(aDest.mStr,aSource.mStr,aCount,aIgnoreCase);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
PRBool nsStr::Alloc(nsStr& aDest,PRUint32 aCount) {
|
||||
|
||||
static int mAllocCount=0;
|
||||
mAllocCount++;
|
||||
|
||||
//we're given the acount value in charunits; now scale up to next multiple.
|
||||
PRUint32 theNewCapacity=kDefaultStringSize;
|
||||
while(theNewCapacity<aCount){
|
||||
theNewCapacity<<=1;
|
||||
}
|
||||
|
||||
aDest.mCapacity=theNewCapacity++;
|
||||
PRUint32 theSize=(theNewCapacity<<aDest.mCharSize);
|
||||
aDest.mStr = (char*)nsAllocator::Alloc(theSize);
|
||||
|
||||
PRBool result=PR_FALSE;
|
||||
if(aDest.mStr) {
|
||||
aDest.mOwnsBuffer=1;
|
||||
result=PR_TRUE;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
PRBool nsStr::Free(nsStr& aDest){
|
||||
if(aDest.mStr){
|
||||
if(aDest.mOwnsBuffer){
|
||||
nsAllocator::Free(aDest.mStr);
|
||||
}
|
||||
aDest.mStr=0;
|
||||
aDest.mOwnsBuffer=0;
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool nsStr::Realloc(nsStr& aDest,PRUint32 aCount){
|
||||
|
||||
nsStr temp;
|
||||
memcpy(&temp,&aDest,sizeof(aDest));
|
||||
|
||||
PRBool result=Alloc(temp,aCount);
|
||||
if(result) {
|
||||
Free(aDest);
|
||||
aDest.mStr=temp.mStr;
|
||||
aDest.mCapacity=temp.mCapacity;
|
||||
aDest.mOwnsBuffer=temp.mOwnsBuffer;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
CBufDescriptor::CBufDescriptor(char* aString,PRBool aStackBased,PRUint32 aCapacity,PRInt32 aLength) {
|
||||
mBuffer=aString;
|
||||
mCharSize=eOneByte;
|
||||
mStackBased=aStackBased;
|
||||
mIsConst=PR_FALSE;
|
||||
mLength=mCapacity=0;
|
||||
if(aString && aCapacity>1) {
|
||||
mCapacity=aCapacity-1;
|
||||
mLength=(-1==aLength) ? strlen(aString) : aLength;
|
||||
if(mLength>PRInt32(mCapacity))
|
||||
mLength=mCapacity;
|
||||
}
|
||||
}
|
||||
|
||||
CBufDescriptor::CBufDescriptor(const char* aString,PRBool aStackBased,PRUint32 aCapacity,PRInt32 aLength) {
|
||||
mBuffer=(char*)aString;
|
||||
mCharSize=eOneByte;
|
||||
mStackBased=aStackBased;
|
||||
mIsConst=PR_TRUE;
|
||||
mLength=mCapacity=0;
|
||||
if(aString && aCapacity>1) {
|
||||
mCapacity=aCapacity-1;
|
||||
mLength=(-1==aLength) ? strlen(aString) : aLength;
|
||||
if(mLength>PRInt32(mCapacity))
|
||||
mLength=mCapacity;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CBufDescriptor::CBufDescriptor(PRUnichar* aString,PRBool aStackBased,PRUint32 aCapacity,PRInt32 aLength) {
|
||||
mBuffer=(char*)aString;
|
||||
mCharSize=eTwoByte;
|
||||
mStackBased=aStackBased;
|
||||
mLength=mCapacity=0;
|
||||
mIsConst=PR_FALSE;
|
||||
if(aString && aCapacity>1) {
|
||||
mCapacity=aCapacity-1;
|
||||
mLength=(-1==aLength) ? nsCRT::strlen(aString) : aLength;
|
||||
if(mLength>PRInt32(mCapacity))
|
||||
mLength=mCapacity;
|
||||
}
|
||||
}
|
||||
|
||||
CBufDescriptor::CBufDescriptor(const PRUnichar* aString,PRBool aStackBased,PRUint32 aCapacity,PRInt32 aLength) {
|
||||
mBuffer=(char*)aString;
|
||||
mCharSize=eTwoByte;
|
||||
mStackBased=aStackBased;
|
||||
mLength=mCapacity=0;
|
||||
mIsConst=PR_TRUE;
|
||||
if(aString && aCapacity>1) {
|
||||
mCapacity=aCapacity-1;
|
||||
mLength=(-1==aLength) ? nsCRT::strlen(aString) : aLength;
|
||||
if(mLength>PRInt32(mCapacity))
|
||||
mLength=mCapacity;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
450
mozilla/string/obsolete/nsStr.h
Normal file
450
mozilla/string/obsolete/nsStr.h
Normal file
@@ -0,0 +1,450 @@
|
||||
/* -*- Mode: C++; tab-width: 2; 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.
|
||||
*/
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
MODULE NOTES:
|
||||
|
||||
1. There are two philosophies to building string classes:
|
||||
A. Hide the underlying buffer & offer API's allow indirect iteration
|
||||
B. Reveal underlying buffer, risk corruption, but gain performance
|
||||
|
||||
We chose the option B for performance reasons.
|
||||
|
||||
2 Our internal buffer always holds capacity+1 bytes.
|
||||
|
||||
The nsStr struct is a simple structure (no methods) that contains
|
||||
the necessary info to be described as a string. This simple struct
|
||||
is manipulated by the static methods provided in this class.
|
||||
(Which effectively makes this a library that works on structs).
|
||||
|
||||
There are also object-based versions called nsString and nsAutoString
|
||||
which use nsStr but makes it look at feel like an object.
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
/***********************************************************************
|
||||
ASSUMPTIONS:
|
||||
|
||||
1. nsStrings and nsAutoString are always null terminated.
|
||||
2. If you try to set a null char (via SetChar()) a new length is set
|
||||
3. nsCStrings can be upsampled into nsString without data loss
|
||||
4. Char searching is faster than string searching. Use char interfaces
|
||||
if your needs will allow it.
|
||||
5. It's easy to use the stack for nsAutostring buffer storage (fast too!).
|
||||
See the CBufDescriptor class in this file.
|
||||
6. It's ONLY ok to provide non-null-terminated buffers to Append() and Insert()
|
||||
provided you specify a 0<n value for the optional count argument.
|
||||
7. Downsampling from nsString to nsCString is lossy -- avoid it if possible!
|
||||
8. Calls to ToNewCString() and ToNewUnicode() should be matched with calls to Recycle().
|
||||
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
/**********************************************************************************
|
||||
|
||||
AND NOW FOR SOME GENERAL DOCUMENTATION ON STRING USAGE...
|
||||
|
||||
The fundamental datatype in the string library is nsStr. It's a structure that
|
||||
provides the buffer storage and meta-info. It also provides a C-style library
|
||||
of functions for direct manipulation (for those of you who prefer K&R to Bjarne).
|
||||
|
||||
Here's a diagram of the class hierarchy:
|
||||
|
||||
nsStr
|
||||
|___nsString
|
||||
| |
|
||||
| ------nsAutoString
|
||||
|
|
||||
|___nsCString
|
||||
|
|
||||
------nsCAutoString
|
||||
|
||||
Why so many string classes? The 4 variants give you the control you need to
|
||||
determine the best class for your purpose. There are 2 dimensions to this
|
||||
flexibility: 1) stack vs. heap; and 2) 1-byte chars vs. 2-byte chars.
|
||||
|
||||
Note: While nsAutoString and nsCAutoString begin life using stack-based storage,
|
||||
they may not stay that way. Like all nsString classes, autostrings will
|
||||
automatically grow to contain the data you provide. When autostrings
|
||||
grow beyond their intrinsic buffer, they switch to heap based allocations.
|
||||
(We avoid alloca to avoid considerable platform difficulties; see the
|
||||
GNU documentation for more details).
|
||||
|
||||
I should also briefly mention that all the string classes use a "memory agent"
|
||||
object to perform memory operations. This class proxies the standard nsAllocator
|
||||
for actual memory calls, but knows the structure of nsStr making heap operations
|
||||
more localized.
|
||||
|
||||
|
||||
CHOOSING A STRING CLASS:
|
||||
|
||||
In order to choose a string class for you purpose, use this handy table:
|
||||
|
||||
heap-based stack-based
|
||||
-----------------------------------
|
||||
ascii data | nsCString nsCAutoString |
|
||||
|----------------------------------
|
||||
unicode data | nsString nsAutoString |
|
||||
-----------------------------------
|
||||
|
||||
|
||||
Note: The i18n folks will stenuously object if we get too carried away with the
|
||||
use of nsCString's that pass interface boundaries. Try to limit your
|
||||
use of these to external interfaces that demand them, or for your own
|
||||
private purposes in cases where they'll never be seen by humans.
|
||||
|
||||
|
||||
PERFORMANCE CONSIDERATIONS:
|
||||
|
||||
Here are a few tricks to know in order to get better string performance:
|
||||
|
||||
1) Try to limit conversions between ascii and unicode; By sticking with nsString
|
||||
wherever possible your code will be i18n-compliant.
|
||||
|
||||
|
||||
2) Preallocating your string buffer cuts down trips to the allocator. So if you
|
||||
have need for an arbitrarily large buffer, pre-size it like this:
|
||||
|
||||
{
|
||||
nsString mBuffer;
|
||||
mBuffer.SetCapacity(aReasonableSize);
|
||||
}
|
||||
|
||||
3) Allocating nsAutoString or nsCAutoString on the heap is memory inefficient
|
||||
(after all, the whole point is to avoid a heap allocation of the buffer).
|
||||
|
||||
|
||||
4) Consider using an autoString to write into your arbitrarily-sized stack buffers, rather
|
||||
than it's own buffers.
|
||||
|
||||
For example, let's say you're going to call printf() to emit pretty-printed debug output
|
||||
of your object. You know from experience that the pretty-printed version of your object
|
||||
exceeds the capacity of an autostring. Ignoring memory considerations, you could simply
|
||||
use nsCString, appending the stringized version of each of your class's data members.
|
||||
This will probably result in calls to the heap manager.
|
||||
|
||||
But there's a way to do this without necessarily having to call the heap manager.
|
||||
All you do is declare a stack based buffer and instruct nsCString to use that instead
|
||||
of it's own internal buffer by using the CBufDescriptor class:
|
||||
|
||||
{
|
||||
char theBuffer[256];
|
||||
CBufDescritor theBufDecriptor( theBuffer, PR_TRUE, sizeof(theBuffer), 0);
|
||||
nsCAutoString s3( theBufDescriptor );
|
||||
s3="HELLO, my name is inigo montoya, you killed my father, prepare to die!.";
|
||||
}
|
||||
|
||||
The assignment statment to s3 will cause the given string to be written to your
|
||||
stack-based buffer via the normal nsString/nsCString interfaces. Cool, huh?
|
||||
Note however that just like any other nsStringXXX use, if you write more data
|
||||
than will fit in the buffer, a visit to the heap manager will be in order.
|
||||
|
||||
|
||||
**********************************************************************************/
|
||||
|
||||
|
||||
#ifndef _nsStr
|
||||
#define _nsStr
|
||||
|
||||
#include "nscore.h"
|
||||
#include "nsIAllocator.h"
|
||||
#include <string.h>
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
enum eCharSize {eOneByte=0,eTwoByte=1};
|
||||
#define kDefaultCharSize eTwoByte
|
||||
#define kRadix10 (10)
|
||||
#define kRadix16 (16)
|
||||
#define kAutoDetect (100)
|
||||
#define kRadixUnknown (kAutoDetect+1)
|
||||
const PRInt32 kDefaultStringSize = 64;
|
||||
const PRInt32 kNotFound = -1;
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
class NS_COM CBufDescriptor {
|
||||
public:
|
||||
CBufDescriptor(char* aString, PRBool aStackBased,PRUint32 aCapacity,PRInt32 aLength=-1);
|
||||
CBufDescriptor(const char* aString, PRBool aStackBased,PRUint32 aCapacity,PRInt32 aLength=-1);
|
||||
CBufDescriptor(PRUnichar* aString, PRBool aStackBased,PRUint32 aCapacity,PRInt32 aLength=-1);
|
||||
CBufDescriptor(const PRUnichar* aString,PRBool aStackBased,PRUint32 aCapacity,PRInt32 aLength=-1);
|
||||
|
||||
char* mBuffer;
|
||||
eCharSize mCharSize;
|
||||
PRUint32 mCapacity;
|
||||
PRInt32 mLength;
|
||||
PRBool mStackBased;
|
||||
PRBool mIsConst;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
struct NS_COM nsStr {
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
nsStr() {
|
||||
MOZ_COUNT_CTOR(nsStr);
|
||||
}
|
||||
|
||||
~nsStr() {
|
||||
MOZ_COUNT_DTOR(nsStr);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method initializes an nsStr for use
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aString is the nsStr to be initialized
|
||||
* @param aCharSize tells us the requested char size (1 or 2 bytes)
|
||||
*/
|
||||
static void Initialize(nsStr& aDest,eCharSize aCharSize);
|
||||
|
||||
/**
|
||||
* This method initializes an nsStr for use
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aString is the nsStr to be initialized
|
||||
* @param aCharSize tells us the requested char size (1 or 2 bytes)
|
||||
*/
|
||||
static void Initialize(nsStr& aDest,char* aCString,PRUint32 aCapacity,PRUint32 aLength,eCharSize aCharSize,PRBool aOwnsBuffer);
|
||||
|
||||
/**
|
||||
* This method destroys the given nsStr, and *MAY*
|
||||
* deallocate it's memory depending on the setting
|
||||
* of the internal mOwnsBUffer flag.
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aString is the nsStr to be manipulated
|
||||
* @param anAgent is the allocator to be used to the nsStr
|
||||
*/
|
||||
static void Destroy(nsStr& aDest);
|
||||
|
||||
/**
|
||||
* These methods are where memory allocation/reallocation occur.
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aString is the nsStr to be manipulated
|
||||
* @param anAgent is the allocator to be used on the nsStr
|
||||
* @return
|
||||
*/
|
||||
static PRBool EnsureCapacity(nsStr& aString,PRUint32 aNewLength);
|
||||
static PRBool GrowCapacity(nsStr& aString,PRUint32 aNewLength);
|
||||
|
||||
/**
|
||||
* These methods are used to append content to the given nsStr
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the nsStr to be appended to
|
||||
* @param aSource is the buffer to be copied from
|
||||
* @param anOffset tells us where in source to start copying
|
||||
* @param aCount tells us the (max) # of chars to copy
|
||||
* @param anAgent is the allocator to be used for alloc/free operations
|
||||
*/
|
||||
static void Append(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 aCount);
|
||||
|
||||
/**
|
||||
* These methods are used to assign contents of a source string to dest string
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the nsStr to be appended to
|
||||
* @param aSource is the buffer to be copied from
|
||||
* @param anOffset tells us where in source to start copying
|
||||
* @param aCount tells us the (max) # of chars to copy
|
||||
* @param anAgent is the allocator to be used for alloc/free operations
|
||||
*/
|
||||
static void Assign(nsStr& aDest,const nsStr& aSource,PRUint32 anOffset,PRInt32 aCount);
|
||||
|
||||
/**
|
||||
* These methods are used to insert content from source string to the dest nsStr
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the nsStr to be appended to
|
||||
* @param aDestOffset tells us where in dest to start insertion
|
||||
* @param aSource is the buffer to be copied from
|
||||
* @param aSrcOffset tells us where in source to start copying
|
||||
* @param aCount tells us the (max) # of chars to insert
|
||||
* @param anAgent is the allocator to be used for alloc/free operations
|
||||
*/
|
||||
static void Insert( nsStr& aDest,PRUint32 aDestOffset,const nsStr& aSource,PRUint32 aSrcOffset,PRInt32 aCount);
|
||||
|
||||
/**
|
||||
* This method deletes chars from the given str.
|
||||
* The given allocator may choose to resize the str as well.
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the nsStr to be deleted from
|
||||
* @param aDestOffset tells us where in dest to start deleting
|
||||
* @param aCount tells us the (max) # of chars to delete
|
||||
* @param anAgent is the allocator to be used for alloc/free operations
|
||||
*/
|
||||
static void Delete(nsStr& aDest,PRUint32 aDestOffset,PRUint32 aCount);
|
||||
|
||||
/**
|
||||
* This method is used to truncate the given string.
|
||||
* The given allocator may choose to resize the str as well (but it's not likely).
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the nsStr to be appended to
|
||||
* @param aDestOffset tells us where in dest to start insertion
|
||||
* @param aSource is the buffer to be copied from
|
||||
* @param aSrcOffset tells us where in source to start copying
|
||||
* @param anAgent is the allocator to be used for alloc/free operations
|
||||
*/
|
||||
static void Truncate(nsStr& aDest,PRUint32 aDestOffset);
|
||||
|
||||
/**
|
||||
* This method is used to perform a case conversion on the given string
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the nsStr to be case shifted
|
||||
* @param toUpper tells us to go upper vs. lower
|
||||
*/
|
||||
static void ChangeCase(nsStr& aDest,PRBool aToUpper);
|
||||
|
||||
|
||||
/**
|
||||
* This method trims chars (given in aSet) from the edges of given buffer
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the buffer to be manipulated
|
||||
* @param aSet tells us which chars to remove from given buffer
|
||||
* @param aEliminateLeading tells us whether to strip chars from the start of the buffer
|
||||
* @param aEliminateTrailing tells us whether to strip chars from the start of the buffer
|
||||
*/
|
||||
static void Trim(nsStr& aDest,const char* aSet,PRBool aEliminateLeading,PRBool aEliminateTrailing);
|
||||
|
||||
/**
|
||||
* This method compresses duplicate runs of a given char from the given buffer
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the buffer to be manipulated
|
||||
* @param aSet tells us which chars to compress from given buffer
|
||||
* @param aChar is the replacement char
|
||||
* @param aEliminateLeading tells us whether to strip chars from the start of the buffer
|
||||
* @param aEliminateTrailing tells us whether to strip chars from the start of the buffer
|
||||
*/
|
||||
static void CompressSet(nsStr& aDest,const char* aSet,PRBool aEliminateLeading,PRBool aEliminateTrailing);
|
||||
|
||||
/**
|
||||
* This method removes all occurances of chars in given set from aDest
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the buffer to be manipulated
|
||||
* @param aSet tells us which chars to compress from given buffer
|
||||
* @param aChar is the replacement char
|
||||
* @param aEliminateLeading tells us whether to strip chars from the start of the buffer
|
||||
* @param aEliminateTrailing tells us whether to strip chars from the start of the buffer
|
||||
*/
|
||||
static void StripChars(nsStr& aDest,const char* aSet);
|
||||
|
||||
/**
|
||||
* This method compares the data bewteen two nsStr's
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aStr1 is the first buffer to be compared
|
||||
* @param aStr2 is the 2nd buffer to be compared
|
||||
* @param aCount is the number of chars to compare
|
||||
* @param aIgnorecase tells us whether to use a case-sensitive comparison
|
||||
* @return -1,0,1 depending on <,==,>
|
||||
*/
|
||||
static PRInt32 Compare(const nsStr& aDest,const nsStr& aSource,PRInt32 aCount,PRBool aIgnoreCase);
|
||||
|
||||
/**
|
||||
* These methods scan the given string for 1 or more chars in a given direction
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the nsStr to be searched to
|
||||
* @param aSource (or aChar) is the substr we're looking to find
|
||||
* @param aIgnoreCase tells us whether to search in a case-sensitive manner
|
||||
* @param anOffset tells us where in the dest string to start searching
|
||||
* @return the index of the source (substr) in dest, or -1 (kNotFound) if not found.
|
||||
*/
|
||||
static PRInt32 FindSubstr(const nsStr& aDest,const nsStr& aSource, PRBool aIgnoreCase,PRInt32 anOffset);
|
||||
static PRInt32 FindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase,PRInt32 anOffset);
|
||||
static PRInt32 FindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRInt32 anOffset);
|
||||
|
||||
static PRInt32 RFindSubstr(const nsStr& aDest,const nsStr& aSource, PRBool aIgnoreCase,PRInt32 anOffset);
|
||||
static PRInt32 RFindChar(const nsStr& aDest,PRUnichar aChar, PRBool aIgnoreCase,PRInt32 anOffset);
|
||||
static PRInt32 RFindCharInSet(const nsStr& aDest,const nsStr& aSet,PRBool aIgnoreCase,PRInt32 anOffset);
|
||||
|
||||
|
||||
PRUint32 mLength;
|
||||
PRUint32 mCapacity;
|
||||
eCharSize mCharSize;
|
||||
PRBool mOwnsBuffer;
|
||||
|
||||
union {
|
||||
char* mStr;
|
||||
PRUnichar* mUStr;
|
||||
};
|
||||
|
||||
private:
|
||||
static PRBool Alloc(nsStr& aString,PRUint32 aCount);
|
||||
static PRBool Realloc(nsStr& aString,PRUint32 aCount);
|
||||
static PRBool Free(nsStr& aString);
|
||||
|
||||
};
|
||||
|
||||
/**************************************************************
|
||||
A couple of tiny helper methods used in the string classes.
|
||||
**************************************************************/
|
||||
|
||||
inline PRInt32 MinInt(PRInt32 anInt1,PRInt32 anInt2){
|
||||
return (anInt1<anInt2) ? anInt1 : anInt2;
|
||||
}
|
||||
|
||||
inline PRInt32 MaxInt(PRInt32 anInt1,PRInt32 anInt2){
|
||||
return (anInt1<anInt2) ? anInt2 : anInt1;
|
||||
}
|
||||
|
||||
inline void AddNullTerminator(nsStr& aDest) {
|
||||
if(eTwoByte==aDest.mCharSize)
|
||||
aDest.mUStr[aDest.mLength]=0;
|
||||
else aDest.mStr[aDest.mLength]=0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the given buffer to the heap manager. Calls allocator::Free()
|
||||
* @return string length
|
||||
*/
|
||||
inline void Recycle( char* aBuffer) { nsAllocator::Free(aBuffer); }
|
||||
inline void Recycle( PRUnichar* aBuffer) { nsAllocator::Free(aBuffer); }
|
||||
|
||||
/**
|
||||
* This method is used to access a given char in the given string
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the nsStr to be appended to
|
||||
* @param anIndex tells us where in dest to get the char from
|
||||
* @return the given char, or 0 if anIndex is out of range
|
||||
*/
|
||||
inline PRUnichar GetCharAt(const nsStr& aDest,PRUint32 anIndex){
|
||||
if(anIndex<aDest.mLength) {
|
||||
return (eTwoByte==aDest.mCharSize) ? aDest.mUStr[anIndex] : aDest.mStr[anIndex];
|
||||
}//if
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
1865
mozilla/string/obsolete/nsString.cpp
Normal file
1865
mozilla/string/obsolete/nsString.cpp
Normal file
File diff suppressed because it is too large
Load Diff
747
mozilla/string/obsolete/nsString.h
Normal file
747
mozilla/string/obsolete/nsString.h
Normal file
@@ -0,0 +1,747 @@
|
||||
/* -*- Mode: C++; tab-width: 2; 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.
|
||||
*/
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
MODULE NOTES:
|
||||
|
||||
See nsStr.h for a more general description of string classes.
|
||||
|
||||
This version of the nsString class offers many improvements over the
|
||||
original version:
|
||||
1. Wide and narrow chars
|
||||
2. Allocators
|
||||
3. Much smarter autostrings
|
||||
4. Subsumable strings
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
#ifndef _nsCString_
|
||||
#define _nsCString_
|
||||
|
||||
#include "nsString2.h"
|
||||
#include "prtypes.h"
|
||||
#include "nscore.h"
|
||||
#include <stdio.h>
|
||||
#include "nsStr.h"
|
||||
#include "nsIAtom.h"
|
||||
|
||||
|
||||
class NS_COM nsSubsumeCStr;
|
||||
|
||||
class NS_COM nsCString : public nsStr {
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
nsCString();
|
||||
|
||||
/**
|
||||
* This constructor accepts an isolatin string
|
||||
* @param aCString is a ptr to a 1-byte cstr
|
||||
*/
|
||||
nsCString(const char* aCString,PRInt32 aLength=-1);
|
||||
|
||||
/**
|
||||
* This constructor accepts a unichar string
|
||||
* @param aCString is a ptr to a 2-byte cstr
|
||||
*/
|
||||
nsCString(const PRUnichar* aString,PRInt32 aLength=-1);
|
||||
|
||||
/**
|
||||
* This is a copy constructor that accepts an nsStr
|
||||
* @param reference to another nsCString
|
||||
*/
|
||||
nsCString(const nsStr&);
|
||||
|
||||
/**
|
||||
* This is our copy constructor
|
||||
* @param reference to another nsCString
|
||||
*/
|
||||
nsCString(const nsCString& aString);
|
||||
|
||||
/**
|
||||
* This constructor takes a subsumestr
|
||||
* @param reference to subsumestr
|
||||
*/
|
||||
nsCString(nsSubsumeCStr& aSubsumeStr);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*
|
||||
*/
|
||||
virtual ~nsCString();
|
||||
|
||||
/**
|
||||
* Retrieve the length of this string
|
||||
* @return string length
|
||||
*/
|
||||
inline PRInt32 Length() const { return (PRInt32)mLength; }
|
||||
|
||||
/**
|
||||
* Retrieve the size of this string
|
||||
* @return string length
|
||||
*/
|
||||
virtual void SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const;
|
||||
|
||||
|
||||
/**
|
||||
* Call this method if you want to force a different string capacity
|
||||
* @update gess7/30/98
|
||||
* @param aLength -- contains new length for mStr
|
||||
* @return
|
||||
*/
|
||||
void SetLength(PRUint32 aLength) {
|
||||
Truncate(aLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the new length of the string.
|
||||
* @param aLength is new string length.
|
||||
* @return nada
|
||||
*/
|
||||
void SetCapacity(PRUint32 aLength);
|
||||
/**
|
||||
* This method truncates this string to given length.
|
||||
*
|
||||
* @param anIndex -- new length of string
|
||||
* @return nada
|
||||
*/
|
||||
void Truncate(PRInt32 anIndex=0);
|
||||
|
||||
|
||||
/**
|
||||
* Determine whether or not the characters in this
|
||||
* string are in sorted order.
|
||||
*
|
||||
* @return TRUE if ordered.
|
||||
*/
|
||||
PRBool IsOrdered(void) const;
|
||||
|
||||
|
||||
/**
|
||||
* Determine whether or not this string has a length of 0
|
||||
*
|
||||
* @return TRUE if empty.
|
||||
*/
|
||||
PRBool IsEmpty(void) const {
|
||||
return PRBool(0==mLength);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
Accessor methods...
|
||||
*********************************************************************/
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve const ptr to internal buffer; DO NOT TRY TO FREE IT!
|
||||
*/
|
||||
const char* GetBuffer(void) const;
|
||||
|
||||
|
||||
/**
|
||||
* Get nth character.
|
||||
*/
|
||||
PRUnichar operator[](PRUint32 anIndex) const;
|
||||
PRUnichar CharAt(PRUint32 anIndex) const;
|
||||
PRUnichar First(void) const;
|
||||
PRUnichar Last(void) const;
|
||||
|
||||
PRBool SetCharAt(PRUnichar aChar,PRUint32 anIndex);
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
String creation methods...
|
||||
*********************************************************************/
|
||||
|
||||
/**
|
||||
* Create a new string by appending given string to this
|
||||
* @param aString -- 2nd string to be appended
|
||||
* @return new string
|
||||
*/
|
||||
nsSubsumeCStr operator+(const nsCString& aString);
|
||||
|
||||
/**
|
||||
* create a new string by adding this to the given char*.
|
||||
* @param aCString is a ptr to cstring to be added to this
|
||||
* @return newly created string
|
||||
*/
|
||||
nsSubsumeCStr operator+(const char* aCString);
|
||||
|
||||
|
||||
/**
|
||||
* create a new string by adding this to the given char.
|
||||
* @param aChar is a char to be added to this
|
||||
* @return newly created string
|
||||
*/
|
||||
nsSubsumeCStr operator+(PRUnichar aChar);
|
||||
nsSubsumeCStr operator+(char aChar);
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
Lexomorphic transforms...
|
||||
*********************************************************************/
|
||||
|
||||
/**
|
||||
* Converts chars in this to lowercase
|
||||
* @update gess 7/27/98
|
||||
*/
|
||||
void ToLowerCase();
|
||||
|
||||
|
||||
/**
|
||||
* Converts chars in this to lowercase, and
|
||||
* stores them in aOut
|
||||
* @update gess 7/27/98
|
||||
* @param aOut is a string to contain result
|
||||
*/
|
||||
void ToLowerCase(nsCString& aString) const;
|
||||
|
||||
/**
|
||||
* Converts chars in this to uppercase
|
||||
* @update gess 7/27/98
|
||||
*/
|
||||
void ToUpperCase();
|
||||
|
||||
/**
|
||||
* Converts chars in this to lowercase, and
|
||||
* stores them in a given output string
|
||||
* @update gess 7/27/98
|
||||
* @param aOut is a string to contain result
|
||||
*/
|
||||
void ToUpperCase(nsCString& aString) const;
|
||||
|
||||
|
||||
/**
|
||||
* This method is used to remove all occurances of the
|
||||
* characters found in aSet from this string.
|
||||
*
|
||||
* @param aSet -- characters to be cut from this
|
||||
* @return *this
|
||||
*/
|
||||
nsCString& StripChars(const char* aSet);
|
||||
nsCString& StripChar(char aChar);
|
||||
|
||||
/**
|
||||
* This method strips whitespace throughout the string
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
nsCString& StripWhitespace();
|
||||
|
||||
/**
|
||||
* swaps occurence of 1 string for another
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
nsCString& ReplaceChar(PRUnichar aOldChar,PRUnichar aNewChar);
|
||||
nsCString& ReplaceChar(const char* aSet,PRUnichar aNewChar);
|
||||
|
||||
PRInt32 CountChar(PRUnichar aChar);
|
||||
|
||||
/**
|
||||
* This method trims characters found in aTrimSet from
|
||||
* either end of the underlying string.
|
||||
*
|
||||
* @param aTrimSet -- contains chars to be trimmed from
|
||||
* both ends
|
||||
* @return this
|
||||
*/
|
||||
nsCString& Trim(const char* aSet,PRBool aEliminateLeading=PR_TRUE,PRBool aEliminateTrailing=PR_TRUE);
|
||||
|
||||
/**
|
||||
* This method strips whitespace from string.
|
||||
* You can control whether whitespace is yanked from
|
||||
* start and end of string as well.
|
||||
*
|
||||
* @param aEliminateLeading controls stripping of leading ws
|
||||
* @param aEliminateTrailing controls stripping of trailing ws
|
||||
* @return this
|
||||
*/
|
||||
nsCString& CompressSet(const char* aSet, PRUnichar aChar,PRBool aEliminateLeading=PR_TRUE,PRBool aEliminateTrailing=PR_TRUE);
|
||||
|
||||
/**
|
||||
* This method strips whitespace from string.
|
||||
* You can control whether whitespace is yanked from
|
||||
* start and end of string as well.
|
||||
*
|
||||
* @param aEliminateLeading controls stripping of leading ws
|
||||
* @param aEliminateTrailing controls stripping of trailing ws
|
||||
* @return this
|
||||
*/
|
||||
nsCString& CompressWhitespace( PRBool aEliminateLeading=PR_TRUE,PRBool aEliminateTrailing=PR_TRUE);
|
||||
|
||||
/**********************************************************************
|
||||
string conversion methods...
|
||||
*********************************************************************/
|
||||
|
||||
operator char*() {return mStr;}
|
||||
operator const char*() const {return (const char*)mStr;}
|
||||
|
||||
/**
|
||||
* This method constructs a new nsCString that is a clone
|
||||
* of this string.
|
||||
*
|
||||
*/
|
||||
nsCString* ToNewString() const;
|
||||
|
||||
/**
|
||||
* Creates an ISOLatin1 clone of this string
|
||||
* Note that calls to this method should be matched with calls to Recycle().
|
||||
* @return ptr to new isolatin1 string
|
||||
*/
|
||||
char* ToNewCString() const;
|
||||
|
||||
/**
|
||||
* Creates a unicode clone of this string
|
||||
* Note that calls to this method should be matched with calls to Recycle().
|
||||
* @return ptr to new unicode string
|
||||
*/
|
||||
PRUnichar* ToNewUnicode() const;
|
||||
|
||||
/**
|
||||
* Copies data from internal buffer onto given char* buffer
|
||||
* NOTE: This only copies as many chars as will fit in given buffer (clips)
|
||||
* @param aBuf is the buffer where data is stored
|
||||
* @param aBuflength is the max # of chars to move to buffer
|
||||
* @return ptr to given buffer
|
||||
*/
|
||||
char* ToCString(char* aBuf,PRUint32 aBufLength,PRUint32 anOffset=0) const;
|
||||
|
||||
/**
|
||||
* Perform string to float conversion.
|
||||
* @param aErrorCode will contain error if one occurs
|
||||
* @return float rep of string value
|
||||
*/
|
||||
float ToFloat(PRInt32* aErrorCode) const;
|
||||
|
||||
/**
|
||||
* Try to derive the radix from the value contained in this string
|
||||
* @return kRadix10, kRadix16 or kAutoDetect (meaning unknown)
|
||||
*/
|
||||
PRUint32 DetermineRadix(void);
|
||||
|
||||
/**
|
||||
* Perform string to int conversion.
|
||||
* @param aErrorCode will contain error if one occurs
|
||||
* @return int rep of string value
|
||||
*/
|
||||
PRInt32 ToInteger(PRInt32* aErrorCode,PRUint32 aRadix=kRadix10) const;
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
String manipulation methods...
|
||||
*********************************************************************/
|
||||
|
||||
/**
|
||||
* Functionally equivalent to assign or operator=
|
||||
*
|
||||
*/
|
||||
nsCString& SetString(const char* aString,PRInt32 aLength=-1) {return Assign(aString,aLength);}
|
||||
nsCString& SetString(const nsStr& aString,PRInt32 aLength=-1) {return Assign(aString,aLength);}
|
||||
|
||||
/**
|
||||
* assign given string to this string
|
||||
* @param aStr: buffer to be assigned to this
|
||||
* @param alength is the length of the given str (or -1)
|
||||
if you want me to determine its length
|
||||
* @return this
|
||||
*/
|
||||
nsCString& Assign(const nsStr& aString,PRInt32 aCount=-1);
|
||||
nsCString& Assign(const char* aString,PRInt32 aCount=-1);
|
||||
nsCString& Assign(const PRUnichar* aString,PRInt32 aCount=-1);
|
||||
nsCString& Assign(PRUnichar aChar);
|
||||
nsCString& Assign(char aChar);
|
||||
|
||||
/**
|
||||
* here come a bunch of assignment operators...
|
||||
* @param aString: string to be added to this
|
||||
* @return this
|
||||
*/
|
||||
nsCString& operator=(const nsCString& aString) {return Assign(aString);}
|
||||
nsCString& operator=(const nsStr& aString) {return Assign(aString);}
|
||||
nsCString& operator=(PRUnichar aChar) {return Assign(aChar);}
|
||||
nsCString& operator=(char aChar) {return Assign(aChar);}
|
||||
nsCString& operator=(const char* aCString) {return Assign(aCString);}
|
||||
nsCString& operator=(const PRUnichar* aString) {return Assign(aString);}
|
||||
#ifdef AIX
|
||||
nsCString& operator=(const nsSubsumeCStr& aSubsumeString); // AIX requires a const here
|
||||
#else
|
||||
nsCString& operator=(nsSubsumeCStr& aSubsumeString);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Here's a bunch of methods that append varying types...
|
||||
* @param various...
|
||||
* @return this
|
||||
*/
|
||||
nsCString& operator+=(const nsCString& aString){return Append(aString,aString.mLength);}
|
||||
nsCString& operator+=(const char* aCString) {return Append(aCString);}
|
||||
nsCString& operator+=(PRUnichar aChar){return Append(aChar);}
|
||||
nsCString& operator+=(char aChar){return Append(aChar);}
|
||||
|
||||
/*
|
||||
* Appends n characters from given string to this,
|
||||
* This version computes the length of your given string
|
||||
*
|
||||
* @param aString is the source to be appended to this
|
||||
* @return number of chars copied
|
||||
*/
|
||||
nsCString& Append(const nsCString& aString) {return Append(aString,aString.mLength);}
|
||||
|
||||
|
||||
/*
|
||||
* Appends n characters from given string to this,
|
||||
*
|
||||
* @param aString is the source to be appended to this
|
||||
* @param aCount -- number of chars to copy; -1 tells us to compute the strlen for you
|
||||
* @return number of chars copied
|
||||
*/
|
||||
nsCString& Append(const nsCString& aString,PRInt32 aCount);
|
||||
nsCString& Append(const nsStr& aString,PRInt32 aCount=-1);
|
||||
nsCString& Append(const char* aString,PRInt32 aCount=-1);
|
||||
nsCString& Append(PRUnichar aChar);
|
||||
nsCString& Append(char aChar);
|
||||
nsCString& Append(PRInt32 aInteger,PRInt32 aRadix=10); //radix=8,10 or 16
|
||||
nsCString& Append(float aFloat);
|
||||
|
||||
/*
|
||||
* Copies n characters from this string to given string,
|
||||
* starting at the leftmost offset.
|
||||
*
|
||||
*
|
||||
* @param aCopy -- Receiving string
|
||||
* @param aCount -- number of chars to copy
|
||||
* @return number of chars copied
|
||||
*/
|
||||
PRUint32 Left(nsCString& aCopy,PRInt32 aCount) const;
|
||||
|
||||
/*
|
||||
* Copies n characters from this string to given string,
|
||||
* starting at the given offset.
|
||||
*
|
||||
*
|
||||
* @param aCopy -- Receiving string
|
||||
* @param aCount -- number of chars to copy
|
||||
* @param anOffset -- position where copying begins
|
||||
* @return number of chars copied
|
||||
*/
|
||||
PRUint32 Mid(nsCString& aCopy,PRUint32 anOffset,PRInt32 aCount) const;
|
||||
|
||||
/*
|
||||
* Copies n characters from this string to given string,
|
||||
* starting at rightmost char.
|
||||
*
|
||||
*
|
||||
* @param aCopy -- Receiving string
|
||||
* @param aCount -- number of chars to copy
|
||||
* @return number of chars copied
|
||||
*/
|
||||
PRUint32 Right(nsCString& aCopy,PRInt32 aCount) const;
|
||||
|
||||
/*
|
||||
* This method inserts n chars from given string into this
|
||||
* string at str[anOffset].
|
||||
*
|
||||
* @param aCopy -- String to be inserted into this
|
||||
* @param anOffset -- insertion position within this str
|
||||
* @param aCount -- number of chars to be copied from aCopy
|
||||
* @return number of chars inserted into this.
|
||||
*/
|
||||
nsCString& Insert(const nsCString& aCopy,PRUint32 anOffset,PRInt32 aCount=-1);
|
||||
|
||||
/**
|
||||
* Insert a given string into this string at
|
||||
* a specified offset.
|
||||
*
|
||||
* @param aString* to be inserted into this string
|
||||
* @param anOffset is insert pos in str
|
||||
* @return the number of chars inserted into this string
|
||||
*/
|
||||
nsCString& Insert(const char* aChar,PRUint32 anOffset,PRInt32 aCount=-1);
|
||||
|
||||
/**
|
||||
* Insert a single char into this string at
|
||||
* a specified offset.
|
||||
*
|
||||
* @param character to be inserted into this string
|
||||
* @param anOffset is insert pos in str
|
||||
* @return the number of chars inserted into this string
|
||||
*/
|
||||
nsCString& Insert(PRUnichar aChar,PRUint32 anOffset);
|
||||
nsCString& Insert(char aChar,PRUint32 anOffset);
|
||||
|
||||
/*
|
||||
* This method is used to cut characters in this string
|
||||
* starting at anOffset, continuing for aCount chars.
|
||||
*
|
||||
* @param anOffset -- start pos for cut operation
|
||||
* @param aCount -- number of chars to be cut
|
||||
* @return *this
|
||||
*/
|
||||
nsCString& Cut(PRUint32 anOffset,PRInt32 aCount);
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
Searching methods...
|
||||
*********************************************************************/
|
||||
|
||||
/**
|
||||
* Search for given character within this string.
|
||||
* This method does so by using a binary search,
|
||||
* so your string HAD BETTER BE ORDERED!
|
||||
*
|
||||
* @param aChar is the unicode char to be found
|
||||
* @return offset in string, or -1 (kNotFound)
|
||||
*/
|
||||
PRInt32 BinarySearch(PRUnichar aChar) const;
|
||||
|
||||
/**
|
||||
* Search for given substring within this string
|
||||
*
|
||||
* @param aString is substring to be sought in this
|
||||
* @param aIgnoreCase selects case sensitivity
|
||||
* @param anOffset tells us where in this strig to start searching
|
||||
* @return offset in string, or -1 (kNotFound)
|
||||
*/
|
||||
PRInt32 Find(const nsStr& aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1) const;
|
||||
PRInt32 Find(const char* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1) const;
|
||||
PRInt32 Find(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1) const;
|
||||
|
||||
/**
|
||||
* Search for given char within this string
|
||||
*
|
||||
* @param aString is substring to be sought in this
|
||||
* @param anOffset tells us where in this strig to start searching
|
||||
* @param aIgnoreCase selects case sensitivity
|
||||
* @return find pos in string, or -1 (kNotFound)
|
||||
*/
|
||||
PRInt32 FindChar(PRUnichar aChar,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1) const;
|
||||
|
||||
/**
|
||||
* This method searches this string for the first character
|
||||
* found in the given charset
|
||||
* @param aString contains set of chars to be found
|
||||
* @param anOffset tells us where to start searching in this
|
||||
* @return -1 if not found, else the offset in this
|
||||
*/
|
||||
PRInt32 FindCharInSet(const char* aString,PRInt32 anOffset=-1) const;
|
||||
PRInt32 FindCharInSet(const PRUnichar* aString,PRInt32 anOffset=-1) const;
|
||||
PRInt32 FindCharInSet(const nsStr& aString,PRInt32 anOffset=-1) const;
|
||||
|
||||
|
||||
/**
|
||||
* This methods scans the string backwards, looking for the given string
|
||||
* @param aString is substring to be sought in this
|
||||
* @param aIgnoreCase tells us whether or not to do caseless compare
|
||||
* @return offset in string, or -1 (kNotFound)
|
||||
*/
|
||||
PRInt32 RFind(const char* aCString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1) const;
|
||||
PRInt32 RFind(const nsStr& aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1) const;
|
||||
PRInt32 RFind(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1) const;
|
||||
|
||||
|
||||
/**
|
||||
* Search for given char within this string
|
||||
*
|
||||
* @param aString is substring to be sought in this
|
||||
* @param anOffset tells us where in this strig to start searching
|
||||
* @param aIgnoreCase selects case sensitivity
|
||||
* @return find pos in string, or -1 (kNotFound)
|
||||
*/
|
||||
PRInt32 RFindChar(PRUnichar aChar,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1) const;
|
||||
|
||||
/**
|
||||
* This method searches this string for the last character
|
||||
* found in the given string
|
||||
* @param aString contains set of chars to be found
|
||||
* @param anOffset tells us where to start searching in this
|
||||
* @return -1 if not found, else the offset in this
|
||||
*/
|
||||
PRInt32 RFindCharInSet(const char* aString,PRInt32 anOffset=-1) const;
|
||||
PRInt32 RFindCharInSet(const PRUnichar* aString,PRInt32 anOffset=-1) const;
|
||||
PRInt32 RFindCharInSet(const nsStr& aString,PRInt32 anOffset=-1) const;
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
Comparison methods...
|
||||
*********************************************************************/
|
||||
|
||||
/**
|
||||
* Compares a given string type to this string.
|
||||
* @update gess 7/27/98
|
||||
* @param S is the string to be compared
|
||||
* @param aIgnoreCase tells us how to treat case
|
||||
* @param aCount tells us how many chars to compare
|
||||
* @return -1,0,1
|
||||
*/
|
||||
virtual PRInt32 Compare(const nsStr &aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const;
|
||||
virtual PRInt32 Compare(const char* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const;
|
||||
virtual PRInt32 Compare(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const;
|
||||
|
||||
/**
|
||||
* These methods compare a given string type to this one
|
||||
* @param aString is the string to be compared to this
|
||||
* @return TRUE or FALSE
|
||||
*/
|
||||
PRBool operator==(const nsStr &aString) const;
|
||||
PRBool operator==(const char* aString) const;
|
||||
PRBool operator==(const PRUnichar* aString) const;
|
||||
|
||||
/**
|
||||
* These methods perform a !compare of a given string type to this
|
||||
* @param aString is the string to be compared to this
|
||||
* @return TRUE
|
||||
*/
|
||||
PRBool operator!=(const nsStr &aString) const;
|
||||
PRBool operator!=(const char* aString) const;
|
||||
PRBool operator!=(const PRUnichar* aString) const;
|
||||
|
||||
/**
|
||||
* These methods test if a given string is < than this
|
||||
* @param aString is the string to be compared to this
|
||||
* @return TRUE or FALSE
|
||||
*/
|
||||
PRBool operator<(const nsStr &aString) const;
|
||||
PRBool operator<(const char* aString) const;
|
||||
PRBool operator<(const PRUnichar* aString) const;
|
||||
|
||||
/**
|
||||
* These methods test if a given string is > than this
|
||||
* @param aString is the string to be compared to this
|
||||
* @return TRUE or FALSE
|
||||
*/
|
||||
PRBool operator>(const nsStr &S) const;
|
||||
PRBool operator>(const char* aString) const;
|
||||
PRBool operator>(const PRUnichar* aString) const;
|
||||
|
||||
/**
|
||||
* These methods test if a given string is <= than this
|
||||
* @param aString is the string to be compared to this
|
||||
* @return TRUE or FALSE
|
||||
*/
|
||||
PRBool operator<=(const nsStr &S) const;
|
||||
PRBool operator<=(const char* aString) const;
|
||||
PRBool operator<=(const PRUnichar* aString) const;
|
||||
|
||||
/**
|
||||
* These methods test if a given string is >= than this
|
||||
* @param aString is the string to be compared to this
|
||||
* @return TRUE or FALSE
|
||||
*/
|
||||
PRBool operator>=(const nsStr &S) const;
|
||||
PRBool operator>=(const char* aString) const;
|
||||
PRBool operator>=(const PRUnichar* aString) const;
|
||||
|
||||
/**
|
||||
* Compare this to given string; note that we compare full strings here.
|
||||
* The optional length argument just lets us know how long the given string is.
|
||||
* If you provide a length, it is compared to length of this string as an
|
||||
* optimization.
|
||||
*
|
||||
* @param aString -- the string to compare to this
|
||||
* @param aCount -- number of chars in given string you want to compare
|
||||
* @return TRUE if equal
|
||||
*/
|
||||
PRBool Equals(const nsString &aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const;
|
||||
PRBool Equals(const nsStr& aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const;
|
||||
PRBool Equals(const char* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const;
|
||||
PRBool Equals(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const;
|
||||
|
||||
PRBool EqualsIgnoreCase(const nsStr& aString) const;
|
||||
PRBool EqualsIgnoreCase(const char* aString,PRInt32 aCount=-1) const;
|
||||
PRBool EqualsIgnoreCase(const PRUnichar* aString,PRInt32 aCount=-1) const;
|
||||
|
||||
|
||||
static void Recycle(nsCString* aString);
|
||||
static nsCString* CreateString(void);
|
||||
|
||||
};
|
||||
|
||||
extern NS_COM int fputs(const nsCString& aString, FILE* out);
|
||||
//ostream& operator<<(ostream& aStream,const nsCString& aString);
|
||||
//virtual void DebugDump(ostream& aStream) const;
|
||||
|
||||
|
||||
/**************************************************************
|
||||
Here comes the AutoString class which uses internal memory
|
||||
(typically found on the stack) for its default buffer.
|
||||
If the buffer needs to grow, it gets reallocated on the heap.
|
||||
**************************************************************/
|
||||
|
||||
class NS_COM nsCAutoString : public nsCString {
|
||||
public:
|
||||
|
||||
nsCAutoString();
|
||||
nsCAutoString(const char* aString,PRInt32 aLength=-1);
|
||||
nsCAutoString(const CBufDescriptor& aBuffer);
|
||||
nsCAutoString(const PRUnichar* aString,PRInt32 aLength=-1);
|
||||
nsCAutoString(const nsStr& aString);
|
||||
nsCAutoString(const nsCAutoString& aString);
|
||||
|
||||
#ifdef AIX
|
||||
nsCAutoString(const nsSubsumeCStr& aSubsumeStr); // AIX requires a const
|
||||
#else
|
||||
nsCAutoString(nsSubsumeCStr& aSubsumeStr);
|
||||
#endif // AIX
|
||||
nsCAutoString(PRUnichar aChar);
|
||||
virtual ~nsCAutoString();
|
||||
|
||||
nsCAutoString& operator=(const nsCString& aString) {nsCString::Assign(aString); return *this;}
|
||||
nsCAutoString& operator=(const char* aCString) {nsCString::Assign(aCString); return *this;}
|
||||
nsCAutoString& operator=(PRUnichar aChar) {nsCString::Assign(aChar); return *this;}
|
||||
nsCAutoString& operator=(char aChar) {nsCString::Assign(aChar); return *this;}
|
||||
|
||||
/**
|
||||
* Retrieve the size of this string
|
||||
* @return string length
|
||||
*/
|
||||
virtual void SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const;
|
||||
|
||||
char mBuffer[kDefaultStringSize];
|
||||
};
|
||||
|
||||
|
||||
/***************************************************************
|
||||
The subsumestr class is very unusual.
|
||||
It differs from a normal string in that it doesn't use normal
|
||||
copy semantics when another string is assign to this.
|
||||
Instead, it "steals" the contents of the source string.
|
||||
|
||||
This is very handy for returning nsString classes as part of
|
||||
an operator+(...) for example, in that it cuts down the number
|
||||
of copy operations that must occur.
|
||||
|
||||
You should probably not use this class unless you really know
|
||||
what you're doing.
|
||||
***************************************************************/
|
||||
class NS_COM nsSubsumeCStr : public nsCString {
|
||||
public:
|
||||
nsSubsumeCStr(nsStr& aString);
|
||||
nsSubsumeCStr(PRUnichar* aString,PRBool assumeOwnership,PRInt32 aLength=-1);
|
||||
nsSubsumeCStr(char* aString,PRBool assumeOwnership,PRInt32 aLength=-1);
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
2233
mozilla/string/obsolete/nsString2.cpp
Normal file
2233
mozilla/string/obsolete/nsString2.cpp
Normal file
File diff suppressed because it is too large
Load Diff
840
mozilla/string/obsolete/nsString2.h
Normal file
840
mozilla/string/obsolete/nsString2.h
Normal file
@@ -0,0 +1,840 @@
|
||||
/* -*- Mode: C++; tab-width: 2; 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.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
MODULE NOTES:
|
||||
|
||||
See nsStr.h for a more general description of string classes.
|
||||
|
||||
This version of the nsString class offers many improvements over the
|
||||
original version:
|
||||
1. Wide and narrow chars
|
||||
2. Allocators
|
||||
3. Much smarter autostrings
|
||||
4. Subsumable strings
|
||||
***********************************************************************/
|
||||
|
||||
|
||||
#ifndef _nsString_
|
||||
#define _nsString_
|
||||
|
||||
#include "prtypes.h"
|
||||
#include "nscore.h"
|
||||
#include <stdio.h>
|
||||
#include "nsString.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsStr.h"
|
||||
#include "nsCRT.h"
|
||||
|
||||
class nsISizeOfHandler;
|
||||
|
||||
|
||||
#define nsString2 nsString
|
||||
#define nsAutoString2 nsAutoString
|
||||
|
||||
|
||||
class NS_COM nsSubsumeStr;
|
||||
class NS_COM nsString : public nsStr {
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
nsString();
|
||||
|
||||
|
||||
/**
|
||||
* This constructor accepts an isolatin string
|
||||
* @param aCString is a ptr to a 1-byte cstr
|
||||
*/
|
||||
nsString(const char* aCString);
|
||||
|
||||
/**
|
||||
* This constructor accepts a unichar string
|
||||
* @param aCString is a ptr to a 2-byte cstr
|
||||
*/
|
||||
nsString(const PRUnichar* aString);
|
||||
|
||||
/**
|
||||
* This is a copy constructor that accepts an nsStr
|
||||
* @param reference to another nsString
|
||||
*/
|
||||
nsString(const nsStr&);
|
||||
|
||||
/**
|
||||
* This is our copy constructor
|
||||
* @param reference to another nsString
|
||||
*/
|
||||
nsString(const nsString& aString);
|
||||
|
||||
/**
|
||||
* This constructor takes a subsumestr
|
||||
* @param reference to subsumestr
|
||||
*/
|
||||
nsString(nsSubsumeStr& aSubsumeStr);
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*
|
||||
*/
|
||||
virtual ~nsString();
|
||||
|
||||
/**
|
||||
* Retrieve the length of this string
|
||||
* @return string length
|
||||
*/
|
||||
inline PRInt32 Length() const { return (PRInt32)mLength; }
|
||||
|
||||
/**
|
||||
* Retrieve the size of this string
|
||||
* @return string length
|
||||
*/
|
||||
virtual void SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const;
|
||||
|
||||
|
||||
/**
|
||||
* Call this method if you want to force a different string length
|
||||
* @update gess7/30/98
|
||||
* @param aLength -- contains new length for mStr
|
||||
* @return
|
||||
*/
|
||||
void SetLength(PRUint32 aLength) {
|
||||
Truncate(aLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the new length of the string.
|
||||
* @param aLength is new string length.
|
||||
* @return nada
|
||||
*/
|
||||
void SetCapacity(PRUint32 aLength);
|
||||
|
||||
/**
|
||||
* This method truncates this string to given length.
|
||||
*
|
||||
* @param anIndex -- new length of string
|
||||
* @return nada
|
||||
*/
|
||||
void Truncate(PRInt32 anIndex=0);
|
||||
|
||||
|
||||
/**
|
||||
* Determine whether or not the characters in this
|
||||
* string are in sorted order.
|
||||
*
|
||||
* @return TRUE if ordered.
|
||||
*/
|
||||
PRBool IsOrdered(void) const;
|
||||
|
||||
/**
|
||||
* Determine whether or not the characters in this
|
||||
* string are in store as 1 or 2 byte (unicode) strings.
|
||||
*
|
||||
* @return TRUE if ordered.
|
||||
*/
|
||||
PRBool IsUnicode(void) const {
|
||||
PRBool result=PRBool(mCharSize==eTwoByte);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether or not this string has a length of 0
|
||||
*
|
||||
* @return TRUE if empty.
|
||||
*/
|
||||
PRBool IsEmpty(void) const {
|
||||
return PRBool(0==mLength);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
Getters/Setters...
|
||||
*********************************************************************/
|
||||
|
||||
/**
|
||||
* Retrieve const ptr to internal buffer; DO NOT TRY TO FREE IT!
|
||||
*/
|
||||
const char* GetBuffer(void) const;
|
||||
const PRUnichar* GetUnicode(void) const;
|
||||
|
||||
|
||||
/**
|
||||
* Get nth character.
|
||||
*/
|
||||
PRUnichar operator[](PRUint32 anIndex) const;
|
||||
PRUnichar CharAt(PRUint32 anIndex) const;
|
||||
PRUnichar First(void) const;
|
||||
PRUnichar Last(void) const;
|
||||
|
||||
/**
|
||||
* Set nth character.
|
||||
*/
|
||||
PRBool SetCharAt(PRUnichar aChar,PRUint32 anIndex);
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
String concatenation methods...
|
||||
*********************************************************************/
|
||||
|
||||
/**
|
||||
* Create a new string by appending given string to this
|
||||
* @param aString -- 2nd string to be appended
|
||||
* @return new subsumable string
|
||||
*/
|
||||
nsSubsumeStr operator+(const nsStr& aString);
|
||||
nsSubsumeStr operator+(const nsString& aString);
|
||||
|
||||
/**
|
||||
* create a new string by adding this to the given cstring
|
||||
* @param aCString is a ptr to cstring to be added to this
|
||||
* @return newly created string
|
||||
*/
|
||||
nsSubsumeStr operator+(const char* aCString);
|
||||
|
||||
/**
|
||||
* create a new string by adding this to the given prunichar*.
|
||||
* @param aString is a ptr to UC-string to be added to this
|
||||
* @return newly created string
|
||||
*/
|
||||
nsSubsumeStr operator+(const PRUnichar* aString);
|
||||
|
||||
/**
|
||||
* create a new string by adding this to the given char.
|
||||
* @param aChar is a char to be added to this
|
||||
* @return newly created string
|
||||
*/
|
||||
nsSubsumeStr operator+(char aChar);
|
||||
|
||||
/**
|
||||
* create a new string by adding this to the given char.
|
||||
* @param aChar is a unichar to be added to this
|
||||
* @return newly created string
|
||||
*/
|
||||
nsSubsumeStr operator+(PRUnichar aChar);
|
||||
|
||||
/**********************************************************************
|
||||
Lexomorphic transforms...
|
||||
*********************************************************************/
|
||||
|
||||
|
||||
/**
|
||||
* Converts chars in this to lowercase
|
||||
* @update gess 7/27/98
|
||||
*/
|
||||
void ToLowerCase();
|
||||
|
||||
|
||||
/**
|
||||
* Converts chars in this to lowercase, and
|
||||
* stores them in aOut
|
||||
* @update gess 7/27/98
|
||||
* @param aOut is a string to contain result
|
||||
*/
|
||||
void ToLowerCase(nsString& aString) const;
|
||||
|
||||
/**
|
||||
* Converts chars in this to uppercase
|
||||
* @update gess 7/27/98
|
||||
*/
|
||||
void ToUpperCase();
|
||||
|
||||
/**
|
||||
* Converts chars in this to lowercase, and
|
||||
* stores them in a given output string
|
||||
* @update gess 7/27/98
|
||||
* @param aOut is a string to contain result
|
||||
*/
|
||||
void ToUpperCase(nsString& aString) const;
|
||||
|
||||
|
||||
/**
|
||||
* This method is used to remove all occurances of the
|
||||
* characters found in aSet from this string.
|
||||
*
|
||||
* @param aSet -- characters to be cut from this
|
||||
* @return *this
|
||||
*/
|
||||
nsString& StripChars(const char* aSet);
|
||||
nsString& StripChar(char aChar);
|
||||
|
||||
/**
|
||||
* This method strips whitespace throughout the string
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
nsString& StripWhitespace();
|
||||
|
||||
/**
|
||||
* swaps occurence of 1 string for another
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
nsString& ReplaceChar(PRUnichar anOldChar,PRUnichar aNewChar);
|
||||
nsString& ReplaceChar(const char* aSet,PRUnichar aNewChar);
|
||||
|
||||
PRInt32 CountChar(PRUnichar aChar);
|
||||
|
||||
/**
|
||||
* This method trims characters found in aTrimSet from
|
||||
* either end of the underlying string.
|
||||
*
|
||||
* @param aTrimSet -- contains chars to be trimmed from
|
||||
* both ends
|
||||
* @return this
|
||||
*/
|
||||
nsString& Trim(const char* aSet,PRBool aEliminateLeading=PR_TRUE,PRBool aEliminateTrailing=PR_TRUE);
|
||||
|
||||
/**
|
||||
* This method strips whitespace from string.
|
||||
* You can control whether whitespace is yanked from
|
||||
* start and end of string as well.
|
||||
*
|
||||
* @param aEliminateLeading controls stripping of leading ws
|
||||
* @param aEliminateTrailing controls stripping of trailing ws
|
||||
* @return this
|
||||
*/
|
||||
nsString& CompressSet(const char* aSet, PRUnichar aChar,PRBool aEliminateLeading=PR_TRUE,PRBool aEliminateTrailing=PR_TRUE);
|
||||
|
||||
/**
|
||||
* This method strips whitespace from string.
|
||||
* You can control whether whitespace is yanked from
|
||||
* start and end of string as well.
|
||||
*
|
||||
* @param aEliminateLeading controls stripping of leading ws
|
||||
* @param aEliminateTrailing controls stripping of trailing ws
|
||||
* @return this
|
||||
*/
|
||||
nsString& CompressWhitespace( PRBool aEliminateLeading=PR_TRUE,PRBool aEliminateTrailing=PR_TRUE);
|
||||
|
||||
/**********************************************************************
|
||||
string conversion methods...
|
||||
*********************************************************************/
|
||||
|
||||
/**
|
||||
* This method constructs a new nsString is a clone of this string.
|
||||
*
|
||||
*/
|
||||
nsString* ToNewString() const;
|
||||
|
||||
/**
|
||||
* Creates an ISOLatin1 clone of this string
|
||||
* Note that calls to this method should be matched with calls to Recycle().
|
||||
* @return ptr to new isolatin1 string
|
||||
*/
|
||||
char* ToNewCString() const;
|
||||
|
||||
/**
|
||||
* Creates an UTF8 clone of this string
|
||||
* Note that calls to this method should be matched with calls to Recycle().
|
||||
* @return ptr to new isolatin1 string
|
||||
*/
|
||||
char* ToNewUTF8String() const;
|
||||
|
||||
/**
|
||||
* Creates a unicode clone of this string
|
||||
* Note that calls to this method should be matched with calls to Recycle().
|
||||
* @return ptr to new unicode string
|
||||
*/
|
||||
PRUnichar* ToNewUnicode() const;
|
||||
|
||||
/**
|
||||
* Copies data from internal buffer onto given char* buffer
|
||||
* NOTE: This only copies as many chars as will fit in given buffer (clips)
|
||||
* @param aBuf is the buffer where data is stored
|
||||
* @param aBuflength is the max # of chars to move to buffer
|
||||
* @return ptr to given buffer
|
||||
*/
|
||||
char* ToCString(char* aBuf,PRUint32 aBufLength,PRUint32 anOffset=0) const;
|
||||
|
||||
/**
|
||||
* Perform string to float conversion.
|
||||
* @param aErrorCode will contain error if one occurs
|
||||
* @return float rep of string value
|
||||
*/
|
||||
float ToFloat(PRInt32* aErrorCode) const;
|
||||
|
||||
/**
|
||||
* Try to derive the radix from the value contained in this string
|
||||
* @return kRadix10, kRadix16 or kAutoDetect (meaning unknown)
|
||||
*/
|
||||
PRUint32 DetermineRadix(void);
|
||||
|
||||
/**
|
||||
* Perform string to int conversion.
|
||||
* @param aErrorCode will contain error if one occurs
|
||||
* @return int rep of string value
|
||||
*/
|
||||
PRInt32 ToInteger(PRInt32* aErrorCode,PRUint32 aRadix=kRadix10) const;
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
String manipulation methods...
|
||||
*********************************************************************/
|
||||
|
||||
/**
|
||||
* Functionally equivalent to assign or operator=
|
||||
*
|
||||
*/
|
||||
nsString& SetString(const char* aString,PRInt32 aLength=-1) {return Assign(aString,aLength);}
|
||||
nsString& SetString(const PRUnichar* aString,PRInt32 aLength=-1) {return Assign(aString,aLength);}
|
||||
nsString& SetString(const nsString& aString,PRInt32 aLength=-1) {return Assign(aString,aLength);}
|
||||
|
||||
/**
|
||||
* assign given string to this string
|
||||
* @param aStr: buffer to be assigned to this
|
||||
* @param alength is the length of the given str (or -1)
|
||||
if you want me to determine its length
|
||||
* @return this
|
||||
*/
|
||||
nsString& Assign(const nsStr& aString,PRInt32 aCount=-1);
|
||||
nsString& Assign(const char* aString,PRInt32 aCount=-1);
|
||||
nsString& Assign(const PRUnichar* aString,PRInt32 aCount=-1);
|
||||
nsString& Assign(char aChar);
|
||||
nsString& Assign(PRUnichar aChar);
|
||||
|
||||
/**
|
||||
* here come a bunch of assignment operators...
|
||||
* @param aString: string to be added to this
|
||||
* @return this
|
||||
*/
|
||||
nsString& operator=(const nsString& aString) {return Assign(aString);}
|
||||
nsString& operator=(const nsStr& aString) {return Assign(aString);}
|
||||
nsString& operator=(char aChar) {return Assign(aChar);}
|
||||
nsString& operator=(PRUnichar aChar) {return Assign(aChar);}
|
||||
nsString& operator=(const char* aCString) {return Assign(aCString);}
|
||||
nsString& operator=(const PRUnichar* aString) {return Assign(aString);}
|
||||
#ifdef AIX
|
||||
nsString& operator=(const nsSubsumeStr& aSubsumeString); // AIX requires a const here
|
||||
#else
|
||||
nsString& operator=(nsSubsumeStr& aSubsumeString);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Here's a bunch of methods that append varying types...
|
||||
* @param various...
|
||||
* @return this
|
||||
*/
|
||||
nsString& operator+=(const nsStr& aString){return Append(aString,aString.mLength);}
|
||||
nsString& operator+=(const nsString& aString){return Append(aString,aString.mLength);}
|
||||
nsString& operator+=(const char* aCString) {return Append(aCString);}
|
||||
//nsString& operator+=(char aChar){return Append(aChar);}
|
||||
nsString& operator+=(const PRUnichar* aUCString) {return Append(aUCString);}
|
||||
nsString& operator+=(PRUnichar aChar){return Append(aChar);}
|
||||
|
||||
/*
|
||||
* Appends n characters from given string to this,
|
||||
* This version computes the length of your given string
|
||||
*
|
||||
* @param aString is the source to be appended to this
|
||||
* @return number of chars copied
|
||||
*/
|
||||
nsString& Append(const nsStr& aString) {return Append(aString,aString.mLength);}
|
||||
nsString& Append(const nsString& aString) {return Append(aString,aString.mLength);}
|
||||
|
||||
|
||||
/*
|
||||
* Appends n characters from given string to this,
|
||||
*
|
||||
* @param aString is the source to be appended to this
|
||||
* @param aCount -- number of chars to copy; -1 tells us to compute the strlen for you
|
||||
* @return number of chars copied
|
||||
*/
|
||||
nsString& Append(const nsStr& aString,PRInt32 aCount);
|
||||
nsString& Append(const nsString& aString,PRInt32 aCount);
|
||||
nsString& Append(const char* aString,PRInt32 aCount=-1);
|
||||
nsString& Append(const PRUnichar* aString,PRInt32 aCount=-1);
|
||||
nsString& Append(char aChar);
|
||||
nsString& Append(PRUnichar aChar);
|
||||
nsString& Append(PRInt32 aInteger,PRInt32 aRadix=10); //radix=8,10 or 16
|
||||
nsString& Append(float aFloat);
|
||||
|
||||
/*
|
||||
* Copies n characters from this string to given string,
|
||||
* starting at the leftmost offset.
|
||||
*
|
||||
*
|
||||
* @param aCopy -- Receiving string
|
||||
* @param aCount -- number of chars to copy
|
||||
* @return number of chars copied
|
||||
*/
|
||||
PRUint32 Left(nsString& aCopy,PRInt32 aCount) const;
|
||||
|
||||
/*
|
||||
* Copies n characters from this string to given string,
|
||||
* starting at the given offset.
|
||||
*
|
||||
*
|
||||
* @param aCopy -- Receiving string
|
||||
* @param aCount -- number of chars to copy
|
||||
* @param anOffset -- position where copying begins
|
||||
* @return number of chars copied
|
||||
*/
|
||||
PRUint32 Mid(nsString& aCopy,PRUint32 anOffset,PRInt32 aCount) const;
|
||||
|
||||
/*
|
||||
* Copies n characters from this string to given string,
|
||||
* starting at rightmost char.
|
||||
*
|
||||
*
|
||||
* @param aCopy -- Receiving string
|
||||
* @param aCount -- number of chars to copy
|
||||
* @return number of chars copied
|
||||
*/
|
||||
PRUint32 Right(nsString& aCopy,PRInt32 aCount) const;
|
||||
|
||||
/*
|
||||
* This method inserts n chars from given string into this
|
||||
* string at str[anOffset].
|
||||
*
|
||||
* @param aCopy -- String to be inserted into this
|
||||
* @param anOffset -- insertion position within this str
|
||||
* @param aCount -- number of chars to be copied from aCopy
|
||||
* @return number of chars inserted into this.
|
||||
*/
|
||||
nsString& Insert(const nsString& aCopy,PRUint32 anOffset,PRInt32 aCount=-1);
|
||||
|
||||
/**
|
||||
* Insert a given string into this string at
|
||||
* a specified offset.
|
||||
*
|
||||
* @param aString* to be inserted into this string
|
||||
* @param anOffset is insert pos in str
|
||||
* @return the number of chars inserted into this string
|
||||
*/
|
||||
nsString& Insert(const char* aChar,PRUint32 anOffset,PRInt32 aCount=-1);
|
||||
nsString& Insert(const PRUnichar* aChar,PRUint32 anOffset,PRInt32 aCount=-1);
|
||||
|
||||
/**
|
||||
* Insert a single char into this string at
|
||||
* a specified offset.
|
||||
*
|
||||
* @param character to be inserted into this string
|
||||
* @param anOffset is insert pos in str
|
||||
* @return the number of chars inserted into this string
|
||||
*/
|
||||
//nsString& Insert(char aChar,PRUint32 anOffset);
|
||||
nsString& Insert(PRUnichar aChar,PRUint32 anOffset);
|
||||
|
||||
/*
|
||||
* This method is used to cut characters in this string
|
||||
* starting at anOffset, continuing for aCount chars.
|
||||
*
|
||||
* @param anOffset -- start pos for cut operation
|
||||
* @param aCount -- number of chars to be cut
|
||||
* @return *this
|
||||
*/
|
||||
nsString& Cut(PRUint32 anOffset,PRInt32 aCount);
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
Searching methods...
|
||||
*********************************************************************/
|
||||
|
||||
/**
|
||||
* Search for given character within this string.
|
||||
* This method does so by using a binary search,
|
||||
* so your string HAD BETTER BE ORDERED!
|
||||
*
|
||||
* @param aChar is the unicode char to be found
|
||||
* @return offset in string, or -1 (kNotFound)
|
||||
*/
|
||||
PRInt32 BinarySearch(PRUnichar aChar) const;
|
||||
|
||||
/**
|
||||
* Search for given substring within this string
|
||||
*
|
||||
* @param aString is substring to be sought in this
|
||||
* @param aIgnoreCase selects case sensitivity
|
||||
* @param anOffset tells us where in this strig to start searching
|
||||
* @return offset in string, or -1 (kNotFound)
|
||||
*/
|
||||
PRInt32 Find(const nsString& aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1) const;
|
||||
PRInt32 Find(const nsStr& aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1) const;
|
||||
PRInt32 Find(const char* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1) const;
|
||||
PRInt32 Find(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1) const;
|
||||
|
||||
|
||||
/**
|
||||
* Search for given char within this string
|
||||
*
|
||||
* @param aString is substring to be sought in this
|
||||
* @param anOffset tells us where in this strig to start searching
|
||||
* @param aIgnoreCase selects case sensitivity
|
||||
* @return find pos in string, or -1 (kNotFound)
|
||||
*/
|
||||
//PRInt32 Find(PRUnichar aChar,PRInt32 offset=-1,PRBool aIgnoreCase=PR_FALSE) const;
|
||||
PRInt32 FindChar(PRUnichar aChar,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1) const;
|
||||
|
||||
/**
|
||||
* This method searches this string for the first character
|
||||
* found in the given charset
|
||||
* @param aString contains set of chars to be found
|
||||
* @param anOffset tells us where to start searching in this
|
||||
* @return -1 if not found, else the offset in this
|
||||
*/
|
||||
PRInt32 FindCharInSet(const char* aString,PRInt32 anOffset=-1) const;
|
||||
PRInt32 FindCharInSet(const PRUnichar* aString,PRInt32 anOffset=-1) const;
|
||||
PRInt32 FindCharInSet(const nsStr& aString,PRInt32 anOffset=-1) const;
|
||||
|
||||
|
||||
/**
|
||||
* This methods scans the string backwards, looking for the given string
|
||||
* @param aString is substring to be sought in this
|
||||
* @param aIgnoreCase tells us whether or not to do caseless compare
|
||||
* @param anOffset tells us where in this strig to start searching (counting from left)
|
||||
*/
|
||||
PRInt32 RFind(const char* aCString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1) const;
|
||||
PRInt32 RFind(const nsString& aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1) const;
|
||||
PRInt32 RFind(const nsStr& aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1) const;
|
||||
PRInt32 RFind(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1) const;
|
||||
|
||||
|
||||
/**
|
||||
* Search for given char within this string
|
||||
*
|
||||
* @param aString is substring to be sought in this
|
||||
* @param anOffset tells us where in this strig to start searching (counting from left)
|
||||
* @param aIgnoreCase selects case sensitivity
|
||||
* @return find pos in string, or -1 (kNotFound)
|
||||
*/
|
||||
//PRInt32 RFind(PRUnichar aChar,PRInt32 offset=-1,PRBool aIgnoreCase=PR_FALSE) const;
|
||||
PRInt32 RFindChar(PRUnichar aChar,PRBool aIgnoreCase=PR_FALSE,PRInt32 anOffset=-1) const;
|
||||
|
||||
/**
|
||||
* This method searches this string for the last character
|
||||
* found in the given string
|
||||
* @param aString contains set of chars to be found
|
||||
* @param anOffset tells us where in this strig to start searching (counting from left)
|
||||
* @return -1 if not found, else the offset in this
|
||||
*/
|
||||
PRInt32 RFindCharInSet(const char* aString,PRInt32 anOffset=-1) const;
|
||||
PRInt32 RFindCharInSet(const PRUnichar* aString,PRInt32 anOffset=-1) const;
|
||||
PRInt32 RFindCharInSet(const nsStr& aString,PRInt32 anOffset=-1) const;
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
Comparison methods...
|
||||
*********************************************************************/
|
||||
|
||||
/**
|
||||
* Compares a given string type to this string.
|
||||
* @update gess 7/27/98
|
||||
* @param S is the string to be compared
|
||||
* @param aIgnoreCase tells us how to treat case
|
||||
* @param aCount tells us how many chars to compare
|
||||
* @return -1,0,1
|
||||
*/
|
||||
virtual PRInt32 Compare(const nsString& aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const;
|
||||
virtual PRInt32 Compare(const nsStr &aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const;
|
||||
virtual PRInt32 Compare(const char* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const;
|
||||
virtual PRInt32 Compare(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const;
|
||||
|
||||
/**
|
||||
* These methods compare a given string type to this one
|
||||
* @param aString is the string to be compared to this
|
||||
* @return TRUE or FALSE
|
||||
*/
|
||||
PRBool operator==(const nsString &aString) const;
|
||||
PRBool operator==(const nsStr &aString) const;
|
||||
PRBool operator==(const char *aString) const;
|
||||
PRBool operator==(const PRUnichar* aString) const;
|
||||
|
||||
/**
|
||||
* These methods perform a !compare of a given string type to this
|
||||
* @param aString is the string to be compared to this
|
||||
* @return TRUE
|
||||
*/
|
||||
PRBool operator!=(const nsString &aString) const;
|
||||
PRBool operator!=(const nsStr &aString) const;
|
||||
PRBool operator!=(const char* aString) const;
|
||||
PRBool operator!=(const PRUnichar* aString) const;
|
||||
|
||||
/**
|
||||
* These methods test if a given string is < than this
|
||||
* @param aString is the string to be compared to this
|
||||
* @return TRUE or FALSE
|
||||
*/
|
||||
PRBool operator<(const nsString &aString) const;
|
||||
PRBool operator<(const nsStr &aString) const;
|
||||
PRBool operator<(const char* aString) const;
|
||||
PRBool operator<(const PRUnichar* aString) const;
|
||||
|
||||
/**
|
||||
* These methods test if a given string is > than this
|
||||
* @param aString is the string to be compared to this
|
||||
* @return TRUE or FALSE
|
||||
*/
|
||||
PRBool operator>(const nsString &aString) const;
|
||||
PRBool operator>(const nsStr &S) const;
|
||||
PRBool operator>(const char* aString) const;
|
||||
PRBool operator>(const PRUnichar* aString) const;
|
||||
|
||||
/**
|
||||
* These methods test if a given string is <= than this
|
||||
* @param aString is the string to be compared to this
|
||||
* @return TRUE or FALSE
|
||||
*/
|
||||
PRBool operator<=(const nsString &aString) const;
|
||||
PRBool operator<=(const nsStr &S) const;
|
||||
PRBool operator<=(const char* aString) const;
|
||||
PRBool operator<=(const PRUnichar* aString) const;
|
||||
|
||||
/**
|
||||
* These methods test if a given string is >= than this
|
||||
* @param aString is the string to be compared to this
|
||||
* @return TRUE or FALSE
|
||||
*/
|
||||
PRBool operator>=(const nsString &aString) const;
|
||||
PRBool operator>=(const nsStr &S) const;
|
||||
PRBool operator>=(const char* aString) const;
|
||||
PRBool operator>=(const PRUnichar* aString) const;
|
||||
|
||||
/**
|
||||
* Compare this to given string; note that we compare full strings here.
|
||||
* The optional length argument just lets us know how long the given string is.
|
||||
* If you provide a length, it is compared to length of this string as an
|
||||
* optimization.
|
||||
*
|
||||
* @param aString -- the string to compare to this
|
||||
* @param aCount -- number of chars to be compared.
|
||||
* @return TRUE if equal
|
||||
*/
|
||||
PRBool Equals(const nsString &aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const;
|
||||
PRBool Equals(const nsStr& aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const;
|
||||
PRBool Equals(const char* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const;
|
||||
PRBool Equals(const PRUnichar* aString,PRBool aIgnoreCase=PR_FALSE,PRInt32 aCount=-1) const;
|
||||
PRBool Equals(/*FIX: const */nsIAtom* anAtom,PRBool aIgnoreCase) const;
|
||||
PRBool Equals(const PRUnichar* s1, const PRUnichar* s2,PRBool aIgnoreCase=PR_FALSE) const;
|
||||
|
||||
PRBool EqualsIgnoreCase(const nsString& aString) const;
|
||||
PRBool EqualsIgnoreCase(const char* aString,PRInt32 aCount=-1) const;
|
||||
PRBool EqualsIgnoreCase(/*FIX: const */nsIAtom *aAtom) const;
|
||||
PRBool EqualsIgnoreCase(const PRUnichar* s1, const PRUnichar* s2) const;
|
||||
|
||||
/**
|
||||
* Determine if given buffer is plain ascii
|
||||
*
|
||||
* @param aBuffer -- if null, then we test *this, otherwise we test given buffer
|
||||
* @return TRUE if is all ascii chars or if strlen==0
|
||||
*/
|
||||
PRBool IsASCII(const PRUnichar* aBuffer=0);
|
||||
|
||||
|
||||
/**
|
||||
* Determine if given char is a valid space character
|
||||
*
|
||||
* @param aChar is character to be tested
|
||||
* @return TRUE if is valid space char
|
||||
*/
|
||||
static PRBool IsSpace(PRUnichar ch);
|
||||
|
||||
/**
|
||||
* Determine if given char in valid alpha range
|
||||
*
|
||||
* @param aChar is character to be tested
|
||||
* @return TRUE if in alpha range
|
||||
*/
|
||||
static PRBool IsAlpha(PRUnichar ch);
|
||||
|
||||
/**
|
||||
* Determine if given char is valid digit
|
||||
*
|
||||
* @param aChar is character to be tested
|
||||
* @return TRUE if char is a valid digit
|
||||
*/
|
||||
static PRBool IsDigit(PRUnichar ch);
|
||||
|
||||
static void Recycle(nsString* aString);
|
||||
static nsString* CreateString(void);
|
||||
|
||||
};
|
||||
|
||||
extern NS_COM int fputs(const nsString& aString, FILE* out);
|
||||
//ostream& operator<<(ostream& aStream,const nsString& aString);
|
||||
//virtual void DebugDump(ostream& aStream) const;
|
||||
|
||||
|
||||
/**************************************************************
|
||||
Here comes the AutoString class which uses internal memory
|
||||
(typically found on the stack) for its default buffer.
|
||||
If the buffer needs to grow, it gets reallocated on the heap.
|
||||
**************************************************************/
|
||||
|
||||
class NS_COM nsAutoString : public nsString {
|
||||
public:
|
||||
|
||||
nsAutoString();
|
||||
nsAutoString(const char* aCString,PRInt32 aLength=-1);
|
||||
nsAutoString(const PRUnichar* aString,PRInt32 aLength=-1);
|
||||
|
||||
nsAutoString(const CBufDescriptor& aBuffer);
|
||||
nsAutoString(const nsStr& aString);
|
||||
nsAutoString(const nsAutoString& aString);
|
||||
#ifdef AIX
|
||||
nsAutoString(const nsSubsumeStr& aSubsumeStr); // AIX requires a const
|
||||
#else
|
||||
nsAutoString(nsSubsumeStr& aSubsumeStr);
|
||||
#endif // AIX
|
||||
nsAutoString(PRUnichar aChar);
|
||||
virtual ~nsAutoString();
|
||||
|
||||
nsAutoString& operator=(const nsStr& aString) {nsString::Assign(aString); return *this;}
|
||||
nsAutoString& operator=(const nsAutoString& aString) {nsString::Assign(aString); return *this;}
|
||||
nsAutoString& operator=(const char* aCString) {nsString::Assign(aCString); return *this;}
|
||||
nsAutoString& operator=(char aChar) {nsString::Assign(aChar); return *this;}
|
||||
nsAutoString& operator=(const PRUnichar* aBuffer) {nsString::Assign(aBuffer); return *this;}
|
||||
nsAutoString& operator=(PRUnichar aChar) {nsString::Assign(aChar); return *this;}
|
||||
|
||||
/**
|
||||
* Retrieve the size of this string
|
||||
* @return string length
|
||||
*/
|
||||
virtual void SizeOf(nsISizeOfHandler* aHandler, PRUint32* aResult) const;
|
||||
|
||||
char mBuffer[kDefaultStringSize<<eTwoByte];
|
||||
};
|
||||
|
||||
|
||||
|
||||
/***************************************************************
|
||||
The subsumestr class is very unusual.
|
||||
It differs from a normal string in that it doesn't use normal
|
||||
copy semantics when another string is assign to this.
|
||||
Instead, it "steals" the contents of the source string.
|
||||
|
||||
This is very handy for returning nsString classes as part of
|
||||
an operator+(...) for example, in that it cuts down the number
|
||||
of copy operations that must occur.
|
||||
|
||||
You should probably not use this class unless you really know
|
||||
what you're doing.
|
||||
***************************************************************/
|
||||
class NS_COM nsSubsumeStr : public nsString {
|
||||
public:
|
||||
nsSubsumeStr(nsStr& aString);
|
||||
nsSubsumeStr(PRUnichar* aString,PRBool assumeOwnership,PRInt32 aLength=-1);
|
||||
nsSubsumeStr(char* aString,PRBool assumeOwnership,PRInt32 aLength=-1);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
179
mozilla/string/obsolete/nsXPIDLString.cpp
Normal file
179
mozilla/string/obsolete/nsXPIDLString.cpp
Normal file
@@ -0,0 +1,179 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 "nsDebug.h"
|
||||
#include "nsIAllocator.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "plstr.h"
|
||||
|
||||
// If the allocator changes, fix it here.
|
||||
#define XPIDL_STRING_ALLOC(__len) ((PRUnichar*) nsAllocator::Alloc((__len) * sizeof(PRUnichar)))
|
||||
#define XPIDL_CSTRING_ALLOC(__len) ((char*) nsAllocator::Alloc((__len) * sizeof(char)))
|
||||
#define XPIDL_FREE(__ptr) (nsAllocator::Free(__ptr))
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// nsXPIDLString
|
||||
|
||||
nsXPIDLString::nsXPIDLString()
|
||||
: mBuf(0),
|
||||
mBufOwner(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
nsXPIDLString::~nsXPIDLString()
|
||||
{
|
||||
if (mBufOwner && mBuf)
|
||||
XPIDL_FREE(mBuf);
|
||||
}
|
||||
|
||||
|
||||
nsXPIDLString::operator const PRUnichar*()
|
||||
{
|
||||
return mBuf;
|
||||
}
|
||||
|
||||
|
||||
PRUnichar*
|
||||
nsXPIDLString::Copy(const PRUnichar* aString)
|
||||
{
|
||||
NS_ASSERTION(aString, "null ptr");
|
||||
if (! aString)
|
||||
return 0;
|
||||
|
||||
PRInt32 len = 0;
|
||||
|
||||
{
|
||||
const PRUnichar* p = aString;
|
||||
while (*p++)
|
||||
len++;
|
||||
}
|
||||
|
||||
PRUnichar* result = XPIDL_STRING_ALLOC(len + 1);
|
||||
if (result) {
|
||||
PRUnichar* q = result;
|
||||
while (*aString) {
|
||||
*q = *aString;
|
||||
q++;
|
||||
aString++;
|
||||
}
|
||||
*q = '\0';
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
PRUnichar**
|
||||
nsXPIDLString::StartAssignmentByValue()
|
||||
{
|
||||
if (mBufOwner && mBuf)
|
||||
XPIDL_FREE(mBuf);
|
||||
|
||||
mBuf = 0;
|
||||
mBufOwner = PR_TRUE;
|
||||
return &mBuf;
|
||||
}
|
||||
|
||||
|
||||
const PRUnichar**
|
||||
nsXPIDLString::StartAssignmentByReference()
|
||||
{
|
||||
if (mBufOwner && mBuf)
|
||||
XPIDL_FREE(mBuf);
|
||||
|
||||
mBuf = 0;
|
||||
mBufOwner = PR_FALSE;
|
||||
return (const PRUnichar**) &mBuf;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// nsXPIDLCString
|
||||
|
||||
nsXPIDLCString::nsXPIDLCString()
|
||||
: mBuf(0),
|
||||
mBufOwner(PR_FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
nsXPIDLCString::~nsXPIDLCString()
|
||||
{
|
||||
if (mBufOwner && mBuf)
|
||||
XPIDL_FREE(mBuf);
|
||||
}
|
||||
|
||||
|
||||
nsXPIDLCString& nsXPIDLCString::operator =(const char* aCString)
|
||||
{
|
||||
if (mBufOwner && mBuf)
|
||||
XPIDL_FREE(mBuf);
|
||||
|
||||
mBuf = Copy(aCString);
|
||||
mBufOwner = PR_TRUE;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
nsXPIDLCString::operator const char*()
|
||||
{
|
||||
return mBuf;
|
||||
}
|
||||
|
||||
|
||||
char*
|
||||
nsXPIDLCString::Copy(const char* aCString)
|
||||
{
|
||||
NS_ASSERTION(aCString, "null ptr");
|
||||
if (! aCString)
|
||||
return 0;
|
||||
|
||||
PRInt32 len = PL_strlen(aCString);
|
||||
char* result = XPIDL_CSTRING_ALLOC(len + 1);
|
||||
if (result)
|
||||
PL_strcpy(result, aCString);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
char**
|
||||
nsXPIDLCString::StartAssignmentByValue()
|
||||
{
|
||||
if (mBufOwner && mBuf)
|
||||
XPIDL_FREE(mBuf);
|
||||
|
||||
mBuf = 0;
|
||||
mBufOwner = PR_TRUE;
|
||||
return &mBuf;
|
||||
}
|
||||
|
||||
|
||||
const char**
|
||||
nsXPIDLCString::StartAssignmentByReference()
|
||||
{
|
||||
if (mBufOwner && mBuf)
|
||||
XPIDL_FREE(mBuf);
|
||||
|
||||
mBuf = 0;
|
||||
mBufOwner = PR_FALSE;
|
||||
return (const char**) &mBuf;
|
||||
}
|
||||
|
||||
|
||||
302
mozilla/string/obsolete/nsXPIDLString.h
Normal file
302
mozilla/string/obsolete/nsXPIDLString.h
Normal file
@@ -0,0 +1,302 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
A set of string wrapper classes that ease transition to use of XPIDL
|
||||
interfaces. nsXPIDLString and nsXPIDLCString are to XPIDL `wstring'
|
||||
and `string' out params as nsCOMPtr is to generic XPCOM interface
|
||||
pointers. They help you deal with object ownership.
|
||||
|
||||
Consider the following interface:
|
||||
|
||||
interface nsIFoo {
|
||||
attribute string Bar;
|
||||
};
|
||||
|
||||
This will generate the following C++ header file:
|
||||
|
||||
class nsIFoo {
|
||||
NS_IMETHOD SetBar(const PRUnichar* aValue);
|
||||
NS_IMETHOD GetBar(PRUnichar* *aValue);
|
||||
};
|
||||
|
||||
The GetBar() method will allocate a copy of the nsIFoo object's
|
||||
"bar" attribute, and leave you to deal with freeing it:
|
||||
|
||||
nsIFoo* aFoo; // assume we get this somehow
|
||||
PRUnichar* bar;
|
||||
aFoo->GetFoo(&bar);
|
||||
// Use bar here...
|
||||
printf("bar is %s!\n", bar);
|
||||
nsAllocator::Free(bar);
|
||||
|
||||
This makes your life harder, because you need to convolute your code
|
||||
to ensure that you don't leak `bar'.
|
||||
|
||||
Enter nsXPIDLString, which manages the ownership of the allocated
|
||||
string, and automatically destroys it when the nsXPIDLString goes
|
||||
out of scope:
|
||||
|
||||
nsIFoo* aFoo;
|
||||
nsXPIDLString bar;
|
||||
aFoo->GetFoo( getter_Copies(bar) );
|
||||
// Use bar here...
|
||||
printf("bar is %s!\n", (const char*) bar);
|
||||
// no need to remember to nsAllocator::Free().
|
||||
|
||||
Like nsCOMPtr, nsXPIDLString uses some syntactic sugar to make it
|
||||
painfully clear exactly what the code expects. You need to wrap an
|
||||
nsXPIDLString object with either `getter_Copies()' or
|
||||
`getter_Shares()' before passing it to a getter: these tell the
|
||||
nsXPIDLString how ownership is being handled.
|
||||
|
||||
In the case of `getter_Copies()', the callee is allocating a copy
|
||||
(which is usually the case). In the case of `getter_Shares()', the
|
||||
callee is returning a const reference to `the real deal' (this can
|
||||
be done using the [shared] attribute in XPIDL).
|
||||
|
||||
*/
|
||||
|
||||
#ifndef nsXPIDLString_h__
|
||||
#define nsXPIDLString_h__
|
||||
|
||||
#include "nsCom.h"
|
||||
#include "prtypes.h"
|
||||
|
||||
#ifndef __PRUNICHAR__
|
||||
#define __PRUNICHAR__
|
||||
typedef PRUint16 PRUnichar;
|
||||
#endif /* __PRUNICHAR__ */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// nsXPIDLString
|
||||
//
|
||||
// A wrapper for Unicode strings. With the |getter_Copies()| and
|
||||
// |getter_Shares()| helper functions, this can be used instead of
|
||||
// the "naked" |PRUnichar*| interface for |wstring| parameters in
|
||||
// XPIDL interfaces.
|
||||
//
|
||||
|
||||
class NS_COM nsXPIDLString {
|
||||
private:
|
||||
PRUnichar* mBuf;
|
||||
PRBool mBufOwner;
|
||||
|
||||
PRUnichar** StartAssignmentByValue();
|
||||
const PRUnichar** StartAssignmentByReference();
|
||||
|
||||
public:
|
||||
/**
|
||||
* Construct a new, uninitialized wrapper for a Unicode string.
|
||||
*/
|
||||
nsXPIDLString();
|
||||
|
||||
virtual ~nsXPIDLString();
|
||||
|
||||
/**
|
||||
* Return a reference to the immutable Unicode string.
|
||||
*/
|
||||
operator const PRUnichar*();
|
||||
|
||||
/**
|
||||
* Make a copy of the Unicode string. Use this function in the
|
||||
* callee to ensure that the correct memory allocator is used.
|
||||
*/
|
||||
static PRUnichar* Copy(const PRUnichar* aString);
|
||||
|
||||
// A helper class for assignment-by-value. This class is an
|
||||
// implementation detail and should not be considered part of the
|
||||
// public interface.
|
||||
class NS_COM GetterCopies {
|
||||
private:
|
||||
nsXPIDLString& mXPIDLString;
|
||||
|
||||
public:
|
||||
GetterCopies(nsXPIDLString& aXPIDLString)
|
||||
: mXPIDLString(aXPIDLString) {}
|
||||
|
||||
operator PRUnichar**() {
|
||||
return mXPIDLString.StartAssignmentByValue();
|
||||
}
|
||||
|
||||
friend GetterCopies getter_Copies(nsXPIDLString& aXPIDLString);
|
||||
};
|
||||
|
||||
friend class GetterCopies;
|
||||
|
||||
// A helper class for assignment-by-reference. This class is an
|
||||
// implementation detail and should not be considered part of the
|
||||
// public interface.
|
||||
class NS_COM GetterShares {
|
||||
private:
|
||||
nsXPIDLString& mXPIDLString;
|
||||
|
||||
public:
|
||||
GetterShares(nsXPIDLString& aXPIDLString)
|
||||
: mXPIDLString(aXPIDLString) {}
|
||||
|
||||
operator const PRUnichar**() {
|
||||
return mXPIDLString.StartAssignmentByReference();
|
||||
}
|
||||
|
||||
friend GetterShares getter_Shares(nsXPIDLString& aXPIDLString);
|
||||
};
|
||||
|
||||
friend class GetterShares;
|
||||
|
||||
private:
|
||||
// not to be implemented
|
||||
nsXPIDLString(nsXPIDLString& /* aXPIDLString */) {}
|
||||
nsXPIDLString& operator =(nsXPIDLString& /* aXPIDLString */) { return *this; }
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Use this function to "wrap" the nsXPIDLString object that is to
|
||||
* receive an |out| value.
|
||||
*/
|
||||
inline nsXPIDLString::GetterCopies
|
||||
getter_Copies(nsXPIDLString& aXPIDLString)
|
||||
{
|
||||
return nsXPIDLString::GetterCopies(aXPIDLString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use this function to "wrap" the nsXPIDLString object that is to
|
||||
* receive a |[shared] out| value.
|
||||
*/
|
||||
inline nsXPIDLString::GetterShares
|
||||
getter_Shares(nsXPIDLString& aXPIDLString)
|
||||
{
|
||||
return nsXPIDLString::GetterShares(aXPIDLString);
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// nsXPIDLCString
|
||||
//
|
||||
// A wrapper for Unicode strings. With the |getter_Copies()| and
|
||||
// |getter_Shares()| helper functions, this can be used instead of
|
||||
// the "naked" |char*| interface for |string| parameters in XPIDL
|
||||
// interfaces.
|
||||
//
|
||||
|
||||
class NS_COM nsXPIDLCString {
|
||||
private:
|
||||
char* mBuf;
|
||||
PRBool mBufOwner;
|
||||
|
||||
char** StartAssignmentByValue();
|
||||
const char** StartAssignmentByReference();
|
||||
|
||||
public:
|
||||
/**
|
||||
* Construct a new, uninitialized wrapper for a single-byte string.
|
||||
*/
|
||||
nsXPIDLCString();
|
||||
|
||||
virtual ~nsXPIDLCString();
|
||||
|
||||
/**
|
||||
* Assign a single-byte string to this wrapper. Copies and owns the result.
|
||||
*/
|
||||
nsXPIDLCString& operator =(const char* aString);
|
||||
|
||||
/**
|
||||
* Return a reference to the immutable single-byte string.
|
||||
*/
|
||||
operator const char*();
|
||||
|
||||
/**
|
||||
* Make a copy of the single-byte string. Use this function in the
|
||||
* callee to ensure that the correct memory allocator is used.
|
||||
*/
|
||||
static char* Copy(const char* aString);
|
||||
|
||||
// A helper class for assignment-by-value. This class is an
|
||||
// implementation detail and should not be considered part of the
|
||||
// public interface.
|
||||
class NS_COM GetterCopies {
|
||||
private:
|
||||
nsXPIDLCString& mXPIDLString;
|
||||
|
||||
public:
|
||||
GetterCopies(nsXPIDLCString& aXPIDLString)
|
||||
: mXPIDLString(aXPIDLString) {}
|
||||
|
||||
operator char**() {
|
||||
return mXPIDLString.StartAssignmentByValue();
|
||||
}
|
||||
|
||||
friend GetterCopies getter_Copies(nsXPIDLCString& aXPIDLString);
|
||||
};
|
||||
|
||||
friend class GetterCopies;
|
||||
|
||||
// A helper class for assignment-by-reference. This class is an
|
||||
// implementation detail and should not be considered part of the
|
||||
// public interface.
|
||||
class NS_COM GetterShares {
|
||||
private:
|
||||
nsXPIDLCString& mXPIDLString;
|
||||
|
||||
public:
|
||||
GetterShares(nsXPIDLCString& aXPIDLString)
|
||||
: mXPIDLString(aXPIDLString) {}
|
||||
|
||||
operator const char**() {
|
||||
return mXPIDLString.StartAssignmentByReference();
|
||||
}
|
||||
|
||||
friend GetterShares getter_Shares(nsXPIDLCString& aXPIDLString);
|
||||
};
|
||||
|
||||
friend class GetterShares;
|
||||
|
||||
private:
|
||||
// not to be implemented
|
||||
nsXPIDLCString(nsXPIDLCString& /* aXPIDLString */) {}
|
||||
nsXPIDLCString& operator =(nsXPIDLCString& /* aXPIDLCString */) { return *this; }
|
||||
};
|
||||
|
||||
/**
|
||||
* Use this function to "wrap" the nsXPIDLCString object that is to
|
||||
* receive an |out| value.
|
||||
*/
|
||||
inline nsXPIDLCString::GetterCopies
|
||||
getter_Copies(nsXPIDLCString& aXPIDLString)
|
||||
{
|
||||
return nsXPIDLCString::GetterCopies(aXPIDLString);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Use this function to "wrap" the nsXPIDLCString object that is to
|
||||
* receive a |[shared] out| value.
|
||||
*/
|
||||
inline nsXPIDLCString::GetterShares
|
||||
getter_Shares(nsXPIDLCString& aXPIDLString)
|
||||
{
|
||||
return nsXPIDLCString::GetterShares(aXPIDLString);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif // nsXPIDLString_h__
|
||||
30
mozilla/xpcom/ds/MANIFEST
Normal file
30
mozilla/xpcom/ds/MANIFEST
Normal file
@@ -0,0 +1,30 @@
|
||||
nsAVLTree.h
|
||||
nsCppSharedAllocator.h
|
||||
nsCRT.h
|
||||
nsDeque.h
|
||||
nsEnumeratorUtils.h
|
||||
nsHashtable.h
|
||||
nsHashtableEnumerator.h
|
||||
nsIArena.h
|
||||
nsIBuffer.h
|
||||
nsIByteBuffer.h
|
||||
nsIObserverList.h
|
||||
nsIPageManager.h
|
||||
nsIProperties.h
|
||||
nsISimpleEnumerator.h
|
||||
nsISizeOfHandler.h
|
||||
nsIUnicharBuffer.h
|
||||
nsIVariant.h
|
||||
nsInt64.h
|
||||
nsQuickSort.h
|
||||
nsStr.h
|
||||
nsString.h
|
||||
nsString2.h
|
||||
nsSupportsPrimitives.h
|
||||
nsTime.h
|
||||
nsUnitConversion.h
|
||||
nsVector.h
|
||||
nsVoidArray.h
|
||||
nsXPIDLString.h
|
||||
plvector.h
|
||||
nsTextFormater.h
|
||||
6
mozilla/xpcom/ds/MANIFEST_IDL
Normal file
6
mozilla/xpcom/ds/MANIFEST_IDL
Normal file
@@ -0,0 +1,6 @@
|
||||
nsIAtom.idl
|
||||
nsICollection.idl
|
||||
nsIEnumerator.idl
|
||||
nsIObserver.idl
|
||||
nsIObserverService.idl
|
||||
nsISupportsArray.idl
|
||||
113
mozilla/xpcom/ds/Makefile.in
Normal file
113
mozilla/xpcom/ds/Makefile.in
Normal file
@@ -0,0 +1,113 @@
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
DEPTH = ../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = xpcom
|
||||
XPIDL_MODULE = xpcom_ds
|
||||
LIBRARY_NAME = xpcomds_s
|
||||
|
||||
REQUIRES = xpcom uconv unicharutil
|
||||
|
||||
CPPSRCS = \
|
||||
nsArena.cpp \
|
||||
nsAtomTable.cpp \
|
||||
nsAVLTree.cpp \
|
||||
nsByteBuffer.cpp \
|
||||
nsCRT.cpp \
|
||||
nsConjoiningEnumerator.cpp \
|
||||
nsDeque.cpp \
|
||||
nsEmptyEnumerator.cpp \
|
||||
nsEnumeratorUtils.cpp \
|
||||
nsHashtable.cpp \
|
||||
nsHashtableEnumerator.cpp \
|
||||
nsObserver.cpp \
|
||||
nsObserverList.cpp \
|
||||
nsObserverService.cpp \
|
||||
nsProperties.cpp \
|
||||
nsQuickSort.cpp \
|
||||
nsSizeOfHandler.cpp \
|
||||
nsStr.cpp \
|
||||
nsString.cpp \
|
||||
nsString2.cpp \
|
||||
nsSupportsArray.cpp \
|
||||
nsSupportsArrayEnumerator.cpp \
|
||||
nsSupportsPrimitives.cpp \
|
||||
nsUnicharBuffer.cpp \
|
||||
nsVariant.cpp \
|
||||
nsVoidArray.cpp \
|
||||
nsXPIDLString.cpp \
|
||||
plvector.cpp \
|
||||
nsTextFormater.cpp \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS = \
|
||||
nsAVLTree.h \
|
||||
nsCppSharedAllocator.h \
|
||||
nsCRT.h \
|
||||
nsDeque.h \
|
||||
nsEnumeratorUtils.h \
|
||||
nsHashtable.h \
|
||||
nsHashtableEnumerator.h \
|
||||
nsIArena.h \
|
||||
nsIByteBuffer.h \
|
||||
nsIObserverList.h \
|
||||
nsIProperties.h \
|
||||
nsISimpleEnumerator.h \
|
||||
nsISizeOfHandler.h \
|
||||
nsIUnicharBuffer.h \
|
||||
nsIVariant.h \
|
||||
nsInt64.h \
|
||||
nsQuickSort.h \
|
||||
nsStr.h \
|
||||
nsString.h \
|
||||
nsString2.h \
|
||||
nsSupportsPrimitives.h \
|
||||
nsTime.h \
|
||||
nsUnitConversion.h \
|
||||
nsVector.h \
|
||||
nsVoidArray.h \
|
||||
nsXPIDLString.h \
|
||||
plvector.h \
|
||||
nsTextFormater.h \
|
||||
$(NULL)
|
||||
|
||||
XPIDLSRCS = \
|
||||
nsIAtom.idl \
|
||||
nsICollection.idl \
|
||||
nsIEnumerator.idl \
|
||||
nsIObserver.idl \
|
||||
nsIObserverService.idl \
|
||||
nsISupportsArray.idl \
|
||||
nsISupportsPrimitives.idl \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
|
||||
|
||||
# we don't want the shared lib, but we want to force the creation of a static lib.
|
||||
override NO_SHARED_LIB=1
|
||||
override NO_STATIC_LIB=
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
DEFINES += -D_IMPL_NS_COM -D_IMPL_NS_BASE
|
||||
|
||||
758
mozilla/xpcom/ds/bufferRoutines.h
Normal file
758
mozilla/xpcom/ds/bufferRoutines.h
Normal file
@@ -0,0 +1,758 @@
|
||||
/* -*- Mode: C++; tab-width: 2; 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.
|
||||
*/
|
||||
|
||||
/******************************************************************************************
|
||||
MODULE NOTES:
|
||||
|
||||
This file contains the workhorse copy and shift functions used in nsStrStruct.
|
||||
Ultimately, I plan to make the function pointers in this system available for
|
||||
use by external modules. They'll be able to install their own "handlers".
|
||||
Not so, today though.
|
||||
|
||||
*******************************************************************************************/
|
||||
|
||||
#ifndef _BUFFERROUTINES_H
|
||||
#define _BUFFERROUTINES_H
|
||||
|
||||
#include "nsCRT.h"
|
||||
|
||||
#ifndef RICKG_TESTBED
|
||||
#include "nsUnicharUtilCIID.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsICaseConversion.h"
|
||||
#endif
|
||||
|
||||
#define KSHIFTLEFT (0)
|
||||
#define KSHIFTRIGHT (1)
|
||||
|
||||
|
||||
inline PRUnichar GetUnicharAt(const char* aString,PRUint32 anIndex) {
|
||||
return ((PRUnichar*)aString)[anIndex];
|
||||
}
|
||||
|
||||
inline PRUnichar GetCharAt(const char* aString,PRUint32 anIndex) {
|
||||
return (PRUnichar)aString[anIndex];
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
//
|
||||
// This set of methods is used to shift the contents of a char buffer.
|
||||
// The functions are differentiated by shift direction and the underlying charsize.
|
||||
//
|
||||
|
||||
/**
|
||||
* This method shifts single byte characters left by a given amount from an given offset.
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is a ptr to a cstring where left-shift is to be performed
|
||||
* @param aLength is the known length of aDest
|
||||
* @param anOffset is the index into aDest where shifting shall begin
|
||||
* @param aCount is the number of chars to be "cut"
|
||||
*/
|
||||
void ShiftCharsLeft(char* aDest,PRUint32 aLength,PRUint32 anOffset,PRUint32 aCount) {
|
||||
char* dst = aDest+anOffset;
|
||||
char* src = aDest+anOffset+aCount;
|
||||
|
||||
memmove(dst,src,aLength-(aCount+anOffset));
|
||||
}
|
||||
|
||||
/**
|
||||
* This method shifts single byte characters right by a given amount from an given offset.
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is a ptr to a cstring where the shift is to be performed
|
||||
* @param aLength is the known length of aDest
|
||||
* @param anOffset is the index into aDest where shifting shall begin
|
||||
* @param aCount is the number of chars to be "inserted"
|
||||
*/
|
||||
void ShiftCharsRight(char* aDest,PRUint32 aLength,PRUint32 anOffset,PRUint32 aCount) {
|
||||
char* src = aDest+anOffset;
|
||||
char* dst = aDest+anOffset+aCount;
|
||||
|
||||
memmove(dst,src,aLength-anOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method shifts unicode characters by a given amount from an given offset.
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is a ptr to a cstring where the shift is to be performed
|
||||
* @param aLength is the known length of aDest
|
||||
* @param anOffset is the index into aDest where shifting shall begin
|
||||
* @param aCount is the number of chars to be "cut"
|
||||
*/
|
||||
void ShiftDoubleCharsLeft(char* aDest,PRUint32 aLength,PRUint32 anOffset,PRUint32 aCount) {
|
||||
PRUnichar* root=(PRUnichar*)aDest;
|
||||
PRUnichar* dst = root+anOffset;
|
||||
PRUnichar* src = root+anOffset+aCount;
|
||||
|
||||
memmove(dst,src,(aLength-(aCount+anOffset))*sizeof(PRUnichar));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method shifts unicode characters by a given amount from an given offset.
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is a ptr to a cstring where the shift is to be performed
|
||||
* @param aLength is the known length of aDest
|
||||
* @param anOffset is the index into aDest where shifting shall begin
|
||||
* @param aCount is the number of chars to be "inserted"
|
||||
*/
|
||||
void ShiftDoubleCharsRight(char* aDest,PRUint32 aLength,PRUint32 anOffset,PRUint32 aCount) {
|
||||
PRUnichar* root=(PRUnichar*)aDest;
|
||||
PRUnichar* src = root+anOffset;
|
||||
PRUnichar* dst = root+anOffset+aCount;
|
||||
|
||||
memmove(dst,src,sizeof(PRUnichar)*(aLength-anOffset));
|
||||
}
|
||||
|
||||
|
||||
typedef void (*ShiftChars)(char* aDest,PRUint32 aLength,PRUint32 anOffset,PRUint32 aCount);
|
||||
ShiftChars gShiftChars[2][2]= {
|
||||
{&ShiftCharsLeft,&ShiftCharsRight},
|
||||
{&ShiftDoubleCharsLeft,&ShiftDoubleCharsRight}
|
||||
};
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
//
|
||||
// This set of methods is used to copy one buffer onto another.
|
||||
// The functions are differentiated by the size of source and dest character sizes.
|
||||
// WARNING: Your destination buffer MUST be big enough to hold all the source bytes.
|
||||
// We don't validate these ranges here (this should be done in higher level routines).
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* Going 1 to 1 is easy, since we assume ascii. No conversions are necessary.
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the destination buffer
|
||||
* @param aDestOffset is the pos to start copy to in the dest buffer
|
||||
* @param aSource is the source buffer
|
||||
* @param anOffset is the offset to start copying from in the source buffer
|
||||
* @param aCount is the (max) number of chars to copy
|
||||
*/
|
||||
void CopyChars1To1(char* aDest,PRInt32 anDestOffset,const char* aSource,PRUint32 anOffset,PRUint32 aCount) {
|
||||
|
||||
char* dst = aDest+anDestOffset;
|
||||
char* src = (char*)aSource+anOffset;
|
||||
|
||||
memcpy(dst,src,aCount);
|
||||
}
|
||||
|
||||
/**
|
||||
* Going 1 to 2 requires a conversion from ascii to unicode. This can be expensive.
|
||||
* @param aDest is the destination buffer
|
||||
* @param aDestOffset is the pos to start copy to in the dest buffer
|
||||
* @param aSource is the source buffer
|
||||
* @param anOffset is the offset to start copying from in the source buffer
|
||||
* @param aCount is the (max) number of chars to copy
|
||||
*/
|
||||
void CopyChars1To2(char* aDest,PRInt32 anDestOffset,const char* aSource,PRUint32 anOffset,PRUint32 aCount) {
|
||||
|
||||
PRUnichar* theDest=(PRUnichar*)aDest;
|
||||
PRUnichar* to = theDest+anDestOffset;
|
||||
const unsigned char* first= (const unsigned char*)aSource+anOffset;
|
||||
const unsigned char* last = first+aCount;
|
||||
|
||||
//now loop over characters, shifting them left...
|
||||
while(first<last) {
|
||||
*to=(PRUnichar)(*first);
|
||||
to++;
|
||||
first++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Going 2 to 1 requires a conversion from unicode down to ascii. This can be lossy.
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the destination buffer
|
||||
* @param aDestOffset is the pos to start copy to in the dest buffer
|
||||
* @param aSource is the source buffer
|
||||
* @param anOffset is the offset to start copying from in the source buffer
|
||||
* @param aCount is the (max) number of chars to copy
|
||||
*/
|
||||
void CopyChars2To1(char* aDest,PRInt32 anDestOffset,const char* aSource,PRUint32 anOffset,PRUint32 aCount) {
|
||||
char* to = aDest+anDestOffset;
|
||||
PRUnichar* theSource=(PRUnichar*)aSource;
|
||||
const PRUnichar* first= theSource+anOffset;
|
||||
const PRUnichar* last = first+aCount;
|
||||
|
||||
//now loop over characters, shifting them left...
|
||||
while(first<last) {
|
||||
if(*first<256)
|
||||
*to=(char)*first;
|
||||
else *to='.';
|
||||
to++;
|
||||
first++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Going 2 to 2 is fast and efficient.
|
||||
* @update gess 01/04/99
|
||||
* @param aDest is the destination buffer
|
||||
* @param aDestOffset is the pos to start copy to in the dest buffer
|
||||
* @param aSource is the source buffer
|
||||
* @param anOffset is the offset to start copying from in the source buffer
|
||||
* @param aCount is the (max) number of chars to copy
|
||||
*/
|
||||
void CopyChars2To2(char* aDest,PRInt32 anDestOffset,const char* aSource,PRUint32 anOffset,PRUint32 aCount) {
|
||||
PRUnichar* theDest=(PRUnichar*)aDest;
|
||||
PRUnichar* to = theDest+anDestOffset;
|
||||
PRUnichar* theSource=(PRUnichar*)aSource;
|
||||
PRUnichar* from= theSource+anOffset;
|
||||
|
||||
memcpy((void*)to,(void*)from,aCount*sizeof(PRUnichar));
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
typedef void (*CopyChars)(char* aDest,PRInt32 anDestOffset,const char* aSource,PRUint32 anOffset,PRUint32 aCount);
|
||||
|
||||
CopyChars gCopyChars[2][2]={
|
||||
{&CopyChars1To1,&CopyChars1To2},
|
||||
{&CopyChars2To1,&CopyChars2To2}
|
||||
};
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
//
|
||||
// This set of methods is used to search a buffer looking for a char.
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* This methods cans the given buffer for the given char
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aDest is the buffer to be searched
|
||||
* @param aLength is the size (in char-units, not bytes) of the buffer
|
||||
* @param anOffset is the start pos to begin searching
|
||||
* @param aChar is the target character we're looking for
|
||||
* @param aIgnorecase tells us whether to use a case sensitive search
|
||||
* @return index of pos if found, else -1 (kNotFound)
|
||||
*/
|
||||
inline PRInt32 FindChar1(const char* aDest,PRUint32 aLength,PRUint32 anOffset,const PRUnichar aChar,PRBool aIgnoreCase) {
|
||||
|
||||
if(aIgnoreCase) {
|
||||
char theChar=(char)nsCRT::ToUpper(aChar);
|
||||
const char* ptr=aDest+(anOffset-1);
|
||||
const char* last=aDest+aLength;
|
||||
while(++ptr<last){
|
||||
if(nsCRT::ToUpper(*ptr)==theChar)
|
||||
return ptr-aDest;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
const char* ptr = aDest+anOffset;
|
||||
char theChar=(char)aChar;
|
||||
const char* result=(const char*)memchr(ptr, theChar,aLength-anOffset);
|
||||
if(result) {
|
||||
return result-aDest;
|
||||
}
|
||||
}
|
||||
return kNotFound;
|
||||
}
|
||||
|
||||
/**
|
||||
* This methods cans the given buffer for the given char
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aDest is the buffer to be searched
|
||||
* @param aLength is the size (in char-units, not bytes) of the buffer
|
||||
* @param anOffset is the start pos to begin searching
|
||||
* @param aChar is the target character we're looking for
|
||||
* @param aIgnorecase tells us whether to use a case sensitive search
|
||||
* @return index of pos if found, else -1 (kNotFound)
|
||||
*/
|
||||
inline PRInt32 FindChar2(const char* aDest,PRUint32 aLength,PRUint32 anOffset,const PRUnichar aChar,PRBool aIgnoreCase) {
|
||||
const PRUnichar* root=(PRUnichar*)aDest;
|
||||
const PRUnichar* ptr=root+(anOffset-1);
|
||||
const PRUnichar* last=root+aLength;
|
||||
|
||||
if(aIgnoreCase) {
|
||||
PRUnichar theChar=nsCRT::ToUpper(aChar);
|
||||
while(++ptr<last){
|
||||
if(nsCRT::ToUpper(*ptr)==theChar)
|
||||
return ptr-root;
|
||||
}
|
||||
}
|
||||
else {
|
||||
while(++ptr<last){
|
||||
if(*ptr==aChar)
|
||||
return (ptr-root);
|
||||
}
|
||||
}
|
||||
|
||||
return kNotFound;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This methods cans the given buffer (in reverse) for the given char
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aDest is the buffer to be searched
|
||||
* @param aLength is the size (in char-units, not bytes) of the buffer
|
||||
* @param anOffset is the start pos to begin searching
|
||||
* @param aChar is the target character we're looking for
|
||||
* @param aIgnorecase tells us whether to use a case sensitive search
|
||||
* @return index of pos if found, else -1 (kNotFound)
|
||||
*/
|
||||
inline PRInt32 RFindChar1(const char* aDest,PRUint32 aDestLength,PRUint32 anOffset,const PRUnichar aChar,PRBool aIgnoreCase) {
|
||||
PRInt32 theIndex=0;
|
||||
|
||||
if(aIgnoreCase) {
|
||||
PRUnichar theChar=nsCRT::ToUpper(aChar);
|
||||
for(theIndex=(PRInt32)anOffset;theIndex>=0;theIndex--){
|
||||
if(nsCRT::ToUpper(aDest[theIndex])==theChar)
|
||||
return theIndex;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(theIndex=(PRInt32)anOffset;theIndex>=0;theIndex--){
|
||||
if(aDest[theIndex]==aChar)
|
||||
return theIndex;
|
||||
}
|
||||
}
|
||||
|
||||
return kNotFound;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This methods cans the given buffer for the given char
|
||||
*
|
||||
* @update gess 3/25/98
|
||||
* @param aDest is the buffer to be searched
|
||||
* @param aLength is the size (in char-units, not bytes) of the buffer
|
||||
* @param anOffset is the start pos to begin searching
|
||||
* @param aChar is the target character we're looking for
|
||||
* @param aIgnorecase tells us whether to use a case sensitive search
|
||||
* @return index of pos if found, else -1 (kNotFound)
|
||||
*/
|
||||
inline PRInt32 RFindChar2(const char* aDest,PRUint32 aDestLength,PRUint32 anOffset,const PRUnichar aChar,PRBool aIgnoreCase) {
|
||||
|
||||
PRInt32 theIndex=0;
|
||||
PRUnichar* theBuf=(PRUnichar*)aDest;
|
||||
|
||||
if(aIgnoreCase) {
|
||||
PRUnichar theChar=nsCRT::ToUpper(aChar);
|
||||
for(theIndex=(PRInt32)anOffset;theIndex>=0;theIndex--){
|
||||
if(nsCRT::ToUpper(theBuf[theIndex])==theChar)
|
||||
return theIndex;
|
||||
}
|
||||
}
|
||||
else {
|
||||
for(theIndex=(PRInt32)anOffset;theIndex>=0;theIndex--){
|
||||
if(theBuf[theIndex]==aChar)
|
||||
return theIndex;
|
||||
}
|
||||
}
|
||||
|
||||
return kNotFound;
|
||||
}
|
||||
|
||||
typedef PRInt32 (*FindChars)(const char* aDest,PRUint32 aDestLength,PRUint32 anOffset,const PRUnichar aChar,PRBool aIgnoreCase);
|
||||
FindChars gFindChars[]={&FindChar1,&FindChar2};
|
||||
FindChars gRFindChars[]={&RFindChar1,&RFindChar2};
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
//
|
||||
// This set of methods is used to compare one buffer onto another.
|
||||
// The functions are differentiated by the size of source and dest character sizes.
|
||||
// WARNING: Your destination buffer MUST be big enough to hold all the source bytes.
|
||||
// We don't validate these ranges here (this should be done in higher level routines).
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* This method compares the data in one buffer with another
|
||||
* @update gess 01/04/99
|
||||
* @param aStr1 is the first buffer to be compared
|
||||
* @param aStr2 is the 2nd buffer to be compared
|
||||
* @param aCount is the number of chars to compare
|
||||
* @param aIgnorecase tells us whether to use a case-sensitive comparison
|
||||
* @return -1,0,1 depending on <,==,>
|
||||
*/
|
||||
PRInt32 Compare1To1(const char* aStr1,const char* aStr2,PRUint32 aCount,PRBool aIgnoreCase){
|
||||
PRInt32 result=0;
|
||||
if(aIgnoreCase)
|
||||
result=nsCRT::strncasecmp(aStr1,aStr2,aCount);
|
||||
else result=strncmp(aStr1,aStr2,aCount);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method compares the data in one buffer with another
|
||||
* @update gess 01/04/99
|
||||
* @param aStr1 is the first buffer to be compared
|
||||
* @param aStr2 is the 2nd buffer to be compared
|
||||
* @param aCount is the number of chars to compare
|
||||
* @param aIgnorecase tells us whether to use a case-sensitive comparison
|
||||
* @return -1,0,1 depending on <,==,>
|
||||
*/
|
||||
PRInt32 Compare2To2(const char* aStr1,const char* aStr2,PRUint32 aCount,PRBool aIgnoreCase){
|
||||
PRInt32 result=0;
|
||||
if(aIgnoreCase)
|
||||
result=nsCRT::strncasecmp((PRUnichar*)aStr1,(PRUnichar*)aStr2,aCount);
|
||||
else result=nsCRT::strncmp((PRUnichar*)aStr1,(PRUnichar*)aStr2,aCount);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method compares the data in one buffer with another
|
||||
* @update gess 01/04/99
|
||||
* @param aStr1 is the first buffer to be compared
|
||||
* @param aStr2 is the 2nd buffer to be compared
|
||||
* @param aCount is the number of chars to compare
|
||||
* @param aIgnorecase tells us whether to use a case-sensitive comparison
|
||||
* @return -1,0,1 depending on <,==,>
|
||||
*/
|
||||
PRInt32 Compare2To1(const char* aStr1,const char* aStr2,PRUint32 aCount,PRBool aIgnoreCase){
|
||||
PRInt32 result;
|
||||
if(aIgnoreCase)
|
||||
result=nsCRT::strncasecmp((PRUnichar*)aStr1,aStr2,aCount);
|
||||
else result=nsCRT::strncmp((PRUnichar*)aStr1,aStr2,aCount);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method compares the data in one buffer with another
|
||||
* @update gess 01/04/99
|
||||
* @param aStr1 is the first buffer to be compared
|
||||
* @param aStr2 is the 2nd buffer to be compared
|
||||
* @param aCount is the number of chars to compare
|
||||
* @param aIgnorecase tells us whether to use a case-sensitive comparison
|
||||
* @return -1,0,1 depending on <,==,>
|
||||
*/
|
||||
PRInt32 Compare1To2(const char* aStr1,const char* aStr2,PRUint32 aCount,PRBool aIgnoreCase){
|
||||
PRInt32 result;
|
||||
if(aIgnoreCase)
|
||||
result=nsCRT::strncasecmp((PRUnichar*)aStr2,aStr1,aCount)*-1;
|
||||
else result=nsCRT::strncmp((PRUnichar*)aStr2,aStr1,aCount)*-1;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
typedef PRInt32 (*CompareChars)(const char* aStr1,const char* aStr2,PRUint32 aCount,PRBool aIgnoreCase);
|
||||
CompareChars gCompare[2][2]={
|
||||
{&Compare1To1,&Compare1To2},
|
||||
{&Compare2To1,&Compare2To2},
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
//
|
||||
// This set of methods is used to convert the case of strings...
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* This method performs a case conversion the data in the given buffer
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aString is the buffer to be case shifted
|
||||
* @param aCount is the number of chars to compare
|
||||
* @param aToUpper tells us whether to convert to upper or lower
|
||||
* @return 0
|
||||
*/
|
||||
PRInt32 ConvertCase1(char* aString,PRUint32 aCount,PRBool aToUpper){
|
||||
PRInt32 result=0;
|
||||
|
||||
typedef char chartype;
|
||||
chartype* cp = (chartype*)aString;
|
||||
chartype* end = cp + aCount-1;
|
||||
while (cp <= end) {
|
||||
chartype ch = *cp;
|
||||
if(aToUpper) {
|
||||
if ((ch >= 'a') && (ch <= 'z')) {
|
||||
*cp = 'A' + (ch - 'a');
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((ch >= 'A') && (ch <= 'Z')) {
|
||||
*cp = 'a' + (ch - 'A');
|
||||
}
|
||||
}
|
||||
cp++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
#ifndef RICKG_TESTBED
|
||||
class HandleCaseConversionShutdown3 : public nsIShutdownListener {
|
||||
public :
|
||||
NS_IMETHOD OnShutdown(const nsCID& cid, nsISupports* service);
|
||||
HandleCaseConversionShutdown3(void) { NS_INIT_REFCNT(); }
|
||||
virtual ~HandleCaseConversionShutdown3(void) {}
|
||||
NS_DECL_ISUPPORTS
|
||||
};
|
||||
|
||||
static NS_DEFINE_CID(kUnicharUtilCID, NS_UNICHARUTIL_CID);
|
||||
static NS_DEFINE_IID(kICaseConversionIID, NS_ICASECONVERSION_IID);
|
||||
static NS_DEFINE_IID(kIShutdownListenerIID, NS_ISHUTDOWNLISTENER_IID);
|
||||
static nsICaseConversion * gCaseConv = 0;
|
||||
|
||||
NS_IMPL_ISUPPORTS(HandleCaseConversionShutdown3, kIShutdownListenerIID);
|
||||
|
||||
nsresult HandleCaseConversionShutdown3::OnShutdown(const nsCID& cid, nsISupports* service) {
|
||||
if (cid.Equals(kUnicharUtilCID)) {
|
||||
NS_ASSERTION(service == gCaseConv, "wrong service!");
|
||||
if(gCaseConv){
|
||||
gCaseConv->Release();
|
||||
gCaseConv = 0;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
class CCaseConversionServiceInitializer {
|
||||
public:
|
||||
CCaseConversionServiceInitializer(){
|
||||
mListener = new HandleCaseConversionShutdown3();
|
||||
if(mListener){
|
||||
mListener->AddRef();
|
||||
nsServiceManager::GetService(kUnicharUtilCID, kICaseConversionIID,(nsISupports**) &gCaseConv, mListener);
|
||||
}
|
||||
}
|
||||
protected:
|
||||
HandleCaseConversionShutdown3* mListener;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* This method performs a case conversion the data in the given buffer
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aString is the buffer to be case shifted
|
||||
* @param aCount is the number of chars to compare
|
||||
* @param aToUpper tells us whether to convert to upper or lower
|
||||
* @return 0
|
||||
*/
|
||||
PRInt32 ConvertCase2(char* aString,PRUint32 aCount,PRBool aToUpper){
|
||||
PRUnichar* cp = (PRUnichar*)aString;
|
||||
PRUnichar* end = cp + aCount-1;
|
||||
PRInt32 result=0;
|
||||
|
||||
#ifndef RICKG_TESTBED
|
||||
static CCaseConversionServiceInitializer gCaseConversionServiceInitializer;
|
||||
|
||||
// I18N code begin
|
||||
if(gCaseConv) {
|
||||
nsresult err=(aToUpper) ? gCaseConv->ToUpper(cp, cp, aCount) : gCaseConv->ToLower(cp, cp, aCount);
|
||||
if(NS_SUCCEEDED(err))
|
||||
return 0;
|
||||
}
|
||||
// I18N code end
|
||||
#endif
|
||||
|
||||
|
||||
while (cp <= end) {
|
||||
PRUnichar ch = *cp;
|
||||
if(aToUpper) {
|
||||
if ((ch >= 'a') && (ch <= 'z')) {
|
||||
*cp = 'A' + (ch - 'a');
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ((ch >= 'A') && (ch <= 'Z')) {
|
||||
*cp = 'a' + (ch - 'A');
|
||||
}
|
||||
}
|
||||
cp++;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
typedef PRInt32 (*CaseConverters)(char*,PRUint32,PRBool);
|
||||
CaseConverters gCaseConverters[]={&ConvertCase1,&ConvertCase2};
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
//
|
||||
// This set of methods is used compress char sequences in a buffer...
|
||||
//
|
||||
|
||||
|
||||
/**
|
||||
* This method compresses duplicate runs of a given char from the given buffer
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aString is the buffer to be manipulated
|
||||
* @param aLength is the length of the buffer
|
||||
* @param aSet tells us which chars to compress from given buffer
|
||||
* @param aEliminateLeading tells us whether to strip chars from the start of the buffer
|
||||
* @param aEliminateTrailing tells us whether to strip chars from the start of the buffer
|
||||
* @return the new length of the given buffer
|
||||
*/
|
||||
PRInt32 CompressChars1(char* aString,PRUint32 aLength,const char* aSet){
|
||||
|
||||
typedef char chartype;
|
||||
chartype* from = aString;
|
||||
chartype* end = aString + aLength-1;
|
||||
chartype* to = from;
|
||||
|
||||
//this code converts /n, /t, /r into normal space ' ';
|
||||
//it also compresses runs of whitespace down to a single char...
|
||||
if(aSet && aString && (0 < aLength)){
|
||||
PRUint32 aSetLen=strlen(aSet);
|
||||
while (from <= end) {
|
||||
chartype theChar = *from++;
|
||||
if(kNotFound!=FindChar1(aSet,aSetLen,0,theChar,PR_FALSE)){
|
||||
*to++=theChar;
|
||||
while (from <= end) {
|
||||
theChar = *from++;
|
||||
if(kNotFound==FindChar1(aSet,aSetLen,0,theChar,PR_FALSE)){
|
||||
*to++ = theChar;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
*to++ = theChar;
|
||||
}
|
||||
}
|
||||
*to = 0;
|
||||
}
|
||||
return to - (chartype*)aString;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method compresses duplicate runs of a given char from the given buffer
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aString is the buffer to be manipulated
|
||||
* @param aLength is the length of the buffer
|
||||
* @param aSet tells us which chars to compress from given buffer
|
||||
* @param aEliminateLeading tells us whether to strip chars from the start of the buffer
|
||||
* @param aEliminateTrailing tells us whether to strip chars from the start of the buffer
|
||||
* @return the new length of the given buffer
|
||||
*/
|
||||
PRInt32 CompressChars2(char* aString,PRUint32 aLength,const char* aSet){
|
||||
|
||||
typedef PRUnichar chartype;
|
||||
chartype* from = (chartype*)aString;
|
||||
chartype* end = from + aLength-1;
|
||||
chartype* to = from;
|
||||
|
||||
//this code converts /n, /t, /r into normal space ' ';
|
||||
//it also compresses runs of whitespace down to a single char...
|
||||
if(aSet && aString && (0 < aLength)){
|
||||
PRUint32 aSetLen=strlen(aSet);
|
||||
while (from <= end) {
|
||||
chartype theChar = *from++;
|
||||
if(kNotFound!=FindChar1(aSet,aSetLen,0,theChar,PR_FALSE)){
|
||||
*to++=theChar;
|
||||
while (from <= end) {
|
||||
theChar = *from++;
|
||||
if(kNotFound==FindChar1(aSet,aSetLen,0,theChar,PR_FALSE)){
|
||||
*to++ = theChar;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
*to++ = theChar;
|
||||
}
|
||||
}
|
||||
*to = 0;
|
||||
}
|
||||
return to - (chartype*)aString;
|
||||
}
|
||||
|
||||
typedef PRInt32 (*CompressChars)(char* aString,PRUint32 aCount,const char* aSet);
|
||||
CompressChars gCompressChars[]={&CompressChars1,&CompressChars2};
|
||||
|
||||
/**
|
||||
* This method strips chars in a given set from the given buffer
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aString is the buffer to be manipulated
|
||||
* @param aLength is the length of the buffer
|
||||
* @param aSet tells us which chars to compress from given buffer
|
||||
* @param aEliminateLeading tells us whether to strip chars from the start of the buffer
|
||||
* @param aEliminateTrailing tells us whether to strip chars from the start of the buffer
|
||||
* @return the new length of the given buffer
|
||||
*/
|
||||
PRInt32 StripChars1(char* aString,PRUint32 aLength,const char* aSet){
|
||||
|
||||
typedef char chartype;
|
||||
chartype* to = aString;
|
||||
chartype* from = aString-1;
|
||||
chartype* end = aString + aLength;
|
||||
|
||||
if(aSet && aString && (0 < aLength)){
|
||||
PRUint32 aSetLen=strlen(aSet);
|
||||
while (++from < end) {
|
||||
chartype theChar = *from;
|
||||
if(kNotFound==FindChar1(aSet,aSetLen,0,theChar,PR_FALSE)){
|
||||
*to++ = theChar;
|
||||
}
|
||||
}
|
||||
*to = 0;
|
||||
}
|
||||
return to - (chartype*)aString;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method strips chars in a given set from the given buffer
|
||||
*
|
||||
* @update gess 01/04/99
|
||||
* @param aString is the buffer to be manipulated
|
||||
* @param aLength is the length of the buffer
|
||||
* @param aSet tells us which chars to compress from given buffer
|
||||
* @param aEliminateLeading tells us whether to strip chars from the start of the buffer
|
||||
* @param aEliminateTrailing tells us whether to strip chars from the start of the buffer
|
||||
* @return the new length of the given buffer
|
||||
*/
|
||||
PRInt32 StripChars2(char* aString,PRUint32 aLength,const char* aSet){
|
||||
|
||||
typedef PRUnichar chartype;
|
||||
chartype* to = (chartype*)aString;
|
||||
chartype* from = (chartype*)aString-1;
|
||||
chartype* end = to + aLength;
|
||||
|
||||
if(aSet && aString && (0 < aLength)){
|
||||
PRUint32 aSetLen=strlen(aSet);
|
||||
while (++from < end) {
|
||||
chartype theChar = *from;
|
||||
if(kNotFound==FindChar1(aSet,aSetLen,0,theChar,PR_FALSE)){
|
||||
*to++ = theChar;
|
||||
}
|
||||
}
|
||||
*to = 0;
|
||||
}
|
||||
return to - (chartype*)aString;
|
||||
}
|
||||
|
||||
typedef PRInt32 (*StripChars)(char* aString,PRUint32 aCount,const char* aSet);
|
||||
StripChars gStripChars[]={&StripChars1,&StripChars2};
|
||||
|
||||
#endif
|
||||
120
mozilla/xpcom/ds/makefile.win
Normal file
120
mozilla/xpcom/ds/makefile.win
Normal file
@@ -0,0 +1,120 @@
|
||||
#!nmake
|
||||
#
|
||||
# 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.
|
||||
|
||||
|
||||
|
||||
DEPTH=..\..
|
||||
MODULE = xpcom
|
||||
|
||||
################################################################################
|
||||
## exports
|
||||
|
||||
EXPORTS = \
|
||||
nsTextFormater.h \
|
||||
nsAVLTree.h \
|
||||
nsCppSharedAllocator.h \
|
||||
nsCRT.h \
|
||||
nsDeque.h \
|
||||
nsEnumeratorUtils.h \
|
||||
nsHashtable.h \
|
||||
nsHashtableEnumerator.h \
|
||||
nsIArena.h \
|
||||
nsIByteBuffer.h \
|
||||
nsIObserverList.h \
|
||||
nsIProperties.h \
|
||||
nsISimpleEnumerator.h \
|
||||
nsISizeOfHandler.h \
|
||||
nsIUnicharBuffer.h \
|
||||
nsIVariant.h \
|
||||
nsInt64.h \
|
||||
nsQuickSort.h \
|
||||
nsStr.h \
|
||||
nsString.h \
|
||||
nsString2.h \
|
||||
nsSupportsPrimitives.h \
|
||||
nsTime.h \
|
||||
nsUnitConversion.h \
|
||||
nsVector.h \
|
||||
nsVoidArray.h \
|
||||
nsXPIDLString.h \
|
||||
plvector.h \
|
||||
$(NULL)
|
||||
|
||||
XPIDL_MODULE = xpcom_ds
|
||||
|
||||
XPIDLSRCS = \
|
||||
.\nsIAtom.idl \
|
||||
.\nsICollection.idl \
|
||||
.\nsIEnumerator.idl \
|
||||
.\nsIObserver.idl \
|
||||
.\nsIObserverService.idl \
|
||||
.\nsISupportsArray.idl \
|
||||
.\nsISupportsPrimitives.idl \
|
||||
$(NULL)
|
||||
|
||||
################################################################################
|
||||
## library
|
||||
|
||||
LIBRARY_NAME=xpcomds_s
|
||||
|
||||
LINCS = \
|
||||
-I$(PUBLIC)\xpcom \
|
||||
-I$(PUBLIC)\uconv \
|
||||
-I$(PUBLIC)\unicharutil \
|
||||
$(NULL)
|
||||
|
||||
LCFLAGS = -D_IMPL_NS_COM -D_IMPL_NS_BASE -DWIN32_LEAN_AND_MEAN
|
||||
|
||||
CPP_OBJS = \
|
||||
.\$(OBJDIR)\nsTextFormater.obj \
|
||||
.\$(OBJDIR)\nsArena.obj \
|
||||
.\$(OBJDIR)\nsAtomTable.obj \
|
||||
.\$(OBJDIR)\nsAVLTree.obj \
|
||||
.\$(OBJDIR)\nsByteBuffer.obj \
|
||||
.\$(OBJDIR)\nsCRT.obj \
|
||||
.\$(OBJDIR)\nsConjoiningEnumerator.obj \
|
||||
.\$(OBJDIR)\nsDeque.obj \
|
||||
.\$(OBJDIR)\nsEmptyEnumerator.obj \
|
||||
.\$(OBJDIR)\nsEnumeratorUtils.obj \
|
||||
.\$(OBJDIR)\nsHashtable.obj \
|
||||
.\$(OBJDIR)\nsHashtableEnumerator.obj \
|
||||
.\$(OBJDIR)\nsObserver.obj \
|
||||
.\$(OBJDIR)\nsObserverList.obj \
|
||||
.\$(OBJDIR)\nsObserverService.obj \
|
||||
.\$(OBJDIR)\nsProperties.obj \
|
||||
.\$(OBJDIR)\nsQuickSort.obj \
|
||||
.\$(OBJDIR)\nsSizeOfHandler.obj \
|
||||
.\$(OBJDIR)\nsStr.obj \
|
||||
.\$(OBJDIR)\nsString.obj \
|
||||
.\$(OBJDIR)\nsString2.obj \
|
||||
.\$(OBJDIR)\nsSupportsArray.obj \
|
||||
.\$(OBJDIR)\nsSupportsArrayEnumerator.obj \
|
||||
.\$(OBJDIR)\nsSupportsPrimitives.obj \
|
||||
.\$(OBJDIR)\nsUnicharBuffer.obj \
|
||||
.\$(OBJDIR)\nsVariant.obj \
|
||||
.\$(OBJDIR)\nsVoidArray.obj \
|
||||
.\$(OBJDIR)\nsXPIDLString.obj \
|
||||
.\$(OBJDIR)\plvector.obj \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
libs:: $(LIBRARY)
|
||||
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
|
||||
|
||||
clobber::
|
||||
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib
|
||||
617
mozilla/xpcom/ds/nsAVLTree.cpp
Normal file
617
mozilla/xpcom/ds/nsAVLTree.cpp
Normal file
@@ -0,0 +1,617 @@
|
||||
/* -*- Mode: C++; tab-width: 2; 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) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#include "nsAVLTree.h"
|
||||
|
||||
|
||||
enum eLean {eLeft,eNeutral,eRight};
|
||||
|
||||
struct NS_COM nsAVLNode {
|
||||
public:
|
||||
|
||||
nsAVLNode(void* aValue) {
|
||||
mLeft=0;
|
||||
mRight=0;
|
||||
mSkew=eNeutral;
|
||||
mValue=aValue;
|
||||
}
|
||||
|
||||
nsAVLNode* mLeft;
|
||||
nsAVLNode* mRight;
|
||||
eLean mSkew;
|
||||
void* mValue;
|
||||
};
|
||||
|
||||
|
||||
/************************************************************
|
||||
Now begin the tree class. Don't forget that the comparison
|
||||
between nodes must occur via the comparitor function,
|
||||
otherwise all you're testing is pointer addresses.
|
||||
************************************************************/
|
||||
|
||||
/** ------------------------------------------------
|
||||
*
|
||||
*
|
||||
* @update gess 4/22/98
|
||||
* @param
|
||||
* @return
|
||||
*/ //----------------------------------------------
|
||||
nsAVLTree::nsAVLTree(nsAVLNodeComparitor& aComparitor,
|
||||
nsAVLNodeFunctor* aDeallocator) :
|
||||
mComparitor(aComparitor), mDeallocator(aDeallocator) {
|
||||
mRoot=0;
|
||||
mCount=0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
avlDeleteTree(nsAVLNode* aNode){
|
||||
if (aNode) {
|
||||
avlDeleteTree(aNode->mLeft);
|
||||
avlDeleteTree(aNode->mRight);
|
||||
delete aNode;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess12/27/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
nsAVLTree::~nsAVLTree(){
|
||||
if (mDeallocator) {
|
||||
ForEachDepthFirst(*mDeallocator);
|
||||
}
|
||||
avlDeleteTree(mRoot);
|
||||
}
|
||||
|
||||
|
||||
class CDoesntExist: public nsAVLNodeFunctor {
|
||||
public:
|
||||
CDoesntExist(const nsAVLTree& anotherTree) : mOtherTree(anotherTree) {
|
||||
}
|
||||
virtual void* operator()(void* anItem) {
|
||||
void* result=mOtherTree.FindItem(anItem);
|
||||
if(result)
|
||||
return nsnull;
|
||||
return anItem;
|
||||
}
|
||||
protected:
|
||||
const nsAVLTree& mOtherTree;
|
||||
};
|
||||
|
||||
/**
|
||||
* This method compares two trees (members by identity).
|
||||
* @update gess12/27/98
|
||||
* @param tree to compare against
|
||||
* @return true if they are identical (contain same stuff).
|
||||
*/
|
||||
PRBool nsAVLTree::operator==(const nsAVLTree& aCopy) const{
|
||||
CDoesntExist functor(aCopy);
|
||||
void* theItem=FirstThat(functor);
|
||||
PRBool result=PRBool(!theItem);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess12/27/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
static void
|
||||
avlRotateRight(nsAVLNode*& aRootNode){
|
||||
nsAVLNode* ptr2;
|
||||
nsAVLNode* ptr3;
|
||||
|
||||
ptr2=aRootNode->mRight;
|
||||
if(ptr2->mSkew==eRight) {
|
||||
aRootNode->mRight=ptr2->mLeft;
|
||||
ptr2->mLeft=aRootNode;
|
||||
aRootNode->mSkew=eNeutral;
|
||||
aRootNode=ptr2;
|
||||
}
|
||||
else {
|
||||
ptr3=ptr2->mLeft;
|
||||
ptr2->mLeft=ptr3->mRight;
|
||||
ptr3->mRight=ptr2;
|
||||
aRootNode->mRight=ptr3->mLeft;
|
||||
ptr3->mLeft=aRootNode;
|
||||
if(ptr3->mSkew==eLeft)
|
||||
ptr2->mSkew=eRight;
|
||||
else ptr2->mSkew=eNeutral;
|
||||
if(ptr3->mSkew==eRight)
|
||||
aRootNode->mSkew=eLeft;
|
||||
else aRootNode->mSkew=eNeutral;
|
||||
aRootNode=ptr3;
|
||||
}
|
||||
aRootNode->mSkew=eNeutral;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess12/27/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
static void
|
||||
avlRotateLeft(nsAVLNode*& aRootNode){
|
||||
nsAVLNode* ptr2;
|
||||
nsAVLNode* ptr3;
|
||||
|
||||
ptr2=aRootNode->mLeft;
|
||||
if(ptr2->mSkew==eLeft) {
|
||||
aRootNode->mLeft=ptr2->mRight;
|
||||
ptr2->mRight=aRootNode;
|
||||
aRootNode->mSkew=eNeutral;
|
||||
aRootNode=ptr2;
|
||||
}
|
||||
else {
|
||||
ptr3=ptr2->mRight;
|
||||
ptr2->mRight=ptr3->mLeft;
|
||||
ptr3->mLeft=ptr2;
|
||||
aRootNode->mLeft=ptr3->mRight;
|
||||
ptr3->mRight=aRootNode;
|
||||
if(ptr3->mSkew==eRight)
|
||||
ptr2->mSkew=eLeft;
|
||||
else ptr2->mSkew=eNeutral;
|
||||
if(ptr3->mSkew==eLeft)
|
||||
aRootNode->mSkew=eRight;
|
||||
else aRootNode->mSkew=eNeutral;
|
||||
aRootNode=ptr3;
|
||||
}
|
||||
aRootNode->mSkew=eNeutral;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/** ------------------------------------------------
|
||||
*
|
||||
*
|
||||
* @update gess 4/22/98
|
||||
* @param
|
||||
* @return
|
||||
*/ //----------------------------------------------
|
||||
static eAVLStatus
|
||||
avlInsert(nsAVLNode*& aRootNode, nsAVLNode* aNewNode,
|
||||
nsAVLNodeComparitor& aComparitor) {
|
||||
eAVLStatus result=eAVL_unknown;
|
||||
|
||||
if(!aRootNode) {
|
||||
aRootNode = aNewNode;
|
||||
return eAVL_ok;
|
||||
}
|
||||
|
||||
if(aNewNode==aRootNode->mValue) {
|
||||
return eAVL_duplicate;
|
||||
}
|
||||
|
||||
PRInt32 theCompareResult=aComparitor(aRootNode->mValue,aNewNode->mValue);
|
||||
if(0 < theCompareResult) { //if(anItem<aRootNode->mValue)
|
||||
result=avlInsert(aRootNode->mLeft,aNewNode,aComparitor);
|
||||
if(eAVL_ok==result) {
|
||||
switch(aRootNode->mSkew){
|
||||
case eLeft:
|
||||
avlRotateLeft(aRootNode);
|
||||
result=eAVL_fail;
|
||||
break;
|
||||
case eRight:
|
||||
aRootNode->mSkew=eNeutral;
|
||||
result=eAVL_fail;
|
||||
break;
|
||||
case eNeutral:
|
||||
aRootNode->mSkew=eLeft;
|
||||
break;
|
||||
} //switch
|
||||
}//if
|
||||
} //if
|
||||
else {
|
||||
result=avlInsert(aRootNode->mRight,aNewNode,aComparitor);
|
||||
if(eAVL_ok==result) {
|
||||
switch(aRootNode->mSkew){
|
||||
case eLeft:
|
||||
aRootNode->mSkew=eNeutral;
|
||||
result=eAVL_fail;
|
||||
break;
|
||||
case eRight:
|
||||
avlRotateRight(aRootNode);
|
||||
result=eAVL_fail;
|
||||
break;
|
||||
case eNeutral:
|
||||
aRootNode->mSkew=eRight;
|
||||
break;
|
||||
} //switch
|
||||
}
|
||||
} //if
|
||||
return result;
|
||||
}
|
||||
|
||||
/** ------------------------------------------------
|
||||
*
|
||||
*
|
||||
* @update gess 4/22/98
|
||||
* @param
|
||||
* @return
|
||||
*/ //----------------------------------------------
|
||||
static void
|
||||
avlBalanceLeft(nsAVLNode*& aRootNode, PRBool& delOk){
|
||||
nsAVLNode* ptr2;
|
||||
nsAVLNode* ptr3;
|
||||
eLean balnc2;
|
||||
eLean balnc3;
|
||||
|
||||
switch(aRootNode->mSkew){
|
||||
case eLeft:
|
||||
ptr2=aRootNode->mLeft;
|
||||
balnc2=ptr2->mSkew;
|
||||
if(balnc2!=eRight) {
|
||||
aRootNode->mLeft=ptr2->mRight;
|
||||
ptr2->mRight=aRootNode;
|
||||
if(balnc2==eNeutral){
|
||||
aRootNode->mSkew=eLeft;
|
||||
ptr2->mSkew=eRight;
|
||||
delOk=PR_FALSE;
|
||||
}
|
||||
else{
|
||||
aRootNode->mSkew=eNeutral;
|
||||
ptr2->mSkew=eNeutral;
|
||||
}
|
||||
aRootNode=ptr2;
|
||||
}
|
||||
else{
|
||||
ptr3=ptr2->mRight;
|
||||
balnc3=ptr3->mSkew;
|
||||
ptr2->mRight=ptr3->mLeft;
|
||||
ptr3->mLeft=ptr2;
|
||||
aRootNode->mLeft=ptr3->mRight;
|
||||
ptr3->mRight=aRootNode;
|
||||
if(balnc3==eRight) {
|
||||
ptr2->mSkew=eLeft;
|
||||
}
|
||||
else {
|
||||
ptr2->mSkew=eNeutral;
|
||||
}
|
||||
if(balnc3==eLeft) {
|
||||
aRootNode->mSkew=eRight;
|
||||
}
|
||||
else {
|
||||
aRootNode->mSkew=eNeutral;
|
||||
}
|
||||
aRootNode=ptr3;
|
||||
ptr3->mSkew=eNeutral;
|
||||
}
|
||||
break;
|
||||
|
||||
case eRight:
|
||||
aRootNode->mSkew=eNeutral;
|
||||
break;
|
||||
|
||||
case eNeutral:
|
||||
aRootNode->mSkew=eLeft;
|
||||
delOk=PR_FALSE;
|
||||
break;
|
||||
}//switch
|
||||
return;
|
||||
}
|
||||
|
||||
/** ------------------------------------------------
|
||||
*
|
||||
*
|
||||
* @update gess 4/22/98
|
||||
* @param
|
||||
* @return
|
||||
*/ //----------------------------------------------
|
||||
static void
|
||||
avlBalanceRight(nsAVLNode*& aRootNode, PRBool& delOk){
|
||||
nsAVLNode* ptr2;
|
||||
nsAVLNode* ptr3;
|
||||
eLean balnc2;
|
||||
eLean balnc3;
|
||||
|
||||
switch(aRootNode->mSkew){
|
||||
case eLeft:
|
||||
aRootNode->mSkew=eNeutral;
|
||||
break;
|
||||
|
||||
case eRight:
|
||||
ptr2=aRootNode->mRight;
|
||||
balnc2=ptr2->mSkew;
|
||||
if(balnc2!=eLeft) {
|
||||
aRootNode->mRight=ptr2->mLeft;
|
||||
ptr2->mLeft=aRootNode;
|
||||
if(balnc2==eNeutral){
|
||||
aRootNode->mSkew=eRight;
|
||||
ptr2->mSkew=eLeft;
|
||||
delOk=PR_FALSE;
|
||||
}
|
||||
else{
|
||||
aRootNode->mSkew=eNeutral;
|
||||
ptr2->mSkew=eNeutral;
|
||||
}
|
||||
aRootNode=ptr2;
|
||||
}
|
||||
else{
|
||||
ptr3=ptr2->mLeft;
|
||||
balnc3=ptr3->mSkew;
|
||||
ptr2->mLeft=ptr3->mRight;
|
||||
ptr3->mRight=ptr2;
|
||||
aRootNode->mRight=ptr3->mLeft;
|
||||
ptr3->mLeft=aRootNode;
|
||||
if(balnc3==eLeft) {
|
||||
ptr2->mSkew=eRight;
|
||||
}
|
||||
else {
|
||||
ptr2->mSkew=eNeutral;
|
||||
}
|
||||
if(balnc3==eRight) {
|
||||
aRootNode->mSkew=eLeft;
|
||||
}
|
||||
else {
|
||||
aRootNode->mSkew=eNeutral;
|
||||
}
|
||||
aRootNode=ptr3;
|
||||
ptr3->mSkew=eNeutral;
|
||||
}
|
||||
break;
|
||||
|
||||
case eNeutral:
|
||||
aRootNode->mSkew=eRight;
|
||||
delOk=PR_FALSE;
|
||||
break;
|
||||
}//switch
|
||||
return;
|
||||
}
|
||||
|
||||
/** ------------------------------------------------
|
||||
*
|
||||
*
|
||||
* @update gess 4/22/98
|
||||
* @param
|
||||
* @return
|
||||
*/ //----------------------------------------------
|
||||
static eAVLStatus
|
||||
avlRemoveChildren(nsAVLNode*& aRootNode,nsAVLNode*& anotherNode, PRBool& delOk){
|
||||
eAVLStatus result=eAVL_ok;
|
||||
|
||||
if(!anotherNode->mRight){
|
||||
aRootNode->mValue=anotherNode->mValue; //swap
|
||||
anotherNode=anotherNode->mLeft;
|
||||
delOk=PR_TRUE;
|
||||
}
|
||||
else{
|
||||
avlRemoveChildren(aRootNode,anotherNode->mRight,delOk);
|
||||
if(delOk)
|
||||
avlBalanceLeft(anotherNode,delOk);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/** ------------------------------------------------
|
||||
*
|
||||
*
|
||||
* @update gess 4/22/98
|
||||
* @param
|
||||
* @return
|
||||
*/ //----------------------------------------------
|
||||
static eAVLStatus
|
||||
avlRemove(nsAVLNode*& aRootNode, void* anItem, PRBool& delOk,
|
||||
nsAVLNodeComparitor& aComparitor){
|
||||
eAVLStatus result=eAVL_ok;
|
||||
|
||||
if(!aRootNode)
|
||||
delOk=PR_FALSE;
|
||||
else {
|
||||
PRInt32 cmp=aComparitor(anItem,aRootNode->mValue);
|
||||
if(cmp<0){
|
||||
avlRemove(aRootNode->mLeft,anItem,delOk,aComparitor);
|
||||
if(delOk)
|
||||
avlBalanceRight(aRootNode,delOk);
|
||||
}
|
||||
else if(cmp>0){
|
||||
avlRemove(aRootNode->mRight,anItem,delOk,aComparitor);
|
||||
if(delOk)
|
||||
avlBalanceLeft(aRootNode,delOk);
|
||||
}
|
||||
else{ //they match...
|
||||
nsAVLNode* temp=aRootNode;
|
||||
if(!aRootNode->mRight) {
|
||||
aRootNode=aRootNode->mLeft;
|
||||
delOk=PR_TRUE;
|
||||
delete temp;
|
||||
}
|
||||
else if(!aRootNode->mLeft) {
|
||||
aRootNode=aRootNode->mRight;
|
||||
delOk=PR_TRUE;
|
||||
delete temp;
|
||||
}
|
||||
else {
|
||||
avlRemoveChildren(aRootNode,aRootNode->mLeft,delOk);
|
||||
if(delOk)
|
||||
avlBalanceRight(aRootNode,delOk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/** ------------------------------------------------
|
||||
*
|
||||
*
|
||||
* @update gess 4/22/98
|
||||
* @param
|
||||
* @return
|
||||
*/ //----------------------------------------------
|
||||
eAVLStatus
|
||||
nsAVLTree::AddItem(void* anItem){
|
||||
eAVLStatus result=eAVL_ok;
|
||||
|
||||
nsAVLNode* theNewNode=new nsAVLNode(anItem);
|
||||
result=avlInsert(mRoot,theNewNode,mComparitor);
|
||||
if(eAVL_duplicate!=result)
|
||||
mCount++;
|
||||
else {
|
||||
delete theNewNode;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/** ------------------------------------------------
|
||||
*
|
||||
*
|
||||
* @update gess 4/22/98
|
||||
* @param
|
||||
* @return
|
||||
*/ //----------------------------------------------
|
||||
void* nsAVLTree::FindItem(void* aValue) const{
|
||||
nsAVLNode* result=mRoot;
|
||||
PRInt32 count=0;
|
||||
while(result) {
|
||||
count++;
|
||||
PRInt32 cmp=mComparitor(aValue,result->mValue);
|
||||
if(0==cmp) {
|
||||
//we matched...
|
||||
break;
|
||||
}
|
||||
else if(0>cmp){
|
||||
//theNode was greater...
|
||||
result=result->mLeft;
|
||||
}
|
||||
else {
|
||||
//aValue is greater...
|
||||
result=result->mRight;
|
||||
}
|
||||
}
|
||||
if(result) {
|
||||
return result->mValue;
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess12/30/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
eAVLStatus
|
||||
nsAVLTree::RemoveItem(void* aValue){
|
||||
PRBool delOk=PR_TRUE;
|
||||
eAVLStatus result=avlRemove(mRoot,aValue,delOk,mComparitor);
|
||||
if(eAVL_ok==result)
|
||||
mCount--;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess9/11/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
static void
|
||||
avlForEachDepthFirst(nsAVLNode* aNode, nsAVLNodeFunctor& aFunctor){
|
||||
if(aNode) {
|
||||
avlForEachDepthFirst(aNode->mLeft,aFunctor);
|
||||
avlForEachDepthFirst(aNode->mRight,aFunctor);
|
||||
aFunctor(aNode->mValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess9/11/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void
|
||||
nsAVLTree::ForEachDepthFirst(nsAVLNodeFunctor& aFunctor) const{
|
||||
::avlForEachDepthFirst(mRoot,aFunctor);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess9/11/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
static void
|
||||
avlForEach(nsAVLNode* aNode, nsAVLNodeFunctor& aFunctor) {
|
||||
if(aNode) {
|
||||
avlForEach(aNode->mLeft,aFunctor);
|
||||
aFunctor(aNode->mValue);
|
||||
avlForEach(aNode->mRight,aFunctor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess9/11/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void
|
||||
nsAVLTree::ForEach(nsAVLNodeFunctor& aFunctor) const{
|
||||
::avlForEach(mRoot,aFunctor);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess9/11/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
static void*
|
||||
avlFirstThat(nsAVLNode* aNode, nsAVLNodeFunctor& aFunctor) {
|
||||
void* result=nsnull;
|
||||
if(aNode) {
|
||||
result = avlFirstThat(aNode->mLeft,aFunctor);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
result = aFunctor(aNode->mValue);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
result = avlFirstThat(aNode->mRight,aFunctor);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess9/11/98
|
||||
* @param
|
||||
* @return
|
||||
*/
|
||||
void*
|
||||
nsAVLTree::FirstThat(nsAVLNodeFunctor& aFunctor) const{
|
||||
return ::avlFirstThat(mRoot,aFunctor);
|
||||
}
|
||||
|
||||
74
mozilla/xpcom/ds/nsAVLTree.h
Normal file
74
mozilla/xpcom/ds/nsAVLTree.h
Normal file
@@ -0,0 +1,74 @@
|
||||
/* -*- Mode: C++; tab-width: 2; 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) 1999 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
#ifndef nsAVLTree_h___
|
||||
#define nsAVLTree_h___
|
||||
|
||||
|
||||
#include "nscore.h"
|
||||
|
||||
|
||||
enum eAVLStatus {eAVL_unknown,eAVL_ok,eAVL_fail,eAVL_duplicate};
|
||||
|
||||
|
||||
struct nsAVLNode;
|
||||
|
||||
/**
|
||||
*
|
||||
* @update gess12/26/98
|
||||
* @param anObject1 is the first object to be compared
|
||||
* @param anObject2 is the second object to be compared
|
||||
* @return -1,0,1 if object1 is less, equal, greater than object2
|
||||
*/
|
||||
class NS_COM nsAVLNodeComparitor {
|
||||
public:
|
||||
virtual PRInt32 operator()(void* anItem1,void* anItem2)=0;
|
||||
};
|
||||
|
||||
class NS_COM nsAVLNodeFunctor {
|
||||
public:
|
||||
virtual void* operator()(void* anItem)=0;
|
||||
};
|
||||
|
||||
class NS_COM nsAVLTree {
|
||||
public:
|
||||
nsAVLTree(nsAVLNodeComparitor& aComparitor, nsAVLNodeFunctor* aDeallocator);
|
||||
~nsAVLTree(void);
|
||||
|
||||
PRBool operator==(const nsAVLTree& aOther) const;
|
||||
PRInt32 GetCount(void) const {return mCount;}
|
||||
|
||||
//main functions...
|
||||
eAVLStatus AddItem(void* anItem);
|
||||
eAVLStatus RemoveItem(void* anItem);
|
||||
void* FindItem(void* anItem) const;
|
||||
void ForEach(nsAVLNodeFunctor& aFunctor) const;
|
||||
void ForEachDepthFirst(nsAVLNodeFunctor& aFunctor) const;
|
||||
void* FirstThat(nsAVLNodeFunctor& aFunctor) const;
|
||||
|
||||
protected:
|
||||
|
||||
nsAVLNode* mRoot;
|
||||
PRInt32 mCount;
|
||||
nsAVLNodeComparitor& mComparitor;
|
||||
nsAVLNodeFunctor* mDeallocator;
|
||||
};
|
||||
|
||||
|
||||
#endif /* nsAVLTree_h___ */
|
||||
|
||||
97
mozilla/xpcom/ds/nsArena.cpp
Normal file
97
mozilla/xpcom/ds/nsArena.cpp
Normal file
@@ -0,0 +1,97 @@
|
||||
/* -*- Mode: C++; tab-width: 2; 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 "nsArena.h"
|
||||
#include "nsCRT.h"
|
||||
|
||||
ArenaImpl::ArenaImpl(void)
|
||||
: mInitialized(PR_FALSE)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
nsCRT::memset(&mPool, 0, sizeof(PLArenaPool));
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ArenaImpl::Init(PRUint32 aBlockSize)
|
||||
{
|
||||
if (aBlockSize < NS_MIN_ARENA_BLOCK_SIZE) {
|
||||
aBlockSize = NS_DEFAULT_ARENA_BLOCK_SIZE;
|
||||
}
|
||||
PL_INIT_ARENA_POOL(&mPool, "nsIArena", aBlockSize);
|
||||
mBlockSize = aBlockSize;
|
||||
mInitialized = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(ArenaImpl, nsIArena)
|
||||
|
||||
ArenaImpl::~ArenaImpl()
|
||||
{
|
||||
if (mInitialized)
|
||||
PL_FinishArenaPool(&mPool);
|
||||
|
||||
mInitialized = PR_FALSE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(void*)
|
||||
ArenaImpl::Alloc(PRUint32 size)
|
||||
{
|
||||
// Adjust size so that it's a multiple of sizeof(double)
|
||||
PRUint32 align = size & (sizeof(double) - 1);
|
||||
if (0 != align) {
|
||||
size += sizeof(double) - align;
|
||||
}
|
||||
|
||||
void* p;
|
||||
PL_ARENA_ALLOCATE(p, &mPool, size);
|
||||
return p;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
ArenaImpl::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
||||
{
|
||||
if (aOuter)
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
ArenaImpl* it = new ArenaImpl();
|
||||
if (nsnull == it)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(it);
|
||||
nsresult rv = it->QueryInterface(aIID, aResult);
|
||||
NS_RELEASE(it);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_COM nsresult NS_NewHeapArena(nsIArena** aInstancePtrResult,
|
||||
PRUint32 aArenaBlockSize)
|
||||
{
|
||||
nsresult rv;
|
||||
nsIArena* arena;
|
||||
rv = ArenaImpl::Create(NULL, nsIArena::GetIID(), (void**)&arena);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = arena->Init(aArenaBlockSize);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_RELEASE(arena);
|
||||
return rv;
|
||||
}
|
||||
|
||||
*aInstancePtrResult = arena;
|
||||
return rv;
|
||||
}
|
||||
50
mozilla/xpcom/ds/nsArena.h
Normal file
50
mozilla/xpcom/ds/nsArena.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/* -*- Mode: C++; tab-width: 2; 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.
|
||||
*/
|
||||
|
||||
#ifndef nsArena_h__
|
||||
#define nsArena_h__
|
||||
|
||||
#include "nsIArena.h"
|
||||
|
||||
#define PL_ARENA_CONST_ALIGN_MASK 7
|
||||
#include "plarena.h"
|
||||
|
||||
// Simple arena implementation layered on plarena
|
||||
class ArenaImpl : public nsIArena {
|
||||
public:
|
||||
ArenaImpl(void);
|
||||
virtual ~ArenaImpl();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
static NS_METHOD
|
||||
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||
|
||||
NS_IMETHOD Init(PRUint32 arenaBlockSize);
|
||||
|
||||
NS_IMETHOD_(void*) Alloc(PRUint32 size);
|
||||
|
||||
protected:
|
||||
PLArenaPool mPool;
|
||||
PRUint32 mBlockSize;
|
||||
|
||||
private:
|
||||
PRBool mInitialized;
|
||||
};
|
||||
|
||||
#endif // nsArena_h__
|
||||
172
mozilla/xpcom/ds/nsAtomTable.cpp
Normal file
172
mozilla/xpcom/ds/nsAtomTable.cpp
Normal file
@@ -0,0 +1,172 @@
|
||||
/* -*- Mode: C++; tab-width: 2; 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 "nsAtomTable.h"
|
||||
#include "nsString.h"
|
||||
#include "nsCRT.h"
|
||||
#include "plhash.h"
|
||||
#include "nsISizeOfHandler.h"
|
||||
|
||||
/**
|
||||
* The shared hash table for atom lookups.
|
||||
*/
|
||||
static nsrefcnt gAtoms;
|
||||
static struct PLHashTable* gAtomHashTable;
|
||||
|
||||
#if defined(DEBUG) && (defined(XP_UNIX) || defined(XP_PC))
|
||||
static PRIntn
|
||||
DumpAtomLeaks(PLHashEntry *he, PRIntn index, void *arg)
|
||||
{
|
||||
AtomImpl* atom = (AtomImpl*) he->value;
|
||||
if (atom) {
|
||||
nsAutoString tmp;
|
||||
atom->ToString(tmp);
|
||||
fputs(tmp, stdout);
|
||||
fputs("\n", stdout);
|
||||
}
|
||||
return HT_ENUMERATE_NEXT;
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_COM void NS_PurgeAtomTable(void)
|
||||
{
|
||||
if (gAtomHashTable) {
|
||||
#if defined(DEBUG) && (defined(XP_UNIX) || defined(XP_PC))
|
||||
if (gAtoms) {
|
||||
if (getenv("MOZ_DUMP_ATOM_LEAKS")) {
|
||||
printf("*** leaking %d atoms\n", gAtoms);
|
||||
PL_HashTableEnumerateEntries(gAtomHashTable, DumpAtomLeaks, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
PL_HashTableDestroy(gAtomHashTable);
|
||||
gAtomHashTable = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
AtomImpl::AtomImpl()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
// Every live atom holds a reference on the atom hashtable
|
||||
gAtoms++;
|
||||
}
|
||||
|
||||
AtomImpl::~AtomImpl()
|
||||
{
|
||||
NS_PRECONDITION(nsnull != gAtomHashTable, "null atom hashtable");
|
||||
if (nsnull != gAtomHashTable) {
|
||||
PL_HashTableRemove(gAtomHashTable, mString);
|
||||
nsrefcnt cnt = --gAtoms;
|
||||
if (0 == cnt) {
|
||||
// When the last atom is destroyed, the atom arena is destroyed
|
||||
NS_ASSERTION(0 == gAtomHashTable->nentries, "bad atom table");
|
||||
PL_HashTableDestroy(gAtomHashTable);
|
||||
gAtomHashTable = nsnull;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(AtomImpl, nsIAtom)
|
||||
|
||||
void* AtomImpl::operator new(size_t size, const PRUnichar* us, PRInt32 uslen)
|
||||
{
|
||||
size = size + uslen * sizeof(PRUnichar);
|
||||
AtomImpl* ii = (AtomImpl*) ::operator new(size);
|
||||
nsCRT::memcpy(ii->mString, us, uslen * sizeof(PRUnichar));
|
||||
ii->mString[uslen] = 0;
|
||||
return ii;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
AtomImpl::ToString(nsString& aBuf) /*FIX: const */
|
||||
{
|
||||
aBuf.SetLength(0);
|
||||
aBuf.Append(mString, nsCRT::strlen(mString));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
AtomImpl::GetUnicode(const PRUnichar **aResult) /*FIX: const */
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
*aResult = mString;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
AtomImpl::SizeOf(nsISizeOfHandler* aHandler, PRUint32* _retval) /*FIX: const */
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(_retval);
|
||||
PRUint32 sum = sizeof(*this) + nsCRT::strlen(mString) * sizeof(PRUnichar);
|
||||
*_retval = sum;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
static PLHashNumber HashKey(const PRUnichar* k)
|
||||
{
|
||||
return (PLHashNumber) nsCRT::HashValue(k);
|
||||
}
|
||||
|
||||
static PRIntn CompareKeys(const PRUnichar* k1, const PRUnichar* k2)
|
||||
{
|
||||
return nsCRT::strcmp(k1, k2) == 0;
|
||||
}
|
||||
|
||||
NS_COM nsIAtom* NS_NewAtom(const char* isolatin1)
|
||||
{
|
||||
nsAutoString tmp(isolatin1);
|
||||
return NS_NewAtom(tmp.GetUnicode());
|
||||
}
|
||||
|
||||
NS_COM nsIAtom* NS_NewAtom(const nsString& aString)
|
||||
{
|
||||
return NS_NewAtom(aString.GetUnicode());
|
||||
}
|
||||
|
||||
NS_COM nsIAtom* NS_NewAtom(const PRUnichar* us)
|
||||
{
|
||||
if (nsnull == gAtomHashTable) {
|
||||
gAtomHashTable = PL_NewHashTable(8, (PLHashFunction) HashKey,
|
||||
(PLHashComparator) CompareKeys,
|
||||
(PLHashComparator) nsnull,
|
||||
nsnull, nsnull);
|
||||
}
|
||||
PRUint32 uslen;
|
||||
PRUint32 hashCode = nsCRT::HashValue(us, &uslen);
|
||||
PLHashEntry** hep = PL_HashTableRawLookup(gAtomHashTable, hashCode, us);
|
||||
PLHashEntry* he = *hep;
|
||||
if (nsnull != he) {
|
||||
nsIAtom* id = (nsIAtom*) he->value;
|
||||
NS_ADDREF(id);
|
||||
return id;
|
||||
}
|
||||
AtomImpl* id = new(us, uslen) AtomImpl();
|
||||
PL_HashTableRawAdd(gAtomHashTable, hep, hashCode, id->mString, id);
|
||||
NS_ADDREF(id);
|
||||
return id;
|
||||
}
|
||||
|
||||
NS_COM nsrefcnt NS_GetNumberOfAtoms(void)
|
||||
{
|
||||
if (nsnull != gAtomHashTable) {
|
||||
NS_PRECONDITION(nsrefcnt(gAtomHashTable->nentries) == gAtoms, "bad atom table");
|
||||
}
|
||||
return gAtoms;
|
||||
}
|
||||
43
mozilla/xpcom/ds/nsAtomTable.h
Normal file
43
mozilla/xpcom/ds/nsAtomTable.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/* -*- Mode: C++; tab-width: 2; 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.
|
||||
*/
|
||||
|
||||
#ifndef nsAtomTable_h__
|
||||
#define nsAtomTable_h__
|
||||
|
||||
#include "nsIAtom.h"
|
||||
|
||||
class AtomImpl : public nsIAtom {
|
||||
public:
|
||||
AtomImpl();
|
||||
virtual ~AtomImpl();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIATOM
|
||||
|
||||
void* operator new(size_t size, const PRUnichar* us, PRInt32 uslen);
|
||||
|
||||
void operator delete(void* ptr) {
|
||||
::operator delete(ptr);
|
||||
}
|
||||
|
||||
// Actually more; 0 terminated. This slot is reserved for the
|
||||
// terminating zero.
|
||||
PRUnichar mString[1];
|
||||
};
|
||||
|
||||
#endif // nsAtomTable_h__
|
||||
723
mozilla/xpcom/ds/nsBuffer.cpp
Normal file
723
mozilla/xpcom/ds/nsBuffer.cpp
Normal file
@@ -0,0 +1,723 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 "nsBuffer.h"
|
||||
#include "nsAutoLock.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIPageManager.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsBuffer::nsBuffer()
|
||||
: mGrowBySize(0),
|
||||
mMaxSize(0),
|
||||
mAllocator(nsnull),
|
||||
mObserver(nsnull),
|
||||
mBufferSize(0),
|
||||
mReadSegment(nsnull),
|
||||
mReadCursor(0),
|
||||
mWriteSegment(nsnull),
|
||||
mWriteCursor(0),
|
||||
mReaderClosed(PR_FALSE),
|
||||
mCondition(NS_OK)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
PR_INIT_CLIST(&mSegments);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::Init(PRUint32 growBySize, PRUint32 maxSize,
|
||||
nsIBufferObserver* observer, nsIAllocator* allocator)
|
||||
{
|
||||
NS_ASSERTION(sizeof(PRCList) <= SEGMENT_OVERHEAD,
|
||||
"need to change SEGMENT_OVERHEAD size");
|
||||
NS_ASSERTION(growBySize > SEGMENT_OVERHEAD, "bad growBySize");
|
||||
mGrowBySize = growBySize;
|
||||
mMaxSize = maxSize;
|
||||
mObserver = observer;
|
||||
NS_IF_ADDREF(mObserver);
|
||||
mAllocator = allocator;
|
||||
NS_ADDREF(mAllocator);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsBuffer::~nsBuffer()
|
||||
{
|
||||
// Free any allocated pages...
|
||||
while (!PR_CLIST_IS_EMPTY(&mSegments)) {
|
||||
PRCList* header = (PRCList*)mSegments.next;
|
||||
char* segment = (char*)header;
|
||||
|
||||
PR_REMOVE_LINK(header); // unlink from mSegments
|
||||
(void) mAllocator->Free(segment);
|
||||
}
|
||||
|
||||
NS_IF_RELEASE(mObserver);
|
||||
NS_IF_RELEASE(mAllocator);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsBuffer, nsIBuffer)
|
||||
|
||||
NS_METHOD
|
||||
nsBuffer::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
||||
{
|
||||
if (aOuter)
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
nsBuffer* buf = new nsBuffer();
|
||||
if (buf == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(buf);
|
||||
nsresult rv = buf->QueryInterface(aIID, aResult);
|
||||
NS_RELEASE(buf);
|
||||
return rv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsresult
|
||||
nsBuffer::PushWriteSegment()
|
||||
{
|
||||
nsAutoCMonitor mon(this); // protect mSegments
|
||||
|
||||
if (mBufferSize >= mMaxSize) {
|
||||
if (mObserver) {
|
||||
nsresult rv = mObserver->OnFull(this);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
return NS_BASE_STREAM_WOULD_BLOCK;
|
||||
}
|
||||
|
||||
// allocate a new segment to write into
|
||||
PRCList* header;
|
||||
|
||||
header = (PRCList*)mAllocator->Alloc(mGrowBySize);
|
||||
if (header == nsnull)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
mBufferSize += mGrowBySize;
|
||||
|
||||
PR_INSERT_BEFORE(header, &mSegments); // insert at end
|
||||
|
||||
// initialize the write segment
|
||||
mWriteSegment = header;
|
||||
mWriteSegmentEnd = (char*)mWriteSegment + mGrowBySize;
|
||||
mWriteCursor = (char*)mWriteSegment + sizeof(PRCList);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsBuffer::PopReadSegment()
|
||||
{
|
||||
nsresult rv;
|
||||
nsAutoCMonitor mon(this); // protect mSegments
|
||||
|
||||
PRCList* header = (PRCList*)mSegments.next;
|
||||
char* segment = (char*)header;
|
||||
|
||||
NS_ASSERTION(mReadSegment == header, "wrong segment");
|
||||
|
||||
// make sure that the writer isn't still in this segment (that the
|
||||
// reader is removing)
|
||||
NS_ASSERTION(!(segment <= mWriteCursor && mWriteCursor < segment + mGrowBySize),
|
||||
"removing writer's segment");
|
||||
|
||||
PR_REMOVE_LINK(header); // unlink from mSegments
|
||||
|
||||
mBufferSize -= mGrowBySize;
|
||||
|
||||
rv = mAllocator->Free(segment);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// initialize the read segment
|
||||
if (PR_CLIST_IS_EMPTY(&mSegments)) {
|
||||
mReadSegment = nsnull;
|
||||
mReadSegmentEnd = nsnull;
|
||||
mReadCursor = nsnull;
|
||||
if (mObserver) {
|
||||
rv = mObserver->OnEmpty(this);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
return NS_BASE_STREAM_WOULD_BLOCK;
|
||||
}
|
||||
else {
|
||||
mReadSegment = mSegments.next;
|
||||
mReadSegmentEnd = (char*)mReadSegment + mGrowBySize;
|
||||
mReadCursor = (char*)mReadSegment + sizeof(PRCList);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIBuffer methods:
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::ReadSegments(nsWriteSegmentFun writer, void* closure, PRUint32 count,
|
||||
PRUint32 *readCount)
|
||||
{
|
||||
NS_ASSERTION(!mReaderClosed, "state change error");
|
||||
|
||||
nsAutoCMonitor mon(this);
|
||||
nsresult rv = NS_OK;
|
||||
PRUint32 readBufferLen;
|
||||
const char* readBuffer;
|
||||
|
||||
*readCount = 0;
|
||||
while (count > 0) {
|
||||
rv = GetReadSegment(0, &readBuffer, &readBufferLen);
|
||||
if (NS_FAILED(rv) || readBufferLen == 0) {
|
||||
return *readCount == 0 ? rv : NS_OK;
|
||||
}
|
||||
|
||||
readBufferLen = PR_MIN(readBufferLen, count);
|
||||
while (readBufferLen > 0) {
|
||||
PRUint32 writeCount;
|
||||
rv = writer(closure, readBuffer, *readCount, readBufferLen, &writeCount);
|
||||
NS_ASSERTION(rv != NS_BASE_STREAM_EOF, "Write should not return EOF");
|
||||
if (rv == NS_BASE_STREAM_WOULD_BLOCK || NS_FAILED(rv) || writeCount == 0) {
|
||||
// if we failed to write just report what we were
|
||||
// able to read so far
|
||||
return *readCount == 0 ? rv : NS_OK;
|
||||
}
|
||||
NS_ASSERTION(writeCount <= readBufferLen, "writer returned bad writeCount");
|
||||
readBuffer += writeCount;
|
||||
readBufferLen -= writeCount;
|
||||
*readCount += writeCount;
|
||||
count -= writeCount;
|
||||
|
||||
if (mReadCursor + writeCount == mReadSegmentEnd) {
|
||||
rv = PopReadSegment();
|
||||
if (NS_FAILED(rv)) {
|
||||
return *readCount == 0 ? rv : NS_OK;
|
||||
}
|
||||
}
|
||||
else {
|
||||
mReadCursor += writeCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static NS_METHOD
|
||||
nsWriteToRawBuffer(void* closure,
|
||||
const char* fromRawSegment,
|
||||
PRUint32 offset,
|
||||
PRUint32 count,
|
||||
PRUint32 *writeCount)
|
||||
{
|
||||
char* toBuf = (char*)closure;
|
||||
nsCRT::memcpy(&toBuf[offset], fromRawSegment, count);
|
||||
*writeCount = count;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::Read(char* toBuf, PRUint32 bufLen, PRUint32 *readCount)
|
||||
{
|
||||
return ReadSegments(nsWriteToRawBuffer, toBuf, bufLen, readCount);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::GetReadSegment(PRUint32 segmentLogicalOffset,
|
||||
const char* *resultSegment,
|
||||
PRUint32 *resultSegmentLen)
|
||||
{
|
||||
nsAutoCMonitor mon(this);
|
||||
|
||||
// set the read segment and cursor if not already set
|
||||
if (mReadSegment == nsnull) {
|
||||
if (PR_CLIST_IS_EMPTY(&mSegments)) {
|
||||
*resultSegmentLen = 0;
|
||||
*resultSegment = nsnull;
|
||||
return mCondition;
|
||||
}
|
||||
else {
|
||||
mReadSegment = mSegments.next;
|
||||
mReadSegmentEnd = (char*)mReadSegment + mGrowBySize;
|
||||
mReadCursor = (char*)mReadSegment + sizeof(PRCList);
|
||||
}
|
||||
}
|
||||
|
||||
// now search for the segment starting from segmentLogicalOffset and return it
|
||||
PRCList* curSeg = mReadSegment;
|
||||
char* curSegStart = mReadCursor;
|
||||
char* curSegEnd = mReadSegmentEnd;
|
||||
PRInt32 amt;
|
||||
PRInt32 offset = (PRInt32)segmentLogicalOffset;
|
||||
while (offset >= 0) {
|
||||
// snapshot the write cursor into a local variable -- this allows
|
||||
// a writer to freely change it while we're reading while avoiding
|
||||
// using a lock
|
||||
char* snapshotWriteCursor = mWriteCursor; // atomic
|
||||
|
||||
// next check if the write cursor is in our segment
|
||||
if (curSegStart <= snapshotWriteCursor &&
|
||||
snapshotWriteCursor < curSegEnd) {
|
||||
// same segment -- read up to the snapshotWriteCursor
|
||||
curSegEnd = snapshotWriteCursor;
|
||||
|
||||
amt = curSegEnd - curSegStart;
|
||||
if (offset < amt) {
|
||||
// segmentLogicalOffset is in this segment, so read up to its end
|
||||
*resultSegmentLen = amt - offset;
|
||||
*resultSegment = curSegStart + offset;
|
||||
return NS_OK;
|
||||
}
|
||||
else {
|
||||
// don't continue past the write segment
|
||||
*resultSegmentLen = 0;
|
||||
*resultSegment = nsnull;
|
||||
return mCondition;
|
||||
}
|
||||
}
|
||||
else {
|
||||
amt = curSegEnd - curSegStart;
|
||||
if (offset < amt) {
|
||||
// segmentLogicalOffset is in this segment, so read up to its end
|
||||
*resultSegmentLen = amt - offset;
|
||||
*resultSegment = curSegStart + offset;
|
||||
return NS_OK;
|
||||
}
|
||||
else {
|
||||
curSeg = PR_NEXT_LINK(curSeg);
|
||||
if (curSeg == mReadSegment) {
|
||||
// been all the way around
|
||||
*resultSegmentLen = 0;
|
||||
*resultSegment = nsnull;
|
||||
return mCondition;
|
||||
}
|
||||
curSegEnd = (char*)curSeg + mGrowBySize;
|
||||
curSegStart = (char*)curSeg + sizeof(PRCList);
|
||||
offset -= amt;
|
||||
}
|
||||
}
|
||||
}
|
||||
NS_NOTREACHED("nsBuffer::GetReadSegment failed");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::GetReadableAmount(PRUint32 *result)
|
||||
{
|
||||
NS_ASSERTION(!mReaderClosed, "state change error");
|
||||
|
||||
nsAutoCMonitor mon(this);
|
||||
*result = 0;
|
||||
|
||||
// first set the read segment and cursor if not already set
|
||||
if (mReadSegment == nsnull) {
|
||||
if (PR_CLIST_IS_EMPTY(&mSegments)) {
|
||||
return NS_OK;
|
||||
}
|
||||
else {
|
||||
mReadSegment = mSegments.next;
|
||||
mReadSegmentEnd = (char*)mReadSegment + mGrowBySize;
|
||||
mReadCursor = (char*)mReadSegment + sizeof(PRCList);
|
||||
}
|
||||
}
|
||||
|
||||
// now search for the segment starting from segmentLogicalOffset and return it
|
||||
PRCList* curSeg = mReadSegment;
|
||||
char* curSegStart = mReadCursor;
|
||||
char* curSegEnd = mReadSegmentEnd;
|
||||
PRInt32 amt;
|
||||
while (PR_TRUE) {
|
||||
// snapshot the write cursor into a local variable -- this allows
|
||||
// a writer to freely change it while we're reading while avoiding
|
||||
// using a lock
|
||||
char* snapshotWriteCursor = mWriteCursor; // atomic
|
||||
|
||||
// next check if the write cursor is in our segment
|
||||
if (curSegStart <= snapshotWriteCursor &&
|
||||
snapshotWriteCursor < curSegEnd) {
|
||||
// same segment -- read up to the snapshotWriteCursor
|
||||
curSegEnd = snapshotWriteCursor;
|
||||
|
||||
amt = curSegEnd - curSegStart;
|
||||
*result += amt;
|
||||
return NS_OK;
|
||||
}
|
||||
else {
|
||||
amt = curSegEnd - curSegStart;
|
||||
*result += amt;
|
||||
curSeg = PR_NEXT_LINK(curSeg);
|
||||
if (curSeg == mReadSegment) {
|
||||
// been all the way around
|
||||
return NS_OK;
|
||||
}
|
||||
curSegEnd = (char*)curSeg + mGrowBySize;
|
||||
curSegStart = (char*)curSeg + sizeof(PRCList);
|
||||
}
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
#define COMPARE(s1, s2, i) ignoreCase ? nsCRT::strncasecmp((const char *)s1, (const char *)s2, (PRUint32)i) : nsCRT::strncmp((const char *)s1, (const char *)s2, (PRUint32)i)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::Search(const char* string, PRBool ignoreCase,
|
||||
PRBool *found, PRUint32 *offsetSearchedTo)
|
||||
{
|
||||
NS_ASSERTION(!mReaderClosed, "state change error");
|
||||
|
||||
nsresult rv;
|
||||
const char* bufSeg1;
|
||||
PRUint32 bufSegLen1;
|
||||
PRUint32 segmentPos = 0;
|
||||
PRUint32 strLen = nsCRT::strlen(string);
|
||||
|
||||
rv = GetReadSegment(segmentPos, &bufSeg1, &bufSegLen1);
|
||||
if (NS_FAILED(rv) || bufSegLen1 == 0) {
|
||||
*found = PR_FALSE;
|
||||
*offsetSearchedTo = segmentPos;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
while (PR_TRUE) {
|
||||
PRUint32 i;
|
||||
// check if the string is in the buffer segment
|
||||
for (i = 0; i < bufSegLen1 - strLen + 1; i++) {
|
||||
if (COMPARE(&bufSeg1[i], string, strLen) == 0) {
|
||||
*found = PR_TRUE;
|
||||
*offsetSearchedTo = segmentPos + i;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// get the next segment
|
||||
const char* bufSeg2;
|
||||
PRUint32 bufSegLen2;
|
||||
segmentPos += bufSegLen1;
|
||||
rv = GetReadSegment(segmentPos, &bufSeg2, &bufSegLen2);
|
||||
if (NS_FAILED(rv) || bufSegLen2 == 0) {
|
||||
*found = PR_FALSE;
|
||||
if (mCondition != NS_OK) // XXX NS_FAILED?
|
||||
*offsetSearchedTo = segmentPos - bufSegLen1;
|
||||
else
|
||||
*offsetSearchedTo = segmentPos - bufSegLen1 - strLen + 1;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// check if the string is straddling the next buffer segment
|
||||
PRUint32 limit = PR_MIN(strLen, bufSegLen2 + 1);
|
||||
for (i = 0; i < limit; i++) {
|
||||
PRUint32 strPart1Len = strLen - i - 1;
|
||||
PRUint32 strPart2Len = strLen - strPart1Len;
|
||||
const char* strPart2 = &string[strLen - strPart2Len];
|
||||
PRUint32 bufSeg1Offset = bufSegLen1 - strPart1Len;
|
||||
if (COMPARE(&bufSeg1[bufSeg1Offset], string, strPart1Len) == 0 &&
|
||||
COMPARE(bufSeg2, strPart2, strPart2Len) == 0) {
|
||||
*found = PR_TRUE;
|
||||
*offsetSearchedTo = segmentPos - strPart1Len;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// finally continue with the next buffer
|
||||
bufSeg1 = bufSeg2;
|
||||
bufSegLen1 = bufSegLen2;
|
||||
}
|
||||
NS_NOTREACHED("can't get here");
|
||||
return NS_ERROR_FAILURE; // keep compiler happy
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::ReaderClosed()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsAutoCMonitor mon(this); // protect mSegments
|
||||
|
||||
// first prevent any more writing
|
||||
mReaderClosed = PR_TRUE;
|
||||
|
||||
// then free any unread segments...
|
||||
|
||||
// first set the read segment and cursor if not already set
|
||||
if (mReadSegment == nsnull) {
|
||||
if (!PR_CLIST_IS_EMPTY(&mSegments)) {
|
||||
mReadSegment = mSegments.next;
|
||||
mReadSegmentEnd = (char*)mReadSegment + mGrowBySize;
|
||||
mReadCursor = (char*)mReadSegment + sizeof(PRCList);
|
||||
}
|
||||
}
|
||||
|
||||
while (mReadSegment) {
|
||||
// snapshot the write cursor into a local variable -- this allows
|
||||
// a writer to freely change it while we're reading while avoiding
|
||||
// using a lock
|
||||
char* snapshotWriteCursor = mWriteCursor; // atomic
|
||||
|
||||
// next check if the write cursor is in our segment
|
||||
if (mReadCursor <= snapshotWriteCursor &&
|
||||
snapshotWriteCursor < mReadSegmentEnd) {
|
||||
// same segment -- we've discarded all the unread segments we
|
||||
// can, so just updatethe read cursor
|
||||
mReadCursor = mWriteCursor;
|
||||
break;
|
||||
}
|
||||
// else advance to the next segment, freeing this one
|
||||
rv = PopReadSegment();
|
||||
if (NS_FAILED(rv)) break;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
PRUint32 amt;
|
||||
const char* buf;
|
||||
rv = GetReadSegment(0, &buf, &amt);
|
||||
NS_ASSERTION(rv == NS_BASE_STREAM_EOF ||
|
||||
(NS_SUCCEEDED(rv) && amt == 0), "ReaderClosed failed");
|
||||
#endif
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::GetCondition(nsresult *result)
|
||||
{
|
||||
*result = mCondition;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::WriteSegments(nsReadSegmentFun reader, void* closure, PRUint32 count,
|
||||
PRUint32 *writeCount)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
nsAutoCMonitor mon(this);
|
||||
*writeCount = 0;
|
||||
|
||||
if (mReaderClosed) {
|
||||
rv = NS_BASE_STREAM_CLOSED;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (NS_FAILED(mCondition)) {
|
||||
rv = mCondition;
|
||||
goto done;
|
||||
}
|
||||
|
||||
while (count > 0) {
|
||||
PRUint32 writeBufLen;
|
||||
char* writeBuf;
|
||||
rv = GetWriteSegment(&writeBuf, &writeBufLen);
|
||||
if (NS_FAILED(rv) || writeBufLen == 0) {
|
||||
// if we failed to allocate a new segment, we're probably out
|
||||
// of memory, but we don't care -- just report what we were
|
||||
// able to write so far
|
||||
rv = (*writeCount == 0) ? rv : NS_OK;
|
||||
goto done;
|
||||
}
|
||||
|
||||
writeBufLen = PR_MIN(writeBufLen, count);
|
||||
while (writeBufLen > 0) {
|
||||
PRUint32 readCount = 0;
|
||||
rv = reader(closure, writeBuf, *writeCount, writeBufLen, &readCount);
|
||||
if (rv == NS_BASE_STREAM_WOULD_BLOCK || readCount == 0) {
|
||||
// if the place we're putting the data would block (probably ran
|
||||
// out of room) just return what we were able to write so far
|
||||
rv = (*writeCount == 0) ? rv : NS_OK;
|
||||
goto done;
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
// save the failure condition so that we can get it again later
|
||||
nsresult rv2 = SetCondition(rv);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv2), "SetCondition failed");
|
||||
// if we failed to read just report what we were
|
||||
// able to write so far
|
||||
rv = (*writeCount == 0) ? rv : NS_OK;
|
||||
goto done;
|
||||
}
|
||||
NS_ASSERTION(readCount <= writeBufLen, "reader returned bad readCount");
|
||||
writeBuf += readCount;
|
||||
writeBufLen -= readCount;
|
||||
*writeCount += readCount;
|
||||
count -= readCount;
|
||||
|
||||
// set the write cursor after the data is valid
|
||||
if (mWriteCursor + readCount == mWriteSegmentEnd) {
|
||||
mWriteSegment = nsnull; // allocate a new segment next time around
|
||||
mWriteSegmentEnd = nsnull;
|
||||
mWriteCursor = nsnull;
|
||||
}
|
||||
else
|
||||
mWriteCursor += readCount;
|
||||
}
|
||||
}
|
||||
done:
|
||||
if (mObserver && *writeCount) {
|
||||
mObserver->OnWrite(this, *writeCount);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
static NS_METHOD
|
||||
nsReadFromRawBuffer(void* closure,
|
||||
char* toRawSegment,
|
||||
PRUint32 offset,
|
||||
PRUint32 count,
|
||||
PRUint32 *readCount)
|
||||
{
|
||||
const char* fromBuf = (const char*)closure;
|
||||
nsCRT::memcpy(toRawSegment, &fromBuf[offset], count);
|
||||
*readCount = count;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::Write(const char* fromBuf, PRUint32 bufLen, PRUint32 *writeCount)
|
||||
{
|
||||
return WriteSegments(nsReadFromRawBuffer, (void*)fromBuf, bufLen, writeCount);
|
||||
}
|
||||
|
||||
static NS_METHOD
|
||||
nsReadFromInputStream(void* closure,
|
||||
char* toRawSegment,
|
||||
PRUint32 offset,
|
||||
PRUint32 count,
|
||||
PRUint32 *readCount)
|
||||
{
|
||||
nsIInputStream* fromStream = (nsIInputStream*)closure;
|
||||
return fromStream->Read(toRawSegment, count, readCount);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::WriteFrom(nsIInputStream* fromStream, PRUint32 count, PRUint32 *writeCount)
|
||||
{
|
||||
return WriteSegments(nsReadFromInputStream, fromStream, count, writeCount);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::GetWriteSegment(char* *resultSegment,
|
||||
PRUint32 *resultSegmentLen)
|
||||
{
|
||||
nsAutoCMonitor mon(this);
|
||||
if (mReaderClosed)
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
|
||||
nsresult rv;
|
||||
*resultSegmentLen = 0;
|
||||
*resultSegment = nsnull;
|
||||
if (mWriteSegment == nsnull) {
|
||||
rv = PushWriteSegment();
|
||||
if (NS_FAILED(rv) || rv == NS_BASE_STREAM_WOULD_BLOCK) return rv;
|
||||
|
||||
NS_ASSERTION(mWriteSegment != nsnull, "failed to allocate segment");
|
||||
}
|
||||
|
||||
*resultSegmentLen = mWriteSegmentEnd - mWriteCursor;
|
||||
*resultSegment = mWriteCursor;
|
||||
NS_ASSERTION(*resultSegmentLen > 0, "Failed to get write segment.");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::GetWritableAmount(PRUint32 *amount)
|
||||
{
|
||||
if (mReaderClosed)
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
|
||||
nsresult rv;
|
||||
PRUint32 readableAmount;
|
||||
rv = GetReadableAmount(&readableAmount);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
*amount = mMaxSize - readableAmount;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::GetReaderClosed(PRBool *result)
|
||||
{
|
||||
*result = mReaderClosed;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsBuffer::SetCondition(nsresult condition)
|
||||
{
|
||||
nsAutoCMonitor mon(this);
|
||||
if (mReaderClosed)
|
||||
return NS_BASE_STREAM_CLOSED;
|
||||
|
||||
mCondition = condition;
|
||||
mWriteSegment = nsnull; // allows reader to free last segment w/o asserting
|
||||
mWriteSegmentEnd = nsnull;
|
||||
// don't reset mWriteCursor here -- we need it for the EOF point in the buffer
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static NS_DEFINE_CID(kAllocatorCID, NS_ALLOCATOR_CID);
|
||||
|
||||
NS_COM nsresult
|
||||
NS_NewBuffer(nsIBuffer* *result,
|
||||
PRUint32 growBySize, PRUint32 maxSize,
|
||||
nsIBufferObserver* observer)
|
||||
{
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE(nsIAllocator, alloc, kAllocatorCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsBuffer* buf;
|
||||
rv = nsBuffer::Create(NULL, nsIBuffer::GetIID(), (void**)&buf);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = buf->Init(growBySize, maxSize, observer, alloc);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_RELEASE(buf);
|
||||
return rv;
|
||||
}
|
||||
|
||||
*result = buf;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static NS_DEFINE_CID(kPageManagerCID, NS_PAGEMANAGER_CID);
|
||||
|
||||
NS_COM nsresult
|
||||
NS_NewPageBuffer(nsIBuffer* *result,
|
||||
PRUint32 growBySize, PRUint32 maxSize,
|
||||
nsIBufferObserver* observer)
|
||||
{
|
||||
nsresult rv;
|
||||
NS_WITH_SERVICE(nsIAllocator, alloc, kPageManagerCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsBuffer* buf;
|
||||
rv = nsBuffer::Create(NULL, nsIBuffer::GetIID(), (void**)&buf);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = buf->Init(growBySize, maxSize, observer, alloc);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_RELEASE(buf);
|
||||
return rv;
|
||||
}
|
||||
|
||||
*result = buf;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
87
mozilla/xpcom/ds/nsBuffer.h
Normal file
87
mozilla/xpcom/ds/nsBuffer.h
Normal file
@@ -0,0 +1,87 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef nsBuffer_h___
|
||||
#define nsBuffer_h___
|
||||
|
||||
#include "nsIBuffer.h"
|
||||
#include "nscore.h"
|
||||
#include "prclist.h"
|
||||
#include "nsIAllocator.h"
|
||||
|
||||
class nsBuffer : public nsIBuffer {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
static NS_METHOD
|
||||
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||
|
||||
// nsIBuffer methods:
|
||||
NS_IMETHOD Init(PRUint32 growBySize, PRUint32 maxSize,
|
||||
nsIBufferObserver* observer, nsIAllocator* allocator);
|
||||
NS_IMETHOD Read(char* toBuf, PRUint32 bufLen, PRUint32 *readCount);
|
||||
NS_IMETHOD ReadSegments(nsWriteSegmentFun writer, void* closure, PRUint32 count,
|
||||
PRUint32 *readCount);
|
||||
NS_IMETHOD GetReadSegment(PRUint32 segmentLogicalOffset,
|
||||
const char* *resultSegment,
|
||||
PRUint32 *resultSegmentLen);
|
||||
NS_IMETHOD GetReadableAmount(PRUint32 *amount);
|
||||
NS_IMETHOD Search(const char* forString, PRBool ignoreCase,
|
||||
PRBool *found, PRUint32 *offsetSearchedTo);
|
||||
NS_IMETHOD ReaderClosed(void);
|
||||
NS_IMETHOD GetCondition(nsresult *result);
|
||||
|
||||
NS_IMETHOD Write(const char* fromBuf, PRUint32 bufLen, PRUint32 *writeCount);
|
||||
NS_IMETHOD WriteFrom(nsIInputStream* fromStream, PRUint32 count, PRUint32 *writeCount);
|
||||
NS_IMETHOD WriteSegments(nsReadSegmentFun reader, void* closure, PRUint32 count,
|
||||
PRUint32 *writeCount);
|
||||
NS_IMETHOD GetWriteSegment(char* *resultSegment,
|
||||
PRUint32 *resultSegmentLen);
|
||||
NS_IMETHOD GetWritableAmount(PRUint32 *amount);
|
||||
NS_IMETHOD GetReaderClosed(PRBool *result);
|
||||
NS_IMETHOD SetCondition(nsresult condition);
|
||||
|
||||
// nsBuffer methods:
|
||||
nsBuffer();
|
||||
virtual ~nsBuffer();
|
||||
|
||||
nsresult PushWriteSegment();
|
||||
nsresult PopReadSegment();
|
||||
|
||||
protected:
|
||||
PRUint32 mGrowBySize;
|
||||
PRUint32 mMaxSize;
|
||||
nsIAllocator* mAllocator;
|
||||
nsIBufferObserver* mObserver;
|
||||
|
||||
PRCList mSegments;
|
||||
PRUint32 mBufferSize;
|
||||
|
||||
PRCList* mReadSegment;
|
||||
char* mReadSegmentEnd;
|
||||
char* mReadCursor;
|
||||
|
||||
PRCList* mWriteSegment;
|
||||
char* mWriteSegmentEnd;
|
||||
char* mWriteCursor;
|
||||
|
||||
PRBool mReaderClosed;
|
||||
nsresult mCondition;
|
||||
};
|
||||
|
||||
#endif // nsBuffer_h___
|
||||
40
mozilla/xpcom/ds/nsBufferPoolService.h
Normal file
40
mozilla/xpcom/ds/nsBufferPoolService.h
Normal file
@@ -0,0 +1,40 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef nsBufferPoolService_h___
|
||||
#define nsBufferPoolService_h___
|
||||
|
||||
#include "nsIBufferPoolService.h"
|
||||
|
||||
class nsBufferPoolService : public nsIBufferPoolService {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIBufferPoolService methods:
|
||||
NS_IMETHOD NewBuffer(PRUint32 minSize, PRUint32 maxSize,
|
||||
nsIByteBuffer* *result);
|
||||
|
||||
// nsBufferPoolService methods:
|
||||
nsBufferPoolService();
|
||||
virtual ~nsBufferPoolService();
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
#endif // nsBufferPoolService_h___
|
||||
151
mozilla/xpcom/ds/nsByteBuffer.cpp
Normal file
151
mozilla/xpcom/ds/nsByteBuffer.cpp
Normal file
@@ -0,0 +1,151 @@
|
||||
/* -*- Mode: C++; tab-width: 2; 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 "nsByteBuffer.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsCRT.h"
|
||||
|
||||
#define MIN_BUFFER_SIZE 32
|
||||
|
||||
ByteBufferImpl::ByteBufferImpl(void)
|
||||
: mBuffer(NULL), mSpace(0), mLength(0)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
ByteBufferImpl::Init(PRUint32 aBufferSize)
|
||||
{
|
||||
if (aBufferSize < MIN_BUFFER_SIZE) {
|
||||
aBufferSize = MIN_BUFFER_SIZE;
|
||||
}
|
||||
mSpace = aBufferSize;
|
||||
mLength = 0;
|
||||
mBuffer = new char[aBufferSize];
|
||||
return mBuffer ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(ByteBufferImpl,nsIByteBuffer)
|
||||
|
||||
ByteBufferImpl::~ByteBufferImpl()
|
||||
{
|
||||
if (nsnull != mBuffer) {
|
||||
delete[] mBuffer;
|
||||
mBuffer = nsnull;
|
||||
}
|
||||
mLength = 0;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
ByteBufferImpl::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
||||
{
|
||||
if (aOuter)
|
||||
return NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
ByteBufferImpl* it = new ByteBufferImpl();
|
||||
if (nsnull == it)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
NS_ADDREF(it);
|
||||
nsresult rv = it->QueryInterface(aIID, (void**)aResult);
|
||||
NS_RELEASE(it);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(PRUint32)
|
||||
ByteBufferImpl::GetLength(void) const
|
||||
{
|
||||
return mLength;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(PRUint32)
|
||||
ByteBufferImpl::GetBufferSize(void) const
|
||||
{
|
||||
return mSpace;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(char*)
|
||||
ByteBufferImpl::GetBuffer(void) const
|
||||
{
|
||||
return mBuffer;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(PRBool)
|
||||
ByteBufferImpl::Grow(PRUint32 aNewSize)
|
||||
{
|
||||
if (aNewSize < MIN_BUFFER_SIZE) {
|
||||
aNewSize = MIN_BUFFER_SIZE;
|
||||
}
|
||||
char* newbuf = new char[aNewSize];
|
||||
if (nsnull != newbuf) {
|
||||
if (0 != mLength) {
|
||||
nsCRT::memcpy(newbuf, mBuffer, mLength);
|
||||
}
|
||||
delete[] mBuffer;
|
||||
mBuffer = newbuf;
|
||||
return PR_TRUE;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(PRInt32)
|
||||
ByteBufferImpl::Fill(nsresult* aErrorCode, nsIInputStream* aStream,
|
||||
PRUint32 aKeep)
|
||||
{
|
||||
NS_PRECONDITION(nsnull != aStream, "null stream");
|
||||
NS_PRECONDITION(aKeep <= mLength, "illegal keep count");
|
||||
if ((nsnull == aStream) || (PRUint32(aKeep) > PRUint32(mLength))) {
|
||||
// whoops
|
||||
*aErrorCode = NS_BASE_STREAM_ILLEGAL_ARGS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (0 != aKeep) {
|
||||
// Slide over kept data
|
||||
nsCRT::memmove(mBuffer, mBuffer + (mLength - aKeep), aKeep);
|
||||
}
|
||||
|
||||
// Read in some new data
|
||||
mLength = aKeep;
|
||||
PRUint32 nb;
|
||||
*aErrorCode = aStream->Read(mBuffer + aKeep, mSpace - aKeep, &nb);
|
||||
if (NS_SUCCEEDED(*aErrorCode)) {
|
||||
mLength += nb;
|
||||
}
|
||||
else
|
||||
nb = 0;
|
||||
return nb;
|
||||
}
|
||||
|
||||
NS_COM nsresult NS_NewByteBuffer(nsIByteBuffer** aInstancePtrResult,
|
||||
nsISupports* aOuter,
|
||||
PRUint32 aBufferSize)
|
||||
{
|
||||
nsresult rv;
|
||||
nsIByteBuffer* buf;
|
||||
rv = ByteBufferImpl::Create(aOuter, nsIByteBuffer::GetIID(), (void**)&buf);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = buf->Init(aBufferSize);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_RELEASE(buf);
|
||||
return rv;
|
||||
}
|
||||
*aInstancePtrResult = buf;
|
||||
return rv;
|
||||
}
|
||||
47
mozilla/xpcom/ds/nsByteBuffer.h
Normal file
47
mozilla/xpcom/ds/nsByteBuffer.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/* -*- Mode: C++; tab-width: 2; 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.
|
||||
*/
|
||||
|
||||
#ifndef nsByteBuffer_h__
|
||||
#define nsByteBuffer_h__
|
||||
|
||||
#include "nsIByteBuffer.h"
|
||||
|
||||
class ByteBufferImpl : public nsIByteBuffer {
|
||||
public:
|
||||
ByteBufferImpl(void);
|
||||
virtual ~ByteBufferImpl();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
static NS_METHOD
|
||||
Create(nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||
|
||||
NS_IMETHOD Init(PRUint32 aBufferSize);
|
||||
NS_IMETHOD_(PRUint32) GetLength(void) const;
|
||||
NS_IMETHOD_(PRUint32) GetBufferSize(void) const;
|
||||
NS_IMETHOD_(char*) GetBuffer() const;
|
||||
NS_IMETHOD_(PRBool) Grow(PRUint32 aNewSize);
|
||||
NS_IMETHOD_(PRInt32) Fill(nsresult* aErrorCode, nsIInputStream* aStream,
|
||||
PRUint32 aKeep);
|
||||
|
||||
char* mBuffer;
|
||||
PRUint32 mSpace;
|
||||
PRUint32 mLength;
|
||||
};
|
||||
|
||||
#endif // nsByteBuffer_h__
|
||||
555
mozilla/xpcom/ds/nsCRT.cpp
Normal file
555
mozilla/xpcom/ds/nsCRT.cpp
Normal file
@@ -0,0 +1,555 @@
|
||||
/* -*- Mode: C++; tab-width: 2; 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.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* MODULE NOTES:
|
||||
* @update gess7/30/98
|
||||
*
|
||||
* Much as I hate to do it, we were using string compares wrong.
|
||||
* Often, programmers call functions like strcmp(s1,s2), and pass
|
||||
* one or more null strings. Rather than blow up on these, I've
|
||||
* added quick checks to ensure that cases like this don't cause
|
||||
* us to fail.
|
||||
*
|
||||
* In general, if you pass a null into any of these string compare
|
||||
* routines, we simply return 0.
|
||||
*/
|
||||
|
||||
|
||||
#include "nsCRT.h"
|
||||
#include "nsUnicharUtilCIID.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsICaseConversion.h"
|
||||
|
||||
|
||||
// XXX Bug: These tables don't lowercase the upper 128 characters properly
|
||||
|
||||
// This table maps uppercase characters to lower case characters;
|
||||
// characters that are neither upper nor lower case are unaffected.
|
||||
static const unsigned char kUpper2Lower[256] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
||||
64,
|
||||
|
||||
// upper band mapped to lower [A-Z] => [a-z]
|
||||
97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
|
||||
112,113,114,115,116,117,118,119,120,121,122,
|
||||
|
||||
91, 92, 93, 94, 95,
|
||||
96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
|
||||
112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
|
||||
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
|
||||
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
|
||||
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
|
||||
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
|
||||
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
|
||||
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
|
||||
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
|
||||
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
|
||||
};
|
||||
|
||||
static const unsigned char kLower2Upper[256] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
||||
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
|
||||
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
|
||||
96,
|
||||
|
||||
// lower band mapped to upper [a-z] => [A-Z]
|
||||
65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
|
||||
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90,
|
||||
|
||||
123,124,125,126,127,
|
||||
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
|
||||
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
|
||||
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
|
||||
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
|
||||
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
|
||||
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
|
||||
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
|
||||
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
|
||||
};
|
||||
|
||||
// XXX bug: this doesn't map 0x80 to 0x9f properly
|
||||
const PRUnichar kIsoLatin1ToUCS2[256] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
||||
64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
|
||||
80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
|
||||
96, 97, 98, 99,100,101,102,103,104,105,106,107,108,109,110,111,
|
||||
112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
|
||||
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
|
||||
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
|
||||
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
|
||||
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
|
||||
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
|
||||
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
|
||||
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
|
||||
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
#define TOLOWER(_ucs2) \
|
||||
(((_ucs2) < 128) ? PRUnichar(kUpper2Lower[_ucs2]) : _ToLower(_ucs2))
|
||||
|
||||
#define TOUPPER(_ucs2) \
|
||||
(((_ucs2) < 128) ? PRUnichar(kLower2Upper[_ucs2]) : _ToUpper(_ucs2))
|
||||
|
||||
class HandleCaseConversionShutdown : public nsIShutdownListener {
|
||||
public :
|
||||
NS_IMETHOD OnShutdown(const nsCID& cid, nsISupports* service);
|
||||
HandleCaseConversionShutdown(void) { NS_INIT_REFCNT(); }
|
||||
virtual ~HandleCaseConversionShutdown(void) {}
|
||||
NS_DECL_ISUPPORTS
|
||||
};
|
||||
static NS_DEFINE_CID(kUnicharUtilCID, NS_UNICHARUTIL_CID);
|
||||
|
||||
static nsICaseConversion * gCaseConv = NULL;
|
||||
|
||||
NS_IMPL_ISUPPORTS1(HandleCaseConversionShutdown, nsIShutdownListener)
|
||||
|
||||
nsresult
|
||||
HandleCaseConversionShutdown::OnShutdown(const nsCID& cid,
|
||||
nsISupports* aService)
|
||||
{
|
||||
if (cid.Equals(kUnicharUtilCID)) {
|
||||
NS_ASSERTION(aService == gCaseConv, "wrong service!");
|
||||
gCaseConv->Release();
|
||||
gCaseConv = NULL;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static HandleCaseConversionShutdown* gListener = NULL;
|
||||
|
||||
static void StartUpCaseConversion()
|
||||
{
|
||||
nsresult err;
|
||||
|
||||
if ( NULL == gListener )
|
||||
{
|
||||
gListener = new HandleCaseConversionShutdown();
|
||||
gListener->AddRef();
|
||||
}
|
||||
err = nsServiceManager::GetService(kUnicharUtilCID, NS_GET_IID(nsICaseConversion),
|
||||
(nsISupports**) &gCaseConv, gListener);
|
||||
}
|
||||
static void CheckCaseConversion()
|
||||
{
|
||||
if(NULL == gCaseConv )
|
||||
StartUpCaseConversion();
|
||||
|
||||
NS_ASSERTION( gCaseConv != NULL , "cannot obtain UnicharUtil");
|
||||
|
||||
}
|
||||
|
||||
static PRUnichar _ToLower(PRUnichar aChar)
|
||||
{
|
||||
PRUnichar oLower;
|
||||
CheckCaseConversion();
|
||||
nsresult err = gCaseConv->ToLower(aChar, &oLower);
|
||||
NS_ASSERTION( NS_SUCCEEDED(err), "failed to communicate to UnicharUtil");
|
||||
return ( NS_SUCCEEDED(err) ) ? oLower : aChar ;
|
||||
}
|
||||
|
||||
static PRUnichar _ToUpper(PRUnichar aChar)
|
||||
{
|
||||
nsresult err;
|
||||
PRUnichar oUpper;
|
||||
CheckCaseConversion();
|
||||
err = gCaseConv->ToUpper(aChar, &oUpper);
|
||||
NS_ASSERTION( NS_SUCCEEDED(err), "failed to communicate to UnicharUtil");
|
||||
return ( NS_SUCCEEDED(err) ) ? oUpper : aChar ;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
PRUnichar nsCRT::ToUpper(PRUnichar aChar)
|
||||
{
|
||||
return TOUPPER(aChar);
|
||||
}
|
||||
|
||||
PRUnichar nsCRT::ToLower(PRUnichar aChar)
|
||||
{
|
||||
return TOLOWER(aChar);
|
||||
}
|
||||
|
||||
PRBool nsCRT::IsUpper(PRUnichar aChar)
|
||||
{
|
||||
return aChar != nsCRT::ToLower(aChar);
|
||||
}
|
||||
|
||||
PRBool nsCRT::IsLower(PRUnichar aChar)
|
||||
{
|
||||
return aChar != nsCRT::ToUpper(aChar);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// My lovely strtok routine
|
||||
|
||||
#define IS_DELIM(m, c) ((m)[(c) >> 3] & (1 << ((c) & 7)))
|
||||
#define SET_DELIM(m, c) ((m)[(c) >> 3] |= (1 << ((c) & 7)))
|
||||
#define DELIM_TABLE_SIZE 32
|
||||
|
||||
char* nsCRT::strtok(char* string, const char* delims, char* *newStr)
|
||||
{
|
||||
NS_ASSERTION(string, "Unlike regular strtok, the first argument cannot be null.");
|
||||
|
||||
char delimTable[DELIM_TABLE_SIZE];
|
||||
PRUint32 i;
|
||||
char* result;
|
||||
char* str = string;
|
||||
|
||||
for (i = 0; i < DELIM_TABLE_SIZE; i++)
|
||||
delimTable[i] = '\0';
|
||||
|
||||
for (i = 0; i < DELIM_TABLE_SIZE && delims[i]; i++) {
|
||||
SET_DELIM(delimTable, delims[i]);
|
||||
}
|
||||
NS_ASSERTION(delims[i] == '\0', "too many delimiters");
|
||||
|
||||
// skip to beginning
|
||||
while (*str && IS_DELIM(delimTable, *str)) {
|
||||
str++;
|
||||
}
|
||||
result = str;
|
||||
|
||||
// fix up the end of the token
|
||||
while (*str) {
|
||||
if (IS_DELIM(delimTable, *str)) {
|
||||
*str++ = '\0';
|
||||
break;
|
||||
}
|
||||
str++;
|
||||
}
|
||||
*newStr = str;
|
||||
|
||||
return str == result ? NULL : result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
PRUint32 nsCRT::strlen(const PRUnichar* s)
|
||||
{
|
||||
PRUint32 len = 0;
|
||||
if(s) {
|
||||
while (*s++ != 0) {
|
||||
len++;
|
||||
}
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compare unichar string ptrs, stopping at the 1st null
|
||||
* NOTE: If both are null, we return 0.
|
||||
* @update gess7/30/98
|
||||
* @param s1 and s2 both point to unichar strings
|
||||
* @return 0 if they match, -1 if s1<s2; 1 if s1>s2
|
||||
*/
|
||||
PRInt32 nsCRT::strcmp(const PRUnichar* s1, const PRUnichar* s2)
|
||||
{
|
||||
if(s1 && s2) {
|
||||
for (;;) {
|
||||
PRUnichar c1 = *s1++;
|
||||
PRUnichar c2 = *s2++;
|
||||
if (c1 != c2) {
|
||||
if (c1 < c2) return -1;
|
||||
return 1;
|
||||
}
|
||||
if ((0==c1) || (0==c2)) break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare unichar string ptrs, stopping at the 1st null or nth char.
|
||||
* NOTE: If either is null, we return 0.
|
||||
* @update gess7/30/98
|
||||
* @param s1 and s2 both point to unichar strings
|
||||
* @return 0 if they match, -1 if s1<s2; 1 if s1>s2
|
||||
*/
|
||||
PRInt32 nsCRT::strncmp(const PRUnichar* s1, const PRUnichar* s2, PRUint32 n)
|
||||
{
|
||||
if(s1 && s2) {
|
||||
if(n != 0) {
|
||||
do {
|
||||
PRUnichar c1 = *s1++;
|
||||
PRUnichar c2 = *s2++;
|
||||
if (c1 != c2) {
|
||||
if (c1 < c2) return -1;
|
||||
return 1;
|
||||
}
|
||||
if ((0==c1) || (0==c2)) break;
|
||||
} while (--n != 0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compare unichar string ptrs without regard to case
|
||||
* NOTE: If both are null, we return 0.
|
||||
* @update gess7/30/98
|
||||
* @param s1 and s2 both point to unichar strings
|
||||
* @return 0 if they match, -1 if s1<s2; 1 if s1>s2
|
||||
*/
|
||||
PRInt32 nsCRT::strcasecmp(const PRUnichar* s1, const PRUnichar* s2)
|
||||
{
|
||||
if(s1 && s2) {
|
||||
for (;;) {
|
||||
PRUnichar c1 = *s1++;
|
||||
PRUnichar c2 = *s2++;
|
||||
if (c1 != c2) {
|
||||
c1 = TOLOWER(c1);
|
||||
c2 = TOLOWER(c2);
|
||||
if (c1 != c2) {
|
||||
if (c1 < c2) return -1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if ((0==c1) || (0==c2)) break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare unichar string ptrs, stopping at the 1st null or nth char;
|
||||
* also ignoring the case of characters.
|
||||
* NOTE: If both are null, we return 0.
|
||||
* @update gess7/30/98
|
||||
* @param s1 and s2 both point to unichar strings
|
||||
* @return 0 if they match, -1 if s1<s2; 1 if s1>s2
|
||||
*/
|
||||
PRInt32 nsCRT::strncasecmp(const PRUnichar* s1, const PRUnichar* s2, PRUint32 n)
|
||||
{
|
||||
if(s1 && s2) {
|
||||
if(n != 0){
|
||||
do {
|
||||
PRUnichar c1 = *s1++;
|
||||
PRUnichar c2 = *s2++;
|
||||
if (c1 != c2) {
|
||||
c1 = TOLOWER(c1);
|
||||
c2 = TOLOWER(c2);
|
||||
if (c1 != c2) {
|
||||
if (c1 < c2) return -1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if ((0==c1) || (0==c2)) break;
|
||||
} while (--n != 0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compare a unichar string ptr to cstring.
|
||||
* NOTE: If both are null, we return 0.
|
||||
* @update gess7/30/98
|
||||
* @param s1 points to unichar string
|
||||
* @param s2 points to cstring
|
||||
* @return 0 if they match, -1 if s1<s2; 1 if s1>s2
|
||||
*/
|
||||
PRInt32 nsCRT::strcmp(const PRUnichar* s1, const char* s2)
|
||||
{
|
||||
if(s1 && s2) {
|
||||
for (;;) {
|
||||
PRUnichar c1 = *s1++;
|
||||
PRUnichar c2 = kIsoLatin1ToUCS2[*(const unsigned char*)s2++];
|
||||
if (c1 != c2) {
|
||||
if (c1 < c2) return -1;
|
||||
return 1;
|
||||
}
|
||||
if ((0==c1) || (0==c2)) break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compare a unichar string ptr to cstring, up to N chars.
|
||||
* NOTE: If both are null, we return 0.
|
||||
* @update gess7/30/98
|
||||
* @param s1 points to unichar string
|
||||
* @param s2 points to cstring
|
||||
* @return 0 if they match, -1 if s1<s2; 1 if s1>s2
|
||||
*/
|
||||
PRInt32 nsCRT::strncmp(const PRUnichar* s1, const char* s2, PRUint32 n)
|
||||
{
|
||||
if(s1 && s2) {
|
||||
if(n != 0){
|
||||
do {
|
||||
PRUnichar c1 = *s1++;
|
||||
PRUnichar c2 = kIsoLatin1ToUCS2[*(const unsigned char*)s2++];
|
||||
if (c1 != c2) {
|
||||
if (c1 < c2) return -1;
|
||||
return 1;
|
||||
}
|
||||
if ((0==c1) || (0==c2)) break;
|
||||
} while (--n != 0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare a unichar string ptr to cstring without regard to case
|
||||
* NOTE: If both are null, we return 0.
|
||||
* @update gess7/30/98
|
||||
* @param s1 points to unichar string
|
||||
* @param s2 points to cstring
|
||||
* @return 0 if they match, -1 if s1<s2; 1 if s1>s2
|
||||
*/
|
||||
PRInt32 nsCRT::strcasecmp(const PRUnichar* s1, const char* s2)
|
||||
{
|
||||
if(s1 && s2) {
|
||||
for (;;) {
|
||||
PRUnichar c1 = *s1++;
|
||||
PRUnichar c2 = kIsoLatin1ToUCS2[*(const unsigned char*)s2++];
|
||||
if (c1 != c2) {
|
||||
c1 = TOLOWER(c1);
|
||||
c2 = TOLOWER(c2);
|
||||
if (c1 != c2) {
|
||||
if (c1 < c2) return -1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if ((0==c1) || (0==c2)) break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Caseless compare up to N chars between unichar string ptr to cstring.
|
||||
* NOTE: If both are null, we return 0.
|
||||
* @update gess7/30/98
|
||||
* @param s1 points to unichar string
|
||||
* @param s2 points to cstring
|
||||
* @return 0 if they match, -1 if s1<s2; 1 if s1>s2
|
||||
*/
|
||||
PRInt32 nsCRT::strncasecmp(const PRUnichar* s1, const char* s2, PRUint32 n)
|
||||
{
|
||||
if(s1 && s2){
|
||||
if(n != 0){
|
||||
do {
|
||||
PRUnichar c1 = *s1++;
|
||||
PRUnichar c2 = kIsoLatin1ToUCS2[*(const unsigned char*)s2++];
|
||||
if (c1 != c2) {
|
||||
c1 = TOLOWER(c1);
|
||||
c2 = TOLOWER(c2);
|
||||
if (c1 != c2) {
|
||||
if (c1 < c2) return -1;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (c1 == 0) break;
|
||||
} while (--n != 0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
PRUnichar* nsCRT::strdup(const PRUnichar* str)
|
||||
{
|
||||
PRUint32 len = nsCRT::strlen(str) + 1; // add one for null
|
||||
|
||||
|
||||
nsCppSharedAllocator<PRUnichar> shared_allocator;
|
||||
PRUnichar* rslt = shared_allocator.allocate(len);
|
||||
// PRUnichar* rslt = new PRUnichar[len];
|
||||
|
||||
if (rslt == NULL) return NULL;
|
||||
nsCRT::memcpy(rslt, str, len * sizeof(PRUnichar));
|
||||
return rslt;
|
||||
}
|
||||
|
||||
PRUint32 nsCRT::HashValue(const char* us)
|
||||
{
|
||||
PRUint32 rv = 0;
|
||||
if(us) {
|
||||
char ch;
|
||||
while ((ch = *us++) != 0) {
|
||||
// FYI: rv = rv*37 + ch
|
||||
rv = ((rv << 5) + (rv << 2) + rv) + ch;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRUint32 nsCRT::HashValue(const char* us, PRUint32* uslenp)
|
||||
{
|
||||
PRUint32 rv = 0;
|
||||
PRUint32 len = 0;
|
||||
char ch;
|
||||
while ((ch = *us++) != 0) {
|
||||
// FYI: rv = rv*37 + ch
|
||||
rv = ((rv << 5) + (rv << 2) + rv) + ch;
|
||||
len++;
|
||||
}
|
||||
*uslenp = len;
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRUint32 nsCRT::HashValue(const PRUnichar* us)
|
||||
{
|
||||
PRUint32 rv = 0;
|
||||
if(us) {
|
||||
PRUnichar ch;
|
||||
while ((ch = *us++) != 0) {
|
||||
// FYI: rv = rv*37 + ch
|
||||
rv = ((rv << 5) + (rv << 2) + rv) + ch;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRUint32 nsCRT::HashValue(const PRUnichar* us, PRUint32* uslenp)
|
||||
{
|
||||
PRUint32 rv = 0;
|
||||
PRUint32 len = 0;
|
||||
PRUnichar ch;
|
||||
while ((ch = *us++) != 0) {
|
||||
// FYI: rv = rv*37 + ch
|
||||
rv = ((rv << 5) + (rv << 2) + rv) + ch;
|
||||
len++;
|
||||
}
|
||||
*uslenp = len;
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRInt32 nsCRT::atoi( const PRUnichar *string )
|
||||
{
|
||||
return atoi(string);
|
||||
}
|
||||
|
||||
239
mozilla/xpcom/ds/nsCRT.h
Normal file
239
mozilla/xpcom/ds/nsCRT.h
Normal file
@@ -0,0 +1,239 @@
|
||||
/* -*- Mode: C++; tab-width: 2; 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.
|
||||
*/
|
||||
#ifndef nsCRT_h___
|
||||
#define nsCRT_h___
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "plstr.h"
|
||||
#include "nscore.h"
|
||||
#include "prtypes.h"
|
||||
#include "nsCppSharedAllocator.h"
|
||||
|
||||
#define CR '\015'
|
||||
#define LF '\012'
|
||||
#define VTAB '\013'
|
||||
#define FF '\014'
|
||||
#define TAB '\011'
|
||||
#define CRLF "\015\012" /* A CR LF equivalent string */
|
||||
|
||||
#ifdef XP_MAC
|
||||
# define NS_LINEBREAK "\015"
|
||||
# define NS_LINEBREAK_LEN 1
|
||||
#else
|
||||
# ifdef XP_PC
|
||||
# define NS_LINEBREAK "\015\012"
|
||||
# define NS_LINEBREAK_LEN 2
|
||||
# else
|
||||
# if defined(XP_UNIX) || defined(XP_BEOS)
|
||||
# define NS_LINEBREAK "\012"
|
||||
# define NS_LINEBREAK_LEN 1
|
||||
# endif /* XP_UNIX */
|
||||
# endif /* XP_PC */
|
||||
#endif /* XP_MAC */
|
||||
|
||||
|
||||
extern const PRUnichar kIsoLatin1ToUCS2[256];
|
||||
|
||||
|
||||
// This macro can be used in a class declaration for classes that want
|
||||
// to ensure that their instance memory is zeroed.
|
||||
#define NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW \
|
||||
void* operator new(size_t sz) { \
|
||||
void* rv = ::operator new(sz); \
|
||||
if (rv) { \
|
||||
nsCRT::zero(rv, sz); \
|
||||
} \
|
||||
return rv; \
|
||||
} \
|
||||
void operator delete(void* ptr) { \
|
||||
::operator delete(ptr); \
|
||||
}
|
||||
|
||||
// This macro works with the next macro to declare a non-inlined
|
||||
// version of the above.
|
||||
#define NS_DECL_ZEROING_OPERATOR_NEW \
|
||||
void* operator new(size_t sz); \
|
||||
void operator delete(void* ptr);
|
||||
|
||||
#define NS_IMPL_ZEROING_OPERATOR_NEW(_class) \
|
||||
void* _class::operator new(size_t sz) { \
|
||||
void* rv = ::operator new(sz); \
|
||||
if (rv) { \
|
||||
nsCRT::zero(rv, sz); \
|
||||
} \
|
||||
return rv; \
|
||||
} \
|
||||
void _class::operator delete(void* ptr) { \
|
||||
::operator delete(ptr); \
|
||||
}
|
||||
|
||||
// Freeing helper
|
||||
#define CRTFREEIF(x) if (x) { nsCRT::free(x); x = 0; }
|
||||
|
||||
/// This is a wrapper class around all the C runtime functions.
|
||||
|
||||
class NS_COM nsCRT {
|
||||
public:
|
||||
|
||||
/** Copy bytes from aSrc to aDest.
|
||||
@param aDest the destination address
|
||||
@param aSrc the source address
|
||||
@param aCount the number of bytes to copy
|
||||
*/
|
||||
static void memcpy(void* aDest, const void* aSrc, PRUint32 aCount) {
|
||||
::memcpy(aDest, aSrc, (size_t)aCount);
|
||||
}
|
||||
|
||||
static void memmove(void* aDest, const void* aSrc, PRUint32 aCount) {
|
||||
::memmove(aDest, aSrc, (size_t)aCount);
|
||||
}
|
||||
|
||||
static void memset(void* aDest, PRUint8 aByte, PRUint32 aCount) {
|
||||
::memset(aDest, aByte, aCount);
|
||||
}
|
||||
|
||||
static void zero(void* aDest, PRUint32 aCount) {
|
||||
::memset(aDest, 0, (size_t)aCount);
|
||||
}
|
||||
|
||||
/** Compute the string length of s
|
||||
@param s the string in question
|
||||
@return the length of s
|
||||
*/
|
||||
static PRUint32 strlen(const char* s) {
|
||||
return PRUint32(::strlen(s));
|
||||
}
|
||||
|
||||
/// Compare s1 and s2.
|
||||
static PRInt32 strcmp(const char* s1, const char* s2) {
|
||||
return PRUint32(PL_strcmp(s1, s2));
|
||||
}
|
||||
|
||||
static PRInt32 strncmp(const char* s1, const char* s2,
|
||||
PRUint32 aMaxLen) {
|
||||
return PRInt32(PL_strncmp(s1, s2, aMaxLen));
|
||||
}
|
||||
|
||||
/// Case-insensitive string comparison.
|
||||
static PRInt32 strcasecmp(const char* s1, const char* s2) {
|
||||
return PRInt32(PL_strcasecmp(s1, s2));
|
||||
}
|
||||
|
||||
/// Case-insensitive string comparison with length
|
||||
static PRInt32 strncasecmp(const char* s1, const char* s2, PRUint32 aMaxLen) {
|
||||
return PRInt32(PL_strncasecmp(s1, s2, aMaxLen));
|
||||
}
|
||||
|
||||
static PRInt32 strncmp(const char* s1, const char* s2, PRInt32 aMaxLen) {
|
||||
// inline the first test (assumes strings are not null):
|
||||
PRInt32 diff = ((const unsigned char*)s1)[0] - ((const unsigned char*)s2)[0];
|
||||
if (diff != 0) return diff;
|
||||
return PRInt32(PL_strncmp(s1,s2,aMaxLen));
|
||||
}
|
||||
|
||||
static char* strdup(const char* str) {
|
||||
return PL_strdup(str);
|
||||
}
|
||||
|
||||
static void free(char* str) {
|
||||
PL_strfree(str);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
How to use this fancy (thread-safe) version of strtok:
|
||||
|
||||
void main( void ) {
|
||||
printf( "%s\n\nTokens:\n", string );
|
||||
// Establish string and get the first token:
|
||||
char* newStr;
|
||||
token = nsCRT::strtok( string, seps, &newStr );
|
||||
while( token != NULL ) {
|
||||
// While there are tokens in "string"
|
||||
printf( " %s\n", token );
|
||||
// Get next token:
|
||||
token = nsCRT::strtok( newStr, seps, &newStr );
|
||||
}
|
||||
}
|
||||
* WARNING - STRTOK WHACKS str THE FIRST TIME IT IS CALLED *
|
||||
* MAKE A COPY OF str IF YOU NEED TO USE IT AFTER strtok() *
|
||||
*/
|
||||
static char* strtok(char* str, const char* delims, char* *newStr);
|
||||
|
||||
/// Like strlen except for ucs2 strings
|
||||
static PRUint32 strlen(const PRUnichar* s);
|
||||
|
||||
/// Like strcmp except for ucs2 strings
|
||||
static PRInt32 strcmp(const PRUnichar* s1, const PRUnichar* s2);
|
||||
/// Like strcmp except for ucs2 strings
|
||||
static PRInt32 strncmp(const PRUnichar* s1, const PRUnichar* s2,
|
||||
PRUint32 aMaxLen);
|
||||
|
||||
/// Like strcasecmp except for ucs2 strings
|
||||
static PRInt32 strcasecmp(const PRUnichar* s1, const PRUnichar* s2);
|
||||
/// Like strncasecmp except for ucs2 strings
|
||||
static PRInt32 strncasecmp(const PRUnichar* s1, const PRUnichar* s2,
|
||||
PRUint32 aMaxLen);
|
||||
|
||||
/// Like strcmp with a char* and a ucs2 string
|
||||
static PRInt32 strcmp(const PRUnichar* s1, const char* s2);
|
||||
/// Like strncmp with a char* and a ucs2 string
|
||||
static PRInt32 strncmp(const PRUnichar* s1, const char* s2,
|
||||
PRUint32 aMaxLen);
|
||||
|
||||
/// Like strcasecmp with a char* and a ucs2 string
|
||||
static PRInt32 strcasecmp(const PRUnichar* s1, const char* s2);
|
||||
/// Like strncasecmp with a char* and a ucs2 string
|
||||
static PRInt32 strncasecmp(const PRUnichar* s1, const char* s2,
|
||||
PRUint32 aMaxLen);
|
||||
|
||||
// Note: uses new[] to allocate memory, so you must use delete[] to
|
||||
// free the memory
|
||||
static PRUnichar* strdup(const PRUnichar* str);
|
||||
|
||||
static void free(PRUnichar* str) {
|
||||
nsCppSharedAllocator<PRUnichar> shared_allocator;
|
||||
shared_allocator.deallocate(str, 0 /*we never new or kept the size*/);
|
||||
}
|
||||
|
||||
/// Compute a hashcode for a C string
|
||||
static PRUint32 HashValue(const char* s1);
|
||||
|
||||
/// Same as above except that we return the length in s1len
|
||||
static PRUint32 HashValue(const char* s1, PRUint32* s1len);
|
||||
|
||||
/// Compute a hashcode for a ucs2 string
|
||||
static PRUint32 HashValue(const PRUnichar* s1);
|
||||
|
||||
/// Same as above except that we return the length in s1len
|
||||
static PRUint32 HashValue(const PRUnichar* s1, PRUint32* s1len);
|
||||
|
||||
/// String to integer.
|
||||
static PRInt32 atoi( const PRUnichar *string );
|
||||
|
||||
static PRUnichar ToUpper(PRUnichar aChar);
|
||||
|
||||
static PRUnichar ToLower(PRUnichar aChar);
|
||||
|
||||
static PRBool IsUpper(PRUnichar aChar);
|
||||
|
||||
static PRBool IsLower(PRUnichar aChar);
|
||||
};
|
||||
|
||||
#endif /* nsCRT_h___ */
|
||||
365
mozilla/xpcom/ds/nsConjoiningEnumerator.cpp
Normal file
365
mozilla/xpcom/ds/nsConjoiningEnumerator.cpp
Normal file
@@ -0,0 +1,365 @@
|
||||
/* -*- Mode: C++; tab-width: 2; 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 "nsIEnumerator.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Intersection Enumerators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class nsConjoiningEnumerator : public nsIBidirectionalEnumerator
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIEnumerator methods:
|
||||
NS_DECL_NSIENUMERATOR
|
||||
|
||||
// nsIBidirectionalEnumerator methods:
|
||||
NS_DECL_NSIBIDIRECTIONALENUMERATOR
|
||||
|
||||
// nsConjoiningEnumerator methods:
|
||||
nsConjoiningEnumerator(nsIEnumerator* first, nsIEnumerator* second);
|
||||
virtual ~nsConjoiningEnumerator(void);
|
||||
|
||||
protected:
|
||||
nsIEnumerator* mFirst;
|
||||
nsIEnumerator* mSecond;
|
||||
nsIEnumerator* mCurrent;
|
||||
};
|
||||
|
||||
nsConjoiningEnumerator::nsConjoiningEnumerator(nsIEnumerator* first, nsIEnumerator* second)
|
||||
: mFirst(first), mSecond(second), mCurrent(first)
|
||||
{
|
||||
NS_ADDREF(mFirst);
|
||||
NS_ADDREF(mSecond);
|
||||
}
|
||||
|
||||
nsConjoiningEnumerator::~nsConjoiningEnumerator(void)
|
||||
{
|
||||
NS_RELEASE(mFirst);
|
||||
NS_RELEASE(mSecond);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS2(nsConjoiningEnumerator, nsIBidirectionalEnumerator, nsIEnumerator)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsConjoiningEnumerator::First(void)
|
||||
{
|
||||
mCurrent = mFirst;
|
||||
return mCurrent->First();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsConjoiningEnumerator::Next(void)
|
||||
{
|
||||
nsresult rv = mCurrent->Next();
|
||||
if (NS_FAILED(rv) && mCurrent == mFirst) {
|
||||
mCurrent = mSecond;
|
||||
rv = mCurrent->First();
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsConjoiningEnumerator::CurrentItem(nsISupports **aItem)
|
||||
{
|
||||
return mCurrent->CurrentItem(aItem);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsConjoiningEnumerator::IsDone(void)
|
||||
{
|
||||
return (mCurrent == mFirst && mCurrent->IsDone() == NS_OK)
|
||||
|| (mCurrent == mSecond && mCurrent->IsDone() == NS_OK)
|
||||
? NS_OK : NS_COMFALSE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsConjoiningEnumerator::Last(void)
|
||||
{
|
||||
nsresult rv;
|
||||
nsIBidirectionalEnumerator* be;
|
||||
rv = mSecond->QueryInterface(nsIBidirectionalEnumerator::GetIID(), (void**)&be);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
mCurrent = mSecond;
|
||||
rv = be->Last();
|
||||
NS_RELEASE(be);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsConjoiningEnumerator::Prev(void)
|
||||
{
|
||||
nsresult rv;
|
||||
nsIBidirectionalEnumerator* be;
|
||||
rv = mCurrent->QueryInterface(nsIBidirectionalEnumerator::GetIID(), (void**)&be);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
rv = be->Prev();
|
||||
NS_RELEASE(be);
|
||||
if (NS_FAILED(rv) && mCurrent == mSecond) {
|
||||
rv = mFirst->QueryInterface(nsIBidirectionalEnumerator::GetIID(), (void**)&be);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
mCurrent = mFirst;
|
||||
rv = be->Last();
|
||||
NS_RELEASE(be);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern "C" NS_COM nsresult
|
||||
NS_NewConjoiningEnumerator(nsIEnumerator* first, nsIEnumerator* second,
|
||||
nsIBidirectionalEnumerator* *aInstancePtrResult)
|
||||
{
|
||||
if (aInstancePtrResult == 0)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
nsConjoiningEnumerator* e = new nsConjoiningEnumerator(first, second);
|
||||
if (e == 0)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(e);
|
||||
*aInstancePtrResult = e;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static nsresult
|
||||
nsEnumeratorContains(nsIEnumerator* e, nsISupports* item)
|
||||
{
|
||||
nsresult rv;
|
||||
for (e->First(); e->IsDone() != NS_OK; e->Next()) {
|
||||
nsISupports* other;
|
||||
rv = e->CurrentItem(&other);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (item == other) {
|
||||
NS_RELEASE(other);
|
||||
return NS_OK; // true -- exists in enumerator
|
||||
}
|
||||
NS_RELEASE(other);
|
||||
}
|
||||
return NS_COMFALSE; // false -- doesn't exist
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Intersection Enumerators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class nsIntersectionEnumerator : public nsIEnumerator
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIEnumerator methods:
|
||||
NS_DECL_NSIENUMERATOR
|
||||
|
||||
// nsIntersectionEnumerator methods:
|
||||
nsIntersectionEnumerator(nsIEnumerator* first, nsIEnumerator* second);
|
||||
virtual ~nsIntersectionEnumerator(void);
|
||||
|
||||
protected:
|
||||
nsIEnumerator* mFirst;
|
||||
nsIEnumerator* mSecond;
|
||||
};
|
||||
|
||||
nsIntersectionEnumerator::nsIntersectionEnumerator(nsIEnumerator* first, nsIEnumerator* second)
|
||||
: mFirst(first), mSecond(second)
|
||||
{
|
||||
NS_ADDREF(mFirst);
|
||||
NS_ADDREF(mSecond);
|
||||
}
|
||||
|
||||
nsIntersectionEnumerator::~nsIntersectionEnumerator(void)
|
||||
{
|
||||
NS_RELEASE(mFirst);
|
||||
NS_RELEASE(mSecond);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsIntersectionEnumerator, nsIEnumerator)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIntersectionEnumerator::First(void)
|
||||
{
|
||||
nsresult rv = mFirst->First();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return Next();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIntersectionEnumerator::Next(void)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// find the first item that exists in both
|
||||
for (; mFirst->IsDone() != NS_OK; mFirst->Next()) {
|
||||
nsISupports* item;
|
||||
rv = mFirst->CurrentItem(&item);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// see if it also exists in mSecond
|
||||
rv = nsEnumeratorContains(mSecond, item);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
NS_RELEASE(item);
|
||||
if (rv == NS_OK) {
|
||||
// found in both, so return leaving it as the current item of mFirst
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIntersectionEnumerator::CurrentItem(nsISupports **aItem)
|
||||
{
|
||||
return mFirst->CurrentItem(aItem);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsIntersectionEnumerator::IsDone(void)
|
||||
{
|
||||
return mFirst->IsDone();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern "C" NS_COM nsresult
|
||||
NS_NewIntersectionEnumerator(nsIEnumerator* first, nsIEnumerator* second,
|
||||
nsIEnumerator* *aInstancePtrResult)
|
||||
{
|
||||
if (aInstancePtrResult == 0)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
nsIntersectionEnumerator* e = new nsIntersectionEnumerator(first, second);
|
||||
if (e == 0)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(e);
|
||||
*aInstancePtrResult = e;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Union Enumerators
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class nsUnionEnumerator : public nsIEnumerator
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIEnumerator methods:
|
||||
NS_DECL_NSIENUMERATOR
|
||||
|
||||
// nsUnionEnumerator methods:
|
||||
nsUnionEnumerator(nsIEnumerator* first, nsIEnumerator* second);
|
||||
virtual ~nsUnionEnumerator(void);
|
||||
|
||||
protected:
|
||||
nsIEnumerator* mFirst;
|
||||
nsIEnumerator* mSecond;
|
||||
};
|
||||
|
||||
nsUnionEnumerator::nsUnionEnumerator(nsIEnumerator* first, nsIEnumerator* second)
|
||||
: mFirst(first), mSecond(second)
|
||||
{
|
||||
NS_ADDREF(mFirst);
|
||||
NS_ADDREF(mSecond);
|
||||
}
|
||||
|
||||
nsUnionEnumerator::~nsUnionEnumerator(void)
|
||||
{
|
||||
NS_RELEASE(mFirst);
|
||||
NS_RELEASE(mSecond);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsUnionEnumerator, nsIEnumerator)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsUnionEnumerator::First(void)
|
||||
{
|
||||
nsresult rv = mFirst->First();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
return Next();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsUnionEnumerator::Next(void)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// find the first item that exists in both
|
||||
for (; mFirst->IsDone() != NS_OK; mFirst->Next()) {
|
||||
nsISupports* item;
|
||||
rv = mFirst->CurrentItem(&item);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
// see if it also exists in mSecond
|
||||
rv = nsEnumeratorContains(mSecond, item);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
NS_RELEASE(item);
|
||||
if (rv != NS_OK) {
|
||||
// if it didn't exist in mSecond, return, making it the current item
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// each time around, make sure that mSecond gets reset to the beginning
|
||||
// so that when mFirst is done, we'll be ready to enumerate mSecond
|
||||
rv = mSecond->First();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
return mSecond->Next();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsUnionEnumerator::CurrentItem(nsISupports **aItem)
|
||||
{
|
||||
if (mFirst->IsDone() != NS_OK)
|
||||
return mFirst->CurrentItem(aItem);
|
||||
else
|
||||
return mSecond->CurrentItem(aItem);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsUnionEnumerator::IsDone(void)
|
||||
{
|
||||
return (mFirst->IsDone() == NS_OK && mSecond->IsDone() == NS_OK)
|
||||
? NS_OK : NS_COMFALSE;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
extern "C" NS_COM nsresult
|
||||
NS_NewUnionEnumerator(nsIEnumerator* first, nsIEnumerator* second,
|
||||
nsIEnumerator* *aInstancePtrResult)
|
||||
{
|
||||
if (aInstancePtrResult == 0)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
nsUnionEnumerator* e = new nsUnionEnumerator(first, second);
|
||||
if (e == 0)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(e);
|
||||
*aInstancePtrResult = e;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
122
mozilla/xpcom/ds/nsCppSharedAllocator.h
Normal file
122
mozilla/xpcom/ds/nsCppSharedAllocator.h
Normal file
@@ -0,0 +1,122 @@
|
||||
#ifndef nsCppSharedAllocator_h__
|
||||
#define nsCppSharedAllocator_h__
|
||||
|
||||
#include "nsIAllocator.h" // for |nsAllocator|
|
||||
#include "nscore.h" // for |NS_XXX_CAST|
|
||||
#include <new.h> // to allow placement |new|
|
||||
|
||||
|
||||
// under Metrowerks (Mac), we don't have autoconf yet
|
||||
#ifdef __MWERKS__
|
||||
#define HAVE_CPP_MEMBER_TEMPLATES
|
||||
#define HAVE_CPP_NUMERIC_LIMITS
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CPP_NUMERIC_LIMITS
|
||||
#include <limits>
|
||||
#else
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
|
||||
template <class T>
|
||||
class nsCppSharedAllocator
|
||||
/*
|
||||
...allows Standard Library containers, et al, to use our global shared
|
||||
(XP)COM-aware allocator.
|
||||
*/
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef size_t size_type;
|
||||
typedef ptrdiff_t difference_type;
|
||||
|
||||
typedef T* pointer;
|
||||
typedef const T* const_pointer;
|
||||
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
|
||||
|
||||
|
||||
nsCppSharedAllocator() { }
|
||||
|
||||
#ifdef HAVE_CPP_MEMBER_TEMPLATES
|
||||
template <class U>
|
||||
nsCppSharedAllocator( const nsCppSharedAllocator<U>& ) { }
|
||||
#endif
|
||||
|
||||
~nsCppSharedAllocator() { }
|
||||
|
||||
|
||||
pointer
|
||||
address( reference r ) const
|
||||
{
|
||||
return &r;
|
||||
}
|
||||
|
||||
const_pointer
|
||||
address( const_reference r ) const
|
||||
{
|
||||
return &r;
|
||||
}
|
||||
|
||||
pointer
|
||||
allocate( size_type n, const void* /*hint*/=0 )
|
||||
{
|
||||
return NS_REINTERPRET_CAST(pointer, nsAllocator::Alloc(NS_STATIC_CAST(PRUint32, n*sizeof(T))));
|
||||
}
|
||||
|
||||
void
|
||||
deallocate( pointer p, size_type /*n*/ )
|
||||
{
|
||||
nsAllocator::Free(p);
|
||||
}
|
||||
|
||||
void
|
||||
construct( pointer p, const T& val )
|
||||
{
|
||||
new (p) T(val);
|
||||
}
|
||||
|
||||
void
|
||||
destroy( pointer p )
|
||||
{
|
||||
p->~T();
|
||||
}
|
||||
|
||||
size_type
|
||||
max_size() const
|
||||
{
|
||||
#ifdef HAVE_CPP_NUMERIC_LIMITS
|
||||
return numeric_limits<size_type>::max() / sizeof(T);
|
||||
#else
|
||||
return ULONG_MAX / sizeof(T);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_CPP_MEMBER_TEMPLATES
|
||||
template <class U>
|
||||
struct rebind
|
||||
{
|
||||
typedef nsCppSharedAllocator<U> other;
|
||||
};
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
PRBool
|
||||
operator==( const nsCppSharedAllocator<T>&, const nsCppSharedAllocator<T>& )
|
||||
{
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
PRBool
|
||||
operator!=( const nsCppSharedAllocator<T>&, const nsCppSharedAllocator<T>& )
|
||||
{
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
#endif /* !defined(nsCppSharedAllocator_h__) */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user