2006-05-04 12:37:20 +00:00

430 lines
9.6 KiB
C++

/*
* Copyright (C) 2005-2006 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
* either express or implied. See the License for the specific
* language governing permissions and limitations under the
* License.
*/
#include <string>
#include "util\DataPacker.h"
#include "util\ByteArray.h"
using namespace Alfresco;
/**
* Unpack a short/16 bit value from the buffer.
*
* @param buf CBUFPTR
* @param pos BUFPOS
* @return int
*/
int DataPacker::getShort(CBUFPTR buf, BUFPOS pos) {
int sval = ( buf[pos] << 8) + buf[pos+1];
return sval;
}
/**
* Unpack an int/32 bit value from the buffer.
*
* @param buf CBUFPTR
* @param pos BUFPOS
* @return int
*/
int DataPacker::getInt(CBUFPTR buf, BUFPOS pos) {
int ival = (buf[pos] << 24) + (buf[pos+1] << 16) + (buf[pos+2] << 8) + buf[pos+3];
return ival;
}
/**
* Unpack a long/64 bit value from the buffer.
*
* @param buf CBUFPTR
* @param pos BUFPOS
* @return LONG64
*/
LONG64 DataPacker::getLong(CBUFPTR buf, BUFPOS pos) {
LONG64 lval = 0;
BUFPTR pLval = (BUFPTR) &lval;
for ( unsigned int i = 0; i < 8; i++) {
pLval[7 - i] = buf[pos + i];
}
return lval;
}
/**
* Unpack a short/16 bit value in Intel format from the buffer.
*
* @param buf CBUFPTR
* @param pos BUFPOS
* @return int
*/
int DataPacker::getIntelShort(CBUFPTR buf, BUFPOS pos) {
int sval = ( buf[pos+1] << 8) + buf[pos];
return sval;
}
/**
* Unpack an int/32 bit value in Intel format from the buffer.
*
* @param buf CBUFPTR
* @param pos BUFPOS
* @return int
*/
int DataPacker::getIntelInt(CBUFPTR buf, BUFPOS pos) {
int ival = (buf[pos+3] << 24) + (buf[pos+2] << 16) + (buf[pos+1] << 8) + buf[pos];
return ival;
}
/**
* Unpack a long/64 bit value in Intel format from the buffer.
*
* @param buf CBUFPTR
* @param pos BUFPOS
* @return LONG64
*/
LONG64 DataPacker::getIntelLong(CBUFPTR buf, BUFPOS pos) {
LONG64 lval = 0;
BUFPTR pLval = (BUFPTR) &lval;
for ( unsigned int i = 0; i < 8; i++) {
pLval[i] = buf[pos + i];
}
return lval;
}
/**
* Unpack a string from the buffer.
*
* @param buf CBUFPTR
* @param pos BUFPOS
* @param maxLen const unsigned int
* @param isUni const bool
* @return String
*/
String DataPacker::getString(CBUFPTR buf, BUFPOS pos, const unsigned int maxLen, const bool isUni) {
// Check for a Unicode string
if ( isUni)
return getUnicodeString( buf, pos, maxLen);
// Search for the trailing null
unsigned int maxpos = pos + maxLen;
unsigned int endpos = pos;
while (buf[endpos] != '\0' && endpos < maxpos)
endpos++;
return String((const char*) buf, pos, endpos - pos);
}
/**
* Unpack a Unicode string from the buffer.
*
* @param buf CBUFPTR
* @param pos BUFPOS
* @param maxLen const unsigned int
* @return String
*/
String DataPacker::getUnicodeString(CBUFPTR buf, BUFPOS pos, const unsigned int maxLen) {
// Check for an empty string
if ( maxLen == 0)
return String();
// Word align the position
pos = wordAlign( pos);
// Search for the trailing null
int maxpos = pos + (maxLen * 2);
int endpos = pos;
std::wstring str;
int cpos = 0;
wchar_t curChar;
do {
// Get a Unicode character from the buffer
curChar = (wchar_t) DataPacker::getIntelShort(buf, endpos);
// Add the character to the string
if ( curChar != 0)
str += curChar;
// Update the buffer pointer
endpos += 2;
} while (curChar != 0 && endpos < maxpos);
// Return the string
return String(str);
}
/**
* Pack a short/16 bit value into the buffer.
*
* @param val const int
* @param buf BUFPTR
* @param pos BUFPOS
*/
void DataPacker::putShort(const int val, BUFPTR buf, BUFPOS pos) {
buf[pos] = (unsigned char) (val >> 8) & 0xFF;
buf[pos+1] = (unsigned char) (val & 0xFF);
}
/**
* Pack an int/32 bit value into the buffer.
*
* @param val const int
* @param buf BUFPTR
* @param pos BUFPOS
*/
void DataPacker::putInt(const int val, BUFPTR buf, BUFPOS pos) {
buf[pos] = (unsigned char) (val >> 24) & 0xFF;
buf[pos+1] = (unsigned char) (val >> 16) & 0xFF;
buf[pos+2] = (unsigned char) (val >> 8) & 0xFF;
buf[pos+3] = (unsigned char) (val & 0xFF);
}
/**
* Pack a long/64 bit value into the buffer.
*
* @param val const LONG64
* @param buf BUFPTR
* @param pos BUFPOS
*/
void DataPacker::putLong(const LONG64 val, BUFPTR buf, BUFPOS pos) {
BUFPTR pLval = (BUFPTR) &val;
buf[pos] = pLval[7];
buf[pos+1] = pLval[6];
buf[pos+2] = pLval[5];
buf[pos+3] = pLval[4];
buf[pos+4] = pLval[3];
buf[pos+5] = pLval[2];
buf[pos+6] = pLval[1];
buf[pos+7] = pLval[0];
}
/**
* Pack a short/16 bit value in Intel format into the buffer.
*
* @param val const int
* @param buf BUFPTR
* @param pos BUFPOS
*/
void DataPacker::putIntelShort(const int val, BUFPTR buf, BUFPOS pos) {
buf[pos+1] = (unsigned char) (val >> 8) & 0xFF;
buf[pos] = (unsigned char) (val & 0xFF);
}
/**
* Pack an int/32 bit value in Intel format into the buffer.
*
* @param val const int
* @param buf BUFPTR
* @param pos BUFPOS
*/
void DataPacker::putIntelInt(const int val, BUFPTR buf, BUFPOS pos) {
buf[pos+3] = (unsigned char) (val >> 24) & 0xFF;
buf[pos+2] = (unsigned char) (val >> 16) & 0xFF;
buf[pos+1] = (unsigned char) (val >> 8) & 0xFF;
buf[pos] = (unsigned char) (val & 0xFF);
}
/**
* Pack a long/64 bit value in Intel format into the buffer.
*
* @param val const LONG64
* @param buf BUFPTR
* @param pos BUFPOS
*/
void DataPacker::putIntelLong(const LONG64 val, BUFPTR buf, BUFPOS pos) {
BUFPTR pLval = (BUFPTR) &val;
buf[pos+7] = pLval[7];
buf[pos+6] = pLval[6];
buf[pos+5] = pLval[5];
buf[pos+4] = pLval[4];
buf[pos+3] = pLval[3];
buf[pos+2] = pLval[2];
buf[pos+1] = pLval[1];
buf[pos] = pLval[0];
}
/**
* Pack a string into the buffer.
*
* @param str const String&
* @param buf BUFPTR
* @param pos BUFPOS
* @param nullTerm const bool
* @param isUni const bool
* @return int
*/
unsigned int DataPacker::putString(const String& str, BUFPTR buf, BUFPOS pos, const bool nullTerm, const bool isUni) {
// Check if the string should be packed as Unicode or ASCII
unsigned int newPos = pos;
if ( isUni == true) {
// Pack the characters
for ( unsigned int i = 0; i < str.length(); i++) {
wchar_t ch = str.charAt(i);
buf[newPos++] = (unsigned char) (ch & 0xFF);
buf[newPos++] = (unsigned char) (ch >> 8) & 0xFF;
}
// Add a null terminator, if required
if ( nullTerm == true) {
buf[newPos++] = '\0';
buf[newPos++] = '\0';
}
}
else {
// Get the string as ASCII characters
ByteArray byts = str.getBytes();
// Pack the characters
for ( unsigned int i = 0; i < str.length(); i++)
buf[newPos++] = byts[i];
// Add a null terminator, if required
if ( nullTerm == true)
buf[newPos++] = '\0';
}
// Return the new buffer position
return newPos;
}
/**
* Pack an ASCII string into the buffer
*
* @param str const char*
* @param buf BUFPTR
* @param pos BUFPOS
* @param nullTerm bool
* @return unsigned int
*/
unsigned int DataPacker::putString(const char* str, BUFLEN len, BUFPTR buf, BUFPOS pos, bool nullTerm) {
// Copy the ASCII string to the buffer
memcpy(buf + pos, str, len);
BUFPOS endPos = pos + len;
if ( nullTerm == true)
buf[endPos] = '\0';
// Return the new buffer position
return endPos;
}
/**
* Pack a Unicode string into the buffer
*
* @param str const wchar_t*
* @param buf BUFPTR
* @param pos BUFPOS
* @param nullTerm bool
* @return unsigned int
*/
unsigned int DataPacker::putString(const wchar_t* str, BUFLEN len, BUFPTR buf, BUFPOS pos, bool nullTerm) {
// Copy the Unicode string to the buffer
BUFLEN uniLen = len * 2;
BUFPOS endPos = pos + uniLen;
memcpy(buf + pos, str, uniLen);
if ( nullTerm == true) {
buf[pos + uniLen + 1] = '\0';
buf[pos + uniLen + 2] = '\0';
endPos += 2;
}
// Return the new buffer position
return endPos;
}
/**
* Pack a number of zero bytes into the buffer.
*
* @param buf BUFPTR
* @param pos BUFPOS
* @param count const unsigned int
*/
void DataPacker::putZeros(BUFPTR buf, BUFPOS pos, const unsigned int count) {
for (unsigned int i = 0; i < count; i++)
buf[pos + i] = (unsigned char) 0;
}
/**
* Determine the amount of buffer space required to pack the string with the specified settings.
*
* @param str const String&
* @param isUni const bool
* @param nulTerm const bool
* @return unsigned int
*/
unsigned int DataPacker::getStringLength(const String& str, const bool isUni, const bool nulTerm) {
int len = str.length();
if ( nulTerm == true)
len += 1;
if ( isUni == true)
len *= 2;
return len;
}
/**
* Calculate the buffer position after packing the string with the specified settings.
*
* @param pos BUFPOS
* @param str const String&
* @param isUni const bool
* @param nulTerm const bool
* @return unsigned int
*/
unsigned int DataPacker::getBufferPosition(BUFPOS pos, const String& str, const bool isUni, const bool nulTerm) {
unsigned int len = str.length();
if ( nulTerm == true)
len += 1;
if ( isUni == true)
len *= 2;
return pos + len;
}