#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
// for MSVC
#ifdef _WIN32
#define snprintf sprintf_s
#endif
int pack( char const * SrcStr, char * DstBuf, size_t DstBuf_Size ) {
int Err = 0;
char const * Src_Ptr = SrcStr;
char * Dst_Ptr = DstBuf;
size_t SrcBuf_Size
= strlen( SrcStr
) + 1; char const * SrcBuf_End = SrcStr + SrcBuf_Size;
char const * DstBuf_End = DstBuf + DstBuf_Size;
char c = 0;
int RepeatCount = 1;
// don't forget about buffers intercrossing
if( !SrcStr || !DstBuf || 0 == DstBuf_Size || (DstBuf < SrcBuf_End && DstBuf_End > SrcStr) ) {
return 1;
}
// source string must contain no digits
// check for destination buffer overflow
while( '\0' != *Src_Ptr
&& Dst_Ptr
< DstBuf_End
- 1 && !isdigit( *Src_Ptr
) && !Err
) {
c = *Dst_Ptr = *Src_Ptr;
++Src_Ptr; ++Dst_Ptr;
for( RepeatCount = 1; *Src_Ptr == c; ++RepeatCount ) {
++Src_Ptr;
}
if( RepeatCount > 1 ) {
int res
= snprintf( Dst_Ptr
, DstBuf_End
- Dst_Ptr
- 1, "%i", RepeatCount
); if( res < 0 ) {
Err = 1;
} else {
Dst_Ptr += res;
RepeatCount = 1;
}
}
}
*Dst_Ptr = '\0';
return Err;
};
int unpack( char const * SrcStr, char * DstBuf, size_t DstBuf_Size ) {
int Err = 0;
char const * Src_Ptr = SrcStr;
char * Dst_Ptr = DstBuf;
size_t SrcBuf_Size
= strlen( SrcStr
) + 1; char const * SrcBuf_End = SrcStr + SrcBuf_Size;
char const * DstBuf_End = DstBuf + DstBuf_Size;
char c = 0;
// don't forget about buffers intercrossing
// first character of source string must be non-digit
if( !SrcStr || !DstBuf || 0 == DstBuf_Size || (DstBuf < SrcBuf_End && DstBuf_End > SrcStr) \
return 1;
}
// check for destination buffer overflow
while( '\0' != *Src_Ptr && Dst_Ptr < DstBuf_End - 1 && !Err ) {
c = *Dst_Ptr = *Src_Ptr;
++Src_Ptr; ++Dst_Ptr;
} else {
int repeat_count
= strtol( Src_Ptr
, (char**)&Src_Ptr
, 10 ); if( !repeat_count || repeat_count - 1 > DstBuf_End - Dst_Ptr - 1 ) {
Err = 1;
} else {
memset( Dst_Ptr
, c
, repeat_count
- 1 ); Dst_Ptr += repeat_count - 1;
}
}
}
*Dst_Ptr = '\0';
return Err;
};
int main() {
char str[] = "aabbbccccddddd";
char buf1[128] = {0};
char buf2[128] = {0};
pack( str, buf1, 128 );
printf( "pack: %s -> %s\n", str
, buf1
);
unpack( buf1, buf2, 128 );
printf( "unpack: %s -> %s\n", buf1
, buf2
);
return 0;
}
I2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8Y3R5cGUuaD4KCgoKLy8gZm9yIE1TVkMKI2lmZGVmIF9XSU4zMgogICAgI2RlZmluZSBzbnByaW50ZiBzcHJpbnRmX3MKI2VuZGlmCgoKCmludCBwYWNrKCBjaGFyIGNvbnN0ICogU3JjU3RyLCBjaGFyICogRHN0QnVmLCBzaXplX3QgRHN0QnVmX1NpemUgKSB7CgogICAgaW50IEVyciA9IDA7CgogICAgY2hhciBjb25zdCAqIFNyY19QdHIgPSBTcmNTdHI7CiAgICBjaGFyICogRHN0X1B0ciA9IERzdEJ1ZjsKCiAgICBzaXplX3QgU3JjQnVmX1NpemUgPSBzdHJsZW4oIFNyY1N0ciApICsgMTsKICAgIGNoYXIgY29uc3QgKiBTcmNCdWZfRW5kID0gU3JjU3RyICsgU3JjQnVmX1NpemU7CiAgICBjaGFyIGNvbnN0ICogRHN0QnVmX0VuZCA9IERzdEJ1ZiArIERzdEJ1Zl9TaXplOwoKICAgIGNoYXIgYyA9IDA7CiAgICBpbnQgUmVwZWF0Q291bnQgPSAxOwoKICAgIC8vIGRvbid0IGZvcmdldCBhYm91dCBidWZmZXJzIGludGVyY3Jvc3NpbmcKICAgIGlmKCAhU3JjU3RyIHx8ICFEc3RCdWYgfHwgMCA9PSBEc3RCdWZfU2l6ZSB8fCAoRHN0QnVmIDwgU3JjQnVmX0VuZCAmJiBEc3RCdWZfRW5kID4gU3JjU3RyKSApIHsKICAgICAgICByZXR1cm4gMTsKICAgIH0KCiAgICAvLyBzb3VyY2Ugc3RyaW5nIG11c3QgY29udGFpbiBubyBkaWdpdHMKICAgIC8vIGNoZWNrIGZvciBkZXN0aW5hdGlvbiBidWZmZXIgb3ZlcmZsb3cKICAgIHdoaWxlKCAnXDAnICE9ICpTcmNfUHRyICYmIERzdF9QdHIgPCBEc3RCdWZfRW5kIC0gMSAmJiAhaXNkaWdpdCggKlNyY19QdHIgKSAmJiAhRXJyICkgewoKICAgICAgICBjID0gKkRzdF9QdHIgPSAqU3JjX1B0cjsKICAgICAgICArK1NyY19QdHI7ICsrRHN0X1B0cjsKCiAgICAgICAgZm9yKCBSZXBlYXRDb3VudCA9IDE7ICpTcmNfUHRyID09IGM7ICsrUmVwZWF0Q291bnQgKSB7CiAgICAgICAgICAgICsrU3JjX1B0cjsKICAgICAgICB9CgogICAgICAgIGlmKCBSZXBlYXRDb3VudCA+IDEgKSB7CiAgICAgICAgICAgIGludCByZXMgPSBzbnByaW50ZiggRHN0X1B0ciwgRHN0QnVmX0VuZCAtIERzdF9QdHIgLSAxLCAiJWkiLCBSZXBlYXRDb3VudCApOwogICAgICAgICAgICBpZiggcmVzIDwgMCApIHsKICAgICAgICAgICAgICAgIEVyciA9IDE7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBEc3RfUHRyICs9IHJlczsKICAgICAgICAgICAgICAgIFJlcGVhdENvdW50ID0gMTsKICAgICAgICAgICAgfQogICAgICAgfQogICAgfQoKICAgICpEc3RfUHRyID0gJ1wwJzsKCiAgICByZXR1cm4gRXJyOwp9OwoKaW50IHVucGFjayggY2hhciBjb25zdCAqIFNyY1N0ciwgY2hhciAqIERzdEJ1Ziwgc2l6ZV90IERzdEJ1Zl9TaXplICkgewoKICAgIGludCBFcnIgPSAwOwoKICAgIGNoYXIgY29uc3QgKiBTcmNfUHRyID0gU3JjU3RyOwogICAgY2hhciAqIERzdF9QdHIgPSBEc3RCdWY7CgogICAgc2l6ZV90IFNyY0J1Zl9TaXplID0gc3RybGVuKCBTcmNTdHIgKSArIDE7CiAgICBjaGFyIGNvbnN0ICogU3JjQnVmX0VuZCA9IFNyY1N0ciArIFNyY0J1Zl9TaXplOwogICAgY2hhciBjb25zdCAqIERzdEJ1Zl9FbmQgPSBEc3RCdWYgKyBEc3RCdWZfU2l6ZTsKCiAgICBjaGFyIGMgPSAwOwoKICAgIC8vIGRvbid0IGZvcmdldCBhYm91dCBidWZmZXJzIGludGVyY3Jvc3NpbmcKICAgIC8vIGZpcnN0IGNoYXJhY3RlciBvZiBzb3VyY2Ugc3RyaW5nIG11c3QgYmUgbm9uLWRpZ2l0CiAgICBpZiggIVNyY1N0ciB8fCAhRHN0QnVmIHx8IDAgPT0gRHN0QnVmX1NpemUgfHwgKERzdEJ1ZiA8IFNyY0J1Zl9FbmQgJiYgRHN0QnVmX0VuZCA+IFNyY1N0cikgXAogICAgICAgIHx8IGlzZGlnaXQoIFNyY1N0clswXSApICkgewoKICAgICAgICByZXR1cm4gMTsKICAgIH0KCiAgICAvLyBjaGVjayBmb3IgZGVzdGluYXRpb24gYnVmZmVyIG92ZXJmbG93CiAgICB3aGlsZSggJ1wwJyAhPSAqU3JjX1B0ciAmJiBEc3RfUHRyIDwgRHN0QnVmX0VuZCAtIDEgJiYgIUVyciApIHsKCiAgICAgICAgaWYoICFpc2RpZ2l0KCAqU3JjX1B0ciApICkgewogICAgICAgICAgICBjID0gKkRzdF9QdHIgPSAqU3JjX1B0cjsKICAgICAgICAgICAgKytTcmNfUHRyOyArK0RzdF9QdHI7CgogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGludCByZXBlYXRfY291bnQgPSBzdHJ0b2woIFNyY19QdHIsIChjaGFyKiopJlNyY19QdHIsIDEwICk7CiAgICAgICAgICAgIGlmKCAhcmVwZWF0X2NvdW50IHx8IHJlcGVhdF9jb3VudCAtIDEgPiBEc3RCdWZfRW5kIC0gRHN0X1B0ciAtIDEgKSB7IAogICAgICAgICAgICAgICAgRXJyID0gMTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIG1lbXNldCggRHN0X1B0ciwgYywgcmVwZWF0X2NvdW50IC0gMSApOwogICAgICAgICAgICAgICAgRHN0X1B0ciArPSByZXBlYXRfY291bnQgLSAxOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgICpEc3RfUHRyID0gJ1wwJzsKCiAgICByZXR1cm4gRXJyOwp9OwoKaW50IG1haW4oKSB7CgogICAgY2hhciBzdHJbXSA9ICJhYWJiYmNjY2NkZGRkZCI7CiAgICBjaGFyIGJ1ZjFbMTI4XSA9IHswfTsKICAgIGNoYXIgYnVmMlsxMjhdID0gezB9OwoKICAgIHBhY2soIHN0ciwgYnVmMSwgMTI4ICk7CiAgICBwcmludGYoICJwYWNrOiAlcyAtPiAlc1xuIiwgc3RyLCBidWYxICk7CgogICAgdW5wYWNrKCBidWYxLCBidWYyLCAxMjggKTsKICAgIHByaW50ZiggInVucGFjazogJXMgLT4gJXNcbiIsIGJ1ZjEsIGJ1ZjIgKTsKCiAgICByZXR1cm4gMDsKfQ==