bool PMDHandler::doLoad(Model& model, istream& stream) noexcept { PMD _pmd; if (!stream.read((char*)&_pmd.Header, sizeof(_pmd.Header))) return false; // vertex if (!stream.read((char*)&_pmd.VertexCount, sizeof(_pmd.VertexCount))) return false; if (_pmd.VertexCount > 0) { _pmd.VertexList.resize(_pmd.VertexCount); if (!stream.read((char*)&_pmd.VertexList[0], (std::streamsize)(sizeof(PMD_Vertex)* _pmd.VertexCount))) return false; } // index if (!stream.read((char*)&_pmd.IndexCount, sizeof(_pmd.IndexCount))) return false; if (_pmd.IndexCount > 0) { _pmd.IndexList.resize(_pmd.IndexCount); if (!stream.read((char*)&_pmd.IndexList[0], (std::streamsize)(sizeof(PMD_Index)* _pmd.IndexCount))) return false; } // materal if (!stream.read((char*)&_pmd.MaterialCount, sizeof(_pmd.MaterialCount))) return false; if (_pmd.MaterialCount > 0) { _pmd.MaterialList.resize(_pmd.MaterialCount); if (!stream.read((char*)&_pmd.MaterialList[0], (std::streamsize)(sizeof(PMD_Material)* _pmd.MaterialCount))) return false; } // bone if (!stream.read((char*)&_pmd.BoneCount, sizeof(_pmd.BoneCount))) return false; if (_pmd.BoneCount > 0) { _pmd.BoneList.resize(_pmd.BoneCount); if (!stream.read((char*)&_pmd.BoneList[0], (std::streamsize)(sizeof(PMD_Bone)* _pmd.BoneCount))) return false; } // IK if (!stream.read((char*)&_pmd.IkCount, sizeof(_pmd.IkCount))) return false; if (_pmd.IkCount > 0) { _pmd.IkList.resize(_pmd.IkCount); for (std::size_t i = 0; i < (std::size_t)_pmd.IkCount; i++) { if (!stream.read((char*)&_pmd.IkList[i].IK, sizeof(_pmd.IkList[i].IK))) return false; if (!stream.read((char*)&_pmd.IkList[i].Target, sizeof(_pmd.IkList[i].Target))) return false; if (!stream.read((char*)&_pmd.IkList[i].LinkCount, sizeof(_pmd.IkList[i].LinkCount))) return false; if (!stream.read((char*)&_pmd.IkList[i].LoopCount, sizeof(_pmd.IkList[i].LoopCount))) return false; if (!stream.read((char*)&_pmd.IkList[i].LimitOnce, sizeof(_pmd.IkList[i].LimitOnce))) return false; _pmd.IkList[i].LinkList.resize(_pmd.IkList[i].LinkCount); if (!stream.read((char*)&_pmd.IkList[i].LinkList[0], (std::streamsize)(sizeof(PMD_Link)* _pmd.IkList[i].LinkCount))) return false; } } // Morph if (!stream.read((char*)&_pmd.MorphCount, sizeof(_pmd.MorphCount))) return false; if (_pmd.MorphCount > 0) { _pmd.MorphList.resize(_pmd.MorphCount); for (std::size_t i = 0; i < (std::size_t)_pmd.MorphCount; i++) { if (!stream.read((char*)&_pmd.MorphList[i].Name, sizeof(_pmd.MorphList[i].Name))) return false; if (!stream.read((char*)&_pmd.MorphList[i].VertexCount, sizeof(_pmd.MorphList[i].VertexCount))) return false; if (!stream.read((char*)&_pmd.MorphList[i].Category, sizeof(_pmd.MorphList[i].Category))) return false; if (_pmd.MorphList[i].VertexCount > 0) { _pmd.MorphList[i].VertexList.resize(_pmd.MorphList[i].VertexCount); if (!stream.read((char*)&_pmd.MorphList[i].VertexList[0], (std::streamsize)(sizeof(PMD_MorphVertex)* _pmd.MorphList[i].VertexCount))) return false; } } } // frame window if (!stream.read((char*)&_pmd.FrameWindow.ExpressionListCount, sizeof(_pmd.FrameWindow.ExpressionListCount))) return false; if (_pmd.FrameWindow.ExpressionListCount > 0) { _pmd.FrameWindow.ExpressionList.resize(_pmd.FrameWindow.ExpressionListCount); if (!stream.read((char*)&_pmd.FrameWindow.ExpressionList[0], (std::streamsize)(sizeof(PMD_Expression)* _pmd.FrameWindow.ExpressionListCount))) return false; } if (!stream.read((char*)&_pmd.FrameWindow.NodeNameCount, sizeof(_pmd.FrameWindow.NodeNameCount))) return false; if (_pmd.FrameWindow.NodeNameCount > 0) { _pmd.FrameWindow.NodeNameList.resize(_pmd.FrameWindow.NodeNameCount); if (!stream.read((char*)&_pmd.FrameWindow.NodeNameList[0].Name, (std::streamsize)(sizeof(PMD_NodeName)* _pmd.FrameWindow.NodeNameCount))) return false; } if (!stream.read((char*)&_pmd.FrameWindow.BoneToNodeCount, sizeof(_pmd.FrameWindow.BoneToNodeCount))) return false; if (_pmd.FrameWindow.BoneToNodeCount > 0) { _pmd.FrameWindow.BoneToNodeList.resize(_pmd.FrameWindow.BoneToNodeCount); if (!stream.read((char*)&_pmd.FrameWindow.BoneToNodeList[0].Bone, (std::streamsize)(sizeof(PMD_BoneToNode)* _pmd.FrameWindow.BoneToNodeCount))) return false; } // description if (!stream.read((char*)&_pmd.HasDescription, sizeof(_pmd.HasDescription))) return false; if (_pmd.HasDescription) { if (!stream.read((char*)&_pmd.Description.ModelName, sizeof(_pmd.Description.ModelName))) return false; if (!stream.read((char*)&_pmd.Description.Comment, sizeof(_pmd.Description.Comment))) return false; for (PMD_BoneCount i = 0; i < _pmd.BoneCount; i++) { PMD_BoneName name; if (!stream.read((char*)&name.Name, sizeof(name))) return false; _pmd.Description.BoneName.push_back(name); } for (PMD_uint8_t i = 0; i < _pmd.FrameWindow.ExpressionListCount; i++) { PMD_MorphName name; if (!stream.read((char*)&name.Name, sizeof(name))) return false; _pmd.Description.FaceName.push_back(name); } for (PMD_uint8_t i = 0; i < _pmd.FrameWindow.NodeNameCount; i++) { PMD_NodeName name; if (!stream.read((char*)&name.Name, sizeof(name))) return false; _pmd.Description.FrameName.push_back(name); } } // toon _pmd.ToonCount = PMD_NUM_TOON; _pmd.ToonList.resize(_pmd.ToonCount); if (!stream.read((char*)&_pmd.ToonList[0].Name, (std::streamsize)(sizeof(PMD_Toon) * _pmd.ToonCount))) return false; // rigidbody if (!stream.read((char*)&_pmd.BodyCount, sizeof(_pmd.BodyCount))) return false; if (_pmd.BodyCount > 0) { _pmd.BodyList.resize(_pmd.BodyCount); if (!stream.read((char*)&_pmd.BodyList[0], (std::streamsize)(sizeof(PMD_Body)* _pmd.BodyCount))) return false; } // joint if (!stream.read((char*)&_pmd.JointCount, sizeof(_pmd.JointCount))) return false; if (_pmd.JointCount > 0) { _pmd.JointList.resize(_pmd.JointCount); if (!stream.read((char*)&_pmd.JointList[0], (std::streamsize)(sizeof(PMD_Body)* _pmd.JointCount))) return false; } for (std::size_t index = 0; index < _pmd.MaterialList.size(); index++) { auto& it = _pmd.MaterialList[index]; auto material = std::make_shared<MaterialProperty>(); material->set(MATKEY_COLOR_DIFFUSE, it.Diffuse); material->set(MATKEY_COLOR_AMBIENT, it.Ambient); material->set(MATKEY_COLOR_SPECULAR, it.Specular); material->set(MATKEY_OPACITY, it.Opacity); material->set(MATKEY_SHININESS, it.Shininess); std::string name = it.TextureName; std::string::size_type substr = name.find_first_of("*"); if (substr != std::string::npos) { name.erase(name.begin() + substr, name.end()); } material->set(MATKEY_TEXTURE_DIFFUSE(0), name); material->set(MATKEY_TEXTURE_AMBIENT(0), name); model.addMaterial(material); } PMD_Index* indices = _pmd.IndexList.data(); PMD_Vertex* vertices = _pmd.VertexList.data(); MeshPropertyPtr root = std::make_shared<MeshProperty>(); MeshPropertyPtr mesh = root; MeshPropertyPtr last = nullptr; for (std::size_t index = 0; index < _pmd.MaterialList.size(); index++) { auto& it = _pmd.MaterialList[index]; Vector3Array points; Vector3Array normals; Vector2Array texcoords; VertexWeights weights; UintArray faces; for (PMD_IndexCount i = 0; i < it.FaceVertexCount; i++, indices++) { PMD_Vertex& v = vertices[*indices]; points.push_back(v.Position); normals.push_back(v.Normal); texcoords.push_back(v.UV); faces.push_back(i); VertexWeight weight; weight.weight1 = v.Weight / 100.0; weight.weight2 = 1.0 - weight.weight1; weight.weight3 = 0.0f; weight.weight4 = 0.0f; weight.bone1 = v.Bone.Bone1; weight.bone2 = v.Bone.Bone2; weight.bone3 = 0; weight.bone4 = 0; weights.push_back(weight); } if (last == mesh) { mesh = std::make_shared<MeshProperty>(); root->addChild(mesh); } mesh->setMaterialID(index); mesh->setVertexArray(points); mesh->setNormalArray(normals); mesh->setTexcoordArray(texcoords); mesh->setWeightArray(weights); mesh->setFaceArray(faces); last = mesh; } if (_pmd.BoneCount > 0) { Bones bones; InverseKinematics iks; for (auto& it : _pmd.BoneList) { Bone bone; char inbuf[MAX_PATH + 1] = { 0 }; char outbuf[MAX_PATH + 1] = { 0 }; char *in = inbuf; char *out = outbuf; std::size_t in_size = (size_t)MAX_PATH; std::size_t out_size = (size_t)MAX_PATH; memcpy(in, it.Name.Name, sizeof(it.Name.Name)); iconv_t ic = iconv_open("GBK", "SJIS"); iconv(ic, &in, &in_size, &out, &out_size); iconv_close(ic); bone.setName(std::string(outbuf)); bone.setPosition(it.Position); bone.setParent(it.Parent); bone.setChild(it.Child); bones.push_back(bone); } for (auto& it : _pmd.IkList) { IKAttr attr; attr.IKBoneIndex = it.IK; attr.IKTargetBoneIndex = it.Target; attr.IKLimitedRadian = it.LimitOnce; attr.IKLinkCount = it.LinkCount; attr.IKLoopCount = it.LoopCount; for (auto& bone : it.LinkList) { IKChild child; child.BoneIndex = bone; child.MinimumRadian = Vector3::Zero; child.MaximumRadian = Vector3(3.14, 3.14, 3.14); child.RotateLimited = 1; attr.IKList.push_back(child); } iks.push_back(attr); } root->setInverseKinematics(iks); root->setBoneArray(bones); } model.addMesh(root); return true; }
int main(int argC,char **argV) { ros::init(argC,argV,"startBody"); ros::NodeHandle n; std::string serverAddress; n.getParam("/serverNameOrIP",serverAddress); Socket mySocket(serverAddress.c_str(),"9003",streamSize); iconv_t charConverter = iconv_open("UTF-8","UTF-16"); ros::Publisher bodyPub = n.advertise<k2_client::BodyArray>(topicName,1); char jsonCharArray[readSkipSize]; while(ros::ok()) { mySocket.readData(); char *jsonCharArrayPtr; char *socketCharArrayPtr; jsonCharArrayPtr = jsonCharArray; socketCharArrayPtr = mySocket.mBuffer; iconv(charConverter,&socketCharArrayPtr,&readSkipSize,&jsonCharArrayPtr,&stringSize); double utcTime; memcpy(&utcTime,&mySocket.mBuffer[readSkipSize],sizeof(double)); std::string jsonString(jsonCharArray); //std::cout<<jsonCharArray<<std::endl<<"***"<<std::endl; Json::Value jsonObject; Json::Reader jsonReader; bool parsingSuccessful = jsonReader.parse(jsonString,jsonObject,false); if(!parsingSuccessful) { std::cout<<"Failure to parse: "<<parsingSuccessful<<std::endl; continue; } k2_client::BodyArray bodyArray; try { for(int i=0;i<6;i++) { k2_client::Body body; body.header.stamp = ros::Time(utcTime); body.header.frame_id = ros::this_node::getNamespace() + "/rgb"; body.leanTrackingState = jsonObject[i]["LeanTrackingState"].asInt(); body.lean.leanX = jsonObject[i]["Lean"]["X"].asDouble(); body.lean.leanY = jsonObject[i]["Lean"]["Y"].asDouble(); body.isTracked = jsonObject[i]["IsTracked"].asBool(); body.trackingId = jsonObject[i]["TrackingId"].asUInt64(); body.clippedEdges = jsonObject[i]["ClippedEdges"].asInt(); body.engaged = jsonObject[i]["Engaged"].asBool(); body.handRightConfidence = jsonObject[i]["HandRightConfidence"].asInt(); body.handRightState = jsonObject[i]["HandRightState"].asInt(); body.handLeftConfidence = jsonObject[i]["HandLeftConfidence"].asInt(); body.handLeftState = jsonObject[i]["HandLeftState"].asInt(); body.appearance.wearingGlasses = jsonObject[i]["Appearance"]["WearingGlasses"].asBool(); body.activities.eyeLeftClosed = jsonObject[i]["Activities"]["EyeLeftClosed"].asBool(); body.activities.eyeRightClosed = jsonObject[i]["Activities"]["EyeRightClosed"].asBool(); body.activities.mouthOpen = jsonObject[i]["Activities"]["MouthOpen"].asBool(); body.activities.mouthMoved = jsonObject[i]["Activities"]["MouthMoved"].asBool(); body.activities.lookingAway = jsonObject[i]["Activities"]["LookingAway"].asBool(); body.expressions.neutral = jsonObject[i]["Expressions"]["Neutral"].asBool(); body.expressions.neutral = jsonObject[i]["Expressions"]["Happy"].asBool(); for(int j=0;j<25;j++) { k2_client::JointOrientationAndType JOAT; k2_client::JointPositionAndState JPAS; std::string fieldName; switch (j) { case 0: fieldName = "SpineBase";break; case 1: fieldName = "SpineMid";break; case 2: fieldName = "Neck";break; case 3: fieldName = "Head";break; case 4: fieldName = "ShoulderLeft";break; case 5: fieldName = "ElbowLeft";break; case 6: fieldName = "WristLeft";break; case 7: fieldName = "HandLeft";break; case 8: fieldName = "ShoulderRight";break; case 9: fieldName = "ElbowRight";break; case 10: fieldName = "WristRight";break; case 11: fieldName = "HandRight";break; case 12: fieldName = "HipLeft";break; case 13: fieldName = "KneeLeft";break; case 14: fieldName = "AnkleLeft";break; case 15: fieldName = "SpineBase";break; case 16: fieldName = "HipRight";break; case 17: fieldName = "KneeRight";break; case 18: fieldName = "AnkleRight";break; case 19: fieldName = "FootRight";break; case 20: fieldName = "SpineShoulder";break; case 21: fieldName = "HandTipLeft";break; case 22: fieldName = "ThumbLeft";break; case 23: fieldName = "HandTipRight";break; case 24: fieldName = "ThumbRight";break; } JOAT.orientation.x = jsonObject[i][fieldName]["Orientation"]["X"].asDouble(); JOAT.orientation.y = jsonObject[i][fieldName]["Orientation"]["Y"].asDouble(); JOAT.orientation.z = jsonObject[i][fieldName]["Orientation"]["Z"].asDouble(); JOAT.orientation.w = jsonObject[i][fieldName]["Orientation"]["W"].asDouble(); JOAT.jointType = jsonObject[i][fieldName]["JointType"].asInt(); JPAS.trackingState = jsonObject[i][fieldName]["TrackingState"].asBool(); JPAS.position.x = jsonObject[i][fieldName]["Position"]["X"].asDouble(); JPAS.position.y = jsonObject[i][fieldName]["Position"]["Y"].asDouble(); JPAS.position.z = jsonObject[i][fieldName]["Position"]["Z"].asDouble(); JPAS.jointType = jsonObject[i][fieldName]["JointType"].asInt(); body.jointOrientations.push_back(JOAT); body.jointPositions.push_back(JPAS); } bodyArray.bodies.push_back(body); } } catch (...) { std::cout<<"An exception occured"<<std::endl; continue; } bodyPub.publish(bodyArray); } return 0; }
iconv_t QIconvCodec::createIconv_t(const char *to, const char *from) { Q_ASSERT((to == 0 && from != 0) || (to != 0 && from == 0)); iconv_t cd = (iconv_t) -1; #if defined(__GLIBC__) || defined(GNU_LIBICONV) || defined(Q_OS_QNX) #if defined(Q_OS_QNX) // on QNX the default locale is UTF-8, and an empty string will cause iconv_open to fail static const char empty_codeset[] = "UTF-8"; #else // both GLIBC and libgnuiconv will use the locale's encoding if from or to is an empty string static const char empty_codeset[] = ""; #endif const char *codeset = empty_codeset; cd = iconv_open(to ? to : codeset, from ? from : codeset); #else char *codeset = 0; #endif #if defined(_XOPEN_UNIX) && !defined(Q_OS_QNX) && !defined(Q_OS_OSF) if (cd == (iconv_t) -1) { codeset = nl_langinfo(CODESET); if (codeset) cd = iconv_open(to ? to : codeset, from ? from : codeset); } #endif if (cd == (iconv_t) -1) { // Very poorly defined and followed standards causes lots of // code to try to get all the cases... This logic is // duplicated in QTextCodec, so if you change it here, change // it there too. // Try to determine locale codeset from locale name assigned to // LC_CTYPE category. // First part is getting that locale name. First try setlocale() which // definitely knows it, but since we cannot fully trust it, get ready // to fall back to environment variables. char * ctype = qstrdup(setlocale(LC_CTYPE, 0)); // Get the first nonempty value from $LC_ALL, $LC_CTYPE, and $LANG // environment variables. char * lang = qstrdup(qgetenv("LC_ALL").constData()); if (!lang || lang[0] == 0 || strcmp(lang, "C") == 0) { if (lang) delete [] lang; lang = qstrdup(qgetenv("LC_CTYPE").constData()); } if (!lang || lang[0] == 0 || strcmp(lang, "C") == 0) { if (lang) delete [] lang; lang = qstrdup(qgetenv("LANG").constData()); } // Now try these in order: // 1. CODESET from ctype if it contains a .CODESET part (e.g. en_US.ISO8859-15) // 2. CODESET from lang if it contains a .CODESET part // 3. ctype (maybe the locale is named "ISO-8859-1" or something) // 4. locale (ditto) // 5. check for "@euro" // 1. CODESET from ctype if it contains a .CODESET part (e.g. en_US.ISO8859-15) codeset = ctype ? strchr(ctype, '.') : 0; if (codeset && *codeset == '.') { ++codeset; cd = iconv_open(to ? to : codeset, from ? from : codeset); } // 2. CODESET from lang if it contains a .CODESET part codeset = lang ? strchr(lang, '.') : 0; if (cd == (iconv_t) -1 && codeset && *codeset == '.') { ++codeset; cd = iconv_open(to ? to : codeset, from ? from : codeset); } // 3. ctype (maybe the locale is named "ISO-8859-1" or something) if (cd == (iconv_t) -1 && ctype && *ctype != 0 && strcmp (ctype, "C") != 0) cd = iconv_open(to ? to : ctype, from ? from : ctype); // 4. locale (ditto) if (cd == (iconv_t) -1 && lang && *lang != 0) cd = iconv_open(to ? to : lang, from ? from : lang); // 5. "@euro" if ((cd == (iconv_t) -1 && ctype && strstr(ctype, "@euro")) || (lang && strstr(lang, "@euro"))) cd = iconv_open(to ? to : "ISO8859-15", from ? from : "ISO8859-15"); delete [] ctype; delete [] lang; } return cd; }
/* This function returns a newly allocated wide string containing the USB device string numbered by the index. The returned string must be freed by using free(). */ static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx) { char buf[512]; int len; wchar_t *str = NULL; #ifndef __ANDROID__ /* we don't use iconv on Android */ wchar_t wbuf[256]; /* iconv variables */ iconv_t ic; size_t inbytes; size_t outbytes; size_t res; #ifdef __FreeBSD__ const char *inptr; #else char *inptr; #endif char *outptr; #endif /* Determine which language to use. */ uint16_t lang; lang = get_usb_code_for_current_locale(); if (!is_language_supported(dev, lang)) lang = get_first_language(dev); /* Get the string from libusb. */ len = libusb_get_string_descriptor(dev, idx, lang, (unsigned char*)buf, sizeof(buf)); if (len < 0) return NULL; #ifdef __ANDROID__ /* Bionic does not have iconv support nor wcsdup() function, so it has to be done manually. The following code will only work for code points that can be represented as a single UTF-16 character, and will incorrectly convert any code points which require more than one UTF-16 character. Skip over the first character (2-bytes). */ len -= 2; str = malloc((len / 2 + 1) * sizeof(wchar_t)); int i; for (i = 0; i < len / 2; i++) { str[i] = buf[i * 2 + 2] | (buf[i * 2 + 3] << 8); } str[len / 2] = 0x00000000; #else /* buf does not need to be explicitly NULL-terminated because it is only passed into iconv() which does not need it. */ /* Initialize iconv. */ ic = iconv_open("WCHAR_T", "UTF-16LE"); if (ic == (iconv_t)-1) { LOG("iconv_open() failed\n"); return NULL; } /* Convert to native wchar_t (UTF-32 on glibc/BSD systems). Skip the first character (2-bytes). */ inptr = buf+2; inbytes = len-2; outptr = (char*) wbuf; outbytes = sizeof(wbuf); res = iconv(ic, (char**)&inptr, &inbytes, &outptr, &outbytes); if (res == (size_t)-1) { LOG("iconv() failed\n"); goto err; } /* Write the terminating NULL. */ wbuf[sizeof(wbuf)/sizeof(wbuf[0])-1] = 0x00000000; if (outbytes >= sizeof(wbuf[0])) *((wchar_t*)outptr) = 0x00000000; /* Allocate and copy the string. */ str = wcsdup(wbuf); err: iconv_close(ic); #endif return str; }
void FontAtlas::conversionU16TOGB2312(const std::u16string& newChars, std::unordered_map<unsigned short, unsigned short>& newCharsMap) { size_t strLen = newChars.length(); auto gb2312StrSize = strLen * 2; auto gb2312Text = new (std::nothrow) char[gb2312StrSize]; memset(gb2312Text, 0, gb2312StrSize); switch (_fontFreeType->getEncoding()) { case FT_ENCODING_GB2312: { #if CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_WINRT WideCharToMultiByte(936, NULL, (LPCWCH)newChars.c_str(), strLen, (LPSTR)gb2312Text, gb2312StrSize, NULL, NULL); #elif CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID conversionEncodingJNI((char*)newChars.c_str(), gb2312StrSize, "UTF-16LE", gb2312Text, "GB2312"); #else if (_iconv == nullptr) { _iconv = iconv_open("gb2312", "utf-16le"); } if (_iconv == (iconv_t)-1) { CCLOG("conversion from utf16 to gb2312 not available"); } else { char* pin = (char*)newChars.c_str(); char* pout = gb2312Text; size_t inLen = strLen * 2; size_t outLen = gb2312StrSize; iconv(_iconv, (char**)&pin, &inLen, &pout, &outLen); } #endif } break; default: CCLOG("Unsupported encoding:%d", _fontFreeType->getEncoding()); break; } unsigned short gb2312Code = 0; unsigned char* dst = (unsigned char*)&gb2312Code; unsigned short u16Code; for (size_t index = 0, gbIndex = 0; index < strLen; ++index) { u16Code = newChars[index]; if (u16Code < 256) { newCharsMap[u16Code] = u16Code; gbIndex += 1; } else { dst[0] = gb2312Text[gbIndex + 1]; dst[1] = gb2312Text[gbIndex]; newCharsMap[u16Code] = gb2312Code; gbIndex += 2; } } delete [] gb2312Text; }
static int iconv_erl_control(ErlDrvData drv_data, unsigned int command, char *buf, int len, char **rbuf, int rlen) { int i; int size; int index = 0; int avail; size_t inleft, outleft; ErlDrvBinary *b; char *from, *to, *string, *stmp, *rstring, *rtmp; iconv_t cd; int error = 0; ei_decode_version(buf, &index, &i); ei_decode_tuple_header(buf, &index, &i); ei_get_type(buf, &index, &i, &size); from = malloc(size + 1); ei_decode_string(buf, &index, from); ei_get_type(buf, &index, &i, &size); to = malloc(size + 1); ei_decode_string(buf, &index, to); ei_get_type(buf, &index, &i, &size); stmp = string = malloc(size + 1); ei_decode_string(buf, &index, string); cd = iconv_open(to, from); if (cd == (iconv_t) -1) { cd = iconv_open("ascii", "ascii"); if (cd == (iconv_t) -1) { *rbuf = (char*)(b = driver_alloc_binary(size)); memcpy(b->orig_bytes, string, size); free(from); free(to); free(string); return size; } } outleft = avail = 4*size; inleft = size; rtmp = rstring = malloc(avail); while (inleft > 0) { if (iconv(cd, &stmp, &inleft, &rtmp, &outleft) == (size_t) -1) { error = 1; break; } } size = error ? 0 : rtmp - rstring; *rbuf = (char*)(b = driver_alloc_binary(size)); memcpy(b->orig_bytes, rstring, size); free(from); free(to); free(string); free(rstring); iconv_close(cd); return size; }
//------------------------------------------------------------------------------ int IGUIStringConv_iconv::Utf8ToWChar( const CGUIString& rSrc, CGUIStringW& rDst ) { if( rSrc.empty()) { rDst.clear(); return 0; } //open iconv iconv_t cd = iconv_open ("UTF-16LE", "UTF-8"); if( cd == (iconv_t)-1 ) { throw CGUIException( "[MultiByteToWideChar]: failed to open iconv, errno is %d", errno); return -1; } //convert size_t buf_size = rSrc.size()+1; size_t inbytesleft = rSrc.size(); size_t outbytesleft = buf_size; char* dst = (char*)(new wchar[buf_size]); char* pOutBuf = NULL; char* pInBuf = (char*)(rSrc.c_str()); bool bError = false; while(inbytesleft > 0) { pOutBuf = dst; outbytesleft = buf_size*sizeof(wchar); size_t retbytes = iconv(cd, &pInBuf, &inbytesleft, &pOutBuf, &outbytesleft); if (dst != pOutBuf) { // wchar is 4byte in mac, but iconv return a "utf-16" buff which is 2byte per code if (sizeof(wchar) == 4) { for (int iChar = 0; iChar < (pOutBuf-dst)/2; iChar++) { unsigned short* pU16Char = (unsigned short*)&dst[2*iChar]; rDst.push_back((wchar)*pU16Char); } } else if (sizeof(wchar) == 2) { rDst.append((wchar*)dst, (pOutBuf-dst)/sizeof(wchar)); } } //check ret if( retbytes == size_t(-1) ) { if( errno == E2BIG ) { continue; } else { bError = true; break; } } else { //success break; } } delete[] dst; if( bError) { switch(errno) { case EILSEQ: throw CGUIException( "[MultiByteToWideChar]: failed to iconv, errno is EILSEQ"); return -1; case EINVAL: throw CGUIException( "[MultiByteToWideChar]: failed to iconv, errno is EINVAL"); return -1; default: throw CGUIException( "[MultiByteToWideChar]: failed to iconv, errno is %d", errno); return -1; } } //close iconv int ret = iconv_close(cd); if( ret == -1 ) { throw CGUIException( "[MultiByteToWideChar]: failed to close iconv, errno is %d", errno); return -1; } return 0; }
int benthos_dc_manifest_parse(plugin_manifest_t * ptr, const char * path) { int rv; struct plugin_manifest_t_ * manifest; struct stat finfo; xmlDoc * doc; xmlNode * root; iconv_t conv; if (! ptr || ! path) return EINVAL; /* Create the Encoding Converter */ conv = iconv_open("ISO-8859-1", "UTF-8"); if (conv == (iconv_t)(-1)) return errno; /* Create the Manifest Object */ manifest = new struct plugin_manifest_t_; if (! manifest) { iconv_close(conv); return ENOMEM; } /* Check that the File Exists */ rv = stat(path, & finfo); if (rv != 0) { delete manifest; iconv_close(conv); return errno; } if (! S_ISREG(finfo.st_mode)) { delete manifest; iconv_close(conv); return ENOENT; } /* Load the Manifest File */ doc = xmlReadFile(path, 0, 0); if (doc == NULL) { delete manifest; xmlCleanupParser(); iconv_close(conv); return MANFIEST_ERR_MALFORMED; } /* Load the Root Node */ root = xmlDocGetRootElement(doc); if ((root == NULL) || (root->type != XML_ELEMENT_NODE)) { delete manifest; xmlFreeDoc(doc); xmlCleanupParser(); iconv_close(conv); return MANIFEST_ERR_NOROOT; } /* Check the Root Node */ if (xmlStrcmp(root->name, BAD_CAST("plugin")) != 0) { delete manifest; xmlFreeDoc(doc); xmlCleanupParser(); iconv_close(conv); return MANIFEST_ERR_NOTPLUGIN; } /* Parse the Manifest Entry */ rv = parse_manifest(manifest, root, conv); if (rv != 0) { delete manifest; xmlFreeDoc(doc); xmlCleanupParser(); iconv_close(conv); return rv; } /* Set Manifest Pointer */ (* ptr) = manifest; /* Cleanup */ xmlFreeDoc(doc); xmlCleanupParser(); iconv_close(conv); return 0; }
CAMLprim value ml_text_recode_string(value enc_src, value enc_dst, value str) { CAMLparam3(str, enc_src, enc_dst); CAMLlocal1(result); iconv_t cd = iconv_open(String_val(enc_dst), String_val(enc_src)); if (cd == (iconv_t)-1) caml_failwith("Encoding.recode_string: invalid encoding"); /* Length of the output buffer. It is initialised to the length of the input string, which should be a good approximation: */ size_t len = caml_string_length(str); /* Pointer to the beginning of the output buffer. The +1 is for the NULL terminating byte. */ char *dst_buffer = malloc(len + 1); if (dst_buffer == NULL) caml_failwith("Encoding.recode_string: out of memory"); /* iconv arguments */ char *src_bytes = String_val(str); char *dst_bytes = dst_buffer; size_t src_remaining = len; size_t dst_remaining = len; while (src_remaining) { size_t count = iconv (cd, &src_bytes, &src_remaining, &dst_bytes, &dst_remaining); if (count == (size_t) -1) { switch (errno) { case EILSEQ: free(dst_buffer); iconv_close(cd); caml_failwith("Encoding.recode_string: invalid multibyte sequence found in the input"); case EINVAL: free(dst_buffer); iconv_close(cd); caml_failwith("Encoding.recode_string: incomplete multibyte sequence found in the input"); case E2BIG: { /* Ouput offest relative to the beginning of the destination buffer: */ size_t offset = dst_bytes - dst_buffer; /* Try with a buffer 2 times bigger: */ len *= 2; dst_buffer = realloc(dst_buffer, len + 1); if (dst_buffer == NULL) caml_failwith("Encoding.recode_string: out of memory"); dst_bytes = dst_buffer + offset; dst_remaining += len; break; } default: free(dst_buffer); iconv_close(cd); caml_failwith("Encoding.recode_string: unknown error"); } } }; *dst_bytes = 0; result = caml_alloc_string(dst_bytes - dst_buffer); memcpy(String_val(result), dst_buffer, dst_bytes - dst_buffer); /* Clean-up */ free(dst_buffer); iconv_close(cd); CAMLreturn(result); }
int conv_enc (SCR *sp, int option, const char *enc) { #if defined(USE_WIDECHAR) && defined(USE_ICONV) iconv_t id; char2wchar_t *c2w; wchar2char_t *w2c; switch (option) { case O_FILEENCODING: c2w = &sp->conv.file2int; w2c = &sp->conv.int2file; break; case O_INPUTENCODING: c2w = &sp->conv.input2int; w2c = NULL; break; default: c2w = NULL; w2c = NULL; break; } if (!*enc) { if (c2w) *c2w = raw2int; if (w2c) *w2c = int2raw; return 0; } if (!strcmp(enc, "WCHAR_T")) { if (c2w) *c2w = CHAR_T_char2int; if (w2c) *w2c = CHAR_T_int2char; return 0; } id = iconv_open(enc, nl_langinfo(CODESET)); if (id == (iconv_t)-1) goto err; iconv_close(id); id = iconv_open(nl_langinfo(CODESET), enc); if (id == (iconv_t)-1) goto err; iconv_close(id); switch (option) { case O_FILEENCODING: *c2w = fe_char2int; *w2c = fe_int2char; break; case O_INPUTENCODING: *c2w = ie_char2int; break; } F_CLR(sp, SC_CONV_ERROR); F_SET(sp, SC_SCR_REFORMAT); return 0; err: switch (option) { case O_FILEENCODING: msgq(sp, M_ERR, "321|File encoding conversion not supported"); break; case O_INPUTENCODING: msgq(sp, M_ERR, "322|Input encoding conversion not supported"); break; } #endif return 1; }
static ErlDrvSSizeT iconv_erl_control(ErlDrvData drv_data, unsigned int command, char *buf, ErlDrvSizeT len, char **rbuf, ErlDrvSizeT rlen) { int i; int size; int index = 0; int avail; size_t inleft, outleft; ErlDrvBinary *b; char *from, *to, *string, *stmp, *rstring, *rtmp; iconv_t cd; int invalid_utf8_as_latin1 = 0; ei_decode_version(buf, &index, &i); ei_decode_tuple_header(buf, &index, &i); ei_get_type(buf, &index, &i, &size); from = driver_alloc(size + 1); ei_decode_string(buf, &index, from); ei_get_type(buf, &index, &i, &size); to = driver_alloc(size + 1); ei_decode_string(buf, &index, to); ei_get_type(buf, &index, &i, &size); stmp = string = driver_alloc(size + 1); ei_decode_string(buf, &index, string); /* Special mode: parse as UTF-8 if possible; otherwise assume it's Latin-1. Makes no difference when encoding. */ if (strcmp(from, "utf-8+latin-1") == 0) { from[5] = '\0'; invalid_utf8_as_latin1 = 1; } if (strcmp(to, "utf-8+latin-1") == 0) { to[5] = '\0'; } cd = iconv_open(to, from); if (cd == (iconv_t) -1) { cd = iconv_open("ascii", "ascii"); if (cd == (iconv_t) -1) { *rbuf = (char*)(b = driver_alloc_binary(size)); memcpy(b->orig_bytes, string, size); driver_free(from); driver_free(to); driver_free(string); return size; } } outleft = avail = 4*size; inleft = size; rtmp = rstring = driver_alloc(avail); while (inleft > 0) { if (iconv(cd, &stmp, &inleft, &rtmp, &outleft) == (size_t) -1) { if (invalid_utf8_as_latin1 && (*stmp & 0x80) && outleft >= 2) { /* Encode one byte of (assumed) Latin-1 into two bytes of UTF-8 */ *rtmp++ = 0xc0 | ((*stmp & 0xc0) >> 6); *rtmp++ = 0x80 | (*stmp & 0x3f); outleft -= 2; } stmp++; inleft--; } }
static int default_int2char(SCR *sp, const CHAR_T * str, ssize_t len, CONVWIN *cw, size_t *tolen, const char **pdst, const char *enc) { size_t i, j; int offset = 0; char **tostr = (char **)(void *)&cw->bp1; size_t *blen = &cw->blen1; mbstate_t mbs; size_t n; ssize_t nlen = len + MB_CUR_MAX; char *dst; size_t buflen; char buffer[CONV_BUFFER_SIZE]; iconv_t id = (iconv_t)-1; /* convert first len bytes of buffer and append it to cw->bp * len is adjusted => 0 * offset contains the offset in cw->bp and is adjusted * cw->bp is grown as required */ #ifdef USE_ICONV #define CONVERT2(len, cw, offset) \ do { \ const char *bp = buffer; \ while (len != 0) { \ size_t outleft = cw->blen1 - offset; \ char *obp = (char *)cw->bp1 + offset; \ if (cw->blen1 < offset + MB_CUR_MAX) { \ nlen += 256; \ BINC_RETC(NULL, cw->bp1, cw->blen1, nlen); \ } \ errno = 0; \ if (iconv(id, &bp, &len, &obp, &outleft) == (size_t)-1 && \ errno != E2BIG) \ HANDLE_ICONV_ERROR(obp, bp, outleft, len); \ offset = cw->blen1 - outleft; \ } \ } while (0) #else #define CONVERT2(len, cw, offset) #endif MEMSET(&mbs, 0, 1); BINC_RETC(NULL, *tostr, *blen, nlen); dst = *tostr; buflen = *blen; #ifdef USE_ICONV if (strcmp(nl_langinfo(CODESET), enc)) { id = iconv_open(enc, nl_langinfo(CODESET)); if (id == (iconv_t)-1) goto err; dst = buffer; buflen = CONV_BUFFER_SIZE; } #endif for (i = 0, j = 0; i < (size_t)len; ++i) { n = wcrtomb(dst+j, str[i], &mbs); if (n == (size_t)-1) HANDLE_MBR_ERROR(n, mbs, dst[j], str[i]); j += n; if (buflen < j + MB_CUR_MAX) { if (id != (iconv_t)-1) { CONVERT2(j, cw, offset); } else { nlen += 256; BINC_RETC(NULL, *tostr, *blen, nlen); dst = *tostr; buflen = *blen; } } } n = wcrtomb(dst+j, L'\0', &mbs); j += n - 1; /* don't count NUL at the end */ *tolen = j; if (id != (iconv_t)-1) { CONVERT2(j, cw, offset); *tolen = offset; } *pdst = cw->bp1; return 0; err: *tolen = j; *pdst = cw->bp1; return 1; }
static int default_char2int(SCR *sp, const char * str, ssize_t len, CONVWIN *cw, size_t *tolen, const CHAR_T **dst, const char *enc) { int j; size_t i = 0; CHAR_T **tostr = (CHAR_T **)(void *)&cw->bp1; size_t *blen = &cw->blen1; mbstate_t mbs; size_t n; ssize_t nlen = len; const char *src = (const char *)str; iconv_t id = (iconv_t)-1; char buffer[CONV_BUFFER_SIZE]; size_t left = len; int error = 1; MEMSET(&mbs, 0, 1); BINC_RETW(NULL, *tostr, *blen, nlen); #ifdef USE_ICONV if (strcmp(nl_langinfo(CODESET), enc)) { id = iconv_open(nl_langinfo(CODESET), enc); if (id == (iconv_t)-1) goto err; CONVERT(str, left, src, len); } #endif for (i = 0, j = 0; j < len; ) { n = mbrtowc((*tostr)+i, src+j, len-j, &mbs); /* NULL character converted */ if (n == (size_t)-2) error = -(len-j); if (n == (size_t)-1 || n == (size_t)-2) HANDLE_MBR_ERROR(n, mbs, (*tostr)[i], src[j]); if (n == 0) n = 1; j += n; if (++i >= *blen) { nlen += 256; BINC_RETW(NULL, *tostr, *blen, nlen); } if (id != (iconv_t)-1 && j == len && left) { CONVERT(str, left, src, len); j = 0; } } *tolen = i; if (id != (iconv_t)-1) iconv_close(id); *dst = cw->bp1; return 0; err: *tolen = i; if (id != (iconv_t)-1) iconv_close(id); *dst = cw->bp1; return error; }
static void do_conv(FILE *fp, const char *from, const char *to, int silent, int hide_invalid) { char inbuf[INBUFSIZE], outbuf[OUTBUFSIZE], *out; const char *in; size_t inbytes, outbytes, invalids; ssize_t ret; iconv_t cd; u_int32_t flags = 0; if (hide_invalid) flags |= __ICONV_F_HIDE_INVALID; cd = iconv_open(to, from); if (cd == (iconv_t)-1) err(EXIT_FAILURE, "iconv_open(%s, %s)", to, from); invalids = 0; while ((inbytes = fread(inbuf, 1, INBUFSIZE, fp)) > 0) { in = inbuf; while (inbytes>0) { size_t inval; out = outbuf; outbytes = OUTBUFSIZE; ret = __iconv(cd, &in, &inbytes, &out, &outbytes, flags, &inval); invalids += inval; if (ret == -1 && errno != E2BIG) { /* * XXX: iconv(3) is bad interface. * invalid character count is lost here. * instead, we just provide __iconv function. */ if (errno != EINVAL || in == inbuf) err(EXIT_FAILURE, "iconv()"); /* incomplete input character */ memmove(inbuf, in, inbytes); ret = fread(inbuf+inbytes, 1, INBUFSIZE-inbytes, fp); if (ret == 0) { if (feof(fp)) errx(EXIT_FAILURE, "iconv(): %s", strerror(EINVAL)); else err(EXIT_FAILURE, "fread()"); } in = inbuf; inbytes += ret; } if (outbytes < OUTBUFSIZE) fwrite(outbuf, 1, OUTBUFSIZE-outbytes, stdout); } } /* reset the shift state of the output buffer */ outbytes = OUTBUFSIZE; out = outbuf; ret = iconv(cd, NULL, NULL, &out, &outbytes); if (ret == -1) err(EXIT_FAILURE, "iconv()"); if (outbytes < OUTBUFSIZE) fwrite(outbuf, 1, OUTBUFSIZE-outbytes, stdout); if (invalids > 0 && !silent) warnx("warning: invalid characters: %lu", (unsigned long)invalids); iconv_close(cd); }
static rc_uint_type wind_WideCharToMultiByte (rc_uint_type cp, const unichar *u, char *mb, rc_uint_type mb_len) { rc_uint_type ret = 0; #if defined (_WIN32) || defined (__CYGWIN__) WINBOOL used_def = FALSE; ret = (rc_uint_type) WideCharToMultiByte (cp, 0, u, -1, mb, mb_len, NULL, & used_def); #elif defined (HAVE_ICONV) int first = 1; char tmp[32]; char *p_tmp; const char *iconv_name = wind_iconv_cp (cp); if (!u || !iconv_name) return 0; iconv_t cd = iconv_open (iconv_name, "UTF-16LE"); while (1) { int iret; const char *n_u = ""; char *n_tmp = ""; p_tmp = tmp; iret = iconv_onechar (cd, (ICONV_CONST char *) u, p_tmp, 32, &n_u, & n_tmp); if (first) { first = 0; continue; } if (!iret) { size_t l_tmp = (size_t) (n_tmp - p_tmp); if (mb) { if ((size_t) mb_len < l_tmp) break; memcpy (mb, tmp, l_tmp); mb += l_tmp; mb_len -= l_tmp; } ret += l_tmp; } else break; if (u[0] == 0) break; u = (const unichar *) n_u; } iconv_close (cd); #else if (cp) ret = 0; while (u[ret] != 0) ++ret; ++ret; if (mb) { while (*u != 0 && mb_len != 0) { if (u[0] == (u[0] & 0x7f)) *mb++ = (char) u[0]; else *mb++ = '_'; ++u; --mb_len; } if (mb_len != 0) *mb = 0; } #endif return ret; }
bool ConvertCharset(const CString& sFrom, const CString& sTo, CString& sData) { if(sData.empty()) return true; DEBUG("charset: Trying to convert [" + sData.Escape_n(CString::EURL) + "] from [" + sFrom + "] to [" + sTo + "]..."); iconv_t ic = iconv_open(sTo.c_str(), sFrom.c_str()); if(ic == (iconv_t)-1) return false; size_t uLength = GetConversionLength(ic, sData); if(uLength == (size_t)-1) { // incompatible input encoding. iconv_close(ic); return false; } else if(uLength == (size_t)-2) { // internal error, preserve errno from GetConversionLength: int tmp_errno = errno; iconv_close(ic); errno = tmp_errno; return false; } else { // no error, so let's do the actual conversion. iconv(ic, NULL, NULL, NULL, NULL); // reset // state vars for iconv: size_t uResultBufSize = uLength + 1; char *pResult = new char[uResultBufSize]; memset(pResult, 0, uResultBufSize); char *pResultWalker = pResult; const char* pIn = sData.c_str(); size_t uInLen = sData.size(); // let's fcking do it! size_t uResult = iconv(ic, (ICONV_CONST char**)&pIn, &uInLen, &pResultWalker, &uResultBufSize); bool bResult = (uResult != (size_t)-1); iconv_close(ic); if(bResult) { sData.assign(pResult, (uLength + 1) - uResultBufSize); DEBUG("charset: Converted: [" + sData.Escape_n(CString::EURL) + "] from [" + sFrom + "] to [" + sTo + "]!"); } else { DEBUG("Conversion failed: [" << uResult << "]"); } delete[] pResult; return bResult; } }
char * str_iconv (const char *src, const char *from_codeset, const char *to_codeset) { if (*src == '\0' || c_strcasecmp (from_codeset, to_codeset) == 0) { char *result = strdup (src); if (result == NULL) errno = ENOMEM; return result; } else { #if HAVE_ICONV iconv_t cd; char *result; /* Avoid glibc-2.1 bug with EUC-KR. */ # if ((__GLIBC__ == 2 && __GLIBC_MINOR__ <= 1) && !defined __UCLIBC__) \ && !defined _LIBICONV_VERSION if (c_strcasecmp (from_codeset, "EUC-KR") == 0 || c_strcasecmp (to_codeset, "EUC-KR") == 0) { errno = EINVAL; return NULL; } # endif cd = iconv_open (to_codeset, from_codeset); if (cd == (iconv_t) -1) return NULL; result = str_cd_iconv (src, cd); if (result == NULL) { /* Close cd, but preserve the errno from str_cd_iconv. */ int saved_errno = errno; iconv_close (cd); errno = saved_errno; } else { if (iconv_close (cd) < 0) { /* Return NULL, but free the allocated memory, and while doing that, preserve the errno from iconv_close. */ int saved_errno = errno; free (result); errno = saved_errno; return NULL; } } return result; #else /* This is a different error code than if iconv_open existed but didn't support from_codeset and to_codeset, so that the caller can emit an error message such as "iconv() is not supported. Installing GNU libiconv and then reinstalling this package would fix this." */ errno = ENOSYS; return NULL; #endif } }
int main(int argc,char *argv[]){ strcpy(fname,argv[1]); FILE *f=fopen(fname,"rb"); if(read_header(f)){ char ofname[0x400]; strcpy(ofname,fname); char *ibuf; char *obuf; ibuf=header_buf+(lrc_offs-9); while(*ibuf==' '){ ibuf--; } *(ibuf+1)=0; size_t ol=0x200,il=(ibuf-(char *)header_buf)-0x16; if(il==lrc_offs-0x1F){ obuf=strrchr(ofname,'.'); char *p=obuf-1; obuf+=5; *obuf=0; while(*p!='/'){ *(p+5)=*p; p--; } p[1]='d'; p[2]='o'; p[3]='n'; p[4]='e'; p[5]='-'; } else{ ibuf=header_buf+0x18; obuf=strrchr(ofname,'/'); strcpy(obuf,"/done-"); obuf+=6; iconv_t cd=iconv_open("UTF-8","GBK"); iconv(cd,&ibuf,&il,&obuf,&ol); iconv_close(cd); obuf--; } fprintf(stderr,"INFO: %s\n",ofname); if(lrc_len){ char *lrc_str=malloc(lrc_len+0x100); memset(lrc_str,0,lrc_len+0x100); fseek(f,lrc_offs,SEEK_SET); fread(lrc_str,1,lrc_len,f); init_keys(lrc_offs); decode_str(lrc_str,lrc_len); strcpy(obuf,".LRC"); FILE *ff=fopen(ofname,"w+"); fwrite(lrc_str,1,lrc_len,ff); fclose(ff); free(lrc_str); } if(dat_len){ unsigned char *dat_str=malloc(dat_len+0x100); memset(dat_str,0,dat_len+0x100); fseek(f,dat_offs,SEEK_SET); int read=fread(dat_str,1,dat_len,f); init_keys(dat_offs); decode_str(dat_str,dat_len); int type_known=1; if(strncmp(dat_str,"RIFF",4)==0&&strncmp(dat_str+8,"AVI LIST",8)==0){ strcpy(obuf,".AVI"); } else if(strncmp(dat_str,"FWS",3)==0){ strcpy(obuf,".SWF"); } else if(dat_str[0]==0xFF&&(dat_str[1]&0xE0)==0xE0){ strcpy(obuf,".MP3"); } else{ int i; fprintf(stderr,"ERR: Unknown header:"); for(i=0;i<10;i++){ fprintf(stderr," %02X",dat_str[i]); } fprintf(stderr,"\n"); strcpy(obuf,".DAT"); type_known=0; } if(type_known){ FILE *ff=fopen(ofname,"w+"); fwrite(dat_str,1,dat_len,ff); fclose(ff); } else{ FILE *ff=fopen(ofname,"w+"); fwrite(dat_str,1,dat_len,ff); fclose(ff); } free(dat_str); } } fclose(f); }
//------------------------------------------------------------------------------ int IGUIStringConv_iconv::WCharToUtf8( const CGUIStringW& rSrc, CGUIString& rDst ) { if( rSrc.empty()) { rDst.clear(); return 0; } //open iconv iconv_t cd = iconv_open ("UTF-8", "UTF-16LE"); if( cd == (iconv_t)-1 ) { throw CGUIException( "[WCharToUtf8]: failed to open iconv, errno is %d", errno); return -1; } //convert size_t buf_size = rSrc.size()*4+1; size_t inbytesleft = rSrc.size()*2; size_t outbytesleft = buf_size; char* dst = (char*)(new char[buf_size]); char* pOutBuf = NULL; char* pInBuf = (char*)rSrc.c_str(); bool bError = false; while(inbytesleft > 0) { pOutBuf = dst; outbytesleft = buf_size; size_t retbytes = iconv(cd, &pInBuf, &inbytesleft, &pOutBuf, &outbytesleft); //int errno_save = errno; if (dst != pOutBuf) { // we have something to write rDst.append(dst, (pOutBuf-dst)); } //check ret if( retbytes == size_t(-1) ) { if( errno == E2BIG ) { continue; } else { bError = true; break; } } else { //success break; } } delete[] dst; if( bError) { switch(errno) { case EILSEQ: throw CGUIException( "[WCharToUtf8]: failed to iconv, errno is EILSEQ"); return -1; case EINVAL: throw CGUIException( "[WCharToUtf8]: failed to iconv, errno is EINVAL"); return -1; default: throw CGUIException( "[WCharToUtf8]: failed to iconv, errno is %d", errno); return -1; } } //close iconv int ret = iconv_close(cd); if( ret == -1 ) { throw CGUIException( "[WCharToUtf8]: failed to close iconv, errno is %d", errno); return -1; } return 0; }
/* * curl_easy_duphandle() is an external interface to allow duplication of a * given input easy handle. The returned handle will be a new working handle * with all options set exactly as the input source handle. */ CURL *curl_easy_duphandle(CURL *incurl) { bool fail = TRUE; struct SessionHandle *data=(struct SessionHandle *)incurl; struct SessionHandle *outcurl = (struct SessionHandle *) calloc(sizeof(struct SessionHandle), 1); if(NULL == outcurl) return NULL; /* failure */ do { /* * We setup a few buffers we need. We should probably make them * get setup on-demand in the code, as that would probably decrease * the likeliness of us forgetting to init a buffer here in the future. */ outcurl->state.headerbuff=(char*)malloc(HEADERSIZE); if(!outcurl->state.headerbuff) { break; } outcurl->state.headersize=HEADERSIZE; /* copy all userdefined values */ if (Curl_dupset(outcurl, data) != CURLE_OK) break; if(data->state.used_interface == Curl_if_multi) outcurl->state.connc = data->state.connc; else outcurl->state.connc = Curl_mk_connc(CONNCACHE_PRIVATE, -1); if(!outcurl->state.connc) break; outcurl->state.lastconnect = -1; outcurl->progress.flags = data->progress.flags; outcurl->progress.callback = data->progress.callback; #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) if(data->cookies) { /* If cookies are enabled in the parent handle, we enable them in the clone as well! */ outcurl->cookies = Curl_cookie_init(data, data->cookies->filename, outcurl->cookies, data->set.cookiesession); if(!outcurl->cookies) { break; } } #endif /* CURL_DISABLE_HTTP */ /* duplicate all values in 'change' */ if(data->change.url) { outcurl->change.url = strdup(data->change.url); if(!outcurl->change.url) break; outcurl->change.url_alloc = TRUE; } if(data->change.referer) { outcurl->change.referer = strdup(data->change.referer); if(!outcurl->change.referer) break; outcurl->change.referer_alloc = TRUE; } #ifdef USE_ARES /* If we use ares, we setup a new ares channel for the new handle */ if(ARES_SUCCESS != ares_init(&outcurl->state.areschannel)) break; #endif #if defined(CURL_DOES_CONVERSIONS) && defined(HAVE_ICONV) outcurl->inbound_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST, CURL_ICONV_CODESET_OF_NETWORK); outcurl->outbound_cd = iconv_open(CURL_ICONV_CODESET_OF_NETWORK, CURL_ICONV_CODESET_OF_HOST); outcurl->utf8_cd = iconv_open(CURL_ICONV_CODESET_OF_HOST, CURL_ICONV_CODESET_FOR_UTF8); #endif Curl_easy_initHandleData(outcurl); outcurl->magic = CURLEASY_MAGIC_NUMBER; fail = FALSE; /* we reach this point and thus we are OK */ } while(0); if(fail) { if(outcurl) { if(outcurl->state.connc && (outcurl->state.connc->type == CONNCACHE_PRIVATE)) Curl_rm_connc(outcurl->state.connc); if(outcurl->state.headerbuff) free(outcurl->state.headerbuff); if(outcurl->change.url) free(outcurl->change.url); if(outcurl->change.referer) free(outcurl->change.referer); Curl_freeset(outcurl); free(outcurl); /* free the memory again */ outcurl = NULL; } } return outcurl; }
iconv_t rpl_iconv_open (const char *tocode, const char *fromcode) #undef iconv_open { char fromcode_upper[32]; char tocode_upper[32]; char *fromcode_upper_end; char *tocode_upper_end; #if REPLACE_ICONV_UTF /* Special handling of conversion between UTF-8 and UTF-{16,32}{BE,LE}. Do this here, before calling the real iconv_open(), because OSF/1 5.1 iconv() to these encoding inserts a BOM, which is wrong. We do not need to handle conversion between arbitrary encodings and UTF-{16,32}{BE,LE}, because the 'striconveh' module implements two-step conversion throough UTF-8. The _ICONV_* constants are chosen to be disjoint from any iconv_t returned by the system's iconv_open() functions. Recall that iconv_t is a scalar type. */ if (c_toupper (fromcode[0]) == 'U' && c_toupper (fromcode[1]) == 'T' && c_toupper (fromcode[2]) == 'F' && fromcode[3] == '-') { if (c_toupper (tocode[0]) == 'U' && c_toupper (tocode[1]) == 'T' && c_toupper (tocode[2]) == 'F' && tocode[3] == '-') { if (strcmp (fromcode + 4, "8") == 0) { if (c_strcasecmp (tocode + 4, "16BE") == 0) return _ICONV_UTF8_UTF16BE; if (c_strcasecmp (tocode + 4, "16LE") == 0) return _ICONV_UTF8_UTF16LE; if (c_strcasecmp (tocode + 4, "32BE") == 0) return _ICONV_UTF8_UTF32BE; if (c_strcasecmp (tocode + 4, "32LE") == 0) return _ICONV_UTF8_UTF32LE; } else if (strcmp (tocode + 4, "8") == 0) { if (c_strcasecmp (fromcode + 4, "16BE") == 0) return _ICONV_UTF16BE_UTF8; if (c_strcasecmp (fromcode + 4, "16LE") == 0) return _ICONV_UTF16LE_UTF8; if (c_strcasecmp (fromcode + 4, "32BE") == 0) return _ICONV_UTF32BE_UTF8; if (c_strcasecmp (fromcode + 4, "32LE") == 0) return _ICONV_UTF32LE_UTF8; } } } #endif /* Do *not* add special support for 8-bit encodings like ASCII or ISO-8859-1 here. This would lead to programs that work in some locales (such as the "C" or "en_US" locales) but do not work in East Asian locales. It is better if programmers make their programs depend on GNU libiconv (except on glibc systems), e.g. by using the AM_ICONV macro and documenting the dependency in an INSTALL or DEPENDENCIES file. */ /* Try with the original names first. This covers the case when fromcode or tocode is a lowercase encoding name that is understood by the system's iconv_open but not listed in our mappings table. */ { iconv_t cd = iconv_open (tocode, fromcode); if (cd != (iconv_t)(-1)) return cd; } /* Convert the encodings to upper case, because 1. in the arguments of iconv_open() on AIX, HP-UX, and OSF/1 the case matters, 2. it makes searching in the table faster. */ { const char *p = fromcode; char *q = fromcode_upper; while ((*q = c_toupper (*p)) != '\0') { p++; q++; if (q == &fromcode_upper[SIZEOF (fromcode_upper)]) { errno = EINVAL; return (iconv_t)(-1); } } fromcode_upper_end = q; } { const char *p = tocode; char *q = tocode_upper; while ((*q = c_toupper (*p)) != '\0') { p++; q++; if (q == &tocode_upper[SIZEOF (tocode_upper)]) { errno = EINVAL; return (iconv_t)(-1); } } tocode_upper_end = q; } #ifdef ICONV_FLAVOR /* Apply the mappings. */ { const struct mapping *m = mapping_lookup (fromcode_upper, fromcode_upper_end - fromcode_upper); fromcode = (m != NULL ? m->vendor_name : fromcode_upper); } { const struct mapping *m = mapping_lookup (tocode_upper, tocode_upper_end - tocode_upper); tocode = (m != NULL ? m->vendor_name : tocode_upper); } #else fromcode = fromcode_upper; tocode = tocode_upper; #endif return iconv_open (tocode, fromcode); }
int qr_code_data_list_extract_text(const qr_code_data_list *_qrlist, zbar_image_scanner_t *iscn, zbar_image_t *img) { iconv_t sjis_cd; iconv_t utf8_cd; iconv_t latin1_cd; const qr_code_data *qrdata; int nqrdata; unsigned char *mark; int ntext; int i; qrdata=_qrlist->qrdata; nqrdata=_qrlist->nqrdata; mark=(unsigned char *)calloc(nqrdata,sizeof(*mark)); ntext=0; /*This is the encoding the standard says is the default.*/ //latin1_cd=iconv_open("UTF-8","ISO8859-1"); latin1_cd=iconv_open("UTF-8","GB18030"); /*But this one is often used, as well.*/ sjis_cd=iconv_open("UTF-8","SJIS"); /*This is a trivial conversion just to check validity without extra code.*/ utf8_cd=iconv_open("UTF-8","UTF-8"); for(i=0;i<nqrdata;i++)if(!mark[i]){ const qr_code_data *qrdataj; const qr_code_data_entry *entry; iconv_t enc_list[3]; iconv_t eci_cd; int sa[16]; int sa_size; char *sa_text; size_t sa_ntext; size_t sa_ctext; int fnc1; int eci; int err; int j; int k; zbar_symbol_t *syms = NULL, **sym = &syms; qr_point dir; int horiz; /*Step 0: Collect the other QR codes belonging to this S-A group.*/ if(qrdata[i].sa_size){ unsigned sa_parity; sa_size=qrdata[i].sa_size; sa_parity=qrdata[i].sa_parity; for(j=0;j<sa_size;j++)sa[j]=-1; for(j=i;j<nqrdata;j++)if(!mark[j]){ /*TODO: We could also match version, ECC level, etc. if size and parity alone are too ambiguous.*/ if(qrdata[j].sa_size==sa_size&&qrdata[j].sa_parity==sa_parity&& sa[qrdata[j].sa_index]<0){ sa[qrdata[j].sa_index]=j; mark[j]=1; } } /*TODO: If the S-A group is complete, check the parity.*/ } else{ sa[0]=i; sa_size=1; } sa_ctext=0; fnc1=0; /*Step 1: Detect FNC1 markers and estimate the required buffer size.*/ for(j=0;j<sa_size;j++)if(sa[j]>=0){ qrdataj=qrdata+sa[j]; for(k=0;k<qrdataj->nentries;k++){ int shift; entry=qrdataj->entries+k; shift=0; switch(entry->mode){ /*FNC1 applies to the entire code and ignores subsequent markers.*/ case QR_MODE_FNC1_1ST: case QR_MODE_FNC1_2ND:fnc1=1;break; /*2 SJIS bytes will be at most 4 UTF-8 bytes.*/ case QR_MODE_KANJI:shift++; /*We assume at most 4 UTF-8 bytes per input byte. I believe this is true for all the encodings we actually use.*/ case QR_MODE_BYTE:shift++; default:{ /*The remaining two modes are already valid UTF-8.*/ if(QR_MODE_HAS_DATA(entry->mode)){ sa_ctext+=entry->payload.data.len<<shift; } }break; } } } /*Step 2: Convert the entries.*/ sa_text=(char *)malloc((sa_ctext+1)*sizeof(*sa_text)); sa_ntext=0; eci=-1; enc_list[0]=sjis_cd; enc_list[1]=latin1_cd; enc_list[2]=utf8_cd; eci_cd=(iconv_t)-1; err=0; for(j = 0; j < sa_size && !err; j++, sym = &(*sym)->next) { *sym = _zbar_image_scanner_alloc_sym(iscn, ZBAR_QRCODE, 0); (*sym)->datalen = sa_ntext; if(sa[j]<0){ /* generic placeholder for unfinished results */ (*sym)->type = ZBAR_PARTIAL; /*Skip all contiguous missing segments.*/ for(j++;j<sa_size&&sa[j]<0;j++); /*If there aren't any more, stop.*/ if(j>=sa_size)break; /* mark break in data */ sa_text[sa_ntext++]='\0'; (*sym)->datalen = sa_ntext; /* advance to next symbol */ sym = &(*sym)->next; *sym = _zbar_image_scanner_alloc_sym(iscn, ZBAR_QRCODE, 0); } qrdataj=qrdata+sa[j]; /* expose bounding box */ sym_add_point(*sym, qrdataj->bbox[0][0], qrdataj->bbox[0][1]); sym_add_point(*sym, qrdataj->bbox[2][0], qrdataj->bbox[2][1]); sym_add_point(*sym, qrdataj->bbox[3][0], qrdataj->bbox[3][1]); sym_add_point(*sym, qrdataj->bbox[1][0], qrdataj->bbox[1][1]); /* approx symbol "up" direction */ dir[0] = (qrdataj->bbox[0][0] - qrdataj->bbox[2][0] + qrdataj->bbox[1][0] - qrdataj->bbox[3][0]); dir[1] = (qrdataj->bbox[2][1] - qrdataj->bbox[0][1] + qrdataj->bbox[3][1] - qrdataj->bbox[1][1]); horiz = abs(dir[0]) > abs(dir[1]); (*sym)->orient = horiz + 2 * (dir[1 - horiz] < 0); for(k=0;k<qrdataj->nentries&&!err;k++){ size_t inleft; size_t outleft; char *in; char *out; entry=qrdataj->entries+k; switch(entry->mode){ case QR_MODE_NUM:{ if(sa_ctext-sa_ntext>=(size_t)entry->payload.data.len){ memcpy(sa_text+sa_ntext,entry->payload.data.buf, entry->payload.data.len*sizeof(*sa_text)); sa_ntext+=entry->payload.data.len; } else err=1; }break; case QR_MODE_ALNUM:{ char *p; in=(char *)entry->payload.data.buf; inleft=entry->payload.data.len; /*FNC1 uses '%' as an escape character.*/ if(fnc1)for(;;){ size_t plen; char c; p=memchr(in,'%',inleft*sizeof(*in)); if(p==NULL)break; plen=p-in; if(sa_ctext-sa_ntext<plen+1)break; memcpy(sa_text+sa_ntext,in,plen*sizeof(*in)); sa_ntext+=plen; /*Two '%'s is a literal '%'*/ if(plen+1<inleft&&p[1]=='%'){ c='%'; plen++; p++; } /*One '%' is the ASCII group separator.*/ else c=0x1D; sa_text[sa_ntext++]=c; inleft-=plen+1; in=p+1; } else p=NULL; if(p!=NULL||sa_ctext-sa_ntext<inleft)err=1; else{ memcpy(sa_text+sa_ntext,in,inleft*sizeof(*sa_text)); sa_ntext+=inleft; } }break; /*TODO: This will not handle a multi-byte sequence split between multiple data blocks. Does such a thing occur? Is it allowed? It requires copying buffers around to handle correctly.*/ case QR_MODE_BYTE:{ in=(char *)entry->payload.data.buf; inleft=entry->payload.data.len; out=sa_text+sa_ntext; outleft=sa_ctext-sa_ntext; /*If we have no specified encoding, attempt to auto-detect it.*/ if(eci<0){ int ei; /*First check for the UTF-8 BOM.*/ if(inleft>=3&& in[0]==(char)0xEF&&in[1]==(char)0xBB&&in[2]==(char)0xBF){ in+=3; inleft-=3; /*Actually try converting (to check validity).*/ err=utf8_cd==(iconv_t)-1|| iconv(utf8_cd,&in,&inleft,&out,&outleft)==(size_t)-1; if(!err){ sa_ntext=out-sa_text; enc_list_mtf(enc_list,utf8_cd); continue; } in=(char *)entry->payload.data.buf; inleft=entry->payload.data.len; out=sa_text+sa_ntext; outleft=sa_ctext-sa_ntext; } /*If the text is 8-bit clean, prefer UTF-8 over SJIS, since SJIS will corrupt the backslashes used for DoCoMo formats.*/ else if(text_is_ascii((unsigned char *)in,inleft)){ enc_list_mtf(enc_list,utf8_cd); } /*Try our list of encodings.*/ for(ei=0;ei<3;ei++)if(enc_list[ei]!=(iconv_t)-1){ /*According to the standard, ISO/IEC 8859-1 (one hyphen) is supposed to be used, but reality is not always so. It's got an invalid range that is used often with SJIS and UTF-8, though, which makes detection easier. However, iconv() does not properly reject characters in those ranges, since ISO-8859-1 (two hyphens) defines a number of seldom-used control code characters there. So if we see any of those characters, move this conversion to the end of the list.*/ if(ei<2&&enc_list[ei]==latin1_cd&& !text_is_latin1((unsigned char *)in,inleft)){ int ej; for(ej=ei+1;ej<3;ej++)enc_list[ej-1]=enc_list[ej]; enc_list[2]=latin1_cd; } err=iconv(enc_list[ei],&in,&inleft,&out,&outleft)==(size_t)-1; if(!err){ sa_ntext=out-sa_text; enc_list_mtf(enc_list,enc_list[ei]); break; } in=(char *)entry->payload.data.buf; inleft=entry->payload.data.len; out=sa_text+sa_ntext; outleft=sa_ctext-sa_ntext; } } /*We were actually given a character set; use it.*/ else{ err=eci_cd==(iconv_t)-1|| iconv(eci_cd,&in,&inleft,&out,&outleft)==(size_t)-1; if(!err)sa_ntext=out-sa_text; } }break; /*Kanji mode always uses SJIS.*/ case QR_MODE_KANJI:{ in=(char *)entry->payload.data.buf; inleft=entry->payload.data.len; out=sa_text+sa_ntext; outleft=sa_ctext-sa_ntext; err=sjis_cd==(iconv_t)-1|| iconv(sjis_cd,&in,&inleft,&out,&outleft)==(size_t)-1; if(!err)sa_ntext=out-sa_text; }break; /*Check to see if a character set was specified.*/ case QR_MODE_ECI:{ const char *enc; char buf[16]; unsigned cur_eci; cur_eci=entry->payload.eci; if(cur_eci<=QR_ECI_ISO8859_16&&cur_eci!=14){ if(cur_eci!=QR_ECI_GLI0&&cur_eci!=QR_ECI_CP437){ sprintf(buf,"ISO8859-%i",QR_MAXI(cur_eci,3)-2); enc=buf; } /*Note that CP437 requires an iconv compiled with --enable-extra-encodings, and thus may not be available.*/ else enc="CP437"; } else if(cur_eci==QR_ECI_SJIS)enc="SJIS"; /*Don't know what this ECI code specifies, but not an encoding that we recognize.*/ else continue; eci=cur_eci; eci_cd=iconv_open("UTF-8",enc); }break; /*Silence stupid compiler warnings.*/ default:break; } } /*If eci should be reset between codes, do so.*/ if(eci<=QR_ECI_GLI1){ eci=-1; if(eci_cd!=(iconv_t)-1)iconv_close(eci_cd); } } if(eci_cd!=(iconv_t)-1)iconv_close(eci_cd); if(!err){ zbar_symbol_t *sa_sym; sa_text[sa_ntext++]='\0'; if(sa_ctext+1>sa_ntext){ sa_text=(char *)realloc(sa_text,sa_ntext*sizeof(*sa_text)); } if(sa_size == 1) sa_sym = syms; else { /* cheap out w/axis aligned bbox for now */ int xmin = img->width, xmax = -2; int ymin = img->height, ymax = -2; /* create "virtual" container symbol for composite result */ sa_sym = _zbar_image_scanner_alloc_sym(iscn, ZBAR_QRCODE, 0); sa_sym->syms = _zbar_symbol_set_create(); sa_sym->syms->head = syms; /* fixup data references */ for(; syms; syms = syms->next) { int next; _zbar_symbol_refcnt(syms, 1); if(syms->type == ZBAR_PARTIAL) sa_sym->type = ZBAR_PARTIAL; else for(j = 0; j < syms->npts; j++) { int u = syms->pts[j].x; if(xmin >= u) xmin = u - 1; if(xmax <= u) xmax = u + 1; u = syms->pts[j].y; if(ymin >= u) ymin = u - 1; if(ymax <= u) ymax = u + 1; } syms->data = sa_text + syms->datalen; next = (syms->next) ? syms->next->datalen : sa_ntext; assert(next > syms->datalen); syms->datalen = next - syms->datalen - 1; } if(xmax >= -1) { sym_add_point(sa_sym, xmin, ymin); sym_add_point(sa_sym, xmin, ymax); sym_add_point(sa_sym, xmax, ymax); sym_add_point(sa_sym, xmax, ymin); } } sa_sym->data = sa_text; sa_sym->data_alloc = sa_ntext; sa_sym->datalen = sa_ntext - 1; _zbar_image_scanner_add_sym(iscn, sa_sym); } else { _zbar_image_scanner_recycle_syms(iscn, syms); free(sa_text); } } if(utf8_cd!=(iconv_t)-1)iconv_close(utf8_cd); if(sjis_cd!=(iconv_t)-1)iconv_close(sjis_cd); if(latin1_cd!=(iconv_t)-1)iconv_close(latin1_cd); free(mark); return ntext; }
int main (int argc, char *argv[]) { int fd; struct stat st; int result; char *inmem; char *outmem; size_t inlen; size_t outlen; #ifdef HAVE_MCHECK_H mtrace (); #endif if (!argv[1]) exit (1); /* Make the content of the file available in memory. */ fd = open (argv[1], O_RDONLY); if (fd == -1) error (EXIT_FAILURE, errno, "cannot open %s", basename (argv[1])); if (fstat (fd, &st) != 0) error (EXIT_FAILURE, errno, "cannot stat %s", basename (argv[1])); memlen = st.st_size; mem = (char *) malloc (memlen + 1); if (mem == NULL) error (EXIT_FAILURE, errno, "while allocating buffer"); if ((size_t) read (fd, mem, memlen) != memlen) error (EXIT_FAILURE, 0, "cannot read entire file"); mem[memlen] = '\0'; close (fd); /* We have to convert a few things from Latin-1 to UTF-8. */ cd = iconv_open ("UTF-8", "ISO-8859-1"); if (cd == (iconv_t) -1) error (EXIT_FAILURE, errno, "cannot get conversion descriptor"); /* For the second test we have to convert the file content to UTF-8. Since the text is mostly ASCII it should be enough to allocate twice as much memory for the UTF-8 text than for the Latin-1 text. */ umem = (char *) calloc (2, memlen); if (umem == NULL) error (EXIT_FAILURE, errno, "while allocating buffer"); inmem = mem; inlen = memlen; outmem = umem; outlen = 2 * memlen - 1; iconv (cd, &inmem, &inlen, &outmem, &outlen); umemlen = outmem - umem; if (inlen != 0) error (EXIT_FAILURE, errno, "cannot convert buffer"); #ifdef DEBUG re_set_syntax (RE_DEBUG); #endif /* Run the actual tests. All tests are run in a single-byte and a multi-byte locale. */ result = test_expr ("[הבאגיטךםלמסצףעפ�תש�]", 2, 2); result |= test_expr ("G.ran", 2, 3); result |= test_expr ("G.\\{1\\}ran", 2, 3); result |= test_expr ("G.*ran", 3, 44); result |= test_expr ("[הבאג]", 0, 0); result |= test_expr ("Uddeborg", 2, 2); result |= test_expr (".Uddeborg", 2, 2); /* Free the resources. */ free (umem); iconv_close (cd); free (mem); return result; }
ORG_LABCRYPTO_ABETTOR_result ORG_LABCRYPTO_ABETTOR__unicode__utf8_to_utf16( ORG_LABCRYPTO_ABETTOR_string utf8, ORG_LABCRYPTO_ABETTOR_string_ptr utf16, ORG_LABCRYPTO_ABETTOR_length_ptr utf16_len ) { ORG_LABCRYPTO_ABETTOR_uint32 i = 0; iconv_t cd; char *inbuf, *outbuf; size_t inbytesleft, outbytesleft, nchars, utf16_buf_len; #if _WIN32 cd = iconv_open("UTF-16LE", "UTF-8"); #else cd = iconv_open("UTF16LE", "UTF8"); #endif if (cd == (iconv_t) - 1) { printf("iconv_open failed: %d\n", errno); return -1; } inbytesleft = strlen(utf8); if (inbytesleft == 0) { printf("!%s: empty string\n", FUNCTION_MACRO); iconv_close(cd); return -1; } inbuf = utf8; utf16_buf_len = 2 * inbytesleft; *utf16 = malloc(utf16_buf_len); if (!*utf16) { printf("!%s: malloc failed\n", FUNCTION_MACRO); iconv_close(cd); return -1; } outbytesleft = utf16_buf_len; outbuf = *utf16; nchars = iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft); while (nchars == (size_t)-1 && errno == E2BIG) { char *ptr; size_t increase = 10; // increase length a bit size_t len; utf16_buf_len += increase; outbytesleft += increase; ptr = realloc(*utf16, utf16_buf_len); if (!ptr) { printf("!%s: realloc failed\n", FUNCTION_MACRO); free(*utf16); iconv_close(cd); return -1; } len = outbuf - *utf16; *utf16 = ptr; outbuf = *utf16 + len; nchars = iconv(cd, &inbuf, &inbytesleft, &outbuf, &outbytesleft); } if (nchars == (size_t)-1) { printf("!%s: iconv failed: %d\n", FUNCTION_MACRO, errno); free(*utf16); iconv_close(cd); return -1; } iconv_close(cd); *utf16_len = utf16_buf_len - outbytesleft; for (; i < *utf16_len; i += 2) { char temp = (*utf16)[i]; (*utf16)[i] = (*utf16)[i + 1]; (*utf16)[i + 1] = temp; } return 0; }
// make our proposed ZIP-file chunk map ngx_int_t ngx_http_zip_generate_pieces(ngx_http_request_t *r, ngx_http_zip_ctx_t *ctx) { ngx_uint_t i, piece_i; off_t offset = 0; time_t unix_time = 0; ngx_uint_t dos_time = 0; ngx_http_zip_file_t *file; ngx_http_zip_piece_t *header_piece, *file_piece, *trailer_piece, *cd_piece; ngx_http_variable_value_t *vv; if ((vv = ngx_palloc(r->pool, sizeof(ngx_http_variable_value_t))) == NULL) return NGX_ERROR; ctx->unicode_path = 0; #ifdef NGX_ZIP_HAVE_ICONV iconv_t *iconv_cd = NULL; #endif // Let's try to find special header that contains separator string. // What for this strange separator string you ask? // Sometimes there might be a problem converting UTF-8 to zips native // charset(CP866), because it's not 1:1 conversion. So my solution is to // developers provide their own version of converted filename and pass it // to mod_zip along with UTF-8 filename which will go straight to Unicode // path extra field (thanks to tony2001). So separator is a solution that doesn't // break current format. And allows passing file name in both formats as one string. // // Normally we pass: // CRC32 <size> <path> <filename>\n // ... // * <filename> passed to archive as filename w/o conversion // * UFT-8 flag for filename is set // // tony2001's X-Archive-Charset: <charset> way: // CRC32 <size> <path> <filename>\n // ... // * <filename> is accepted to be UTF-8 string // * <filename>, converted to <charset> and passed to archive as filename // * <filename> passed to Unicode path extra field // * UFT-8 flag for filename is not set // // My X-Archive-Name-Sep: <sep> solution: // CRC32 <size> <path> <native-filename><sep><utf8-filename>\n // ... // * <native-filename> passed to archive as filename w/o conversion // * <utf8-filename> passed to Unicode path extra field // * UFT-8 flag for filename is not set // // You just need to provide separator that won't interfere with file names. I suggest using '/' // as it is ASCII character and forbidden on most (if not all) platforms as a part of filename. // // Empty separator string means no UTF-8 version provided. Usefull when we need to pass only // names encoded in native charset. It's equal to 'X-Archive-Charset: native;'. // Note: Currently it is impossible after '[PATCH] Support for UTF-8 file names.'(4f61592b) // because UFT-8 flag (zip_utf8_flag) is set default for templates. if(ngx_http_upstream_header_variable(r, vv, (uintptr_t)(&ngx_http_zip_header_name_separator)) == NGX_OK && !vv->not_found) { ctx->native_charset = 1; if(vv->len) ctx->unicode_path = 1; } else { #ifdef NGX_ZIP_HAVE_ICONV if (ngx_http_upstream_header_variable(r, vv, (uintptr_t)(&ngx_http_zip_header_charset_name)) == NGX_OK && !vv->not_found && ngx_strncmp(vv->data, "utf8", sizeof("utf8") - 1) != 0) { if(ngx_strncmp(vv->data, "native", sizeof("native") - 1)) { char encoding[ICONV_CSNMAXLEN]; snprintf(encoding, sizeof(encoding), "%s//TRANSLIT//IGNORE", vv->data); iconv_cd = iconv_open((const char *)encoding, "utf-8"); if (iconv_cd == (iconv_t)(-1)) { ngx_log_error(NGX_LOG_WARN, r->connection->log, errno, "mod_zip: iconv_open('%s', 'utf-8') failed", vv->data); iconv_cd = NULL; } else { ctx->unicode_path = 1; ctx->native_charset = 1; } } else ctx->native_charset = 1; } #endif } // pieces: for each file: header, data, footer (if needed) -> 2 or 3 per file // plus file footer (CD + [zip64 end + zip64 locator +] end of cd) in one chunk ctx->pieces_n = ctx->files.nelts * (2 + (!!ctx->missing_crc32)) + 1; if ((ctx->pieces = ngx_palloc(r->pool, sizeof(ngx_http_zip_piece_t) * ctx->pieces_n)) == NULL) return NGX_ERROR; ctx->cd_size = 0; unix_time = time(NULL); dos_time = ngx_dos_time(unix_time); for (piece_i = i = 0; i < ctx->files.nelts; i++) { file = &((ngx_http_zip_file_t *)ctx->files.elts)[i]; file->offset = offset; file->unix_time = unix_time; file->dos_time = dos_time; if(ctx->unicode_path) { #ifdef NGX_ZIP_HAVE_ICONV if (iconv_cd) { size_t inlen = file->filename.len, outlen, outleft; u_char *p, *in; //inbuf file->filename_utf8.data = ngx_pnalloc(r->pool, file->filename.len + 1); ngx_memcpy(file->filename_utf8.data, file->filename.data, file->filename.len); file->filename_utf8.len = file->filename.len; file->filename_utf8.data[file->filename.len] = '\0'; //outbuf outlen = outleft = inlen * sizeof(int) + 15; file->filename.data = ngx_pnalloc(r->pool, outlen + 1); in = file->filename_utf8.data; p = file->filename.data; //reset state iconv(iconv_cd, NULL, NULL, NULL, NULL); //convert the string iconv(iconv_cd, (char **)&in, &inlen, (char **)&p, &outleft); //XXX if (res == (size_t)-1) { ? } file->filename.len = outlen - outleft; file->filename_utf8_crc32 = ngx_crc32_long(file->filename_utf8.data, file->filename_utf8.len); } #endif else if(vv->len) { const char * sep = ngx_http_zip_strnrstr((const char*)file->filename.data, file->filename.len, (const char*)vv->data, vv->len); if(sep) { size_t utf8_len = file->filename.len - vv->len - (size_t)(sep - (const char *)file->filename.data); file->filename_utf8.data = ngx_pnalloc(r->pool, utf8_len); file->filename_utf8.len = utf8_len; ngx_memcpy(file->filename_utf8.data, sep + vv->len, utf8_len); file->filename.len -= utf8_len + vv->len; file->filename_utf8_crc32 = ngx_crc32_long(file->filename_utf8.data, file->filename_utf8.len); } /* else { } */ // Separator not found. Okay, no extra field for this one then. } } if(offset >= (off_t) NGX_MAX_UINT32_VALUE) ctx->zip64_used = file->need_zip64_offset = 1; if(file->size >= (off_t) NGX_MAX_UINT32_VALUE) ctx->zip64_used = file->need_zip64 = 1; ctx->cd_size += sizeof(ngx_zip_central_directory_file_header_t) + file->filename.len + sizeof(ngx_zip_extra_field_central_t) + (file->need_zip64_offset ? (file->need_zip64 ? sizeof(ngx_zip_extra_field_zip64_sizes_offset_t) : sizeof(ngx_zip_extra_field_zip64_offset_only_t)) : (file->need_zip64 ? sizeof(ngx_zip_extra_field_zip64_sizes_only_t) : 0) + (ctx->unicode_path && file->filename_utf8.len ? (sizeof(ngx_zip_extra_field_unicode_path_t) + file->filename_utf8.len): 0) ); header_piece = &ctx->pieces[piece_i++]; header_piece->type = zip_header_piece; header_piece->file = file; header_piece->range.start = offset; header_piece->range.end = offset += sizeof(ngx_zip_local_file_header_t) + file->filename.len + sizeof(ngx_zip_extra_field_local_t) + (file->need_zip64? sizeof(ngx_zip_extra_field_zip64_sizes_only_t):0) + (ctx->unicode_path && file->filename_utf8.len ? (sizeof(ngx_zip_extra_field_unicode_path_t) + file->filename_utf8.len): 0); file_piece = &ctx->pieces[piece_i++]; file_piece->type = zip_file_piece; file_piece->file = file; file_piece->range.start = offset; file_piece->range.end = offset += file->size; //!note: (sizeless chunks): we need file size here / or mark it and modify ranges after if (file->missing_crc32) { // if incomplete header -> add footer with that info to file trailer_piece = &ctx->pieces[piece_i++]; trailer_piece->type = zip_trailer_piece; trailer_piece->file = file; trailer_piece->range.start = offset; trailer_piece->range.end = offset += file->need_zip64? sizeof(ngx_zip_data_descriptor_zip64_t) : sizeof(ngx_zip_data_descriptor_t); //!!TODO: if we want Ranges support - here we know it is impossible for this set //? check conf/some state and abort? } } #ifdef NGX_ZIP_HAVE_ICONV if (iconv_cd) { iconv_close(iconv_cd); } #endif ctx->zip64_used |= offset >= (off_t) NGX_MAX_UINT32_VALUE || ctx->files.nelts >= NGX_MAX_UINT16_VALUE; ctx->cd_size += sizeof(ngx_zip_end_of_central_directory_record_t); if (ctx->zip64_used) ctx->cd_size += sizeof(ngx_zip_zip64_end_of_central_directory_record_t) + sizeof(ngx_zip_zip64_end_of_central_directory_locator_t); cd_piece = &ctx->pieces[piece_i++]; cd_piece->type = zip_central_directory_piece; cd_piece->range.start = offset; cd_piece->range.end = offset += ctx->cd_size; ctx->pieces_n = piece_i; //!! nasty hack (truncating allocated array without reallocation) ctx->archive_size = offset; return NGX_OK; }
int git_path_iconv_init_precompose(git_path_iconv_t *ic) { git_buf_init(&ic->buf, 0); ic->map = iconv_open(GIT_PATH_REPO_ENCODING, GIT_PATH_NATIVE_ENCODING); return 0; }
static void printSelBuf(FILE * fout, Atom sel_type, unsigned char *sel_buf, size_t sel_len) { #ifdef HAVE_ICONV Atom html = XInternAtom(dpy, "text/html", True); #endif if (fverb == OVERBOSE) { /* print in verbose mode only */ char *atom_name = XGetAtomName(dpy, sel_type); fprintf(stderr, "Type is %s.\n", atom_name); XFree(atom_name); } if (sel_type == XA_INTEGER) { /* if the buffer contains integers, print them */ long *long_buf = (long *) sel_buf; size_t long_len = sel_len / sizeof(long); while (long_len--) fprintf(fout, "%ld\n", *long_buf++); return; } if (sel_type == XA_ATOM) { /* if the buffer contains atoms, print their names */ Atom *atom_buf = (Atom *) sel_buf; size_t atom_len = sel_len / sizeof(Atom); while (atom_len--) { char *atom_name = XGetAtomName(dpy, *atom_buf++); fprintf(fout, "%s\n", atom_name); XFree(atom_name); } return; } #ifdef HAVE_ICONV if (html != None && sel_type == html) { /* if the buffer contains UCS-2 (UTF-16), convert to * UTF-8. Mozilla-based browsers do this for the * text/html target. */ iconv_t cd; char *sel_charset = NULL; if (sel_buf[0] == 0xFF && sel_buf[1] == 0xFE) sel_charset = "UTF-16LE"; else if (sel_buf[0] == 0xFE && sel_buf[1] == 0xFF) sel_charset = "UTF-16BE"; if (sel_charset != NULL && (cd = iconv_open("UTF-8", sel_charset)) != (iconv_t) - 1) { char *out_buf_start = malloc(sel_len), *in_buf = (char *) sel_buf + 2, *out_buf = out_buf_start; size_t in_bytesleft = sel_len - 2, out_bytesleft = sel_len; while (iconv(cd, &in_buf, &in_bytesleft, &out_buf, &out_bytesleft) == -1 && errno == E2BIG) { fwrite(out_buf_start, sizeof(char), sel_len - out_bytesleft, fout); out_buf = out_buf_start; out_bytesleft = sel_len; } if (out_buf != out_buf_start) fwrite(out_buf_start, sizeof(char), sel_len - out_bytesleft, fout); free(out_buf_start); iconv_close(cd); return; } } #endif /* otherwise, print the raw buffer out */ fwrite(sel_buf, sizeof(char), sel_len, fout); }
static rc_uint_type wind_MultiByteToWideChar (rc_uint_type cp, const char *mb, unichar *u, rc_uint_type u_len) { rc_uint_type ret = 0; #if defined (_WIN32) || defined (__CYGWIN__) rc_uint_type conv_flags = MB_PRECOMPOSED; /* MB_PRECOMPOSED is not allowed for UTF-7 or UTF-8. MultiByteToWideChar will set the last error to ERROR_INVALID_FLAGS if we do. */ if (cp == CP_UTF8 || cp == CP_UTF7) conv_flags = 0; ret = (rc_uint_type) MultiByteToWideChar (cp, conv_flags, mb, -1, u, u_len); /* Convert to bytes. */ ret *= sizeof (unichar); #elif defined (HAVE_ICONV) int first = 1; char tmp[32]; char *p_tmp; const char *iconv_name = wind_iconv_cp (cp); if (!mb || !iconv_name) return 0; iconv_t cd = iconv_open ("UTF-16LE", iconv_name); while (1) { int iret; const char *n_mb = ""; char *n_tmp = ""; p_tmp = tmp; iret = iconv_onechar (cd, (ICONV_CONST char *) mb, p_tmp, 32, & n_mb, & n_tmp); if (first) { first = 0; continue; } if (!iret) { size_t l_tmp = (size_t) (n_tmp - p_tmp); if (u) { if ((size_t) u_len < l_tmp) break; memcpy (u, tmp, l_tmp); u += l_tmp/2; u_len -= l_tmp; } ret += l_tmp; } else break; if (tmp[0] == 0 && tmp[1] == 0) break; mb = n_mb; } iconv_close (cd); #else if (cp) ret = 0; ret = strlen (mb) + 1; ret *= sizeof (unichar); if (u != NULL && u_len != 0) { do { *u++ = ((unichar) *mb) & 0xff; --u_len; mb++; } while (u_len != 0 && mb[-1] != 0); } if (u != NULL && u_len != 0) *u = 0; #endif return ret; }
void test(const char *from, const char *fromstr, int fromsize, const char *to, const char *tostr, int tosize, int errcode, int bufsize, int line) { char outbuf[BUFSIZ]; char *pin; char *pout; size_t inbytesleft; size_t outbytesleft; iconv_t cd; size_t r; #ifdef USE_LIBICONV_DLL char dllpath[_MAX_PATH]; #endif cd = iconv_open(to, from); if (cd == (iconv_t)(-1)) { printf("%s -> %s: NG: INVALID ENCODING NAME: line=%d\n", from, to, line); exit(1); } #ifdef USE_LIBICONV_DLL if (((rec_iconv_t *)cd)->hlibiconv != NULL) GetModuleFileNameA(((rec_iconv_t *)cd)->hlibiconv, dllpath, sizeof(dllpath)); if (use_dll && ((rec_iconv_t *)cd)->hlibiconv == NULL) { printf("%s: %s -> %s: NG: FAILED TO USE DLL: line=%d\n", dllpath, from, to, line); exit(1); } else if (!use_dll && ((rec_iconv_t *)cd)->hlibiconv != NULL) { printf("%s: %s -> %s: NG: DLL IS LOADED UNEXPECTEDLY: line=%d\n", dllpath, from, to, line); exit(1); } #endif errno = 0; pin = (char *)fromstr; pout = outbuf; inbytesleft = fromsize; outbytesleft = bufsize; r = iconv(cd, &pin, &inbytesleft, &pout, &outbytesleft); if (r != (size_t)(-1)) r = iconv(cd, NULL, NULL, &pout, &outbytesleft); *pout = 0; #ifdef USE_LIBICONV_DLL if (use_dll) printf("%s: ", dllpath); #endif printf("%s(%s) -> ", from, tohex(fromstr, fromsize)); printf("%s(%s%s%s): ", to, tohex(tostr, tosize), errcode == 0 ? "" : ":", errcode == 0 ? "" : errstr(errcode)); if (strcmp(outbuf, tostr) == 0 && errno == errcode) printf("OK\n"); else { printf("RESULT(%s:%s): ", tohex(outbuf, sizeof(outbuf) - outbytesleft), errstr(errno)); printf("NG: line=%d\n", line); exit(1); } }
int my_xmlStrncopy(char ** out, const char * in, int len) { if(in) { size_t lin=0; size_t lout=0; int l1=0; int l2=0; int retval=1; char *inbuf; char *inbuf2; char *outbuf; char *outbuf2; lin=strlen(in); l2=xmlUTF8Strlen((xmlChar*)in); if(l2<0) lout=l1; else if (len>0 && len<l2) lout=len; else lout=l2; inbuf=inbuf2=(char *)malloc((lin+1)*sizeof(char)); outbuf=outbuf2=(char *)malloc((lout+1)*sizeof(char)); memcpy(inbuf,in,lin); l1=lin; l2=lout; #ifndef LINUX if(my_UTF8Toisolat1(&outbuf2,&lout,(const char **)&inbuf2,&lin)<0) { #else if(my_UTF8Toisolat1(&outbuf2,&lout,&inbuf2,&lin)<0) { #endif retval=-1; } free(inbuf); outbuf[l2]=0; if(*out) { memcpy(*out,outbuf,l2+1); free(outbuf); } else { *out=outbuf; } return retval<0?-1:l2; } else return -1; } #ifndef LINUX int my_UTF8Toisolat1(char **dest, size_t * lu, const char **src, size_t * l) #else int my_UTF8Toisolat1(char **dest, size_t * lu, char **src, size_t * l) #endif { iconv_t t=iconv_open("ISO_8859-1","UTF-8"); iconv(t, src, l, dest, lu); iconv_close(t); return 1; }