X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/cce08fb5aca7dd01706cecea845b183dc62b1717..40cdb71e715cf1c8e6d8201da307f992763f1654:/apt-pkg/contrib/strutl.cc diff --git a/apt-pkg/contrib/strutl.cc b/apt-pkg/contrib/strutl.cc index aa37a099a..4c05f2df8 100644 --- a/apt-pkg/contrib/strutl.cc +++ b/apt-pkg/contrib/strutl.cc @@ -24,16 +24,71 @@ #include #include #include +#include #include #include #include #include +#include #include "config.h" using namespace std; /*}}}*/ +// UTF8ToCodeset - Convert some UTF-8 string for some codeset /*{{{*/ +// --------------------------------------------------------------------- +/* This is handy to use before display some information for enduser */ +bool UTF8ToCodeset(const char *codeset, const string &orig, string *dest) +{ + iconv_t cd; + const char *inbuf; + char *inptr, *outbuf, *outptr; + size_t insize, outsize; + + cd = iconv_open(codeset, "UTF-8"); + if (cd == (iconv_t)(-1)) { + // Something went wrong + if (errno == EINVAL) + _error->Error("conversion from 'UTF-8' to '%s' not available", + codeset); + else + perror("iconv_open"); + + // Clean the destination string + *dest = ""; + + return false; + } + + insize = outsize = orig.size(); + inbuf = orig.data(); + inptr = (char *)inbuf; + outbuf = new char[insize+1]; + outptr = outbuf; + + while (insize != 0) + { + size_t const err = iconv(cd, &inptr, &insize, &outptr, &outsize); + if (err == (size_t)(-1)) + { + insize--; + outsize++; + inptr++; + *outptr = '?'; + outptr++; + } + } + + *outptr = '\0'; + *dest = outbuf; + delete[] outbuf; + + iconv_close(cd); + + return true; +} + /*}}}*/ // strstrip - Remove white space from the front and back of a string /*{{{*/ // --------------------------------------------------------------------- /* This is handy to use when parsing a file. It also removes \n's left @@ -260,13 +315,13 @@ string SizeToStr(double Size) { if (ASize < 100 && I != 0) { - sprintf(S,"%.1f%c",ASize,Ext[I]); + sprintf(S,"%'.1f%c",ASize,Ext[I]); break; } if (ASize < 10000) { - sprintf(S,"%.0f%c",ASize,Ext[I]); + sprintf(S,"%'.0f%c",ASize,Ext[I]); break; } ASize /= 1000.0; @@ -287,23 +342,27 @@ string TimeToStr(unsigned long Sec) { if (Sec > 60*60*24) { - sprintf(S,"%lid %lih%lim%lis",Sec/60/60/24,(Sec/60/60) % 24,(Sec/60) % 60,Sec % 60); + //d means days, h means hours, min means minutes, s means seconds + sprintf(S,_("%lid %lih %limin %lis"),Sec/60/60/24,(Sec/60/60) % 24,(Sec/60) % 60,Sec % 60); break; } if (Sec > 60*60) { - sprintf(S,"%lih%lim%lis",Sec/60/60,(Sec/60) % 60,Sec % 60); + //h means hours, min means minutes, s means seconds + sprintf(S,_("%lih %limin %lis"),Sec/60/60,(Sec/60) % 60,Sec % 60); break; } if (Sec > 60) { - sprintf(S,"%lim%lis",Sec/60,Sec % 60); + //min means minutes, s means seconds + sprintf(S,_("%limin %lis"),Sec/60,Sec % 60); break; } - - sprintf(S,"%lis",Sec); + + //s means seconds + sprintf(S,_("%lis"),Sec); break; } @@ -339,6 +398,17 @@ string SubstVar(string Str,const struct SubstVar *Vars) return Str; } /*}}}*/ +// OutputInDepth - return a string with separator multiplied with depth /*{{{*/ +// --------------------------------------------------------------------- +/* Returns a string with the supplied separator depth + 1 times in it */ +std::string OutputInDepth(const unsigned long Depth, const char* Separator) +{ + std::string output = ""; + for(unsigned long d=Depth+1; d > 0; d--) + output.append(Separator); + return output; +} + /*}}}*/ // URItoFileName - Convert the uri into a unique file name /*{{{*/ // --------------------------------------------------------------------- /* This converts a URI into a safe filename. It quotes all unsafe characters @@ -415,9 +485,9 @@ string Base64Encode(const string &S) return Final; } /*}}}*/ -// stringcmp - Arbitary string compare /*{{{*/ +// stringcmp - Arbitrary string compare /*{{{*/ // --------------------------------------------------------------------- -/* This safely compares two non-null terminated strings of arbitary +/* This safely compares two non-null terminated strings of arbitrary length */ int stringcmp(const char *A,const char *AEnd,const char *B,const char *BEnd) { @@ -473,7 +543,7 @@ int stringcmp(string::const_iterator A,string::const_iterator AEnd, } #endif /*}}}*/ -// stringcasecmp - Arbitary case insensitive string compare /*{{{*/ +// stringcasecmp - Arbitrary case insensitive string compare /*{{{*/ // --------------------------------------------------------------------- /* */ int stringcasecmp(const char *A,const char *AEnd,const char *B,const char *BEnd) @@ -614,11 +684,24 @@ string TimeRFC1123(time_t Date) // --------------------------------------------------------------------- /* This pulls full messages from the input FD into the message buffer. It assumes that messages will not pause during transit so no - fancy buffering is used. */ + fancy buffering is used. + + In particular: this reads blocks from the input until it believes + that it's run out of input text. Each block is terminated by a + double newline ('\n' followed by '\n'). As noted below, there is a + bug in this code: it assumes that all the blocks have been read if + it doesn't see additional text in the buffer after the last one is + parsed, which will cause it to lose blocks if the last block + coincides with the end of the buffer. + */ bool ReadMessages(int Fd, vector &List) { char Buffer[64000]; char *End = Buffer; + // Represents any left-over from the previous iteration of the + // parse loop. (i.e., if a message is split across the end + // of the buffer, it goes here) + string PartialMessage; while (1) { @@ -646,6 +729,7 @@ bool ReadMessages(int Fd, vector &List) // Pull the message out string Message(Buffer,I-Buffer); + PartialMessage += Message; // Fix up the buffer for (; I < End && *I == '\n'; I++); @@ -653,10 +737,32 @@ bool ReadMessages(int Fd, vector &List) memmove(Buffer,I,End-Buffer); I = Buffer; - List.push_back(Message); + List.push_back(PartialMessage); + PartialMessage.clear(); } - if (End == Buffer) - return true; + if (End != Buffer) + { + // If there's text left in the buffer, store it + // in PartialMessage and throw the rest of the buffer + // away. This allows us to handle messages that + // are longer than the static buffer size. + PartialMessage += string(Buffer, End); + End = Buffer; + } + else + { + // BUG ALERT: if a message block happens to end at a + // multiple of 64000 characters, this will cause it to + // terminate early, leading to a badly formed block and + // probably crashing the method. However, this is the only + // way we have to find the end of the message block. I have + // an idea of how to fix this, but it will require changes + // to the protocol (essentially to mark the beginning and + // end of the block). + // + // -- dburrows 2008-04-02 + return true; + } if (WaitFd(Fd) == false) return false; @@ -947,11 +1053,26 @@ void ioprintf(ostream &out,const char *format,...) va_start(args,format); // sprintf the description - char S[400]; + char S[4096]; vsnprintf(S,sizeof(S),format,args); out << S; } /*}}}*/ +// strprintf - C format string outputter to C++ strings /*{{{*/ +// --------------------------------------------------------------------- +/* This is used to make the internationalization strings easier to translate + and to allow reordering of parameters */ +void strprintf(string &out,const char *format,...) +{ + va_list args; + va_start(args,format); + + // sprintf the description + char S[4096]; + vsnprintf(S,sizeof(S),format,args); + out = string(S); +} + /*}}}*/ // safe_snprintf - Safer snprintf /*{{{*/ // --------------------------------------------------------------------- /* This is a snprintf that will never (ever) go past 'End' and returns a @@ -975,6 +1096,17 @@ char *safe_snprintf(char *Buffer,char *End,const char *Format,...) } /*}}}*/ +// tolower_ascii - tolower() function that ignores the locale /*{{{*/ +// --------------------------------------------------------------------- +/* */ +int tolower_ascii(int c) +{ + if (c >= 'A' and c <= 'Z') + return c + 32; + return c; +} + /*}}}*/ + // CheckDomainList - See if Host is in a , seperate list /*{{{*/ // --------------------------------------------------------------------- /* The domain list is a comma seperate list of domains that are suffix