UCS2 *Parser::String_Literal_To_UCS2(const char *str, bool pathname) { UCS2 *char_string = NULL; UCS2 *char_array = NULL; int char_array_size = 0; int utf8arraysize = 0; unsigned char *utf8array = NULL; int index_in = 0; int index_out = 0; char buffer[8]; char *dummy_ptr = NULL; int i = 0; if(strlen(str) == 0) { char_string = reinterpret_cast<UCS2 *>(POV_MALLOC(sizeof(UCS2), "UCS2 String")); char_string[0] = 0; return char_string; } switch(sceneData->stringEncoding) { case kStringEncoding_ASCII: char_array_size = (int)strlen(str); char_array = reinterpret_cast<UCS2 *>(POV_MALLOC(char_array_size * sizeof(UCS2), "Character Array")); for(i = 0; i < char_array_size; i++) { if(sceneData->EffectiveLanguageVersion() < 350) char_array[i] = (unsigned char)(str[i]); else { char_array[i] = str[i] & 0x007F; if(char_array[i] != str[i]) { char_array[i] = ' '; PossibleError("Non-ASCII character has been replaced by space character."); } } } break; case kStringEncoding_UTF8: char_array = Convert_UTF8_To_UCS2(reinterpret_cast<const unsigned char *>(str), (int)strlen(str), &char_array_size); break; case kStringEncoding_System: char_array = POV_CONVERT_TEXT_TO_UCS2(reinterpret_cast<const unsigned char *>(str), strlen(str), &char_array_size); if(char_array == NULL) Error("Cannot convert system specific text format to Unicode."); break; default: Error("Unsupported text encoding format."); break; } if(char_array == NULL) Error("Cannot convert text to UCS2 format."); char_string = reinterpret_cast<UCS2 *>(POV_MALLOC((char_array_size + 1) * sizeof(UCS2), "UCS2 String")); for(index_in = 0, index_out = 0; index_in < char_array_size; index_in++, index_out++) { if((char_array[index_in] == '\\') && (sceneData->EffectiveLanguageVersion() >= 371 || !pathname)) { // Historically, escape sequences were ignored when parsing for a filename. // As of POV-Ray 3.71, this has been changed. #if (FILENAME_SEPARATOR == '\\') if (pathname) { Warning("Backslash encountered while parsing for a filename." " As of version 3.71, this is interpreted as an escape sequence just like in any other string literal." " If this is supposed to be a path separator, use a forward slash instead."); } #endif index_in++; switch(char_array[index_in]) { case 'a': char_string[index_out] = 0x07; break; case 'b': char_string[index_out] = 0x08; break; case 'f': char_string[index_out] = 0x0c; break; case 'n': char_string[index_out] = 0x0a; break; case 'r': char_string[index_out] = 0x0d; break; case 't': char_string[index_out] = 0x09; break; case 'v': char_string[index_out] = 0x0b; break; case '\0': // [CLi] shouldn't happen, as having a backslash as the last character of a string literal would invalidate the string terminator Error("Unexpected end of escape sequence in text string."); break; case '\'': case '\"': case '\\': char_string[index_out] = char_array[index_in]; break; case 'u': if(index_in + 4 >= char_array_size) Error("Unexpected end of escape sequence in text string."); buffer[0] = char_array[++index_in]; buffer[1] = char_array[++index_in]; buffer[2] = char_array[++index_in]; buffer[3] = char_array[++index_in]; buffer[4] = 0; char_string[index_out] = (UCS2)strtoul(buffer, &dummy_ptr, 16); break; default: char_string[index_out] = char_array[index_in]; if ( char_array ) POV_FREE(char_array); char_array = NULL; Error( "Illegal escape sequence in string." ); break; } } else { if ((char_array[index_in] == '\\') && pathname) { // Historically, escape sequences were ignored when parsing for a filename. // As of POV-Ray 3.71, this has been changed. #if (FILENAME_SEPARATOR == '\\') Warning("Backslash encountered while parsing for a filename." " In legacy (pre-3.71) scenes, this is NOT interpreted as the start of an escape sequence." " However, for future compatibility it is recommended to use a forward slash as path separator instead."); #else Warning("Backslash encountered while parsing for a filename." " In legacy (pre-3.71) scenes, this is NOT interpreted as the start of an escape sequence."); #endif } char_string[index_out] = char_array[index_in]; } } char_string[index_out] = 0; index_out++; char_string = reinterpret_cast<UCS2 *>(POV_REALLOC(char_string, index_out * sizeof(UCS2), "UCS2 String")); if(char_array != NULL) POV_FREE(char_array); return char_string; }
UCS2 *Parser::String_To_UCS2(const char *str, bool pathname) { UCS2 *char_string = NULL; UCS2 *char_array = NULL; int char_array_size = 0; int utf8arraysize = 0; unsigned char *utf8array = NULL; int index_in = 0; int index_out = 0; char buffer[8]; char *dummy_ptr = NULL; int i = 0; if(strlen(str) == 0) { char_string = reinterpret_cast<UCS2 *>(POV_MALLOC(sizeof(UCS2), "UCS2 String")); char_string[0] = 0; return char_string; } switch(sceneData->stringEncoding) { case 0: // ASCII char_array_size = (int)strlen(str); char_array = reinterpret_cast<UCS2 *>(POV_MALLOC(char_array_size * sizeof(UCS2), "Character Array")); for(i = 0; i < char_array_size; i++) { if(sceneData->languageVersion < 350) char_array[i] = (unsigned char)(str[i]); else { char_array[i] = str[i] & 0x007F; if(char_array[i] != str[i]) { char_array[i] = ' '; PossibleError("Non-ASCII character has been replaced by space character."); } } } break; case 1: // UTF8 char_array = Convert_UTF8_To_UCS2(reinterpret_cast<const unsigned char *>(str), (int)strlen(str), &char_array_size); break; case 2: // System Specific char_array = POV_CONVERT_TEXT_TO_UCS2(reinterpret_cast<const unsigned char *>(str), strlen(str), &char_array_size); if(char_array == NULL) Error("Cannot convert system specific text format to Unicode."); break; default: Error("Unsupported text encoding format."); break; } if(char_array == NULL) Error("Cannot convert text to UCS2 format."); char_string = reinterpret_cast<UCS2 *>(POV_MALLOC((char_array_size + 1) * sizeof(UCS2), "UCS2 String")); for(index_in = 0, index_out = 0; index_in < char_array_size; index_in++, index_out++) { if((char_array[index_in] == '\\') && (pathname == false)) { index_in++; switch(char_array[index_in]) { case 'a': char_string[index_out] = 0x07; break; case 'b': char_string[index_out] = 0x08; break; case 'f': char_string[index_out] = 0x0c; break; case 'n': char_string[index_out] = 0x0a; break; case 'r': char_string[index_out] = 0x0d; break; case 't': char_string[index_out] = 0x09; break; case 'v': char_string[index_out] = 0x0b; break; case '\0': char_string[index_out] = 0x5c; break; case '\'': char_string[index_out] = 0x27; break; case '\\': char_string[index_out] = '\\'; break; case 'u': if(index_in + 4 >= char_array_size) Error("Unexpected end of escape sequence in text string."); buffer[0] = char_array[++index_in]; buffer[1] = char_array[++index_in]; buffer[2] = char_array[++index_in]; buffer[3] = char_array[++index_in]; buffer[4] = 0; char_string[index_out] = (UCS2)strtoul(buffer, &dummy_ptr, 16); break; default: char_string[index_out] = char_array[index_in]; if ( char_array ) POV_FREE(char_array); char_array = NULL; Error( "Illegal escape sequence in string." ); break; } } else char_string[index_out] = char_array[index_in]; } char_string[index_out] = 0; index_out++; char_string = reinterpret_cast<UCS2 *>(POV_REALLOC(char_string, index_out * sizeof(UCS2), "UCS2 String")); if(char_array != NULL) POV_FREE(char_array); return char_string; }
UCS2 *Parser::String_To_UCS2(const char *str) { UCS2 *char_string = NULL; UCS2 *char_array = NULL; int char_array_size = 0; int utf8arraysize = 0; unsigned char *utf8array = NULL; int index_in = 0; int index_out = 0; char *dummy_ptr = NULL; int i = 0; if(strlen(str) == 0) { char_string = reinterpret_cast<UCS2 *>(POV_MALLOC(sizeof(UCS2), "UCS2 String")); char_string[0] = 0; return char_string; } switch(sceneData->stringEncoding) { case kStringEncoding_ASCII: char_array_size = (int)strlen(str); char_array = reinterpret_cast<UCS2 *>(POV_MALLOC(char_array_size * sizeof(UCS2), "Character Array")); for(i = 0; i < char_array_size; i++) { if(sceneData->EffectiveLanguageVersion() < 350) char_array[i] = (unsigned char)(str[i]); else { char_array[i] = str[i] & 0x007F; if(char_array[i] != str[i]) { char_array[i] = ' '; PossibleError("Non-ASCII character has been replaced by space character."); } } } break; case kStringEncoding_UTF8: char_array = Convert_UTF8_To_UCS2(reinterpret_cast<const unsigned char *>(str), (int)strlen(str), &char_array_size); break; case kStringEncoding_System: char_array = POV_CONVERT_TEXT_TO_UCS2(reinterpret_cast<const unsigned char *>(str), strlen(str), &char_array_size); if(char_array == NULL) Error("Cannot convert system specific text format to Unicode."); break; default: Error("Unsupported text encoding format."); break; } if(char_array == NULL) Error("Cannot convert text to UCS2 format."); char_string = reinterpret_cast<UCS2 *>(POV_MALLOC((char_array_size + 1) * sizeof(UCS2), "UCS2 String")); for(index_in = 0, index_out = 0; index_in < char_array_size; index_in++, index_out++) char_string[index_out] = char_array[index_in]; char_string[index_out] = 0; index_out++; if(char_array != NULL) POV_FREE(char_array); return char_string; }