예제 #1
0
unsigned int FAR PASCAL SJIS2UTF8(WORD KCode, int *byte, char *locale)
{
	wchar_t wchar;
	int ret;
	unsigned int code = KCode;
	unsigned int c, c1, c2, c3;
	unsigned char *ptr, buf[3];
	unsigned short cset;
	int len = 0;

	*byte = 2;

	// CP932からUTF-16LEへ変換する
	setlocale(LC_ALL, locale);

	buf[0] = KCode >> 8;
	if (buf[0] > 0) {
		len++;
	}
	buf[len++] = KCode & 0xff;
	ret = mbtowc(&wchar, buf, len);
	if (ret <= 0) { // 変換失敗
		cset = 0;
		if (_stricmp(locale, DEFAULT_LOCALE) == 0) {
			cset = ConvertUnicode(KCode, mapSJISToUnicode, sizeof(mapSJISToUnicode)/sizeof(mapSJISToUnicode[0]));
		}
		if (cset == 0) {
			c = 0xfffd; // U+FFFD: Replacement Character
		} else {
			c = cset;
		}
	} else {
		ptr = (unsigned char *)&wchar;
		c = ((ptr[1] << 8) | ptr[0]);
	}

	// UTF-16LEからUTF-8へ変換する
	if (0x00000000 <= c && c <= 0x0000007f) {
		code = (c & 0xff);
		*byte = 1;

	} else if (0x00000080 <= c && c <= 0x000007ff) {
		c1 = ((c >> 6) & 0x1f) | 0xc0;
		c2 = (c & 0x3f) | 0x80;
		code = (c1 << 8) | c2;
		*byte = 2;

	} else if (0x00000800 <= c && c <= 0x0000ffff) {
예제 #2
0
파일: parser.cpp 프로젝트: zapta/misc
void ProcessNextChar(char c) {
  if (c == '\n') {
    state = jsBegin;  // abandon current parse (if any) and start again
    return;
  }

  switch (state) {
    case jsBegin:  // initial state, expecting '{'
      if (c == '{') {
        parser_watcher::StartReceivedMessage();
        state = jsExpectId;
        fieldVal.clear();
        fieldId.clear();
        arrayDepth = 0;
      }
      break;

    case jsExpectId:  // expecting a quoted ID
      switch (c) {
        case ' ':  // ignore space
          break;
        case '"':
          state = jsId;
          break;
        case '}':  // empty object, or extra comma at end of field list
          RemoveLastId();
          if (fieldId.size() == 0) {
            // TODO: should we report this to the monitor as an error?
            parser_watcher::EndReceivedMessage();
            state = jsBegin;
          } else {
            RemoveLastIdChar();
            state = jsEndVal;
          }
          break;
        default:
          state = JsError();
          break;
      }
      break;

    case jsId:  // expecting an identifier, or in the middle of one
      switch (c) {
        case '"':
          state = jsHadId;
          break;
        default:
          if (c < ' ') {
            state = JsError();
          } else if (c != ':' && c != '^') {
            if (!fieldId.add(c)) {
              state = JsError();
            }
          }
          break;
      }
      break;

    case jsHadId:  // had a quoted identifier, expecting ':'
      switch (c) {
        case ':':
          state = jsVal;
          break;
        case ' ':
          break;
        default:
          state = JsError();
          break;
      }
      break;

    case jsVal:  // had ':' or ':[', expecting value
      switch (c) {
        case ' ':
          break;
        case '"':
          fieldVal.clear();
          state = jsStringVal;
          break;
        case '[':
          if (arrayDepth < MAX_ARRAY_NESTING && fieldId.add('^')) {
            arrayIndices[arrayDepth] = 0;  // start an array
            ++arrayDepth;
          } else {
            state = JsError();
          }
          break;
        case ']':
          if (InArray()) {
            EndArray();  // empty array
            state = jsEndVal;
          } else {
            state = JsError();  // ']' received without a matching '[' first
          }
          break;
        case '-':
          fieldVal.clear();
          // TODO: an report error to the watcher
          state = (fieldVal.add(c)) ? jsNegIntVal : JsError();
          break;
        case '{':  // start of a nested object
                   // TODO: report an error to the watcher
          state = (fieldId.add(':')) ? jsExpectId : JsError();
          break;
        default:
          if (c >= '0' && c <= '9') {
            fieldVal.clear();
            fieldVal.add(c);  // must succeed because we just cleared fieldVal
            state = jsIntVal;
            break;
          } else {
            state = JsError();
          }
      }
      break;

    case jsStringVal:  // just had '"' and expecting a string value
      switch (c) {
        case '"':
          ConvertUnicode();
          ProcessField();
          state = jsEndVal;
          break;
        case '\\':
          state = jsStringEscape;
          break;
        default:
          if (c < ' ') {
            state = JsError();
          } else {
            fieldVal.add(c);  // ignore any error so that long string parameters
                              // just get truncated
          }
          break;
      }
      break;

    case jsStringEscape:  // just had backslash in a string
      if (!fieldVal.full()) {
        switch (c) {
          case '"':
          case '\\':
          case '/':
            if (!fieldVal.add(c)) {
              state = JsError();
            }
            break;
          case 'n':
          case 't':
            if (!fieldVal.add(' '))  // replace newline and tab by space
            {
              // parser_watcher::ProcessError();

              state = JsError();
            }
            break;
          case 'b':
          case 'f':
          case 'r':
          default:
            break;
        }
      }
      state = jsStringVal;
      break;

    case jsNegIntVal:  // had '-' so expecting a integer value
                       // TODO: report an error to the watcher
      state = (c >= '0' && c <= '9' && fieldVal.add(c)) ? jsIntVal : JsError();
      break;

    case jsIntVal:  // receiving an integer value
      switch (c) {
        case '.':
          state = (fieldVal.add(c)) ? jsFracVal : JsError();
          break;
        case ',':
          ProcessField();
          if (InArray()) {
            ++arrayIndices[arrayDepth - 1];
            fieldVal.clear();
            state = jsVal;
          } else {
            RemoveLastId();
            state = jsExpectId;
          }
          break;
        case ']':
          if (InArray()) {
            ProcessField();
            ++arrayIndices[arrayDepth - 1];
            EndArray();
            state = jsEndVal;
          } else {
            state = JsError();
          }
          break;
        case '}':
          if (InArray()) {
            state = JsError();
          } else {
            ProcessField();
            RemoveLastId();
            if (fieldId.size() == 0) {
              parser_watcher::EndReceivedMessage();
              state = jsBegin;
            } else {
              RemoveLastIdChar();
              state = jsEndVal;
            }
          }
          break;
        default:
          if (!(c >= '0' && c <= '9' && fieldVal.add(c))) {
            state = JsError();
          }
          break;
      }
      break;

    case jsFracVal:  // receiving a fractional value
      switch (c) {
        case ',':
          ProcessField();
          if (InArray()) {
            ++arrayIndices[arrayDepth - 1];
            state = jsVal;
          } else {
            RemoveLastId();
            state = jsExpectId;
          }
          break;
        case ']':
          if (InArray()) {
            ProcessField();
            ++arrayIndices[arrayDepth - 1];
            EndArray();
            state = jsEndVal;
          } else {
            state = JsError();
          }
          break;
        case '}':
          if (InArray()) {
            state = JsError();
          } else {
            ProcessField();
            RemoveLastId();
            if (fieldId.size() == 0) {
              parser_watcher::EndReceivedMessage();
              state = jsBegin;
            } else {
              RemoveLastIdChar();
              state = jsEndVal;
            }
          }
          break;
        default:
          if (!(c >= '0' && c <= '9' && fieldVal.add(c))) {
            state = JsError();
          }
          break;
      }
      break;

    case jsEndVal:  // had the end of a string or array value, expecting comma
                    // or ] or }
      switch (c) {
        case ',':
          if (InArray()) {
            ++arrayIndices[arrayDepth - 1];
            fieldVal.clear();
            state = jsVal;
          } else {
            RemoveLastId();
            state = jsExpectId;
          }
          break;
        case ']':
          if (InArray()) {
            ++arrayIndices[arrayDepth - 1];
            EndArray();
          } else {
            state = JsError();
          }
          break;
        case '}':
          if (InArray()) {
            state = JsError();
          } else {
            RemoveLastId();
            if (fieldId.size() == 0) {
              parser_watcher::EndReceivedMessage();
              state = jsBegin;
            } else {
              RemoveLastIdChar();
              // state = jsEndVal;     // not needed, state == jsEndVal already
            }
          }
          break;
        default:
          break;
      }
      break;

    case jsError:
      // Ignore all characters. State will be reset to jsBegin at the start of
      // this function when we receive a newline.
      break;
  }
}