//日期/时间字符串 //length对于年份,=2则为短格式(如2004年则返回"04"),其余 //数值则为4位字符串 //对于其他日期/时间,=2则为固定两位字符串,(如1返回"01", //29返回"29"),其余数值则根据具体日期/时间返回1或2位字符串 //因此只有length=2的情况才会有相应操作,其余均采用默认操作。 LPCTSTR ringDateTime::year2str(int length/*=0*/) { if(length == 2) return formatStr(m_str,year()%100,length); else return formatStr(m_str,year(),0); }
void MainLayer::createSpecRecomend() { if (!_hideNode->isVisible() || _pageView->getCurPageIndex() != MAIN_PAGE || !_isUseSpec) return; auto rt = RenderTexture::create(_pageView->getContentSize().width, _pageView->getContentSize().height, Texture2D::PixelFormat::RGBA8888, GL_DEPTH24_STENCIL8); rt->beginWithClear(0, 0, 0, 0, 0); _pageView->getPage(MAIN_PAGE)->visit(_director->getRenderer(), _director->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW), true); rt->end(); rt->getSprite()->setScaleY(-1); auto sprite = dynamic_cast<Sprite*>(LsTools::seekNodeByName(_rootNode, formatStr("dy_%d", MAIN_PAGE))); sprite->setTexture(rt->getSprite()->getTexture()); auto pane1 = LsTools::seekNodeByName(_pageView, "Panel_0"); auto img3 = (ui::ImageView*)(LsTools::seekNodeByName(pane1, "3")); auto img0 = (ui::ImageView*)(LsTools::seekNodeByName(pane1, "0")); auto img2 = (ui::ImageView*)(LsTools::seekNodeByName(pane1, "2")); auto img1 = (ui::ImageView*)(LsTools::seekNodeByName(pane1, "1")); Rect rect(img1->getLeftBoundary(), img1->getBottomBoundary(), img3->getRightBoundary() - img1->getLeftBoundary(), img2->getContentSize().height); sprite->setTextureRect(Rect(rect.origin.x, rect.origin.y, rect.size.width, 300)); float bot = img2->getBottomBoundary() - (sprite->getTextureRect().getMaxY() - sprite->getTextureRect().getMinY()) / 2 - 5; }
ui::Button* MainLayer::getCurTabBtn() { int index = _pageView->getCurPageIndex(); auto node = LsTools::seekNodeByName(_rootNode, "Node_btn"); index = index == MAIN_PAGE ? index : index - 1; auto btn = node->getChildByName<Button*>(formatStr("Button_%d", index)); return btn; }
void MainLayer::updateRecommend(float dt) { if ((_focus && _focus->getTag() == CENTER_RECOMEND_TAG) || !_recommend || !_hideNode->isVisible()) return; /*if (NM->_isLoadFile || NM->_isSendCommend) return;*/ if (_pageView->getCurPageIndex() != MAIN_PAGE) return; _recommendIndex++; if (_recommendIndex >= 5) _recommendIndex = 0; std::string fileName = _recommendDoc[_recommendIndex]["png"].GetString(); if (fileName.empty() || !FileUtils::getInstance()->isFileExist(fileName)) return; _recommend->loadTexture(fileName); for (auto& child : LsTools::seekNodeByName(_rootNode, "Node_Dot")->getChildren()) { auto sprite = dynamic_cast<Sprite*>(child); sprite->setTexture("Common_Dot01.png"); } auto dot = dynamic_cast<Sprite*>(LsTools::seekNodeByName( _rootNode, formatStr("Common_Dot_%02d", _recommendIndex + 1))); dot->setTexture("Common_Dot02.png"); auto title = _recommend->getChildByName<Sprite*>("title"); title->setTexture(_recommendDoc[_recommendIndex]["name"].GetString()); _recommend->getChildByName<ui::Text*>("intro")->setString(_recommendDoc[_recommendIndex]["intro"].GetString()); float gameScore = _recommendDoc[_recommendIndex]["score"].GetDouble(); int sw = (int)gameScore % 10; int gw = (int)(gameScore * 10) % 10; _recommend->getChildByName<ui::Text*>("score_1")->setString(formatStr("%d", sw)); _recommend->getChildByName<ui::Text*>("score_2")->setString(formatStr(".%d", gw)); createSpecRecomend(); }
void MainLayer::createSpec(int index) { //return; if (!_hideNode->isVisible() || !_isUseSpec) return; _pageView->setPositionX(-MY_SCREEN.width * index); auto rt = RenderTexture::create(_pageView->getContentSize().width, _pageView->getContentSize().height, Texture2D::PixelFormat::RGBA8888, GL_DEPTH24_STENCIL8); rt->beginWithClear(0, 0, 0, 0, 0); _pageView->getPage(index)->visit(_director->getRenderer(), _director->getMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW), true); rt->end(); rt->getSprite()->setScaleY(-1); // _renderPageViewTex->saveToFile("pageview.png"); auto sprite = dynamic_cast<Sprite*>(LsTools::seekNodeByName(_rootNode, formatStr("dy_%d", index))); sprite->setTexture(rt->getSprite()->getTexture()); //sprite->setTextureRect(rt->getSprite()->getTextureRect()); if (index == 0)//main page { auto pane1 = LsTools::seekNodeByName(_pageView, "Panel_0"); auto img3 = (ui::ImageView*)(LsTools::seekNodeByName(pane1, "3")); auto img0 = (ui::ImageView*)(LsTools::seekNodeByName(pane1, "0")); auto img2 = (ui::ImageView*)(LsTools::seekNodeByName(pane1, "2")); auto img1 = (ui::ImageView*)(LsTools::seekNodeByName(pane1, "1")); Rect rect(img1->getLeftBoundary(), img1->getBottomBoundary(), img3->getRightBoundary() - img1->getLeftBoundary(), img2->getContentSize().height); sprite->setTextureRect(Rect(rect.origin.x, rect.origin.y, rect.size.width, 300)); float bot = img2->getBottomBoundary() - (sprite->getTextureRect().getMaxY() - sprite->getTextureRect().getMinY()) / 2 - 5; //sprite->setPosition(_pageView->getContentSize().width / 2, bot); } else/* if (curPage == 1)*///game category page { auto pane2 = LsTools::seekNodeByName(_pageView, "Panel_1"); auto img0 = (ui::ImageView*)(LsTools::seekNodeByName(pane2, "0")); auto img5 = (ui::ImageView*)(LsTools::seekNodeByName(pane2, "5")); Rect rect(img0->getLeftBoundary(), img0->getBottomBoundary(), img5->getRightBoundary() - img0->getLeftBoundary(), img5->getContentSize().height); sprite->setTextureRect(Rect(rect.origin.x, rect.origin.y, rect.size.width, 300)); float bot = img0->getBottomBoundary() - (sprite->getTextureRect().getMaxY() - sprite->getTextureRect().getMinY()) / 2 - 5; //sprite->setPosition(_pageView->getContentSize().width / 2, bot); } }
DgOutLocFile& DgOutGeoJSONFile::insert(const DgDVec2D& pt) { DgOutGeoJSONFile& o(*this); const int maxBuffSize = 200; char buff[maxBuffSize]; sprintf(buff, formatStr(), pt.x(), pt.y()); o << buff; o.flush(); return o; }
size_t wcsftime(wchar_t *s, const size_t maxsize, const wchar_t *format, const struct tm *t) { wxCharBuffer sBuf(maxsize/sizeof(wchar_t)); wxString formatStr(format); wxCharBuffer bufFormatStr(formatStr.mb_str()); size_t sz = strftime(sBuf.data(), maxsize/sizeof(wchar_t), bufFormatStr, t); wxMB2WC(s, sBuf, maxsize); return sz; }
void MainLayer::changeTab(int index) { if (index >= PAGE_COUNT) return; LS_LOG("index %d", index); _pageView->scrollToPage(index); _tabNode = _pageView->getPage(index); index = index == MAIN_PAGE ? index : index - 1; auto btn = LsTools::seekNodeByName(_rootNode, "Node_btn")->getChildByName<Button*>(formatStr("Button_%d", index)); _navi_Scelect->stopAllActions(); _navi_Scelect->runAction(MoveTo::create(0.2f, Vec2(btn->getPositionX(), _navi_Scelect->getPositionY()))); //_navi_Scelect->setVisible(!_isFocusNotOnTab); }
void MainLayer::clickMainBtn(Ref* sender, Widget::TouchEventType type) { if (type != Widget::TouchEventType::ENDED) return; auto btn = dynamic_cast<Button*>(sender); std::string name = btn->getName(); char ch = name[name.length() - 1]; int index = atoi(formatStr("%c", ch).c_str()); _isFocusNotOnTab = false; removeFocusAction(); _tabNode->setUserObject(nullptr); index = index == MAIN_PAGE ? index : index + 1; changeTab(index); }
// This test is a regression test for a fixed bug in the copy constructor. // It is kept as a global function rather than as a method since the test depends on memory values. // (At least before the bug was fixed, whether it showed up or not depended on memory contents, // which is probably why it didn't show up in the regular test for the copy constructor.) // For this reason, the test isn't changed even though it contains function calls whose results are // not tested and had no problems. Actually, the test failed by *crashing*. static void _testCopyConstructor2() { UErrorCode status = U_ZERO_ERROR; UnicodeString formatStr("Hello World on {0,date,full}", ""); UnicodeString resultStr(" ", ""); UnicodeString result; FieldPosition fp(0); UDate d = Calendar::getNow(); const Formattable fargs( d, Formattable::kIsDate ); MessageFormat* fmt1 = new MessageFormat( formatStr, status ); MessageFormat* fmt2 = new MessageFormat( *fmt1 ); MessageFormat* fmt3; MessageFormat* fmt4; if (fmt1 == NULL) it_err("testCopyConstructor2: (fmt1 != NULL)"); result = fmt1->format( &fargs, 1, resultStr, fp, status ); if (fmt2 == NULL) it_err("testCopyConstructor2: (fmt2 != NULL)"); fmt3 = (MessageFormat*) fmt1->clone(); fmt4 = (MessageFormat*) fmt2->clone(); if (fmt3 == NULL) it_err("testCopyConstructor2: (fmt3 != NULL)"); if (fmt4 == NULL) it_err("testCopyConstructor2: (fmt4 != NULL)"); result = fmt1->format( &fargs, 1, resultStr, fp, status ); result = fmt2->format( &fargs, 1, resultStr, fp, status ); result = fmt3->format( &fargs, 1, resultStr, fp, status ); result = fmt4->format( &fargs, 1, resultStr, fp, status ); delete fmt1; delete fmt2; delete fmt3; delete fmt4; }
LPCTSTR ringDateTime::day2str(int length/*=0*/) { return formatStr(m_str+8,day(),length); }
bool MainLayer::initUI() { _rootNode = CSLoader::createNode("MainScene.csb"); _hideNode = _rootNode->getChildByName<Node*>("Node_Main"); this->addChild(_rootNode); for (auto& child : LsTools::seekNodeByName(_rootNode, "Node_btn")->getChildren()) { auto btn = dynamic_cast<Button*>(child); btn->addTouchEventListener(CC_CALLBACK_2(MainLayer::clickMainBtn, this)); } _pageView = static_cast<PageView*>(LsTools::seekNodeByName(_rootNode, "PageView")); CCASSERT(_pageView, "page view"); _pageView->setCustomScrollThreshold(MY_SCREEN.width / 8); _pageView->setUsingCustomScrollThreshold(true); _pageView->addEventListener(CC_CALLBACK_2(MainLayer::pageViewEvent, this)); _pageView->setClippingType(Layout::ClippingType::SCISSOR); _mapFocusZOrder.clear(); for (ssize_t i = 0; i < PAGE_COUNT; i++) { auto page = _pageView->getPage(i); if (i == MAIN_PAGE) { for (auto& child : page->getChildren()) { //排除倒影 std::string::size_type idx = child->getName().find("dy_"); if (idx != std::string::npos) continue; _mapFocusZOrder.insert(std::pair<int, int>(child->getTag(), child->getLocalZOrder())); auto view = dynamic_cast<ImageView*>(child); view->addTouchEventListener(CC_CALLBACK_2(MainLayer::clickMainPageItem, this)); if (view->getTag() == 22){ _recommend = view; CC_SAFE_RETAIN(_recommend); } } } else if (i == MAIN_PAGE_PLUS){ for (auto& child : page->getChildren()) { //排除倒影 std::string::size_type idx = child->getName().find("dy_"); if (idx != std::string::npos) continue; _mapFocusZOrder.insert(std::pair<int, int>(child->getTag(), child->getLocalZOrder())); auto view = dynamic_cast<ImageView*>(child); view->addTouchEventListener(CC_CALLBACK_2(MainLayer::clickMainPlusPageItem, this)); } } else if (i == CATEGORY_PAGE) { for (auto& child : page->getChildren()) { std::string::size_type idx = child->getName().find("dy_"); if (idx != std::string::npos) continue; _mapFocusZOrder.insert(std::pair<int, int>(child->getTag(), child->getLocalZOrder())); auto view = dynamic_cast<ImageView*>(child); view->addTouchEventListener(CC_CALLBACK_2(MainLayer::clickCategoryPageItem, this)); } } else if (i == MANAGE_PAGE) { for (auto& child : page->getChildren()) { std::string::size_type idx = child->getName().find("dy_"); if (idx != std::string::npos) continue; _mapFocusZOrder.insert(std::pair<int, int>(child->getTag(), child->getLocalZOrder())); auto view = dynamic_cast<ImageView*>(child); if (view->getName() == "3") //Remote QR { CQR_Encode code; float size = 5.5f; std::string ip = PH::getPlatformIP(); std::string str = ZM->getServerAddress() + "?" + formatStr("commend=%d&xLinkIP=%s", CommendEnum::DOWNLOAD_REMOTE, ip.c_str()); LS_LOG("CQR_Encode:%s", str.c_str()); auto drawNode = LsTools::createQRAndDraw(code, size, LsTools::str2charp(str)); drawNode->setPosition(cocos2d::Vec2((view->getContentSize().width - size * code.m_nSymbleSize) / 2 - 6, view->getContentSize().height - (view->getContentSize().height - size * code.m_nSymbleSize) / 2 + 45)); view->addChild(drawNode); } else view->addTouchEventListener(CC_CALLBACK_2(MainLayer::clickManagerPageItem, this)); } } } _tabNode = _pageView->getPage(_pageView->getCurPageIndex()); _navi_Scelect = dynamic_cast<Sprite*>(LsTools::seekNodeByName(_rootNode, "Navi_Scelect")); _bg = _rootNode->getChildByName<Sprite*>("background"); //倒影 if (_isUseSpec) { initSpec(); for (int i = 0; i < PAGE_COUNT; i++) { auto sprite = dynamic_cast<Sprite*>(LsTools::seekNodeByName(_rootNode, formatStr("dy_%d", i))); sprite->setVisible(true); GLchar * fragSource = (GLchar*)String::createWithContentsOfFile( FileUtils::getInstance()->fullPathForFilename("blend.fsh").c_str())->getCString(); auto glprogram = GLProgram::createWithByteArrays(ccPositionTextureColor_noMVP_vert, fragSource); auto program = GLProgramState::getOrCreateWithGLProgram(glprogram); V3F_C4B_T2F_Quad quad = sprite->getQuad(); float minTex = (quad.tl.texCoords.v > quad.bl.texCoords.v ? quad.bl.texCoords.v : quad.tl.texCoords.v); float maxTex = (quad.tl.texCoords.v < quad.bl.texCoords.v ? quad.bl.texCoords.v : quad.tl.texCoords.v); program->setUniformFloat("minTex", minTex); program->setUniformFloat("maxTex", maxTex); sprite->setGLProgramState(program); } } return true; }
void TestMessageFormat::testAdopt() { UErrorCode err = U_ZERO_ERROR; UnicodeString formatStr("{0,date},{1},{2,number}", ""); UnicodeString formatStrChange("{0,number},{1,number},{2,date}", ""); err = U_ZERO_ERROR; MessageFormat msg( formatStr, err); MessageFormat msgCmp( formatStr, err); int32_t count, countCmp; const Format** formats = msg.getFormats(count); const Format** formatsCmp = msgCmp.getFormats(countCmp); const Format** formatsChg = 0; const Format** formatsAct = 0; int32_t countAct; const Format* a; const Format* b; UnicodeString patCmp; UnicodeString patAct; Format** formatsToAdopt; if (!formats || !formatsCmp || (count <= 0) || (count != countCmp)) { errln("Error getting Formats"); return; } int32_t i; for (i = 0; i < count; i++) { a = formats[i]; b = formatsCmp[i]; if ((a != NULL) && (b != NULL)) { if (*a != *b) { errln("a != b"); return; } }else if ((a != NULL) || (b != NULL)) { errln("(a != NULL) || (b != NULL)"); return; } } msg.applyPattern( formatStrChange, err ); //set msg formats to something different int32_t countChg; formatsChg = msg.getFormats(countChg); // tested function if (!formatsChg || (countChg != count)) { errln("Error getting Formats"); return; } UBool diff; diff = TRUE; for (i = 0; i < count; i++) { a = formatsChg[i]; b = formatsCmp[i]; if ((a != NULL) && (b != NULL)) { if (*a == *b) { logln("formatsChg == formatsCmp at index %d", i); diff = FALSE; } } } if (!diff) { errln("*** MSG getFormats diff err."); return; } logln("MSG getFormats tested."); msg.setFormats( formatsCmp, countCmp ); //tested function formatsAct = msg.getFormats(countAct); if (!formatsAct || (countAct <=0) || (countAct != countCmp)) { errln("Error getting Formats"); return; } assertEquals("msgCmp.toPattern()", formatStr, msgCmp.toPattern(patCmp.remove())); assertEquals("msg.toPattern()", formatStr, msg.toPattern(patAct.remove())); for (i = 0; i < countAct; i++) { a = formatsAct[i]; b = formatsCmp[i]; if ((a != NULL) && (b != NULL)) { if (*a != *b) { logln("formatsAct != formatsCmp at index %d", i); errln("a != b"); return; } }else if ((a != NULL) || (b != NULL)) { errln("(a != NULL) || (b != NULL)"); return; } } logln("MSG setFormats tested."); //---- msg.applyPattern( formatStrChange, err ); //set msg formats to something different formatsToAdopt = new Format* [countCmp]; if (!formatsToAdopt) { errln("memory allocation error"); return; } for (i = 0; i < countCmp; i++) { if (formatsCmp[i] == NULL) { formatsToAdopt[i] = NULL; }else{ formatsToAdopt[i] = formatsCmp[i]->clone(); if (!formatsToAdopt[i]) { errln("Can't clone format at index %d", i); return; } } } msg.adoptFormats( formatsToAdopt, countCmp ); // function to test delete[] formatsToAdopt; assertEquals("msgCmp.toPattern()", formatStr, msgCmp.toPattern(patCmp.remove())); assertEquals("msg.toPattern()", formatStr, msg.toPattern(patAct.remove())); formatsAct = msg.getFormats(countAct); if (!formatsAct || (countAct <=0) || (countAct != countCmp)) { errln("Error getting Formats"); return; } for (i = 0; i < countAct; i++) { a = formatsAct[i]; b = formatsCmp[i]; if ((a != NULL) && (b != NULL)) { if (*a != *b) { errln("a != b"); return; } }else if ((a != NULL) || (b != NULL)) { errln("(a != NULL) || (b != NULL)"); return; } } logln("MSG adoptFormats tested."); //---- adoptFormat msg.applyPattern( formatStrChange, err ); //set msg formats to something different formatsToAdopt = new Format* [countCmp]; if (!formatsToAdopt) { errln("memory allocation error"); return; } for (i = 0; i < countCmp; i++) { if (formatsCmp[i] == NULL) { formatsToAdopt[i] = NULL; }else{ formatsToAdopt[i] = formatsCmp[i]->clone(); if (!formatsToAdopt[i]) { errln("Can't clone format at index %d", i); return; } } } for ( i = 0; i < countCmp; i++ ) { msg.adoptFormat( i, formatsToAdopt[i] ); // function to test } delete[] formatsToAdopt; // array itself not needed in this case; assertEquals("msgCmp.toPattern()", formatStr, msgCmp.toPattern(patCmp.remove())); assertEquals("msg.toPattern()", formatStr, msg.toPattern(patAct.remove())); formatsAct = msg.getFormats(countAct); if (!formatsAct || (countAct <=0) || (countAct != countCmp)) { errln("Error getting Formats"); return; } for (i = 0; i < countAct; i++) { a = formatsAct[i]; b = formatsCmp[i]; if ((a != NULL) && (b != NULL)) { if (*a != *b) { errln("a != b"); return; } }else if ((a != NULL) || (b != NULL)) { errln("(a != NULL) || (b != NULL)"); return; } } logln("MSG adoptFormat tested."); }
LPCTSTR ringDateTime::second2str(int length/*=0*/) { return formatStr(m_str+17,second(),length); }
LPCTSTR ringDateTime::minute2str(int length/*=0*/) { return formatStr(m_str+14,minute(),length); }
// populatePower10 grabs data for a particular power of 10 from CLDR. // The loaded data is stored in result. static void populatePower10(const UResourceBundle* power10Bundle, CDFLocaleStyleData* result, UErrorCode& status) { if (U_FAILURE(status)) { return; } char* endPtr = NULL; double power10 = uprv_strtod(ures_getKey(power10Bundle), &endPtr); if (*endPtr != 0) { status = U_INTERNAL_PROGRAM_ERROR; return; } int32_t log10Value = computeLog10(power10, FALSE); // Silently ignore divisors that are too big. if (log10Value == MAX_DIGITS) { return; } int32_t size = ures_getSize(power10Bundle); int32_t numZeros = 0; UBool otherVariantDefined = FALSE; UResourceBundle* variantBundle = NULL; // Iterate over all the plural variants for the power of 10 for (int32_t i = 0; i < size; ++i) { variantBundle = ures_getByIndex(power10Bundle, i, variantBundle, &status); if (U_FAILURE(status)) { ures_close(variantBundle); return; } const char* variant = ures_getKey(variantBundle); int32_t resLen; const UChar* formatStrP = ures_getString(variantBundle, &resLen, &status); if (U_FAILURE(status)) { ures_close(variantBundle); return; } UnicodeString formatStr(false, formatStrP, resLen); if (uprv_strcmp(variant, gOther) == 0) { otherVariantDefined = TRUE; } int32_t nz = populatePrefixSuffix( variant, log10Value, formatStr, result->unitsByVariant, status); if (U_FAILURE(status)) { ures_close(variantBundle); return; } if (nz != numZeros) { // We expect all format strings to have the same number of 0's // left of the decimal point. if (numZeros != 0) { status = U_INTERNAL_PROGRAM_ERROR; ures_close(variantBundle); return; } numZeros = nz; } } ures_close(variantBundle); // We expect to find an OTHER variant for each power of 10. if (!otherVariantDefined) { status = U_INTERNAL_PROGRAM_ERROR; return; } double divisor = power10; for (int32_t i = 1; i < numZeros; ++i) { divisor /= 10.0; } result->divisors[log10Value] = divisor; }
LPCTSTR ringDateTime::month2str(int length/*=0*/) { return formatStr(m_str+5,month(),length); }
LPCTSTR ringDateTime::hour2str(int length/*=0*/) { return formatStr(m_str+11,hour(),length); }
//-------------------------------------------------------------------------- // Process GPS info directory //-------------------------------------------------------------------------- void ProcessGpsInfo(unsigned char * DirStart, int ByteCountUnused, unsigned char * OffsetBase, unsigned ExifLength) { int de; unsigned a; int NumDirEntries; NumDirEntries = Get16u(DirStart); #define DIR_ENTRY_ADDR(Start, Entry) (Start+2+12*(Entry)) if (ShowTags){ printf("(dir has %d entries)\n",NumDirEntries); } ImageInfo.GpsInfoPresent = TRUE; strcpy(ImageInfo.GpsLat, "? ?"); strcpy(ImageInfo.GpsLong, "? ?"); ImageInfo.GpsAlt[0] = 0; for (de=0;de<NumDirEntries;de++){ unsigned Tag, Format, Components; unsigned char * ValuePtr; int ComponentSize; unsigned ByteCount; unsigned char * DirEntry; DirEntry = DIR_ENTRY_ADDR(DirStart, de); if (DirEntry+12 > OffsetBase+ExifLength){ ErrNonfatal("GPS info directory goes past end of exif",0,0); return; } Tag = Get16u(DirEntry); Format = Get16u(DirEntry+2); Components = Get32u(DirEntry+4); if ((Format-1) >= NUM_FORMATS) { // (-1) catches illegal zero case as unsigned underflows to positive large. ErrNonfatal("Illegal number format %d for tag %04x", Format, Tag); continue; } ComponentSize = BytesPerFormat[Format]; ByteCount = Components * ComponentSize; #ifdef SUPERDEBUG printf("GPS tag %x format %s #components %d componentsize %d bytecount %d", Tag, formatStr(Format), Components, ComponentSize, ByteCount); #endif if (ByteCount > 4){ unsigned OffsetVal; OffsetVal = Get32u(DirEntry+8); // If its bigger than 4 bytes, the dir entry contains an offset. if (OffsetVal+ByteCount > ExifLength){ // Bogus pointer offset and / or bytecount value ErrNonfatal("Illegal value pointer for tag %04x", Tag,0); continue; } ValuePtr = OffsetBase+OffsetVal; }else{ // 4 bytes or less and value is in the dir entry itself ValuePtr = DirEntry+8; } switch(Tag){ char FmtString[21]; char TempString[56]; double Values[3]; case TAG_GPS_LAT_REF: ImageInfo.GpsLat[0] = ValuePtr[0]; ImageInfo.GpsLatRef[0] = ValuePtr[0]; ImageInfo.GpsLatRef[1] = '\0'; break; case TAG_GPS_LONG_REF: ImageInfo.GpsLong[0] = ValuePtr[0]; ImageInfo.GpsLongRef[0] = ValuePtr[0]; ImageInfo.GpsLongRef[1] = '\0'; break; case TAG_GPS_LAT: case TAG_GPS_LONG: if (Format != FMT_URATIONAL){ ErrNonfatal("Inappropriate format (%d) for GPS coordinates!", Format, 0); } strcpy(FmtString, "%0.0fd %0.0fm %0.0fs"); for (a=0;a<3;a++){ int den, digits; den = Get32s(ValuePtr+4+a*ComponentSize); digits = 0; while (den > 1 && digits <= 6){ den = den / 10; digits += 1; } if (digits > 6) digits = 6; FmtString[1+a*7] = (char)('2'+digits+(digits ? 1 : 0)); FmtString[3+a*7] = (char)('0'+digits); Values[a] = ConvertAnyFormat(ValuePtr+a*ComponentSize, Format); } sprintf(TempString, FmtString, Values[0], Values[1], Values[2]); if (Tag == TAG_GPS_LAT){ strncpy(ImageInfo.GpsLat+2, TempString, 29); }else{ strncpy(ImageInfo.GpsLong+2, TempString, 29); } sprintf(TempString, "%d/%d,%d/%d,%d/%d", Get32s(ValuePtr), Get32s(4+(char*)ValuePtr), Get32s(8+(char*)ValuePtr), Get32s(12+(char*)ValuePtr), Get32s(16+(char*)ValuePtr), Get32s(20+(char*)ValuePtr)); if (Tag == TAG_GPS_LAT){ strncpy(ImageInfo.GpsLatRaw, TempString, 31); }else{ strncpy(ImageInfo.GpsLongRaw, TempString, 31); } break; case TAG_GPS_ALT_REF: ImageInfo.GpsAlt[0] = (char)(ValuePtr[0] ? '-' : ' '); ImageInfo.GpsAltRef = (char)ValuePtr[0]; break; case TAG_GPS_ALT: sprintf(ImageInfo.GpsAlt + 1, "%.2fm", ConvertAnyFormat(ValuePtr, Format)); ImageInfo.GpsAltRaw.num = Get32u(ValuePtr); ImageInfo.GpsAltRaw.denom = Get32u(4+(char *)ValuePtr); break; case TAG_GPS_TIMESTAMP: snprintf(ImageInfo.GpsTimeStamp, sizeof(ImageInfo.GpsTimeStamp), "%d:%d:%d", (int) ConvertAnyFormat(ValuePtr, Format), (int) ConvertAnyFormat(ValuePtr + 8, Format), (int) ConvertAnyFormat(ValuePtr + 16, Format) ); break; case TAG_GPS_DATESTAMP: strncpy(ImageInfo.GpsDateStamp, (char*)ValuePtr, sizeof(ImageInfo.GpsDateStamp)); break; case TAG_GPS_PROCESSING_METHOD: if (ByteCount > EXIF_ASCII_PREFIX_LEN && memcmp(ValuePtr, ExifAsciiPrefix, EXIF_ASCII_PREFIX_LEN) == 0) { int length = ByteCount < GPS_PROCESSING_METHOD_LEN + EXIF_ASCII_PREFIX_LEN ? ByteCount - EXIF_ASCII_PREFIX_LEN : GPS_PROCESSING_METHOD_LEN; memcpy(ImageInfo.GpsProcessingMethod, (char*)(ValuePtr + EXIF_ASCII_PREFIX_LEN), length); ImageInfo.GpsProcessingMethod[length] = 0; } else { ALOGW("Unsupported encoding for GPSProcessingMethod"); } break; } if (ShowTags){ // Show tag value. if (Tag < MAX_GPS_TAG){ printf(" %s =", GpsTags[Tag].Desc); }else{ // Show unknown tag printf(" Illegal GPS tag %04x=", Tag); } switch(Format){ case FMT_UNDEFINED: // Undefined is typically an ascii string. case FMT_STRING: // String arrays printed without function call (different from int arrays) { printf("\""); for (a=0;a<ByteCount;a++){ int ZeroSkipped = 0; if (ValuePtr[a] >= 32){ if (ZeroSkipped){ printf("?"); ZeroSkipped = 0; } putchar(ValuePtr[a]); }else{ if (ValuePtr[a] == 0){ ZeroSkipped = 1; } } } printf("\"\n"); } break; default: // Handle arrays of numbers later (will there ever be?) for (a=0;;){ PrintFormatNumber(ValuePtr+a*ComponentSize, Format, ByteCount); if (++a >= Components) break; printf(", "); } printf("\n"); } } } }