2012-12-20 24 views
6

मैं सी में एक HTML पार्सर लिख रहा हूं, और the W3C guidelines on parser implementation का सही ढंग से अनुसरण करने के लिए देख रहा हूं। मुख्य बिंदुओं में से एक यह है कि पार्सर बाइट्स की बजाय यूनिकोड कोड पॉइंट्स की धारा पर काम करता है, जो समझ में आता है।सी में बाइट्स से यूनिकोड कोड पॉइंट्स का स्ट्रीम?

असल में, तो, ज्ञात वर्ण एन्कोडिंग के एक बफर दिया (मैं या तो एक स्पष्ट इनपुट एनकोडिंग दिया जाएगा, या एक अच्छा अनुमान लगाने के लिए एचटीएमएल 5 Prescan एल्गोरिथ्म का उपयोग करेगा), क्या सी में सबसे अच्छा तरीका है - आदर्श क्रॉस-प्लेटफार्म, लेकिन यूनिक्स को चिपकाना ठीक है - यूनिकोड कोड पॉइंट्स के बराबर अनुक्रम पर फिर से शुरू करने के लिए?

कुछ उचित आकार के बफर आवंटित कर रहे हैं और iconv का उपयोग करने का तरीका उपयोग कर रहे हैं? क्या मुझे आईसीयू देखना चाहिए? U16_NEXT जैसे मैक्रोज़ मेरे काम के लिए उपयुक्त हैं, लेकिन आईसीयू दस्तावेज अविश्वसनीय रूप से लंबे समय से हवादार है, और यह देखने में थोड़ा मुश्किल है कि चीजों को एक साथ कैसे चिपकाया जाए।

+0

'iconv' एक अच्छी शुरुआत की तरह लगता है। यह अवधारणात्मक रूप से सरल और व्यापक रूप से उपलब्ध है। –

+0

ठीक है, मैं कोशिश करूँगा 'iconv'। क्या आप कहेंगे कि यह यूटीएफ -32 में परिवर्तित करने के लिए सबसे अधिक समझ में आता है? भले ही यह तर्कसंगत रूप से लगभग बेकार एन्कोडिंग है, इसका मतलब यह होगा कि प्रत्येक 4 बाइट्स वास्तव में यूनिकोड कोड पॉइंट का प्रतिनिधित्व करेंगे। –

+1

हां, वास्तव में। यूटीएफ -32 एक बिल्कुल ठीक एन्कोडिंग है। –

उत्तर

2

आईसीयू एक अच्छा विकल्प है। मैंने इसे सी ++ के साथ इस्तेमाल किया और इसे बहुत पसंद आया। मुझे पूरा यकीन है कि आप सी में समान विचार-एपीआई एपीआई भी प्राप्त करते हैं।

नहीं पूरी तरह से एक ही लेकिन कुछ हद तक संबंधित इस tutorial बताते हैं कि कैसे स्ट्रीमिंग/वृद्धिशील लिप्यंतरण प्रदर्शन करने के लिए (इस मामले में कठिनाई यह है कि "कर्सर" अंदर एक कोड बिंदु कभी कभी हो सकता है) हो सकता है।

0

दो बातें आपकी रुचि का हो सकता है:

  1. Markus Kuhn Unicode tutorials
  2. lib9, Plan9, ओएस से utf पुस्तकालय जो UTF के आविष्कारक पर काम कर रहे थे।
2

निम्नलिखित कोड बिंदु को डीकोड करेगा और स्ट्रिंग को कितना बढ़ाएगा (कितना "चबाना" था) लौटाएगा। ध्यान दें कि xs_utf16 एक हस्ताक्षरित छोटा है। अधिक जानकारी: http://sree.kotay.com/2006/12/unicode-is-pain-in.html

enum 
{ 
    xs_UTF_Max   = 0x0010FFFFUL, 
    xs_UTF_Replace  = 0x0000FFFDUL, 
    xs_UTF16_HalfBase = 0x00010000UL, 
    xs_UTF16_HighStart = 0x0000D800UL, 
    xs_UTF16_HighEnd = 0x0000DBFFUL, 
    xs_UTF16_LowStart = 0x0000DC00UL, 
    xs_UTF16_LowEnd  = 0x0000DFFFUL, 
    xs_UTF16_MaxUCS2 = 0x0000FFFFUL, 
    xs_UTF16_HalfMask = 0x000003FFUL, 
    xs_UTF16_HalfShift = 10 
}; 


int32 xs_UTF16Decode (uint32 &code, const xs_utf16* str, int32 len, bool strict) 
{ 
      if (str==0||len==0)   {code=0; return 0;} 

      uint32 c1 = str[0]; 

      //note: many implementations test from HighStart to HighEnd, 
      //     this may be a partial code point, and is incorrect(?) 
      //     trivial checking should exclude the WHOLE surrogate range 
      if (c1<xs_UTF16_HighStart || c1>xs_UTF16_LowEnd)   return 1; 
          //really an error if we're starting in the low range 

      //surrogate pair 
      if (len<=1 || str[1]==0)         {code=xs_UTF_Replace; return strict ? 0 : 1;} //error 
      uint32 c2 = str[1]; 
      code = ((c1-xs_UTF16_HighStart)<<xs_UTF16_HalfShift) + (c2-xs_UTF16_LowStart) + xs_UTF16_HalfBase; 

      if (strict==false)          return 2; 

      //check for errors 
      if (c1>=xs_UTF16_LowStart && c1<=xs_UTF16_LowEnd)   {code=xs_UTF_Replace; return 0;} //error 
      if (c2<xs_UTF16_LowStart || c2>xs_UTF16_LowEnd)   {code=xs_UTF_Replace; return 0;} //error 
      if (code>xs_UTF_Max)          {code=xs_UTF_Replace; return 0;} //error 

      //success 
      return 2; 
}