BString BString::justify(int leftMargin, int width){
BString r;
char* s;
int x = 0;
if(ostr){
for(s = ostr->data(); *s; s++){
if(x > width){
r = r + "\n";
x = 0;
}
if(x == 0){
while(x < leftMargin){
r = r + " ";
x++;
}
}
if(*s == '\n'){
r = r + *s;
x = 0;
}
else if((x > (7 * width) / 8) && isspace(*s)){
r = r + "\n";
x = 0;
}
else {
r = r + *s;
x++;
}
}
}
return r;
}
BString BString::fixedLen(int length, int rightJustify){
BString str;
int l;
int ls = length;
int p = 0;
str.ostr = new BRefData(length + 1);
str.ostr->data()[length] = '\0';
if(len() < ls)
ls = len();
if(rightJustify){
l = length - len();
while(l-- > 0)
str.ostr->data()[p++] = ' ';
}
for(l = 0; l < ls; l++){
str.ostr->data()[p++] = get(l);
}
if(!rightJustify){
while(l++ < length)
str.ostr->data()[p++] = ' ';
}
return str;
}
BString BString::firstLine(){
return subString(0, find('\n'));
}
BString BString::translateChar(char ch, BString replace){
BString s;
char c;
int i;
for(i = 0; i < len(); i++){
c = get(i);
if(c == ch)
s += replace;
else
s += c;
}
return s;
}
BString BString::csvEncode() const {
BString s;
char c;
int i;
for(i = 0; i < len(); i++){
c = get(i);
if(c == ',')
s += "\\,";
else if(c == '\n')
s += "\\n";
else
s += c;
}
return s;
}
BString& BString::csvDecode(const BString str){
char c;
int i;
clear();
for(i = 0; i < str.len(); i++){
c = str[i];
if((c == '\\') && (i < (len() - 2)))
*this += get(++i);
else
*this += c;
}
return *this;
}
// Base64 functions
BString BString::base64Encode() const {
const char base64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const BUInt8* data = (const BUInt8*)retStr();
BUInt resultIndex = 0;
int x;
BUInt32 n = 0;
int padCount = len() % 3;
BUInt8 n0, n1, n2, n3;
BString str;
for(x = 0; x < len(); x += 3){
n = ((uint32_t)data[x]) << 16;
if((x + 1) < len())
n += ((BUInt32)data[x + 1]) << 8;
if((x + 2) < len())
n += data[x + 2];
/* This 24-bit number gets separated into four 6-bit numbers */
n0 = (BUInt8)(n >> 18) & 63;
n1 = (BUInt8)(n >> 12) & 63;
n2 = (BUInt8)(n >> 6) & 63;
n3 = (BUInt8)n & 63;
str += char(base64chars[n0]);
str += char(base64chars[n1]);
if((x + 1) < len()){
str += char(base64chars[n2]);
}
if((x + 2) < len()){
str += char(base64chars[n3]);
}
}
if(padCount > 0){
for(; padCount < 3; padCount++){
str += '=';
}
}
return str;
}
static const BUInt8 base64_decode_table[] = {
66,66,66,66,66,66,66,66,66,66,64,66,66,66,66,66,66,66,66,66,66,66,66,66,66,
66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,62,66,66,66,63,52,53,
54,55,56,57,58,59,60,61,66,66,66,65,66,66,66, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,66,66,66,66,66,66,26,27,28,
29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,66,66,
66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,
66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,
66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,
66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,
66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,66,
66,66,66,66,66,66
};
BError BString::base64Decode(BString& str) const {
BError err;
const char* in = retStr();
const char* end = in + len();
char iter = 0;
uint32_t buf = 0;
size_t len = 0;
while(in < end){
BUInt8 c = base64_decode_table[int(*in++)];
switch(c){
case 64:
// Skip whitespace
continue;
case 66:
// Error
return err.set(1);
case 65:
// Pad character, end of data
in = end;
continue;
default:
buf = buf << 6 | c;
iter++;
if(iter == 4){
str += char((buf >> 16) & 255);
str += char((buf >> 8) & 255);
str += char(buf & 255);
buf = 0;
iter = 0;
}
}
}
if(iter == 3){
str += char((buf >> 10) & 255);
str += char((buf >> 2) & 255);
}
else if(iter == 2) {
str += char((buf >> 4) & 255);
}
return err;
}
BString BString::reverse() const {
BString s = copy();
int f;
int t;
if(ostr){
for(t = 0, f = len() - 1; t < len(); t++, f--)
s.ostr->data()[t] = ostr->data()[f];
}
return s;
}