diff options
Diffstat (limited to 'kviewshell/plugins/djvu/libdjvu/DjVuMessageLite.cpp')
-rw-r--r-- | kviewshell/plugins/djvu/libdjvu/DjVuMessageLite.cpp | 478 |
1 files changed, 478 insertions, 0 deletions
diff --git a/kviewshell/plugins/djvu/libdjvu/DjVuMessageLite.cpp b/kviewshell/plugins/djvu/libdjvu/DjVuMessageLite.cpp new file mode 100644 index 00000000..258b0649 --- /dev/null +++ b/kviewshell/plugins/djvu/libdjvu/DjVuMessageLite.cpp @@ -0,0 +1,478 @@ +//C- -*- C++ -*- +//C- ------------------------------------------------------------------- +//C- DjVuLibre-3.5 +//C- Copyright (c) 2002 Leon Bottou and Yann Le Cun. +//C- Copyright (c) 2001 AT&T +//C- +//C- This software is subject to, and may be distributed under, the +//C- GNU General Public License, Version 2. The license should have +//C- accompanied the software or you may obtain a copy of the license +//C- from the Free Software Foundation at http://www.fsf.org . +//C- +//C- This program is distributed in the hope that it will be useful, +//C- but WITHOUT ANY WARRANTY; without even the implied warranty of +//C- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +//C- GNU General Public License for more details. +//C- +//C- DjVuLibre-3.5 is derived from the DjVu(r) Reference Library +//C- distributed by Lizardtech Software. On July 19th 2002, Lizardtech +//C- Software authorized us to replace the original DjVu(r) Reference +//C- Library notice by the following text (see doc/lizard2002.djvu): +//C- +//C- ------------------------------------------------------------------ +//C- | DjVu (r) Reference Library (v. 3.5) +//C- | Copyright (c) 1999-2001 LizardTech, Inc. All Rights Reserved. +//C- | The DjVu Reference Library is protected by U.S. Pat. No. +//C- | 6,058,214 and patents pending. +//C- | +//C- | This software is subject to, and may be distributed under, the +//C- | GNU General Public License, Version 2. The license should have +//C- | accompanied the software or you may obtain a copy of the license +//C- | from the Free Software Foundation at http://www.fsf.org . +//C- | +//C- | The computer code originally released by LizardTech under this +//C- | license and unmodified by other parties is deemed "the LIZARDTECH +//C- | ORIGINAL CODE." Subject to any third party intellectual property +//C- | claims, LizardTech grants recipient a worldwide, royalty-free, +//C- | non-exclusive license to make, use, sell, or otherwise dispose of +//C- | the LIZARDTECH ORIGINAL CODE or of programs derived from the +//C- | LIZARDTECH ORIGINAL CODE in compliance with the terms of the GNU +//C- | General Public License. This grant only confers the right to +//C- | infringe patent claims underlying the LIZARDTECH ORIGINAL CODE to +//C- | the extent such infringement is reasonably necessary to enable +//C- | recipient to make, have made, practice, sell, or otherwise dispose +//C- | of the LIZARDTECH ORIGINAL CODE (or portions thereof) and not to +//C- | any greater extent that may be necessary to utilize further +//C- | modifications or combinations. +//C- | +//C- | The LIZARDTECH ORIGINAL CODE is provided "AS IS" WITHOUT WARRANTY +//C- | OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +//C- | TO ANY WARRANTY OF NON-INFRINGEMENT, OR ANY IMPLIED WARRANTY OF +//C- | MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. +//C- +------------------------------------------------------------------ +// +// $Id: DjVuMessageLite.cpp,v 1.13 2005/04/27 16:34:13 leonb Exp $ +// $Name: release_3_5_15 $ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif +#if NEED_GNUG_PRAGMAS +# pragma implementation +#endif + +// From: Leon Bottou, 1/31/2002 +// All these I18N XML messages are Lizardtech innovations. +// For DjvuLibre, I changed the path extraction logic +// and added support for non I18N messages. + +#include "DjVuMessageLite.h" +#include "GOS.h" +#include "XMLTags.h" +#include "ByteStream.h" +#include "GURL.h" +#include "debug.h" +#include <ctype.h> +#include <string.h> +#include <stdlib.h> +// #include <stdio.h> +#ifdef WIN32 +#include <tchar.h> +#include <atlbase.h> +#include <windows.h> +#include <winreg.h> +#endif +#ifdef UNIX +#include <unistd.h> +#include <pwd.h> +#include <sys/types.h> +#endif +#include <locale.h> + + +#ifdef HAVE_NAMESPACES +namespace DJVU { +# ifdef NOT_DEFINED // Just to fool emacs c++ mode +} +#endif +#endif + + +const DjVuMessageLite& (*DjVuMessageLite::create)(void) = + DjVuMessageLite::create_lite; + +static const char *failed_to_parse_XML= + ERR_MSG("DjVuMessage.failed_to_parse_XML"); +static const char *unrecognized= + ERR_MSG("DjVuMessage.Unrecognized"); +static const char *uparameter= + ERR_MSG("DjVuMessage.Parameter"); +#ifdef LIZARDTECH_1_800_NUMBER +static const char unrecognized_default[] = + "** Unrecognized DjVu Message: [Contact LizardTech at " + LIZARDTECH_1_800_NUMBER " \n" + "\t** Message name: %1!s!"; +#else +static const char unrecognized_default[] = + "** Unrecognized DjVu Message:\n" + "\t** Message name: %1!s!"; +#endif +static const char uparameter_default[] = + "\t Parameter: %1!s!"; +static const char failed_to_parse_XML_default[]= + "Failed to parse XML message file: 	'%1!s!'."; + +static const char namestring[]="name"; +static const char valuestring[]="value"; +static const char numberstring[]="number"; +static const char bodystring[]="BODY"; +static const char messagestring[]="MESSAGE"; + +GPList<ByteStream> & +DjVuMessageLite::getByteStream(void) +{ + static GPList<ByteStream> gbs; + return gbs; +} + +GP<DjVuMessageLite> & +DjVuMessageLite::getDjVuMessageLite(void) +{ + static GP<DjVuMessageLite> message; + return message; +} + +void +DjVuMessageLite::AddByteStreamLater(const GP<ByteStream> &bs) +{ + getByteStream().append(bs); +} + +// There is only object of class DjVuMessage in a program, and here it is: +//DjVuMessage DjVuMsg; +const DjVuMessageLite & +DjVuMessageLite::create_lite(void) +{ + GP<DjVuMessageLite> &static_message=getDjVuMessageLite(); + if(!static_message) + { + static_message=new DjVuMessageLite; + } + DjVuMessageLite &m=*static_message; + GPList<ByteStream> &bs = getByteStream(); + for(GPosition pos;(pos=bs);bs.del(pos)) + { + m.AddByteStream(bs[pos]); + } + return m; +} + +// Constructor +DjVuMessageLite::DjVuMessageLite( void ) {} + +// Destructor +DjVuMessageLite::~DjVuMessageLite( ) {} + + +void +DjVuMessageLite::perror( const GUTF8String & MessageList ) +{ + DjVuPrintErrorUTF8("%s\n",(const char *)DjVuMessageLite::LookUpUTF8(MessageList)); +} + + +// Expands message lists by looking up the message IDs and inserting +// arguments into the retrieved messages. +// N.B. The resulting string may be encoded in UTF-8 format (ISO 10646-1 Annex R) +// and SHOULD NOT BE ASSUMED TO BE ASCII. +GUTF8String +DjVuMessageLite::LookUp( const GUTF8String & MessageList ) const +{ +// DEBUG_MSG( "========== DjVuMessageLite::LookUp ==========\n" << +// MessageList << +// "\n========== DjVuMessageLite::LookUp ==========\n" ); + GUTF8String result; // Result string; begins empty + if(errors.length()) + { + const GUTF8String err1(errors); + (const_cast<GUTF8String &>(errors)).empty(); + result=LookUp(err1)+"\n"; + } + + int start = 0; // Beginning of next message + int end = MessageList.length(); // End of the message string + + // Isolate single messages and process them + while( start < end ) + { + if( MessageList[start] == '\n' ) + { + result += MessageList[start++]; // move the newline to the result + // and advance to the next message + } + else + { + // Find the end of the next message and process it + int next_ending = MessageList.search((unsigned long)'\n', start); + if( next_ending < 0 ) + next_ending = end; + result += LookUpSingle( MessageList.substr(start, next_ending-start) ); + // Advance to the next message + start = next_ending; + } + } + + // All done + return result; +} + + +// Expands a single message and inserts the arguments. Single_Message +// contains no separators (newlines), but includes all the parameters +// separated by tabs. +GUTF8String +DjVuMessageLite::LookUpSingle( const GUTF8String &Single_Message ) const +{ +#if HAS_CTRL_C_IN_ERR_MSG + if (Single_Message[0] != '\003') + return Single_Message; +#endif + // Isolate the message ID and get the corresponding message text + int ending_posn = Single_Message.contains("\t\v"); + if( ending_posn < 0 ) + ending_posn = Single_Message.length(); + GUTF8String msg_text; + GUTF8String msg_number; + const GUTF8String message=Single_Message.substr(0,ending_posn); + LookUpID( message, msg_text, msg_number ); + + // Check whether we found anything + if( !msg_text.length()) + { + if(message == unrecognized) + { + msg_text = unrecognized_default; + }else if(message == uparameter) + { + msg_text = uparameter_default; + }else if(message == failed_to_parse_XML) + { + msg_text = failed_to_parse_XML_default; + }else + { + return LookUpSingle(unrecognized + ("\t" + Single_Message)); + } + } + + // Insert the parameters (if any) + unsigned int param_num = 0; + while( (unsigned int)ending_posn < Single_Message.length() ) + { + GUTF8String arg; + const int start_posn = ending_posn+1; + if(Single_Message[ending_posn] == '\v') + { + ending_posn=Single_Message.length(); + arg=LookUpSingle(Single_Message.substr(start_posn,ending_posn)); + }else + { + ending_posn = Single_Message.contains("\v\t",start_posn); + if( ending_posn < 0 ) + ending_posn = Single_Message.length(); + arg=Single_Message.substr(start_posn, ending_posn-start_posn); + } + InsertArg( msg_text, ++param_num, arg); + } + // Insert the message number + InsertArg( msg_text, 0, msg_number ); + + return msg_text; +} + + +// Looks up the msgID in the file of messages and returns a pointer to +// the beginning of the translated message, if found; and an empty string +// otherwise. +void +DjVuMessageLite::LookUpID( const GUTF8String &xmsgID, + GUTF8String &message_text, + GUTF8String &message_number ) const +{ + if(!Map.isempty()) + { + GUTF8String msgID = xmsgID; +#if HAS_CTRL_C_IN_ERR_MSG + int start = 0; + while (msgID[start] == '\003') + start ++; + if (start > 0) + msgID = msgID.substr(start, msgID.length() - start); +#endif + GPosition pos=Map.contains(msgID); + if(pos) + { + const GP<lt_XMLTags> tag=Map[pos]; + GPosition valuepos=tag->get_args().contains(valuestring); + if(valuepos) + { + message_text=tag->get_args()[valuepos]; + }else + { + const GUTF8String raw(tag->get_raw()); + const int start_line=raw.search((unsigned long)'\n',0); + + const int start_text=raw.nextNonSpace(0); + const int end_text=raw.firstEndSpace(0); + if(start_line<0 || start_text<0 || start_text < start_line) + { + message_text=raw.substr(0,end_text).fromEscaped(); + }else + { + message_text=raw.substr(start_line+1,end_text-start_line-1).fromEscaped(); + } + } + GPosition numberpos=tag->get_args().contains(numberstring); + if(numberpos) + { + message_number=tag->get_args()[numberpos]; + } + } + } +} + + +// Insert a string into the message text. Will insert into any field +// description. Except for an ArgId of zero (message number), if the ArgId +// is not found, the routine adds a line with the parameter so information +// will not be lost. +void +DjVuMessageLite::InsertArg( GUTF8String &message, + const int ArgId, const GUTF8String &arg ) const +{ + // argument target string + const GUTF8String target= "%"+GUTF8String(ArgId)+"!"; + // location of target string + int format_start = message.search( (const char *)target ); + if( format_start >= 0 ) + { + do + { + const int n=format_start+target.length()+1; + const int format_end=message.search((unsigned long)'!',n); + if(format_end > format_start) + { + const int len=1+format_end-n; + if(len && isascii(message[n-1])) + { + GUTF8String narg; + GUTF8String format="%"+message.substr(n-1,len); + switch(format[len]) + { + case 'd': + case 'i': + narg.format((const char *)format,arg.toInt()); + break; + case 'u': + case 'o': + case 'x': + case 'X': + narg.format((const char *)format,(unsigned int)arg.toInt()); + break; + case 'f': + { + int endpos; + narg.format((const char *)format, arg.toDouble(0,endpos)); + if( endpos < 0 ) + narg = arg; + } + break; + default: + narg.format((const char *)format,(const char *)arg); + break; + } + message = message.substr( 0, format_start )+narg + +message.substr( format_end+1, -1 ); + }else + { + message = message.substr( 0, format_start )+arg + +message.substr( format_end+1, -1 ); + } + } + format_start=message.search((const char*)target, format_start+arg.length()); + } while(format_start >= 0); + } + else + { + // Not found, fake it + if( ArgId != 0 ) + { + message += "\n"+LookUpSingle(uparameter+("\t"+arg)); + } + } +} + + +// A C function to perform a message lookup. Arguments are a buffer to received the +// translated message, a buffer size (bytes), and a message_list. The translated +// result is returned in msg_buffer encoded in UTF-8. In case of error, msg_buffer is +// empty (i.e., msg_buffer[0] == '\0'). +void +DjVuMessageLite_LookUp( char *msg_buffer, const unsigned int buffer_size, const char *message ) +{ + GUTF8String converted = DjVuMessageLite::LookUpUTF8( message ); + if( converted.length() >= buffer_size ) + msg_buffer[0] = '\0'; + else + strcpy( msg_buffer, converted ); +} + +void +DjVuMessageLite::AddByteStream(const GP<ByteStream> &bs) +{ + const GP<lt_XMLTags> gtags(lt_XMLTags::create(bs)); + lt_XMLTags &tags=*gtags; + GPList<lt_XMLTags> Bodies=tags.get_Tags(bodystring); + if(! Bodies.isempty()) + { + lt_XMLTags::get_Maps(messagestring,namestring,Bodies,Map); + } +} + + + +#ifdef HAVE_NAMESPACES +} +# ifndef NOT_USING_DJVU_NAMESPACE +using namespace DJVU; +# endif +#endif + +void +DjVuWriteError( const char *message ) +{ + G_TRY { + GP<ByteStream> errout = ByteStream::get_stderr(); + if (errout) + { + const GUTF8String external = DjVuMessageLite::LookUpUTF8( message ); + errout->writestring(external+"\n"); + } + // Need to catch all exceptions because these might be + // called from an outer exception handler (with prejudice) + } G_CATCH_ALL { } G_ENDCATCH; +} + +void +DjVuWriteMessage( const char *message ) +{ + G_TRY { + GP<ByteStream> strout = ByteStream::get_stdout(); + if (strout) + { + const GUTF8String external = DjVuMessageLite::LookUpUTF8( message ); + strout->writestring(external+"\n"); + } + // Need to catch all exceptions because these might be + // called from an outer exception handler (with prejudice) + } G_CATCH_ALL { } G_ENDCATCH; +} |