From ec05778d5718a7912e506764d443a78d6a6179e3 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Mon, 5 Nov 2012 22:41:51 +0000 Subject: Converted tabs to spaces with tabconv. --- src/unstable/bitstring.cpp | 660 +++++++++---------- src/unstable/bitstring.h | 412 ++++++------ src/unstable/fifo.cpp | 118 ++-- src/unstable/fifo.h | 80 +-- src/unstable/itoserver.cpp | 312 ++++----- src/unstable/itoserver.h | 224 +++---- src/unstable/minimacro.cpp | 252 ++++---- src/unstable/minimacro.h | 212 +++--- src/unstable/myriadfs.cpp | 1078 +++++++++++++++---------------- src/unstable/myriadfs.h | 368 +++++------ src/unstable/newline.cpp | 66 +- src/unstable/newline.h | 42 +- src/unstable/settings.cpp | 44 +- src/unstable/settings.h | 46 +- src/unstable/settingsdriver.h | 32 +- src/unstable/settingsdriverini.cpp | 258 ++++---- src/unstable/settingsdriverini.h | 30 +- src/unstable/settingsdriverregistry.cpp | 116 ++-- src/unstable/settingsdriverregistry.h | 24 +- src/unstable/settingsdrivertaf.cpp | 148 ++--- src/unstable/settingsdrivertaf.h | 34 +- src/unstable/udpsocket.cpp | 216 +++---- src/unstable/udpsocket.h | 92 +-- src/unstable/url.cpp | 378 +++++------ src/unstable/url.h | 114 ++-- src/unstable/utfstring.cpp | 842 ++++++++++++------------ src/unstable/utfstring.h | 482 +++++++------- src/unstable/uuid.cpp | 150 ++--- src/unstable/uuid.h | 84 +-- 29 files changed, 3457 insertions(+), 3457 deletions(-) (limited to 'src/unstable') diff --git a/src/unstable/bitstring.cpp b/src/unstable/bitstring.cpp index 9559aad..3f24ec7 100644 --- a/src/unstable/bitstring.cpp +++ b/src/unstable/bitstring.cpp @@ -16,460 +16,460 @@ Bu::BitString::BitString() { - caData = NULL; - cTopByteMask = 0; - iBits = iBytes = 0; + caData = NULL; + cTopByteMask = 0; + iBits = iBytes = 0; } Bu::BitString::BitString( const Bu::BitString &xSrc ) { - iBits = xSrc.iBits; - iBytes = xSrc.iBytes; - cTopByteMask = xSrc.cTopByteMask; - caData = new unsigned char[iBytes]; - memcpy( caData, xSrc.caData, iBytes ); + iBits = xSrc.iBits; + iBytes = xSrc.iBytes; + cTopByteMask = xSrc.cTopByteMask; + caData = new unsigned char[iBytes]; + memcpy( caData, xSrc.caData, iBytes ); - fixup(); + fixup(); } Bu::BitString::BitString( long iNewBits, bool bFillRandomly ) { - long j; - iBits = iNewBits; - iBytes = bitsToBytes( iNewBits );//(iNewBits/8)+((iNewBits%8)?(1):(0)); - caData = new unsigned char[iBytes]; - - setMask(); - - if( bFillRandomly ) - { - // rand() only returns a value up to RAND_MAX (0x7FFF on my system) so - // I'll just use the low order byte) - for( j = 0; j < iBytes; j++ ) - { - caData[j] = (unsigned char)(Bu::Random::rand() & 0xFF); - } - } - else - { - clear(); - } - - fixup(); + long j; + iBits = iNewBits; + iBytes = bitsToBytes( iNewBits );//(iNewBits/8)+((iNewBits%8)?(1):(0)); + caData = new unsigned char[iBytes]; + + setMask(); + + if( bFillRandomly ) + { + // rand() only returns a value up to RAND_MAX (0x7FFF on my system) so + // I'll just use the low order byte) + for( j = 0; j < iBytes; j++ ) + { + caData[j] = (unsigned char)(Bu::Random::rand() & 0xFF); + } + } + else + { + clear(); + } + + fixup(); } Bu::BitString::~BitString() { - if( caData != NULL ) delete[] caData; + if( caData != NULL ) delete[] caData; } Bu::BitString &Bu::BitString::operator=( const Bu::BitString &xSrc ) { - if( caData != NULL ) - { - delete[] caData; - } - iBits = xSrc.iBits; - iBytes = xSrc.iBytes; - cTopByteMask = xSrc.cTopByteMask; - caData = new unsigned char[iBytes]; - memcpy( caData, xSrc.caData, iBytes ); - - fixup(); - - return *this; + if( caData != NULL ) + { + delete[] caData; + } + iBits = xSrc.iBits; + iBytes = xSrc.iBytes; + cTopByteMask = xSrc.cTopByteMask; + caData = new unsigned char[iBytes]; + memcpy( caData, xSrc.caData, iBytes ); + + fixup(); + + return *this; } Bu::BitString Bu::BitString::operator~() { - Bu::BitString xRet( *this ); + Bu::BitString xRet( *this ); - for( int j = 0; j < xRet.iBytes; j++ ) - { - xRet.caData[j] = ~xRet.caData[j]; - } + for( int j = 0; j < xRet.iBytes; j++ ) + { + xRet.caData[j] = ~xRet.caData[j]; + } - xRet.fixup(); + xRet.fixup(); - return xRet; + return xRet; } Bu::BitString Bu::BitString::operator<<( const long iAmt ) { - if( iAmt == 0 ) - { - return (*this); - } - //int iByteShift = iAmt/8; - - Bu::BitString xSub( getSize() ); - - long shft = (iAmt%8); - long base = (iAmt/8); - unsigned char lowmask=0; - for( long j = 0; j < 8-shft; j++ ) - { - lowmask |= (1<>shft)&(lowmask)) | ((caData[j+1]<<(8-shft))&(~lowmask)); - } - xSub.fixup(); - - return xSub; + if( iAmt == 0 ) + { + return (*this); + } + //int iByteShift = iAmt/8; + + Bu::BitString xSub( getSize() ); + + long shft = (iAmt%8); + long base = (iAmt/8); + unsigned char lowmask=0; + for( long j = 0; j < 8-shft; j++ ) + { + lowmask |= (1<>shft)&(lowmask)) | ((caData[j+1]<<(8-shft))&(~lowmask)); + } + xSub.fixup(); + + return xSub; } Bu::BitString Bu::BitString::operator>>( const long iAmt ) { - if( iAmt == 0 ) - { - return (*this); - } - return (*this); + if( iAmt == 0 ) + { + return (*this); + } + return (*this); } void Bu::BitString::shiftLeft( long iAmt ) { - if( iAmt == 0 ) - { - return; - } - else if( iAmt < 0 ) - { - shiftRight( -iAmt ); - return; - } - - long iByteShift = iAmt/8; - long iBitShift = iAmt%8; - - long j; - for( j = iBytes-1; j >= 0; j-- ) - { - caData[j] = (((j-iByteShift)<0)?(0):((caData[j-iByteShift]<>(8-iBitShift)))); - } - - fixup(); + if( iAmt == 0 ) + { + return; + } + else if( iAmt < 0 ) + { + shiftRight( -iAmt ); + return; + } + + long iByteShift = iAmt/8; + long iBitShift = iAmt%8; + + long j; + for( j = iBytes-1; j >= 0; j-- ) + { + caData[j] = (((j-iByteShift)<0)?(0):((caData[j-iByteShift]<>(8-iBitShift)))); + } + + fixup(); } void Bu::BitString::shiftRight( long iAmt ) { - if( iAmt == 0 ) - { - return; - } - else if( iAmt < 0 ) - { - shiftLeft( -iAmt ); - return; - } - - long iByteShift = iAmt/8; - long iBitShift = iAmt%8; - - long j; - for( j = 0; j < iBytes; j++ ) - { - caData[j] = (((j+iByteShift)>iBytes)?(0):((caData[j+iByteShift]>>iBitShift))) | (((j+iByteShift+1)>iBytes)?(0):((caData[j+iByteShift+1]<<(8-iBitShift)))); - } - - fixup(); + if( iAmt == 0 ) + { + return; + } + else if( iAmt < 0 ) + { + shiftLeft( -iAmt ); + return; + } + + long iByteShift = iAmt/8; + long iBitShift = iAmt%8; + + long j; + for( j = 0; j < iBytes; j++ ) + { + caData[j] = (((j+iByteShift)>iBytes)?(0):((caData[j+iByteShift]>>iBitShift))) | (((j+iByteShift+1)>iBytes)?(0):((caData[j+iByteShift+1]<<(8-iBitShift)))); + } + + fixup(); } /* long Bu::BitString::bitsToBytes( long iBits ) { - return (iBits/8)+((iBits%8)?(1):(0)); + return (iBits/8)+((iBits%8)?(1):(0)); } */ void Bu::BitString::fixup() { - if( caData != NULL ) - { - caData[iBytes-1] &= cTopByteMask; - } + if( caData != NULL ) + { + caData[iBytes-1] &= cTopByteMask; + } } void Bu::BitString::setBit( long iBit, bool bBitState ) { - if( iBit < 0 || iBit >= iBits ) - throw Bu::ExceptionBase("bit out of range: %d in (0-%d)", iBit, iBits ); - if( bBitState ) - { - caData[iBit/8] |= (1<<(iBit%8)); - } - else - { - caData[iBit/8] &= ~(1<<(iBit%8)); - } + if( iBit < 0 || iBit >= iBits ) + throw Bu::ExceptionBase("bit out of range: %d in (0-%d)", iBit, iBits ); + if( bBitState ) + { + caData[iBit/8] |= (1<<(iBit%8)); + } + else + { + caData[iBit/8] &= ~(1<<(iBit%8)); + } } void Bu::BitString::flipBit( long iBit ) { - caData[iBit/8] ^= (1<<(iBit%8)); + caData[iBit/8] ^= (1<<(iBit%8)); } bool Bu::BitString::getBit( long iBit ) { - if( iBit >= iBits || iBit < 0 ) return false; - if( (caData[iBit/8] & (1<<(iBit%8))) == 0 ) - { - return false; - } - return true; + if( iBit >= iBits || iBit < 0 ) return false; + if( (caData[iBit/8] & (1<<(iBit%8))) == 0 ) + { + return false; + } + return true; } long Bu::BitString::getBitLength() { - return iBits; + return iBits; } long Bu::BitString::getSize() { - return iBits; + return iBits; } class Bu::BitString Bu::BitString::getSubString( long iLower, long iUpper ) { - if( iUpper == 0 || iUpper < iLower ) iUpper = iBits; - - Bu::BitString xSub( iUpper-iLower+1 ); - - long shft = (iLower%8); - long base = (iLower/8); - unsigned char lowmask=0; - for( long j = 0; j < 8-shft; j++ ) - { - lowmask |= (1<>shft)&(lowmask)) | ((caData[base+j+1]<<(8-shft))&(~lowmask)); - } - xSub.fixup(); - - return xSub; + if( iUpper == 0 || iUpper < iLower ) iUpper = iBits; + + Bu::BitString xSub( iUpper-iLower+1 ); + + long shft = (iLower%8); + long base = (iLower/8); + unsigned char lowmask=0; + for( long j = 0; j < 8-shft; j++ ) + { + lowmask |= (1<>shft)&(lowmask)) | ((caData[base+j+1]<<(8-shft))&(~lowmask)); + } + xSub.fixup(); + + return xSub; } long Bu::BitString::toLong( long iStart, long iSize ) { - if( iSize < 1 ) iSize = 1; - if( iSize > 32 ) iSize = 32; - if( iStart < 0 ) return 0; - if( iStart+iSize > getSize() ) return 0; + if( iSize < 1 ) iSize = 1; + if( iSize > 32 ) iSize = 32; + if( iStart < 0 ) return 0; + if( iStart+iSize > getSize() ) return 0; - Bu::BitString tmpo; - tmpo = getSubString( iStart, iStart+iSize-1 ); - long x = *((long *)tmpo.caData); + Bu::BitString tmpo; + tmpo = getSubString( iStart, iStart+iSize-1 ); + long x = *((long *)tmpo.caData); - return x; + return x; } /* std::string Bu::BitString::toString( bool bAddSpacers ) { - long iSz = iBits; - if( bAddSpacers ) - { - iSz += (iBits/8); - if( iBits%8 == 0 ) iSz--; - } - std::string xStr; - - int bw=0; - int of=0; - for( int j = iBits-1; j >= 0; j-- ) - { - if( getBit( j ) ) - { - xStr += '1'; - } - else - { - xStr += '0'; - } - - if( bAddSpacers ) - { - bw++; - if( bw >= 8 && j < iBits-1 ) - { - bw = 0; - of++; - xStr += ' '; - } - } - } - - return xStr; + long iSz = iBits; + if( bAddSpacers ) + { + iSz += (iBits/8); + if( iBits%8 == 0 ) iSz--; + } + std::string xStr; + + int bw=0; + int of=0; + for( int j = iBits-1; j >= 0; j-- ) + { + if( getBit( j ) ) + { + xStr += '1'; + } + else + { + xStr += '0'; + } + + if( bAddSpacers ) + { + bw++; + if( bw >= 8 && j < iBits-1 ) + { + bw = 0; + of++; + xStr += ' '; + } + } + } + + return xStr; } */ void Bu::BitString::clear() { - if( caData != NULL ) - { - memset( caData, 0, iBytes ); - } + if( caData != NULL ) + { + memset( caData, 0, iBytes ); + } } bool Bu::BitString::setBitLength( long iLength, bool bClear ) { - return setSize( iLength, bClear ); + return setSize( iLength, bClear ); } bool Bu::BitString::setSize( long iLength, bool bClear ) { - // First, if there's nothing, then allocate an empty one. - if( caData == NULL ) - { - iBits = iLength; - iBytes = bitsToBytes( iLength ); - caData = new unsigned char[iBytes]; - memset( caData, 0, iBytes ); - return true; - } - - // If the new length is the same as the old, don't do anything, but do - // check to see if we should still clear the data. - if( iBits != iLength ) - { - // Ok, we are changing the number if bits, but are we changing the - // number of bytes? - long iNewBytes = bitsToBytes( iLength ); - if( iBytes == iNewBytes ) - { - // No? That makes life easier - iBits = iLength; - setMask(); - if( bClear ) - { - clear(); - } - } - else - { - // Ok, reallocate and copy... - iBits = iLength; -// long iNewBytes = bitsToBytes( iLength ); - if( bClear ) - { - delete[] caData; - caData = new unsigned char[iNewBytes]; - memset( caData, 0, iNewBytes ); - } - else - { - unsigned char *tmp = caData; - caData = new unsigned char[iNewBytes]; - if( iNewBytes < iBytes ) - { - memcpy( caData, tmp, iNewBytes ); - } - else - { - memcpy( caData, tmp, iBytes ); - } - delete[] tmp; - } - iBytes = iNewBytes; - - setMask(); - } - - } - else if( bClear ) - { - clear(); - } - - return true; + // First, if there's nothing, then allocate an empty one. + if( caData == NULL ) + { + iBits = iLength; + iBytes = bitsToBytes( iLength ); + caData = new unsigned char[iBytes]; + memset( caData, 0, iBytes ); + return true; + } + + // If the new length is the same as the old, don't do anything, but do + // check to see if we should still clear the data. + if( iBits != iLength ) + { + // Ok, we are changing the number if bits, but are we changing the + // number of bytes? + long iNewBytes = bitsToBytes( iLength ); + if( iBytes == iNewBytes ) + { + // No? That makes life easier + iBits = iLength; + setMask(); + if( bClear ) + { + clear(); + } + } + else + { + // Ok, reallocate and copy... + iBits = iLength; +// long iNewBytes = bitsToBytes( iLength ); + if( bClear ) + { + delete[] caData; + caData = new unsigned char[iNewBytes]; + memset( caData, 0, iNewBytes ); + } + else + { + unsigned char *tmp = caData; + caData = new unsigned char[iNewBytes]; + if( iNewBytes < iBytes ) + { + memcpy( caData, tmp, iNewBytes ); + } + else + { + memcpy( caData, tmp, iBytes ); + } + delete[] tmp; + } + iBytes = iNewBytes; + + setMask(); + } + + } + else if( bClear ) + { + clear(); + } + + return true; } void Bu::BitString::setMask() { - // This can either mean that there are a multiple of eight bits or - // zero, if there are zero you're an idiot (zero can't happen, because - // we would allocate an extra byte and never use it) - if( (iBits%8 == 0) ) - { - cTopByteMask = 0xFF; - } - else - { - cTopByteMask = 0; - for( long j = 0; j < (iBits%8); j++ ) - { - cTopByteMask |= (1<= 0; j-- ) - { - if( getBit( j ) ) - { - return j; - } - } - - return -1; + for( long j = iBits-1; j >= 0; j-- ) + { + if( getBit( j ) ) + { + return j; + } + } + + return -1; } Bu::String Bu::BitString::toString() { - Bu::String sRet; - for( int j = iBits-1; j >= 0; j-- ) - sRet.append( getBit( j )?'1':'0' ); - return sRet; + Bu::String sRet; + for( int j = iBits-1; j >= 0; j-- ) + sRet.append( getBit( j )?'1':'0' ); + return sRet; } /* bool Bu::BitString::writeToFile( FILE *fh ) { - fwrite( &iBits, sizeof(long), 1, fh ); - fwrite( caData, sizeof(char), iBytes, fh ); - - return true; + fwrite( &iBits, sizeof(long), 1, fh ); + fwrite( caData, sizeof(char), iBytes, fh ); + + return true; } bool Bu::BitString::readFromFile( FILE *fh ) { - fread( &iBits, sizeof(long), 1, fh ); - - iBytes = bitsToBytes( iBits ); - if( caData ) delete[] caData; - caData = new unsigned char[iBytes]; + fread( &iBits, sizeof(long), 1, fh ); + + iBytes = bitsToBytes( iBits ); + if( caData ) delete[] caData; + caData = new unsigned char[iBytes]; - fread( caData, sizeof(char), iBytes, fh ); + fread( caData, sizeof(char), iBytes, fh ); - setMask(); - - fixup(); + setMask(); + + fixup(); - return true; + return true; }*/ diff --git a/src/unstable/bitstring.h b/src/unstable/bitstring.h index fd34402..ea884f6 100644 --- a/src/unstable/bitstring.h +++ b/src/unstable/bitstring.h @@ -13,212 +13,212 @@ namespace Bu { - /** - * Manages an arbitrarily sized string of bits, and allows basic interaction - * with them. This includes basic non-mathematical bitwise operations such - * as setting and testing bits, shifting the string, inversion and a few - * extras like randomization. On linux systems this takes advantage of long - * longs giving you a maximum size of about 2tb per string. - * - * For more general and mathematical type interaction see BitStringInt. - * - */ - class BitString - { - public: - /** - * Constructs a blank and basic BitString. This is actually useful - * since you can resize BitStrings at will, and even retain the data - * that was in them. - */ - BitString(); - - /** - * Constructs a BitString object as a copy of another BitString. This - * is a standard copy constructor and produces an exact duplicate of - * the original BitString object. - *@param xSrc Source BitString to copy data from. - */ - BitString( const BitString &xSrc ); - - /** - * Constructs a BitString with length iBits and optionally fills it with - * random data. The default setting, to not fill randomly, will produce - * a blank (all zeros) string of the specified size. - *@param iBits The length of the new BitString in bits. - *@param bFillRandomly Wether or not to randomize this BitString. - */ - BitString( long iBits, bool bFillRandomly=false ); - - /** - * Virtual deconstructor for the BitString. Takes care of cleanup for - * you. What more do you really want to know? - */ - virtual ~BitString(); - - // basic interaction - /** - * Sets a bit in the BitString. In it's normal mode it will always turn - * the given bit on, to clear a bit set bBitState to false instead of - * true. This operation runs in O(1). - *@param iBit The zero-based index of the bit to modify. - *@param bBitState Set to true to set the bit to 1, set to false to set - * the bit to 0. - */ - void setBit( long iBit, bool bBitState=true ); - - /** - * Reverses the state of the given bit. This will set the given bit - * to a 1 if it was 0, and to 0 if it was 1. This operation runs in - * O(1), and it should be noted that using this is marginally faster - * than doing the test and flip yourself with getBit and setBit since - * it uses a bitwise not operation and doesn't actually test the bit - * itself. - *@param iBit The index of the bit to flip. - */ - void flipBit( long iBit ); - - /** - * Gets the state of the given bit. This follows the standard - * convention used so far, a returned value of true means the bit in - * question is 1, and a value of flase means the bit is 0. All bits - * out of range of the BitString are treated as off, but are - * "accessable" in that this does not produce any kind of error - * message. This is intentional. This operation runs in O(1). - *@param iBit The index of the bit to test. - *@returns True for a 1, false for a 0. - */ - bool getBit( long iBit ); - - /** - * Inverts the entire BitString, in effect this calls flipBit on every - * bit in the string but is faster since it can operate on whole bytes - * at a time instead of individual bits. This operation runs in O(N). - */ - void invert(); - - /** - * Returns the number of bits allocated in this BitString. This - * operation runs in O(1) time since this value is cached and not - * computed. - *@returns The number of bits allocated in this BitString. - */ - DEPRECATED - long getBitLength(); - - long getSize(); - - /** - * Sets the entire BitString to zeros, but it does it very quickly. - * This operation runs in O(N). - */ - void clear(); - - /** - * Gets another BitString that is autonomous of the current one - * (contains a copy of the memory, not a pointer) and contains a subset - * of the data in the current BitString. This is an inclusive - * operation, so grabbing bits 0-5 will give you 6 bits. This is based - * on a very tricky bit-shifting algorithm and runs very quickly, in - * O(N) time. Passing in a value of zero for iUpper, or any value for - * iUpper that is less than iLower will set iUpper equal to the number - * of bits in the BitString. - *@param iLower The first bit in the current string, will be the first - * bit (0 index) in the new sub string. - *@param iUpper The last bit in the current string, will be the last - * bit in the new sub string. iUpper is included in the sub string. - *@returns A new BitString object ready to be used. Please note that - * managing this new object is up to whomever calls this function. - */ - class BitString getSubString( long iLower, long iUpper ); - - /** - * Sets the number of bits in the BitString, allocating more memory if - * necesarry, or freeing extra if able. The default operation of this - * function clears all data in the BitString while resizing it. If you - * would like to keep as much of the data that you had in your BitString - * as possible, then set bClear to false, and any data that will fit - * into the new BitString length will be retained. If increasing the - * number of bits, the new bits will come into existance cleared (set - * to 0). - *@param iLength The number of bits to set the BitString to. - *@param bClear When true, all data is eradicated and zeroed, when set - * to false an effort is made to retain the existing data. - *@returns true on success, false on failure. - */ - DEPRECATED - bool setBitLength( long iLength, bool bClear=true ); - bool setSize( long iLength, bool bClear=true ); - - /** - * Randomize the entire BitString, one bit at a time. This is actually - * the function called by the constructor when the user selects initial - * randomization. This function uses the system random() function, so - * srandom may be used to effect this process at will. - */ - void randomize(); - - /** - * Operates exactly like <<. All data in the BitString is shifted to - * the left by some number of bits, any data pushed off the edge of the - * BitString is lost, and all new data coming in will be zeroed. - * Using a negative value in the shiftLeft function will turn it into - * the shiftRight function. - *@param iAmt The number of bit positions to shift all data. - */ - void shiftLeft( long iAmt ); // just like << - - /** - * Operates exactly like >>. All data in the BitString is shifted to - * the right by some number of bits, any data pushed off the edge of the - * BitString is lost, and all new data coming in will be zeroed. - * Using a negative value in the shiftRight function will turn it into - * the shiftLeft function. - *@param iAmt The number of bit positions to shift all data. - */ - void shiftRight( long iAmt ); // just like >> - - /** - * Searches through the BitString and returns the index of the highest - * order bit position (the highest index) with an on bit (a bit set to - * 1). This is a handy helper function and rather faster than calling - * getBit() over and over again. - *@returns The index of the highest indexed on bit. - */ - long getHighestOrderBitPos(); - - // Conversion - /** - * Convert a block of data (no more than 32 bits) to a primitive long - * type. - * This is done in a little bit interesting way, so it may not always be - * the fastest way to access the data that you want, although it will - * always ensure that the long that is written makes numerical sense, as - * we write numbers, regaurdless of platform. - *@param iStart The first bit in the BitString to include in the long - *@param iSize THe number of bits to include, if this value is set over - * 32 it will be automatically truncated to, or however many bits there - * are in a long in your system. - *@returns A long converted from your raw BitString data. - */ - long toLong( long iStart = 0, long iSize = 32 ); - - Bu::String toString(); - - //operators - BitString &operator=( const BitString &xSrc ); - BitString operator~(); - BitString operator<<( const long iAmt ); - BitString operator>>( const long iAmt ); - - private: - void fixup(); - void setMask(); - unsigned char *caData; - long iBits; - long iBytes; - unsigned char cTopByteMask; - }; + /** + * Manages an arbitrarily sized string of bits, and allows basic interaction + * with them. This includes basic non-mathematical bitwise operations such + * as setting and testing bits, shifting the string, inversion and a few + * extras like randomization. On linux systems this takes advantage of long + * longs giving you a maximum size of about 2tb per string. + * + * For more general and mathematical type interaction see BitStringInt. + * + */ + class BitString + { + public: + /** + * Constructs a blank and basic BitString. This is actually useful + * since you can resize BitStrings at will, and even retain the data + * that was in them. + */ + BitString(); + + /** + * Constructs a BitString object as a copy of another BitString. This + * is a standard copy constructor and produces an exact duplicate of + * the original BitString object. + *@param xSrc Source BitString to copy data from. + */ + BitString( const BitString &xSrc ); + + /** + * Constructs a BitString with length iBits and optionally fills it with + * random data. The default setting, to not fill randomly, will produce + * a blank (all zeros) string of the specified size. + *@param iBits The length of the new BitString in bits. + *@param bFillRandomly Wether or not to randomize this BitString. + */ + BitString( long iBits, bool bFillRandomly=false ); + + /** + * Virtual deconstructor for the BitString. Takes care of cleanup for + * you. What more do you really want to know? + */ + virtual ~BitString(); + + // basic interaction + /** + * Sets a bit in the BitString. In it's normal mode it will always turn + * the given bit on, to clear a bit set bBitState to false instead of + * true. This operation runs in O(1). + *@param iBit The zero-based index of the bit to modify. + *@param bBitState Set to true to set the bit to 1, set to false to set + * the bit to 0. + */ + void setBit( long iBit, bool bBitState=true ); + + /** + * Reverses the state of the given bit. This will set the given bit + * to a 1 if it was 0, and to 0 if it was 1. This operation runs in + * O(1), and it should be noted that using this is marginally faster + * than doing the test and flip yourself with getBit and setBit since + * it uses a bitwise not operation and doesn't actually test the bit + * itself. + *@param iBit The index of the bit to flip. + */ + void flipBit( long iBit ); + + /** + * Gets the state of the given bit. This follows the standard + * convention used so far, a returned value of true means the bit in + * question is 1, and a value of flase means the bit is 0. All bits + * out of range of the BitString are treated as off, but are + * "accessable" in that this does not produce any kind of error + * message. This is intentional. This operation runs in O(1). + *@param iBit The index of the bit to test. + *@returns True for a 1, false for a 0. + */ + bool getBit( long iBit ); + + /** + * Inverts the entire BitString, in effect this calls flipBit on every + * bit in the string but is faster since it can operate on whole bytes + * at a time instead of individual bits. This operation runs in O(N). + */ + void invert(); + + /** + * Returns the number of bits allocated in this BitString. This + * operation runs in O(1) time since this value is cached and not + * computed. + *@returns The number of bits allocated in this BitString. + */ + DEPRECATED + long getBitLength(); + + long getSize(); + + /** + * Sets the entire BitString to zeros, but it does it very quickly. + * This operation runs in O(N). + */ + void clear(); + + /** + * Gets another BitString that is autonomous of the current one + * (contains a copy of the memory, not a pointer) and contains a subset + * of the data in the current BitString. This is an inclusive + * operation, so grabbing bits 0-5 will give you 6 bits. This is based + * on a very tricky bit-shifting algorithm and runs very quickly, in + * O(N) time. Passing in a value of zero for iUpper, or any value for + * iUpper that is less than iLower will set iUpper equal to the number + * of bits in the BitString. + *@param iLower The first bit in the current string, will be the first + * bit (0 index) in the new sub string. + *@param iUpper The last bit in the current string, will be the last + * bit in the new sub string. iUpper is included in the sub string. + *@returns A new BitString object ready to be used. Please note that + * managing this new object is up to whomever calls this function. + */ + class BitString getSubString( long iLower, long iUpper ); + + /** + * Sets the number of bits in the BitString, allocating more memory if + * necesarry, or freeing extra if able. The default operation of this + * function clears all data in the BitString while resizing it. If you + * would like to keep as much of the data that you had in your BitString + * as possible, then set bClear to false, and any data that will fit + * into the new BitString length will be retained. If increasing the + * number of bits, the new bits will come into existance cleared (set + * to 0). + *@param iLength The number of bits to set the BitString to. + *@param bClear When true, all data is eradicated and zeroed, when set + * to false an effort is made to retain the existing data. + *@returns true on success, false on failure. + */ + DEPRECATED + bool setBitLength( long iLength, bool bClear=true ); + bool setSize( long iLength, bool bClear=true ); + + /** + * Randomize the entire BitString, one bit at a time. This is actually + * the function called by the constructor when the user selects initial + * randomization. This function uses the system random() function, so + * srandom may be used to effect this process at will. + */ + void randomize(); + + /** + * Operates exactly like <<. All data in the BitString is shifted to + * the left by some number of bits, any data pushed off the edge of the + * BitString is lost, and all new data coming in will be zeroed. + * Using a negative value in the shiftLeft function will turn it into + * the shiftRight function. + *@param iAmt The number of bit positions to shift all data. + */ + void shiftLeft( long iAmt ); // just like << + + /** + * Operates exactly like >>. All data in the BitString is shifted to + * the right by some number of bits, any data pushed off the edge of the + * BitString is lost, and all new data coming in will be zeroed. + * Using a negative value in the shiftRight function will turn it into + * the shiftLeft function. + *@param iAmt The number of bit positions to shift all data. + */ + void shiftRight( long iAmt ); // just like >> + + /** + * Searches through the BitString and returns the index of the highest + * order bit position (the highest index) with an on bit (a bit set to + * 1). This is a handy helper function and rather faster than calling + * getBit() over and over again. + *@returns The index of the highest indexed on bit. + */ + long getHighestOrderBitPos(); + + // Conversion + /** + * Convert a block of data (no more than 32 bits) to a primitive long + * type. + * This is done in a little bit interesting way, so it may not always be + * the fastest way to access the data that you want, although it will + * always ensure that the long that is written makes numerical sense, as + * we write numbers, regaurdless of platform. + *@param iStart The first bit in the BitString to include in the long + *@param iSize THe number of bits to include, if this value is set over + * 32 it will be automatically truncated to, or however many bits there + * are in a long in your system. + *@returns A long converted from your raw BitString data. + */ + long toLong( long iStart = 0, long iSize = 32 ); + + Bu::String toString(); + + //operators + BitString &operator=( const BitString &xSrc ); + BitString operator~(); + BitString operator<<( const long iAmt ); + BitString operator>>( const long iAmt ); + + private: + void fixup(); + void setMask(); + unsigned char *caData; + long iBits; + long iBytes; + unsigned char cTopByteMask; + }; }; #endif diff --git a/src/unstable/fifo.cpp b/src/unstable/fifo.cpp index 6f327df..4b4a2bf 100644 --- a/src/unstable/fifo.cpp +++ b/src/unstable/fifo.cpp @@ -17,75 +17,75 @@ namespace Bu { subExceptionDef( FifoException ) } Bu::Fifo::Fifo( const Bu::String &sName, int iFlags, mode_t mAcc ) : - iFlags( iFlags ), - iIn( -1 ), - iOut( -1 ) + iFlags( iFlags ), + iIn( -1 ), + iOut( -1 ) { #ifndef WIN32 - if( iFlags&Create ) - { - if( mkfifo( sName.getStr(), mAcc ) ) - { - throw FifoException("Error creating fifo: %s\n", strerror( errno ) ); - } - } - if( iFlags&Read ) - { - iIn = ::open( - sName.getStr(), - O_RDONLY|((iFlags&NonBlock)?O_NONBLOCK:0) - ); - } - if( iFlags&Write ) - { - iOut = ::open( - sName.getStr(), - O_WRONLY - ); - } + if( iFlags&Create ) + { + if( mkfifo( sName.getStr(), mAcc ) ) + { + throw FifoException("Error creating fifo: %s\n", strerror( errno ) ); + } + } + if( iFlags&Read ) + { + iIn = ::open( + sName.getStr(), + O_RDONLY|((iFlags&NonBlock)?O_NONBLOCK:0) + ); + } + if( iFlags&Write ) + { + iOut = ::open( + sName.getStr(), + O_WRONLY + ); + } #else - #warning Bu::Fifo::Fifo IS A STUB for WIN32!!!! + #warning Bu::Fifo::Fifo IS A STUB for WIN32!!!! #endif } Bu::Fifo::~Fifo() { - close(); + close(); } void Bu::Fifo::close() { - if( iIn > -1 ) - { - ::close( iIn ); - iIn = -1; - } - if( iOut > -1 ) - { - ::close( iOut ); - iOut = -1; - } + if( iIn > -1 ) + { + ::close( iIn ); + iIn = -1; + } + if( iOut > -1 ) + { + ::close( iOut ); + iOut = -1; + } } Bu::size Bu::Fifo::read( void *pBuf, Bu::size nBytes ) { - if( iIn < 0 ) - throw FifoException("Fifo not open for reading."); + if( iIn < 0 ) + throw FifoException("Fifo not open for reading."); - return TEMP_FAILURE_RETRY( ::read( iIn, pBuf, nBytes ) ); + return TEMP_FAILURE_RETRY( ::read( iIn, pBuf, nBytes ) ); } Bu::size Bu::Fifo::write( const void *pBuf, Bu::size nBytes ) { - if( iOut < 0 ) - throw FifoException("Fifo not open for writing."); + if( iOut < 0 ) + throw FifoException("Fifo not open for writing."); - return TEMP_FAILURE_RETRY( ::write( iOut, pBuf, nBytes ) ); + return TEMP_FAILURE_RETRY( ::write( iOut, pBuf, nBytes ) ); } Bu::size Bu::Fifo::tell() { - return -1; + return -1; } void Bu::Fifo::seek( Bu::size ) @@ -102,53 +102,53 @@ void Bu::Fifo::setPosEnd( Bu::size ) bool Bu::Fifo::isEos() { - return false; + return false; } bool Bu::Fifo::canRead() { - return (iIn>-1); + return (iIn>-1); } bool Bu::Fifo::canWrite() { - return (iOut>-1); + return (iOut>-1); } bool Bu::Fifo::isReadable() { - return (iIn>-1); + return (iIn>-1); } bool Bu::Fifo::isWritable() { - return (iOut>-1); + return (iOut>-1); } bool Bu::Fifo::isSeekable() { - return false; + return false; } bool Bu::Fifo::isBlocking() { #ifndef WIN32 - return ((fcntl( iIn, F_GETFL, 0 )&O_NONBLOCK) == O_NONBLOCK); + return ((fcntl( iIn, F_GETFL, 0 )&O_NONBLOCK) == O_NONBLOCK); #else - #warning Bu::Fifo::isBlocking IS A STUB for WIN32!!!! -#endif + #warning Bu::Fifo::isBlocking IS A STUB for WIN32!!!! +#endif } void Bu::Fifo::setBlocking( bool bBlocking ) { #ifndef WIN32 - if( bBlocking ) - fcntl( iIn, F_SETFL, fcntl( iIn, F_GETFL, 0 )&(~O_NONBLOCK) ); - else - fcntl( iIn, F_SETFL, fcntl( iIn, F_GETFL, 0 )|O_NONBLOCK ); + if( bBlocking ) + fcntl( iIn, F_SETFL, fcntl( iIn, F_GETFL, 0 )&(~O_NONBLOCK) ); + else + fcntl( iIn, F_SETFL, fcntl( iIn, F_GETFL, 0 )|O_NONBLOCK ); #else - #warning Bu::Fifo::setBlocking IS A STUB for WIN32!!!! -#endif + #warning Bu::Fifo::setBlocking IS A STUB for WIN32!!!! +#endif } void Bu::Fifo::flush() @@ -157,6 +157,6 @@ void Bu::Fifo::flush() bool Bu::Fifo::isOpen() { - return (iIn > -1) || (iOut > -1); + return (iIn > -1) || (iOut > -1); } diff --git a/src/unstable/fifo.h b/src/unstable/fifo.h index ea32f04..3d9192a 100644 --- a/src/unstable/fifo.h +++ b/src/unstable/fifo.h @@ -18,55 +18,55 @@ namespace Bu { - subExceptionDecl( FifoException ); + subExceptionDecl( FifoException ); - /** - * A fifo stream. - *@ingroup Streams - */ - class Fifo : public Bu::Stream - { - public: - Fifo( const Bu::String &sName, int iFlags, mode_t mAcc=-1 ); - virtual ~Fifo(); + /** + * A fifo stream. + *@ingroup Streams + */ + class Fifo : public Bu::Stream + { + public: + Fifo( const Bu::String &sName, int iFlags, mode_t mAcc=-1 ); + virtual ~Fifo(); - virtual void close(); - virtual Bu::size read( void *pBuf, Bu::size nBytes ); - virtual Bu::size write( const void *pBuf, Bu::size nBytes ); - using Stream::write; + virtual void close(); + virtual Bu::size read( void *pBuf, Bu::size nBytes ); + virtual Bu::size write( const void *pBuf, Bu::size nBytes ); + using Stream::write; - virtual Bu::size tell(); - virtual void seek( Bu::size offset ); - virtual void setPos( Bu::size pos ); - virtual void setPosEnd( Bu::size pos ); - virtual bool isEos(); - virtual bool isOpen(); + virtual Bu::size tell(); + virtual void seek( Bu::size offset ); + virtual void setPos( Bu::size pos ); + virtual void setPosEnd( Bu::size pos ); + virtual bool isEos(); + virtual bool isOpen(); - virtual void flush(); + virtual void flush(); - virtual bool canRead(); - virtual bool canWrite(); + virtual bool canRead(); + virtual bool canWrite(); - virtual bool isReadable(); - virtual bool isWritable(); - virtual bool isSeekable(); + virtual bool isReadable(); + virtual bool isWritable(); + virtual bool isSeekable(); - virtual bool isBlocking(); - virtual void setBlocking( bool bBlocking=true ); + virtual bool isBlocking(); + virtual void setBlocking( bool bBlocking=true ); - enum { - Read = 0x01, - Write = 0x02, - Create = 0x04, - Delete = 0x08, - NonBlock = 0x10 - }; + enum { + Read = 0x01, + Write = 0x02, + Create = 0x04, + Delete = 0x08, + NonBlock = 0x10 + }; - private: - int iFlags; - int iIn; - int iOut; - }; + private: + int iFlags; + int iIn; + int iOut; + }; } #endif diff --git a/src/unstable/itoserver.cpp b/src/unstable/itoserver.cpp index 7dbce6c..103bf90 100644 --- a/src/unstable/itoserver.cpp +++ b/src/unstable/itoserver.cpp @@ -13,121 +13,121 @@ #include "bu/tcpsocket.h" Bu::ItoServer::ItoServer() : - nTimeoutSec( 1 ), - nTimeoutUSec( 0 ) + nTimeoutSec( 1 ), + nTimeoutUSec( 0 ) { - FD_ZERO( &fdActive ); + FD_ZERO( &fdActive ); } Bu::ItoServer::~ItoServer() { - while( !qClientCleanup.isEmpty() ) - { - ItoClient *pCli = qClientCleanup.dequeue(); - pCli->join(); - delete pCli; - } - // TODO: Make sure here that each client has shutdown it's socket, and - // maybe even written any extra data, we could put a timelimit on this... - // anyway, it's not as clean as it could be right now. - for( ClientHash::iterator i = hClients.begin(); i != hClients.end(); i++ ) - { - ItoClient *pCli = (*i); - pCli->join(); - delete pCli; - } + while( !qClientCleanup.isEmpty() ) + { + ItoClient *pCli = qClientCleanup.dequeue(); + pCli->join(); + delete pCli; + } + // TODO: Make sure here that each client has shutdown it's socket, and + // maybe even written any extra data, we could put a timelimit on this... + // anyway, it's not as clean as it could be right now. + for( ClientHash::iterator i = hClients.begin(); i != hClients.end(); i++ ) + { + ItoClient *pCli = (*i); + pCli->join(); + delete pCli; + } } void Bu::ItoServer::addPort( int nPort, int nPoolSize ) { - TcpServerSocket *s = new TcpServerSocket( nPort, nPoolSize ); - socket_t nSocket = s->getSocket(); - FD_SET( nSocket, &fdActive ); - hServers.insert( nSocket, s ); + TcpServerSocket *s = new TcpServerSocket( nPort, nPoolSize ); + socket_t nSocket = s->getSocket(); + FD_SET( nSocket, &fdActive ); + hServers.insert( nSocket, s ); } void Bu::ItoServer::addPort( const String &sAddr, int nPort, int nPoolSize ) { - TcpServerSocket *s = new TcpServerSocket( sAddr, nPort, nPoolSize ); - socket_t nSocket = s->getSocket(); - FD_SET( nSocket, &fdActive ); - hServers.insert( nSocket, s ); + TcpServerSocket *s = new TcpServerSocket( sAddr, nPort, nPoolSize ); + socket_t nSocket = s->getSocket(); + FD_SET( nSocket, &fdActive ); + hServers.insert( nSocket, s ); } void Bu::ItoServer::setTimeout( int nTimeoutSec, int nTimeoutUSec ) { - this->nTimeoutSec = nTimeoutSec; - this->nTimeoutUSec = nTimeoutUSec; + this->nTimeoutSec = nTimeoutSec; + this->nTimeoutUSec = nTimeoutUSec; } void Bu::ItoServer::addClient( socket_t nSocket, int nPort ) { - ItoClient *pC = new ItoClient( *this, nSocket, nPort, nTimeoutSec, - nTimeoutUSec ); + ItoClient *pC = new ItoClient( *this, nSocket, nPort, nTimeoutSec, + nTimeoutUSec ); - imClients.lock(); - hClients.insert( nSocket, pC ); - imClients.unlock(); - - pC->start(); + imClients.lock(); + hClients.insert( nSocket, pC ); + imClients.unlock(); + + pC->start(); } void Bu::ItoServer::run() { - for(;;) - { - struct timeval xTimeout = { nTimeoutSec, nTimeoutUSec }; - - fd_set fdRead = fdActive; - //fd_set fdWrite = fdActive; - fd_set fdException = fdActive; - - if( TEMP_FAILURE_RETRY( select( FD_SETSIZE, &fdRead, NULL, &fdException, &xTimeout ) ) < 0 ) - { - throw ExceptionBase("Error attempting to scan open connections."); - } - - for( ServerHash::iterator i = hServers.begin(); i != hServers.end(); i++ ) - { - if( FD_ISSET( i.getKey(), &fdRead ) ) - { - TcpServerSocket *pSrv = i.getValue(); - addClient( pSrv->accept(), pSrv->getPort() ); - } - } - - while( !qClientCleanup.isEmpty() ) - { - ItoClient *pCli = qClientCleanup.dequeue(); - pCli->join(); - delete pCli; - } - } + for(;;) + { + struct timeval xTimeout = { nTimeoutSec, nTimeoutUSec }; + + fd_set fdRead = fdActive; + //fd_set fdWrite = fdActive; + fd_set fdException = fdActive; + + if( TEMP_FAILURE_RETRY( select( FD_SETSIZE, &fdRead, NULL, &fdException, &xTimeout ) ) < 0 ) + { + throw ExceptionBase("Error attempting to scan open connections."); + } + + for( ServerHash::iterator i = hServers.begin(); i != hServers.end(); i++ ) + { + if( FD_ISSET( i.getKey(), &fdRead ) ) + { + TcpServerSocket *pSrv = i.getValue(); + addClient( pSrv->accept(), pSrv->getPort() ); + } + } + + while( !qClientCleanup.isEmpty() ) + { + ItoClient *pCli = qClientCleanup.dequeue(); + pCli->join(); + delete pCli; + } + } } void Bu::ItoServer::clientCleanup( socket_t iSocket ) { - imClients.lock(); - ItoClient *pCli = hClients.get( iSocket ); - imClients.unlock(); - qClientCleanup.enqueue( pCli ); + imClients.lock(); + ItoClient *pCli = hClients.get( iSocket ); + imClients.unlock(); + qClientCleanup.enqueue( pCli ); } Bu::ItoServer::ItoClient::ItoClient( ItoServer &rSrv, Bu::ItoServer::socket_t iSocket, int iPort, - int nTimeoutSec, int nTimeoutUSec ) : - rSrv( rSrv ), - iSocket( iSocket ), - iPort( iPort ), - nTimeoutSec( nTimeoutSec ), - nTimeoutUSec( nTimeoutUSec ) + int nTimeoutSec, int nTimeoutUSec ) : + rSrv( rSrv ), + iSocket( iSocket ), + iPort( iPort ), + nTimeoutSec( nTimeoutSec ), + nTimeoutUSec( nTimeoutUSec ) { - FD_ZERO( &fdActive ); - FD_SET( iSocket, &fdActive ); + FD_ZERO( &fdActive ); + FD_SET( iSocket, &fdActive ); - pClient = new Client( - new Bu::TcpSocket( iSocket ), - new SrvClientLinkFactory( rSrv ) - ); + pClient = new Client( + new Bu::TcpSocket( iSocket ), + new SrvClientLinkFactory( rSrv ) + ); } Bu::ItoServer::ItoClient::~ItoClient() @@ -136,67 +136,67 @@ Bu::ItoServer::ItoClient::~ItoClient() void Bu::ItoServer::ItoClient::run() { - imProto.lock(); - rSrv.onNewConnection( pClient, iPort ); - pClient->processOutput(); - imProto.unlock(); - - for(;;) - { - struct timeval xTimeout = { nTimeoutSec, nTimeoutUSec }; - - fd_set fdRead = fdActive; - fd_set fdWrite; - fd_set fdException = fdActive; - - FD_ZERO( &fdWrite ); - if( pClient->hasOutput() ) - FD_SET( iSocket, &fdWrite ); - - if( TEMP_FAILURE_RETRY( select( FD_SETSIZE, - &fdRead, &fdWrite, &fdException, &xTimeout ) ) < 0 ) - { - throw ExceptionBase("Error attempting to scan open connections."); - } - - while( !qMsg.isEmpty() ) - { - imProto.lock(); - Bu::String *pMsg = qMsg.dequeue(); - pClient->onMessage( *pMsg ); - delete pMsg; - pClient->processOutput(); - imProto.unlock(); - } - - if( FD_ISSET( iSocket, &fdRead ) ) - { - imProto.lock(); - pClient->processInput(); - imProto.unlock(); - if( !pClient->isOpen() ) - { - imProto.lock(); - rSrv.onClosedConnection( pClient ); - imProto.unlock(); - - rSrv.clientCleanup( iSocket ); - - return; - } - } - - if( FD_ISSET( iSocket, &fdWrite ) ) - { - imProto.lock(); - pClient->processOutput(); - imProto.unlock(); - } - } + imProto.lock(); + rSrv.onNewConnection( pClient, iPort ); + pClient->processOutput(); + imProto.unlock(); + + for(;;) + { + struct timeval xTimeout = { nTimeoutSec, nTimeoutUSec }; + + fd_set fdRead = fdActive; + fd_set fdWrite; + fd_set fdException = fdActive; + + FD_ZERO( &fdWrite ); + if( pClient->hasOutput() ) + FD_SET( iSocket, &fdWrite ); + + if( TEMP_FAILURE_RETRY( select( FD_SETSIZE, + &fdRead, &fdWrite, &fdException, &xTimeout ) ) < 0 ) + { + throw ExceptionBase("Error attempting to scan open connections."); + } + + while( !qMsg.isEmpty() ) + { + imProto.lock(); + Bu::String *pMsg = qMsg.dequeue(); + pClient->onMessage( *pMsg ); + delete pMsg; + pClient->processOutput(); + imProto.unlock(); + } + + if( FD_ISSET( iSocket, &fdRead ) ) + { + imProto.lock(); + pClient->processInput(); + imProto.unlock(); + if( !pClient->isOpen() ) + { + imProto.lock(); + rSrv.onClosedConnection( pClient ); + imProto.unlock(); + + rSrv.clientCleanup( iSocket ); + + return; + } + } + + if( FD_ISSET( iSocket, &fdWrite ) ) + { + imProto.lock(); + pClient->processOutput(); + imProto.unlock(); + } + } } Bu::ItoServer::SrvClientLink::SrvClientLink( ItoClient *pClient ) : - pClient( pClient ) + pClient( pClient ) { } @@ -206,22 +206,22 @@ Bu::ItoServer::SrvClientLink::~SrvClientLink() void Bu::ItoServer::SrvClientLink::sendMessage( const Bu::String &sMsg ) { - if( !pClient->imProto.trylock() ) - { - pClient->pClient->onMessage( sMsg ); - pClient->pClient->processOutput(); - pClient->imProto.unlock(); - } - else - { - Bu::String *pMsg = new Bu::String( sMsg ); - pClient->qMsg.enqueue( pMsg ); - } + if( !pClient->imProto.trylock() ) + { + pClient->pClient->onMessage( sMsg ); + pClient->pClient->processOutput(); + pClient->imProto.unlock(); + } + else + { + Bu::String *pMsg = new Bu::String( sMsg ); + pClient->qMsg.enqueue( pMsg ); + } } Bu::ItoServer::SrvClientLinkFactory::SrvClientLinkFactory( - Bu::ItoServer &rSrv ) : - rSrv( rSrv ) + Bu::ItoServer &rSrv ) : + rSrv( rSrv ) { } @@ -230,12 +230,12 @@ Bu::ItoServer::SrvClientLinkFactory::~SrvClientLinkFactory() } Bu::ClientLink *Bu::ItoServer::SrvClientLinkFactory::createLink( - Bu::Client *pClient ) + Bu::Client *pClient ) { - rSrv.imClients.lock(); - ItoClient *pCli = rSrv.hClients.get( *pClient->getSocket() ); - rSrv.imClients.unlock(); + rSrv.imClients.lock(); + ItoClient *pCli = rSrv.hClients.get( *pClient->getSocket() ); + rSrv.imClients.unlock(); - return new SrvClientLink( pCli ); + return new SrvClientLink( pCli ); } diff --git a/src/unstable/itoserver.h b/src/unstable/itoserver.h index 6a0df56..34f0fb1 100644 --- a/src/unstable/itoserver.h +++ b/src/unstable/itoserver.h @@ -11,7 +11,7 @@ #include #ifndef WIN32 - #include + #include #endif #include "bu/string.h" @@ -26,122 +26,122 @@ namespace Bu { - class TcpServerSocket; - class TcpSocket; - class Client; - - /** - * Core of a network server. This class is distinct from a ServerSocket in - * that a ServerSocket is one listening socket, nothing more. Socket will - * manage a pool of both ServerSockets and connected Sockets along with - * their protocols and buffers. - * - * To start serving on a new port, use the addPort functions. Each call to - * addPort creates a new ServerSocket, starts it listening, and adds it to - * the server pool. - * - * All of the real work is done by scan, which will wait for up - * to the timeout set by setTimeout before returning if there is no data - * pending. scan should probably be called in some sort of tight - * loop, possibly in it's own thread, or in the main control loop. - * - * In order to use a Server you must subclass it and implement the pure - * virtual functions. These allow you to receive notification of events - * happening within the server itself, and actually makes it useful. - *@ingroup Threading Serving - */ - class ItoServer : public Thread - { - friend class ItoClient; - friend class SrvClientLinkFactory; - public: - ItoServer(); - virtual ~ItoServer(); + class TcpServerSocket; + class TcpSocket; + class Client; + + /** + * Core of a network server. This class is distinct from a ServerSocket in + * that a ServerSocket is one listening socket, nothing more. Socket will + * manage a pool of both ServerSockets and connected Sockets along with + * their protocols and buffers. + * + * To start serving on a new port, use the addPort functions. Each call to + * addPort creates a new ServerSocket, starts it listening, and adds it to + * the server pool. + * + * All of the real work is done by scan, which will wait for up + * to the timeout set by setTimeout before returning if there is no data + * pending. scan should probably be called in some sort of tight + * loop, possibly in it's own thread, or in the main control loop. + * + * In order to use a Server you must subclass it and implement the pure + * virtual functions. These allow you to receive notification of events + * happening within the server itself, and actually makes it useful. + *@ingroup Threading Serving + */ + class ItoServer : public Thread + { + friend class ItoClient; + friend class SrvClientLinkFactory; + public: + ItoServer(); + virtual ~ItoServer(); #ifdef WIN32 - typedef unsigned int socket_t; + typedef unsigned int socket_t; #else - typedef int socket_t; + typedef int socket_t; #endif - void addPort( int nPort, int nPoolSize=40 ); - void addPort( const String &sAddr, int nPort, int nPoolSize=40 ); - - //void scan(); - void setTimeout( int nTimeoutSec, int nTimeoutUSec=0 ); - - void addClient( socket_t nSocket, int nPort ); - - virtual void onNewConnection( Client *pClient, int nPort )=0; - virtual void onClosedConnection( Client *pClient )=0; - - protected: - virtual void run(); - - private: - class SrvClientLink; - class ItoClient : public Thread - { - friend class Bu::ItoServer::SrvClientLink; - public: - ItoClient( ItoServer &rSrv, socket_t nSocket, int nPort, - int nTimeoutSec, int nTimeoutUSec ); - virtual ~ItoClient(); - - typedef SynchroQueue StringQueue; - StringQueue qMsg; - - protected: - virtual void run(); - - private: - ItoServer &rSrv; - Client *pClient; - fd_set fdActive; - socket_t iSocket; - int iPort; - int nTimeoutSec; - int nTimeoutUSec; - Mutex imProto; - }; - - class SrvClientLink : public Bu::ClientLink - { - public: - SrvClientLink( ItoClient *pClient ); - virtual ~SrvClientLink(); - - virtual void sendMessage( const Bu::String &sMsg ); - - private: - ItoClient *pClient; - }; - - class SrvClientLinkFactory : public Bu::ClientLinkFactory - { - public: - SrvClientLinkFactory( ItoServer &rSrv ); - virtual ~SrvClientLinkFactory(); - - virtual Bu::ClientLink *createLink( Bu::Client *pClient ); - - private: - ItoServer &rSrv; - }; - - int nTimeoutSec; - int nTimeoutUSec; - fd_set fdActive; - typedef Hash ServerHash; - ServerHash hServers; - typedef Hash ClientHash; - typedef SynchroQueue ClientQueue; - ClientHash hClients; - ClientQueue qClientCleanup; - Mutex imClients; - - void clientCleanup( socket_t iSocket ); - }; + void addPort( int nPort, int nPoolSize=40 ); + void addPort( const String &sAddr, int nPort, int nPoolSize=40 ); + + //void scan(); + void setTimeout( int nTimeoutSec, int nTimeoutUSec=0 ); + + void addClient( socket_t nSocket, int nPort ); + + virtual void onNewConnection( Client *pClient, int nPort )=0; + virtual void onClosedConnection( Client *pClient )=0; + + protected: + virtual void run(); + + private: + class SrvClientLink; + class ItoClient : public Thread + { + friend class Bu::ItoServer::SrvClientLink; + public: + ItoClient( ItoServer &rSrv, socket_t nSocket, int nPort, + int nTimeoutSec, int nTimeoutUSec ); + virtual ~ItoClient(); + + typedef SynchroQueue StringQueue; + StringQueue qMsg; + + protected: + virtual void run(); + + private: + ItoServer &rSrv; + Client *pClient; + fd_set fdActive; + socket_t iSocket; + int iPort; + int nTimeoutSec; + int nTimeoutUSec; + Mutex imProto; + }; + + class SrvClientLink : public Bu::ClientLink + { + public: + SrvClientLink( ItoClient *pClient ); + virtual ~SrvClientLink(); + + virtual void sendMessage( const Bu::String &sMsg ); + + private: + ItoClient *pClient; + }; + + class SrvClientLinkFactory : public Bu::ClientLinkFactory + { + public: + SrvClientLinkFactory( ItoServer &rSrv ); + virtual ~SrvClientLinkFactory(); + + virtual Bu::ClientLink *createLink( Bu::Client *pClient ); + + private: + ItoServer &rSrv; + }; + + int nTimeoutSec; + int nTimeoutUSec; + fd_set fdActive; + typedef Hash ServerHash; + ServerHash hServers; + typedef Hash ClientHash; + typedef SynchroQueue ClientQueue; + ClientHash hClients; + ClientQueue qClientCleanup; + Mutex imClients; + + void clientCleanup( socket_t iSocket ); + }; } #endif diff --git a/src/unstable/minimacro.cpp b/src/unstable/minimacro.cpp index ff12267..72178ad 100644 --- a/src/unstable/minimacro.cpp +++ b/src/unstable/minimacro.cpp @@ -9,16 +9,16 @@ Bu::MiniMacro::MiniMacro() { - hFuncs.insert("toupper", new FuncToUpper() ); - hFuncs.insert("tolower", new FuncToLower() ); + hFuncs.insert("toupper", new FuncToUpper() ); + hFuncs.insert("tolower", new FuncToLower() ); } Bu::MiniMacro::MiniMacro( const StrHash &sVarSrc ) { - for( StrHash::const_iterator i = sVarSrc.begin(); i != sVarSrc.end(); i++ ) - { - addVar( i.getKey(), i.getValue() ); - } + for( StrHash::const_iterator i = sVarSrc.begin(); i != sVarSrc.end(); i++ ) + { + addVar( i.getKey(), i.getValue() ); + } } Bu::MiniMacro::~MiniMacro() @@ -27,161 +27,161 @@ Bu::MiniMacro::~MiniMacro() Bu::String Bu::MiniMacro::parse( const Bu::String &sIn ) { - bContinue = true; - Bu::String sOut; - for( sCur = sIn.getStr(); *sCur && bContinue; sCur++ ) - { - if( *sCur == '{' ) - { - switch( sCur[1] ) - { - case '=': - sCur += 2; - sOut += parseRepl(); - break; - - case '?': - sCur += 2; - sOut += parseCond(); - break; - - case ':': - sCur += 2; - sOut += parseCmd(); - break; - - default: - sOut += *sCur; - continue; - } - } - else - { - sOut += *sCur; - } - } - - iLastPos = (ptrdiff_t)sCur - (ptrdiff_t)sIn.getStr(); - - return sOut; + bContinue = true; + Bu::String sOut; + for( sCur = sIn.getStr(); *sCur && bContinue; sCur++ ) + { + if( *sCur == '{' ) + { + switch( sCur[1] ) + { + case '=': + sCur += 2; + sOut += parseRepl(); + break; + + case '?': + sCur += 2; + sOut += parseCond(); + break; + + case ':': + sCur += 2; + sOut += parseCmd(); + break; + + default: + sOut += *sCur; + continue; + } + } + else + { + sOut += *sCur; + } + } + + iLastPos = (ptrdiff_t)sCur - (ptrdiff_t)sIn.getStr(); + + return sOut; } Bu::String Bu::MiniMacro::parseRepl() { - Bu::String sOut; - bool bIsFirst = true; - for( const char *sNext = sCur;;) - { - for(; *sNext != ':' && *sNext != '}' && *sNext != '\0'; sNext++ ) { } - if( *sNext == '\0' ) - break; - Bu::String sName( sCur, (ptrdiff_t)sNext-(ptrdiff_t)sCur ); - if( bIsFirst ) - { - sOut = hVars[sName]; - bIsFirst = false; - //printf("Variable: \"%s\"\n", sName.getStr() ); - } - else - { - sOut = callFunc( sOut, sName ); - //printf("Filter: \"%s\"\n", sName.getStr() ); - } - if( *sNext == '}' ) - { - sCur = sNext; - break; - } - else if( *sNext == ':' ) - { - } - sNext++; - sCur = sNext; - } - return sOut; + Bu::String sOut; + bool bIsFirst = true; + for( const char *sNext = sCur;;) + { + for(; *sNext != ':' && *sNext != '}' && *sNext != '\0'; sNext++ ) { } + if( *sNext == '\0' ) + break; + Bu::String sName( sCur, (ptrdiff_t)sNext-(ptrdiff_t)sCur ); + if( bIsFirst ) + { + sOut = hVars[sName]; + bIsFirst = false; + //printf("Variable: \"%s\"\n", sName.getStr() ); + } + else + { + sOut = callFunc( sOut, sName ); + //printf("Filter: \"%s\"\n", sName.getStr() ); + } + if( *sNext == '}' ) + { + sCur = sNext; + break; + } + else if( *sNext == ':' ) + { + } + sNext++; + sCur = sNext; + } + return sOut; } Bu::String Bu::MiniMacro::parseCond() { - Bu::String sOut; - //printf("%20s\n", sCur ); - return sOut; + Bu::String sOut; + //printf("%20s\n", sCur ); + return sOut; } Bu::String Bu::MiniMacro::parseCmd() { - Bu::String sOut; - const char *sNext = sCur; - for(; *sNext != ':' && *sNext != '}' && *sNext != '\0'; sNext++ ) { } - if( *sNext != '\0' ) - { - Bu::String sName( sCur, (ptrdiff_t)sNext-(ptrdiff_t)sCur ); - if( sName == "end" ) - { - sCur = sNext; - bContinue = false; - return sOut; - } - else - { - throw Bu::ExceptionBase("Unknown command '%s'.", - sName.getStr() - ); - } - } - else - { - //printf("Uh...?\n"); - } - - //printf("%20s\n", sCur ); - return sOut; + Bu::String sOut; + const char *sNext = sCur; + for(; *sNext != ':' && *sNext != '}' && *sNext != '\0'; sNext++ ) { } + if( *sNext != '\0' ) + { + Bu::String sName( sCur, (ptrdiff_t)sNext-(ptrdiff_t)sCur ); + if( sName == "end" ) + { + sCur = sNext; + bContinue = false; + return sOut; + } + else + { + throw Bu::ExceptionBase("Unknown command '%s'.", + sName.getStr() + ); + } + } + else + { + //printf("Uh...?\n"); + } + + //printf("%20s\n", sCur ); + return sOut; } Bu::String Bu::MiniMacro::callFunc( - const Bu::String &sIn, const Bu::String &sFunc ) + const Bu::String &sIn, const Bu::String &sFunc ) { - int i = sFunc.findIdx('('); - if( i < 0 ) - throw Bu::ExceptionBase("That doesn't look like a function call"); - Bu::String sName( sFunc.getStr(), i ); - StrList lsParams; - for( const char *s = sFunc.getStr()+i+1; *s && *s != ')'; s++ ) - { - for(; *s == ' ' || *s == '\t' || *s == '\r' || *s == '\n'; s++ ) { } - const char *sNext; - for( sNext = s; *sNext && *sNext != ')' && *sNext != ','; sNext++ ) { } - Bu::String p( s, (ptrdiff_t)sNext-(ptrdiff_t)s ); - lsParams.append( p ); - sNext++; - s = sNext; - } - return hFuncs.get( sName )->call( sIn, lsParams ); + int i = sFunc.findIdx('('); + if( i < 0 ) + throw Bu::ExceptionBase("That doesn't look like a function call"); + Bu::String sName( sFunc.getStr(), i ); + StrList lsParams; + for( const char *s = sFunc.getStr()+i+1; *s && *s != ')'; s++ ) + { + for(; *s == ' ' || *s == '\t' || *s == '\r' || *s == '\n'; s++ ) { } + const char *sNext; + for( sNext = s; *sNext && *sNext != ')' && *sNext != ','; sNext++ ) { } + Bu::String p( s, (ptrdiff_t)sNext-(ptrdiff_t)s ); + lsParams.append( p ); + sNext++; + s = sNext; + } + return hFuncs.get( sName )->call( sIn, lsParams ); } void Bu::MiniMacro::addVar( - const Bu::String &sName, const Bu::String &sValue ) + const Bu::String &sName, const Bu::String &sValue ) { - hVars.insert( sName, sValue ); + hVars.insert( sName, sValue ); } bool Bu::MiniMacro::hasVar( const Bu::String &sName ) { - return hVars.has( sName ); + return hVars.has( sName ); } const Bu::String &Bu::MiniMacro::getVar( const Bu::String &sName ) { - return hVars.get( sName ); + return hVars.get( sName ); } const Bu::StrHash &Bu::MiniMacro::getVars() { - return hVars; + return hVars; } int Bu::MiniMacro::getPosition() { - return iLastPos; + return iLastPos; } diff --git a/src/unstable/minimacro.h b/src/unstable/minimacro.h index dc38891..1c33ea4 100644 --- a/src/unstable/minimacro.h +++ b/src/unstable/minimacro.h @@ -13,118 +13,118 @@ namespace Bu { - typedef Bu::Hash StrHash; - /** - * A processor for Libbu++ brand Mini Macros. These are really simple, but - * still fairly flexible. It's mainly text replacement, but with a few - * extras like filter functions and conditional text segments. So far we - * don't support loops or anything, I'm not sure we ever will. - * - * Anatomy of a mini macro: - * - Every macro begins with a two character code, the first character is - * always '{', the second character determines the operation to perform. - * - If the '{' is followed by a character that is not valid it is not - * considered for expansion and the characters are copied to the output. - * - Every macro ends with a closing '}' - * - Macro types: - * - '=': variable replacement. The '=' is immediatley followed by the - * name of the variable to replace, then any number of optional filter - * segments. - * - '?': conditional text. The '?' is immediately followed by the - * variable to test. This works two ways, the variable can be alone, in - * which case it's existance is tested, or it can be followed by a "=" - * and a string to compare to. This is then followed by a text segment - * that will be used if the test is true, and an optional text segment - * to be used if the test is false. - * - ':': command. The ':' is immediately followed by a command string, - * of which there's only one right now, but that's ok. These are not - * put into the output stream, but instead mark something for the - * parser. Currently supported: - * - {:end}: end of parsing, stop here, also make note of how many input - * characters were used. - * - Segments: - * - Each segment is seperated by a colon. - * - Filter segments give the name of the filter, followed by - * parenthesies. Parameters may be provided within the parenthesies. - * - Text segments should always be quoted, but may contain any characters - * within the quotes, backslash is used as per C/ANSI/ISO standard. - * You can also quote any text using [' '] instead of quotes, which - * allows for nested strings. The [' token is only recognised within - * a macro. - * - *@verbatim - {=name:tolower()} - {=name:ccsplit("_"):toupper()} - {?name:"name exists and is {=name}"} - {?name:"{=name}":"no name!"} - {?name="bob":"You're named bob!":"Who are you? I only know bob..."} - @endverbatim - */ - class MiniMacro - { - public: - MiniMacro(); - MiniMacro( const StrHash &sVarSrc ); - virtual ~MiniMacro(); + typedef Bu::Hash StrHash; + /** + * A processor for Libbu++ brand Mini Macros. These are really simple, but + * still fairly flexible. It's mainly text replacement, but with a few + * extras like filter functions and conditional text segments. So far we + * don't support loops or anything, I'm not sure we ever will. + * + * Anatomy of a mini macro: + * - Every macro begins with a two character code, the first character is + * always '{', the second character determines the operation to perform. + * - If the '{' is followed by a character that is not valid it is not + * considered for expansion and the characters are copied to the output. + * - Every macro ends with a closing '}' + * - Macro types: + * - '=': variable replacement. The '=' is immediatley followed by the + * name of the variable to replace, then any number of optional filter + * segments. + * - '?': conditional text. The '?' is immediately followed by the + * variable to test. This works two ways, the variable can be alone, in + * which case it's existance is tested, or it can be followed by a "=" + * and a string to compare to. This is then followed by a text segment + * that will be used if the test is true, and an optional text segment + * to be used if the test is false. + * - ':': command. The ':' is immediately followed by a command string, + * of which there's only one right now, but that's ok. These are not + * put into the output stream, but instead mark something for the + * parser. Currently supported: + * - {:end}: end of parsing, stop here, also make note of how many input + * characters were used. + * - Segments: + * - Each segment is seperated by a colon. + * - Filter segments give the name of the filter, followed by + * parenthesies. Parameters may be provided within the parenthesies. + * - Text segments should always be quoted, but may contain any characters + * within the quotes, backslash is used as per C/ANSI/ISO standard. + * You can also quote any text using [' '] instead of quotes, which + * allows for nested strings. The [' token is only recognised within + * a macro. + * + *@verbatim + {=name:tolower()} + {=name:ccsplit("_"):toupper()} + {?name:"name exists and is {=name}"} + {?name:"{=name}":"no name!"} + {?name="bob":"You're named bob!":"Who are you? I only know bob..."} + @endverbatim + */ + class MiniMacro + { + public: + MiniMacro(); + MiniMacro( const StrHash &sVarSrc ); + virtual ~MiniMacro(); - Bu::String parse( const Bu::String &sIn ); - void addVar( const Bu::String &sName, const Bu::String &sValue ); - bool hasVar( const Bu::String &sName ); - const Bu::String &getVar( const Bu::String &sName ); - const StrHash &getVars(); - int getPosition(); + Bu::String parse( const Bu::String &sIn ); + void addVar( const Bu::String &sName, const Bu::String &sValue ); + bool hasVar( const Bu::String &sName ); + const Bu::String &getVar( const Bu::String &sName ); + const StrHash &getVars(); + int getPosition(); - private: - const char *sCur; - Bu::String parseRepl(); - Bu::String parseCond(); - Bu::String parseCmd(); - Bu::String callFunc( - const Bu::String &sIn, const Bu::String &sFunc ); + private: + const char *sCur; + Bu::String parseRepl(); + Bu::String parseCond(); + Bu::String parseCmd(); + Bu::String callFunc( + const Bu::String &sIn, const Bu::String &sFunc ); - StrHash hVars; - bool bContinue; - int iLastPos; + StrHash hVars; + bool bContinue; + int iLastPos; - public: - typedef Bu::List StrList; - class Func - { - public: - Func(){} - virtual ~Func(){} - virtual Bu::String call( - const Bu::String &sIn, StrList &lsParam )=0; - }; + public: + typedef Bu::List StrList; + class Func + { + public: + Func(){} + virtual ~Func(){} + virtual Bu::String call( + const Bu::String &sIn, StrList &lsParam )=0; + }; - class FuncToUpper : public Func - { - public: - FuncToUpper(){} - virtual ~FuncToUpper(){} - virtual Bu::String call( - const Bu::String &sIn, StrList & ) - { - return sIn.toUpper(); - } - }; + class FuncToUpper : public Func + { + public: + FuncToUpper(){} + virtual ~FuncToUpper(){} + virtual Bu::String call( + const Bu::String &sIn, StrList & ) + { + return sIn.toUpper(); + } + }; - class FuncToLower : public Func - { - public: - FuncToLower(){} - virtual ~FuncToLower(){} - virtual Bu::String call( - const Bu::String &sIn, StrList & ) - { - return sIn.toLower(); - } - }; - - private: - typedef Bu::Hash FuncHash; - FuncHash hFuncs; - }; + class FuncToLower : public Func + { + public: + FuncToLower(){} + virtual ~FuncToLower(){} + virtual Bu::String call( + const Bu::String &sIn, StrList & ) + { + return sIn.toLower(); + } + }; + + private: + typedef Bu::Hash FuncHash; + FuncHash hFuncs; + }; }; #endif diff --git a/src/unstable/myriadfs.cpp b/src/unstable/myriadfs.cpp index 6ed176d..3680c3f 100644 --- a/src/unstable/myriadfs.cpp +++ b/src/unstable/myriadfs.cpp @@ -19,686 +19,686 @@ using Bu::Fmt; namespace Bu { subExceptionDef( MyriadFsException ) } -#define Myriad_Fs_MAGIC_CODE ((char *)"\xa7\x18\x8b\x39") +#define Myriad_Fs_MAGIC_CODE ((char *)"\xa7\x18\x8b\x39") Bu::MyriadFs::MyriadFs( Bu::Stream &rStore, int iBlockSize ) : - rStore( rStore ), - mStore( rStore, iBlockSize ), - iUser( 0 ), - iGroup( 0 ) + rStore( rStore ), + mStore( rStore, iBlockSize ), + iUser( 0 ), + iGroup( 0 ) { #ifndef WIN32 - iUser = getuid(); - iGroup = getgid(); + iUser = getuid(); + iGroup = getgid(); #endif - if( mStore.hasStream( 1 ) ) - { - // Check to see if this is a MyriadFs stream. - Bu::MyriadStream ms = mStore.openStream( 1 ); - char sMagic[4]; - if( ms.read( sMagic, 4 ) < 4 ) - throw MyriadFsException("The provided stream does not appear to be " - "a MyriadFs stream."); - if( ::strncmp( sMagic, Myriad_Fs_MAGIC_CODE, 4 ) ) - throw MyriadFsException("The provided stream does not appear to be " - "a MyriadFs stream."); - - int8_t iVer; - ms.read( &iVer, 1 ); - - int32_t iNumNodes; - ms.read( &iNumNodes, 4 ); - for( int32_t j = 0; j < iNumNodes; j++ ) - { - int32_t iNode; - int32_t iPos; - ms.read( &iNode, 4 ); - ms.read( &iPos, 4 ); - hNodeIndex.insert( iNode, iPos ); - } - } - else - { - // Create initial header stream - { - mStore.createStream( 1 ); - Bu::MyriadStream ms = mStore.openStream( 1 ); - ms.write( Myriad_Fs_MAGIC_CODE, 4 ); - int8_t iVer = 1; - int32_t iTmp = 1; - ms.write( &iVer, 1 ); - ms.write( &iTmp, 4 ); // iNumNodes - iTmp = 0; - ms.write( &iTmp, 4 ); // iInode - ms.write( &iTmp, 4 ); // iPosition - hNodeIndex.insert( 0, 0 ); - } - - // Create initial inode stream, with one root node. - { - mStore.createStream( 2 ); - Bu::MyriadStream ms = mStore.openStream( 2 ); - RawStat rs; - rs.iNode = 0; - rs.iUser = iUser; - rs.iGroup = iGroup; - rs.uPerms = 0755|typeDir; - rs.iLinks = 1; - rs.uStreamIndex = 3; - rs.iCTime = rs.iMTime = rs.iATime = time(NULL); - ms.write( &rs, sizeof(RawStat) ); - } - - // Create inode 0's storage stream. - { - mStore.createStream( 3 ); - Bu::MyriadStream ms = mStore.openStream( 3 ); - int32_t iTmp32 = 0; - ms.write( &iTmp32, 4 ); // iChildCount - } - } + if( mStore.hasStream( 1 ) ) + { + // Check to see if this is a MyriadFs stream. + Bu::MyriadStream ms = mStore.openStream( 1 ); + char sMagic[4]; + if( ms.read( sMagic, 4 ) < 4 ) + throw MyriadFsException("The provided stream does not appear to be " + "a MyriadFs stream."); + if( ::strncmp( sMagic, Myriad_Fs_MAGIC_CODE, 4 ) ) + throw MyriadFsException("The provided stream does not appear to be " + "a MyriadFs stream."); + + int8_t iVer; + ms.read( &iVer, 1 ); + + int32_t iNumNodes; + ms.read( &iNumNodes, 4 ); + for( int32_t j = 0; j < iNumNodes; j++ ) + { + int32_t iNode; + int32_t iPos; + ms.read( &iNode, 4 ); + ms.read( &iPos, 4 ); + hNodeIndex.insert( iNode, iPos ); + } + } + else + { + // Create initial header stream + { + mStore.createStream( 1 ); + Bu::MyriadStream ms = mStore.openStream( 1 ); + ms.write( Myriad_Fs_MAGIC_CODE, 4 ); + int8_t iVer = 1; + int32_t iTmp = 1; + ms.write( &iVer, 1 ); + ms.write( &iTmp, 4 ); // iNumNodes + iTmp = 0; + ms.write( &iTmp, 4 ); // iInode + ms.write( &iTmp, 4 ); // iPosition + hNodeIndex.insert( 0, 0 ); + } + + // Create initial inode stream, with one root node. + { + mStore.createStream( 2 ); + Bu::MyriadStream ms = mStore.openStream( 2 ); + RawStat rs; + rs.iNode = 0; + rs.iUser = iUser; + rs.iGroup = iGroup; + rs.uPerms = 0755|typeDir; + rs.iLinks = 1; + rs.uStreamIndex = 3; + rs.iCTime = rs.iMTime = rs.iATime = time(NULL); + ms.write( &rs, sizeof(RawStat) ); + } + + // Create inode 0's storage stream. + { + mStore.createStream( 3 ); + Bu::MyriadStream ms = mStore.openStream( 3 ); + int32_t iTmp32 = 0; + ms.write( &iTmp32, 4 ); // iChildCount + } + } } Bu::MyriadFs::~MyriadFs() { - writeHeader(); + writeHeader(); } void Bu::MyriadFs::stat( const Bu::String &sPath, Bu::MyriadFs::Stat &rBuf ) { - int32_t iParent; - int32_t iNode = lookupInode( sPath, iParent ); - Bu::MyriadStream is = mStore.openStream( 2 ); - stat( iNode, rBuf, is ); + int32_t iParent; + int32_t iNode = lookupInode( sPath, iParent ); + Bu::MyriadStream is = mStore.openStream( 2 ); + stat( iNode, rBuf, is ); } Bu::MyriadStream Bu::MyriadFs::open( const Bu::String &sPath, int /*iMode*/, - uint16_t uPerms ) -{ - int32_t iParent = -1; - int32_t iNode; - try - { - iNode = lookupInode( sPath, iParent ); - sio << "File found." << sio.nl; - // The file was found - return openByInode( iNode ); - } - catch( Bu::MyriadFsException &e ) - { - if( iParent < 0 ) - throw; - - // This means that an intermediate path component couldn't be found - if( e.getErrorCode() == 1 ) - throw; - - // The file wasn't found, but the path leading up to it was. - // first, figure out the final path element... - Bu::String sName = filePart( sPath ); - sio << "End filename: " << sName << sio.nl; - sio << "Parent inode: " << iParent << sio.nl; - iNode = create( iParent, sName, (uPerms&permMask)|typeRegFile, 0 ); - sio << "New iNode: " << iNode << sio.nl; - return openByInode( iNode ); - } + uint16_t uPerms ) +{ + int32_t iParent = -1; + int32_t iNode; + try + { + iNode = lookupInode( sPath, iParent ); + sio << "File found." << sio.nl; + // The file was found + return openByInode( iNode ); + } + catch( Bu::MyriadFsException &e ) + { + if( iParent < 0 ) + throw; + + // This means that an intermediate path component couldn't be found + if( e.getErrorCode() == 1 ) + throw; + + // The file wasn't found, but the path leading up to it was. + // first, figure out the final path element... + Bu::String sName = filePart( sPath ); + sio << "End filename: " << sName << sio.nl; + sio << "Parent inode: " << iParent << sio.nl; + iNode = create( iParent, sName, (uPerms&permMask)|typeRegFile, 0 ); + sio << "New iNode: " << iNode << sio.nl; + return openByInode( iNode ); + } } void Bu::MyriadFs::create( const Bu::String &sPath, uint16_t iPerms ) { - create( sPath, iPerms, 0 ); + create( sPath, iPerms, 0 ); } void Bu::MyriadFs::create( const Bu::String &sPath, uint16_t iPerms, - uint16_t iDevHi, uint16_t iDevLo ) + uint16_t iDevHi, uint16_t iDevLo ) { - create( sPath, iPerms, ((uint32_t)iDevHi<<16)|(uint32_t)iDevLo ); + create( sPath, iPerms, ((uint32_t)iDevHi<<16)|(uint32_t)iDevLo ); } void Bu::MyriadFs::create( const Bu::String &sPath, uint16_t iPerms, - uint32_t uSpecial ) -{ - int32_t iParent = -1; - int32_t iNode; - try - { - iNode = lookupInode( sPath, iParent ); - sio << "File found." << sio.nl; - // The file was found - throw Bu::MyriadFsException("Path already exists."); - } - catch( Bu::MyriadFsException &e ) - { - if( iParent < 0 ) - throw; - - // This means that an intermediate path component couldn't be found - if( e.getErrorCode() == 1 ) - throw; - - // The file wasn't found, but the path leading up to it was. - // first, figure out the final path element... - Bu::String sName = filePart( sPath ); - sio << "End filename: " << sName << sio.nl; - sio << "Parent inode: " << iParent << sio.nl; - iNode = create( iParent, sName, iPerms, uSpecial ); - sio << "New iNode: " << iNode << sio.nl; - } + uint32_t uSpecial ) +{ + int32_t iParent = -1; + int32_t iNode; + try + { + iNode = lookupInode( sPath, iParent ); + sio << "File found." << sio.nl; + // The file was found + throw Bu::MyriadFsException("Path already exists."); + } + catch( Bu::MyriadFsException &e ) + { + if( iParent < 0 ) + throw; + + // This means that an intermediate path component couldn't be found + if( e.getErrorCode() == 1 ) + throw; + + // The file wasn't found, but the path leading up to it was. + // first, figure out the final path element... + Bu::String sName = filePart( sPath ); + sio << "End filename: " << sName << sio.nl; + sio << "Parent inode: " << iParent << sio.nl; + iNode = create( iParent, sName, iPerms, uSpecial ); + sio << "New iNode: " << iNode << sio.nl; + } } void Bu::MyriadFs::mkDir( const Bu::String &sPath, uint16_t iPerms ) { - create( sPath, (iPerms&permMask)|typeDir, 0 ); + create( sPath, (iPerms&permMask)|typeDir, 0 ); } void Bu::MyriadFs::mkSymLink( const Bu::String &sTarget, - const Bu::String &sPath ) -{ - int32_t iParent = -1; - int32_t iNode; - try - { - iNode = lookupInode( sPath, iParent ); - throw Bu::MyriadFsException("Path already exists."); - } - catch( Bu::MyriadFsException &e ) - { - if( iParent < 0 ) - throw; - - // This means that an intermediate path component couldn't be found - if( e.getErrorCode() == 1 ) - throw; - - // The file wasn't found, but the path leading up to it was. - // first, figure out the final path element... - Bu::String sName = filePart( sPath ); - sio << "End filename: " << sName << sio.nl; - sio << "Parent inode: " << iParent << sio.nl; - iNode = create( iParent, sName, 0777|typeSymLink, 0 ); - sio << "New iNode: " << iNode << sio.nl; - MyriadStream ms = openByInode( iNode ); - ms.write( sTarget ); - } + const Bu::String &sPath ) +{ + int32_t iParent = -1; + int32_t iNode; + try + { + iNode = lookupInode( sPath, iParent ); + throw Bu::MyriadFsException("Path already exists."); + } + catch( Bu::MyriadFsException &e ) + { + if( iParent < 0 ) + throw; + + // This means that an intermediate path component couldn't be found + if( e.getErrorCode() == 1 ) + throw; + + // The file wasn't found, but the path leading up to it was. + // first, figure out the final path element... + Bu::String sName = filePart( sPath ); + sio << "End filename: " << sName << sio.nl; + sio << "Parent inode: " << iParent << sio.nl; + iNode = create( iParent, sName, 0777|typeSymLink, 0 ); + sio << "New iNode: " << iNode << sio.nl; + MyriadStream ms = openByInode( iNode ); + ms.write( sTarget ); + } } void Bu::MyriadFs::mkHardLink( const Bu::String &sTarget, - const Bu::String &sPath ) -{ - int32_t iParent = -1; - int32_t iNode; - - iNode = lookupInode( sTarget, iParent ); - - try - { - lookupInode( sPath, iParent ); - throw Bu::MyriadFsException("Path already exists."); - } - catch( Bu::MyriadFsException &e ) - { - if( iParent < 0 ) - throw; - - // This means that an intermediate path component couldn't be found - if( e.getErrorCode() == 1 ) - throw; - - // The file wasn't found, but the path leading up to it was. - // first, figure out the final path element... - Bu::String sName = filePart( sPath ); - sio << "End filename: " << sName << sio.nl; - sio << "Parent inode: " << iParent << sio.nl; - addToDir( iParent, iNode, sName ); - MyriadStream is = mStore.openStream( 2 ); - RawStat rs; - readInode( iNode, rs, is ); - rs.iLinks++; - writeInode( rs, is ); - } + const Bu::String &sPath ) +{ + int32_t iParent = -1; + int32_t iNode; + + iNode = lookupInode( sTarget, iParent ); + + try + { + lookupInode( sPath, iParent ); + throw Bu::MyriadFsException("Path already exists."); + } + catch( Bu::MyriadFsException &e ) + { + if( iParent < 0 ) + throw; + + // This means that an intermediate path component couldn't be found + if( e.getErrorCode() == 1 ) + throw; + + // The file wasn't found, but the path leading up to it was. + // first, figure out the final path element... + Bu::String sName = filePart( sPath ); + sio << "End filename: " << sName << sio.nl; + sio << "Parent inode: " << iParent << sio.nl; + addToDir( iParent, iNode, sName ); + MyriadStream is = mStore.openStream( 2 ); + RawStat rs; + readInode( iNode, rs, is ); + rs.iLinks++; + writeInode( rs, is ); + } } Bu::String Bu::MyriadFs::readSymLink( const Bu::String &sPath ) { - int32_t iParent = -1; - int32_t iNode; - iNode = lookupInode( sPath, iParent ); - MyriadStream ms = openByInode( iNode ); - Bu::String sRet; - sRet.setSize( ms.getSize() ); - ms.read( sRet.getStr(), ms.getSize() ); - return sRet; + int32_t iParent = -1; + int32_t iNode; + iNode = lookupInode( sPath, iParent ); + MyriadStream ms = openByInode( iNode ); + Bu::String sRet; + sRet.setSize( ms.getSize() ); + ms.read( sRet.getStr(), ms.getSize() ); + return sRet; } Bu::MyriadFs::Dir Bu::MyriadFs::readDir( const Bu::String &sPath ) { - int32_t iParent = -1; - int32_t iNode = lookupInode( sPath, iParent ); - return readDir( iNode ); + int32_t iParent = -1; + int32_t iNode = lookupInode( sPath, iParent ); + return readDir( iNode ); } void Bu::MyriadFs::setTimes( const Bu::String &sPath, int64_t iATime, - int64_t iMTime ) + int64_t iMTime ) { - int32_t iParent = -1; - int32_t iNode; + int32_t iParent = -1; + int32_t iNode; - iNode = lookupInode( sPath, iParent ); - - setTimes( iNode, iATime, iMTime ); + iNode = lookupInode( sPath, iParent ); + + setTimes( iNode, iATime, iMTime ); } void Bu::MyriadFs::unlink( const Bu::String &sPath ) { - int32_t iParent = -1; -// int32_t iNode; - - /*iNode =*/ lookupInode( sPath, iParent ); - - Dir lDir = readDir( iParent ); - - Bu::String sName = filePart( sPath ); - - for( Dir::iterator i = lDir.begin(); i; i++ ) - { - if( sName == (*i).sName ) - { - RawStat rs; - readInode( (*i).iNode, rs ); - if( (rs.uPerms&typeMask) == typeDir ) - { - MyriadStream msDir = mStore.openStream( rs.uStreamIndex ); - int32_t iCount; - msDir.read( &iCount, 4 ); - if( iCount > 0 ) - { - throw Bu::MyriadFsException("Directory not empty."); - } - } - if( --rs.iLinks == 0 ) - { - destroyNode( (*i).iNode ); - } - else - { - writeInode( rs ); - } - lDir.erase( i ); - break; - } - } - - Bu::MyriadStream ms = openByInode( iParent ); - int32_t iNumChildren = lDir.getSize(); - ms.write( &iNumChildren, 4 ); - for( Dir::iterator i = lDir.begin(); i; i++ ) - { - ms.write( &(*i).iNode, 4 ); - uint8_t iSize = (*i).sName.getSize(); - ms.write( &iSize, 1 ); - ms.write( (*i).sName.getStr(), iSize ); - } - ms.setSize( ms.tell() ); + int32_t iParent = -1; +// int32_t iNode; + + /*iNode =*/ lookupInode( sPath, iParent ); + + Dir lDir = readDir( iParent ); + + Bu::String sName = filePart( sPath ); + + for( Dir::iterator i = lDir.begin(); i; i++ ) + { + if( sName == (*i).sName ) + { + RawStat rs; + readInode( (*i).iNode, rs ); + if( (rs.uPerms&typeMask) == typeDir ) + { + MyriadStream msDir = mStore.openStream( rs.uStreamIndex ); + int32_t iCount; + msDir.read( &iCount, 4 ); + if( iCount > 0 ) + { + throw Bu::MyriadFsException("Directory not empty."); + } + } + if( --rs.iLinks == 0 ) + { + destroyNode( (*i).iNode ); + } + else + { + writeInode( rs ); + } + lDir.erase( i ); + break; + } + } + + Bu::MyriadStream ms = openByInode( iParent ); + int32_t iNumChildren = lDir.getSize(); + ms.write( &iNumChildren, 4 ); + for( Dir::iterator i = lDir.begin(); i; i++ ) + { + ms.write( &(*i).iNode, 4 ); + uint8_t iSize = (*i).sName.getSize(); + ms.write( &iSize, 1 ); + ms.write( (*i).sName.getStr(), iSize ); + } + ms.setSize( ms.tell() ); } void Bu::MyriadFs::setFileSize( const Bu::String &sPath, int32_t iSize ) { - int32_t iParent = -1; - int32_t iNode; - iNode = lookupInode( sPath, iParent ); - MyriadStream ms = openByInode( iNode ); - ms.setSize( iSize ); + int32_t iParent = -1; + int32_t iNode; + iNode = lookupInode( sPath, iParent ); + MyriadStream ms = openByInode( iNode ); + ms.setSize( iSize ); } void Bu::MyriadFs::rename( const Bu::String &sFrom, const Bu::String &sTo ) { - mkHardLink( sFrom, sTo ); - unlink( sFrom ); + mkHardLink( sFrom, sTo ); + unlink( sFrom ); } dev_t Bu::MyriadFs::devToSys( uint32_t uDev ) { - return (((uDev&0xFFFF0000)>>8)&0xFF00) | ((uDev&0xFF)); + return (((uDev&0xFFFF0000)>>8)&0xFF00) | ((uDev&0xFF)); } uint32_t Bu::MyriadFs::sysToDev( dev_t uDev ) { - return (((uint32_t)uDev&0xFF00)<<8) | ((uint32_t)uDev&0xFF); + return (((uint32_t)uDev&0xFF00)<<8) | ((uint32_t)uDev&0xFF); } int32_t Bu::MyriadFs::lookupInode( const Bu::String &sPath, int32_t &iParent ) { - if( sPath == "/" ) - { - return 0; - } - if( sPath[0] == '/' ) - { - // Absolute lookup - return lookupInode( sPath.begin()+1, 0, iParent ); - } - else - { - // Relative lookup - throw Bu::ExceptionBase( - "Relative lookups in MyriadFs are not working yet."); - } + if( sPath == "/" ) + { + return 0; + } + if( sPath[0] == '/' ) + { + // Absolute lookup + return lookupInode( sPath.begin()+1, 0, iParent ); + } + else + { + // Relative lookup + throw Bu::ExceptionBase( + "Relative lookups in MyriadFs are not working yet."); + } } int32_t Bu::MyriadFs::lookupInode( Bu::String::const_iterator iStart, - int32_t iNode, int32_t &iParent ) -{ - iParent = iNode; - - Bu::String::const_iterator iEnd = iStart.find('/'); - Bu::String sTok( iStart, iEnd ); - -// sio << "Direcotry component: " << sTok << sio.nl; - - Dir lDir = readDir( iNode ); - - for( Dir::iterator i = lDir.begin(); i; i++ ) - { - if( (*i).sName == sTok ) - { - // We found an item - if( !iEnd ) - { - // It's the last one in the requested path, return it - return (*i).iNode; - } - else - { - // Not the last one in our path, double check it's a dir - if( ((*i).uPerms&typeMask) == typeDir ) - { - return lookupInode( iEnd+1, (*i).iNode, iParent ); - } - else - { - iParent = -1; - throw Bu::MyriadFsException( - "Element '%s' in given path is not a directory.", - sTok.getStr() ); - } - } - } - } - - if( iEnd ) - throw Bu::MyriadFsException( 1, "Path not found"); - else - throw Bu::MyriadFsException( 2, "Path not found"); + int32_t iNode, int32_t &iParent ) +{ + iParent = iNode; + + Bu::String::const_iterator iEnd = iStart.find('/'); + Bu::String sTok( iStart, iEnd ); + +// sio << "Direcotry component: " << sTok << sio.nl; + + Dir lDir = readDir( iNode ); + + for( Dir::iterator i = lDir.begin(); i; i++ ) + { + if( (*i).sName == sTok ) + { + // We found an item + if( !iEnd ) + { + // It's the last one in the requested path, return it + return (*i).iNode; + } + else + { + // Not the last one in our path, double check it's a dir + if( ((*i).uPerms&typeMask) == typeDir ) + { + return lookupInode( iEnd+1, (*i).iNode, iParent ); + } + else + { + iParent = -1; + throw Bu::MyriadFsException( + "Element '%s' in given path is not a directory.", + sTok.getStr() ); + } + } + } + } + + if( iEnd ) + throw Bu::MyriadFsException( 1, "Path not found"); + else + throw Bu::MyriadFsException( 2, "Path not found"); } void Bu::MyriadFs::readInode( int32_t iNode, RawStat &rs, MyriadStream &rIs ) { - rIs.setPos( hNodeIndex.get( iNode )*sizeof(RawStat) ); - if( rIs.read( &rs, sizeof(RawStat) ) < (int)sizeof(RawStat) ) - throw Bu::MyriadFsException("Filesystem corruption detected."); - if( rs.iNode != iNode ) - throw Bu::MyriadFsException("Filesystem corruption detected."); + rIs.setPos( hNodeIndex.get( iNode )*sizeof(RawStat) ); + if( rIs.read( &rs, sizeof(RawStat) ) < (int)sizeof(RawStat) ) + throw Bu::MyriadFsException("Filesystem corruption detected."); + if( rs.iNode != iNode ) + throw Bu::MyriadFsException("Filesystem corruption detected."); } void Bu::MyriadFs::readInode( int32_t iNode, RawStat &rs ) { - MyriadStream ms = mStore.openStream( 2 ); - readInode( iNode, rs, ms ); + MyriadStream ms = mStore.openStream( 2 ); + readInode( iNode, rs, ms ); } void Bu::MyriadFs::writeInode( const RawStat &rs, - MyriadStream &rOs ) + MyriadStream &rOs ) { - rOs.setSize( hNodeIndex.getSize()*sizeof(RawStat) ); - rOs.setPos( hNodeIndex.get( rs.iNode )*sizeof(RawStat) ); - if( rOs.write( &rs, sizeof(RawStat) ) < (int)sizeof(RawStat) ) - throw Bu::MyriadFsException("Error writing inode to header stream."); + rOs.setSize( hNodeIndex.getSize()*sizeof(RawStat) ); + rOs.setPos( hNodeIndex.get( rs.iNode )*sizeof(RawStat) ); + if( rOs.write( &rs, sizeof(RawStat) ) < (int)sizeof(RawStat) ) + throw Bu::MyriadFsException("Error writing inode to header stream."); } void Bu::MyriadFs::writeInode( const RawStat &rs ) { - MyriadStream ms = mStore.openStream( 2 ); - writeInode( rs, ms ); + MyriadStream ms = mStore.openStream( 2 ); + writeInode( rs, ms ); } Bu::MyriadFs::Dir Bu::MyriadFs::readDir( int32_t iNode ) { - Bu::MyriadStream ms = openByInode( iNode ); - int32_t iNumChildren = 0; - ms.read( &iNumChildren, 4 ); - - Bu::MyriadStream is = mStore.openStream( 2 ); - Dir lDir; -// sio << "Reading dir, " << iNumChildren << " entries:" << sio.nl; - for( int32_t j = 0; j < iNumChildren; j++ ) - { - int32_t iChildNode; - ms.read( &iChildNode, 4 ); - Stat s; - stat( iChildNode, s, is ); - uint8_t uLen; - ms.read( &uLen, 1 ); - s.sName.setSize( uLen ); - ms.read( s.sName.getStr(), uLen ); - lDir.append( s ); - -// sio << " " << s.sName << sio.nl; - } - - return lDir; + Bu::MyriadStream ms = openByInode( iNode ); + int32_t iNumChildren = 0; + ms.read( &iNumChildren, 4 ); + + Bu::MyriadStream is = mStore.openStream( 2 ); + Dir lDir; +// sio << "Reading dir, " << iNumChildren << " entries:" << sio.nl; + for( int32_t j = 0; j < iNumChildren; j++ ) + { + int32_t iChildNode; + ms.read( &iChildNode, 4 ); + Stat s; + stat( iChildNode, s, is ); + uint8_t uLen; + ms.read( &uLen, 1 ); + s.sName.setSize( uLen ); + ms.read( s.sName.getStr(), uLen ); + lDir.append( s ); + +// sio << " " << s.sName << sio.nl; + } + + return lDir; } Bu::MyriadStream Bu::MyriadFs::openByInode( int32_t iNode ) { - RawStat rs; - readInode( iNode, rs ); - switch( (rs.uPerms&typeMask) ) - { - case typeDir: - case typeSymLink: - case typeRegFile: - return mStore.openStream( rs.uStreamIndex ); + RawStat rs; + readInode( iNode, rs ); + switch( (rs.uPerms&typeMask) ) + { + case typeDir: + case typeSymLink: + case typeRegFile: + return mStore.openStream( rs.uStreamIndex ); - default: - throw Bu::MyriadFsException( - "inode incorrect type for low-level openByInode."); - } + default: + throw Bu::MyriadFsException( + "inode incorrect type for low-level openByInode."); + } } void Bu::MyriadFs::addToDir( int32_t iDir, int32_t iNode, - const Bu::String &sName ) -{ - if( sName.getSize() > 255 ) - { - throw Bu::MyriadFsException("Filename too long, max is 255 bytes."); - } - Bu::MyriadStream ms = openByInode( iDir ); - int32_t iNumChildren = 0; - ms.read( &iNumChildren, 4 ); - iNumChildren++; - ms.setPos( 0 ); - ms.write( &iNumChildren, 4 ); - ms.setPosEnd( 0 ); - ms.write( &iNode, 4 ); - uint8_t uLen = sName.getSize(); - ms.write( &uLen, 1 ); - ms.write( sName.getStr(), uLen ); + const Bu::String &sName ) +{ + if( sName.getSize() > 255 ) + { + throw Bu::MyriadFsException("Filename too long, max is 255 bytes."); + } + Bu::MyriadStream ms = openByInode( iDir ); + int32_t iNumChildren = 0; + ms.read( &iNumChildren, 4 ); + iNumChildren++; + ms.setPos( 0 ); + ms.write( &iNumChildren, 4 ); + ms.setPosEnd( 0 ); + ms.write( &iNode, 4 ); + uint8_t uLen = sName.getSize(); + ms.write( &uLen, 1 ); + ms.write( sName.getStr(), uLen ); } int32_t Bu::MyriadFs::create( int32_t iParent, const Bu::String &sName, - uint16_t uPerms, uint32_t uSpecial ) + uint16_t uPerms, uint32_t uSpecial ) { - int32_t iNode = allocInode( uPerms, uSpecial ); - addToDir( iParent, iNode, sName ); - return iNode; + int32_t iNode = allocInode( uPerms, uSpecial ); + addToDir( iParent, iNode, sName ); + return iNode; } int32_t Bu::MyriadFs::allocInode( uint16_t uPerms, uint32_t uSpecial ) { - int32_t iNode = 0; - for(; iNode < 0xfffffff; iNode++ ) - { - if( !hNodeIndex.has( iNode ) ) - { - hNodeIndex.insert( iNode, hNodeIndex.getSize() ); - RawStat rs; - rs.iNode = iNode; - rs.iUser = iUser; - rs.iGroup = iGroup; - rs.uPerms = uPerms; - rs.iLinks = 1; - switch( (uPerms&typeMask) ) - { - case typeRegFile: - case typeSymLink: - rs.uStreamIndex = mStore.createStream(); - break; - - case typeDir: - rs.uStreamIndex = mStore.createStream(); - sio << "Creating directory node, storage: " - << rs.uStreamIndex << sio.nl; - { - Bu::MyriadStream msDir = mStore.openStream( - rs.uStreamIndex - ); - uint32_t uSize = 0; - msDir.write( &uSize, 4 ); - } - break; - - case typeChrDev: - case typeBlkDev: - rs.uStreamIndex = uSpecial; - break; - - default: - rs.uStreamIndex = 0; - break; - } - rs.iATime = time(NULL); - rs.iMTime = time(NULL); - rs.iCTime = time(NULL); - writeInode( rs ); - - return iNode; - } - } - - throw Bu::MyriadFsException( - "No inode could be allocated. You've run out!"); + int32_t iNode = 0; + for(; iNode < 0xfffffff; iNode++ ) + { + if( !hNodeIndex.has( iNode ) ) + { + hNodeIndex.insert( iNode, hNodeIndex.getSize() ); + RawStat rs; + rs.iNode = iNode; + rs.iUser = iUser; + rs.iGroup = iGroup; + rs.uPerms = uPerms; + rs.iLinks = 1; + switch( (uPerms&typeMask) ) + { + case typeRegFile: + case typeSymLink: + rs.uStreamIndex = mStore.createStream(); + break; + + case typeDir: + rs.uStreamIndex = mStore.createStream(); + sio << "Creating directory node, storage: " + << rs.uStreamIndex << sio.nl; + { + Bu::MyriadStream msDir = mStore.openStream( + rs.uStreamIndex + ); + uint32_t uSize = 0; + msDir.write( &uSize, 4 ); + } + break; + + case typeChrDev: + case typeBlkDev: + rs.uStreamIndex = uSpecial; + break; + + default: + rs.uStreamIndex = 0; + break; + } + rs.iATime = time(NULL); + rs.iMTime = time(NULL); + rs.iCTime = time(NULL); + writeInode( rs ); + + return iNode; + } + } + + throw Bu::MyriadFsException( + "No inode could be allocated. You've run out!"); } void Bu::MyriadFs::stat( int32_t iNode, Stat &rBuf, MyriadStream &rIs ) { - RawStat rs; - readInode( iNode, rs, rIs ); - rBuf.iNode = iNode; - rBuf.iUser = rs.iUser; - rBuf.iGroup = rs.iGroup; - rBuf.uPerms = rs.uPerms; - rBuf.iLinks = rs.iLinks; - rBuf.iATime = rs.iATime; - rBuf.iMTime = rs.iMTime; - rBuf.iCTime = rs.iCTime; - rBuf.uDev = 0; - rBuf.iSize = 0; - switch( (rBuf.uPerms&typeMask) ) - { - case typeRegFile: - case typeSymLink: - rBuf.iSize = mStore.getStreamSize( rs.uStreamIndex ); - break; - - case typeChrDev: - case typeBlkDev: - rBuf.uDev = rs.uStreamIndex; - break; - - default: - rBuf.iSize = 0; - break; - } + RawStat rs; + readInode( iNode, rs, rIs ); + rBuf.iNode = iNode; + rBuf.iUser = rs.iUser; + rBuf.iGroup = rs.iGroup; + rBuf.uPerms = rs.uPerms; + rBuf.iLinks = rs.iLinks; + rBuf.iATime = rs.iATime; + rBuf.iMTime = rs.iMTime; + rBuf.iCTime = rs.iCTime; + rBuf.uDev = 0; + rBuf.iSize = 0; + switch( (rBuf.uPerms&typeMask) ) + { + case typeRegFile: + case typeSymLink: + rBuf.iSize = mStore.getStreamSize( rs.uStreamIndex ); + break; + + case typeChrDev: + case typeBlkDev: + rBuf.uDev = rs.uStreamIndex; + break; + + default: + rBuf.iSize = 0; + break; + } } void Bu::MyriadFs::writeHeader() { - Bu::MyriadStream ms = mStore.openStream( 1 ); - ms.write( Myriad_Fs_MAGIC_CODE, 4 ); - int8_t iVer = 1; - int32_t iNumNodes = hNodeIndex.getSize(); - ms.write( &iVer, 1 ); - ms.write( &iNumNodes, 4 ); // iNumNodes - for( NodeIndex::iterator i = hNodeIndex.begin(); i; i++ ) - { - int32_t iNode = i.getKey(); - int32_t iPosition = i.getValue(); - ms.write( &iNode, 4 ); - ms.write( &iPosition, 4 ); - } + Bu::MyriadStream ms = mStore.openStream( 1 ); + ms.write( Myriad_Fs_MAGIC_CODE, 4 ); + int8_t iVer = 1; + int32_t iNumNodes = hNodeIndex.getSize(); + ms.write( &iVer, 1 ); + ms.write( &iNumNodes, 4 ); // iNumNodes + for( NodeIndex::iterator i = hNodeIndex.begin(); i; i++ ) + { + int32_t iNode = i.getKey(); + int32_t iPosition = i.getValue(); + ms.write( &iNode, 4 ); + ms.write( &iPosition, 4 ); + } - // Truncate the stream afterwards so we don't use up too much space. - ms.setSize( ms.tell() ); + // Truncate the stream afterwards so we don't use up too much space. + ms.setSize( ms.tell() ); } void Bu::MyriadFs::setTimes( int32_t iNode, int64_t iATime, int64_t iMTime ) { - RawStat rs; - Bu::MyriadStream is = mStore.openStream( 2 ); + RawStat rs; + Bu::MyriadStream is = mStore.openStream( 2 ); - readInode( iNode, rs, is ); - rs.iATime = iATime; - rs.iMTime = iMTime; - writeInode( rs, is ); + readInode( iNode, rs, is ); + rs.iATime = iATime; + rs.iMTime = iMTime; + writeInode( rs, is ); } void Bu::MyriadFs::destroyNode( int32_t iNode ) { - if( iNode == 0 ) - throw Bu::MyriadFsException("You cannot destroy the root."); + if( iNode == 0 ) + throw Bu::MyriadFsException("You cannot destroy the root."); - Bu::MyriadStream is = mStore.openStream( 2 ); + Bu::MyriadStream is = mStore.openStream( 2 ); - // This will be overwritten with the last node - uint32_t iPosition = hNodeIndex.get( iNode ); - RawStat rsOld; - readInode( iNode, rsOld, is ); - switch( (rsOld.uPerms&typeMask) ) - { - case typeRegFile: - case typeDir: - case typeSymLink: - mStore.deleteStream( rsOld.uStreamIndex ); - break; - } + // This will be overwritten with the last node + uint32_t iPosition = hNodeIndex.get( iNode ); + RawStat rsOld; + readInode( iNode, rsOld, is ); + switch( (rsOld.uPerms&typeMask) ) + { + case typeRegFile: + case typeDir: + case typeSymLink: + mStore.deleteStream( rsOld.uStreamIndex ); + break; + } - hNodeIndex.erase( iNode ); + hNodeIndex.erase( iNode ); - // Read the last node, can't use the helpers, because we don't know the - // iNode yet. - if( iPosition != hNodeIndex.getSize() ) - { - // If this is the last node, then we don't need to do anything, but - // this case handles what to do if we aren't on the last node - RawStat rs; - is.setPos( (hNodeIndex.getSize())*sizeof(RawStat) ); - is.read( &rs, sizeof(RawStat) ); + // Read the last node, can't use the helpers, because we don't know the + // iNode yet. + if( iPosition != hNodeIndex.getSize() ) + { + // If this is the last node, then we don't need to do anything, but + // this case handles what to do if we aren't on the last node + RawStat rs; + is.setPos( (hNodeIndex.getSize())*sizeof(RawStat) ); + is.read( &rs, sizeof(RawStat) ); - hNodeIndex.get( rs.iNode ) = iPosition; - writeInode( rs, is ); - } + hNodeIndex.get( rs.iNode ) = iPosition; + writeInode( rs, is ); + } - is.setSize( hNodeIndex.getSize() * sizeof(RawStat) ); + is.setSize( hNodeIndex.getSize() * sizeof(RawStat) ); } Bu::String Bu::MyriadFs::filePart( const Bu::String &sPath ) { - Bu::String::const_iterator iStart = sPath.begin(); - if( *iStart == '/' ) - iStart++; - for( Bu::String::const_iterator iEnd = iStart.find('/'); iEnd; - iStart = iEnd+1, iEnd = iStart.find('/') ) { } - return Bu::String( iStart, sPath.end() ); + Bu::String::const_iterator iStart = sPath.begin(); + if( *iStart == '/' ) + iStart++; + for( Bu::String::const_iterator iEnd = iStart.find('/'); iEnd; + iStart = iEnd+1, iEnd = iStart.find('/') ) { } + return Bu::String( iStart, sPath.end() ); } diff --git a/src/unstable/myriadfs.h b/src/unstable/myriadfs.h index 126be7a..dfb051b 100644 --- a/src/unstable/myriadfs.h +++ b/src/unstable/myriadfs.h @@ -14,190 +14,190 @@ namespace Bu { - class Stream; - - subExceptionDecl( MyriadFsException ); - - /** - * A POSIX compliant, node based filesystem built on top of Myriad. - * - * A header is placed into stream 1. - * Header format: - * int32_t iMagicHeader (A7188B39) - * int8_t iVersion (1) - * int32_t iNumNodes - * NodeLookup[iNumNodes] nNode - * - * Node lookup: - * int32_t iInode - * int32_t iPosition - * - * The node headers or inode structures have a base size of 44 bytes. - * The name is stored in the directory format. - * Basic node header format: - * int32_t iNode - * int32_t iUser - * int32_t iGroup - * uint16_t uPerms - * int16_t iLinks - * uint32_t uStreamIndex - * int64_t iATime - * int64_t iMTime - * int64_t iCTime - * - * Some types get special formats for their assosiated data stream, or - * other special considerations, here's a list: - * - * - typeFifo: No stream, uStreamIndex unused (probably) - * - typeChrDev: No stream, uStreamIndex is device hi/lo - * - typeDir: The stream contains a directory contents listing, described - * below - * - typeBlkDev: No stream, uStreamIndex is device hi/lo - * - typeRegFile: The stream is the file data - * - typeSymLink: The stream is the destination of the symlink - * - typeSocket: No steram, uStreamIndex unused (probably) - * - * Directory streams have this simple listing format. They contain a list - * of all child elements, with no particular order at the moment. The . and - * .. entries are not listed, they are implicit: - * int32_t iNumNodes - * NodeTable[iNumNodes] nChildren - * - * NodeTable: - * int32_t iInode - * uint8_t uNameSize - * char[uNameSize] sName - */ - class MyriadFs - { - public: - MyriadFs( Bu::Stream &rStore, int iBlockSize=512 ); - virtual ~MyriadFs(); - - enum - { - permOthX = 0000001, - permOthW = 0000002, - permOthR = 0000004, - permGrpX = 0000010, - permGrpW = 0000020, - permGrpR = 0000040, - permUsrX = 0000100, - permUsrW = 0000200, - permUsrR = 0000400, - permSticky = 0001000, - permSetGid = 0002000, - permSetUid = 0004000, - permMask = 0007777, - typeFifo = 0010000, - typeChrDev = 0020000, - typeDir = 0040000, - typeBlkDev = 0060000, - typeRegFile = 0100000, - typeSymLink = 0120000, - typeSocket = 0140000, - typeMask = 0170000 - }; - - enum - { - Read = 0x01, ///< Open file for reading - Write = 0x02, ///< Open file for writing - Create = 0x04, ///< Create file if it doesn't exist - Truncate = 0x08, ///< Truncate file if it does exist - Append = 0x10, ///< Always append on every write - NonBlock = 0x20, ///< Open file in non-blocking mode - Exclusive = 0x44, ///< Create file, if it exists then fail - - // Helpful mixes - ReadWrite = 0x03, ///< Open for reading and writing - WriteNew = 0x0E ///< Create a file (or truncate) for writing. - /// Same as Write|Create|Truncate - }; - - class Stat - { - public: - int32_t iNode; - int32_t iUser; - int32_t iGroup; - uint16_t uPerms; - int16_t iLinks; - int64_t iATime; - int64_t iMTime; - int64_t iCTime; - int32_t iSize; - uint32_t uDev; - Bu::String sName; - }; - typedef Bu::List Dir; - - void stat( const Bu::String &sPath, Stat &rBuf ); - MyriadStream open( const Bu::String &sPath, int iMode, - uint16_t uPerms=0664 ); - void create( const Bu::String &sPath, uint16_t iPerms ); - void create( const Bu::String &sPath, uint16_t iPerms, - uint16_t iDevHi, uint16_t iDevLo ); - void create( const Bu::String &sPath, uint16_t iPerms, - uint32_t uSpecial ); - void mkDir( const Bu::String &sPath, uint16_t iPerms ); - void mkSymLink( const Bu::String &sTarget, const Bu::String &sPath ); - void mkHardLink( const Bu::String &sTarget, const Bu::String &sPath ); - Bu::String readSymLink( const Bu::String &sPath ); - Dir readDir( const Bu::String &sPath ); - void setTimes( const Bu::String &sPath, int64_t iATime, - int64_t iMTime ); - void unlink( const Bu::String &sPath ); - void setFileSize( const Bu::String &sPath, int32_t iSize ); - void rename( const Bu::String &sFrom, const Bu::String &sTo ); - - static dev_t devToSys( uint32_t uDev ); - static uint32_t sysToDev( dev_t uDev ); - - private: - class RawStat - { - public: - int32_t iNode; - int32_t iUser; - int32_t iGroup; - uint16_t uPerms; - int16_t iLinks; - uint32_t uStreamIndex; - int64_t iATime; - int64_t iMTime; - int64_t iCTime; - }; - typedef Bu::Hash NodeIndex; - - private: - int32_t lookupInode( const Bu::String &sPath, int32_t &iParent ); - int32_t lookupInode( Bu::String::const_iterator iStart, - int32_t iNode, int32_t &iParent ); - void readInode( int32_t iNode, RawStat &rs, MyriadStream &rIs ); - void readInode( int32_t iNode, RawStat &rs ); - void writeInode( const RawStat &rs ); - void writeInode( const RawStat &rs, MyriadStream &rOs ); - Dir readDir( int32_t iNode ); - MyriadStream openByInode( int32_t iNode ); - void addToDir( int32_t iDir, int32_t iNode, const Bu::String &sName ); - int32_t create( int32_t iParent, const Bu::String &sName, - uint16_t uPerms, uint32_t uSpecial ); - int32_t allocInode( uint16_t uPerms, uint32_t uSpecial ); - void stat( int32_t iNode, Stat &rBuf, MyriadStream &rIs ); - void writeHeader(); - void setTimes( int32_t iNode, int64_t iATime, int64_t iMTime ); - void destroyNode( int32_t iNode ); - - Bu::String filePart( const Bu::String &sPath ); - - private: - Bu::Stream &rStore; - Bu::Myriad mStore; - NodeIndex hNodeIndex; - int32_t iUser; - int32_t iGroup; - }; + class Stream; + + subExceptionDecl( MyriadFsException ); + + /** + * A POSIX compliant, node based filesystem built on top of Myriad. + * + * A header is placed into stream 1. + * Header format: + * int32_t iMagicHeader (A7188B39) + * int8_t iVersion (1) + * int32_t iNumNodes + * NodeLookup[iNumNodes] nNode + * + * Node lookup: + * int32_t iInode + * int32_t iPosition + * + * The node headers or inode structures have a base size of 44 bytes. + * The name is stored in the directory format. + * Basic node header format: + * int32_t iNode + * int32_t iUser + * int32_t iGroup + * uint16_t uPerms + * int16_t iLinks + * uint32_t uStreamIndex + * int64_t iATime + * int64_t iMTime + * int64_t iCTime + * + * Some types get special formats for their assosiated data stream, or + * other special considerations, here's a list: + * + * - typeFifo: No stream, uStreamIndex unused (probably) + * - typeChrDev: No stream, uStreamIndex is device hi/lo + * - typeDir: The stream contains a directory contents listing, described + * below + * - typeBlkDev: No stream, uStreamIndex is device hi/lo + * - typeRegFile: The stream is the file data + * - typeSymLink: The stream is the destination of the symlink + * - typeSocket: No steram, uStreamIndex unused (probably) + * + * Directory streams have this simple listing format. They contain a list + * of all child elements, with no particular order at the moment. The . and + * .. entries are not listed, they are implicit: + * int32_t iNumNodes + * NodeTable[iNumNodes] nChildren + * + * NodeTable: + * int32_t iInode + * uint8_t uNameSize + * char[uNameSize] sName + */ + class MyriadFs + { + public: + MyriadFs( Bu::Stream &rStore, int iBlockSize=512 ); + virtual ~MyriadFs(); + + enum + { + permOthX = 0000001, + permOthW = 0000002, + permOthR = 0000004, + permGrpX = 0000010, + permGrpW = 0000020, + permGrpR = 0000040, + permUsrX = 0000100, + permUsrW = 0000200, + permUsrR = 0000400, + permSticky = 0001000, + permSetGid = 0002000, + permSetUid = 0004000, + permMask = 0007777, + typeFifo = 0010000, + typeChrDev = 0020000, + typeDir = 0040000, + typeBlkDev = 0060000, + typeRegFile = 0100000, + typeSymLink = 0120000, + typeSocket = 0140000, + typeMask = 0170000 + }; + + enum + { + Read = 0x01, ///< Open file for reading + Write = 0x02, ///< Open file for writing + Create = 0x04, ///< Create file if it doesn't exist + Truncate = 0x08, ///< Truncate file if it does exist + Append = 0x10, ///< Always append on every write + NonBlock = 0x20, ///< Open file in non-blocking mode + Exclusive = 0x44, ///< Create file, if it exists then fail + + // Helpful mixes + ReadWrite = 0x03, ///< Open for reading and writing + WriteNew = 0x0E ///< Create a file (or truncate) for writing. + /// Same as Write|Create|Truncate + }; + + class Stat + { + public: + int32_t iNode; + int32_t iUser; + int32_t iGroup; + uint16_t uPerms; + int16_t iLinks; + int64_t iATime; + int64_t iMTime; + int64_t iCTime; + int32_t iSize; + uint32_t uDev; + Bu::String sName; + }; + typedef Bu::List Dir; + + void stat( const Bu::String &sPath, Stat &rBuf ); + MyriadStream open( const Bu::String &sPath, int iMode, + uint16_t uPerms=0664 ); + void create( const Bu::String &sPath, uint16_t iPerms ); + void create( const Bu::String &sPath, uint16_t iPerms, + uint16_t iDevHi, uint16_t iDevLo ); + void create( const Bu::String &sPath, uint16_t iPerms, + uint32_t uSpecial ); + void mkDir( const Bu::String &sPath, uint16_t iPerms ); + void mkSymLink( const Bu::String &sTarget, const Bu::String &sPath ); + void mkHardLink( const Bu::String &sTarget, const Bu::String &sPath ); + Bu::String readSymLink( const Bu::String &sPath ); + Dir readDir( const Bu::String &sPath ); + void setTimes( const Bu::String &sPath, int64_t iATime, + int64_t iMTime ); + void unlink( const Bu::String &sPath ); + void setFileSize( const Bu::String &sPath, int32_t iSize ); + void rename( const Bu::String &sFrom, const Bu::String &sTo ); + + static dev_t devToSys( uint32_t uDev ); + static uint32_t sysToDev( dev_t uDev ); + + private: + class RawStat + { + public: + int32_t iNode; + int32_t iUser; + int32_t iGroup; + uint16_t uPerms; + int16_t iLinks; + uint32_t uStreamIndex; + int64_t iATime; + int64_t iMTime; + int64_t iCTime; + }; + typedef Bu::Hash NodeIndex; + + private: + int32_t lookupInode( const Bu::String &sPath, int32_t &iParent ); + int32_t lookupInode( Bu::String::const_iterator iStart, + int32_t iNode, int32_t &iParent ); + void readInode( int32_t iNode, RawStat &rs, MyriadStream &rIs ); + void readInode( int32_t iNode, RawStat &rs ); + void writeInode( const RawStat &rs ); + void writeInode( const RawStat &rs, MyriadStream &rOs ); + Dir readDir( int32_t iNode ); + MyriadStream openByInode( int32_t iNode ); + void addToDir( int32_t iDir, int32_t iNode, const Bu::String &sName ); + int32_t create( int32_t iParent, const Bu::String &sName, + uint16_t uPerms, uint32_t uSpecial ); + int32_t allocInode( uint16_t uPerms, uint32_t uSpecial ); + void stat( int32_t iNode, Stat &rBuf, MyriadStream &rIs ); + void writeHeader(); + void setTimes( int32_t iNode, int64_t iATime, int64_t iMTime ); + void destroyNode( int32_t iNode ); + + Bu::String filePart( const Bu::String &sPath ); + + private: + Bu::Stream &rStore; + Bu::Myriad mStore; + NodeIndex hNodeIndex; + int32_t iUser; + int32_t iGroup; + }; }; #endif diff --git a/src/unstable/newline.cpp b/src/unstable/newline.cpp index c7eb94c..50a4d4e 100644 --- a/src/unstable/newline.cpp +++ b/src/unstable/newline.cpp @@ -8,8 +8,8 @@ #include "bu/newline.h" Bu::NewLine::NewLine( Bu::Stream &rNext ) : - Bu::Filter( rNext ), - bExChar( false ) + Bu::Filter( rNext ), + bExChar( false ) { } @@ -23,46 +23,46 @@ void Bu::NewLine::start() Bu::size Bu::NewLine::stop() { - return 0; + return 0; } Bu::size Bu::NewLine::read( void *pBufV, Bu::size iAmnt ) { - Bu::size iTotal = 0; - Bu::size iOffset = 0; - Bu::size iRead = rNext.read( pBufV, iAmnt ); - char *pBuf = (char *)pBufV; + Bu::size iTotal = 0; + Bu::size iOffset = 0; + Bu::size iRead = rNext.read( pBufV, iAmnt ); + char *pBuf = (char *)pBufV; - for( Bu::size i = 0; i < iRead; i++ ) - { - if( pBuf[i] == '\r' ) - { - pBuf[i+iOffset] = '\n'; - if( pBuf[i+1] == '\n' ) - { - iOffset--; - } - } - else if( pBuf[i] == '\n' ) - { - pBuf[i+iOffset] = '\n'; - if( pBuf[i+1] == '\r' ) - { - iOffset--; - } - } - else if( iOffset ) - { - pBuf[i+iOffset] = pBuf[i]; - } - } + for( Bu::size i = 0; i < iRead; i++ ) + { + if( pBuf[i] == '\r' ) + { + pBuf[i+iOffset] = '\n'; + if( pBuf[i+1] == '\n' ) + { + iOffset--; + } + } + else if( pBuf[i] == '\n' ) + { + pBuf[i+iOffset] = '\n'; + if( pBuf[i+1] == '\r' ) + { + iOffset--; + } + } + else if( iOffset ) + { + pBuf[i+iOffset] = pBuf[i]; + } + } - iTotal += iRead + iOffset; - return iTotal; + iTotal += iRead + iOffset; + return iTotal; } Bu::size Bu::NewLine::write( const void *, Bu::size ) { - return 0; + return 0; } diff --git a/src/unstable/newline.h b/src/unstable/newline.h index 417f8cc..1597dc6 100644 --- a/src/unstable/newline.h +++ b/src/unstable/newline.h @@ -12,30 +12,30 @@ namespace Bu { - /** - * Converts new-line characters from any standard convention into linefeeds - * (\\n) on reading, and converts them to either your OS's standard or a - * specified standard, depending on how you construct the class. - * - * If you're reading in a text file, then this filter is practically - * required. - */ - class NewLine : public Bu::Filter - { - public: - NewLine( Bu::Stream &rNext ); - virtual ~NewLine(); + /** + * Converts new-line characters from any standard convention into linefeeds + * (\\n) on reading, and converts them to either your OS's standard or a + * specified standard, depending on how you construct the class. + * + * If you're reading in a text file, then this filter is practically + * required. + */ + class NewLine : public Bu::Filter + { + public: + NewLine( Bu::Stream &rNext ); + virtual ~NewLine(); - virtual void start(); - virtual Bu::size stop(); + virtual void start(); + virtual Bu::size stop(); - virtual Bu::size read( void *pBuf, Bu::size iAmnt ); - virtual Bu::size write( const void *pBuf, Bu::size iAmnt ); + virtual Bu::size read( void *pBuf, Bu::size iAmnt ); + virtual Bu::size write( const void *pBuf, Bu::size iAmnt ); - private: - bool bExChar; - char cExChar; - }; + private: + bool bExChar; + char cExChar; + }; }; #endif diff --git a/src/unstable/settings.cpp b/src/unstable/settings.cpp index b812b60..ced8c97 100644 --- a/src/unstable/settings.cpp +++ b/src/unstable/settings.cpp @@ -5,46 +5,46 @@ #include "bu/settingsdriverini.h" Bu::Settings::Settings( const Bu::UtfString &sCompany, - const Bu::UtfString &sProduct, Bu::Settings::Driver eDriver ) : - sCompany( sCompany ), - sProduct( sProduct ), - pDriver( NULL ) + const Bu::UtfString &sProduct, Bu::Settings::Driver eDriver ) : + sCompany( sCompany ), + sProduct( sProduct ), + pDriver( NULL ) { - switch( eDriver ) - { - case DriverNative: + switch( eDriver ) + { + case DriverNative: #if defined( WIN32 ) - pDriver = new Bu::SettingsDriverRegistry(); + pDriver = new Bu::SettingsDriverRegistry(); #else - pDriver = new Bu::SettingsDriverIni(); + pDriver = new Bu::SettingsDriverIni(); #endif - break; + break; - case DriverTaf: - pDriver = new Bu::SettingsDriverTaf(); - break; + case DriverTaf: + pDriver = new Bu::SettingsDriverTaf(); + break; - case DriverIni: - pDriver = new Bu::SettingsDriverIni(); - break; - } + case DriverIni: + pDriver = new Bu::SettingsDriverIni(); + break; + } - pDriver->init( sCompany, sProduct ); + pDriver->init( sCompany, sProduct ); } Bu::Settings::~Settings() { - delete pDriver; + delete pDriver; } void Bu::Settings::set( const Bu::UtfString &sKey, const Bu::UtfString &sValue ) { - pDriver->set( sKey, sValue ); + pDriver->set( sKey, sValue ); } Bu::UtfString Bu::Settings::get( const Bu::UtfString &sKey, - const Bu::UtfString &sValue ) + const Bu::UtfString &sValue ) { - return pDriver->get( sKey, sValue ); + return pDriver->get( sKey, sValue ); } diff --git a/src/unstable/settings.h b/src/unstable/settings.h index c1d0e1c..80d3049 100644 --- a/src/unstable/settings.h +++ b/src/unstable/settings.h @@ -5,31 +5,31 @@ namespace Bu { - /** - * Simple access to configuration data. Provides a consistant, cross - * platform interface to configuration data using native storage. - */ - class Settings - { - public: - enum Driver - { - DriverNative, - DriverTaf, - DriverIni - }; - Settings( const Bu::UtfString &sCompany, const Bu::UtfString &sProduct, - Driver driver=DriverNative ); - virtual ~Settings(); + /** + * Simple access to configuration data. Provides a consistant, cross + * platform interface to configuration data using native storage. + */ + class Settings + { + public: + enum Driver + { + DriverNative, + DriverTaf, + DriverIni + }; + Settings( const Bu::UtfString &sCompany, const Bu::UtfString &sProduct, + Driver driver=DriverNative ); + virtual ~Settings(); - void set( const Bu::UtfString &sKey, const Bu::UtfString &sValue ); - Bu::UtfString get( const Bu::UtfString &sKey, const Bu::UtfString &sValue=Bu::UtfString() ); + void set( const Bu::UtfString &sKey, const Bu::UtfString &sValue ); + Bu::UtfString get( const Bu::UtfString &sKey, const Bu::UtfString &sValue=Bu::UtfString() ); - private: - Bu::UtfString sCompany; - Bu::UtfString sProduct; - class SettingsDriver *pDriver; - }; + private: + Bu::UtfString sCompany; + Bu::UtfString sProduct; + class SettingsDriver *pDriver; + }; }; #endif diff --git a/src/unstable/settingsdriver.h b/src/unstable/settingsdriver.h index 47b7d9d..4dfe09c 100644 --- a/src/unstable/settingsdriver.h +++ b/src/unstable/settingsdriver.h @@ -5,24 +5,24 @@ namespace Bu { - class Settings; + class Settings; - /** - * Base class for i/o interfaces for Bu::Settings. By subclassing this you - * can provide custom storage for application settings. - */ - class SettingsDriver - { - friend class Bu::Settings; - public: - SettingsDriver(); - virtual ~SettingsDriver(); + /** + * Base class for i/o interfaces for Bu::Settings. By subclassing this you + * can provide custom storage for application settings. + */ + class SettingsDriver + { + friend class Bu::Settings; + public: + SettingsDriver(); + virtual ~SettingsDriver(); - protected: - virtual void init( const Bu::UtfString &sCompany, const Bu::UtfString &sProduct )=0; - virtual void set( const Bu::UtfString &sKey, const Bu::UtfString &sValue )=0; - virtual Bu::UtfString get( const Bu::UtfString &sKey, const Bu::UtfString &sValue )=0; - }; + protected: + virtual void init( const Bu::UtfString &sCompany, const Bu::UtfString &sProduct )=0; + virtual void set( const Bu::UtfString &sKey, const Bu::UtfString &sValue )=0; + virtual Bu::UtfString get( const Bu::UtfString &sKey, const Bu::UtfString &sValue )=0; + }; }; #endif diff --git a/src/unstable/settingsdriverini.cpp b/src/unstable/settingsdriverini.cpp index 90debcb..31bc146 100644 --- a/src/unstable/settingsdriverini.cpp +++ b/src/unstable/settingsdriverini.cpp @@ -15,146 +15,146 @@ Bu::SettingsDriverIni::SettingsDriverIni() Bu::SettingsDriverIni::~SettingsDriverIni() { - Bu::File fOut( sPath, Bu::File::WriteNew ); - Bu::Buffer bOut( fOut ); - Bu::Formatter f( bOut ); - - for( GroupHash::iterator i = hGroup.begin(); i; i++ ) - { - f << "[" << i.getKey().get() << "]" << f.nl; - for( StrHash::iterator k = (*i).begin(); k; k++ ) - { - f << k.getKey().get() << " = " << k.getValue().get() << f.nl; - } - f << f.nl; - } + Bu::File fOut( sPath, Bu::File::WriteNew ); + Bu::Buffer bOut( fOut ); + Bu::Formatter f( bOut ); + + for( GroupHash::iterator i = hGroup.begin(); i; i++ ) + { + f << "[" << i.getKey().get() << "]" << f.nl; + for( StrHash::iterator k = (*i).begin(); k; k++ ) + { + f << k.getKey().get() << " = " << k.getValue().get() << f.nl; + } + f << f.nl; + } } void Bu::SettingsDriverIni::init( const Bu::UtfString &sCompany, - const Bu::UtfString &sProduct ) + const Bu::UtfString &sProduct ) { - Bu::UtfString us( getenv("HOME") ); - us += "/.config/"; - us += sCompany; - us += "/"; - us += sProduct; - sPath = us.get(); - try - { - Bu::File fIn( sPath, Bu::File::Read|Bu::File::Create ); - Bu::Buffer bIn( fIn ); - StrHash hKeys; - Bu::String sGroup; - bool bStart = true; - while( !bIn.isEos() ) - { - Bu::String sIn = bIn.readLine(); - if( sIn.isEmpty() ) - continue; - if( sIn[0] == '[' ) - { - if( bStart != true ) - { - hGroup.insert( sGroup, hKeys ); - hKeys.clear(); - } - sGroup = Bu::String( sIn.begin()+1, sIn.find(']') ); - bStart = false; - } - else - { - Bu::String::iterator i = sIn.find('='); - if( !i ) - continue; - - hKeys.insert( Bu::String( sIn.begin(), i ).trimWhitespace(), - Bu::String( i+1, sIn.end() ).trimWhitespace() ); - } - } - hGroup.insert( sGroup, hKeys ); - } - catch(...) - { - } + Bu::UtfString us( getenv("HOME") ); + us += "/.config/"; + us += sCompany; + us += "/"; + us += sProduct; + sPath = us.get(); + try + { + Bu::File fIn( sPath, Bu::File::Read|Bu::File::Create ); + Bu::Buffer bIn( fIn ); + StrHash hKeys; + Bu::String sGroup; + bool bStart = true; + while( !bIn.isEos() ) + { + Bu::String sIn = bIn.readLine(); + if( sIn.isEmpty() ) + continue; + if( sIn[0] == '[' ) + { + if( bStart != true ) + { + hGroup.insert( sGroup, hKeys ); + hKeys.clear(); + } + sGroup = Bu::String( sIn.begin()+1, sIn.find(']') ); + bStart = false; + } + else + { + Bu::String::iterator i = sIn.find('='); + if( !i ) + continue; + + hKeys.insert( Bu::String( sIn.begin(), i ).trimWhitespace(), + Bu::String( i+1, sIn.end() ).trimWhitespace() ); + } + } + hGroup.insert( sGroup, hKeys ); + } + catch(...) + { + } } void Bu::SettingsDriverIni::set( const Bu::UtfString &sKey, const Bu::UtfString &sValue ) { - Bu::String suKey = sKey.get(); - Bu::String::iterator i = suKey.find('/'); - Bu::UtfString sGrp; - Bu::UtfString sId; - if( !i ) - { - sGrp = ""; - sId = sKey; - } - else - { - Bu::String::iterator in; - for(;;) - { - in = i; - i = (in + 1).find('/'); - if( !i ) - break; - } - - sGrp.set( Bu::String( suKey.begin(), in ) ); - sId.set( Bu::String( in+1, suKey.end() ) ); - } - -// sio << "Group: " << sGrp.get() << sio.nl -// << "Key: " << sId.get() << sio.nl; - - if( !hGroup.has( sGrp ) ) - { - StrHash hVal; - hVal.insert( sId, sValue ); - hGroup.insert( sGrp, hVal ); - } - else - { - hGroup.get( sGrp ).insert( sId, sValue ); - } + Bu::String suKey = sKey.get(); + Bu::String::iterator i = suKey.find('/'); + Bu::UtfString sGrp; + Bu::UtfString sId; + if( !i ) + { + sGrp = ""; + sId = sKey; + } + else + { + Bu::String::iterator in; + for(;;) + { + in = i; + i = (in + 1).find('/'); + if( !i ) + break; + } + + sGrp.set( Bu::String( suKey.begin(), in ) ); + sId.set( Bu::String( in+1, suKey.end() ) ); + } + +// sio << "Group: " << sGrp.get() << sio.nl +// << "Key: " << sId.get() << sio.nl; + + if( !hGroup.has( sGrp ) ) + { + StrHash hVal; + hVal.insert( sId, sValue ); + hGroup.insert( sGrp, hVal ); + } + else + { + hGroup.get( sGrp ).insert( sId, sValue ); + } } Bu::UtfString Bu::SettingsDriverIni::get( const Bu::UtfString &sKey, const Bu::UtfString &sValue ) { - Bu::String suKey = sKey.get(); - Bu::String::iterator i = suKey.find('/'); - Bu::UtfString sGrp; - Bu::UtfString sId; - if( !i ) - { - sGrp = ""; - sId = sKey; - } - else - { - Bu::String::iterator in; - for(;;) - { - in = i; - i = (in + 1).find('/'); - if( !i ) - break; - } - - sGrp.set( Bu::String( suKey.begin(), in ) ); - sId.set( Bu::String( in+1, suKey.end() ) ); - } - -// sio << "Group: " << sGrp.get() << sio.nl -// << "Key: " << sId.get() << sio.nl; - - try - { - return hGroup.get( sGrp ).get( sId ); - } - catch(...) - { - return sValue; - } + Bu::String suKey = sKey.get(); + Bu::String::iterator i = suKey.find('/'); + Bu::UtfString sGrp; + Bu::UtfString sId; + if( !i ) + { + sGrp = ""; + sId = sKey; + } + else + { + Bu::String::iterator in; + for(;;) + { + in = i; + i = (in + 1).find('/'); + if( !i ) + break; + } + + sGrp.set( Bu::String( suKey.begin(), in ) ); + sId.set( Bu::String( in+1, suKey.end() ) ); + } + +// sio << "Group: " << sGrp.get() << sio.nl +// << "Key: " << sId.get() << sio.nl; + + try + { + return hGroup.get( sGrp ).get( sId ); + } + catch(...) + { + return sValue; + } } diff --git a/src/unstable/settingsdriverini.h b/src/unstable/settingsdriverini.h index c3942d6..bd3097d 100644 --- a/src/unstable/settingsdriverini.h +++ b/src/unstable/settingsdriverini.h @@ -7,23 +7,23 @@ namespace Bu { - class SettingsDriverIni : public SettingsDriver - { - public: - SettingsDriverIni(); - virtual ~SettingsDriverIni(); + class SettingsDriverIni : public SettingsDriver + { + public: + SettingsDriverIni(); + virtual ~SettingsDriverIni(); - protected: - virtual void init( const Bu::UtfString &sCompany, const Bu::UtfString &sProduct ); - virtual void set( const Bu::UtfString &sKey, const Bu::UtfString &sValue ); - virtual Bu::UtfString get( const Bu::UtfString &sKey, const Bu::UtfString &sValue ); + protected: + virtual void init( const Bu::UtfString &sCompany, const Bu::UtfString &sProduct ); + virtual void set( const Bu::UtfString &sKey, const Bu::UtfString &sValue ); + virtual Bu::UtfString get( const Bu::UtfString &sKey, const Bu::UtfString &sValue ); - private: - Bu::String sPath; - typedef Bu::Hash StrHash; - typedef Bu::Hash GroupHash; - GroupHash hGroup; - }; + private: + Bu::String sPath; + typedef Bu::Hash StrHash; + typedef Bu::Hash GroupHash; + GroupHash hGroup; + }; }; #endif diff --git a/src/unstable/settingsdriverregistry.cpp b/src/unstable/settingsdriverregistry.cpp index 89eda7b..983f48e 100644 --- a/src/unstable/settingsdriverregistry.cpp +++ b/src/unstable/settingsdriverregistry.cpp @@ -12,80 +12,80 @@ Bu::SettingsDriverRegistry::SettingsDriverRegistry() Bu::SettingsDriverRegistry::~SettingsDriverRegistry() { - RegCloseKey( *phKey ); + RegCloseKey( *phKey ); } void Bu::SettingsDriverRegistry::init( const Bu::UtfString &sCompany, const Bu::UtfString &sProduct ) { - Bu::UtfString us("Software\\"); - us += sCompany; - us += "\\"; - us += sProduct; - rphKey = new HKEY; - RegCreateKeyExA( HKEY_CURRENT_USER, us.get().getStr(), 0, NULL, 0, KEY_ALL_ACCESS, NULL, phKey, NULL ); + Bu::UtfString us("Software\\"); + us += sCompany; + us += "\\"; + us += sProduct; + rphKey = new HKEY; + RegCreateKeyExA( HKEY_CURRENT_USER, us.get().getStr(), 0, NULL, 0, KEY_ALL_ACCESS, NULL, phKey, NULL ); } void Bu::SettingsDriverRegistry::set( const Bu::UtfString &sKey, const Bu::UtfString &sValue ) { - Bu::StringList lPath = sKey.get().split('/'); - Bu::StringList::iterator i = lPath.begin(); - Bu::StringList::iterator in; + Bu::StringList lPath = sKey.get().split('/'); + Bu::StringList::iterator i = lPath.begin(); + Bu::StringList::iterator in; - Bu::String sPKey; - for(; i;) - { - in = i; - in++; - if( in ) - { - if( !sPKey.isEmpty() ) - sPKey += "\\"; - sPKey += *i; - } - i = in; - } + Bu::String sPKey; + for(; i;) + { + in = i; + in++; + if( in ) + { + if( !sPKey.isEmpty() ) + sPKey += "\\"; + sPKey += *i; + } + i = in; + } - HKEY key; - RegCreateKeyExA( *phKey, sPKey.getStr(), 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL ); - Bu::String sTmp = sValue.get(); - RegSetValueExA( key, lPath.last().getStr(), 0, REG_SZ, (BYTE *)sTmp.getStr(), sTmp.getSize()+1 ); - RegCloseKey( key ); + HKEY key; + RegCreateKeyExA( *phKey, sPKey.getStr(), 0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL ); + Bu::String sTmp = sValue.get(); + RegSetValueExA( key, lPath.last().getStr(), 0, REG_SZ, (BYTE *)sTmp.getStr(), sTmp.getSize()+1 ); + RegCloseKey( key ); } Bu::UtfString Bu::SettingsDriverRegistry::get( const Bu::UtfString &sKey, const Bu::UtfString &sValue ) { - Bu::StringList lPath = sKey.get().split('/'); - Bu::StringList::iterator i = lPath.begin(); - Bu::StringList::iterator in; + Bu::StringList lPath = sKey.get().split('/'); + Bu::StringList::iterator i = lPath.begin(); + Bu::StringList::iterator in; - Bu::String sPKey; - for(; i;) - { - in = i; - in++; - if( in ) - { - if( !sPKey.isEmpty() ) - sPKey += "\\"; - sPKey += *i; - } - i = in; - } + Bu::String sPKey; + for(; i;) + { + in = i; + in++; + if( in ) + { + if( !sPKey.isEmpty() ) + sPKey += "\\"; + sPKey += *i; + } + i = in; + } - HKEY key; - if( RegOpenKeyExA( *phKey, sPKey.getStr(), 0, KEY_ALL_ACCESS, &key ) - != ERROR_SUCCESS ) - return sValue; - char buf[4096]; - DWORD iRet = 4096; - if( RegQueryValueEx( key, lPath.last().getStr(), NULL, NULL, (BYTE *)buf, &iRet ) != ERROR_SUCCESS ) - { - RegCloseKey( key ); - return sValue; - } - RegCloseKey( key ); - - return Bu::UtfString( Bu::String( buf, iRet ) ); + HKEY key; + if( RegOpenKeyExA( *phKey, sPKey.getStr(), 0, KEY_ALL_ACCESS, &key ) + != ERROR_SUCCESS ) + return sValue; + char buf[4096]; + DWORD iRet = 4096; + if( RegQueryValueEx( key, lPath.last().getStr(), NULL, NULL, (BYTE *)buf, &iRet ) != ERROR_SUCCESS ) + { + RegCloseKey( key ); + return sValue; + } + RegCloseKey( key ); + + return Bu::UtfString( Bu::String( buf, iRet ) ); } #endif diff --git a/src/unstable/settingsdriverregistry.h b/src/unstable/settingsdriverregistry.h index 2d718d2..d1a2896 100644 --- a/src/unstable/settingsdriverregistry.h +++ b/src/unstable/settingsdriverregistry.h @@ -7,20 +7,20 @@ namespace Bu { - class SettingsDriverRegistry : public SettingsDriver - { - public: - SettingsDriverRegistry(); - virtual ~SettingsDriverRegistry(); + class SettingsDriverRegistry : public SettingsDriver + { + public: + SettingsDriverRegistry(); + virtual ~SettingsDriverRegistry(); - protected: - virtual void init( const Bu::UtfString &sCompany, const Bu::UtfString &sProduct ); - virtual void set( const Bu::UtfString &sKey, const Bu::UtfString &sValue ); - virtual Bu::UtfString get( const Bu::UtfString &sKey, const Bu::UtfString &sValue ); + protected: + virtual void init( const Bu::UtfString &sCompany, const Bu::UtfString &sProduct ); + virtual void set( const Bu::UtfString &sKey, const Bu::UtfString &sValue ); + virtual Bu::UtfString get( const Bu::UtfString &sKey, const Bu::UtfString &sValue ); - private: - void *rphKey; - }; + private: + void *rphKey; + }; }; #endif diff --git a/src/unstable/settingsdrivertaf.cpp b/src/unstable/settingsdrivertaf.cpp index 8cbcbc5..3fd61b3 100644 --- a/src/unstable/settingsdrivertaf.cpp +++ b/src/unstable/settingsdrivertaf.cpp @@ -6,97 +6,97 @@ #include Bu::SettingsDriverTaf::SettingsDriverTaf() : - pRoot( NULL ) + pRoot( NULL ) { } Bu::SettingsDriverTaf::~SettingsDriverTaf() { - if( !pRoot ) - return; + if( !pRoot ) + return; - Bu::File fOut( sPath, Bu::File::WriteNew ); - Bu::TafWriter tw( fOut ); - tw.writeGroup( pRoot ); - delete pRoot; + Bu::File fOut( sPath, Bu::File::WriteNew ); + Bu::TafWriter tw( fOut ); + tw.writeGroup( pRoot ); + delete pRoot; } void Bu::SettingsDriverTaf::init( const Bu::UtfString &sCompany, - const Bu::UtfString &sProduct ) + const Bu::UtfString &sProduct ) { - Bu::UtfString us( getenv("HOME") ); - us += "/.config/"; - us += sCompany; - us += "/"; - us += sProduct; - sPath = us.get(); - try - { - Bu::File fIn( sPath, Bu::File::Read|Bu::File::Create ); - Bu::TafReader tr( fIn ); - pRoot = tr.readGroup(); - } - catch(...) - { - } - if( !pRoot ) - { - pRoot = new Bu::TafGroup( sProduct.get() ); - } + Bu::UtfString us( getenv("HOME") ); + us += "/.config/"; + us += sCompany; + us += "/"; + us += sProduct; + sPath = us.get(); + try + { + Bu::File fIn( sPath, Bu::File::Read|Bu::File::Create ); + Bu::TafReader tr( fIn ); + pRoot = tr.readGroup(); + } + catch(...) + { + } + if( !pRoot ) + { + pRoot = new Bu::TafGroup( sProduct.get() ); + } } void Bu::SettingsDriverTaf::set( const Bu::UtfString &sKey, - const Bu::UtfString &sValue ) + const Bu::UtfString &sValue ) { - Bu::StringList lPath = sKey.get().split('/'); - Bu::StringList::iterator i = lPath.begin(); - Bu::StringList::iterator in; - Bu::TafGroup *pGrp = pRoot; - for(; i;) - { - in = i; - in++; - if( in ) - { - if( pGrp->hasChild( *i ) ) - pGrp = (Bu::TafGroup *)pGrp->getChild( *i ); - else - pGrp = pGrp->addGroup( *i ); - } - else - { - pGrp->addProperty( *i, sValue.get() ); - } - i = in; - } + Bu::StringList lPath = sKey.get().split('/'); + Bu::StringList::iterator i = lPath.begin(); + Bu::StringList::iterator in; + Bu::TafGroup *pGrp = pRoot; + for(; i;) + { + in = i; + in++; + if( in ) + { + if( pGrp->hasChild( *i ) ) + pGrp = (Bu::TafGroup *)pGrp->getChild( *i ); + else + pGrp = pGrp->addGroup( *i ); + } + else + { + pGrp->addProperty( *i, sValue.get() ); + } + i = in; + } } Bu::UtfString Bu::SettingsDriverTaf::get( const Bu::UtfString &sKey, - const Bu::UtfString &sValue ) + const Bu::UtfString &sValue ) { - Bu::StringList lPath = sKey.get().split('/'); - Bu::StringList::iterator i = lPath.begin(); - Bu::StringList::iterator in; - Bu::TafGroup *pGrp = pRoot; - for(; i;) - { - in = i; - in++; - if( in ) - { - if( pGrp->hasChild( *i ) ) - pGrp = (Bu::TafGroup *)pGrp->getChild( *i ); - else - return sValue; - } - else - { - if( pGrp->hasProperty( *i ) ) - return pGrp->getProperty( *i ); - else - return sValue; - } - i = in; - } + Bu::StringList lPath = sKey.get().split('/'); + Bu::StringList::iterator i = lPath.begin(); + Bu::StringList::iterator in; + Bu::TafGroup *pGrp = pRoot; + for(; i;) + { + in = i; + in++; + if( in ) + { + if( pGrp->hasChild( *i ) ) + pGrp = (Bu::TafGroup *)pGrp->getChild( *i ); + else + return sValue; + } + else + { + if( pGrp->hasProperty( *i ) ) + return pGrp->getProperty( *i ); + else + return sValue; + } + i = in; + } } diff --git a/src/unstable/settingsdrivertaf.h b/src/unstable/settingsdrivertaf.h index b5f8b07..28b5f5c 100644 --- a/src/unstable/settingsdrivertaf.h +++ b/src/unstable/settingsdrivertaf.h @@ -6,26 +6,26 @@ namespace Bu { - class TafGroup; + class TafGroup; - /** - * The taf driver is flawed until I fix taf editing, I've been meaning to... - */ - class SettingsDriverTaf : public SettingsDriver - { - public: - SettingsDriverTaf(); - virtual ~SettingsDriverTaf(); + /** + * The taf driver is flawed until I fix taf editing, I've been meaning to... + */ + class SettingsDriverTaf : public SettingsDriver + { + public: + SettingsDriverTaf(); + virtual ~SettingsDriverTaf(); - protected: - virtual void init( const Bu::UtfString &sCompany, const Bu::UtfString &sProduct ); - virtual void set( const Bu::UtfString &sKey, const Bu::UtfString &sValue ); - virtual Bu::UtfString get( const Bu::UtfString &sKey, const Bu::UtfString &sValue ); + protected: + virtual void init( const Bu::UtfString &sCompany, const Bu::UtfString &sProduct ); + virtual void set( const Bu::UtfString &sKey, const Bu::UtfString &sValue ); + virtual Bu::UtfString get( const Bu::UtfString &sKey, const Bu::UtfString &sValue ); - private: - Bu::String sPath; - class Bu::TafGroup *pRoot; - }; + private: + Bu::String sPath; + class Bu::TafGroup *pRoot; + }; }; #endif diff --git a/src/unstable/udpsocket.cpp b/src/unstable/udpsocket.cpp index f554165..141c2cf 100644 --- a/src/unstable/udpsocket.cpp +++ b/src/unstable/udpsocket.cpp @@ -24,135 +24,135 @@ namespace Bu { subExceptionDef( UdpSocketException ) } #define saTarget ( *((struct sockaddr_in *)paTarget) ) Bu::UdpSocket::UdpSocket( int iUdpSocket ) : - iUdpSocket( iUdpSocket ), - paTarget( NULL ), - bBound( false ) + iUdpSocket( iUdpSocket ), + paTarget( NULL ), + bBound( false ) { } Bu::UdpSocket::UdpSocket( const Bu::String &sAddr, int iPort, int iFlags ) : - iUdpSocket( 0 ), - paTarget( NULL ), - bBound( false ) -{ - iUdpSocket = socket( PF_INET, SOCK_DGRAM, 0 ); - if( iUdpSocket < 0 ) - { - throw UdpSocketException("Couldn't open udp socket: %s", - strerror( errno ) - ); - } - - if( (iFlags&Broadcast) ) - { - int broadcast = 1; - if( (setsockopt( iUdpSocket, SOL_SOCKET, SO_BROADCAST, - &broadcast, sizeof(broadcast) )) == -1) - { - throw UdpSocketException("Couldn't set udp socket to broadcast: %s", - strerror( errno ) - ); - } - } - - paTarget = new struct sockaddr_in; - saTarget.sin_family = AF_INET; - saTarget.sin_port = htons( iPort ); - saTarget.sin_addr.s_addr = inet_addr( sAddr.getStr() ); // INADDR_ANY; - memset( saTarget.sin_zero, '\0', sizeof(saTarget.sin_zero) ); - - if( (iFlags&Read) ) - { - if( bind( iUdpSocket, (struct sockaddr*)paTarget, sizeof(struct sockaddr_in) ) - == -1 ) - { - throw UdpSocketException("Couldn't bind port to udp socket: %s", - strerror( errno ) - ); - } - bBound = true; - } + iUdpSocket( 0 ), + paTarget( NULL ), + bBound( false ) +{ + iUdpSocket = socket( PF_INET, SOCK_DGRAM, 0 ); + if( iUdpSocket < 0 ) + { + throw UdpSocketException("Couldn't open udp socket: %s", + strerror( errno ) + ); + } + + if( (iFlags&Broadcast) ) + { + int broadcast = 1; + if( (setsockopt( iUdpSocket, SOL_SOCKET, SO_BROADCAST, + &broadcast, sizeof(broadcast) )) == -1) + { + throw UdpSocketException("Couldn't set udp socket to broadcast: %s", + strerror( errno ) + ); + } + } + + paTarget = new struct sockaddr_in; + saTarget.sin_family = AF_INET; + saTarget.sin_port = htons( iPort ); + saTarget.sin_addr.s_addr = inet_addr( sAddr.getStr() ); // INADDR_ANY; + memset( saTarget.sin_zero, '\0', sizeof(saTarget.sin_zero) ); + + if( (iFlags&Read) ) + { + if( bind( iUdpSocket, (struct sockaddr*)paTarget, sizeof(struct sockaddr_in) ) + == -1 ) + { + throw UdpSocketException("Couldn't bind port to udp socket: %s", + strerror( errno ) + ); + } + bBound = true; + } } Bu::UdpSocket::~UdpSocket() { - close(); - delete (struct sockaddr_in *)paTarget; - paTarget = NULL; + close(); + delete (struct sockaddr_in *)paTarget; + paTarget = NULL; } Bu::String Bu::UdpSocket::addrToStr( const addr &a ) { - return Bu::String("%1.%2.%3.%4"). - arg( (a&0xff) ). - arg( (a&0xff00)>>8 ). - arg( (a&0xff0000)>>16 ). - arg( (a&0xff000000)>>24 ); + return Bu::String("%1.%2.%3.%4"). + arg( (a&0xff) ). + arg( (a&0xff00)>>8 ). + arg( (a&0xff0000)>>16 ). + arg( (a&0xff000000)>>24 ); } void Bu::UdpSocket::close() { - ::close( iUdpSocket ); + ::close( iUdpSocket ); } Bu::size Bu::UdpSocket::read( void *pBuf, Bu::size nBytes ) { - return recv( iUdpSocket, pBuf, nBytes, 0 ); + return recv( iUdpSocket, pBuf, nBytes, 0 ); } Bu::size Bu::UdpSocket::read( void *pBuf, Bu::size nBytes, - Bu::UdpSocket::addr &aHost, int &iPort ) + Bu::UdpSocket::addr &aHost, int &iPort ) { - sockaddr_in name; - socklen_t size = sizeof(name); - Bu::size ret = recvfrom( iUdpSocket, pBuf, nBytes, 0, - (struct sockaddr *)&name, &size ); - aHost = name.sin_addr.s_addr; - iPort = ntohs(name.sin_port); - return ret; + sockaddr_in name; + socklen_t size = sizeof(name); + Bu::size ret = recvfrom( iUdpSocket, pBuf, nBytes, 0, + (struct sockaddr *)&name, &size ); + aHost = name.sin_addr.s_addr; + iPort = ntohs(name.sin_port); + return ret; } Bu::size Bu::UdpSocket::write( const void *pBuf, Bu::size nBytes ) { - if( bBound ) - { - return sendto( iUdpSocket, pBuf, nBytes, 0, NULL, 0 ); - } - else - { - return sendto( iUdpSocket, pBuf, nBytes, 0, - (struct sockaddr*)paTarget, sizeof(struct sockaddr_in) ); - } + if( bBound ) + { + return sendto( iUdpSocket, pBuf, nBytes, 0, NULL, 0 ); + } + else + { + return sendto( iUdpSocket, pBuf, nBytes, 0, + (struct sockaddr*)paTarget, sizeof(struct sockaddr_in) ); + } } Bu::size Bu::UdpSocket::tell() { - throw Bu::UnsupportedException(); + throw Bu::UnsupportedException(); } void Bu::UdpSocket::seek( Bu::size ) { - throw Bu::UnsupportedException(); + throw Bu::UnsupportedException(); } void Bu::UdpSocket::setPos( Bu::size ) { - throw Bu::UnsupportedException(); + throw Bu::UnsupportedException(); } void Bu::UdpSocket::setPosEnd( Bu::size ) { - throw Bu::UnsupportedException(); + throw Bu::UnsupportedException(); } bool Bu::UdpSocket::isEos() { - return false; + return false; } bool Bu::UdpSocket::isOpen() { - return true; + return true; } void Bu::UdpSocket::flush() @@ -161,79 +161,79 @@ void Bu::UdpSocket::flush() bool Bu::UdpSocket::canRead() { - return bBound; + return bBound; } bool Bu::UdpSocket::canWrite() { - return true; + return true; } bool Bu::UdpSocket::isReadable() { - return bBound; + return bBound; } bool Bu::UdpSocket::isWritable() { - return true; + return true; } bool Bu::UdpSocket::isSeekable() { - return false; + return false; } bool Bu::UdpSocket::isBlocking() { - return true; + return true; } void Bu::UdpSocket::setBlocking( bool bBlocking ) { #ifndef WIN32 - if( bBlocking ) - { - fcntl( iUdpSocket, F_SETFL, fcntl( iUdpSocket, F_GETFL, 0 ) & (~O_NONBLOCK) ); - } - else - { - fcntl( iUdpSocket, F_SETFL, fcntl( iUdpSocket, F_GETFL, 0 ) | O_NONBLOCK ); - } + if( bBlocking ) + { + fcntl( iUdpSocket, F_SETFL, fcntl( iUdpSocket, F_GETFL, 0 ) & (~O_NONBLOCK) ); + } + else + { + fcntl( iUdpSocket, F_SETFL, fcntl( iUdpSocket, F_GETFL, 0 ) | O_NONBLOCK ); + } #else - u_long iMode; - if( bBlocking ) - iMode = 0; - else - iMode = 1; - //------------------------- - // Set the socket I/O mode: In this case FIONBIO - // enables or disables the blocking mode for the - // socket based on the numerical value of iMode. - // If iMode = 0, blocking is enabled; - // If iMode != 0, non-blocking mode is enabled. - bu_ioctlsocket(iUdpSocket, FIONBIO, &iMode); -#endif + u_long iMode; + if( bBlocking ) + iMode = 0; + else + iMode = 1; + //------------------------- + // Set the socket I/O mode: In this case FIONBIO + // enables or disables the blocking mode for the + // socket based on the numerical value of iMode. + // If iMode = 0, blocking is enabled; + // If iMode != 0, non-blocking mode is enabled. + bu_ioctlsocket(iUdpSocket, FIONBIO, &iMode); +#endif } void Bu::UdpSocket::setSize( Bu::size ) { - throw Bu::UnsupportedException(); + throw Bu::UnsupportedException(); } Bu::size Bu::UdpSocket::getSize() const { - throw Bu::UnsupportedException(); + throw Bu::UnsupportedException(); } Bu::size Bu::UdpSocket::getBlockSize() const { - return 1500; + return 1500; } Bu::String Bu::UdpSocket::getLocation() const { - throw Bu::UnsupportedException(); + throw Bu::UnsupportedException(); } #endif diff --git a/src/unstable/udpsocket.h b/src/unstable/udpsocket.h index 8f8630a..569a6fb 100644 --- a/src/unstable/udpsocket.h +++ b/src/unstable/udpsocket.h @@ -15,68 +15,68 @@ namespace Bu { - subExceptionDecl( UdpSocketException ); + subExceptionDecl( UdpSocketException ); - class UdpSocket : public Stream - { - public: - UdpSocket( int iUdpSocket ); - UdpSocket( const Bu::String &sAddr, int iPort, int iFlags ); - virtual ~UdpSocket(); + class UdpSocket : public Stream + { + public: + UdpSocket( int iUdpSocket ); + UdpSocket( const Bu::String &sAddr, int iPort, int iFlags ); + virtual ~UdpSocket(); - typedef uint32_t addr; + typedef uint32_t addr; - static Bu::String addrToStr( const addr &a ); + static Bu::String addrToStr( const addr &a ); - virtual void close(); - virtual Bu::size read( void *pBuf, Bu::size nBytes ); - virtual Bu::size read( void *pBuf, Bu::size nBytes, - addr &sHost, int &iPort ); - virtual Bu::size write( const void *pBuf, Bu::size nBytes ); - using Stream::write; + virtual void close(); + virtual Bu::size read( void *pBuf, Bu::size nBytes ); + virtual Bu::size read( void *pBuf, Bu::size nBytes, + addr &sHost, int &iPort ); + virtual Bu::size write( const void *pBuf, Bu::size nBytes ); + using Stream::write; - virtual Bu::size tell(); - virtual void seek( Bu::size offset ); - virtual void setPos( Bu::size pos ); - virtual void setPosEnd( Bu::size pos ); - virtual bool isEos(); - virtual bool isOpen(); + virtual Bu::size tell(); + virtual void seek( Bu::size offset ); + virtual void setPos( Bu::size pos ); + virtual void setPosEnd( Bu::size pos ); + virtual bool isEos(); + virtual bool isOpen(); - virtual void flush(); + virtual void flush(); - virtual bool canRead(); - virtual bool canWrite(); + virtual bool canRead(); + virtual bool canWrite(); - virtual bool isReadable(); - virtual bool isWritable(); - virtual bool isSeekable(); + virtual bool isReadable(); + virtual bool isWritable(); + virtual bool isSeekable(); - virtual bool isBlocking(); - virtual void setBlocking( bool bBlocking=true ); + virtual bool isBlocking(); + virtual void setBlocking( bool bBlocking=true ); - virtual void setSize( Bu::size iSize ); + virtual void setSize( Bu::size iSize ); - enum { - // Flags - Read = 0x01, ///< Open udp socket for reading - Write = 0x02, ///< Open udp socket for writing - ReadWrite = 0x03, ///< Open for both read and write - Broadcast = 0x04, ///< Open for broadcast - }; + enum { + // Flags + Read = 0x01, ///< Open udp socket for reading + Write = 0x02, ///< Open udp socket for writing + ReadWrite = 0x03, ///< Open for both read and write + Broadcast = 0x04, ///< Open for broadcast + }; - virtual size getSize() const; - virtual size getBlockSize() const; - virtual Bu::String getLocation() const; + virtual size getSize() const; + virtual size getBlockSize() const; + virtual Bu::String getLocation() const; - private: + private: #ifdef WIN32 - unsigned int iUdpSocket; + unsigned int iUdpSocket; #else - int iUdpSocket; + int iUdpSocket; #endif - void *paTarget; - bool bBound; - }; + void *paTarget; + bool bBound; + }; }; #endif diff --git a/src/unstable/url.cpp b/src/unstable/url.cpp index 3c9da4b..75131af 100644 --- a/src/unstable/url.cpp +++ b/src/unstable/url.cpp @@ -13,8 +13,8 @@ #include char Bu::Url::hexcode[] = { - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; Bu::Url::Url() @@ -23,7 +23,7 @@ Bu::Url::Url() Bu::Url::Url( const Bu::String &sUrl ) { - parseUrl( sUrl ); + parseUrl( sUrl ); } Bu::Url::~Url() @@ -32,254 +32,254 @@ Bu::Url::~Url() void Bu::Url::parseUrl( const Bu::String &sUrl ) { - clear(); + clear(); - Bu::String::const_iterator i = sUrl.begin(); - parseProtocol( i ); - parseUserPass( i ); - parseHost( i ); - parsePath( i ); + Bu::String::const_iterator i = sUrl.begin(); + parseProtocol( i ); + parseUserPass( i ); + parseHost( i ); + parsePath( i ); } Bu::String Bu::Url::decode( const Bu::String &sStr ) { - Bu::String sRet; - char buf[3] = {0, 0, 0}; - for( Bu::String::const_iterator i = sStr.begin(); i; i++ ) - { - if( *i == '+' ) - { - sRet += ' '; - } - else if( *i == '%' ) - { - i++; - buf[0] = *i; - i++; - buf[1] = *i; - sRet += (char)((unsigned char)strtol( buf, NULL, 16 )); - } - else - { - sRet += *i; - } - } - return sRet; + Bu::String sRet; + char buf[3] = {0, 0, 0}; + for( Bu::String::const_iterator i = sStr.begin(); i; i++ ) + { + if( *i == '+' ) + { + sRet += ' '; + } + else if( *i == '%' ) + { + i++; + buf[0] = *i; + i++; + buf[1] = *i; + sRet += (char)((unsigned char)strtol( buf, NULL, 16 )); + } + else + { + sRet += *i; + } + } + return sRet; } Bu::String Bu::Url::encode( const Bu::String &sStr ) { - Bu::String sRet; - for( Bu::String::const_iterator i = sStr.begin(); i; i++ ) - { - if( *i == ' ' ) - { - sRet += '+'; - } - else if( - (*i >= 'A' && *i <= 'Z') || - (*i >= 'a' && *i <= 'z') || - (*i >= '0' && *i <= '9') || - (*i == '-' || *i == '_' || *i == '.' || *i == '~') - ) - { - sRet += *i; - } - else - { - unsigned char b = *i; - sRet += '%'; - sRet += hexcode[(b>>4)&0xF]; - sRet += hexcode[b&0xF]; - } - } - return sRet; + Bu::String sRet; + for( Bu::String::const_iterator i = sStr.begin(); i; i++ ) + { + if( *i == ' ' ) + { + sRet += '+'; + } + else if( + (*i >= 'A' && *i <= 'Z') || + (*i >= 'a' && *i <= 'z') || + (*i >= '0' && *i <= '9') || + (*i == '-' || *i == '_' || *i == '.' || *i == '~') + ) + { + sRet += *i; + } + else + { + unsigned char b = *i; + sRet += '%'; + sRet += hexcode[(b>>4)&0xF]; + sRet += hexcode[b&0xF]; + } + } + return sRet; } void Bu::Url::parseProtocol( Bu::String::const_iterator &i ) { - Bu::String::const_iterator s = i.find("://", 3); - if( !s ) - throw Bu::ExceptionBase("No :// in url"); - Bu::String sTmp( i, s ); - setProtocol( sTmp ); - i = s + 3; + Bu::String::const_iterator s = i.find("://", 3); + if( !s ) + throw Bu::ExceptionBase("No :// in url"); + Bu::String sTmp( i, s ); + setProtocol( sTmp ); + i = s + 3; } void Bu::Url::setProtocol( const Bu::String &sNewProto, bool bAutoSetPort ) { - sProtocol = sNewProto; + sProtocol = sNewProto; #ifndef WIN32 - if( bAutoSetPort ) - { - struct servent *se = getservbyname( sProtocol.getStr(), "tcp" ); - if( se ) - { - iPort = ntohs( se->s_port ); - } - } + if( bAutoSetPort ) + { + struct servent *se = getservbyname( sProtocol.getStr(), "tcp" ); + if( se ) + { + iPort = ntohs( se->s_port ); + } + } #endif } void Bu::Url::parseUserPass( Bu::String::const_iterator &i ) { - Bu::String::const_iterator s = i.find('@'); - if( !s ) - return; + Bu::String::const_iterator s = i.find('@'); + if( !s ) + return; - Bu::String::const_iterator p = i.find(':'); - if( p ) - { - sUser.set( i, p ); - sPass.set( p+1, s ); - } - else - { - sUser.set( i, s ); - } + Bu::String::const_iterator p = i.find(':'); + if( p ) + { + sUser.set( i, p ); + sPass.set( p+1, s ); + } + else + { + sUser.set( i, s ); + } - i = s + 1; + i = s + 1; } void Bu::Url::parseHost( Bu::String::const_iterator &i ) { - Bu::String::const_iterator s = i; - for( ; s && *s != '/'; s++ ) - { - if( *s == ':' ) - { - sHost.set( i, s ); - i = s + 1; - s = i.find('/'); - Bu::String sPort( i, s ); - iPort = strtol( sPort.getStr(), NULL, 10 ); - i = s; - return; - } - } - sHost.set( i, s ); - i = s; + Bu::String::const_iterator s = i; + for( ; s && *s != '/'; s++ ) + { + if( *s == ':' ) + { + sHost.set( i, s ); + i = s + 1; + s = i.find('/'); + Bu::String sPort( i, s ); + iPort = strtol( sPort.getStr(), NULL, 10 ); + i = s; + return; + } + } + sHost.set( i, s ); + i = s; } void Bu::Url::parsePath( const Bu::String &sPath ) { - Bu::String::const_iterator i = sPath.begin(); - parsePath( i ); + Bu::String::const_iterator i = sPath.begin(); + parsePath( i ); } void Bu::Url::parsePath( Bu::String::const_iterator &i ) { - if( i ) - { - Bu::String::const_iterator s = i.find('?'); - sPath.set( i, s ); - i = s + 1; - if( s ) - { - parseParams( i ); - } - } - else - { - sPath = "/"; - } + if( i ) + { + Bu::String::const_iterator s = i.find('?'); + sPath.set( i, s ); + i = s + 1; + if( s ) + { + parseParams( i ); + } + } + else + { + sPath = "/"; + } } void Bu::Url::parseParams( const Bu::String &sQuery ) { - Bu::String::const_iterator i = sQuery.begin(); - parseParams( i ); + Bu::String::const_iterator i = sQuery.begin(); + parseParams( i ); } void Bu::Url::parseParams( Bu::String::const_iterator &i ) { - bool bName = true; - Bu::String sName, sValue; - for( Bu::String::const_iterator s = i; s; s++ ) - { - if( bName ) - { - if( *s == '&' ) - { - sName.set( i, s ); - sValue.clear(); - i = s + 1; - addParam( decode( sName ), decode( sValue ) ); - } - else if( *s == '=' ) - { - sName.set( i, s ); - i = s + 1; - bName = false; - } - } - else - { - if( *s == '&' ) - { - sValue.set( i, s ); - i = s + 1; - bName = true; - addParam( decode( sName ), decode( sValue ) ); - } - } - } - if( i ) - { - if( bName ) - { - sName.set( i ); - sValue.clear(); - } - else - { - sValue.set( i ); - } - addParam( decode( sName ), decode( sValue ) ); - } + bool bName = true; + Bu::String sName, sValue; + for( Bu::String::const_iterator s = i; s; s++ ) + { + if( bName ) + { + if( *s == '&' ) + { + sName.set( i, s ); + sValue.clear(); + i = s + 1; + addParam( decode( sName ), decode( sValue ) ); + } + else if( *s == '=' ) + { + sName.set( i, s ); + i = s + 1; + bName = false; + } + } + else + { + if( *s == '&' ) + { + sValue.set( i, s ); + i = s + 1; + bName = true; + addParam( decode( sName ), decode( sValue ) ); + } + } + } + if( i ) + { + if( bName ) + { + sName.set( i ); + sValue.clear(); + } + else + { + sValue.set( i ); + } + addParam( decode( sName ), decode( sValue ) ); + } } void Bu::Url::addParam( const Bu::String &n, const Bu::String &v ) { - lParam.append( Param( n, v ) ); + lParam.append( Param( n, v ) ); } void Bu::Url::clear() { - sProtocol.clear(); - sUser.clear(); - sPass.clear(); - sHost.clear(); - sPath.clear(); - iPort.clear(); + sProtocol.clear(); + sUser.clear(); + sPass.clear(); + sHost.clear(); + sPath.clear(); + iPort.clear(); } Bu::String Bu::Url::getFullPath() const { - Bu::String sBuf = sPath; - if( !lParam.isEmpty() ) - { - for( ParamList::const_iterator i = lParam.begin(); i; i++ ) - { - if( i == lParam.begin() ) - sBuf += "?"; - else - sBuf += "&"; + Bu::String sBuf = sPath; + if( !lParam.isEmpty() ) + { + for( ParamList::const_iterator i = lParam.begin(); i; i++ ) + { + if( i == lParam.begin() ) + sBuf += "?"; + else + sBuf += "&"; - sBuf += encode( (*i).sName ); - if( !(*i).sValue.isEmpty() ) - { - sBuf += "=" + encode( (*i).sValue ); - } - } - } + sBuf += encode( (*i).sName ); + if( !(*i).sValue.isEmpty() ) + { + sBuf += "=" + encode( (*i).sValue ); + } + } + } - return sBuf; + return sBuf; } Bu::String Bu::Url::getUrl() const { - Bu::String sBuf = sProtocol + "://" + sHost + getFullPath(); - return sBuf; + Bu::String sBuf = sProtocol + "://" + sHost + getFullPath(); + return sBuf; } diff --git a/src/unstable/url.h b/src/unstable/url.h index 34a335d..3edf94b 100644 --- a/src/unstable/url.h +++ b/src/unstable/url.h @@ -13,73 +13,73 @@ namespace Bu { - class Url - { - public: - typedef struct Param - { - Param() { } - Param( const Param &r ) : sName( r.sName ), sValue( r.sValue ) { } - Param( const Bu::String &n, const Bu::String &v ) : - sName( n ), sValue( v ) { } - Bu::String sName; - Bu::String sValue; - } Param; - typedef Bu::List ParamList; + class Url + { + public: + typedef struct Param + { + Param() { } + Param( const Param &r ) : sName( r.sName ), sValue( r.sValue ) { } + Param( const Bu::String &n, const Bu::String &v ) : + sName( n ), sValue( v ) { } + Bu::String sName; + Bu::String sValue; + } Param; + typedef Bu::List ParamList; - public: - Url(); - Url( const Bu::String &sUrl ); - virtual ~Url(); + public: + Url(); + Url( const Bu::String &sUrl ); + virtual ~Url(); - void parseUrl( const Bu::String &sUrl ); - void parseParams( const Bu::String &sQuery ); - void parseParams( Bu::String::const_iterator &i ); - void parsePath( const Bu::String &sPath ); - void parsePath( Bu::String::const_iterator &i ); - void clear(); + void parseUrl( const Bu::String &sUrl ); + void parseParams( const Bu::String &sQuery ); + void parseParams( Bu::String::const_iterator &i ); + void parsePath( const Bu::String &sPath ); + void parsePath( Bu::String::const_iterator &i ); + void clear(); - Bu::String getUrl() const; - Bu::String getFullPath() const; + Bu::String getUrl() const; + Bu::String getFullPath() const; - const Bu::String &getProtocol() const { return sProtocol; } - const Bu::String &getUser() const { return sUser; } - const Bu::String &getPass() const { return sPass; } - const Bu::String &getHost() const { return sHost; } - const Bu::String &getPath() const { return sPath; } - int getPort() const { return iPort; } - ParamList::const_iterator getParamBegin() const - { return lParam.begin(); } + const Bu::String &getProtocol() const { return sProtocol; } + const Bu::String &getUser() const { return sUser; } + const Bu::String &getPass() const { return sPass; } + const Bu::String &getHost() const { return sHost; } + const Bu::String &getPath() const { return sPath; } + int getPort() const { return iPort; } + ParamList::const_iterator getParamBegin() const + { return lParam.begin(); } - void setProtocol( const Bu::String &sNewHost, bool bAutoSetPort=true ); - void setUser( const Bu::String &s ) { sUser = s; } - void setPass( const Bu::String &s ) { sPass = s; } - void setHost( const Bu::String &s ) { sHost = s; } - void setPath( const Bu::String &s ) { sPath = s; } - void setPort( int i ) { iPort = i; } - void addParam( const Bu::String &n, const Bu::String &v ); + void setProtocol( const Bu::String &sNewHost, bool bAutoSetPort=true ); + void setUser( const Bu::String &s ) { sUser = s; } + void setPass( const Bu::String &s ) { sPass = s; } + void setHost( const Bu::String &s ) { sHost = s; } + void setPath( const Bu::String &s ) { sPath = s; } + void setPort( int i ) { iPort = i; } + void addParam( const Bu::String &n, const Bu::String &v ); - bool hasPort() const { return iPort.has(); } + bool hasPort() const { return iPort.has(); } - static Bu::String decode( const Bu::String &sStr ); - static Bu::String encode( const Bu::String &sStr ); + static Bu::String decode( const Bu::String &sStr ); + static Bu::String encode( const Bu::String &sStr ); - private: // Parsing code - void parseProtocol( Bu::String::const_iterator &i ); - void parseUserPass( Bu::String::const_iterator &i ); - void parseHost( Bu::String::const_iterator &i ); + private: // Parsing code + void parseProtocol( Bu::String::const_iterator &i ); + void parseUserPass( Bu::String::const_iterator &i ); + void parseHost( Bu::String::const_iterator &i ); - private: - Bu::String sProtocol; - Bu::String sUser; - Bu::String sPass; - Bu::String sHost; - Bu::String sPath; - Bu::Atom iPort; - ParamList lParam; + private: + Bu::String sProtocol; + Bu::String sUser; + Bu::String sPass; + Bu::String sHost; + Bu::String sPath; + Bu::Atom iPort; + ParamList lParam; - static char hexcode[16]; - }; + static char hexcode[16]; + }; }; #endif diff --git a/src/unstable/utfstring.cpp b/src/unstable/utfstring.cpp index 9fe2d02..421d5fb 100644 --- a/src/unstable/utfstring.cpp +++ b/src/unstable/utfstring.cpp @@ -20,12 +20,12 @@ Bu::UtfString::UtfString() Bu::UtfString::UtfString( const Bu::String &sInput, Encoding eEnc ) { - set( sInput, eEnc ); + set( sInput, eEnc ); } Bu::UtfString::UtfString( const char *sInput, Encoding eEnc ) { - set( sInput, eEnc ); + set( sInput, eEnc ); } Bu::UtfString::~UtfString() @@ -34,340 +34,340 @@ Bu::UtfString::~UtfString() Bu::UtfString::iterator Bu::UtfString::begin() { - return Bu::UtfString::iterator( this, 0 ); + return Bu::UtfString::iterator( this, 0 ); } Bu::UtfString::const_iterator Bu::UtfString::begin() const { - return Bu::UtfString::const_iterator( this, 0 ); + return Bu::UtfString::const_iterator( this, 0 ); } void Bu::UtfString::set( const Bu::String &sInput, Encoding eEnc ) { - switch( eEnc ) - { - case Utf8: - setUtf8( sInput ); - break; + switch( eEnc ) + { + case Utf8: + setUtf8( sInput ); + break; - case Utf16: - setUtf16( sInput ); - break; + case Utf16: + setUtf16( sInput ); + break; - case Utf16be: - setUtf16be( sInput ); - break; + case Utf16be: + setUtf16be( sInput ); + break; - case Utf16le: - setUtf16le( sInput ); - break; + case Utf16le: + setUtf16le( sInput ); + break; - case Utf32: - setUtf32( sInput ); - break; + case Utf32: + setUtf32( sInput ); + break; - case Utf32be: - setUtf32be( sInput ); - break; + case Utf32be: + setUtf32be( sInput ); + break; - case Utf32le: - setUtf32le( sInput ); - break; + case Utf32le: + setUtf32le( sInput ); + break; - case Ucs2: - throw Bu::ExceptionBase("Ucs2 not supported yet."); - break; + case Ucs2: + throw Bu::ExceptionBase("Ucs2 not supported yet."); + break; - case Ucs4: - throw Bu::ExceptionBase("Ucs4 not supported yet."); - break; + case Ucs4: + throw Bu::ExceptionBase("Ucs4 not supported yet."); + break; - case GuessEncoding: - throw Bu::ExceptionBase("Guessing mode not supported yet."); - break; - } + case GuessEncoding: + throw Bu::ExceptionBase("Guessing mode not supported yet."); + break; + } } void Bu::UtfString::append( UtfChar ch ) { - if( ch >= 0x10000 ) - { - ch -= 0x10000; - append16( ((ch>>10)&0x3FF)| 0xD800u ); - append16( (ch&0x3FF)| 0xDC00u ); - } - else - { - append16( (uint16_t)(ch) ); - } + if( ch >= 0x10000 ) + { + ch -= 0x10000; + append16( ((ch>>10)&0x3FF)| 0xD800u ); + append16( (ch&0x3FF)| 0xDC00u ); + } + else + { + append16( (uint16_t)(ch) ); + } } void Bu::UtfString::append( const UtfString &rSrc ) { - aData.append( rSrc.aData ); - iRawLen += rSrc.iRawLen; - iCharLen += rSrc.iCharLen; + aData.append( rSrc.aData ); + iRawLen += rSrc.iRawLen; + iCharLen += rSrc.iCharLen; } void Bu::UtfString::setUtf8( const Bu::String &sInput ) { - static uint8_t lmask[8] = { - 0x00, - 0x01, - 0x03, - 0x07, - 0x0f, - 0x1f, - 0x3f, - 0x7f - }; - for( Bu::String::const_iterator i = sInput.begin(); i; i++ ) - { - if( ((int)(uint8_t)*i)&0x80 ) - { - int iBytes = 1; - for(; (((uint8_t)(*i))<= 1; iBytes-- ) - { - i++; - uPt |= ((*i)&lmask[6])<<(6*(iBytes-1)); - } - append( uPt ); - } - else - { - append( (Bu::UtfChar)(*i) ); - } - } + static uint8_t lmask[8] = { + 0x00, + 0x01, + 0x03, + 0x07, + 0x0f, + 0x1f, + 0x3f, + 0x7f + }; + for( Bu::String::const_iterator i = sInput.begin(); i; i++ ) + { + if( ((int)(uint8_t)*i)&0x80 ) + { + int iBytes = 1; + for(; (((uint8_t)(*i))<= 1; iBytes-- ) + { + i++; + uPt |= ((*i)&lmask[6])<<(6*(iBytes-1)); + } + append( uPt ); + } + else + { + append( (Bu::UtfChar)(*i) ); + } + } } void Bu::UtfString::setUtf16( const Bu::String &sInput ) { -// Bu::String::const_iterator i = sInput.begin(); - if( (uint8_t)*sInput.begin() == 0xFF && - (uint8_t)*(sInput.begin()+1) == 0xFE ) - { - setUtf16le( sInput ); - return; - } - setUtf16be( sInput ); +// Bu::String::const_iterator i = sInput.begin(); + if( (uint8_t)*sInput.begin() == 0xFF && + (uint8_t)*(sInput.begin()+1) == 0xFE ) + { + setUtf16le( sInput ); + return; + } + setUtf16be( sInput ); } void Bu::UtfString::setUtf16be( const Bu::String &sInput ) { - Bu::String::const_iterator i = sInput.begin(); - if( (uint8_t)*sInput.begin() == 0xFE && - (uint8_t)*(sInput.begin()+1) == 0xFF ) - - { - i += 2; - sio << "Verified big endian." << sio.nl; - } - else - { - sio << "Assuming big endian." << sio.nl; - } - uint16_t hi, lo; - for( ; i; i++ ) - { - hi = (((uint8_t)*i)<<8) | ((uint8_t)*(++i)); - append16( hi ); - if( (hi&0xD800u) == 0xD800u ) - { - lo = (((uint8_t)*(++i))<<8) | ((uint8_t)*(++i)); - append16( lo ); - } - } + Bu::String::const_iterator i = sInput.begin(); + if( (uint8_t)*sInput.begin() == 0xFE && + (uint8_t)*(sInput.begin()+1) == 0xFF ) + + { + i += 2; + sio << "Verified big endian." << sio.nl; + } + else + { + sio << "Assuming big endian." << sio.nl; + } + uint16_t hi, lo; + for( ; i; i++ ) + { + hi = (((uint8_t)*i)<<8) | ((uint8_t)*(++i)); + append16( hi ); + if( (hi&0xD800u) == 0xD800u ) + { + lo = (((uint8_t)*(++i))<<8) | ((uint8_t)*(++i)); + append16( lo ); + } + } } void Bu::UtfString::setUtf16le( const Bu::String &sInput ) { - Bu::String::const_iterator i = sInput.begin(); - if( (uint8_t)*sInput.begin() == 0xFF && - (uint8_t)*(sInput.begin()+1) == 0xFE ) - { - i += 2; - sio << "Verified little endian." << sio.nl; - } - else - { - sio << "Assuming little endian." << sio.nl; - } - uint16_t hi, lo; - for( ; i; i++ ) - { - hi = (((uint8_t)*i)) | ((uint8_t)*(++i)<<8); - append16( hi ); - if( (hi&0xD800u) == 0xD800u ) - { - lo = (((uint8_t)*(++i))) | ((uint8_t)*(++i)<<8); - append16( lo ); - } - } + Bu::String::const_iterator i = sInput.begin(); + if( (uint8_t)*sInput.begin() == 0xFF && + (uint8_t)*(sInput.begin()+1) == 0xFE ) + { + i += 2; + sio << "Verified little endian." << sio.nl; + } + else + { + sio << "Assuming little endian." << sio.nl; + } + uint16_t hi, lo; + for( ; i; i++ ) + { + hi = (((uint8_t)*i)) | ((uint8_t)*(++i)<<8); + append16( hi ); + if( (hi&0xD800u) == 0xD800u ) + { + lo = (((uint8_t)*(++i))) | ((uint8_t)*(++i)<<8); + append16( lo ); + } + } } void Bu::UtfString::setUtf32( const Bu::String &sInput ) { - Bu::String::const_iterator i = sInput.begin(); - if( (uint8_t)*i == 0x00 && - (uint8_t)*(++i) == 0x00 && - (uint8_t)*(++i) == 0xFF && - (uint8_t)*(++i) == 0xFE ) - { - setUtf32le( sInput ); - return; - } - setUtf32be( sInput ); + Bu::String::const_iterator i = sInput.begin(); + if( (uint8_t)*i == 0x00 && + (uint8_t)*(++i) == 0x00 && + (uint8_t)*(++i) == 0xFF && + (uint8_t)*(++i) == 0xFE ) + { + setUtf32le( sInput ); + return; + } + setUtf32be( sInput ); } void Bu::UtfString::setUtf32be( const Bu::String &sInput ) { - Bu::String::const_iterator i = sInput.begin(); - if( (uint8_t)*i == 0x00 && - (uint8_t)*(++i) == 0x00 && - (uint8_t)*(++i) == 0xFE && - (uint8_t)*(++i) == 0xFF ) - { - i++; - sio << "Verified big endian." << sio.nl; - } - else - { - i = sInput.begin(); - sio << "Assuming big endian." << sio.nl; - } - for( ; i; i++ ) - { - append( (((uint8_t)*i)<<24) | - (((uint8_t)*(++i))<<16) | - (((uint8_t)*(++i))<<8) | - ((uint8_t)*(++i)) - ); - } + Bu::String::const_iterator i = sInput.begin(); + if( (uint8_t)*i == 0x00 && + (uint8_t)*(++i) == 0x00 && + (uint8_t)*(++i) == 0xFE && + (uint8_t)*(++i) == 0xFF ) + { + i++; + sio << "Verified big endian." << sio.nl; + } + else + { + i = sInput.begin(); + sio << "Assuming big endian." << sio.nl; + } + for( ; i; i++ ) + { + append( (((uint8_t)*i)<<24) | + (((uint8_t)*(++i))<<16) | + (((uint8_t)*(++i))<<8) | + ((uint8_t)*(++i)) + ); + } } void Bu::UtfString::setUtf32le( const Bu::String &sInput ) { - Bu::String::const_iterator i = sInput.begin(); - if( (uint8_t)*i == 0x00 && - (uint8_t)*(++i) == 0x00 && - (uint8_t)*(++i) == 0xFF && - (uint8_t)*(++i) == 0xFE ) - { - i++; - sio << "Verified little endian." << sio.nl; - } - else - { - i = sInput.begin(); - sio << "Assuming little endian." << sio.nl; - } - for( ; i; i++ ) - { - append( ((uint8_t)*i) | - (((uint8_t)*(++i))<<8) | - (((uint8_t)*(++i))<<16) | - (((uint8_t)*(++i))<<24) - ); - } + Bu::String::const_iterator i = sInput.begin(); + if( (uint8_t)*i == 0x00 && + (uint8_t)*(++i) == 0x00 && + (uint8_t)*(++i) == 0xFF && + (uint8_t)*(++i) == 0xFE ) + { + i++; + sio << "Verified little endian." << sio.nl; + } + else + { + i = sInput.begin(); + sio << "Assuming little endian." << sio.nl; + } + for( ; i; i++ ) + { + append( ((uint8_t)*i) | + (((uint8_t)*(++i))<<8) | + (((uint8_t)*(++i))<<16) | + (((uint8_t)*(++i))<<24) + ); + } } void Bu::UtfString::write( Bu::Stream &sOut, Encoding eEnc ) const { - switch( eEnc ) - { - case Utf8: - writeUtf8( sOut ); - break; + switch( eEnc ) + { + case Utf8: + writeUtf8( sOut ); + break; - case Utf16: -// writeUtf16( sOut ); -// break; + case Utf16: +// writeUtf16( sOut ); +// break; - case Utf16be: - writeUtf16be( sOut ); - break; + case Utf16be: + writeUtf16be( sOut ); + break; - case Utf16le: - writeUtf16le( sOut ); - break; + case Utf16le: + writeUtf16le( sOut ); + break; - case Utf32: -// writeUtf32( sOut ); -// break; + case Utf32: +// writeUtf32( sOut ); +// break; - case Utf32be: - writeUtf32be( sOut ); - break; + case Utf32be: + writeUtf32be( sOut ); + break; - case Utf32le: - writeUtf32le( sOut ); - break; + case Utf32le: + writeUtf32le( sOut ); + break; - case Ucs2: - throw Bu::ExceptionBase("Ucs2 not supported yet."); - break; + case Ucs2: + throw Bu::ExceptionBase("Ucs2 not supported yet."); + break; - case Ucs4: - throw Bu::ExceptionBase("Ucs4 not supported yet."); - break; + case Ucs4: + throw Bu::ExceptionBase("Ucs4 not supported yet."); + break; - case GuessEncoding: - throw Bu::ExceptionBase( - "GuessEncoding is incompatible with encoding."); - break; + case GuessEncoding: + throw Bu::ExceptionBase( + "GuessEncoding is incompatible with encoding."); + break; - } + } } void Bu::UtfString::writeUtf8( Bu::Stream &sOut ) const { - int iPos = 0; - while( iPos < aData.getSize() ) - { - uint8_t uByte; - Bu::UtfChar chr = nextChar( iPos ); - if( chr >= 0x010000 ) - { - // Four bytes - // 111 111111 111111 111111 - uByte = (chr>>18)|0xF0; - sOut.write( &uByte, 1 ); - uByte = ((chr>>12)&0x3F)|0x80; - sOut.write( &uByte, 1 ); - uByte = ((chr>>6)&0x3F)|0x80; - sOut.write( &uByte, 1 ); - uByte = (chr&0x3F)|0x80; - sOut.write( &uByte, 1 ); - } - else if( chr >= 0x800 ) - { - // Three bytes - // 1111 111111 111111 - uByte = (chr>>12)|0xE0; - sOut.write( &uByte, 1 ); - uByte = ((chr>>6)&0x3F)|0x80; - sOut.write( &uByte, 1 ); - uByte = (chr&0x3F)|0x80; - sOut.write( &uByte, 1 ); - } - else if( chr >= 0x80 ) - { - // Two bytes - // 11111 111111 - uByte = (chr>>6)|0xC0; - sOut.write( &uByte, 1 ); - uByte = (chr&0x3F)|0x80; - sOut.write( &uByte, 1 ); - } - else - { - // One byte - uByte = chr; - sOut.write( &uByte, 1 ); - } - } + int iPos = 0; + while( iPos < aData.getSize() ) + { + uint8_t uByte; + Bu::UtfChar chr = nextChar( iPos ); + if( chr >= 0x010000 ) + { + // Four bytes + // 111 111111 111111 111111 + uByte = (chr>>18)|0xF0; + sOut.write( &uByte, 1 ); + uByte = ((chr>>12)&0x3F)|0x80; + sOut.write( &uByte, 1 ); + uByte = ((chr>>6)&0x3F)|0x80; + sOut.write( &uByte, 1 ); + uByte = (chr&0x3F)|0x80; + sOut.write( &uByte, 1 ); + } + else if( chr >= 0x800 ) + { + // Three bytes + // 1111 111111 111111 + uByte = (chr>>12)|0xE0; + sOut.write( &uByte, 1 ); + uByte = ((chr>>6)&0x3F)|0x80; + sOut.write( &uByte, 1 ); + uByte = (chr&0x3F)|0x80; + sOut.write( &uByte, 1 ); + } + else if( chr >= 0x80 ) + { + // Two bytes + // 11111 111111 + uByte = (chr>>6)|0xC0; + sOut.write( &uByte, 1 ); + uByte = (chr&0x3F)|0x80; + sOut.write( &uByte, 1 ); + } + else + { + // One byte + uByte = chr; + sOut.write( &uByte, 1 ); + } + } } /* void Bu::UtfString::writeUtf16( Bu::Stream &sOut ) @@ -377,228 +377,228 @@ void Bu::UtfString::writeUtf16( Bu::Stream &sOut ) void Bu::UtfString::writeUtf16be( Bu::Stream &sOut ) const { #if BYTE_ORDER == BIG_ENDIAN - uint16_t iTmp = 0xFEFF; // Byte Order Marker - sOut.write( &iTmp, 2 ); - for( Array::const_iterator i = aData.begin(); i; i++ ) - { - iTmp = *i; - sOut.write( &iTmp, 2 ); - } + uint16_t iTmp = 0xFEFF; // Byte Order Marker + sOut.write( &iTmp, 2 ); + for( Array::const_iterator i = aData.begin(); i; i++ ) + { + iTmp = *i; + sOut.write( &iTmp, 2 ); + } #else - uint16_t iTmp = 0xFEFF; // Byte Order Marker - iTmp = (iTmp>>8) | (iTmp<<8); - sOut.write( &iTmp, 2 ); - for( Array::const_iterator i = aData.begin(); i; i++ ) - { - iTmp = *i; - iTmp = (iTmp>>8) | (iTmp<<8); - sOut.write( &iTmp, 2 ); - } + uint16_t iTmp = 0xFEFF; // Byte Order Marker + iTmp = (iTmp>>8) | (iTmp<<8); + sOut.write( &iTmp, 2 ); + for( Array::const_iterator i = aData.begin(); i; i++ ) + { + iTmp = *i; + iTmp = (iTmp>>8) | (iTmp<<8); + sOut.write( &iTmp, 2 ); + } #endif } void Bu::UtfString::writeUtf16le( Bu::Stream &sOut ) const { #if BYTE_ORDER == LITTLE_ENDIAN - uint16_t iTmp = 0xFEFF; // Byte Order Marker - sOut.write( &iTmp, 2 ); - for( Array::const_iterator i = aData.begin(); i; i++ ) - { - iTmp = *i; - sOut.write( &iTmp, 2 ); - } + uint16_t iTmp = 0xFEFF; // Byte Order Marker + sOut.write( &iTmp, 2 ); + for( Array::const_iterator i = aData.begin(); i; i++ ) + { + iTmp = *i; + sOut.write( &iTmp, 2 ); + } #else - uint16_t iTmp = 0xFEFF; // Byte Order Marker - iTmp = (iTmp>>8) | (iTmp<<8); - sOut.write( &iTmp, 2 ); - for( Array::const_iterator i = aData.begin(); i; i++ ) - { - iTmp = *i; - iTmp = (iTmp>>8) | (iTmp<<8); - sOut.write( &iTmp, 2 ); - } + uint16_t iTmp = 0xFEFF; // Byte Order Marker + iTmp = (iTmp>>8) | (iTmp<<8); + sOut.write( &iTmp, 2 ); + for( Array::const_iterator i = aData.begin(); i; i++ ) + { + iTmp = *i; + iTmp = (iTmp>>8) | (iTmp<<8); + sOut.write( &iTmp, 2 ); + } #endif } void Bu::UtfString::writeUtf32be( Bu::Stream &sOut ) const { #if BYTE_ORDER == BIG_ENDIAN - uint32_t iTmp = 0xFEFF; // Byte Order Marker - sOut.write( &iTmp, 4 ); - int i = 0; - while( i < aData.getSize() ) - { - iTmp = nextChar( i ); - sOut.write( &iTmp, 4 ); - } + uint32_t iTmp = 0xFEFF; // Byte Order Marker + sOut.write( &iTmp, 4 ); + int i = 0; + while( i < aData.getSize() ) + { + iTmp = nextChar( i ); + sOut.write( &iTmp, 4 ); + } #else - uint32_t iTmp = 0xFEFF; // Byte Order Marker - iTmp = (iTmp>>24)|(iTmp<<24)|((iTmp&0xff0000)>>8)|((iTmp&0xff00)<<8); - sOut.write( &iTmp, 4 ); - int i = 0; - while( i < aData.getSize() ) - { - iTmp = nextChar( i ); - iTmp = (iTmp>>24)|(iTmp<<24)|((iTmp&0xff0000)>>8)|((iTmp&0xff00)<<8); - sOut.write( &iTmp, 4 ); - } + uint32_t iTmp = 0xFEFF; // Byte Order Marker + iTmp = (iTmp>>24)|(iTmp<<24)|((iTmp&0xff0000)>>8)|((iTmp&0xff00)<<8); + sOut.write( &iTmp, 4 ); + int i = 0; + while( i < aData.getSize() ) + { + iTmp = nextChar( i ); + iTmp = (iTmp>>24)|(iTmp<<24)|((iTmp&0xff0000)>>8)|((iTmp&0xff00)<<8); + sOut.write( &iTmp, 4 ); + } #endif } void Bu::UtfString::writeUtf32le( Bu::Stream &sOut ) const { #if BYTE_ORDER == LITTLE_ENDIAN - uint32_t iTmp = 0xFEFF; // Byte Order Marker - sOut.write( &iTmp, 4 ); - int i = 0; - while( i < aData.getSize() ) - { - iTmp = nextChar( i ); - sOut.write( &iTmp, 4 ); - } + uint32_t iTmp = 0xFEFF; // Byte Order Marker + sOut.write( &iTmp, 4 ); + int i = 0; + while( i < aData.getSize() ) + { + iTmp = nextChar( i ); + sOut.write( &iTmp, 4 ); + } #else - uint32_t iTmp = 0xFEFF; // Byte Order Marker - iTmp = (iTmp>>24)|(iTmp<<24)|((iTmp&0xff0000)>>8)|((iTmp&0xff00)<<8); - sOut.write( &iTmp, 4 ); - int i = 0; - while( i < aData.getSize() ) - { - iTmp = nextChar( i ); - iTmp = (iTmp>>24)|(iTmp<<24)|((iTmp&0xff0000)>>8)|((iTmp&0xff00)<<8); - sOut.write( &iTmp, 4 ); - } + uint32_t iTmp = 0xFEFF; // Byte Order Marker + iTmp = (iTmp>>24)|(iTmp<<24)|((iTmp&0xff0000)>>8)|((iTmp&0xff00)<<8); + sOut.write( &iTmp, 4 ); + int i = 0; + while( i < aData.getSize() ) + { + iTmp = nextChar( i ); + iTmp = (iTmp>>24)|(iTmp<<24)|((iTmp&0xff0000)>>8)|((iTmp&0xff00)<<8); + sOut.write( &iTmp, 4 ); + } #endif } Bu::UtfChar Bu::UtfString::get( int iIndex ) const { - return nextChar( iIndex ); + return nextChar( iIndex ); } Bu::UtfChar Bu::UtfString::nextChar( int &iIndex ) const { - Bu::UtfChar i = aData[iIndex++]; - switch( i&0xFC00 ) - { - case 0xD800: - return (((i&0x3FF)<<10) | ((aData[iIndex++]&0x3FF)))+0x10000; + Bu::UtfChar i = aData[iIndex++]; + switch( i&0xFC00 ) + { + case 0xD800: + return (((i&0x3FF)<<10) | ((aData[iIndex++]&0x3FF)))+0x10000; - case 0xDC00: - return (((aData[iIndex-2]&0x3FF)<<10) | ((i&0x3FF)))+0x10000; + case 0xDC00: + return (((aData[iIndex-2]&0x3FF)<<10) | ((i&0x3FF)))+0x10000; - default: - return i; - } + default: + return i; + } } bool Bu::UtfString::operator==( const Bu::UtfString &rhs ) const { - return aData == rhs.aData; + return aData == rhs.aData; } Bu::UtfString &Bu::UtfString::operator+=( const Bu::UtfString &rhs ) { - append( rhs ); - return *this; + append( rhs ); + return *this; } Bu::UtfString &Bu::UtfString::operator+=( const UtfChar &rhs ) { - append( rhs ); - return *this; + append( rhs ); + return *this; } Bu::String Bu::UtfString::get( Encoding eEnc ) const { - Bu::MemBuf mb; - write( mb, eEnc ); - return mb.getString(); + Bu::MemBuf mb; + write( mb, eEnc ); + return mb.getString(); } void Bu::UtfString::debug() const { - sio << "Raw Utf16: "; - for( int i = 0; i < aData.getSize(); i++ ) - { - if( i > 0 ) - sio << ", "; - sio << "0x" << Fmt::hex() << aData[i]; - } - sio << sio.nl; - sio << "Code Points: "; - for( int i = 0; i < aData.getSize(); i++ ) - { - if( i > 0 ) - sio << ", "; - sio << "0x" << Fmt::hex() << nextChar( i ); - } - sio << sio.nl; + sio << "Raw Utf16: "; + for( int i = 0; i < aData.getSize(); i++ ) + { + if( i > 0 ) + sio << ", "; + sio << "0x" << Fmt::hex() << aData[i]; + } + sio << sio.nl; + sio << "Code Points: "; + for( int i = 0; i < aData.getSize(); i++ ) + { + if( i > 0 ) + sio << ", "; + sio << "0x" << Fmt::hex() << nextChar( i ); + } + sio << sio.nl; } /* void Bu::UtfString::debugUtf8( const Bu::String &sUtf8 ) { - static uint8_t lmask[8] = { - 0x00, - 0x01, - 0x03, - 0x07, - 0x0f, - 0x1f, - 0x3f, - 0x7f - }; - for( Bu::String::const_iterator i = sUtf8.begin(); i; i++ ) - { - if( i != sUtf8.begin() ) - sio << ", "; - if( ((int)(uint8_t)*i)&0x80 ) - { -// sio << "Flag byte: " << Bu::Fmt().radix(2).width(8).fill('0') -// << (int)(uint8_t)*i << sio.nl; - int iBytes = 1; - for(; (((uint8_t)(*i))<= 1; iBytes-- ) - { -// sio << "iBytes = " << iBytes << ", shift = " << (6*(iBytes-1)) -// << sio.nl; -// sio << "next: " << Bu::Fmt().radix(2).width(8).fill('0') -// << (int)(uint8_t)*i << sio.nl -// << "mask: " << Bu::Fmt().radix(2).width(8).fill('0') -// << (int)lmask[6] << sio.nl; - i++; - uPt |= ((*i)&lmask[6])<<(6*(iBytes-1)); - } - sio << uPt; -// sio << " (" << Bu::Fmt( 8, 2 ).fill('0') -// << uPt << ")"; - } - else - { - sio << (int)((uint8_t)*i); - } - } - sio << sio.nl; + static uint8_t lmask[8] = { + 0x00, + 0x01, + 0x03, + 0x07, + 0x0f, + 0x1f, + 0x3f, + 0x7f + }; + for( Bu::String::const_iterator i = sUtf8.begin(); i; i++ ) + { + if( i != sUtf8.begin() ) + sio << ", "; + if( ((int)(uint8_t)*i)&0x80 ) + { +// sio << "Flag byte: " << Bu::Fmt().radix(2).width(8).fill('0') +// << (int)(uint8_t)*i << sio.nl; + int iBytes = 1; + for(; (((uint8_t)(*i))<= 1; iBytes-- ) + { +// sio << "iBytes = " << iBytes << ", shift = " << (6*(iBytes-1)) +// << sio.nl; +// sio << "next: " << Bu::Fmt().radix(2).width(8).fill('0') +// << (int)(uint8_t)*i << sio.nl +// << "mask: " << Bu::Fmt().radix(2).width(8).fill('0') +// << (int)lmask[6] << sio.nl; + i++; + uPt |= ((*i)&lmask[6])<<(6*(iBytes-1)); + } + sio << uPt; +// sio << " (" << Bu::Fmt( 8, 2 ).fill('0') +// << uPt << ")"; + } + else + { + sio << (int)((uint8_t)*i); + } + } + sio << sio.nl; } */ template<> uint32_t Bu::__calcHashCode( const Bu::UtfString &k ) { - uint32_t uCode = 0; + uint32_t uCode = 0; - for( Bu::UtfString::const_iterator i = k.begin(); i; i++ ) - { - uCode = *i + (uCode<<6) + (uCode<<16) - uCode; - } + for( Bu::UtfString::const_iterator i = k.begin(); i; i++ ) + { + uCode = *i + (uCode<<6) + (uCode<<16) - uCode; + } - return uCode; + return uCode; } template<> bool Bu::__cmpHashKeys( - const Bu::UtfString &a, const Bu::UtfString &b ) + const Bu::UtfString &a, const Bu::UtfString &b ) { - return a == b; + return a == b; } diff --git a/src/unstable/utfstring.h b/src/unstable/utfstring.h index 1bd4cce..560faae 100644 --- a/src/unstable/utfstring.h +++ b/src/unstable/utfstring.h @@ -13,247 +13,247 @@ namespace Bu { - class String; - class Stream; - - /** - * UtfChar isn't actually a character, unicode specifies "code points" not - * characters. The main reason for this is that not all code points define - * usable characters. Some control text directionality, some apply - * properties to other code points which are characters. However, most of - * these distinctions are only important when implementing displays that - * comply with the Unicode standard fully. - */ - typedef uint32_t UtfChar; - - /** - * A unicode string. This class represents a string of unicode code points. - * Every character in unicode can be represented with 21 bits, but we don't - * have a datatype that's 24 bits long, so we return all code points as a - * 32 bit unsigned value represented by Bu::UtfChar. However, the UtfString - * class, for efficiency purposes doesn't store 32 bit values internally. - * It represents all code points in the native utf16 encodeng. This means - * that it may be very difficult to quickly determine the length of a - * UtfString in code points. Unlike many Unicode handling systems, this - * one actually works with complete code points. When using this class you - * don't ever have to know about the inner workings of the different - * encoding schemes. All of the data is dealt with as whole code points. - * - * As an aside, this means that when encoding a UtfString to a Utf16 - * encoding that matches your archetecture this operation will be very - * fast since it will effectively be a raw dump of the internal data - * structures. However, it is highly reccomended that you DO NOT use the - * little endian encodings if you can possibly avoid it. They are not - * reccomended by the Unicode Consortium and are mainly supported as a - * means of communicating with other systems that encode their data - * incorrectly. That said, whenever UtfString encodes the contained string - * it always includes a BOM at the begining (the byte order marker) so that - * proper byte order can be easily determined by the program reading the - * data. - * - *@todo Investigate http://www.unicode.org/reports/tr6/ for compression. - */ - class UtfString - { - public: - enum Encoding - { - Utf8, - Utf16, - Utf16be, - Utf16le, - Utf32, - Utf32be, - Utf32le, - Ucs2, - Ucs4, - GuessEncoding - }; - - UtfString(); - UtfString( const Bu::String &sInput, Encoding eEnc=Utf8 ); - UtfString( const char *sInput, Encoding eEnc=Utf8 ); - virtual ~UtfString(); - - class iterator - { - friend class UtfString; - private: - iterator( UtfString *pSrc, int iCodePos ) : - pSrc( pSrc ), iCodePos( iCodePos ) - { - } - - public: - iterator() : - pSrc( NULL ), iCodePos( 0 ) - { - } - - UtfChar operator*() - { - if( !pSrc ) - throw Bu::ExceptionBase("invalid UtfString::iterator dereferenced."); - return pSrc->get( iCodePos ); - } - - iterator operator++() - { - pSrc->nextChar( iCodePos ); - return *this; - } - - iterator operator++( int ) - { - pSrc->nextChar( iCodePos ); - return *this; - } - - operator bool() const - { - return iCodePos < pSrc->aData.getSize(); - } - - private: - UtfString *pSrc; - int iCodePos; - }; - - class const_iterator - { - friend class UtfString; - private: - const_iterator( const UtfString *pSrc, int iCodePos ) : - pSrc( pSrc ), iCodePos( iCodePos ) - { - } - - public: - const_iterator() : - pSrc( NULL ), iCodePos( 0 ) - { - } - - UtfChar operator*() - { - if( !pSrc ) - throw Bu::ExceptionBase("invalid UtfString::iterator dereferenced."); - return pSrc->get( iCodePos ); - } - - const_iterator operator++() - { - pSrc->nextChar( iCodePos ); - return *this; - } - - const_iterator operator++( int ) - { - pSrc->nextChar( iCodePos ); - return *this; - } - - operator bool() const - { - return iCodePos < pSrc->aData.getSize(); - } - - private: - const UtfString *pSrc; - int iCodePos; - }; - - iterator begin(); - const_iterator begin() const; - - /** - * Append a UtfChar (A unicode code point) to the string. This can be - * any valid code point, and is just the value of the code point, no - * encoding necessary. - */ - void append( UtfChar ch ); - - void append( const UtfString &rSrc ); - - /** - * Set the value of the entire string based on the given input and - * encoding. The default encoding is Utf8, which is compatible with - * 7-bit ascii, so it's a great choice for setting UtfStrings from - * string literals in code. - */ - void set( const Bu::String &sInput, Encoding eEnc=Utf8 ); - - /** - * This encodes the UtfString in the given encoding and outputs it to - * the provided stream. all Utf16 and Utf32 encodings will have the - * correct BOM (byte order marker) at the begining. - */ - void write( Bu::Stream &sOut, Encoding eEnc=Utf8 ) const; - - /** - * This encodes the UtfString in the given encoding and returns it as - * a binary Bu::String. Like write, this also includes the proper BOM - * at the begining. - */ - Bu::String get( Encoding eEnc=Utf8 ) const; - - void debug() const; - - /** - * This may or may not stick around, given an index, this returns a - * codepoint, however there isn't necesarilly a 1:1 ratio between - * indexes and code points. - */ - UtfChar get( int iIndex ) const; - - /** - * This is what to use if you want to iterate through a section of the - * UtfString and you want to use a numerical index. In most cases it - * will be much easier to use an iterator, though. Given an index this - * will return the codepoint at that position and increment iIndex an - * appropriate amount for it to point to the next code point. - */ - UtfChar nextChar( int &iIndex ) const; - - bool operator==( const Bu::UtfString &rhs ) const; - UtfString &operator+=( const Bu::UtfString &rhs ); - UtfString &operator+=( const UtfChar &rhs ); - - private: - void append16( uint16_t i ) { aData.append( i ); } - - void setUtf8( const Bu::String &sInput ); - void setUtf16( const Bu::String &sInput ); - void setUtf16be( const Bu::String &sInput ); - void setUtf16le( const Bu::String &sInput ); - void setUtf32( const Bu::String &sInput ); - void setUtf32be( const Bu::String &sInput ); - void setUtf32le( const Bu::String &sInput ); - - void writeUtf8( Bu::Stream &sOut ) const; - void writeUtf16be( Bu::Stream &sOut ) const; - void writeUtf16le( Bu::Stream &sOut ) const; - void writeUtf32be( Bu::Stream &sOut ) const; - void writeUtf32le( Bu::Stream &sOut ) const; - - private: - Bu::Array aData; - int iRawLen; - int iCharLen; - }; - - // - // Hash support - // - template - uint32_t __calcHashCode( const T &k ); - - template - bool __cmpHashKeys( const T &a, const T &b ); - - template<> uint32_t __calcHashCode( const UtfString &k ); - template<> bool __cmpHashKeys( - const UtfString &a, const UtfString &b ); + class String; + class Stream; + + /** + * UtfChar isn't actually a character, unicode specifies "code points" not + * characters. The main reason for this is that not all code points define + * usable characters. Some control text directionality, some apply + * properties to other code points which are characters. However, most of + * these distinctions are only important when implementing displays that + * comply with the Unicode standard fully. + */ + typedef uint32_t UtfChar; + + /** + * A unicode string. This class represents a string of unicode code points. + * Every character in unicode can be represented with 21 bits, but we don't + * have a datatype that's 24 bits long, so we return all code points as a + * 32 bit unsigned value represented by Bu::UtfChar. However, the UtfString + * class, for efficiency purposes doesn't store 32 bit values internally. + * It represents all code points in the native utf16 encodeng. This means + * that it may be very difficult to quickly determine the length of a + * UtfString in code points. Unlike many Unicode handling systems, this + * one actually works with complete code points. When using this class you + * don't ever have to know about the inner workings of the different + * encoding schemes. All of the data is dealt with as whole code points. + * + * As an aside, this means that when encoding a UtfString to a Utf16 + * encoding that matches your archetecture this operation will be very + * fast since it will effectively be a raw dump of the internal data + * structures. However, it is highly reccomended that you DO NOT use the + * little endian encodings if you can possibly avoid it. They are not + * reccomended by the Unicode Consortium and are mainly supported as a + * means of communicating with other systems that encode their data + * incorrectly. That said, whenever UtfString encodes the contained string + * it always includes a BOM at the begining (the byte order marker) so that + * proper byte order can be easily determined by the program reading the + * data. + * + *@todo Investigate http://www.unicode.org/reports/tr6/ for compression. + */ + class UtfString + { + public: + enum Encoding + { + Utf8, + Utf16, + Utf16be, + Utf16le, + Utf32, + Utf32be, + Utf32le, + Ucs2, + Ucs4, + GuessEncoding + }; + + UtfString(); + UtfString( const Bu::String &sInput, Encoding eEnc=Utf8 ); + UtfString( const char *sInput, Encoding eEnc=Utf8 ); + virtual ~UtfString(); + + class iterator + { + friend class UtfString; + private: + iterator( UtfString *pSrc, int iCodePos ) : + pSrc( pSrc ), iCodePos( iCodePos ) + { + } + + public: + iterator() : + pSrc( NULL ), iCodePos( 0 ) + { + } + + UtfChar operator*() + { + if( !pSrc ) + throw Bu::ExceptionBase("invalid UtfString::iterator dereferenced."); + return pSrc->get( iCodePos ); + } + + iterator operator++() + { + pSrc->nextChar( iCodePos ); + return *this; + } + + iterator operator++( int ) + { + pSrc->nextChar( iCodePos ); + return *this; + } + + operator bool() const + { + return iCodePos < pSrc->aData.getSize(); + } + + private: + UtfString *pSrc; + int iCodePos; + }; + + class const_iterator + { + friend class UtfString; + private: + const_iterator( const UtfString *pSrc, int iCodePos ) : + pSrc( pSrc ), iCodePos( iCodePos ) + { + } + + public: + const_iterator() : + pSrc( NULL ), iCodePos( 0 ) + { + } + + UtfChar operator*() + { + if( !pSrc ) + throw Bu::ExceptionBase("invalid UtfString::iterator dereferenced."); + return pSrc->get( iCodePos ); + } + + const_iterator operator++() + { + pSrc->nextChar( iCodePos ); + return *this; + } + + const_iterator operator++( int ) + { + pSrc->nextChar( iCodePos ); + return *this; + } + + operator bool() const + { + return iCodePos < pSrc->aData.getSize(); + } + + private: + const UtfString *pSrc; + int iCodePos; + }; + + iterator begin(); + const_iterator begin() const; + + /** + * Append a UtfChar (A unicode code point) to the string. This can be + * any valid code point, and is just the value of the code point, no + * encoding necessary. + */ + void append( UtfChar ch ); + + void append( const UtfString &rSrc ); + + /** + * Set the value of the entire string based on the given input and + * encoding. The default encoding is Utf8, which is compatible with + * 7-bit ascii, so it's a great choice for setting UtfStrings from + * string literals in code. + */ + void set( const Bu::String &sInput, Encoding eEnc=Utf8 ); + + /** + * This encodes the UtfString in the given encoding and outputs it to + * the provided stream. all Utf16 and Utf32 encodings will have the + * correct BOM (byte order marker) at the begining. + */ + void write( Bu::Stream &sOut, Encoding eEnc=Utf8 ) const; + + /** + * This encodes the UtfString in the given encoding and returns it as + * a binary Bu::String. Like write, this also includes the proper BOM + * at the begining. + */ + Bu::String get( Encoding eEnc=Utf8 ) const; + + void debug() const; + + /** + * This may or may not stick around, given an index, this returns a + * codepoint, however there isn't necesarilly a 1:1 ratio between + * indexes and code points. + */ + UtfChar get( int iIndex ) const; + + /** + * This is what to use if you want to iterate through a section of the + * UtfString and you want to use a numerical index. In most cases it + * will be much easier to use an iterator, though. Given an index this + * will return the codepoint at that position and increment iIndex an + * appropriate amount for it to point to the next code point. + */ + UtfChar nextChar( int &iIndex ) const; + + bool operator==( const Bu::UtfString &rhs ) const; + UtfString &operator+=( const Bu::UtfString &rhs ); + UtfString &operator+=( const UtfChar &rhs ); + + private: + void append16( uint16_t i ) { aData.append( i ); } + + void setUtf8( const Bu::String &sInput ); + void setUtf16( const Bu::String &sInput ); + void setUtf16be( const Bu::String &sInput ); + void setUtf16le( const Bu::String &sInput ); + void setUtf32( const Bu::String &sInput ); + void setUtf32be( const Bu::String &sInput ); + void setUtf32le( const Bu::String &sInput ); + + void writeUtf8( Bu::Stream &sOut ) const; + void writeUtf16be( Bu::Stream &sOut ) const; + void writeUtf16le( Bu::Stream &sOut ) const; + void writeUtf32be( Bu::Stream &sOut ) const; + void writeUtf32le( Bu::Stream &sOut ) const; + + private: + Bu::Array aData; + int iRawLen; + int iCharLen; + }; + + // + // Hash support + // + template + uint32_t __calcHashCode( const T &k ); + + template + bool __cmpHashKeys( const T &a, const T &b ); + + template<> uint32_t __calcHashCode( const UtfString &k ); + template<> bool __cmpHashKeys( + const UtfString &a, const UtfString &b ); }; #endif diff --git a/src/unstable/uuid.cpp b/src/unstable/uuid.cpp index aef8bc0..5400f8f 100644 --- a/src/unstable/uuid.cpp +++ b/src/unstable/uuid.cpp @@ -18,25 +18,25 @@ Bu::Uuid::Uuid() { - clear(); + clear(); } Bu::Uuid::Uuid( const Uuid &src ) { - memcpy( data, src.data, 16 ); + memcpy( data, src.data, 16 ); } Bu::Uuid::Uuid( const Bu::String &sSrc ) { - if( sSrc.getSize() == 16 ) - { - memcpy( data, sSrc.getStr(), 16 ); - } - else if( sSrc.getSize() == 36 ) - { - // Parse it - set( sSrc ); - } + if( sSrc.getSize() == 16 ) + { + memcpy( data, sSrc.getStr(), 16 ); + } + else if( sSrc.getSize() == 36 ) + { + // Parse it + set( sSrc ); + } } Bu::Uuid::~Uuid() @@ -45,130 +45,130 @@ Bu::Uuid::~Uuid() Bu::String Bu::Uuid::toRawString() const { - return Bu::String( (char *)data, 16 ); + return Bu::String( (char *)data, 16 ); } Bu::String Bu::Uuid::toString() const { - Bu::MemBuf mb; - Bu::Formatter f( mb ); + Bu::MemBuf mb; + Bu::Formatter f( mb ); - for( int j = 0; j < 16; j++ ) - { - if( j == 4 || j == 6 || j == 8 || j == 10 ) - f << '-'; - f << Bu::Fmt::hex(2).caps(false) << (unsigned int)data[j]; - } + for( int j = 0; j < 16; j++ ) + { + if( j == 4 || j == 6 || j == 8 || j == 10 ) + f << '-'; + f << Bu::Fmt::hex(2).caps(false) << (unsigned int)data[j]; + } - return mb.getString(); + return mb.getString(); } Bu::String Bu::Uuid::toUrn() const { - return "urn:uuid:" + toString(); + return "urn:uuid:" + toString(); } int Bu::Uuid::getVersion() { - return (data[6]&((8|4|2|1)<<4))>>4; + return (data[6]&((8|4|2|1)<<4))>>4; } #define msb( i ) (1<<(7-i)) void Bu::Uuid::clear() { - data[7] = msb(0); + data[7] = msb(0); } Bu::Uuid Bu::Uuid::generate( Bu::Uuid::Type eType ) { - switch( eType ) - { - case Version1: - case Version2: - case Version3: - case Version4: - case Version5: - default: - case System: + switch( eType ) + { + case Version1: + case Version2: + case Version3: + case Version4: + case Version5: + default: + case System: #if defined(linux) - Bu::File fIn( "/proc/sys/kernel/random/uuid", Bu::File::Read ); - char dat[36]; - fIn.read( dat, 36 ); - Uuid id; - id.set( dat ); - return id; + Bu::File fIn( "/proc/sys/kernel/random/uuid", Bu::File::Read ); + char dat[36]; + fIn.read( dat, 36 ); + Uuid id; + id.set( dat ); + return id; #elif defined(WIN32) - UUID uuid; - UuidCreate( &uuid ); - Uuid id; - id.data[0] = ((unsigned char *)&uuid.Data1)[3]; - id.data[1] = ((unsigned char *)&uuid.Data1)[2]; - id.data[2] = ((unsigned char *)&uuid.Data1)[1]; - id.data[3] = ((unsigned char *)&uuid.Data1)[0]; - id.data[4] = ((unsigned char *)&uuid.Data2)[1]; - id.data[5] = ((unsigned char *)&uuid.Data2)[0]; - id.data[6] = ((unsigned char *)&uuid.Data3)[1]; - id.data[7] = ((unsigned char *)&uuid.Data3)[0]; - memcpy( id.data+8, uuid.Data4, 8 ); - - return id; + UUID uuid; + UuidCreate( &uuid ); + Uuid id; + id.data[0] = ((unsigned char *)&uuid.Data1)[3]; + id.data[1] = ((unsigned char *)&uuid.Data1)[2]; + id.data[2] = ((unsigned char *)&uuid.Data1)[1]; + id.data[3] = ((unsigned char *)&uuid.Data1)[0]; + id.data[4] = ((unsigned char *)&uuid.Data2)[1]; + id.data[5] = ((unsigned char *)&uuid.Data2)[0]; + id.data[6] = ((unsigned char *)&uuid.Data3)[1]; + id.data[7] = ((unsigned char *)&uuid.Data3)[0]; + memcpy( id.data+8, uuid.Data4, 8 ); + + return id; #else # error We should be using one of the other fallbacks, but your platform is not supported yet. Sorry. #endif - } + } } void Bu::Uuid::set( const Bu::String &sSrc ) { - const char *dat = sSrc.getStr(); - int iNibble = 0; - memset( data, 0, 16 ); - for( int j = 0; j < 36; j++ ) - { - if( dat[j] == '-' ) - continue; - unsigned char c = (dat[j]>='0'&&dat[j]<='9')?(dat[j]-'0'):(dat[j]-'a'+10); - data[iNibble/2] |= (iNibble%2==0)?(c<<4):(c); - iNibble++; - } + const char *dat = sSrc.getStr(); + int iNibble = 0; + memset( data, 0, 16 ); + for( int j = 0; j < 36; j++ ) + { + if( dat[j] == '-' ) + continue; + unsigned char c = (dat[j]>='0'&&dat[j]<='9')?(dat[j]-'0'):(dat[j]-'a'+10); + data[iNibble/2] |= (iNibble%2==0)?(c<<4):(c); + iNibble++; + } } bool Bu::Uuid::operator==( const Uuid &rhs ) const { - return memcmp( data, rhs.data, 16 ) == 0; + return memcmp( data, rhs.data, 16 ) == 0; } bool Bu::Uuid::operator!=( const Uuid &rhs ) const { - return !(*this == rhs); + return !(*this == rhs); } Bu::Uuid &Bu::Uuid::operator=( const Uuid &rhs ) { - memcpy( data, rhs.data, 16 ); - return *this; + memcpy( data, rhs.data, 16 ); + return *this; } template<> uint32_t Bu::__calcHashCode( const Bu::Uuid &k ) { - return __calcHashCode( k.toRawString() ); + return __calcHashCode( k.toRawString() ); } template<> bool Bu::__cmpHashKeys( const Bu::Uuid &a, const Bu::Uuid &b ) { - return a == b; + return a == b; } Bu::ArchiveBase &Bu::operator>>( Bu::ArchiveBase &ar, Uuid &u ) { - ar.read( u.data, 16 ); - return ar; + ar.read( u.data, 16 ); + return ar; } Bu::ArchiveBase &Bu::operator<<( Bu::ArchiveBase &ar, const Uuid &u ) { - ar.write( u.data, 16 ); - return ar; + ar.write( u.data, 16 ); + return ar; } diff --git a/src/unstable/uuid.h b/src/unstable/uuid.h index bb3d608..ecc142d 100644 --- a/src/unstable/uuid.h +++ b/src/unstable/uuid.h @@ -13,59 +13,59 @@ namespace Bu { - class Uuid - { - friend Bu::ArchiveBase &operator>>( Bu::ArchiveBase &ar, Uuid &u ); - friend Bu::ArchiveBase &operator<<( Bu::ArchiveBase &ar, const Uuid &u ); - public: - Uuid(); - Uuid( const Uuid &src ); - Uuid( const Bu::String &sSrc ); - virtual ~Uuid(); + class Uuid + { + friend Bu::ArchiveBase &operator>>( Bu::ArchiveBase &ar, Uuid &u ); + friend Bu::ArchiveBase &operator<<( Bu::ArchiveBase &ar, const Uuid &u ); + public: + Uuid(); + Uuid( const Uuid &src ); + Uuid( const Bu::String &sSrc ); + virtual ~Uuid(); - Bu::String toRawString() const; - Bu::String toString() const; - Bu::String toUrn() const; + Bu::String toRawString() const; + Bu::String toString() const; + Bu::String toUrn() const; - enum Type - { - System, - Version1, - Version2, - Version3, - Version4, - Version5, - }; + enum Type + { + System, + Version1, + Version2, + Version3, + Version4, + Version5, + }; - int getVersion(); + int getVersion(); - static Uuid generate( Type eType = System ); - DEPRECATED static Uuid gen() { return generate(); } + static Uuid generate( Type eType = System ); + DEPRECATED static Uuid gen() { return generate(); } - void clear(); - void set( const Bu::String &sSrc ); + void clear(); + void set( const Bu::String &sSrc ); - bool operator==( const Uuid &rhs ) const; - bool operator!=( const Uuid &rhs ) const; - Uuid &operator=( const Bu::String &rhs ) { set( rhs ); return *this; } - Uuid &operator=( const Uuid &rhs ); + bool operator==( const Uuid &rhs ) const; + bool operator!=( const Uuid &rhs ) const; + Uuid &operator=( const Bu::String &rhs ) { set( rhs ); return *this; } + Uuid &operator=( const Uuid &rhs ); - private: - unsigned char data[16]; - }; + private: + unsigned char data[16]; + }; - template - uint32_t __calcHashCode( const T &k ); + template + uint32_t __calcHashCode( const T &k ); - template - bool __cmpHashKeys( const T &a, const T &b ); + template + bool __cmpHashKeys( const T &a, const T &b ); - template<> uint32_t __calcHashCode( const Uuid &k ); - template<> bool __cmpHashKeys( - const Uuid &a, const Uuid &b ); + template<> uint32_t __calcHashCode( const Uuid &k ); + template<> bool __cmpHashKeys( + const Uuid &a, const Uuid &b ); - Bu::ArchiveBase &operator>>( Bu::ArchiveBase &ar, Uuid &u ); - Bu::ArchiveBase &operator<<( Bu::ArchiveBase &ar, const Uuid &u ); + Bu::ArchiveBase &operator>>( Bu::ArchiveBase &ar, Uuid &u ); + Bu::ArchiveBase &operator<<( Bu::ArchiveBase &ar, const Uuid &u ); }; #endif -- cgit v1.2.3