[Aptitude-svn-commit] r3420 - in branches/aptitude-0.3/aptitude: . src/vscreen
Daniel Burrows
dburrows@costa.debian.org
Sat, 25 Jun 2005 15:45:45 +0000
Author: dburrows
Date: Sat Jun 25 15:45:42 2005
New Revision: 3420
Added:
branches/aptitude-0.3/aptitude/src/vscreen/transcode.cc
branches/aptitude-0.3/aptitude/src/vscreen/transcode.h
Modified:
branches/aptitude-0.3/aptitude/ChangeLog
branches/aptitude-0.3/aptitude/src/vscreen/Makefile.am
Log:
Add an iconv wrapper to decode multibyte strings.
Modified: branches/aptitude-0.3/aptitude/ChangeLog
==============================================================================
--- branches/aptitude-0.3/aptitude/ChangeLog (original)
+++ branches/aptitude-0.3/aptitude/ChangeLog Sat Jun 25 15:45:42 2005
@@ -1,5 +1,10 @@
2005-06-25 Daniel Burrows <dburrows@debian.org>
+ * src/vscreen/Makefile.am, src/vscreen/transcode.cc, src/vscreen/transcode.h:
+
+ Add support code to wrap iconv in a simpler (less efficient)
+ interface.
+
* src/vscreen/curses++.h:
Fix formatting errors in a comment.
Modified: branches/aptitude-0.3/aptitude/src/vscreen/Makefile.am
==============================================================================
--- branches/aptitude-0.3/aptitude/src/vscreen/Makefile.am (original)
+++ branches/aptitude-0.3/aptitude/src/vscreen/Makefile.am Sat Jun 25 15:45:42 2005
@@ -82,7 +82,9 @@
vs_tree.h \
vs_tree.cc \
columnify.h \
- columnify.cc
+ columnify.cc \
+ transcode.h \
+ transcode.cc
testvscreen_SOURCES= \
testvscreen.cc
Added: branches/aptitude-0.3/aptitude/src/vscreen/transcode.cc
==============================================================================
--- (empty file)
+++ branches/aptitude-0.3/aptitude/src/vscreen/transcode.cc Sat Jun 25 15:45:42 2005
@@ -0,0 +1,106 @@
+// transcode.cc
+//
+// Copyright (C) 2005 Daniel Burrows
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; see the file COPYING. If not, write to
+// the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+// Boston, MA 02111-1307, USA.
+
+#include "transcode.h"
+
+#include <assert.h>
+#include <errno.h>
+#include <iconv.h>
+
+using namespace std;
+
+bool decode_multibyte(const char *s,
+ wstring &out,
+ const char *encoding)
+{
+ if(encoding == NULL)
+ encoding=setlocale(LC_CTYPE, NULL);
+
+ iconv_t converter=iconv_open("WCHAR_T", encoding);
+
+ if(converter==((iconv_t)-1))
+ return false;
+
+ // arbitrary initial starting size; expected to be large enough for
+ // most "small" strings.
+ size_t outbufsize=1024, outbufremaining=1024;
+ size_t inremaining=strlen(s);
+
+ try
+ {
+ // auto_ptr used so we free stuff automatically when we return
+ // (especially abnormally).
+ auto_ptr<char> outbufhead(new char[outbufsize]);
+ char *outbufcur=outbufhead.get();
+
+ while(inremaining>0)
+ {
+ if(iconv(converter,
+ const_cast<char **>(&s), &inremaining,
+ &outbufcur, &outbufremaining) == ((size_t)-1))
+ {
+ // Some error conditions can be corrected. There are three
+ // reasons iconv can terminate abnormally:
+ //
+ // (1) an invalid multibyte sequence occured. We do not
+ // attempt to recover in this case.
+ //
+ // (2) an incomplete multibyte sequence occured; as the
+ // input string is all the input we have, this reduces
+ // to case (1).
+ //
+ // (3) no room left in the output buffer. We respond by
+ // doubling the output buffer's size, or failing if
+ // it's doubled as far as it can go.
+
+ if(errno != E2BIG)
+ {
+ if(outbufremaining<outbufsize)
+ out=wstring((wchar_t *) outbufhead.get(),
+ outbufsize-outbufremaining);
+ return false;
+ }
+ else
+ {
+ auto_ptr<char> outbufnew(new char[outbufsize]);
+ memcpy(outbufnew.get(), outbufhead.get(),
+ outbufsize-outbufremaining);
+ outbufremaining+=outbufsize;
+ outbufsize*=2;
+ // will deallocate outbufhead.
+ outbufhead=outbufnew;
+ }
+ }
+ else
+ // if this fails, my understanding of iconv is wrong: the
+ // iconv docs say that if it doesn't fail, then the whole
+ // input sequence was converted.
+ assert(inremaining==0);
+ }
+
+ out=wstring((wchar_t *) outbufhead.get(), outbufsize-outbufremaining);
+ return true;
+ }
+ catch(bad_alloc)
+ {
+ errno=ENOMEM;
+ return false;
+ }
+}
+
Added: branches/aptitude-0.3/aptitude/src/vscreen/transcode.h
==============================================================================
--- (empty file)
+++ branches/aptitude-0.3/aptitude/src/vscreen/transcode.h Sat Jun 25 15:45:42 2005
@@ -0,0 +1,42 @@
+// transcode.h -*-c++-*-
+//
+// Copyright (C) 2005 Daniel Burrows
+//
+// This program is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; see the file COPYING. If not, write to
+// the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+// Boston, MA 02111-1307, USA.
+
+#ifndef TRANSCODE_H
+#define TRANSCODE_H
+
+#include <string>
+
+/** Convenience function to convert a multibyte encoding to wide
+ * characters. This is a wrapper around iconv.
+ *
+ * \param s the string to decode
+ * \param out the location to write the transcoded string
+ * \param encoding the encoding of s; if \b null or unspecified,
+ * the value of LC_CTYPE is used.
+ *
+ * \return \b true if the entire string was successfully transcoded;
+ * if transcoding failed, returns \b false and sets errno.
+ */
+bool transcode(const char *s,
+ std::wstring &out,
+ const char *encoding=NULL);
+
+// Note: would it be saner to express errors via exceptions?
+
+#endif // TRANSCODE_H